| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/frame_host/frame_tree.h" | 5 #include "content/browser/frame_host/frame_tree.h" |
| 6 | 6 |
| 7 #include "base/run_loop.h" | 7 #include "base/run_loop.h" |
| 8 #include "base/strings/string_number_conversions.h" | 8 #include "base/strings/string_number_conversions.h" |
| 9 #include "content/browser/frame_host/navigator_impl.h" | 9 #include "content/browser/frame_host/navigator_impl.h" |
| 10 #include "content/browser/frame_host/render_frame_host_factory.h" | 10 #include "content/browser/frame_host/render_frame_host_factory.h" |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 129 FrameTreeNode* root = frame_tree->root(); | 129 FrameTreeNode* root = frame_tree->root(); |
| 130 | 130 |
| 131 std::string no_children_node("no children node"); | 131 std::string no_children_node("no children node"); |
| 132 std::string deep_subtree("node with deep subtree"); | 132 std::string deep_subtree("node with deep subtree"); |
| 133 int process_id = root->current_frame_host()->GetProcess()->GetID(); | 133 int process_id = root->current_frame_host()->GetProcess()->GetID(); |
| 134 | 134 |
| 135 // Do not navigate each frame separately, since that will clutter the test | 135 // Do not navigate each frame separately, since that will clutter the test |
| 136 // itself. Instead, leave them in "not live" state, which is indicated by the | 136 // itself. Instead, leave them in "not live" state, which is indicated by the |
| 137 // * after the frame id, since this test cares about the shape, not the | 137 // * after the frame id, since this test cares about the shape, not the |
| 138 // frame liveliness. | 138 // frame liveliness. |
| 139 EXPECT_EQ("1*: []", GetTreeState(frame_tree)); | 139 EXPECT_EQ("2*: []", GetTreeState(frame_tree)); |
| 140 | 140 |
| 141 // Simulate attaching a series of frames to build the frame tree. | 141 // Simulate attaching a series of frames to build the frame tree. |
| 142 frame_tree->AddFrame(root, process_id, 14, blink::WebTreeScopeType::Document, | 142 frame_tree->AddFrame(root, process_id, 14, blink::WebTreeScopeType::Document, |
| 143 std::string(), blink::WebSandboxFlags::None); | 143 std::string(), blink::WebSandboxFlags::None); |
| 144 frame_tree->AddFrame(root, process_id, 15, blink::WebTreeScopeType::Document, | 144 frame_tree->AddFrame(root, process_id, 15, blink::WebTreeScopeType::Document, |
| 145 std::string(), blink::WebSandboxFlags::None); | 145 std::string(), blink::WebSandboxFlags::None); |
| 146 frame_tree->AddFrame(root, process_id, 16, blink::WebTreeScopeType::Document, | 146 frame_tree->AddFrame(root, process_id, 16, blink::WebTreeScopeType::Document, |
| 147 std::string(), blink::WebSandboxFlags::None); | 147 std::string(), blink::WebSandboxFlags::None); |
| 148 | 148 |
| 149 frame_tree->AddFrame(root->child_at(0), process_id, 244, | 149 frame_tree->AddFrame(root->child_at(0), process_id, 244, |
| 150 blink::WebTreeScopeType::Document, std::string(), | 150 blink::WebTreeScopeType::Document, std::string(), |
| 151 blink::WebSandboxFlags::None); | 151 blink::WebSandboxFlags::None); |
| 152 frame_tree->AddFrame(root->child_at(1), process_id, 255, | 152 frame_tree->AddFrame(root->child_at(1), process_id, 255, |
| 153 blink::WebTreeScopeType::Document, no_children_node, | 153 blink::WebTreeScopeType::Document, no_children_node, |
| 154 blink::WebSandboxFlags::None); | 154 blink::WebSandboxFlags::None); |
| 155 frame_tree->AddFrame(root->child_at(0), process_id, 245, | 155 frame_tree->AddFrame(root->child_at(0), process_id, 245, |
| 156 blink::WebTreeScopeType::Document, std::string(), | 156 blink::WebTreeScopeType::Document, std::string(), |
| 157 blink::WebSandboxFlags::None); | 157 blink::WebSandboxFlags::None); |
| 158 | 158 |
| 159 EXPECT_EQ("1*: [14*: [244*: [], 245*: []], " | 159 EXPECT_EQ( |
| 160 "15*: [255* 'no children node': []], " | 160 "2*: [14*: [244*: [], 245*: []], " |
| 161 "16*: []]", | 161 "15*: [255* 'no children node': []], " |
| 162 GetTreeState(frame_tree)); | 162 "16*: []]", |
| 163 GetTreeState(frame_tree)); |
| 163 | 164 |
| 164 FrameTreeNode* child_16 = root->child_at(2); | 165 FrameTreeNode* child_16 = root->child_at(2); |
| 165 frame_tree->AddFrame(child_16, process_id, 264, | 166 frame_tree->AddFrame(child_16, process_id, 264, |
| 166 blink::WebTreeScopeType::Document, std::string(), | 167 blink::WebTreeScopeType::Document, std::string(), |
| 167 blink::WebSandboxFlags::None); | 168 blink::WebSandboxFlags::None); |
| 168 frame_tree->AddFrame(child_16, process_id, 265, | 169 frame_tree->AddFrame(child_16, process_id, 265, |
| 169 blink::WebTreeScopeType::Document, std::string(), | 170 blink::WebTreeScopeType::Document, std::string(), |
| 170 blink::WebSandboxFlags::None); | 171 blink::WebSandboxFlags::None); |
| 171 frame_tree->AddFrame(child_16, process_id, 266, | 172 frame_tree->AddFrame(child_16, process_id, 266, |
| 172 blink::WebTreeScopeType::Document, std::string(), | 173 blink::WebTreeScopeType::Document, std::string(), |
| (...skipping 13 matching lines...) Expand all Loading... |
| 186 blink::WebTreeScopeType::Document, std::string(), | 187 blink::WebTreeScopeType::Document, std::string(), |
| 187 blink::WebSandboxFlags::None); | 188 blink::WebSandboxFlags::None); |
| 188 frame_tree->AddFrame(child_267->child_at(0)->child_at(0), process_id, 555, | 189 frame_tree->AddFrame(child_267->child_at(0)->child_at(0), process_id, 555, |
| 189 blink::WebTreeScopeType::Document, std::string(), | 190 blink::WebTreeScopeType::Document, std::string(), |
| 190 blink::WebSandboxFlags::None); | 191 blink::WebSandboxFlags::None); |
| 191 frame_tree->AddFrame(child_267->child_at(0)->child_at(0)->child_at(0), | 192 frame_tree->AddFrame(child_267->child_at(0)->child_at(0)->child_at(0), |
| 192 process_id, 655, blink::WebTreeScopeType::Document, | 193 process_id, 655, blink::WebTreeScopeType::Document, |
| 193 std::string(), blink::WebSandboxFlags::None); | 194 std::string(), blink::WebSandboxFlags::None); |
| 194 | 195 |
| 195 // Now that's it's fully built, verify the tree structure is as expected. | 196 // Now that's it's fully built, verify the tree structure is as expected. |
| 196 EXPECT_EQ("1*: [14*: [244*: [], 245*: []], " | 197 EXPECT_EQ( |
| 197 "15*: [255* 'no children node': []], " | 198 "2*: [14*: [244*: [], 245*: []], " |
| 198 "16*: [264*: [], 265*: [], 266*: [], " | 199 "15*: [255* 'no children node': []], " |
| 199 "267* 'node with deep subtree': " | 200 "16*: [264*: [], 265*: [], 266*: [], " |
| 200 "[365*: [455*: [555*: [655*: []]]]], 268*: []]]", | 201 "267* 'node with deep subtree': " |
| 201 GetTreeState(frame_tree)); | 202 "[365*: [455*: [555*: [655*: []]]]], 268*: []]]", |
| 203 GetTreeState(frame_tree)); |
| 202 | 204 |
| 203 FrameTreeNode* child_555 = child_267->child_at(0)->child_at(0)->child_at(0); | 205 FrameTreeNode* child_555 = child_267->child_at(0)->child_at(0)->child_at(0); |
| 204 frame_tree->RemoveFrame(child_555); | 206 frame_tree->RemoveFrame(child_555); |
| 205 EXPECT_EQ("1*: [14*: [244*: [], 245*: []], " | 207 EXPECT_EQ( |
| 206 "15*: [255* 'no children node': []], " | 208 "2*: [14*: [244*: [], 245*: []], " |
| 207 "16*: [264*: [], 265*: [], 266*: [], " | 209 "15*: [255* 'no children node': []], " |
| 208 "267* 'node with deep subtree': " | 210 "16*: [264*: [], 265*: [], 266*: [], " |
| 209 "[365*: [455*: []]], 268*: []]]", | 211 "267* 'node with deep subtree': " |
| 210 GetTreeState(frame_tree)); | 212 "[365*: [455*: []]], 268*: []]]", |
| 213 GetTreeState(frame_tree)); |
| 211 | 214 |
| 212 frame_tree->RemoveFrame(child_16->child_at(1)); | 215 frame_tree->RemoveFrame(child_16->child_at(1)); |
| 213 EXPECT_EQ("1*: [14*: [244*: [], 245*: []], " | 216 EXPECT_EQ( |
| 214 "15*: [255* 'no children node': []], " | 217 "2*: [14*: [244*: [], 245*: []], " |
| 215 "16*: [264*: [], 266*: [], " | 218 "15*: [255* 'no children node': []], " |
| 216 "267* 'node with deep subtree': " | 219 "16*: [264*: [], 266*: [], " |
| 217 "[365*: [455*: []]], 268*: []]]", | 220 "267* 'node with deep subtree': " |
| 218 GetTreeState(frame_tree)); | 221 "[365*: [455*: []]], 268*: []]]", |
| 222 GetTreeState(frame_tree)); |
| 219 | 223 |
| 220 frame_tree->RemoveFrame(root->child_at(1)); | 224 frame_tree->RemoveFrame(root->child_at(1)); |
| 221 EXPECT_EQ("1*: [14*: [244*: [], 245*: []], " | 225 EXPECT_EQ( |
| 222 "16*: [264*: [], 266*: [], " | 226 "2*: [14*: [244*: [], 245*: []], " |
| 223 "267* 'node with deep subtree': " | 227 "16*: [264*: [], 266*: [], " |
| 224 "[365*: [455*: []]], 268*: []]]", | 228 "267* 'node with deep subtree': " |
| 225 GetTreeState(frame_tree)); | 229 "[365*: [455*: []]], 268*: []]]", |
| 230 GetTreeState(frame_tree)); |
| 226 } | 231 } |
| 227 | 232 |
| 228 // Ensure frames can be found by frame_tree_node_id, routing ID, or name. | 233 // Ensure frames can be found by frame_tree_node_id, routing ID, or name. |
| 229 TEST_F(FrameTreeTest, FindFrames) { | 234 TEST_F(FrameTreeTest, FindFrames) { |
| 230 main_test_rfh()->InitializeRenderFrameIfNeeded(); | 235 main_test_rfh()->InitializeRenderFrameIfNeeded(); |
| 231 | 236 |
| 232 // Add a few child frames to the main frame. | 237 // Add a few child frames to the main frame. |
| 233 FrameTree* frame_tree = contents()->GetFrameTree(); | 238 FrameTree* frame_tree = contents()->GetFrameTree(); |
| 234 FrameTreeNode* root = frame_tree->root(); | 239 FrameTreeNode* root = frame_tree->root(); |
| 235 | 240 |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 305 EXPECT_EQ(child0, child1->PreviousSibling()); | 310 EXPECT_EQ(child0, child1->PreviousSibling()); |
| 306 EXPECT_EQ(child1, child2->PreviousSibling()); | 311 EXPECT_EQ(child1, child2->PreviousSibling()); |
| 307 EXPECT_EQ(nullptr, grandchild->PreviousSibling()); | 312 EXPECT_EQ(nullptr, grandchild->PreviousSibling()); |
| 308 } | 313 } |
| 309 | 314 |
| 310 // Do some simple manipulations of the frame tree, making sure that | 315 // Do some simple manipulations of the frame tree, making sure that |
| 311 // WebContentsObservers see a consistent view of the tree as we go. | 316 // WebContentsObservers see a consistent view of the tree as we go. |
| 312 TEST_F(FrameTreeTest, ObserverWalksTreeDuringFrameCreation) { | 317 TEST_F(FrameTreeTest, ObserverWalksTreeDuringFrameCreation) { |
| 313 TreeWalkingWebContentsLogger activity(contents()); | 318 TreeWalkingWebContentsLogger activity(contents()); |
| 314 contents()->NavigateAndCommit(GURL("http://www.google.com")); | 319 contents()->NavigateAndCommit(GURL("http://www.google.com")); |
| 315 EXPECT_EQ("RenderFrameCreated(1) -> 1: []", activity.GetLog()); | 320 EXPECT_EQ("RenderFrameCreated(2) -> 2: []", activity.GetLog()); |
| 316 | 321 |
| 317 FrameTree* frame_tree = contents()->GetFrameTree(); | 322 FrameTree* frame_tree = contents()->GetFrameTree(); |
| 318 FrameTreeNode* root = frame_tree->root(); | 323 FrameTreeNode* root = frame_tree->root(); |
| 319 | 324 |
| 320 // Simulate attaching a series of frames to build the frame tree. | 325 // Simulate attaching a series of frames to build the frame tree. |
| 321 main_test_rfh()->OnCreateChildFrame(14, blink::WebTreeScopeType::Document, | 326 main_test_rfh()->OnCreateChildFrame(14, blink::WebTreeScopeType::Document, |
| 322 std::string(), | 327 std::string(), |
| 323 blink::WebSandboxFlags::None); | 328 blink::WebSandboxFlags::None); |
| 324 EXPECT_EQ( | 329 EXPECT_EQ( |
| 325 "RenderFrameHostChanged(new)(14) -> 1: []\n" | 330 "RenderFrameHostChanged(new)(14) -> 2: []\n" |
| 326 "RenderFrameCreated(14) -> 1: [14: []]", | 331 "RenderFrameCreated(14) -> 2: [14: []]", |
| 327 activity.GetLog()); | 332 activity.GetLog()); |
| 328 main_test_rfh()->OnCreateChildFrame(18, blink::WebTreeScopeType::Document, | 333 main_test_rfh()->OnCreateChildFrame(18, blink::WebTreeScopeType::Document, |
| 329 std::string(), | 334 std::string(), |
| 330 blink::WebSandboxFlags::None); | 335 blink::WebSandboxFlags::None); |
| 331 EXPECT_EQ( | 336 EXPECT_EQ( |
| 332 "RenderFrameHostChanged(new)(18) -> 1: [14: []]\n" | 337 "RenderFrameHostChanged(new)(18) -> 2: [14: []]\n" |
| 333 "RenderFrameCreated(18) -> 1: [14: [], 18: []]", | 338 "RenderFrameCreated(18) -> 2: [14: [], 18: []]", |
| 334 activity.GetLog()); | 339 activity.GetLog()); |
| 335 frame_tree->RemoveFrame(root->child_at(0)); | 340 frame_tree->RemoveFrame(root->child_at(0)); |
| 336 EXPECT_EQ("RenderFrameDeleted(14) -> 1: [18: []]", activity.GetLog()); | 341 EXPECT_EQ("RenderFrameDeleted(14) -> 2: [18: []]", activity.GetLog()); |
| 337 frame_tree->RemoveFrame(root->child_at(0)); | 342 frame_tree->RemoveFrame(root->child_at(0)); |
| 338 EXPECT_EQ("RenderFrameDeleted(18) -> 1: []", activity.GetLog()); | 343 EXPECT_EQ("RenderFrameDeleted(18) -> 2: []", activity.GetLog()); |
| 339 } | 344 } |
| 340 | 345 |
| 341 // Make sure that WebContentsObservers see a consistent view of the tree after | 346 // Make sure that WebContentsObservers see a consistent view of the tree after |
| 342 // recovery from a render process crash. | 347 // recovery from a render process crash. |
| 343 TEST_F(FrameTreeTest, ObserverWalksTreeAfterCrash) { | 348 TEST_F(FrameTreeTest, ObserverWalksTreeAfterCrash) { |
| 344 TreeWalkingWebContentsLogger activity(contents()); | 349 TreeWalkingWebContentsLogger activity(contents()); |
| 345 contents()->NavigateAndCommit(GURL("http://www.google.com")); | 350 contents()->NavigateAndCommit(GURL("http://www.google.com")); |
| 346 EXPECT_EQ("RenderFrameCreated(1) -> 1: []", activity.GetLog()); | 351 EXPECT_EQ("RenderFrameCreated(2) -> 2: []", activity.GetLog()); |
| 347 | 352 |
| 348 main_test_rfh()->OnCreateChildFrame(22, blink::WebTreeScopeType::Document, | 353 main_test_rfh()->OnCreateChildFrame(22, blink::WebTreeScopeType::Document, |
| 349 std::string(), | 354 std::string(), |
| 350 blink::WebSandboxFlags::None); | 355 blink::WebSandboxFlags::None); |
| 351 EXPECT_EQ( | 356 EXPECT_EQ( |
| 352 "RenderFrameHostChanged(new)(22) -> 1: []\n" | 357 "RenderFrameHostChanged(new)(22) -> 2: []\n" |
| 353 "RenderFrameCreated(22) -> 1: [22: []]", | 358 "RenderFrameCreated(22) -> 2: [22: []]", |
| 354 activity.GetLog()); | 359 activity.GetLog()); |
| 355 main_test_rfh()->OnCreateChildFrame(23, blink::WebTreeScopeType::Document, | 360 main_test_rfh()->OnCreateChildFrame(23, blink::WebTreeScopeType::Document, |
| 356 std::string(), | 361 std::string(), |
| 357 blink::WebSandboxFlags::None); | 362 blink::WebSandboxFlags::None); |
| 358 EXPECT_EQ( | 363 EXPECT_EQ( |
| 359 "RenderFrameHostChanged(new)(23) -> 1: [22: []]\n" | 364 "RenderFrameHostChanged(new)(23) -> 2: [22: []]\n" |
| 360 "RenderFrameCreated(23) -> 1: [22: [], 23: []]", | 365 "RenderFrameCreated(23) -> 2: [22: [], 23: []]", |
| 361 activity.GetLog()); | 366 activity.GetLog()); |
| 362 | 367 |
| 363 // Crash the renderer | 368 // Crash the renderer |
| 364 main_test_rfh()->GetProcess()->SimulateCrash(); | 369 main_test_rfh()->GetProcess()->SimulateCrash(); |
| 365 EXPECT_EQ( | 370 EXPECT_EQ( |
| 366 "RenderProcessGone -> 1*: [22*: [], 23*: []]\n" | 371 "RenderProcessGone -> 2*: [22*: [], 23*: []]\n" |
| 367 "RenderFrameDeleted(23) -> 1*: [22*: [], 23*: []]\n" | 372 "RenderFrameDeleted(23) -> 2*: [22*: [], 23*: []]\n" |
| 368 "RenderFrameDeleted(22) -> 1*: [22*: [], 23*: []]\n" | 373 "RenderFrameDeleted(22) -> 2*: [22*: [], 23*: []]\n" |
| 369 "RenderFrameDeleted(1) -> 1*: []", | 374 "RenderFrameDeleted(2) -> 2*: []", |
| 370 activity.GetLog()); | 375 activity.GetLog()); |
| 371 } | 376 } |
| 372 | 377 |
| 373 // Ensure that frames are not added to the tree, if the process passed in | 378 // Ensure that frames are not added to the tree, if the process passed in |
| 374 // is different than the process of the parent node. | 379 // is different than the process of the parent node. |
| 375 TEST_F(FrameTreeTest, FailAddFrameWithWrongProcessId) { | 380 TEST_F(FrameTreeTest, FailAddFrameWithWrongProcessId) { |
| 376 contents()->NavigateAndCommit(GURL("http://www.google.com")); | 381 contents()->NavigateAndCommit(GURL("http://www.google.com")); |
| 377 FrameTree* frame_tree = contents()->GetFrameTree(); | 382 FrameTree* frame_tree = contents()->GetFrameTree(); |
| 378 FrameTreeNode* root = frame_tree->root(); | 383 FrameTreeNode* root = frame_tree->root(); |
| 379 int process_id = root->current_frame_host()->GetProcess()->GetID(); | 384 int process_id = root->current_frame_host()->GetProcess()->GetID(); |
| 380 | 385 |
| 381 ASSERT_EQ("1: []", GetTreeState(frame_tree)); | 386 ASSERT_EQ("2: []", GetTreeState(frame_tree)); |
| 382 | 387 |
| 383 // Simulate attaching a frame from mismatched process id. | 388 // Simulate attaching a frame from mismatched process id. |
| 384 ASSERT_FALSE(frame_tree->AddFrame( | 389 ASSERT_FALSE(frame_tree->AddFrame( |
| 385 root, process_id + 1, 1, blink::WebTreeScopeType::Document, std::string(), | 390 root, process_id + 1, 1, blink::WebTreeScopeType::Document, std::string(), |
| 386 blink::WebSandboxFlags::None)); | 391 blink::WebSandboxFlags::None)); |
| 387 ASSERT_EQ("1: []", GetTreeState(frame_tree)); | 392 ASSERT_EQ("2: []", GetTreeState(frame_tree)); |
| 388 } | 393 } |
| 389 | 394 |
| 390 // Ensure that frames removed while a process has crashed are not preserved in | 395 // Ensure that frames removed while a process has crashed are not preserved in |
| 391 // the global map of id->frame. | 396 // the global map of id->frame. |
| 392 TEST_F(FrameTreeTest, ProcessCrashClearsGlobalMap) { | 397 TEST_F(FrameTreeTest, ProcessCrashClearsGlobalMap) { |
| 393 main_test_rfh()->InitializeRenderFrameIfNeeded(); | 398 main_test_rfh()->InitializeRenderFrameIfNeeded(); |
| 394 | 399 |
| 395 // Add a couple child frames to the main frame. | 400 // Add a couple child frames to the main frame. |
| 396 FrameTreeNode* root = contents()->GetFrameTree()->root(); | 401 FrameTreeNode* root = contents()->GetFrameTree()->root(); |
| 397 | 402 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 418 // Crash the renderer. | 423 // Crash the renderer. |
| 419 main_test_rfh()->GetProcess()->SimulateCrash(); | 424 main_test_rfh()->GetProcess()->SimulateCrash(); |
| 420 | 425 |
| 421 // Ensure they cannot be found by id after the process has crashed. | 426 // Ensure they cannot be found by id after the process has crashed. |
| 422 EXPECT_FALSE(FrameTreeNode::GloballyFindByID(id1)); | 427 EXPECT_FALSE(FrameTreeNode::GloballyFindByID(id1)); |
| 423 EXPECT_FALSE(FrameTreeNode::GloballyFindByID(id2)); | 428 EXPECT_FALSE(FrameTreeNode::GloballyFindByID(id2)); |
| 424 EXPECT_FALSE(FrameTreeNode::GloballyFindByID(id3)); | 429 EXPECT_FALSE(FrameTreeNode::GloballyFindByID(id3)); |
| 425 } | 430 } |
| 426 | 431 |
| 427 } // namespace content | 432 } // namespace content |
| OLD | NEW |