blob: 9554ebf43f75704d705bad1bbdf0afba3015ee23 [file] [log] [blame]
Avi Drissman4e1b7bc32022-09-15 14:03:501// Copyright 2013 The Chromium Authors
danakjc492bf82020-09-09 20:02:442// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CONTENT_BROWSER_RENDERER_HOST_FRAME_TREE_H_
6#define CONTENT_BROWSER_RENDERER_HOST_FRAME_TREE_H_
7
8#include <stdint.h>
9
10#include <iterator>
11#include <memory>
12#include <string>
13#include <unordered_map>
14
15#include "base/callback.h"
16#include "base/containers/queue.h"
Carlos Caballero101ac26b2021-03-24 11:54:0517#include "base/dcheck_is_on.h"
danakjc492bf82020-09-09 20:02:4418#include "base/gtest_prod_util.h"
Keishi Hattori0e45c022021-11-27 09:25:5219#include "base/memory/raw_ptr.h"
Dave Tapuskad8b0530f2021-10-19 15:12:3120#include "base/memory/safe_ref.h"
21#include "base/memory/weak_ptr.h"
Paul Semel3e241042022-10-11 12:57:3122#include "content/browser/renderer_host/frame_tree_node.h"
danakjc492bf82020-09-09 20:02:4423#include "content/browser/renderer_host/navigator.h"
24#include "content/browser/renderer_host/navigator_delegate.h"
25#include "content/browser/renderer_host/render_frame_host_manager.h"
26#include "content/common/content_export.h"
27#include "mojo/public/cpp/bindings/pending_receiver.h"
28#include "services/service_manager/public/mojom/interface_provider.mojom.h"
David Bokanc3fb5fa2022-07-04 14:55:3129#include "third_party/blink/public/common/features.h"
Kevin McNee43fe8292021-10-04 22:59:4130#include "third_party/blink/public/common/frame/frame_owner_element_type.h"
Chris Hamilton3ff6ed0e2021-02-19 03:54:0431#include "third_party/blink/public/common/tokens/tokens.h"
danakjc492bf82020-09-09 20:02:4432#include "third_party/blink/public/mojom/frame/frame_owner_properties.mojom-forward.h"
33
34namespace blink {
Lei Zhang4a867672021-07-19 06:30:1435namespace mojom {
36class BrowserInterfaceBroker;
37enum class TreeScopeType;
38} // namespace mojom
39
danakjc492bf82020-09-09 20:02:4440struct FramePolicy;
41} // namespace blink
42
43namespace content {
44
Carlos Caballero40b0efd2021-01-26 11:55:0045class BrowserContext;
Jeremy Roman2d8dfe132021-07-06 20:51:2646class PageDelegate;
Lei Zhang4a867672021-07-19 06:30:1447class PageImpl;
danakjc492bf82020-09-09 20:02:4448class RenderFrameHostDelegate;
49class RenderViewHostDelegate;
50class RenderViewHostImpl;
51class RenderFrameHostManager;
52class RenderWidgetHostDelegate;
Carlos Caballero40b0efd2021-01-26 11:55:0053class SiteInstance;
Sharon Yang57bde122022-03-01 20:01:1254class SiteInstanceGroup;
danakjc492bf82020-09-09 20:02:4455
56// Represents the frame tree for a page. With the exception of the main frame,
57// all FrameTreeNodes will be created/deleted in response to frame attach and
58// detach events in the DOM.
59//
60// The main frame's FrameTreeNode is special in that it is reused. This allows
61// it to serve as an anchor for state that needs to persist across top-level
62// page navigations.
63//
64// TODO(ajwong): Move NavigationController ownership to the main frame
65// FrameTreeNode. Possibly expose access to it from here.
66//
67// This object is only used on the UI thread.
68class CONTENT_EXPORT FrameTree {
69 public:
70 class NodeRange;
71
Alan Zhao8a882d12022-05-18 01:32:1572 class CONTENT_EXPORT NodeIterator {
danakjc492bf82020-09-09 20:02:4473 public:
Alan Zhao8a882d12022-05-18 01:32:1574 using iterator_category = std::forward_iterator_tag;
75 using value_type = FrameTreeNode*;
76 using difference_type = std::ptrdiff_t;
77 using pointer = FrameTreeNode**;
78 using reference = FrameTreeNode*&;
79
danakjc492bf82020-09-09 20:02:4480 NodeIterator(const NodeIterator& other);
81 ~NodeIterator();
82
83 NodeIterator& operator++();
Kevin McNee5f594382021-05-06 23:18:2384 // Advances the iterator and excludes the children of the current node
85 NodeIterator& AdvanceSkippingChildren();
danakjc492bf82020-09-09 20:02:4486
87 bool operator==(const NodeIterator& rhs) const;
88 bool operator!=(const NodeIterator& rhs) const { return !(*this == rhs); }
89
90 FrameTreeNode* operator*() { return current_node_; }
91
92 private:
Jayson Adams4db0bfe22021-07-15 19:24:0793 friend class FrameTreeTest;
danakjc492bf82020-09-09 20:02:4494 friend class NodeRange;
95
Kevin McNee5f594382021-05-06 23:18:2396 NodeIterator(const std::vector<FrameTreeNode*>& starting_nodes,
97 const FrameTreeNode* root_of_subtree_to_skip,
Dave Tapuskadda303d2022-10-04 16:56:4898 bool should_descend_into_inner_trees,
99 bool include_delegate_nodes_for_inner_frame_trees);
Kevin McNee5f594382021-05-06 23:18:23100
101 void AdvanceNode();
danakjc492bf82020-09-09 20:02:44102
Lukasz Anforowicz877e6222021-11-26 00:03:23103 // `current_node_` and `root_of_subtree_to_skip_` are not a raw_ptr<...> for
104 // performance reasons (based on analysis of sampling profiler data and
105 // tab_search:top100:2020).
Keishi Hattori488b7602022-05-02 13:09:31106 RAW_PTR_EXCLUSION FrameTreeNode* current_node_;
107 RAW_PTR_EXCLUSION const FrameTreeNode* const root_of_subtree_to_skip_;
Lukasz Anforowicz877e6222021-11-26 00:03:23108
Kevin McNee5f594382021-05-06 23:18:23109 const bool should_descend_into_inner_trees_;
Dave Tapuskadda303d2022-10-04 16:56:48110 const bool include_delegate_nodes_for_inner_frame_trees_;
Jayson Adams4db0bfe22021-07-15 19:24:07111 base::circular_deque<FrameTreeNode*> queue_;
danakjc492bf82020-09-09 20:02:44112 };
113
114 class CONTENT_EXPORT NodeRange {
115 public:
Kevin McNee5f594382021-05-06 23:18:23116 NodeRange(const NodeRange&);
117 ~NodeRange();
118
danakjc492bf82020-09-09 20:02:44119 NodeIterator begin();
120 NodeIterator end();
121
122 private:
123 friend class FrameTree;
124
Kevin McNee5f594382021-05-06 23:18:23125 NodeRange(const std::vector<FrameTreeNode*>& starting_nodes,
126 const FrameTreeNode* root_of_subtree_to_skip,
Dave Tapuskadda303d2022-10-04 16:56:48127 bool should_descend_into_inner_trees,
128 bool include_delegate_nodes_for_inner_frame_trees);
danakjc492bf82020-09-09 20:02:44129
Kevin McNee5f594382021-05-06 23:18:23130 const std::vector<FrameTreeNode*> starting_nodes_;
Keishi Hattori0e45c022021-11-27 09:25:52131 const raw_ptr<const FrameTreeNode> root_of_subtree_to_skip_;
Kevin McNee5f594382021-05-06 23:18:23132 const bool should_descend_into_inner_trees_;
Dave Tapuskadda303d2022-10-04 16:56:48133 const bool include_delegate_nodes_for_inner_frame_trees_;
danakjc492bf82020-09-09 20:02:44134 };
135
Carlos Caballero03262522021-02-05 14:49:58136 class CONTENT_EXPORT Delegate {
137 public:
138 // A RenderFrameHost in the specified |frame_tree_node| started loading a
139 // new document. This corresponds to browser UI starting to show a spinner
140 // or other visual indicator for loading. This method is only invoked if the
Nate Chapin9aabf5f2021-11-12 00:31:19141 // FrameTree hadn't been previously loading. |should_show_loading_ui| will
142 // be true unless the load is a fragment navigation, or triggered by
Carlos Caballero03262522021-02-05 14:49:58143 // history.pushState/replaceState.
144 virtual void DidStartLoading(FrameTreeNode* frame_tree_node,
Nate Chapin9aabf5f2021-11-12 00:31:19145 bool should_show_loading_ui) = 0;
Carlos Caballero03262522021-02-05 14:49:58146
Takashi Toyoshima74090df62021-03-09 14:34:57147 // This is called when all nodes in the FrameTree stopped loading. This
Carlos Caballero03262522021-02-05 14:49:58148 // corresponds to the browser UI stop showing a spinner or other visual
149 // indicator for loading.
150 virtual void DidStopLoading() = 0;
151
Sreeja Kamishettyd64b993d2022-02-14 12:04:42152 // Returns the delegate's top loading tree, which should be used to infer
Yu Gaoc8c18552022-06-22 14:38:45153 // the values of loading-related states. The state of
154 // IsLoadingIncludingInnerFrameTrees() is a WebContents level concept and
155 // LoadingTree would return the frame tree to which loading events should be
156 // directed.
Sreeja Kamishettyd64b993d2022-02-14 12:04:42157 //
158 // TODO(crbug.com/1261928): Remove this method and directly rely on
159 // GetOutermostMainFrame() once portals and guest views are migrated to
160 // MPArch.
161 virtual FrameTree* LoadingTree() = 0;
162
Carlos Caballero6ff6ace2021-02-05 16:53:00163 // Returns true when the active RenderWidgetHostView should be hidden.
164 virtual bool IsHidden() = 0;
Sreeja Kamishettya21b4f62021-06-25 07:48:25165
Sreeja Kamishetty53468972021-07-13 11:53:32166 // Called when current Page of this frame tree changes to `page`.
167 virtual void NotifyPageChanged(PageImpl& page) = 0;
Dominic Farolinoedf44ee2021-07-20 23:50:59168
169 // If the FrameTree using this delegate is an inner/nested FrameTree, then
170 // there may be a FrameTreeNode in the outer FrameTree that is considered
171 // our outer delegate FrameTreeNode. This method returns the outer delegate
172 // FrameTreeNode ID if one exists. If we don't have a an outer delegate
173 // FrameTreeNode, this method returns
174 // FrameTreeNode::kFrameTreeNodeInvalidId.
175 virtual int GetOuterDelegateFrameTreeNodeId() = 0;
Dave Tapuskac8de3b02021-12-03 21:51:01176
177 // Returns if this FrameTree represents a portal.
178 virtual bool IsPortal() = 0;
Carlos Caballero03262522021-02-05 14:49:58179 };
180
Sreeja Kamishetty74bacd522021-03-22 17:04:24181 // Type of FrameTree instance.
182 enum class Type {
183 // This FrameTree is the primary frame tree for the WebContents, whose main
184 // document URL is shown in the Omnibox.
185 kPrimary,
186
187 // This FrameTree is used to prerender a page in the background which is
188 // invisible to the user.
Dominic Farolino4bc10ee2021-08-31 00:37:36189 kPrerender,
190
191 // This FrameTree is used to host the contents of a <fencedframe> element.
192 // Even for <fencedframe>s hosted inside a prerendered page, the FrameTree
193 // associated with the fenced frame will be kFencedFrame, but the
194 // RenderFrameHosts inside of it will have their lifecycle state set to
195 // `RenderFrameHost::LifecycleState::kActive`.
196 //
197 // TODO(crbug.com/1232528, crbug.com/1244274): We should either:
198 // * Fully support nested FrameTrees inside prerendered pages, in which
199 // case all of the RenderFrameHosts inside the nested trees should have
200 // their lifecycle state set to kPrerendering, or...
201 // * Ban nested FrameTrees in prerendered pages, and therefore obsolete the
202 // above paragraph about <fencedframe>s hosted in prerendered pages.
203 kFencedFrame
Sreeja Kamishetty74bacd522021-03-22 17:04:24204 };
Sreeja Kamishetty837a10402021-04-23 12:41:59205
206 // A set of delegates are remembered here so that we can create
207 // RenderFrameHostManagers.
Dave Tapuska144570102022-08-02 19:28:27208 // `dev_tools_frame_token` is the devtools token for the root `FrameTreeNode`
209 // of this new `FrameTree`.
Sreeja Kamishetty837a10402021-04-23 12:41:59210 FrameTree(BrowserContext* browser_context,
211 Delegate* delegate,
212 NavigationControllerDelegate* navigation_controller_delegate,
213 NavigatorDelegate* navigator_delegate,
214 RenderFrameHostDelegate* render_frame_delegate,
215 RenderViewHostDelegate* render_view_delegate,
216 RenderWidgetHostDelegate* render_widget_delegate,
217 RenderFrameHostManager::Delegate* manager_delegate,
Jeremy Roman2d8dfe132021-07-06 20:51:26218 PageDelegate* page_delegate,
Dave Tapuska144570102022-08-02 19:28:27219 Type type,
220 const base::UnguessableToken& devtools_frame_token);
Peter Boström828b9022021-09-21 02:28:43221
222 FrameTree(const FrameTree&) = delete;
223 FrameTree& operator=(const FrameTree&) = delete;
224
Sreeja Kamishetty837a10402021-04-23 12:41:59225 ~FrameTree();
Sreeja Kamishetty74bacd522021-03-22 17:04:24226
Carlos Caballero40b0efd2021-01-26 11:55:00227 // Initializes the main frame for this FrameTree. That is it creates the
Rakina Zata Amniafd3c6582021-11-30 06:19:17228 // initial RenderFrameHost in the root node's RenderFrameHostManager, and also
Rakina Zata Amni2322f4f82022-01-24 13:24:24229 // creates an initial NavigationEntry (if the InitialNavigationEntry feature
Rakina Zata Amni4eb716e2022-04-05 21:32:46230 // is enabled) that potentially inherits `opener_for_origin`'s origin in its
Rakina Zata Amni2322f4f82022-01-24 13:24:24231 // NavigationController. This method will call back into the delegates so it
232 // should only be called once they have completed their initialization. Pass
233 // in frame_policy so that it can be set in the root node's replication_state.
Carlos Caballero40b0efd2021-01-26 11:55:00234 // TODO(carlscab): It would be great if initialization could happened in the
235 // constructor so we do not leave objects in a half initialized state.
236 void Init(SiteInstance* main_frame_site_instance,
237 bool renderer_initiated_creation,
Rakina Zata Amniafd3c6582021-11-30 06:19:17238 const std::string& main_frame_name,
Rakina Zata Amni4eb716e2022-04-05 21:32:46239 RenderFrameHostImpl* opener_for_origin,
Harkiran Bolaria5ce27632022-01-20 15:05:05240 const blink::FramePolicy& frame_policy);
Sreeja Kamishetty837a10402021-04-23 12:41:59241
242 Type type() const { return type_; }
Carlos Caballero40b0efd2021-01-26 11:55:00243
Paul Semel3e241042022-10-11 12:57:31244 FrameTreeNode* root() { return &root_; }
245 const FrameTreeNode* root() const { return &root_; }
danakjc492bf82020-09-09 20:02:44246
Sreeja Kamishetty74bacd522021-03-22 17:04:24247 bool is_prerendering() const { return type_ == FrameTree::Type::kPrerender; }
Sreeja Kamishetty46f762c2021-02-05 07:52:46248
Sreeja Kamishetty60e47132022-02-08 12:51:53249 // Returns true if this frame tree is a portal.
250 //
251 // TODO(crbug.com/1254770): Once portals are migrated to MPArch, portals will
252 // have their own FrameTree::Type.
253 bool IsPortal();
254
Carlos Caballero03262522021-02-05 14:49:58255 Delegate* delegate() { return delegate_; }
256
Jeremy Roman2d8dfe132021-07-06 20:51:26257 // Delegates for various objects. These can be kept centrally on the
258 // FrameTree because they are expected to be the same for all frames on a
259 // given FrameTree.
danakjc492bf82020-09-09 20:02:44260 RenderFrameHostDelegate* render_frame_delegate() {
261 return render_frame_delegate_;
262 }
263 RenderViewHostDelegate* render_view_delegate() {
264 return render_view_delegate_;
265 }
266 RenderWidgetHostDelegate* render_widget_delegate() {
267 return render_widget_delegate_;
268 }
269 RenderFrameHostManager::Delegate* manager_delegate() {
270 return manager_delegate_;
271 }
Jeremy Roman2d8dfe132021-07-06 20:51:26272 PageDelegate* page_delegate() { return page_delegate_; }
Aaron Colwell78b4bde2021-03-16 16:16:09273
Albert J. Wong1b6dc962021-07-09 18:06:57274 using RenderViewHostMapId = base::IdType32<class RenderViewHostMap>;
Sharon Yangc581a0c2021-11-02 18:09:39275
276 // SiteInstanceGroup IDs are used to look up RenderViewHosts, since there is
277 // one RenderViewHost per SiteInstanceGroup in a given FrameTree.
Aaron Colwell78b4bde2021-03-16 16:16:09278 using RenderViewHostMap = std::unordered_map<RenderViewHostMapId,
279 RenderViewHostImpl*,
280 RenderViewHostMapId::Hasher>;
281 const RenderViewHostMap& render_view_hosts() const {
danakjc492bf82020-09-09 20:02:44282 return render_view_host_map_;
283 }
284
285 // Returns the FrameTreeNode with the given |frame_tree_node_id| if it is part
286 // of this FrameTree.
287 FrameTreeNode* FindByID(int frame_tree_node_id);
288
289 // Returns the FrameTreeNode with the given renderer-specific |routing_id|.
290 FrameTreeNode* FindByRoutingID(int process_id, int routing_id);
291
292 // Returns the first frame in this tree with the given |name|, or the main
293 // frame if |name| is empty.
294 // Note that this does NOT support pseudo-names like _self, _top, and _blank,
295 // nor searching other FrameTrees (unlike blink::WebView::findFrameByName).
296 FrameTreeNode* FindByName(const std::string& name);
297
298 // Returns a range to iterate over all FrameTreeNodes in the frame tree in
299 // breadth-first traversal order.
300 NodeRange Nodes();
301
302 // Returns a range to iterate over all FrameTreeNodes in a subtree of the
303 // frame tree, starting from |subtree_root|.
304 NodeRange SubtreeNodes(FrameTreeNode* subtree_root);
305
Kevin McNee53f0b2d2021-11-02 18:00:45306 // Returns a range to iterate over all FrameTreeNodes in this frame tree, as
307 // well as any FrameTreeNodes of inner frame trees. Note that this includes
308 // inner frame trees of inner WebContents as well.
309 NodeRange NodesIncludingInnerTreeNodes();
310
Kevin McNee5f594382021-05-06 23:18:23311 // Returns a range to iterate over all FrameTreeNodes in a subtree, starting
312 // from, but not including |parent|, as well as any FrameTreeNodes of inner
Kevin McNee53f0b2d2021-11-02 18:00:45313 // frame trees. Note that this includes inner frame trees of inner WebContents
Dave Tapuskadda303d2022-10-04 16:56:48314 // as well. If `include_delegate_nodes_for_inner_frame_trees` is true the
315 // delegate RenderFrameHost owning the inner frame tree will also be returned.
316 static NodeRange SubtreeAndInnerTreeNodes(
317 RenderFrameHostImpl* parent,
318 bool include_delegate_nodes_for_inner_frame_trees = false);
Kevin McNee5f594382021-05-06 23:18:23319
danakjc492bf82020-09-09 20:02:44320 // Adds a new child frame to the frame tree. |process_id| is required to
321 // disambiguate |new_routing_id|, and it must match the process of the
Kevin McNee43fe8292021-10-04 22:59:41322 // |parent| node. Otherwise no child is added and this method returns nullptr.
danakjc492bf82020-09-09 20:02:44323 // |interface_provider_receiver| is the receiver end of the InterfaceProvider
324 // interface through which the child RenderFrame can access Mojo services
325 // exposed by the corresponding RenderFrameHost. The caller takes care of
Antonio Sartoridb967c52021-01-20 09:54:30326 // sending the client end of the interface down to the
327 // RenderFrame. |policy_container_bind_params|, if not null, is used for
328 // binding Blink's policy container to the new RenderFrameHost's
329 // PolicyContainerHost. This is only needed if this frame is the result of the
330 // CreateChildFrame mojo call, which also delivers the
Kevin McNee43fe8292021-10-04 22:59:41331 // |policy_container_bind_params|. |is_dummy_frame_for_inner_tree| is true if
332 // the added frame is only to serve as a placeholder for an inner frame tree
333 // (e.g. fenced frames, portals) and will not have a live RenderFrame of its
334 // own.
danakjc492bf82020-09-09 20:02:44335 FrameTreeNode* AddFrame(
336 RenderFrameHostImpl* parent,
337 int process_id,
338 int new_routing_id,
danakj0bdfacd2021-01-20 19:27:18339 mojo::PendingAssociatedRemote<mojom::Frame> frame_remote,
danakjc492bf82020-09-09 20:02:44340 mojo::PendingReceiver<blink::mojom::BrowserInterfaceBroker>
341 browser_interface_broker_receiver,
Antonio Sartoridb967c52021-01-20 09:54:30342 blink::mojom::PolicyContainerBindParamsPtr policy_container_bind_params,
Dominic Farolino12e06d72022-08-05 02:29:49343 mojo::PendingAssociatedReceiver<blink::mojom::AssociatedInterfaceProvider>
344 associated_interface_provider_receiver,
danakjc492bf82020-09-09 20:02:44345 blink::mojom::TreeScopeType scope,
346 const std::string& frame_name,
347 const std::string& frame_unique_name,
348 bool is_created_by_script,
Chris Hamilton3ff6ed0e2021-02-19 03:54:04349 const blink::LocalFrameToken& frame_token,
danakjc492bf82020-09-09 20:02:44350 const base::UnguessableToken& devtools_frame_token,
Daniel Cheng284c38942022-09-22 23:30:34351 const blink::DocumentToken& document_token,
danakjc492bf82020-09-09 20:02:44352 const blink::FramePolicy& frame_policy,
353 const blink::mojom::FrameOwnerProperties& frame_owner_properties,
354 bool was_discarded,
Kevin McNee43fe8292021-10-04 22:59:41355 blink::FrameOwnerElementType owner_type,
356 bool is_dummy_frame_for_inner_tree);
danakjc492bf82020-09-09 20:02:44357
358 // Removes a frame from the frame tree. |child|, its children, and objects
359 // owned by their RenderFrameHostManagers are immediately deleted. The root
360 // node cannot be removed this way.
361 void RemoveFrame(FrameTreeNode* child);
362
363 // This method walks the entire frame tree and creates a RenderFrameProxyHost
364 // for the given |site_instance| in each node except the |source| one --
365 // the source will have a RenderFrameHost. |source| may be null if there is
366 // no node navigating in this frame tree (such as when this is called
367 // for an opener's frame tree), in which case no nodes are skipped for
Harkiran Bolaria2912a6b32022-02-22 16:43:45368 // RenderFrameProxyHost creation. |source_new_browsing_context_state| is the
369 // BrowsingContextState used by the speculative frame host, which may differ
370 // from the BrowsingContextState in |source| during cross-origin cross-
371 // browsing-instance navigations.
danakjc492bf82020-09-09 20:02:44372 void CreateProxiesForSiteInstance(FrameTreeNode* source,
Harkiran Bolaria2912a6b32022-02-22 16:43:45373 SiteInstance* site_instance,
374 const scoped_refptr<BrowsingContextState>&
375 source_new_browsing_context_state);
danakjc492bf82020-09-09 20:02:44376
377 // Convenience accessor for the main frame's RenderFrameHostImpl.
378 RenderFrameHostImpl* GetMainFrame() const;
379
380 // Returns the focused frame.
381 FrameTreeNode* GetFocusedFrame();
382
Sharon Yangefe52632022-03-08 23:06:06383 // Sets the focused frame to |node|. |source| identifies the
384 // SiteInstanceGroup that initiated this focus change. If this FrameTree has
385 // SiteInstanceGroups other than |source|, those SiteInstanceGroups will be
386 // notified about the new focused frame. Note that |source| may differ from
387 // |node|'s current SiteInstanceGroup (e.g., this happens for cross-process
388 // window.focus() calls).
389 void SetFocusedFrame(FrameTreeNode* node, SiteInstanceGroup* source);
danakjc492bf82020-09-09 20:02:44390
danakjc492bf82020-09-09 20:02:44391 // Creates a RenderViewHostImpl for a given |site_instance| in the tree.
392 //
393 // The RenderFrameHostImpls and the RenderFrameProxyHosts will share ownership
394 // of this object.
395 scoped_refptr<RenderViewHostImpl> CreateRenderViewHost(
396 SiteInstance* site_instance,
397 int32_t main_frame_routing_id,
Harkiran Bolaria57e2b062022-03-14 10:27:58398 bool renderer_initiated_creation,
399 scoped_refptr<BrowsingContextState> main_browsing_context_state);
danakjc492bf82020-09-09 20:02:44400
401 // Returns the existing RenderViewHost for a new RenderFrameHost.
402 // There should always be such a RenderViewHost, because the main frame
403 // RenderFrameHost for each SiteInstance should be created before subframes.
Sharon Yang57bde122022-03-01 20:01:12404 scoped_refptr<RenderViewHostImpl> GetRenderViewHost(SiteInstanceGroup* group);
danakjc492bf82020-09-09 20:02:44405
Sharon Yangc581a0c2021-11-02 18:09:39406 // Returns the ID used for the RenderViewHost associated with
407 // |site_instance_group|.
408 RenderViewHostMapId GetRenderViewHostMapId(
409 SiteInstanceGroup* site_instance_group) const;
Aaron Colwell78b4bde2021-03-16 16:16:09410
danakjc492bf82020-09-09 20:02:44411 // Registers a RenderViewHost so that it can be reused by other frames
Aaron Colwell78b4bde2021-03-16 16:16:09412 // whose SiteInstance maps to the same RenderViewHostMapId.
danakjc492bf82020-09-09 20:02:44413 //
414 // This method does not take ownership of|rvh|.
415 //
416 // NOTE: This method CHECK fails if a RenderViewHost is already registered for
417 // |rvh|'s SiteInstance.
418 //
419 // ALSO NOTE: After calling RegisterRenderViewHost, UnregisterRenderViewHost
420 // *must* be called for |rvh| when it is destroyed or put into the
421 // BackForwardCache, to prevent FrameTree::CreateRenderViewHost from trying to
422 // reuse it.
Aaron Colwell78b4bde2021-03-16 16:16:09423 void RegisterRenderViewHost(RenderViewHostMapId id, RenderViewHostImpl* rvh);
danakjc492bf82020-09-09 20:02:44424
425 // Unregisters the RenderViewHostImpl that's available for reuse for a
Aaron Colwell78b4bde2021-03-16 16:16:09426 // particular RenderViewHostMapId. NOTE: This method CHECK fails if it is
427 // called for a |render_view_host| that is not currently set for reuse.
428 void UnregisterRenderViewHost(RenderViewHostMapId id,
Aaron Colwellc4bd7d62021-01-29 04:23:13429 RenderViewHostImpl* render_view_host);
danakjc492bf82020-09-09 20:02:44430
431 // This is called when the frame is about to be removed and started to run
432 // unload handlers.
433 void FrameUnloading(FrameTreeNode* frame);
434
435 // This is only meant to be called by FrameTreeNode. Triggers calling
436 // the listener installed by SetFrameRemoveListener.
437 void FrameRemoved(FrameTreeNode* frame);
438
Carlos Caballero03262522021-02-05 14:49:58439 void DidStartLoadingNode(FrameTreeNode& node,
Nate Chapin9aabf5f2021-11-12 00:31:19440 bool should_show_loading_ui,
Carlos Caballero03262522021-02-05 14:49:58441 bool was_previously_loading);
442 void DidStopLoadingNode(FrameTreeNode& node);
Carlos Caballero03262522021-02-05 14:49:58443 void DidCancelLoading();
danakjc492bf82020-09-09 20:02:44444
Sreeja Kamishetty0be3b1b2021-08-12 17:04:15445 // Returns this FrameTree's total load progress. If the `root_` FrameTreeNode
446 // is navigating returns `blink::kInitialLoadProgress`.
447 double GetLoadProgress();
danakjc492bf82020-09-09 20:02:44448
Sreeja Kamishetty15f9944a22022-03-10 10:16:08449 // Returns true if at least one of the nodes in this frame tree or nodes in
450 // any inner frame tree of the same WebContents is loading.
Yu Gaoc8c18552022-06-22 14:38:45451 bool IsLoadingIncludingInnerFrameTrees() const;
danakjc492bf82020-09-09 20:02:44452
453 // Set page-level focus in all SiteInstances involved in rendering
454 // this FrameTree, not including the current main frame's
455 // SiteInstance. The focus update will be sent via the main frame's proxies
456 // in those SiteInstances.
457 void ReplicatePageFocus(bool is_focused);
458
459 // Updates page-level focus for this FrameTree in the subframe renderer
Sharon Yangefe52632022-03-08 23:06:06460 // identified by |group|.
461 void SetPageFocus(SiteInstanceGroup* group, bool is_focused);
danakjc492bf82020-09-09 20:02:44462
W. James MacLeanc07dc41b2022-07-25 18:52:16463 // Walks the current frame tree and registers any origins matching
464 // `previously_visited_origin`, either the last committed origin of a
465 // RenderFrameHost or the origin associated with a NavigationRequest that has
466 // been assigned to a SiteInstance, as having the default origin isolation
467 // state. This is only necessary when `previously_visited_origin` is seen with
468 // an OriginAgentCluster header explicitly requesting something other than the
469 // default.
470 void RegisterExistingOriginAsHavingDefaultIsolation(
danakjc492bf82020-09-09 20:02:44471 const url::Origin& previously_visited_origin,
472 NavigationRequest* navigation_request_to_exclude);
473
Carlos Caballero40b0efd2021-01-26 11:55:00474 NavigationControllerImpl& controller() { return navigator_.controller(); }
danakjc492bf82020-09-09 20:02:44475 Navigator& navigator() { return navigator_; }
476
Carlos Caballeroede6f8c2021-01-28 11:01:50477 // Another page accessed the initial empty main document, which means it
478 // is no longer safe to display a pending URL without risking a URL spoof.
479 void DidAccessInitialMainDocument();
480
481 bool has_accessed_initial_main_document() const {
482 return has_accessed_initial_main_document_;
483 }
484
485 void ResetHasAccessedInitialMainDocument() {
486 has_accessed_initial_main_document_ = false;
487 }
488
Carlos Caballero6ff6ace2021-02-05 16:53:00489 bool IsHidden() const { return delegate_->IsHidden(); }
490
Sreeja Kamishettyd64b993d2022-02-14 12:04:42491 // LoadingTree returns the following for different frame trees to direct
492 // loading related events. Please see FrameTree::Delegate::LoadingTree for
493 // more comments.
494 // - For prerender frame tree -> returns the frame tree itself.
495 // - For fenced frame and primary frame tree (including portal) -> returns
496 // the delegate's primary frame tree.
497 FrameTree* LoadingTree();
498
Carlos Caballero03262522021-02-05 14:49:58499 // Stops all ongoing navigations in each of the nodes of this FrameTree.
500 void StopLoading();
501
Carlos Caballero101ac26b2021-03-24 11:54:05502 // Prepares this frame tree for destruction, cleaning up the internal state
503 // and firing the appropriate events like FrameDeleted.
504 // Must be called before FrameTree is destroyed.
505 void Shutdown();
506
Takashi Toyoshimaea534ef22021-07-21 03:27:59507 bool IsBeingDestroyed() const { return is_being_destroyed_; }
508
Dave Tapuskad8b0530f2021-10-19 15:12:31509 base::SafeRef<FrameTree> GetSafeRef();
510
Dave Tapuska54c76a032021-10-27 22:10:42511 // Walks up the FrameTree chain and focuses the FrameTreeNode where
512 // each inner FrameTree is attached.
513 void FocusOuterFrameTrees();
514
David Bokanc3fb5fa2022-07-04 14:55:31515 absl::optional<blink::features::FencedFramesImplementationType>
516 FencedFramesImplementationType() const {
517 return fenced_frames_impl_;
518 }
519
520 bool IsFencedFramesMPArchBased() const {
521 return fenced_frames_impl_.has_value() &&
522 fenced_frames_impl_.value() ==
523 blink::features::FencedFramesImplementationType::kMPArch;
524 }
525 bool IsFencedFramesShadowDOMBased() const {
526 return fenced_frames_impl_.has_value() &&
527 fenced_frames_impl_.value() ==
528 blink::features::FencedFramesImplementationType::kShadowDOM;
529 }
530
danakjc492bf82020-09-09 20:02:44531 private:
532 friend class FrameTreeTest;
533 FRIEND_TEST_ALL_PREFIXES(RenderFrameHostImplBrowserTest, RemoveFocusedFrame);
Sreeja Kamishettyd64b993d2022-02-14 12:04:42534 FRIEND_TEST_ALL_PREFIXES(PortalBrowserTest, NodesForIsLoading);
Xiaochen Zhou6443f752022-08-10 16:40:46535 FRIEND_TEST_ALL_PREFIXES(FencedFrameMPArchBrowserTest, NodesForIsLoading);
Sharon Yang2f3304a2022-05-13 02:24:25536 FRIEND_TEST_ALL_PREFIXES(RenderFrameHostManagerTest,
537 CreateRenderViewAfterProcessKillAndClosedProxy);
danakjc492bf82020-09-09 20:02:44538
539 // Returns a range to iterate over all FrameTreeNodes in the frame tree in
540 // breadth-first traversal order, skipping the subtree rooted at
541 // |node|, but including |node| itself.
542 NodeRange NodesExceptSubtree(FrameTreeNode* node);
543
Sreeja Kamishettyd64b993d2022-02-14 12:04:42544 // Returns all FrameTreeNodes in this frame tree, as well as any
545 // FrameTreeNodes of inner frame trees. Note that this doesn't include inner
546 // frame trees of inner delegates. This is used to find the aggregate
547 // IsLoading value for a frame tree.
548 //
549 // TODO(crbug.com/1261928, crbug.com/1261928): Remove this method and directly
550 // rely on GetOutermostMainFrame() and NodesIncludingInnerTreeNodes() once
551 // portals and guest views are migrated to MPArch.
552 std::vector<FrameTreeNode*> CollectNodesForIsLoading();
553
Keishi Hattori0e45c022021-11-27 09:25:52554 const raw_ptr<Delegate> delegate_;
Carlos Caballero03262522021-02-05 14:49:58555
danakjc492bf82020-09-09 20:02:44556 // These delegates are installed into all the RenderViewHosts and
557 // RenderFrameHosts that we create.
Keishi Hattori0e45c022021-11-27 09:25:52558 raw_ptr<RenderFrameHostDelegate> render_frame_delegate_;
559 raw_ptr<RenderViewHostDelegate> render_view_delegate_;
560 raw_ptr<RenderWidgetHostDelegate> render_widget_delegate_;
561 raw_ptr<RenderFrameHostManager::Delegate> manager_delegate_;
562 raw_ptr<PageDelegate> page_delegate_;
danakjc492bf82020-09-09 20:02:44563
564 // The Navigator object responsible for managing navigations on this frame
Carlos Caballero40b0efd2021-01-26 11:55:00565 // tree. Each FrameTreeNode will default to using it for navigation tasks in
566 // the frame.
danakjc492bf82020-09-09 20:02:44567 Navigator navigator_;
568
Aaron Colwell78b4bde2021-03-16 16:16:09569 // Map of RenderViewHostMapId to RenderViewHost. This allows us to look up the
danakjc492bf82020-09-09 20:02:44570 // RenderViewHost for a given SiteInstance when creating RenderFrameHosts.
571 // Each RenderViewHost maintains a refcount and is deleted when there are no
572 // more RenderFrameHosts or RenderFrameProxyHosts using it.
Aaron Colwell78b4bde2021-03-16 16:16:09573 RenderViewHostMap render_view_host_map_;
danakjc492bf82020-09-09 20:02:44574
Harkiran Bolaria16f2c48d2022-04-22 12:39:57575 // Indicates type of frame tree.
576 const Type type_;
577
danakjc492bf82020-09-09 20:02:44578 int focused_frame_tree_node_id_;
579
danakjc492bf82020-09-09 20:02:44580 // Overall load progress.
581 double load_progress_;
582
David Bokanc3fb5fa2022-07-04 14:55:31583 absl::optional<blink::features::FencedFramesImplementationType>
584 fenced_frames_impl_;
585
Carlos Caballeroede6f8c2021-01-28 11:01:50586 // Whether the initial empty page has been accessed by another page, making it
587 // unsafe to show the pending URL. Usually false unless another window tries
588 // to modify the blank page. Always false after the first commit.
589 bool has_accessed_initial_main_document_ = false;
590
Takashi Toyoshimaea534ef22021-07-21 03:27:59591 bool is_being_destroyed_ = false;
592
Carlos Caballero101ac26b2021-03-24 11:54:05593#if DCHECK_IS_ON()
594 // Whether Shutdown() was called.
595 bool was_shut_down_ = false;
596#endif
Dave Tapuskad8b0530f2021-10-19 15:12:31597
Paul Semel3e241042022-10-11 12:57:31598 // The root FrameTreeNode.
599 //
600 // Note: It is common for a node to test whether it's the root node, via the
601 // `root()` method, even while `root_` is running its destructor.
602 // For that reason, we want to destroy |root_| before any other fields.
603 FrameTreeNode root_;
604
Dave Tapuskad8b0530f2021-10-19 15:12:31605 base::WeakPtrFactory<FrameTree> weak_ptr_factory_{this};
danakjc492bf82020-09-09 20:02:44606};
607
608} // namespace content
609
610#endif // CONTENT_BROWSER_RENDERER_HOST_FRAME_TREE_H_