blob: 8d1a0959a6cc88260964824ebe9ce1c4f74ff655 [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.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"
Carlos Caballeroede6f8c2021-01-28 11:01:5019#include "base/trace_event/optional_trace_event.h"
Rakina Zata Amni4b1968d2021-09-09 03:29:4720#include "base/trace_event/typed_macros.h"
Pavel Feldman25234722017-10-11 02:49:0621#include "base/unguessable_token.h"
danakjc492bf82020-09-09 20:02:4422#include "content/browser/renderer_host/frame_tree_node.h"
23#include "content/browser/renderer_host/navigation_controller_impl.h"
24#include "content/browser/renderer_host/navigation_entry_impl.h"
25#include "content/browser/renderer_host/navigation_request.h"
26#include "content/browser/renderer_host/navigator.h"
27#include "content/browser/renderer_host/navigator_delegate.h"
Sreeja Kamishetty0be3b1b2021-08-12 17:04:1528#include "content/browser/renderer_host/page_impl.h"
Kevin McNee5f594382021-05-06 23:18:2329#include "content/browser/renderer_host/render_frame_host_delegate.h"
danakjc492bf82020-09-09 20:02:4430#include "content/browser/renderer_host/render_frame_host_factory.h"
31#include "content/browser/renderer_host/render_frame_host_impl.h"
32#include "content/browser/renderer_host/render_frame_proxy_host.h"
Carlos Caballero101ac26b2021-03-24 11:54:0533#include "content/browser/renderer_host/render_view_host_delegate.h"
[email protected]94d0cc12013-12-18 00:07:4134#include "content/browser/renderer_host/render_view_host_factory.h"
35#include "content/browser/renderer_host/render_view_host_impl.h"
japhet98e9bd82016-06-28 23:48:4536#include "content/common/content_switches_internal.h"
Sreeja Kamishetty46f762c2021-02-05 07:52:4637#include "third_party/blink/public/common/features.h"
Kevin McNee43fe8292021-10-04 22:59:4138#include "third_party/blink/public/common/frame/frame_owner_element_type.h"
Blink Reformata30d4232018-04-07 15:31:0639#include "third_party/blink/public/common/frame/frame_policy.h"
Sreeja Kamishetty0be3b1b2021-08-12 17:04:1540#include "third_party/blink/public/common/loader/loader_constants.h"
Julie Jeongeun Kim70a2e4e2020-02-21 05:09:5441#include "third_party/blink/public/mojom/frame/frame_owner_properties.mojom.h"
[email protected]9b159a52013-10-03 17:24:5542
43namespace content {
44
45namespace {
[email protected]20edca72014-08-14 10:27:5346
Rakina Zata Amni4b1968d2021-09-09 03:29:4747using perfetto::protos::pbzero::ChromeTrackEvent;
48
Sharon Yangefe52632022-03-08 23:06:0649// Helper function to collect SiteInstanceGroups involved in rendering a single
50// FrameTree (which is a subset of SiteInstanceGroups in main frame's
51// proxy_hosts_ because of openers).
52std::set<SiteInstanceGroup*> CollectSiteInstanceGroups(FrameTree* tree) {
53 std::set<SiteInstanceGroup*> groups;
dcheng57e39e22016-01-21 00:25:3854 for (FrameTreeNode* node : tree->Nodes())
Sharon Yangefe52632022-03-08 23:06:0655 groups.insert(node->current_frame_host()->GetSiteInstance()->group());
56 return groups;
alexmos3fcd0ca2015-10-23 18:18:3357}
58
Kevin McNee5f594382021-05-06 23:18:2359// If |node| is the placeholder FrameTreeNode for an embedded frame tree,
60// returns the inner tree's main frame's FrameTreeNode. Otherwise, returns null.
61FrameTreeNode* GetInnerTreeMainFrameNode(FrameTreeNode* node) {
Dominic Farolino377edb302021-07-29 05:57:1862 FrameTreeNode* inner_main_frame_tree_node = FrameTreeNode::GloballyFindByID(
63 node->current_frame_host()->inner_tree_main_frame_tree_node_id());
Kevin McNee5f594382021-05-06 23:18:2364 RenderFrameHostImpl* inner_tree_main_frame =
Dominic Farolino377edb302021-07-29 05:57:1865 inner_main_frame_tree_node
66 ? inner_main_frame_tree_node->current_frame_host()
67 : nullptr;
Kevin McNee5f594382021-05-06 23:18:2368
69 if (inner_tree_main_frame) {
70 DCHECK_NE(node->frame_tree(), inner_tree_main_frame->frame_tree());
71 DCHECK(inner_tree_main_frame->frame_tree_node());
72 }
73
74 return inner_tree_main_frame ? inner_tree_main_frame->frame_tree_node()
75 : nullptr;
76}
77
[email protected]9b159a52013-10-03 17:24:5578} // namespace
79
vmpstr33895d992016-02-24 20:55:2180FrameTree::NodeIterator::NodeIterator(const NodeIterator& other) = default;
81
Fergal Daly55b6d722020-09-11 07:56:3382FrameTree::NodeIterator::~NodeIterator() = default;
dcheng57e39e22016-01-21 00:25:3883
84FrameTree::NodeIterator& FrameTree::NodeIterator::operator++() {
Alex Moshchuk27caae82017-09-11 23:11:1885 if (current_node_ != root_of_subtree_to_skip_) {
Jayson Adams4db0bfe22021-07-15 19:24:0786 // Reserve enough space in the queue to accommodate the nodes we're
87 // going to add, to avoid repeated resize calls.
88 queue_.reserve(queue_.size() + current_node_->child_count());
89
Alex Moshchuk27caae82017-09-11 23:11:1890 for (size_t i = 0; i < current_node_->child_count(); ++i) {
91 FrameTreeNode* child = current_node_->child_at(i);
Kevin McNee5f594382021-05-06 23:18:2392 FrameTreeNode* inner_tree_main_ftn = GetInnerTreeMainFrameNode(child);
Jayson Adams4db0bfe22021-07-15 19:24:0793 queue_.push_back((should_descend_into_inner_trees_ && inner_tree_main_ftn)
94 ? inner_tree_main_ftn
95 : child);
Kevin McNee5f594382021-05-06 23:18:2396 }
97
98 if (should_descend_into_inner_trees_) {
Jayson Adams4db0bfe22021-07-15 19:24:0799 auto unattached_nodes =
100 current_node_->current_frame_host()
101 ->delegate()
102 ->GetUnattachedOwnedNodes(current_node_->current_frame_host());
103
104 // Reserve enough space in the queue to accommodate the nodes we're
105 // going to add.
106 queue_.reserve(queue_.size() + unattached_nodes.size());
107
108 for (auto* unattached_node : unattached_nodes) {
109 queue_.push_back(unattached_node);
Kevin McNee5f594382021-05-06 23:18:23110 }
Alex Moshchuk27caae82017-09-11 23:11:18111 }
dcheng57e39e22016-01-21 00:25:38112 }
113
Kevin McNee5f594382021-05-06 23:18:23114 AdvanceNode();
115 return *this;
116}
dcheng57e39e22016-01-21 00:25:38117
Kevin McNee5f594382021-05-06 23:18:23118FrameTree::NodeIterator& FrameTree::NodeIterator::AdvanceSkippingChildren() {
119 AdvanceNode();
dcheng57e39e22016-01-21 00:25:38120 return *this;
121}
122
123bool FrameTree::NodeIterator::operator==(const NodeIterator& rhs) const {
124 return current_node_ == rhs.current_node_;
125}
126
Kevin McNee5f594382021-05-06 23:18:23127void FrameTree::NodeIterator::AdvanceNode() {
128 if (!queue_.empty()) {
129 current_node_ = queue_.front();
Jayson Adams4db0bfe22021-07-15 19:24:07130 queue_.pop_front();
Kevin McNee5f594382021-05-06 23:18:23131 } else {
132 current_node_ = nullptr;
133 }
134}
135
136FrameTree::NodeIterator::NodeIterator(
137 const std::vector<FrameTreeNode*>& starting_nodes,
138 const FrameTreeNode* root_of_subtree_to_skip,
139 bool should_descend_into_inner_trees)
140 : current_node_(nullptr),
141 root_of_subtree_to_skip_(root_of_subtree_to_skip),
142 should_descend_into_inner_trees_(should_descend_into_inner_trees),
Jayson Adams4db0bfe22021-07-15 19:24:07143 queue_(starting_nodes.begin(), starting_nodes.end()) {
Kevin McNee5f594382021-05-06 23:18:23144 AdvanceNode();
145}
dcheng57e39e22016-01-21 00:25:38146
147FrameTree::NodeIterator FrameTree::NodeRange::begin() {
W. James MacLeance3176d2019-10-18 04:01:45148 // We shouldn't be attempting a frame tree traversal while the tree is
Kevin McNee5f594382021-05-06 23:18:23149 // being constructed or destructed.
150 DCHECK(std::all_of(
151 starting_nodes_.begin(), starting_nodes_.end(),
152 [](FrameTreeNode* ftn) { return ftn->current_frame_host(); }));
153
154 return NodeIterator(starting_nodes_, root_of_subtree_to_skip_,
155 should_descend_into_inner_trees_);
dcheng57e39e22016-01-21 00:25:38156}
157
158FrameTree::NodeIterator FrameTree::NodeRange::end() {
Kevin McNee5f594382021-05-06 23:18:23159 return NodeIterator({}, nullptr, should_descend_into_inner_trees_);
dcheng57e39e22016-01-21 00:25:38160}
161
Kevin McNee5f594382021-05-06 23:18:23162FrameTree::NodeRange::NodeRange(
163 const std::vector<FrameTreeNode*>& starting_nodes,
164 const FrameTreeNode* root_of_subtree_to_skip,
165 bool should_descend_into_inner_trees)
166 : starting_nodes_(starting_nodes),
167 root_of_subtree_to_skip_(root_of_subtree_to_skip),
168 should_descend_into_inner_trees_(should_descend_into_inner_trees) {}
169
170FrameTree::NodeRange::NodeRange(const NodeRange&) = default;
171FrameTree::NodeRange::~NodeRange() = default;
dcheng57e39e22016-01-21 00:25:38172
Carlos Caballero40b0efd2021-01-26 11:55:00173FrameTree::FrameTree(
174 BrowserContext* browser_context,
Carlos Caballero03262522021-02-05 14:49:58175 Delegate* delegate,
Carlos Caballero40b0efd2021-01-26 11:55:00176 NavigationControllerDelegate* navigation_controller_delegate,
177 NavigatorDelegate* navigator_delegate,
178 RenderFrameHostDelegate* render_frame_delegate,
179 RenderViewHostDelegate* render_view_delegate,
180 RenderWidgetHostDelegate* render_widget_delegate,
Sreeja Kamishetty837a10402021-04-23 12:41:59181 RenderFrameHostManager::Delegate* manager_delegate,
Jeremy Roman2d8dfe132021-07-06 20:51:26182 PageDelegate* page_delegate,
Sreeja Kamishetty837a10402021-04-23 12:41:59183 Type type)
Carlos Caballero03262522021-02-05 14:49:58184 : delegate_(delegate),
185 render_frame_delegate_(render_frame_delegate),
[email protected]92404c62013-12-04 16:40:46186 render_view_delegate_(render_view_delegate),
[email protected]fa944cb82013-11-15 17:51:21187 render_widget_delegate_(render_widget_delegate),
188 manager_delegate_(manager_delegate),
Jeremy Roman2d8dfe132021-07-06 20:51:26189 page_delegate_(page_delegate),
Carlos Caballero40b0efd2021-01-26 11:55:00190 navigator_(browser_context,
191 *this,
192 navigator_delegate,
193 navigation_controller_delegate),
[email protected]94d0cc12013-12-18 00:07:41194 root_(new FrameTreeNode(this,
xiaochengh98488162016-05-19 15:17:59195 nullptr,
dcheng860817a2015-05-22 03:16:56196 // The top-level frame must always be in a
197 // document scope.
Antonio Gomes9d5c1ef2020-04-30 20:56:41198 blink::mojom::TreeScopeType::kDocument,
Lukasz Anforowicz7bfb2e92017-11-22 17:19:45199 false,
Pavel Feldman25234722017-10-11 02:49:06200 base::UnguessableToken::Create(),
Julie Jeongeun Kim70a2e4e2020-02-21 05:09:54201 blink::mojom::FrameOwnerProperties(),
Kevin McNee43fe8292021-10-04 22:59:41202 blink::FrameOwnerElementType::kNone,
Dominic Farolino08662c82021-06-11 07:36:34203 blink::FramePolicy())),
thestige62f7382016-11-08 18:31:39204 focused_frame_tree_node_id_(FrameTreeNode::kFrameTreeNodeInvalidId),
Sreeja Kamishetty837a10402021-04-23 12:41:59205 load_progress_(0.0),
206 type_(type) {}
[email protected]9b159a52013-10-03 17:24:55207
208FrameTree::~FrameTree() {
Takashi Toyoshimaea534ef22021-07-21 03:27:59209 is_being_destroyed_ = true;
Carlos Caballero101ac26b2021-03-24 11:54:05210#if DCHECK_IS_ON()
211 DCHECK(was_shut_down_);
212#endif
nick70b782d2015-10-06 17:37:04213 delete root_;
214 root_ = nullptr;
[email protected]9b159a52013-10-03 17:24:55215}
216
vishal.b782eb5d2015-04-29 12:22:57217FrameTreeNode* FrameTree::FindByID(int frame_tree_node_id) {
dcheng57e39e22016-01-21 00:25:38218 for (FrameTreeNode* node : Nodes()) {
219 if (node->frame_tree_node_id() == frame_tree_node_id)
220 return node;
221 }
222 return nullptr;
[email protected]9b159a52013-10-03 17:24:55223}
224
nasko479ea5a2015-02-14 00:03:04225FrameTreeNode* FrameTree::FindByRoutingID(int process_id, int routing_id) {
dmazzoni0b5d2482014-09-10 19:45:57226 RenderFrameHostImpl* render_frame_host =
227 RenderFrameHostImpl::FromID(process_id, routing_id);
228 if (render_frame_host) {
229 FrameTreeNode* result = render_frame_host->frame_tree_node();
230 if (this == result->frame_tree())
231 return result;
232 }
233
234 RenderFrameProxyHost* render_frame_proxy_host =
235 RenderFrameProxyHost::FromID(process_id, routing_id);
236 if (render_frame_proxy_host) {
237 FrameTreeNode* result = render_frame_proxy_host->frame_tree_node();
238 if (this == result->frame_tree())
239 return result;
240 }
241
creis6a93a812015-04-24 23:13:17242 return nullptr;
243}
244
245FrameTreeNode* FrameTree::FindByName(const std::string& name) {
246 if (name.empty())
nick70b782d2015-10-06 17:37:04247 return root_;
creis6a93a812015-04-24 23:13:17248
dcheng57e39e22016-01-21 00:25:38249 for (FrameTreeNode* node : Nodes()) {
250 if (node->frame_name() == name)
251 return node;
[email protected]9b159a52013-10-03 17:24:55252 }
dcheng57e39e22016-01-21 00:25:38253
254 return nullptr;
255}
256
257FrameTree::NodeRange FrameTree::Nodes() {
Alex Moshchuk27caae82017-09-11 23:11:18258 return NodesExceptSubtree(nullptr);
dcheng57e39e22016-01-21 00:25:38259}
260
kenrb61b6c252016-03-22 17:37:15261FrameTree::NodeRange FrameTree::SubtreeNodes(FrameTreeNode* subtree_root) {
Kevin McNee5f594382021-05-06 23:18:23262 return NodeRange({subtree_root}, nullptr,
263 /* should_descend_into_inner_trees */ false);
264}
265
Kevin McNee53f0b2d2021-11-02 18:00:45266FrameTree::NodeRange FrameTree::NodesIncludingInnerTreeNodes() {
267 return NodeRange({root_}, nullptr,
268 /* should_descend_into_inner_trees */ true);
269}
270
Sreeja Kamishettyd64b993d2022-02-14 12:04:42271std::vector<FrameTreeNode*> FrameTree::CollectNodesForIsLoading() {
272 FrameTree::NodeRange node_range = NodesIncludingInnerTreeNodes();
273 FrameTree::NodeIterator node_iter = node_range.begin();
274 std::vector<FrameTreeNode*> nodes;
275
276 DCHECK(node_iter != node_range.end());
277 FrameTree* root_loading_tree = root_->frame_tree()->LoadingTree();
278 while (node_iter != node_range.end()) {
279 // Skip over frame trees and children which belong to inner web contents
280 // i.e., when nodes doesn't point to the same loading frame tree.
281 if ((*node_iter)->frame_tree()->LoadingTree() != root_loading_tree) {
282 node_iter.AdvanceSkippingChildren();
283 } else {
284 nodes.push_back(*node_iter);
285 ++node_iter;
286 }
287 }
288 return nodes;
289}
290
Kevin McNee5f594382021-05-06 23:18:23291FrameTree::NodeRange FrameTree::SubtreeAndInnerTreeNodes(
292 RenderFrameHostImpl* parent) {
293 std::vector<FrameTreeNode*> starting_nodes;
294 starting_nodes.reserve(parent->child_count());
295 for (size_t i = 0; i < parent->child_count(); ++i) {
296 FrameTreeNode* child = parent->child_at(i);
297 FrameTreeNode* inner_tree_main_ftn = GetInnerTreeMainFrameNode(child);
298 starting_nodes.push_back(inner_tree_main_ftn ? inner_tree_main_ftn : child);
299 }
300 const std::vector<FrameTreeNode*> unattached_owned_nodes =
301 parent->delegate()->GetUnattachedOwnedNodes(parent);
302 starting_nodes.insert(starting_nodes.end(), unattached_owned_nodes.begin(),
303 unattached_owned_nodes.end());
304 return NodeRange(starting_nodes, nullptr,
305 /* should_descend_into_inner_trees */ true);
kenrb61b6c252016-03-22 17:37:15306}
307
Alex Moshchuk27caae82017-09-11 23:11:18308FrameTree::NodeRange FrameTree::NodesExceptSubtree(FrameTreeNode* node) {
Kevin McNee5f594382021-05-06 23:18:23309 return NodeRange({root_}, node, /* should_descend_into_inner_trees */ false);
[email protected]9b159a52013-10-03 17:24:55310}
311
Sreeja Kamishettyd64b993d2022-02-14 12:04:42312FrameTree* FrameTree::LoadingTree() {
313 // We return the delegate's loading frame tree to infer loading related
314 // states.
315 return delegate_->LoadingTree();
316}
317
Lucas Furukawa Gadani99125822019-01-03 15:41:49318FrameTreeNode* FrameTree::AddFrame(
Alexander Timin381e7e182020-04-28 19:04:03319 RenderFrameHostImpl* parent,
Balazs Engedyba034e72017-10-27 22:26:28320 int process_id,
321 int new_routing_id,
danakj0bdfacd2021-01-20 19:27:18322 mojo::PendingAssociatedRemote<mojom::Frame> frame_remote,
Oksana Zhuravlovafee097c2019-07-26 17:01:30323 mojo::PendingReceiver<blink::mojom::BrowserInterfaceBroker>
324 browser_interface_broker_receiver,
Antonio Sartoridb967c52021-01-20 09:54:30325 blink::mojom::PolicyContainerBindParamsPtr policy_container_bind_params,
Antonio Gomes9d5c1ef2020-04-30 20:56:41326 blink::mojom::TreeScopeType scope,
Balazs Engedyba034e72017-10-27 22:26:28327 const std::string& frame_name,
328 const std::string& frame_unique_name,
Lukasz Anforowicz7bfb2e92017-11-22 17:19:45329 bool is_created_by_script,
Chris Hamilton3ff6ed0e2021-02-19 03:54:04330 const blink::LocalFrameToken& frame_token,
Balazs Engedyba034e72017-10-27 22:26:28331 const base::UnguessableToken& devtools_frame_token,
Luna Luc3fdacdf2017-11-08 04:48:53332 const blink::FramePolicy& frame_policy,
Julie Jeongeun Kim70a2e4e2020-02-21 05:09:54333 const blink::mojom::FrameOwnerProperties& frame_owner_properties,
Ehsan Karamad192a8da2018-10-21 03:48:08334 bool was_discarded,
Kevin McNee43fe8292021-10-04 22:59:41335 blink::FrameOwnerElementType owner_type,
336 bool is_dummy_frame_for_inner_tree) {
nick8814e652015-12-18 01:44:12337 CHECK_NE(new_routing_id, MSG_ROUTING_NONE);
Dominic Farolino4bc10ee2021-08-31 00:37:36338 // Normally this path is for blink adding a child local frame. But both
339 // portals and fenced frames add a dummy child frame that never gets a
340 // corresponding RenderFrameImpl in any renderer process, and therefore its
341 // `frame_remote` is invalid. Also its RenderFrameHostImpl is exempt from
342 // having `RenderFrameCreated()` called on it (see later in this method, as
343 // well as `WebContentsObserverConsistencyChecker::RenderFrameHostChanged()`).
Kevin McNee43fe8292021-10-04 22:59:41344 DCHECK_NE(frame_remote.is_valid(), is_dummy_frame_for_inner_tree);
345 DCHECK_NE(browser_interface_broker_receiver.is_valid(),
346 is_dummy_frame_for_inner_tree);
nick8814e652015-12-18 01:44:12347
dgroganfb22f9a2014-10-20 21:32:32348 // A child frame always starts with an initial empty document, which means
349 // it is in the same SiteInstance as the parent frame. Ensure that the process
350 // which requested a child frame to be added is the same as the process of the
351 // parent node.
Dominic Farolino6caf3032021-10-20 03:50:08352 CHECK_EQ(parent->GetProcess()->GetID(), process_id);
dgroganfb22f9a2014-10-20 21:32:32353
iclelland098da752017-06-28 13:46:50354 std::unique_ptr<FrameTreeNode> new_node = base::WrapUnique(new FrameTreeNode(
Harkiran Bolaria0b3bdef02022-03-10 13:04:40355 this, parent, scope, is_created_by_script, devtools_frame_token,
356 frame_owner_properties, owner_type, frame_policy));
iclelland098da752017-06-28 13:46:50357
358 // Set sandbox flags and container policy and make them effective immediately,
Charlie Hu5130d25e2021-03-05 21:53:39359 // since initial sandbox flags and permissions policy should apply to the
360 // initial empty document in the frame. This needs to happen before the call
361 // to AddChild so that the effective policy is sent to any newly-created
iclelland098da752017-06-28 13:46:50362 // RenderFrameProxy objects when the RenderFrameHost is created.
Charlie Hu5ffc0152019-12-06 15:59:53363 // SetPendingFramePolicy is necessary here because next navigation on this
364 // frame will need the value of pending frame policy instead of effective
365 // frame policy.
Ian Clellandcdc4f312017-10-13 22:24:12366 new_node->SetPendingFramePolicy(frame_policy);
iclelland098da752017-06-28 13:46:50367
Shubhie Panickerddf2a4e2018-03-06 00:09:06368 if (was_discarded)
369 new_node->set_was_discarded();
370
iclelland098da752017-06-28 13:46:50371 // Add the new node to the FrameTree, creating the RenderFrameHost.
Harkiran Bolaria0b3bdef02022-03-10 13:04:40372 FrameTreeNode* added_node = parent->AddChild(
373 std::move(new_node), new_routing_id, std::move(frame_remote), frame_token,
374 frame_policy, frame_name, frame_unique_name);
nick8814e652015-12-18 01:44:12375
shivanigithub4cd016a2021-09-20 21:10:30376 added_node->SetFencedFrameNonceIfNeeded();
377
Kevin McNee43fe8292021-10-04 22:59:41378 if (browser_interface_broker_receiver.is_valid()) {
379 added_node->current_frame_host()->BindBrowserInterfaceBrokerReceiver(
380 std::move(browser_interface_broker_receiver));
381 }
Oksana Zhuravlovafee097c2019-07-26 17:01:30382
Antonio Sartoridb967c52021-01-20 09:54:30383 if (policy_container_bind_params) {
Antonio Sartoria1fd1432020-11-25 09:10:20384 added_node->current_frame_host()->policy_container_host()->Bind(
Antonio Sartoridb967c52021-01-20 09:54:30385 std::move(policy_container_bind_params));
Antonio Sartoria1fd1432020-11-25 09:10:20386 }
387
nasko03ecfad2016-08-02 00:54:06388 // The last committed NavigationEntry may have a FrameNavigationEntry with the
389 // same |frame_unique_name|, since we don't remove FrameNavigationEntries if
390 // their frames are deleted. If there is a stale one, remove it to avoid
391 // conflicts on future updates.
Fergal Daly09d6c762020-05-29 02:05:18392 NavigationEntryImpl* last_committed_entry = static_cast<NavigationEntryImpl*>(
Carlos Caballero40b0efd2021-01-26 11:55:00393 navigator_.controller().GetLastCommittedEntry());
Lukasz Anforowicz7bfb2e92017-11-22 17:19:45394 if (last_committed_entry) {
395 last_committed_entry->RemoveEntryForFrame(
396 added_node, /* only_if_different_position = */ true);
397 }
nasko03ecfad2016-08-02 00:54:06398
nick8814e652015-12-18 01:44:12399 // Now that the new node is part of the FrameTree and has a RenderFrameHost,
400 // we can announce the creation of the initial RenderFrame which already
401 // exists in the renderer process.
Sreeja Kamishetty5b699622021-01-22 12:54:08402 // For consistency with navigating to a new RenderFrameHost case, we dispatch
403 // RenderFrameCreated before RenderFrameHostChanged.
Kevin McNee43fe8292021-10-04 22:59:41404 if (!is_dummy_frame_for_inner_tree) {
Dominic Farolino4bc10ee2021-08-31 00:37:36405 // The outer dummy FrameTreeNode for both portals and fenced frames does not
406 // have a live RenderFrame in the renderer process.
Fergal Dalyf9ea35c2020-12-11 15:26:01407 added_node->current_frame_host()->RenderFrameCreated();
Ehsan Karamad44fc72112019-02-26 18:15:47408 }
Sreeja Kamishetty5b699622021-01-22 12:54:08409
410 // Notify the delegate of the creation of the current RenderFrameHost.
411 // This is only for subframes, as the main frame case is taken care of by
412 // WebContentsImpl::Init.
413 manager_delegate_->NotifySwappedFromRenderManager(
Dave Tapuskae45d6fd2021-09-29 17:03:59414 nullptr, added_node->current_frame_host());
Lucas Furukawa Gadani99125822019-01-03 15:41:49415 return added_node;
[email protected]9b159a52013-10-03 17:24:55416}
417
[email protected]58faf942014-02-20 21:03:58418void FrameTree::RemoveFrame(FrameTreeNode* child) {
Alexander Timin381e7e182020-04-28 19:04:03419 RenderFrameHostImpl* parent = child->parent();
[email protected]58faf942014-02-20 21:03:58420 if (!parent) {
421 NOTREACHED() << "Unexpected RemoveFrame call for main frame.";
422 return;
[email protected]9b159a52013-10-03 17:24:55423 }
424
Alexander Timin381e7e182020-04-28 19:04:03425 parent->RemoveChild(child);
[email protected]9b159a52013-10-03 17:24:55426}
427
Harkiran Bolaria2912a6b32022-02-22 16:43:45428void FrameTree::CreateProxiesForSiteInstance(
429 FrameTreeNode* source,
430 SiteInstance* site_instance,
431 const scoped_refptr<BrowsingContextState>&
432 source_new_browsing_context_state) {
Sharon Yang57bde122022-03-01 20:01:12433 SiteInstanceGroup* group =
434 static_cast<SiteInstanceImpl*>(site_instance)->group();
naskob3041b98a42016-03-12 04:43:06435 // Create the RenderFrameProxyHost for the new SiteInstance.
alexmos58729042015-06-18 23:20:00436 if (!source || !source->IsMainFrame()) {
Sharon Yang57bde122022-03-01 20:01:12437 RenderViewHostImpl* render_view_host = GetRenderViewHost(group).get();
arthursonzognic5be3842019-07-09 11:49:14438 if (render_view_host) {
Sharon Yang57bde122022-03-01 20:01:12439 root()->render_manager()->EnsureRenderViewInitialized(render_view_host,
440 group);
arthursonzognic5be3842019-07-09 11:49:14441 } else {
Harkiran Bolaria2912a6b32022-02-22 16:43:45442 // Due to the check above, we are creating either an opener proxy (when
443 // source is null) or a main frame proxy due to a subframe navigation
444 // (when source is not a main frame). In the former case, we should use
445 // root's current BrowsingContextState, while in the latter case we should
446 // use BrowsingContextState from the main RenderFrameHost of the subframe
447 // being navigated. We want to ensure that the RenderView is created in
448 // the right SiteInstance if it doesn't exist, before creating the other
449 // proxies; if the RenderView doesn't exist, the only way to do this is to
450 // also create a proxy for the main frame as well.
451 root()->render_manager()->CreateRenderFrameProxy(
452 site_instance,
453 source ? source->parent()->GetMainFrame()->browsing_context_state()
454 : root()->current_frame_host()->browsing_context_state());
[email protected]82307f6b2014-08-07 03:30:12455 }
456 }
457
Alex Moshchuk1226b152019-11-08 18:23:45458 // Check whether we're in an inner delegate and |site_instance| corresponds
459 // to the outer delegate. Subframe proxies aren't needed if this is the
460 // case.
461 bool is_site_instance_for_outer_delegate = false;
462 RenderFrameProxyHost* outer_delegate_proxy =
463 root()->render_manager()->GetProxyToOuterDelegate();
464 if (outer_delegate_proxy) {
465 is_site_instance_for_outer_delegate =
466 (site_instance == outer_delegate_proxy->GetSiteInstance());
467 }
468
naskoe6edde32014-10-17 15:36:48469 // Proxies are created in the FrameTree in response to a node navigating to a
470 // new SiteInstance. Since |source|'s navigation will replace the currently
Alex Moshchuk27caae82017-09-11 23:11:18471 // loaded document, the entire subtree under |source| will be removed, and
472 // thus proxy creation is skipped for all nodes in that subtree.
473 //
474 // However, a proxy *is* needed for the |source| node itself. This lets
475 // cross-process navigations in |source| start with a proxy and follow a
476 // remote-to-local transition, which avoids race conditions in cases where
477 // other navigations need to reference |source| before it commits. See
478 // https://crbug.com/756790 for more background. Therefore,
479 // NodesExceptSubtree(source) will include |source| in the nodes traversed
480 // (see NodeIterator::operator++).
481 for (FrameTreeNode* node : NodesExceptSubtree(source)) {
dcheng57e39e22016-01-21 00:25:38482 // If a new frame is created in the current SiteInstance, other frames in
483 // that SiteInstance don't need a proxy for the new frame.
Alex Moshchuk27caae82017-09-11 23:11:18484 RenderFrameHostImpl* current_host =
485 node->render_manager()->current_frame_host();
486 SiteInstance* current_instance = current_host->GetSiteInstance();
487 if (current_instance != site_instance) {
488 if (node == source && !current_host->IsRenderFrameLive()) {
Fergal Daly6de62f52020-10-14 01:56:44489 // We don't create a proxy at |source| when the current RenderFrameHost
490 // isn't live. This is because either (1) the speculative
Alex Moshchuk27caae82017-09-11 23:11:18491 // RenderFrameHost will be committed immediately, and the proxy
Fergal Daly6de62f52020-10-14 01:56:44492 // destroyed right away, in GetFrameHostForNavigation, which makes the
493 // races above impossible, or (2) the early commit will be skipped due
494 // to ShouldSkipEarlyCommitPendingForCrashedFrame, in which case the
495 // proxy for |source| *is* needed, but it will be created later in
496 // CreateProxiesForNewRenderFrameHost.
497 //
498 // TODO(fergal): Consider creating a proxy for |source| here rather than
499 // in CreateProxiesForNewRenderFrameHost for case (2) above.
Alex Moshchuk27caae82017-09-11 23:11:18500 continue;
501 }
Alex Moshchuk1226b152019-11-08 18:23:45502
503 // Do not create proxies for subframes in the outer delegate's
504 // SiteInstance, since there is no need to expose these subframes to the
505 // outer delegate. See also comments in CreateProxiesForChildFrame() and
506 // https://crbug.com/1013553.
507 if (!node->IsMainFrame() && is_site_instance_for_outer_delegate)
508 continue;
509
Harkiran Bolaria2912a6b32022-02-22 16:43:45510 // If |node| is the FrameTreeNode being navigated, we use
511 // |browsing_context_state| (as BrowsingContextState might change for
512 // cross-BrowsingInstance navigations). Otherwise, we should use the
513 // |node|'s current BrowsingContextState.
514 node->render_manager()->CreateRenderFrameProxy(
515 site_instance,
516 node == source
517 ? source_new_browsing_context_state
518 : node->current_frame_host()->browsing_context_state());
Alex Moshchuk27caae82017-09-11 23:11:18519 }
dcheng57e39e22016-01-21 00:25:38520 }
[email protected]82307f6b2014-08-07 03:30:12521}
522
[email protected]9b159a52013-10-03 17:24:55523RenderFrameHostImpl* FrameTree::GetMainFrame() const {
[email protected]94d0cc12013-12-18 00:07:41524 return root_->current_frame_host();
[email protected]9b159a52013-10-03 17:24:55525}
526
[email protected]9c9343b2014-03-08 02:56:07527FrameTreeNode* FrameTree::GetFocusedFrame() {
528 return FindByID(focused_frame_tree_node_id_);
529}
530
Sharon Yangefe52632022-03-08 23:06:06531void FrameTree::SetFocusedFrame(FrameTreeNode* node,
532 SiteInstanceGroup* source) {
Rakina Zata Amnicca4889e2021-09-28 23:25:55533 CHECK(node->current_frame_host()->IsActive());
alexmos5357efb2015-12-16 21:44:00534 if (node == GetFocusedFrame())
535 return;
536
Sharon Yangefe52632022-03-08 23:06:06537 std::set<SiteInstanceGroup*> frame_tree_groups =
538 CollectSiteInstanceGroups(this);
alexmosb1dc2162015-11-05 00:59:20539
Sharon Yangefe52632022-03-08 23:06:06540 SiteInstanceGroup* current_group =
541 node->current_frame_host()->GetSiteInstance()->group();
alexmos5357efb2015-12-16 21:44:00542
Sharon Yang7424bda2021-11-04 20:27:43543 // Update the focused frame in all other SiteInstanceGroups. If focus changes
544 // to a cross-group frame, this allows the old focused frame's renderer
alexmosb1dc2162015-11-05 00:59:20545 // process to clear focus from that frame and fire blur events. It also
546 // ensures that the latest focused frame is available in all renderers to
547 // compute document.activeElement.
alexmos5357efb2015-12-16 21:44:00548 //
Sharon Yangefe52632022-03-08 23:06:06549 // We do not notify the |source| SiteInstanceGroup because it already knows
550 // the new focused frame (since it initiated the focus change), and we notify
551 // the new focused frame's SiteInstanceGroup (if it differs from |source|)
552 // separately below.
553 for (auto* group : frame_tree_groups) {
554 if (group != source && group != current_group) {
555 RenderFrameProxyHost* proxy = node->current_frame_host()
556 ->browsing_context_state()
557 ->GetRenderFrameProxyHost(group);
Sharon Yangf92842a2022-03-01 18:21:47558
Rakina Zata Amni80700402021-09-20 17:18:03559 if (proxy) {
560 proxy->SetFocusedFrame();
561 } else {
Sharon Yangf92842a2022-03-01 18:21:47562 base::debug::DumpWithoutCrashing();
Rakina Zata Amni80700402021-09-20 17:18:03563 }
alexmosb1dc2162015-11-05 00:59:20564 }
alexmosca2c6ba2015-10-01 21:52:25565 }
566
Sharon Yangefe52632022-03-08 23:06:06567 // If |node| was focused from a cross-group frame (i.e., via
alexmos5357efb2015-12-16 21:44:00568 // window.focus()), tell its RenderFrame that it should focus.
Sharon Yangefe52632022-03-08 23:06:06569 if (current_group != source)
alexmos5357efb2015-12-16 21:44:00570 node->current_frame_host()->SetFocusedFrame();
571
[email protected]9c9343b2014-03-08 02:56:07572 focused_frame_tree_node_id_ = node->frame_tree_node_id();
alexmos21acae52015-11-07 01:04:43573 node->DidFocus();
dmazzonif27bf892016-03-10 15:51:55574
575 // The accessibility tree data for the root of the frame tree keeps
576 // track of the focused frame too, so update that every time the
577 // focused frame changes.
Kevin McNee582a7d62021-10-12 21:42:22578 root()
579 ->current_frame_host()
580 ->GetOutermostMainFrameOrEmbedder()
581 ->UpdateAXTreeData();
[email protected]9c9343b2014-03-08 02:56:07582}
583
arthursonzognic5be3842019-07-09 11:49:14584scoped_refptr<RenderViewHostImpl> FrameTree::CreateRenderViewHost(
avib7348942015-12-25 20:57:10585 SiteInstance* site_instance,
avib7348942015-12-25 20:57:10586 int32_t main_frame_routing_id,
danakj08eb51d2020-12-30 20:15:23587 bool swapped_out,
588 bool renderer_initiated_creation) {
dcheng29f5a6c2015-08-31 21:43:27589 RenderViewHostImpl* rvh =
590 static_cast<RenderViewHostImpl*>(RenderViewHostFactory::Create(
Carlos Caballero00d9c862021-01-22 12:37:34591 this, site_instance, render_view_delegate_, render_widget_delegate_,
danakj08eb51d2020-12-30 20:15:23592 main_frame_routing_id, swapped_out, renderer_initiated_creation));
arthursonzognic5be3842019-07-09 11:49:14593 return base::WrapRefCounted(rvh);
[email protected]94d0cc12013-12-18 00:07:41594}
595
arthursonzognic5be3842019-07-09 11:49:14596scoped_refptr<RenderViewHostImpl> FrameTree::GetRenderViewHost(
Sharon Yang57bde122022-03-01 20:01:12597 SiteInstanceGroup* group) {
Sharon Yanga2fe85e2022-02-09 21:38:29598 // When called from RenderFrameHostManager::CreateRenderFrameHost, it's
599 // possible that a RenderProcessHost hasn't yet been created, which means
Sharon Yang57bde122022-03-01 20:01:12600 // a SiteInstanceGroup won't have been created yet.
Sharon Yanga2fe85e2022-02-09 21:38:29601 if (!group)
602 return nullptr;
603
604 auto it = render_view_host_map_.find(GetRenderViewHostMapId(group));
arthursonzogni88e54ae2019-04-15 12:57:36605 if (it == render_view_host_map_.end())
606 return nullptr;
alexmos9aa61232016-04-26 21:54:02607
arthursonzognic5be3842019-07-09 11:49:14608 return base::WrapRefCounted(it->second);
[email protected]94d0cc12013-12-18 00:07:41609}
610
Aaron Colwell78b4bde2021-03-16 16:16:09611FrameTree::RenderViewHostMapId FrameTree::GetRenderViewHostMapId(
Sharon Yangc581a0c2021-11-02 18:09:39612 SiteInstanceGroup* site_instance_group) const {
613 return RenderViewHostMapId::FromUnsafeValue(
614 site_instance_group->GetId().value());
Lowell Manners75055a132019-10-11 10:30:29615}
616
Aaron Colwell78b4bde2021-03-16 16:16:09617void FrameTree::RegisterRenderViewHost(RenderViewHostMapId id,
618 RenderViewHostImpl* rvh) {
Rakina Zata Amni4b1968d2021-09-09 03:29:47619 TRACE_EVENT_INSTANT("navigation", "FrameTree::RegisterRenderViewHost",
620 ChromeTrackEvent::kRenderViewHost, *rvh);
Aaron Colwell78b4bde2021-03-16 16:16:09621 CHECK(!base::Contains(render_view_host_map_, id));
622 render_view_host_map_[id] = rvh;
623}
624
625void FrameTree::UnregisterRenderViewHost(RenderViewHostMapId id,
Aaron Colwellc4bd7d62021-01-29 04:23:13626 RenderViewHostImpl* rvh) {
Rakina Zata Amni4b1968d2021-09-09 03:29:47627 TRACE_EVENT_INSTANT("navigation", "FrameTree::UnregisterRenderViewHost",
628 ChromeTrackEvent::kRenderViewHost, *rvh);
Aaron Colwell78b4bde2021-03-16 16:16:09629 auto it = render_view_host_map_.find(id);
arthursonzogni88e54ae2019-04-15 12:57:36630 CHECK(it != render_view_host_map_.end());
arthursonzognic5be3842019-07-09 11:49:14631 CHECK_EQ(it->second, rvh);
632 render_view_host_map_.erase(it);
[email protected]94d0cc12013-12-18 00:07:41633}
634
arthursonzogni0a2007792019-05-28 21:32:48635void FrameTree::FrameUnloading(FrameTreeNode* frame) {
636 if (frame->frame_tree_node_id() == focused_frame_tree_node_id_)
637 focused_frame_tree_node_id_ = FrameTreeNode::kFrameTreeNodeInvalidId;
638
639 // Ensure frames that are about to be deleted aren't visible from the other
640 // processes anymore.
Harkiran Bolaria0b3bdef02022-03-10 13:04:40641 frame->GetBrowsingContextStateForSubframe()->ResetProxyHosts();
arthursonzogni0a2007792019-05-28 21:32:48642}
643
dmazzonie950ea232015-03-13 21:39:45644void FrameTree::FrameRemoved(FrameTreeNode* frame) {
nick53d5cbf2015-04-23 22:50:14645 if (frame->frame_tree_node_id() == focused_frame_tree_node_id_)
thestige62f7382016-11-08 18:31:39646 focused_frame_tree_node_id_ = FrameTreeNode::kFrameTreeNodeInvalidId;
dmazzonie950ea232015-03-13 21:39:45647}
648
Sreeja Kamishetty0be3b1b2021-08-12 17:04:15649double FrameTree::GetLoadProgress() {
650 if (root_->HasNavigation())
651 return blink::kInitialLoadProgress;
652
653 return root_->current_frame_host()->GetPage().load_progress();
fdegans1d16355162015-03-26 11:58:34654}
655
clamy44e84ce2016-02-22 15:38:25656bool FrameTree::IsLoading() const {
Sreeja Kamishetty15f9944a22022-03-10 10:16:08657 for (const FrameTreeNode* node :
658 const_cast<FrameTree*>(this)->CollectNodesForIsLoading()) {
dcheng57e39e22016-01-21 00:25:38659 if (node->IsLoading())
660 return true;
661 }
662 return false;
fdegans1d16355162015-03-26 11:58:34663}
664
alexmos3fcd0ca2015-10-23 18:18:33665void FrameTree::ReplicatePageFocus(bool is_focused) {
Dave Tapuska53e6ce12021-08-06 16:08:24666 // Focus loss may occur while this FrameTree is being destroyed. Don't
667 // send the message in this case, as the main frame's RenderFrameHost and
668 // other state has already been cleared.
669 if (is_being_destroyed_)
670 return;
Sharon Yangefe52632022-03-08 23:06:06671 std::set<SiteInstanceGroup*> frame_tree_site_instance_groups =
672 CollectSiteInstanceGroups(this);
alexmos3fcd0ca2015-10-23 18:18:33673
Sharon Yangefe52632022-03-08 23:06:06674 // Send the focus update to main frame's proxies in all SiteInstanceGroups of
alexmos3fcd0ca2015-10-23 18:18:33675 // other frames in this FrameTree. Note that the main frame might also know
Sharon Yangefe52632022-03-08 23:06:06676 // about proxies in SiteInstanceGroups for frames in a different FrameTree
677 // (e.g., for window.open), so we can't just iterate over its proxy_hosts_ in
alexmos3fcd0ca2015-10-23 18:18:33678 // RenderFrameHostManager.
Sharon Yangefe52632022-03-08 23:06:06679 for (auto* group : frame_tree_site_instance_groups)
680 SetPageFocus(group, is_focused);
alexmos0d7e0b09b2015-10-29 22:11:48681}
alexmos3fcd0ca2015-10-23 18:18:33682
Sreeja Kamishetty60e47132022-02-08 12:51:53683bool FrameTree::IsPortal() {
684 return delegate_->IsPortal();
685}
686
Sharon Yangefe52632022-03-08 23:06:06687void FrameTree::SetPageFocus(SiteInstanceGroup* group, bool is_focused) {
alexmos0d7e0b09b2015-10-29 22:11:48688 RenderFrameHostManager* root_manager = root_->render_manager();
689
Adithya Srinivasan47731222021-01-22 15:02:42690 // Portal frame tree should not get page focus.
Sreeja Kamishetty60e47132022-02-08 12:51:53691 DCHECK(!IsPortal() || !is_focused);
Adithya Srinivasan47731222021-01-22 15:02:42692
alexmos0d7e0b09b2015-10-29 22:11:48693 // This is only used to set page-level focus in cross-process subframes, and
Sharon Yangefe52632022-03-08 23:06:06694 // requests to set focus in main frame's SiteInstanceGroup are ignored.
695 if (group != root_manager->current_frame_host()->GetSiteInstance()->group()) {
696 RenderFrameProxyHost* proxy = root_manager->current_frame_host()
697 ->browsing_context_state()
698 ->GetRenderFrameProxyHost(group);
Julie Jeongeun Kim2002cb32020-01-17 11:37:29699 proxy->GetAssociatedRemoteFrame()->SetPageFocus(is_focused);
alexmos3fcd0ca2015-10-23 18:18:33700 }
701}
702
W. James MacLeanb70fab82020-05-01 18:51:14703void FrameTree::RegisterExistingOriginToPreventOptInIsolation(
704 const url::Origin& previously_visited_origin,
705 NavigationRequest* navigation_request_to_exclude) {
W. James MacLeanc6dc86c2021-08-12 13:58:37706 controller().RegisterExistingOriginToPreventOptInIsolation(
707 previously_visited_origin);
708
W. James MacLeanb70fab82020-05-01 18:51:14709 std::unordered_set<SiteInstance*> matching_site_instances;
710
711 // Be sure to visit all RenderFrameHosts associated with this frame that might
712 // have an origin that could script other frames. We skip RenderFrameHosts
713 // that are in the bfcache, assuming there's no way for a frame to join the
714 // BrowsingInstance of a bfcache RFH while it's in the cache.
715 for (auto* frame_tree_node : SubtreeNodes(root())) {
716 auto* frame_host = frame_tree_node->current_frame_host();
W. James MacLeanb70fab82020-05-01 18:51:14717 if (previously_visited_origin == frame_host->GetLastCommittedOrigin())
718 matching_site_instances.insert(frame_host->GetSiteInstance());
719
720 if (frame_host->HasCommittingNavigationRequestForOrigin(
721 previously_visited_origin, navigation_request_to_exclude)) {
722 matching_site_instances.insert(frame_host->GetSiteInstance());
723 }
724
725 auto* spec_frame_host =
726 frame_tree_node->render_manager()->speculative_frame_host();
727 if (spec_frame_host &&
728 spec_frame_host->HasCommittingNavigationRequestForOrigin(
729 previously_visited_origin, navigation_request_to_exclude)) {
730 matching_site_instances.insert(spec_frame_host->GetSiteInstance());
731 }
732
733 auto* navigation_request = frame_tree_node->navigation_request();
734 if (navigation_request &&
735 navigation_request != navigation_request_to_exclude &&
736 navigation_request->HasCommittingOrigin(previously_visited_origin)) {
737 matching_site_instances.insert(frame_host->GetSiteInstance());
738 }
739 }
740
741 // Update any SiteInstances found to contain |origin|.
742 for (auto* site_instance : matching_site_instances) {
743 static_cast<SiteInstanceImpl*>(site_instance)
744 ->PreventOptInOriginIsolation(previously_visited_origin);
745 }
746}
747
Carlos Caballero40b0efd2021-01-26 11:55:00748void FrameTree::Init(SiteInstance* main_frame_site_instance,
749 bool renderer_initiated_creation,
Rakina Zata Amniafd3c6582021-11-30 06:19:17750 const std::string& main_frame_name,
Harkiran Bolaria5ce27632022-01-20 15:05:05751 RenderFrameHostImpl* opener,
752 const blink::FramePolicy& frame_policy) {
Carlos Caballero40b0efd2021-01-26 11:55:00753 // blink::FrameTree::SetName always keeps |unique_name| empty in case of a
754 // main frame - let's do the same thing here.
755 std::string unique_name;
Sreeja Kamishetty3699c35f2021-02-12 15:10:58756 root_->render_manager()->InitRoot(main_frame_site_instance,
Harkiran Bolaria880a7632022-02-28 16:02:50757 renderer_initiated_creation, frame_policy,
758 main_frame_name);
shivanigithub4cd016a2021-09-20 21:10:30759 root_->SetFencedFrameNonceIfNeeded();
Rakina Zata Amniafd3c6582021-11-30 06:19:17760
761 // The initial empty document should inherit the origin of its opener (the
762 // origin may change after the first commit), except when they are in
763 // different browsing context groups (`renderer_initiated_creation` is false),
764 // where it should use a new opaque origin.
765 // See also https://crbug.com/932067.
766 //
767 // Note that the origin of the new frame might depend on sandbox flags.
768 // Checking sandbox flags of the new frame should be safe at this point,
769 // because the flags should be already inherited when creating the root node.
770 DCHECK(!renderer_initiated_creation || opener);
771 root_->current_frame_host()->SetOriginDependentStateOfNewFrame(
772 renderer_initiated_creation ? opener->GetLastCommittedOrigin()
773 : url::Origin());
Rakina Zata Amni2322f4f82022-01-24 13:24:24774
775 if (blink::features::IsInitialNavigationEntryEnabled())
776 controller().CreateInitialEntry();
Carlos Caballero40b0efd2021-01-26 11:55:00777}
778
Carlos Caballeroede6f8c2021-01-28 11:01:50779void FrameTree::DidAccessInitialMainDocument() {
780 OPTIONAL_TRACE_EVENT0("content", "FrameTree::DidAccessInitialDocument");
781 has_accessed_initial_main_document_ = true;
782 controller().DidAccessInitialMainDocument();
783}
784
Carlos Caballero03262522021-02-05 14:49:58785void FrameTree::DidStartLoadingNode(FrameTreeNode& node,
Nate Chapin9aabf5f2021-11-12 00:31:19786 bool should_show_loading_ui,
Carlos Caballero03262522021-02-05 14:49:58787 bool was_previously_loading) {
Carlos Caballero03262522021-02-05 14:49:58788 if (was_previously_loading)
789 return;
790
791 root()->render_manager()->SetIsLoading(IsLoading());
Nate Chapin9aabf5f2021-11-12 00:31:19792 delegate_->DidStartLoading(&node, should_show_loading_ui);
Carlos Caballero03262522021-02-05 14:49:58793}
794
795void FrameTree::DidStopLoadingNode(FrameTreeNode& node) {
796 if (IsLoading())
797 return;
798
799 root()->render_manager()->SetIsLoading(false);
800 delegate_->DidStopLoading();
801}
802
Carlos Caballero03262522021-02-05 14:49:58803void FrameTree::DidCancelLoading() {
804 OPTIONAL_TRACE_EVENT0("content", "FrameTree::DidCancelLoading");
805 navigator_.controller().DiscardNonCommittedEntries();
Carlos Caballero03262522021-02-05 14:49:58806}
807
808void FrameTree::StopLoading() {
809 for (FrameTreeNode* node : Nodes())
810 node->StopLoading();
811}
812
Carlos Caballero101ac26b2021-03-24 11:54:05813void FrameTree::Shutdown() {
Dave Tapuskae88286de2021-08-05 19:10:42814 is_being_destroyed_ = true;
Carlos Caballero101ac26b2021-03-24 11:54:05815#if DCHECK_IS_ON()
816 DCHECK(!was_shut_down_);
817 was_shut_down_ = true;
818#endif
819
820 RenderFrameHostManager* root_manager = root_->render_manager();
821
Carlos Caballerodb7a8f6e2021-04-09 18:17:47822 if (!root_manager->current_frame_host()) {
823 // The page has been transferred out during an activation. There is little
824 // left to do.
Carlos Caballerod1c80432021-04-20 08:16:32825 // TODO(https://crbug.com/1199693): If we decide that pending delete RFHs
Carlos Caballerodb7a8f6e2021-04-09 18:17:47826 // need to be moved along during activation replace this line with a DCHECK
827 // that there are no pending delete instances.
828 root_manager->ClearRFHsPendingShutdown();
Carlos Caballerodb7a8f6e2021-04-09 18:17:47829 DCHECK(!root_->navigation_request());
830 DCHECK(!root_manager->speculative_frame_host());
831 manager_delegate_->OnFrameTreeNodeDestroyed(root_);
Carlos Caballero101ac26b2021-03-24 11:54:05832 return;
Carlos Caballerodb7a8f6e2021-04-09 18:17:47833 }
Carlos Caballero101ac26b2021-03-24 11:54:05834
835 for (FrameTreeNode* node : Nodes()) {
836 // Delete all RFHs pending shutdown, which will lead the corresponding RVHs
837 // to be shutdown and be deleted as well.
838 node->render_manager()->ClearRFHsPendingShutdown();
Carlos Caballerod1c80432021-04-20 08:16:32839 // TODO(https://crbug.com/1199676): Ban WebUI instance in Prerender pages.
Carlos Caballero101ac26b2021-03-24 11:54:05840 node->render_manager()->ClearWebUIInstances();
841 }
842
843 // Destroy all subframes now. This notifies observers.
844 root_manager->current_frame_host()->ResetChildren();
Harkiran Bolaria0b3bdef02022-03-10 13:04:40845 root_manager->current_frame_host()
846 ->browsing_context_state()
847 ->ResetProxyHosts();
Carlos Caballero101ac26b2021-03-24 11:54:05848
Carlos Caballero101ac26b2021-03-24 11:54:05849 // Manually call the observer methods for the root FrameTreeNode. It is
850 // necessary to manually delete all objects tracking navigations
851 // (NavigationHandle, NavigationRequest) for observers to be properly
852 // notified of these navigations stopping before the WebContents is
853 // destroyed.
854
855 root_manager->current_frame_host()->RenderFrameDeleted();
856 root_manager->current_frame_host()->ResetNavigationRequests();
857
858 // Do not update state as the FrameTree::Delegate (possibly a WebContents) is
859 // being destroyed.
860 root_->ResetNavigationRequest(/*keep_state=*/true);
861 if (root_manager->speculative_frame_host()) {
Daniel Chengc3d1e8d2021-06-23 02:11:45862 root_manager->DiscardSpeculativeRenderFrameHostForShutdown();
Carlos Caballero101ac26b2021-03-24 11:54:05863 }
864
Alexander Timin8aeee642021-05-12 08:39:33865 // NavigationRequests restoring the page from bfcache have a reference to the
866 // RFHs stored in the cache, so the cache should be cleared after the
867 // navigation request is reset.
868 controller().GetBackForwardCache().Shutdown();
869
Carlos Caballero101ac26b2021-03-24 11:54:05870 manager_delegate_->OnFrameTreeNodeDestroyed(root_);
871 render_view_delegate_->RenderViewDeleted(
872 root_manager->current_frame_host()->render_view_host());
873}
874
Dave Tapuskad8b0530f2021-10-19 15:12:31875base::SafeRef<FrameTree> FrameTree::GetSafeRef() {
876 return weak_ptr_factory_.GetSafeRef();
877}
878
Dave Tapuska54c76a032021-10-27 22:10:42879void FrameTree::FocusOuterFrameTrees() {
880 OPTIONAL_TRACE_EVENT0("content", "FrameTree::FocusOuterFrameTrees");
881
882 FrameTree* frame_tree_to_focus = this;
883 while (true) {
884 FrameTreeNode* outer_node = FrameTreeNode::GloballyFindByID(
885 frame_tree_to_focus->delegate()->GetOuterDelegateFrameTreeNodeId());
886 if (!outer_node || !outer_node->current_frame_host()->IsActive()) {
887 // Don't set focus on an inactive FrameTreeNode.
888 return;
889 }
890 outer_node->frame_tree()->SetFocusedFrame(outer_node, nullptr);
891
892 // For a browser initiated focus change, let embedding renderer know of the
893 // change. Otherwise, if the currently focused element is just across a
894 // process boundary in focus order, it will not be possible to move across
895 // that boundary. This is because the target element will already be focused
896 // (that renderer was not notified) and drop the event.
897 if (auto* proxy_to_outer_delegate = frame_tree_to_focus->root()
898 ->render_manager()
899 ->GetProxyToOuterDelegate()) {
900 proxy_to_outer_delegate->SetFocusedFrame();
901 }
902 frame_tree_to_focus = outer_node->frame_tree();
903 }
904}
905
[email protected]9b159a52013-10-03 17:24:55906} // namespace content