blob: da1aa9c1ec75e287088bec8e5e19f9c48bbe6f00 [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
159 // sending the client end of the interface down to the RenderFrame.
160 FrameTreeNode* AddFrame(
161 RenderFrameHostImpl* parent,
162 int process_id,
163 int new_routing_id,
danakjc492bf82020-09-09 20:02:44164 mojo::PendingReceiver<blink::mojom::BrowserInterfaceBroker>
165 browser_interface_broker_receiver,
Antonio Sartoria1fd1432020-11-25 09:10:20166 mojo::PendingAssociatedReceiver<blink::mojom::PolicyContainerHost>
167 policy_container_host_receiver,
danakjc492bf82020-09-09 20:02:44168 blink::mojom::TreeScopeType scope,
169 const std::string& frame_name,
170 const std::string& frame_unique_name,
171 bool is_created_by_script,
172 const base::UnguessableToken& frame_token,
173 const base::UnguessableToken& devtools_frame_token,
174 const blink::FramePolicy& frame_policy,
175 const blink::mojom::FrameOwnerProperties& frame_owner_properties,
176 bool was_discarded,
177 blink::mojom::FrameOwnerElementType owner_type);
178
179 // Removes a frame from the frame tree. |child|, its children, and objects
180 // owned by their RenderFrameHostManagers are immediately deleted. The root
181 // node cannot be removed this way.
182 void RemoveFrame(FrameTreeNode* child);
183
184 // This method walks the entire frame tree and creates a RenderFrameProxyHost
185 // for the given |site_instance| in each node except the |source| one --
186 // the source will have a RenderFrameHost. |source| may be null if there is
187 // no node navigating in this frame tree (such as when this is called
188 // for an opener's frame tree), in which case no nodes are skipped for
189 // RenderFrameProxyHost creation.
190 void CreateProxiesForSiteInstance(FrameTreeNode* source,
191 SiteInstance* site_instance);
192
193 // Convenience accessor for the main frame's RenderFrameHostImpl.
194 RenderFrameHostImpl* GetMainFrame() const;
195
196 // Returns the focused frame.
197 FrameTreeNode* GetFocusedFrame();
198
199 // Sets the focused frame to |node|. |source| identifies the SiteInstance
200 // that initiated this focus change. If this FrameTree has SiteInstances
201 // other than |source|, those SiteInstances will be notified about the new
202 // focused frame. Note that |source| may differ from |node|'s current
203 // SiteInstance (e.g., this happens for cross-process window.focus() calls).
204 void SetFocusedFrame(FrameTreeNode* node, SiteInstance* source);
205
206 // Allows a client to listen for frame removal. The listener should expect
207 // to receive the RenderViewHostImpl containing the frame and the renderer-
208 // specific frame routing ID of the removed frame.
209 void SetFrameRemoveListener(
210 base::RepeatingCallback<void(RenderFrameHost*)> on_frame_removed);
211
212 // Creates a RenderViewHostImpl for a given |site_instance| in the tree.
213 //
214 // The RenderFrameHostImpls and the RenderFrameProxyHosts will share ownership
215 // of this object.
216 scoped_refptr<RenderViewHostImpl> CreateRenderViewHost(
217 SiteInstance* site_instance,
218 int32_t main_frame_routing_id,
danakj08eb51d2020-12-30 20:15:23219 bool swapped_out,
220 bool renderer_initiated_creation);
danakjc492bf82020-09-09 20:02:44221
222 // Returns the existing RenderViewHost for a new RenderFrameHost.
223 // There should always be such a RenderViewHost, because the main frame
224 // RenderFrameHost for each SiteInstance should be created before subframes.
225 scoped_refptr<RenderViewHostImpl> GetRenderViewHost(
226 SiteInstance* site_instance);
227
228 // Registers a RenderViewHost so that it can be reused by other frames
229 // belonging to the same SiteInstance.
230 //
231 // This method does not take ownership of|rvh|.
232 //
233 // NOTE: This method CHECK fails if a RenderViewHost is already registered for
234 // |rvh|'s SiteInstance.
235 //
236 // ALSO NOTE: After calling RegisterRenderViewHost, UnregisterRenderViewHost
237 // *must* be called for |rvh| when it is destroyed or put into the
238 // BackForwardCache, to prevent FrameTree::CreateRenderViewHost from trying to
239 // reuse it.
240 void RegisterRenderViewHost(RenderViewHostImpl* rvh);
241
242 // Unregisters the RenderViewHostImpl that's available for reuse for a
243 // particular SiteInstance. NOTE: This method CHECK fails if it is called for
244 // a |render_view_host| that is not currently set for reuse.
245 void UnregisterRenderViewHost(RenderViewHostImpl* render_view_host);
246
247 // This is called when the frame is about to be removed and started to run
248 // unload handlers.
249 void FrameUnloading(FrameTreeNode* frame);
250
251 // This is only meant to be called by FrameTreeNode. Triggers calling
252 // the listener installed by SetFrameRemoveListener.
253 void FrameRemoved(FrameTreeNode* frame);
254
255 // Updates the overall load progress and notifies the WebContents.
256 // Set based on the main frame's progress only.
257 void UpdateLoadProgress(double progress);
258
259 // Returns this FrameTree's total load progress.
260 double load_progress() const { return load_progress_; }
261
262 // Resets the load progress on all nodes in this FrameTree.
263 void ResetLoadProgress();
264
265 // Returns true if at least one of the nodes in this FrameTree is loading.
266 bool IsLoading() const;
267
268 // Set page-level focus in all SiteInstances involved in rendering
269 // this FrameTree, not including the current main frame's
270 // SiteInstance. The focus update will be sent via the main frame's proxies
271 // in those SiteInstances.
272 void ReplicatePageFocus(bool is_focused);
273
274 // Updates page-level focus for this FrameTree in the subframe renderer
275 // identified by |instance|.
276 void SetPageFocus(SiteInstance* instance, bool is_focused);
277
278 // Walks the current frame tree and registers any origins matching |origin|,
279 // either the last committed origin of a RenderFrameHost or the origin
280 // associated with a NavigationRequest that has been assigned to a
281 // SiteInstance, as not-opted-in for origin isolation.
282 void RegisterExistingOriginToPreventOptInIsolation(
283 const url::Origin& previously_visited_origin,
284 NavigationRequest* navigation_request_to_exclude);
285
286 NavigationControllerImpl* controller() { return navigator_.controller(); }
287 Navigator& navigator() { return navigator_; }
288
289 private:
290 friend class FrameTreeTest;
291 FRIEND_TEST_ALL_PREFIXES(RenderFrameHostImplBrowserTest, RemoveFocusedFrame);
292
293 // Returns a range to iterate over all FrameTreeNodes in the frame tree in
294 // breadth-first traversal order, skipping the subtree rooted at
295 // |node|, but including |node| itself.
296 NodeRange NodesExceptSubtree(FrameTreeNode* node);
297
298 // These delegates are installed into all the RenderViewHosts and
299 // RenderFrameHosts that we create.
300 RenderFrameHostDelegate* render_frame_delegate_;
301 RenderViewHostDelegate* render_view_delegate_;
302 RenderWidgetHostDelegate* render_widget_delegate_;
303 RenderFrameHostManager::Delegate* manager_delegate_;
304
305 // The Navigator object responsible for managing navigations on this frame
306 // tree.
307 Navigator navigator_;
308
309 // Map of SiteInstance ID to RenderViewHost. This allows us to look up the
310 // RenderViewHost for a given SiteInstance when creating RenderFrameHosts.
311 // Each RenderViewHost maintains a refcount and is deleted when there are no
312 // more RenderFrameHosts or RenderFrameProxyHosts using it.
313 std::unordered_map<int /* SiteInstance ID */, RenderViewHostImpl*>
314 render_view_host_map_;
315
316 // This is an owned ptr to the root FrameTreeNode, which never changes over
317 // the lifetime of the FrameTree. It is not a scoped_ptr because we need the
318 // pointer to remain valid even while the FrameTreeNode is being destroyed,
319 // since it's common for a node to test whether it's the root node.
320 FrameTreeNode* root_;
321
322 int focused_frame_tree_node_id_;
323
324 base::RepeatingCallback<void(RenderFrameHost*)> on_frame_removed_;
325
326 // Overall load progress.
327 double load_progress_;
328
329 DISALLOW_COPY_AND_ASSIGN(FrameTree);
330};
331
332} // namespace content
333
334#endif // CONTENT_BROWSER_RENDERER_HOST_FRAME_TREE_H_