// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CONTENT_BROWSER_FRAME_HOST_RENDER_FRAME_HOST_MANAGER_H_
#define CONTENT_BROWSER_FRAME_HOST_RENDER_FRAME_HOST_MANAGER_H_

#include <stdint.h>

#include <list>
#include <map>
#include <memory>
#include <unordered_map>

#include "base/containers/hash_tables.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/renderer_host/render_view_host_delegate.h"
#include "content/browser/site_instance_impl.h"
#include "content/common/content_export.h"
#include "content/public/browser/global_request_id.h"
#include "content/public/common/referrer.h"
#include "ui/base/page_transition_types.h"
#include "url/origin.h"

namespace content {
class BrowserContext;
class CrossProcessFrameConnector;
class CrossSiteTransferringRequest;
class FrameNavigationEntry;
class FrameTreeNode;
class InterstitialPageImpl;
class NavigationControllerImpl;
class NavigationEntry;
class NavigationEntryImpl;
class NavigationHandleImpl;
class NavigationRequest;
class NavigatorTestWithBrowserSideNavigation;
class RenderFrameHostDelegate;
class RenderFrameHostManagerTest;
class RenderFrameProxyHost;
class RenderViewHost;
class RenderViewHostImpl;
class RenderWidgetHostDelegate;
class RenderWidgetHostView;
class TestWebContents;
class WebUIImpl;
struct CommonNavigationParams;
struct ContentSecurityPolicyHeader;
struct FrameReplicationState;

// Manages RenderFrameHosts for a FrameTreeNode. It maintains a
// current_frame_host() which is the content currently visible to the user. When
// a frame is told to navigate to a different web site (as determined by
// SiteInstance), it will replace its current RenderFrameHost with a new
// RenderFrameHost dedicated to the new SiteInstance, possibly in a new process.
//
// Cross-process navigation works like this:
//
// - RFHM::Navigate determines whether the destination is cross-site, and if so,
//   it creates a pending_render_frame_host_.
//
// - The pending RFH is created in the "navigations suspended" state, meaning no
//   navigation messages are sent to its renderer until the beforeunload handler
//   has a chance to run in the current RFH.
//
// - The current RFH runs its beforeunload handler. If it returns false, we
//   cancel all the pending logic. Otherwise we allow the pending RFH to send
//   the navigation request to its renderer.
//
// - ResourceDispatcherHost receives a ResourceRequest on the IO thread for the
//   main resource load from the pending RFH. It creates a
//   CrossSiteResourceHandler to check whether a process transfer is needed when
//   the request is ready to commit.
//
// - When RDH receives a response, the MimeTypeResourceHandler determines
//   whether it is a navigation type that doesn't commit (e.g. download, 204 or
//   error page). If so, it sends a message to the new renderer causing it to
//   cancel the request, and the request (e.g. the download) proceeds. In this
//   case, the pending RFH will never become the current RFH, but it remains
//   until the next DidNavigate event for this WebContentsImpl.
//
// - After RDH receives a response and determines that it is safe and not a
//   download, the CrossSiteResourceHandler checks whether a transfer for a
//   redirect is needed. If so, it pauses the network response and starts an
//   identical navigation in a new pending RFH. When the identical request is
//   later received by RDH, the response is transferred and unpaused.
//
// - Otherwise, the network response commits in the pending RFH's renderer,
//   which sends a DidCommitProvisionalLoad message back to the browser process.
//
// - RFHM::CommitPending makes visible the new RFH, and initiates the unload
//   handler in the old RFH. The unload handler will complete in the background.
//
// - RenderFrameHostManager may keep the previous RFH alive as a
//   RenderFrameProxyHost, to be used (for example) if the user goes back. The
//   process only stays live if another tab is using it, but if so, the existing
//   frame relationships will be maintained.
class CONTENT_EXPORT RenderFrameHostManager
    : public SiteInstanceImpl::Observer {
 public:
  // Functions implemented by our owner that we need.
  //
  // TODO(brettw) Clean this up! These are all the functions in WebContentsImpl
  // that are required to run this class. The design should probably be better
  // such that these are more clear.
  //
  // There is additional complexity that some of the functions we need in
  // WebContentsImpl are inherited and non-virtual. These are named with
  // "RenderManager" so that the duplicate implementation of them will be clear.
  //
  // Functions and parameters whose description are prefixed by PlzNavigate are
  // part of a navigation refactoring project, currently behind the
  // enable-browser-side-navigation flag. The idea is to move the logic behind
  // driving navigations from the renderer to the browser.
  class CONTENT_EXPORT Delegate {
   public:
    // Initializes the given renderer if necessary and creates the view ID
    // corresponding to this view host. If this method is not called and the
    // process is not shared, then the WebContentsImpl will act as though the
    // renderer is not running (i.e., it will render "sad tab"). This method is
    // automatically called from LoadURL.
    virtual bool CreateRenderViewForRenderManager(
        RenderViewHost* render_view_host,
        int opener_frame_routing_id,
        int proxy_routing_id,
        const FrameReplicationState& replicated_frame_state) = 0;
    virtual void CreateRenderWidgetHostViewForRenderManager(
        RenderViewHost* render_view_host) = 0;
    virtual bool CreateRenderFrameForRenderManager(
        RenderFrameHost* render_frame_host,
        int proxy_routing_id,
        int opener_routing_id,
        int parent_routing_id,
        int previous_sibling_routing_id) = 0;
    virtual void BeforeUnloadFiredFromRenderManager(
        bool proceed, const base::TimeTicks& proceed_time,
        bool* proceed_to_fire_unload) = 0;
    virtual void RenderProcessGoneFromRenderManager(
        RenderViewHost* render_view_host) = 0;
    virtual void UpdateRenderViewSizeForRenderManager() = 0;
    virtual void CancelModalDialogsForRenderManager() = 0;
    virtual void NotifySwappedFromRenderManager(RenderFrameHost* old_host,
                                                RenderFrameHost* new_host,
                                                bool is_main_frame) = 0;
    // TODO(nasko): This should be removed once extensions no longer use
    // NotificationService. See https://crbug.com/462682.
    virtual void NotifyMainFrameSwappedFromRenderManager(
        RenderViewHost* old_host,
        RenderViewHost* new_host) = 0;
    virtual NavigationControllerImpl&
        GetControllerForRenderManager() = 0;

    // Returns the navigation entry of the current navigation, or NULL if there
    // is none.
    virtual NavigationEntry*
        GetLastCommittedNavigationEntryForRenderManager() = 0;

    // Returns true if the location bar should be focused by default rather than
    // the page contents. The view calls this function when the tab is focused
    // to see what it should do.
    virtual bool FocusLocationBarByDefault() = 0;

    // Focuses the location bar.
    virtual void SetFocusToLocationBar(bool select_all) = 0;

    // Returns true if views created for this delegate should be created in a
    // hidden state.
    virtual bool IsHidden() = 0;

    // If the delegate is an inner WebContents, this method returns the
    // FrameTreeNode ID of the frame in the outer WebContents which hosts
    // the inner WebContents. Returns FrameTreeNode::kFrameTreeNodeInvalidId
    // if the delegate does not have an outer WebContents.
    virtual int GetOuterDelegateFrameTreeNodeId() = 0;

   protected:
    virtual ~Delegate() {}
  };

  // All three delegate pointers must be non-NULL and are not owned by this
  // class. They must outlive this class. The RenderViewHostDelegate and
  // RenderWidgetHostDelegate are what will be installed into all
  // RenderViewHosts that are created.
  //
  // You must call Init() before using this class.
  RenderFrameHostManager(
      FrameTreeNode* frame_tree_node,
      RenderFrameHostDelegate* render_frame_delegate,
      RenderWidgetHostDelegate* render_widget_delegate,
      Delegate* delegate);
  ~RenderFrameHostManager();

  // For arguments, see WebContentsImpl constructor.
  void Init(SiteInstance* site_instance,
            int32_t view_routing_id,
            int32_t frame_routing_id,
            int32_t widget_routing_id);

  // Returns the currently active RenderFrameHost.
  //
  // This will be non-NULL between Init() and Shutdown(). You may want to NULL
  // check it in many cases, however. Windows can send us messages during the
  // destruction process after it has been shut down.
  RenderFrameHostImpl* current_frame_host() const {
    return render_frame_host_.get();
  }

  // TODO(creis): Remove this when we no longer use RVH for navigation.
  RenderViewHostImpl* current_host() const;

  // Returns the view associated with the current RenderViewHost, or NULL if
  // there is no current one.
  RenderWidgetHostView* GetRenderWidgetHostView() const;

  // Returns whether this manager belongs to a FrameTreeNode that belongs to an
  // inner WebContents.
  bool ForInnerDelegate();

  // Returns the RenderWidgetHost of the outer WebContents (if any) that can be
  // used to fetch the last keyboard event.
  // TODO(lazyboy): This can be removed once input events are sent directly to
  // remote frames.
  RenderWidgetHostImpl* GetOuterRenderWidgetHostForKeyboardInput();

  // Return the FrameTreeNode for the frame in the outer WebContents (if any)
  // that contains the inner WebContents.
  FrameTreeNode* GetOuterDelegateNode();

  RenderFrameProxyHost* GetProxyToParent();

  // Returns the proxy to inner WebContents in the outer WebContents's
  // SiteInstance. Returns nullptr if this WebContents isn't part of inner/outer
  // relationship.
  RenderFrameProxyHost* GetProxyToOuterDelegate();

  // Removes the FrameTreeNode in the outer WebContents that represents this
  // FrameTreeNode.
  // TODO(lazyboy): This does not belong to RenderFrameHostManager, move it to
  // somehwere else.
  void RemoveOuterDelegateFrame();

  // Returns the pending RenderFrameHost, or null if there is no pending one.
  RenderFrameHostImpl* pending_frame_host() const {
    return pending_render_frame_host_.get();
  }

  // Returns the speculative RenderFrameHost, or null if there is no speculative
  // one.
  RenderFrameHostImpl* speculative_frame_host() const {
    return speculative_render_frame_host_.get();
  }

  // TODO(creis): Remove this when we no longer use RVH for navigation.
  RenderViewHostImpl* pending_render_view_host() const;

  // Returns the WebUI associated with the ongoing navigation, it being either
  // the active or the pending one from the navigating RenderFrameHost. Returns
  // null if there's no ongoing navigation or if no WebUI applies.
  WebUIImpl* GetNavigatingWebUI() const;

  // Called when we want to instruct the renderer to navigate to the given
  // navigation entry. It may create a new RenderFrameHost or re-use an existing
  // one. The RenderFrameHost to navigate will be returned. Returns NULL if one
  // could not be created. |dest_url| takes precedence over the |frame_entry|'s
  // url (this is necessary because ReloadOriginalRequest navigates to a
  // different URL than the last committed entry, without modifying it).
  RenderFrameHostImpl* Navigate(const GURL& dest_url,
                                const FrameNavigationEntry& frame_entry,
                                const NavigationEntryImpl& entry);

  // Instructs the various live views to stop. Called when the user directed the
  // page to stop loading.
  void Stop();

  // Notifies the regular and pending RenderViewHosts that a load is or is not
  // happening. Even though the message is only for one of them, we don't know
  // which one so we tell both.
  void SetIsLoading(bool is_loading);

  // Whether to close the tab or not when there is a hang during an unload
  // handler. If we are mid-crosssite navigation, then we should proceed
  // with the navigation instead of closing the tab.
  bool ShouldCloseTabOnUnresponsiveRenderer();

  // Confirms whether we should close the page or navigate away.  This is called
  // before a cross-site request or before a tab/window is closed (as indicated
  // by the first parameter) to allow the appropriate renderer to approve or
  // deny the request.  |proceed| indicates whether the user chose to proceed.
  // |proceed_time| is the time when the request was allowed to proceed.
  void OnBeforeUnloadACK(bool for_cross_site_transition,
                         bool proceed,
                         const base::TimeTicks& proceed_time);

  // The |pending_render_frame_host| is ready to commit a page.  We should
  // ensure that the old RenderFrameHost runs its unload handler first and
  // determine whether a RenderFrameHost transfer is needed.
  // |cross_site_transferring_request| is NULL if a request is not being
  // transferred between renderers.
  void OnCrossSiteResponse(RenderFrameHostImpl* pending_render_frame_host,
                           const GlobalRequestID& global_request_id,
                           std::unique_ptr<CrossSiteTransferringRequest>
                               cross_site_transferring_request,
                           const std::vector<GURL>& transfer_url_chain,
                           const Referrer& referrer,
                           ui::PageTransition page_transition,
                           bool should_replace_current_entry);

  // Determines whether a navigation to |dest_url| may be completed using an
  // existing RenderFrameHost, or whether transferring to a new RenderFrameHost
  // backed by a different render process is required. This is a security policy
  // check determined by the current site isolation mode, and must be done
  // before the resource at |dest_url| is delivered to |existing_rfh|.
  //
  // |existing_rfh| must belong to this RFHM, but it can be a pending or current
  // host.
  //
  // When this function returns true for a subframe, an out-of-process iframe
  // must be created.
  bool IsRendererTransferNeededForNavigation(RenderFrameHostImpl* existing_rfh,
                                             const GURL& dest_url);

  // Called when a renderer's frame navigates.
  void DidNavigateFrame(RenderFrameHostImpl* render_frame_host,
                        bool was_caused_by_user_gesture);

  // Called when this frame's opener is changed to the frame specified by
  // |opener_routing_id| in |source_site_instance|'s process.  This change
  // could come from either the current RenderFrameHost or one of the
  // proxies (e.g., window.open that targets a RemoteFrame by name).  The
  // updated opener will be forwarded to any other RenderFrameProxies and
  // RenderFrames for this FrameTreeNode.
  void DidChangeOpener(int opener_routing_id,
                       SiteInstance* source_site_instance);

  // Creates and initializes a RenderFrameHost. If |view_routing_id_ptr|
  // is not nullptr it will be set to the routing id of the view associated with
  // the frame.
  std::unique_ptr<RenderFrameHostImpl> CreateRenderFrame(
      SiteInstance* instance,
      bool hidden,
      int* view_routing_id_ptr);

  // Helper method to create and initialize a RenderFrameProxyHost and return
  // its routing id.
  int CreateRenderFrameProxy(SiteInstance* instance);

  // Creates proxies for a new child frame at FrameTreeNode |child| in all
  // SiteInstances for which the current frame has proxies.  This method is
  // called on the parent of a new child frame before the child leaves the
  // SiteInstance.
  void CreateProxiesForChildFrame(FrameTreeNode* child);

  // Sets the passed passed interstitial as the currently showing interstitial.
  // |interstitial_page| should be non NULL (use the remove_interstitial_page
  // method to unset the interstitial) and no interstitial page should be set
  // when there is already a non NULL interstitial page set.
  void set_interstitial_page(InterstitialPageImpl* interstitial_page) {
    DCHECK(!interstitial_page_ && interstitial_page);
    interstitial_page_ = interstitial_page;
  }

  // Unsets the currently showing interstitial.
  void remove_interstitial_page() {
    DCHECK(interstitial_page_);
    interstitial_page_ = NULL;
  }

  // Returns the currently showing interstitial, NULL if no interstitial is
  // showing.
  InterstitialPageImpl* interstitial_page() const { return interstitial_page_; }

  // Returns the swapped out RenderViewHost for the given SiteInstance, if any.
  // This method is *deprecated* and GetRenderFrameProxyHost should be used.
  RenderViewHostImpl* GetSwappedOutRenderViewHost(SiteInstance* instance) const;

  // Returns the RenderFrameProxyHost for the given SiteInstance, if any.
  RenderFrameProxyHost* GetRenderFrameProxyHost(
      SiteInstance* instance) const;

  // If |render_frame_host| is on the pending deletion list, this deletes it.
  // Returns whether it was deleted.
  bool DeleteFromPendingList(RenderFrameHostImpl* render_frame_host);

  // Deletes any proxy hosts associated with this node. Used during destruction
  // of WebContentsImpl.
  void ResetProxyHosts();

  void ClearRFHsPendingShutdown();
  void ClearWebUIInstances();

  // Returns the routing id for a RenderFrameHost or RenderFrameProxyHost
  // that has the given SiteInstance and is associated with this
  // RenderFrameHostManager. Returns MSG_ROUTING_NONE if none is found.
  int GetRoutingIdForSiteInstance(SiteInstance* site_instance);

  // PlzNavigate
  // Notifies the RenderFrameHostManager that a new NavigationRequest has been
  // created and set in the FrameTreeNode so that it can speculatively create a
  // new RenderFrameHost (and potentially a new process) if needed.
  void DidCreateNavigationRequest(NavigationRequest* request);

  // PlzNavigate
  // Called (possibly several times) during a navigation to select or create an
  // appropriate RenderFrameHost for the provided URL. The returned pointer will
  // be for the current or the speculative RenderFrameHost and the instance is
  // owned by this manager.
  RenderFrameHostImpl* GetFrameHostForNavigation(
      const NavigationRequest& request);

  // PlzNavigate
  // Clean up any state for any ongoing navigation.
  void CleanUpNavigation();

  // PlzNavigate
  // Clears the speculative members, returning the RenderFrameHost to the caller
  // for disposal.
  std::unique_ptr<RenderFrameHostImpl> UnsetSpeculativeRenderFrameHost();

  // Notification methods to tell this RenderFrameHostManager that the frame it
  // is responsible for has started or stopped loading a document.
  void OnDidStartLoading();
  void OnDidStopLoading();

  // OnDidUpdateName gets called when a frame changes its name - it gets the new
  // |name| and the recalculated |unique_name| and replicates them into all
  // frame proxies.
  void OnDidUpdateName(const std::string& name, const std::string& unique_name);

  // Sends the newly added Content Security Policy header to all the proxies.
  void OnDidAddContentSecurityPolicy(const ContentSecurityPolicyHeader& header);

  // Resets Content Security Policy in all the proxies.
  void OnDidResetContentSecurityPolicy();

  // Sends updated enforcement of strict mixed content checking to all
  // frame proxies when the frame changes its setting.
  void OnEnforceStrictMixedContentChecking(bool should_enforce);

  // Send updated origin to all frame proxies when the frame navigates to a new
  // origin.
  void OnDidUpdateOrigin(const url::Origin& origin,
                         bool is_potentially_trustworthy_unique_origin);

  void EnsureRenderViewInitialized(RenderViewHostImpl* render_view_host,
                                   SiteInstance* instance);

  // Creates swapped out RenderViews and RenderFrameProxies for this frame's
  // FrameTree and for its opener chain in the given SiteInstance. This allows
  // other tabs to send cross-process JavaScript calls to their opener(s) and
  // to any other frames in the opener's FrameTree (e.g., supporting calls like
  // window.opener.opener.frames[x][y]).  Does not create proxies for the
  // subtree rooted at |skip_this_node| (e.g., if a node is being navigated, it
  // can be passed here to prevent proxies from being created for it, in
  // case it is in the same FrameTree as another node on its opener chain).
  void CreateOpenerProxies(SiteInstance* instance,
                           FrameTreeNode* skip_this_node);

  // Ensure that this frame has proxies in all SiteInstances that can discover
  // this frame by name (e.g., via window.open("", "frame_name")).  See
  // https://crbug.com/511474.
  void CreateProxiesForNewNamedFrame();

  // Returns a routing ID for the current FrameTreeNode's opener node in the
  // given SiteInstance.  May return a routing ID of either a RenderFrameHost
  // (if opener's current or pending RFH has SiteInstance |instance|) or a
  // RenderFrameProxyHost.  Returns MSG_ROUTING_NONE if there is no opener, or
  // if the opener node doesn't have a proxy for |instance|.
  int GetOpenerRoutingID(SiteInstance* instance);

  // Called on the RFHM of the inner WebContents to create a
  // RenderFrameProxyHost in its outer WebContents's SiteInstance,
  // |outer_contents_site_instance|. The frame in outer WebContents that is
  // hosting the inner WebContents is |render_frame_host|, and the frame will
  // be swapped out with the proxy.
  void CreateOuterDelegateProxy(SiteInstance* outer_contents_site_instance,
                                RenderFrameHostImpl* render_frame_host);

  // Sets the child RenderWidgetHostView for this frame, which must be part of
  // an inner WebContents.
  void SetRWHViewForInnerContents(RenderWidgetHostView* child_rwhv);

  // Returns the number of RenderFrameProxyHosts for this frame.
  int GetProxyCount();

  // Sends an IPC message to every process in the FrameTree. This should only be
  // called in the top-level RenderFrameHostManager.
  void SendPageMessage(IPC::Message* msg);

  // Returns a const reference to the map of proxy hosts. The keys are
  // SiteInstance IDs, the values are RenderFrameProxyHosts.
  const std::unordered_map<int32_t, std::unique_ptr<RenderFrameProxyHost>>&
  GetAllProxyHostsForTesting() const {
    return proxy_hosts_;
  }

  // SiteInstanceImpl::Observer
  void ActiveFrameCountIsZero(SiteInstanceImpl* site_instance) override;
  void RenderProcessGone(SiteInstanceImpl* site_instance) override;

  // Sets up the necessary state for a new RenderViewHost.  If |proxy| is not
  // null, it creates a RenderFrameProxy in the target renderer process which is
  // used to route IPC messages when in swapped out state.  Returns early if the
  // RenderViewHost has already been initialized for another RenderFrameHost.
  bool InitRenderView(RenderViewHostImpl* render_view_host,
    RenderFrameProxyHost* proxy);

 private:
  friend class NavigatorTestWithBrowserSideNavigation;
  friend class RenderFrameHostManagerTest;
  friend class TestWebContents;

  enum class SiteInstanceRelation {
    // A SiteInstance in a different browsing instance from the current.
    UNRELATED,
    // A SiteInstance in the same browsing instance as the current.
    RELATED,
    // The default subframe SiteInstance for the current browsing instance.
    RELATED_DEFAULT_SUBFRAME,
  };

  // Stores information regarding a SiteInstance targeted at a specific URL to
  // allow for comparisons without having to actually create new instances. It
  // can point to an existing one or store the details needed to create a new
  // one.
  struct CONTENT_EXPORT SiteInstanceDescriptor {
    explicit SiteInstanceDescriptor(content::SiteInstance* site_instance)
        : existing_site_instance(site_instance),
          relation(SiteInstanceRelation::UNRELATED) {}

    SiteInstanceDescriptor(BrowserContext* browser_context,
                           GURL dest_url,
                           SiteInstanceRelation relation_to_current);

    // Set with an existing SiteInstance to be reused.
    content::SiteInstance* existing_site_instance;

    // In case |existing_site_instance| is null, specify a new site URL.
    GURL new_site_url;

    // In case |existing_site_instance| is null, specify how the new site is
    // related to the current BrowsingInstance.
    SiteInstanceRelation relation;
  };

  // Create a RenderFrameProxyHost owned by this object.
  RenderFrameProxyHost* CreateRenderFrameProxyHost(SiteInstance* site_instance,
                                                   RenderViewHostImpl* rvh);
  // Delete a RenderFrameProxyHost owned by this object.
  void DeleteRenderFrameProxyHost(SiteInstance* site_instance);

  // Returns whether this tab should transition to a new renderer for
  // cross-site URLs.  Enabled unless we see the --process-per-tab command line
  // switch.  Can be overridden in unit tests.
  bool ShouldTransitionCrossSite();

  // Returns true if for the navigation from |current_effective_url| to
  // |new_effective_url|, a new SiteInstance and BrowsingInstance should be
  // created (even if we are in a process model that doesn't usually swap).
  // This forces a process swap and severs script connections with existing
  // tabs.  Cases where this can happen include transitions between WebUI and
  // regular web pages. |new_site_instance| may be null.
  // If there is no current NavigationEntry, then |current_is_view_source_mode|
  // should be the same as |new_is_view_source_mode|.
  //
  // We use the effective URL here, since that's what is used in the
  // SiteInstance's site and when we later call IsSameWebSite.  If there is no
  // current NavigationEntry, check the current SiteInstance's site, which might
  // already be committed to a Web UI URL (such as the NTP).
  bool ShouldSwapBrowsingInstancesForNavigation(
      const GURL& current_effective_url,
      bool current_is_view_source_mode,
      SiteInstance* new_site_instance,
      const GURL& new_effective_url,
      bool new_is_view_source_mode) const;

  // Returns the SiteInstance to use for the navigation.
  scoped_refptr<SiteInstance> GetSiteInstanceForNavigation(
      const GURL& dest_url,
      SiteInstance* source_instance,
      SiteInstance* dest_instance,
      SiteInstance* candidate_instance,
      ui::PageTransition transition,
      bool dest_is_restore,
      bool dest_is_view_source_mode);

  // Returns a descriptor of the appropriate SiteInstance object for the given
  // |dest_url|, possibly reusing the current, source or destination
  // SiteInstance. The actual SiteInstance can then be obtained calling
  // ConvertToSiteInstance with the descriptor.
  //
  // |source_instance| is the SiteInstance of the frame that initiated the
  // navigation. |current_instance| is the SiteInstance of the frame that is
  // currently navigating. |dest_instance| is a predetermined SiteInstance that
  // will be used if not null.
  // For example, if you have a parent frame A, which has a child frame B, and
  // A is trying to change the src attribute of B, this will cause a navigation
  // where the source SiteInstance is A and B is the current SiteInstance.
  //
  // This is a helper function for GetSiteInstanceForNavigation.
  SiteInstanceDescriptor DetermineSiteInstanceForURL(
      const GURL& dest_url,
      SiteInstance* source_instance,
      SiteInstance* current_instance,
      SiteInstance* dest_instance,
      ui::PageTransition transition,
      bool dest_is_restore,
      bool dest_is_view_source_mode,
      bool force_browsing_instance_swap);

  // Converts a SiteInstanceDescriptor to the actual SiteInstance it describes.
  // If a |candidate_instance| is provided (is not nullptr) and it matches the
  // description, it is returned as is.
  scoped_refptr<SiteInstance> ConvertToSiteInstance(
      const SiteInstanceDescriptor& descriptor,
      SiteInstance* candidate_instance);

  // Returns true if |candidate| is currently on the same web site as dest_url.
  bool IsCurrentlySameSite(RenderFrameHostImpl* candidate,
                           const GURL& dest_url);

  // Creates a new RenderFrameHostImpl for the |new_instance| and assign it to
  // |pending_render_frame_host_| while respecting the opener route if needed
  // and stores it in pending_render_frame_host_.
  void CreatePendingRenderFrameHost(SiteInstance* old_instance,
                                    SiteInstance* new_instance);

  // Ensure that we have created all needed proxies for a new RFH with
  // SiteInstance |new_instance|: (1) create swapped-out RVHs and proxies for
  // the new RFH's opener chain if we are staying in the same BrowsingInstance;
  // (2) Create proxies for the new RFH's SiteInstance in its own frame tree.
  void CreateProxiesForNewRenderFrameHost(SiteInstance* old_instance,
                                          SiteInstance* new_instance);

  // Traverse the opener chain and populate |opener_frame_trees| with
  // all FrameTrees accessible by following frame openers of nodes in the
  // given node's FrameTree. |opener_frame_trees| is ordered so that openers
  // of smaller-indexed entries point to larger-indexed entries (i.e., this
  // node's FrameTree is at index 0, its opener's FrameTree is at index 1,
  // etc). If the traversal encounters a node with an opener pointing to a
  // FrameTree that has already been traversed (such as when there's a cycle),
  // the node is added to |nodes_with_back_links|.
  void CollectOpenerFrameTrees(
      std::vector<FrameTree*>* opener_frame_trees,
      base::hash_set<FrameTreeNode*>* nodes_with_back_links);

  // Create swapped out RenderViews and RenderFrameProxies in the given
  // SiteInstance for the current node's FrameTree.  Used as a helper function
  // in CreateOpenerProxies for creating proxies in each FrameTree on the
  // opener chain.  Don't create proxies for the subtree rooted at
  // |skip_this_node|.
  void CreateOpenerProxiesForFrameTree(SiteInstance* instance,
                                       FrameTreeNode* skip_this_node);

  // Creates a RenderFrameHost and corresponding RenderViewHost if necessary.
  std::unique_ptr<RenderFrameHostImpl> CreateRenderFrameHost(
      SiteInstance* instance,
      int32_t view_routing_id,
      int32_t frame_routing_id,
      int32_t widget_routing_id,
      bool hidden);

  // PlzNavigate
  // Create and initialize a speculative RenderFrameHost for an ongoing
  // navigation. It might be destroyed and re-created later if the navigation
  // is redirected to a different SiteInstance.
  bool CreateSpeculativeRenderFrameHost(SiteInstance* old_instance,
                                        SiteInstance* new_instance);

  // Initialization for RenderFrameHost uses the same sequence as InitRenderView
  // above.
  bool InitRenderFrame(RenderFrameHostImpl* render_frame_host);

  // Makes the pending WebUI on the current RenderFrameHost active. Call this
  // when the current RenderFrameHost commits and it has a pending WebUI.
  void CommitPendingWebUI();

  // Sets the pending RenderFrameHost to be the active one. Call when the
  // pending RenderFrameHost commits.
  // If PlzNavigate is enabled the method will set the speculative (not pending)
  // RenderFrameHost to be the active one.
  void CommitPending();

  // Helper to call CommitPending() in all necessary cases.
  void CommitPendingIfNecessary(RenderFrameHostImpl* render_frame_host,
                                bool was_caused_by_user_gesture);

  // Commits any pending sandbox flag updates when the renderer's frame
  // navigates.
  void CommitPendingSandboxFlags();

  // Runs the unload handler in the old RenderFrameHost, after the new
  // RenderFrameHost has committed.  |old_render_frame_host| will either be
  // deleted or put on the pending delete list during this call.
  void SwapOutOldFrame(
      std::unique_ptr<RenderFrameHostImpl> old_render_frame_host);

  // Discards a RenderFrameHost that was never made active (for active ones
  // SwapOutOldFrame is used instead).
  void DiscardUnusedFrame(
      std::unique_ptr<RenderFrameHostImpl> render_frame_host);

  // Helper method to terminate the pending RenderFrameHost. The frame may be
  // deleted immediately, or it may be kept around in hopes of later reuse.
  void CancelPending();

  // Clears pending_render_frame_host_, returning it to the caller for disposal.
  std::unique_ptr<RenderFrameHostImpl> UnsetPendingRenderFrameHost();

  // Helper method to set the active RenderFrameHost. Returns the old
  // RenderFrameHost and updates counts.
  std::unique_ptr<RenderFrameHostImpl> SetRenderFrameHost(
      std::unique_ptr<RenderFrameHostImpl> render_frame_host);

  RenderFrameHostImpl* UpdateStateForNavigate(
      const GURL& dest_url,
      SiteInstance* source_instance,
      SiteInstance* dest_instance,
      ui::PageTransition transition,
      bool dest_is_restore,
      bool dest_is_view_source_mode,
      const GlobalRequestID& transferred_request_id,
      int bindings);

  // Updates the pending WebUI of the current RenderFrameHost for a same-site
  // navigation.
  void UpdatePendingWebUIOnCurrentFrameHost(const GURL& dest_url,
                                            int entry_bindings);

  // Returns true if a subframe can navigate cross-process.
  bool CanSubframeSwapProcess(const GURL& dest_url,
                              SiteInstance* source_instance,
                              SiteInstance* dest_instance);

  // For use in creating RenderFrameHosts.
  FrameTreeNode* frame_tree_node_;

  // Our delegate, not owned by us. Guaranteed non-NULL.
  Delegate* delegate_;

  // Implemented by the owner of this class.  These delegates are installed into
  // all the RenderFrameHosts that we create.
  RenderFrameHostDelegate* render_frame_delegate_;
  RenderWidgetHostDelegate* render_widget_delegate_;

  // Our RenderFrameHost which is responsible for all communication with a child
  // RenderFrame instance.
  // For now, RenderFrameHost keeps a RenderViewHost in its SiteInstance alive.
  // Eventually, RenderViewHost will be replaced with a page context.
  std::unique_ptr<RenderFrameHostImpl> render_frame_host_;

  // A RenderFrameHost used to load a cross-site page. This remains hidden
  // while a cross-site request is pending until it calls DidNavigate.
  // Note: This member is not used in PlzNavigate.
  std::unique_ptr<RenderFrameHostImpl> pending_render_frame_host_;

  // If a pending request needs to be transferred to another process, this
  // owns the request until it's transferred to the new process, so it will be
  // cleaned up if the navigation is cancelled.  Otherwise, this is NULL.
  std::unique_ptr<CrossSiteTransferringRequest>
      cross_site_transferring_request_;

  // This is used to temporarily store the NavigationHandle during
  // transferring navigations. The handle needs to be stored because the old
  // RenderFrameHost may be discarded before a new RenderFrameHost is created
  // for the navigation.
  // PlzNavigate: this will never be set since there are no transferring
  // navigations in PlzNavigate.
  std::unique_ptr<NavigationHandleImpl> transfer_navigation_handle_;

  // Proxy hosts, indexed by site instance ID.
  std::unordered_map<int32_t, std::unique_ptr<RenderFrameProxyHost>>
      proxy_hosts_;

  // A list of RenderFrameHosts waiting to shut down after swapping out.
  using RFHPendingDeleteList = std::list<std::unique_ptr<RenderFrameHostImpl>>;
  RFHPendingDeleteList pending_delete_hosts_;

  // The intersitial page currently shown if any, not own by this class
  // (the InterstitialPage is self-owned, it deletes itself when hidden).
  InterstitialPageImpl* interstitial_page_;

  // PlzNavigate
  // Stores a speculative RenderFrameHost which is created early in a navigation
  // so a renderer process can be started in parallel, if needed.
  // This is purely a performance optimization and is not required for correct
  // behavior. The speculative RenderFrameHost might be discarded later on if
  // the final URL's SiteInstance isn't compatible with the one used to create
  // it.
  // Note: PlzNavigate only uses the speculative RenderFrameHost, not the
  // pending one.
  std::unique_ptr<RenderFrameHostImpl> speculative_render_frame_host_;

  base::WeakPtrFactory<RenderFrameHostManager> weak_factory_;

  DISALLOW_COPY_AND_ASSIGN(RenderFrameHostManager);
};

}  // namespace content

#endif  // CONTENT_BROWSER_FRAME_HOST_RENDER_FRAME_HOST_MANAGER_H_
