1 // Copyright 2014 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 "chrome/browser/ui/cocoa/apps/quit_with_apps_controller_mac.h"
7 #include "base/command_line.h"
8 #include "base/run_loop.h"
9 #include "chrome/browser/apps/app_browsertest_util.h"
10 #include "chrome/browser/apps/app_window_registry_util.h"
11 #include "chrome/browser/browser_process.h"
12 #include "chrome/browser/chrome_browser_application_mac.h"
13 #include "chrome/browser/extensions/extension_service.h"
14 #include "chrome/browser/lifetime/application_lifetime.h"
15 #include "chrome/browser/notifications/message_center_notification_manager.h"
16 #include "chrome/browser/notifications/notification_ui_manager.h"
17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/ui/browser_iterator.h"
19 #include "chrome/browser/ui/browser_window.h"
20 #include "chrome/common/chrome_switches.h"
21 #include "content/public/browser/notification_service.h"
22 #include "content/public/test/test_utils.h"
23 #include "extensions/common/extension.h"
24 #include "extensions/test/extension_test_message_listener.h"
25 #include "ui/message_center/message_center.h"
29 class QuitWithAppsControllerInteractiveTest
30 : public extensions::PlatformAppBrowserTest {
32 QuitWithAppsControllerInteractiveTest() : app_(NULL) {}
34 virtual ~QuitWithAppsControllerInteractiveTest() {}
36 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
37 PlatformAppBrowserTest::SetUpCommandLine(command_line);
38 command_line->AppendSwitch(switches::kAppsKeepChromeAliveInTests);
41 const extensions::Extension* app_;
44 DISALLOW_COPY_AND_ASSIGN(QuitWithAppsControllerInteractiveTest);
49 // Test that quitting while apps are open shows a notification instead.
50 IN_PROC_BROWSER_TEST_F(QuitWithAppsControllerInteractiveTest, QuitBehavior) {
51 scoped_refptr<QuitWithAppsController> controller =
52 new QuitWithAppsController();
53 const Notification* notification;
54 message_center::MessageCenter* message_center =
55 message_center::MessageCenter::Get();
57 // With no app windows open, ShouldQuit returns true.
58 EXPECT_TRUE(controller->ShouldQuit());
59 notification = g_browser_process->notification_ui_manager()->FindById(
60 QuitWithAppsController::kQuitWithAppsNotificationID);
61 EXPECT_EQ(NULL, notification);
63 // Open an app window.
64 ExtensionTestMessageListener listener("Launched", false);
65 app_ = InstallAndLaunchPlatformApp("minimal_id");
66 ASSERT_TRUE(listener.WaitUntilSatisfied());
68 // One browser and one app window at this point.
69 EXPECT_FALSE(chrome::BrowserIterator().done());
70 EXPECT_TRUE(AppWindowRegistryUtil::IsAppWindowRegisteredInAnyProfile(0));
72 // On the first quit, show notification.
73 EXPECT_FALSE(controller->ShouldQuit());
74 EXPECT_TRUE(AppWindowRegistryUtil::IsAppWindowRegisteredInAnyProfile(0));
75 notification = g_browser_process->notification_ui_manager()->FindById(
76 QuitWithAppsController::kQuitWithAppsNotificationID);
77 ASSERT_TRUE(notification);
79 // If notification was dismissed by click, show again on next quit.
80 notification->delegate()->Click();
81 message_center->RemoveAllNotifications(false);
82 EXPECT_FALSE(controller->ShouldQuit());
83 EXPECT_TRUE(AppWindowRegistryUtil::IsAppWindowRegisteredInAnyProfile(0));
84 notification = g_browser_process->notification_ui_manager()->FindById(
85 QuitWithAppsController::kQuitWithAppsNotificationID);
86 ASSERT_TRUE(notification);
88 EXPECT_FALSE(chrome::BrowserIterator().done());
89 EXPECT_TRUE(AppWindowRegistryUtil::IsAppWindowRegisteredInAnyProfile(0));
91 // If notification is closed by user, don't show it next time.
92 notification->delegate()->Close(true);
93 message_center->RemoveAllNotifications(false);
94 EXPECT_FALSE(controller->ShouldQuit());
95 EXPECT_TRUE(AppWindowRegistryUtil::IsAppWindowRegisteredInAnyProfile(0));
96 notification = g_browser_process->notification_ui_manager()->FindById(
97 QuitWithAppsController::kQuitWithAppsNotificationID);
98 EXPECT_EQ(NULL, notification);
100 EXPECT_FALSE(chrome::BrowserIterator().done());
101 EXPECT_TRUE(AppWindowRegistryUtil::IsAppWindowRegisteredInAnyProfile(0));
103 // Quitting should not quit but close all browsers
104 content::WindowedNotificationObserver observer(
105 chrome::NOTIFICATION_BROWSER_CLOSED,
106 content::NotificationService::AllSources());
107 chrome_browser_application_mac::Terminate();
110 EXPECT_TRUE(chrome::BrowserIterator().done());
111 EXPECT_TRUE(AppWindowRegistryUtil::IsAppWindowRegisteredInAnyProfile(0));
113 // Trying to quit while there are no browsers always shows notification.
114 EXPECT_FALSE(controller->ShouldQuit());
115 notification = g_browser_process->notification_ui_manager()->FindById(
116 QuitWithAppsController::kQuitWithAppsNotificationID);
117 ASSERT_TRUE(notification);
119 // Clicking "Quit All Apps." button closes all app windows. With no browsers
120 // open, this should also quit Chrome.
121 content::WindowedNotificationObserver quit_observer(
122 chrome::NOTIFICATION_APP_TERMINATING,
123 content::NotificationService::AllSources());
124 notification->delegate()->ButtonClick(0);
125 message_center->RemoveAllNotifications(false);
126 EXPECT_FALSE(AppWindowRegistryUtil::IsAppWindowRegisteredInAnyProfile(0));
127 quit_observer.Wait();