1 // 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 
28 namespace blink {
29 struct FramePolicy;
30 }  // namespace blink
31 
32 namespace content {
33 
34 class NavigationControllerImpl;
35 class RenderFrameHostDelegate;
36 class RenderViewHostDelegate;
37 class RenderViewHostImpl;
38 class RenderFrameHostManager;
39 class 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.
53 class 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 
root()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.
render_frame_delegate()115   RenderFrameHostDelegate* render_frame_delegate() {
116     return render_frame_delegate_;
117   }
render_view_delegate()118   RenderViewHostDelegate* render_view_delegate() {
119     return render_view_delegate_;
120   }
render_widget_delegate()121   RenderWidgetHostDelegate* render_widget_delegate() {
122     return render_widget_delegate_;
123   }
manager_delegate()124   RenderFrameHostManager::Delegate* manager_delegate() {
125     return manager_delegate_;
126   }
127   const std::unordered_map<int /* SiteInstance ID */, RenderViewHostImpl*>&
render_view_hosts()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,
164       mojo::PendingReceiver<service_manager::mojom::InterfaceProvider>
165           interface_provider_receiver,
166       mojo::PendingReceiver<blink::mojom::BrowserInterfaceBroker>
167           browser_interface_broker_receiver,
168       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,
219       bool swapped_out);
220 
221   // Returns the existing RenderViewHost for a new RenderFrameHost.
222   // There should always be such a RenderViewHost, because the main frame
223   // RenderFrameHost for each SiteInstance should be created before subframes.
224   scoped_refptr<RenderViewHostImpl> GetRenderViewHost(
225       SiteInstance* site_instance);
226 
227   // Registers a RenderViewHost so that it can be reused by other frames
228   // belonging to the same SiteInstance.
229   //
230   // This method does not take ownership of|rvh|.
231   //
232   // NOTE: This method CHECK fails if a RenderViewHost is already registered for
233   // |rvh|'s SiteInstance.
234   //
235   // ALSO NOTE: After calling RegisterRenderViewHost, UnregisterRenderViewHost
236   // *must* be called for |rvh| when it is destroyed or put into the
237   // BackForwardCache, to prevent FrameTree::CreateRenderViewHost from trying to
238   // reuse it.
239   void RegisterRenderViewHost(RenderViewHostImpl* rvh);
240 
241   // Unregisters the RenderViewHostImpl that's available for reuse for a
242   // particular SiteInstance. NOTE: This method CHECK fails if it is called for
243   // a |render_view_host| that is not currently set for reuse.
244   void UnregisterRenderViewHost(RenderViewHostImpl* render_view_host);
245 
246   // This is called when the frame is about to be removed and started to run
247   // unload handlers.
248   void FrameUnloading(FrameTreeNode* frame);
249 
250   // This is only meant to be called by FrameTreeNode. Triggers calling
251   // the listener installed by SetFrameRemoveListener.
252   void FrameRemoved(FrameTreeNode* frame);
253 
254   // Updates the overall load progress and notifies the WebContents.
255   // Set based on the main frame's progress only.
256   void UpdateLoadProgress(double progress);
257 
258   // Returns this FrameTree's total load progress.
load_progress()259   double load_progress() const { return load_progress_; }
260 
261   // Resets the load progress on all nodes in this FrameTree.
262   void ResetLoadProgress();
263 
264   // Returns true if at least one of the nodes in this FrameTree is loading.
265   bool IsLoading() const;
266 
267   // Set page-level focus in all SiteInstances involved in rendering
268   // this FrameTree, not including the current main frame's
269   // SiteInstance. The focus update will be sent via the main frame's proxies
270   // in those SiteInstances.
271   void ReplicatePageFocus(bool is_focused);
272 
273   // Updates page-level focus for this FrameTree in the subframe renderer
274   // identified by |instance|.
275   void SetPageFocus(SiteInstance* instance, bool is_focused);
276 
277   // Walks the current frame tree and registers any origins matching |origin|,
278   // either the last committed origin of a RenderFrameHost or the origin
279   // associated with a NavigationRequest that has been assigned to a
280   // SiteInstance, as not-opted-in for origin isolation.
281   void RegisterExistingOriginToPreventOptInIsolation(
282       const url::Origin& previously_visited_origin,
283       NavigationRequest* navigation_request_to_exclude);
284 
controller()285   NavigationControllerImpl* controller() { return navigator_.controller(); }
navigator()286   Navigator& navigator() { return navigator_; }
287 
288  private:
289   friend class FrameTreeTest;
290   FRIEND_TEST_ALL_PREFIXES(RenderFrameHostImplBrowserTest, RemoveFocusedFrame);
291 
292   // Returns a range to iterate over all FrameTreeNodes in the frame tree in
293   // breadth-first traversal order, skipping the subtree rooted at
294   // |node|, but including |node| itself.
295   NodeRange NodesExceptSubtree(FrameTreeNode* node);
296 
297   // These delegates are installed into all the RenderViewHosts and
298   // RenderFrameHosts that we create.
299   RenderFrameHostDelegate* render_frame_delegate_;
300   RenderViewHostDelegate* render_view_delegate_;
301   RenderWidgetHostDelegate* render_widget_delegate_;
302   RenderFrameHostManager::Delegate* manager_delegate_;
303 
304   // The Navigator object responsible for managing navigations on this frame
305   // tree.
306   Navigator navigator_;
307 
308   // Map of SiteInstance ID to RenderViewHost. This allows us to look up the
309   // RenderViewHost for a given SiteInstance when creating RenderFrameHosts.
310   // Each RenderViewHost maintains a refcount and is deleted when there are no
311   // more RenderFrameHosts or RenderFrameProxyHosts using it.
312   std::unordered_map<int /* SiteInstance ID */, RenderViewHostImpl*>
313       render_view_host_map_;
314 
315   // This is an owned ptr to the root FrameTreeNode, which never changes over
316   // the lifetime of the FrameTree. It is not a scoped_ptr because we need the
317   // pointer to remain valid even while the FrameTreeNode is being destroyed,
318   // since it's common for a node to test whether it's the root node.
319   FrameTreeNode* root_;
320 
321   int focused_frame_tree_node_id_;
322 
323   base::RepeatingCallback<void(RenderFrameHost*)> on_frame_removed_;
324 
325   // Overall load progress.
326   double load_progress_;
327 
328   DISALLOW_COPY_AND_ASSIGN(FrameTree);
329 };
330 
331 }  // namespace content
332 
333 #endif  // CONTENT_BROWSER_RENDERER_HOST_FRAME_TREE_H_
334