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
3 // found in the LICENSE file.
7 #include "base/command_line.h"
8 #include "chrome/browser/background/background_mode_manager.h"
9 #include "chrome/browser/browser_process.h"
10 #include "chrome/browser/browser_shutdown.h"
11 #include "chrome/browser/chrome_notification_types.h"
12 #include "chrome/browser/download/chrome_download_manager_delegate.h"
13 #include "chrome/browser/download/download_service.h"
14 #include "chrome/browser/download/download_service_factory.h"
15 #include "chrome/browser/lifetime/application_lifetime.h"
16 #include "chrome/browser/lifetime/browser_close_manager.h"
17 #include "chrome/browser/net/url_request_mock_util.h"
18 #include "chrome/browser/prefs/session_startup_pref.h"
19 #include "chrome/browser/profiles/profile.h"
20 #include "chrome/browser/profiles/profile_manager.h"
21 #include "chrome/browser/ui/app_modal_dialogs/javascript_app_modal_dialog.h"
22 #include "chrome/browser/ui/app_modal_dialogs/native_app_modal_dialog.h"
23 #include "chrome/browser/ui/browser.h"
24 #include "chrome/browser/ui/browser_commands.h"
25 #include "chrome/browser/ui/browser_iterator.h"
26 #include "chrome/browser/ui/browser_window.h"
27 #include "chrome/browser/ui/tabs/tab_strip_model.h"
28 #include "chrome/common/chrome_switches.h"
29 #include "chrome/common/url_constants.h"
30 #include "chrome/test/base/in_process_browser_test.h"
31 #include "chrome/test/base/ui_test_utils.h"
32 #include "content/public/browser/browser_context.h"
33 #include "content/public/browser/download_item.h"
34 #include "content/public/browser/download_manager.h"
35 #include "content/public/browser/notification_service.h"
36 #include "content/public/browser/web_contents.h"
37 #include "content/public/test/download_test_observer.h"
38 #include "content/public/test/test_navigation_observer.h"
39 #include "content/test/net/url_request_mock_http_job.h"
40 #include "content/test/net/url_request_slow_download_job.h"
41 #include "net/test/embedded_test_server/embedded_test_server.h"
45 class AppModalDialogObserver {
47 AppModalDialogObserver() {}
50 observer_.reset(new content::WindowedNotificationObserver(
51 chrome::NOTIFICATION_APP_MODAL_DIALOG_SHOWN,
52 content::NotificationService::AllSources()));
56 NativeAppModalDialog* dialog = GetNextDialog();
58 dialog->AcceptAppModalDialog();
62 NativeAppModalDialog* dialog = GetNextDialog();
64 dialog->CancelAppModalDialog();
68 NativeAppModalDialog* GetNextDialog() {
71 if (observer_->source() == content::NotificationService::AllSources())
74 AppModalDialog* dialog =
75 content::Source<AppModalDialog>(observer_->source()).ptr();
76 EXPECT_TRUE(dialog->IsJavaScriptModalDialog());
77 JavaScriptAppModalDialog* js_dialog =
78 static_cast<JavaScriptAppModalDialog*>(dialog);
79 observer_.reset(new content::WindowedNotificationObserver(
80 chrome::NOTIFICATION_APP_MODAL_DIALOG_SHOWN,
81 content::NotificationService::AllSources()));
82 return js_dialog->native_dialog();
85 scoped_ptr<content::WindowedNotificationObserver> observer_;
87 DISALLOW_COPY_AND_ASSIGN(AppModalDialogObserver);
90 class RepeatedNotificationObserver : public content::NotificationObserver {
92 explicit RepeatedNotificationObserver(int type, int count)
93 : num_outstanding_(count), running_(false) {
94 registrar_.Add(this, type, content::NotificationService::AllSources());
97 virtual void Observe(int type,
98 const content::NotificationSource& source,
99 const content::NotificationDetails& details) OVERRIDE {
100 ASSERT_GT(num_outstanding_, 0);
101 if (!--num_outstanding_ && running_) {
102 content::BrowserThread::PostTask(
103 content::BrowserThread::UI, FROM_HERE, run_loop_.QuitClosure());
108 if (num_outstanding_ <= 0)
117 int num_outstanding_;
118 content::NotificationRegistrar registrar_;
120 base::RunLoop run_loop_;
122 DISALLOW_COPY_AND_ASSIGN(RepeatedNotificationObserver);
125 class TestBrowserCloseManager : public BrowserCloseManager {
128 USER_CHOICE_USER_CANCELS_CLOSE,
129 USER_CHOICE_USER_ALLOWS_CLOSE,
133 static void AttemptClose(UserChoice user_choice) {
134 scoped_refptr<BrowserCloseManager> browser_close_manager =
135 new TestBrowserCloseManager(user_choice);
136 browser_shutdown::SetTryingToQuit(true);
137 browser_close_manager->StartClosingBrowsers();
141 virtual ~TestBrowserCloseManager() {}
143 virtual void ConfirmCloseWithPendingDownloads(
145 const base::Callback<void(bool)>& callback) OVERRIDE {
146 EXPECT_NE(NO_USER_CHOICE, user_choice_);
147 switch (user_choice_) {
149 case USER_CHOICE_USER_CANCELS_CLOSE: {
153 case USER_CHOICE_USER_ALLOWS_CLOSE: {
161 explicit TestBrowserCloseManager(UserChoice user_choice)
162 : user_choice_(user_choice) {}
164 UserChoice user_choice_;
166 DISALLOW_COPY_AND_ASSIGN(TestBrowserCloseManager);
169 class TestDownloadManagerDelegate : public ChromeDownloadManagerDelegate {
171 explicit TestDownloadManagerDelegate(Profile* profile)
172 : ChromeDownloadManagerDelegate(profile) {
173 SetNextId(content::DownloadItem::kInvalidId + 1);
176 virtual bool DetermineDownloadTarget(
177 content::DownloadItem* item,
178 const content::DownloadTargetCallback& callback) OVERRIDE {
179 content::DownloadTargetCallback dangerous_callback =
180 base::Bind(&TestDownloadManagerDelegate::SetDangerous, this, callback);
181 return ChromeDownloadManagerDelegate::DetermineDownloadTarget(
182 item, dangerous_callback);
186 const content::DownloadTargetCallback& callback,
187 const base::FilePath& target_path,
188 content::DownloadItem::TargetDisposition disp,
189 content::DownloadDangerType danger_type,
190 const base::FilePath& intermediate_path) {
191 callback.Run(target_path,
193 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL,
198 virtual ~TestDownloadManagerDelegate() {}
201 class FakeBackgroundModeManager : public BackgroundModeManager {
203 FakeBackgroundModeManager()
204 : BackgroundModeManager(
205 CommandLine::ForCurrentProcess(),
206 &g_browser_process->profile_manager()->GetProfileInfoCache()),
209 virtual void SuspendBackgroundMode() OVERRIDE {
210 BackgroundModeManager::SuspendBackgroundMode();
214 virtual void ResumeBackgroundMode() OVERRIDE {
215 BackgroundModeManager::ResumeBackgroundMode();
219 bool IsBackgroundModeSuspended() {
226 DISALLOW_COPY_AND_ASSIGN(FakeBackgroundModeManager);
231 class BrowserCloseManagerBrowserTest
232 : public InProcessBrowserTest,
233 public testing::WithParamInterface<bool> {
235 virtual void SetUpOnMainThread() OVERRIDE {
236 InProcessBrowserTest::SetUpOnMainThread();
237 SessionStartupPref::SetStartupPref(
238 browser()->profile(), SessionStartupPref(SessionStartupPref::LAST));
239 browsers_.push_back(browser());
241 content::BrowserThread::PostTask(
242 content::BrowserThread::IO,
244 base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled, true));
247 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
249 command_line->AppendSwitch(switches::kEnableFastUnload);
252 void CreateStalledDownload(Browser* browser) {
253 content::DownloadTestObserverInProgress observer(
254 content::BrowserContext::GetDownloadManager(browser->profile()), 1);
255 ui_test_utils::NavigateToURLWithDisposition(
257 GURL(content::URLRequestSlowDownloadJob::kKnownSizeUrl),
259 ui_test_utils::BROWSER_TEST_NONE);
260 observer.WaitForFinished();
263 observer.NumDownloadsSeenInState(content::DownloadItem::IN_PROGRESS));
266 std::vector<Browser*> browsers_;
267 AppModalDialogObserver dialogs_;
270 IN_PROC_BROWSER_TEST_P(BrowserCloseManagerBrowserTest, TestSingleTabShutdown) {
271 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
272 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
273 browser(), embedded_test_server()->GetURL("/beforeunload.html")));
274 RepeatedNotificationObserver cancel_observer(
275 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, 1);
276 chrome::CloseAllBrowsersAndQuit();
277 ASSERT_NO_FATAL_FAILURE(dialogs_.CancelClose());
278 cancel_observer.Wait();
279 EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
280 EXPECT_EQ(1, browser()->tab_strip_model()->count());
282 RepeatedNotificationObserver close_observer(
283 chrome::NOTIFICATION_BROWSER_CLOSED, 1);
284 chrome::CloseAllBrowsersAndQuit();
285 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
286 close_observer.Wait();
287 EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
288 EXPECT_TRUE(chrome::BrowserIterator().done());
291 IN_PROC_BROWSER_TEST_P(BrowserCloseManagerBrowserTest,
292 TestShutdownMoreThanOnce) {
293 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
294 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
295 browser(), embedded_test_server()->GetURL("/beforeunload.html")));
296 RepeatedNotificationObserver cancel_observer(
297 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, 1);
298 chrome::CloseAllBrowsersAndQuit();
299 chrome::CloseAllBrowsersAndQuit();
300 ASSERT_NO_FATAL_FAILURE(dialogs_.CancelClose());
301 cancel_observer.Wait();
302 EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
303 EXPECT_EQ(1, browser()->tab_strip_model()->count());
305 RepeatedNotificationObserver close_observer(
306 chrome::NOTIFICATION_BROWSER_CLOSED, 1);
307 chrome::CloseAllBrowsersAndQuit();
308 chrome::CloseAllBrowsersAndQuit();
309 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
310 close_observer.Wait();
311 EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
312 EXPECT_TRUE(chrome::BrowserIterator().done());
315 IN_PROC_BROWSER_TEST_P(BrowserCloseManagerBrowserTest, PRE_TestSessionRestore) {
316 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
317 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
318 browser(), embedded_test_server()->GetURL("/beforeunload.html")));
319 AddBlankTabAndShow(browser());
320 ASSERT_NO_FATAL_FAILURE(
321 ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIAboutURL)));
322 RepeatedNotificationObserver cancel_observer(
323 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, 1);
324 chrome::CloseAllBrowsersAndQuit();
325 ASSERT_NO_FATAL_FAILURE(dialogs_.CancelClose());
326 cancel_observer.Wait();
327 EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
329 browser()->tab_strip_model()
330 ->CloseWebContentsAt(1, TabStripModel::CLOSE_USER_GESTURE);
331 content::TestNavigationObserver navigation_observer(
332 browser()->tab_strip_model()->GetActiveWebContents(), 1);
333 ASSERT_NO_FATAL_FAILURE(
334 NavigateToURLWithDisposition(browser(),
335 GURL(chrome::kChromeUIVersionURL),
337 ui_test_utils::BROWSER_TEST_NONE));
338 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
339 navigation_observer.Wait();
341 RepeatedNotificationObserver close_observer(
342 chrome::NOTIFICATION_BROWSER_CLOSED, 1);
343 chrome::CloseAllBrowsersAndQuit();
344 close_observer.Wait();
345 EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
346 EXPECT_TRUE(chrome::BrowserIterator().done());
349 // Test that the tab closed after the aborted shutdown attempt is not re-opened
350 // when restoring the session.
351 IN_PROC_BROWSER_TEST_P(BrowserCloseManagerBrowserTest, TestSessionRestore) {
352 // The testing framework launches Chrome with about:blank as args.
353 EXPECT_EQ(2, browser()->tab_strip_model()->count());
354 EXPECT_EQ(GURL(chrome::kChromeUIVersionURL),
355 browser()->tab_strip_model()->GetWebContentsAt(0)->GetURL());
356 EXPECT_EQ(GURL("about:blank"),
357 browser()->tab_strip_model()->GetWebContentsAt(1)->GetURL());
360 // Test that browser windows are only closed if all browsers are ready to close
361 // and that all beforeunload dialogs are shown again after a cancel.
362 IN_PROC_BROWSER_TEST_P(BrowserCloseManagerBrowserTest, TestMultipleWindows) {
363 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
364 browsers_.push_back(CreateBrowser(browser()->profile()));
365 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
366 browsers_[0], embedded_test_server()->GetURL("/beforeunload.html")));
367 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
368 browsers_[1], embedded_test_server()->GetURL("/beforeunload.html")));
370 // Cancel shutdown on the first beforeunload event.
372 RepeatedNotificationObserver cancel_observer(
373 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, 1);
374 chrome::CloseAllBrowsersAndQuit();
375 ASSERT_NO_FATAL_FAILURE(dialogs_.CancelClose());
376 cancel_observer.Wait();
378 EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
379 EXPECT_EQ(1, browsers_[0]->tab_strip_model()->count());
380 EXPECT_EQ(1, browsers_[1]->tab_strip_model()->count());
382 // Cancel shutdown on the second beforeunload event.
384 RepeatedNotificationObserver cancel_observer(
385 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, 2);
386 chrome::CloseAllBrowsersAndQuit();
387 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
388 ASSERT_NO_FATAL_FAILURE(dialogs_.CancelClose());
389 cancel_observer.Wait();
391 EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
392 EXPECT_EQ(1, browsers_[0]->tab_strip_model()->count());
393 EXPECT_EQ(1, browsers_[1]->tab_strip_model()->count());
395 // Allow shutdown for both beforeunload events.
396 RepeatedNotificationObserver close_observer(
397 chrome::NOTIFICATION_BROWSER_CLOSED, 2);
398 chrome::CloseAllBrowsersAndQuit();
399 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
400 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
401 close_observer.Wait();
402 EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
403 EXPECT_TRUE(chrome::BrowserIterator().done());
406 // Test that tabs in the same window with a beforeunload event that hangs are
407 // treated the same as the user accepting the close, but do not close the tab
409 // Test is flaky on windows, disabled. See http://crbug.com/276366
411 #define MAYBE_TestHangInBeforeUnloadMultipleTabs \
412 DISABLED_TestHangInBeforeUnloadMultipleTabs
414 #define MAYBE_TestHangInBeforeUnloadMultipleTabs \
415 TestHangInBeforeUnloadMultipleTabs
417 IN_PROC_BROWSER_TEST_P(BrowserCloseManagerBrowserTest,
418 MAYBE_TestHangInBeforeUnloadMultipleTabs) {
419 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
420 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
421 browsers_[0], embedded_test_server()->GetURL("/beforeunload_hang.html")));
422 AddBlankTabAndShow(browsers_[0]);
423 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
424 browsers_[0], embedded_test_server()->GetURL("/beforeunload.html")));
425 AddBlankTabAndShow(browsers_[0]);
426 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
427 browsers_[0], embedded_test_server()->GetURL("/beforeunload_hang.html")));
429 RepeatedNotificationObserver cancel_observer(
430 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, 1);
431 chrome::CloseAllBrowsersAndQuit();
432 ASSERT_NO_FATAL_FAILURE(dialogs_.CancelClose());
433 cancel_observer.Wait();
434 EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
435 // All tabs should still be open.
436 EXPECT_EQ(3, browsers_[0]->tab_strip_model()->count());
438 RepeatedNotificationObserver close_observer(
439 chrome::NOTIFICATION_BROWSER_CLOSED, 1);
440 chrome::CloseAllBrowsersAndQuit();
441 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
442 close_observer.Wait();
443 EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
444 EXPECT_TRUE(chrome::BrowserIterator().done());
447 // Test that tabs in different windows with a beforeunload event that hangs are
448 // treated the same as the user accepting the close, but do not close the tab
450 IN_PROC_BROWSER_TEST_P(BrowserCloseManagerBrowserTest,
451 TestHangInBeforeUnloadMultipleWindows) {
452 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
453 browsers_.push_back(CreateBrowser(browser()->profile()));
454 browsers_.push_back(CreateBrowser(browser()->profile()));
455 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
456 browsers_[0], embedded_test_server()->GetURL("/beforeunload_hang.html")));
457 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
458 browsers_[1], embedded_test_server()->GetURL("/beforeunload.html")));
459 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
460 browsers_[2], embedded_test_server()->GetURL("/beforeunload_hang.html")));
462 RepeatedNotificationObserver cancel_observer(
463 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, 2);
464 chrome::CloseAllBrowsersAndQuit();
465 ASSERT_NO_FATAL_FAILURE(dialogs_.CancelClose());
466 cancel_observer.Wait();
467 EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
468 // All windows should still be open.
469 EXPECT_EQ(1, browsers_[0]->tab_strip_model()->count());
470 EXPECT_EQ(1, browsers_[1]->tab_strip_model()->count());
471 EXPECT_EQ(1, browsers_[2]->tab_strip_model()->count());
473 RepeatedNotificationObserver close_observer(
474 chrome::NOTIFICATION_BROWSER_CLOSED, 3);
475 chrome::CloseAllBrowsersAndQuit();
476 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
477 close_observer.Wait();
478 EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
479 EXPECT_TRUE(chrome::BrowserIterator().done());
482 // Test that a window created during shutdown is closed.
483 IN_PROC_BROWSER_TEST_P(BrowserCloseManagerBrowserTest,
484 TestAddWindowDuringShutdown) {
485 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
486 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
487 browsers_[0], embedded_test_server()->GetURL("/beforeunload.html")));
489 RepeatedNotificationObserver close_observer(
490 chrome::NOTIFICATION_BROWSER_CLOSED, 2);
491 chrome::CloseAllBrowsersAndQuit();
492 browsers_.push_back(CreateBrowser(browser()->profile()));
493 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
494 close_observer.Wait();
495 EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
496 EXPECT_TRUE(chrome::BrowserIterator().done());
499 // Test that a window created during shutdown with a beforeunload handler can
500 // cancel the shutdown.
501 IN_PROC_BROWSER_TEST_P(BrowserCloseManagerBrowserTest,
502 TestAddWindowWithBeforeUnloadDuringShutdown) {
503 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
504 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
505 browsers_[0], embedded_test_server()->GetURL("/beforeunload.html")));
507 RepeatedNotificationObserver cancel_observer(
508 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, 2);
509 chrome::CloseAllBrowsersAndQuit();
510 browsers_.push_back(CreateBrowser(browser()->profile()));
511 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
512 browsers_[1], embedded_test_server()->GetURL("/beforeunload.html")));
513 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
514 ASSERT_NO_FATAL_FAILURE(dialogs_.CancelClose());
515 cancel_observer.Wait();
516 EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
517 EXPECT_EQ(1, browsers_[0]->tab_strip_model()->count());
518 EXPECT_EQ(1, browsers_[1]->tab_strip_model()->count());
520 // Allow shutdown for both beforeunload dialogs.
521 RepeatedNotificationObserver close_observer(
522 chrome::NOTIFICATION_BROWSER_CLOSED, 2);
523 chrome::CloseAllBrowsersAndQuit();
524 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
525 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
526 close_observer.Wait();
527 EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
528 EXPECT_TRUE(chrome::BrowserIterator().done());
531 // Test that tabs added during shutdown are closed.
532 IN_PROC_BROWSER_TEST_P(BrowserCloseManagerBrowserTest,
533 TestAddTabDuringShutdown) {
534 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
535 browsers_.push_back(CreateBrowser(browser()->profile()));
536 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
537 browsers_[0], embedded_test_server()->GetURL("/beforeunload.html")));
538 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
539 browsers_[1], embedded_test_server()->GetURL("/beforeunload.html")));
541 RepeatedNotificationObserver close_observer(
542 chrome::NOTIFICATION_BROWSER_CLOSED, 2);
543 chrome::CloseAllBrowsersAndQuit();
544 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
545 AddBlankTabAndShow(browsers_[0]);
546 AddBlankTabAndShow(browsers_[1]);
547 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
548 close_observer.Wait();
549 EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
550 EXPECT_TRUE(chrome::BrowserIterator().done());
553 // Test that tabs created during shutdown with beforeunload handlers can cancel
555 IN_PROC_BROWSER_TEST_P(BrowserCloseManagerBrowserTest,
556 TestAddTabWithBeforeUnloadDuringShutdown) {
557 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
558 browsers_.push_back(CreateBrowser(browser()->profile()));
559 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
560 browsers_[0], embedded_test_server()->GetURL("/beforeunload.html")));
561 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
562 browsers_[1], embedded_test_server()->GetURL("/beforeunload.html")));
563 RepeatedNotificationObserver cancel_observer(
564 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, 2);
565 chrome::CloseAllBrowsersAndQuit();
566 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
567 AddBlankTabAndShow(browsers_[0]);
568 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
569 browsers_[0], embedded_test_server()->GetURL("/beforeunload.html")));
570 AddBlankTabAndShow(browsers_[1]);
571 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
572 browsers_[1], embedded_test_server()->GetURL("/beforeunload.html")));
573 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
574 ASSERT_NO_FATAL_FAILURE(dialogs_.CancelClose());
575 cancel_observer.Wait();
576 EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
577 EXPECT_EQ(2, browsers_[0]->tab_strip_model()->count());
578 EXPECT_EQ(2, browsers_[1]->tab_strip_model()->count());
580 RepeatedNotificationObserver close_observer(
581 chrome::NOTIFICATION_BROWSER_CLOSED, 2);
582 chrome::CloseAllBrowsersAndQuit();
583 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
584 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
585 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
586 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
588 close_observer.Wait();
589 EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
590 EXPECT_TRUE(chrome::BrowserIterator().done());
593 IN_PROC_BROWSER_TEST_P(BrowserCloseManagerBrowserTest,
594 TestCloseTabDuringShutdown) {
595 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
596 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
597 browsers_[0], embedded_test_server()->GetURL("/beforeunload.html")));
598 RepeatedNotificationObserver cancel_observer(
599 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, 1);
600 chrome::CloseAllBrowsersAndQuit();
602 browsers_.push_back(CreateBrowser(browser()->profile()));
603 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
604 browsers_[1], embedded_test_server()->GetURL("/beforeunload.html")));
605 browsers_[1]->tab_strip_model()->CloseAllTabs();
606 ASSERT_NO_FATAL_FAILURE(dialogs_.CancelClose());
607 ASSERT_NO_FATAL_FAILURE(dialogs_.CancelClose());
608 cancel_observer.Wait();
609 EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
610 EXPECT_EQ(1, browsers_[0]->tab_strip_model()->count());
611 EXPECT_EQ(1, browsers_[1]->tab_strip_model()->count());
613 RepeatedNotificationObserver close_observer(
614 chrome::NOTIFICATION_BROWSER_CLOSED, 2);
615 chrome::CloseAllBrowsersAndQuit();
616 browsers_[1]->tab_strip_model()->CloseAllTabs();
617 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
618 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
620 close_observer.Wait();
621 EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
622 EXPECT_TRUE(chrome::BrowserIterator().done());
625 // Test is flaky on windows, disabled. See http://crbug.com/276366
627 #define MAYBE_TestOpenAndCloseWindowDuringShutdown \
628 DISABLED_TestOpenAndCloseWindowDuringShutdown
630 #define MAYBE_TestOpenAndCloseWindowDuringShutdown \
631 TestOpenAndCloseWindowDuringShutdown
633 IN_PROC_BROWSER_TEST_P(BrowserCloseManagerBrowserTest,
634 MAYBE_TestOpenAndCloseWindowDuringShutdown) {
635 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
636 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
637 browsers_[0], embedded_test_server()->GetURL("/beforeunload.html")));
638 RepeatedNotificationObserver cancel_observer(
639 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, 2);
640 chrome::CloseAllBrowsersAndQuit();
642 browsers_.push_back(CreateBrowser(browser()->profile()));
643 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
644 browsers_[1], embedded_test_server()->GetURL("/beforeunload.html")));
645 ASSERT_FALSE(browsers_[1]->ShouldCloseWindow());
646 ASSERT_NO_FATAL_FAILURE(dialogs_.CancelClose());
647 ASSERT_NO_FATAL_FAILURE(dialogs_.CancelClose());
648 cancel_observer.Wait();
649 EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
650 EXPECT_EQ(1, browsers_[0]->tab_strip_model()->count());
651 EXPECT_EQ(1, browsers_[1]->tab_strip_model()->count());
653 RepeatedNotificationObserver close_observer(
654 chrome::NOTIFICATION_BROWSER_CLOSED, 2);
655 chrome::CloseAllBrowsersAndQuit();
656 ASSERT_FALSE(browsers_[1]->ShouldCloseWindow());
657 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
658 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
660 close_observer.Wait();
661 EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
662 EXPECT_TRUE(chrome::BrowserIterator().done());
665 IN_PROC_BROWSER_TEST_P(BrowserCloseManagerBrowserTest,
666 TestCloseWindowDuringShutdown) {
667 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
668 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
669 browsers_[0], embedded_test_server()->GetURL("/beforeunload.html")));
670 browsers_.push_back(CreateBrowser(browser()->profile()));
671 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
672 browsers_[1], embedded_test_server()->GetURL("/beforeunload.html")));
673 RepeatedNotificationObserver cancel_observer(
674 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, 1);
675 chrome::CloseAllBrowsersAndQuit();
677 ASSERT_FALSE(browsers_[0]->ShouldCloseWindow());
678 ASSERT_NO_FATAL_FAILURE(dialogs_.CancelClose());
679 cancel_observer.Wait();
680 EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
681 EXPECT_EQ(1, browsers_[0]->tab_strip_model()->count());
682 EXPECT_EQ(1, browsers_[1]->tab_strip_model()->count());
684 RepeatedNotificationObserver close_observer(
685 chrome::NOTIFICATION_BROWSER_CLOSED, 2);
686 chrome::CloseAllBrowsersAndQuit();
687 ASSERT_FALSE(browsers_[0]->ShouldCloseWindow());
688 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
689 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
691 close_observer.Wait();
692 EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
693 EXPECT_TRUE(chrome::BrowserIterator().done());
696 // Test shutdown with a DANGEROUS_URL download undecided.
697 IN_PROC_BROWSER_TEST_P(BrowserCloseManagerBrowserTest,
698 TestWithDangerousUrlDownload) {
699 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
701 // Set up the fake delegate that forces the download to be malicious.
702 scoped_refptr<TestDownloadManagerDelegate> test_delegate(
703 new TestDownloadManagerDelegate(browser()->profile()));
704 DownloadServiceFactory::GetForBrowserContext(browser()->profile())->
705 SetDownloadManagerDelegateForTesting(test_delegate.get());
707 // Run a dangerous download, but the user doesn't make a decision.
708 // This .swf normally would be categorized as DANGEROUS_FILE, but
709 // TestDownloadManagerDelegate turns it into DANGEROUS_URL.
710 base::FilePath file(FILE_PATH_LITERAL("downloads/dangerous/dangerous.swf"));
711 GURL download_url(content::URLRequestMockHTTPJob::GetMockUrl(file));
712 content::DownloadTestObserverInterrupted observer(
713 content::BrowserContext::GetDownloadManager(browser()->profile()),
715 content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_QUIT);
716 ui_test_utils::NavigateToURLWithDisposition(
720 ui_test_utils::BROWSER_TEST_NONE);
721 observer.WaitForFinished();
723 // Check that the download manager has the expected state.
724 EXPECT_EQ(1, content::BrowserContext::GetDownloadManager(
725 browser()->profile())->InProgressCount());
726 EXPECT_EQ(0, content::BrowserContext::GetDownloadManager(
727 browser()->profile())->NonMaliciousInProgressCount());
729 // Close the browser with no user action.
730 RepeatedNotificationObserver close_observer(
731 chrome::NOTIFICATION_BROWSER_CLOSED, 1);
732 TestBrowserCloseManager::AttemptClose(
733 TestBrowserCloseManager::NO_USER_CHOICE);
734 close_observer.Wait();
735 EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
736 EXPECT_TRUE(chrome::BrowserIterator().done());
739 // Test shutdown with a download in progress.
740 IN_PROC_BROWSER_TEST_P(BrowserCloseManagerBrowserTest, TestWithDownloads) {
741 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
742 ASSERT_NO_FATAL_FAILURE(CreateStalledDownload(browser()));
743 content::TestNavigationObserver navigation_observer(
744 browser()->tab_strip_model()->GetActiveWebContents(), 1);
745 TestBrowserCloseManager::AttemptClose(
746 TestBrowserCloseManager::USER_CHOICE_USER_CANCELS_CLOSE);
747 EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
748 navigation_observer.Wait();
749 EXPECT_EQ(GURL(chrome::kChromeUIDownloadsURL),
750 browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
752 RepeatedNotificationObserver close_observer(
753 chrome::NOTIFICATION_BROWSER_CLOSED, 1);
755 TestBrowserCloseManager::AttemptClose(
756 TestBrowserCloseManager::USER_CHOICE_USER_ALLOWS_CLOSE);
757 close_observer.Wait();
758 EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
759 EXPECT_TRUE(chrome::BrowserIterator().done());
762 // Test shutdown with a download in progress from one profile, where the only
763 // open windows are for another profile.
764 IN_PROC_BROWSER_TEST_P(BrowserCloseManagerBrowserTest,
765 TestWithDownloadsFromDifferentProfiles) {
766 ProfileManager* profile_manager = g_browser_process->profile_manager();
767 base::FilePath path =
768 profile_manager->user_data_dir().AppendASCII("test_profile");
769 if (!base::PathExists(path))
770 ASSERT_TRUE(file_util::CreateDirectory(path));
771 Profile* other_profile =
772 Profile::CreateProfile(path, NULL, Profile::CREATE_MODE_SYNCHRONOUS);
773 profile_manager->RegisterTestingProfile(other_profile, true, false);
774 Browser* other_profile_browser = CreateBrowser(other_profile);
776 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
777 ASSERT_NO_FATAL_FAILURE(CreateStalledDownload(browser()));
779 RepeatedNotificationObserver close_observer(
780 chrome::NOTIFICATION_BROWSER_CLOSED, 1);
781 browser()->window()->Close();
782 close_observer.Wait();
785 // When the shutdown is cancelled, the downloads page should be opened in a
786 // browser for that profile. Because there are no browsers for that profile, a
787 // new browser should be opened.
788 ui_test_utils::BrowserAddedObserver new_browser_observer;
789 TestBrowserCloseManager::AttemptClose(
790 TestBrowserCloseManager::USER_CHOICE_USER_CANCELS_CLOSE);
791 EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
792 Browser* opened_browser = new_browser_observer.WaitForSingleNewBrowser();
794 GURL(chrome::kChromeUIDownloadsURL),
795 opened_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
796 EXPECT_EQ(GURL("about:blank"),
797 other_profile_browser->tab_strip_model()->GetActiveWebContents()
800 RepeatedNotificationObserver close_observer(
801 chrome::NOTIFICATION_BROWSER_CLOSED, 2);
802 TestBrowserCloseManager::AttemptClose(
803 TestBrowserCloseManager::USER_CHOICE_USER_ALLOWS_CLOSE);
804 close_observer.Wait();
805 EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
806 EXPECT_TRUE(chrome::BrowserIterator().done());
809 // Test shutdown with downloads in progress and beforeunload handlers.
810 IN_PROC_BROWSER_TEST_P(BrowserCloseManagerBrowserTest,
811 TestBeforeUnloadAndDownloads) {
812 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
813 ASSERT_NO_FATAL_FAILURE(CreateStalledDownload(browser()));
814 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
815 browser(), embedded_test_server()->GetURL("/beforeunload.html")));
817 content::WindowedNotificationObserver cancel_observer(
818 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED,
819 content::NotificationService::AllSources());
820 TestBrowserCloseManager::AttemptClose(
821 TestBrowserCloseManager::USER_CHOICE_USER_CANCELS_CLOSE);
822 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
823 cancel_observer.Wait();
824 EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
826 RepeatedNotificationObserver close_observer(
827 chrome::NOTIFICATION_BROWSER_CLOSED, 1);
828 TestBrowserCloseManager::AttemptClose(
829 TestBrowserCloseManager::USER_CHOICE_USER_ALLOWS_CLOSE);
830 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
831 close_observer.Wait();
832 EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
833 EXPECT_TRUE(chrome::BrowserIterator().done());
836 INSTANTIATE_TEST_CASE_P(BrowserCloseManagerBrowserTest,
837 BrowserCloseManagerBrowserTest,
840 class BrowserCloseManagerWithBackgroundModeBrowserTest
841 : public BrowserCloseManagerBrowserTest {
843 BrowserCloseManagerWithBackgroundModeBrowserTest() {}
845 virtual void SetUpOnMainThread() OVERRIDE {
846 BrowserCloseManagerBrowserTest::SetUpOnMainThread();
847 g_browser_process->set_background_mode_manager_for_test(
848 scoped_ptr<BackgroundModeManager>(new FakeBackgroundModeManager));
851 bool IsBackgroundModeSuspended() {
852 return static_cast<FakeBackgroundModeManager*>(
853 g_browser_process->background_mode_manager())
854 ->IsBackgroundModeSuspended();
858 DISALLOW_COPY_AND_ASSIGN(BrowserCloseManagerWithBackgroundModeBrowserTest);
861 // Check that background mode is suspended when closing all browsers unless we
862 // are quitting and that background mode is resumed when a new browser window is
864 IN_PROC_BROWSER_TEST_P(BrowserCloseManagerWithBackgroundModeBrowserTest,
865 CloseAllBrowsersWithBackgroundMode) {
866 EXPECT_FALSE(IsBackgroundModeSuspended());
867 Profile* profile = browser()->profile();
869 RepeatedNotificationObserver close_observer(
870 chrome::NOTIFICATION_BROWSER_CLOSED, 1);
871 chrome::StartKeepAlive();
872 chrome::CloseAllBrowsers();
873 close_observer.Wait();
875 EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
876 EXPECT_TRUE(chrome::BrowserIterator().done());
877 EXPECT_TRUE(IsBackgroundModeSuspended());
879 // Background mode should be resumed when a new browser window is opened.
880 ui_test_utils::BrowserAddedObserver new_browser_observer;
881 chrome::NewEmptyWindow(profile, chrome::HOST_DESKTOP_TYPE_NATIVE);
882 new_browser_observer.WaitForSingleNewBrowser();
883 chrome::EndKeepAlive();
884 EXPECT_FALSE(IsBackgroundModeSuspended());
885 RepeatedNotificationObserver close_observer(
886 chrome::NOTIFICATION_BROWSER_CLOSED, 1);
888 // Background mode should not be suspended when quitting.
889 chrome::CloseAllBrowsersAndQuit();
890 close_observer.Wait();
891 EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
892 EXPECT_TRUE(chrome::BrowserIterator().done());
893 EXPECT_FALSE(IsBackgroundModeSuspended());
897 // Check that closing the last browser window individually does not affect
899 IN_PROC_BROWSER_TEST_P(BrowserCloseManagerWithBackgroundModeBrowserTest,
900 CloseSingleBrowserWithBackgroundMode) {
901 RepeatedNotificationObserver close_observer(
902 chrome::NOTIFICATION_BROWSER_CLOSED, 1);
903 EXPECT_FALSE(IsBackgroundModeSuspended());
904 browser()->window()->Close();
905 close_observer.Wait();
906 EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
907 EXPECT_TRUE(chrome::BrowserIterator().done());
908 EXPECT_FALSE(IsBackgroundModeSuspended());
911 // Check that closing all browsers with no browser windows open suspends
912 // background mode but does not cause Chrome to quit.
913 IN_PROC_BROWSER_TEST_P(BrowserCloseManagerWithBackgroundModeBrowserTest,
914 CloseAllBrowsersWithNoOpenBrowsersWithBackgroundMode) {
915 RepeatedNotificationObserver close_observer(
916 chrome::NOTIFICATION_BROWSER_CLOSED, 1);
917 EXPECT_FALSE(IsBackgroundModeSuspended());
918 chrome::StartKeepAlive();
919 browser()->window()->Close();
920 close_observer.Wait();
921 EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
922 EXPECT_TRUE(chrome::BrowserIterator().done());
923 EXPECT_FALSE(IsBackgroundModeSuspended());
925 chrome::CloseAllBrowsers();
926 EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
927 EXPECT_TRUE(chrome::BrowserIterator().done());
928 EXPECT_TRUE(IsBackgroundModeSuspended());
931 INSTANTIATE_TEST_CASE_P(BrowserCloseManagerWithBackgroundModeBrowserTest,
932 BrowserCloseManagerWithBackgroundModeBrowserTest,