blob: 60fece03b17daa20c21cf992f8d98365e2ddfefc [file] [log] [blame]
Avi Drissman4e1b7bc32022-09-15 14:03:501// Copyright 2013 The Chromium Authors
[email protected]9b159a52013-10-03 17:24:552// 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.h"
[email protected]9b159a52013-10-03 17:24:556
avib7348942015-12-25 20:57:107#include <stddef.h>
8
[email protected]9b159a52013-10-03 17:24:559#include <queue>
Lukasz Anforowicz7bfb2e92017-11-22 17:19:4510#include <set>
dcheng29f5a6c2015-08-31 21:43:2711#include <utility>
[email protected]9b159a52013-10-03 17:24:5512
13#include "base/bind.h"
14#include "base/callback.h"
Lei Zhangde197672021-04-29 08:11:2415#include "base/containers/contains.h"
Rakina Zata Amni80700402021-09-20 17:18:0316#include "base/debug/dump_without_crashing.h"
[email protected]20edca72014-08-14 10:27:5317#include "base/lazy_instance.h"
dcheng9bfa5162016-04-09 01:00:5718#include "base/memory/ptr_util.h"
Peter Kastingd5685942022-09-02 17:52:1719#include "base/ranges/algorithm.h"
Carlos Caballeroede6f8c2021-01-28 11:01:5020#include "base/trace_event/optional_trace_event.h"
Rakina Zata Amni4b1968d2021-09-09 03:29:4721#include "base/trace_event/typed_macros.h"
Pavel Feldman25234722017-10-11 02:49:0622#include "base/unguessable_token.h"
danakjc492bf82020-09-09 20:02:4423#include "content/browser/renderer_host/frame_tree_node.h"
24#include "content/browser/renderer_host/navigation_controller_impl.h"
25#include "content/browser/renderer_host/navigation_entry_impl.h"
26#include "content/browser/renderer_host/navigation_request.h"
27#include "content/browser/renderer_host/navigator.h"
28#include "content/browser/renderer_host/navigator_delegate.h"
Sreeja Kamishetty0be3b1b2021-08-12 17:04:1529#include "content/browser/renderer_host/page_impl.h"
Kevin McNee5f594382021-05-06 23:18:2330#include "content/browser/renderer_host/render_frame_host_delegate.h"
danakjc492bf82020-09-09 20:02:4431#include "content/browser/renderer_host/render_frame_host_factory.h"
32#include "content/browser/renderer_host/render_frame_host_impl.h"
33#include "content/browser/renderer_host/render_frame_proxy_host.h"
Carlos Caballero101ac26b2021-03-24 11:54:0534#include "content/browser/renderer_host/render_view_host_delegate.h"
[email protected]94d0cc12013-12-18 00:07:4135#include "content/browser/renderer_host/render_view_host_factory.h"
36#include "content/browser/renderer_host/render_view_host_impl.h"
japhet98e9bd82016-06-28 23:48:4537#include "content/common/content_switches_internal.h"
Sreeja Kamishetty46f762c2021-02-05 07:52:4638#include "third_party/blink/public/common/features.h"
Kevin McNee43fe8292021-10-04 22:59:4139#include "third_party/blink/public/common/frame/frame_owner_element_type.h"
Blink Reformata30d4232018-04-07 15:31:0640#include "third_party/blink/public/common/frame/frame_policy.h"
Sreeja Kamishetty0be3b1b2021-08-12 17:04:1541#include "third_party/blink/public/common/loader/loader_constants.h"
Julie Jeongeun Kim70a2e4e2020-02-21 05:09:5442#include "third_party/blink/public/mojom/frame/frame_owner_properties.mojom.h"
[email protected]9b159a52013-10-03 17:24:5543
44namespace content {
45
46namespace {
[email protected]20edca72014-08-14 10:27:5347
Rakina Zata Amni4b1968d2021-09-09 03:29:4748using perfetto::protos::pbzero::ChromeTrackEvent;
49
Sharon Yangefe52632022-03-08 23:06:0650// Helper function to collect SiteInstanceGroups involved in rendering a single
51// FrameTree (which is a subset of SiteInstanceGroups in main frame's
52// proxy_hosts_ because of openers).
53std::set<SiteInstanceGroup*> CollectSiteInstanceGroups(FrameTree* tree) {
54 std::set<SiteInstanceGroup*> groups;
dcheng57e39e22016-01-21 00:25:3855 for (FrameTreeNode* node : tree->Nodes())
Sharon Yangefe52632022-03-08 23:06:0656 groups.insert(node->current_frame_host()->GetSiteInstance()->group());
57 return groups;
alexmos3fcd0ca2015-10-23 18:18:3358}
59
Kevin McNee5f594382021-05-06 23:18:2360// If |node| is the placeholder FrameTreeNode for an embedded frame tree,
61// returns the inner tree's main frame's FrameTreeNode. Otherwise, returns null.
62FrameTreeNode* GetInnerTreeMainFrameNode(FrameTreeNode* node) {
Dominic Farolino377edb302021-07-29 05:57:1863 FrameTreeNode* inner_main_frame_tree_node = FrameTreeNode::GloballyFindByID(
64 node->current_frame_host()->inner_tree_main_frame_tree_node_id());
Kevin McNee5f594382021-05-06 23:18:2365
Kevin McNeed459ad42022-09-12 19:24:5966 if (inner_main_frame_tree_node) {
67 DCHECK_NE(node->frame_tree(), inner_main_frame_tree_node->frame_tree());
Kevin McNee5f594382021-05-06 23:18:2368 }
69
Kevin McNeed459ad42022-09-12 19:24:5970 return inner_main_frame_tree_node;
Kevin McNee5f594382021-05-06 23:18:2371}
72
[email protected]9b159a52013-10-03 17:24:5573} // namespace
74
vmpstr33895d992016-02-24 20:55:2175FrameTree::NodeIterator::NodeIterator(const NodeIterator& other) = default;
76
Fergal Daly55b6d722020-09-11 07:56:3377FrameTree::NodeIterator::~NodeIterator() = default;
dcheng57e39e22016-01-21 00:25:3878
79FrameTree::NodeIterator& FrameTree::NodeIterator::operator++() {
Alex Moshchuk27caae82017-09-11 23:11:1880 if (current_node_ != root_of_subtree_to_skip_) {
Jayson Adams4db0bfe22021-07-15 19:24:0781 // Reserve enough space in the queue to accommodate the nodes we're
82 // going to add, to avoid repeated resize calls.
83 queue_.reserve(queue_.size() + current_node_->child_count());
84
Alex Moshchuk27caae82017-09-11 23:11:1885 for (size_t i = 0; i < current_node_->child_count(); ++i) {
86 FrameTreeNode* child = current_node_->child_at(i);
Kevin McNee5f594382021-05-06 23:18:2387 FrameTreeNode* inner_tree_main_ftn = GetInnerTreeMainFrameNode(child);
Jayson Adams4db0bfe22021-07-15 19:24:0788 queue_.push_back((should_descend_into_inner_trees_ && inner_tree_main_ftn)
89 ? inner_tree_main_ftn
90 : child);
Kevin McNee5f594382021-05-06 23:18:2391 }
92
93 if (should_descend_into_inner_trees_) {
Jayson Adams4db0bfe22021-07-15 19:24:0794 auto unattached_nodes =
95 current_node_->current_frame_host()
96 ->delegate()
97 ->GetUnattachedOwnedNodes(current_node_->current_frame_host());
98
99 // Reserve enough space in the queue to accommodate the nodes we're
100 // going to add.
101 queue_.reserve(queue_.size() + unattached_nodes.size());
102
103 for (auto* unattached_node : unattached_nodes) {
104 queue_.push_back(unattached_node);
Kevin McNee5f594382021-05-06 23:18:23105 }
Alex Moshchuk27caae82017-09-11 23:11:18106 }
dcheng57e39e22016-01-21 00:25:38107 }
108
Kevin McNee5f594382021-05-06 23:18:23109 AdvanceNode();
110 return *this;
111}
dcheng57e39e22016-01-21 00:25:38112
Kevin McNee5f594382021-05-06 23:18:23113FrameTree::NodeIterator& FrameTree::NodeIterator::AdvanceSkippingChildren() {
114 AdvanceNode();
dcheng57e39e22016-01-21 00:25:38115 return *this;
116}
117
118bool FrameTree::NodeIterator::operator==(const NodeIterator& rhs) const {
119 return current_node_ == rhs.current_node_;
120}
121
Kevin McNee5f594382021-05-06 23:18:23122void FrameTree::NodeIterator::AdvanceNode() {
123 if (!queue_.empty()) {
124 current_node_ = queue_.front();
Jayson Adams4db0bfe22021-07-15 19:24:07125 queue_.pop_front();
Kevin McNee5f594382021-05-06 23:18:23126 } else {
127 current_node_ = nullptr;
128 }
129}
130
131FrameTree::NodeIterator::NodeIterator(
132 const std::vector<FrameTreeNode*>& starting_nodes,
133 const FrameTreeNode* root_of_subtree_to_skip,
134 bool should_descend_into_inner_trees)
135 : current_node_(nullptr),
136 root_of_subtree_to_skip_(root_of_subtree_to_skip),
137 should_descend_into_inner_trees_(should_descend_into_inner_trees),
Jayson Adams4db0bfe22021-07-15 19:24:07138 queue_(starting_nodes.begin(), starting_nodes.end()) {
Kevin McNee5f594382021-05-06 23:18:23139 AdvanceNode();
140}
dcheng57e39e22016-01-21 00:25:38141
142FrameTree::NodeIterator FrameTree::NodeRange::begin() {
W. James MacLeance3176d2019-10-18 04:01:45143 // We shouldn't be attempting a frame tree traversal while the tree is
Kevin McNee5f594382021-05-06 23:18:23144 // being constructed or destructed.
Peter Kastingd5685942022-09-02 17:52:17145 DCHECK(base::ranges::all_of(starting_nodes_, [](FrameTreeNode* ftn) {
146 return ftn->current_frame_host();
147 }));
Kevin McNee5f594382021-05-06 23:18:23148
149 return NodeIterator(starting_nodes_, root_of_subtree_to_skip_,
150 should_descend_into_inner_trees_);
dcheng57e39e22016-01-21 00:25:38151}
152
153FrameTree::NodeIterator FrameTree::NodeRange::end() {
Kevin McNee5f594382021-05-06 23:18:23154 return NodeIterator({}, nullptr, should_descend_into_inner_trees_);
dcheng57e39e22016-01-21 00:25:38155}
156
Kevin McNee5f594382021-05-06 23:18:23157FrameTree::NodeRange::NodeRange(
158 const std::vector<FrameTreeNode*>& starting_nodes,
159 const FrameTreeNode* root_of_subtree_to_skip,
160 bool should_descend_into_inner_trees)
161 : starting_nodes_(starting_nodes),
162 root_of_subtree_to_skip_(root_of_subtree_to_skip),
163 should_descend_into_inner_trees_(should_descend_into_inner_trees) {}
164
165FrameTree::NodeRange::NodeRange(const NodeRange&) = default;
166FrameTree::NodeRange::~NodeRange() = default;
dcheng57e39e22016-01-21 00:25:38167
Carlos Caballero40b0efd2021-01-26 11:55:00168FrameTree::FrameTree(
169 BrowserContext* browser_context,
Carlos Caballero03262522021-02-05 14:49:58170 Delegate* delegate,
Carlos Caballero40b0efd2021-01-26 11:55:00171 NavigationControllerDelegate* navigation_controller_delegate,
172 NavigatorDelegate* navigator_delegate,
173 RenderFrameHostDelegate* render_frame_delegate,
174 RenderViewHostDelegate* render_view_delegate,
175 RenderWidgetHostDelegate* render_widget_delegate,
Sreeja Kamishetty837a10402021-04-23 12:41:59176 RenderFrameHostManager::Delegate* manager_delegate,
Jeremy Roman2d8dfe132021-07-06 20:51:26177 PageDelegate* page_delegate,
Dave Tapuska144570102022-08-02 19:28:27178 Type type,
179 const base::UnguessableToken& devtools_frame_token)
Carlos Caballero03262522021-02-05 14:49:58180 : delegate_(delegate),
181 render_frame_delegate_(render_frame_delegate),
[email protected]92404c62013-12-04 16:40:46182 render_view_delegate_(render_view_delegate),
[email protected]fa944cb82013-11-15 17:51:21183 render_widget_delegate_(render_widget_delegate),
184 manager_delegate_(manager_delegate),
Jeremy Roman2d8dfe132021-07-06 20:51:26185 page_delegate_(page_delegate),
Carlos Caballero40b0efd2021-01-26 11:55:00186 navigator_(browser_context,
187 *this,
188 navigator_delegate,
189 navigation_controller_delegate),
Harkiran Bolaria16f2c48d2022-04-22 12:39:57190 type_(type),
[email protected]94d0cc12013-12-18 00:07:41191 root_(new FrameTreeNode(this,
xiaochengh98488162016-05-19 15:17:59192 nullptr,
dcheng860817a2015-05-22 03:16:56193 // The top-level frame must always be in a
194 // document scope.
Antonio Gomes9d5c1ef2020-04-30 20:56:41195 blink::mojom::TreeScopeType::kDocument,
Lukasz Anforowicz7bfb2e92017-11-22 17:19:45196 false,
Dave Tapuska144570102022-08-02 19:28:27197 devtools_frame_token,
Julie Jeongeun Kim70a2e4e2020-02-21 05:09:54198 blink::mojom::FrameOwnerProperties(),
Kevin McNee43fe8292021-10-04 22:59:41199 blink::FrameOwnerElementType::kNone,
Dominic Farolino08662c82021-06-11 07:36:34200 blink::FramePolicy())),
thestige62f7382016-11-08 18:31:39201 focused_frame_tree_node_id_(FrameTreeNode::kFrameTreeNodeInvalidId),
David Bokanc3fb5fa2022-07-04 14:55:31202 load_progress_(0.0),
203 fenced_frames_impl_(
204 blink::features::IsFencedFramesEnabled()
205 ? absl::optional<blink::features::FencedFramesImplementationType>(
206 blink::features::kFencedFramesImplementationTypeParam.Get())
207 : absl::nullopt) {}
[email protected]9b159a52013-10-03 17:24:55208
209FrameTree::~FrameTree() {
Takashi Toyoshimaea534ef22021-07-21 03:27:59210 is_being_destroyed_ = true;
Carlos Caballero101ac26b2021-03-24 11:54:05211#if DCHECK_IS_ON()
212 DCHECK(was_shut_down_);
213#endif
nick70b782d2015-10-06 17:37:04214 delete root_;
215 root_ = nullptr;
[email protected]9b159a52013-10-03 17:24:55216}
217
vishal.b782eb5d2015-04-29 12:22:57218FrameTreeNode* FrameTree::FindByID(int frame_tree_node_id) {
dcheng57e39e22016-01-21 00:25:38219 for (FrameTreeNode* node : Nodes()) {
220 if (node->frame_tree_node_id() == frame_tree_node_id)
221 return node;
222 }
223 return nullptr;
[email protected]9b159a52013-10-03 17:24:55224}
225
nasko479ea5a2015-02-14 00:03:04226FrameTreeNode* FrameTree::FindByRoutingID(int process_id, int routing_id) {
dmazzoni0b5d2482014-09-10 19:45:57227 RenderFrameHostImpl* render_frame_host =
228 RenderFrameHostImpl::FromID(process_id, routing_id);
229 if (render_frame_host) {
230 FrameTreeNode* result = render_frame_host->frame_tree_node();
231 if (this == result->frame_tree())
232 return result;
233 }
234
235 RenderFrameProxyHost* render_frame_proxy_host =
236 RenderFrameProxyHost::FromID(process_id, routing_id);
237 if (render_frame_proxy_host) {
238 FrameTreeNode* result = render_frame_proxy_host->frame_tree_node();
239 if (this == result->frame_tree())
240 return result;
241 }
242
creis6a93a812015-04-24 23:13:17243 return nullptr;
244}
245
246FrameTreeNode* FrameTree::FindByName(const std::string& name) {
247 if (name.empty())
nick70b782d2015-10-06 17:37:04248 return root_;
creis6a93a812015-04-24 23:13:17249
dcheng57e39e22016-01-21 00:25:38250 for (FrameTreeNode* node : Nodes()) {
251 if (node->frame_name() == name)
252 return node;
[email protected]9b159a52013-10-03 17:24:55253 }
dcheng57e39e22016-01-21 00:25:38254
255 return nullptr;
256}
257
258FrameTree::NodeRange FrameTree::Nodes() {
Alex Moshchuk27caae82017-09-11 23:11:18259 return NodesExceptSubtree(nullptr);
dcheng57e39e22016-01-21 00:25:38260}
261
kenrb61b6c252016-03-22 17:37:15262FrameTree::NodeRange FrameTree::SubtreeNodes(FrameTreeNode* subtree_root) {
Kevin McNee5f594382021-05-06 23:18:23263 return NodeRange({subtree_root}, nullptr,
264 /* should_descend_into_inner_trees */ false);
265}
266
Kevin McNee53f0b2d2021-11-02 18:00:45267FrameTree::NodeRange FrameTree::NodesIncludingInnerTreeNodes() {
268 return NodeRange({root_}, nullptr,
269 /* should_descend_into_inner_trees */ true);
270}
271
Sreeja Kamishettyd64b993d2022-02-14 12:04:42272std::vector<FrameTreeNode*> FrameTree::CollectNodesForIsLoading() {
273 FrameTree::NodeRange node_range = NodesIncludingInnerTreeNodes();
274 FrameTree::NodeIterator node_iter = node_range.begin();
275 std::vector<FrameTreeNode*> nodes;
276
277 DCHECK(node_iter != node_range.end());
278 FrameTree* root_loading_tree = root_->frame_tree()->LoadingTree();
279 while (node_iter != node_range.end()) {
280 // Skip over frame trees and children which belong to inner web contents
281 // i.e., when nodes doesn't point to the same loading frame tree.
282 if ((*node_iter)->frame_tree()->LoadingTree() != root_loading_tree) {
283 node_iter.AdvanceSkippingChildren();
284 } else {
285 nodes.push_back(*node_iter);
286 ++node_iter;
287 }
288 }
289 return nodes;
290}
291
Kevin McNee5f594382021-05-06 23:18:23292FrameTree::NodeRange FrameTree::SubtreeAndInnerTreeNodes(
293 RenderFrameHostImpl* parent) {
294 std::vector<FrameTreeNode*> starting_nodes;
295 starting_nodes.reserve(parent->child_count());
296 for (size_t i = 0; i < parent->child_count(); ++i) {
297 FrameTreeNode* child = parent->child_at(i);
298 FrameTreeNode* inner_tree_main_ftn = GetInnerTreeMainFrameNode(child);
299 starting_nodes.push_back(inner_tree_main_ftn ? inner_tree_main_ftn : child);
300 }
301 const std::vector<FrameTreeNode*> unattached_owned_nodes =
302 parent->delegate()->GetUnattachedOwnedNodes(parent);
303 starting_nodes.insert(starting_nodes.end(), unattached_owned_nodes.begin(),
304 unattached_owned_nodes.end());
305 return NodeRange(starting_nodes, nullptr,
306 /* should_descend_into_inner_trees */ true);
kenrb61b6c252016-03-22 17:37:15307}
308
Alex Moshchuk27caae82017-09-11 23:11:18309FrameTree::NodeRange FrameTree::NodesExceptSubtree(FrameTreeNode* node) {
Kevin McNee5f594382021-05-06 23:18:23310 return NodeRange({root_}, node, /* should_descend_into_inner_trees */ false);
[email protected]9b159a52013-10-03 17:24:55311}
312
Sreeja Kamishettyd64b993d2022-02-14 12:04:42313FrameTree* FrameTree::LoadingTree() {
314 // We return the delegate's loading frame tree to infer loading related
315 // states.
316 return delegate_->LoadingTree();
317}
318
Lucas Furukawa Gadani99125822019-01-03 15:41:49319FrameTreeNode* FrameTree::AddFrame(
Alexander Timin381e7e182020-04-28 19:04:03320 RenderFrameHostImpl* parent,
Balazs Engedyba034e72017-10-27 22:26:28321 int process_id,
322 int new_routing_id,
danakj0bdfacd2021-01-20 19:27:18323 mojo::PendingAssociatedRemote<mojom::Frame> frame_remote,
Oksana Zhuravlovafee097c2019-07-26 17:01:30324 mojo::PendingReceiver<blink::mojom::BrowserInterfaceBroker>
325 browser_interface_broker_receiver,
Antonio Sartoridb967c52021-01-20 09:54:30326 blink::mojom::PolicyContainerBindParamsPtr policy_container_bind_params,
Dominic Farolino12e06d72022-08-05 02:29:49327 mojo::PendingAssociatedReceiver<blink::mojom::AssociatedInterfaceProvider>
328 associated_interface_provider_receiver,
Antonio Gomes9d5c1ef2020-04-30 20:56:41329 blink::mojom::TreeScopeType scope,
Balazs Engedyba034e72017-10-27 22:26:28330 const std::string& frame_name,
331 const std::string& frame_unique_name,
Lukasz Anforowicz7bfb2e92017-11-22 17:19:45332 bool is_created_by_script,
Chris Hamilton3ff6ed0e2021-02-19 03:54:04333 const blink::LocalFrameToken& frame_token,
Balazs Engedyba034e72017-10-27 22:26:28334 const base::UnguessableToken& devtools_frame_token,
Daniel Cheng284c38942022-09-22 23:30:34335 const blink::DocumentToken& document_token,
Luna Luc3fdacdf2017-11-08 04:48:53336 const blink::FramePolicy& frame_policy,
Julie Jeongeun Kim70a2e4e2020-02-21 05:09:54337 const blink::mojom::FrameOwnerProperties& frame_owner_properties,
Ehsan Karamad192a8da2018-10-21 03:48:08338 bool was_discarded,
Kevin McNee43fe8292021-10-04 22:59:41339 blink::FrameOwnerElementType owner_type,
340 bool is_dummy_frame_for_inner_tree) {
nick8814e652015-12-18 01:44:12341 CHECK_NE(new_routing_id, MSG_ROUTING_NONE);
Dominic Farolino4bc10ee2021-08-31 00:37:36342 // Normally this path is for blink adding a child local frame. But both
343 // portals and fenced frames add a dummy child frame that never gets a
344 // corresponding RenderFrameImpl in any renderer process, and therefore its
345 // `frame_remote` is invalid. Also its RenderFrameHostImpl is exempt from
346 // having `RenderFrameCreated()` called on it (see later in this method, as
347 // well as `WebContentsObserverConsistencyChecker::RenderFrameHostChanged()`).
Kevin McNee43fe8292021-10-04 22:59:41348 DCHECK_NE(frame_remote.is_valid(), is_dummy_frame_for_inner_tree);
349 DCHECK_NE(browser_interface_broker_receiver.is_valid(),
350 is_dummy_frame_for_inner_tree);
Dominic Farolino12e06d72022-08-05 02:29:49351 DCHECK_NE(associated_interface_provider_receiver.is_valid(),
352 is_dummy_frame_for_inner_tree);
nick8814e652015-12-18 01:44:12353
dgroganfb22f9a2014-10-20 21:32:32354 // A child frame always starts with an initial empty document, which means
355 // it is in the same SiteInstance as the parent frame. Ensure that the process
356 // which requested a child frame to be added is the same as the process of the
357 // parent node.
Dominic Farolino6caf3032021-10-20 03:50:08358 CHECK_EQ(parent->GetProcess()->GetID(), process_id);
dgroganfb22f9a2014-10-20 21:32:32359
iclelland098da752017-06-28 13:46:50360 std::unique_ptr<FrameTreeNode> new_node = base::WrapUnique(new FrameTreeNode(
Harkiran Bolaria0b3bdef02022-03-10 13:04:40361 this, parent, scope, is_created_by_script, devtools_frame_token,
362 frame_owner_properties, owner_type, frame_policy));
iclelland098da752017-06-28 13:46:50363
364 // Set sandbox flags and container policy and make them effective immediately,
Charlie Hu5130d25e2021-03-05 21:53:39365 // since initial sandbox flags and permissions policy should apply to the
366 // initial empty document in the frame. This needs to happen before the call
367 // to AddChild so that the effective policy is sent to any newly-created
Dave Tapuska2402595f2022-08-03 16:24:21368 // `blink::RemoteFrame` objects when the RenderFrameHost is created.
Charlie Hu5ffc0152019-12-06 15:59:53369 // SetPendingFramePolicy is necessary here because next navigation on this
370 // frame will need the value of pending frame policy instead of effective
371 // frame policy.
Ian Clellandcdc4f312017-10-13 22:24:12372 new_node->SetPendingFramePolicy(frame_policy);
iclelland098da752017-06-28 13:46:50373
Shubhie Panickerddf2a4e2018-03-06 00:09:06374 if (was_discarded)
375 new_node->set_was_discarded();
376
iclelland098da752017-06-28 13:46:50377 // Add the new node to the FrameTree, creating the RenderFrameHost.
Harkiran Bolaria0b3bdef02022-03-10 13:04:40378 FrameTreeNode* added_node = parent->AddChild(
379 std::move(new_node), new_routing_id, std::move(frame_remote), frame_token,
Daniel Cheng284c38942022-09-22 23:30:34380 document_token, frame_policy, frame_name, frame_unique_name);
nick8814e652015-12-18 01:44:12381
Garrett Tanzer34cb92fe2022-09-28 17:50:54382 added_node->SetFencedFramePropertiesIfNeeded();
shivanigithub4cd016a2021-09-20 21:10:30383
Kevin McNee43fe8292021-10-04 22:59:41384 if (browser_interface_broker_receiver.is_valid()) {
385 added_node->current_frame_host()->BindBrowserInterfaceBrokerReceiver(
386 std::move(browser_interface_broker_receiver));
387 }
Oksana Zhuravlovafee097c2019-07-26 17:01:30388
Antonio Sartoridb967c52021-01-20 09:54:30389 if (policy_container_bind_params) {
Antonio Sartoria1fd1432020-11-25 09:10:20390 added_node->current_frame_host()->policy_container_host()->Bind(
Antonio Sartoridb967c52021-01-20 09:54:30391 std::move(policy_container_bind_params));
Antonio Sartoria1fd1432020-11-25 09:10:20392 }
393
Dominic Farolino12e06d72022-08-05 02:29:49394 if (associated_interface_provider_receiver.is_valid()) {
395 added_node->current_frame_host()->BindAssociatedInterfaceProviderReceiver(
396 std::move(associated_interface_provider_receiver));
397 }
398
nasko03ecfad2016-08-02 00:54:06399 // The last committed NavigationEntry may have a FrameNavigationEntry with the
400 // same |frame_unique_name|, since we don't remove FrameNavigationEntries if
401 // their frames are deleted. If there is a stale one, remove it to avoid
402 // conflicts on future updates.
Fergal Daly09d6c762020-05-29 02:05:18403 NavigationEntryImpl* last_committed_entry = static_cast<NavigationEntryImpl*>(
Carlos Caballero40b0efd2021-01-26 11:55:00404 navigator_.controller().GetLastCommittedEntry());
Lukasz Anforowicz7bfb2e92017-11-22 17:19:45405 if (last_committed_entry) {
406 last_committed_entry->RemoveEntryForFrame(
407 added_node, /* only_if_different_position = */ true);
408 }
nasko03ecfad2016-08-02 00:54:06409
nick8814e652015-12-18 01:44:12410 // Now that the new node is part of the FrameTree and has a RenderFrameHost,
411 // we can announce the creation of the initial RenderFrame which already
412 // exists in the renderer process.
Sreeja Kamishetty5b699622021-01-22 12:54:08413 // For consistency with navigating to a new RenderFrameHost case, we dispatch
414 // RenderFrameCreated before RenderFrameHostChanged.
Kevin McNee43fe8292021-10-04 22:59:41415 if (!is_dummy_frame_for_inner_tree) {
Dominic Farolino4bc10ee2021-08-31 00:37:36416 // The outer dummy FrameTreeNode for both portals and fenced frames does not
417 // have a live RenderFrame in the renderer process.
Fergal Dalyf9ea35c2020-12-11 15:26:01418 added_node->current_frame_host()->RenderFrameCreated();
Ehsan Karamad44fc72112019-02-26 18:15:47419 }
Sreeja Kamishetty5b699622021-01-22 12:54:08420
421 // Notify the delegate of the creation of the current RenderFrameHost.
422 // This is only for subframes, as the main frame case is taken care of by
423 // WebContentsImpl::Init.
424 manager_delegate_->NotifySwappedFromRenderManager(
Dave Tapuskae45d6fd2021-09-29 17:03:59425 nullptr, added_node->current_frame_host());
Lucas Furukawa Gadani99125822019-01-03 15:41:49426 return added_node;
[email protected]9b159a52013-10-03 17:24:55427}
428
[email protected]58faf942014-02-20 21:03:58429void FrameTree::RemoveFrame(FrameTreeNode* child) {
Alexander Timin381e7e182020-04-28 19:04:03430 RenderFrameHostImpl* parent = child->parent();
[email protected]58faf942014-02-20 21:03:58431 if (!parent) {
432 NOTREACHED() << "Unexpected RemoveFrame call for main frame.";
433 return;
[email protected]9b159a52013-10-03 17:24:55434 }
435
Alexander Timin381e7e182020-04-28 19:04:03436 parent->RemoveChild(child);
[email protected]9b159a52013-10-03 17:24:55437}
438
Harkiran Bolaria2912a6b32022-02-22 16:43:45439void FrameTree::CreateProxiesForSiteInstance(
440 FrameTreeNode* source,
441 SiteInstance* site_instance,
442 const scoped_refptr<BrowsingContextState>&
443 source_new_browsing_context_state) {
Sharon Yang57bde122022-03-01 20:01:12444 SiteInstanceGroup* group =
445 static_cast<SiteInstanceImpl*>(site_instance)->group();
naskob3041b98a42016-03-12 04:43:06446 // Create the RenderFrameProxyHost for the new SiteInstance.
alexmos58729042015-06-18 23:20:00447 if (!source || !source->IsMainFrame()) {
Sharon Yang57bde122022-03-01 20:01:12448 RenderViewHostImpl* render_view_host = GetRenderViewHost(group).get();
arthursonzognic5be3842019-07-09 11:49:14449 if (render_view_host) {
Sharon Yang57bde122022-03-01 20:01:12450 root()->render_manager()->EnsureRenderViewInitialized(render_view_host,
451 group);
arthursonzognic5be3842019-07-09 11:49:14452 } else {
Harkiran Bolaria2912a6b32022-02-22 16:43:45453 // Due to the check above, we are creating either an opener proxy (when
454 // source is null) or a main frame proxy due to a subframe navigation
455 // (when source is not a main frame). In the former case, we should use
456 // root's current BrowsingContextState, while in the latter case we should
457 // use BrowsingContextState from the main RenderFrameHost of the subframe
Dave Tapuska2cf1f532022-08-10 15:30:49458 // being navigated. We want to ensure that the `blink::WebView` is created
459 // in the right SiteInstance if it doesn't exist, before creating the
460 // other proxies; if the `blink::WebView` doesn't exist, the only way to
461 // do this is to also create a proxy for the main frame as well.
Harkiran Bolaria2912a6b32022-02-22 16:43:45462 root()->render_manager()->CreateRenderFrameProxy(
463 site_instance,
464 source ? source->parent()->GetMainFrame()->browsing_context_state()
465 : root()->current_frame_host()->browsing_context_state());
[email protected]82307f6b2014-08-07 03:30:12466 }
467 }
468
Alex Moshchuk1226b152019-11-08 18:23:45469 // Check whether we're in an inner delegate and |site_instance| corresponds
470 // to the outer delegate. Subframe proxies aren't needed if this is the
471 // case.
472 bool is_site_instance_for_outer_delegate = false;
473 RenderFrameProxyHost* outer_delegate_proxy =
474 root()->render_manager()->GetProxyToOuterDelegate();
475 if (outer_delegate_proxy) {
476 is_site_instance_for_outer_delegate =
477 (site_instance == outer_delegate_proxy->GetSiteInstance());
478 }
479
naskoe6edde32014-10-17 15:36:48480 // Proxies are created in the FrameTree in response to a node navigating to a
481 // new SiteInstance. Since |source|'s navigation will replace the currently
Alex Moshchuk27caae82017-09-11 23:11:18482 // loaded document, the entire subtree under |source| will be removed, and
483 // thus proxy creation is skipped for all nodes in that subtree.
484 //
485 // However, a proxy *is* needed for the |source| node itself. This lets
486 // cross-process navigations in |source| start with a proxy and follow a
487 // remote-to-local transition, which avoids race conditions in cases where
488 // other navigations need to reference |source| before it commits. See
489 // https://crbug.com/756790 for more background. Therefore,
490 // NodesExceptSubtree(source) will include |source| in the nodes traversed
491 // (see NodeIterator::operator++).
492 for (FrameTreeNode* node : NodesExceptSubtree(source)) {
dcheng57e39e22016-01-21 00:25:38493 // If a new frame is created in the current SiteInstance, other frames in
494 // that SiteInstance don't need a proxy for the new frame.
Alex Moshchuk27caae82017-09-11 23:11:18495 RenderFrameHostImpl* current_host =
496 node->render_manager()->current_frame_host();
497 SiteInstance* current_instance = current_host->GetSiteInstance();
498 if (current_instance != site_instance) {
499 if (node == source && !current_host->IsRenderFrameLive()) {
Fergal Daly6de62f52020-10-14 01:56:44500 // We don't create a proxy at |source| when the current RenderFrameHost
501 // isn't live. This is because either (1) the speculative
Alex Moshchuk27caae82017-09-11 23:11:18502 // RenderFrameHost will be committed immediately, and the proxy
Fergal Daly6de62f52020-10-14 01:56:44503 // destroyed right away, in GetFrameHostForNavigation, which makes the
504 // races above impossible, or (2) the early commit will be skipped due
505 // to ShouldSkipEarlyCommitPendingForCrashedFrame, in which case the
506 // proxy for |source| *is* needed, but it will be created later in
507 // CreateProxiesForNewRenderFrameHost.
508 //
509 // TODO(fergal): Consider creating a proxy for |source| here rather than
510 // in CreateProxiesForNewRenderFrameHost for case (2) above.
Alex Moshchuk27caae82017-09-11 23:11:18511 continue;
512 }
Alex Moshchuk1226b152019-11-08 18:23:45513
514 // Do not create proxies for subframes in the outer delegate's
515 // SiteInstance, since there is no need to expose these subframes to the
516 // outer delegate. See also comments in CreateProxiesForChildFrame() and
517 // https://crbug.com/1013553.
518 if (!node->IsMainFrame() && is_site_instance_for_outer_delegate)
519 continue;
520
Harkiran Bolaria2912a6b32022-02-22 16:43:45521 // If |node| is the FrameTreeNode being navigated, we use
522 // |browsing_context_state| (as BrowsingContextState might change for
523 // cross-BrowsingInstance navigations). Otherwise, we should use the
524 // |node|'s current BrowsingContextState.
525 node->render_manager()->CreateRenderFrameProxy(
526 site_instance,
527 node == source
528 ? source_new_browsing_context_state
529 : node->current_frame_host()->browsing_context_state());
Alex Moshchuk27caae82017-09-11 23:11:18530 }
dcheng57e39e22016-01-21 00:25:38531 }
[email protected]82307f6b2014-08-07 03:30:12532}
533
[email protected]9b159a52013-10-03 17:24:55534RenderFrameHostImpl* FrameTree::GetMainFrame() const {
[email protected]94d0cc12013-12-18 00:07:41535 return root_->current_frame_host();
[email protected]9b159a52013-10-03 17:24:55536}
537
[email protected]9c9343b2014-03-08 02:56:07538FrameTreeNode* FrameTree::GetFocusedFrame() {
539 return FindByID(focused_frame_tree_node_id_);
540}
541
Sharon Yangefe52632022-03-08 23:06:06542void FrameTree::SetFocusedFrame(FrameTreeNode* node,
543 SiteInstanceGroup* source) {
Rakina Zata Amnicca4889e2021-09-28 23:25:55544 CHECK(node->current_frame_host()->IsActive());
alexmos5357efb2015-12-16 21:44:00545 if (node == GetFocusedFrame())
546 return;
547
Sharon Yangefe52632022-03-08 23:06:06548 std::set<SiteInstanceGroup*> frame_tree_groups =
549 CollectSiteInstanceGroups(this);
alexmosb1dc2162015-11-05 00:59:20550
Sharon Yangefe52632022-03-08 23:06:06551 SiteInstanceGroup* current_group =
552 node->current_frame_host()->GetSiteInstance()->group();
alexmos5357efb2015-12-16 21:44:00553
Sharon Yang7424bda2021-11-04 20:27:43554 // Update the focused frame in all other SiteInstanceGroups. If focus changes
555 // to a cross-group frame, this allows the old focused frame's renderer
alexmosb1dc2162015-11-05 00:59:20556 // process to clear focus from that frame and fire blur events. It also
557 // ensures that the latest focused frame is available in all renderers to
558 // compute document.activeElement.
alexmos5357efb2015-12-16 21:44:00559 //
Sharon Yangefe52632022-03-08 23:06:06560 // We do not notify the |source| SiteInstanceGroup because it already knows
561 // the new focused frame (since it initiated the focus change), and we notify
562 // the new focused frame's SiteInstanceGroup (if it differs from |source|)
563 // separately below.
564 for (auto* group : frame_tree_groups) {
565 if (group != source && group != current_group) {
566 RenderFrameProxyHost* proxy = node->current_frame_host()
567 ->browsing_context_state()
568 ->GetRenderFrameProxyHost(group);
Sharon Yangf92842a2022-03-01 18:21:47569
Rakina Zata Amni80700402021-09-20 17:18:03570 if (proxy) {
571 proxy->SetFocusedFrame();
572 } else {
Sharon Yangf92842a2022-03-01 18:21:47573 base::debug::DumpWithoutCrashing();
Rakina Zata Amni80700402021-09-20 17:18:03574 }
alexmosb1dc2162015-11-05 00:59:20575 }
alexmosca2c6ba2015-10-01 21:52:25576 }
577
Sharon Yangefe52632022-03-08 23:06:06578 // If |node| was focused from a cross-group frame (i.e., via
alexmos5357efb2015-12-16 21:44:00579 // window.focus()), tell its RenderFrame that it should focus.
Sharon Yangefe52632022-03-08 23:06:06580 if (current_group != source)
alexmos5357efb2015-12-16 21:44:00581 node->current_frame_host()->SetFocusedFrame();
582
[email protected]9c9343b2014-03-08 02:56:07583 focused_frame_tree_node_id_ = node->frame_tree_node_id();
alexmos21acae52015-11-07 01:04:43584 node->DidFocus();
dmazzonif27bf892016-03-10 15:51:55585
586 // The accessibility tree data for the root of the frame tree keeps
587 // track of the focused frame too, so update that every time the
588 // focused frame changes.
Kevin McNee582a7d62021-10-12 21:42:22589 root()
590 ->current_frame_host()
591 ->GetOutermostMainFrameOrEmbedder()
592 ->UpdateAXTreeData();
[email protected]9c9343b2014-03-08 02:56:07593}
594
arthursonzognic5be3842019-07-09 11:49:14595scoped_refptr<RenderViewHostImpl> FrameTree::CreateRenderViewHost(
avib7348942015-12-25 20:57:10596 SiteInstance* site_instance,
avib7348942015-12-25 20:57:10597 int32_t main_frame_routing_id,
Harkiran Bolaria57e2b062022-03-14 10:27:58598 bool renderer_initiated_creation,
599 scoped_refptr<BrowsingContextState> main_browsing_context_state) {
600 if (main_browsing_context_state) {
601 DCHECK(main_browsing_context_state->is_main_frame());
602 }
dcheng29f5a6c2015-08-31 21:43:27603 RenderViewHostImpl* rvh =
604 static_cast<RenderViewHostImpl*>(RenderViewHostFactory::Create(
Sharon Yangcadd00b82022-05-13 19:16:33605 this, static_cast<SiteInstanceImpl*>(site_instance)->group(),
606 site_instance->GetStoragePartitionConfig(), render_view_delegate_,
Dave Tapuska658bfec2022-08-05 14:27:20607 render_widget_delegate_, main_frame_routing_id,
Sharon Yangcadd00b82022-05-13 19:16:33608 renderer_initiated_creation, std::move(main_browsing_context_state)));
arthursonzognic5be3842019-07-09 11:49:14609 return base::WrapRefCounted(rvh);
[email protected]94d0cc12013-12-18 00:07:41610}
611
arthursonzognic5be3842019-07-09 11:49:14612scoped_refptr<RenderViewHostImpl> FrameTree::GetRenderViewHost(
Sharon Yang57bde122022-03-01 20:01:12613 SiteInstanceGroup* group) {
Sharon Yanga2fe85e2022-02-09 21:38:29614 // When called from RenderFrameHostManager::CreateRenderFrameHost, it's
615 // possible that a RenderProcessHost hasn't yet been created, which means
Sharon Yang57bde122022-03-01 20:01:12616 // a SiteInstanceGroup won't have been created yet.
Sharon Yanga2fe85e2022-02-09 21:38:29617 if (!group)
618 return nullptr;
619
620 auto it = render_view_host_map_.find(GetRenderViewHostMapId(group));
arthursonzogni88e54ae2019-04-15 12:57:36621 if (it == render_view_host_map_.end())
622 return nullptr;
alexmos9aa61232016-04-26 21:54:02623
arthursonzognic5be3842019-07-09 11:49:14624 return base::WrapRefCounted(it->second);
[email protected]94d0cc12013-12-18 00:07:41625}
626
Aaron Colwell78b4bde2021-03-16 16:16:09627FrameTree::RenderViewHostMapId FrameTree::GetRenderViewHostMapId(
Sharon Yangc581a0c2021-11-02 18:09:39628 SiteInstanceGroup* site_instance_group) const {
629 return RenderViewHostMapId::FromUnsafeValue(
630 site_instance_group->GetId().value());
Lowell Manners75055a132019-10-11 10:30:29631}
632
Aaron Colwell78b4bde2021-03-16 16:16:09633void FrameTree::RegisterRenderViewHost(RenderViewHostMapId id,
634 RenderViewHostImpl* rvh) {
Rakina Zata Amni4b1968d2021-09-09 03:29:47635 TRACE_EVENT_INSTANT("navigation", "FrameTree::RegisterRenderViewHost",
636 ChromeTrackEvent::kRenderViewHost, *rvh);
Aaron Colwell78b4bde2021-03-16 16:16:09637 CHECK(!base::Contains(render_view_host_map_, id));
638 render_view_host_map_[id] = rvh;
639}
640
641void FrameTree::UnregisterRenderViewHost(RenderViewHostMapId id,
Aaron Colwellc4bd7d62021-01-29 04:23:13642 RenderViewHostImpl* rvh) {
Rakina Zata Amni4b1968d2021-09-09 03:29:47643 TRACE_EVENT_INSTANT("navigation", "FrameTree::UnregisterRenderViewHost",
644 ChromeTrackEvent::kRenderViewHost, *rvh);
Aaron Colwell78b4bde2021-03-16 16:16:09645 auto it = render_view_host_map_.find(id);
arthursonzogni88e54ae2019-04-15 12:57:36646 CHECK(it != render_view_host_map_.end());
arthursonzognic5be3842019-07-09 11:49:14647 CHECK_EQ(it->second, rvh);
648 render_view_host_map_.erase(it);
[email protected]94d0cc12013-12-18 00:07:41649}
650
arthursonzogni0a2007792019-05-28 21:32:48651void FrameTree::FrameUnloading(FrameTreeNode* frame) {
652 if (frame->frame_tree_node_id() == focused_frame_tree_node_id_)
653 focused_frame_tree_node_id_ = FrameTreeNode::kFrameTreeNodeInvalidId;
654
655 // Ensure frames that are about to be deleted aren't visible from the other
656 // processes anymore.
Harkiran Bolaria0b3bdef02022-03-10 13:04:40657 frame->GetBrowsingContextStateForSubframe()->ResetProxyHosts();
arthursonzogni0a2007792019-05-28 21:32:48658}
659
dmazzonie950ea232015-03-13 21:39:45660void FrameTree::FrameRemoved(FrameTreeNode* frame) {
nick53d5cbf2015-04-23 22:50:14661 if (frame->frame_tree_node_id() == focused_frame_tree_node_id_)
thestige62f7382016-11-08 18:31:39662 focused_frame_tree_node_id_ = FrameTreeNode::kFrameTreeNodeInvalidId;
dmazzonie950ea232015-03-13 21:39:45663}
664
Sreeja Kamishetty0be3b1b2021-08-12 17:04:15665double FrameTree::GetLoadProgress() {
666 if (root_->HasNavigation())
667 return blink::kInitialLoadProgress;
668
669 return root_->current_frame_host()->GetPage().load_progress();
fdegans1d16355162015-03-26 11:58:34670}
671
Yu Gaoc8c18552022-06-22 14:38:45672bool FrameTree::IsLoadingIncludingInnerFrameTrees() const {
Sreeja Kamishetty15f9944a22022-03-10 10:16:08673 for (const FrameTreeNode* node :
674 const_cast<FrameTree*>(this)->CollectNodesForIsLoading()) {
dcheng57e39e22016-01-21 00:25:38675 if (node->IsLoading())
676 return true;
677 }
678 return false;
fdegans1d16355162015-03-26 11:58:34679}
680
alexmos3fcd0ca2015-10-23 18:18:33681void FrameTree::ReplicatePageFocus(bool is_focused) {
Dave Tapuska53e6ce12021-08-06 16:08:24682 // Focus loss may occur while this FrameTree is being destroyed. Don't
683 // send the message in this case, as the main frame's RenderFrameHost and
684 // other state has already been cleared.
685 if (is_being_destroyed_)
686 return;
Sharon Yangefe52632022-03-08 23:06:06687 std::set<SiteInstanceGroup*> frame_tree_site_instance_groups =
688 CollectSiteInstanceGroups(this);
alexmos3fcd0ca2015-10-23 18:18:33689
Sharon Yangefe52632022-03-08 23:06:06690 // Send the focus update to main frame's proxies in all SiteInstanceGroups of
alexmos3fcd0ca2015-10-23 18:18:33691 // other frames in this FrameTree. Note that the main frame might also know
Sharon Yangefe52632022-03-08 23:06:06692 // about proxies in SiteInstanceGroups for frames in a different FrameTree
693 // (e.g., for window.open), so we can't just iterate over its proxy_hosts_ in
alexmos3fcd0ca2015-10-23 18:18:33694 // RenderFrameHostManager.
Sharon Yangefe52632022-03-08 23:06:06695 for (auto* group : frame_tree_site_instance_groups)
696 SetPageFocus(group, is_focused);
alexmos0d7e0b09b2015-10-29 22:11:48697}
alexmos3fcd0ca2015-10-23 18:18:33698
Sreeja Kamishetty60e47132022-02-08 12:51:53699bool FrameTree::IsPortal() {
700 return delegate_->IsPortal();
701}
702
Sharon Yangefe52632022-03-08 23:06:06703void FrameTree::SetPageFocus(SiteInstanceGroup* group, bool is_focused) {
alexmos0d7e0b09b2015-10-29 22:11:48704 RenderFrameHostManager* root_manager = root_->render_manager();
705
Adithya Srinivasan47731222021-01-22 15:02:42706 // Portal frame tree should not get page focus.
Sreeja Kamishetty60e47132022-02-08 12:51:53707 DCHECK(!IsPortal() || !is_focused);
Adithya Srinivasan47731222021-01-22 15:02:42708
alexmos0d7e0b09b2015-10-29 22:11:48709 // This is only used to set page-level focus in cross-process subframes, and
Sharon Yangefe52632022-03-08 23:06:06710 // requests to set focus in main frame's SiteInstanceGroup are ignored.
711 if (group != root_manager->current_frame_host()->GetSiteInstance()->group()) {
712 RenderFrameProxyHost* proxy = root_manager->current_frame_host()
713 ->browsing_context_state()
714 ->GetRenderFrameProxyHost(group);
Dave Tapuska82b54012022-07-15 23:26:10715 if (proxy->is_render_frame_proxy_live())
716 proxy->GetAssociatedRemoteFrame()->SetPageFocus(is_focused);
alexmos3fcd0ca2015-10-23 18:18:33717 }
718}
719
W. James MacLeanc07dc41b2022-07-25 18:52:16720void FrameTree::RegisterExistingOriginAsHavingDefaultIsolation(
W. James MacLeanb70fab82020-05-01 18:51:14721 const url::Origin& previously_visited_origin,
722 NavigationRequest* navigation_request_to_exclude) {
W. James MacLeanc07dc41b2022-07-25 18:52:16723 controller().RegisterExistingOriginAsHavingDefaultIsolation(
W. James MacLeanc6dc86c2021-08-12 13:58:37724 previously_visited_origin);
725
W. James MacLeanb70fab82020-05-01 18:51:14726 std::unordered_set<SiteInstance*> matching_site_instances;
727
728 // Be sure to visit all RenderFrameHosts associated with this frame that might
729 // have an origin that could script other frames. We skip RenderFrameHosts
730 // that are in the bfcache, assuming there's no way for a frame to join the
731 // BrowsingInstance of a bfcache RFH while it's in the cache.
732 for (auto* frame_tree_node : SubtreeNodes(root())) {
733 auto* frame_host = frame_tree_node->current_frame_host();
W. James MacLeanb70fab82020-05-01 18:51:14734 if (previously_visited_origin == frame_host->GetLastCommittedOrigin())
735 matching_site_instances.insert(frame_host->GetSiteInstance());
736
737 if (frame_host->HasCommittingNavigationRequestForOrigin(
738 previously_visited_origin, navigation_request_to_exclude)) {
739 matching_site_instances.insert(frame_host->GetSiteInstance());
740 }
741
742 auto* spec_frame_host =
743 frame_tree_node->render_manager()->speculative_frame_host();
744 if (spec_frame_host &&
745 spec_frame_host->HasCommittingNavigationRequestForOrigin(
746 previously_visited_origin, navigation_request_to_exclude)) {
747 matching_site_instances.insert(spec_frame_host->GetSiteInstance());
748 }
749
750 auto* navigation_request = frame_tree_node->navigation_request();
751 if (navigation_request &&
752 navigation_request != navigation_request_to_exclude &&
753 navigation_request->HasCommittingOrigin(previously_visited_origin)) {
754 matching_site_instances.insert(frame_host->GetSiteInstance());
755 }
756 }
757
758 // Update any SiteInstances found to contain |origin|.
759 for (auto* site_instance : matching_site_instances) {
760 static_cast<SiteInstanceImpl*>(site_instance)
W. James MacLeanc07dc41b2022-07-25 18:52:16761 ->RegisterAsDefaultOriginIsolation(previously_visited_origin);
W. James MacLeanb70fab82020-05-01 18:51:14762 }
763}
764
Carlos Caballero40b0efd2021-01-26 11:55:00765void FrameTree::Init(SiteInstance* main_frame_site_instance,
766 bool renderer_initiated_creation,
Rakina Zata Amniafd3c6582021-11-30 06:19:17767 const std::string& main_frame_name,
Rakina Zata Amni4eb716e2022-04-05 21:32:46768 RenderFrameHostImpl* opener_for_origin,
Harkiran Bolaria5ce27632022-01-20 15:05:05769 const blink::FramePolicy& frame_policy) {
Carlos Caballero40b0efd2021-01-26 11:55:00770 // blink::FrameTree::SetName always keeps |unique_name| empty in case of a
771 // main frame - let's do the same thing here.
772 std::string unique_name;
Sreeja Kamishetty3699c35f2021-02-12 15:10:58773 root_->render_manager()->InitRoot(main_frame_site_instance,
Harkiran Bolaria880a7632022-02-28 16:02:50774 renderer_initiated_creation, frame_policy,
775 main_frame_name);
Garrett Tanzer34cb92fe2022-09-28 17:50:54776 root_->SetFencedFramePropertiesIfNeeded();
Rakina Zata Amniafd3c6582021-11-30 06:19:17777
778 // The initial empty document should inherit the origin of its opener (the
779 // origin may change after the first commit), except when they are in
Rakina Zata Amni4eb716e2022-04-05 21:32:46780 // different browsing context groups (`renderer_initiated_creation` will be
781 // false), where it should use a new opaque origin.
Rakina Zata Amniafd3c6582021-11-30 06:19:17782 // See also https://crbug.com/932067.
783 //
784 // Note that the origin of the new frame might depend on sandbox flags.
785 // Checking sandbox flags of the new frame should be safe at this point,
786 // because the flags should be already inherited when creating the root node.
Rakina Zata Amni4eb716e2022-04-05 21:32:46787 DCHECK(!renderer_initiated_creation || opener_for_origin);
Rakina Zata Amniafd3c6582021-11-30 06:19:17788 root_->current_frame_host()->SetOriginDependentStateOfNewFrame(
Rakina Zata Amni4eb716e2022-04-05 21:32:46789 renderer_initiated_creation ? opener_for_origin->GetLastCommittedOrigin()
Rakina Zata Amniafd3c6582021-11-30 06:19:17790 : url::Origin());
Rakina Zata Amni2322f4f82022-01-24 13:24:24791
792 if (blink::features::IsInitialNavigationEntryEnabled())
793 controller().CreateInitialEntry();
Carlos Caballero40b0efd2021-01-26 11:55:00794}
795
Carlos Caballeroede6f8c2021-01-28 11:01:50796void FrameTree::DidAccessInitialMainDocument() {
797 OPTIONAL_TRACE_EVENT0("content", "FrameTree::DidAccessInitialDocument");
798 has_accessed_initial_main_document_ = true;
799 controller().DidAccessInitialMainDocument();
800}
801
Carlos Caballero03262522021-02-05 14:49:58802void FrameTree::DidStartLoadingNode(FrameTreeNode& node,
Nate Chapin9aabf5f2021-11-12 00:31:19803 bool should_show_loading_ui,
Carlos Caballero03262522021-02-05 14:49:58804 bool was_previously_loading) {
Carlos Caballero03262522021-02-05 14:49:58805 if (was_previously_loading)
806 return;
807
Yu Gaoc8c18552022-06-22 14:38:45808 root()->render_manager()->SetIsLoading(IsLoadingIncludingInnerFrameTrees());
Nate Chapin9aabf5f2021-11-12 00:31:19809 delegate_->DidStartLoading(&node, should_show_loading_ui);
Carlos Caballero03262522021-02-05 14:49:58810}
811
812void FrameTree::DidStopLoadingNode(FrameTreeNode& node) {
Yu Gaoc8c18552022-06-22 14:38:45813 if (IsLoadingIncludingInnerFrameTrees())
Carlos Caballero03262522021-02-05 14:49:58814 return;
815
816 root()->render_manager()->SetIsLoading(false);
817 delegate_->DidStopLoading();
818}
819
Carlos Caballero03262522021-02-05 14:49:58820void FrameTree::DidCancelLoading() {
821 OPTIONAL_TRACE_EVENT0("content", "FrameTree::DidCancelLoading");
822 navigator_.controller().DiscardNonCommittedEntries();
Carlos Caballero03262522021-02-05 14:49:58823}
824
825void FrameTree::StopLoading() {
826 for (FrameTreeNode* node : Nodes())
827 node->StopLoading();
828}
829
Carlos Caballero101ac26b2021-03-24 11:54:05830void FrameTree::Shutdown() {
Dave Tapuskae88286de2021-08-05 19:10:42831 is_being_destroyed_ = true;
Carlos Caballero101ac26b2021-03-24 11:54:05832#if DCHECK_IS_ON()
833 DCHECK(!was_shut_down_);
834 was_shut_down_ = true;
835#endif
836
837 RenderFrameHostManager* root_manager = root_->render_manager();
838
Carlos Caballerodb7a8f6e2021-04-09 18:17:47839 if (!root_manager->current_frame_host()) {
840 // The page has been transferred out during an activation. There is little
841 // left to do.
Carlos Caballerod1c80432021-04-20 08:16:32842 // TODO(https://crbug.com/1199693): If we decide that pending delete RFHs
Carlos Caballerodb7a8f6e2021-04-09 18:17:47843 // need to be moved along during activation replace this line with a DCHECK
844 // that there are no pending delete instances.
845 root_manager->ClearRFHsPendingShutdown();
Carlos Caballerodb7a8f6e2021-04-09 18:17:47846 DCHECK(!root_->navigation_request());
847 DCHECK(!root_manager->speculative_frame_host());
848 manager_delegate_->OnFrameTreeNodeDestroyed(root_);
Carlos Caballero101ac26b2021-03-24 11:54:05849 return;
Carlos Caballerodb7a8f6e2021-04-09 18:17:47850 }
Carlos Caballero101ac26b2021-03-24 11:54:05851
852 for (FrameTreeNode* node : Nodes()) {
853 // Delete all RFHs pending shutdown, which will lead the corresponding RVHs
854 // to be shutdown and be deleted as well.
855 node->render_manager()->ClearRFHsPendingShutdown();
Carlos Caballerod1c80432021-04-20 08:16:32856 // TODO(https://crbug.com/1199676): Ban WebUI instance in Prerender pages.
Carlos Caballero101ac26b2021-03-24 11:54:05857 node->render_manager()->ClearWebUIInstances();
858 }
859
860 // Destroy all subframes now. This notifies observers.
861 root_manager->current_frame_host()->ResetChildren();
Harkiran Bolaria0b3bdef02022-03-10 13:04:40862 root_manager->current_frame_host()
863 ->browsing_context_state()
864 ->ResetProxyHosts();
Carlos Caballero101ac26b2021-03-24 11:54:05865
Carlos Caballero101ac26b2021-03-24 11:54:05866 // Manually call the observer methods for the root FrameTreeNode. It is
867 // necessary to manually delete all objects tracking navigations
868 // (NavigationHandle, NavigationRequest) for observers to be properly
869 // notified of these navigations stopping before the WebContents is
870 // destroyed.
871
872 root_manager->current_frame_host()->RenderFrameDeleted();
873 root_manager->current_frame_host()->ResetNavigationRequests();
874
875 // Do not update state as the FrameTree::Delegate (possibly a WebContents) is
876 // being destroyed.
Daniel Cheng390e2a72022-09-28 06:07:53877 root_->ResetNavigationRequestButKeepState();
Carlos Caballero101ac26b2021-03-24 11:54:05878 if (root_manager->speculative_frame_host()) {
Daniel Chengc3d1e8d2021-06-23 02:11:45879 root_manager->DiscardSpeculativeRenderFrameHostForShutdown();
Carlos Caballero101ac26b2021-03-24 11:54:05880 }
881
Alexander Timin8aeee642021-05-12 08:39:33882 // NavigationRequests restoring the page from bfcache have a reference to the
883 // RFHs stored in the cache, so the cache should be cleared after the
884 // navigation request is reset.
885 controller().GetBackForwardCache().Shutdown();
886
Carlos Caballero101ac26b2021-03-24 11:54:05887 manager_delegate_->OnFrameTreeNodeDestroyed(root_);
888 render_view_delegate_->RenderViewDeleted(
889 root_manager->current_frame_host()->render_view_host());
890}
891
Dave Tapuskad8b0530f2021-10-19 15:12:31892base::SafeRef<FrameTree> FrameTree::GetSafeRef() {
893 return weak_ptr_factory_.GetSafeRef();
894}
895
Dave Tapuska54c76a032021-10-27 22:10:42896void FrameTree::FocusOuterFrameTrees() {
897 OPTIONAL_TRACE_EVENT0("content", "FrameTree::FocusOuterFrameTrees");
898
899 FrameTree* frame_tree_to_focus = this;
900 while (true) {
901 FrameTreeNode* outer_node = FrameTreeNode::GloballyFindByID(
902 frame_tree_to_focus->delegate()->GetOuterDelegateFrameTreeNodeId());
903 if (!outer_node || !outer_node->current_frame_host()->IsActive()) {
904 // Don't set focus on an inactive FrameTreeNode.
905 return;
906 }
907 outer_node->frame_tree()->SetFocusedFrame(outer_node, nullptr);
908
909 // For a browser initiated focus change, let embedding renderer know of the
910 // change. Otherwise, if the currently focused element is just across a
911 // process boundary in focus order, it will not be possible to move across
912 // that boundary. This is because the target element will already be focused
913 // (that renderer was not notified) and drop the event.
914 if (auto* proxy_to_outer_delegate = frame_tree_to_focus->root()
915 ->render_manager()
916 ->GetProxyToOuterDelegate()) {
917 proxy_to_outer_delegate->SetFocusedFrame();
918 }
919 frame_tree_to_focus = outer_node->frame_tree();
920 }
921}
922
[email protected]9b159a52013-10-03 17:24:55923} // namespace content