blob: 60f3ccef64f5776b3a2193031d40a9fd79cee953 [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"
17#include "base/gtest_prod_util.h"
18#include "base/macros.h"
19#include "content/browser/renderer_host/navigator.h"
20#include "content/browser/renderer_host/navigator_delegate.h"
21#include "content/browser/renderer_host/render_frame_host_manager.h"
22#include "content/common/content_export.h"
23#include "mojo/public/cpp/bindings/pending_receiver.h"
24#include "services/service_manager/public/mojom/interface_provider.mojom.h"
25#include "third_party/blink/public/mojom/frame/frame_owner_element_type.mojom.h"
26#include "third_party/blink/public/mojom/frame/frame_owner_properties.mojom-forward.h"
27
28namespace blink {
29struct FramePolicy;
30} // namespace blink
31
32namespace content {
33
34class NavigationControllerImpl;
35class RenderFrameHostDelegate;
36class RenderViewHostDelegate;
37class RenderViewHostImpl;
38class RenderFrameHostManager;
39class RenderWidgetHostDelegate;
40
41// Represents the frame tree for a page. With the exception of the main frame,
42// all FrameTreeNodes will be created/deleted in response to frame attach and
43// detach events in the DOM.
44//
45// The main frame's FrameTreeNode is special in that it is reused. This allows
46// it to serve as an anchor for state that needs to persist across top-level
47// page navigations.
48//
49// TODO(ajwong): Move NavigationController ownership to the main frame
50// FrameTreeNode. Possibly expose access to it from here.
51//
52// This object is only used on the UI thread.
53class CONTENT_EXPORT FrameTree {
54 public:
55 class NodeRange;
56
57 class CONTENT_EXPORT NodeIterator
58 : public std::iterator<std::forward_iterator_tag, FrameTreeNode> {
59 public:
60 NodeIterator(const NodeIterator& other);
61 ~NodeIterator();
62
63 NodeIterator& operator++();
64
65 bool operator==(const NodeIterator& rhs) const;
66 bool operator!=(const NodeIterator& rhs) const { return !(*this == rhs); }
67
68 FrameTreeNode* operator*() { return current_node_; }
69
70 private:
71 friend class NodeRange;
72
73 NodeIterator(FrameTreeNode* starting_node,
74 FrameTreeNode* root_of_subtree_to_skip);
75
76 FrameTreeNode* current_node_;
77 FrameTreeNode* const root_of_subtree_to_skip_;
78 base::queue<FrameTreeNode*> queue_;
79 };
80
81 class CONTENT_EXPORT NodeRange {
82 public:
83 NodeIterator begin();
84 NodeIterator end();
85
86 private:
87 friend class FrameTree;
88
89 NodeRange(FrameTreeNode* root, FrameTreeNode* root_of_subtree_to_skip);
90
91 FrameTreeNode* const root_;
92 FrameTreeNode* const root_of_subtree_to_skip_;
93 };
94
95 // Each FrameTreeNode will default to using the given |navigator| for
96 // navigation tasks in the frame.
97 // A set of delegates are remembered here so that we can create
98 // RenderFrameHostManagers.
99 // TODO(creis): This set of delegates will change as we move things to
100 // Navigator.
101 FrameTree(NavigationControllerImpl* navigation_controller,
102 NavigatorDelegate* navigator_delegate,
103 RenderFrameHostDelegate* render_frame_delegate,
104 RenderViewHostDelegate* render_view_delegate,
105 RenderWidgetHostDelegate* render_widget_delegate,
106 RenderFrameHostManager::Delegate* manager_delegate);
107 ~FrameTree();
108
109 FrameTreeNode* root() const { return root_; }
110
111 // Delegates for RenderFrameHosts, RenderViewHosts, RenderWidgetHosts and
112 // RenderFrameHostManagers. These can be kept centrally on the FrameTree
113 // because they are expected to be the same for all frames on a given
114 // FrameTree.
115 RenderFrameHostDelegate* render_frame_delegate() {
116 return render_frame_delegate_;
117 }
118 RenderViewHostDelegate* render_view_delegate() {
119 return render_view_delegate_;
120 }
121 RenderWidgetHostDelegate* render_widget_delegate() {
122 return render_widget_delegate_;
123 }
124 RenderFrameHostManager::Delegate* manager_delegate() {
125 return manager_delegate_;
126 }
127 const std::unordered_map<int /* SiteInstance ID */, RenderViewHostImpl*>&
128 render_view_hosts() const {
129 return render_view_host_map_;
130 }
131
132 // Returns the FrameTreeNode with the given |frame_tree_node_id| if it is part
133 // of this FrameTree.
134 FrameTreeNode* FindByID(int frame_tree_node_id);
135
136 // Returns the FrameTreeNode with the given renderer-specific |routing_id|.
137 FrameTreeNode* FindByRoutingID(int process_id, int routing_id);
138
139 // Returns the first frame in this tree with the given |name|, or the main
140 // frame if |name| is empty.
141 // Note that this does NOT support pseudo-names like _self, _top, and _blank,
142 // nor searching other FrameTrees (unlike blink::WebView::findFrameByName).
143 FrameTreeNode* FindByName(const std::string& name);
144
145 // Returns a range to iterate over all FrameTreeNodes in the frame tree in
146 // breadth-first traversal order.
147 NodeRange Nodes();
148
149 // Returns a range to iterate over all FrameTreeNodes in a subtree of the
150 // frame tree, starting from |subtree_root|.
151 NodeRange SubtreeNodes(FrameTreeNode* subtree_root);
152
153 // Adds a new child frame to the frame tree. |process_id| is required to
154 // disambiguate |new_routing_id|, and it must match the process of the
155 // |parent| node. Otherwise no child is added and this method returns false.
156 // |interface_provider_receiver| is the receiver end of the InterfaceProvider
157 // interface through which the child RenderFrame can access Mojo services
158 // exposed by the corresponding RenderFrameHost. The caller takes care of
Antonio Sartoridb967c52021-01-20 09:54:30159 // sending the client end of the interface down to the
160 // RenderFrame. |policy_container_bind_params|, if not null, is used for
161 // binding Blink's policy container to the new RenderFrameHost's
162 // PolicyContainerHost. This is only needed if this frame is the result of the
163 // CreateChildFrame mojo call, which also delivers the
164 // |policy_container_bind_params|.
danakjc492bf82020-09-09 20:02:44165 FrameTreeNode* AddFrame(
166 RenderFrameHostImpl* parent,
167 int process_id,
168 int new_routing_id,
danakj0bdfacd2021-01-20 19:27:18169 mojo::PendingAssociatedRemote<mojom::Frame> frame_remote,
danakjc492bf82020-09-09 20:02:44170 mojo::PendingReceiver<blink::mojom::BrowserInterfaceBroker>
171 browser_interface_broker_receiver,
Antonio Sartoridb967c52021-01-20 09:54:30172 blink::mojom::PolicyContainerBindParamsPtr policy_container_bind_params,
danakjc492bf82020-09-09 20:02:44173 blink::mojom::TreeScopeType scope,
174 const std::string& frame_name,
175 const std::string& frame_unique_name,
176 bool is_created_by_script,
177 const base::UnguessableToken& frame_token,
178 const base::UnguessableToken& devtools_frame_token,
179 const blink::FramePolicy& frame_policy,
180 const blink::mojom::FrameOwnerProperties& frame_owner_properties,
181 bool was_discarded,
182 blink::mojom::FrameOwnerElementType owner_type);
183
184 // Removes a frame from the frame tree. |child|, its children, and objects
185 // owned by their RenderFrameHostManagers are immediately deleted. The root
186 // node cannot be removed this way.
187 void RemoveFrame(FrameTreeNode* child);
188
189 // This method walks the entire frame tree and creates a RenderFrameProxyHost
190 // for the given |site_instance| in each node except the |source| one --
191 // the source will have a RenderFrameHost. |source| may be null if there is
192 // no node navigating in this frame tree (such as when this is called
193 // for an opener's frame tree), in which case no nodes are skipped for
194 // RenderFrameProxyHost creation.
195 void CreateProxiesForSiteInstance(FrameTreeNode* source,
196 SiteInstance* site_instance);
197
198 // Convenience accessor for the main frame's RenderFrameHostImpl.
199 RenderFrameHostImpl* GetMainFrame() const;
200
201 // Returns the focused frame.
202 FrameTreeNode* GetFocusedFrame();
203
204 // Sets the focused frame to |node|. |source| identifies the SiteInstance
205 // that initiated this focus change. If this FrameTree has SiteInstances
206 // other than |source|, those SiteInstances will be notified about the new
207 // focused frame. Note that |source| may differ from |node|'s current
208 // SiteInstance (e.g., this happens for cross-process window.focus() calls).
209 void SetFocusedFrame(FrameTreeNode* node, SiteInstance* source);
210
211 // Allows a client to listen for frame removal. The listener should expect
212 // to receive the RenderViewHostImpl containing the frame and the renderer-
213 // specific frame routing ID of the removed frame.
214 void SetFrameRemoveListener(
215 base::RepeatingCallback<void(RenderFrameHost*)> on_frame_removed);
216
217 // Creates a RenderViewHostImpl for a given |site_instance| in the tree.
218 //
219 // The RenderFrameHostImpls and the RenderFrameProxyHosts will share ownership
220 // of this object.
221 scoped_refptr<RenderViewHostImpl> CreateRenderViewHost(
222 SiteInstance* site_instance,
223 int32_t main_frame_routing_id,
danakj08eb51d2020-12-30 20:15:23224 bool swapped_out,
225 bool renderer_initiated_creation);
danakjc492bf82020-09-09 20:02:44226
227 // Returns the existing RenderViewHost for a new RenderFrameHost.
228 // There should always be such a RenderViewHost, because the main frame
229 // RenderFrameHost for each SiteInstance should be created before subframes.
230 scoped_refptr<RenderViewHostImpl> GetRenderViewHost(
231 SiteInstance* site_instance);
232
233 // Registers a RenderViewHost so that it can be reused by other frames
234 // belonging to the same SiteInstance.
235 //
236 // This method does not take ownership of|rvh|.
237 //
238 // NOTE: This method CHECK fails if a RenderViewHost is already registered for
239 // |rvh|'s SiteInstance.
240 //
241 // ALSO NOTE: After calling RegisterRenderViewHost, UnregisterRenderViewHost
242 // *must* be called for |rvh| when it is destroyed or put into the
243 // BackForwardCache, to prevent FrameTree::CreateRenderViewHost from trying to
244 // reuse it.
245 void RegisterRenderViewHost(RenderViewHostImpl* rvh);
246
247 // Unregisters the RenderViewHostImpl that's available for reuse for a
248 // particular SiteInstance. NOTE: This method CHECK fails if it is called for
249 // a |render_view_host| that is not currently set for reuse.
250 void UnregisterRenderViewHost(RenderViewHostImpl* render_view_host);
251
252 // This is called when the frame is about to be removed and started to run
253 // unload handlers.
254 void FrameUnloading(FrameTreeNode* frame);
255
256 // This is only meant to be called by FrameTreeNode. Triggers calling
257 // the listener installed by SetFrameRemoveListener.
258 void FrameRemoved(FrameTreeNode* frame);
259
260 // Updates the overall load progress and notifies the WebContents.
261 // Set based on the main frame's progress only.
262 void UpdateLoadProgress(double progress);
263
264 // Returns this FrameTree's total load progress.
265 double load_progress() const { return load_progress_; }
266
267 // Resets the load progress on all nodes in this FrameTree.
268 void ResetLoadProgress();
269
270 // Returns true if at least one of the nodes in this FrameTree is loading.
271 bool IsLoading() const;
272
273 // Set page-level focus in all SiteInstances involved in rendering
274 // this FrameTree, not including the current main frame's
275 // SiteInstance. The focus update will be sent via the main frame's proxies
276 // in those SiteInstances.
277 void ReplicatePageFocus(bool is_focused);
278
279 // Updates page-level focus for this FrameTree in the subframe renderer
280 // identified by |instance|.
281 void SetPageFocus(SiteInstance* instance, bool is_focused);
282
283 // Walks the current frame tree and registers any origins matching |origin|,
284 // either the last committed origin of a RenderFrameHost or the origin
285 // associated with a NavigationRequest that has been assigned to a
286 // SiteInstance, as not-opted-in for origin isolation.
287 void RegisterExistingOriginToPreventOptInIsolation(
288 const url::Origin& previously_visited_origin,
289 NavigationRequest* navigation_request_to_exclude);
290
291 NavigationControllerImpl* controller() { return navigator_.controller(); }
292 Navigator& navigator() { return navigator_; }
293
294 private:
295 friend class FrameTreeTest;
296 FRIEND_TEST_ALL_PREFIXES(RenderFrameHostImplBrowserTest, RemoveFocusedFrame);
297
298 // Returns a range to iterate over all FrameTreeNodes in the frame tree in
299 // breadth-first traversal order, skipping the subtree rooted at
300 // |node|, but including |node| itself.
301 NodeRange NodesExceptSubtree(FrameTreeNode* node);
302
303 // These delegates are installed into all the RenderViewHosts and
304 // RenderFrameHosts that we create.
305 RenderFrameHostDelegate* render_frame_delegate_;
306 RenderViewHostDelegate* render_view_delegate_;
307 RenderWidgetHostDelegate* render_widget_delegate_;
308 RenderFrameHostManager::Delegate* manager_delegate_;
309
310 // The Navigator object responsible for managing navigations on this frame
311 // tree.
312 Navigator navigator_;
313
314 // Map of SiteInstance ID to RenderViewHost. This allows us to look up the
315 // RenderViewHost for a given SiteInstance when creating RenderFrameHosts.
316 // Each RenderViewHost maintains a refcount and is deleted when there are no
317 // more RenderFrameHosts or RenderFrameProxyHosts using it.
318 std::unordered_map<int /* SiteInstance ID */, RenderViewHostImpl*>
319 render_view_host_map_;
320
321 // This is an owned ptr to the root FrameTreeNode, which never changes over
322 // the lifetime of the FrameTree. It is not a scoped_ptr because we need the
323 // pointer to remain valid even while the FrameTreeNode is being destroyed,
324 // since it's common for a node to test whether it's the root node.
325 FrameTreeNode* root_;
326
327 int focused_frame_tree_node_id_;
328
329 base::RepeatingCallback<void(RenderFrameHost*)> on_frame_removed_;
330
331 // Overall load progress.
332 double load_progress_;
333
334 DISALLOW_COPY_AND_ASSIGN(FrameTree);
335};
336
337} // namespace content
338
339#endif // CONTENT_BROWSER_RENDERER_HOST_FRAME_TREE_H_