blob: 591cadcdbe1a26aa3b08cba8cb6aa0559d19dec6 [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_NODE_H_
6#define CONTENT_BROWSER_RENDERER_HOST_FRAME_TREE_NODE_H_
7
8#include <stddef.h>
9
10#include <memory>
11#include <string>
12#include <vector>
13
14#include "base/gtest_prod_util.h"
Keishi Hattori0e45c022021-11-27 09:25:5215#include "base/memory/raw_ptr.h"
danakjc492bf82020-09-09 20:02:4416#include "base/memory/ref_counted.h"
David Sandersd4bf5eb2022-03-17 07:12:0517#include "base/observer_list.h"
danakjc492bf82020-09-09 20:02:4418#include "content/browser/renderer_host/frame_tree.h"
19#include "content/browser/renderer_host/frame_tree_node_blame_context.h"
20#include "content/browser/renderer_host/navigator.h"
21#include "content/browser/renderer_host/render_frame_host_impl.h"
22#include "content/browser/renderer_host/render_frame_host_manager.h"
23#include "content/common/content_export.h"
Julie Jeongeun Kimf38c1eca2021-12-14 07:46:5524#include "content/public/browser/frame_type.h"
danakjc492bf82020-09-09 20:02:4425#include "services/network/public/mojom/content_security_policy.mojom-forward.h"
Lei Zhang698df03c2021-05-21 04:23:3426#include "third_party/abseil-cpp/absl/types/optional.h"
Kevin McNee43fe8292021-10-04 22:59:4127#include "third_party/blink/public/common/frame/frame_owner_element_type.h"
danakjc492bf82020-09-09 20:02:4428#include "third_party/blink/public/common/frame/frame_policy.h"
29#include "third_party/blink/public/common/frame/user_activation_state.h"
danakjc492bf82020-09-09 20:02:4430#include "third_party/blink/public/mojom/frame/frame_owner_properties.mojom.h"
Gyuyoung Kimc16e52e92021-03-19 02:45:3731#include "third_party/blink/public/mojom/frame/frame_replication_state.mojom-forward.h"
Daniel Cheng6ac128172021-05-25 18:49:0132#include "third_party/blink/public/mojom/frame/tree_scope_type.mojom.h"
danakjc492bf82020-09-09 20:02:4433#include "third_party/blink/public/mojom/frame/user_activation_update_types.mojom.h"
34#include "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom-forward.h"
35
36#include "url/gurl.h"
37#include "url/origin.h"
38
39namespace content {
40
41class NavigationRequest;
42class RenderFrameHostImpl;
43class NavigationEntryImpl;
44
45// When a page contains iframes, its renderer process maintains a tree structure
46// of those frames. We are mirroring this tree in the browser process. This
47// class represents a node in this tree and is a wrapper for all objects that
48// are frame-specific (as opposed to page-specific).
49//
50// Each FrameTreeNode has a current RenderFrameHost, which can change over
51// time as the frame is navigated. Any immediate subframes of the current
52// document are tracked using FrameTreeNodes owned by the current
53// RenderFrameHost, rather than as children of FrameTreeNode itself. This
54// allows subframe FrameTreeNodes to stay alive while a RenderFrameHost is
55// still alive - for example while pending deletion, after a new current
56// RenderFrameHost has replaced it.
57class CONTENT_EXPORT FrameTreeNode {
58 public:
59 class Observer {
60 public:
61 // Invoked when a FrameTreeNode is being destroyed.
62 virtual void OnFrameTreeNodeDestroyed(FrameTreeNode* node) {}
63
64 // Invoked when a FrameTreeNode becomes focused.
65 virtual void OnFrameTreeNodeFocused(FrameTreeNode* node) {}
66
Arthur Hemerye4659282022-03-28 08:36:1567 // Invoked when a FrameTreeNode moves to a different BrowsingInstance and
68 // the popups it opened should be disowned.
69 virtual void OnFrameTreeNodeDisownedOpenee(FrameTreeNode* node) {}
70
Fergal Dalya1d569972021-03-16 03:24:5371 virtual ~Observer() = default;
danakjc492bf82020-09-09 20:02:4472 };
73
74 static const int kFrameTreeNodeInvalidId;
75
76 // Returns the FrameTreeNode with the given global |frame_tree_node_id|,
77 // regardless of which FrameTree it is in.
78 static FrameTreeNode* GloballyFindByID(int frame_tree_node_id);
79
80 // Returns the FrameTreeNode for the given |rfh|. Same as
81 // rfh->frame_tree_node(), but also supports nullptrs.
82 static FrameTreeNode* From(RenderFrameHost* rfh);
83
84 // Callers are are expected to initialize sandbox flags separately after
85 // calling the constructor.
86 FrameTreeNode(
87 FrameTree* frame_tree,
88 RenderFrameHostImpl* parent,
Daniel Cheng6ac128172021-05-25 18:49:0189 blink::mojom::TreeScopeType tree_scope_type,
danakjc492bf82020-09-09 20:02:4490 bool is_created_by_script,
91 const base::UnguessableToken& devtools_frame_token,
92 const blink::mojom::FrameOwnerProperties& frame_owner_properties,
Kevin McNee43fe8292021-10-04 22:59:4193 blink::FrameOwnerElementType owner_type,
Dominic Farolino08662c82021-06-11 07:36:3494 const blink::FramePolicy& frame_owner);
danakjc492bf82020-09-09 20:02:4495
Peter Boström828b9022021-09-21 02:28:4396 FrameTreeNode(const FrameTreeNode&) = delete;
97 FrameTreeNode& operator=(const FrameTreeNode&) = delete;
98
danakjc492bf82020-09-09 20:02:4499 ~FrameTreeNode();
100
101 void AddObserver(Observer* observer);
102 void RemoveObserver(Observer* observer);
103
104 bool IsMainFrame() const;
105
arthursonzogni76098e52020-11-25 14:18:45106 // Clears any state in this node which was set by the document itself (CSP &
107 // UserActivationState) and notifies proxies as appropriate. Invoked after
108 // committing navigation to a new document (since the new document comes with
109 // a fresh set of CSP).
110 // TODO(arthursonzogni): Remove this function. The frame/document must not be
111 // left temporarily with lax state.
Hiroki Nakagawaab309622021-05-19 16:38:13112 void ResetForNavigation();
danakjc492bf82020-09-09 20:02:44113
114 FrameTree* frame_tree() const { return frame_tree_; }
115 Navigator& navigator() { return frame_tree()->navigator(); }
116
117 RenderFrameHostManager* render_manager() { return &render_manager_; }
Alexander Timin33e2e2c12022-03-03 04:21:33118 const RenderFrameHostManager* render_manager() const {
119 return &render_manager_;
120 }
danakjc492bf82020-09-09 20:02:44121 int frame_tree_node_id() const { return frame_tree_node_id_; }
Harkiran Bolaria4eacb3a2021-12-13 20:03:47122 const std::string& frame_name() const {
123 return render_manager_.current_replication_state().name;
124 }
danakjc492bf82020-09-09 20:02:44125
126 const std::string& unique_name() const {
Harkiran Bolaria4eacb3a2021-12-13 20:03:47127 return render_manager_.current_replication_state().unique_name;
danakjc492bf82020-09-09 20:02:44128 }
129
130 // See comment on the member declaration.
131 const base::UnguessableToken& devtools_frame_token() const {
132 return devtools_frame_token_;
133 }
134
135 size_t child_count() const { return current_frame_host()->child_count(); }
136
danakjc492bf82020-09-09 20:02:44137 RenderFrameHostImpl* parent() const { return parent_; }
138
Dave Tapuskac8de3b02021-12-03 21:51:01139 // See `RenderFrameHost::GetParentOrOuterDocument()` for
140 // documentation.
141 RenderFrameHostImpl* GetParentOrOuterDocument();
142
143 // See `RenderFrameHostImpl::GetParentOrOuterDocumentOrEmbedder()` for
144 // documentation.
145 RenderFrameHostImpl* GetParentOrOuterDocumentOrEmbedder();
146
danakjc492bf82020-09-09 20:02:44147 FrameTreeNode* opener() const { return opener_; }
148
149 FrameTreeNode* original_opener() const { return original_opener_; }
150
Anton Bikineevf62d1bf2021-05-15 17:56:07151 const absl::optional<base::UnguessableToken>& opener_devtools_frame_token() {
Wolfgang Beyerd8809db2020-09-30 15:29:39152 return opener_devtools_frame_token_;
153 }
154
Julie Jeongeun Kimf38c1eca2021-12-14 07:46:55155 // Returns the type of the frame. Refer to frame_type.h for the details.
156 FrameType GetFrameType() const;
157
danakjc492bf82020-09-09 20:02:44158 // Assigns a new opener for this node and, if |opener| is non-null, registers
159 // an observer that will clear this node's opener if |opener| is ever
160 // destroyed.
161 void SetOpener(FrameTreeNode* opener);
162
163 // Assigns the initial opener for this node, and if |opener| is non-null,
164 // registers an observer that will clear this node's opener if |opener| is
165 // ever destroyed. The value set here is the root of the tree.
166 //
167 // It is not possible to change the opener once it was set.
168 void SetOriginalOpener(FrameTreeNode* opener);
169
Wolfgang Beyerd8809db2020-09-30 15:29:39170 // Assigns an opener frame id for this node. This string id is only set once
171 // and cannot be changed. It persists, even if the |opener| is destroyed. It
172 // is used for attribution in the DevTools frontend.
173 void SetOpenerDevtoolsFrameToken(
174 base::UnguessableToken opener_devtools_frame_token);
175
danakjc492bf82020-09-09 20:02:44176 FrameTreeNode* child_at(size_t index) const {
177 return current_frame_host()->child_at(index);
178 }
179
180 // Returns the URL of the last committed page in the current frame.
181 const GURL& current_url() const {
182 return current_frame_host()->GetLastCommittedURL();
183 }
184
Rakina Zata Amni86c88fa2021-11-01 01:27:30185 // Sets the last committed URL for this frame.
danakjc492bf82020-09-09 20:02:44186 void SetCurrentURL(const GURL& url);
187
Rakina Zata Amni90555282022-01-21 07:35:54188 // Sets `is_on_initial_empty_document_` to false.
189 void SetNotOnInitialEmptyDocument() { is_on_initial_empty_document_ = false; }
Rakina Zata Amni86c88fa2021-11-01 01:27:30190
Rakina Zata Amni91d485b42021-12-08 02:50:13191 // Returns false if the frame has committed a document that is not the initial
Rakina Zata Amni86c88fa2021-11-01 01:27:30192 // empty document, or if the current document's input stream has been opened
193 // with document.open(), causing the document to lose its "initial empty
194 // document" status. For more details, see the definition of
195 // `is_on_initial_empty_document_`.
196 bool is_on_initial_empty_document() const {
197 return is_on_initial_empty_document_;
Rakina Zata Amnifc4cc3d42021-06-10 09:03:56198 }
199
Rakina Zata Amni86c88fa2021-11-01 01:27:30200 // Sets `is_on_initial_empty_document_` to
Rakina Zata Amnifc4cc3d42021-06-10 09:03:56201 // false. Must only be called after the current document's input stream has
202 // been opened with document.open().
Rakina Zata Amni86c88fa2021-11-01 01:27:30203 void DidOpenDocumentInputStream() { is_on_initial_empty_document_ = false; }
Rakina Zata Amnid09b6112021-06-05 06:20:14204
danakjc492bf82020-09-09 20:02:44205 // Returns whether the frame's owner element in the parent document is
206 // collapsed, that is, removed from the layout as if it did not exist, as per
207 // request by the embedder (of the content/ layer).
208 bool is_collapsed() const { return is_collapsed_; }
209
210 // Sets whether to collapse the frame's owner element in the parent document,
211 // that is, to remove it from the layout as if it did not exist, as per
212 // request by the embedder (of the content/ layer). Cannot be called for main
213 // frames.
214 //
215 // This only has an effect for <iframe> owner elements, and is a no-op when
216 // called on sub-frames hosted in <frame>, <object>, and <embed> elements.
217 void SetCollapsed(bool collapsed);
218
219 // Returns the origin of the last committed page in this frame.
220 // WARNING: To get the last committed origin for a particular
221 // RenderFrameHost, use RenderFrameHost::GetLastCommittedOrigin() instead,
222 // which will behave correctly even when the RenderFrameHost is not the
223 // current one for this frame (such as when it's pending deletion).
224 const url::Origin& current_origin() const {
Harkiran Bolaria4eacb3a2021-12-13 20:03:47225 return render_manager_.current_replication_state().origin;
danakjc492bf82020-09-09 20:02:44226 }
227
Harkiran Bolaria0b3bdef02022-03-10 13:04:40228 // Set the current name and notify proxies about the update.
229 void SetFrameName(const std::string& name, const std::string& unique_name);
230
danakjc492bf82020-09-09 20:02:44231 // Returns the latest frame policy (sandbox flags and container policy) for
232 // this frame. This includes flags inherited from parent frames and the latest
233 // flags from the <iframe> element hosting this frame. The returned policies
234 // may not yet have taken effect, since "sandbox" and "allow" attribute
235 // updates in an <iframe> element take effect on next navigation. To retrieve
236 // the currently active policy for this frame, use effective_frame_policy().
237 const blink::FramePolicy& pending_frame_policy() const {
238 return pending_frame_policy_;
239 }
240
241 // Update this frame's sandbox flags and container policy. This is called
242 // when a parent frame updates the "sandbox" attribute in the <iframe> element
243 // for this frame, or any of the attributes which affect the container policy
244 // ("allowfullscreen", "allowpaymentrequest", "allow", and "src".)
245 // These policies won't take effect until next navigation. If this frame's
246 // parent is itself sandboxed, the parent's sandbox flags are combined with
247 // those in |frame_policy|.
248 // Attempting to change the container policy on the main frame will have no
249 // effect.
250 void SetPendingFramePolicy(blink::FramePolicy frame_policy);
251
252 // Returns the currently active frame policy for this frame, including the
253 // sandbox flags which were present at the time the document was loaded, and
Charlie Hu5130d25e2021-03-05 21:53:39254 // the permissions policy container policy, which is set by the iframe's
danakjc492bf82020-09-09 20:02:44255 // allowfullscreen, allowpaymentrequest, and allow attributes, along with the
256 // origin of the iframe's src attribute (which may be different from the URL
257 // of the document currently loaded into the frame). This does not include
258 // policy changes that have been made by updating the containing iframe
259 // element attributes since the frame was last navigated; use
260 // pending_frame_policy() for those.
261 const blink::FramePolicy& effective_frame_policy() const {
Harkiran Bolaria4eacb3a2021-12-13 20:03:47262 return render_manager_.current_replication_state().frame_policy;
danakjc492bf82020-09-09 20:02:44263 }
264
danakjc492bf82020-09-09 20:02:44265 const blink::mojom::FrameOwnerProperties& frame_owner_properties() {
266 return frame_owner_properties_;
267 }
268
269 void set_frame_owner_properties(
270 const blink::mojom::FrameOwnerProperties& frame_owner_properties) {
271 frame_owner_properties_ = frame_owner_properties;
272 }
273
274 const network::mojom::ContentSecurityPolicy* csp_attribute() {
275 return csp_attribute_.get();
276 }
277
278 void set_csp_attribute(
279 network::mojom::ContentSecurityPolicyPtr parsed_csp_attribute) {
280 csp_attribute_ = std::move(parsed_csp_attribute);
281 }
282
Antonio Sartori5abc8de2021-07-13 08:42:47283 // Reflects the 'anonymous' attribute of the corresponding iframe html
284 // element.
285 bool anonymous() const { return anonymous_; }
286 void set_anonymous(bool anonymous) { anonymous_ = anonymous; }
287
danakjc492bf82020-09-09 20:02:44288 bool HasSameOrigin(const FrameTreeNode& node) const {
Harkiran Bolaria4eacb3a2021-12-13 20:03:47289 return render_manager_.current_replication_state().origin.IsSameOriginWith(
290 node.current_replication_state().origin);
danakjc492bf82020-09-09 20:02:44291 }
292
Gyuyoung Kimc16e52e92021-03-19 02:45:37293 const blink::mojom::FrameReplicationState& current_replication_state() const {
Harkiran Bolaria4eacb3a2021-12-13 20:03:47294 return render_manager_.current_replication_state();
danakjc492bf82020-09-09 20:02:44295 }
296
297 RenderFrameHostImpl* current_frame_host() const {
298 return render_manager_.current_frame_host();
299 }
300
danakjc492bf82020-09-09 20:02:44301 // Returns true if this node is in a loading state.
302 bool IsLoading() const;
303
Alex Moshchuk9b0fd822020-10-26 23:08:15304 // Returns true if this node has a cross-document navigation in progress.
305 bool HasPendingCrossDocumentNavigation() const;
306
danakjc492bf82020-09-09 20:02:44307 NavigationRequest* navigation_request() { return navigation_request_.get(); }
308
309 // Transfers the ownership of the NavigationRequest to |render_frame_host|.
310 // From ReadyToCommit to DidCommit, the NavigationRequest is owned by the
311 // RenderFrameHost that is committing the navigation.
312 void TransferNavigationRequestOwnership(
313 RenderFrameHostImpl* render_frame_host);
314
315 // Takes ownership of |navigation_request| and makes it the current
316 // NavigationRequest of this frame. This corresponds to the start of a new
317 // navigation. If there was an ongoing navigation request before calling this
318 // function, it is canceled. |navigation_request| should not be null.
319 void CreatedNavigationRequest(
320 std::unique_ptr<NavigationRequest> navigation_request);
321
322 // Resets the current navigation request. If |keep_state| is true, any state
323 // created by the NavigationRequest (e.g. speculative RenderFrameHost,
324 // loading state) will not be reset by the function.
325 void ResetNavigationRequest(bool keep_state);
326
327 // A RenderFrameHost in this node started loading.
Nate Chapin9aabf5f2021-11-12 00:31:19328 // |should_show_loading_ui| indicates whether this navigation should be
329 // visible in the UI. True for cross-document navigations and navigations
Domenic Denicola30810742022-03-17 20:11:23330 // intercepted by the navigation API's transitionWhile().
danakjc492bf82020-09-09 20:02:44331 // |was_previously_loading| is false if the FrameTree was not loading before.
332 // The caller is required to provide this boolean as the delegate should only
333 // be notified if the FrameTree went from non-loading to loading state.
334 // However, when it is called, the FrameTree should be in a loading state.
Nate Chapin9aabf5f2021-11-12 00:31:19335 void DidStartLoading(bool should_show_loading_ui,
336 bool was_previously_loading);
danakjc492bf82020-09-09 20:02:44337
338 // A RenderFrameHost in this node stopped loading.
339 void DidStopLoading();
340
341 // The load progress for a RenderFrameHost in this node was updated to
342 // |load_progress|. This will notify the FrameTree which will in turn notify
343 // the WebContents.
344 void DidChangeLoadProgress(double load_progress);
345
346 // Called when the user directed the page to stop loading. Stops all loads
347 // happening in the FrameTreeNode. This method should be used with
348 // FrameTree::ForEach to stop all loads in the entire FrameTree.
349 bool StopLoading();
350
351 // Returns the time this frame was last focused.
352 base::TimeTicks last_focus_time() const { return last_focus_time_; }
353
354 // Called when this node becomes focused. Updates the node's last focused
355 // time and notifies observers.
356 void DidFocus();
357
358 // Called when the user closed the modal dialogue for BeforeUnload and
359 // cancelled the navigation. This should stop any load happening in the
360 // FrameTreeNode.
361 void BeforeUnloadCanceled();
362
363 // Returns the BlameContext associated with this node.
364 FrameTreeNodeBlameContext& blame_context() { return blame_context_; }
365
366 // Updates the user activation state in the browser frame tree and in the
367 // frame trees in all renderer processes except the renderer for this node
368 // (which initiated the update). Returns |false| if the update tries to
369 // consume an already consumed/expired transient state, |true| otherwise. See
370 // the comment on user_activation_state_ below.
371 //
372 // The |notification_type| parameter is used for histograms, only for the case
373 // |update_state == kNotifyActivation|.
374 bool UpdateUserActivationState(
375 blink::mojom::UserActivationUpdateType update_type,
376 blink::mojom::UserActivationNotificationType notification_type);
377
danakjc492bf82020-09-09 20:02:44378 // Returns the sandbox flags currently in effect for this frame. This includes
379 // flags inherited from parent frames, the currently active flags from the
380 // <iframe> element hosting this frame, as well as any flags set from a
381 // Content-Security-Policy HTTP header. This does not include flags that have
382 // have been updated in an <iframe> element but have not taken effect yet; use
383 // pending_frame_policy() for those. To see the flags which will take effect
384 // on navigation (which does not include the CSP-set flags), use
385 // effective_frame_policy().
386 network::mojom::WebSandboxFlags active_sandbox_flags() const {
Harkiran Bolaria4eacb3a2021-12-13 20:03:47387 return render_manager_.current_replication_state().active_sandbox_flags;
danakjc492bf82020-09-09 20:02:44388 }
389
danakjc492bf82020-09-09 20:02:44390 // Returns whether the frame received a user gesture on a previous navigation
391 // on the same eTLD+1.
392 bool has_received_user_gesture_before_nav() const {
Harkiran Bolaria4eacb3a2021-12-13 20:03:47393 return render_manager_.current_replication_state()
394 .has_received_user_gesture_before_nav;
danakjc492bf82020-09-09 20:02:44395 }
396
397 // When a tab is discarded, WebContents sets was_discarded on its
398 // root FrameTreeNode.
399 // In addition, when a child frame is created, this bit is passed on from
400 // parent to child.
401 // When a navigation request is created, was_discarded is passed on to the
402 // request and reset to false in FrameTreeNode.
403 void set_was_discarded() { was_discarded_ = true; }
404 bool was_discarded() const { return was_discarded_; }
405
406 // Returns the sticky bit of the User Activation v2 state of the
407 // |FrameTreeNode|.
408 bool HasStickyUserActivation() const {
409 return user_activation_state_.HasBeenActive();
410 }
411
412 // Returns the transient bit of the User Activation v2 state of the
413 // |FrameTreeNode|.
414 bool HasTransientUserActivation() {
415 return user_activation_state_.IsActive();
416 }
417
418 // Remove history entries for all frames created by script in this frame's
419 // subtree. If a frame created by a script is removed, then its history entry
420 // will never be reused - this saves memory.
421 void PruneChildFrameNavigationEntries(NavigationEntryImpl* entry);
422
Kevin McNee43fe8292021-10-04 22:59:41423 blink::FrameOwnerElementType frame_owner_element_type() const {
Daniel Cheng9bd90f92021-04-23 20:49:45424 return frame_owner_element_type_;
danakjc492bf82020-09-09 20:02:44425 }
danakjc492bf82020-09-09 20:02:44426
Daniel Cheng6ac128172021-05-25 18:49:01427 blink::mojom::TreeScopeType tree_scope_type() const {
428 return tree_scope_type_;
429 }
430
arthursonzogni034bb9c2020-10-01 08:29:56431 // The initial popup URL for new window opened using:
432 // `window.open(initial_popup_url)`.
433 // An empty GURL otherwise.
434 //
435 // [WARNING] There is no guarantee the FrameTreeNode will ever host a
436 // document served from this URL. The FrameTreeNode always starts hosting the
437 // initial empty document and attempts a navigation toward this URL. However
438 // the navigation might be delayed, redirected and even cancelled.
439 void SetInitialPopupURL(const GURL& initial_popup_url);
440 const GURL& initial_popup_url() const { return initial_popup_url_; }
441
442 // The origin of the document that used window.open() to create this frame.
443 // Otherwise, an opaque Origin with a nonce different from all previously
444 // existing Origins.
445 void SetPopupCreatorOrigin(const url::Origin& popup_creator_origin);
446 const url::Origin& popup_creator_origin() const {
447 return popup_creator_origin_;
448 }
449
Harkiran Bolaria59290d62021-03-17 01:53:01450 // Sets the associated FrameTree for this node. The node can change FrameTrees
451 // when blink::features::Prerender2 is enabled, which allows a page loaded in
452 // the prerendered FrameTree to be used for a navigation in the primary frame
453 // tree.
454 void SetFrameTree(FrameTree& frame_tree);
455
Alexander Timin074cd182022-03-23 18:11:22456 using TraceProto = perfetto::protos::pbzero::FrameTreeNodeInfo;
Alexander Timinf785f342021-03-18 00:00:56457 // Write a representation of this object into a trace.
Alexander Timin074cd182022-03-23 18:11:22458 void WriteIntoTrace(perfetto::TracedProto<TraceProto> proto) const;
Alexander Timinf785f342021-03-18 00:00:56459
Carlos Caballero76711352021-03-24 17:38:21460 // Returns true the node is navigating, i.e. it has an associated
461 // NavigationRequest.
462 bool HasNavigation();
463
shivanigithubf3ddff52021-07-03 22:06:30464 // Fenced frames (meta-bug crbug.com/1111084):
shivanigithub4cd016a2021-09-20 21:10:30465 // Note that these two functions cannot be invoked from a FrameTree's or
466 // its root node's constructor since they require the frame tree and the
467 // root node to be completely constructed.
468 //
shivanigithubf3ddff52021-07-03 22:06:30469 // Returns false if fenced frames are disabled. Returns true if the feature is
470 // enabled and if |this| is a fenced frame. Returns false for
471 // iframes embedded in a fenced frame. To clarify: for the MPArch
472 // implementation this only returns true if |this| is the actual
473 // root node of the inner FrameTree and not the proxy FrameTreeNode in the
474 // outer FrameTree.
Dominic Farolino4bc10ee2021-08-31 00:37:36475 bool IsFencedFrameRoot() const;
shivanigithubf3ddff52021-07-03 22:06:30476
477 // Returns false if fenced frames are disabled. Returns true if the
478 // feature is enabled and if |this| or any of its ancestor nodes is a
479 // fenced frame.
480 bool IsInFencedFrameTree() const;
481
shivanigithub4cd016a2021-09-20 21:10:30482 // Returns a valid nonce if `IsInFencedFrameTree()` returns true for `this`.
483 // Returns nullopt otherwise. See comments on `fenced_frame_nonce_` for more
484 // details.
485 absl::optional<base::UnguessableToken> fenced_frame_nonce() {
486 return fenced_frame_nonce_;
487 }
488
489 // If applicable, set the fenced frame nonce. See comment on
490 // fenced_frame_nonce() for when it is set to a non-null value. Invoked
491 // by FrameTree::Init() or FrameTree::AddFrame().
492 void SetFencedFrameNonceIfNeeded();
493
Nan Line376738a2022-03-25 22:05:41494 // Returns the mode attribute set on the fenced frame if this is a fenced
495 // frame root, otherwise returns `absl::nullopt`.
496 absl::optional<blink::mojom::FencedFrameMode> GetFencedFrameMode();
Nan Lin171fe9a2022-02-17 16:42:16497
Dave Tapuskac8de3b02021-12-03 21:51:01498 // Helper for GetParentOrOuterDocument/GetParentOrOuterDocumentOrEmbedder.
499 // Do not use directly.
500 RenderFrameHostImpl* GetParentOrOuterDocumentHelper(bool escape_guest_view);
501
Harkiran Bolariab4437fd2021-08-11 17:51:22502 // Sets the unique_name and name fields on replication_state_. To be used in
503 // prerender activation to make sure the FrameTreeNode replication state is
504 // correct after the RenderFrameHost is moved between FrameTreeNodes. The
505 // renderers should already have the correct value, so unlike
506 // FrameTreeNode::SetFrameName, we do not notify them here.
Harkiran Bolaria4eacb3a2021-12-13 20:03:47507 // TODO(https://crbug.com/1237091): Remove this once the BrowsingContextState
508 // is implemented to utilize the new path.
Harkiran Bolariab4437fd2021-08-11 17:51:22509 void set_frame_name_for_activation(const std::string& unique_name,
510 const std::string& name) {
Harkiran Bolaria0b3bdef02022-03-10 13:04:40511 current_frame_host()->browsing_context_state()->set_frame_name(unique_name,
512 name);
Harkiran Bolariab4437fd2021-08-11 17:51:22513 }
514
Nan Linaaf84f72021-12-02 22:31:56515 // Returns true if error page isolation is enabled.
516 bool IsErrorPageIsolationEnabled() const;
517
W. James MacLean81b8d01f2022-01-25 20:50:59518 // Functions to store and retrieve a frame's srcdoc value on this
519 // FrameTreeNode.
520 void SetSrcdocValue(const std::string& srcdoc_value);
521 const std::string& srcdoc_value() const { return srcdoc_value_; }
522
Harkiran Bolariaebbe7702022-02-22 19:19:03523 // Accessor to BrowsingContextState for subframes only. Only main frame
524 // navigations can change BrowsingInstances and BrowsingContextStates,
525 // therefore for subframes associated BrowsingContextState never changes. This
526 // helper method makes this more explicit and guards against calling this on
527 // main frames (there an appropriate BrowsingContextState should be obtained
528 // from RenderFrameHost or from RenderFrameProxyHost as e.g. during
529 // cross-BrowsingInstance navigations multiple BrowsingContextStates exist in
530 // the same frame).
531 const scoped_refptr<BrowsingContextState>&
532 GetBrowsingContextStateForSubframe() const;
533
Arthur Hemerye4659282022-03-28 08:36:15534 // Clears the opener property of popups referencing this FrameTreeNode as
535 // their opener.
536 void ClearOpenerReferences();
537
danakjc492bf82020-09-09 20:02:44538 private:
Charlie Hubb5943d2021-03-09 19:46:12539 FRIEND_TEST_ALL_PREFIXES(SitePerProcessPermissionsPolicyBrowserTest,
danakjc492bf82020-09-09 20:02:44540 ContainerPolicyDynamic);
Charlie Hubb5943d2021-03-09 19:46:12541 FRIEND_TEST_ALL_PREFIXES(SitePerProcessPermissionsPolicyBrowserTest,
danakjc492bf82020-09-09 20:02:44542 ContainerPolicySandboxDynamic);
543
Dominic Farolino8a2187b2021-12-24 20:44:21544 // Called by the destructor. When `this` is an outer dummy FrameTreeNode
545 // representing an inner FrameTree, this method destroys said inner FrameTree.
546 void DestroyInnerFrameTreeIfExists();
547
danakjc492bf82020-09-09 20:02:44548 class OpenerDestroyedObserver;
549
danakjc492bf82020-09-09 20:02:44550 // The |notification_type| parameter is used for histograms only.
551 bool NotifyUserActivation(
552 blink::mojom::UserActivationNotificationType notification_type);
553
554 bool ConsumeTransientUserActivation();
555
556 bool ClearUserActivation();
557
558 // Verify that the renderer process is allowed to set user activation on this
559 // frame by checking whether this frame's RenderWidgetHost had previously seen
560 // an input event that might lead to user activation. If user activation
561 // should be allowed, this returns true and also clears corresponding pending
562 // user activation state in the widget. Otherwise, this returns false.
563 bool VerifyUserActivation();
564
565 // The next available browser-global FrameTreeNode ID.
566 static int next_frame_tree_node_id_;
567
568 // The FrameTree that owns us.
Keishi Hattori0e45c022021-11-27 09:25:52569 raw_ptr<FrameTree> frame_tree_; // not owned.
danakjc492bf82020-09-09 20:02:44570
danakjc492bf82020-09-09 20:02:44571 // A browser-global identifier for the frame in the page, which stays stable
572 // even if the frame does a cross-process navigation.
573 const int frame_tree_node_id_;
574
575 // The RenderFrameHost owning this FrameTreeNode, which cannot change for the
576 // life of this FrameTreeNode. |nullptr| if this node is the root.
Keishi Hattori0e45c022021-11-27 09:25:52577 const raw_ptr<RenderFrameHostImpl> parent_;
danakjc492bf82020-09-09 20:02:44578
danakjc492bf82020-09-09 20:02:44579 // The frame that opened this frame, if any. Will be set to null if the
580 // opener is closed, or if this frame disowns its opener by setting its
581 // window.opener to null.
Keishi Hattori0e45c022021-11-27 09:25:52582 raw_ptr<FrameTreeNode> opener_ = nullptr;
danakjc492bf82020-09-09 20:02:44583
584 // An observer that clears this node's |opener_| if the opener is destroyed.
585 // This observer is added to the |opener_|'s observer list when the |opener_|
586 // is set to a non-null node, and it is removed from that list when |opener_|
587 // changes or when this node is destroyed. It is also cleared if |opener_|
588 // is disowned.
589 std::unique_ptr<OpenerDestroyedObserver> opener_observer_;
590
591 // The frame that opened this frame, if any. Contrary to opener_, this
592 // cannot be changed unless the original opener is destroyed.
Keishi Hattori0e45c022021-11-27 09:25:52593 raw_ptr<FrameTreeNode> original_opener_ = nullptr;
danakjc492bf82020-09-09 20:02:44594
Wolfgang Beyerd8809db2020-09-30 15:29:39595 // The devtools frame token of the frame which opened this frame. This is
596 // not cleared even if the opener is destroyed or disowns the frame.
Anton Bikineevf62d1bf2021-05-15 17:56:07597 absl::optional<base::UnguessableToken> opener_devtools_frame_token_;
Wolfgang Beyerd8809db2020-09-30 15:29:39598
danakjc492bf82020-09-09 20:02:44599 // An observer that clears this node's |original_opener_| if the opener is
600 // destroyed.
601 std::unique_ptr<OpenerDestroyedObserver> original_opener_observer_;
602
arthursonzogni034bb9c2020-10-01 08:29:56603 // When created by an opener, the URL specified in window.open(url)
604 // Please refer to {Get,Set}InitialPopupURL() documentation.
605 GURL initial_popup_url_;
606
607 // When created using window.open, the origin of the creator.
608 // Please refer to {Get,Set}PopupCreatorOrigin() documentation.
609 url::Origin popup_creator_origin_;
610
W. James MacLean81b8d01f2022-01-25 20:50:59611 // If the url from the the last BeginNavigation is about:srcdoc, this value
612 // stores the srcdoc_attribute's value for re-use in history navigations.
613 std::string srcdoc_value_;
614
Rakina Zata Amni86c88fa2021-11-01 01:27:30615 // Whether this frame is still on the initial about:blank document or the
616 // synchronously committed about:blank document committed at frame creation,
617 // and its "initial empty document"-ness is still true.
618 // This will be false if either of these has happened:
619 // - SetCurrentUrl() was called after committing a document that is not the
620 // initial about:blank document or the synchronously committed about:blank
621 // document, per
622 // https://html.spec.whatwg.org/multipage/browsers.html#creating-browsing-contexts:is-initial-about:blank
623 // - The document's input stream has been opened with document.open(), per
624 // https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#opening-the-input-stream:is-initial-about:blank
625 // NOTE: we treat both the "initial about:blank document" and the
626 // "synchronously committed about:blank document" as the initial empty
627 // document. In the future, we plan to remove the synchronous about:blank
628 // commit so that this state will only be true if the frame is on the
629 // "initial about:blank document". See also:
630 // - https://github.com/whatwg/html/issues/6863
631 // - https://crbug.com/1215096
632 bool is_on_initial_empty_document_ = true;
Rakina Zata Amnifc4cc3d42021-06-10 09:03:56633
danakjc492bf82020-09-09 20:02:44634 // Whether the frame's owner element in the parent document is collapsed.
arthursonzogni9816b9192021-03-29 16:09:19635 bool is_collapsed_ = false;
danakjc492bf82020-09-09 20:02:44636
Daniel Cheng6ac128172021-05-25 18:49:01637 // The type of frame owner for this frame. This is only relevant for non-main
638 // frames.
Kevin McNee43fe8292021-10-04 22:59:41639 const blink::FrameOwnerElementType frame_owner_element_type_ =
640 blink::FrameOwnerElementType::kNone;
Daniel Cheng9bd90f92021-04-23 20:49:45641
Daniel Cheng6ac128172021-05-25 18:49:01642 // The tree scope type of frame owner element, i.e. whether the element is in
643 // the document tree (https://dom.spec.whatwg.org/#document-trees) or the
644 // shadow tree (https://dom.spec.whatwg.org/#shadow-trees). This is only
645 // relevant for non-main frames.
646 const blink::mojom::TreeScopeType tree_scope_type_ =
647 blink::mojom::TreeScopeType::kDocument;
648
danakjc492bf82020-09-09 20:02:44649 // Track the pending sandbox flags and container policy for this frame. When a
650 // parent frame dynamically updates 'sandbox', 'allow', 'allowfullscreen',
651 // 'allowpaymentrequest' or 'src' attributes, the updated policy for the frame
Harkiran Bolaria4eacb3a2021-12-13 20:03:47652 // is stored here, and transferred into
653 // render_manager_.current_replication_state().frame_policy when they take
654 // effect on the next frame navigation.
danakjc492bf82020-09-09 20:02:44655 blink::FramePolicy pending_frame_policy_;
656
657 // Whether the frame was created by javascript. This is useful to prune
658 // history entries when the frame is removed (because frames created by
659 // scripts are never recreated with the same unique name - see
660 // https://crbug.com/500260).
arthursonzogni9816b9192021-03-29 16:09:19661 const bool is_created_by_script_;
danakjc492bf82020-09-09 20:02:44662
663 // Used for devtools instrumentation and trace-ability. The token is
664 // propagated to Blink's LocalFrame and both Blink and content/
665 // can tag calls and requests with this token in order to attribute them
666 // to the context frame.
667 // |devtools_frame_token_| is only defined by the browser process and is never
668 // sent back from the renderer in the control calls. It should be never used
669 // to look up the FrameTreeNode instance.
arthursonzogni9816b9192021-03-29 16:09:19670 const base::UnguessableToken devtools_frame_token_;
danakjc492bf82020-09-09 20:02:44671
672 // Tracks the scrolling and margin properties for this frame. These
673 // properties affect the child renderer but are stored on its parent's
674 // frame element. When this frame's parent dynamically updates these
675 // properties, we update them here too.
676 //
677 // Note that dynamic updates only take effect on the next frame navigation.
678 blink::mojom::FrameOwnerProperties frame_owner_properties_;
679
680 // Contains the current parsed value of the 'csp' attribute of this frame.
681 network::mojom::ContentSecurityPolicyPtr csp_attribute_;
682
Antonio Sartori5abc8de2021-07-13 08:42:47683 // Reflects the 'anonymous' attribute of the corresponding iframe html
684 // element.
685 bool anonymous_ = false;
686
danakjc492bf82020-09-09 20:02:44687 // Owns an ongoing NavigationRequest until it is ready to commit. It will then
688 // be reset and a RenderFrameHost will be responsible for the navigation.
689 std::unique_ptr<NavigationRequest> navigation_request_;
690
691 // List of objects observing this FrameTreeNode.
692 base::ObserverList<Observer>::Unchecked observers_;
693
694 base::TimeTicks last_focus_time_;
695
arthursonzogni9816b9192021-03-29 16:09:19696 bool was_discarded_ = false;
danakjc492bf82020-09-09 20:02:44697
698 // The user activation state of the current frame. See |UserActivationState|
699 // for details on how this state is maintained.
700 blink::UserActivationState user_activation_state_;
701
702 // A helper for tracing the snapshots of this FrameTreeNode and attributing
703 // browser process activities to this node (when possible). It is unrelated
704 // to the core logic of FrameTreeNode.
705 FrameTreeNodeBlameContext blame_context_;
706
shivanigithub4cd016a2021-09-20 21:10:30707 // Fenced Frames:
708 // Nonce used in the net::IsolationInfo and blink::StorageKey for a fenced
709 // frame and any iframes nested within it. Not set if this frame is not in a
710 // fenced frame's FrameTree. Note that this could be a field in FrameTree for
711 // the MPArch version but for the shadow DOM version we need to keep it here
712 // since the fenced frame root is not a main frame for the latter. The value
713 // of the nonce will be the same for all of the the frames inside a fenced
714 // frame tree. If there is a nested fenced frame it will have a different
715 // nonce than its parent fenced frame. The nonce will stay the same across
716 // navigations because it is always used in conjunction with other fields of
717 // the keys. If the navigation is same-origin/site then the same network stack
718 // partition/storage will be reused and if it's cross-origin/site then other
719 // parts of the key will change and so, even with the same nonce, another
720 // partition will be used.
721 absl::optional<base::UnguessableToken> fenced_frame_nonce_;
722
Lukasz Anforowicz147141962020-12-16 18:03:24723 // Manages creation and swapping of RenderFrameHosts for this frame.
724 //
725 // This field needs to be declared last, because destruction of
726 // RenderFrameHostManager may call arbitrary callbacks (e.g. via
727 // WebContentsObserver::DidFinishNavigation fired after RenderFrameHostManager
728 // destructs a RenderFrameHostImpl and its NavigationRequest). Such callbacks
729 // may try to use FrameTreeNode's fields above - this would be an undefined
730 // behavior if the fields (even trivially-destructible ones) were destructed
731 // before the RenderFrameHostManager's destructor runs. See also
732 // https://crbug.com/1157988.
733 RenderFrameHostManager render_manager_;
danakjc492bf82020-09-09 20:02:44734};
735
736} // namespace content
737
738#endif // CONTENT_BROWSER_RENDERER_HOST_FRAME_TREE_NODE_H_