blob: 0765e428801f5df07f90c277e888a93454e8a2a6 [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
danakjc492bf82020-09-09 20:02:4415#include "base/containers/queue.h"
Carlos Caballero101ac26b2021-03-24 11:54:0516#include "base/dcheck_is_on.h"
Avi Drissmanadac21992023-01-11 23:46:3917#include "base/functional/callback.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"
Sharon Yang7ce309e2023-01-19 21:39:5726#include "content/browser/renderer_host/render_view_host_enums.h"
danakjc492bf82020-09-09 20:02:4427#include "content/common/content_export.h"
28#include "mojo/public/cpp/bindings/pending_receiver.h"
29#include "services/service_manager/public/mojom/interface_provider.mojom.h"
David Bokanc3fb5fa2022-07-04 14:55:3130#include "third_party/blink/public/common/features.h"
Kevin McNee43fe8292021-10-04 22:59:4131#include "third_party/blink/public/common/frame/frame_owner_element_type.h"
Chris Hamilton3ff6ed0e2021-02-19 03:54:0432#include "third_party/blink/public/common/tokens/tokens.h"
danakjc492bf82020-09-09 20:02:4433#include "third_party/blink/public/mojom/frame/frame_owner_properties.mojom-forward.h"
Ari Chivukula5d15efb2023-01-21 04:33:5234#include "url/origin.h"
danakjc492bf82020-09-09 20:02:4435
36namespace blink {
Lei Zhang4a867672021-07-19 06:30:1437namespace mojom {
38class BrowserInterfaceBroker;
39enum class TreeScopeType;
40} // namespace mojom
41
danakjc492bf82020-09-09 20:02:4442struct FramePolicy;
43} // namespace blink
44
45namespace content {
46
Carlos Caballero40b0efd2021-01-26 11:55:0047class BrowserContext;
Jeremy Roman2d8dfe132021-07-06 20:51:2648class PageDelegate;
danakjc492bf82020-09-09 20:02:4449class RenderFrameHostDelegate;
50class RenderViewHostDelegate;
51class RenderViewHostImpl;
52class RenderFrameHostManager;
53class RenderWidgetHostDelegate;
Carlos Caballero40b0efd2021-01-26 11:55:0054class SiteInstance;
Sharon Yang57bde122022-03-01 20:01:1255class SiteInstanceGroup;
danakjc492bf82020-09-09 20:02:4456
57// Represents the frame tree for a page. With the exception of the main frame,
58// all FrameTreeNodes will be created/deleted in response to frame attach and
59// detach events in the DOM.
60//
61// The main frame's FrameTreeNode is special in that it is reused. This allows
62// it to serve as an anchor for state that needs to persist across top-level
63// page navigations.
64//
65// TODO(ajwong): Move NavigationController ownership to the main frame
66// FrameTreeNode. Possibly expose access to it from here.
67//
68// This object is only used on the UI thread.
69class CONTENT_EXPORT FrameTree {
70 public:
71 class NodeRange;
72
Alan Zhao8a882d12022-05-18 01:32:1573 class CONTENT_EXPORT NodeIterator {
danakjc492bf82020-09-09 20:02:4474 public:
Alan Zhao8a882d12022-05-18 01:32:1575 using iterator_category = std::forward_iterator_tag;
76 using value_type = FrameTreeNode*;
77 using difference_type = std::ptrdiff_t;
78 using pointer = FrameTreeNode**;
79 using reference = FrameTreeNode*&;
80
danakjc492bf82020-09-09 20:02:4481 NodeIterator(const NodeIterator& other);
82 ~NodeIterator();
83
84 NodeIterator& operator++();
Kevin McNee5f594382021-05-06 23:18:2385 // Advances the iterator and excludes the children of the current node
86 NodeIterator& AdvanceSkippingChildren();
danakjc492bf82020-09-09 20:02:4487
88 bool operator==(const NodeIterator& rhs) const;
89 bool operator!=(const NodeIterator& rhs) const { return !(*this == rhs); }
90
91 FrameTreeNode* operator*() { return current_node_; }
92
93 private:
Jayson Adams4db0bfe22021-07-15 19:24:0794 friend class FrameTreeTest;
danakjc492bf82020-09-09 20:02:4495 friend class NodeRange;
96
Ali Hijazie63cbaf62023-12-20 19:29:3597 NodeIterator(const std::vector<raw_ptr<FrameTreeNode, VectorExperimental>>&
98 starting_nodes,
Kevin McNee5f594382021-05-06 23:18:2399 const FrameTreeNode* root_of_subtree_to_skip,
Dave Tapuskadda303d2022-10-04 16:56:48100 bool should_descend_into_inner_trees,
101 bool include_delegate_nodes_for_inner_frame_trees);
Kevin McNee5f594382021-05-06 23:18:23102
103 void AdvanceNode();
danakjc492bf82020-09-09 20:02:44104
Lukasz Anforowicz877e6222021-11-26 00:03:23105 // `current_node_` and `root_of_subtree_to_skip_` are not a raw_ptr<...> for
106 // performance reasons (based on analysis of sampling profiler data and
107 // tab_search:top100:2020).
Keishi Hattori488b7602022-05-02 13:09:31108 RAW_PTR_EXCLUSION FrameTreeNode* current_node_;
109 RAW_PTR_EXCLUSION const FrameTreeNode* const root_of_subtree_to_skip_;
Lukasz Anforowicz877e6222021-11-26 00:03:23110
Kevin McNee5f594382021-05-06 23:18:23111 const bool should_descend_into_inner_trees_;
Dave Tapuskadda303d2022-10-04 16:56:48112 const bool include_delegate_nodes_for_inner_frame_trees_;
Jayson Adams4db0bfe22021-07-15 19:24:07113 base::circular_deque<FrameTreeNode*> queue_;
danakjc492bf82020-09-09 20:02:44114 };
115
116 class CONTENT_EXPORT NodeRange {
117 public:
Kevin McNee5f594382021-05-06 23:18:23118 NodeRange(const NodeRange&);
119 ~NodeRange();
120
danakjc492bf82020-09-09 20:02:44121 NodeIterator begin();
122 NodeIterator end();
123
124 private:
125 friend class FrameTree;
126
Ali Hijazie63cbaf62023-12-20 19:29:35127 NodeRange(const std::vector<raw_ptr<FrameTreeNode, VectorExperimental>>&
128 starting_nodes,
Kevin McNee5f594382021-05-06 23:18:23129 const FrameTreeNode* root_of_subtree_to_skip,
Dave Tapuskadda303d2022-10-04 16:56:48130 bool should_descend_into_inner_trees,
131 bool include_delegate_nodes_for_inner_frame_trees);
danakjc492bf82020-09-09 20:02:44132
Ali Hijazie63cbaf62023-12-20 19:29:35133 const std::vector<raw_ptr<FrameTreeNode, VectorExperimental>>
134 starting_nodes_;
Keishi Hattori0e45c022021-11-27 09:25:52135 const raw_ptr<const FrameTreeNode> root_of_subtree_to_skip_;
Kevin McNee5f594382021-05-06 23:18:23136 const bool should_descend_into_inner_trees_;
Dave Tapuskadda303d2022-10-04 16:56:48137 const bool include_delegate_nodes_for_inner_frame_trees_;
danakjc492bf82020-09-09 20:02:44138 };
139
Carlos Caballero03262522021-02-05 14:49:58140 class CONTENT_EXPORT Delegate {
141 public:
Nate Chapin470dbc62023-04-25 16:34:38142 // The FrameTree changed its LoadingState. This can be a transition between
143 // not-loading and loading (in which case it will be accompanied by either a
144 // DidStartLoading or DidStopLoading), or a transition between not showing
145 // loading UI and showing loading UI while a navigation is in progress (in
146 // which case it will be called without either DidStartLoading or
147 // DidStopLoading).
148 virtual void LoadingStateChanged(LoadingState new_state) = 0;
Carlos Caballero03262522021-02-05 14:49:58149
Nate Chapin470dbc62023-04-25 16:34:38150 // The FrameTree has started loading in `frame_tree_node`. Note that this
151 // is only called when the FrameTree as a whole goes from not-loading to
152 // loading. If a second FrameTreeNode begins loading, a new DidStartLoading
153 // message will not be sent.
154 virtual void DidStartLoading(FrameTreeNode* frame_tree_node) = 0;
155
156 // The FrameTree has stopped loading. Sent only when all FrameTreeNodes have
157 // stopped loading.
Carlos Caballero03262522021-02-05 14:49:58158 virtual void DidStopLoading() = 0;
159
Sreeja Kamishettyd64b993d2022-02-14 12:04:42160 // Returns the delegate's top loading tree, which should be used to infer
Yu Gaoc8c18552022-06-22 14:38:45161 // the values of loading-related states. The state of
162 // IsLoadingIncludingInnerFrameTrees() is a WebContents level concept and
163 // LoadingTree would return the frame tree to which loading events should be
164 // directed.
Sreeja Kamishettyd64b993d2022-02-14 12:04:42165 //
Alison Gale81f4f2c72024-04-22 19:33:31166 // TODO(crbug.com/40202416): Remove this method and directly rely on
Jeremy Romanc0c69be2023-11-21 19:14:52167 // GetOutermostMainFrame() once guest views are migrated to MPArch.
Sreeja Kamishettyd64b993d2022-02-14 12:04:42168 virtual FrameTree* LoadingTree() = 0;
169
Carlos Caballero6ff6ace2021-02-05 16:53:00170 // Returns true when the active RenderWidgetHostView should be hidden.
171 virtual bool IsHidden() = 0;
Sreeja Kamishettya21b4f62021-06-25 07:48:25172
Dominic Farolinoedf44ee2021-07-20 23:50:59173 // If the FrameTree using this delegate is an inner/nested FrameTree, then
174 // there may be a FrameTreeNode in the outer FrameTree that is considered
175 // our outer delegate FrameTreeNode. This method returns the outer delegate
176 // FrameTreeNode ID if one exists. If we don't have a an outer delegate
Avi Drissmanbd153642024-09-03 18:58:05177 // FrameTreeNode, this method returns an invalid value.
178 virtual FrameTreeNodeId GetOuterDelegateFrameTreeNodeId() = 0;
Dave Tapuskac8de3b02021-12-03 21:51:01179
Kevin McNee86e64ee2023-02-17 16:35:50180 // If the FrameTree using this delegate is an inner/nested FrameTree that
181 // has not yet been attached to an outer FrameTreeNode, returns the parent
182 // RenderFrameHost of the intended outer FrameTreeNode to which the inner
183 // frame tree will be attached. This is usually the RenderFrameHost that is
184 // the outer document once attachment occurs, however in the case of some
185 // kinds of GuestView, the outer document may end up being a same-origin
186 // subframe of the RenderFrameHost returned by this method (see the
187 // `testNewWindowAttachInSubFrame` webview test for an example of this).
188 // Otherwise, returns null.
189 virtual RenderFrameHostImpl* GetProspectiveOuterDocument() = 0;
190
Julie Jeongeun Kim2132b37f82022-11-23 08:30:46191 // Set the `node` frame as focused in its own FrameTree as well as possibly
192 // changing the focused frame tree in the case of inner/outer FrameTrees.
193 virtual void SetFocusedFrame(FrameTreeNode* node,
194 SiteInstanceGroup* source) = 0;
Tommy Steimel71f154462024-05-22 19:05:07195
196 // Returns this FrameTree's picture-in-picture FrameTree if it has one.
197 virtual FrameTree* GetOwnedPictureInPictureFrameTree() = 0;
198
199 // Returns this FrameTree's opener if this FrameTree represents a
200 // picture-in-picture window.
201 virtual FrameTree* GetPictureInPictureOpenerFrameTree() = 0;
Carlos Caballero03262522021-02-05 14:49:58202 };
203
Sreeja Kamishetty74bacd522021-03-22 17:04:24204 // Type of FrameTree instance.
205 enum class Type {
206 // This FrameTree is the primary frame tree for the WebContents, whose main
207 // document URL is shown in the Omnibox.
208 kPrimary,
209
210 // This FrameTree is used to prerender a page in the background which is
211 // invisible to the user.
Dominic Farolino4bc10ee2021-08-31 00:37:36212 kPrerender,
213
214 // This FrameTree is used to host the contents of a <fencedframe> element.
Dominic Farolino4bc10ee2021-08-31 00:37:36215 //
Kevin McNeef1b0f0b2024-09-17 21:49:41216 // Note that the FrameTree's Type should not be confused for
217 // `RenderFrameHost::LifecycleState`. For example, when a <fencedframe> is
218 // nested in a page in the bfcache, the FrameTree associated with the fenced
219 // frame will be kFencedFrame, but the RenderFrameHosts inside of it will
220 // have their lifecycle state indicate that they are bfcached.
221 kFencedFrame,
Kevin McNee2585e732024-10-28 22:11:19222
223 // This FrameTree is used to host the contents of a guest page. Guests are
224 // kinds of embedded pages, but their semantics are mostly delegated outside
225 // of the content/ layer. See components/guest_view/README.md.
226 // The implementation of guests is being migrated from using a separate
227 // WebContents to using this FrameTree Type. This type is used with the
228 // `features::kGuestViewMPArch` flag.
229 kGuest,
Sreeja Kamishetty74bacd522021-03-22 17:04:24230 };
Sreeja Kamishetty837a10402021-04-23 12:41:59231
232 // A set of delegates are remembered here so that we can create
233 // RenderFrameHostManagers.
234 FrameTree(BrowserContext* browser_context,
235 Delegate* delegate,
236 NavigationControllerDelegate* navigation_controller_delegate,
237 NavigatorDelegate* navigator_delegate,
238 RenderFrameHostDelegate* render_frame_delegate,
239 RenderViewHostDelegate* render_view_delegate,
240 RenderWidgetHostDelegate* render_widget_delegate,
241 RenderFrameHostManager::Delegate* manager_delegate,
Jeremy Roman2d8dfe132021-07-06 20:51:26242 PageDelegate* page_delegate,
Danil Somsikov259aa65f2022-11-11 20:49:44243 Type type);
Peter Boström828b9022021-09-21 02:28:43244
245 FrameTree(const FrameTree&) = delete;
246 FrameTree& operator=(const FrameTree&) = delete;
247
Sreeja Kamishetty837a10402021-04-23 12:41:59248 ~FrameTree();
Sreeja Kamishetty74bacd522021-03-22 17:04:24249
Carlos Caballero40b0efd2021-01-26 11:55:00250 // Initializes the main frame for this FrameTree. That is it creates the
Rakina Zata Amniafd3c6582021-11-30 06:19:17251 // initial RenderFrameHost in the root node's RenderFrameHostManager, and also
Rakina Zata Amni46087a12022-11-11 08:28:38252 // creates an initial NavigationEntry that potentially inherits
253 // `opener_for_origin`'s origin in its NavigationController. This method will
254 // call back into the delegates so it should only be called once they have
255 // completed their initialization. Pass in frame_policy so that it can be set
256 // in the root node's replication_state.
Carlos Caballero40b0efd2021-01-26 11:55:00257 // TODO(carlscab): It would be great if initialization could happened in the
258 // constructor so we do not leave objects in a half initialized state.
Charlie Reis37be2682023-01-10 17:04:47259 void Init(SiteInstanceImpl* main_frame_site_instance,
Carlos Caballero40b0efd2021-01-26 11:55:00260 bool renderer_initiated_creation,
Rakina Zata Amniafd3c6582021-11-30 06:19:17261 const std::string& main_frame_name,
Rakina Zata Amni4eb716e2022-04-05 21:32:46262 RenderFrameHostImpl* opener_for_origin,
Danil Somsikov259aa65f2022-11-11 20:49:44263 const blink::FramePolicy& frame_policy,
264 const base::UnguessableToken& devtools_frame_token);
Sreeja Kamishetty837a10402021-04-23 12:41:59265
266 Type type() const { return type_; }
Carlos Caballero40b0efd2021-01-26 11:55:00267
Paul Semel3e241042022-10-11 12:57:31268 FrameTreeNode* root() { return &root_; }
269 const FrameTreeNode* root() const { return &root_; }
danakjc492bf82020-09-09 20:02:44270
Takashi Toyoshima7c041d82023-09-26 16:09:21271 bool is_primary() const { return type_ == Type::kPrimary; }
272 bool is_prerendering() const { return type_ == Type::kPrerender; }
273 bool is_fenced_frame() const { return type_ == Type::kFencedFrame; }
Kevin McNee2585e732024-10-28 22:11:19274 bool is_guest() const { return type_ == Type::kGuest; }
Sreeja Kamishetty46f762c2021-02-05 07:52:46275
Carlos Caballero03262522021-02-05 14:49:58276 Delegate* delegate() { return delegate_; }
277
Jeremy Roman2d8dfe132021-07-06 20:51:26278 // Delegates for various objects. These can be kept centrally on the
279 // FrameTree because they are expected to be the same for all frames on a
280 // given FrameTree.
danakjc492bf82020-09-09 20:02:44281 RenderFrameHostDelegate* render_frame_delegate() {
282 return render_frame_delegate_;
283 }
284 RenderViewHostDelegate* render_view_delegate() {
285 return render_view_delegate_;
286 }
287 RenderWidgetHostDelegate* render_widget_delegate() {
288 return render_widget_delegate_;
289 }
290 RenderFrameHostManager::Delegate* manager_delegate() {
291 return manager_delegate_;
292 }
Jeremy Roman2d8dfe132021-07-06 20:51:26293 PageDelegate* page_delegate() { return page_delegate_; }
Aaron Colwell78b4bde2021-03-16 16:16:09294
Sharon Yanged884542023-02-02 17:33:44295 // Iterate over all RenderViewHosts, including speculative RenderViewHosts.
296 // See `speculative_render_view_host_` for more details.
297 void ForEachRenderViewHost(
298 base::FunctionRef<void(RenderViewHostImpl*)> on_host);
danakjc492bf82020-09-09 20:02:44299
Sharon Yang7ce309e2023-01-19 21:39:57300 // Speculative RenderViewHost accessors.
301 RenderViewHostImpl* speculative_render_view_host() const {
302 return speculative_render_view_host_.get();
303 }
304 void set_speculative_render_view_host(
305 base::WeakPtr<RenderViewHostImpl> render_view_host) {
306 speculative_render_view_host_ = render_view_host;
307 }
308
309 // Moves `speculative_render_view_host_` to `render_view_host_map_`. This
310 // should be called every time a main-frame same-SiteInstanceGroup speculative
311 // RenderFrameHost gets swapped in and becomes the active RenderFrameHost.
312 // This overwrites the previous RenderViewHost for the SiteInstanceGroup in
313 // `render_view_host_map_`, if one exists.
314 void MakeSpeculativeRVHCurrent();
315
danakjc492bf82020-09-09 20:02:44316 // Returns the FrameTreeNode with the given |frame_tree_node_id| if it is part
317 // of this FrameTree.
Avi Drissmanbd153642024-09-03 18:58:05318 FrameTreeNode* FindByID(FrameTreeNodeId frame_tree_node_id);
danakjc492bf82020-09-09 20:02:44319
320 // Returns the FrameTreeNode with the given renderer-specific |routing_id|.
321 FrameTreeNode* FindByRoutingID(int process_id, int routing_id);
322
323 // Returns the first frame in this tree with the given |name|, or the main
324 // frame if |name| is empty.
325 // Note that this does NOT support pseudo-names like _self, _top, and _blank,
326 // nor searching other FrameTrees (unlike blink::WebView::findFrameByName).
327 FrameTreeNode* FindByName(const std::string& name);
328
329 // Returns a range to iterate over all FrameTreeNodes in the frame tree in
330 // breadth-first traversal order.
331 NodeRange Nodes();
332
333 // Returns a range to iterate over all FrameTreeNodes in a subtree of the
334 // frame tree, starting from |subtree_root|.
335 NodeRange SubtreeNodes(FrameTreeNode* subtree_root);
336
Kevin McNee53f0b2d2021-11-02 18:00:45337 // Returns a range to iterate over all FrameTreeNodes in this frame tree, as
338 // well as any FrameTreeNodes of inner frame trees. Note that this includes
339 // inner frame trees of inner WebContents as well.
340 NodeRange NodesIncludingInnerTreeNodes();
341
Kevin McNee5f594382021-05-06 23:18:23342 // Returns a range to iterate over all FrameTreeNodes in a subtree, starting
343 // from, but not including |parent|, as well as any FrameTreeNodes of inner
Kevin McNee53f0b2d2021-11-02 18:00:45344 // frame trees. Note that this includes inner frame trees of inner WebContents
Dave Tapuskadda303d2022-10-04 16:56:48345 // as well. If `include_delegate_nodes_for_inner_frame_trees` is true the
346 // delegate RenderFrameHost owning the inner frame tree will also be returned.
347 static NodeRange SubtreeAndInnerTreeNodes(
348 RenderFrameHostImpl* parent,
349 bool include_delegate_nodes_for_inner_frame_trees = false);
Kevin McNee5f594382021-05-06 23:18:23350
danakjc492bf82020-09-09 20:02:44351 // Adds a new child frame to the frame tree. |process_id| is required to
352 // disambiguate |new_routing_id|, and it must match the process of the
Kevin McNee43fe8292021-10-04 22:59:41353 // |parent| node. Otherwise no child is added and this method returns nullptr.
danakjc492bf82020-09-09 20:02:44354 // |interface_provider_receiver| is the receiver end of the InterfaceProvider
355 // interface through which the child RenderFrame can access Mojo services
356 // exposed by the corresponding RenderFrameHost. The caller takes care of
Antonio Sartoridb967c52021-01-20 09:54:30357 // sending the client end of the interface down to the
358 // RenderFrame. |policy_container_bind_params|, if not null, is used for
359 // binding Blink's policy container to the new RenderFrameHost's
360 // PolicyContainerHost. This is only needed if this frame is the result of the
361 // CreateChildFrame mojo call, which also delivers the
Kevin McNee43fe8292021-10-04 22:59:41362 // |policy_container_bind_params|. |is_dummy_frame_for_inner_tree| is true if
363 // the added frame is only to serve as a placeholder for an inner frame tree
Jeremy Romanc0c69be2023-11-21 19:14:52364 // (e.g. fenced frames) and will not have a live RenderFrame of its
Kevin McNee43fe8292021-10-04 22:59:41365 // own.
danakjc492bf82020-09-09 20:02:44366 FrameTreeNode* AddFrame(
367 RenderFrameHostImpl* parent,
368 int process_id,
369 int new_routing_id,
danakj0bdfacd2021-01-20 19:27:18370 mojo::PendingAssociatedRemote<mojom::Frame> frame_remote,
danakjc492bf82020-09-09 20:02:44371 mojo::PendingReceiver<blink::mojom::BrowserInterfaceBroker>
372 browser_interface_broker_receiver,
Antonio Sartoridb967c52021-01-20 09:54:30373 blink::mojom::PolicyContainerBindParamsPtr policy_container_bind_params,
Dominic Farolino12e06d72022-08-05 02:29:49374 mojo::PendingAssociatedReceiver<blink::mojom::AssociatedInterfaceProvider>
375 associated_interface_provider_receiver,
danakjc492bf82020-09-09 20:02:44376 blink::mojom::TreeScopeType scope,
377 const std::string& frame_name,
378 const std::string& frame_unique_name,
379 bool is_created_by_script,
Chris Hamilton3ff6ed0e2021-02-19 03:54:04380 const blink::LocalFrameToken& frame_token,
danakjc492bf82020-09-09 20:02:44381 const base::UnguessableToken& devtools_frame_token,
Daniel Cheng284c38942022-09-22 23:30:34382 const blink::DocumentToken& document_token,
danakjc492bf82020-09-09 20:02:44383 const blink::FramePolicy& frame_policy,
384 const blink::mojom::FrameOwnerProperties& frame_owner_properties,
385 bool was_discarded,
Kevin McNee43fe8292021-10-04 22:59:41386 blink::FrameOwnerElementType owner_type,
387 bool is_dummy_frame_for_inner_tree);
danakjc492bf82020-09-09 20:02:44388
389 // Removes a frame from the frame tree. |child|, its children, and objects
390 // owned by their RenderFrameHostManagers are immediately deleted. The root
391 // node cannot be removed this way.
392 void RemoveFrame(FrameTreeNode* child);
393
Sharon Yangdcc5f252024-05-09 18:27:23394 // This method walks the entire frame tree and creates RenderFrameProxyHosts
395 // as needed. Proxies are not created if suitable proxies already exist. See
396 // below for special handling of |source|. Otherwise proxies are created for
397 // the given |site_instance_group| in each node.
398 //
399 // |source| may be null if there is no node navigating in this frame tree
400 // (such as when this is called for an opener's frame tree), in which case no
401 // nodes are skipped for RenderFrameProxyHost creation. Otherwise, a proxy is
402 // temporarily created for |source| in cross-SiteInstanceGroup cases (to allow
403 // a remote-to-local swap to the new RenderFrameHost in |source|), but the
404 // subtree rooted at source is skipped.
405 // |source_new_browsing_context_state| is the BrowsingContextState used by the
406 // speculative frame host, which may differ from the BrowsingContextState in
407 // |source| during cross-origin cross- browsing-instance navigations.
408 void CreateProxiesForSiteInstanceGroup(
409 FrameTreeNode* source,
410 SiteInstanceGroup* site_instance_group,
411 const scoped_refptr<BrowsingContextState>&
412 source_new_browsing_context_state);
danakjc492bf82020-09-09 20:02:44413
414 // Convenience accessor for the main frame's RenderFrameHostImpl.
415 RenderFrameHostImpl* GetMainFrame() const;
416
417 // Returns the focused frame.
418 FrameTreeNode* GetFocusedFrame();
419
Sharon Yangefe52632022-03-08 23:06:06420 // Sets the focused frame to |node|. |source| identifies the
421 // SiteInstanceGroup that initiated this focus change. If this FrameTree has
422 // SiteInstanceGroups other than |source|, those SiteInstanceGroups will be
423 // notified about the new focused frame. Note that |source| may differ from
424 // |node|'s current SiteInstanceGroup (e.g., this happens for cross-process
425 // window.focus() calls).
426 void SetFocusedFrame(FrameTreeNode* node, SiteInstanceGroup* source);
danakjc492bf82020-09-09 20:02:44427
danakjc492bf82020-09-09 20:02:44428 // Creates a RenderViewHostImpl for a given |site_instance| in the tree.
429 //
430 // The RenderFrameHostImpls and the RenderFrameProxyHosts will share ownership
431 // of this object.
Sharon Yang7ce309e2023-01-19 21:39:57432 // `create_case` indicates whether or not the RenderViewHost being created is
433 // speculative or not. It should only be registered with the FrameTree if it
434 // is not speculative.
Khushal Sagar402d1c9f2023-11-15 22:21:48435 // `frame_sink_id` is optionally set only if we're creating a speculative
436 // RenderViewHost. If set, it implies we're reusing the compositor from the
437 // previous RenderViewHost.
danakjc492bf82020-09-09 20:02:44438 scoped_refptr<RenderViewHostImpl> CreateRenderViewHost(
Sharon Yangeb76ee22023-11-29 00:42:09439 SiteInstanceGroup* site_instance_group,
danakjc492bf82020-09-09 20:02:44440 int32_t main_frame_routing_id,
Harkiran Bolaria57e2b062022-03-14 10:27:58441 bool renderer_initiated_creation,
Sharon Yang7ce309e2023-01-19 21:39:57442 scoped_refptr<BrowsingContextState> main_browsing_context_state,
Khushal Sagar402d1c9f2023-11-15 22:21:48443 CreateRenderViewHostCase create_case,
Arthur Sonzognic686e8f2024-01-11 08:36:37444 std::optional<viz::FrameSinkId> frame_sink_id);
danakjc492bf82020-09-09 20:02:44445
446 // Returns the existing RenderViewHost for a new RenderFrameHost.
447 // There should always be such a RenderViewHost, because the main frame
448 // RenderFrameHost for each SiteInstance should be created before subframes.
Sharon Yang7ce309e2023-01-19 21:39:57449 // Note that this will never return `speculative_render_view_host_`. If that
450 // is needed, call `speculative_render_view_host()` instead.
Sharon Yang57bde122022-03-01 20:01:12451 scoped_refptr<RenderViewHostImpl> GetRenderViewHost(SiteInstanceGroup* group);
danakjc492bf82020-09-09 20:02:44452
Sharon Yanged884542023-02-02 17:33:44453 using RenderViewHostMapId = base::IdType32<class RenderViewHostMap>;
454
Sharon Yangc581a0c2021-11-02 18:09:39455 // Returns the ID used for the RenderViewHost associated with
456 // |site_instance_group|.
457 RenderViewHostMapId GetRenderViewHostMapId(
458 SiteInstanceGroup* site_instance_group) const;
Aaron Colwell78b4bde2021-03-16 16:16:09459
danakjc492bf82020-09-09 20:02:44460 // Registers a RenderViewHost so that it can be reused by other frames
Aaron Colwell78b4bde2021-03-16 16:16:09461 // whose SiteInstance maps to the same RenderViewHostMapId.
danakjc492bf82020-09-09 20:02:44462 //
463 // This method does not take ownership of|rvh|.
464 //
465 // NOTE: This method CHECK fails if a RenderViewHost is already registered for
466 // |rvh|'s SiteInstance.
467 //
468 // ALSO NOTE: After calling RegisterRenderViewHost, UnregisterRenderViewHost
469 // *must* be called for |rvh| when it is destroyed or put into the
470 // BackForwardCache, to prevent FrameTree::CreateRenderViewHost from trying to
471 // reuse it.
Aaron Colwell78b4bde2021-03-16 16:16:09472 void RegisterRenderViewHost(RenderViewHostMapId id, RenderViewHostImpl* rvh);
danakjc492bf82020-09-09 20:02:44473
474 // Unregisters the RenderViewHostImpl that's available for reuse for a
Aaron Colwell78b4bde2021-03-16 16:16:09475 // particular RenderViewHostMapId. NOTE: This method CHECK fails if it is
476 // called for a |render_view_host| that is not currently set for reuse.
477 void UnregisterRenderViewHost(RenderViewHostMapId id,
Aaron Colwellc4bd7d62021-01-29 04:23:13478 RenderViewHostImpl* render_view_host);
danakjc492bf82020-09-09 20:02:44479
480 // This is called when the frame is about to be removed and started to run
481 // unload handlers.
482 void FrameUnloading(FrameTreeNode* frame);
483
484 // This is only meant to be called by FrameTreeNode. Triggers calling
485 // the listener installed by SetFrameRemoveListener.
486 void FrameRemoved(FrameTreeNode* frame);
487
Nate Chapin470dbc62023-04-25 16:34:38488 void NodeLoadingStateChanged(FrameTreeNode& node,
489 LoadingState previous_frame_tree_loading_state);
Carlos Caballero03262522021-02-05 14:49:58490 void DidCancelLoading();
danakjc492bf82020-09-09 20:02:44491
Sreeja Kamishetty0be3b1b2021-08-12 17:04:15492 // Returns this FrameTree's total load progress. If the `root_` FrameTreeNode
493 // is navigating returns `blink::kInitialLoadProgress`.
494 double GetLoadProgress();
danakjc492bf82020-09-09 20:02:44495
Sreeja Kamishetty15f9944a22022-03-10 10:16:08496 // Returns true if at least one of the nodes in this frame tree or nodes in
497 // any inner frame tree of the same WebContents is loading.
Yu Gaoc8c18552022-06-22 14:38:45498 bool IsLoadingIncludingInnerFrameTrees() const;
danakjc492bf82020-09-09 20:02:44499
Nate Chapin470dbc62023-04-25 16:34:38500 // Returns the LoadingState for the FrameTree as a whole, indicating whether
501 // a load is in progress, as well as whether loading UI should be shown.
502 LoadingState GetLoadingState() const;
503
danakjc492bf82020-09-09 20:02:44504 // Set page-level focus in all SiteInstances involved in rendering
505 // this FrameTree, not including the current main frame's
506 // SiteInstance. The focus update will be sent via the main frame's proxies
507 // in those SiteInstances.
508 void ReplicatePageFocus(bool is_focused);
509
510 // Updates page-level focus for this FrameTree in the subframe renderer
Sharon Yangefe52632022-03-08 23:06:06511 // identified by |group|.
512 void SetPageFocus(SiteInstanceGroup* group, bool is_focused);
danakjc492bf82020-09-09 20:02:44513
W. James MacLeanc07dc41b2022-07-25 18:52:16514 // Walks the current frame tree and registers any origins matching
515 // `previously_visited_origin`, either the last committed origin of a
516 // RenderFrameHost or the origin associated with a NavigationRequest that has
517 // been assigned to a SiteInstance, as having the default origin isolation
518 // state. This is only necessary when `previously_visited_origin` is seen with
519 // an OriginAgentCluster header explicitly requesting something other than the
520 // default.
521 void RegisterExistingOriginAsHavingDefaultIsolation(
danakjc492bf82020-09-09 20:02:44522 const url::Origin& previously_visited_origin,
523 NavigationRequest* navigation_request_to_exclude);
524
Carlos Caballero40b0efd2021-01-26 11:55:00525 NavigationControllerImpl& controller() { return navigator_.controller(); }
danakjc492bf82020-09-09 20:02:44526 Navigator& navigator() { return navigator_; }
527
Carlos Caballeroede6f8c2021-01-28 11:01:50528 // Another page accessed the initial empty main document, which means it
529 // is no longer safe to display a pending URL without risking a URL spoof.
530 void DidAccessInitialMainDocument();
531
532 bool has_accessed_initial_main_document() const {
533 return has_accessed_initial_main_document_;
534 }
535
536 void ResetHasAccessedInitialMainDocument() {
537 has_accessed_initial_main_document_ = false;
538 }
539
Carlos Caballero6ff6ace2021-02-05 16:53:00540 bool IsHidden() const { return delegate_->IsHidden(); }
541
Sreeja Kamishettyd64b993d2022-02-14 12:04:42542 // LoadingTree returns the following for different frame trees to direct
543 // loading related events. Please see FrameTree::Delegate::LoadingTree for
544 // more comments.
545 // - For prerender frame tree -> returns the frame tree itself.
Jeremy Romanc0c69be2023-11-21 19:14:52546 // - For fenced frame and primary frame tree -> returns
Sreeja Kamishettyd64b993d2022-02-14 12:04:42547 // the delegate's primary frame tree.
548 FrameTree* LoadingTree();
549
Carlos Caballero03262522021-02-05 14:49:58550 // Stops all ongoing navigations in each of the nodes of this FrameTree.
551 void StopLoading();
552
Carlos Caballero101ac26b2021-03-24 11:54:05553 // Prepares this frame tree for destruction, cleaning up the internal state
554 // and firing the appropriate events like FrameDeleted.
555 // Must be called before FrameTree is destroyed.
556 void Shutdown();
557
Takashi Toyoshimaea534ef22021-07-21 03:27:59558 bool IsBeingDestroyed() const { return is_being_destroyed_; }
559
Dave Tapuskad8b0530f2021-10-19 15:12:31560 base::SafeRef<FrameTree> GetSafeRef();
561
Dave Tapuska54c76a032021-10-27 22:10:42562 // Walks up the FrameTree chain and focuses the FrameTreeNode where
563 // each inner FrameTree is attached.
564 void FocusOuterFrameTrees();
565
Thomas Lukaszewicz8ada31b2024-09-01 19:18:16566 // Discards the frame tree. The root frame is transitioned to an empty
567 // document in blink and BFCache entries are cleared. The tree is configured
568 // to reload when activated.
569 void Discard();
570
danakjc492bf82020-09-09 20:02:44571 private:
572 friend class FrameTreeTest;
573 FRIEND_TEST_ALL_PREFIXES(RenderFrameHostImplBrowserTest, RemoveFocusedFrame);
Xiaochen Zhou6443f752022-08-10 16:40:46574 FRIEND_TEST_ALL_PREFIXES(FencedFrameMPArchBrowserTest, NodesForIsLoading);
Sharon Yang2f3304a2022-05-13 02:24:25575 FRIEND_TEST_ALL_PREFIXES(RenderFrameHostManagerTest,
576 CreateRenderViewAfterProcessKillAndClosedProxy);
danakjc492bf82020-09-09 20:02:44577
578 // Returns a range to iterate over all FrameTreeNodes in the frame tree in
579 // breadth-first traversal order, skipping the subtree rooted at
580 // |node|, but including |node| itself.
581 NodeRange NodesExceptSubtree(FrameTreeNode* node);
582
Sreeja Kamishettyd64b993d2022-02-14 12:04:42583 // Returns all FrameTreeNodes in this frame tree, as well as any
584 // FrameTreeNodes of inner frame trees. Note that this doesn't include inner
585 // frame trees of inner delegates. This is used to find the aggregate
586 // IsLoading value for a frame tree.
587 //
588 // TODO(crbug.com/1261928, crbug.com/1261928): Remove this method and directly
589 // rely on GetOutermostMainFrame() and NodesIncludingInnerTreeNodes() once
Jeremy Romanc0c69be2023-11-21 19:14:52590 // guest views are migrated to MPArch.
Sreeja Kamishettyd64b993d2022-02-14 12:04:42591 std::vector<FrameTreeNode*> CollectNodesForIsLoading();
592
Keishi Hattori0e45c022021-11-27 09:25:52593 const raw_ptr<Delegate> delegate_;
Carlos Caballero03262522021-02-05 14:49:58594
danakjc492bf82020-09-09 20:02:44595 // These delegates are installed into all the RenderViewHosts and
596 // RenderFrameHosts that we create.
Keishi Hattori0e45c022021-11-27 09:25:52597 raw_ptr<RenderFrameHostDelegate> render_frame_delegate_;
598 raw_ptr<RenderViewHostDelegate> render_view_delegate_;
599 raw_ptr<RenderWidgetHostDelegate> render_widget_delegate_;
600 raw_ptr<RenderFrameHostManager::Delegate> manager_delegate_;
601 raw_ptr<PageDelegate> page_delegate_;
danakjc492bf82020-09-09 20:02:44602
603 // The Navigator object responsible for managing navigations on this frame
Carlos Caballero40b0efd2021-01-26 11:55:00604 // tree. Each FrameTreeNode will default to using it for navigation tasks in
605 // the frame.
danakjc492bf82020-09-09 20:02:44606 Navigator navigator_;
607
Sharon Yanged884542023-02-02 17:33:44608 // A map to store RenderViewHosts, keyed by SiteInstanceGroup ID.
609 // This map does not cover all RenderViewHosts in a FrameTree. See
610 // `speculative_render_view_host_`.
Devon Loehr92631c892025-01-02 20:15:15611 using RenderViewHostMap =
612 std::unordered_map<RenderViewHostMapId, RenderViewHostImpl*>;
Aaron Colwell78b4bde2021-03-16 16:16:09613 // Map of RenderViewHostMapId to RenderViewHost. This allows us to look up the
danakjc492bf82020-09-09 20:02:44614 // RenderViewHost for a given SiteInstance when creating RenderFrameHosts.
615 // Each RenderViewHost maintains a refcount and is deleted when there are no
616 // more RenderFrameHosts or RenderFrameProxyHosts using it.
Aaron Colwell78b4bde2021-03-16 16:16:09617 RenderViewHostMap render_view_host_map_;
danakjc492bf82020-09-09 20:02:44618
Sharon Yang7ce309e2023-01-19 21:39:57619 // A speculative RenderViewHost is created for all speculative cross-page
620 // same-SiteInstanceGroup RenderFrameHosts. When the corresponding
621 // RenderFrameHost gets committed and becomes the current RenderFrameHost,
622 // `speculative_render_view_host_` will be moved to `render_view_host_map_`,
623 // overwriting the previous RenderViewHost of the same SiteInstanceGroup, if
624 // applicable. This field will also be reset at that time, or if the
625 // speculative RenderFrameHost gets deleted.
626 //
627 // For any given FrameTree, there will be at most one
628 // `speculative_render_view_host_`, because only main-frame speculative
629 // RenderFrameHosts have speculative RenderViewHosts, and there is at most one
630 // such RenderFrameHost per FrameTree at a time.
631 // This is a WeakPtr, since the RenderViewHost is owned by the
632 // RenderFrameHostImpl, not the FrameTree. This implies that if the owning
633 // RenderFrameHostImpl gets deleted, this will too.
634 //
635 // This supports but is independent of RenderDocument, which introduces cases
636 // where there may be more than one RenderViewHost per SiteInstanceGroup, such
637 // as cross-page same-SiteInstanceGroup navigations. The speculative
638 // RenderFrameHost has an associated RenderViewHost, but it cannot be put in
639 // `render_view_host_map_` when it is created, as the existing RenderViewHost
640 // will be incorrectly overwritten.
641 // TODO(yangsharon, crbug.com/1336305): Expand support to include
642 // cross-SiteInstanceGroup main-frame navigations, so all main-frame
643 // navigations use speculative RenderViewHost.
644 base::WeakPtr<RenderViewHostImpl> speculative_render_view_host_;
645
Harkiran Bolaria16f2c48d2022-04-22 12:39:57646 // Indicates type of frame tree.
647 const Type type_;
648
Avi Drissmanbd153642024-09-03 18:58:05649 FrameTreeNodeId focused_frame_tree_node_id_;
danakjc492bf82020-09-09 20:02:44650
danakjc492bf82020-09-09 20:02:44651 // Overall load progress.
652 double load_progress_;
653
Carlos Caballeroede6f8c2021-01-28 11:01:50654 // Whether the initial empty page has been accessed by another page, making it
655 // unsafe to show the pending URL. Usually false unless another window tries
656 // to modify the blank page. Always false after the first commit.
657 bool has_accessed_initial_main_document_ = false;
658
Takashi Toyoshimaea534ef22021-07-21 03:27:59659 bool is_being_destroyed_ = false;
660
Carlos Caballero101ac26b2021-03-24 11:54:05661#if DCHECK_IS_ON()
662 // Whether Shutdown() was called.
663 bool was_shut_down_ = false;
664#endif
Dave Tapuskad8b0530f2021-10-19 15:12:31665
Paul Semel3e241042022-10-11 12:57:31666 // The root FrameTreeNode.
667 //
668 // Note: It is common for a node to test whether it's the root node, via the
669 // `root()` method, even while `root_` is running its destructor.
670 // For that reason, we want to destroy |root_| before any other fields.
671 FrameTreeNode root_;
672
Dave Tapuskad8b0530f2021-10-19 15:12:31673 base::WeakPtrFactory<FrameTree> weak_ptr_factory_{this};
danakjc492bf82020-09-09 20:02:44674};
675
676} // namespace content
677
678#endif // CONTENT_BROWSER_RENDERER_HOST_FRAME_TREE_H_