blob: 344362f43523fb1bb8d3d025ed944112736f0a01 [file] [log] [blame]
danakjc492bf82020-09-09 20:02:441// Copyright 2013 The Chromium Authors. All rights reserved.
2// 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"
19#include "base/macros.h"
20#include "content/browser/renderer_host/navigator.h"
21#include "content/browser/renderer_host/navigator_delegate.h"
22#include "content/browser/renderer_host/render_frame_host_manager.h"
23#include "content/common/content_export.h"
24#include "mojo/public/cpp/bindings/pending_receiver.h"
25#include "services/service_manager/public/mojom/interface_provider.mojom.h"
Chris Hamilton3ff6ed0e2021-02-19 03:54:0426#include "third_party/blink/public/common/tokens/tokens.h"
danakjc492bf82020-09-09 20:02:4427#include "third_party/blink/public/mojom/frame/frame_owner_element_type.mojom.h"
28#include "third_party/blink/public/mojom/frame/frame_owner_properties.mojom-forward.h"
29
30namespace blink {
31struct FramePolicy;
32} // namespace blink
33
34namespace content {
35
Carlos Caballero40b0efd2021-01-26 11:55:0036class BrowserContext;
danakjc492bf82020-09-09 20:02:4437class RenderFrameHostDelegate;
38class RenderViewHostDelegate;
39class RenderViewHostImpl;
40class RenderFrameHostManager;
41class RenderWidgetHostDelegate;
Carlos Caballero40b0efd2021-01-26 11:55:0042class SiteInstance;
danakjc492bf82020-09-09 20:02:4443
44// Represents the frame tree for a page. With the exception of the main frame,
45// all FrameTreeNodes will be created/deleted in response to frame attach and
46// detach events in the DOM.
47//
48// The main frame's FrameTreeNode is special in that it is reused. This allows
49// it to serve as an anchor for state that needs to persist across top-level
50// page navigations.
51//
52// TODO(ajwong): Move NavigationController ownership to the main frame
53// FrameTreeNode. Possibly expose access to it from here.
54//
55// This object is only used on the UI thread.
56class CONTENT_EXPORT FrameTree {
57 public:
58 class NodeRange;
59
60 class CONTENT_EXPORT NodeIterator
61 : public std::iterator<std::forward_iterator_tag, FrameTreeNode> {
62 public:
63 NodeIterator(const NodeIterator& other);
64 ~NodeIterator();
65
66 NodeIterator& operator++();
Kevin McNee5f594382021-05-06 23:18:2367 // Advances the iterator and excludes the children of the current node
68 NodeIterator& AdvanceSkippingChildren();
danakjc492bf82020-09-09 20:02:4469
70 bool operator==(const NodeIterator& rhs) const;
71 bool operator!=(const NodeIterator& rhs) const { return !(*this == rhs); }
72
73 FrameTreeNode* operator*() { return current_node_; }
74
75 private:
76 friend class NodeRange;
77
Kevin McNee5f594382021-05-06 23:18:2378 NodeIterator(const std::vector<FrameTreeNode*>& starting_nodes,
79 const FrameTreeNode* root_of_subtree_to_skip,
80 bool should_descend_into_inner_trees);
81
82 void AdvanceNode();
danakjc492bf82020-09-09 20:02:4483
84 FrameTreeNode* current_node_;
Kevin McNee5f594382021-05-06 23:18:2385 const FrameTreeNode* const root_of_subtree_to_skip_;
86 const bool should_descend_into_inner_trees_;
danakjc492bf82020-09-09 20:02:4487 base::queue<FrameTreeNode*> queue_;
88 };
89
90 class CONTENT_EXPORT NodeRange {
91 public:
Kevin McNee5f594382021-05-06 23:18:2392 NodeRange(const NodeRange&);
93 ~NodeRange();
94
danakjc492bf82020-09-09 20:02:4495 NodeIterator begin();
96 NodeIterator end();
97
98 private:
99 friend class FrameTree;
100
Kevin McNee5f594382021-05-06 23:18:23101 NodeRange(const std::vector<FrameTreeNode*>& starting_nodes,
102 const FrameTreeNode* root_of_subtree_to_skip,
103 bool should_descend_into_inner_trees);
danakjc492bf82020-09-09 20:02:44104
Kevin McNee5f594382021-05-06 23:18:23105 const std::vector<FrameTreeNode*> starting_nodes_;
106 const FrameTreeNode* const root_of_subtree_to_skip_;
107 const bool should_descend_into_inner_trees_;
danakjc492bf82020-09-09 20:02:44108 };
109
Carlos Caballero03262522021-02-05 14:49:58110 class CONTENT_EXPORT Delegate {
111 public:
112 // A RenderFrameHost in the specified |frame_tree_node| started loading a
113 // new document. This corresponds to browser UI starting to show a spinner
114 // or other visual indicator for loading. This method is only invoked if the
115 // FrameTree hadn't been previously loading. |to_different_document| will be
116 // true unless the load is a fragment navigation, or triggered by
117 // history.pushState/replaceState.
118 virtual void DidStartLoading(FrameTreeNode* frame_tree_node,
119 bool to_different_document) = 0;
120
Takashi Toyoshima74090df62021-03-09 14:34:57121 // This is called when all nodes in the FrameTree stopped loading. This
Carlos Caballero03262522021-02-05 14:49:58122 // corresponds to the browser UI stop showing a spinner or other visual
123 // indicator for loading.
124 virtual void DidStopLoading() = 0;
125
126 // The load progress was changed.
127 virtual void DidChangeLoadProgress() = 0;
Carlos Caballero6ff6ace2021-02-05 16:53:00128
129 // Returns true when the active RenderWidgetHostView should be hidden.
130 virtual bool IsHidden() = 0;
Carlos Caballero03262522021-02-05 14:49:58131 };
132
Sreeja Kamishetty74bacd522021-03-22 17:04:24133 // Type of FrameTree instance.
134 enum class Type {
135 // This FrameTree is the primary frame tree for the WebContents, whose main
136 // document URL is shown in the Omnibox.
137 kPrimary,
138
139 // This FrameTree is used to prerender a page in the background which is
140 // invisible to the user.
141 kPrerender
142 };
Sreeja Kamishetty837a10402021-04-23 12:41:59143
144 // A set of delegates are remembered here so that we can create
145 // RenderFrameHostManagers.
146 FrameTree(BrowserContext* browser_context,
147 Delegate* delegate,
148 NavigationControllerDelegate* navigation_controller_delegate,
149 NavigatorDelegate* navigator_delegate,
150 RenderFrameHostDelegate* render_frame_delegate,
151 RenderViewHostDelegate* render_view_delegate,
152 RenderWidgetHostDelegate* render_widget_delegate,
153 RenderFrameHostManager::Delegate* manager_delegate,
154 Type type);
155 ~FrameTree();
Sreeja Kamishetty74bacd522021-03-22 17:04:24156
Carlos Caballero40b0efd2021-01-26 11:55:00157 // Initializes the main frame for this FrameTree. That is it creates the
158 // initial RenderFrameHost in the root node's RenderFrameHostManager. This
159 // method will call back into the delegates so it should only be called once
160 // they have completed their initialization.
161 // TODO(carlscab): It would be great if initialization could happened in the
162 // constructor so we do not leave objects in a half initialized state.
163 void Init(SiteInstance* main_frame_site_instance,
164 bool renderer_initiated_creation,
Sreeja Kamishetty837a10402021-04-23 12:41:59165 const std::string& main_frame_name);
166
167 Type type() const { return type_; }
Carlos Caballero40b0efd2021-01-26 11:55:00168
danakjc492bf82020-09-09 20:02:44169 FrameTreeNode* root() const { return root_; }
170
Sreeja Kamishetty74bacd522021-03-22 17:04:24171 bool is_prerendering() const { return type_ == FrameTree::Type::kPrerender; }
Sreeja Kamishetty46f762c2021-02-05 07:52:46172
Carlos Caballero03262522021-02-05 14:49:58173 Delegate* delegate() { return delegate_; }
174
danakjc492bf82020-09-09 20:02:44175 // Delegates for RenderFrameHosts, RenderViewHosts, RenderWidgetHosts and
176 // RenderFrameHostManagers. These can be kept centrally on the FrameTree
177 // because they are expected to be the same for all frames on a given
178 // FrameTree.
179 RenderFrameHostDelegate* render_frame_delegate() {
180 return render_frame_delegate_;
181 }
182 RenderViewHostDelegate* render_view_delegate() {
183 return render_view_delegate_;
184 }
185 RenderWidgetHostDelegate* render_widget_delegate() {
186 return render_widget_delegate_;
187 }
188 RenderFrameHostManager::Delegate* manager_delegate() {
189 return manager_delegate_;
190 }
Aaron Colwell78b4bde2021-03-16 16:16:09191
192 using RenderViewHostMapId = util::IdType32<class RenderViewHostMap>;
193 using RenderViewHostMap = std::unordered_map<RenderViewHostMapId,
194 RenderViewHostImpl*,
195 RenderViewHostMapId::Hasher>;
196 const RenderViewHostMap& render_view_hosts() const {
danakjc492bf82020-09-09 20:02:44197 return render_view_host_map_;
198 }
199
200 // Returns the FrameTreeNode with the given |frame_tree_node_id| if it is part
201 // of this FrameTree.
202 FrameTreeNode* FindByID(int frame_tree_node_id);
203
204 // Returns the FrameTreeNode with the given renderer-specific |routing_id|.
205 FrameTreeNode* FindByRoutingID(int process_id, int routing_id);
206
207 // Returns the first frame in this tree with the given |name|, or the main
208 // frame if |name| is empty.
209 // Note that this does NOT support pseudo-names like _self, _top, and _blank,
210 // nor searching other FrameTrees (unlike blink::WebView::findFrameByName).
211 FrameTreeNode* FindByName(const std::string& name);
212
213 // Returns a range to iterate over all FrameTreeNodes in the frame tree in
214 // breadth-first traversal order.
215 NodeRange Nodes();
216
217 // Returns a range to iterate over all FrameTreeNodes in a subtree of the
218 // frame tree, starting from |subtree_root|.
219 NodeRange SubtreeNodes(FrameTreeNode* subtree_root);
220
Kevin McNee5f594382021-05-06 23:18:23221 // Returns a range to iterate over all FrameTreeNodes in a subtree, starting
222 // from, but not including |parent|, as well as any FrameTreeNodes of inner
223 // frame trees.
224 static NodeRange SubtreeAndInnerTreeNodes(RenderFrameHostImpl* parent);
225
danakjc492bf82020-09-09 20:02:44226 // Adds a new child frame to the frame tree. |process_id| is required to
227 // disambiguate |new_routing_id|, and it must match the process of the
228 // |parent| node. Otherwise no child is added and this method returns false.
229 // |interface_provider_receiver| is the receiver end of the InterfaceProvider
230 // interface through which the child RenderFrame can access Mojo services
231 // exposed by the corresponding RenderFrameHost. The caller takes care of
Antonio Sartoridb967c52021-01-20 09:54:30232 // sending the client end of the interface down to the
233 // RenderFrame. |policy_container_bind_params|, if not null, is used for
234 // binding Blink's policy container to the new RenderFrameHost's
235 // PolicyContainerHost. This is only needed if this frame is the result of the
236 // CreateChildFrame mojo call, which also delivers the
237 // |policy_container_bind_params|.
danakjc492bf82020-09-09 20:02:44238 FrameTreeNode* AddFrame(
239 RenderFrameHostImpl* parent,
240 int process_id,
241 int new_routing_id,
danakj0bdfacd2021-01-20 19:27:18242 mojo::PendingAssociatedRemote<mojom::Frame> frame_remote,
danakjc492bf82020-09-09 20:02:44243 mojo::PendingReceiver<blink::mojom::BrowserInterfaceBroker>
244 browser_interface_broker_receiver,
Antonio Sartoridb967c52021-01-20 09:54:30245 blink::mojom::PolicyContainerBindParamsPtr policy_container_bind_params,
danakjc492bf82020-09-09 20:02:44246 blink::mojom::TreeScopeType scope,
247 const std::string& frame_name,
248 const std::string& frame_unique_name,
249 bool is_created_by_script,
Chris Hamilton3ff6ed0e2021-02-19 03:54:04250 const blink::LocalFrameToken& frame_token,
danakjc492bf82020-09-09 20:02:44251 const base::UnguessableToken& devtools_frame_token,
252 const blink::FramePolicy& frame_policy,
253 const blink::mojom::FrameOwnerProperties& frame_owner_properties,
254 bool was_discarded,
255 blink::mojom::FrameOwnerElementType owner_type);
256
257 // Removes a frame from the frame tree. |child|, its children, and objects
258 // owned by their RenderFrameHostManagers are immediately deleted. The root
259 // node cannot be removed this way.
260 void RemoveFrame(FrameTreeNode* child);
261
262 // This method walks the entire frame tree and creates a RenderFrameProxyHost
263 // for the given |site_instance| in each node except the |source| one --
264 // the source will have a RenderFrameHost. |source| may be null if there is
265 // no node navigating in this frame tree (such as when this is called
266 // for an opener's frame tree), in which case no nodes are skipped for
267 // RenderFrameProxyHost creation.
268 void CreateProxiesForSiteInstance(FrameTreeNode* source,
269 SiteInstance* site_instance);
270
271 // Convenience accessor for the main frame's RenderFrameHostImpl.
272 RenderFrameHostImpl* GetMainFrame() const;
273
274 // Returns the focused frame.
275 FrameTreeNode* GetFocusedFrame();
276
277 // Sets the focused frame to |node|. |source| identifies the SiteInstance
278 // that initiated this focus change. If this FrameTree has SiteInstances
279 // other than |source|, those SiteInstances will be notified about the new
280 // focused frame. Note that |source| may differ from |node|'s current
281 // SiteInstance (e.g., this happens for cross-process window.focus() calls).
282 void SetFocusedFrame(FrameTreeNode* node, SiteInstance* source);
283
danakjc492bf82020-09-09 20:02:44284 // Creates a RenderViewHostImpl for a given |site_instance| in the tree.
285 //
286 // The RenderFrameHostImpls and the RenderFrameProxyHosts will share ownership
287 // of this object.
288 scoped_refptr<RenderViewHostImpl> CreateRenderViewHost(
289 SiteInstance* site_instance,
290 int32_t main_frame_routing_id,
danakj08eb51d2020-12-30 20:15:23291 bool swapped_out,
292 bool renderer_initiated_creation);
danakjc492bf82020-09-09 20:02:44293
294 // Returns the existing RenderViewHost for a new RenderFrameHost.
295 // There should always be such a RenderViewHost, because the main frame
296 // RenderFrameHost for each SiteInstance should be created before subframes.
297 scoped_refptr<RenderViewHostImpl> GetRenderViewHost(
298 SiteInstance* site_instance);
299
Aaron Colwell78b4bde2021-03-16 16:16:09300 // Returns the ID used for the RenderViewHost associated with |site_instance|.
301 // Note: Callers should not assume that there is a 1:1 mapping between
302 // SiteInstances and IDs returned by this function, since several
303 // SiteInstances may share a RenderViewHost.
304 RenderViewHostMapId GetRenderViewHostMapId(SiteInstance* site_instance) const;
305
danakjc492bf82020-09-09 20:02:44306 // Registers a RenderViewHost so that it can be reused by other frames
Aaron Colwell78b4bde2021-03-16 16:16:09307 // whose SiteInstance maps to the same RenderViewHostMapId.
danakjc492bf82020-09-09 20:02:44308 //
309 // This method does not take ownership of|rvh|.
310 //
311 // NOTE: This method CHECK fails if a RenderViewHost is already registered for
312 // |rvh|'s SiteInstance.
313 //
314 // ALSO NOTE: After calling RegisterRenderViewHost, UnregisterRenderViewHost
315 // *must* be called for |rvh| when it is destroyed or put into the
316 // BackForwardCache, to prevent FrameTree::CreateRenderViewHost from trying to
317 // reuse it.
Aaron Colwell78b4bde2021-03-16 16:16:09318 void RegisterRenderViewHost(RenderViewHostMapId id, RenderViewHostImpl* rvh);
danakjc492bf82020-09-09 20:02:44319
320 // Unregisters the RenderViewHostImpl that's available for reuse for a
Aaron Colwell78b4bde2021-03-16 16:16:09321 // particular RenderViewHostMapId. NOTE: This method CHECK fails if it is
322 // called for a |render_view_host| that is not currently set for reuse.
323 void UnregisterRenderViewHost(RenderViewHostMapId id,
Aaron Colwellc4bd7d62021-01-29 04:23:13324 RenderViewHostImpl* render_view_host);
danakjc492bf82020-09-09 20:02:44325
326 // This is called when the frame is about to be removed and started to run
327 // unload handlers.
328 void FrameUnloading(FrameTreeNode* frame);
329
330 // This is only meant to be called by FrameTreeNode. Triggers calling
331 // the listener installed by SetFrameRemoveListener.
332 void FrameRemoved(FrameTreeNode* frame);
333
Carlos Caballero03262522021-02-05 14:49:58334 void DidStartLoadingNode(FrameTreeNode& node,
335 bool to_different_document,
336 bool was_previously_loading);
337 void DidStopLoadingNode(FrameTreeNode& node);
338 void DidChangeLoadProgressForNode(FrameTreeNode& node, double load_progress);
339 void DidCancelLoading();
danakjc492bf82020-09-09 20:02:44340
341 // Returns this FrameTree's total load progress.
342 double load_progress() const { return load_progress_; }
343
344 // Resets the load progress on all nodes in this FrameTree.
345 void ResetLoadProgress();
346
347 // Returns true if at least one of the nodes in this FrameTree is loading.
348 bool IsLoading() const;
349
350 // Set page-level focus in all SiteInstances involved in rendering
351 // this FrameTree, not including the current main frame's
352 // SiteInstance. The focus update will be sent via the main frame's proxies
353 // in those SiteInstances.
354 void ReplicatePageFocus(bool is_focused);
355
356 // Updates page-level focus for this FrameTree in the subframe renderer
357 // identified by |instance|.
358 void SetPageFocus(SiteInstance* instance, bool is_focused);
359
360 // Walks the current frame tree and registers any origins matching |origin|,
361 // either the last committed origin of a RenderFrameHost or the origin
362 // associated with a NavigationRequest that has been assigned to a
363 // SiteInstance, as not-opted-in for origin isolation.
364 void RegisterExistingOriginToPreventOptInIsolation(
365 const url::Origin& previously_visited_origin,
366 NavigationRequest* navigation_request_to_exclude);
367
Carlos Caballero40b0efd2021-01-26 11:55:00368 NavigationControllerImpl& controller() { return navigator_.controller(); }
danakjc492bf82020-09-09 20:02:44369 Navigator& navigator() { return navigator_; }
370
Carlos Caballeroede6f8c2021-01-28 11:01:50371 // Another page accessed the initial empty main document, which means it
372 // is no longer safe to display a pending URL without risking a URL spoof.
373 void DidAccessInitialMainDocument();
374
375 bool has_accessed_initial_main_document() const {
376 return has_accessed_initial_main_document_;
377 }
378
379 void ResetHasAccessedInitialMainDocument() {
380 has_accessed_initial_main_document_ = false;
381 }
382
Carlos Caballero6ff6ace2021-02-05 16:53:00383 bool IsHidden() const { return delegate_->IsHidden(); }
384
Carlos Caballero03262522021-02-05 14:49:58385 // Stops all ongoing navigations in each of the nodes of this FrameTree.
386 void StopLoading();
387
Carlos Caballero101ac26b2021-03-24 11:54:05388 // Prepares this frame tree for destruction, cleaning up the internal state
389 // and firing the appropriate events like FrameDeleted.
390 // Must be called before FrameTree is destroyed.
391 void Shutdown();
392
shivanigithub93878d02021-06-15 11:37:53393 // Returns true if this is a fenced frame tree.
394 // TODO(crbug.com/1123606): Integrate this with the MPArch based fenced frame
395 // code once that lands.
396 bool IsFencedFrameTree() const { return is_fenced_frame_tree_; }
397 void SetFencedFrameTreeForTesting() { is_fenced_frame_tree_ = true; }
398
danakjc492bf82020-09-09 20:02:44399 private:
400 friend class FrameTreeTest;
401 FRIEND_TEST_ALL_PREFIXES(RenderFrameHostImplBrowserTest, RemoveFocusedFrame);
402
403 // Returns a range to iterate over all FrameTreeNodes in the frame tree in
404 // breadth-first traversal order, skipping the subtree rooted at
405 // |node|, but including |node| itself.
406 NodeRange NodesExceptSubtree(FrameTreeNode* node);
407
Carlos Caballero03262522021-02-05 14:49:58408 Delegate* const delegate_;
409
danakjc492bf82020-09-09 20:02:44410 // These delegates are installed into all the RenderViewHosts and
411 // RenderFrameHosts that we create.
412 RenderFrameHostDelegate* render_frame_delegate_;
413 RenderViewHostDelegate* render_view_delegate_;
414 RenderWidgetHostDelegate* render_widget_delegate_;
415 RenderFrameHostManager::Delegate* manager_delegate_;
416
417 // The Navigator object responsible for managing navigations on this frame
Carlos Caballero40b0efd2021-01-26 11:55:00418 // tree. Each FrameTreeNode will default to using it for navigation tasks in
419 // the frame.
danakjc492bf82020-09-09 20:02:44420 Navigator navigator_;
421
Aaron Colwell78b4bde2021-03-16 16:16:09422 // Map of RenderViewHostMapId to RenderViewHost. This allows us to look up the
danakjc492bf82020-09-09 20:02:44423 // RenderViewHost for a given SiteInstance when creating RenderFrameHosts.
424 // Each RenderViewHost maintains a refcount and is deleted when there are no
425 // more RenderFrameHosts or RenderFrameProxyHosts using it.
Aaron Colwell78b4bde2021-03-16 16:16:09426 RenderViewHostMap render_view_host_map_;
danakjc492bf82020-09-09 20:02:44427
428 // This is an owned ptr to the root FrameTreeNode, which never changes over
429 // the lifetime of the FrameTree. It is not a scoped_ptr because we need the
430 // pointer to remain valid even while the FrameTreeNode is being destroyed,
431 // since it's common for a node to test whether it's the root node.
432 FrameTreeNode* root_;
433
434 int focused_frame_tree_node_id_;
435
danakjc492bf82020-09-09 20:02:44436 // Overall load progress.
437 double load_progress_;
438
Carlos Caballeroede6f8c2021-01-28 11:01:50439 // Whether the initial empty page has been accessed by another page, making it
440 // unsafe to show the pending URL. Usually false unless another window tries
441 // to modify the blank page. Always false after the first commit.
442 bool has_accessed_initial_main_document_ = false;
443
Sreeja Kamishetty837a10402021-04-23 12:41:59444 // Indicates type of frame tree.
445 const Type type_;
Sreeja Kamishetty74bacd522021-03-22 17:04:24446
shivanigithub93878d02021-06-15 11:37:53447 // TODO(crbug.com/1123606): Integrate this with the MPArch based fenced frame
448 // code once that lands. Possibly this will then be part of |type_|.
449 bool is_fenced_frame_tree_ = false;
450
Carlos Caballero101ac26b2021-03-24 11:54:05451#if DCHECK_IS_ON()
452 // Whether Shutdown() was called.
453 bool was_shut_down_ = false;
454#endif
455
danakjc492bf82020-09-09 20:02:44456 DISALLOW_COPY_AND_ASSIGN(FrameTree);
457};
458
459} // namespace content
460
461#endif // CONTENT_BROWSER_RENDERER_HOST_FRAME_TREE_H_