blob: 3b7819680277310ff5f8a3070c07d48746441490 [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;
Ari Chivukula5d15efb2023-01-21 04:33:5243class StorageKey;
danakjc492bf82020-09-09 20:02:4444} // namespace blink
45
46namespace content {
47
Carlos Caballero40b0efd2021-01-26 11:55:0048class BrowserContext;
Jeremy Roman2d8dfe132021-07-06 20:51:2649class PageDelegate;
danakjc492bf82020-09-09 20:02:4450class RenderFrameHostDelegate;
51class RenderViewHostDelegate;
52class RenderViewHostImpl;
53class RenderFrameHostManager;
54class RenderWidgetHostDelegate;
Carlos Caballero40b0efd2021-01-26 11:55:0055class SiteInstance;
Sharon Yang57bde122022-03-01 20:01:1256class SiteInstanceGroup;
danakjc492bf82020-09-09 20:02:4457
58// Represents the frame tree for a page. With the exception of the main frame,
59// all FrameTreeNodes will be created/deleted in response to frame attach and
60// detach events in the DOM.
61//
62// The main frame's FrameTreeNode is special in that it is reused. This allows
63// it to serve as an anchor for state that needs to persist across top-level
64// page navigations.
65//
66// TODO(ajwong): Move NavigationController ownership to the main frame
67// FrameTreeNode. Possibly expose access to it from here.
68//
69// This object is only used on the UI thread.
70class CONTENT_EXPORT FrameTree {
71 public:
72 class NodeRange;
73
Alan Zhao8a882d12022-05-18 01:32:1574 class CONTENT_EXPORT NodeIterator {
danakjc492bf82020-09-09 20:02:4475 public:
Alan Zhao8a882d12022-05-18 01:32:1576 using iterator_category = std::forward_iterator_tag;
77 using value_type = FrameTreeNode*;
78 using difference_type = std::ptrdiff_t;
79 using pointer = FrameTreeNode**;
80 using reference = FrameTreeNode*&;
81
danakjc492bf82020-09-09 20:02:4482 NodeIterator(const NodeIterator& other);
83 ~NodeIterator();
84
85 NodeIterator& operator++();
Kevin McNee5f594382021-05-06 23:18:2386 // Advances the iterator and excludes the children of the current node
87 NodeIterator& AdvanceSkippingChildren();
danakjc492bf82020-09-09 20:02:4488
89 bool operator==(const NodeIterator& rhs) const;
90 bool operator!=(const NodeIterator& rhs) const { return !(*this == rhs); }
91
92 FrameTreeNode* operator*() { return current_node_; }
93
94 private:
Jayson Adams4db0bfe22021-07-15 19:24:0795 friend class FrameTreeTest;
danakjc492bf82020-09-09 20:02:4496 friend class NodeRange;
97
Kevin McNee5f594382021-05-06 23:18:2398 NodeIterator(const std::vector<FrameTreeNode*>& starting_nodes,
99 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
Kevin McNee5f594382021-05-06 23:18:23127 NodeRange(const std::vector<FrameTreeNode*>& starting_nodes,
128 const FrameTreeNode* root_of_subtree_to_skip,
Dave Tapuskadda303d2022-10-04 16:56:48129 bool should_descend_into_inner_trees,
130 bool include_delegate_nodes_for_inner_frame_trees);
danakjc492bf82020-09-09 20:02:44131
Kevin McNee5f594382021-05-06 23:18:23132 const std::vector<FrameTreeNode*> starting_nodes_;
Keishi Hattori0e45c022021-11-27 09:25:52133 const raw_ptr<const FrameTreeNode> root_of_subtree_to_skip_;
Kevin McNee5f594382021-05-06 23:18:23134 const bool should_descend_into_inner_trees_;
Dave Tapuskadda303d2022-10-04 16:56:48135 const bool include_delegate_nodes_for_inner_frame_trees_;
danakjc492bf82020-09-09 20:02:44136 };
137
Carlos Caballero03262522021-02-05 14:49:58138 class CONTENT_EXPORT Delegate {
139 public:
140 // A RenderFrameHost in the specified |frame_tree_node| started loading a
141 // new document. This corresponds to browser UI starting to show a spinner
142 // or other visual indicator for loading. This method is only invoked if the
Nate Chapin9aabf5f2021-11-12 00:31:19143 // FrameTree hadn't been previously loading. |should_show_loading_ui| will
144 // be true unless the load is a fragment navigation, or triggered by
Carlos Caballero03262522021-02-05 14:49:58145 // history.pushState/replaceState.
146 virtual void DidStartLoading(FrameTreeNode* frame_tree_node,
Nate Chapin9aabf5f2021-11-12 00:31:19147 bool should_show_loading_ui) = 0;
Carlos Caballero03262522021-02-05 14:49:58148
Takashi Toyoshima74090df62021-03-09 14:34:57149 // This is called when all nodes in the FrameTree stopped loading. This
Carlos Caballero03262522021-02-05 14:49:58150 // corresponds to the browser UI stop showing a spinner or other visual
151 // indicator for loading.
152 virtual void DidStopLoading() = 0;
153
Sreeja Kamishettyd64b993d2022-02-14 12:04:42154 // Returns the delegate's top loading tree, which should be used to infer
Yu Gaoc8c18552022-06-22 14:38:45155 // the values of loading-related states. The state of
156 // IsLoadingIncludingInnerFrameTrees() is a WebContents level concept and
157 // LoadingTree would return the frame tree to which loading events should be
158 // directed.
Sreeja Kamishettyd64b993d2022-02-14 12:04:42159 //
160 // TODO(crbug.com/1261928): Remove this method and directly rely on
161 // GetOutermostMainFrame() once portals and guest views are migrated to
162 // MPArch.
163 virtual FrameTree* LoadingTree() = 0;
164
Carlos Caballero6ff6ace2021-02-05 16:53:00165 // Returns true when the active RenderWidgetHostView should be hidden.
166 virtual bool IsHidden() = 0;
Sreeja Kamishettya21b4f62021-06-25 07:48:25167
Dominic Farolinoedf44ee2021-07-20 23:50:59168 // If the FrameTree using this delegate is an inner/nested FrameTree, then
169 // there may be a FrameTreeNode in the outer FrameTree that is considered
170 // our outer delegate FrameTreeNode. This method returns the outer delegate
171 // FrameTreeNode ID if one exists. If we don't have a an outer delegate
172 // FrameTreeNode, this method returns
173 // FrameTreeNode::kFrameTreeNodeInvalidId.
174 virtual int GetOuterDelegateFrameTreeNodeId() = 0;
Dave Tapuskac8de3b02021-12-03 21:51:01175
176 // Returns if this FrameTree represents a portal.
177 virtual bool IsPortal() = 0;
Julie Jeongeun Kim2132b37f82022-11-23 08:30:46178
179 // Set the `node` frame as focused in its own FrameTree as well as possibly
180 // changing the focused frame tree in the case of inner/outer FrameTrees.
181 virtual void SetFocusedFrame(FrameTreeNode* node,
182 SiteInstanceGroup* source) = 0;
Carlos Caballero03262522021-02-05 14:49:58183 };
184
Sreeja Kamishetty74bacd522021-03-22 17:04:24185 // Type of FrameTree instance.
186 enum class Type {
187 // This FrameTree is the primary frame tree for the WebContents, whose main
188 // document URL is shown in the Omnibox.
189 kPrimary,
190
191 // This FrameTree is used to prerender a page in the background which is
192 // invisible to the user.
Dominic Farolino4bc10ee2021-08-31 00:37:36193 kPrerender,
194
195 // This FrameTree is used to host the contents of a <fencedframe> element.
196 // Even for <fencedframe>s hosted inside a prerendered page, the FrameTree
197 // associated with the fenced frame will be kFencedFrame, but the
198 // RenderFrameHosts inside of it will have their lifecycle state set to
199 // `RenderFrameHost::LifecycleState::kActive`.
200 //
201 // TODO(crbug.com/1232528, crbug.com/1244274): We should either:
202 // * Fully support nested FrameTrees inside prerendered pages, in which
203 // case all of the RenderFrameHosts inside the nested trees should have
204 // their lifecycle state set to kPrerendering, or...
205 // * Ban nested FrameTrees in prerendered pages, and therefore obsolete the
206 // above paragraph about <fencedframe>s hosted in prerendered pages.
207 kFencedFrame
Sreeja Kamishetty74bacd522021-03-22 17:04:24208 };
Sreeja Kamishetty837a10402021-04-23 12:41:59209
210 // A set of delegates are remembered here so that we can create
211 // RenderFrameHostManagers.
212 FrameTree(BrowserContext* browser_context,
213 Delegate* delegate,
214 NavigationControllerDelegate* navigation_controller_delegate,
215 NavigatorDelegate* navigator_delegate,
216 RenderFrameHostDelegate* render_frame_delegate,
217 RenderViewHostDelegate* render_view_delegate,
218 RenderWidgetHostDelegate* render_widget_delegate,
219 RenderFrameHostManager::Delegate* manager_delegate,
Jeremy Roman2d8dfe132021-07-06 20:51:26220 PageDelegate* page_delegate,
Danil Somsikov259aa65f2022-11-11 20:49:44221 Type type);
Peter Boström828b9022021-09-21 02:28:43222
223 FrameTree(const FrameTree&) = delete;
224 FrameTree& operator=(const FrameTree&) = delete;
225
Sreeja Kamishetty837a10402021-04-23 12:41:59226 ~FrameTree();
Sreeja Kamishetty74bacd522021-03-22 17:04:24227
Carlos Caballero40b0efd2021-01-26 11:55:00228 // Initializes the main frame for this FrameTree. That is it creates the
Rakina Zata Amniafd3c6582021-11-30 06:19:17229 // initial RenderFrameHost in the root node's RenderFrameHostManager, and also
Rakina Zata Amni46087a12022-11-11 08:28:38230 // creates an initial NavigationEntry that potentially inherits
231 // `opener_for_origin`'s origin in its NavigationController. This method will
232 // call back into the delegates so it should only be called once they have
233 // completed their initialization. Pass in frame_policy so that it can be set
234 // in the root node's replication_state.
Carlos Caballero40b0efd2021-01-26 11:55:00235 // TODO(carlscab): It would be great if initialization could happened in the
236 // constructor so we do not leave objects in a half initialized state.
Charlie Reis37be2682023-01-10 17:04:47237 void Init(SiteInstanceImpl* main_frame_site_instance,
Carlos Caballero40b0efd2021-01-26 11:55:00238 bool renderer_initiated_creation,
Rakina Zata Amniafd3c6582021-11-30 06:19:17239 const std::string& main_frame_name,
Rakina Zata Amni4eb716e2022-04-05 21:32:46240 RenderFrameHostImpl* opener_for_origin,
Danil Somsikov259aa65f2022-11-11 20:49:44241 const blink::FramePolicy& frame_policy,
242 const base::UnguessableToken& devtools_frame_token);
Sreeja Kamishetty837a10402021-04-23 12:41:59243
244 Type type() const { return type_; }
Carlos Caballero40b0efd2021-01-26 11:55:00245
Paul Semel3e241042022-10-11 12:57:31246 FrameTreeNode* root() { return &root_; }
247 const FrameTreeNode* root() const { return &root_; }
danakjc492bf82020-09-09 20:02:44248
Sreeja Kamishetty74bacd522021-03-22 17:04:24249 bool is_prerendering() const { return type_ == FrameTree::Type::kPrerender; }
Sreeja Kamishetty46f762c2021-02-05 07:52:46250
Sreeja Kamishetty60e47132022-02-08 12:51:53251 // Returns true if this frame tree is a portal.
252 //
253 // TODO(crbug.com/1254770): Once portals are migrated to MPArch, portals will
254 // have their own FrameTree::Type.
255 bool IsPortal();
256
Carlos Caballero03262522021-02-05 14:49:58257 Delegate* delegate() { return delegate_; }
258
Jeremy Roman2d8dfe132021-07-06 20:51:26259 // Delegates for various objects. These can be kept centrally on the
260 // FrameTree because they are expected to be the same for all frames on a
261 // given FrameTree.
danakjc492bf82020-09-09 20:02:44262 RenderFrameHostDelegate* render_frame_delegate() {
263 return render_frame_delegate_;
264 }
265 RenderViewHostDelegate* render_view_delegate() {
266 return render_view_delegate_;
267 }
268 RenderWidgetHostDelegate* render_widget_delegate() {
269 return render_widget_delegate_;
270 }
271 RenderFrameHostManager::Delegate* manager_delegate() {
272 return manager_delegate_;
273 }
Jeremy Roman2d8dfe132021-07-06 20:51:26274 PageDelegate* page_delegate() { return page_delegate_; }
Aaron Colwell78b4bde2021-03-16 16:16:09275
Sharon Yanged884542023-02-02 17:33:44276 // Iterate over all RenderViewHosts, including speculative RenderViewHosts.
277 // See `speculative_render_view_host_` for more details.
278 void ForEachRenderViewHost(
279 base::FunctionRef<void(RenderViewHostImpl*)> on_host);
danakjc492bf82020-09-09 20:02:44280
Sharon Yang7ce309e2023-01-19 21:39:57281 // Speculative RenderViewHost accessors.
282 RenderViewHostImpl* speculative_render_view_host() const {
283 return speculative_render_view_host_.get();
284 }
285 void set_speculative_render_view_host(
286 base::WeakPtr<RenderViewHostImpl> render_view_host) {
287 speculative_render_view_host_ = render_view_host;
288 }
289
290 // Moves `speculative_render_view_host_` to `render_view_host_map_`. This
291 // should be called every time a main-frame same-SiteInstanceGroup speculative
292 // RenderFrameHost gets swapped in and becomes the active RenderFrameHost.
293 // This overwrites the previous RenderViewHost for the SiteInstanceGroup in
294 // `render_view_host_map_`, if one exists.
295 void MakeSpeculativeRVHCurrent();
296
danakjc492bf82020-09-09 20:02:44297 // Returns the FrameTreeNode with the given |frame_tree_node_id| if it is part
298 // of this FrameTree.
299 FrameTreeNode* FindByID(int frame_tree_node_id);
300
301 // Returns the FrameTreeNode with the given renderer-specific |routing_id|.
302 FrameTreeNode* FindByRoutingID(int process_id, int routing_id);
303
304 // Returns the first frame in this tree with the given |name|, or the main
305 // frame if |name| is empty.
306 // Note that this does NOT support pseudo-names like _self, _top, and _blank,
307 // nor searching other FrameTrees (unlike blink::WebView::findFrameByName).
308 FrameTreeNode* FindByName(const std::string& name);
309
310 // Returns a range to iterate over all FrameTreeNodes in the frame tree in
311 // breadth-first traversal order.
312 NodeRange Nodes();
313
314 // Returns a range to iterate over all FrameTreeNodes in a subtree of the
315 // frame tree, starting from |subtree_root|.
316 NodeRange SubtreeNodes(FrameTreeNode* subtree_root);
317
Kevin McNee53f0b2d2021-11-02 18:00:45318 // Returns a range to iterate over all FrameTreeNodes in this frame tree, as
319 // well as any FrameTreeNodes of inner frame trees. Note that this includes
320 // inner frame trees of inner WebContents as well.
321 NodeRange NodesIncludingInnerTreeNodes();
322
Kevin McNee5f594382021-05-06 23:18:23323 // Returns a range to iterate over all FrameTreeNodes in a subtree, starting
324 // from, but not including |parent|, as well as any FrameTreeNodes of inner
Kevin McNee53f0b2d2021-11-02 18:00:45325 // frame trees. Note that this includes inner frame trees of inner WebContents
Dave Tapuskadda303d2022-10-04 16:56:48326 // as well. If `include_delegate_nodes_for_inner_frame_trees` is true the
327 // delegate RenderFrameHost owning the inner frame tree will also be returned.
328 static NodeRange SubtreeAndInnerTreeNodes(
329 RenderFrameHostImpl* parent,
330 bool include_delegate_nodes_for_inner_frame_trees = false);
Kevin McNee5f594382021-05-06 23:18:23331
danakjc492bf82020-09-09 20:02:44332 // Adds a new child frame to the frame tree. |process_id| is required to
333 // disambiguate |new_routing_id|, and it must match the process of the
Kevin McNee43fe8292021-10-04 22:59:41334 // |parent| node. Otherwise no child is added and this method returns nullptr.
danakjc492bf82020-09-09 20:02:44335 // |interface_provider_receiver| is the receiver end of the InterfaceProvider
336 // interface through which the child RenderFrame can access Mojo services
337 // exposed by the corresponding RenderFrameHost. The caller takes care of
Antonio Sartoridb967c52021-01-20 09:54:30338 // sending the client end of the interface down to the
339 // RenderFrame. |policy_container_bind_params|, if not null, is used for
340 // binding Blink's policy container to the new RenderFrameHost's
341 // PolicyContainerHost. This is only needed if this frame is the result of the
342 // CreateChildFrame mojo call, which also delivers the
Kevin McNee43fe8292021-10-04 22:59:41343 // |policy_container_bind_params|. |is_dummy_frame_for_inner_tree| is true if
344 // the added frame is only to serve as a placeholder for an inner frame tree
345 // (e.g. fenced frames, portals) and will not have a live RenderFrame of its
346 // own.
danakjc492bf82020-09-09 20:02:44347 FrameTreeNode* AddFrame(
348 RenderFrameHostImpl* parent,
349 int process_id,
350 int new_routing_id,
danakj0bdfacd2021-01-20 19:27:18351 mojo::PendingAssociatedRemote<mojom::Frame> frame_remote,
danakjc492bf82020-09-09 20:02:44352 mojo::PendingReceiver<blink::mojom::BrowserInterfaceBroker>
353 browser_interface_broker_receiver,
Antonio Sartoridb967c52021-01-20 09:54:30354 blink::mojom::PolicyContainerBindParamsPtr policy_container_bind_params,
Dominic Farolino12e06d72022-08-05 02:29:49355 mojo::PendingAssociatedReceiver<blink::mojom::AssociatedInterfaceProvider>
356 associated_interface_provider_receiver,
danakjc492bf82020-09-09 20:02:44357 blink::mojom::TreeScopeType scope,
358 const std::string& frame_name,
359 const std::string& frame_unique_name,
360 bool is_created_by_script,
Chris Hamilton3ff6ed0e2021-02-19 03:54:04361 const blink::LocalFrameToken& frame_token,
danakjc492bf82020-09-09 20:02:44362 const base::UnguessableToken& devtools_frame_token,
Daniel Cheng284c38942022-09-22 23:30:34363 const blink::DocumentToken& document_token,
danakjc492bf82020-09-09 20:02:44364 const blink::FramePolicy& frame_policy,
365 const blink::mojom::FrameOwnerProperties& frame_owner_properties,
366 bool was_discarded,
Kevin McNee43fe8292021-10-04 22:59:41367 blink::FrameOwnerElementType owner_type,
368 bool is_dummy_frame_for_inner_tree);
danakjc492bf82020-09-09 20:02:44369
370 // Removes a frame from the frame tree. |child|, its children, and objects
371 // owned by their RenderFrameHostManagers are immediately deleted. The root
372 // node cannot be removed this way.
373 void RemoveFrame(FrameTreeNode* child);
374
375 // This method walks the entire frame tree and creates a RenderFrameProxyHost
376 // for the given |site_instance| in each node except the |source| one --
377 // the source will have a RenderFrameHost. |source| may be null if there is
378 // no node navigating in this frame tree (such as when this is called
379 // for an opener's frame tree), in which case no nodes are skipped for
Harkiran Bolaria2912a6b32022-02-22 16:43:45380 // RenderFrameProxyHost creation. |source_new_browsing_context_state| is the
381 // BrowsingContextState used by the speculative frame host, which may differ
382 // from the BrowsingContextState in |source| during cross-origin cross-
383 // browsing-instance navigations.
danakjc492bf82020-09-09 20:02:44384 void CreateProxiesForSiteInstance(FrameTreeNode* source,
Charlie Reis37be2682023-01-10 17:04:47385 SiteInstanceImpl* site_instance,
Harkiran Bolaria2912a6b32022-02-22 16:43:45386 const scoped_refptr<BrowsingContextState>&
387 source_new_browsing_context_state);
danakjc492bf82020-09-09 20:02:44388
389 // Convenience accessor for the main frame's RenderFrameHostImpl.
390 RenderFrameHostImpl* GetMainFrame() const;
391
392 // Returns the focused frame.
393 FrameTreeNode* GetFocusedFrame();
394
Sharon Yangefe52632022-03-08 23:06:06395 // Sets the focused frame to |node|. |source| identifies the
396 // SiteInstanceGroup that initiated this focus change. If this FrameTree has
397 // SiteInstanceGroups other than |source|, those SiteInstanceGroups will be
398 // notified about the new focused frame. Note that |source| may differ from
399 // |node|'s current SiteInstanceGroup (e.g., this happens for cross-process
400 // window.focus() calls).
401 void SetFocusedFrame(FrameTreeNode* node, SiteInstanceGroup* source);
danakjc492bf82020-09-09 20:02:44402
danakjc492bf82020-09-09 20:02:44403 // Creates a RenderViewHostImpl for a given |site_instance| in the tree.
404 //
405 // The RenderFrameHostImpls and the RenderFrameProxyHosts will share ownership
406 // of this object.
Sharon Yang7ce309e2023-01-19 21:39:57407 // `create_case` indicates whether or not the RenderViewHost being created is
408 // speculative or not. It should only be registered with the FrameTree if it
409 // is not speculative.
danakjc492bf82020-09-09 20:02:44410 scoped_refptr<RenderViewHostImpl> CreateRenderViewHost(
Charlie Reis37be2682023-01-10 17:04:47411 SiteInstanceImpl* site_instance,
danakjc492bf82020-09-09 20:02:44412 int32_t main_frame_routing_id,
Harkiran Bolaria57e2b062022-03-14 10:27:58413 bool renderer_initiated_creation,
Sharon Yang7ce309e2023-01-19 21:39:57414 scoped_refptr<BrowsingContextState> main_browsing_context_state,
415 CreateRenderViewHostCase create_case);
danakjc492bf82020-09-09 20:02:44416
417 // Returns the existing RenderViewHost for a new RenderFrameHost.
418 // There should always be such a RenderViewHost, because the main frame
419 // RenderFrameHost for each SiteInstance should be created before subframes.
Sharon Yang7ce309e2023-01-19 21:39:57420 // Note that this will never return `speculative_render_view_host_`. If that
421 // is needed, call `speculative_render_view_host()` instead.
Sharon Yang57bde122022-03-01 20:01:12422 scoped_refptr<RenderViewHostImpl> GetRenderViewHost(SiteInstanceGroup* group);
danakjc492bf82020-09-09 20:02:44423
Sharon Yanged884542023-02-02 17:33:44424 using RenderViewHostMapId = base::IdType32<class RenderViewHostMap>;
425
Sharon Yangc581a0c2021-11-02 18:09:39426 // Returns the ID used for the RenderViewHost associated with
427 // |site_instance_group|.
428 RenderViewHostMapId GetRenderViewHostMapId(
429 SiteInstanceGroup* site_instance_group) const;
Aaron Colwell78b4bde2021-03-16 16:16:09430
danakjc492bf82020-09-09 20:02:44431 // Registers a RenderViewHost so that it can be reused by other frames
Aaron Colwell78b4bde2021-03-16 16:16:09432 // whose SiteInstance maps to the same RenderViewHostMapId.
danakjc492bf82020-09-09 20:02:44433 //
434 // This method does not take ownership of|rvh|.
435 //
436 // NOTE: This method CHECK fails if a RenderViewHost is already registered for
437 // |rvh|'s SiteInstance.
438 //
439 // ALSO NOTE: After calling RegisterRenderViewHost, UnregisterRenderViewHost
440 // *must* be called for |rvh| when it is destroyed or put into the
441 // BackForwardCache, to prevent FrameTree::CreateRenderViewHost from trying to
442 // reuse it.
Aaron Colwell78b4bde2021-03-16 16:16:09443 void RegisterRenderViewHost(RenderViewHostMapId id, RenderViewHostImpl* rvh);
danakjc492bf82020-09-09 20:02:44444
445 // Unregisters the RenderViewHostImpl that's available for reuse for a
Aaron Colwell78b4bde2021-03-16 16:16:09446 // particular RenderViewHostMapId. NOTE: This method CHECK fails if it is
447 // called for a |render_view_host| that is not currently set for reuse.
448 void UnregisterRenderViewHost(RenderViewHostMapId id,
Aaron Colwellc4bd7d62021-01-29 04:23:13449 RenderViewHostImpl* render_view_host);
danakjc492bf82020-09-09 20:02:44450
451 // This is called when the frame is about to be removed and started to run
452 // unload handlers.
453 void FrameUnloading(FrameTreeNode* frame);
454
455 // This is only meant to be called by FrameTreeNode. Triggers calling
456 // the listener installed by SetFrameRemoveListener.
457 void FrameRemoved(FrameTreeNode* frame);
458
Carlos Caballero03262522021-02-05 14:49:58459 void DidStartLoadingNode(FrameTreeNode& node,
Nate Chapin9aabf5f2021-11-12 00:31:19460 bool should_show_loading_ui,
Carlos Caballero03262522021-02-05 14:49:58461 bool was_previously_loading);
462 void DidStopLoadingNode(FrameTreeNode& node);
Carlos Caballero03262522021-02-05 14:49:58463 void DidCancelLoading();
danakjc492bf82020-09-09 20:02:44464
Sreeja Kamishetty0be3b1b2021-08-12 17:04:15465 // Returns this FrameTree's total load progress. If the `root_` FrameTreeNode
466 // is navigating returns `blink::kInitialLoadProgress`.
467 double GetLoadProgress();
danakjc492bf82020-09-09 20:02:44468
Sreeja Kamishetty15f9944a22022-03-10 10:16:08469 // Returns true if at least one of the nodes in this frame tree or nodes in
470 // any inner frame tree of the same WebContents is loading.
Yu Gaoc8c18552022-06-22 14:38:45471 bool IsLoadingIncludingInnerFrameTrees() const;
danakjc492bf82020-09-09 20:02:44472
473 // Set page-level focus in all SiteInstances involved in rendering
474 // this FrameTree, not including the current main frame's
475 // SiteInstance. The focus update will be sent via the main frame's proxies
476 // in those SiteInstances.
477 void ReplicatePageFocus(bool is_focused);
478
479 // Updates page-level focus for this FrameTree in the subframe renderer
Sharon Yangefe52632022-03-08 23:06:06480 // identified by |group|.
481 void SetPageFocus(SiteInstanceGroup* group, bool is_focused);
danakjc492bf82020-09-09 20:02:44482
W. James MacLeanc07dc41b2022-07-25 18:52:16483 // Walks the current frame tree and registers any origins matching
484 // `previously_visited_origin`, either the last committed origin of a
485 // RenderFrameHost or the origin associated with a NavigationRequest that has
486 // been assigned to a SiteInstance, as having the default origin isolation
487 // state. This is only necessary when `previously_visited_origin` is seen with
488 // an OriginAgentCluster header explicitly requesting something other than the
489 // default.
490 void RegisterExistingOriginAsHavingDefaultIsolation(
danakjc492bf82020-09-09 20:02:44491 const url::Origin& previously_visited_origin,
492 NavigationRequest* navigation_request_to_exclude);
493
Carlos Caballero40b0efd2021-01-26 11:55:00494 NavigationControllerImpl& controller() { return navigator_.controller(); }
danakjc492bf82020-09-09 20:02:44495 Navigator& navigator() { return navigator_; }
496
Carlos Caballeroede6f8c2021-01-28 11:01:50497 // Another page accessed the initial empty main document, which means it
498 // is no longer safe to display a pending URL without risking a URL spoof.
499 void DidAccessInitialMainDocument();
500
501 bool has_accessed_initial_main_document() const {
502 return has_accessed_initial_main_document_;
503 }
504
505 void ResetHasAccessedInitialMainDocument() {
506 has_accessed_initial_main_document_ = false;
507 }
508
Carlos Caballero6ff6ace2021-02-05 16:53:00509 bool IsHidden() const { return delegate_->IsHidden(); }
510
Sreeja Kamishettyd64b993d2022-02-14 12:04:42511 // LoadingTree returns the following for different frame trees to direct
512 // loading related events. Please see FrameTree::Delegate::LoadingTree for
513 // more comments.
514 // - For prerender frame tree -> returns the frame tree itself.
515 // - For fenced frame and primary frame tree (including portal) -> returns
516 // the delegate's primary frame tree.
517 FrameTree* LoadingTree();
518
Carlos Caballero03262522021-02-05 14:49:58519 // Stops all ongoing navigations in each of the nodes of this FrameTree.
520 void StopLoading();
521
Carlos Caballero101ac26b2021-03-24 11:54:05522 // Prepares this frame tree for destruction, cleaning up the internal state
523 // and firing the appropriate events like FrameDeleted.
524 // Must be called before FrameTree is destroyed.
525 void Shutdown();
526
Takashi Toyoshimaea534ef22021-07-21 03:27:59527 bool IsBeingDestroyed() const { return is_being_destroyed_; }
528
Dave Tapuskad8b0530f2021-10-19 15:12:31529 base::SafeRef<FrameTree> GetSafeRef();
530
Dave Tapuska54c76a032021-10-27 22:10:42531 // Walks up the FrameTree chain and focuses the FrameTreeNode where
532 // each inner FrameTree is attached.
533 void FocusOuterFrameTrees();
534
Ari Chivukula5d15efb2023-01-21 04:33:52535 // This should only be called by NavigationRequest when it detects that an
536 // origin is participating in the deprecation trial.
537 //
538 // TODO(crbug.com/1407150): Remove this when deprecation trial is complete.
539 void RegisterOriginForUnpartitionedSessionStorageAccess(
540 const url::Origin& origin);
541
Ari Chivukula9a96a582023-02-03 21:02:29542 // This should only be called by NavigationRequest when it detects that an
543 // origin is not participating in the deprecation trial.
544 //
545 // TODO(crbug.com/1407150): Remove this when deprecation trial is complete.
546 void UnregisterOriginForUnpartitionedSessionStorageAccess(
547 const url::Origin& origin);
548
Ari Chivukula5d15efb2023-01-21 04:33:52549 // This should be used for all session storage related bindings as it adjusts
550 // the storage key used depending on the deprecation trial.
551 //
552 // TODO(crbug.com/1407150): Remove this when deprecation trial is complete.
553 const blink::StorageKey GetSessionStorageKey(
554 const blink::StorageKey& storage_key);
555
danakjc492bf82020-09-09 20:02:44556 private:
557 friend class FrameTreeTest;
558 FRIEND_TEST_ALL_PREFIXES(RenderFrameHostImplBrowserTest, RemoveFocusedFrame);
Sreeja Kamishettyd64b993d2022-02-14 12:04:42559 FRIEND_TEST_ALL_PREFIXES(PortalBrowserTest, NodesForIsLoading);
Xiaochen Zhou6443f752022-08-10 16:40:46560 FRIEND_TEST_ALL_PREFIXES(FencedFrameMPArchBrowserTest, NodesForIsLoading);
Sharon Yang2f3304a2022-05-13 02:24:25561 FRIEND_TEST_ALL_PREFIXES(RenderFrameHostManagerTest,
562 CreateRenderViewAfterProcessKillAndClosedProxy);
danakjc492bf82020-09-09 20:02:44563
564 // Returns a range to iterate over all FrameTreeNodes in the frame tree in
565 // breadth-first traversal order, skipping the subtree rooted at
566 // |node|, but including |node| itself.
567 NodeRange NodesExceptSubtree(FrameTreeNode* node);
568
Sreeja Kamishettyd64b993d2022-02-14 12:04:42569 // Returns all FrameTreeNodes in this frame tree, as well as any
570 // FrameTreeNodes of inner frame trees. Note that this doesn't include inner
571 // frame trees of inner delegates. This is used to find the aggregate
572 // IsLoading value for a frame tree.
573 //
574 // TODO(crbug.com/1261928, crbug.com/1261928): Remove this method and directly
575 // rely on GetOutermostMainFrame() and NodesIncludingInnerTreeNodes() once
576 // portals and guest views are migrated to MPArch.
577 std::vector<FrameTreeNode*> CollectNodesForIsLoading();
578
Keishi Hattori0e45c022021-11-27 09:25:52579 const raw_ptr<Delegate> delegate_;
Carlos Caballero03262522021-02-05 14:49:58580
danakjc492bf82020-09-09 20:02:44581 // These delegates are installed into all the RenderViewHosts and
582 // RenderFrameHosts that we create.
Keishi Hattori0e45c022021-11-27 09:25:52583 raw_ptr<RenderFrameHostDelegate> render_frame_delegate_;
584 raw_ptr<RenderViewHostDelegate> render_view_delegate_;
585 raw_ptr<RenderWidgetHostDelegate> render_widget_delegate_;
586 raw_ptr<RenderFrameHostManager::Delegate> manager_delegate_;
587 raw_ptr<PageDelegate> page_delegate_;
danakjc492bf82020-09-09 20:02:44588
589 // The Navigator object responsible for managing navigations on this frame
Carlos Caballero40b0efd2021-01-26 11:55:00590 // tree. Each FrameTreeNode will default to using it for navigation tasks in
591 // the frame.
danakjc492bf82020-09-09 20:02:44592 Navigator navigator_;
593
Sharon Yanged884542023-02-02 17:33:44594 // A map to store RenderViewHosts, keyed by SiteInstanceGroup ID.
595 // This map does not cover all RenderViewHosts in a FrameTree. See
596 // `speculative_render_view_host_`.
597 using RenderViewHostMap = std::unordered_map<RenderViewHostMapId,
598 RenderViewHostImpl*,
599 RenderViewHostMapId::Hasher>;
Aaron Colwell78b4bde2021-03-16 16:16:09600 // Map of RenderViewHostMapId to RenderViewHost. This allows us to look up the
danakjc492bf82020-09-09 20:02:44601 // RenderViewHost for a given SiteInstance when creating RenderFrameHosts.
602 // Each RenderViewHost maintains a refcount and is deleted when there are no
603 // more RenderFrameHosts or RenderFrameProxyHosts using it.
Aaron Colwell78b4bde2021-03-16 16:16:09604 RenderViewHostMap render_view_host_map_;
danakjc492bf82020-09-09 20:02:44605
Sharon Yang7ce309e2023-01-19 21:39:57606 // A speculative RenderViewHost is created for all speculative cross-page
607 // same-SiteInstanceGroup RenderFrameHosts. When the corresponding
608 // RenderFrameHost gets committed and becomes the current RenderFrameHost,
609 // `speculative_render_view_host_` will be moved to `render_view_host_map_`,
610 // overwriting the previous RenderViewHost of the same SiteInstanceGroup, if
611 // applicable. This field will also be reset at that time, or if the
612 // speculative RenderFrameHost gets deleted.
613 //
614 // For any given FrameTree, there will be at most one
615 // `speculative_render_view_host_`, because only main-frame speculative
616 // RenderFrameHosts have speculative RenderViewHosts, and there is at most one
617 // such RenderFrameHost per FrameTree at a time.
618 // This is a WeakPtr, since the RenderViewHost is owned by the
619 // RenderFrameHostImpl, not the FrameTree. This implies that if the owning
620 // RenderFrameHostImpl gets deleted, this will too.
621 //
622 // This supports but is independent of RenderDocument, which introduces cases
623 // where there may be more than one RenderViewHost per SiteInstanceGroup, such
624 // as cross-page same-SiteInstanceGroup navigations. The speculative
625 // RenderFrameHost has an associated RenderViewHost, but it cannot be put in
626 // `render_view_host_map_` when it is created, as the existing RenderViewHost
627 // will be incorrectly overwritten.
628 // TODO(yangsharon, crbug.com/1336305): Expand support to include
629 // cross-SiteInstanceGroup main-frame navigations, so all main-frame
630 // navigations use speculative RenderViewHost.
631 base::WeakPtr<RenderViewHostImpl> speculative_render_view_host_;
632
Harkiran Bolaria16f2c48d2022-04-22 12:39:57633 // Indicates type of frame tree.
634 const Type type_;
635
danakjc492bf82020-09-09 20:02:44636 int focused_frame_tree_node_id_;
637
danakjc492bf82020-09-09 20:02:44638 // Overall load progress.
639 double load_progress_;
640
Carlos Caballeroede6f8c2021-01-28 11:01:50641 // Whether the initial empty page has been accessed by another page, making it
642 // unsafe to show the pending URL. Usually false unless another window tries
643 // to modify the blank page. Always false after the first commit.
644 bool has_accessed_initial_main_document_ = false;
645
Takashi Toyoshimaea534ef22021-07-21 03:27:59646 bool is_being_destroyed_ = false;
647
Carlos Caballero101ac26b2021-03-24 11:54:05648#if DCHECK_IS_ON()
649 // Whether Shutdown() was called.
650 bool was_shut_down_ = false;
651#endif
Dave Tapuskad8b0530f2021-10-19 15:12:31652
Paul Semel3e241042022-10-11 12:57:31653 // The root FrameTreeNode.
654 //
655 // Note: It is common for a node to test whether it's the root node, via the
656 // `root()` method, even while `root_` is running its destructor.
657 // For that reason, we want to destroy |root_| before any other fields.
658 FrameTreeNode root_;
659
Ari Chivukula5d15efb2023-01-21 04:33:52660 // Origins in this set have enabled a deprecation trial that prevents the
661 // partitioning of session storage when embedded as a third-party iframe.
662 // This list persists for the lifetime of the associated tab.
663 //
664 // TODO(crbug.com/1407150): Remove this when deprecation trial is complete.
665 std::set<url::Origin> unpartitioned_session_storage_origins_;
666
Dave Tapuskad8b0530f2021-10-19 15:12:31667 base::WeakPtrFactory<FrameTree> weak_ptr_factory_{this};
danakjc492bf82020-09-09 20:02:44668};
669
670} // namespace content
671
672#endif // CONTENT_BROWSER_RENDERER_HOST_FRAME_TREE_H_