blob: 23c8683f560e97fe92c0cb8d5de20fa79e95a3b5 [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 "base/run_loop.h"
[email protected]7cc7ebd2013-10-08 00:59:0010#include "base/strings/string_number_conversions.h"
Lei Zhange02299a2021-04-26 23:12:2411#include "base/strings/stringprintf.h"
danakjc492bf82020-09-09 20:02:4412#include "content/browser/renderer_host/navigator.h"
13#include "content/browser/renderer_host/render_frame_host_factory.h"
14#include "content/browser/renderer_host/render_frame_host_impl.h"
[email protected]9b159a52013-10-03 17:24:5515#include "content/browser/renderer_host/render_view_host_impl.h"
[email protected]94d0cc12013-12-18 00:07:4116#include "content/browser/web_contents/web_contents_impl.h"
[email protected]14266072014-04-19 00:35:2017#include "content/public/browser/web_contents_observer.h"
Gabriel Charettec7108742019-08-23 03:31:4018#include "content/public/test/browser_task_environment.h"
[email protected]9b159a52013-10-03 17:24:5519#include "content/public/test/mock_render_process_host.h"
20#include "content/public/test/test_browser_context.h"
[email protected]6b50e362014-08-15 05:15:5921#include "content/test/test_render_frame_host.h"
[email protected]14266072014-04-19 00:35:2022#include "content/test/test_render_view_host.h"
23#include "content/test/test_web_contents.h"
Gyuyoung Kim6c9ce9022019-11-26 05:40:0824#include "mojo/public/cpp/bindings/pending_receiver.h"
[email protected]9b159a52013-10-03 17:24:5525#include "testing/gtest/include/gtest/gtest.h"
Kevin McNee43fe8292021-10-04 22:59:4126#include "third_party/blink/public/common/frame/frame_owner_element_type.h"
Blink Reformata30d4232018-04-07 15:31:0627#include "third_party/blink/public/common/frame/frame_policy.h"
Chris Hamilton3ff6ed0e2021-02-19 03:54:0428#include "third_party/blink/public/common/tokens/tokens.h"
Julie Jeongeun Kim70a2e4e2020-02-21 05:09:5429#include "third_party/blink/public/mojom/frame/frame_owner_properties.mojom.h"
[email protected]9b159a52013-10-03 17:24:5530
31namespace content {
dgroganfb22f9a2014-10-20 21:32:3232
[email protected]9b159a52013-10-03 17:24:5533namespace {
34
[email protected]14266072014-04-19 00:35:2035// Appends a description of the structure of the frame tree to |result|.
36void AppendTreeNodeState(FrameTreeNode* node, std::string* result) {
37 result->append(
Raul Tambre6c0c3f5b2019-02-04 17:44:1738 base::NumberToString(node->current_frame_host()->GetRoutingID()));
schenney6408fed22015-04-17 17:44:5739 if (!node->current_frame_host()->IsRenderFrameLive())
40 result->append("*"); // Asterisk next to dead frames.
41
[email protected]14266072014-04-19 00:35:2042 if (!node->frame_name().empty()) {
43 result->append(" '");
44 result->append(node->frame_name());
45 result->append("'");
46 }
47 result->append(": [");
48 const char* separator = "";
49 for (size_t i = 0; i < node->child_count(); i++) {
50 result->append(separator);
51 AppendTreeNodeState(node->child_at(i), result);
52 separator = ", ";
53 }
54 result->append("]");
55}
56
danakj0bdfacd2021-01-20 19:27:1857mojo::PendingAssociatedRemote<mojom::Frame> CreateStubFrameRemote() {
58 return TestRenderFrameHost::CreateStubFrameRemote();
59}
60
Oksana Zhuravlovafee097c2019-07-26 17:01:3061mojo::PendingReceiver<blink::mojom::BrowserInterfaceBroker>
62CreateStubBrowserInterfaceBrokerReceiver() {
63 return TestRenderFrameHost::CreateStubBrowserInterfaceBrokerReceiver();
64}
65
Antonio Sartoridb967c52021-01-20 09:54:3066blink::mojom::PolicyContainerBindParamsPtr
67CreateStubPolicyContainerBindParams() {
68 return TestRenderFrameHost::CreateStubPolicyContainerBindParams();
Antonio Sartoria1fd1432020-11-25 09:10:2069}
70
Dominic Farolino12e06d72022-08-05 02:29:4971mojo::PendingAssociatedReceiver<blink::mojom::AssociatedInterfaceProvider>
72CreateStubAssociatedInterfaceProviderReceiver() {
73 return TestRenderFrameHost::CreateStubAssociatedInterfaceProviderReceiver();
74}
75
[email protected]14266072014-04-19 00:35:2076// Logs calls to WebContentsObserver along with the state of the frame tree,
77// for later use in EXPECT_EQ().
78class TreeWalkingWebContentsLogger : public WebContentsObserver {
79 public:
80 explicit TreeWalkingWebContentsLogger(WebContents* web_contents)
81 : WebContentsObserver(web_contents) {}
82
Peter Boström828b9022021-09-21 02:28:4383 TreeWalkingWebContentsLogger(const TreeWalkingWebContentsLogger&) = delete;
84 TreeWalkingWebContentsLogger& operator=(const TreeWalkingWebContentsLogger&) =
85 delete;
86
dchengc2282aa2014-10-21 12:07:5887 ~TreeWalkingWebContentsLogger() override {
[email protected]14266072014-04-19 00:35:2088 EXPECT_EQ("", log_) << "Activity logged that was not expected";
89 }
90
91 // Gets and resets the log, which is a string of what happened.
92 std::string GetLog() {
93 std::string result = log_;
94 log_.clear();
95 return result;
96 }
97
98 // content::WebContentsObserver implementation.
dchengc2282aa2014-10-21 12:07:5899 void RenderFrameCreated(RenderFrameHost* render_frame_host) override {
[email protected]14266072014-04-19 00:35:20100 LogWhatHappened("RenderFrameCreated", render_frame_host);
101 }
102
dchengc2282aa2014-10-21 12:07:58103 void RenderFrameHostChanged(RenderFrameHost* old_host,
104 RenderFrameHost* new_host) override {
[email protected]02d7b6e2014-06-24 21:01:50105 if (old_host)
naskof5940b9f2015-03-02 23:04:05106 LogWhatHappened("RenderFrameHostChanged(old)", old_host);
107 LogWhatHappened("RenderFrameHostChanged(new)", new_host);
[email protected]02d7b6e2014-06-24 21:01:50108 }
109
dchengc2282aa2014-10-21 12:07:58110 void RenderFrameDeleted(RenderFrameHost* render_frame_host) override {
[email protected]14266072014-04-19 00:35:20111 LogWhatHappened("RenderFrameDeleted", render_frame_host);
112 }
113
Dave Tapuska7052b7c52021-10-18 17:30:53114 void PrimaryMainFrameRenderProcessGone(
115 base::TerminationStatus status) override {
[email protected]14266072014-04-19 00:35:20116 LogWhatHappened("RenderProcessGone");
117 }
118
119 private:
120 void LogWhatHappened(const std::string& event_name) {
121 if (!log_.empty()) {
122 log_.append("\n");
123 }
124 log_.append(event_name + " -> ");
Carlos Caballero15caeeb2021-10-27 09:57:55125 AppendTreeNodeState(static_cast<WebContentsImpl*>(web_contents())
126 ->GetPrimaryFrameTree()
127 .root(),
128 &log_);
[email protected]14266072014-04-19 00:35:20129 }
130
131 void LogWhatHappened(const std::string& event_name, RenderFrameHost* rfh) {
132 LogWhatHappened(
133 base::StringPrintf("%s(%d)", event_name.c_str(), rfh->GetRoutingID()));
134 }
135
136 std::string log_;
[email protected]14266072014-04-19 00:35:20137};
138
dgroganfb22f9a2014-10-20 21:32:32139} // namespace
140
[email protected]14266072014-04-19 00:35:20141class FrameTreeTest : public RenderViewHostImplTestHarness {
[email protected]7cc7ebd2013-10-08 00:59:00142 protected:
143 // Prints a FrameTree, for easy assertions of the tree hierarchy.
Carlos Caballero15caeeb2021-10-27 09:57:55144 std::string GetTreeState(FrameTree& frame_tree) {
[email protected]7cc7ebd2013-10-08 00:59:00145 std::string result;
Carlos Caballero15caeeb2021-10-27 09:57:55146 AppendTreeNodeState(frame_tree.root(), &result);
[email protected]7cc7ebd2013-10-08 00:59:00147 return result;
148 }
nick4ed970292016-01-20 21:46:45149
Carlos Caballero15caeeb2021-10-27 09:57:55150 std::string GetTraversalOrder(FrameTree& frame_tree,
Alex Moshchuk27caae82017-09-11 23:11:18151 FrameTreeNode* subtree_to_skip) {
nick4ed970292016-01-20 21:46:45152 std::string result;
Carlos Caballero15caeeb2021-10-27 09:57:55153 for (FrameTreeNode* node : frame_tree.NodesExceptSubtree(subtree_to_skip)) {
dcheng57e39e22016-01-21 00:25:38154 if (!result.empty())
155 result += " ";
Raul Tambre6c0c3f5b2019-02-04 17:44:17156 result +=
157 base::NumberToString(node->current_frame_host()->GetRoutingID());
dcheng57e39e22016-01-21 00:25:38158 }
nick4ed970292016-01-20 21:46:45159 return result;
160 }
Jayson Adams4db0bfe22021-07-15 19:24:07161
162 size_t GetIteratorSize(FrameTree::NodeIterator iterator) {
163 return iterator.queue_.size();
164 }
[email protected]9b159a52013-10-03 17:24:55165};
166
Jayson Adams4db0bfe22021-07-15 19:24:07167// Confirm expected operation of the node queue that supports node iterators.
168TEST_F(FrameTreeTest, FrameNodeQueue) {
169 main_test_rfh()->InitializeRenderFrameIfNeeded();
170
171 // Use the FrameTree of the WebContents so that it has all the delegates it
172 // needs. We may want to consider a test version of this.
Carlos Caballero15caeeb2021-10-27 09:57:55173 FrameTree& frame_tree = contents()->GetPrimaryFrameTree();
174 FrameTreeNode* root = frame_tree.root();
Jayson Adams4db0bfe22021-07-15 19:24:07175
Kevin McNee43fe8292021-10-04 22:59:41176 constexpr auto kOwnerType = blink::FrameOwnerElementType::kIframe;
Emily Andrewsd15fd762024-12-10 20:41:54177 int process_id = root->current_frame_host()->GetProcess()->GetDeprecatedID();
Carlos Caballero15caeeb2021-10-27 09:57:55178 frame_tree.AddFrame(
Kevin McNee43fe8292021-10-04 22:59:41179 root->current_frame_host(), process_id, 14, CreateStubFrameRemote(),
180 CreateStubBrowserInterfaceBrokerReceiver(),
181 CreateStubPolicyContainerBindParams(),
Dominic Farolino12e06d72022-08-05 02:29:49182 CreateStubAssociatedInterfaceProviderReceiver(),
Kevin McNee43fe8292021-10-04 22:59:41183 blink::mojom::TreeScopeType::kDocument, std::string(), "uniqueName0",
184 false, blink::LocalFrameToken(), base::UnguessableToken::Create(),
Daniel Cheng284c38942022-09-22 23:30:34185 blink::DocumentToken(), blink::FramePolicy(),
186 blink::mojom::FrameOwnerProperties(), false, kOwnerType, false);
Carlos Caballero15caeeb2021-10-27 09:57:55187 frame_tree.AddFrame(
Kevin McNee43fe8292021-10-04 22:59:41188 root->current_frame_host(), process_id, 15, CreateStubFrameRemote(),
189 CreateStubBrowserInterfaceBrokerReceiver(),
190 CreateStubPolicyContainerBindParams(),
Dominic Farolino12e06d72022-08-05 02:29:49191 CreateStubAssociatedInterfaceProviderReceiver(),
Kevin McNee43fe8292021-10-04 22:59:41192 blink::mojom::TreeScopeType::kDocument, std::string(), "uniqueName1",
193 false, blink::LocalFrameToken(), base::UnguessableToken::Create(),
Daniel Cheng284c38942022-09-22 23:30:34194 blink::DocumentToken(), blink::FramePolicy(),
195 blink::mojom::FrameOwnerProperties(), false, kOwnerType, false);
Carlos Caballero15caeeb2021-10-27 09:57:55196 frame_tree.AddFrame(
Kevin McNee43fe8292021-10-04 22:59:41197 root->current_frame_host(), process_id, 16, CreateStubFrameRemote(),
198 CreateStubBrowserInterfaceBrokerReceiver(),
199 CreateStubPolicyContainerBindParams(),
Dominic Farolino12e06d72022-08-05 02:29:49200 CreateStubAssociatedInterfaceProviderReceiver(),
Kevin McNee43fe8292021-10-04 22:59:41201 blink::mojom::TreeScopeType::kDocument, std::string(), "uniqueName2",
202 false, blink::LocalFrameToken(), base::UnguessableToken::Create(),
Daniel Cheng284c38942022-09-22 23:30:34203 blink::DocumentToken(), blink::FramePolicy(),
204 blink::mojom::FrameOwnerProperties(), false, kOwnerType, false);
Jayson Adams4db0bfe22021-07-15 19:24:07205
206 EXPECT_EQ(3U, root->child_count());
Carlos Caballero15caeeb2021-10-27 09:57:55207 FrameTree::NodeIterator node_iterator = frame_tree.Nodes().begin();
Jayson Adams4db0bfe22021-07-15 19:24:07208
209 // Before the iterator advances the frame node queue should be empty.
210 EXPECT_EQ(0U, GetIteratorSize(node_iterator));
211
212 std::advance(node_iterator, 1);
213
214 // Advancing the iterator should fill the queue, then pop the first node
215 // from the front of the queue and make it the current node (available by
216 // dereferencing the iterator).
217 EXPECT_EQ(2U, GetIteratorSize(node_iterator));
218 EXPECT_EQ(root->child_at(0), *node_iterator);
219}
220
[email protected]9b159a52013-10-03 17:24:55221// Exercise tree manipulation routines.
222// - Add a series of nodes and verify tree structure.
223// - Remove a series of nodes and verify tree structure.
nasko9f2261b2015-07-02 11:40:26224TEST_F(FrameTreeTest, Shape) {
nick8814e652015-12-18 01:44:12225 main_test_rfh()->InitializeRenderFrameIfNeeded();
226
[email protected]94d0cc12013-12-18 00:07:41227 // Use the FrameTree of the WebContents so that it has all the delegates it
228 // needs. We may want to consider a test version of this.
Carlos Caballero15caeeb2021-10-27 09:57:55229 FrameTree& frame_tree = contents()->GetPrimaryFrameTree();
230 FrameTreeNode* root = frame_tree.root();
[email protected]190b8c52013-11-09 01:35:44231
[email protected]9b159a52013-10-03 17:24:55232 std::string no_children_node("no children node");
233 std::string deep_subtree("node with deep subtree");
Emily Andrewsd15fd762024-12-10 20:41:54234 int process_id = root->current_frame_host()->GetProcess()->GetDeprecatedID();
[email protected]9b159a52013-10-03 17:24:55235
nasko9f2261b2015-07-02 11:40:26236 // Do not navigate each frame separately, since that will clutter the test
237 // itself. Instead, leave them in "not live" state, which is indicated by the
238 // * after the frame id, since this test cares about the shape, not the
nick8814e652015-12-18 01:44:12239 // frame liveness.
Fergal Dalyfd9136d2020-03-11 14:53:36240 EXPECT_EQ("1: []", GetTreeState(frame_tree));
[email protected]7cc7ebd2013-10-08 00:59:00241
Kevin McNee43fe8292021-10-04 22:59:41242 constexpr auto kOwnerType = blink::FrameOwnerElementType::kIframe;
[email protected]9b159a52013-10-03 17:24:55243 // Simulate attaching a series of frames to build the frame tree.
Carlos Caballero15caeeb2021-10-27 09:57:55244 frame_tree.AddFrame(
Kevin McNee43fe8292021-10-04 22:59:41245 root->current_frame_host(), process_id, 14, CreateStubFrameRemote(),
246 CreateStubBrowserInterfaceBrokerReceiver(),
247 CreateStubPolicyContainerBindParams(),
Dominic Farolino12e06d72022-08-05 02:29:49248 CreateStubAssociatedInterfaceProviderReceiver(),
Kevin McNee43fe8292021-10-04 22:59:41249 blink::mojom::TreeScopeType::kDocument, std::string(), "uniqueName0",
250 false, blink::LocalFrameToken(), base::UnguessableToken::Create(),
Daniel Cheng284c38942022-09-22 23:30:34251 blink::DocumentToken(), blink::FramePolicy(),
252 blink::mojom::FrameOwnerProperties(), false, kOwnerType, false);
Carlos Caballero15caeeb2021-10-27 09:57:55253 frame_tree.AddFrame(
Kevin McNee43fe8292021-10-04 22:59:41254 root->current_frame_host(), process_id, 15, CreateStubFrameRemote(),
255 CreateStubBrowserInterfaceBrokerReceiver(),
256 CreateStubPolicyContainerBindParams(),
Dominic Farolino12e06d72022-08-05 02:29:49257 CreateStubAssociatedInterfaceProviderReceiver(),
Kevin McNee43fe8292021-10-04 22:59:41258 blink::mojom::TreeScopeType::kDocument, std::string(), "uniqueName1",
259 false, blink::LocalFrameToken(), base::UnguessableToken::Create(),
Daniel Cheng284c38942022-09-22 23:30:34260 blink::DocumentToken(), blink::FramePolicy(),
261 blink::mojom::FrameOwnerProperties(), false, kOwnerType, false);
Carlos Caballero15caeeb2021-10-27 09:57:55262 frame_tree.AddFrame(
Kevin McNee43fe8292021-10-04 22:59:41263 root->current_frame_host(), process_id, 16, CreateStubFrameRemote(),
264 CreateStubBrowserInterfaceBrokerReceiver(),
265 CreateStubPolicyContainerBindParams(),
Dominic Farolino12e06d72022-08-05 02:29:49266 CreateStubAssociatedInterfaceProviderReceiver(),
Kevin McNee43fe8292021-10-04 22:59:41267 blink::mojom::TreeScopeType::kDocument, std::string(), "uniqueName2",
268 false, blink::LocalFrameToken(), base::UnguessableToken::Create(),
Daniel Cheng284c38942022-09-22 23:30:34269 blink::DocumentToken(), blink::FramePolicy(),
270 blink::mojom::FrameOwnerProperties(), false, kOwnerType, false);
Carlos Caballero15caeeb2021-10-27 09:57:55271 frame_tree.AddFrame(
Kevin McNee43fe8292021-10-04 22:59:41272 root->child_at(0)->current_frame_host(), process_id, 244,
273 CreateStubFrameRemote(), CreateStubBrowserInterfaceBrokerReceiver(),
274 CreateStubPolicyContainerBindParams(),
Dominic Farolino12e06d72022-08-05 02:29:49275 CreateStubAssociatedInterfaceProviderReceiver(),
Kevin McNee43fe8292021-10-04 22:59:41276 blink::mojom::TreeScopeType::kDocument, std::string(), "uniqueName3",
277 false, blink::LocalFrameToken(), base::UnguessableToken::Create(),
Daniel Cheng284c38942022-09-22 23:30:34278 blink::DocumentToken(), blink::FramePolicy(),
279 blink::mojom::FrameOwnerProperties(), false, kOwnerType, false);
Carlos Caballero15caeeb2021-10-27 09:57:55280 frame_tree.AddFrame(
Kevin McNee43fe8292021-10-04 22:59:41281 root->child_at(1)->current_frame_host(), process_id, 255,
282 CreateStubFrameRemote(), CreateStubBrowserInterfaceBrokerReceiver(),
283 CreateStubPolicyContainerBindParams(),
Dominic Farolino12e06d72022-08-05 02:29:49284 CreateStubAssociatedInterfaceProviderReceiver(),
Kevin McNee43fe8292021-10-04 22:59:41285 blink::mojom::TreeScopeType::kDocument, no_children_node, "uniqueName4",
286 false, blink::LocalFrameToken(), base::UnguessableToken::Create(),
Daniel Cheng284c38942022-09-22 23:30:34287 blink::DocumentToken(), blink::FramePolicy(),
288 blink::mojom::FrameOwnerProperties(), false, kOwnerType, false);
Carlos Caballero15caeeb2021-10-27 09:57:55289 frame_tree.AddFrame(
Kevin McNee43fe8292021-10-04 22:59:41290 root->child_at(0)->current_frame_host(), process_id, 245,
291 CreateStubFrameRemote(), CreateStubBrowserInterfaceBrokerReceiver(),
292 CreateStubPolicyContainerBindParams(),
Dominic Farolino12e06d72022-08-05 02:29:49293 CreateStubAssociatedInterfaceProviderReceiver(),
Kevin McNee43fe8292021-10-04 22:59:41294 blink::mojom::TreeScopeType::kDocument, std::string(), "uniqueName5",
295 false, blink::LocalFrameToken(), base::UnguessableToken::Create(),
Daniel Cheng284c38942022-09-22 23:30:34296 blink::DocumentToken(), blink::FramePolicy(),
297 blink::mojom::FrameOwnerProperties(), false, kOwnerType, false);
[email protected]9b159a52013-10-03 17:24:55298
dcheng3ce04b62015-10-26 23:30:55299 EXPECT_EQ(
Fergal Dalyfd9136d2020-03-11 14:53:36300 "1: [14: [244: [], 245: []], "
nick8814e652015-12-18 01:44:12301 "15: [255 'no children node': []], "
302 "16: []]",
dcheng3ce04b62015-10-26 23:30:55303 GetTreeState(frame_tree));
[email protected]9b159a52013-10-03 17:24:55304
[email protected]58faf942014-02-20 21:03:58305 FrameTreeNode* child_16 = root->child_at(2);
Carlos Caballero15caeeb2021-10-27 09:57:55306 frame_tree.AddFrame(
Kevin McNee43fe8292021-10-04 22:59:41307 child_16->current_frame_host(), process_id, 264, CreateStubFrameRemote(),
308 CreateStubBrowserInterfaceBrokerReceiver(),
309 CreateStubPolicyContainerBindParams(),
Dominic Farolino12e06d72022-08-05 02:29:49310 CreateStubAssociatedInterfaceProviderReceiver(),
Kevin McNee43fe8292021-10-04 22:59:41311 blink::mojom::TreeScopeType::kDocument, std::string(), "uniqueName6",
312 false, blink::LocalFrameToken(), base::UnguessableToken::Create(),
Daniel Cheng284c38942022-09-22 23:30:34313 blink::DocumentToken(), blink::FramePolicy(),
314 blink::mojom::FrameOwnerProperties(), false, kOwnerType, false);
Carlos Caballero15caeeb2021-10-27 09:57:55315 frame_tree.AddFrame(
Kevin McNee43fe8292021-10-04 22:59:41316 child_16->current_frame_host(), process_id, 265, CreateStubFrameRemote(),
317 CreateStubBrowserInterfaceBrokerReceiver(),
318 CreateStubPolicyContainerBindParams(),
Dominic Farolino12e06d72022-08-05 02:29:49319 CreateStubAssociatedInterfaceProviderReceiver(),
Kevin McNee43fe8292021-10-04 22:59:41320 blink::mojom::TreeScopeType::kDocument, std::string(), "uniqueName7",
321 false, blink::LocalFrameToken(), base::UnguessableToken::Create(),
Daniel Cheng284c38942022-09-22 23:30:34322 blink::DocumentToken(), blink::FramePolicy(),
323 blink::mojom::FrameOwnerProperties(), false, kOwnerType, false);
Carlos Caballero15caeeb2021-10-27 09:57:55324 frame_tree.AddFrame(
Kevin McNee43fe8292021-10-04 22:59:41325 child_16->current_frame_host(), process_id, 266, CreateStubFrameRemote(),
326 CreateStubBrowserInterfaceBrokerReceiver(),
327 CreateStubPolicyContainerBindParams(),
Dominic Farolino12e06d72022-08-05 02:29:49328 CreateStubAssociatedInterfaceProviderReceiver(),
Kevin McNee43fe8292021-10-04 22:59:41329 blink::mojom::TreeScopeType::kDocument, std::string(), "uniqueName8",
330 false, blink::LocalFrameToken(), base::UnguessableToken::Create(),
Daniel Cheng284c38942022-09-22 23:30:34331 blink::DocumentToken(), blink::FramePolicy(),
332 blink::mojom::FrameOwnerProperties(), false, kOwnerType, false);
Carlos Caballero15caeeb2021-10-27 09:57:55333 frame_tree.AddFrame(
Kevin McNee43fe8292021-10-04 22:59:41334 child_16->current_frame_host(), process_id, 267, CreateStubFrameRemote(),
335 CreateStubBrowserInterfaceBrokerReceiver(),
336 CreateStubPolicyContainerBindParams(),
Dominic Farolino12e06d72022-08-05 02:29:49337 CreateStubAssociatedInterfaceProviderReceiver(),
Kevin McNee43fe8292021-10-04 22:59:41338 blink::mojom::TreeScopeType::kDocument, deep_subtree, "uniqueName9",
339 false, blink::LocalFrameToken(), base::UnguessableToken::Create(),
Daniel Cheng284c38942022-09-22 23:30:34340 blink::DocumentToken(), blink::FramePolicy(),
341 blink::mojom::FrameOwnerProperties(), false, kOwnerType, false);
Carlos Caballero15caeeb2021-10-27 09:57:55342 frame_tree.AddFrame(
Kevin McNee43fe8292021-10-04 22:59:41343 child_16->current_frame_host(), process_id, 268, CreateStubFrameRemote(),
344 CreateStubBrowserInterfaceBrokerReceiver(),
345 CreateStubPolicyContainerBindParams(),
Dominic Farolino12e06d72022-08-05 02:29:49346 CreateStubAssociatedInterfaceProviderReceiver(),
Kevin McNee43fe8292021-10-04 22:59:41347 blink::mojom::TreeScopeType::kDocument, std::string(), "uniqueName10",
348 false, blink::LocalFrameToken(), base::UnguessableToken::Create(),
Daniel Cheng284c38942022-09-22 23:30:34349 blink::DocumentToken(), blink::FramePolicy(),
350 blink::mojom::FrameOwnerProperties(), false, kOwnerType, false);
[email protected]9b159a52013-10-03 17:24:55351
[email protected]58faf942014-02-20 21:03:58352 FrameTreeNode* child_267 = child_16->child_at(3);
Carlos Caballero15caeeb2021-10-27 09:57:55353 frame_tree.AddFrame(
Kevin McNee43fe8292021-10-04 22:59:41354 child_267->current_frame_host(), process_id, 365, CreateStubFrameRemote(),
355 CreateStubBrowserInterfaceBrokerReceiver(),
356 CreateStubPolicyContainerBindParams(),
Dominic Farolino12e06d72022-08-05 02:29:49357 CreateStubAssociatedInterfaceProviderReceiver(),
Kevin McNee43fe8292021-10-04 22:59:41358 blink::mojom::TreeScopeType::kDocument, std::string(), "uniqueName11",
359 false, blink::LocalFrameToken(), base::UnguessableToken::Create(),
Daniel Cheng284c38942022-09-22 23:30:34360 blink::DocumentToken(), blink::FramePolicy(),
361 blink::mojom::FrameOwnerProperties(), false, kOwnerType, false);
Carlos Caballero15caeeb2021-10-27 09:57:55362 frame_tree.AddFrame(
Kevin McNee43fe8292021-10-04 22:59:41363 child_267->child_at(0)->current_frame_host(), process_id, 455,
364 CreateStubFrameRemote(), CreateStubBrowserInterfaceBrokerReceiver(),
365 CreateStubPolicyContainerBindParams(),
Dominic Farolino12e06d72022-08-05 02:29:49366 CreateStubAssociatedInterfaceProviderReceiver(),
Kevin McNee43fe8292021-10-04 22:59:41367 blink::mojom::TreeScopeType::kDocument, std::string(), "uniqueName12",
368 false, blink::LocalFrameToken(), base::UnguessableToken::Create(),
Daniel Cheng284c38942022-09-22 23:30:34369 blink::DocumentToken(), blink::FramePolicy(),
370 blink::mojom::FrameOwnerProperties(), false, kOwnerType, false);
Carlos Caballero15caeeb2021-10-27 09:57:55371 frame_tree.AddFrame(
Alexander Timin381e7e182020-04-28 19:04:03372 child_267->child_at(0)->child_at(0)->current_frame_host(), process_id,
danakj0bdfacd2021-01-20 19:27:18373 555, CreateStubFrameRemote(), CreateStubBrowserInterfaceBrokerReceiver(),
Antonio Sartoridb967c52021-01-20 09:54:30374 CreateStubPolicyContainerBindParams(),
Dominic Farolino12e06d72022-08-05 02:29:49375 CreateStubAssociatedInterfaceProviderReceiver(),
Antonio Sartoridb967c52021-01-20 09:54:30376 blink::mojom::TreeScopeType::kDocument, std::string(), "uniqueName13",
Chris Hamilton3ff6ed0e2021-02-19 03:54:04377 false, blink::LocalFrameToken(), base::UnguessableToken::Create(),
Daniel Cheng284c38942022-09-22 23:30:34378 blink::DocumentToken(), blink::FramePolicy(),
379 blink::mojom::FrameOwnerProperties(), false, kOwnerType, false);
Carlos Caballero15caeeb2021-10-27 09:57:55380 frame_tree.AddFrame(
Alexander Timin381e7e182020-04-28 19:04:03381 child_267->child_at(0)->child_at(0)->child_at(0)->current_frame_host(),
danakj0bdfacd2021-01-20 19:27:18382 process_id, 655, CreateStubFrameRemote(),
383 CreateStubBrowserInterfaceBrokerReceiver(),
Antonio Sartoridb967c52021-01-20 09:54:30384 CreateStubPolicyContainerBindParams(),
Dominic Farolino12e06d72022-08-05 02:29:49385 CreateStubAssociatedInterfaceProviderReceiver(),
Antonio Sartoridb967c52021-01-20 09:54:30386 blink::mojom::TreeScopeType::kDocument, std::string(), "uniqueName14",
Chris Hamilton3ff6ed0e2021-02-19 03:54:04387 false, blink::LocalFrameToken(), base::UnguessableToken::Create(),
Daniel Cheng284c38942022-09-22 23:30:34388 blink::DocumentToken(), blink::FramePolicy(),
389 blink::mojom::FrameOwnerProperties(), false, kOwnerType, false);
[email protected]9b159a52013-10-03 17:24:55390
[email protected]7cc7ebd2013-10-08 00:59:00391 // Now that's it's fully built, verify the tree structure is as expected.
dcheng3ce04b62015-10-26 23:30:55392 EXPECT_EQ(
Fergal Dalyfd9136d2020-03-11 14:53:36393 "1: [14: [244: [], 245: []], "
nick8814e652015-12-18 01:44:12394 "15: [255 'no children node': []], "
395 "16: [264: [], 265: [], 266: [], "
396 "267 'node with deep subtree': "
397 "[365: [455: [555: [655: []]]]], 268: []]]",
dcheng3ce04b62015-10-26 23:30:55398 GetTreeState(frame_tree));
[email protected]9b159a52013-10-03 17:24:55399
nick4ed970292016-01-20 21:46:45400 // Verify that traversal order is breadth first, even if we skip a subtree.
401 FrameTreeNode* child_14 = root->child_at(0);
402 FrameTreeNode* child_15 = root->child_at(1);
403 FrameTreeNode* child_244 = child_14->child_at(0);
404 FrameTreeNode* child_245 = child_14->child_at(1);
[email protected]58faf942014-02-20 21:03:58405 FrameTreeNode* child_555 = child_267->child_at(0)->child_at(0)->child_at(0);
nick4ed970292016-01-20 21:46:45406 FrameTreeNode* child_655 = child_555->child_at(0);
Fergal Dalyfd9136d2020-03-11 14:53:36407 EXPECT_EQ("1 14 15 16 244 245 255 264 265 266 267 268 365 455 555 655",
nick4ed970292016-01-20 21:46:45408 GetTraversalOrder(frame_tree, nullptr));
Fergal Dalyfd9136d2020-03-11 14:53:36409 EXPECT_EQ("1", GetTraversalOrder(frame_tree, root));
410 EXPECT_EQ("1 14 15 16 255 264 265 266 267 268 365 455 555 655",
nick4ed970292016-01-20 21:46:45411 GetTraversalOrder(frame_tree, child_14));
Fergal Dalyfd9136d2020-03-11 14:53:36412 EXPECT_EQ("1 14 15 16 244 245 255 264 265 266 267 268 365 455 555 655",
nick4ed970292016-01-20 21:46:45413 GetTraversalOrder(frame_tree, child_244));
Fergal Dalyfd9136d2020-03-11 14:53:36414 EXPECT_EQ("1 14 15 16 244 245 255 264 265 266 267 268 365 455 555 655",
nick4ed970292016-01-20 21:46:45415 GetTraversalOrder(frame_tree, child_245));
Fergal Dalyfd9136d2020-03-11 14:53:36416 EXPECT_EQ("1 14 15 16 244 245 264 265 266 267 268 365 455 555 655",
nick4ed970292016-01-20 21:46:45417 GetTraversalOrder(frame_tree, child_15));
Fergal Dalyfd9136d2020-03-11 14:53:36418 EXPECT_EQ("1 14 15 16 244 245 255 264 265 266 267 268",
nick4ed970292016-01-20 21:46:45419 GetTraversalOrder(frame_tree, child_267));
Fergal Dalyfd9136d2020-03-11 14:53:36420 EXPECT_EQ("1 14 15 16 244 245 255 264 265 266 267 268 365 455 555",
Alex Moshchuk27caae82017-09-11 23:11:18421 GetTraversalOrder(frame_tree, child_555));
Fergal Dalyfd9136d2020-03-11 14:53:36422 EXPECT_EQ("1 14 15 16 244 245 255 264 265 266 267 268 365 455 555 655",
nick4ed970292016-01-20 21:46:45423 GetTraversalOrder(frame_tree, child_655));
424
Carlos Caballero15caeeb2021-10-27 09:57:55425 frame_tree.RemoveFrame(child_555);
dcheng3ce04b62015-10-26 23:30:55426 EXPECT_EQ(
Fergal Dalyfd9136d2020-03-11 14:53:36427 "1: [14: [244: [], 245: []], "
nick8814e652015-12-18 01:44:12428 "15: [255 'no children node': []], "
429 "16: [264: [], 265: [], 266: [], "
430 "267 'node with deep subtree': "
431 "[365: [455: []]], 268: []]]",
dcheng3ce04b62015-10-26 23:30:55432 GetTreeState(frame_tree));
[email protected]9b159a52013-10-03 17:24:55433
Carlos Caballero15caeeb2021-10-27 09:57:55434 frame_tree.RemoveFrame(child_16->child_at(1));
dcheng3ce04b62015-10-26 23:30:55435 EXPECT_EQ(
Fergal Dalyfd9136d2020-03-11 14:53:36436 "1: [14: [244: [], 245: []], "
nick8814e652015-12-18 01:44:12437 "15: [255 'no children node': []], "
438 "16: [264: [], 266: [], "
439 "267 'node with deep subtree': "
440 "[365: [455: []]], 268: []]]",
dcheng3ce04b62015-10-26 23:30:55441 GetTreeState(frame_tree));
[email protected]9b159a52013-10-03 17:24:55442
Carlos Caballero15caeeb2021-10-27 09:57:55443 frame_tree.RemoveFrame(root->child_at(1));
dcheng3ce04b62015-10-26 23:30:55444 EXPECT_EQ(
Fergal Dalyfd9136d2020-03-11 14:53:36445 "1: [14: [244: [], 245: []], "
nick8814e652015-12-18 01:44:12446 "16: [264: [], 266: [], "
447 "267 'node with deep subtree': "
448 "[365: [455: []]], 268: []]]",
dcheng3ce04b62015-10-26 23:30:55449 GetTreeState(frame_tree));
[email protected]9b159a52013-10-03 17:24:55450}
451
creis6a93a812015-04-24 23:13:17452// Ensure frames can be found by frame_tree_node_id, routing ID, or name.
Charlie Reisb1405622018-04-02 22:52:39453TEST_F(FrameTreeTest, FindFrames) {
lfg269b702f2015-06-08 19:28:19454 main_test_rfh()->InitializeRenderFrameIfNeeded();
455
creis6a93a812015-04-24 23:13:17456 // Add a few child frames to the main frame.
Carlos Caballero15caeeb2021-10-27 09:57:55457 FrameTree& frame_tree = contents()->GetPrimaryFrameTree();
458 FrameTreeNode* root = frame_tree.root();
lfg269b702f2015-06-08 19:28:19459
Kevin McNee43fe8292021-10-04 22:59:41460 constexpr auto kOwnerType = blink::FrameOwnerElementType::kIframe;
lukasza464d8692016-02-22 19:26:32461 main_test_rfh()->OnCreateChildFrame(
danakj0bdfacd2021-01-20 19:27:18462 22, CreateStubFrameRemote(), CreateStubBrowserInterfaceBrokerReceiver(),
Antonio Sartoridb967c52021-01-20 09:54:30463 CreateStubPolicyContainerBindParams(),
Dominic Farolino12e06d72022-08-05 02:29:49464 CreateStubAssociatedInterfaceProviderReceiver(),
Antonio Gomes9d5c1ef2020-04-30 20:56:41465 blink::mojom::TreeScopeType::kDocument, "child0", "uniqueName0", false,
Chris Hamilton3ff6ed0e2021-02-19 03:54:04466 blink::LocalFrameToken(), base::UnguessableToken::Create(),
Daniel Cheng284c38942022-09-22 23:30:34467 blink::DocumentToken(), blink::FramePolicy(),
Antonio Sartori55369fff2022-11-30 09:17:56468 blink::mojom::FrameOwnerProperties(), kOwnerType, ukm::kInvalidSourceId);
lukasza464d8692016-02-22 19:26:32469 main_test_rfh()->OnCreateChildFrame(
danakj0bdfacd2021-01-20 19:27:18470 23, CreateStubFrameRemote(), CreateStubBrowserInterfaceBrokerReceiver(),
Antonio Sartoridb967c52021-01-20 09:54:30471 CreateStubPolicyContainerBindParams(),
Dominic Farolino12e06d72022-08-05 02:29:49472 CreateStubAssociatedInterfaceProviderReceiver(),
Antonio Gomes9d5c1ef2020-04-30 20:56:41473 blink::mojom::TreeScopeType::kDocument, "child1", "uniqueName1", false,
Chris Hamilton3ff6ed0e2021-02-19 03:54:04474 blink::LocalFrameToken(), base::UnguessableToken::Create(),
Daniel Cheng284c38942022-09-22 23:30:34475 blink::DocumentToken(), blink::FramePolicy(),
Antonio Sartori55369fff2022-11-30 09:17:56476 blink::mojom::FrameOwnerProperties(), kOwnerType, ukm::kInvalidSourceId);
lukasza464d8692016-02-22 19:26:32477 main_test_rfh()->OnCreateChildFrame(
danakj0bdfacd2021-01-20 19:27:18478 24, CreateStubFrameRemote(), CreateStubBrowserInterfaceBrokerReceiver(),
Antonio Sartoridb967c52021-01-20 09:54:30479 CreateStubPolicyContainerBindParams(),
Dominic Farolino12e06d72022-08-05 02:29:49480 CreateStubAssociatedInterfaceProviderReceiver(),
Antonio Gomes9d5c1ef2020-04-30 20:56:41481 blink::mojom::TreeScopeType::kDocument, std::string(), "uniqueName2",
Chris Hamilton3ff6ed0e2021-02-19 03:54:04482 false, blink::LocalFrameToken(), base::UnguessableToken::Create(),
Daniel Cheng284c38942022-09-22 23:30:34483 blink::DocumentToken(), blink::FramePolicy(),
Antonio Sartori55369fff2022-11-30 09:17:56484 blink::mojom::FrameOwnerProperties(), kOwnerType, ukm::kInvalidSourceId);
creis6a93a812015-04-24 23:13:17485 FrameTreeNode* child0 = root->child_at(0);
486 FrameTreeNode* child1 = root->child_at(1);
487 FrameTreeNode* child2 = root->child_at(2);
488
489 // Add one grandchild frame.
dcheng860817a2015-05-22 03:16:56490 child1->current_frame_host()->OnCreateChildFrame(
danakj0bdfacd2021-01-20 19:27:18491 33, CreateStubFrameRemote(), CreateStubBrowserInterfaceBrokerReceiver(),
Antonio Sartoridb967c52021-01-20 09:54:30492 CreateStubPolicyContainerBindParams(),
Dominic Farolino12e06d72022-08-05 02:29:49493 CreateStubAssociatedInterfaceProviderReceiver(),
Antonio Gomes9d5c1ef2020-04-30 20:56:41494 blink::mojom::TreeScopeType::kDocument, "grandchild", "uniqueName3",
Chris Hamilton3ff6ed0e2021-02-19 03:54:04495 false, blink::LocalFrameToken(), base::UnguessableToken::Create(),
Daniel Cheng284c38942022-09-22 23:30:34496 blink::DocumentToken(), blink::FramePolicy(),
Antonio Sartori55369fff2022-11-30 09:17:56497 blink::mojom::FrameOwnerProperties(), kOwnerType, ukm::kInvalidSourceId);
creis6a93a812015-04-24 23:13:17498 FrameTreeNode* grandchild = child1->child_at(0);
499
500 // Ensure they can be found by FTN id.
Carlos Caballero15caeeb2021-10-27 09:57:55501 EXPECT_EQ(root, frame_tree.FindByID(root->frame_tree_node_id()));
502 EXPECT_EQ(child0, frame_tree.FindByID(child0->frame_tree_node_id()));
503 EXPECT_EQ(child1, frame_tree.FindByID(child1->frame_tree_node_id()));
504 EXPECT_EQ(child2, frame_tree.FindByID(child2->frame_tree_node_id()));
505 EXPECT_EQ(grandchild, frame_tree.FindByID(grandchild->frame_tree_node_id()));
Avi Drissmanbd153642024-09-03 18:58:05506 EXPECT_EQ(nullptr, frame_tree.FindByID(FrameTreeNodeId()));
creis6a93a812015-04-24 23:13:17507
508 // Ensure they can be found by routing id.
Emily Andrewsd15fd762024-12-10 20:41:54509 int process_id = main_test_rfh()->GetProcess()->GetDeprecatedID();
Carlos Caballero15caeeb2021-10-27 09:57:55510 EXPECT_EQ(root, frame_tree.FindByRoutingID(process_id,
511 main_test_rfh()->GetRoutingID()));
512 EXPECT_EQ(child0, frame_tree.FindByRoutingID(process_id, 22));
513 EXPECT_EQ(child1, frame_tree.FindByRoutingID(process_id, 23));
514 EXPECT_EQ(child2, frame_tree.FindByRoutingID(process_id, 24));
515 EXPECT_EQ(grandchild, frame_tree.FindByRoutingID(process_id, 33));
516 EXPECT_EQ(nullptr, frame_tree.FindByRoutingID(process_id, 37));
creis6a93a812015-04-24 23:13:17517
518 // Ensure they can be found by name, if they have one.
Carlos Caballero15caeeb2021-10-27 09:57:55519 EXPECT_EQ(root, frame_tree.FindByName(std::string()));
520 EXPECT_EQ(child0, frame_tree.FindByName("child0"));
521 EXPECT_EQ(child1, frame_tree.FindByName("child1"));
522 EXPECT_EQ(grandchild, frame_tree.FindByName("grandchild"));
523 EXPECT_EQ(nullptr, frame_tree.FindByName("no such frame"));
creis6a93a812015-04-24 23:13:17524}
525
paulmeyer322777fb2016-05-16 23:15:39526// Check that PreviousSibling() and NextSibling() are retrieved correctly.
527TEST_F(FrameTreeTest, GetSibling) {
lfg269b702f2015-06-08 19:28:19528 main_test_rfh()->InitializeRenderFrameIfNeeded();
529
Kevin McNee43fe8292021-10-04 22:59:41530 constexpr auto kOwnerType = blink::FrameOwnerElementType::kIframe;
alexmos9f8705a2015-05-06 19:58:59531 // Add a few child frames to the main frame.
Carlos Caballero15caeeb2021-10-27 09:57:55532 FrameTree& frame_tree = contents()->GetPrimaryFrameTree();
533 FrameTreeNode* root = frame_tree.root();
lukasza464d8692016-02-22 19:26:32534 main_test_rfh()->OnCreateChildFrame(
danakj0bdfacd2021-01-20 19:27:18535 22, CreateStubFrameRemote(), CreateStubBrowserInterfaceBrokerReceiver(),
Antonio Sartoridb967c52021-01-20 09:54:30536 CreateStubPolicyContainerBindParams(),
Dominic Farolino12e06d72022-08-05 02:29:49537 CreateStubAssociatedInterfaceProviderReceiver(),
Antonio Gomes9d5c1ef2020-04-30 20:56:41538 blink::mojom::TreeScopeType::kDocument, "child0", "uniqueName0", false,
Chris Hamilton3ff6ed0e2021-02-19 03:54:04539 blink::LocalFrameToken(), base::UnguessableToken::Create(),
Daniel Cheng284c38942022-09-22 23:30:34540 blink::DocumentToken(), blink::FramePolicy(),
Antonio Sartori55369fff2022-11-30 09:17:56541 blink::mojom::FrameOwnerProperties(), kOwnerType, ukm::kInvalidSourceId);
lukasza464d8692016-02-22 19:26:32542 main_test_rfh()->OnCreateChildFrame(
danakj0bdfacd2021-01-20 19:27:18543 23, CreateStubFrameRemote(), CreateStubBrowserInterfaceBrokerReceiver(),
Antonio Sartoridb967c52021-01-20 09:54:30544 CreateStubPolicyContainerBindParams(),
Dominic Farolino12e06d72022-08-05 02:29:49545 CreateStubAssociatedInterfaceProviderReceiver(),
Antonio Gomes9d5c1ef2020-04-30 20:56:41546 blink::mojom::TreeScopeType::kDocument, "child1", "uniqueName1", false,
Chris Hamilton3ff6ed0e2021-02-19 03:54:04547 blink::LocalFrameToken(), base::UnguessableToken::Create(),
Daniel Cheng284c38942022-09-22 23:30:34548 blink::DocumentToken(), blink::FramePolicy(),
Antonio Sartori55369fff2022-11-30 09:17:56549 blink::mojom::FrameOwnerProperties(), kOwnerType, ukm::kInvalidSourceId);
lukasza464d8692016-02-22 19:26:32550 main_test_rfh()->OnCreateChildFrame(
danakj0bdfacd2021-01-20 19:27:18551 24, CreateStubFrameRemote(), CreateStubBrowserInterfaceBrokerReceiver(),
Antonio Sartoridb967c52021-01-20 09:54:30552 CreateStubPolicyContainerBindParams(),
Dominic Farolino12e06d72022-08-05 02:29:49553 CreateStubAssociatedInterfaceProviderReceiver(),
Antonio Gomes9d5c1ef2020-04-30 20:56:41554 blink::mojom::TreeScopeType::kDocument, "child2", "uniqueName2", false,
Chris Hamilton3ff6ed0e2021-02-19 03:54:04555 blink::LocalFrameToken(), base::UnguessableToken::Create(),
Daniel Cheng284c38942022-09-22 23:30:34556 blink::DocumentToken(), blink::FramePolicy(),
Antonio Sartori55369fff2022-11-30 09:17:56557 blink::mojom::FrameOwnerProperties(), kOwnerType, ukm::kInvalidSourceId);
alexmos9f8705a2015-05-06 19:58:59558 FrameTreeNode* child0 = root->child_at(0);
559 FrameTreeNode* child1 = root->child_at(1);
560 FrameTreeNode* child2 = root->child_at(2);
561
562 // Add one grandchild frame.
dcheng860817a2015-05-22 03:16:56563 child1->current_frame_host()->OnCreateChildFrame(
danakj0bdfacd2021-01-20 19:27:18564 33, CreateStubFrameRemote(), CreateStubBrowserInterfaceBrokerReceiver(),
Antonio Sartoridb967c52021-01-20 09:54:30565 CreateStubPolicyContainerBindParams(),
Dominic Farolino12e06d72022-08-05 02:29:49566 CreateStubAssociatedInterfaceProviderReceiver(),
Antonio Gomes9d5c1ef2020-04-30 20:56:41567 blink::mojom::TreeScopeType::kDocument, "grandchild", "uniqueName3",
Chris Hamilton3ff6ed0e2021-02-19 03:54:04568 false, blink::LocalFrameToken(), base::UnguessableToken::Create(),
Daniel Cheng284c38942022-09-22 23:30:34569 blink::DocumentToken(), blink::FramePolicy(),
Antonio Sartori55369fff2022-11-30 09:17:56570 blink::mojom::FrameOwnerProperties(), kOwnerType, ukm::kInvalidSourceId);
alexmos9f8705a2015-05-06 19:58:59571 FrameTreeNode* grandchild = child1->child_at(0);
572
paulmeyer322777fb2016-05-16 23:15:39573 // Test PreviousSibling().
Harkiran Bolaria37e212682021-10-14 19:44:37574 EXPECT_EQ(nullptr, root->current_frame_host()->PreviousSibling());
575 EXPECT_EQ(nullptr, child0->current_frame_host()->PreviousSibling());
576 EXPECT_EQ(child0, child1->current_frame_host()->PreviousSibling());
577 EXPECT_EQ(child1, child2->current_frame_host()->PreviousSibling());
578 EXPECT_EQ(nullptr, grandchild->current_frame_host()->PreviousSibling());
paulmeyer322777fb2016-05-16 23:15:39579
580 // Test NextSibling().
Harkiran Bolaria37e212682021-10-14 19:44:37581 EXPECT_EQ(nullptr, root->current_frame_host()->NextSibling());
582 EXPECT_EQ(child1, child0->current_frame_host()->NextSibling());
583 EXPECT_EQ(child2, child1->current_frame_host()->NextSibling());
584 EXPECT_EQ(nullptr, child2->current_frame_host()->NextSibling());
585 EXPECT_EQ(nullptr, grandchild->current_frame_host()->NextSibling());
alexmos9f8705a2015-05-06 19:58:59586}
587
[email protected]14266072014-04-19 00:35:20588// Do some simple manipulations of the frame tree, making sure that
589// WebContentsObservers see a consistent view of the tree as we go.
590TEST_F(FrameTreeTest, ObserverWalksTreeDuringFrameCreation) {
591 TreeWalkingWebContentsLogger activity(contents());
schenney6408fed22015-04-17 17:44:57592 contents()->NavigateAndCommit(GURL("http://www.google.com"));
Fergal Dalyfd9136d2020-03-11 14:53:36593 EXPECT_EQ("RenderFrameCreated(1) -> 1: []", activity.GetLog());
schenney6408fed22015-04-17 17:44:57594
Carlos Caballero15caeeb2021-10-27 09:57:55595 FrameTree& frame_tree = contents()->GetPrimaryFrameTree();
596 FrameTreeNode* root = frame_tree.root();
[email protected]14266072014-04-19 00:35:20597
Kevin McNee43fe8292021-10-04 22:59:41598 constexpr auto kOwnerType = blink::FrameOwnerElementType::kIframe;
[email protected]14266072014-04-19 00:35:20599 // Simulate attaching a series of frames to build the frame tree.
lukasza464d8692016-02-22 19:26:32600 main_test_rfh()->OnCreateChildFrame(
danakj0bdfacd2021-01-20 19:27:18601 14, CreateStubFrameRemote(), CreateStubBrowserInterfaceBrokerReceiver(),
Antonio Sartoridb967c52021-01-20 09:54:30602 CreateStubPolicyContainerBindParams(),
Dominic Farolino12e06d72022-08-05 02:29:49603 CreateStubAssociatedInterfaceProviderReceiver(),
Antonio Gomes9d5c1ef2020-04-30 20:56:41604 blink::mojom::TreeScopeType::kDocument, std::string(), "uniqueName0",
Chris Hamilton3ff6ed0e2021-02-19 03:54:04605 false, blink::LocalFrameToken(), base::UnguessableToken::Create(),
Daniel Cheng284c38942022-09-22 23:30:34606 blink::DocumentToken(), blink::FramePolicy(),
Antonio Sartori55369fff2022-11-30 09:17:56607 blink::mojom::FrameOwnerProperties(), kOwnerType, ukm::kInvalidSourceId);
naskof5940b9f2015-03-02 23:04:05608 EXPECT_EQ(
Sreeja Kamishetty5b699622021-01-22 12:54:08609 "RenderFrameCreated(14) -> 1: [14: []]\n"
610 "RenderFrameHostChanged(new)(14) -> 1: [14: []]",
naskof5940b9f2015-03-02 23:04:05611 activity.GetLog());
lukasza464d8692016-02-22 19:26:32612 main_test_rfh()->OnCreateChildFrame(
danakj0bdfacd2021-01-20 19:27:18613 18, CreateStubFrameRemote(), CreateStubBrowserInterfaceBrokerReceiver(),
Antonio Sartoridb967c52021-01-20 09:54:30614 CreateStubPolicyContainerBindParams(),
Dominic Farolino12e06d72022-08-05 02:29:49615 CreateStubAssociatedInterfaceProviderReceiver(),
Antonio Gomes9d5c1ef2020-04-30 20:56:41616 blink::mojom::TreeScopeType::kDocument, std::string(), "uniqueName1",
Chris Hamilton3ff6ed0e2021-02-19 03:54:04617 false, blink::LocalFrameToken(), base::UnguessableToken::Create(),
Daniel Cheng284c38942022-09-22 23:30:34618 blink::DocumentToken(), blink::FramePolicy(),
Antonio Sartori55369fff2022-11-30 09:17:56619 blink::mojom::FrameOwnerProperties(), kOwnerType, ukm::kInvalidSourceId);
naskof5940b9f2015-03-02 23:04:05620 EXPECT_EQ(
Sreeja Kamishetty5b699622021-01-22 12:54:08621 "RenderFrameCreated(18) -> 1: [14: [], 18: []]\n"
622 "RenderFrameHostChanged(new)(18) -> 1: [14: [], 18: []]",
naskof5940b9f2015-03-02 23:04:05623 activity.GetLog());
Carlos Caballero15caeeb2021-10-27 09:57:55624 frame_tree.RemoveFrame(root->child_at(0));
Fergal Dalyfd9136d2020-03-11 14:53:36625 EXPECT_EQ("RenderFrameDeleted(14) -> 1: [18: []]", activity.GetLog());
Carlos Caballero15caeeb2021-10-27 09:57:55626 frame_tree.RemoveFrame(root->child_at(0));
Fergal Dalyfd9136d2020-03-11 14:53:36627 EXPECT_EQ("RenderFrameDeleted(18) -> 1: []", activity.GetLog());
[email protected]14266072014-04-19 00:35:20628}
629
630// Make sure that WebContentsObservers see a consistent view of the tree after
631// recovery from a render process crash.
632TEST_F(FrameTreeTest, ObserverWalksTreeAfterCrash) {
633 TreeWalkingWebContentsLogger activity(contents());
schenney6408fed22015-04-17 17:44:57634 contents()->NavigateAndCommit(GURL("http://www.google.com"));
Fergal Dalyfd9136d2020-03-11 14:53:36635 EXPECT_EQ("RenderFrameCreated(1) -> 1: []", activity.GetLog());
[email protected]14266072014-04-19 00:35:20636
Kevin McNee43fe8292021-10-04 22:59:41637 constexpr auto kOwnerType = blink::FrameOwnerElementType::kIframe;
lukasza464d8692016-02-22 19:26:32638 main_test_rfh()->OnCreateChildFrame(
danakj0bdfacd2021-01-20 19:27:18639 22, CreateStubFrameRemote(), CreateStubBrowserInterfaceBrokerReceiver(),
Antonio Sartoridb967c52021-01-20 09:54:30640 CreateStubPolicyContainerBindParams(),
Dominic Farolino12e06d72022-08-05 02:29:49641 CreateStubAssociatedInterfaceProviderReceiver(),
Antonio Gomes9d5c1ef2020-04-30 20:56:41642 blink::mojom::TreeScopeType::kDocument, std::string(), "uniqueName0",
Chris Hamilton3ff6ed0e2021-02-19 03:54:04643 false, blink::LocalFrameToken(), base::UnguessableToken::Create(),
Daniel Cheng284c38942022-09-22 23:30:34644 blink::DocumentToken(), blink::FramePolicy(),
Antonio Sartori55369fff2022-11-30 09:17:56645 blink::mojom::FrameOwnerProperties(), kOwnerType, ukm::kInvalidSourceId);
naskof5940b9f2015-03-02 23:04:05646 EXPECT_EQ(
Sreeja Kamishetty5b699622021-01-22 12:54:08647 "RenderFrameCreated(22) -> 1: [22: []]\n"
648 "RenderFrameHostChanged(new)(22) -> 1: [22: []]",
naskof5940b9f2015-03-02 23:04:05649 activity.GetLog());
lukasza464d8692016-02-22 19:26:32650 main_test_rfh()->OnCreateChildFrame(
danakj0bdfacd2021-01-20 19:27:18651 23, CreateStubFrameRemote(), CreateStubBrowserInterfaceBrokerReceiver(),
Antonio Sartoridb967c52021-01-20 09:54:30652 CreateStubPolicyContainerBindParams(),
Dominic Farolino12e06d72022-08-05 02:29:49653 CreateStubAssociatedInterfaceProviderReceiver(),
Antonio Gomes9d5c1ef2020-04-30 20:56:41654 blink::mojom::TreeScopeType::kDocument, std::string(), "uniqueName1",
Chris Hamilton3ff6ed0e2021-02-19 03:54:04655 false, blink::LocalFrameToken(), base::UnguessableToken::Create(),
Daniel Cheng284c38942022-09-22 23:30:34656 blink::DocumentToken(), blink::FramePolicy(),
Antonio Sartori55369fff2022-11-30 09:17:56657 blink::mojom::FrameOwnerProperties(), kOwnerType, ukm::kInvalidSourceId);
naskof5940b9f2015-03-02 23:04:05658 EXPECT_EQ(
Sreeja Kamishetty5b699622021-01-22 12:54:08659 "RenderFrameCreated(23) -> 1: [22: [], 23: []]\n"
660 "RenderFrameHostChanged(new)(23) -> 1: [22: [], 23: []]",
naskof5940b9f2015-03-02 23:04:05661 activity.GetLog());
[email protected]14266072014-04-19 00:35:20662
663 // Crash the renderer
nick16b07652015-04-18 02:35:31664 main_test_rfh()->GetProcess()->SimulateCrash();
[email protected]14266072014-04-19 00:35:20665 EXPECT_EQ(
Fergal Dalyfd9136d2020-03-11 14:53:36666 "RenderFrameDeleted(23) -> 1*: []\n"
667 "RenderFrameDeleted(22) -> 1*: []\n"
Nasko Oskov4ef7cb12022-01-14 06:13:47668 "RenderFrameDeleted(1) -> 1*: []\n"
669 "RenderProcessGone -> 1*: []",
[email protected]14266072014-04-19 00:35:20670 activity.GetLog());
671}
672
dgroganfb22f9a2014-10-20 21:32:32673// Ensure that frames are not added to the tree, if the process passed in
674// is different than the process of the parent node.
675TEST_F(FrameTreeTest, FailAddFrameWithWrongProcessId) {
schenney6408fed22015-04-17 17:44:57676 contents()->NavigateAndCommit(GURL("http://www.google.com"));
Carlos Caballero15caeeb2021-10-27 09:57:55677 FrameTree& frame_tree = contents()->GetPrimaryFrameTree();
678 FrameTreeNode* root = frame_tree.root();
Emily Andrewsd15fd762024-12-10 20:41:54679 int process_id = root->current_frame_host()->GetProcess()->GetDeprecatedID();
dgroganfb22f9a2014-10-20 21:32:32680
Fergal Dalyfd9136d2020-03-11 14:53:36681 ASSERT_EQ("1: []", GetTreeState(frame_tree));
dgroganfb22f9a2014-10-20 21:32:32682
683 // Simulate attaching a frame from mismatched process id.
Dominic Farolino6caf3032021-10-20 03:50:08684 EXPECT_DEATH_IF_SUPPORTED(
Carlos Caballero15caeeb2021-10-27 09:57:55685 frame_tree.AddFrame(
Dominic Farolino6caf3032021-10-20 03:50:08686 root->current_frame_host(), process_id + 1, 1,
687 CreateStubFrameRemote(), CreateStubBrowserInterfaceBrokerReceiver(),
688 CreateStubPolicyContainerBindParams(),
Dominic Farolino12e06d72022-08-05 02:29:49689 CreateStubAssociatedInterfaceProviderReceiver(),
Dominic Farolino6caf3032021-10-20 03:50:08690 blink::mojom::TreeScopeType::kDocument, std::string(), "uniqueName0",
691 false, blink::LocalFrameToken(), base::UnguessableToken::Create(),
Daniel Cheng284c38942022-09-22 23:30:34692 blink::DocumentToken(), blink::FramePolicy(),
693 blink::mojom::FrameOwnerProperties(), false,
Dominic Farolino6caf3032021-10-20 03:50:08694 blink::FrameOwnerElementType::kIframe, false),
695 "");
Fergal Dalyfd9136d2020-03-11 14:53:36696 ASSERT_EQ("1: []", GetTreeState(frame_tree));
dgroganfb22f9a2014-10-20 21:32:32697}
698
naskoaeca57b2015-02-13 00:50:46699// Ensure that frames removed while a process has crashed are not preserved in
700// the global map of id->frame.
701TEST_F(FrameTreeTest, ProcessCrashClearsGlobalMap) {
lfg269b702f2015-06-08 19:28:19702 main_test_rfh()->InitializeRenderFrameIfNeeded();
703
naskoaeca57b2015-02-13 00:50:46704 // Add a couple child frames to the main frame.
Carlos Caballero15caeeb2021-10-27 09:57:55705 FrameTreeNode* root = contents()->GetPrimaryFrameTree().root();
naskoaeca57b2015-02-13 00:50:46706
Kevin McNee43fe8292021-10-04 22:59:41707 constexpr auto kOwnerType = blink::FrameOwnerElementType::kIframe;
lukasza464d8692016-02-22 19:26:32708 main_test_rfh()->OnCreateChildFrame(
danakj0bdfacd2021-01-20 19:27:18709 22, CreateStubFrameRemote(), CreateStubBrowserInterfaceBrokerReceiver(),
Antonio Sartoridb967c52021-01-20 09:54:30710 CreateStubPolicyContainerBindParams(),
Dominic Farolino12e06d72022-08-05 02:29:49711 CreateStubAssociatedInterfaceProviderReceiver(),
Antonio Gomes9d5c1ef2020-04-30 20:56:41712 blink::mojom::TreeScopeType::kDocument, std::string(), "uniqueName0",
Chris Hamilton3ff6ed0e2021-02-19 03:54:04713 false, blink::LocalFrameToken(), base::UnguessableToken::Create(),
Daniel Cheng284c38942022-09-22 23:30:34714 blink::DocumentToken(), blink::FramePolicy(),
Antonio Sartori55369fff2022-11-30 09:17:56715 blink::mojom::FrameOwnerProperties(), kOwnerType, ukm::kInvalidSourceId);
lukasza464d8692016-02-22 19:26:32716 main_test_rfh()->OnCreateChildFrame(
danakj0bdfacd2021-01-20 19:27:18717 23, CreateStubFrameRemote(), CreateStubBrowserInterfaceBrokerReceiver(),
Antonio Sartoridb967c52021-01-20 09:54:30718 CreateStubPolicyContainerBindParams(),
Dominic Farolino12e06d72022-08-05 02:29:49719 CreateStubAssociatedInterfaceProviderReceiver(),
Antonio Gomes9d5c1ef2020-04-30 20:56:41720 blink::mojom::TreeScopeType::kDocument, std::string(), "uniqueName1",
Chris Hamilton3ff6ed0e2021-02-19 03:54:04721 false, blink::LocalFrameToken(), base::UnguessableToken::Create(),
Daniel Cheng284c38942022-09-22 23:30:34722 blink::DocumentToken(), blink::FramePolicy(),
Antonio Sartori55369fff2022-11-30 09:17:56723 blink::mojom::FrameOwnerProperties(), kOwnerType, ukm::kInvalidSourceId);
naskoaeca57b2015-02-13 00:50:46724
dmazzonie950ea232015-03-13 21:39:45725 // Add one grandchild frame.
726 RenderFrameHostImpl* child1_rfh = root->child_at(0)->current_frame_host();
Ehsan Karamad192a8da2018-10-21 03:48:08727 child1_rfh->OnCreateChildFrame(
danakj0bdfacd2021-01-20 19:27:18728 33, CreateStubFrameRemote(), CreateStubBrowserInterfaceBrokerReceiver(),
Antonio Sartoridb967c52021-01-20 09:54:30729 CreateStubPolicyContainerBindParams(),
Dominic Farolino12e06d72022-08-05 02:29:49730 CreateStubAssociatedInterfaceProviderReceiver(),
Antonio Gomes9d5c1ef2020-04-30 20:56:41731 blink::mojom::TreeScopeType::kDocument, std::string(), "uniqueName2",
Chris Hamilton3ff6ed0e2021-02-19 03:54:04732 false, blink::LocalFrameToken(), base::UnguessableToken::Create(),
Daniel Cheng284c38942022-09-22 23:30:34733 blink::DocumentToken(), blink::FramePolicy(),
Antonio Sartori55369fff2022-11-30 09:17:56734 blink::mojom::FrameOwnerProperties(), kOwnerType, ukm::kInvalidSourceId);
dmazzonie950ea232015-03-13 21:39:45735
naskoaeca57b2015-02-13 00:50:46736 // Ensure they can be found by id.
Avi Drissmanbd153642024-09-03 18:58:05737 FrameTreeNodeId id1 = root->child_at(0)->frame_tree_node_id();
738 FrameTreeNodeId id2 = root->child_at(1)->frame_tree_node_id();
739 FrameTreeNodeId id3 = root->child_at(0)->child_at(0)->frame_tree_node_id();
dmazzonie950ea232015-03-13 21:39:45740 EXPECT_TRUE(FrameTreeNode::GloballyFindByID(id1));
741 EXPECT_TRUE(FrameTreeNode::GloballyFindByID(id2));
742 EXPECT_TRUE(FrameTreeNode::GloballyFindByID(id3));
naskoaeca57b2015-02-13 00:50:46743
744 // Crash the renderer.
nick16b07652015-04-18 02:35:31745 main_test_rfh()->GetProcess()->SimulateCrash();
naskoaeca57b2015-02-13 00:50:46746
747 // Ensure they cannot be found by id after the process has crashed.
dmazzonie950ea232015-03-13 21:39:45748 EXPECT_FALSE(FrameTreeNode::GloballyFindByID(id1));
749 EXPECT_FALSE(FrameTreeNode::GloballyFindByID(id2));
750 EXPECT_FALSE(FrameTreeNode::GloballyFindByID(id3));
naskoaeca57b2015-02-13 00:50:46751}
752
[email protected]9b159a52013-10-03 17:24:55753} // namespace content