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

#ifndef CONTENT_BROWSER_RENDERER_HOST_FRAME_TREE_H_
#define CONTENT_BROWSER_RENDERER_HOST_FRAME_TREE_H_

#include <stdint.h>

#include <iterator>
#include <memory>
#include <string>
#include <unordered_map>

#include "base/containers/queue.h"
#include "base/dcheck_is_on.h"
#include "base/functional/callback.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/safe_ref.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/renderer_host/frame_tree_node.h"
#include "content/browser/renderer_host/navigator.h"
#include "content/browser/renderer_host/navigator_delegate.h"
#include "content/browser/renderer_host/render_frame_host_manager.h"
#include "content/browser/renderer_host/render_view_host_enums.h"
#include "content/common/content_export.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "services/service_manager/public/mojom/interface_provider.mojom.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/frame/frame_owner_element_type.h"
#include "third_party/blink/public/common/tokens/tokens.h"
#include "third_party/blink/public/mojom/frame/frame_owner_properties.mojom-forward.h"
#include "url/origin.h"

namespace blink {
namespace mojom {
class BrowserInterfaceBroker;
enum class TreeScopeType;
}  // namespace mojom

struct FramePolicy;
}  // namespace blink

namespace content {

class BrowserContext;
class PageDelegate;
class RenderFrameHostDelegate;
class RenderFrameProxyHost;
class RenderViewHostDelegate;
class RenderViewHostImpl;
class RenderFrameHostManager;
class RenderWidgetHostDelegate;
class SiteInstance;
class SiteInstanceGroup;

// Represents the frame tree for a page. With the exception of the main frame,
// all FrameTreeNodes will be created/deleted in response to frame attach and
// detach events in the DOM.
//
// The main frame's FrameTreeNode is special in that it is reused. This allows
// it to serve as an anchor for state that needs to persist across top-level
// page navigations.
//
// TODO(ajwong): Move NavigationController ownership to the main frame
// FrameTreeNode. Possibly expose access to it from here.
//
// This object is only used on the UI thread.
class CONTENT_EXPORT FrameTree {
 public:
  class NodeRange;

  class CONTENT_EXPORT NodeIterator {
   public:
    using iterator_category = std::forward_iterator_tag;
    using value_type = FrameTreeNode*;
    using difference_type = std::ptrdiff_t;
    using pointer = FrameTreeNode**;
    using reference = FrameTreeNode*&;

    NodeIterator(const NodeIterator& other);
    ~NodeIterator();

    NodeIterator& operator++();
    // Advances the iterator and excludes the children of the current node
    NodeIterator& AdvanceSkippingChildren();

    bool operator==(const NodeIterator& rhs) const;

    FrameTreeNode* operator*() { return current_node_; }

   private:
    friend class FrameTreeTest;
    friend class NodeRange;

    NodeIterator(const std::vector<raw_ptr<FrameTreeNode, VectorExperimental>>&
                     starting_nodes,
                 const FrameTreeNode* root_of_subtree_to_skip,
                 bool should_descend_into_inner_trees,
                 bool include_delegate_nodes_for_inner_frame_trees);

    void AdvanceNode();

    // `current_node_` and `root_of_subtree_to_skip_` are not a raw_ptr<...> for
    // performance reasons (based on analysis of sampling profiler data and
    // tab_search:top100:2020).
    RAW_PTR_EXCLUSION FrameTreeNode* current_node_;
    RAW_PTR_EXCLUSION const FrameTreeNode* const root_of_subtree_to_skip_;

    const bool should_descend_into_inner_trees_;
    const bool include_delegate_nodes_for_inner_frame_trees_;
    base::circular_deque<FrameTreeNode*> queue_;
  };

  class CONTENT_EXPORT NodeRange {
   public:
    NodeRange(const NodeRange&);
    ~NodeRange();

    NodeIterator begin();
    NodeIterator end();

   private:
    friend class FrameTree;

    NodeRange(const std::vector<raw_ptr<FrameTreeNode, VectorExperimental>>&
                  starting_nodes,
              const FrameTreeNode* root_of_subtree_to_skip,
              bool should_descend_into_inner_trees,
              bool include_delegate_nodes_for_inner_frame_trees);

    const std::vector<raw_ptr<FrameTreeNode, VectorExperimental>>
        starting_nodes_;
    const raw_ptr<const FrameTreeNode> root_of_subtree_to_skip_;
    const bool should_descend_into_inner_trees_;
    const bool include_delegate_nodes_for_inner_frame_trees_;
  };

  class CONTENT_EXPORT Delegate {
   public:
    // The FrameTree changed its LoadingState. This can be a transition between
    // not-loading and loading (in which case it will be accompanied by either a
    // DidStartLoading or DidStopLoading), or a transition between not showing
    // loading UI and showing loading UI while a navigation is in progress (in
    // which case it will be called without either DidStartLoading or
    // DidStopLoading).
    virtual void LoadingStateChanged(LoadingState new_state) = 0;

    // The FrameTree has started loading in `frame_tree_node`. Note that this
    // is only called when the FrameTree as a whole goes from not-loading to
    // loading. If a second FrameTreeNode begins loading, a new DidStartLoading
    // message will not be sent.
    virtual void DidStartLoading(FrameTreeNode* frame_tree_node) = 0;

    // The FrameTree has stopped loading. Sent only when all FrameTreeNodes have
    // stopped loading.
    virtual void DidStopLoading() = 0;

    // Returns the delegate's top loading tree, which should be used to infer
    // the values of loading-related states. The state of
    // IsLoadingIncludingInnerFrameTrees() is a WebContents level concept and
    // LoadingTree would return the frame tree to which loading events should be
    // directed.
    //
    // TODO(crbug.com/40202416): Remove this method and directly rely on
    // GetOutermostMainFrame() once guest views are migrated to MPArch.
    virtual FrameTree* LoadingTree() = 0;

    // Returns true when the active RenderWidgetHostView should be hidden.
    virtual bool IsHidden() = 0;

    // If the FrameTree using this delegate is an inner/nested FrameTree, then
    // there may be a FrameTreeNode in the outer FrameTree that is considered
    // our outer delegate FrameTreeNode. This method returns the outer delegate
    // FrameTreeNode ID if one exists. If we don't have a an outer delegate
    // FrameTreeNode, this method returns an invalid value.
    virtual FrameTreeNodeId GetOuterDelegateFrameTreeNodeId() = 0;

    // If the FrameTree using this delegate is an inner/nested FrameTree that
    // has not yet been attached to an outer FrameTreeNode, returns the parent
    // RenderFrameHost of the intended outer FrameTreeNode to which the inner
    // frame tree will be attached. This is usually the RenderFrameHost that is
    // the outer document once attachment occurs, however in the case of some
    // kinds of GuestView, the outer document may end up being a same-origin
    // subframe of the RenderFrameHost returned by this method (see the
    // `testNewWindowAttachInSubFrame` webview test for an example of this).
    // Otherwise, returns null.
    virtual RenderFrameHostImpl* GetProspectiveOuterDocument() = 0;

    // Set the `node` frame as focused in its own FrameTree as well as possibly
    // changing the focused frame tree in the case of inner/outer FrameTrees.
    virtual void SetFocusedFrame(FrameTreeNode* node,
                                 SiteInstanceGroup* source) = 0;

    // Returns this FrameTree's picture-in-picture FrameTree if it has one.
    virtual FrameTree* GetOwnedPictureInPictureFrameTree() = 0;

    // Returns this FrameTree's opener if this FrameTree represents a
    // picture-in-picture window.
    virtual FrameTree* GetPictureInPictureOpenerFrameTree() = 0;

    // Called when the visibility of the RenderFrameProxyHost changes.
    // This method should only handle visibility for inner WebContents and
    // will eventually notify all the RenderWidgetHostViews belonging to that
    // WebContents. If this is not an inner WebContents or the inner WebContents
    // FrameTree root does not match `render_frame_proxy_host` FrameTreeNode it
    // should return false.
    virtual bool OnRenderFrameProxyVisibilityChanged(
        RenderFrameProxyHost* render_frame_proxy_host,
        blink::mojom::FrameVisibility visibility) = 0;
  };

  // Type of FrameTree instance.
  enum class Type {
    // This FrameTree is the primary frame tree for the WebContents, whose main
    // document URL is shown in the Omnibox.
    kPrimary,

    // This FrameTree is used to prerender a page in the background which is
    // invisible to the user.
    kPrerender,

    // This FrameTree is used to host the contents of a <fencedframe> element.
    //
    // Note that the FrameTree's Type should not be confused for
    // `RenderFrameHost::LifecycleState`. For example, when a <fencedframe> is
    // nested in a page in the bfcache, the FrameTree associated with the fenced
    // frame will be kFencedFrame, but the RenderFrameHosts inside of it will
    // have their lifecycle state indicate that they are bfcached.
    kFencedFrame,

    // This FrameTree is used to host the contents of a guest page. Guests are
    // kinds of embedded pages, but their semantics are mostly delegated outside
    // of the content/ layer. See components/guest_view/README.md.
    // The implementation of guests is being migrated from using a separate
    // WebContents to using this FrameTree Type. This type is used with the
    // `features::kGuestViewMPArch` flag.
    kGuest,
  };

  // A set of delegates are remembered here so that we can create
  // RenderFrameHostManagers.
  FrameTree(BrowserContext* browser_context,
            Delegate* delegate,
            NavigationControllerDelegate* navigation_controller_delegate,
            NavigatorDelegate* navigator_delegate,
            RenderFrameHostDelegate* render_frame_delegate,
            RenderViewHostDelegate* render_view_delegate,
            RenderWidgetHostDelegate* render_widget_delegate,
            RenderFrameHostManager::Delegate* manager_delegate,
            PageDelegate* page_delegate,
            Type type);

  FrameTree(const FrameTree&) = delete;
  FrameTree& operator=(const FrameTree&) = delete;

  ~FrameTree();

  // Initializes the main frame for this FrameTree. That is it creates the
  // initial RenderFrameHost in the root node's RenderFrameHostManager, and also
  // creates an initial NavigationEntry that potentially inherits
  // `opener_for_origin`'s origin in its NavigationController. This method will
  // call back into the delegates so it should only be called once they have
  // completed their initialization. Pass in frame_policy so that it can be set
  // in the root node's replication_state.
  // TODO(carlscab): It would be great if initialization could happened in the
  // constructor so we do not leave objects in a half initialized state.
  void Init(SiteInstanceImpl* main_frame_site_instance,
            bool renderer_initiated_creation,
            const std::string& main_frame_name,
            RenderFrameHostImpl* opener_for_origin,
            const blink::FramePolicy& frame_policy,
            const base::UnguessableToken& devtools_frame_token);

  Type type() const { return type_; }

  FrameTreeNode* root() { return &root_; }
  const FrameTreeNode* root() const { return &root_; }

  bool is_primary() const { return type_ == Type::kPrimary; }
  bool is_prerendering() const { return type_ == Type::kPrerender; }
  bool is_fenced_frame() const { return type_ == Type::kFencedFrame; }
  bool is_guest() const { return type_ == Type::kGuest; }

  Delegate* delegate() { return delegate_; }

  // Delegates for various objects.  These can be kept centrally on the
  // FrameTree because they are expected to be the same for all frames on a
  // given FrameTree.
  RenderFrameHostDelegate* render_frame_delegate() {
    return render_frame_delegate_;
  }
  RenderViewHostDelegate* render_view_delegate() {
    return render_view_delegate_;
  }
  RenderWidgetHostDelegate* render_widget_delegate() {
    return render_widget_delegate_;
  }
  RenderFrameHostManager::Delegate* manager_delegate() {
    return manager_delegate_;
  }
  PageDelegate* page_delegate() { return page_delegate_; }

  // Iterate over all RenderViewHosts, including speculative RenderViewHosts.
  // See `speculative_render_view_host_` for more details.
  void ForEachRenderViewHost(
      base::FunctionRef<void(RenderViewHostImpl*)> on_host);

  // Speculative RenderViewHost accessors.
  RenderViewHostImpl* speculative_render_view_host() const {
    return speculative_render_view_host_.get();
  }
  void set_speculative_render_view_host(
      base::WeakPtr<RenderViewHostImpl> render_view_host) {
    speculative_render_view_host_ = render_view_host;
  }

  // Moves `speculative_render_view_host_` to `render_view_host_map_`. This
  // should be called every time a main-frame same-SiteInstanceGroup speculative
  // RenderFrameHost gets swapped in and becomes the active RenderFrameHost.
  // This overwrites the previous RenderViewHost for the SiteInstanceGroup in
  // `render_view_host_map_`, if one exists.
  void MakeSpeculativeRVHCurrent();

  // Returns the FrameTreeNode with the given |frame_tree_node_id| if it is part
  // of this FrameTree.
  FrameTreeNode* FindByID(FrameTreeNodeId frame_tree_node_id);

  // Returns the FrameTreeNode with the given renderer-specific |routing_id|.
  FrameTreeNode* FindByRoutingID(int process_id, int routing_id);

  // Returns the first frame in this tree with the given |name|, or the main
  // frame if |name| is empty.
  // Note that this does NOT support pseudo-names like _self, _top, and _blank,
  // nor searching other FrameTrees (unlike blink::WebView::findFrameByName).
  FrameTreeNode* FindByName(const std::string& name);

  // Returns a range to iterate over all FrameTreeNodes in the frame tree in
  // breadth-first traversal order.
  NodeRange Nodes();

  // Returns a range to iterate over all FrameTreeNodes in a subtree of the
  // frame tree, starting from |subtree_root|.
  NodeRange SubtreeNodes(FrameTreeNode* subtree_root);

  // Returns a range to iterate over all FrameTreeNodes in this frame tree, as
  // well as any FrameTreeNodes of inner frame trees. Note that this includes
  // inner frame trees of inner WebContents as well.
  NodeRange NodesIncludingInnerTreeNodes();

  // Returns a range to iterate over all FrameTreeNodes in a subtree, starting
  // from, but not including |parent|, as well as any FrameTreeNodes of inner
  // frame trees. Note that this includes inner frame trees of inner WebContents
  // as well. If `include_delegate_nodes_for_inner_frame_trees` is true the
  // delegate RenderFrameHost owning the inner frame tree will also be returned.
  static NodeRange SubtreeAndInnerTreeNodes(
      RenderFrameHostImpl* parent,
      bool include_delegate_nodes_for_inner_frame_trees = false);

  // Adds a new child frame to the frame tree. |process_id| is required to
  // disambiguate |new_routing_id|, and it must match the process of the
  // |parent| node. Otherwise no child is added and this method returns nullptr.
  // |interface_provider_receiver| is the receiver end of the InterfaceProvider
  // interface through which the child RenderFrame can access Mojo services
  // exposed by the corresponding RenderFrameHost. The caller takes care of
  // sending the client end of the interface down to the
  // RenderFrame. |policy_container_bind_params|, if not null, is used for
  // binding Blink's policy container to the new RenderFrameHost's
  // PolicyContainerHost. This is only needed if this frame is the result of the
  // CreateChildFrame mojo call, which also delivers the
  // |policy_container_bind_params|. |is_dummy_frame_for_inner_tree| is true if
  // the added frame is only to serve as a placeholder for an inner frame tree
  // (e.g. fenced frames) and will not have a live RenderFrame of its
  // own.
  FrameTreeNode* AddFrame(
      RenderFrameHostImpl* parent,
      int process_id,
      int new_routing_id,
      mojo::PendingAssociatedRemote<mojom::Frame> frame_remote,
      mojo::PendingReceiver<blink::mojom::BrowserInterfaceBroker>
          browser_interface_broker_receiver,
      blink::mojom::PolicyContainerBindParamsPtr policy_container_bind_params,
      mojo::PendingAssociatedReceiver<blink::mojom::AssociatedInterfaceProvider>
          associated_interface_provider_receiver,
      blink::mojom::TreeScopeType scope,
      const std::string& frame_name,
      const std::string& frame_unique_name,
      bool is_created_by_script,
      const blink::LocalFrameToken& frame_token,
      const base::UnguessableToken& devtools_frame_token,
      const blink::DocumentToken& document_token,
      const blink::FramePolicy& frame_policy,
      const blink::mojom::FrameOwnerProperties& frame_owner_properties,
      bool was_discarded,
      blink::FrameOwnerElementType owner_type,
      bool is_dummy_frame_for_inner_tree);

  // Removes a frame from the frame tree. |child|, its children, and objects
  // owned by their RenderFrameHostManagers are immediately deleted. The root
  // node cannot be removed this way.
  void RemoveFrame(FrameTreeNode* child);

  // This method walks the entire frame tree and creates RenderFrameProxyHosts
  // as needed. Proxies are not created if suitable proxies already exist. See
  // below for special handling of |source|. Otherwise proxies are created for
  // the given |site_instance_group| in each node.
  //
  // |source| may be null if there is no node navigating in this frame tree
  // (such as when this is called for an opener's frame tree), in which case no
  // nodes are skipped for RenderFrameProxyHost creation. Otherwise, a proxy is
  // temporarily created for |source| in cross-SiteInstanceGroup cases (to allow
  // a remote-to-local swap to the new RenderFrameHost in |source|), but the
  // subtree rooted at source is skipped.
  //
  // |source_new_browsing_context_state| is the BrowsingContextState used by the
  // speculative frame host, which may differ from the BrowsingContextState in
  // |source| during cross-origin cross- browsing-instance navigations.
  //
  // |navigation_metrics_token| is a token identifying the navigation for which
  // these proxies are being created, if any. It allows metrics code and trace
  // events to tie together different IPCs and events pertaining to a particular
  // navigation. It's nullopt for non-navigation cases such as creating proxies
  // for a new subframe.
  void CreateProxiesForSiteInstanceGroup(
      FrameTreeNode* source,
      SiteInstanceGroup* site_instance_group,
      const scoped_refptr<BrowsingContextState>&
          source_new_browsing_context_state,
      const std::optional<base::UnguessableToken>& navigation_metrics_token);

  // Convenience accessor for the main frame's RenderFrameHostImpl.
  RenderFrameHostImpl* GetMainFrame() const;

  // Returns the focused frame.
  FrameTreeNode* GetFocusedFrame();

  // Sets the focused frame to |node|.  |source| identifies the
  // SiteInstanceGroup that initiated this focus change.  If this FrameTree has
  // SiteInstanceGroups other than |source|, those SiteInstanceGroups will be
  // notified about the new focused frame.   Note that |source| may differ from
  // |node|'s current SiteInstanceGroup (e.g., this happens for cross-process
  // window.focus() calls).
  void SetFocusedFrame(FrameTreeNode* node, SiteInstanceGroup* source);

  // Creates a RenderViewHostImpl for a given |site_instance| in the tree.
  //
  // The RenderFrameHostImpls and the RenderFrameProxyHosts will share ownership
  // of this object.
  // `create_case` indicates whether or not the RenderViewHost being created is
  // speculative or not. It should only be registered with the FrameTree if it
  // is not speculative.
  // `frame_sink_id` is optionally set only if we're creating a speculative
  // RenderViewHost. If set, it implies we're reusing the compositor from the
  // previous RenderViewHost.
  scoped_refptr<RenderViewHostImpl> CreateRenderViewHost(
      SiteInstanceGroup* site_instance_group,
      int32_t main_frame_routing_id,
      bool renderer_initiated_creation,
      scoped_refptr<BrowsingContextState> main_browsing_context_state,
      CreateRenderViewHostCase create_case,
      std::optional<viz::FrameSinkId> frame_sink_id);

  // Returns the existing RenderViewHost for a new RenderFrameHost.
  // There should always be such a RenderViewHost, because the main frame
  // RenderFrameHost for each SiteInstance should be created before subframes.
  // Note that this will never return `speculative_render_view_host_`. If that
  // is needed, call `speculative_render_view_host()` instead.
  scoped_refptr<RenderViewHostImpl> GetRenderViewHost(SiteInstanceGroup* group);

  using RenderViewHostMapId = base::IdType32<class RenderViewHostMap>;

  // Returns the ID used for the RenderViewHost associated with
  // |site_instance_group|.
  RenderViewHostMapId GetRenderViewHostMapId(
      SiteInstanceGroup* site_instance_group) const;

  // Registers a RenderViewHost so that it can be reused by other frames
  // whose SiteInstance maps to the same RenderViewHostMapId.
  //
  // This method does not take ownership of|rvh|.
  //
  // NOTE: This method CHECK fails if a RenderViewHost is already registered for
  // |rvh|'s SiteInstance.
  //
  // ALSO NOTE: After calling RegisterRenderViewHost, UnregisterRenderViewHost
  // *must* be called for |rvh| when it is destroyed or put into the
  // BackForwardCache, to prevent FrameTree::CreateRenderViewHost from trying to
  // reuse it.
  void RegisterRenderViewHost(RenderViewHostMapId id, RenderViewHostImpl* rvh);

  // Unregisters the RenderViewHostImpl that's available for reuse for a
  // particular RenderViewHostMapId. NOTE: This method CHECK fails if it is
  // called for a |render_view_host| that is not currently set for reuse.
  void UnregisterRenderViewHost(RenderViewHostMapId id,
                                RenderViewHostImpl* render_view_host);

  // This is called when the frame is about to be removed and started to run
  // unload handlers.
  void FrameUnloading(FrameTreeNode* frame);

  // This is only meant to be called by FrameTreeNode. Triggers calling
  // the listener installed by SetFrameRemoveListener.
  void FrameRemoved(FrameTreeNode* frame);

  void NodeLoadingStateChanged(FrameTreeNode& node,
                               LoadingState previous_frame_tree_loading_state);
  void DidCancelLoading();

  // Returns this FrameTree's total load progress. If the `root_` FrameTreeNode
  // is navigating returns `blink::kInitialLoadProgress`.
  double GetLoadProgress();

  // Returns true if at least one of the nodes in this frame tree or nodes in
  // any inner frame tree of the same WebContents is loading.
  bool IsLoadingIncludingInnerFrameTrees() const;

  // Returns the LoadingState for the FrameTree as a whole, indicating whether
  // a load is in progress, as well as whether loading UI should be shown.
  LoadingState GetLoadingState() const;

  // Set page-level focus in all SiteInstances involved in rendering
  // this FrameTree, not including the current main frame's
  // SiteInstance. The focus update will be sent via the main frame's proxies
  // in those SiteInstances.
  void ReplicatePageFocus(bool is_focused);

  // Updates page-level focus for this FrameTree in the subframe renderer
  // identified by |group|.
  void SetPageFocus(SiteInstanceGroup* group, bool is_focused);

  // Walks the current frame tree and registers any origins matching
  // `previously_visited_origin`, either the last committed origin of a
  // RenderFrameHost or the origin associated with a NavigationRequest that has
  // been assigned to a SiteInstance, as having the default origin isolation
  // state. This is only necessary when `previously_visited_origin` is seen with
  // an OriginAgentCluster header explicitly requesting something other than the
  // default.
  void RegisterExistingOriginAsHavingDefaultIsolation(
      const url::Origin& previously_visited_origin,
      NavigationRequest* navigation_request_to_exclude);

  const NavigationControllerImpl& controller() const {
    return navigator_.controller();
  }
  NavigationControllerImpl& controller() { return navigator_.controller(); }

  Navigator& navigator() { return navigator_; }

  // Another page accessed the initial empty main document, which means it
  // is no longer safe to display a pending URL without risking a URL spoof.
  void DidAccessInitialMainDocument();

  bool has_accessed_initial_main_document() const {
    return has_accessed_initial_main_document_;
  }

  void ResetHasAccessedInitialMainDocument() {
    has_accessed_initial_main_document_ = false;
  }

  bool IsHidden() const { return delegate_->IsHidden(); }

  // LoadingTree returns the following for different frame trees to direct
  // loading related events. Please see FrameTree::Delegate::LoadingTree for
  // more comments.
  // - For prerender frame tree -> returns the frame tree itself.
  // - For fenced frame and primary frame tree -> returns
  // the delegate's primary frame tree.
  FrameTree* LoadingTree();

  // Stops all ongoing navigations in each of the nodes of this FrameTree.
  void StopLoading();

  // Prepares this frame tree for destruction, cleaning up the internal state
  // and firing the appropriate events like FrameDeleted.
  // Must be called before FrameTree is destroyed.
  void Shutdown();

  bool IsBeingDestroyed() const { return is_being_destroyed_; }

  base::SafeRef<FrameTree> GetSafeRef();

  // Walks up the FrameTree chain and focuses the FrameTreeNode where
  // each inner FrameTree is attached.
  void FocusOuterFrameTrees();

  // Discards the frame tree. The root frame is transitioned to an empty
  // document in blink and BFCache entries are cleared. The tree is configured
  // to reload when activated.
  void Discard(base::OnceClosure on_discarded_cb = base::NullCallback());

 private:
  friend class FrameTreeTest;
  FRIEND_TEST_ALL_PREFIXES(RenderFrameHostImplBrowserTest, RemoveFocusedFrame);
  FRIEND_TEST_ALL_PREFIXES(FencedFrameMPArchBrowserTest, NodesForIsLoading);
  FRIEND_TEST_ALL_PREFIXES(RenderFrameHostManagerTest,
                           CreateRenderViewAfterProcessKillAndClosedProxy);

  // Returns a range to iterate over all FrameTreeNodes in the frame tree in
  // breadth-first traversal order, skipping the subtree rooted at
  // |node|, but including |node| itself.
  NodeRange NodesExceptSubtree(FrameTreeNode* node);

  // Returns all FrameTreeNodes in this frame tree, as well as any
  // FrameTreeNodes of inner frame trees. Note that this doesn't include inner
  // frame trees of inner delegates. This is used to find the aggregate
  // IsLoading value for a frame tree.
  //
  // TODO(crbug.com/1261928, crbug.com/1261928): Remove this method and directly
  // rely on GetOutermostMainFrame() and NodesIncludingInnerTreeNodes() once
  // guest views are migrated to MPArch.
  std::vector<FrameTreeNode*> CollectNodesForIsLoading();

  const raw_ptr<Delegate> delegate_;

  // These delegates are installed into all the RenderViewHosts and
  // RenderFrameHosts that we create.
  raw_ptr<RenderFrameHostDelegate> render_frame_delegate_;
  raw_ptr<RenderViewHostDelegate> render_view_delegate_;
  raw_ptr<RenderWidgetHostDelegate> render_widget_delegate_;
  raw_ptr<RenderFrameHostManager::Delegate> manager_delegate_;
  raw_ptr<PageDelegate> page_delegate_;

  // The Navigator object responsible for managing navigations on this frame
  // tree. Each FrameTreeNode will default to using it for navigation tasks in
  // the frame.
  Navigator navigator_;

  // A map to store RenderViewHosts, keyed by SiteInstanceGroup ID.
  // This map does not cover all RenderViewHosts in a FrameTree. See
  // `speculative_render_view_host_`.
  using RenderViewHostMap =
      std::unordered_map<RenderViewHostMapId, RenderViewHostImpl*>;
  // Map of RenderViewHostMapId to RenderViewHost. This allows us to look up the
  // RenderViewHost for a given SiteInstance when creating RenderFrameHosts.
  // Each RenderViewHost maintains a refcount and is deleted when there are no
  // more RenderFrameHosts or RenderFrameProxyHosts using it.
  RenderViewHostMap render_view_host_map_;

  // A speculative RenderViewHost is created for all speculative cross-page
  // same-SiteInstanceGroup RenderFrameHosts. When the corresponding
  // RenderFrameHost gets committed and becomes the current RenderFrameHost,
  // `speculative_render_view_host_` will be moved to `render_view_host_map_`,
  // overwriting the previous RenderViewHost of the same SiteInstanceGroup, if
  // applicable. This field will also be reset at that time, or if the
  // speculative RenderFrameHost gets deleted.
  //
  // For any given FrameTree, there will be at most one
  // `speculative_render_view_host_`, because only main-frame speculative
  // RenderFrameHosts have speculative RenderViewHosts, and there is at most one
  // such RenderFrameHost per FrameTree at a time.
  // This is a WeakPtr, since the RenderViewHost is owned by the
  // RenderFrameHostImpl, not the FrameTree. This implies that if the owning
  // RenderFrameHostImpl gets deleted, this will too.
  //
  // This supports but is independent of RenderDocument, which introduces cases
  // where there may be more than one RenderViewHost per SiteInstanceGroup, such
  // as cross-page same-SiteInstanceGroup navigations. The speculative
  // RenderFrameHost has an associated RenderViewHost, but it cannot be put in
  // `render_view_host_map_` when it is created, as the existing RenderViewHost
  // will be incorrectly overwritten.
  // TODO(yangsharon, crbug.com/1336305): Expand support to include
  // cross-SiteInstanceGroup main-frame navigations, so all main-frame
  // navigations use speculative RenderViewHost.
  base::WeakPtr<RenderViewHostImpl> speculative_render_view_host_;

  // Indicates type of frame tree.
  const Type type_;

  FrameTreeNodeId focused_frame_tree_node_id_;

  // Whether the initial empty page has been accessed by another page, making it
  // unsafe to show the pending URL. Usually false unless another window tries
  // to modify the blank page.  Always false after the first commit.
  bool has_accessed_initial_main_document_ = false;

  bool is_being_destroyed_ = false;

#if DCHECK_IS_ON()
  // Whether Shutdown() was called.
  bool was_shut_down_ = false;
#endif

  // The root FrameTreeNode.
  //
  // Note: It is common for a node to test whether it's the root node, via the
  // `root()` method, even while `root_` is running its destructor.
  // For that reason, we want to destroy |root_| before any other fields.
  FrameTreeNode root_;

  base::WeakPtrFactory<FrameTree> weak_ptr_factory_{this};
};

}  // namespace content

#endif  // CONTENT_BROWSER_RENDERER_HOST_FRAME_TREE_H_
