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