Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / lifetime / browser_close_manager_browsertest.cc
blobdd3e1fde848f001e71b23bb533c890469741aebe
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.
5 #include <vector>
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/defaults.h"
13 #include "chrome/browser/download/chrome_download_manager_delegate.h"
14 #include "chrome/browser/download/download_service.h"
15 #include "chrome/browser/download/download_service_factory.h"
16 #include "chrome/browser/lifetime/application_lifetime.h"
17 #include "chrome/browser/lifetime/browser_close_manager.h"
18 #include "chrome/browser/net/url_request_mock_util.h"
19 #include "chrome/browser/prefs/session_startup_pref.h"
20 #include "chrome/browser/profiles/profile.h"
21 #include "chrome/browser/profiles/profile_manager.h"
22 #include "chrome/browser/ui/app_modal_dialogs/javascript_app_modal_dialog.h"
23 #include "chrome/browser/ui/app_modal_dialogs/native_app_modal_dialog.h"
24 #include "chrome/browser/ui/browser.h"
25 #include "chrome/browser/ui/browser_commands.h"
26 #include "chrome/browser/ui/browser_iterator.h"
27 #include "chrome/browser/ui/browser_window.h"
28 #include "chrome/browser/ui/tabs/tab_strip_model.h"
29 #include "chrome/common/chrome_switches.h"
30 #include "chrome/common/url_constants.h"
31 #include "chrome/test/base/in_process_browser_test.h"
32 #include "chrome/test/base/ui_test_utils.h"
33 #include "content/public/browser/browser_context.h"
34 #include "content/public/browser/download_item.h"
35 #include "content/public/browser/download_manager.h"
36 #include "content/public/browser/notification_service.h"
37 #include "content/public/browser/web_contents.h"
38 #include "content/public/test/download_test_observer.h"
39 #include "content/public/test/test_navigation_observer.h"
40 #include "content/test/net/url_request_mock_http_job.h"
41 #include "content/test/net/url_request_slow_download_job.h"
42 #include "net/test/embedded_test_server/embedded_test_server.h"
44 namespace {
46 class AppModalDialogObserver {
47 public:
48 AppModalDialogObserver() {}
50 void Start() {
51 observer_.reset(new content::WindowedNotificationObserver(
52 chrome::NOTIFICATION_APP_MODAL_DIALOG_SHOWN,
53 content::NotificationService::AllSources()));
56 void AcceptClose() {
57 NativeAppModalDialog* dialog = GetNextDialog();
58 ASSERT_TRUE(dialog);
59 dialog->AcceptAppModalDialog();
62 void CancelClose() {
63 NativeAppModalDialog* dialog = GetNextDialog();
64 ASSERT_TRUE(dialog);
65 dialog->CancelAppModalDialog();
68 private:
69 NativeAppModalDialog* GetNextDialog() {
70 DCHECK(observer_);
71 observer_->Wait();
72 if (observer_->source() == content::NotificationService::AllSources())
73 return NULL;
75 AppModalDialog* dialog =
76 content::Source<AppModalDialog>(observer_->source()).ptr();
77 EXPECT_TRUE(dialog->IsJavaScriptModalDialog());
78 JavaScriptAppModalDialog* js_dialog =
79 static_cast<JavaScriptAppModalDialog*>(dialog);
80 observer_.reset(new content::WindowedNotificationObserver(
81 chrome::NOTIFICATION_APP_MODAL_DIALOG_SHOWN,
82 content::NotificationService::AllSources()));
83 return js_dialog->native_dialog();
86 scoped_ptr<content::WindowedNotificationObserver> observer_;
88 DISALLOW_COPY_AND_ASSIGN(AppModalDialogObserver);
91 class RepeatedNotificationObserver : public content::NotificationObserver {
92 public:
93 explicit RepeatedNotificationObserver(int type, int count)
94 : num_outstanding_(count), running_(false) {
95 registrar_.Add(this, type, content::NotificationService::AllSources());
98 virtual void Observe(int type,
99 const content::NotificationSource& source,
100 const content::NotificationDetails& details) OVERRIDE {
101 ASSERT_GT(num_outstanding_, 0);
102 if (!--num_outstanding_ && running_) {
103 content::BrowserThread::PostTask(
104 content::BrowserThread::UI, FROM_HERE, run_loop_.QuitClosure());
108 void Wait() {
109 if (num_outstanding_ <= 0)
110 return;
112 running_ = true;
113 run_loop_.Run();
114 running_ = false;
117 private:
118 int num_outstanding_;
119 content::NotificationRegistrar registrar_;
120 bool running_;
121 base::RunLoop run_loop_;
123 DISALLOW_COPY_AND_ASSIGN(RepeatedNotificationObserver);
126 class TestBrowserCloseManager : public BrowserCloseManager {
127 public:
128 enum UserChoice {
129 USER_CHOICE_USER_CANCELS_CLOSE,
130 USER_CHOICE_USER_ALLOWS_CLOSE,
131 NO_USER_CHOICE
134 static void AttemptClose(UserChoice user_choice) {
135 scoped_refptr<BrowserCloseManager> browser_close_manager =
136 new TestBrowserCloseManager(user_choice);
137 browser_shutdown::SetTryingToQuit(true);
138 browser_close_manager->StartClosingBrowsers();
141 protected:
142 virtual ~TestBrowserCloseManager() {}
144 virtual void ConfirmCloseWithPendingDownloads(
145 int download_count,
146 const base::Callback<void(bool)>& callback) OVERRIDE {
147 EXPECT_NE(NO_USER_CHOICE, user_choice_);
148 switch (user_choice_) {
149 case NO_USER_CHOICE:
150 case USER_CHOICE_USER_CANCELS_CLOSE: {
151 callback.Run(false);
152 break;
154 case USER_CHOICE_USER_ALLOWS_CLOSE: {
155 callback.Run(true);
156 break;
161 private:
162 explicit TestBrowserCloseManager(UserChoice user_choice)
163 : user_choice_(user_choice) {}
165 UserChoice user_choice_;
167 DISALLOW_COPY_AND_ASSIGN(TestBrowserCloseManager);
170 class TestDownloadManagerDelegate : public ChromeDownloadManagerDelegate {
171 public:
172 explicit TestDownloadManagerDelegate(Profile* profile)
173 : ChromeDownloadManagerDelegate(profile) {
174 GetDownloadIdReceiverCallback().Run(content::DownloadItem::kInvalidId + 1);
176 virtual ~TestDownloadManagerDelegate() {}
178 virtual bool DetermineDownloadTarget(
179 content::DownloadItem* item,
180 const content::DownloadTargetCallback& callback) OVERRIDE {
181 content::DownloadTargetCallback dangerous_callback =
182 base::Bind(&TestDownloadManagerDelegate::SetDangerous, callback);
183 return ChromeDownloadManagerDelegate::DetermineDownloadTarget(
184 item, dangerous_callback);
187 static void SetDangerous(
188 const content::DownloadTargetCallback& callback,
189 const base::FilePath& target_path,
190 content::DownloadItem::TargetDisposition disp,
191 content::DownloadDangerType danger_type,
192 const base::FilePath& intermediate_path) {
193 callback.Run(target_path,
194 disp,
195 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL,
196 intermediate_path);
200 class FakeBackgroundModeManager : public BackgroundModeManager {
201 public:
202 FakeBackgroundModeManager()
203 : BackgroundModeManager(
204 CommandLine::ForCurrentProcess(),
205 &g_browser_process->profile_manager()->GetProfileInfoCache()),
206 suspended_(false) {}
208 virtual void SuspendBackgroundMode() OVERRIDE {
209 BackgroundModeManager::SuspendBackgroundMode();
210 suspended_ = true;
213 virtual void ResumeBackgroundMode() OVERRIDE {
214 BackgroundModeManager::ResumeBackgroundMode();
215 suspended_ = false;
218 bool IsBackgroundModeSuspended() {
219 return suspended_;
222 private:
223 bool suspended_;
225 DISALLOW_COPY_AND_ASSIGN(FakeBackgroundModeManager);
228 } // namespace
230 class BrowserCloseManagerBrowserTest
231 : public InProcessBrowserTest,
232 public testing::WithParamInterface<bool> {
233 protected:
234 virtual void SetUpOnMainThread() OVERRIDE {
235 InProcessBrowserTest::SetUpOnMainThread();
236 SessionStartupPref::SetStartupPref(
237 browser()->profile(), SessionStartupPref(SessionStartupPref::LAST));
238 browsers_.push_back(browser());
239 dialogs_.Start();
240 content::BrowserThread::PostTask(
241 content::BrowserThread::IO,
242 FROM_HERE,
243 base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled, true));
246 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
247 if (GetParam())
248 command_line->AppendSwitch(switches::kEnableFastUnload);
251 void CreateStalledDownload(Browser* browser) {
252 content::DownloadTestObserverInProgress observer(
253 content::BrowserContext::GetDownloadManager(browser->profile()), 1);
254 ui_test_utils::NavigateToURLWithDisposition(
255 browser,
256 GURL(content::URLRequestSlowDownloadJob::kKnownSizeUrl),
257 NEW_BACKGROUND_TAB,
258 ui_test_utils::BROWSER_TEST_NONE);
259 observer.WaitForFinished();
260 EXPECT_EQ(
261 1UL,
262 observer.NumDownloadsSeenInState(content::DownloadItem::IN_PROGRESS));
265 std::vector<Browser*> browsers_;
266 AppModalDialogObserver dialogs_;
269 IN_PROC_BROWSER_TEST_P(BrowserCloseManagerBrowserTest, TestSingleTabShutdown) {
270 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
271 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
272 browser(), embedded_test_server()->GetURL("/beforeunload.html")));
273 RepeatedNotificationObserver cancel_observer(
274 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, 1);
275 chrome::CloseAllBrowsersAndQuit();
276 ASSERT_NO_FATAL_FAILURE(dialogs_.CancelClose());
277 cancel_observer.Wait();
278 EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
279 EXPECT_EQ(1, browser()->tab_strip_model()->count());
281 RepeatedNotificationObserver close_observer(
282 chrome::NOTIFICATION_BROWSER_CLOSED, 1);
283 chrome::CloseAllBrowsersAndQuit();
284 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
285 close_observer.Wait();
286 EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
287 EXPECT_TRUE(chrome::BrowserIterator().done());
290 IN_PROC_BROWSER_TEST_P(BrowserCloseManagerBrowserTest,
291 TestShutdownMoreThanOnce) {
292 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
293 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
294 browser(), embedded_test_server()->GetURL("/beforeunload.html")));
295 RepeatedNotificationObserver cancel_observer(
296 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, 1);
297 chrome::CloseAllBrowsersAndQuit();
298 chrome::CloseAllBrowsersAndQuit();
299 ASSERT_NO_FATAL_FAILURE(dialogs_.CancelClose());
300 cancel_observer.Wait();
301 EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
302 EXPECT_EQ(1, browser()->tab_strip_model()->count());
304 RepeatedNotificationObserver close_observer(
305 chrome::NOTIFICATION_BROWSER_CLOSED, 1);
306 chrome::CloseAllBrowsersAndQuit();
307 chrome::CloseAllBrowsersAndQuit();
308 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
309 close_observer.Wait();
310 EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
311 EXPECT_TRUE(chrome::BrowserIterator().done());
314 IN_PROC_BROWSER_TEST_P(BrowserCloseManagerBrowserTest, PRE_TestSessionRestore) {
315 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
316 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
317 browser(), embedded_test_server()->GetURL("/beforeunload.html")));
318 AddBlankTabAndShow(browser());
319 ASSERT_NO_FATAL_FAILURE(
320 ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIAboutURL)));
321 RepeatedNotificationObserver cancel_observer(
322 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, 1);
323 chrome::CloseAllBrowsersAndQuit();
324 ASSERT_NO_FATAL_FAILURE(dialogs_.CancelClose());
325 cancel_observer.Wait();
326 EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
328 browser()->tab_strip_model()
329 ->CloseWebContentsAt(1, TabStripModel::CLOSE_USER_GESTURE);
330 content::TestNavigationObserver navigation_observer(
331 browser()->tab_strip_model()->GetActiveWebContents(), 1);
332 ASSERT_NO_FATAL_FAILURE(
333 NavigateToURLWithDisposition(browser(),
334 GURL(chrome::kChromeUIVersionURL),
335 CURRENT_TAB,
336 ui_test_utils::BROWSER_TEST_NONE));
337 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
338 navigation_observer.Wait();
340 RepeatedNotificationObserver close_observer(
341 chrome::NOTIFICATION_BROWSER_CLOSED, 1);
342 chrome::CloseAllBrowsersAndQuit();
343 close_observer.Wait();
344 EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
345 EXPECT_TRUE(chrome::BrowserIterator().done());
348 // Test that the tab closed after the aborted shutdown attempt is not re-opened
349 // when restoring the session.
350 IN_PROC_BROWSER_TEST_P(BrowserCloseManagerBrowserTest, TestSessionRestore) {
351 // The testing framework launches Chrome with about:blank as args.
352 EXPECT_EQ(2, browser()->tab_strip_model()->count());
353 EXPECT_EQ(GURL(chrome::kChromeUIVersionURL),
354 browser()->tab_strip_model()->GetWebContentsAt(0)->GetURL());
355 EXPECT_EQ(GURL("about:blank"),
356 browser()->tab_strip_model()->GetWebContentsAt(1)->GetURL());
359 // Test that browser windows are only closed if all browsers are ready to close
360 // and that all beforeunload dialogs are shown again after a cancel.
361 IN_PROC_BROWSER_TEST_P(BrowserCloseManagerBrowserTest, TestMultipleWindows) {
362 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
363 browsers_.push_back(CreateBrowser(browser()->profile()));
364 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
365 browsers_[0], embedded_test_server()->GetURL("/beforeunload.html")));
366 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
367 browsers_[1], embedded_test_server()->GetURL("/beforeunload.html")));
369 // Cancel shutdown on the first beforeunload event.
371 RepeatedNotificationObserver cancel_observer(
372 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, 1);
373 chrome::CloseAllBrowsersAndQuit();
374 ASSERT_NO_FATAL_FAILURE(dialogs_.CancelClose());
375 cancel_observer.Wait();
377 EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
378 EXPECT_EQ(1, browsers_[0]->tab_strip_model()->count());
379 EXPECT_EQ(1, browsers_[1]->tab_strip_model()->count());
381 // Cancel shutdown on the second beforeunload event.
383 RepeatedNotificationObserver cancel_observer(
384 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, 2);
385 chrome::CloseAllBrowsersAndQuit();
386 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
387 ASSERT_NO_FATAL_FAILURE(dialogs_.CancelClose());
388 cancel_observer.Wait();
390 EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
391 EXPECT_EQ(1, browsers_[0]->tab_strip_model()->count());
392 EXPECT_EQ(1, browsers_[1]->tab_strip_model()->count());
394 // Allow shutdown for both beforeunload events.
395 RepeatedNotificationObserver close_observer(
396 chrome::NOTIFICATION_BROWSER_CLOSED, 2);
397 chrome::CloseAllBrowsersAndQuit();
398 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
399 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
400 close_observer.Wait();
401 EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
402 EXPECT_TRUE(chrome::BrowserIterator().done());
405 // Test that tabs in the same window with a beforeunload event that hangs are
406 // treated the same as the user accepting the close, but do not close the tab
407 // early.
408 // Test is flaky on windows, disabled. See http://crbug.com/276366
409 #if defined(OS_WIN)
410 #define MAYBE_TestHangInBeforeUnloadMultipleTabs \
411 DISABLED_TestHangInBeforeUnloadMultipleTabs
412 #else
413 #define MAYBE_TestHangInBeforeUnloadMultipleTabs \
414 TestHangInBeforeUnloadMultipleTabs
415 #endif
416 IN_PROC_BROWSER_TEST_P(BrowserCloseManagerBrowserTest,
417 MAYBE_TestHangInBeforeUnloadMultipleTabs) {
418 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
419 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
420 browsers_[0], embedded_test_server()->GetURL("/beforeunload_hang.html")));
421 AddBlankTabAndShow(browsers_[0]);
422 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
423 browsers_[0], embedded_test_server()->GetURL("/beforeunload.html")));
424 AddBlankTabAndShow(browsers_[0]);
425 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
426 browsers_[0], embedded_test_server()->GetURL("/beforeunload_hang.html")));
428 RepeatedNotificationObserver cancel_observer(
429 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, 1);
430 chrome::CloseAllBrowsersAndQuit();
431 ASSERT_NO_FATAL_FAILURE(dialogs_.CancelClose());
432 cancel_observer.Wait();
433 EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
434 // All tabs should still be open.
435 EXPECT_EQ(3, browsers_[0]->tab_strip_model()->count());
437 RepeatedNotificationObserver close_observer(
438 chrome::NOTIFICATION_BROWSER_CLOSED, 1);
439 chrome::CloseAllBrowsersAndQuit();
440 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
441 close_observer.Wait();
442 EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
443 EXPECT_TRUE(chrome::BrowserIterator().done());
446 // Test that tabs in different windows with a beforeunload event that hangs are
447 // treated the same as the user accepting the close, but do not close the tab
448 // early.
449 IN_PROC_BROWSER_TEST_P(BrowserCloseManagerBrowserTest,
450 TestHangInBeforeUnloadMultipleWindows) {
451 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
452 browsers_.push_back(CreateBrowser(browser()->profile()));
453 browsers_.push_back(CreateBrowser(browser()->profile()));
454 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
455 browsers_[0], embedded_test_server()->GetURL("/beforeunload_hang.html")));
456 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
457 browsers_[1], embedded_test_server()->GetURL("/beforeunload.html")));
458 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
459 browsers_[2], embedded_test_server()->GetURL("/beforeunload_hang.html")));
461 RepeatedNotificationObserver cancel_observer(
462 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, 2);
463 chrome::CloseAllBrowsersAndQuit();
464 ASSERT_NO_FATAL_FAILURE(dialogs_.CancelClose());
465 cancel_observer.Wait();
466 EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
467 // All windows should still be open.
468 EXPECT_EQ(1, browsers_[0]->tab_strip_model()->count());
469 EXPECT_EQ(1, browsers_[1]->tab_strip_model()->count());
470 EXPECT_EQ(1, browsers_[2]->tab_strip_model()->count());
472 RepeatedNotificationObserver close_observer(
473 chrome::NOTIFICATION_BROWSER_CLOSED, 3);
474 chrome::CloseAllBrowsersAndQuit();
475 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
476 close_observer.Wait();
477 EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
478 EXPECT_TRUE(chrome::BrowserIterator().done());
481 // Test that a window created during shutdown is closed.
482 IN_PROC_BROWSER_TEST_P(BrowserCloseManagerBrowserTest,
483 TestAddWindowDuringShutdown) {
484 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
485 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
486 browsers_[0], embedded_test_server()->GetURL("/beforeunload.html")));
488 RepeatedNotificationObserver close_observer(
489 chrome::NOTIFICATION_BROWSER_CLOSED, 2);
490 chrome::CloseAllBrowsersAndQuit();
491 browsers_.push_back(CreateBrowser(browser()->profile()));
492 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
493 close_observer.Wait();
494 EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
495 EXPECT_TRUE(chrome::BrowserIterator().done());
498 // Test that a window created during shutdown with a beforeunload handler can
499 // cancel the shutdown.
500 IN_PROC_BROWSER_TEST_P(BrowserCloseManagerBrowserTest,
501 TestAddWindowWithBeforeUnloadDuringShutdown) {
502 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
503 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
504 browsers_[0], embedded_test_server()->GetURL("/beforeunload.html")));
506 RepeatedNotificationObserver cancel_observer(
507 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, 2);
508 chrome::CloseAllBrowsersAndQuit();
509 browsers_.push_back(CreateBrowser(browser()->profile()));
510 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
511 browsers_[1], embedded_test_server()->GetURL("/beforeunload.html")));
512 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
513 ASSERT_NO_FATAL_FAILURE(dialogs_.CancelClose());
514 cancel_observer.Wait();
515 EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
516 EXPECT_EQ(1, browsers_[0]->tab_strip_model()->count());
517 EXPECT_EQ(1, browsers_[1]->tab_strip_model()->count());
519 // Allow shutdown for both beforeunload dialogs.
520 RepeatedNotificationObserver close_observer(
521 chrome::NOTIFICATION_BROWSER_CLOSED, 2);
522 chrome::CloseAllBrowsersAndQuit();
523 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
524 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
525 close_observer.Wait();
526 EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
527 EXPECT_TRUE(chrome::BrowserIterator().done());
530 // Test that tabs added during shutdown are closed.
531 IN_PROC_BROWSER_TEST_P(BrowserCloseManagerBrowserTest,
532 TestAddTabDuringShutdown) {
533 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
534 browsers_.push_back(CreateBrowser(browser()->profile()));
535 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
536 browsers_[0], embedded_test_server()->GetURL("/beforeunload.html")));
537 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
538 browsers_[1], embedded_test_server()->GetURL("/beforeunload.html")));
540 RepeatedNotificationObserver close_observer(
541 chrome::NOTIFICATION_BROWSER_CLOSED, 2);
542 chrome::CloseAllBrowsersAndQuit();
543 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
544 AddBlankTabAndShow(browsers_[0]);
545 AddBlankTabAndShow(browsers_[1]);
546 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
547 close_observer.Wait();
548 EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
549 EXPECT_TRUE(chrome::BrowserIterator().done());
552 // Test that tabs created during shutdown with beforeunload handlers can cancel
553 // the shutdown.
554 IN_PROC_BROWSER_TEST_P(BrowserCloseManagerBrowserTest,
555 TestAddTabWithBeforeUnloadDuringShutdown) {
556 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
557 browsers_.push_back(CreateBrowser(browser()->profile()));
558 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
559 browsers_[0], embedded_test_server()->GetURL("/beforeunload.html")));
560 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
561 browsers_[1], embedded_test_server()->GetURL("/beforeunload.html")));
562 RepeatedNotificationObserver cancel_observer(
563 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, 2);
564 chrome::CloseAllBrowsersAndQuit();
565 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
566 AddBlankTabAndShow(browsers_[0]);
567 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
568 browsers_[0], embedded_test_server()->GetURL("/beforeunload.html")));
569 AddBlankTabAndShow(browsers_[1]);
570 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
571 browsers_[1], embedded_test_server()->GetURL("/beforeunload.html")));
572 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
573 ASSERT_NO_FATAL_FAILURE(dialogs_.CancelClose());
574 cancel_observer.Wait();
575 EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
576 EXPECT_EQ(2, browsers_[0]->tab_strip_model()->count());
577 EXPECT_EQ(2, browsers_[1]->tab_strip_model()->count());
579 RepeatedNotificationObserver close_observer(
580 chrome::NOTIFICATION_BROWSER_CLOSED, 2);
581 chrome::CloseAllBrowsersAndQuit();
582 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
583 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
584 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
585 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
587 close_observer.Wait();
588 EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
589 EXPECT_TRUE(chrome::BrowserIterator().done());
592 IN_PROC_BROWSER_TEST_P(BrowserCloseManagerBrowserTest,
593 TestCloseTabDuringShutdown) {
594 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
595 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
596 browsers_[0], embedded_test_server()->GetURL("/beforeunload.html")));
597 RepeatedNotificationObserver cancel_observer(
598 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, 1);
599 chrome::CloseAllBrowsersAndQuit();
601 browsers_.push_back(CreateBrowser(browser()->profile()));
602 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
603 browsers_[1], embedded_test_server()->GetURL("/beforeunload.html")));
604 browsers_[1]->tab_strip_model()->CloseAllTabs();
605 ASSERT_NO_FATAL_FAILURE(dialogs_.CancelClose());
606 ASSERT_NO_FATAL_FAILURE(dialogs_.CancelClose());
607 cancel_observer.Wait();
608 EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
609 EXPECT_EQ(1, browsers_[0]->tab_strip_model()->count());
610 EXPECT_EQ(1, browsers_[1]->tab_strip_model()->count());
612 RepeatedNotificationObserver close_observer(
613 chrome::NOTIFICATION_BROWSER_CLOSED, 2);
614 chrome::CloseAllBrowsersAndQuit();
615 browsers_[1]->tab_strip_model()->CloseAllTabs();
616 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
617 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
619 close_observer.Wait();
620 EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
621 EXPECT_TRUE(chrome::BrowserIterator().done());
624 // Test is flaky on windows, disabled. See http://crbug.com/276366
625 #if defined(OS_WIN)
626 #define MAYBE_TestOpenAndCloseWindowDuringShutdown \
627 DISABLED_TestOpenAndCloseWindowDuringShutdown
628 #else
629 #define MAYBE_TestOpenAndCloseWindowDuringShutdown \
630 TestOpenAndCloseWindowDuringShutdown
631 #endif
632 IN_PROC_BROWSER_TEST_P(BrowserCloseManagerBrowserTest,
633 MAYBE_TestOpenAndCloseWindowDuringShutdown) {
634 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
635 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
636 browsers_[0], embedded_test_server()->GetURL("/beforeunload.html")));
637 RepeatedNotificationObserver cancel_observer(
638 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, 2);
639 chrome::CloseAllBrowsersAndQuit();
641 browsers_.push_back(CreateBrowser(browser()->profile()));
642 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
643 browsers_[1], embedded_test_server()->GetURL("/beforeunload.html")));
644 ASSERT_FALSE(browsers_[1]->ShouldCloseWindow());
645 ASSERT_NO_FATAL_FAILURE(dialogs_.CancelClose());
646 ASSERT_NO_FATAL_FAILURE(dialogs_.CancelClose());
647 cancel_observer.Wait();
648 EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
649 EXPECT_EQ(1, browsers_[0]->tab_strip_model()->count());
650 EXPECT_EQ(1, browsers_[1]->tab_strip_model()->count());
652 RepeatedNotificationObserver close_observer(
653 chrome::NOTIFICATION_BROWSER_CLOSED, 2);
654 chrome::CloseAllBrowsersAndQuit();
655 ASSERT_FALSE(browsers_[1]->ShouldCloseWindow());
656 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
657 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
659 close_observer.Wait();
660 EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
661 EXPECT_TRUE(chrome::BrowserIterator().done());
664 IN_PROC_BROWSER_TEST_P(BrowserCloseManagerBrowserTest,
665 TestCloseWindowDuringShutdown) {
666 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
667 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
668 browsers_[0], embedded_test_server()->GetURL("/beforeunload.html")));
669 browsers_.push_back(CreateBrowser(browser()->profile()));
670 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
671 browsers_[1], embedded_test_server()->GetURL("/beforeunload.html")));
672 RepeatedNotificationObserver cancel_observer(
673 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, 1);
674 chrome::CloseAllBrowsersAndQuit();
676 ASSERT_FALSE(browsers_[0]->ShouldCloseWindow());
677 ASSERT_NO_FATAL_FAILURE(dialogs_.CancelClose());
678 cancel_observer.Wait();
679 EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
680 EXPECT_EQ(1, browsers_[0]->tab_strip_model()->count());
681 EXPECT_EQ(1, browsers_[1]->tab_strip_model()->count());
683 RepeatedNotificationObserver close_observer(
684 chrome::NOTIFICATION_BROWSER_CLOSED, 2);
685 chrome::CloseAllBrowsersAndQuit();
686 ASSERT_FALSE(browsers_[0]->ShouldCloseWindow());
687 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
688 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
690 close_observer.Wait();
691 EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
692 EXPECT_TRUE(chrome::BrowserIterator().done());
695 // Test shutdown with a DANGEROUS_URL download undecided.
696 IN_PROC_BROWSER_TEST_P(BrowserCloseManagerBrowserTest,
697 TestWithDangerousUrlDownload) {
698 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
700 // Set up the fake delegate that forces the download to be malicious.
701 scoped_ptr<TestDownloadManagerDelegate> test_delegate(
702 new TestDownloadManagerDelegate(browser()->profile()));
703 DownloadServiceFactory::GetForBrowserContext(browser()->profile())->
704 SetDownloadManagerDelegateForTesting(
705 test_delegate.PassAs<ChromeDownloadManagerDelegate>());
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(
717 browser(),
718 GURL(download_url),
719 NEW_BACKGROUND_TAB,
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());
760 if (browser_defaults::kBrowserAliveWithNoWindows)
761 EXPECT_EQ(1, DownloadService::NonMaliciousDownloadCountAllProfiles());
762 else
763 EXPECT_EQ(0, DownloadService::NonMaliciousDownloadCountAllProfiles());
766 // Test shutdown with a download in progress from one profile, where the only
767 // open windows are for another profile.
768 IN_PROC_BROWSER_TEST_P(BrowserCloseManagerBrowserTest,
769 TestWithDownloadsFromDifferentProfiles) {
770 ProfileManager* profile_manager = g_browser_process->profile_manager();
771 base::FilePath path =
772 profile_manager->user_data_dir().AppendASCII("test_profile");
773 if (!base::PathExists(path))
774 ASSERT_TRUE(base::CreateDirectory(path));
775 Profile* other_profile =
776 Profile::CreateProfile(path, NULL, Profile::CREATE_MODE_SYNCHRONOUS);
777 profile_manager->RegisterTestingProfile(other_profile, true, false);
778 Browser* other_profile_browser = CreateBrowser(other_profile);
780 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
781 ASSERT_NO_FATAL_FAILURE(CreateStalledDownload(browser()));
783 RepeatedNotificationObserver close_observer(
784 chrome::NOTIFICATION_BROWSER_CLOSED, 1);
785 browser()->window()->Close();
786 close_observer.Wait();
789 // When the shutdown is cancelled, the downloads page should be opened in a
790 // browser for that profile. Because there are no browsers for that profile, a
791 // new browser should be opened.
792 ui_test_utils::BrowserAddedObserver new_browser_observer;
793 TestBrowserCloseManager::AttemptClose(
794 TestBrowserCloseManager::USER_CHOICE_USER_CANCELS_CLOSE);
795 EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
796 Browser* opened_browser = new_browser_observer.WaitForSingleNewBrowser();
797 EXPECT_EQ(
798 GURL(chrome::kChromeUIDownloadsURL),
799 opened_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
800 EXPECT_EQ(GURL("about:blank"),
801 other_profile_browser->tab_strip_model()->GetActiveWebContents()
802 ->GetURL());
804 RepeatedNotificationObserver close_observer(
805 chrome::NOTIFICATION_BROWSER_CLOSED, 2);
806 TestBrowserCloseManager::AttemptClose(
807 TestBrowserCloseManager::USER_CHOICE_USER_ALLOWS_CLOSE);
808 close_observer.Wait();
809 EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
810 EXPECT_TRUE(chrome::BrowserIterator().done());
811 if (browser_defaults::kBrowserAliveWithNoWindows)
812 EXPECT_EQ(1, DownloadService::NonMaliciousDownloadCountAllProfiles());
813 else
814 EXPECT_EQ(0, DownloadService::NonMaliciousDownloadCountAllProfiles());
817 // Test shutdown with downloads in progress and beforeunload handlers.
818 // Disabled, see http://crbug.com/315754.
819 IN_PROC_BROWSER_TEST_P(BrowserCloseManagerBrowserTest,
820 DISABLED_TestBeforeUnloadAndDownloads) {
821 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
822 ASSERT_NO_FATAL_FAILURE(CreateStalledDownload(browser()));
823 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
824 browser(), embedded_test_server()->GetURL("/beforeunload.html")));
826 content::WindowedNotificationObserver cancel_observer(
827 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED,
828 content::NotificationService::AllSources());
829 TestBrowserCloseManager::AttemptClose(
830 TestBrowserCloseManager::USER_CHOICE_USER_CANCELS_CLOSE);
831 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
832 cancel_observer.Wait();
833 EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
835 RepeatedNotificationObserver close_observer(
836 chrome::NOTIFICATION_BROWSER_CLOSED, 1);
837 TestBrowserCloseManager::AttemptClose(
838 TestBrowserCloseManager::USER_CHOICE_USER_ALLOWS_CLOSE);
839 ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
840 close_observer.Wait();
841 EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
842 EXPECT_TRUE(chrome::BrowserIterator().done());
845 INSTANTIATE_TEST_CASE_P(BrowserCloseManagerBrowserTest,
846 BrowserCloseManagerBrowserTest,
847 testing::Bool());
849 class BrowserCloseManagerWithBackgroundModeBrowserTest
850 : public BrowserCloseManagerBrowserTest {
851 public:
852 BrowserCloseManagerWithBackgroundModeBrowserTest() {}
854 virtual void SetUpOnMainThread() OVERRIDE {
855 BrowserCloseManagerBrowserTest::SetUpOnMainThread();
856 g_browser_process->set_background_mode_manager_for_test(
857 scoped_ptr<BackgroundModeManager>(new FakeBackgroundModeManager));
860 bool IsBackgroundModeSuspended() {
861 return static_cast<FakeBackgroundModeManager*>(
862 g_browser_process->background_mode_manager())
863 ->IsBackgroundModeSuspended();
866 private:
867 DISALLOW_COPY_AND_ASSIGN(BrowserCloseManagerWithBackgroundModeBrowserTest);
870 // Check that background mode is suspended when closing all browsers unless we
871 // are quitting and that background mode is resumed when a new browser window is
872 // opened.
873 IN_PROC_BROWSER_TEST_P(BrowserCloseManagerWithBackgroundModeBrowserTest,
874 CloseAllBrowsersWithBackgroundMode) {
875 EXPECT_FALSE(IsBackgroundModeSuspended());
876 Profile* profile = browser()->profile();
878 RepeatedNotificationObserver close_observer(
879 chrome::NOTIFICATION_BROWSER_CLOSED, 1);
880 chrome::StartKeepAlive();
881 chrome::CloseAllBrowsers();
882 close_observer.Wait();
884 EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
885 EXPECT_TRUE(chrome::BrowserIterator().done());
886 EXPECT_TRUE(IsBackgroundModeSuspended());
888 // Background mode should be resumed when a new browser window is opened.
889 ui_test_utils::BrowserAddedObserver new_browser_observer;
890 chrome::NewEmptyWindow(profile, chrome::HOST_DESKTOP_TYPE_NATIVE);
891 new_browser_observer.WaitForSingleNewBrowser();
892 chrome::EndKeepAlive();
893 EXPECT_FALSE(IsBackgroundModeSuspended());
894 RepeatedNotificationObserver close_observer(
895 chrome::NOTIFICATION_BROWSER_CLOSED, 1);
897 // Background mode should not be suspended when quitting.
898 chrome::CloseAllBrowsersAndQuit();
899 close_observer.Wait();
900 EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
901 EXPECT_TRUE(chrome::BrowserIterator().done());
902 EXPECT_FALSE(IsBackgroundModeSuspended());
906 // Check that closing the last browser window individually does not affect
907 // background mode.
908 IN_PROC_BROWSER_TEST_P(BrowserCloseManagerWithBackgroundModeBrowserTest,
909 CloseSingleBrowserWithBackgroundMode) {
910 RepeatedNotificationObserver close_observer(
911 chrome::NOTIFICATION_BROWSER_CLOSED, 1);
912 EXPECT_FALSE(IsBackgroundModeSuspended());
913 browser()->window()->Close();
914 close_observer.Wait();
915 EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
916 EXPECT_TRUE(chrome::BrowserIterator().done());
917 EXPECT_FALSE(IsBackgroundModeSuspended());
920 // Check that closing all browsers with no browser windows open suspends
921 // background mode but does not cause Chrome to quit.
922 IN_PROC_BROWSER_TEST_P(BrowserCloseManagerWithBackgroundModeBrowserTest,
923 CloseAllBrowsersWithNoOpenBrowsersWithBackgroundMode) {
924 RepeatedNotificationObserver close_observer(
925 chrome::NOTIFICATION_BROWSER_CLOSED, 1);
926 EXPECT_FALSE(IsBackgroundModeSuspended());
927 chrome::StartKeepAlive();
928 browser()->window()->Close();
929 close_observer.Wait();
930 EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
931 EXPECT_TRUE(chrome::BrowserIterator().done());
932 EXPECT_FALSE(IsBackgroundModeSuspended());
934 chrome::CloseAllBrowsers();
935 EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
936 EXPECT_TRUE(chrome::BrowserIterator().done());
937 EXPECT_TRUE(IsBackgroundModeSuspended());
940 INSTANTIATE_TEST_CASE_P(BrowserCloseManagerWithBackgroundModeBrowserTest,
941 BrowserCloseManagerWithBackgroundModeBrowserTest,
942 testing::Bool());