Chromium Code Reviews| 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 "base/command_line.h" | 5 #include "base/command_line.h" |
| 6 #include "base/files/file_path.h" | 6 #include "base/files/file_path.h" |
| 7 #include "base/strings/utf_string_conversions.h" | 7 #include "base/strings/utf_string_conversions.h" |
| 8 #include "base/test/histogram_tester.h" | 8 #include "base/test/histogram_tester.h" |
| 9 #include "base/time/time.h" | 9 #include "base/time/time.h" |
| 10 #include "content/browser/compositor/test/no_transport_image_transport_factory.h " | 10 #include "content/browser/compositor/test/no_transport_image_transport_factory.h " |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 31 #include "content/public/browser/web_contents_observer.h" | 31 #include "content/public/browser/web_contents_observer.h" |
| 32 #include "content/public/browser/web_ui_controller.h" | 32 #include "content/public/browser/web_ui_controller.h" |
| 33 #include "content/public/common/bindings_policy.h" | 33 #include "content/public/common/bindings_policy.h" |
| 34 #include "content/public/common/content_switches.h" | 34 #include "content/public/common/content_switches.h" |
| 35 #include "content/public/common/javascript_message_type.h" | 35 #include "content/public/common/javascript_message_type.h" |
| 36 #include "content/public/common/url_constants.h" | 36 #include "content/public/common/url_constants.h" |
| 37 #include "content/public/common/url_utils.h" | 37 #include "content/public/common/url_utils.h" |
| 38 #include "content/public/test/mock_render_process_host.h" | 38 #include "content/public/test/mock_render_process_host.h" |
| 39 #include "content/public/test/test_notification_tracker.h" | 39 #include "content/public/test/test_notification_tracker.h" |
| 40 #include "content/public/test/test_utils.h" | 40 #include "content/public/test/test_utils.h" |
| 41 #include "content/test/browser_side_navigation_test_utils.h" | |
| 41 #include "content/test/test_content_browser_client.h" | 42 #include "content/test/test_content_browser_client.h" |
| 42 #include "content/test/test_content_client.h" | 43 #include "content/test/test_content_client.h" |
| 43 #include "content/test/test_render_frame_host.h" | 44 #include "content/test/test_render_frame_host.h" |
| 44 #include "content/test/test_render_view_host.h" | 45 #include "content/test/test_render_view_host.h" |
| 45 #include "content/test/test_web_contents.h" | 46 #include "content/test/test_web_contents.h" |
| 46 #include "net/base/load_flags.h" | 47 #include "net/base/load_flags.h" |
| 47 #include "testing/gtest/include/gtest/gtest.h" | 48 #include "testing/gtest/include/gtest/gtest.h" |
| 48 #include "third_party/WebKit/public/web/WebFrameOwnerProperties.h" | 49 #include "third_party/WebKit/public/web/WebFrameOwnerProperties.h" |
| 49 #include "third_party/WebKit/public/web/WebSandboxFlags.h" | 50 #include "third_party/WebKit/public/web/WebSandboxFlags.h" |
| 50 #include "ui/base/page_transition_types.h" | 51 #include "ui/base/page_transition_types.h" |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 63 EXPECT_EQ(expected_routing_id, message->routing_id()); | 64 EXPECT_EQ(expected_routing_id, message->routing_id()); |
| 64 InputMsg_SetFocus::Param params; | 65 InputMsg_SetFocus::Param params; |
| 65 EXPECT_TRUE(InputMsg_SetFocus::Read(message, ¶ms)); | 66 EXPECT_TRUE(InputMsg_SetFocus::Read(message, ¶ms)); |
| 66 EXPECT_EQ(expected_focus, base::get<0>(params)); | 67 EXPECT_EQ(expected_focus, base::get<0>(params)); |
| 67 } | 68 } |
| 68 | 69 |
| 69 class RenderFrameHostManagerTestWebUIControllerFactory | 70 class RenderFrameHostManagerTestWebUIControllerFactory |
| 70 : public WebUIControllerFactory { | 71 : public WebUIControllerFactory { |
| 71 public: | 72 public: |
| 72 RenderFrameHostManagerTestWebUIControllerFactory() | 73 RenderFrameHostManagerTestWebUIControllerFactory() |
| 73 : should_create_webui_(false) { | 74 : should_create_webui_(false), type_(1) { |
| 75 CHECK_NE(reinterpret_cast<WebUI::TypeID>(type_), WebUI::kNoWebUI); | |
| 74 } | 76 } |
| 75 ~RenderFrameHostManagerTestWebUIControllerFactory() override {} | 77 ~RenderFrameHostManagerTestWebUIControllerFactory() override {} |
| 76 | 78 |
| 77 void set_should_create_webui(bool should_create_webui) { | 79 void set_should_create_webui(bool should_create_webui) { |
| 78 should_create_webui_ = should_create_webui; | 80 should_create_webui_ = should_create_webui; |
| 79 } | 81 } |
| 80 | 82 |
| 83 // This method simulates the expectation that different WebUI instance types | |
| 84 // would be created. The |type| value will be returned by GetWebUIType casted | |
| 85 // to WebUI::TypeID. | |
| 86 // As WebUI::TypeID is a typedef to void pointer, factory implementations | |
| 87 // return values that they know to be unique to their respective cases. So | |
| 88 // values set here should be safe if kept very low (just above zero). | |
| 89 void set_webui_type(uintptr_t type) { | |
| 90 CHECK_NE(reinterpret_cast<WebUI::TypeID>(type), WebUI::kNoWebUI); | |
| 91 type_ = type; | |
| 92 } | |
| 93 | |
| 81 // WebUIFactory implementation. | 94 // WebUIFactory implementation. |
| 82 WebUIController* CreateWebUIControllerForURL(WebUI* web_ui, | 95 WebUIController* CreateWebUIControllerForURL(WebUI* web_ui, |
| 83 const GURL& url) const override { | 96 const GURL& url) const override { |
| 84 if (!(should_create_webui_ && HasWebUIScheme(url))) | 97 // If WebUI creation is enabled for the test and this is a WebUI URL, |
| 85 return NULL; | 98 // returns a new instance. |
| 86 return new WebUIController(web_ui); | 99 if (should_create_webui_ && HasWebUIScheme(url)) |
| 100 return new WebUIController(web_ui); | |
| 101 return nullptr; | |
| 87 } | 102 } |
| 88 | 103 |
| 89 WebUI::TypeID GetWebUIType(BrowserContext* browser_context, | 104 WebUI::TypeID GetWebUIType(BrowserContext* browser_context, |
| 90 const GURL& url) const override { | 105 const GURL& url) const override { |
| 106 // If WebUI creation is enabled for the test and this is a WebUI URL, | |
| 107 // returns a mock WebUI type. | |
| 108 if (should_create_webui_ && HasWebUIScheme(url)) { | |
| 109 return reinterpret_cast<WebUI::TypeID>(type_); | |
| 110 } | |
| 91 return WebUI::kNoWebUI; | 111 return WebUI::kNoWebUI; |
| 92 } | 112 } |
| 93 | 113 |
| 94 bool UseWebUIForURL(BrowserContext* browser_context, | 114 bool UseWebUIForURL(BrowserContext* browser_context, |
| 95 const GURL& url) const override { | 115 const GURL& url) const override { |
| 96 return HasWebUIScheme(url); | 116 return HasWebUIScheme(url); |
| 97 } | 117 } |
| 98 | 118 |
| 99 bool UseWebUIBindingsForURL(BrowserContext* browser_context, | 119 bool UseWebUIBindingsForURL(BrowserContext* browser_context, |
| 100 const GURL& url) const override { | 120 const GURL& url) const override { |
| 101 return HasWebUIScheme(url); | 121 return HasWebUIScheme(url); |
| 102 } | 122 } |
| 103 | 123 |
| 104 private: | 124 private: |
| 105 bool should_create_webui_; | 125 bool should_create_webui_; |
| 126 uintptr_t type_; | |
| 106 | 127 |
| 107 DISALLOW_COPY_AND_ASSIGN(RenderFrameHostManagerTestWebUIControllerFactory); | 128 DISALLOW_COPY_AND_ASSIGN(RenderFrameHostManagerTestWebUIControllerFactory); |
| 108 }; | 129 }; |
| 109 | 130 |
| 110 class BeforeUnloadFiredWebContentsDelegate : public WebContentsDelegate { | 131 class BeforeUnloadFiredWebContentsDelegate : public WebContentsDelegate { |
| 111 public: | 132 public: |
| 112 BeforeUnloadFiredWebContentsDelegate() {} | 133 BeforeUnloadFiredWebContentsDelegate() {} |
| 113 ~BeforeUnloadFiredWebContentsDelegate() override {} | 134 ~BeforeUnloadFiredWebContentsDelegate() override {} |
| 114 | 135 |
| 115 void BeforeUnloadFired(WebContents* web_contents, | 136 void BeforeUnloadFired(WebContents* web_contents, |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 273 // RenderWidgetHostView holds on to a reference to SurfaceManager, so it | 294 // RenderWidgetHostView holds on to a reference to SurfaceManager, so it |
| 274 // must be shut down before the ImageTransportFactory. | 295 // must be shut down before the ImageTransportFactory. |
| 275 ImageTransportFactory::Terminate(); | 296 ImageTransportFactory::Terminate(); |
| 276 #endif | 297 #endif |
| 277 } | 298 } |
| 278 | 299 |
| 279 void set_should_create_webui(bool should_create_webui) { | 300 void set_should_create_webui(bool should_create_webui) { |
| 280 factory_.set_should_create_webui(should_create_webui); | 301 factory_.set_should_create_webui(should_create_webui); |
| 281 } | 302 } |
| 282 | 303 |
| 304 void set_webui_type(int type) { factory_.set_webui_type(type); } | |
| 305 | |
| 283 void NavigateActiveAndCommit(const GURL& url) { | 306 void NavigateActiveAndCommit(const GURL& url) { |
| 284 // Note: we navigate the active RenderFrameHost because previous navigations | 307 // Note: we navigate the active RenderFrameHost because previous navigations |
| 285 // won't have committed yet, so NavigateAndCommit does the wrong thing | 308 // won't have committed yet, so NavigateAndCommit does the wrong thing |
| 286 // for us. | 309 // for us. |
| 287 controller().LoadURL( | 310 controller().LoadURL( |
| 288 url, Referrer(), ui::PAGE_TRANSITION_LINK, std::string()); | 311 url, Referrer(), ui::PAGE_TRANSITION_LINK, std::string()); |
| 289 int entry_id = controller().GetPendingEntry()->GetUniqueID(); | 312 int entry_id = controller().GetPendingEntry()->GetUniqueID(); |
| 290 | 313 |
| 291 // Simulate the BeforeUnload_ACK that is received from the current renderer | 314 // Simulate the BeforeUnload_ACK that is received from the current renderer |
| 292 // for a cross-site navigation. | 315 // for a cross-site navigation. |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 404 | 427 |
| 405 // Returns the RenderFrameHost that should be used in the navigation to | 428 // Returns the RenderFrameHost that should be used in the navigation to |
| 406 // |entry|. | 429 // |entry|. |
| 407 RenderFrameHostImpl* NavigateToEntry( | 430 RenderFrameHostImpl* NavigateToEntry( |
| 408 RenderFrameHostManager* manager, | 431 RenderFrameHostManager* manager, |
| 409 const NavigationEntryImpl& entry) { | 432 const NavigationEntryImpl& entry) { |
| 410 // Tests currently only navigate using main frame FrameNavigationEntries. | 433 // Tests currently only navigate using main frame FrameNavigationEntries. |
| 411 FrameNavigationEntry* frame_entry = entry.root_node()->frame_entry.get(); | 434 FrameNavigationEntry* frame_entry = entry.root_node()->frame_entry.get(); |
| 412 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 435 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 413 switches::kEnableBrowserSideNavigation)) { | 436 switches::kEnableBrowserSideNavigation)) { |
| 437 NavigationControllerImpl* controller = | |
| 438 static_cast<NavigationControllerImpl*>(manager->current_frame_host() | |
| 439 ->frame_tree_node() | |
| 440 ->navigator() | |
| 441 ->GetController()); | |
| 442 // TODO(carlosk): This implementation below will not work with restore | |
| 443 // navigations. Method GetNavigationType should be exposed from | |
| 444 // navigator_impl.cc and used here to determine FrameMsg_Navigate_Type. | |
| 445 CHECK(entry.restore_type() == NavigationEntryImpl::RESTORE_NONE); | |
| 414 scoped_ptr<NavigationRequest> navigation_request = | 446 scoped_ptr<NavigationRequest> navigation_request = |
| 415 NavigationRequest::CreateBrowserInitiated( | 447 NavigationRequest::CreateBrowserInitiated( |
| 416 manager->frame_tree_node_, frame_entry->url(), | 448 manager->frame_tree_node_, frame_entry->url(), |
| 417 frame_entry->referrer(), *frame_entry, entry, | 449 frame_entry->referrer(), *frame_entry, entry, |
| 418 FrameMsg_Navigate_Type::NORMAL, false, base::TimeTicks::Now(), | 450 FrameMsg_Navigate_Type::NORMAL, false, base::TimeTicks::Now(), |
| 419 static_cast<NavigationControllerImpl*>(&controller())); | 451 controller); |
| 452 | |
| 453 // Simulates request creation that triggers the 1st internal call to | |
| 454 // GetFrameHostForNavigation. | |
| 455 manager->DidCreateNavigationRequest(*navigation_request); | |
| 456 | |
| 457 // And also simulates the 2nd and final call to GetFrameHostForNavigation | |
| 458 // that determines the final frame that will commit the navigation. | |
| 420 TestRenderFrameHost* frame_host = static_cast<TestRenderFrameHost*>( | 459 TestRenderFrameHost* frame_host = static_cast<TestRenderFrameHost*>( |
| 421 manager->GetFrameHostForNavigation(*navigation_request)); | 460 manager->GetFrameHostForNavigation(*navigation_request)); |
| 422 CHECK(frame_host); | 461 CHECK(frame_host); |
| 423 frame_host->set_pending_commit(true); | 462 frame_host->set_pending_commit(true); |
| 424 return frame_host; | 463 return frame_host; |
| 425 } | 464 } |
| 426 | 465 |
| 427 return manager->Navigate(frame_entry->url(), *frame_entry, entry); | 466 return manager->Navigate(frame_entry->url(), *frame_entry, entry); |
| 428 } | 467 } |
| 429 | 468 |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 440 | 479 |
| 441 // Exposes RenderFrameHostManager::CollectOpenerFrameTrees for testing. | 480 // Exposes RenderFrameHostManager::CollectOpenerFrameTrees for testing. |
| 442 void CollectOpenerFrameTrees( | 481 void CollectOpenerFrameTrees( |
| 443 FrameTreeNode* node, | 482 FrameTreeNode* node, |
| 444 std::vector<FrameTree*>* opener_frame_trees, | 483 std::vector<FrameTree*>* opener_frame_trees, |
| 445 base::hash_set<FrameTreeNode*>* nodes_with_back_links) { | 484 base::hash_set<FrameTreeNode*>* nodes_with_back_links) { |
| 446 node->render_manager()->CollectOpenerFrameTrees(opener_frame_trees, | 485 node->render_manager()->CollectOpenerFrameTrees(opener_frame_trees, |
| 447 nodes_with_back_links); | 486 nodes_with_back_links); |
| 448 } | 487 } |
| 449 | 488 |
| 489 void BaseSimultaneousNavigationWithOneWebUI( | |
| 490 const std::function<void(RenderFrameHostImpl*, | |
| 491 RenderFrameHostImpl*, | |
| 492 WebUIImpl*, | |
| 493 RenderFrameHostManager*)>& commit_lambda); | |
| 494 | |
| 495 void BaseSimultaneousNavigationWithTwoWebUIs( | |
| 496 const std::function<void(RenderFrameHostImpl*, | |
| 497 RenderFrameHostImpl*, | |
| 498 WebUIImpl*, | |
| 499 WebUIImpl*, | |
| 500 RenderFrameHostManager*)>& commit_lambda); | |
| 501 | |
| 450 private: | 502 private: |
| 451 RenderFrameHostManagerTestWebUIControllerFactory factory_; | 503 RenderFrameHostManagerTestWebUIControllerFactory factory_; |
| 452 }; | 504 }; |
| 453 | 505 |
| 454 // Tests that when you navigate from a chrome:// url to another page, and | 506 // Tests that when you navigate from a chrome:// url to another page, and |
| 455 // then do that same thing in another tab, that the two resulting pages have | 507 // then do that same thing in another tab, that the two resulting pages have |
| 456 // different SiteInstances, BrowsingInstances, and RenderProcessHosts. This is | 508 // different SiteInstances, BrowsingInstances, and RenderProcessHosts. This is |
| 457 // a regression test for bug 9364. | 509 // a regression test for bug 9364. |
| 458 TEST_F(RenderFrameHostManagerTest, NewTabPageProcesses) { | 510 TEST_F(RenderFrameHostManagerTest, NewTabPageProcesses) { |
| 459 set_should_create_webui(true); | 511 set_should_create_webui(true); |
| (...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1082 TEST_F(RenderFrameHostManagerTest, WebUI) { | 1134 TEST_F(RenderFrameHostManagerTest, WebUI) { |
| 1083 set_should_create_webui(true); | 1135 set_should_create_webui(true); |
| 1084 SiteInstance* instance = SiteInstance::Create(browser_context()); | 1136 SiteInstance* instance = SiteInstance::Create(browser_context()); |
| 1085 | 1137 |
| 1086 scoped_ptr<TestWebContents> web_contents( | 1138 scoped_ptr<TestWebContents> web_contents( |
| 1087 TestWebContents::Create(browser_context(), instance)); | 1139 TestWebContents::Create(browser_context(), instance)); |
| 1088 RenderFrameHostManager* manager = web_contents->GetRenderManagerForTesting(); | 1140 RenderFrameHostManager* manager = web_contents->GetRenderManagerForTesting(); |
| 1089 RenderFrameHostImpl* initial_rfh = manager->current_frame_host(); | 1141 RenderFrameHostImpl* initial_rfh = manager->current_frame_host(); |
| 1090 | 1142 |
| 1091 EXPECT_FALSE(manager->current_host()->IsRenderViewLive()); | 1143 EXPECT_FALSE(manager->current_host()->IsRenderViewLive()); |
| 1092 EXPECT_FALSE(manager->web_ui()); | 1144 EXPECT_FALSE(manager->current_frame_host()->web_ui()); |
| 1093 EXPECT_TRUE(initial_rfh); | 1145 EXPECT_TRUE(initial_rfh); |
| 1094 | 1146 |
| 1095 const GURL kUrl("chrome://foo"); | 1147 const GURL kUrl("chrome://foo"); |
| 1096 NavigationEntryImpl entry(NULL /* instance */, -1 /* page_id */, kUrl, | 1148 NavigationEntryImpl entry(NULL /* instance */, -1 /* page_id */, kUrl, |
| 1097 Referrer(), base::string16() /* title */, | 1149 Referrer(), base::string16() /* title */, |
| 1098 ui::PAGE_TRANSITION_TYPED, | 1150 ui::PAGE_TRANSITION_TYPED, |
| 1099 false /* is_renderer_init */); | 1151 false /* is_renderer_init */); |
| 1100 RenderFrameHostImpl* host = NavigateToEntry(manager, entry); | 1152 RenderFrameHostImpl* host = NavigateToEntry(manager, entry); |
| 1101 | 1153 |
| 1102 // We commit the pending RenderFrameHost immediately because the previous | 1154 // We commit the pending RenderFrameHost immediately because the previous |
| 1103 // RenderFrameHost was not live. We test a case where it is live in | 1155 // RenderFrameHost was not live. We test a case where it is live in |
| 1104 // WebUIInNewTab. | 1156 // WebUIInNewTab. |
| 1105 EXPECT_TRUE(host); | 1157 EXPECT_TRUE(host); |
| 1106 EXPECT_NE(initial_rfh, host); | 1158 EXPECT_NE(initial_rfh, host); |
| 1107 EXPECT_EQ(host, manager->current_frame_host()); | 1159 EXPECT_EQ(host, manager->current_frame_host()); |
| 1108 EXPECT_FALSE(GetPendingFrameHost(manager)); | 1160 EXPECT_FALSE(GetPendingFrameHost(manager)); |
| 1109 | 1161 |
| 1110 // It's important that the SiteInstance get set on the Web UI page as soon | 1162 // It's important that the SiteInstance get set on the Web UI page as soon |
| 1111 // as the navigation starts, rather than lazily after it commits, so we don't | 1163 // as the navigation starts, rather than lazily after it commits, so we don't |
| 1112 // try to re-use the SiteInstance/process for non Web UI things that may | 1164 // try to re-use the SiteInstance/process for non Web UI things that may |
| 1113 // get loaded in between. | 1165 // get loaded in between. |
| 1114 EXPECT_TRUE(host->GetSiteInstance()->HasSite()); | 1166 EXPECT_TRUE(host->GetSiteInstance()->HasSite()); |
| 1115 EXPECT_EQ(kUrl, host->GetSiteInstance()->GetSiteURL()); | 1167 EXPECT_EQ(kUrl, host->GetSiteInstance()->GetSiteURL()); |
| 1116 | 1168 |
| 1117 // The Web UI is committed immediately because the RenderViewHost has not been | 1169 // The Web UI is committed immediately because the RenderViewHost has not been |
| 1118 // used yet. UpdateStateForNavigate() took the short cut path. | 1170 // used yet. UpdateStateForNavigate() took the short cut path. |
| 1119 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 1171 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 1120 switches::kEnableBrowserSideNavigation)) { | 1172 switches::kEnableBrowserSideNavigation)) { |
| 1121 EXPECT_FALSE(manager->speculative_web_ui()); | 1173 // In PlzNavigate, there will be a navigating WebUI because |
| 1174 // GetFrameHostForNavigation was already called twice and the committed | |
| 1175 // WebUI should be set to be reused. | |
| 1176 EXPECT_TRUE(manager->GetNavigatingWebUI()); | |
| 1177 EXPECT_EQ(host->web_ui(), manager->GetNavigatingWebUI()); | |
| 1178 EXPECT_EQ(host->web_ui(), host->pending_web_ui()); | |
| 1122 } else { | 1179 } else { |
| 1123 EXPECT_FALSE(manager->pending_web_ui()); | 1180 // The WebUI was immediately committed and there should be none navigating. |
| 1181 EXPECT_FALSE(manager->GetNavigatingWebUI()); | |
| 1124 } | 1182 } |
| 1125 EXPECT_TRUE(manager->web_ui()); | 1183 EXPECT_TRUE(manager->current_frame_host()->web_ui()); |
| 1126 | 1184 |
| 1127 // Commit. | 1185 // Commit. |
| 1128 manager->DidNavigateFrame(host, true); | 1186 manager->DidNavigateFrame(host, true); |
| 1129 EXPECT_TRUE( | 1187 EXPECT_TRUE( |
| 1130 host->render_view_host()->GetEnabledBindings() & BINDINGS_POLICY_WEB_UI); | 1188 host->render_view_host()->GetEnabledBindings() & BINDINGS_POLICY_WEB_UI); |
| 1131 } | 1189 } |
| 1132 | 1190 |
| 1133 // Tests that we can open a WebUI link in a new tab from a WebUI page and still | 1191 // Tests that we can open a WebUI link in a new tab from a WebUI page and still |
| 1134 // grant the correct bindings. http://crbug.com/189101. | 1192 // grant the correct bindings. http://crbug.com/189101. |
| 1135 TEST_F(RenderFrameHostManagerTest, WebUIInNewTab) { | 1193 TEST_F(RenderFrameHostManagerTest, WebUIInNewTab) { |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1184 const GURL kUrl2("chrome://foo/bar"); | 1242 const GURL kUrl2("chrome://foo/bar"); |
| 1185 NavigationEntryImpl entry2(NULL /* instance */, -1 /* page_id */, kUrl2, | 1243 NavigationEntryImpl entry2(NULL /* instance */, -1 /* page_id */, kUrl2, |
| 1186 Referrer(), base::string16() /* title */, | 1244 Referrer(), base::string16() /* title */, |
| 1187 ui::PAGE_TRANSITION_LINK, | 1245 ui::PAGE_TRANSITION_LINK, |
| 1188 true /* is_renderer_init */); | 1246 true /* is_renderer_init */); |
| 1189 RenderFrameHostImpl* host2 = NavigateToEntry(manager2, entry2); | 1247 RenderFrameHostImpl* host2 = NavigateToEntry(manager2, entry2); |
| 1190 | 1248 |
| 1191 // No cross-process transition happens because we are already in the right | 1249 // No cross-process transition happens because we are already in the right |
| 1192 // SiteInstance. We should grant bindings immediately. | 1250 // SiteInstance. We should grant bindings immediately. |
| 1193 EXPECT_EQ(host2, manager2->current_frame_host()); | 1251 EXPECT_EQ(host2, manager2->current_frame_host()); |
| 1194 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 1252 EXPECT_TRUE(manager2->GetNavigatingWebUI()); |
| 1195 switches::kEnableBrowserSideNavigation)) { | 1253 EXPECT_FALSE(host2->web_ui()); |
| 1196 EXPECT_TRUE(manager2->speculative_web_ui()); | |
| 1197 } else { | |
| 1198 EXPECT_TRUE(manager2->pending_web_ui()); | |
| 1199 } | |
| 1200 EXPECT_TRUE( | 1254 EXPECT_TRUE( |
| 1201 host2->render_view_host()->GetEnabledBindings() & BINDINGS_POLICY_WEB_UI); | 1255 host2->render_view_host()->GetEnabledBindings() & BINDINGS_POLICY_WEB_UI); |
| 1202 | 1256 |
| 1203 manager2->DidNavigateFrame(host2, true); | 1257 manager2->DidNavigateFrame(host2, true); |
| 1204 } | 1258 } |
| 1205 | 1259 |
| 1206 // Tests that a WebUI is correctly reused between chrome:// pages. | 1260 // Tests that a WebUI is correctly reused between chrome:// pages. |
| 1207 TEST_F(RenderFrameHostManagerTest, WebUIWasReused) { | 1261 TEST_F(RenderFrameHostManagerTest, WebUIWasReused) { |
| 1208 set_should_create_webui(true); | 1262 set_should_create_webui(true); |
| 1209 | 1263 |
| 1210 // Navigate to a WebUI page. | 1264 // Navigate to a WebUI page. |
| 1211 const GURL kUrl1("chrome://foo"); | 1265 const GURL kUrl1("chrome://foo"); |
| 1212 contents()->NavigateAndCommit(kUrl1); | 1266 contents()->NavigateAndCommit(kUrl1); |
| 1213 RenderFrameHostManager* manager = | 1267 WebUIImpl* web_ui = main_test_rfh()->web_ui(); |
| 1214 main_test_rfh()->frame_tree_node()->render_manager(); | |
| 1215 WebUIImpl* web_ui = manager->web_ui(); | |
| 1216 EXPECT_TRUE(web_ui); | 1268 EXPECT_TRUE(web_ui); |
| 1217 | 1269 |
| 1218 // Navigate to another WebUI page which should be same-site and keep the | 1270 // Navigate to another WebUI page which should be same-site and keep the |
| 1219 // current WebUI. | 1271 // current WebUI. |
| 1220 const GURL kUrl2("chrome://foo/bar"); | 1272 const GURL kUrl2("chrome://foo/bar"); |
| 1221 contents()->NavigateAndCommit(kUrl2); | 1273 contents()->NavigateAndCommit(kUrl2); |
| 1222 EXPECT_EQ(web_ui, manager->web_ui()); | 1274 EXPECT_EQ(web_ui, main_test_rfh()->web_ui()); |
| 1223 } | 1275 } |
| 1224 | 1276 |
| 1225 // Tests that a WebUI is correctly cleaned up when navigating from a chrome:// | 1277 // Tests that a WebUI is correctly cleaned up when navigating from a chrome:// |
| 1226 // page to a non-chrome:// page. | 1278 // page to a non-chrome:// page. |
| 1227 TEST_F(RenderFrameHostManagerTest, WebUIWasCleared) { | 1279 TEST_F(RenderFrameHostManagerTest, WebUIWasCleared) { |
| 1228 set_should_create_webui(true); | 1280 set_should_create_webui(true); |
| 1229 | 1281 |
| 1230 // Navigate to a WebUI page. | 1282 // Navigate to a WebUI page. |
| 1231 const GURL kUrl1("chrome://foo"); | 1283 const GURL kUrl1("chrome://foo"); |
| 1232 contents()->NavigateAndCommit(kUrl1); | 1284 contents()->NavigateAndCommit(kUrl1); |
| 1233 EXPECT_TRUE(main_test_rfh()->frame_tree_node()->render_manager()->web_ui()); | 1285 EXPECT_TRUE(main_test_rfh()->web_ui()); |
| 1234 | 1286 |
| 1235 // Navigate to a non-WebUI page. | 1287 // Navigate to a non-WebUI page. |
| 1236 const GURL kUrl2("http://www.google.com"); | 1288 const GURL kUrl2("http://www.google.com"); |
| 1237 contents()->NavigateAndCommit(kUrl2); | 1289 contents()->NavigateAndCommit(kUrl2); |
| 1238 EXPECT_FALSE(main_test_rfh()->frame_tree_node()->render_manager()->web_ui()); | 1290 EXPECT_FALSE(main_test_rfh()->web_ui()); |
| 1239 } | 1291 } |
| 1240 | 1292 |
| 1241 // Tests that we don't end up in an inconsistent state if a page does a back and | 1293 // Tests that we don't end up in an inconsistent state if a page does a back and |
| 1242 // then reload. http://crbug.com/51680 | 1294 // then reload. http://crbug.com/51680 |
| 1243 // Also tests that only user-gesture navigations can interrupt cross-process | 1295 // Also tests that only user-gesture navigations can interrupt cross-process |
| 1244 // navigations. http://crbug.com/75195 | 1296 // navigations. http://crbug.com/75195 |
| 1245 TEST_F(RenderFrameHostManagerTest, PageDoesBackAndReload) { | 1297 TEST_F(RenderFrameHostManagerTest, PageDoesBackAndReload) { |
| 1246 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 1298 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 1247 switches::kEnableBrowserSideNavigation)) { | 1299 switches::kEnableBrowserSideNavigation)) { |
| 1248 // PlzNavigate uses a significantly different logic for renderer initiated | 1300 // PlzNavigate uses a significantly different logic for renderer initiated |
| (...skipping 1406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2655 RenderFrameProxyHost* proxy = | 2707 RenderFrameProxyHost* proxy = |
| 2656 root->render_manager()->GetRenderFrameProxyHost(hostC->GetSiteInstance()); | 2708 root->render_manager()->GetRenderFrameProxyHost(hostC->GetSiteInstance()); |
| 2657 EXPECT_TRUE(proxy); | 2709 EXPECT_TRUE(proxy); |
| 2658 | 2710 |
| 2659 // Since the B->C navigation happened while the current page was focused, | 2711 // Since the B->C navigation happened while the current page was focused, |
| 2660 // page focus should propagate to the new subframe process. Check that | 2712 // page focus should propagate to the new subframe process. Check that |
| 2661 // process C received the proper focus message. | 2713 // process C received the proper focus message. |
| 2662 VerifyPageFocusMessage(hostC->GetProcess(), true, proxy->GetRoutingID()); | 2714 VerifyPageFocusMessage(hostC->GetProcess(), true, proxy->GetRoutingID()); |
| 2663 } | 2715 } |
| 2664 | 2716 |
| 2717 // Checks that a restore navigation to a WebUI works. | |
| 2718 TEST_F(RenderFrameHostManagerTest, RestoreNavigationToWebUI) { | |
| 2719 set_should_create_webui(true); | |
| 2720 | |
| 2721 const GURL kInitUrl("chrome://foo/"); | |
| 2722 SiteInstanceImpl* initial_instance = | |
| 2723 static_cast<SiteInstanceImpl*>(SiteInstance::Create(browser_context())); | |
| 2724 initial_instance->SetSite(kInitUrl); | |
| 2725 scoped_ptr<TestWebContents> web_contents( | |
| 2726 TestWebContents::Create(browser_context(), initial_instance)); | |
| 2727 RenderFrameHostManager* manager = web_contents->GetRenderManagerForTesting(); | |
| 2728 NavigationControllerImpl& controller = web_contents->GetController(); | |
| 2729 | |
| 2730 // Setup a restored entry. | |
| 2731 std::vector<scoped_ptr<NavigationEntry>> entries; | |
| 2732 scoped_ptr<NavigationEntry> new_entry = | |
| 2733 NavigationControllerImpl::CreateNavigationEntry( | |
| 2734 kInitUrl, Referrer(), ui::PAGE_TRANSITION_TYPED, false, std::string(), | |
| 2735 browser_context()); | |
| 2736 new_entry->SetPageID(0); | |
| 2737 entries.push_back(new_entry.Pass()); | |
| 2738 controller.Restore( | |
| 2739 0, NavigationController::RESTORE_LAST_SESSION_EXITED_CLEANLY, &entries); | |
| 2740 ASSERT_EQ(0u, entries.size()); | |
| 2741 ASSERT_EQ(1, controller.GetEntryCount()); | |
| 2742 | |
| 2743 RenderFrameHostImpl* initial_host = manager->current_frame_host(); | |
| 2744 ASSERT_TRUE(initial_host); | |
| 2745 EXPECT_FALSE(initial_host->IsRenderFrameLive()); | |
| 2746 EXPECT_FALSE(initial_host->web_ui()); | |
| 2747 | |
| 2748 // Navigation request to an entry from a previous browsing session. | |
| 2749 NavigationEntryImpl entry(nullptr /* instance */, 0 /* page_id */, kInitUrl, | |
| 2750 Referrer(), base::string16() /* title */, | |
| 2751 ui::PAGE_TRANSITION_RELOAD, | |
| 2752 false /* is_renderer_init */); | |
| 2753 entry.set_restore_type( | |
| 2754 NavigationEntryImpl::RESTORE_LAST_SESSION_EXITED_CLEANLY); | |
| 2755 NavigateToEntry(manager, entry); | |
| 2756 | |
| 2757 // As the initial renderer was not live, the new RenderFrameHost should be | |
| 2758 // made immediately active at request time. | |
| 2759 EXPECT_FALSE(GetPendingFrameHost(manager)); | |
| 2760 TestRenderFrameHost* current_host = | |
| 2761 static_cast<TestRenderFrameHost*>(manager->current_frame_host()); | |
| 2762 ASSERT_TRUE(current_host); | |
| 2763 EXPECT_EQ(current_host, initial_host); | |
| 2764 EXPECT_TRUE(current_host->IsRenderFrameLive()); | |
| 2765 WebUIImpl* web_ui = manager->GetNavigatingWebUI(); | |
| 2766 EXPECT_TRUE(web_ui); | |
| 2767 EXPECT_EQ(web_ui, current_host->pending_web_ui()); | |
| 2768 EXPECT_FALSE(current_host->web_ui()); | |
| 2769 | |
| 2770 // The RenderFrameHost committed. | |
| 2771 manager->DidNavigateFrame(current_host, true); | |
| 2772 EXPECT_EQ(current_host, manager->current_frame_host()); | |
| 2773 EXPECT_EQ(web_ui, current_host->web_ui()); | |
| 2774 EXPECT_FALSE(current_host->pending_web_ui()); | |
| 2775 } | |
| 2776 | |
| 2777 // Shared code until before commit for the SimultaneousNavigationWithOneWebUI* | |
| 2778 // tests, accepting a lambda to execute the commit step. | |
| 2779 void RenderFrameHostManagerTest::BaseSimultaneousNavigationWithOneWebUI( | |
| 2780 const std::function<void(RenderFrameHostImpl*, | |
| 2781 RenderFrameHostImpl*, | |
| 2782 WebUIImpl*, | |
| 2783 RenderFrameHostManager*)>& commit_lambda) { | |
| 2784 set_should_create_webui(true); | |
| 2785 NavigateActiveAndCommit(GURL("chrome://foo/")); | |
| 2786 | |
| 2787 RenderFrameHostManager* manager = contents()->GetRenderManagerForTesting(); | |
| 2788 RenderFrameHostImpl* host1 = manager->current_frame_host(); | |
| 2789 EXPECT_TRUE(host1->IsRenderFrameLive()); | |
| 2790 WebUIImpl* web_ui = host1->web_ui(); | |
| 2791 EXPECT_TRUE(web_ui); | |
| 2792 | |
| 2793 // Starts a reload of the WebUI page. | |
| 2794 contents()->GetController().Reload(true); | |
| 2795 | |
| 2796 // It should be a same-site navigation reusing the same WebUI. | |
| 2797 EXPECT_EQ(web_ui, manager->GetNavigatingWebUI()); | |
| 2798 EXPECT_EQ(web_ui, host1->web_ui()); | |
| 2799 EXPECT_EQ(web_ui, host1->pending_web_ui()); | |
| 2800 EXPECT_FALSE(GetPendingFrameHost(manager)); | |
| 2801 | |
| 2802 // Navigation request to a non-WebUI page. | |
| 2803 const GURL kUrl("http://google.com"); | |
| 2804 NavigationEntryImpl entry(NULL /* instance */, -1 /* page_id */, kUrl, | |
| 2805 Referrer(), base::string16() /* title */, | |
| 2806 ui::PAGE_TRANSITION_TYPED, | |
| 2807 false /* is_renderer_init */); | |
| 2808 RenderFrameHostImpl* host2 = NavigateToEntry(manager, entry); | |
| 2809 ASSERT_TRUE(host2); | |
| 2810 | |
| 2811 // The previous navigation should still be ongoing along with the new, | |
| 2812 // cross-site one. | |
| 2813 // Note: Simultaneous navigations are weird: there are two ongoing | |
| 2814 // navigations, a same-site using a WebUI and a cross-site not using one. So | |
| 2815 // it's unclear what GetNavigatingWebUI should return in this case. As it | |
| 2816 // currently favors the cross-site navigation it returns null. | |
| 2817 EXPECT_FALSE(manager->GetNavigatingWebUI()); | |
| 2818 EXPECT_EQ(web_ui, host1->web_ui()); | |
| 2819 EXPECT_EQ(web_ui, host1->pending_web_ui()); | |
| 2820 | |
| 2821 EXPECT_NE(host2, host1); | |
| 2822 EXPECT_EQ(host2, GetPendingFrameHost(manager)); | |
| 2823 EXPECT_FALSE(host2->web_ui()); | |
| 2824 EXPECT_FALSE(host2->pending_web_ui()); | |
| 2825 EXPECT_NE(web_ui, host2->web_ui()); | |
| 2826 | |
| 2827 commit_lambda(host1, host2, web_ui, manager); | |
| 2828 } | |
| 2829 | |
| 2830 // Simulates two simultaneous navigations involving one WebUI where the current | |
| 2831 // RenderFrameHost commits. | |
| 2832 TEST_F(RenderFrameHostManagerTest, SimultaneousNavigationWithOneWebUI1) { | |
| 2833 auto commit_current_frame_host = [this]( | |
| 2834 RenderFrameHostImpl* host1, RenderFrameHostImpl* host2, WebUIImpl* web_ui, | |
| 2835 RenderFrameHostManager* manager) { | |
| 2836 // The current RenderFrameHost commits; its WebUI should still be in place. | |
| 2837 manager->DidNavigateFrame(host1, true); | |
| 2838 EXPECT_EQ(host1, manager->current_frame_host()); | |
| 2839 EXPECT_EQ(web_ui, host1->web_ui()); | |
| 2840 EXPECT_FALSE(host1->pending_web_ui()); | |
| 2841 EXPECT_FALSE(manager->GetNavigatingWebUI()); | |
| 2842 EXPECT_FALSE(GetPendingFrameHost(manager)); | |
| 2843 }; | |
| 2844 | |
| 2845 BaseSimultaneousNavigationWithOneWebUI(commit_current_frame_host); | |
| 2846 } | |
| 2847 | |
| 2848 // Simulates two simultaneous navigations involving one WebUI where the new, | |
| 2849 // cross-site RenderFrameHost commits. | |
| 2850 TEST_F(RenderFrameHostManagerTest, SimultaneousNavigationWithOneWebUI2) { | |
| 2851 auto commit_new_frame_host = [this]( | |
| 2852 RenderFrameHostImpl* host1, RenderFrameHostImpl* host2, WebUIImpl* web_ui, | |
| 2853 RenderFrameHostManager* manager) { | |
| 2854 // The new RenderFrameHost commits; there should be no active WebUI. | |
| 2855 manager->DidNavigateFrame(host2, true); | |
| 2856 EXPECT_EQ(host2, manager->current_frame_host()); | |
| 2857 EXPECT_FALSE(host2->web_ui()); | |
| 2858 EXPECT_FALSE(host2->pending_web_ui()); | |
| 2859 EXPECT_FALSE(manager->GetNavigatingWebUI()); | |
| 2860 EXPECT_FALSE(GetPendingFrameHost(manager)); | |
| 2861 }; | |
| 2862 | |
| 2863 BaseSimultaneousNavigationWithOneWebUI(commit_new_frame_host); | |
| 2864 } | |
| 2865 | |
| 2866 // Shared code until before commit for the SimultaneousNavigationWithTwoWebUIs* | |
| 2867 // tests, accepting a lambda to execute the commit step. | |
| 2868 void RenderFrameHostManagerTest::BaseSimultaneousNavigationWithTwoWebUIs( | |
| 2869 const std::function<void(RenderFrameHostImpl*, | |
| 2870 RenderFrameHostImpl*, | |
| 2871 WebUIImpl*, | |
| 2872 WebUIImpl*, | |
| 2873 RenderFrameHostManager*)>& commit_lambda) { | |
| 2874 set_should_create_webui(true); | |
| 2875 set_webui_type(1); | |
| 2876 NavigateActiveAndCommit(GURL("chrome://foo/")); | |
| 2877 | |
| 2878 RenderFrameHostManager* manager = contents()->GetRenderManagerForTesting(); | |
| 2879 RenderFrameHostImpl* host1 = manager->current_frame_host(); | |
| 2880 EXPECT_TRUE(host1->IsRenderFrameLive()); | |
| 2881 WebUIImpl* web_ui1 = host1->web_ui(); | |
| 2882 EXPECT_TRUE(web_ui1); | |
| 2883 | |
| 2884 // Starts a reload of the WebUI page. | |
| 2885 contents()->GetController().Reload(true); | |
| 2886 | |
| 2887 // It should be a same-site navigation reusing the same WebUI. | |
| 2888 EXPECT_EQ(web_ui1, manager->GetNavigatingWebUI()); | |
| 2889 EXPECT_EQ(web_ui1, host1->web_ui()); | |
| 2890 EXPECT_EQ(web_ui1, host1->pending_web_ui()); | |
| 2891 EXPECT_FALSE(GetPendingFrameHost(manager)); | |
| 2892 | |
| 2893 // Navigation another WebUI page, with a different type. | |
| 2894 set_webui_type(2); | |
| 2895 const GURL kUrl("chrome://bar/"); | |
| 2896 NavigationEntryImpl entry(NULL /* instance */, -1 /* page_id */, kUrl, | |
| 2897 Referrer(), base::string16() /* title */, | |
| 2898 ui::PAGE_TRANSITION_TYPED, | |
| 2899 false /* is_renderer_init */); | |
| 2900 RenderFrameHostImpl* host2 = NavigateToEntry(manager, entry); | |
| 2901 ASSERT_TRUE(host2); | |
| 2902 | |
| 2903 // The previous navigation should still be ongoing along with the new, | |
| 2904 // cross-site one. | |
| 2905 // Note: simultaneous navigations are weird: there are two ongoing | |
| 2906 // navigations, a same-site and a cross-site both going to WebUIs. So it's | |
| 2907 // unclear what GetNavigatingWebUI should return in this case. As it currently | |
| 2908 // favors the cross-site navigation it returns the speculative/pending | |
| 2909 // RenderFrameHost's WebUI instance. | |
| 2910 EXPECT_EQ(web_ui1, host1->web_ui()); | |
| 2911 EXPECT_EQ(web_ui1, host1->pending_web_ui()); | |
| 2912 WebUIImpl* web_ui2 = manager->GetNavigatingWebUI(); | |
| 2913 EXPECT_TRUE(web_ui2); | |
| 2914 EXPECT_NE(web_ui2, web_ui1); | |
| 2915 | |
| 2916 EXPECT_NE(host2, host1); | |
| 2917 EXPECT_EQ(host2, GetPendingFrameHost(manager)); | |
| 2918 EXPECT_EQ(web_ui2, host2->web_ui()); | |
| 2919 EXPECT_FALSE(host2->pending_web_ui()); | |
| 2920 | |
| 2921 commit_lambda(host1, host2, web_ui1, web_ui2, manager); | |
| 2922 } | |
| 2923 | |
| 2924 // Simulates two simultaneous navigations involving two WebUIs where the current | |
| 2925 // RenderFrameHost commits. | |
| 2926 TEST_F(RenderFrameHostManagerTest, SimultaneousNavigationWithTwoWebUIs1) { | |
| 2927 auto commit_current_frame_host = [this]( | |
| 2928 RenderFrameHostImpl* host1, RenderFrameHostImpl* host2, | |
| 2929 WebUIImpl* web_ui1, WebUIImpl* web_ui2, RenderFrameHostManager* manager) { | |
| 2930 // The current RenderFrameHost commits; its WebUI should still be active. | |
| 2931 manager->DidNavigateFrame(host1, true); | |
| 2932 EXPECT_EQ(host1, manager->current_frame_host()); | |
| 2933 EXPECT_EQ(web_ui1, host1->web_ui()); | |
| 2934 EXPECT_FALSE(host1->pending_web_ui()); | |
| 2935 EXPECT_FALSE(manager->GetNavigatingWebUI()); | |
| 2936 EXPECT_FALSE(GetPendingFrameHost(manager)); | |
| 2937 }; | |
| 2938 | |
| 2939 BaseSimultaneousNavigationWithTwoWebUIs(commit_current_frame_host); | |
| 2940 } | |
| 2941 | |
| 2942 // Simulates two simultaneous navigations involving two WebUIs where the new, | |
| 2943 // cross-site RenderFrameHost commits. | |
| 2944 TEST_F(RenderFrameHostManagerTest, SimultaneousNavigationWithTwoWebUIs2) { | |
| 2945 auto commit_new_frame_host = [this]( | |
| 2946 RenderFrameHostImpl* host1, RenderFrameHostImpl* host2, | |
| 2947 WebUIImpl* web_ui1, WebUIImpl* web_ui2, RenderFrameHostManager* manager) { | |
| 2948 // The new RenderFrameHost commits; its WebUI should now be active. | |
| 2949 manager->DidNavigateFrame(host2, true); | |
| 2950 EXPECT_EQ(host2, manager->current_frame_host()); | |
| 2951 EXPECT_EQ(web_ui2, host2->web_ui()); | |
| 2952 EXPECT_FALSE(host2->pending_web_ui()); | |
| 2953 EXPECT_FALSE(manager->GetNavigatingWebUI()); | |
| 2954 EXPECT_FALSE(GetPendingFrameHost(manager)); | |
| 2955 }; | |
| 2956 | |
| 2957 BaseSimultaneousNavigationWithTwoWebUIs(commit_new_frame_host); | |
| 2958 } | |
| 2959 | |
| 2960 // RenderFrameHostManagerTest extension for PlzNavigate enabled tests. | |
| 2961 class RenderFrameHostManagerTestWithBrowserSideNavigation | |
| 2962 : public RenderFrameHostManagerTest { | |
| 2963 public: | |
| 2964 void SetUp() override { | |
| 2965 EnableBrowserSideNavigation(); | |
| 2966 RenderFrameHostManagerTest::SetUp(); | |
| 2967 } | |
| 2968 }; | |
| 2969 | |
| 2970 // PlzNavigate: Tests that the correct intermediary and final navigation states | |
| 2971 // are reached when navigating from a renderer that is not live to a WebUI URL. | |
| 2972 TEST_F(RenderFrameHostManagerTestWithBrowserSideNavigation, | |
| 2973 NavigateFromDeadRendererToWebUI) { | |
| 2974 set_should_create_webui(true); | |
| 2975 RenderFrameHostManager* manager = contents()->GetRenderManagerForTesting(); | |
| 2976 | |
| 2977 RenderFrameHostImpl* initial_host = manager->current_frame_host(); | |
| 2978 ASSERT_TRUE(initial_host); | |
| 2979 EXPECT_FALSE(initial_host->IsRenderFrameLive()); | |
| 2980 | |
| 2981 // Navigation request. | |
| 2982 const GURL kUrl("chrome://foo"); | |
| 2983 NavigationEntryImpl entry(nullptr /* instance */, -1 /* page_id */, kUrl, | |
| 2984 Referrer(), base::string16() /* title */, | |
| 2985 ui::PAGE_TRANSITION_TYPED, | |
| 2986 false /* is_renderer_init */); | |
| 2987 FrameNavigationEntry* frame_entry = entry.root_node()->frame_entry.get(); | |
| 2988 scoped_ptr<NavigationRequest> navigation_request = | |
| 2989 NavigationRequest::CreateBrowserInitiated( | |
| 2990 contents()->GetFrameTree()->root(), frame_entry->url(), | |
| 2991 frame_entry->referrer(), *frame_entry, entry, | |
| 2992 FrameMsg_Navigate_Type::NORMAL, false, base::TimeTicks::Now(), | |
| 2993 static_cast<NavigationControllerImpl*>(&controller())); | |
| 2994 manager->DidCreateNavigationRequest(*navigation_request); | |
| 2995 | |
| 2996 // As the initial RenderFrame was not live, the new RenderFrameHost should be | |
| 2997 // made as active/current immediately along with its WebUI at request time. | |
| 2998 RenderFrameHostImpl* host = manager->current_frame_host(); | |
| 2999 ASSERT_TRUE(host); | |
| 3000 EXPECT_NE(host, initial_host); | |
| 3001 EXPECT_TRUE(host->IsRenderFrameLive()); | |
| 3002 WebUIImpl* web_ui = host->web_ui(); | |
| 3003 EXPECT_TRUE(web_ui); | |
| 3004 EXPECT_FALSE(host->pending_web_ui()); | |
| 3005 EXPECT_FALSE(manager->GetNavigatingWebUI()); | |
| 3006 EXPECT_FALSE(GetPendingFrameHost(manager)); | |
| 3007 | |
| 3008 // Prepare to commit, update the navigating RenderFrameHost. | |
| 3009 EXPECT_EQ(host, manager->GetFrameHostForNavigation(*navigation_request)); | |
| 3010 | |
| 3011 // There should be a pending WebUI set to reuse the current one. | |
| 3012 EXPECT_EQ(web_ui, host->web_ui()); | |
| 3013 EXPECT_EQ(web_ui, host->pending_web_ui()); | |
| 3014 EXPECT_EQ(web_ui, manager->GetNavigatingWebUI()); | |
| 3015 | |
| 3016 // No pending RenderFrameHost as the current one should be reused. | |
| 3017 EXPECT_FALSE(GetPendingFrameHost(manager)); | |
| 3018 | |
| 3019 // The RenderFrameHost committed. | |
| 3020 manager->DidNavigateFrame(host, true); | |
| 3021 EXPECT_EQ(host, manager->current_frame_host()); | |
| 3022 EXPECT_FALSE(GetPendingFrameHost(manager)); | |
| 3023 EXPECT_EQ(web_ui, host->web_ui()); | |
| 3024 EXPECT_FALSE(host->pending_web_ui()); | |
| 3025 EXPECT_FALSE(manager->GetNavigatingWebUI()); | |
| 3026 } | |
| 3027 | |
| 3028 // PlzNavigate: Tests that the correct intermediary and final navigation states | |
| 3029 // are reached when navigating same-site between two WebUIs of the same type. | |
| 3030 TEST_F(RenderFrameHostManagerTestWithBrowserSideNavigation, | |
| 3031 NavigateSameSiteBetweenWebUIs) { | |
| 3032 set_should_create_webui(true); | |
| 3033 NavigateActiveAndCommit(GURL("chrome://foo")); | |
| 3034 | |
| 3035 RenderFrameHostManager* manager = contents()->GetRenderManagerForTesting(); | |
| 3036 RenderFrameHostImpl* host = manager->current_frame_host(); | |
| 3037 EXPECT_TRUE(host->IsRenderFrameLive()); | |
| 3038 WebUIImpl* web_ui = host->web_ui(); | |
| 3039 EXPECT_TRUE(web_ui); | |
| 3040 | |
| 3041 // Navigation request. No change in the returned WebUI type. | |
| 3042 const GURL kUrl("chrome://foo/bar"); | |
| 3043 NavigationEntryImpl entry(nullptr /* instance */, -1 /* page_id */, kUrl, | |
| 3044 Referrer(), base::string16() /* title */, | |
| 3045 ui::PAGE_TRANSITION_TYPED, | |
| 3046 false /* is_renderer_init */); | |
| 3047 FrameNavigationEntry* frame_entry = entry.root_node()->frame_entry.get(); | |
| 3048 scoped_ptr<NavigationRequest> navigation_request = | |
| 3049 NavigationRequest::CreateBrowserInitiated( | |
| 3050 contents()->GetFrameTree()->root(), frame_entry->url(), | |
| 3051 frame_entry->referrer(), *frame_entry, entry, | |
| 3052 FrameMsg_Navigate_Type::NORMAL, false, base::TimeTicks::Now(), | |
| 3053 static_cast<NavigationControllerImpl*>(&controller())); | |
| 3054 manager->DidCreateNavigationRequest(*navigation_request); | |
| 3055 | |
| 3056 // The current WebUI should still be in place and the pending WebUI should be | |
| 3057 // set to reuse it. | |
| 3058 EXPECT_EQ(web_ui, manager->GetNavigatingWebUI()); | |
| 3059 EXPECT_EQ(web_ui, host->web_ui()); | |
| 3060 EXPECT_EQ(web_ui, host->pending_web_ui()); | |
| 3061 EXPECT_FALSE(GetPendingFrameHost(manager)); | |
| 3062 | |
| 3063 // Prepare to commit, update the navigating RenderFrameHost. | |
| 3064 EXPECT_EQ(host, manager->GetFrameHostForNavigation(*navigation_request)); | |
| 3065 | |
| 3066 EXPECT_EQ(web_ui, manager->GetNavigatingWebUI()); | |
| 3067 EXPECT_EQ(web_ui, host->web_ui()); | |
| 3068 EXPECT_EQ(web_ui, host->pending_web_ui()); | |
| 3069 EXPECT_FALSE(GetPendingFrameHost(manager)); | |
|
nasko
2015/11/30 16:57:49
Why do we have no speculative RFH before we've com
carlosk
2015/11/30 19:54:16
We never have one in this navigation as it is a sa
nasko
2015/12/01 00:52:14
D'oh! Yes indeed!
| |
| 3070 | |
| 3071 // The RenderFrameHost committed. | |
| 3072 manager->DidNavigateFrame(host, true); | |
| 3073 EXPECT_EQ(web_ui, host->web_ui()); | |
| 3074 EXPECT_FALSE(manager->GetNavigatingWebUI()); | |
| 3075 EXPECT_FALSE(host->pending_web_ui()); | |
| 3076 } | |
| 3077 | |
| 3078 // PlzNavigate: Tests that the correct intermediary and final navigation states | |
| 3079 // are reached when navigating cross-site between two different WebUI types. | |
| 3080 TEST_F(RenderFrameHostManagerTestWithBrowserSideNavigation, | |
| 3081 NavigateCrossSiteBetweenWebUIs) { | |
| 3082 // Cross-site navigations will always cause the change of the WebUI instance | |
| 3083 // but for consistency sake different types will be set for each navigation. | |
| 3084 set_should_create_webui(true); | |
| 3085 set_webui_type(1); | |
| 3086 NavigateActiveAndCommit(GURL("chrome://foo")); | |
| 3087 | |
| 3088 RenderFrameHostManager* manager = contents()->GetRenderManagerForTesting(); | |
| 3089 RenderFrameHostImpl* host = manager->current_frame_host(); | |
| 3090 EXPECT_TRUE(host->IsRenderFrameLive()); | |
| 3091 EXPECT_TRUE(host->web_ui()); | |
| 3092 | |
| 3093 // Set the WebUI controller to return a different WebUIType value. This will | |
| 3094 // cause the next navigation to "chrome://bar" to require a different WebUI | |
| 3095 // than the current one, forcing it to be treated as cross-site. | |
| 3096 set_webui_type(2); | |
| 3097 | |
| 3098 // Navigation request. | |
| 3099 const GURL kUrl("chrome://bar"); | |
| 3100 NavigationEntryImpl entry(nullptr /* instance */, -1 /* page_id */, kUrl, | |
| 3101 Referrer(), base::string16() /* title */, | |
| 3102 ui::PAGE_TRANSITION_TYPED, | |
| 3103 false /* is_renderer_init */); | |
| 3104 FrameNavigationEntry* frame_entry = entry.root_node()->frame_entry.get(); | |
| 3105 scoped_ptr<NavigationRequest> navigation_request = | |
| 3106 NavigationRequest::CreateBrowserInitiated( | |
| 3107 contents()->GetFrameTree()->root(), frame_entry->url(), | |
| 3108 frame_entry->referrer(), *frame_entry, entry, | |
| 3109 FrameMsg_Navigate_Type::NORMAL, false, base::TimeTicks::Now(), | |
| 3110 static_cast<NavigationControllerImpl*>(&controller())); | |
| 3111 manager->DidCreateNavigationRequest(*navigation_request); | |
| 3112 | |
| 3113 // The current WebUI should still be in place and there should be a new | |
| 3114 // active WebUI instance in the speculative RenderFrameHost. | |
| 3115 EXPECT_TRUE(manager->current_frame_host()->web_ui()); | |
| 3116 EXPECT_FALSE(manager->current_frame_host()->pending_web_ui()); | |
| 3117 RenderFrameHostImpl* speculative_host = GetPendingFrameHost(manager); | |
| 3118 EXPECT_TRUE(speculative_host); | |
| 3119 WebUIImpl* next_web_ui = manager->GetNavigatingWebUI(); | |
| 3120 EXPECT_TRUE(next_web_ui); | |
| 3121 EXPECT_EQ(next_web_ui, speculative_host->web_ui()); | |
| 3122 EXPECT_NE(next_web_ui, manager->current_frame_host()->web_ui()); | |
| 3123 EXPECT_FALSE(speculative_host->pending_web_ui()); | |
| 3124 | |
| 3125 // Prepare to commit, update the navigating RenderFrameHost. | |
| 3126 EXPECT_EQ(speculative_host, | |
| 3127 manager->GetFrameHostForNavigation(*navigation_request)); | |
| 3128 | |
| 3129 EXPECT_TRUE(manager->current_frame_host()->web_ui()); | |
| 3130 EXPECT_FALSE(manager->current_frame_host()->pending_web_ui()); | |
| 3131 EXPECT_EQ(speculative_host, GetPendingFrameHost(manager)); | |
| 3132 EXPECT_NE(next_web_ui, manager->current_frame_host()->web_ui()); | |
| 3133 EXPECT_EQ(next_web_ui, speculative_host->web_ui()); | |
| 3134 EXPECT_EQ(next_web_ui, manager->GetNavigatingWebUI()); | |
| 3135 EXPECT_FALSE(speculative_host->pending_web_ui()); | |
| 3136 | |
| 3137 // The RenderFrameHost committed. | |
| 3138 manager->DidNavigateFrame(speculative_host, true); | |
| 3139 EXPECT_EQ(speculative_host, manager->current_frame_host()); | |
| 3140 EXPECT_EQ(next_web_ui, manager->current_frame_host()->web_ui()); | |
| 3141 EXPECT_FALSE(GetPendingFrameHost(manager)); | |
| 3142 EXPECT_FALSE(speculative_host->pending_web_ui()); | |
| 3143 EXPECT_FALSE(manager->GetNavigatingWebUI()); | |
| 3144 } | |
| 3145 | |
| 2665 } // namespace content | 3146 } // namespace content |
| OLD | NEW |