OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |