blob: a57e16e97f7871c5a4d34a33e87cf372f228b444 [file] [log] [blame]
[email protected]9b159a52013-10-03 17:24:551// 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
danakjc492bf82020-09-09 20:02:445#include "content/browser/renderer_host/frame_tree_node.h"
[email protected]9b159a52013-10-03 17:24:556
Daniel Cheng6ca7f1c92017-08-09 21:45:417#include <math.h>
[email protected]9b159a52013-10-03 17:24:558#include <queue>
Takuto Ikutaadf31eb2019-01-05 00:32:489#include <unordered_map>
dcheng36b6aec92015-12-26 06:16:3610#include <utility>
[email protected]9b159a52013-10-03 17:24:5511
Mustaq Ahmeda5dfa60b2018-12-08 00:30:1412#include "base/feature_list.h"
scottmg6ece5ae2017-02-01 18:25:1913#include "base/lazy_instance.h"
avib7348942015-12-25 20:57:1014#include "base/macros.h"
Liviu Tintad9391fb92020-09-28 23:50:0715#include "base/metrics/histogram_functions.h"
dcheng23ca947d2016-05-04 20:04:1516#include "base/metrics/histogram_macros.h"
[email protected]9b159a52013-10-03 17:24:5517#include "base/stl_util.h"
Daniel Cheng6ca7f1c92017-08-09 21:45:4118#include "base/strings/string_util.h"
Andrey Kosyakovf2d4ff72018-10-29 20:09:5919#include "content/browser/devtools/devtools_instrumentation.h"
danakjc492bf82020-09-09 20:02:4420#include "content/browser/renderer_host/navigation_controller_impl.h"
21#include "content/browser/renderer_host/navigation_request.h"
22#include "content/browser/renderer_host/navigator.h"
23#include "content/browser/renderer_host/navigator_delegate.h"
24#include "content/browser/renderer_host/render_frame_host_impl.h"
[email protected]94d0cc12013-12-18 00:07:4125#include "content/browser/renderer_host/render_view_host_impl.h"
clamyf73862c42015-07-08 12:31:3326#include "content/common/frame_messages.h"
Lucas Furukawa Gadanief8290a2019-07-29 20:27:5127#include "content/common/navigation_params.h"
28#include "content/common/navigation_params_utils.h"
dmazzonie950ea232015-03-13 21:39:4529#include "content/public/browser/browser_thread.h"
Mustaq Ahmeda5dfa60b2018-12-08 00:30:1430#include "content/public/common/content_features.h"
arthursonzognib93a4472020-04-10 07:38:0031#include "services/network/public/cpp/web_sandbox_flags.h"
32#include "services/network/public/mojom/web_sandbox_flags.mojom-shared.h"
Harkiran Bolaria59290d62021-03-17 01:53:0133#include "third_party/blink/public/common/features.h"
Antonio Gomes4b2c5132020-01-16 11:49:4834#include "third_party/blink/public/mojom/frame/user_activation_update_types.mojom.h"
Julie Jeongeun Kimd90e2dd2020-03-03 11:45:3735#include "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom.h"
[email protected]9b159a52013-10-03 17:24:5536
37namespace content {
38
dmazzonie950ea232015-03-13 21:39:4539namespace {
40
41// This is a global map between frame_tree_node_ids and pointers to
42// FrameTreeNodes.
Takuto Ikutaadf31eb2019-01-05 00:32:4843typedef std::unordered_map<int, FrameTreeNode*> FrameTreeNodeIdMap;
dmazzonie950ea232015-03-13 21:39:4544
scottmg5e65e3a2017-03-08 08:48:4645base::LazyInstance<FrameTreeNodeIdMap>::DestructorAtExit
46 g_frame_tree_node_id_map = LAZY_INSTANCE_INITIALIZER;
dmazzonie950ea232015-03-13 21:39:4547
fdegansa696e5112015-04-17 01:57:5948// These values indicate the loading progress status. The minimum progress
49// value matches what Blink's ProgressTracker has traditionally used for a
50// minimum progress value.
fdegansa696e5112015-04-17 01:57:5951const double kLoadingProgressMinimum = 0.1;
52const double kLoadingProgressDone = 1.0;
dmazzonie950ea232015-03-13 21:39:4553
fdegansa696e5112015-04-17 01:57:5954} // namespace
fdegans1d16355162015-03-26 11:58:3455
alexmose201c7cd2015-06-10 17:14:2156// This observer watches the opener of its owner FrameTreeNode and clears the
57// owner's opener if the opener is destroyed.
58class FrameTreeNode::OpenerDestroyedObserver : public FrameTreeNode::Observer {
59 public:
jochen6004a362017-02-04 00:11:4060 OpenerDestroyedObserver(FrameTreeNode* owner, bool observing_original_opener)
61 : owner_(owner), observing_original_opener_(observing_original_opener) {}
alexmose201c7cd2015-06-10 17:14:2162
63 // FrameTreeNode::Observer
64 void OnFrameTreeNodeDestroyed(FrameTreeNode* node) override {
jochen6004a362017-02-04 00:11:4065 if (observing_original_opener_) {
Avi Drissman36465f332017-09-11 20:49:3966 // The "original owner" is special. It's used for attribution, and clients
67 // walk down the original owner chain. Therefore, if a link in the chain
68 // is being destroyed, reconnect the observation to the parent of the link
69 // being destroyed.
jochen6004a362017-02-04 00:11:4070 CHECK_EQ(owner_->original_opener(), node);
Avi Drissman36465f332017-09-11 20:49:3971 owner_->SetOriginalOpener(node->original_opener());
72 // |this| is deleted at this point.
jochen6004a362017-02-04 00:11:4073 } else {
74 CHECK_EQ(owner_->opener(), node);
75 owner_->SetOpener(nullptr);
Avi Drissman36465f332017-09-11 20:49:3976 // |this| is deleted at this point.
jochen6004a362017-02-04 00:11:4077 }
alexmose201c7cd2015-06-10 17:14:2178 }
79
80 private:
81 FrameTreeNode* owner_;
jochen6004a362017-02-04 00:11:4082 bool observing_original_opener_;
alexmose201c7cd2015-06-10 17:14:2183
84 DISALLOW_COPY_AND_ASSIGN(OpenerDestroyedObserver);
85};
86
Kevin McNee88e61552020-10-22 20:41:1187const int FrameTreeNode::kFrameTreeNodeInvalidId = -1;
88
89static_assert(FrameTreeNode::kFrameTreeNodeInvalidId ==
90 RenderFrameHost::kNoFrameTreeNodeId,
91 "Have consistent sentinel values for an invalid FTN id.");
92
vishal.b782eb5d2015-04-29 12:22:5793int FrameTreeNode::next_frame_tree_node_id_ = 1;
[email protected]9b159a52013-10-03 17:24:5594
dmazzonie950ea232015-03-13 21:39:4595// static
vishal.b782eb5d2015-04-29 12:22:5796FrameTreeNode* FrameTreeNode::GloballyFindByID(int frame_tree_node_id) {
mostynb366eaf12015-03-26 00:51:1997 DCHECK_CURRENTLY_ON(BrowserThread::UI);
rob97250742015-12-10 17:45:1598 FrameTreeNodeIdMap* nodes = g_frame_tree_node_id_map.Pointer();
jdoerrie55ec69d2018-10-08 13:34:4699 auto it = nodes->find(frame_tree_node_id);
dmazzonie950ea232015-03-13 21:39:45100 return it == nodes->end() ? nullptr : it->second;
101}
102
Alexander Timin381e7e182020-04-28 19:04:03103// static
104FrameTreeNode* FrameTreeNode::From(RenderFrameHost* rfh) {
105 if (!rfh)
106 return nullptr;
107 return static_cast<RenderFrameHostImpl*>(rfh)->frame_tree_node();
108}
109
Julie Jeongeun Kim70a2e4e2020-02-21 05:09:54110FrameTreeNode::FrameTreeNode(
111 FrameTree* frame_tree,
Alexander Timin381e7e182020-04-28 19:04:03112 RenderFrameHostImpl* parent,
Antonio Gomes9d5c1ef2020-04-30 20:56:41113 blink::mojom::TreeScopeType scope,
Julie Jeongeun Kim70a2e4e2020-02-21 05:09:54114 const std::string& name,
115 const std::string& unique_name,
116 bool is_created_by_script,
117 const base::UnguessableToken& devtools_frame_token,
118 const blink::mojom::FrameOwnerProperties& frame_owner_properties,
Antonio Gomes58d38062020-04-30 01:50:14119 blink::mojom::FrameOwnerElementType owner_type)
[email protected]bffc8302014-01-23 20:52:16120 : frame_tree_(frame_tree),
[email protected]bffc8302014-01-23 20:52:16121 frame_tree_node_id_(next_frame_tree_node_id_++),
xiaochengh98488162016-05-19 15:17:59122 parent_(parent),
Alexander Timin381e7e182020-04-28 19:04:03123 depth_(parent ? parent->frame_tree_node()->depth_ + 1 : 0u),
Gyuyoung Kimc16e52e92021-03-19 02:45:37124 replication_state_(blink::mojom::FrameReplicationState::New(
Antonio Sartori90f41212021-01-22 10:08:34125 url::Origin(),
estarka886b8d2015-12-18 21:53:08126 name,
lukasza464d8692016-02-22 19:26:32127 unique_name,
Charlie Hue24f04832021-03-04 21:07:06128 blink::ParsedPermissionsPolicy(),
Antonio Sartori90f41212021-01-22 10:08:34129 network::mojom::WebSandboxFlags::kNone,
130 blink::FramePolicy(),
Antonio Sartori90f41212021-01-22 10:08:34131 scope,
Julie Jeongeun Kimd90e2dd2020-03-03 11:45:37132 blink::mojom::InsecureRequestPolicy::
133 kLeaveInsecureRequestsAlone /* should enforce strict mixed content
134 checking */
135 ,
arthursonzogni4b62a5cb2018-01-17 14:14:26136 std::vector<uint32_t>()
137 /* hashes of hosts for insecure request upgrades */,
japhet61835ae12017-01-20 01:25:39138 false /* is a potentially trustworthy unique origin */,
danakj359a4342020-05-29 20:38:39139 false /* has an active user gesture */,
Ehsan Karamad192a8da2018-10-21 03:48:08140 false /* has received a user gesture before nav */,
Antonio Sartori90f41212021-01-22 10:08:34141 owner_type,
142 blink::mojom::AdFrameType::kNonAd)),
Lukasz Anforowicz7bfb2e92017-11-22 17:19:45143 is_created_by_script_(is_created_by_script),
Pavel Feldman25234722017-10-11 02:49:06144 devtools_frame_token_(devtools_frame_token),
lazyboy70605c32015-11-03 01:27:31145 frame_owner_properties_(frame_owner_properties),
Lukasz Anforowicz147141962020-12-16 18:03:24146 blame_context_(frame_tree_node_id_, FrameTreeNode::From(parent)),
147 render_manager_(this, frame_tree->manager_delegate()) {
rob97250742015-12-10 17:45:15148 std::pair<FrameTreeNodeIdMap::iterator, bool> result =
dmazzonie950ea232015-03-13 21:39:45149 g_frame_tree_node_id_map.Get().insert(
150 std::make_pair(frame_tree_node_id_, this));
151 CHECK(result.second);
benjhaydend4da63d2016-03-11 21:29:33152
xiaochenghb9554bb2016-05-21 14:20:48153 // Note: this should always be done last in the constructor.
154 blame_context_.Initialize();
alexmos998581d2015-01-22 01:01:59155}
[email protected]9b159a52013-10-03 17:24:55156
157FrameTreeNode::~FrameTreeNode() {
Harkiran Bolaria59290d62021-03-17 01:53:01158 // The current frame host may be null when destroying the old frame tree
159 // during prerender activation. However, in such cases, the FrameTree and its
160 // root FrameTreeNode objects are deleted immediately with activation. In all
161 // other cases, there should always be a current frame host.
162 //
163 // TODO(https://crbug.com/1170277): Need to find a solution for being notified
164 // in various places. They do not support having no current_frame_host().
165 if (current_frame_host()) {
166 // Remove the children.
167 current_frame_host()->ResetChildren();
Lukasz Anforowicz7bfb2e92017-11-22 17:19:45168
Harkiran Bolaria59290d62021-03-17 01:53:01169 current_frame_host()->ResetLoadingState();
170 } else {
171 DCHECK(blink::features::IsPrerenderMPArchEnabled());
172 DCHECK(!parent()); // Only main documents can be activated.
173 DCHECK(!opener()); // Prerendered frame trees can't have openers.
174
175 // Activation is not allowed during ongoing navigations.
176 DCHECK(!navigation_request_);
177
178 // TODO(https://crbug.com/1170277): Need to determine how to handle pending
179 // deletions, as observers will be notified.
180 DCHECK(!render_manager()->speculative_frame_host());
181 }
Nate Chapin22ea6592019-03-05 22:29:02182
Lukasz Anforowicz7bfb2e92017-11-22 17:19:45183 // If the removed frame was created by a script, then its history entry will
184 // never be reused - we can save some memory by removing the history entry.
185 // See also https://crbug.com/784356.
186 if (is_created_by_script_ && parent_) {
Carlos Caballero04aab362021-02-15 17:38:16187 NavigationEntryImpl* nav_entry =
188 navigator().controller().GetLastCommittedEntry();
Lukasz Anforowicz7bfb2e92017-11-22 17:19:45189 if (nav_entry) {
190 nav_entry->RemoveEntryForFrame(this,
191 /* only_if_different_position = */ false);
192 }
193 }
194
dmazzonie950ea232015-03-13 21:39:45195 frame_tree_->FrameRemoved(this);
Carlos Caballero6ff6ace2021-02-05 16:53:00196
197 // Do not dispatch notification for the root frame as ~WebContentsImpl already
198 // dispatches it for now.
199 // TODO(https://crbug.com/1170277): This is only needed because the FrameTree
200 // is a member of WebContentsImpl and we would call back into it during
201 // destruction. We should clean up the FrameTree destruction code and call the
202 // delegate unconditionally.
203 if (parent())
204 render_manager_.delegate()->OnFrameTreeNodeDestroyed(this);
205
ericwilligers254597b2016-10-17 10:32:31206 for (auto& observer : observers_)
207 observer.OnFrameTreeNodeDestroyed(this);
Lukasz Anforowicz147141962020-12-16 18:03:24208 observers_.Clear();
alexmose201c7cd2015-06-10 17:14:21209
210 if (opener_)
211 opener_->RemoveObserver(opener_observer_.get());
jochen6004a362017-02-04 00:11:40212 if (original_opener_)
213 original_opener_->RemoveObserver(original_opener_observer_.get());
dmazzonie950ea232015-03-13 21:39:45214
215 g_frame_tree_node_id_map.Get().erase(frame_tree_node_id_);
jam39258caf2016-11-02 14:48:18216
danakjf9400602019-06-07 15:44:58217 bool did_stop_loading = false;
218
jam39258caf2016-11-02 14:48:18219 if (navigation_request_) {
danakjf9400602019-06-07 15:44:58220 navigation_request_.reset();
Arthur Hemery0dd65812019-08-01 14:18:45221 // If a frame with a pending navigation is detached, make sure the
222 // WebContents (and its observers) update their loading state.
danakjf9400602019-06-07 15:44:58223 did_stop_loading = true;
jam39258caf2016-11-02 14:48:18224 }
Nate Chapin22ea6592019-03-05 22:29:02225
danakjf9400602019-06-07 15:44:58226 // ~SiteProcessCountTracker DCHECKs in some tests if the speculative
227 // RenderFrameHostImpl is not destroyed last. Ideally this would be closer to
228 // (possible before) the ResetLoadingState() call above.
229 //
230 // There is an inherent race condition causing bugs 838348/915179/et al, where
231 // the renderer may have committed the speculative main frame and the browser
232 // has not heard about it yet. If this is a main frame, then in that case the
233 // speculative RenderFrame was unable to be deleted (it is owned by the
234 // renderer) and we should not be able to cancel the navigation at this point.
235 // CleanUpNavigation() would normally be called here but it will try to undo
236 // the navigation and expose the race condition. When it replaces the main
237 // frame with a RenderFrameProxy, that leaks the committed main frame, leaving
238 // the frame and its friend group with pointers that will become invalid
239 // shortly as we are shutting everything down and deleting the RenderView etc.
240 // We avoid this problematic situation by not calling CleanUpNavigation() or
241 // DiscardUnusedFrame() here. The speculative RenderFrameHost is simply
242 // returned and deleted immediately. This satisfies the requirement that the
243 // speculative RenderFrameHost is removed from the RenderFrameHostManager
244 // before it is destroyed.
245 if (render_manager_.speculative_frame_host()) {
246 did_stop_loading |= render_manager_.speculative_frame_host()->is_loading();
247 render_manager_.UnsetSpeculativeRenderFrameHost();
248 }
249
250 if (did_stop_loading)
251 DidStopLoading();
252
Harkiran Bolaria59290d62021-03-17 01:53:01253 // IsLoading() requires that current_frame_host() is non-null.
254 DCHECK(!current_frame_host() || !IsLoading());
[email protected]9b159a52013-10-03 17:24:55255}
256
alexmose201c7cd2015-06-10 17:14:21257void FrameTreeNode::AddObserver(Observer* observer) {
258 observers_.AddObserver(observer);
259}
260
261void FrameTreeNode::RemoveObserver(Observer* observer) {
262 observers_.RemoveObserver(observer);
263}
264
[email protected]94d0cc12013-12-18 00:07:41265bool FrameTreeNode::IsMainFrame() const {
266 return frame_tree_->root() == this;
267}
268
arthursonzogni76098e52020-11-25 14:18:45269void FrameTreeNode::ResetForNavigation(
Alexander Timin45b716c2020-11-06 01:40:31270 bool was_served_from_back_forward_cache) {
arthursonzogni76098e52020-11-25 14:18:45271 // This frame has had its user activation bits cleared in the renderer before
272 // arriving here. We just need to clear them here and in the other renderer
273 // processes that may have a reference to this frame.
Alexander Timin45b716c2020-11-06 01:40:31274 //
275 // We do not take user activation into account when calculating
276 // |ResetForNavigationResult|, as we are using it to determine bfcache
277 // eligibility and the page can get another user gesture after restore.
Antonio Gomes4b2c5132020-01-16 11:49:48278 UpdateUserActivationState(
Mustaq Ahmeddc195e5b2020-08-04 18:45:11279 blink::mojom::UserActivationUpdateType::kClearActivation,
280 blink::mojom::UserActivationNotificationType::kNone);
Ian Clelland5cbaaf82017-11-27 22:00:03281}
282
yilkal34a3d752019-08-30 18:20:30283size_t FrameTreeNode::GetFrameTreeSize() const {
284 if (is_collapsed())
285 return 0;
286
287 size_t size = 0;
288 for (size_t i = 0; i < child_count(); i++) {
289 size += child_at(i)->GetFrameTreeSize();
290 }
291
292 // Account for this node.
293 size++;
294 return size;
295}
296
alexmose201c7cd2015-06-10 17:14:21297void FrameTreeNode::SetOpener(FrameTreeNode* opener) {
298 if (opener_) {
299 opener_->RemoveObserver(opener_observer_.get());
300 opener_observer_.reset();
301 }
302
303 opener_ = opener;
304
305 if (opener_) {
Jeremy Roman04f27c372017-10-27 15:20:55306 opener_observer_ = std::make_unique<OpenerDestroyedObserver>(this, false);
alexmose201c7cd2015-06-10 17:14:21307 opener_->AddObserver(opener_observer_.get());
308 }
309}
310
Wolfgang Beyerd8809db2020-09-30 15:29:39311void FrameTreeNode::SetOpenerDevtoolsFrameToken(
312 base::UnguessableToken opener_devtools_frame_token) {
313 DCHECK(!opener_devtools_frame_token_ ||
314 opener_devtools_frame_token_->is_empty());
315 opener_devtools_frame_token_ = std::move(opener_devtools_frame_token);
316}
317
jochen6004a362017-02-04 00:11:40318void FrameTreeNode::SetOriginalOpener(FrameTreeNode* opener) {
Avi Drissman36465f332017-09-11 20:49:39319 // The original opener tracks main frames only.
avi8d1aa162017-03-27 18:27:37320 DCHECK(opener == nullptr || !opener->parent());
jochen6004a362017-02-04 00:11:40321
Avi Drissman36465f332017-09-11 20:49:39322 if (original_opener_) {
323 original_opener_->RemoveObserver(original_opener_observer_.get());
324 original_opener_observer_.reset();
325 }
326
jochen6004a362017-02-04 00:11:40327 original_opener_ = opener;
328
329 if (original_opener_) {
jochen6004a362017-02-04 00:11:40330 original_opener_observer_ =
Jeremy Roman04f27c372017-10-27 15:20:55331 std::make_unique<OpenerDestroyedObserver>(this, true);
jochen6004a362017-02-04 00:11:40332 original_opener_->AddObserver(original_opener_observer_.get());
333 }
334}
335
creisf0f069a2015-07-23 23:51:53336void FrameTreeNode::SetCurrentURL(const GURL& url) {
Balazs Engedyc8a7cccf2018-03-12 23:00:49337 if (!has_committed_real_load_ && !url.IsAboutBlank())
creisf0f069a2015-07-23 23:51:53338 has_committed_real_load_ = true;
Erik Chen173bf3042017-07-31 06:06:21339 current_frame_host()->SetLastCommittedUrl(url);
xiaochenghb9554bb2016-05-21 14:20:48340 blame_context_.TakeSnapshot();
creisf0f069a2015-07-23 23:51:53341}
342
estarkbd8e26f2016-03-16 23:30:37343void FrameTreeNode::SetCurrentOrigin(
344 const url::Origin& origin,
345 bool is_potentially_trustworthy_unique_origin) {
Antonio Sartori90f41212021-01-22 10:08:34346 if (!origin.IsSameOriginWith(replication_state_->origin) ||
347 replication_state_->has_potentially_trustworthy_unique_origin !=
estarkbd8e26f2016-03-16 23:30:37348 is_potentially_trustworthy_unique_origin) {
349 render_manager_.OnDidUpdateOrigin(origin,
350 is_potentially_trustworthy_unique_origin);
351 }
Antonio Sartori90f41212021-01-22 10:08:34352 replication_state_->origin = origin;
353 replication_state_->has_potentially_trustworthy_unique_origin =
estarkbd8e26f2016-03-16 23:30:37354 is_potentially_trustworthy_unique_origin;
alexmosa7a4ff822015-04-27 17:59:56355}
alexmosbe2f4c32015-03-10 02:30:23356
engedy6e2e0992017-05-25 18:58:42357void FrameTreeNode::SetCollapsed(bool collapsed) {
358 DCHECK(!IsMainFrame());
359 if (is_collapsed_ == collapsed)
360 return;
361
362 is_collapsed_ = collapsed;
363 render_manager_.OnDidChangeCollapsedState(collapsed);
364}
365
Harkiran Bolaria59290d62021-03-17 01:53:01366void FrameTreeNode::SetFrameTree(FrameTree& frame_tree) {
367 DCHECK(blink::features::IsPrerenderMPArchEnabled());
368 frame_tree_ = &frame_tree;
369}
370
lukasza464d8692016-02-22 19:26:32371void FrameTreeNode::SetFrameName(const std::string& name,
372 const std::string& unique_name) {
Antonio Sartori90f41212021-01-22 10:08:34373 if (name == replication_state_->name) {
lukasza464d8692016-02-22 19:26:32374 // |unique_name| shouldn't change unless |name| changes.
Antonio Sartori90f41212021-01-22 10:08:34375 DCHECK_EQ(unique_name, replication_state_->unique_name);
lukasza464d8692016-02-22 19:26:32376 return;
377 }
lukasza5140a412016-09-15 21:12:30378
379 if (parent()) {
380 // Non-main frames should have a non-empty unique name.
381 DCHECK(!unique_name.empty());
382 } else {
383 // Unique name of main frames should always stay empty.
384 DCHECK(unique_name.empty());
385 }
386
Daniel Cheng6ca7f1c92017-08-09 21:45:41387 // Note the unique name should only be able to change before the first real
388 // load is committed, but that's not strongly enforced here.
lukasza464d8692016-02-22 19:26:32389 render_manager_.OnDidUpdateName(name, unique_name);
Antonio Sartori90f41212021-01-22 10:08:34390 replication_state_->name = name;
391 replication_state_->unique_name = unique_name;
alexmosbe2f4c32015-03-10 02:30:23392}
393
mkwstf672e7ef2016-06-09 20:51:07394void FrameTreeNode::SetInsecureRequestPolicy(
Julie Jeongeun Kimd90e2dd2020-03-03 11:45:37395 blink::mojom::InsecureRequestPolicy policy) {
Antonio Sartori90f41212021-01-22 10:08:34396 if (policy == replication_state_->insecure_request_policy)
estarka886b8d2015-12-18 21:53:08397 return;
mkwstf672e7ef2016-06-09 20:51:07398 render_manager_.OnEnforceInsecureRequestPolicy(policy);
Antonio Sartori90f41212021-01-22 10:08:34399 replication_state_->insecure_request_policy = policy;
estarka886b8d2015-12-18 21:53:08400}
401
arthursonzogni4b62a5cb2018-01-17 14:14:26402void FrameTreeNode::SetInsecureNavigationsSet(
403 const std::vector<uint32_t>& insecure_navigations_set) {
404 DCHECK(std::is_sorted(insecure_navigations_set.begin(),
405 insecure_navigations_set.end()));
Antonio Sartori90f41212021-01-22 10:08:34406 if (insecure_navigations_set == replication_state_->insecure_navigations_set)
arthursonzogni4b62a5cb2018-01-17 14:14:26407 return;
408 render_manager_.OnEnforceInsecureNavigationsSet(insecure_navigations_set);
Antonio Sartori90f41212021-01-22 10:08:34409 replication_state_->insecure_navigations_set = insecure_navigations_set;
arthursonzogni4b62a5cb2018-01-17 14:14:26410}
411
Luna Luc3fdacdf2017-11-08 04:48:53412void FrameTreeNode::SetPendingFramePolicy(blink::FramePolicy frame_policy) {
Ian Clellandcdc4f312017-10-13 22:24:12413 pending_frame_policy_.sandbox_flags = frame_policy.sandbox_flags;
Dave Tapuska9b153a942020-02-10 19:35:10414 pending_frame_policy_.disallow_document_access =
415 frame_policy.disallow_document_access;
alexmos6e940102016-01-19 22:47:25416
Ian Clellandcdc4f312017-10-13 22:24:12417 if (parent()) {
418 // Subframes should always inherit their parent's sandbox flags.
Alexander Timin381e7e182020-04-28 19:04:03419 pending_frame_policy_.sandbox_flags |=
420 parent()->frame_tree_node()->active_sandbox_flags();
Charlie Hue1b77ac2019-12-13 21:30:17421 // This is only applied on subframes; container policy and required document
422 // policy are not mutable on main frame.
Ian Clellandcdc4f312017-10-13 22:24:12423 pending_frame_policy_.container_policy = frame_policy.container_policy;
Charlie Hue1b77ac2019-12-13 21:30:17424 pending_frame_policy_.required_document_policy =
425 frame_policy.required_document_policy;
Ian Clellandcdc4f312017-10-13 22:24:12426 }
iclelland92f8c0b2017-04-19 12:43:05427}
428
alexmos9f8705a2015-05-06 19:58:59429FrameTreeNode* FrameTreeNode::PreviousSibling() const {
paulmeyer322777fb2016-05-16 23:15:39430 return GetSibling(-1);
431}
alexmos9f8705a2015-05-06 19:58:59432
paulmeyer322777fb2016-05-16 23:15:39433FrameTreeNode* FrameTreeNode::NextSibling() const {
434 return GetSibling(1);
alexmos9f8705a2015-05-06 19:58:59435}
436
fdegans4a49ce932015-03-12 17:11:37437bool FrameTreeNode::IsLoading() const {
438 RenderFrameHostImpl* current_frame_host =
439 render_manager_.current_frame_host();
fdegans4a49ce932015-03-12 17:11:37440
441 DCHECK(current_frame_host);
fdegans39ff0382015-04-29 19:04:39442
clamy610c63b32017-12-22 15:05:18443 if (navigation_request_)
444 return true;
clamy11e11512015-07-07 16:42:17445
clamy610c63b32017-12-22 15:05:18446 RenderFrameHostImpl* speculative_frame_host =
447 render_manager_.speculative_frame_host();
448 if (speculative_frame_host && speculative_frame_host->is_loading())
449 return true;
fdegans4a49ce932015-03-12 17:11:37450 return current_frame_host->is_loading();
451}
452
Alex Moshchuk9b0fd822020-10-26 23:08:15453bool FrameTreeNode::HasPendingCrossDocumentNavigation() const {
454 // Having a |navigation_request_| on FrameTreeNode implies that there's an
455 // ongoing navigation that hasn't reached the ReadyToCommit state. If the
456 // navigation is between ReadyToCommit and DidCommitNavigation, the
457 // NavigationRequest will be held by RenderFrameHost, which is checked below.
458 if (navigation_request_ && !navigation_request_->IsSameDocument())
459 return true;
460
461 // Having a speculative RenderFrameHost should imply a cross-document
462 // navigation.
463 if (render_manager_.speculative_frame_host())
464 return true;
465
466 return render_manager_.current_frame_host()
467 ->HasPendingCommitForCrossDocumentNavigation();
468}
469
Charlie Hu5ffc0152019-12-06 15:59:53470bool FrameTreeNode::CommitFramePolicy(
471 const blink::FramePolicy& new_frame_policy) {
472 bool did_change_flags = new_frame_policy.sandbox_flags !=
Antonio Sartori90f41212021-01-22 10:08:34473 replication_state_->frame_policy.sandbox_flags;
iclelland92f8c0b2017-04-19 12:43:05474 bool did_change_container_policy =
Charlie Hu5ffc0152019-12-06 15:59:53475 new_frame_policy.container_policy !=
Antonio Sartori90f41212021-01-22 10:08:34476 replication_state_->frame_policy.container_policy;
Charlie Hue1b77ac2019-12-13 21:30:17477 bool did_change_required_document_policy =
478 pending_frame_policy_.required_document_policy !=
Antonio Sartori90f41212021-01-22 10:08:34479 replication_state_->frame_policy.required_document_policy;
Dave Tapuska9b153a942020-02-10 19:35:10480 bool did_change_document_access =
481 new_frame_policy.disallow_document_access !=
Antonio Sartori90f41212021-01-22 10:08:34482 replication_state_->frame_policy.disallow_document_access;
483 if (did_change_flags) {
484 replication_state_->frame_policy.sandbox_flags =
Charlie Hu5ffc0152019-12-06 15:59:53485 new_frame_policy.sandbox_flags;
Antonio Sartori90f41212021-01-22 10:08:34486 }
487 if (did_change_container_policy) {
488 replication_state_->frame_policy.container_policy =
Charlie Hu5ffc0152019-12-06 15:59:53489 new_frame_policy.container_policy;
Antonio Sartori90f41212021-01-22 10:08:34490 }
491 if (did_change_required_document_policy) {
492 replication_state_->frame_policy.required_document_policy =
Charlie Hue1b77ac2019-12-13 21:30:17493 new_frame_policy.required_document_policy;
Antonio Sartori90f41212021-01-22 10:08:34494 }
495 if (did_change_document_access) {
496 replication_state_->frame_policy.disallow_document_access =
Dave Tapuska9b153a942020-02-10 19:35:10497 new_frame_policy.disallow_document_access;
Antonio Sartori90f41212021-01-22 10:08:34498 }
Charlie Hue1b77ac2019-12-13 21:30:17499
Charlie Hu5ffc0152019-12-06 15:59:53500 UpdateFramePolicyHeaders(new_frame_policy.sandbox_flags,
Charlie Hue20fe2f2021-03-07 03:39:59501 replication_state_->permissions_policy_header);
Charlie Hue1b77ac2019-12-13 21:30:17502 return did_change_flags || did_change_container_policy ||
Dave Tapuska9b153a942020-02-10 19:35:10503 did_change_required_document_policy || did_change_document_access;
alexmos6b294562015-03-05 19:24:10504}
505
Arthur Hemeryc3380172018-01-22 14:00:17506void FrameTreeNode::TransferNavigationRequestOwnership(
507 RenderFrameHostImpl* render_frame_host) {
Andrey Kosyakovf2d4ff72018-10-29 20:09:59508 devtools_instrumentation::OnResetNavigationRequest(navigation_request_.get());
Arthur Hemeryc3380172018-01-22 14:00:17509 render_frame_host->SetNavigationRequest(std::move(navigation_request_));
510}
511
carloskc49005eb2015-06-16 11:25:07512void FrameTreeNode::CreatedNavigationRequest(
dcheng9bfa5162016-04-09 01:00:57513 std::unique_ptr<NavigationRequest> navigation_request) {
arthursonzognic79c251c2016-08-18 15:00:37514 // This is never called when navigating to a Javascript URL. For the loading
515 // state, this matches what Blink is doing: Blink doesn't send throbber
516 // notifications for Javascript URLS.
517 DCHECK(!navigation_request->common_params().url.SchemeIs(
518 url::kJavaScriptScheme));
519
clamy44e84ce2016-02-22 15:38:25520 bool was_previously_loading = frame_tree()->IsLoading();
521
clamy82a2f4d2016-02-02 14:20:41522 // There's no need to reset the state: there's still an ongoing load, and the
523 // RenderFrameHostManager will take care of updates to the speculative
524 // RenderFrameHost in DidCreateNavigationRequest below.
jamcd0b7b22017-03-24 22:13:05525 if (was_previously_loading) {
Mohamed Abdelhalimf03d4a22019-10-01 13:34:31526 if (navigation_request_ && navigation_request_->IsNavigationStarted()) {
jamcd0b7b22017-03-24 22:13:05527 // Mark the old request as aborted.
Mohamed Abdelhalimb4db22a2019-06-18 10:46:52528 navigation_request_->set_net_error(net::ERR_ABORTED);
jamcd0b7b22017-03-24 22:13:05529 }
Arthur Hemery241b9392019-10-24 11:08:41530 ResetNavigationRequest(true);
jamcd0b7b22017-03-24 22:13:05531 }
clamy44e84ce2016-02-22 15:38:25532
533 navigation_request_ = std::move(navigation_request);
Shubhie Panickerddf2a4e2018-03-06 00:09:06534 if (was_discarded_) {
535 navigation_request_->set_was_discarded();
536 was_discarded_ = false;
537 }
clamy8e2e299202016-04-05 11:44:59538 render_manager()->DidCreateNavigationRequest(navigation_request_.get());
fdegans39ff0382015-04-29 19:04:39539
Lucas Furukawa Gadanief8290a2019-07-29 20:27:51540 bool to_different_document = !NavigationTypeUtils::IsSameDocument(
arthursonzogni92f18682017-02-08 23:00:04541 navigation_request_->common_params().navigation_type);
542
543 DidStartLoading(to_different_document, was_previously_loading);
clamydcb434c12015-04-16 19:29:16544}
545
Arthur Hemery241b9392019-10-24 11:08:41546void FrameTreeNode::ResetNavigationRequest(bool keep_state) {
fdegans39ff0382015-04-29 19:04:39547 if (!navigation_request_)
548 return;
John Abd-El-Malekdcc7bf42017-09-12 22:30:23549
Andrey Kosyakovf2d4ff72018-10-29 20:09:59550 devtools_instrumentation::OnResetNavigationRequest(navigation_request_.get());
clamydcb434c12015-04-16 19:29:16551 navigation_request_.reset();
fdegans39ff0382015-04-29 19:04:39552
clamy82a2f4d2016-02-02 14:20:41553 if (keep_state)
fdegans39ff0382015-04-29 19:04:39554 return;
555
clamy82a2f4d2016-02-02 14:20:41556 // The RenderFrameHostManager should clean up any speculative RenderFrameHost
557 // it created for the navigation. Also register that the load stopped.
fdegans39ff0382015-04-29 19:04:39558 DidStopLoading();
559 render_manager_.CleanUpNavigation();
clamydcb434c12015-04-16 19:29:16560}
561
clamy44e84ce2016-02-22 15:38:25562void FrameTreeNode::DidStartLoading(bool to_different_document,
563 bool was_previously_loading) {
Camille Lamyefd54b02018-10-04 16:54:14564 TRACE_EVENT2("navigation", "FrameTreeNode::DidStartLoading",
565 "frame_tree_node", frame_tree_node_id(), "to different document",
566 to_different_document);
fdegansa696e5112015-04-17 01:57:59567
Carlos Caballero03262522021-02-05 14:49:58568 frame_tree_->DidStartLoadingNode(*this, to_different_document,
569 was_previously_loading);
fdegansa696e5112015-04-17 01:57:59570
571 // Set initial load progress and update overall progress. This will notify
572 // the WebContents of the load progress change.
573 DidChangeLoadProgress(kLoadingProgressMinimum);
574
575 // Notify the RenderFrameHostManager of the event.
576 render_manager()->OnDidStartLoading();
577}
578
579void FrameTreeNode::DidStopLoading() {
Camille Lamyefd54b02018-10-04 16:54:14580 TRACE_EVENT1("navigation", "FrameTreeNode::DidStopLoading", "frame_tree_node",
581 frame_tree_node_id());
fdegansa696e5112015-04-17 01:57:59582 // Set final load progress and update overall progress. This will notify
583 // the WebContents of the load progress change.
584 DidChangeLoadProgress(kLoadingProgressDone);
585
Lucas Furukawa Gadani6faef602019-05-06 21:16:03586 // Notify the RenderFrameHostManager of the event.
587 render_manager()->OnDidStopLoading();
588
Carlos Caballero03262522021-02-05 14:49:58589 frame_tree_->DidStopLoadingNode(*this);
fdegansa696e5112015-04-17 01:57:59590}
591
592void FrameTreeNode::DidChangeLoadProgress(double load_progress) {
Nate Chapin93536702018-02-07 00:12:21593 DCHECK_GE(load_progress, kLoadingProgressMinimum);
594 DCHECK_LE(load_progress, kLoadingProgressDone);
Carlos Caballero03262522021-02-05 14:49:58595 frame_tree_->DidChangeLoadProgressForNode(*this, load_progress);
fdegansa696e5112015-04-17 01:57:59596}
597
clamyf73862c42015-07-08 12:31:33598bool FrameTreeNode::StopLoading() {
arthursonzogni66f711c2019-10-08 14:40:36599 if (navigation_request_ && navigation_request_->IsNavigationStarted())
600 navigation_request_->set_net_error(net::ERR_ABORTED);
Arthur Hemery241b9392019-10-24 11:08:41601 ResetNavigationRequest(false);
clamyf73862c42015-07-08 12:31:33602
clamyf73862c42015-07-08 12:31:33603 if (!IsMainFrame())
604 return true;
605
606 render_manager_.Stop();
607 return true;
608}
609
alexmos21acae52015-11-07 01:04:43610void FrameTreeNode::DidFocus() {
611 last_focus_time_ = base::TimeTicks::Now();
ericwilligers254597b2016-10-17 10:32:31612 for (auto& observer : observers_)
613 observer.OnFrameTreeNodeFocused(this);
alexmos21acae52015-11-07 01:04:43614}
615
clamy44e84ce2016-02-22 15:38:25616void FrameTreeNode::BeforeUnloadCanceled() {
617 // TODO(clamy): Support BeforeUnload in subframes.
618 if (!IsMainFrame())
619 return;
620
621 RenderFrameHostImpl* current_frame_host =
622 render_manager_.current_frame_host();
623 DCHECK(current_frame_host);
624 current_frame_host->ResetLoadingState();
625
clamy610c63b32017-12-22 15:05:18626 RenderFrameHostImpl* speculative_frame_host =
627 render_manager_.speculative_frame_host();
628 if (speculative_frame_host)
629 speculative_frame_host->ResetLoadingState();
Alexander Timin23c110b2021-01-14 02:39:04630 // Note: there is no need to set an error code on the NavigationHandle as
631 // the observers have not been notified about its creation.
632 // We also reset navigation request only when this navigation request was
633 // responsible for this dialog, as a new navigation request might cancel
634 // existing unrelated dialog.
635 if (navigation_request_ && navigation_request_->IsWaitingForBeforeUnload())
Arthur Hemery241b9392019-10-24 11:08:41636 ResetNavigationRequest(false);
clamy44e84ce2016-02-22 15:38:25637}
638
Mustaq Ahmedecb5c38e2020-07-29 00:34:30639bool FrameTreeNode::NotifyUserActivation(
640 blink::mojom::UserActivationNotificationType notification_type) {
Alex Moshchuk03904192021-04-02 07:29:08641 // User Activation V2 requires activating all ancestor frames in addition to
642 // the current frame. See
643 // https://html.spec.whatwg.org/multipage/interaction.html#tracking-user-activation.
Alexander Timina1dfadaa2020-04-28 13:30:06644 for (RenderFrameHostImpl* rfh = current_frame_host(); rfh;
645 rfh = rfh->GetParent()) {
John Delaneyb625dca92021-04-14 17:00:34646 rfh->DidReceiveUserActivation();
Mustaq Ahmedecb5c38e2020-07-29 00:34:30647 rfh->frame_tree_node()->user_activation_state_.Activate(notification_type);
John Delaneyedd8d6c2019-01-25 00:23:57648 }
Alex Moshchuk03904192021-04-02 07:29:08649
Antonio Sartori90f41212021-01-22 10:08:34650 replication_state_->has_active_user_gesture = true;
Mustaq Ahmeda5dfa60b2018-12-08 00:30:14651
Mustaq Ahmed0180320f2019-03-21 16:07:01652 // See the "Same-origin Visibility" section in |UserActivationState| class
653 // doc.
Mustaq Ahmede5f12562019-10-30 18:02:03654 if (base::FeatureList::IsEnabled(
Mustaq Ahmeda5dfa60b2018-12-08 00:30:14655 features::kUserActivationSameOriginVisibility)) {
656 const url::Origin& current_origin =
657 this->current_frame_host()->GetLastCommittedOrigin();
658 for (FrameTreeNode* node : frame_tree()->Nodes()) {
659 if (node->current_frame_host()->GetLastCommittedOrigin().IsSameOriginWith(
660 current_origin)) {
Mustaq Ahmedecb5c38e2020-07-29 00:34:30661 node->user_activation_state_.Activate(notification_type);
Mustaq Ahmeda5dfa60b2018-12-08 00:30:14662 }
663 }
664 }
665
Carlos Caballero40b0efd2021-01-26 11:55:00666 navigator().controller().NotifyUserActivation();
Alex Moshchuk03904192021-04-02 07:29:08667 current_frame_host()->MaybeIsolateForUserActivation();
Shivani Sharma194877032019-03-07 17:52:47668
Mustaq Ahmedc4cb7162018-06-05 16:28:36669 return true;
670}
671
672bool FrameTreeNode::ConsumeTransientUserActivation() {
673 bool was_active = user_activation_state_.IsActive();
674 for (FrameTreeNode* node : frame_tree()->Nodes())
675 node->user_activation_state_.ConsumeIfActive();
Antonio Sartori90f41212021-01-22 10:08:34676 replication_state_->has_active_user_gesture = false;
Mustaq Ahmedc4cb7162018-06-05 16:28:36677 return was_active;
678}
679
Shivani Sharmac4f561582018-11-15 15:58:39680bool FrameTreeNode::ClearUserActivation() {
Shivani Sharmac4f561582018-11-15 15:58:39681 for (FrameTreeNode* node : frame_tree()->SubtreeNodes(this))
682 node->user_activation_state_.Clear();
Antonio Sartori90f41212021-01-22 10:08:34683 replication_state_->has_active_user_gesture = false;
Shivani Sharmac4f561582018-11-15 15:58:39684 return true;
685}
686
Ella Ge9caed612019-08-09 16:17:25687bool FrameTreeNode::VerifyUserActivation() {
Ella Gea78f6772019-12-11 10:35:25688 DCHECK(base::FeatureList::IsEnabled(
689 features::kBrowserVerifiedUserActivationMouse) ||
690 base::FeatureList::IsEnabled(
691 features::kBrowserVerifiedUserActivationKeyboard));
692
Ella Ge9caed612019-08-09 16:17:25693 return render_manager_.current_frame_host()
694 ->GetRenderWidgetHost()
Mustaq Ahmed83bb1722019-10-22 20:00:10695 ->RemovePendingUserActivationIfAvailable();
Ella Ge9caed612019-08-09 16:17:25696}
697
Mustaq Ahmedc4cb7162018-06-05 16:28:36698bool FrameTreeNode::UpdateUserActivationState(
Mustaq Ahmeddc195e5b2020-08-04 18:45:11699 blink::mojom::UserActivationUpdateType update_type,
700 blink::mojom::UserActivationNotificationType notification_type) {
Ella Ge9caed612019-08-09 16:17:25701 bool update_result = false;
Mustaq Ahmedc4cb7162018-06-05 16:28:36702 switch (update_type) {
Antonio Gomes4b2c5132020-01-16 11:49:48703 case blink::mojom::UserActivationUpdateType::kConsumeTransientActivation:
Ella Ge9caed612019-08-09 16:17:25704 update_result = ConsumeTransientUserActivation();
705 break;
Antonio Gomes4b2c5132020-01-16 11:49:48706 case blink::mojom::UserActivationUpdateType::kNotifyActivation:
Mustaq Ahmeddc195e5b2020-08-04 18:45:11707 update_result = NotifyUserActivation(notification_type);
Ella Ge9caed612019-08-09 16:17:25708 break;
Antonio Gomes4b2c5132020-01-16 11:49:48709 case blink::mojom::UserActivationUpdateType::
Liviu Tintad9391fb92020-09-28 23:50:07710 kNotifyActivationPendingBrowserVerification: {
711 const bool user_activation_verified = VerifyUserActivation();
712 // Add UMA metric for when browser user activation verification succeeds
713 base::UmaHistogramBoolean("Event.BrowserVerifiedUserActivation",
714 user_activation_verified);
715 if (user_activation_verified) {
Mustaq Ahmedecb5c38e2020-07-29 00:34:30716 update_result = NotifyUserActivation(
Mustaq Ahmed2cfb0402020-09-29 19:24:35717 blink::mojom::UserActivationNotificationType::kInteraction);
Antonio Gomes4b2c5132020-01-16 11:49:48718 update_type = blink::mojom::UserActivationUpdateType::kNotifyActivation;
Ella Ge9caed612019-08-09 16:17:25719 } else {
arthursonzogni9816b9192021-03-29 16:09:19720 // TODO(https://crbug.com/848778): We need to decide what to do when
721 // user activation verification failed. NOTREACHED here will make all
Ella Ge9caed612019-08-09 16:17:25722 // unrelated tests that inject event to renderer fail.
723 return false;
724 }
Liviu Tintad9391fb92020-09-28 23:50:07725 } break;
Antonio Gomes4b2c5132020-01-16 11:49:48726 case blink::mojom::UserActivationUpdateType::kClearActivation:
Ella Ge9caed612019-08-09 16:17:25727 update_result = ClearUserActivation();
728 break;
Mustaq Ahmedc4cb7162018-06-05 16:28:36729 }
Mustaq Ahmeddc195e5b2020-08-04 18:45:11730 render_manager_.UpdateUserActivationState(update_type, notification_type);
Ella Ge9caed612019-08-09 16:17:25731 return update_result;
japhet61835ae12017-01-20 01:25:39732}
733
Mustaq Ahmed01261742019-12-16 15:49:06734void FrameTreeNode::OnSetHadStickyUserActivationBeforeNavigation(bool value) {
735 render_manager_.OnSetHadStickyUserActivationBeforeNavigation(value);
Antonio Sartori90f41212021-01-22 10:08:34736 replication_state_->has_received_user_gesture_before_nav = value;
Becca Hughes60af7d42017-12-12 10:53:15737}
738
paulmeyer322777fb2016-05-16 23:15:39739FrameTreeNode* FrameTreeNode::GetSibling(int relative_offset) const {
paulmeyerf3119f52016-05-17 17:37:19740 if (!parent_ || !parent_->child_count())
paulmeyer322777fb2016-05-16 23:15:39741 return nullptr;
742
743 for (size_t i = 0; i < parent_->child_count(); ++i) {
744 if (parent_->child_at(i) == this) {
745 if ((relative_offset < 0 && static_cast<size_t>(-relative_offset) > i) ||
746 i + relative_offset >= parent_->child_count()) {
747 return nullptr;
748 }
749 return parent_->child_at(i + relative_offset);
750 }
751 }
752
753 NOTREACHED() << "FrameTreeNode not found in its parent's children.";
754 return nullptr;
755}
756
Alexander Timin45b716c2020-11-06 01:40:31757bool FrameTreeNode::UpdateFramePolicyHeaders(
arthursonzognib93a4472020-04-10 07:38:00758 network::mojom::WebSandboxFlags sandbox_flags,
Charlie Hue24f04832021-03-04 21:07:06759 const blink::ParsedPermissionsPolicy& parsed_header) {
Ian Clellandedb8c5dd2018-03-01 17:01:37760 bool changed = false;
Charlie Hue20fe2f2021-03-07 03:39:59761 if (replication_state_->permissions_policy_header != parsed_header) {
762 replication_state_->permissions_policy_header = parsed_header;
Ian Clellandedb8c5dd2018-03-01 17:01:37763 changed = true;
764 }
Ian Clelland5cbaaf82017-11-27 22:00:03765 // TODO(iclelland): Kill the renderer if sandbox flags is not a subset of the
766 // currently effective sandbox flags from the frame. https://crbug.com/740556
arthursonzognib93a4472020-04-10 07:38:00767 network::mojom::WebSandboxFlags updated_flags =
Ian Clelland5cbaaf82017-11-27 22:00:03768 sandbox_flags | effective_frame_policy().sandbox_flags;
Antonio Sartori90f41212021-01-22 10:08:34769 if (replication_state_->active_sandbox_flags != updated_flags) {
770 replication_state_->active_sandbox_flags = updated_flags;
Ian Clellandedb8c5dd2018-03-01 17:01:37771 changed = true;
772 }
773 // Notify any proxies if the policies have been changed.
774 if (changed)
775 render_manager()->OnDidSetFramePolicyHeaders();
Alexander Timin45b716c2020-11-06 01:40:31776 return changed;
Ian Clelland5cbaaf82017-11-27 22:00:03777}
778
Arthur Sonzognif8840b92018-11-07 14:10:35779void FrameTreeNode::PruneChildFrameNavigationEntries(
780 NavigationEntryImpl* entry) {
781 for (size_t i = 0; i < current_frame_host()->child_count(); ++i) {
782 FrameTreeNode* child = current_frame_host()->child_at(i);
783 if (child->is_created_by_script_) {
784 entry->RemoveEntryForFrame(child,
785 /* only_if_different_position = */ false);
786 } else {
787 child->PruneChildFrameNavigationEntries(entry);
788 }
789 }
790}
791
Yao Xiao24ec9aa2020-01-28 16:36:00792void FrameTreeNode::SetAdFrameType(blink::mojom::AdFrameType ad_frame_type) {
Alex Turner5a09c462021-03-17 17:07:35793 if (ad_frame_type == replication_state_->ad_frame_type)
794 return;
795
796 replication_state_->ad_frame_type = ad_frame_type;
797 render_manager()->OnDidSetAdFrameType(ad_frame_type);
Yao Xiao24ec9aa2020-01-28 16:36:00798}
799
arthursonzogni034bb9c2020-10-01 08:29:56800void FrameTreeNode::SetInitialPopupURL(const GURL& initial_popup_url) {
801 DCHECK(initial_popup_url_.is_empty());
802 DCHECK(!has_committed_real_load_);
803 initial_popup_url_ = initial_popup_url;
804}
805
806void FrameTreeNode::SetPopupCreatorOrigin(
807 const url::Origin& popup_creator_origin) {
808 DCHECK(!has_committed_real_load_);
809 popup_creator_origin_ = popup_creator_origin;
810}
811
Alexander Timinf785f342021-03-18 00:00:56812void FrameTreeNode::WriteIntoTracedValue(perfetto::TracedValue context) const {
813 auto dict = std::move(context).WriteDictionary();
814 dict.Add("id", frame_tree_node_id());
815 dict.Add("is_main_frame", IsMainFrame());
816}
817
Carlos Caballero76711352021-03-24 17:38:21818bool FrameTreeNode::HasNavigation() {
819 if (navigation_request())
820 return true;
821
822 // Same-RenderFrameHost navigation is committing:
823 if (current_frame_host()->HasPendingCommitNavigation())
824 return true;
825
826 // Cross-RenderFrameHost navigation is committing:
827 if (render_manager()->speculative_frame_host())
828 return true;
829
830 return false;
831}
832
[email protected]9b159a52013-10-03 17:24:55833} // namespace content