Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(394)

Side by Side Diff: content/browser/renderer_host/render_view_host_manager_browsertest.cc

Issue 10827078: Support frame tree propagation between renderers in the same browsing instance. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Let the reviews begin :) Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "base/file_util.h" 5 #include "base/file_util.h"
6 #include "base/json/json_reader.h"
6 #include "base/memory/ref_counted.h" 7 #include "base/memory/ref_counted.h"
7 #include "base/path_service.h" 8 #include "base/path_service.h"
8 #include "base/utf_string_conversions.h" 9 #include "base/utf_string_conversions.h"
9 #include "content/browser/renderer_host/render_view_host_impl.h" 10 #include "content/browser/renderer_host/render_view_host_impl.h"
10 #include "content/browser/site_instance_impl.h" 11 #include "content/browser/site_instance_impl.h"
11 #include "content/browser/web_contents/web_contents_impl.h" 12 #include "content/browser/web_contents/web_contents_impl.h"
12 #include "content/public/browser/navigation_controller.h" 13 #include "content/public/browser/navigation_controller.h"
13 #include "content/public/browser/navigation_entry.h" 14 #include "content/public/browser/navigation_entry.h"
14 #include "content/public/browser/notification_details.h" 15 #include "content/public/browser/notification_details.h"
15 #include "content/public/browser/notification_observer.h" 16 #include "content/public/browser/notification_observer.h"
(...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after
479 480
480 // 2) Fail to post a message from the foo window to the opener if the target 481 // 2) Fail to post a message from the foo window to the opener if the target
481 // origin is wrong. We won't see an error, but we can check for the right 482 // origin is wrong. We won't see an error, but we can check for the right
482 // number of received messages below. 483 // number of received messages below.
483 EXPECT_TRUE(ExecuteJavaScriptAndExtractBool( 484 EXPECT_TRUE(ExecuteJavaScriptAndExtractBool(
484 foo_contents->GetRenderViewHost(), L"", 485 foo_contents->GetRenderViewHost(), L"",
485 L"window.domAutomationController.send(postToOpener('msg'," 486 L"window.domAutomationController.send(postToOpener('msg',"
486 L"'http://google.com'));", 487 L"'http://google.com'));",
487 &success)); 488 &success));
488 EXPECT_TRUE(success); 489 EXPECT_TRUE(success);
490 ASSERT_FALSE(opener_manager->GetSwappedOutRenderViewHost(orig_site_instance));
489 491
490 // 3) Post a message from the foo window to the opener. The opener will 492 // 3) Post a message from the foo window to the opener. The opener will
491 // reply, causing the foo window to update its own title. 493 // reply, causing the foo window to update its own title.
492 WindowedNotificationObserver title_observer( 494 WindowedNotificationObserver title_observer(
493 NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED, 495 NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED,
494 Source<WebContents>(foo_contents)); 496 Source<WebContents>(foo_contents));
495 EXPECT_TRUE(ExecuteJavaScriptAndExtractBool( 497 EXPECT_TRUE(ExecuteJavaScriptAndExtractBool(
496 foo_contents->GetRenderViewHost(), L"", 498 foo_contents->GetRenderViewHost(), L"",
497 L"window.domAutomationController.send(postToOpener('msg','*'));", 499 L"window.domAutomationController.send(postToOpener('msg','*'));",
498 &success)); 500 &success));
499 EXPECT_TRUE(success); 501 EXPECT_TRUE(success);
502 ASSERT_FALSE(opener_manager->GetSwappedOutRenderViewHost(orig_site_instance));
500 title_observer.Wait(); 503 title_observer.Wait();
501 504
502 // We should have received only 1 message in the opener and "foo" tabs, 505 // We should have received only 1 message in the opener and "foo" tabs,
503 // and updated the title. 506 // and updated the title.
504 int opener_received_messages = 0; 507 int opener_received_messages = 0;
505 EXPECT_TRUE(ExecuteJavaScriptAndExtractInt( 508 EXPECT_TRUE(ExecuteJavaScriptAndExtractInt(
506 opener_contents->GetRenderViewHost(), L"", 509 opener_contents->GetRenderViewHost(), L"",
507 L"window.domAutomationController.send(window.receivedMessages);", 510 L"window.domAutomationController.send(window.receivedMessages);",
508 &opener_received_messages)); 511 &opener_received_messages));
509 int foo_received_messages = 0; 512 int foo_received_messages = 0;
(...skipping 14 matching lines...) Expand all
524 new_contents->GetRenderViewHost(), L"", 527 new_contents->GetRenderViewHost(), L"",
525 L"window.domAutomationController.send(postToFoo('msg2'));", 528 L"window.domAutomationController.send(postToFoo('msg2'));",
526 &success)); 529 &success));
527 EXPECT_TRUE(success); 530 EXPECT_TRUE(success);
528 title_observer2.Wait(); 531 title_observer2.Wait();
529 EXPECT_EQ(ASCIIToUTF16("msg2"), foo_contents->GetTitle()); 532 EXPECT_EQ(ASCIIToUTF16("msg2"), foo_contents->GetTitle());
530 533
531 // This postMessage should have created a swapped out RVH for the new 534 // This postMessage should have created a swapped out RVH for the new
532 // SiteInstance in the target=_blank window. 535 // SiteInstance in the target=_blank window.
533 EXPECT_TRUE(new_manager->GetSwappedOutRenderViewHost(foo_site_instance)); 536 EXPECT_TRUE(new_manager->GetSwappedOutRenderViewHost(foo_site_instance));
537
538 NavigateToURL(new_shell, https_server.GetURL("files/post_message2.html"));
539
540 // 5) Now verify that posting a message from the foo window to a subframe of
541 // the opener window works fine. The opener subframe will reply, causing the
542 // foo window to update its own title.
543 WindowedNotificationObserver title_observer3(
544 NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED,
545 Source<WebContents>(new_shell->web_contents()));
546 EXPECT_TRUE(ExecuteJavaScriptAndExtractBool(
547 foo_contents->GetRenderViewHost(), L"",
548 L"window.domAutomationController.send(postToOpenerFrame('msg3','*'));",
549 &success));
550 EXPECT_TRUE(success);
551 title_observer3.Wait();
552 EXPECT_EQ(ASCIIToUTF16("msg3"), new_shell->web_contents()->GetTitle());
553
554 // 5) Lastly, verify that the _blank window can post a message to subframe
555 // of the foo window. The subframe of foo will set the foo window title and
556 // will reply, setting the _blank window title.
557 WindowedNotificationObserver title_observer4(
558 NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED,
559 Source<WebContents>(new_shell2->web_contents()));
560 EXPECT_TRUE(ExecuteJavaScriptAndExtractBool(
561 new_contents->GetRenderViewHost(), L"",
562 L"window.domAutomationController.send(postToFooFrame('msg4'));",
563 &success));
564 EXPECT_TRUE(success);
565 title_observer4.Wait();
566 EXPECT_EQ(ASCIIToUTF16("msg4"), new_shell2->web_contents()->GetTitle());
534 } 567 }
535 568
536 // Test for crbug.com/116192. Navigations to a window's opener should 569 // Test for crbug.com/116192. Navigations to a window's opener should
537 // still work after a process swap. 570 // still work after a process swap.
538 IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, 571 IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest,
539 AllowTargetedNavigationsInOpenerAfterSwap) { 572 AllowTargetedNavigationsInOpenerAfterSwap) {
540 // Start two servers with different sites. 573 // Start two servers with different sites.
541 ASSERT_TRUE(test_server()->Start()); 574 ASSERT_TRUE(test_server()->Start());
542 net::TestServer https_server( 575 net::TestServer https_server(
543 net::TestServer::TYPE_HTTPS, 576 net::TestServer::TYPE_HTTPS,
(...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after
1032 rvh_observers.AddObserverToRVH(shell()->web_contents()->GetRenderViewHost()); 1065 rvh_observers.AddObserverToRVH(shell()->web_contents()->GetRenderViewHost());
1033 1066
1034 // This used to leak a render view host. 1067 // This used to leak a render view host.
1035 shell()->Close(); 1068 shell()->Close();
1036 1069
1037 RunAllPendingInMessageLoop(); // Needed on ChromeOS. 1070 RunAllPendingInMessageLoop(); // Needed on ChromeOS.
1038 1071
1039 EXPECT_EQ(0U, rvh_observers.GetNumObservers()); 1072 EXPECT_EQ(0U, rvh_observers.GetNumObservers());
1040 } 1073 }
1041 1074
1075 namespace {
1076
1077 bool CompareTrees(base::DictionaryValue* first, base::DictionaryValue* second) {
1078 string16 name1;
1079 string16 name2;
1080 if (!first->GetString("name", &name1) || !second->GetString("name", &name2))
1081 return false;
1082 if (name1 != name2)
1083 return false;
1084
1085 int id1;
1086 int id2;
1087 if (!first->GetInteger("id", &id1) || !second->GetInteger("id", &id2))
1088 return false;
1089 if (id1 != id2)
1090 return false;
1091
1092 ListValue* subtree1;
awong 2012/08/20 21:56:31 Pointer OCDness...can we initialize these things t
nasko 2012/08/21 00:34:45 Done.
1093 ListValue* subtree2;
1094 bool result1 = first->GetList("subtree", &subtree1);
1095 bool result2 = second->GetList("subtree", &subtree2);
1096 if (!result1 && !result2)
1097 return true;
1098 if (!result1 || !result2)
1099 return false;
1100
1101 if (subtree1->GetSize() != subtree2->GetSize())
1102 return false;
1103
1104 base::DictionaryValue* child1;
1105 base::DictionaryValue* child2;
1106 for (size_t i = 0; i < subtree1->GetSize(); ++i) {
1107 if (!subtree1->GetDictionary(i, &child1) ||
1108 !subtree2->GetDictionary(i, &child2))
1109 return false;
1110 if (!CompareTrees(child1, child2))
1111 return false;
1112 }
1113
1114 return true;
1115 }
1116
1117 base::DictionaryValue* GetTree(std::string frame_tree) {
1118 EXPECT_FALSE(frame_tree.empty());
1119 base::Value* v = base::JSONReader::Read(frame_tree);
1120 base::DictionaryValue* tree;
1121 EXPECT_TRUE(v->IsType(base::Value::TYPE_DICTIONARY));
1122 EXPECT_TRUE(v->GetAsDictionary(&tree));
1123 return tree;
1124 }
1125
1126 } // namespace
1127
1128 // Test for correct propagation of frames hierarchy across processes in the
1129 // same browsing context.
1130 IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, FrameTreeUpdates) {
1131 // Start two servers to allow using different sites.
1132 EXPECT_TRUE(test_server()->Start());
1133 net::TestServer https_server(
1134 net::TestServer::TYPE_HTTPS,
1135 net::TestServer::kLocalhost,
1136 FilePath(FILE_PATH_LITERAL("content/test/data")));
1137 EXPECT_TRUE(https_server.Start());
1138
1139 GURL frame_tree_url(test_server()->GetURL("files/frame_tree/top.html"));
1140
1141 // Replace the 127.0.0.1 with localhost, which will give us a different
1142 // site instance.
1143 GURL::Replacements replacements;
1144 std::string new_host("localhost");
1145 replacements.SetHostStr(new_host);
1146 GURL remote_frame = test_server()->GetURL(
1147 "files/frame_tree/1-1.html").ReplaceComponents(replacements);
1148
1149 bool success = false;
1150 base::DictionaryValue* frames = NULL;
1151 base::ListValue* subtree = NULL;
1152
1153 NavigateToURL(shell(), test_server()->GetURL("files/simple_page.html"));
1154 WebContents* opener_contents = shell()->web_contents();
1155 RenderViewHostManager* opener_rvhm = static_cast<WebContentsImpl*>(
1156 opener_contents)->GetRenderManagerForTesting();
1157 frames = GetTree(opener_contents->GetRenderViewHost()->GetFrameTree());
1158 EXPECT_FALSE(frames->GetList("subtree", &subtree));
1159
1160 NavigateToURL(shell(), frame_tree_url);
1161 frames = GetTree(opener_contents->GetRenderViewHost()->GetFrameTree());
1162 EXPECT_TRUE(frames->GetList("subtree", &subtree));
1163 EXPECT_TRUE(subtree->GetSize() == 3);
1164
1165 scoped_refptr<SiteInstance> orig_site_instance(
1166 opener_contents->GetSiteInstance());
1167 EXPECT_TRUE(orig_site_instance != NULL);
1168
1169 ShellAddedObserver shell_observer1;
1170 EXPECT_TRUE(ExecuteJavaScriptAndExtractBool(
1171 opener_contents->GetRenderViewHost(),
1172 L"", L"window.domAutomationController.send(openWindow('1-3.html'));",
1173 &success));
1174 EXPECT_TRUE(success);
1175
1176 Shell* shell1 = shell_observer1.GetShell();
1177 WebContents* contents1 = shell1->web_contents();
1178 WaitForLoadStop(contents1);
1179 RenderViewHostManager* rvhm1 = static_cast<WebContentsImpl*>(
1180 contents1)->GetRenderManagerForTesting();
1181 EXPECT_EQ("/files/frame_tree/1-3.html", contents1->GetURL().path());
1182
1183 NavigateToURL(shell1, https_server.GetURL("files/title1.html"));
1184 EXPECT_EQ("/files/title1.html", contents1->GetURL().path());
1185 scoped_refptr<SiteInstance> site_instance1(
1186 contents1->GetSiteInstance());
1187 EXPECT_NE(orig_site_instance, site_instance1);
1188
1189 ShellAddedObserver shell_observer2;
1190 EXPECT_TRUE(ExecuteJavaScriptAndExtractBool(
1191 opener_contents->GetRenderViewHost(), L"",
1192 L"window.domAutomationController.send(openWindow('../title2.html'));",
1193 &success));
1194 EXPECT_TRUE(success);
1195
1196 Shell* shell2 = shell_observer2.GetShell();
1197 WebContents* contents2 = shell2->web_contents();
1198 WaitForLoadStop(contents2);
1199 EXPECT_EQ("/files/title2.html", contents2->GetURL().path());
1200
1201 NavigateToURL(shell2, remote_frame);
1202 EXPECT_EQ("/files/frame_tree/1-1.html", contents2->GetURL().path());
1203 scoped_refptr<SiteInstance> site_instance2(
1204 contents2->GetSiteInstance());
1205 EXPECT_NE(orig_site_instance, site_instance2);
1206 EXPECT_NE(site_instance1, site_instance2);
1207
1208 RenderViewHostManager* rvhm2 = static_cast<WebContentsImpl*>(
1209 contents2)->GetRenderManagerForTesting();
1210
1211 EXPECT_TRUE(CompareTrees(
1212 GetTree(opener_rvhm->current_host()->GetFrameTree()),
1213 GetTree(opener_rvhm->GetSwappedOutRenderViewHost(
1214 rvhm1->current_host()->GetSiteInstance())->GetFrameTree())));
1215 EXPECT_TRUE(CompareTrees(
1216 GetTree(opener_rvhm->current_host()->GetFrameTree()),
1217 GetTree(opener_rvhm->GetSwappedOutRenderViewHost(
1218 rvhm2->current_host()->GetSiteInstance())->GetFrameTree())));
1219
1220 EXPECT_TRUE(CompareTrees(
1221 GetTree(rvhm1->current_host()->GetFrameTree()),
1222 GetTree(rvhm1->GetSwappedOutRenderViewHost(
1223 opener_rvhm->current_host()->GetSiteInstance())->GetFrameTree())));
1224 EXPECT_TRUE(CompareTrees(
1225 GetTree(rvhm2->current_host()->GetFrameTree()),
1226 GetTree(rvhm2->GetSwappedOutRenderViewHost(
1227 opener_rvhm->current_host()->GetSiteInstance())->GetFrameTree())));
1228
1229 EXPECT_FALSE(CompareTrees(
1230 GetTree(opener_rvhm->current_host()->GetFrameTree()),
1231 GetTree(rvhm1->current_host()->GetFrameTree())));
1232 EXPECT_FALSE(CompareTrees(
1233 GetTree(opener_rvhm->current_host()->GetFrameTree()),
1234 GetTree(rvhm2->current_host()->GetFrameTree())));
1235
1236 // Reload the original page, which will cause subframe ids to change. This
1237 // will ensure that the ids are properly replicated across reload.
1238 NavigateToURL(shell(), frame_tree_url);
1239
1240 EXPECT_TRUE(CompareTrees(
1241 GetTree(opener_rvhm->current_host()->GetFrameTree()),
1242 GetTree(opener_rvhm->GetSwappedOutRenderViewHost(
1243 rvhm1->current_host()->GetSiteInstance())->GetFrameTree())));
1244 EXPECT_TRUE(CompareTrees(
1245 GetTree(opener_rvhm->current_host()->GetFrameTree()),
1246 GetTree(opener_rvhm->GetSwappedOutRenderViewHost(
1247 rvhm2->current_host()->GetSiteInstance())->GetFrameTree())));
1248
1249 EXPECT_FALSE(CompareTrees(
1250 GetTree(opener_rvhm->current_host()->GetFrameTree()),
1251 GetTree(rvhm1->current_host()->GetFrameTree())));
1252 EXPECT_FALSE(CompareTrees(
1253 GetTree(opener_rvhm->current_host()->GetFrameTree()),
1254 GetTree(rvhm2->current_host()->GetFrameTree())));
1255 }
1256
1042 } // namespace content 1257 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698