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. 4 5#include "chrome/browser/ui/cocoa/apps/quit_with_apps_controller_mac.h" 6 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" 26 27namespace { 28 29class QuitWithAppsControllerInteractiveTest 30 : public extensions::PlatformAppBrowserTest { 31 protected: 32 QuitWithAppsControllerInteractiveTest() : app_(NULL) {} 33 34 virtual ~QuitWithAppsControllerInteractiveTest() {} 35 36 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 37 PlatformAppBrowserTest::SetUpCommandLine(command_line); 38 command_line->AppendSwitch(switches::kAppsKeepChromeAliveInTests); 39 } 40 41 const extensions::Extension* app_; 42 43 private: 44 DISALLOW_COPY_AND_ASSIGN(QuitWithAppsControllerInteractiveTest); 45}; 46 47} // namespace 48 49// Test that quitting while apps are open shows a notification instead. 50IN_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(); 56 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); 62 63 // Open an app window. 64 ExtensionTestMessageListener listener("Launched", false); 65 app_ = InstallAndLaunchPlatformApp("minimal_id"); 66 ASSERT_TRUE(listener.WaitUntilSatisfied()); 67 68 // One browser and one app window at this point. 69 EXPECT_FALSE(chrome::BrowserIterator().done()); 70 EXPECT_TRUE(AppWindowRegistryUtil::IsAppWindowRegisteredInAnyProfile(0)); 71 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); 78 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); 87 88 EXPECT_FALSE(chrome::BrowserIterator().done()); 89 EXPECT_TRUE(AppWindowRegistryUtil::IsAppWindowRegisteredInAnyProfile(0)); 90 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); 99 100 EXPECT_FALSE(chrome::BrowserIterator().done()); 101 EXPECT_TRUE(AppWindowRegistryUtil::IsAppWindowRegisteredInAnyProfile(0)); 102 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(); 108 observer.Wait(); 109 110 EXPECT_TRUE(chrome::BrowserIterator().done()); 111 EXPECT_TRUE(AppWindowRegistryUtil::IsAppWindowRegisteredInAnyProfile(0)); 112 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); 118 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(); 128} 129