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

Side by Side Diff: content/browser/frame_host/render_frame_host_manager_unittest.cc

Issue 464593003: Don't swap out the old RenderFrameHost until the new one commits. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase past PlzNavigate CL Created 6 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 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/time/time.h" 8 #include "base/time/time.h"
9 #include "content/browser/frame_host/cross_site_transferring_request.h" 9 #include "content/browser/frame_host/cross_site_transferring_request.h"
10 #include "content/browser/frame_host/navigation_before_commit_info.h" 10 #include "content/browser/frame_host/navigation_before_commit_info.h"
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 virtual void TearDown() OVERRIDE { 267 virtual void TearDown() OVERRIDE {
268 lifetime_checker_.reset(); 268 lifetime_checker_.reset();
269 RenderViewHostImplTestHarness::TearDown(); 269 RenderViewHostImplTestHarness::TearDown();
270 WebUIControllerFactory::UnregisterFactoryForTesting(&factory_); 270 WebUIControllerFactory::UnregisterFactoryForTesting(&factory_);
271 } 271 }
272 272
273 void set_should_create_webui(bool should_create_webui) { 273 void set_should_create_webui(bool should_create_webui) {
274 factory_.set_should_create_webui(should_create_webui); 274 factory_.set_should_create_webui(should_create_webui);
275 } 275 }
276 276
277 void StartCrossSiteTransition(TestWebContents* contents) {
278 std::vector<GURL> url_chain;
279 contents->GetRenderManagerForTesting()->OnCrossSiteResponse(
280 contents->GetRenderManagerForTesting()->pending_frame_host(),
281 GlobalRequestID(0, 0), scoped_ptr<CrossSiteTransferringRequest>(),
282 url_chain, Referrer(), PAGE_TRANSITION_TYPED, false);
283 EXPECT_TRUE(contents->cross_navigation_pending());
284 RenderViewHostImpl* rvh = contents->GetRenderViewHost();
285 EXPECT_EQ(RenderViewHostImpl::STATE_WAITING_FOR_UNLOAD_ACK,
286 rvh->rvh_state());
287 }
288
289 void NavigateActiveAndCommit(const GURL& url) { 277 void NavigateActiveAndCommit(const GURL& url) {
290 // Note: we navigate the active RenderViewHost because previous navigations 278 // Note: we navigate the active RenderFrameHost because previous navigations
291 // won't have committed yet, so NavigateAndCommit does the wrong thing 279 // won't have committed yet, so NavigateAndCommit does the wrong thing
292 // for us. 280 // for us.
293 controller().LoadURL(url, Referrer(), PAGE_TRANSITION_LINK, std::string()); 281 controller().LoadURL(url, Referrer(), PAGE_TRANSITION_LINK, std::string());
294 TestRenderViewHost* old_rvh = test_rvh(); 282 TestRenderViewHost* old_rvh = test_rvh();
295 283
296 // Simulate the BeforeUnload_ACK that is received from the current renderer 284 // Simulate the BeforeUnload_ACK that is received from the current renderer
297 // for a cross-site navigation. 285 // for a cross-site navigation.
298 if (old_rvh != active_rvh()) { 286 if (old_rvh != active_rvh()) {
299 old_rvh->SendBeforeUnloadACK(true); 287 old_rvh->SendBeforeUnloadACK(true);
300 EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT, old_rvh->rvh_state()); 288 EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT, old_rvh->rvh_state());
301 } 289 }
302 290
303 // Commit the navigation with a new page ID. 291 // Commit the navigation with a new page ID.
304 int32 max_page_id = contents()->GetMaxPageIDForSiteInstance( 292 int32 max_page_id = contents()->GetMaxPageIDForSiteInstance(
305 active_rvh()->GetSiteInstance()); 293 active_rvh()->GetSiteInstance());
306 294
307 // Simulate the response coming from the pending renderer.
308 if (old_rvh != active_rvh())
309 StartCrossSiteTransition(contents());
310
311 // Simulate the SwapOut_ACK that fires if you commit a cross-site
312 // navigation.
313 if (old_rvh != active_rvh()) {
314 old_rvh->OnSwappedOut(false);
315 EXPECT_EQ(RenderViewHostImpl::STATE_WAITING_FOR_COMMIT,
316 old_rvh->rvh_state());
317 }
318
319 // Use an observer to avoid accessing a deleted renderer later on when the 295 // Use an observer to avoid accessing a deleted renderer later on when the
320 // state is being checked. 296 // state is being checked.
321 RenderViewHostDeletedObserver rvh_observer(old_rvh); 297 RenderViewHostDeletedObserver rvh_observer(old_rvh);
322 active_test_rvh()->SendNavigate(max_page_id + 1, url); 298 active_test_rvh()->SendNavigate(max_page_id + 1, url);
323 299
324 if (old_rvh != active_rvh() && !rvh_observer.deleted()) 300 // Make sure that we start to run the unload handler at the time of commit.
325 EXPECT_TRUE(old_rvh->IsSwappedOut()); 301 bool expecting_rvh_shutdown = false;
302 if (old_rvh != active_rvh() && !rvh_observer.deleted()) {
303 if (!static_cast<SiteInstanceImpl*>(
304 old_rvh->GetSiteInstance())->active_view_count()) {
305 expecting_rvh_shutdown = true;
306 EXPECT_EQ(RenderViewHostImpl::STATE_PENDING_SHUTDOWN,
307 old_rvh->rvh_state());
308 } else {
309 EXPECT_EQ(RenderViewHostImpl::STATE_PENDING_SWAP_OUT,
310 old_rvh->rvh_state());
311 }
312 }
313
314 // Simulate the swap out ACK coming from the pending renderer. This should
315 // either shut down the old RVH or leave it in a swapped out state.
316 if (old_rvh != active_rvh()) {
317 old_rvh->OnSwappedOut(false);
318 if (expecting_rvh_shutdown) {
319 EXPECT_TRUE(rvh_observer.deleted());
320 } else {
321 EXPECT_EQ(RenderViewHostImpl::STATE_SWAPPED_OUT,
322 old_rvh->rvh_state());
323 }
324 }
326 } 325 }
327 326
328 bool ShouldSwapProcesses(RenderFrameHostManager* manager, 327 bool ShouldSwapProcesses(RenderFrameHostManager* manager,
329 const NavigationEntryImpl* current_entry, 328 const NavigationEntryImpl* current_entry,
330 const NavigationEntryImpl* new_entry) const { 329 const NavigationEntryImpl* new_entry) const {
331 CHECK(new_entry); 330 CHECK(new_entry);
332 BrowserContext* browser_context = 331 BrowserContext* browser_context =
333 manager->delegate_->GetControllerForRenderManager().GetBrowserContext(); 332 manager->delegate_->GetControllerForRenderManager().GetBrowserContext();
334 const GURL& current_effective_url = current_entry ? 333 const GURL& current_effective_url = current_entry ?
335 SiteInstanceImpl::GetEffectiveURL(browser_context, 334 SiteInstanceImpl::GetEffectiveURL(browser_context,
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 424
426 // The second one is the opposite, creating a cross-site transition and 425 // The second one is the opposite, creating a cross-site transition and
427 // requiring a beforeunload ack. 426 // requiring a beforeunload ack.
428 contents2->GetController().LoadURL( 427 contents2->GetController().LoadURL(
429 kDestUrl, Referrer(), PAGE_TRANSITION_LINK, std::string()); 428 kDestUrl, Referrer(), PAGE_TRANSITION_LINK, std::string());
430 EXPECT_TRUE(contents2->cross_navigation_pending()); 429 EXPECT_TRUE(contents2->cross_navigation_pending());
431 TestRenderFrameHost* dest_rfh2 = contents2->GetPendingMainFrame(); 430 TestRenderFrameHost* dest_rfh2 = contents2->GetPendingMainFrame();
432 ASSERT_TRUE(dest_rfh2); 431 ASSERT_TRUE(dest_rfh2);
433 432
434 ntp_rfh2->GetRenderViewHost()->SendBeforeUnloadACK(true); 433 ntp_rfh2->GetRenderViewHost()->SendBeforeUnloadACK(true);
435 StartCrossSiteTransition(contents2.get());
436 dest_rfh2->SendNavigate(101, kDestUrl); 434 dest_rfh2->SendNavigate(101, kDestUrl);
437 435
438 // The two RFH's should be different in every way. 436 // The two RFH's should be different in every way.
439 EXPECT_NE(contents()->GetMainFrame()->GetProcess(), dest_rfh2->GetProcess()); 437 EXPECT_NE(contents()->GetMainFrame()->GetProcess(), dest_rfh2->GetProcess());
440 EXPECT_NE(contents()->GetMainFrame()->GetSiteInstance(), 438 EXPECT_NE(contents()->GetMainFrame()->GetSiteInstance(),
441 dest_rfh2->GetSiteInstance()); 439 dest_rfh2->GetSiteInstance());
442 EXPECT_FALSE(dest_rfh2->GetSiteInstance()->IsRelatedSiteInstance( 440 EXPECT_FALSE(dest_rfh2->GetSiteInstance()->IsRelatedSiteInstance(
443 contents()->GetMainFrame()->GetSiteInstance())); 441 contents()->GetMainFrame()->GetSiteInstance()));
444 442
445 // Navigate both to the new tab page, and verify that they share a 443 // Navigate both to the new tab page, and verify that they share a
446 // RenderProcessHost (not a SiteInstance). 444 // RenderProcessHost (not a SiteInstance).
447 NavigateActiveAndCommit(kChromeUrl); 445 NavigateActiveAndCommit(kChromeUrl);
448 EXPECT_FALSE(contents()->GetPendingMainFrame()); 446 EXPECT_FALSE(contents()->GetPendingMainFrame());
449 447
450 contents2->GetController().LoadURL( 448 contents2->GetController().LoadURL(
451 kChromeUrl, Referrer(), PAGE_TRANSITION_LINK, std::string()); 449 kChromeUrl, Referrer(), PAGE_TRANSITION_LINK, std::string());
452 dest_rfh2->GetRenderViewHost()->SendBeforeUnloadACK(true); 450 dest_rfh2->GetRenderViewHost()->SendBeforeUnloadACK(true);
453 StartCrossSiteTransition(contents2.get());
454 contents2->GetPendingMainFrame()->SendNavigate(102, kChromeUrl); 451 contents2->GetPendingMainFrame()->SendNavigate(102, kChromeUrl);
455 452
456 EXPECT_NE(contents()->GetMainFrame()->GetSiteInstance(), 453 EXPECT_NE(contents()->GetMainFrame()->GetSiteInstance(),
457 contents2->GetMainFrame()->GetSiteInstance()); 454 contents2->GetMainFrame()->GetSiteInstance());
458 EXPECT_EQ(contents()->GetMainFrame()->GetSiteInstance()->GetProcess(), 455 EXPECT_EQ(contents()->GetMainFrame()->GetSiteInstance()->GetProcess(),
459 contents2->GetMainFrame()->GetSiteInstance()->GetProcess()); 456 contents2->GetMainFrame()->GetSiteInstance()->GetProcess());
460 } 457 }
461 458
462 // Ensure that the browser ignores most IPC messages that arrive from a 459 // Ensure that the browser ignores most IPC messages that arrive from a
463 // RenderViewHost that has been swapped out. We do not want to take 460 // RenderViewHost that has been swapped out. We do not want to take
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after
879 EXPECT_TRUE(static_cast<SiteInstanceImpl*>(host->GetSiteInstance())-> 876 EXPECT_TRUE(static_cast<SiteInstanceImpl*>(host->GetSiteInstance())->
880 HasSite()); 877 HasSite());
881 // Check the pending RenderFrameHost has been committed. 878 // Check the pending RenderFrameHost has been committed.
882 EXPECT_FALSE(manager->pending_frame_host()); 879 EXPECT_FALSE(manager->pending_frame_host());
883 880
884 // We should observe a notification. 881 // We should observe a notification.
885 EXPECT_TRUE( 882 EXPECT_TRUE(
886 notifications.Check1AndReset(NOTIFICATION_RENDER_VIEW_HOST_CHANGED)); 883 notifications.Check1AndReset(NOTIFICATION_RENDER_VIEW_HOST_CHANGED));
887 } 884 }
888 885
889 // Tests the Navigate function. In this unit test we verify that the Navigate
890 // function can handle a new navigation event before the previous navigation
891 // has been committed. This is also a regression test for
892 // http://crbug.com/104600.
893 TEST_F(RenderFrameHostManagerTest, NavigateWithEarlyReNavigation) {
894 TestNotificationTracker notifications;
895
896 SiteInstance* instance = SiteInstance::Create(browser_context());
897
898 scoped_ptr<TestWebContents> web_contents(
899 TestWebContents::Create(browser_context(), instance));
900 notifications.ListenFor(NOTIFICATION_RENDER_VIEW_HOST_CHANGED,
901 Source<WebContents>(web_contents.get()));
902
903 RenderFrameHostManager* manager = web_contents->GetRenderManagerForTesting();
904
905 // 1) The first navigation. --------------------------
906 const GURL kUrl1("http://www.google.com/");
907 NavigationEntryImpl entry1(NULL /* instance */, -1 /* page_id */, kUrl1,
908 Referrer(), base::string16() /* title */,
909 PAGE_TRANSITION_TYPED,
910 false /* is_renderer_init */);
911 RenderFrameHostImpl* host = manager->Navigate(entry1);
912
913 // The RenderFrameHost created in Init will be reused.
914 EXPECT_TRUE(host == manager->current_frame_host());
915 EXPECT_FALSE(manager->pending_frame_host());
916
917 // We should observe a notification.
918 EXPECT_TRUE(
919 notifications.Check1AndReset(NOTIFICATION_RENDER_VIEW_HOST_CHANGED));
920 notifications.Reset();
921
922 // Commit.
923 manager->DidNavigateFrame(host);
924
925 // Commit to SiteInstance should be delayed until RenderView commit.
926 EXPECT_TRUE(host == manager->current_frame_host());
927 ASSERT_TRUE(host);
928 EXPECT_FALSE(static_cast<SiteInstanceImpl*>(host->GetSiteInstance())->
929 HasSite());
930 static_cast<SiteInstanceImpl*>(host->GetSiteInstance())->SetSite(kUrl1);
931
932 // 2) Cross-site navigate to next site. -------------------------
933 const GURL kUrl2("http://www.example.com");
934 NavigationEntryImpl entry2(
935 NULL /* instance */, -1 /* page_id */, kUrl2, Referrer(),
936 base::string16() /* title */, PAGE_TRANSITION_TYPED,
937 false /* is_renderer_init */);
938 RenderFrameHostImpl* host2 = manager->Navigate(entry2);
939 int host2_process_id = host2->GetProcess()->GetID();
940
941 // A new RenderFrameHost should be created.
942 EXPECT_TRUE(manager->pending_frame_host());
943 ASSERT_EQ(host2, manager->pending_frame_host());
944 EXPECT_NE(host2, host);
945
946 // Check that the navigation is still suspended because the old RVH
947 // is not swapped out, yet.
948 EXPECT_TRUE(host2->are_navigations_suspended());
949 MockRenderProcessHost* test_process_host2 =
950 static_cast<MockRenderProcessHost*>(host2->GetProcess());
951 test_process_host2->sink().ClearMessages();
952 host2->render_view_host()->NavigateToURL(kUrl2);
953 EXPECT_FALSE(test_process_host2->sink().GetUniqueMessageMatching(
954 FrameMsg_Navigate::ID));
955
956 // Allow closing the current Render View (precondition for swapping out
957 // the RVH): Simulate response from RenderFrame for FrameMsg_BeforeUnload sent
958 // by DispatchBeforeUnload.
959 TestRenderViewHost* test_host =
960 static_cast<TestRenderViewHost*>(host->render_view_host());
961 MockRenderProcessHost* test_process_host =
962 static_cast<MockRenderProcessHost*>(test_host->GetProcess());
963 EXPECT_TRUE(test_process_host->sink().GetUniqueMessageMatching(
964 FrameMsg_BeforeUnload::ID));
965 test_host->SendBeforeUnloadACK(true);
966
967 // CrossSiteResourceHandler::StartCrossSiteTransition triggers a
968 // call of RenderFrameHostManager::SwapOutOldPage before
969 // RenderFrameHostManager::DidNavigateFrame is called.
970 // The RVH is swapped out after receiving the unload ack.
971 manager->SwapOutOldPage();
972 EXPECT_TRUE(test_process_host->sink().GetUniqueMessageMatching(
973 FrameMsg_SwapOut::ID));
974 test_host->OnSwappedOut(false);
975
976 EXPECT_EQ(host, manager->current_frame_host());
977 EXPECT_FALSE(manager->current_frame_host()->is_swapped_out());
978 EXPECT_EQ(host2, manager->pending_frame_host());
979 // There should be still no navigation messages being sent.
980 EXPECT_FALSE(test_process_host2->sink().GetUniqueMessageMatching(
981 FrameMsg_Navigate::ID));
982
983 // 3) Cross-site navigate to next site before 2) has committed. --------------
984 const GURL kUrl3("http://webkit.org/");
985 NavigationEntryImpl entry3(NULL /* instance */, -1 /* page_id */, kUrl3,
986 Referrer(), base::string16() /* title */,
987 PAGE_TRANSITION_TYPED,
988 false /* is_renderer_init */);
989 test_process_host->sink().ClearMessages();
990 RenderFrameHostImpl* host3 = manager->Navigate(entry3);
991
992 // A new RenderFrameHost should be created. host2 is now deleted.
993 EXPECT_TRUE(manager->pending_frame_host());
994 ASSERT_EQ(host3, manager->pending_frame_host());
995 EXPECT_NE(host3, host);
996 EXPECT_NE(host3->GetProcess()->GetID(), host2_process_id);
997
998 // Navigations in the new RFH should be suspended.
999 EXPECT_TRUE(host3->are_navigations_suspended());
1000 EXPECT_EQ(host, manager->current_frame_host());
1001 EXPECT_FALSE(manager->current_frame_host()->is_swapped_out());
1002
1003 // Simulate a response to the second beforeunload request.
1004 EXPECT_TRUE(test_process_host->sink().GetUniqueMessageMatching(
1005 FrameMsg_BeforeUnload::ID));
1006 test_host->SendBeforeUnloadACK(true);
1007
1008 // CrossSiteResourceHandler::StartCrossSiteTransition triggers a
1009 // call of RenderFrameHostManager::SwapOutOldPage before
1010 // RenderFrameHostManager::DidNavigateFrame is called. Since the previous
1011 // navigation has already caused the renderer to start swapping out, there
1012 // will be no more SwapOut messages being sent.
1013 manager->SwapOutOldPage();
1014 EXPECT_FALSE(test_process_host->sink().GetUniqueMessageMatching(
1015 FrameMsg_SwapOut::ID));
1016 test_host->OnSwappedOut(false);
1017
1018 // Commit.
1019 manager->DidNavigateFrame(host3);
1020 EXPECT_TRUE(host3 == manager->current_frame_host());
1021 ASSERT_TRUE(host3);
1022 EXPECT_TRUE(static_cast<SiteInstanceImpl*>(host3->GetSiteInstance())->
1023 HasSite());
1024 // Check the pending RenderFrameHost has been committed.
1025 EXPECT_FALSE(manager->pending_frame_host());
1026
1027 // We should observe a notification.
1028 EXPECT_TRUE(
1029 notifications.Check1AndReset(NOTIFICATION_RENDER_VIEW_HOST_CHANGED));
1030 }
1031
1032 // Test that navigation is not blocked when we make new navigation before
1033 // previous one has been committed. This is also a regression test for
1034 // http://crbug.com/104600.
1035 TEST_F(RenderFrameHostManagerTest, NewCrossNavigationBetweenSwapOutAndCommit) {
1036 const GURL kUrl1("http://www.google.com/");
1037 const GURL kUrl2("http://www.chromium.org/");
1038 const GURL kUrl3("http://www.youtube.com/");
1039
1040 contents()->NavigateAndCommit(kUrl1);
1041 TestRenderViewHost* rvh1 = test_rvh();
1042
1043 // Keep active_view_count nonzero so that no swapped out views in
1044 // this SiteInstance get forcefully deleted.
1045 static_cast<SiteInstanceImpl*>(rvh1->GetSiteInstance())->
1046 increment_active_view_count();
1047
1048 // Navigate but don't commit.
1049 contents()->GetController().LoadURL(
1050 kUrl2, Referrer(), PAGE_TRANSITION_LINK, std::string());
1051 EXPECT_TRUE(rvh1->is_waiting_for_beforeunload_ack());
1052 contents()->ProceedWithCrossSiteNavigation();
1053 EXPECT_FALSE(rvh1->is_waiting_for_beforeunload_ack());
1054 StartCrossSiteTransition(contents());
1055 EXPECT_TRUE(rvh1->IsWaitingForUnloadACK());
1056
1057 rvh1->OnSwappedOut(false);
1058 EXPECT_EQ(RenderViewHostImpl::STATE_WAITING_FOR_COMMIT, rvh1->rvh_state());
1059
1060 TestRenderViewHost* rvh2 = pending_test_rvh();
1061 EXPECT_TRUE(rvh2);
1062 static_cast<SiteInstanceImpl*>(rvh2->GetSiteInstance())->
1063 increment_active_view_count();
1064
1065 contents()->GetController().LoadURL(
1066 kUrl3, Referrer(), PAGE_TRANSITION_LINK, std::string());
1067 // Pending rvh2 is already deleted.
1068 contents()->ProceedWithCrossSiteNavigation();
1069
1070 TestRenderFrameHost* rfh3 = contents()->GetPendingMainFrame();
1071 EXPECT_TRUE(rfh3);
1072 // Navigation should be already unblocked by rvh1.
1073 EXPECT_FALSE(rfh3->are_navigations_suspended());
1074 }
1075
1076 // Tests WebUI creation. 886 // Tests WebUI creation.
1077 TEST_F(RenderFrameHostManagerTest, WebUI) { 887 TEST_F(RenderFrameHostManagerTest, WebUI) {
1078 set_should_create_webui(true); 888 set_should_create_webui(true);
1079 SiteInstance* instance = SiteInstance::Create(browser_context()); 889 SiteInstance* instance = SiteInstance::Create(browser_context());
1080 890
1081 scoped_ptr<TestWebContents> web_contents( 891 scoped_ptr<TestWebContents> web_contents(
1082 TestWebContents::Create(browser_context(), instance)); 892 TestWebContents::Create(browser_context(), instance));
1083 RenderFrameHostManager* manager = web_contents->GetRenderManagerForTesting(); 893 RenderFrameHostManager* manager = web_contents->GetRenderManagerForTesting();
1084 894
1085 EXPECT_FALSE(manager->current_host()->IsRenderViewLive()); 895 EXPECT_FALSE(manager->current_host()->IsRenderViewLive());
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
1255 static_cast<SiteInstanceImpl*>(rvh2->GetSiteInstance())-> 1065 static_cast<SiteInstanceImpl*>(rvh2->GetSiteInstance())->
1256 increment_active_view_count(); 1066 increment_active_view_count();
1257 1067
1258 // Now go back, but suppose the SwapOut_ACK isn't received. This shouldn't 1068 // Now go back, but suppose the SwapOut_ACK isn't received. This shouldn't
1259 // happen, but we have seen it when going back quickly across many entries 1069 // happen, but we have seen it when going back quickly across many entries
1260 // (http://crbug.com/93427). 1070 // (http://crbug.com/93427).
1261 contents()->GetController().GoBack(); 1071 contents()->GetController().GoBack();
1262 EXPECT_TRUE(rvh2->is_waiting_for_beforeunload_ack()); 1072 EXPECT_TRUE(rvh2->is_waiting_for_beforeunload_ack());
1263 contents()->ProceedWithCrossSiteNavigation(); 1073 contents()->ProceedWithCrossSiteNavigation();
1264 EXPECT_FALSE(rvh2->is_waiting_for_beforeunload_ack()); 1074 EXPECT_FALSE(rvh2->is_waiting_for_beforeunload_ack());
1265 StartCrossSiteTransition(contents());
1266 EXPECT_TRUE(rvh2->IsWaitingForUnloadACK());
1267 1075
1268 // The back navigation commits. 1076 // The back navigation commits.
1269 const NavigationEntry* entry1 = contents()->GetController().GetPendingEntry(); 1077 const NavigationEntry* entry1 = contents()->GetController().GetPendingEntry();
1270 rvh1->SendNavigate(entry1->GetPageID(), entry1->GetURL()); 1078 rvh1->SendNavigate(entry1->GetPageID(), entry1->GetURL());
1079 EXPECT_TRUE(rvh2->IsWaitingForUnloadACK());
1271 EXPECT_EQ(RenderViewHostImpl::STATE_PENDING_SWAP_OUT, rvh2->rvh_state()); 1080 EXPECT_EQ(RenderViewHostImpl::STATE_PENDING_SWAP_OUT, rvh2->rvh_state());
1272 1081
1273 // We should be able to navigate forward. 1082 // We should be able to navigate forward.
1274 contents()->GetController().GoForward(); 1083 contents()->GetController().GoForward();
1275 contents()->ProceedWithCrossSiteNavigation(); 1084 contents()->ProceedWithCrossSiteNavigation();
1276 StartCrossSiteTransition(contents());
1277 const NavigationEntry* entry2 = contents()->GetController().GetPendingEntry(); 1085 const NavigationEntry* entry2 = contents()->GetController().GetPendingEntry();
1278 rvh2->SendNavigate(entry2->GetPageID(), entry2->GetURL()); 1086 rvh2->SendNavigate(entry2->GetPageID(), entry2->GetURL());
1279 EXPECT_EQ(rvh2, rvh()); 1087 EXPECT_EQ(rvh2, rvh());
1280 EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT, rvh2->rvh_state()); 1088 EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT, rvh2->rvh_state());
1281 EXPECT_EQ(RenderViewHostImpl::STATE_PENDING_SWAP_OUT, rvh1->rvh_state()); 1089 EXPECT_EQ(RenderViewHostImpl::STATE_PENDING_SWAP_OUT, rvh1->rvh_state());
1282 rvh1->OnSwappedOut(false); 1090 rvh1->OnSwappedOut(false);
1283 EXPECT_TRUE(rvh1->IsSwappedOut()); 1091 EXPECT_TRUE(rvh1->IsSwappedOut());
1092 EXPECT_EQ(RenderViewHostImpl::STATE_SWAPPED_OUT, rvh1->rvh_state());
1284 } 1093 }
1285 1094
1286 // Test that we create swapped out RVHs for the opener chain when navigating an 1095 // Test that we create swapped out RVHs for the opener chain when navigating an
1287 // opened tab cross-process. This allows us to support certain cross-process 1096 // opened tab cross-process. This allows us to support certain cross-process
1288 // JavaScript calls (http://crbug.com/99202). 1097 // JavaScript calls (http://crbug.com/99202).
1289 TEST_F(RenderFrameHostManagerTest, CreateSwappedOutOpenerRVHs) { 1098 TEST_F(RenderFrameHostManagerTest, CreateSwappedOutOpenerRVHs) {
1290 const GURL kUrl1("http://www.google.com/"); 1099 const GURL kUrl1("http://www.google.com/");
1291 const GURL kUrl2("http://www.chromium.org/"); 1100 const GURL kUrl2("http://www.chromium.org/");
1292 const GURL kChromeUrl("chrome://foo"); 1101 const GURL kChromeUrl("chrome://foo");
1293 1102
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
1561 notifications.ListenFor(NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED, 1370 notifications.ListenFor(NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED,
1562 Source<RenderWidgetHost>(host2->render_view_host())); 1371 Source<RenderWidgetHost>(host2->render_view_host()));
1563 manager->OnBeforeUnloadACK(false, true, base::TimeTicks()); 1372 manager->OnBeforeUnloadACK(false, true, base::TimeTicks());
1564 1373
1565 EXPECT_TRUE( 1374 EXPECT_TRUE(
1566 notifications.Check1AndReset(NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED)); 1375 notifications.Check1AndReset(NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED));
1567 EXPECT_FALSE(manager->pending_frame_host()); 1376 EXPECT_FALSE(manager->pending_frame_host());
1568 EXPECT_EQ(host, manager->current_frame_host()); 1377 EXPECT_EQ(host, manager->current_frame_host());
1569 } 1378 }
1570 1379
1571 // Tests that the RenderViewHost is properly deleted when the SwapOutACK is 1380 // Tests that the RenderFrameHost is properly deleted when the SwapOutACK is
1572 // received before the new page commits. 1381 // received. (SwapOut and the corresponding ACK always occur after commit.)
1573 TEST_F(RenderFrameHostManagerTest, 1382 // Also tests that an early SwapOutACK is properly ignored.
1574 SwapOutACKBeforeNewPageCommitsLeadsToDeletion) { 1383 TEST_F(RenderFrameHostManagerTest, DeleteFrameAfterSwapOutACK) {
1575 const GURL kUrl1("http://www.google.com/"); 1384 const GURL kUrl1("http://www.google.com/");
1576 const GURL kUrl2("http://www.chromium.org/"); 1385 const GURL kUrl2("http://www.chromium.org/");
1577 1386
1578 // Navigate to the first page. 1387 // Navigate to the first page.
1579 contents()->NavigateAndCommit(kUrl1); 1388 contents()->NavigateAndCommit(kUrl1);
1580 TestRenderFrameHost* rfh1 = contents()->GetMainFrame(); 1389 TestRenderFrameHost* rfh1 = contents()->GetMainFrame();
1581 RenderViewHostDeletedObserver rvh_deleted_observer(rfh1->GetRenderViewHost()); 1390 RenderViewHostDeletedObserver rvh_deleted_observer(rfh1->GetRenderViewHost());
1582 EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT, 1391 EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT,
1583 rfh1->GetRenderViewHost()->rvh_state()); 1392 rfh1->GetRenderViewHost()->rvh_state());
1584 1393
1585 // Navigate to new site, simulating onbeforeunload approval. 1394 // Navigate to new site, simulating onbeforeunload approval.
1586 controller().LoadURL(kUrl2, Referrer(), PAGE_TRANSITION_LINK, std::string()); 1395 controller().LoadURL(kUrl2, Referrer(), PAGE_TRANSITION_LINK, std::string());
1587 base::TimeTicks now = base::TimeTicks::Now(); 1396 base::TimeTicks now = base::TimeTicks::Now();
1588 rfh1->OnMessageReceived(FrameHostMsg_BeforeUnload_ACK(0, true, now, now));
1589 EXPECT_TRUE(contents()->cross_navigation_pending());
1590 TestRenderFrameHost* rfh2 = contents()->GetPendingMainFrame();
1591
1592 // Simulate rfh2's response, which leads to an unload request being sent to
1593 // rfh1.
1594 std::vector<GURL> url_chain;
1595 url_chain.push_back(GURL());
1596 contents()->GetRenderManagerForTesting()->OnCrossSiteResponse(
1597 rfh2,
1598 GlobalRequestID(0, 0), scoped_ptr<CrossSiteTransferringRequest>(),
1599 url_chain, Referrer(), PAGE_TRANSITION_TYPED, false);
1600 EXPECT_TRUE(contents()->cross_navigation_pending());
1601 EXPECT_EQ(RenderViewHostImpl::STATE_WAITING_FOR_UNLOAD_ACK,
1602 rfh1->GetRenderViewHost()->rvh_state());
1603
1604 // Simulate the swap out ack.
1605 rfh1->OnSwappedOut(false);
1606 EXPECT_EQ(RenderViewHostImpl::STATE_WAITING_FOR_COMMIT,
1607 rfh1->GetRenderViewHost()->rvh_state());
1608
1609 // The new page commits.
1610 contents()->TestDidNavigate(rfh2, 1, kUrl2, PAGE_TRANSITION_TYPED);
1611 EXPECT_FALSE(contents()->cross_navigation_pending());
1612 EXPECT_EQ(rfh2, contents()->GetMainFrame());
1613 EXPECT_TRUE(contents()->GetPendingMainFrame() == NULL);
1614 EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT,
1615 rfh2->GetRenderViewHost()->rvh_state());
1616
1617 // rfh1's rvh should have been deleted.
1618 EXPECT_TRUE(rvh_deleted_observer.deleted());
1619 rfh1 = NULL;
1620 }
1621
1622 // Tests that the RenderViewHost is properly swapped out when the SwapOutACK is
1623 // received before the new page commits.
1624 TEST_F(RenderFrameHostManagerTest,
1625 SwapOutACKBeforeNewPageCommitsLeadsToSwapOut) {
1626 const GURL kUrl1("http://www.google.com/");
1627 const GURL kUrl2("http://www.chromium.org/");
1628
1629 // Navigate to the first page.
1630 contents()->NavigateAndCommit(kUrl1);
1631 TestRenderFrameHost* rfh1 = contents()->GetMainFrame();
1632 RenderViewHostDeletedObserver rvh_deleted_observer(rfh1->GetRenderViewHost());
1633 EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT,
1634 rfh1->GetRenderViewHost()->rvh_state());
1635
1636 // Increment the number of active views in SiteInstanceImpl so that rfh2 is
1637 // not deleted on swap out.
1638 static_cast<SiteInstanceImpl*>(
1639 rfh1->GetSiteInstance())->increment_active_view_count();
1640
1641 // Navigate to new site, simulating onbeforeunload approval.
1642 controller().LoadURL(kUrl2, Referrer(), PAGE_TRANSITION_LINK, std::string());
1643 base::TimeTicks now = base::TimeTicks::Now();
1644 contents()->GetMainFrame()->OnMessageReceived( 1397 contents()->GetMainFrame()->OnMessageReceived(
1645 FrameHostMsg_BeforeUnload_ACK(0, true, now, now)); 1398 FrameHostMsg_BeforeUnload_ACK(0, true, now, now));
1646 EXPECT_TRUE(contents()->cross_navigation_pending()); 1399 EXPECT_TRUE(contents()->cross_navigation_pending());
1400 EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT,
1401 rfh1->GetRenderViewHost()->rvh_state());
1647 TestRenderFrameHost* rfh2 = contents()->GetPendingMainFrame(); 1402 TestRenderFrameHost* rfh2 = contents()->GetPendingMainFrame();
1648 1403
1649 // Simulate rfh2's response, which leads to an unload request being sent to 1404 // Simulate the swap out ack, unexpectedly early (before commit). It should
1650 // rfh1. 1405 // have no effect.
1651 std::vector<GURL> url_chain; 1406 rfh1->OnSwappedOut(false);
1652 url_chain.push_back(GURL());
1653 contents()->GetRenderManagerForTesting()->OnCrossSiteResponse(
1654 rfh2,
1655 GlobalRequestID(0, 0), scoped_ptr<CrossSiteTransferringRequest>(),
1656 url_chain, Referrer(), PAGE_TRANSITION_TYPED, false);
1657 EXPECT_TRUE(contents()->cross_navigation_pending()); 1407 EXPECT_TRUE(contents()->cross_navigation_pending());
1658 EXPECT_EQ(RenderViewHostImpl::STATE_WAITING_FOR_UNLOAD_ACK, 1408 EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT,
1659 rfh1->GetRenderViewHost()->rvh_state());
1660
1661 // Simulate the swap out ack.
1662 rfh1->OnSwappedOut(false);
1663 EXPECT_EQ(RenderViewHostImpl::STATE_WAITING_FOR_COMMIT,
1664 rfh1->GetRenderViewHost()->rvh_state()); 1409 rfh1->GetRenderViewHost()->rvh_state());
1665 1410
1666 // The new page commits. 1411 // The new page commits.
1667 contents()->TestDidNavigate(rfh2, 1, kUrl2, PAGE_TRANSITION_TYPED);
1668 EXPECT_FALSE(contents()->cross_navigation_pending());
1669 EXPECT_EQ(rfh2, contents()->GetMainFrame());
1670 EXPECT_TRUE(contents()->GetPendingMainFrame() == NULL);
1671 EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT,
1672 rfh2->GetRenderViewHost()->rvh_state());
1673
1674 // rfh1 should be swapped out.
1675 EXPECT_FALSE(rvh_deleted_observer.deleted());
1676 EXPECT_TRUE(rfh1->GetRenderViewHost()->IsSwappedOut());
1677 }
1678
1679 // Tests that the RenderViewHost is properly deleted when the new
1680 // page commits before the swap out ack is received.
1681 TEST_F(RenderFrameHostManagerTest,
1682 NewPageCommitsBeforeSwapOutACKLeadsToDeletion) {
1683 const GURL kUrl1("http://www.google.com/");
1684 const GURL kUrl2("http://www.chromium.org/");
1685
1686 // Navigate to the first page.
1687 contents()->NavigateAndCommit(kUrl1);
1688 TestRenderFrameHost* rfh1 = contents()->GetMainFrame();
1689 RenderViewHostDeletedObserver rvh_deleted_observer(rfh1->GetRenderViewHost());
1690 EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT,
1691 rfh1->GetRenderViewHost()->rvh_state());
1692
1693 // Navigate to new site, simulating onbeforeunload approval.
1694 controller().LoadURL(kUrl2, Referrer(), PAGE_TRANSITION_LINK, std::string());
1695 base::TimeTicks now = base::TimeTicks::Now();
1696 contents()->GetMainFrame()->OnMessageReceived(
1697 FrameHostMsg_BeforeUnload_ACK(0, true, now, now));
1698 EXPECT_TRUE(contents()->cross_navigation_pending());
1699 TestRenderFrameHost* rfh2 = contents()->GetPendingMainFrame();
1700
1701 // Simulate rfh2's response, which leads to an unload request being sent to
1702 // rfh1.
1703 std::vector<GURL> url_chain;
1704 url_chain.push_back(GURL());
1705 contents()->GetRenderManagerForTesting()->OnCrossSiteResponse(
1706 rfh2,
1707 GlobalRequestID(0, 0), scoped_ptr<CrossSiteTransferringRequest>(),
1708 url_chain, Referrer(), PAGE_TRANSITION_TYPED, false);
1709 EXPECT_TRUE(contents()->cross_navigation_pending());
1710 EXPECT_EQ(RenderViewHostImpl::STATE_WAITING_FOR_UNLOAD_ACK,
1711 rfh1->GetRenderViewHost()->rvh_state());
1712
1713 // The new page commits.
1714 contents()->TestDidNavigate(rfh2, 1, kUrl2, PAGE_TRANSITION_TYPED); 1412 contents()->TestDidNavigate(rfh2, 1, kUrl2, PAGE_TRANSITION_TYPED);
1715 EXPECT_FALSE(contents()->cross_navigation_pending()); 1413 EXPECT_FALSE(contents()->cross_navigation_pending());
1716 EXPECT_EQ(rfh2, contents()->GetMainFrame()); 1414 EXPECT_EQ(rfh2, contents()->GetMainFrame());
1717 EXPECT_TRUE(contents()->GetPendingMainFrame() == NULL); 1415 EXPECT_TRUE(contents()->GetPendingMainFrame() == NULL);
1718 EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT, 1416 EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT,
1719 rfh2->GetRenderViewHost()->rvh_state()); 1417 rfh2->GetRenderViewHost()->rvh_state());
1720 EXPECT_EQ(RenderViewHostImpl::STATE_PENDING_SHUTDOWN, 1418 EXPECT_EQ(RenderViewHostImpl::STATE_PENDING_SHUTDOWN,
1721 rfh1->GetRenderViewHost()->rvh_state()); 1419 rfh1->GetRenderViewHost()->rvh_state());
1722 1420
1723 // Simulate the swap out ack. 1421 // Simulate the swap out ack.
1724 rfh1->OnSwappedOut(false); 1422 rfh1->OnSwappedOut(false);
1725 1423
1726 // rfh1 should have been deleted. 1424 // rfh1 should have been deleted.
1727 EXPECT_TRUE(rvh_deleted_observer.deleted()); 1425 EXPECT_TRUE(rvh_deleted_observer.deleted());
1728 rfh1 = NULL; 1426 rfh1 = NULL;
1729 } 1427 }
1730 1428
1731 // Tests that the RenderViewHost is properly swapped out when the new page 1429 // Tests that the RenderFrameHost is properly swapped out when the SwapOut ACK
1732 // commits before the swap out ack is received. 1430 // is received. (SwapOut and the corresponding ACK always occur after commit.)
1733 TEST_F(RenderFrameHostManagerTest, 1431 TEST_F(RenderFrameHostManagerTest, SwapOutFrameAfterSwapOutACK) {
1734 NewPageCommitsBeforeSwapOutACKLeadsToSwapOut) {
1735 const GURL kUrl1("http://www.google.com/"); 1432 const GURL kUrl1("http://www.google.com/");
1736 const GURL kUrl2("http://www.chromium.org/"); 1433 const GURL kUrl2("http://www.chromium.org/");
1737 1434
1738 // Navigate to the first page. 1435 // Navigate to the first page.
1739 contents()->NavigateAndCommit(kUrl1); 1436 contents()->NavigateAndCommit(kUrl1);
1740 TestRenderFrameHost* rfh1 = contents()->GetMainFrame(); 1437 TestRenderFrameHost* rfh1 = contents()->GetMainFrame();
1741 RenderViewHostDeletedObserver rvh_deleted_observer(rfh1->GetRenderViewHost()); 1438 RenderViewHostDeletedObserver rvh_deleted_observer(rfh1->GetRenderViewHost());
1742 EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT, 1439 EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT,
1743 rfh1->GetRenderViewHost()->rvh_state()); 1440 rfh1->GetRenderViewHost()->rvh_state());
1744 1441
1745 // Increment the number of active views in SiteInstanceImpl so that rfh1 is 1442 // Increment the number of active views in SiteInstanceImpl so that rfh1 is
1746 // not deleted on swap out. 1443 // not deleted on swap out.
1747 static_cast<SiteInstanceImpl*>( 1444 static_cast<SiteInstanceImpl*>(
1748 rfh1->GetSiteInstance())->increment_active_view_count(); 1445 rfh1->GetSiteInstance())->increment_active_view_count();
1749 1446
1750 // Navigate to new site, simulating onbeforeunload approval. 1447 // Navigate to new site, simulating onbeforeunload approval.
1751 controller().LoadURL(kUrl2, Referrer(), PAGE_TRANSITION_LINK, std::string()); 1448 controller().LoadURL(kUrl2, Referrer(), PAGE_TRANSITION_LINK, std::string());
1752 base::TimeTicks now = base::TimeTicks::Now(); 1449 base::TimeTicks now = base::TimeTicks::Now();
1753 contents()->GetMainFrame()->OnMessageReceived( 1450 contents()->GetMainFrame()->OnMessageReceived(
1754 FrameHostMsg_BeforeUnload_ACK(0, true, now, now)); 1451 FrameHostMsg_BeforeUnload_ACK(0, true, now, now));
1755 EXPECT_TRUE(contents()->cross_navigation_pending()); 1452 EXPECT_TRUE(contents()->cross_navigation_pending());
1453 EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT,
1454 rfh1->GetRenderViewHost()->rvh_state());
1756 TestRenderFrameHost* rfh2 = contents()->GetPendingMainFrame(); 1455 TestRenderFrameHost* rfh2 = contents()->GetPendingMainFrame();
1757 1456
1758 // Simulate rfh2's response, which leads to an unload request being sent to
1759 // rfh1.
1760 std::vector<GURL> url_chain;
1761 url_chain.push_back(GURL());
1762 contents()->GetRenderManagerForTesting()->OnCrossSiteResponse(
1763 rfh2,
1764 GlobalRequestID(0, 0), scoped_ptr<CrossSiteTransferringRequest>(),
1765 url_chain, Referrer(), PAGE_TRANSITION_TYPED, false);
1766 EXPECT_TRUE(contents()->cross_navigation_pending());
1767 EXPECT_EQ(RenderViewHostImpl::STATE_WAITING_FOR_UNLOAD_ACK,
1768 rfh1->GetRenderViewHost()->rvh_state());
1769
1770 // The new page commits. 1457 // The new page commits.
1771 contents()->TestDidNavigate(rfh2, 1, kUrl2, PAGE_TRANSITION_TYPED); 1458 contents()->TestDidNavigate(rfh2, 1, kUrl2, PAGE_TRANSITION_TYPED);
1772 EXPECT_FALSE(contents()->cross_navigation_pending()); 1459 EXPECT_FALSE(contents()->cross_navigation_pending());
1773 EXPECT_EQ(rfh2, contents()->GetMainFrame()); 1460 EXPECT_EQ(rfh2, contents()->GetMainFrame());
1774 EXPECT_TRUE(contents()->GetPendingMainFrame() == NULL); 1461 EXPECT_TRUE(contents()->GetPendingMainFrame() == NULL);
1775 EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT, 1462 EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT,
1776 rfh2->GetRenderViewHost()->rvh_state()); 1463 rfh2->GetRenderViewHost()->rvh_state());
1777 EXPECT_EQ(RenderViewHostImpl::STATE_PENDING_SWAP_OUT, 1464 EXPECT_EQ(RenderViewHostImpl::STATE_PENDING_SWAP_OUT,
1778 rfh1->GetRenderViewHost()->rvh_state()); 1465 rfh1->GetRenderViewHost()->rvh_state());
1779 1466
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
1977 ASSERT_TRUE(main_request); 1664 ASSERT_TRUE(main_request);
1978 1665
1979 NavigationBeforeCommitInfo commit_info; 1666 NavigationBeforeCommitInfo commit_info;
1980 commit_info.navigation_url = kUrl2; 1667 commit_info.navigation_url = kUrl2;
1981 render_manager->CommitNavigation(commit_info); 1668 render_manager->CommitNavigation(commit_info);
1982 main_request = GetNavigationRequestForRenderFrameManager(render_manager); 1669 main_request = GetNavigationRequestForRenderFrameManager(render_manager);
1983 EXPECT_NE(main_test_rfh(), rfh); 1670 EXPECT_NE(main_test_rfh(), rfh);
1984 } 1671 }
1985 1672
1986 } // namespace content 1673 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/frame_host/render_frame_host_manager.cc ('k') | content/browser/loader/cross_site_resource_handler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698