Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/lifetime/browser_close_manager.h" | 5 #include "chrome/browser/lifetime/browser_close_manager.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| 11 #include "base/files/scoped_temp_dir.h" | 11 #include "base/files/scoped_temp_dir.h" |
| 12 #include "base/macros.h" | 12 #include "base/macros.h" |
| 13 #include "build/build_config.h" | 13 #include "build/build_config.h" |
| 14 #include "chrome/browser/background/background_mode_manager.h" | 14 #include "chrome/browser/background/background_mode_manager.h" |
| 15 #include "chrome/browser/browser_process.h" | 15 #include "chrome/browser/browser_process.h" |
| 16 #include "chrome/browser/browser_shutdown.h" | 16 #include "chrome/browser/browser_shutdown.h" |
| 17 #include "chrome/browser/chrome_notification_types.h" | 17 #include "chrome/browser/chrome_notification_types.h" |
| 18 #include "chrome/browser/defaults.h" | 18 #include "chrome/browser/defaults.h" |
| 19 #include "chrome/browser/download/chrome_download_manager_delegate.h" | 19 #include "chrome/browser/download/chrome_download_manager_delegate.h" |
| 20 #include "chrome/browser/download/download_prefs.h" | 20 #include "chrome/browser/download/download_prefs.h" |
| 21 #include "chrome/browser/download/download_service.h" | 21 #include "chrome/browser/download/download_service.h" |
| 22 #include "chrome/browser/download/download_service_factory.h" | 22 #include "chrome/browser/download/download_service_factory.h" |
| 23 #include "chrome/browser/lifetime/application_lifetime.h" | 23 #include "chrome/browser/lifetime/application_lifetime.h" |
| 24 #include "chrome/browser/lifetime/keep_alive_types.h" | 24 #include "chrome/browser/lifetime/keep_alive_types.h" |
| 25 #include "chrome/browser/lifetime/scoped_keep_alive.h" | 25 #include "chrome/browser/lifetime/scoped_keep_alive.h" |
| 26 #include "chrome/browser/net/url_request_mock_util.h" | 26 #include "chrome/browser/net/url_request_mock_util.h" |
| 27 #include "chrome/browser/prefs/session_startup_pref.h" | 27 #include "chrome/browser/prefs/session_startup_pref.h" |
| 28 #include "chrome/browser/profiles/profile.h" | 28 #include "chrome/browser/profiles/profile.h" |
| 29 #include "chrome/browser/profiles/profile_manager.h" | 29 #include "chrome/browser/profiles/profile_manager.h" |
| 30 #include "chrome/browser/sessions/tab_restore_service_factory.h" | |
| 30 #include "chrome/browser/ui/browser.h" | 31 #include "chrome/browser/ui/browser.h" |
| 31 #include "chrome/browser/ui/browser_commands.h" | 32 #include "chrome/browser/ui/browser_commands.h" |
| 32 #include "chrome/browser/ui/browser_list.h" | 33 #include "chrome/browser/ui/browser_list.h" |
| 33 #include "chrome/browser/ui/browser_window.h" | 34 #include "chrome/browser/ui/browser_window.h" |
| 34 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 35 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| 35 #include "chrome/common/chrome_switches.h" | 36 #include "chrome/common/chrome_switches.h" |
| 36 #include "chrome/common/url_constants.h" | 37 #include "chrome/common/url_constants.h" |
| 37 #include "chrome/test/base/in_process_browser_test.h" | 38 #include "chrome/test/base/in_process_browser_test.h" |
| 38 #include "chrome/test/base/ui_test_utils.h" | 39 #include "chrome/test/base/ui_test_utils.h" |
| 39 #include "components/app_modal/javascript_app_modal_dialog.h" | 40 #include "components/app_modal/javascript_app_modal_dialog.h" |
| 40 #include "components/app_modal/native_app_modal_dialog.h" | 41 #include "components/app_modal/native_app_modal_dialog.h" |
| 42 #include "components/sessions/core/tab_restore_service.h" | |
| 43 #include "components/sessions/core/tab_restore_service_observer.h" | |
| 41 #include "content/public/browser/browser_context.h" | 44 #include "content/public/browser/browser_context.h" |
| 42 #include "content/public/browser/download_item.h" | 45 #include "content/public/browser/download_item.h" |
| 43 #include "content/public/browser/download_manager.h" | 46 #include "content/public/browser/download_manager.h" |
| 44 #include "content/public/browser/notification_service.h" | 47 #include "content/public/browser/notification_service.h" |
| 45 #include "content/public/browser/render_view_host.h" | 48 #include "content/public/browser/render_view_host.h" |
| 46 #include "content/public/browser/render_widget_host.h" | 49 #include "content/public/browser/render_widget_host.h" |
| 47 #include "content/public/browser/web_contents.h" | 50 #include "content/public/browser/web_contents.h" |
| 51 #include "content/public/test/browser_test_utils.h" | |
| 48 #include "content/public/test/download_test_observer.h" | 52 #include "content/public/test/download_test_observer.h" |
| 49 #include "content/public/test/test_navigation_observer.h" | 53 #include "content/public/test/test_navigation_observer.h" |
| 50 #include "net/test/embedded_test_server/embedded_test_server.h" | 54 #include "net/test/embedded_test_server/embedded_test_server.h" |
| 51 #include "net/test/url_request/url_request_mock_http_job.h" | 55 #include "net/test/url_request/url_request_mock_http_job.h" |
| 52 #include "net/test/url_request/url_request_slow_download_job.h" | 56 #include "net/test/url_request/url_request_slow_download_job.h" |
| 53 | 57 |
| 54 #if defined(OS_CHROMEOS) | 58 #if defined(OS_CHROMEOS) |
| 55 #include "chromeos/chromeos_switches.h" | 59 #include "chromeos/chromeos_switches.h" |
| 56 #endif | 60 #endif |
| 57 | 61 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 106 | 110 |
| 107 private: | 111 private: |
| 108 int num_outstanding_; | 112 int num_outstanding_; |
| 109 content::NotificationRegistrar registrar_; | 113 content::NotificationRegistrar registrar_; |
| 110 bool running_; | 114 bool running_; |
| 111 base::RunLoop run_loop_; | 115 base::RunLoop run_loop_; |
| 112 | 116 |
| 113 DISALLOW_COPY_AND_ASSIGN(RepeatedNotificationObserver); | 117 DISALLOW_COPY_AND_ASSIGN(RepeatedNotificationObserver); |
| 114 }; | 118 }; |
| 115 | 119 |
| 120 class TabRestoreServiceChangesObserver | |
| 121 : public sessions::TabRestoreServiceObserver { | |
| 122 public: | |
| 123 explicit TabRestoreServiceChangesObserver(Profile* profile) { | |
| 124 service_ = TabRestoreServiceFactory::GetForProfile(profile); | |
|
sky
2017/02/16 17:16:53
Use member initializer.
Michael K. (Yandex Team)
2017/02/17 09:43:04
Done.
| |
| 125 if (service_) | |
| 126 service_->AddObserver(this); | |
| 127 } | |
| 128 | |
| 129 ~TabRestoreServiceChangesObserver() override { | |
| 130 if (service_) | |
| 131 service_->RemoveObserver(this); | |
| 132 } | |
| 133 | |
| 134 size_t GetChangesCount() const { return changes_count_; } | |
|
sky
2017/02/16 17:16:53
GetChangesCount() -> changes_count()
Michael K. (Yandex Team)
2017/02/17 09:43:04
Done.
| |
| 135 | |
| 136 private: | |
| 137 void TabRestoreServiceChanged(sessions::TabRestoreService*) override { | |
|
sky
2017/02/16 17:16:53
Prefix with where overrides come from, e.g.:
// se
Michael K. (Yandex Team)
2017/02/17 09:43:04
Done.
| |
| 138 changes_count_++; | |
| 139 } | |
| 140 | |
| 141 void TabRestoreServiceDestroyed(sessions::TabRestoreService*) override { | |
| 142 service_ = nullptr; | |
| 143 } | |
| 144 | |
| 145 sessions::TabRestoreService* service_ = nullptr; | |
| 146 size_t changes_count_ = 0; | |
| 147 | |
| 148 DISALLOW_COPY_AND_ASSIGN(TabRestoreServiceChangesObserver); | |
| 149 }; | |
| 150 | |
| 116 class TestBrowserCloseManager : public BrowserCloseManager { | 151 class TestBrowserCloseManager : public BrowserCloseManager { |
| 117 public: | 152 public: |
| 118 enum UserChoice { | 153 enum UserChoice { |
| 119 USER_CHOICE_USER_CANCELS_CLOSE, | 154 USER_CHOICE_USER_CANCELS_CLOSE, |
| 120 USER_CHOICE_USER_ALLOWS_CLOSE, | 155 USER_CHOICE_USER_ALLOWS_CLOSE, |
| 121 NO_USER_CHOICE | 156 NO_USER_CHOICE |
| 122 }; | 157 }; |
| 123 | 158 |
| 124 static void AttemptClose(UserChoice user_choice) { | 159 static void AttemptClose(UserChoice user_choice) { |
| 125 scoped_refptr<BrowserCloseManager> browser_close_manager = | 160 scoped_refptr<BrowserCloseManager> browser_close_manager = |
| (...skipping 575 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 701 ASSERT_NO_FATAL_FAILURE(AcceptClose()); | 736 ASSERT_NO_FATAL_FAILURE(AcceptClose()); |
| 702 ASSERT_NO_FATAL_FAILURE(AcceptClose()); | 737 ASSERT_NO_FATAL_FAILURE(AcceptClose()); |
| 703 ASSERT_NO_FATAL_FAILURE(AcceptClose()); | 738 ASSERT_NO_FATAL_FAILURE(AcceptClose()); |
| 704 | 739 |
| 705 close_observer.Wait(); | 740 close_observer.Wait(); |
| 706 EXPECT_TRUE(browser_shutdown::IsTryingToQuit()); | 741 EXPECT_TRUE(browser_shutdown::IsTryingToQuit()); |
| 707 EXPECT_TRUE(BrowserList::GetInstance()->empty()); | 742 EXPECT_TRUE(BrowserList::GetInstance()->empty()); |
| 708 } | 743 } |
| 709 | 744 |
| 710 IN_PROC_BROWSER_TEST_P(BrowserCloseManagerBrowserTest, | 745 IN_PROC_BROWSER_TEST_P(BrowserCloseManagerBrowserTest, |
| 746 AddBeforeUnloadDuringClosing) { | |
| 747 // Currently FastUnloadController is broken :( | |
| 748 // TODO. | |
| 749 if (GetParam()) | |
| 750 return; | |
| 751 | |
| 752 ASSERT_TRUE(embedded_test_server()->Start()); | |
| 753 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL( | |
| 754 browser(), embedded_test_server()->GetURL("/title1.html"))); | |
| 755 | |
| 756 // Open second window. | |
| 757 ui_test_utils::NavigateToURLWithDisposition( | |
| 758 browser(), embedded_test_server()->GetURL("/beforeunload.html"), | |
| 759 WindowOpenDisposition::NEW_WINDOW, | |
| 760 ui_test_utils::BROWSER_TEST_WAIT_FOR_BROWSER); | |
| 761 EXPECT_EQ(2u, BrowserList::GetInstance()->size()); | |
| 762 auto* browser2 = BrowserList::GetInstance()->get(0) != browser() | |
| 763 ? BrowserList::GetInstance()->get(0) | |
| 764 : BrowserList::GetInstance()->get(1); | |
| 765 content::WaitForLoadStop(browser2->tab_strip_model()->GetWebContentsAt(0)); | |
| 766 | |
| 767 // Let's work with second window only. | |
| 768 // This page has beforeunload handler already. | |
| 769 EXPECT_TRUE(browser2->tab_strip_model() | |
| 770 ->GetWebContentsAt(0) | |
| 771 ->NeedToFireBeforeUnload()); | |
| 772 // This page doesn't have beforeunload handler. Yet. | |
| 773 ui_test_utils::NavigateToURLWithDisposition( | |
| 774 browser2, embedded_test_server()->GetURL("/title2.html"), | |
| 775 WindowOpenDisposition::NEW_FOREGROUND_TAB, | |
| 776 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); | |
| 777 content::WaitForLoadStop(browser2->tab_strip_model()->GetWebContentsAt(1)); | |
| 778 EXPECT_FALSE(browser2->tab_strip_model() | |
| 779 ->GetWebContentsAt(1) | |
| 780 ->NeedToFireBeforeUnload()); | |
| 781 EXPECT_EQ(2, browser2->tab_strip_model()->count()); | |
| 782 | |
| 783 DisableHangMonitor(browser2); | |
| 784 | |
| 785 // The test. | |
| 786 | |
| 787 TabRestoreServiceChangesObserver restore_observer(browser2->profile()); | |
| 788 content::WindowedNotificationObserver observer( | |
| 789 chrome::NOTIFICATION_BROWSER_CLOSED, | |
| 790 content::NotificationService::AllSources()); | |
| 791 chrome::CloseWindow(browser2); | |
| 792 // Just to be sure CloseWindow doesn't have asynchronous tasks | |
| 793 // that could have an impact. | |
| 794 content::RunAllPendingInMessageLoop(); | |
| 795 | |
| 796 // Closing browser shouldn't happen because of beforeunload handler. | |
| 797 EXPECT_EQ(2u, BrowserList::GetInstance()->size()); | |
| 798 // Add beforeunload handler for the 2nd (title2.html) tab which haven't had it | |
| 799 // yet. | |
| 800 ASSERT_TRUE(content::ExecuteScript( | |
| 801 browser2->tab_strip_model()->GetWebContentsAt(1)->GetRenderViewHost(), | |
| 802 "window.addEventListener('beforeunload', " | |
| 803 "function(event) { event.returnValue = 'Foo'; });")); | |
| 804 EXPECT_TRUE(browser2->tab_strip_model() | |
| 805 ->GetWebContentsAt(1) | |
| 806 ->NeedToFireBeforeUnload()); | |
| 807 // Accept closing the first tab. | |
| 808 ASSERT_NO_FATAL_FAILURE(AcceptClose()); | |
| 809 // Just to be sure accepting a dialog doesn't have asynchronous tasks | |
| 810 // that could have an impact. | |
| 811 content::RunAllPendingInMessageLoop(); | |
| 812 // It shouldn't close the whole window/browser. | |
| 813 EXPECT_EQ(2u, BrowserList::GetInstance()->size()); | |
| 814 EXPECT_EQ(2, browser2->tab_strip_model()->count()); | |
| 815 // Accept closing the second tab. | |
| 816 ASSERT_NO_FATAL_FAILURE(AcceptClose()); | |
| 817 observer.Wait(); | |
| 818 // Now the second window/browser should be closed. | |
| 819 EXPECT_EQ(1u, BrowserList::GetInstance()->size()); | |
| 820 EXPECT_EQ(browser(), BrowserList::GetInstance()->get(0)); | |
| 821 EXPECT_EQ(1u, restore_observer.GetChangesCount()); | |
| 822 | |
| 823 // Restore the closed browser. | |
| 824 content::WindowedNotificationObserver open_window_observer( | |
| 825 chrome::NOTIFICATION_BROWSER_OPENED, | |
| 826 content::NotificationService::AllSources()); | |
| 827 chrome::OpenWindowWithRestoredTabs(browser()->profile()); | |
| 828 open_window_observer.Wait(); | |
| 829 EXPECT_EQ(2u, BrowserList::GetInstance()->size()); | |
| 830 browser2 = BrowserList::GetInstance()->get(0) != browser() | |
| 831 ? BrowserList::GetInstance()->get(0) | |
| 832 : BrowserList::GetInstance()->get(1); | |
| 833 | |
| 834 // Check the restored browser contents. | |
| 835 EXPECT_EQ(2, browser2->tab_strip_model()->count()); | |
| 836 EXPECT_EQ(embedded_test_server()->GetURL("/beforeunload.html"), | |
| 837 browser2->tab_strip_model()->GetWebContentsAt(0)->GetURL()); | |
| 838 EXPECT_EQ(embedded_test_server()->GetURL("/title2.html"), | |
| 839 browser2->tab_strip_model()->GetWebContentsAt(1)->GetURL()); | |
| 840 } | |
| 841 | |
| 842 IN_PROC_BROWSER_TEST_P(BrowserCloseManagerBrowserTest, | |
| 711 TestCloseTabDuringShutdown) { | 843 TestCloseTabDuringShutdown) { |
| 712 ASSERT_TRUE(embedded_test_server()->Start()); | 844 ASSERT_TRUE(embedded_test_server()->Start()); |
| 713 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL( | 845 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL( |
| 714 browsers_[0], embedded_test_server()->GetURL("/beforeunload.html"))); | 846 browsers_[0], embedded_test_server()->GetURL("/beforeunload.html"))); |
| 715 DisableHangMonitor(browsers_[0]); | 847 DisableHangMonitor(browsers_[0]); |
| 716 | 848 |
| 717 RepeatedNotificationObserver cancel_observer( | 849 RepeatedNotificationObserver cancel_observer( |
| 718 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, 1); | 850 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, 1); |
| 719 chrome::CloseAllBrowsersAndQuit(); | 851 chrome::CloseAllBrowsersAndQuit(); |
| 720 | 852 |
| (...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1147 | 1279 |
| 1148 chrome::CloseAllBrowsers(); | 1280 chrome::CloseAllBrowsers(); |
| 1149 EXPECT_FALSE(browser_shutdown::IsTryingToQuit()); | 1281 EXPECT_FALSE(browser_shutdown::IsTryingToQuit()); |
| 1150 EXPECT_TRUE(BrowserList::GetInstance()->empty()); | 1282 EXPECT_TRUE(BrowserList::GetInstance()->empty()); |
| 1151 EXPECT_TRUE(IsBackgroundModeSuspended()); | 1283 EXPECT_TRUE(IsBackgroundModeSuspended()); |
| 1152 } | 1284 } |
| 1153 | 1285 |
| 1154 INSTANTIATE_TEST_CASE_P(BrowserCloseManagerWithBackgroundModeBrowserTest, | 1286 INSTANTIATE_TEST_CASE_P(BrowserCloseManagerWithBackgroundModeBrowserTest, |
| 1155 BrowserCloseManagerWithBackgroundModeBrowserTest, | 1287 BrowserCloseManagerWithBackgroundModeBrowserTest, |
| 1156 testing::Bool()); | 1288 testing::Bool()); |
| OLD | NEW |