- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / lifetime / browser_close_manager_browsertest.cc
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.
4
5 #include <vector>
6
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"
42
43 namespace {
44
45 class AppModalDialogObserver {
46  public:
47   AppModalDialogObserver() {}
48
49   void Start() {
50     observer_.reset(new content::WindowedNotificationObserver(
51         chrome::NOTIFICATION_APP_MODAL_DIALOG_SHOWN,
52         content::NotificationService::AllSources()));
53   }
54
55   void AcceptClose() {
56     NativeAppModalDialog* dialog = GetNextDialog();
57     ASSERT_TRUE(dialog);
58     dialog->AcceptAppModalDialog();
59   }
60
61   void CancelClose() {
62     NativeAppModalDialog* dialog = GetNextDialog();
63     ASSERT_TRUE(dialog);
64     dialog->CancelAppModalDialog();
65   }
66
67  private:
68   NativeAppModalDialog* GetNextDialog() {
69     DCHECK(observer_);
70     observer_->Wait();
71     if (observer_->source() == content::NotificationService::AllSources())
72       return NULL;
73
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();
83   }
84
85   scoped_ptr<content::WindowedNotificationObserver> observer_;
86
87   DISALLOW_COPY_AND_ASSIGN(AppModalDialogObserver);
88 };
89
90 class RepeatedNotificationObserver : public content::NotificationObserver {
91  public:
92   explicit RepeatedNotificationObserver(int type, int count)
93       : num_outstanding_(count), running_(false) {
94     registrar_.Add(this, type, content::NotificationService::AllSources());
95   }
96
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());
104     }
105   }
106
107   void Wait() {
108     if (num_outstanding_ <= 0)
109       return;
110
111     running_ = true;
112     run_loop_.Run();
113     running_ = false;
114   }
115
116  private:
117   int num_outstanding_;
118   content::NotificationRegistrar registrar_;
119   bool running_;
120   base::RunLoop run_loop_;
121
122   DISALLOW_COPY_AND_ASSIGN(RepeatedNotificationObserver);
123 };
124
125 class TestBrowserCloseManager : public BrowserCloseManager {
126  public:
127   enum UserChoice {
128     USER_CHOICE_USER_CANCELS_CLOSE,
129     USER_CHOICE_USER_ALLOWS_CLOSE,
130     NO_USER_CHOICE
131   };
132
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();
138   }
139
140  protected:
141   virtual ~TestBrowserCloseManager() {}
142
143   virtual void ConfirmCloseWithPendingDownloads(
144       int download_count,
145       const base::Callback<void(bool)>& callback) OVERRIDE {
146     EXPECT_NE(NO_USER_CHOICE, user_choice_);
147     switch (user_choice_) {
148       case NO_USER_CHOICE:
149       case USER_CHOICE_USER_CANCELS_CLOSE: {
150         callback.Run(false);
151         break;
152       }
153       case USER_CHOICE_USER_ALLOWS_CLOSE: {
154         callback.Run(true);
155         break;
156       }
157     }
158   }
159
160  private:
161   explicit TestBrowserCloseManager(UserChoice user_choice)
162       : user_choice_(user_choice) {}
163
164   UserChoice user_choice_;
165
166   DISALLOW_COPY_AND_ASSIGN(TestBrowserCloseManager);
167 };
168
169 class TestDownloadManagerDelegate : public ChromeDownloadManagerDelegate {
170  public:
171   explicit TestDownloadManagerDelegate(Profile* profile)
172       : ChromeDownloadManagerDelegate(profile) {
173     SetNextId(content::DownloadItem::kInvalidId + 1);
174   }
175
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);
183   }
184
185   void SetDangerous(
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,
192                  disp,
193                  content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL,
194                  intermediate_path);
195   }
196
197  private:
198   virtual ~TestDownloadManagerDelegate() {}
199 };
200
201 class FakeBackgroundModeManager : public BackgroundModeManager {
202  public:
203   FakeBackgroundModeManager()
204       : BackgroundModeManager(
205             CommandLine::ForCurrentProcess(),
206             &g_browser_process->profile_manager()->GetProfileInfoCache()),
207         suspended_(false) {}
208
209   virtual void SuspendBackgroundMode() OVERRIDE {
210     BackgroundModeManager::SuspendBackgroundMode();
211     suspended_ = true;
212   }
213
214   virtual void ResumeBackgroundMode() OVERRIDE {
215     BackgroundModeManager::ResumeBackgroundMode();
216     suspended_ = false;
217   }
218
219   bool IsBackgroundModeSuspended() {
220     return suspended_;
221   }
222
223  private:
224   bool suspended_;
225
226   DISALLOW_COPY_AND_ASSIGN(FakeBackgroundModeManager);
227 };
228
229 }  // namespace
230
231 class BrowserCloseManagerBrowserTest
232     : public InProcessBrowserTest,
233       public testing::WithParamInterface<bool> {
234  protected:
235   virtual void SetUpOnMainThread() OVERRIDE {
236     InProcessBrowserTest::SetUpOnMainThread();
237     SessionStartupPref::SetStartupPref(
238         browser()->profile(), SessionStartupPref(SessionStartupPref::LAST));
239     browsers_.push_back(browser());
240     dialogs_.Start();
241     content::BrowserThread::PostTask(
242         content::BrowserThread::IO,
243         FROM_HERE,
244         base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled, true));
245   }
246
247   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
248     if (GetParam())
249       command_line->AppendSwitch(switches::kEnableFastUnload);
250   }
251
252   void CreateStalledDownload(Browser* browser) {
253     content::DownloadTestObserverInProgress observer(
254         content::BrowserContext::GetDownloadManager(browser->profile()), 1);
255     ui_test_utils::NavigateToURLWithDisposition(
256         browser,
257         GURL(content::URLRequestSlowDownloadJob::kKnownSizeUrl),
258         NEW_BACKGROUND_TAB,
259         ui_test_utils::BROWSER_TEST_NONE);
260     observer.WaitForFinished();
261     EXPECT_EQ(
262         1UL,
263         observer.NumDownloadsSeenInState(content::DownloadItem::IN_PROGRESS));
264   }
265
266   std::vector<Browser*> browsers_;
267   AppModalDialogObserver dialogs_;
268 };
269
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());
281
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());
289 }
290
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());
304
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());
313 }
314
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());
328
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),
336                                    CURRENT_TAB,
337                                    ui_test_utils::BROWSER_TEST_NONE));
338   ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
339   navigation_observer.Wait();
340
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());
347 }
348
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());
358 }
359
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")));
369
370   // Cancel shutdown on the first beforeunload event.
371   {
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();
377   }
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());
381
382   // Cancel shutdown on the second beforeunload event.
383   {
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();
390   }
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());
394
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());
404 }
405
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
408 // early.
409 // Test is flaky on windows, disabled. See http://crbug.com/276366
410 #if defined(OS_WIN)
411 #define MAYBE_TestHangInBeforeUnloadMultipleTabs \
412     DISABLED_TestHangInBeforeUnloadMultipleTabs
413 #else
414 #define MAYBE_TestHangInBeforeUnloadMultipleTabs \
415     TestHangInBeforeUnloadMultipleTabs
416 #endif
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")));
428
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());
437
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());
445 }
446
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
449 // early.
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")));
461
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());
472
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());
480 }
481
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")));
488
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());
497 }
498
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")));
506
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());
519
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());
529 }
530
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")));
540
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());
551 }
552
553 // Test that tabs created during shutdown with beforeunload handlers can cancel
554 // the shutdown.
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());
579
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());
587
588   close_observer.Wait();
589   EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
590   EXPECT_TRUE(chrome::BrowserIterator().done());
591 }
592
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();
601
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());
612
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());
619
620   close_observer.Wait();
621   EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
622   EXPECT_TRUE(chrome::BrowserIterator().done());
623 }
624
625 // Test is flaky on windows, disabled. See http://crbug.com/276366
626 #if defined(OS_WIN)
627 #define MAYBE_TestOpenAndCloseWindowDuringShutdown \
628     DISABLED_TestOpenAndCloseWindowDuringShutdown
629 #else
630 #define MAYBE_TestOpenAndCloseWindowDuringShutdown \
631     TestOpenAndCloseWindowDuringShutdown
632 #endif
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();
641
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());
652
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());
659
660   close_observer.Wait();
661   EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
662   EXPECT_TRUE(chrome::BrowserIterator().done());
663 }
664
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();
676
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());
683
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());
690
691   close_observer.Wait();
692   EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
693   EXPECT_TRUE(chrome::BrowserIterator().done());
694 }
695
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());
700
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());
706
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()),
714       1,
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();
722
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());
728
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());
737 }
738
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());
751
752   RepeatedNotificationObserver close_observer(
753       chrome::NOTIFICATION_BROWSER_CLOSED, 1);
754
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 }
761
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);
775
776   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
777   ASSERT_NO_FATAL_FAILURE(CreateStalledDownload(browser()));
778   {
779     RepeatedNotificationObserver close_observer(
780         chrome::NOTIFICATION_BROWSER_CLOSED, 1);
781     browser()->window()->Close();
782     close_observer.Wait();
783   }
784
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();
793   EXPECT_EQ(
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()
798                 ->GetURL());
799
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());
807 }
808
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")));
816
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());
825
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());
834 }
835
836 INSTANTIATE_TEST_CASE_P(BrowserCloseManagerBrowserTest,
837                         BrowserCloseManagerBrowserTest,
838                         testing::Bool());
839
840 class BrowserCloseManagerWithBackgroundModeBrowserTest
841     : public BrowserCloseManagerBrowserTest {
842  public:
843   BrowserCloseManagerWithBackgroundModeBrowserTest() {}
844
845   virtual void SetUpOnMainThread() OVERRIDE {
846     BrowserCloseManagerBrowserTest::SetUpOnMainThread();
847     g_browser_process->set_background_mode_manager_for_test(
848         scoped_ptr<BackgroundModeManager>(new FakeBackgroundModeManager));
849   }
850
851   bool IsBackgroundModeSuspended() {
852     return static_cast<FakeBackgroundModeManager*>(
853         g_browser_process->background_mode_manager())
854         ->IsBackgroundModeSuspended();
855   }
856
857  private:
858   DISALLOW_COPY_AND_ASSIGN(BrowserCloseManagerWithBackgroundModeBrowserTest);
859 };
860
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
863 // opened.
864 IN_PROC_BROWSER_TEST_P(BrowserCloseManagerWithBackgroundModeBrowserTest,
865                        CloseAllBrowsersWithBackgroundMode) {
866   EXPECT_FALSE(IsBackgroundModeSuspended());
867   Profile* profile = browser()->profile();
868   {
869     RepeatedNotificationObserver close_observer(
870         chrome::NOTIFICATION_BROWSER_CLOSED, 1);
871     chrome::StartKeepAlive();
872     chrome::CloseAllBrowsers();
873     close_observer.Wait();
874   }
875   EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
876   EXPECT_TRUE(chrome::BrowserIterator().done());
877   EXPECT_TRUE(IsBackgroundModeSuspended());
878
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);
887
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());
894
895 }
896
897 // Check that closing the last browser window individually does not affect
898 // background mode.
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());
909 }
910
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());
924
925   chrome::CloseAllBrowsers();
926   EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
927   EXPECT_TRUE(chrome::BrowserIterator().done());
928   EXPECT_TRUE(IsBackgroundModeSuspended());
929 }
930
931 INSTANTIATE_TEST_CASE_P(BrowserCloseManagerWithBackgroundModeBrowserTest,
932                         BrowserCloseManagerWithBackgroundModeBrowserTest,
933                         testing::Bool());