| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/logging.h" | 5 #include "base/logging.h" |
| 6 #include "base/utf_string_conversions.h" | 6 #include "base/utf_string_conversions.h" |
| 7 #include "chrome/browser/dom_operation_notification_details.h" | 7 #include "chrome/browser/dom_operation_notification_details.h" |
| 8 #include "chrome/browser/prefs/pref_service.h" | 8 #include "chrome/browser/prefs/pref_service.h" |
| 9 #include "chrome/browser/tab_contents/chrome_interstitial_page.h" | 9 #include "chrome/browser/tab_contents/chrome_interstitial_page.h" |
| 10 #include "chrome/common/pref_names.h" | 10 #include "chrome/common/pref_names.h" |
| (...skipping 696 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 707 PageTransition::AUTO_SUBFRAME); | 707 PageTransition::AUTO_SUBFRAME); |
| 708 EXPECT_TRUE(orig_rvh->is_waiting_for_beforeunload_ack()); | 708 EXPECT_TRUE(orig_rvh->is_waiting_for_beforeunload_ack()); |
| 709 | 709 |
| 710 // Now simulate the onbeforeunload approval and verify the navigation is | 710 // Now simulate the onbeforeunload approval and verify the navigation is |
| 711 // not canceled. | 711 // not canceled. |
| 712 orig_rvh->TestOnMessageReceived(ViewHostMsg_ShouldClose_ACK(0, true)); | 712 orig_rvh->TestOnMessageReceived(ViewHostMsg_ShouldClose_ACK(0, true)); |
| 713 EXPECT_FALSE(orig_rvh->is_waiting_for_beforeunload_ack()); | 713 EXPECT_FALSE(orig_rvh->is_waiting_for_beforeunload_ack()); |
| 714 EXPECT_TRUE(contents()->cross_navigation_pending()); | 714 EXPECT_TRUE(contents()->cross_navigation_pending()); |
| 715 } | 715 } |
| 716 | 716 |
| 717 // Test that the original renderer can preempt a cross-site navigation while the | 717 // Test that a cross-site navigation is not preempted if the previous |
| 718 // beforeunload request is in flight. | 718 // renderer sends a FrameNavigate message just before being told to stop. |
| 719 TEST_F(TabContentsTest, CrossSitePreemptDuringBeforeUnload) { | 719 // We should only preempt the cross-site navigation if the previous renderer |
| 720 // has started a new navigation. See http://crbug.com/79176. |
| 721 TEST_F(TabContentsTest, CrossSiteNotPreemptedDuringBeforeUnload) { |
| 720 contents()->transition_cross_site = true; | 722 contents()->transition_cross_site = true; |
| 723 |
| 724 // Navigate to NTP URL. |
| 725 const GURL url("chrome://newtab"); |
| 726 controller().LoadURL(url, GURL(), PageTransition::TYPED); |
| 721 TestRenderViewHost* orig_rvh = rvh(); | 727 TestRenderViewHost* orig_rvh = rvh(); |
| 722 SiteInstance* instance1 = contents()->GetSiteInstance(); | 728 EXPECT_FALSE(contents()->cross_navigation_pending()); |
| 723 | 729 |
| 724 // Navigate to URL. First URL should use first RenderViewHost. | 730 // Navigate to new site, with the beforeunload request in flight. |
| 725 const GURL url("http://www.google.com"); | |
| 726 controller().LoadURL(url, GURL(), PageTransition::TYPED); | |
| 727 ViewHostMsg_FrameNavigate_Params params1; | |
| 728 InitNavigateParams(¶ms1, 1, url, PageTransition::TYPED); | |
| 729 contents()->TestDidNavigate(orig_rvh, params1); | |
| 730 EXPECT_FALSE(contents()->cross_navigation_pending()); | |
| 731 EXPECT_EQ(orig_rvh, contents()->render_view_host()); | |
| 732 | |
| 733 // Navigate to new site, with the befureunload request in flight. | |
| 734 const GURL url2("http://www.yahoo.com"); | 731 const GURL url2("http://www.yahoo.com"); |
| 735 controller().LoadURL(url2, GURL(), PageTransition::TYPED); | 732 controller().LoadURL(url2, GURL(), PageTransition::TYPED); |
| 733 TestRenderViewHost* pending_rvh = contents()->pending_rvh(); |
| 734 EXPECT_TRUE(contents()->cross_navigation_pending()); |
| 735 EXPECT_TRUE(orig_rvh->is_waiting_for_beforeunload_ack()); |
| 736 | 736 |
| 737 // Suppose the original renderer navigates now, while the beforeunload request | 737 // Suppose the first navigation tries to commit now, with a |
| 738 // is in flight. We must cancel the pending navigation and show this new | 738 // ViewMsg_Stop in flight. This should not cancel the pending navigation, |
| 739 // page, because the beforeunload handler might return false. | 739 // but it should act as if the beforeunload ack arrived. |
| 740 orig_rvh->SendNavigate(2, GURL("http://www.google.com/foo")); | 740 orig_rvh->SendNavigate(1, GURL("chrome://newtab")); |
| 741 EXPECT_TRUE(contents()->cross_navigation_pending()); |
| 742 EXPECT_EQ(orig_rvh, contents()->render_view_host()); |
| 743 EXPECT_FALSE(orig_rvh->is_waiting_for_beforeunload_ack()); |
| 741 | 744 |
| 742 // Verify that the pending navigation is cancelled. | 745 // The pending navigation should be able to commit successfully. |
| 743 SiteInstance* instance2 = contents()->GetSiteInstance(); | 746 ViewHostMsg_FrameNavigate_Params params2; |
| 747 InitNavigateParams(¶ms2, 1, url2, PageTransition::TYPED); |
| 748 contents()->TestDidNavigate(pending_rvh, params2); |
| 744 EXPECT_FALSE(contents()->cross_navigation_pending()); | 749 EXPECT_FALSE(contents()->cross_navigation_pending()); |
| 745 EXPECT_EQ(orig_rvh, rvh()); | 750 EXPECT_EQ(pending_rvh, contents()->render_view_host()); |
| 746 EXPECT_EQ(instance1, instance2); | |
| 747 EXPECT_TRUE(contents()->pending_rvh() == NULL); | |
| 748 | |
| 749 // Make sure the beforeunload ack doesn't cause problems if it arrives here. | |
| 750 orig_rvh->TestOnMessageReceived(ViewHostMsg_ShouldClose_ACK(0, true)); | |
| 751 } | 751 } |
| 752 | 752 |
| 753 // Test that the original renderer cannot preempt a cross-site navigation once | 753 // Test that the original renderer cannot preempt a cross-site navigation once |
| 754 // the unload request has been made. At this point, the cross-site navigation | 754 // the unload request has been made. At this point, the cross-site navigation |
| 755 // is almost ready to be displayed, and the original renderer is only given a | 755 // is almost ready to be displayed, and the original renderer is only given a |
| 756 // short chance to run an unload handler. Prevents regression of bug 23942. | 756 // short chance to run an unload handler. Prevents regression of bug 23942. |
| 757 TEST_F(TabContentsTest, CrossSiteCantPreemptAfterUnload) { | 757 TEST_F(TabContentsTest, CrossSiteCantPreemptAfterUnload) { |
| 758 contents()->transition_cross_site = true; | 758 contents()->transition_cross_site = true; |
| 759 TestRenderViewHost* orig_rvh = rvh(); | 759 TestRenderViewHost* orig_rvh = rvh(); |
| 760 SiteInstance* instance1 = contents()->GetSiteInstance(); | 760 SiteInstance* instance1 = contents()->GetSiteInstance(); |
| (...skipping 991 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1752 window.close_count = 0; | 1752 window.close_count = 0; |
| 1753 | 1753 |
| 1754 const int kWindowCount = 4; | 1754 const int kWindowCount = 4; |
| 1755 for (int i = 0; i < kWindowCount; i++) { | 1755 for (int i = 0; i < kWindowCount; i++) { |
| 1756 tab_contents->AddConstrainedDialog(&window); | 1756 tab_contents->AddConstrainedDialog(&window); |
| 1757 } | 1757 } |
| 1758 EXPECT_EQ(window.close_count, 0); | 1758 EXPECT_EQ(window.close_count, 0); |
| 1759 delete tab_contents; | 1759 delete tab_contents; |
| 1760 EXPECT_EQ(window.close_count, kWindowCount); | 1760 EXPECT_EQ(window.close_count, kWindowCount); |
| 1761 } | 1761 } |
| OLD | NEW |