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

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

Issue 88503002: Have the unload event execute in background on cross-site navigations (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressed Nasko's comments Created 6 years, 10 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/strings/utf_string_conversions.h" 5 #include "base/strings/utf_string_conversions.h"
6 #include "content/browser/frame_host/navigation_controller_impl.h" 6 #include "content/browser/frame_host/navigation_controller_impl.h"
7 #include "content/browser/frame_host/navigation_entry_impl.h" 7 #include "content/browser/frame_host/navigation_entry_impl.h"
8 #include "content/browser/frame_host/render_frame_host_manager.h" 8 #include "content/browser/frame_host/render_frame_host_manager.h"
9 #include "content/browser/site_instance_impl.h" 9 #include "content/browser/site_instance_impl.h"
10 #include "content/browser/webui/web_ui_controller_factory_registry.h" 10 #include "content/browser/webui/web_ui_controller_factory_registry.h"
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 increment_active_view_count(); 162 increment_active_view_count();
163 163
164 TestRenderViewHost* dest_rvh = static_cast<TestRenderViewHost*>( 164 TestRenderViewHost* dest_rvh = static_cast<TestRenderViewHost*>(
165 contents()->GetRenderManagerForTesting()->pending_render_view_host()); 165 contents()->GetRenderManagerForTesting()->pending_render_view_host());
166 CHECK(dest_rvh); 166 CHECK(dest_rvh);
167 EXPECT_NE(ntp_rvh, dest_rvh); 167 EXPECT_NE(ntp_rvh, dest_rvh);
168 168
169 // BeforeUnload finishes. 169 // BeforeUnload finishes.
170 ntp_rvh->SendShouldCloseACK(true); 170 ntp_rvh->SendShouldCloseACK(true);
171 171
172 // Assume SwapOutACK times out, so the dest_rvh proceeds and commits.
173 dest_rvh->SendNavigate(101, kDestUrl); 172 dest_rvh->SendNavigate(101, kDestUrl);
173 ntp_rvh->OnSwappedOut(false);
174 174
175 EXPECT_TRUE(ntp_rvh->is_swapped_out()); 175 EXPECT_EQ(RenderViewHostImpl::STATE_SWAPPED_OUT, ntp_rvh->rvh_state());
176 return ntp_rvh; 176 return ntp_rvh;
177 } 177 }
178 178
179 private: 179 private:
180 RenderFrameHostManagerTestWebUIControllerFactory factory_; 180 RenderFrameHostManagerTestWebUIControllerFactory factory_;
181 }; 181 };
182 182
183 // Tests that when you navigate from a chrome:// url to another page, and 183 // Tests that when you navigate from a chrome:// url to another page, and
184 // then do that same thing in another tab, that the two resulting pages have 184 // then do that same thing in another tab, that the two resulting pages have
185 // different SiteInstances, BrowsingInstances, and RenderProcessHosts. This is 185 // different SiteInstances, BrowsingInstances, and RenderProcessHosts. This is
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 289
290 // The new RVH should be able to update its title. 290 // The new RVH should be able to update its title.
291 const base::string16 dest_title = base::ASCIIToUTF16("Google"); 291 const base::string16 dest_title = base::ASCIIToUTF16("Google");
292 EXPECT_TRUE(dest_rvh->OnMessageReceived( 292 EXPECT_TRUE(dest_rvh->OnMessageReceived(
293 ViewHostMsg_UpdateTitle(rvh()->GetRoutingID(), 101, dest_title, 293 ViewHostMsg_UpdateTitle(rvh()->GetRoutingID(), 101, dest_title,
294 direction))); 294 direction)));
295 EXPECT_EQ(dest_title, contents()->GetTitle()); 295 EXPECT_EQ(dest_title, contents()->GetTitle());
296 296
297 // The old renderer, being slow, now updates the title. It should be filtered 297 // The old renderer, being slow, now updates the title. It should be filtered
298 // out and not take effect. 298 // out and not take effect.
299 EXPECT_TRUE(ntp_rvh->is_swapped_out()); 299 EXPECT_EQ(RenderViewHostImpl::STATE_PENDING_SWAP_OUT, ntp_rvh->rvh_state());
300 EXPECT_TRUE(ntp_rvh->OnMessageReceived( 300 EXPECT_TRUE(ntp_rvh->OnMessageReceived(
301 ViewHostMsg_UpdateTitle(rvh()->GetRoutingID(), 0, ntp_title, direction))); 301 ViewHostMsg_UpdateTitle(rvh()->GetRoutingID(), 0, ntp_title, direction)));
302 EXPECT_EQ(dest_title, contents()->GetTitle()); 302 EXPECT_EQ(dest_title, contents()->GetTitle());
303 303
304 // We cannot filter out synchronous IPC messages, because the renderer would 304 // We cannot filter out synchronous IPC messages, because the renderer would
305 // be left waiting for a reply. We pick RunBeforeUnloadConfirm as an example 305 // be left waiting for a reply. We pick RunBeforeUnloadConfirm as an example
306 // that can run easily within a unit test, and that needs to receive a reply 306 // that can run easily within a unit test, and that needs to receive a reply
307 // without showing an actual dialog. 307 // without showing an actual dialog.
308 MockRenderProcessHost* ntp_process_host = 308 MockRenderProcessHost* ntp_process_host =
309 static_cast<MockRenderProcessHost*>(ntp_rvh->GetProcess()); 309 static_cast<MockRenderProcessHost*>(ntp_rvh->GetProcess());
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 ViewHostMsg_DidActivateAcceleratedCompositing msg( 354 ViewHostMsg_DidActivateAcceleratedCompositing msg(
355 rvh()->GetRoutingID(), true); 355 rvh()->GetRoutingID(), true);
356 EXPECT_TRUE(swapped_out_rvh->OnMessageReceived(msg)); 356 EXPECT_TRUE(swapped_out_rvh->OnMessageReceived(msg));
357 EXPECT_TRUE(swapped_out_rvh->is_accelerated_compositing_active()); 357 EXPECT_TRUE(swapped_out_rvh->is_accelerated_compositing_active());
358 } 358 }
359 359
360 // Test if RenderViewHost::GetRenderWidgetHosts() only returns active 360 // Test if RenderViewHost::GetRenderWidgetHosts() only returns active
361 // widgets. 361 // widgets.
362 TEST_F(RenderFrameHostManagerTest, GetRenderWidgetHostsReturnsActiveViews) { 362 TEST_F(RenderFrameHostManagerTest, GetRenderWidgetHostsReturnsActiveViews) {
363 TestRenderViewHost* swapped_out_rvh = CreateSwappedOutRenderViewHost(); 363 TestRenderViewHost* swapped_out_rvh = CreateSwappedOutRenderViewHost();
364 EXPECT_TRUE(swapped_out_rvh->is_swapped_out()); 364 EXPECT_EQ(RenderViewHostImpl::STATE_SWAPPED_OUT,
365 swapped_out_rvh->rvh_state());
365 366
366 scoped_ptr<RenderWidgetHostIterator> widgets( 367 scoped_ptr<RenderWidgetHostIterator> widgets(
367 RenderWidgetHost::GetRenderWidgetHosts()); 368 RenderWidgetHost::GetRenderWidgetHosts());
368 // We know that there is the only one active widget. Another view is 369 // We know that there is the only one active widget. Another view is
369 // now swapped out, so the swapped out view is not included in the 370 // now swapped out, so the swapped out view is not included in the
370 // list. 371 // list.
371 RenderWidgetHost* widget = widgets->GetNextHost(); 372 RenderWidgetHost* widget = widgets->GetNextHost();
372 EXPECT_FALSE(widgets->GetNextHost()); 373 EXPECT_FALSE(widgets->GetNextHost());
373 RenderViewHost* rvh = RenderViewHost::From(widget); 374 RenderViewHost* rvh = RenderViewHost::From(widget);
374 EXPECT_FALSE(static_cast<RenderViewHostImpl*>(rvh)->is_swapped_out()); 375 EXPECT_EQ(RenderViewHostImpl::STATE_LIVE,
376 static_cast<RenderViewHostImpl*>(rvh)->rvh_state());
375 } 377 }
376 378
377 // Test if RenderViewHost::GetRenderWidgetHosts() returns a subset of 379 // Test if RenderViewHost::GetRenderWidgetHosts() returns a subset of
378 // RenderViewHostImpl::GetAllRenderWidgetHosts(). 380 // RenderViewHostImpl::GetAllRenderWidgetHosts().
379 // RenderViewHost::GetRenderWidgetHosts() returns only active widgets, but 381 // RenderViewHost::GetRenderWidgetHosts() returns only active widgets, but
380 // RenderViewHostImpl::GetAllRenderWidgetHosts() returns everything 382 // RenderViewHostImpl::GetAllRenderWidgetHosts() returns everything
381 // including swapped out ones. 383 // including swapped out ones.
382 TEST_F(RenderFrameHostManagerTest, 384 TEST_F(RenderFrameHostManagerTest,
383 GetRenderWidgetHostsWithinGetAllRenderWidgetHosts) { 385 GetRenderWidgetHostsWithinGetAllRenderWidgetHosts) {
384 TestRenderViewHost* swapped_out_rvh = CreateSwappedOutRenderViewHost(); 386 TestRenderViewHost* swapped_out_rvh = CreateSwappedOutRenderViewHost();
385 EXPECT_TRUE(swapped_out_rvh->is_swapped_out()); 387 EXPECT_EQ(RenderViewHostImpl::STATE_SWAPPED_OUT,
388 swapped_out_rvh->rvh_state());
386 389
387 scoped_ptr<RenderWidgetHostIterator> widgets( 390 scoped_ptr<RenderWidgetHostIterator> widgets(
388 RenderWidgetHost::GetRenderWidgetHosts()); 391 RenderWidgetHost::GetRenderWidgetHosts());
389 392
390 while (RenderWidgetHost* w = widgets->GetNextHost()) { 393 while (RenderWidgetHost* w = widgets->GetNextHost()) {
391 bool found = false; 394 bool found = false;
392 scoped_ptr<RenderWidgetHostIterator> all_widgets( 395 scoped_ptr<RenderWidgetHostIterator> all_widgets(
393 RenderWidgetHostImpl::GetAllRenderWidgetHosts()); 396 RenderWidgetHostImpl::GetAllRenderWidgetHosts());
394 while (RenderWidgetHost* widget = all_widgets->GetNextHost()) { 397 while (RenderWidgetHost* widget = all_widgets->GetNextHost()) {
395 if (w == widget) { 398 if (w == widget) {
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after
761 static_cast<TestRenderViewHost*>(host->render_view_host()); 764 static_cast<TestRenderViewHost*>(host->render_view_host());
762 MockRenderProcessHost* test_process_host = 765 MockRenderProcessHost* test_process_host =
763 static_cast<MockRenderProcessHost*>(test_host->GetProcess()); 766 static_cast<MockRenderProcessHost*>(test_host->GetProcess());
764 EXPECT_TRUE(test_process_host->sink().GetUniqueMessageMatching( 767 EXPECT_TRUE(test_process_host->sink().GetUniqueMessageMatching(
765 ViewMsg_ShouldClose::ID)); 768 ViewMsg_ShouldClose::ID));
766 test_host->SendShouldCloseACK(true); 769 test_host->SendShouldCloseACK(true);
767 770
768 // CrossSiteResourceHandler::StartCrossSiteTransition triggers a 771 // CrossSiteResourceHandler::StartCrossSiteTransition triggers a
769 // call of RenderFrameHostManager::SwapOutOldPage before 772 // call of RenderFrameHostManager::SwapOutOldPage before
770 // RenderFrameHostManager::DidNavigateMainFrame is called. 773 // RenderFrameHostManager::DidNavigateMainFrame is called.
771 // The RVH is not swapped out until the commit. 774 // The RVH is swapped out after receiving the unload ack.
772 manager->SwapOutOldPage(); 775 manager->SwapOutOldPage();
773 EXPECT_TRUE(test_process_host->sink().GetUniqueMessageMatching( 776 EXPECT_TRUE(test_process_host->sink().GetUniqueMessageMatching(
774 ViewMsg_SwapOut::ID)); 777 ViewMsg_SwapOut::ID));
775 test_host->OnSwappedOut(false); 778 test_host->OnSwappedOut(false);
776 779
777 EXPECT_EQ(host, manager->current_frame_host()); 780 EXPECT_EQ(host, manager->current_frame_host());
778 EXPECT_FALSE(manager->current_frame_host()->is_swapped_out()); 781 EXPECT_FALSE(manager->current_frame_host()->is_swapped_out());
779 EXPECT_EQ(host2, manager->pending_frame_host()); 782 EXPECT_EQ(host2, manager->pending_frame_host());
780 // There should be still no navigation messages being sent. 783 // There should be still no navigation messages being sent.
781 EXPECT_FALSE(test_process_host2->sink().GetUniqueMessageMatching( 784 EXPECT_FALSE(test_process_host2->sink().GetUniqueMessageMatching(
782 ViewMsg_Navigate::ID)); 785 ViewMsg_Navigate::ID));
783 786
784 // 3) Cross-site navigate to next site before 2) has committed. -------------- 787 // 3) Cross-site navigate to next site before 2) has committed. --------------
785 const GURL kUrl3("http://webkit.org/"); 788 const GURL kUrl3("http://webkit.org/");
786 NavigationEntryImpl entry3(NULL /* instance */, -1 /* page_id */, kUrl3, 789 NavigationEntryImpl entry3(NULL /* instance */, -1 /* page_id */, kUrl3,
787 Referrer(), base::string16() /* title */, 790 Referrer(), base::string16() /* title */,
788 PAGE_TRANSITION_TYPED, 791 PAGE_TRANSITION_TYPED,
789 false /* is_renderer_init */); 792 false /* is_renderer_init */);
790 test_process_host->sink().ClearMessages(); 793 test_process_host->sink().ClearMessages();
791 RenderFrameHostImpl* host3 = manager->Navigate(entry3); 794 RenderFrameHostImpl* host3 = manager->Navigate(entry3);
792 795
793 // A new RenderFrameHost should be created. host2 is now deleted. 796 // A new RenderFrameHost should be created. host2 is now deleted.
794 EXPECT_TRUE(manager->pending_frame_host()); 797 EXPECT_TRUE(manager->pending_frame_host());
795 ASSERT_EQ(host3, manager->pending_frame_host()); 798 ASSERT_EQ(host3, manager->pending_frame_host());
796 EXPECT_NE(host3, host); 799 EXPECT_NE(host3, host);
797 EXPECT_NE(host3->GetProcess()->GetID(), host2_process_id); 800 EXPECT_NE(host3->GetProcess()->GetID(), host2_process_id);
798 801
799 // Navigations in the new RVH should be suspended, which is ok because the 802 // Navigations in the new RVH should be suspended.
800 // old RVH is not yet swapped out and can respond to a second beforeunload
801 // request.
802 EXPECT_TRUE(static_cast<RenderViewHostImpl*>( 803 EXPECT_TRUE(static_cast<RenderViewHostImpl*>(
803 host3->render_view_host())->are_navigations_suspended()); 804 host3->render_view_host())->are_navigations_suspended());
804 EXPECT_EQ(host, manager->current_frame_host()); 805 EXPECT_EQ(host, manager->current_frame_host());
805 EXPECT_FALSE(manager->current_frame_host()->is_swapped_out()); 806 EXPECT_FALSE(manager->current_frame_host()->is_swapped_out());
806 807
807 // Simulate a response to the second beforeunload request. 808 // Simulate a response to the second beforeunload request.
808 EXPECT_TRUE(test_process_host->sink().GetUniqueMessageMatching( 809 EXPECT_TRUE(test_process_host->sink().GetUniqueMessageMatching(
809 ViewMsg_ShouldClose::ID)); 810 ViewMsg_ShouldClose::ID));
810 test_host->SendShouldCloseACK(true); 811 test_host->SendShouldCloseACK(true);
811 812
812 // CrossSiteResourceHandler::StartCrossSiteTransition triggers a 813 // CrossSiteResourceHandler::StartCrossSiteTransition triggers a
813 // call of RenderFrameHostManager::SwapOutOldPage before 814 // call of RenderFrameHostManager::SwapOutOldPage before
814 // RenderFrameHostManager::DidNavigateMainFrame is called. 815 // RenderFrameHostManager::DidNavigateMainFrame is called.
815 // The RVH is not swapped out until the commit.
816 manager->SwapOutOldPage(); 816 manager->SwapOutOldPage();
817 EXPECT_TRUE(test_process_host->sink().GetUniqueMessageMatching( 817 EXPECT_TRUE(test_process_host->sink().GetUniqueMessageMatching(
818 ViewMsg_SwapOut::ID)); 818 ViewMsg_SwapOut::ID));
819 test_host->OnSwappedOut(false); 819 test_host->OnSwappedOut(false);
820 820
821 // Commit. 821 // Commit.
822 manager->DidNavigateMainFrame(host3->render_view_host()); 822 manager->DidNavigateMainFrame(host3->render_view_host());
823 EXPECT_TRUE(host3 == manager->current_frame_host()); 823 EXPECT_TRUE(host3 == manager->current_frame_host());
824 ASSERT_TRUE(host3); 824 ASSERT_TRUE(host3);
825 EXPECT_TRUE(static_cast<SiteInstanceImpl*>(host3->GetSiteInstance())-> 825 EXPECT_TRUE(static_cast<SiteInstanceImpl*>(host3->GetSiteInstance())->
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
1018 increment_active_view_count(); 1018 increment_active_view_count();
1019 1019
1020 // Now go back, but suppose the SwapOut_ACK isn't received. This shouldn't 1020 // Now go back, but suppose the SwapOut_ACK isn't received. This shouldn't
1021 // happen, but we have seen it when going back quickly across many entries 1021 // happen, but we have seen it when going back quickly across many entries
1022 // (http://crbug.com/93427). 1022 // (http://crbug.com/93427).
1023 contents()->GetController().GoBack(); 1023 contents()->GetController().GoBack();
1024 EXPECT_TRUE(rvh2->is_waiting_for_beforeunload_ack()); 1024 EXPECT_TRUE(rvh2->is_waiting_for_beforeunload_ack());
1025 contents()->ProceedWithCrossSiteNavigation(); 1025 contents()->ProceedWithCrossSiteNavigation();
1026 EXPECT_FALSE(rvh2->is_waiting_for_beforeunload_ack()); 1026 EXPECT_FALSE(rvh2->is_waiting_for_beforeunload_ack());
1027 rvh2->SwapOut(); 1027 rvh2->SwapOut();
1028 EXPECT_TRUE(rvh2->is_waiting_for_unload_ack()); 1028 EXPECT_TRUE(rvh2->IsWaitingForUnloadACK());
1029 1029
1030 // The back navigation commits. We should proactively clear the 1030 // The back navigation commits.
1031 // is_waiting_for_unload_ack state to be safe.
1032 const NavigationEntry* entry1 = contents()->GetController().GetPendingEntry(); 1031 const NavigationEntry* entry1 = contents()->GetController().GetPendingEntry();
1033 rvh1->SendNavigate(entry1->GetPageID(), entry1->GetURL()); 1032 rvh1->SendNavigate(entry1->GetPageID(), entry1->GetURL());
1034 EXPECT_TRUE(rvh2->is_swapped_out()); 1033 EXPECT_EQ(RenderViewHostImpl::STATE_PENDING_SWAP_OUT, rvh2->rvh_state());
1035 EXPECT_FALSE(rvh2->is_waiting_for_unload_ack());
1036 1034
1037 // We should be able to navigate forward. 1035 // We should be able to navigate forward.
1038 contents()->GetController().GoForward(); 1036 contents()->GetController().GoForward();
1039 contents()->ProceedWithCrossSiteNavigation(); 1037 contents()->ProceedWithCrossSiteNavigation();
1040 const NavigationEntry* entry2 = contents()->GetController().GetPendingEntry(); 1038 const NavigationEntry* entry2 = contents()->GetController().GetPendingEntry();
1041 rvh2->SendNavigate(entry2->GetPageID(), entry2->GetURL()); 1039 rvh2->SendNavigate(entry2->GetPageID(), entry2->GetURL());
1042 EXPECT_EQ(rvh2, rvh()); 1040 EXPECT_EQ(rvh2, rvh());
1043 EXPECT_FALSE(rvh2->is_swapped_out()); 1041 EXPECT_EQ(RenderViewHostImpl::STATE_LIVE, rvh2->rvh_state());
1044 EXPECT_TRUE(rvh1->is_swapped_out()); 1042 EXPECT_EQ(RenderViewHostImpl::STATE_PENDING_SWAP_OUT, rvh1->rvh_state());
1043 rvh1->OnSwappedOut(false);
1044 EXPECT_EQ(RenderViewHostImpl::STATE_SWAPPED_OUT, rvh1->rvh_state());
1045 } 1045 }
1046 1046
1047 // Test that we create swapped out RVHs for the opener chain when navigating an 1047 // Test that we create swapped out RVHs for the opener chain when navigating an
1048 // opened tab cross-process. This allows us to support certain cross-process 1048 // opened tab cross-process. This allows us to support certain cross-process
1049 // JavaScript calls (http://crbug.com/99202). 1049 // JavaScript calls (http://crbug.com/99202).
1050 TEST_F(RenderFrameHostManagerTest, CreateSwappedOutOpenerRVHs) { 1050 TEST_F(RenderFrameHostManagerTest, CreateSwappedOutOpenerRVHs) {
1051 const GURL kUrl1("http://www.google.com/"); 1051 const GURL kUrl1("http://www.google.com/");
1052 const GURL kUrl2("http://www.chromium.org/"); 1052 const GURL kUrl2("http://www.chromium.org/");
1053 const GURL kChromeUrl("chrome://foo"); 1053 const GURL kChromeUrl("chrome://foo");
1054 1054
(...skipping 26 matching lines...) Expand all
1081 1081
1082 // Ensure rvh1 is placed on swapped out list of the current tab. 1082 // Ensure rvh1 is placed on swapped out list of the current tab.
1083 EXPECT_TRUE(manager->IsRVHOnSwappedOutList(rvh1)); 1083 EXPECT_TRUE(manager->IsRVHOnSwappedOutList(rvh1));
1084 EXPECT_EQ(rvh1, 1084 EXPECT_EQ(rvh1,
1085 manager->GetSwappedOutRenderViewHost(rvh1->GetSiteInstance())); 1085 manager->GetSwappedOutRenderViewHost(rvh1->GetSiteInstance()));
1086 1086
1087 // Ensure a swapped out RVH is created in the first opener tab. 1087 // Ensure a swapped out RVH is created in the first opener tab.
1088 TestRenderViewHost* opener1_rvh = static_cast<TestRenderViewHost*>( 1088 TestRenderViewHost* opener1_rvh = static_cast<TestRenderViewHost*>(
1089 opener1_manager->GetSwappedOutRenderViewHost(rvh2->GetSiteInstance())); 1089 opener1_manager->GetSwappedOutRenderViewHost(rvh2->GetSiteInstance()));
1090 EXPECT_TRUE(opener1_manager->IsRVHOnSwappedOutList(opener1_rvh)); 1090 EXPECT_TRUE(opener1_manager->IsRVHOnSwappedOutList(opener1_rvh));
1091 EXPECT_TRUE(opener1_rvh->is_swapped_out()); 1091 EXPECT_EQ(RenderViewHostImpl::STATE_SWAPPED_OUT, opener1_rvh->rvh_state());
1092 1092
1093 // Ensure a swapped out RVH is created in the second opener tab. 1093 // Ensure a swapped out RVH is created in the second opener tab.
1094 TestRenderViewHost* opener2_rvh = static_cast<TestRenderViewHost*>( 1094 TestRenderViewHost* opener2_rvh = static_cast<TestRenderViewHost*>(
1095 opener2_manager->GetSwappedOutRenderViewHost(rvh2->GetSiteInstance())); 1095 opener2_manager->GetSwappedOutRenderViewHost(rvh2->GetSiteInstance()));
1096 EXPECT_TRUE(opener2_manager->IsRVHOnSwappedOutList(opener2_rvh)); 1096 EXPECT_TRUE(opener2_manager->IsRVHOnSwappedOutList(opener2_rvh));
1097 EXPECT_TRUE(opener2_rvh->is_swapped_out()); 1097 EXPECT_EQ(RenderViewHostImpl::STATE_SWAPPED_OUT, opener2_rvh->rvh_state());
1098 1098
1099 // Navigate to a cross-BrowsingInstance URL. 1099 // Navigate to a cross-BrowsingInstance URL.
1100 contents()->NavigateAndCommit(kChromeUrl); 1100 contents()->NavigateAndCommit(kChromeUrl);
1101 TestRenderViewHost* rvh3 = test_rvh(); 1101 TestRenderViewHost* rvh3 = test_rvh();
1102 EXPECT_NE(rvh1->GetSiteInstance(), rvh3->GetSiteInstance()); 1102 EXPECT_NE(rvh1->GetSiteInstance(), rvh3->GetSiteInstance());
1103 EXPECT_FALSE(rvh1->GetSiteInstance()->IsRelatedSiteInstance( 1103 EXPECT_FALSE(rvh1->GetSiteInstance()->IsRelatedSiteInstance(
1104 rvh3->GetSiteInstance())); 1104 rvh3->GetSiteInstance()));
1105 1105
1106 // No scripting is allowed across BrowsingInstances, so we should not create 1106 // No scripting is allowed across BrowsingInstances, so we should not create
1107 // swapped out RVHs for the opener chain in this case. 1107 // swapped out RVHs for the opener chain in this case.
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
1189 contents()->NavigateAndCommit(kPluginUrl); 1189 contents()->NavigateAndCommit(kPluginUrl);
1190 TestRenderViewHost* rvh2 = test_rvh(); 1190 TestRenderViewHost* rvh2 = test_rvh();
1191 EXPECT_NE(rvh1->GetSiteInstance(), rvh2->GetSiteInstance()); 1191 EXPECT_NE(rvh1->GetSiteInstance(), rvh2->GetSiteInstance());
1192 EXPECT_TRUE(rvh1->GetSiteInstance()->IsRelatedSiteInstance( 1192 EXPECT_TRUE(rvh1->GetSiteInstance()->IsRelatedSiteInstance(
1193 rvh2->GetSiteInstance())); 1193 rvh2->GetSiteInstance()));
1194 1194
1195 // Ensure a swapped out RVH is created in the first opener tab. 1195 // Ensure a swapped out RVH is created in the first opener tab.
1196 TestRenderViewHost* opener1_rvh = static_cast<TestRenderViewHost*>( 1196 TestRenderViewHost* opener1_rvh = static_cast<TestRenderViewHost*>(
1197 opener1_manager->GetSwappedOutRenderViewHost(rvh2->GetSiteInstance())); 1197 opener1_manager->GetSwappedOutRenderViewHost(rvh2->GetSiteInstance()));
1198 EXPECT_TRUE(opener1_manager->IsRVHOnSwappedOutList(opener1_rvh)); 1198 EXPECT_TRUE(opener1_manager->IsRVHOnSwappedOutList(opener1_rvh));
1199 EXPECT_TRUE(opener1_rvh->is_swapped_out()); 1199 EXPECT_EQ(RenderViewHostImpl::STATE_SWAPPED_OUT, opener1_rvh->rvh_state());
1200 1200
1201 // Ensure the new RVH has WebUI bindings. 1201 // Ensure the new RVH has WebUI bindings.
1202 EXPECT_TRUE(rvh2->GetEnabledBindings() & BINDINGS_POLICY_WEB_UI); 1202 EXPECT_TRUE(rvh2->GetEnabledBindings() & BINDINGS_POLICY_WEB_UI);
1203 } 1203 }
1204 1204
1205 // Test that we reuse the same guest SiteInstance if we navigate across sites. 1205 // Test that we reuse the same guest SiteInstance if we navigate across sites.
1206 TEST_F(RenderFrameHostManagerTest, NoSwapOnGuestNavigations) { 1206 TEST_F(RenderFrameHostManagerTest, NoSwapOnGuestNavigations) {
1207 TestNotificationTracker notifications; 1207 TestNotificationTracker notifications;
1208 1208
1209 GURL guest_url(std::string(kGuestScheme).append("://abc123")); 1209 GURL guest_url(std::string(kGuestScheme).append("://abc123"));
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
1335 notifications.ListenFor(NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED, 1335 notifications.ListenFor(NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED,
1336 Source<RenderWidgetHost>(host2->render_view_host())); 1336 Source<RenderWidgetHost>(host2->render_view_host()));
1337 manager->ShouldClosePage(false, true, base::TimeTicks()); 1337 manager->ShouldClosePage(false, true, base::TimeTicks());
1338 1338
1339 EXPECT_TRUE( 1339 EXPECT_TRUE(
1340 notifications.Check1AndReset(NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED)); 1340 notifications.Check1AndReset(NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED));
1341 EXPECT_FALSE(manager->pending_frame_host()); 1341 EXPECT_FALSE(manager->pending_frame_host());
1342 EXPECT_EQ(host, manager->current_frame_host()); 1342 EXPECT_EQ(host, manager->current_frame_host());
1343 } 1343 }
1344 1344
1345 // This checks that the given RVH has been properly deleted.
1346 class RenderViewHostDestructionObserver : public WebContentsObserver {
1347 public:
1348 RenderViewHostDestructionObserver(RenderViewHost* render_view_host)
1349 : WebContentsObserver(WebContents::FromRenderViewHost(render_view_host)),
1350 render_view_host_(render_view_host),
1351 rvh_deleted_(false) {}
1352
1353 bool rvh_deleted() { return rvh_deleted_; }
1354
1355 virtual void RenderViewDeleted(RenderViewHost* render_view_host) OVERRIDE {
1356 if (render_view_host == render_view_host_)
1357 rvh_deleted_ = true;
1358 }
1359
1360 private:
1361 RenderViewHost* render_view_host_;
1362 bool rvh_deleted_;
1363
1364 DISALLOW_COPY_AND_ASSIGN(RenderViewHostDestructionObserver);
1365 };
1366
1367 // Tests that the RenderViewHost is properly deleted when the SwapOutACK is
1368 // received before the new page commits.
1369 TEST_F(RenderFrameHostManagerTest,
1370 SwapOutACKBeforeNewPageCommitsLeadsToDeletion) {
1371 const GURL kUrl1("http://www.google.com/");
1372 const GURL kUrl2("http://www.chromium.org/");
1373
1374 // Navigate to the first page.
1375 contents()->NavigateAndCommit(kUrl1);
1376 TestRenderViewHost* rvh1 = test_rvh();
1377 RenderViewHostDestructionObserver destruction_observer(rvh1);
1378 EXPECT_EQ(RenderViewHostImpl::STATE_LIVE, rvh1->rvh_state());
1379
1380 // Navigate to new site, simulating onbeforeunload approval.
1381 controller().LoadURL(kUrl2, Referrer(), PAGE_TRANSITION_LINK, std::string());
1382 base::TimeTicks now = base::TimeTicks::Now();
1383 rvh1->OnMessageReceived(ViewHostMsg_ShouldClose_ACK(0, true, now, now));
1384 EXPECT_TRUE(contents()->cross_navigation_pending());
1385 TestRenderViewHost* rvh2 =
1386 static_cast<TestRenderViewHost*>(contents()->GetPendingRenderViewHost());
1387
1388 // Simulate rvh2's response, which leads to an unload request being sent to
1389 // rvh1.
1390 std::vector<GURL> url_chain;
1391 url_chain.push_back(GURL());
1392 contents()->GetRenderManagerForTesting()->OnCrossSiteResponse(
1393 rvh2, GlobalRequestID(0, 0), false, url_chain, Referrer(),
1394 PAGE_TRANSITION_TYPED, 1, false);
1395 EXPECT_TRUE(contents()->cross_navigation_pending());
1396 EXPECT_EQ(RenderViewHostImpl::STATE_WAITING_FOR_UNLOAD_ACK,
1397 rvh1->rvh_state());
1398
1399 // Simulate the swap out ack.
1400 rvh1->OnSwappedOut(false);
1401 EXPECT_EQ(RenderViewHostImpl::STATE_WAITING_FOR_COMMIT, rvh1->rvh_state());
1402
1403 // The new page commits.
1404 contents()->TestDidNavigate(rvh2, 1, kUrl2, PAGE_TRANSITION_TYPED);
1405 EXPECT_FALSE(contents()->cross_navigation_pending());
1406 EXPECT_EQ(rvh2, rvh());
1407 EXPECT_TRUE(contents()->GetPendingRenderViewHost() == NULL);
1408 EXPECT_EQ(RenderViewHostImpl::STATE_LIVE, rvh2->rvh_state());
1409
1410 // rvh1 should have been deleted.
1411 EXPECT_TRUE(destruction_observer.rvh_deleted());
1412 rvh1 = NULL;
1413 }
1414
1415 // Tests that the RenderViewHost is properly swapped out when the SwapOutACK is
1416 // received before the new page commits.
1417 TEST_F(RenderFrameHostManagerTest,
1418 SwapOutACKBeforeNewPageCommitsLeadsToSwapOut) {
1419 const GURL kUrl1("http://www.google.com/");
1420 const GURL kUrl2("http://www.chromium.org/");
1421
1422 // Navigate to the first page.
1423 contents()->NavigateAndCommit(kUrl1);
1424 TestRenderViewHost* rvh1 = test_rvh();
1425 RenderViewHostDestructionObserver destruction_observer(rvh1);
1426 EXPECT_EQ(RenderViewHostImpl::STATE_LIVE, rvh1->rvh_state());
1427
1428 // Increment the number of active views in SiteInstanceImpl so that rvh2 is
1429 // not deleted on swap out.
1430 static_cast<SiteInstanceImpl*>(
1431 rvh1->GetSiteInstance())->increment_active_view_count();
1432
1433 // Navigate to new site, simulating onbeforeunload approval.
1434 controller().LoadURL(kUrl2, Referrer(), PAGE_TRANSITION_LINK, std::string());
1435 base::TimeTicks now = base::TimeTicks::Now();
1436 rvh1->OnMessageReceived(ViewHostMsg_ShouldClose_ACK(0, true, now, now));
1437 EXPECT_TRUE(contents()->cross_navigation_pending());
1438 TestRenderViewHost* rvh2 =
1439 static_cast<TestRenderViewHost*>(contents()->GetPendingRenderViewHost());
1440
1441 // Simulate rvh2's response, which leads to an unload request being sent to
1442 // rvh1.
1443 std::vector<GURL> url_chain;
1444 url_chain.push_back(GURL());
1445 contents()->GetRenderManagerForTesting()->OnCrossSiteResponse(
1446 rvh2, GlobalRequestID(0, 0), false, url_chain, Referrer(),
1447 PAGE_TRANSITION_TYPED, 1, false);
1448 EXPECT_TRUE(contents()->cross_navigation_pending());
1449 EXPECT_EQ(RenderViewHostImpl::STATE_WAITING_FOR_UNLOAD_ACK,
1450 rvh1->rvh_state());
1451
1452 // Simulate the swap out ack.
1453 rvh1->OnSwappedOut(false);
1454 EXPECT_EQ(RenderViewHostImpl::STATE_WAITING_FOR_COMMIT, rvh1->rvh_state());
1455
1456 // The new page commits.
1457 contents()->TestDidNavigate(rvh2, 1, kUrl2, PAGE_TRANSITION_TYPED);
1458 EXPECT_FALSE(contents()->cross_navigation_pending());
1459 EXPECT_EQ(rvh2, rvh());
1460 EXPECT_TRUE(contents()->GetPendingRenderViewHost() == NULL);
1461 EXPECT_EQ(RenderViewHostImpl::STATE_LIVE, rvh2->rvh_state());
1462
1463 // rvh1 should be swapped out.
1464 EXPECT_FALSE(destruction_observer.rvh_deleted());
1465 EXPECT_EQ(RenderViewHostImpl::STATE_SWAPPED_OUT, rvh1->rvh_state());
1466 }
1467
1468 // Tests that the RenderViewHost is properly deleted when the new
1469 // page commits before the swap out ack is received.
1470 TEST_F(RenderFrameHostManagerTest,
1471 NewPageCommitsBeforeSwapOutACKLeadsToDeletion) {
1472 const GURL kUrl1("http://www.google.com/");
1473 const GURL kUrl2("http://www.chromium.org/");
1474
1475 // Navigate to the first page.
1476 contents()->NavigateAndCommit(kUrl1);
1477 TestRenderViewHost* rvh1 = test_rvh();
1478 RenderViewHostDestructionObserver destruction_observer(rvh1);
1479 EXPECT_EQ(RenderViewHostImpl::STATE_LIVE, rvh1->rvh_state());
1480
1481 // Navigate to new site, simulating onbeforeunload approval.
1482 controller().LoadURL(kUrl2, Referrer(), PAGE_TRANSITION_LINK, std::string());
1483 base::TimeTicks now = base::TimeTicks::Now();
1484 rvh1->OnMessageReceived(ViewHostMsg_ShouldClose_ACK(0, true, now, now));
1485 EXPECT_TRUE(contents()->cross_navigation_pending());
1486 TestRenderViewHost* rvh2 =
1487 static_cast<TestRenderViewHost*>(contents()->GetPendingRenderViewHost());
1488
1489 // Simulate rvh2's response, which leads to an unload request being sent to
1490 // rvh1.
1491 std::vector<GURL> url_chain;
1492 url_chain.push_back(GURL());
1493 contents()->GetRenderManagerForTesting()->OnCrossSiteResponse(
1494 rvh2, GlobalRequestID(0, 0), false, url_chain, Referrer(),
1495 PAGE_TRANSITION_TYPED, 1, false);
1496 EXPECT_TRUE(contents()->cross_navigation_pending());
1497 EXPECT_EQ(RenderViewHostImpl::STATE_WAITING_FOR_UNLOAD_ACK,
1498 rvh1->rvh_state());
1499
1500 // The new page commits.
1501 contents()->TestDidNavigate(rvh2, 1, kUrl2, PAGE_TRANSITION_TYPED);
1502 EXPECT_FALSE(contents()->cross_navigation_pending());
1503 EXPECT_EQ(rvh2, rvh());
1504 EXPECT_TRUE(contents()->GetPendingRenderViewHost() == NULL);
1505 EXPECT_EQ(RenderViewHostImpl::STATE_LIVE, rvh2->rvh_state());
1506 EXPECT_EQ(RenderViewHostImpl::STATE_PENDING_SHUTDOWN, rvh1->rvh_state());
1507
1508 // Simulate the swap out ack.
1509 rvh1->OnSwappedOut(false);
1510
1511 // rvh1 should have been deleted.
1512 EXPECT_TRUE(destruction_observer.rvh_deleted());
1513 rvh1 = NULL;
1514 }
1515
1516 // Tests that the RenderViewHost is properly swapped out when the new page
1517 // commits before the swap out ack is received.
1518 TEST_F(RenderFrameHostManagerTest,
1519 NewPageCommitsBeforeSwapOutACKLeadsToSwapOut) {
1520 const GURL kUrl1("http://www.google.com/");
1521 const GURL kUrl2("http://www.chromium.org/");
1522
1523 // Navigate to the first page.
1524 contents()->NavigateAndCommit(kUrl1);
1525 TestRenderViewHost* rvh1 = test_rvh();
1526 RenderViewHostDestructionObserver destruction_observer(rvh1);
1527 EXPECT_EQ(RenderViewHostImpl::STATE_LIVE, rvh1->rvh_state());
1528
1529 // Increment the number of active views in SiteInstanceImpl so that rvh1 is
1530 // not deleted on swap out.
1531 static_cast<SiteInstanceImpl*>(
1532 rvh1->GetSiteInstance())->increment_active_view_count();
1533
1534 // Navigate to new site, simulating onbeforeunload approval.
1535 controller().LoadURL(kUrl2, Referrer(), PAGE_TRANSITION_LINK, std::string());
1536 base::TimeTicks now = base::TimeTicks::Now();
1537 rvh1->OnMessageReceived(ViewHostMsg_ShouldClose_ACK(0, true, now, now));
1538 EXPECT_TRUE(contents()->cross_navigation_pending());
1539 TestRenderViewHost* rvh2 =
1540 static_cast<TestRenderViewHost*>(contents()->GetPendingRenderViewHost());
1541
1542 // Simulate rvh2's response, which leads to an unload request being sent to
1543 // rvh1.
1544 std::vector<GURL> url_chain;
1545 url_chain.push_back(GURL());
1546 contents()->GetRenderManagerForTesting()->OnCrossSiteResponse(
1547 rvh2, GlobalRequestID(0, 0), false, url_chain, Referrer(),
1548 PAGE_TRANSITION_TYPED, 1, false);
1549 EXPECT_TRUE(contents()->cross_navigation_pending());
1550 EXPECT_EQ(RenderViewHostImpl::STATE_WAITING_FOR_UNLOAD_ACK,
1551 rvh1->rvh_state());
1552
1553 // The new page commits.
1554 contents()->TestDidNavigate(rvh2, 1, kUrl2, PAGE_TRANSITION_TYPED);
1555 EXPECT_FALSE(contents()->cross_navigation_pending());
1556 EXPECT_EQ(rvh2, rvh());
1557 EXPECT_TRUE(contents()->GetPendingRenderViewHost() == NULL);
1558 EXPECT_EQ(RenderViewHostImpl::STATE_LIVE, rvh2->rvh_state());
1559 EXPECT_EQ(RenderViewHostImpl::STATE_PENDING_SWAP_OUT, rvh1->rvh_state());
1560
1561 // Simulate the swap out ack.
1562 rvh1->OnSwappedOut(false);
1563
1564 // rvh1 should be swapped out.
1565 EXPECT_FALSE(destruction_observer.rvh_deleted());
1566 EXPECT_EQ(RenderViewHostImpl::STATE_SWAPPED_OUT, rvh1->rvh_state());
1567 }
1568
1345 } // namespace content 1569 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698