quit_with_apps_controller_mac_interactive_uitest.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
15c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Copyright 2014 The Chromium Authors. All rights reserved.
25c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Use of this source code is governed by a BSD-style license that can be
35c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// found in the LICENSE file.
45c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
55c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "chrome/browser/ui/cocoa/apps/quit_with_apps_controller_mac.h"
65c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
75c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "apps/app_window_registry.h"
85c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "apps/ui/native_app_window.h"
95c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/command_line.h"
10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/run_loop.h"
115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "chrome/browser/apps/app_browsertest_util.h"
125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "chrome/browser/browser_process.h"
13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chrome_browser_application_mac.h"
145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "chrome/browser/extensions/extension_service.h"
155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "chrome/browser/extensions/extension_test_message_listener.h"
165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "chrome/browser/lifetime/application_lifetime.h"
175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "chrome/browser/notifications/message_center_notification_manager.h"
185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "chrome/browser/notifications/notification_ui_manager.h"
195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "chrome/browser/profiles/profile.h"
205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "chrome/browser/ui/browser_iterator.h"
215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "chrome/browser/ui/browser_window.h"
225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "chrome/common/chrome_switches.h"
235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "content/public/browser/notification_service.h"
245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "content/public/test/test_utils.h"
255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "extensions/common/extension.h"
265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ui/message_center/message_center.h"
275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liutypedef apps::AppWindowRegistry::AppWindowList AppWindowList;
295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liunamespace {
315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuclass QuitWithAppsControllerInteractiveTest
335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    : public extensions::PlatformAppBrowserTest {
345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu protected:
355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  QuitWithAppsControllerInteractiveTest() : app_(NULL) {}
365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  virtual ~QuitWithAppsControllerInteractiveTest() {}
385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    PlatformAppBrowserTest::SetUpCommandLine(command_line);
415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    command_line->AppendSwitch(switches::kAppsKeepChromeAlive);
425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  const extensions::Extension* app_;
455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu private:
475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  DISALLOW_COPY_AND_ASSIGN(QuitWithAppsControllerInteractiveTest);
485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu};
495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}  // namespace
515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Test that quitting while apps are open shows a notification instead.
535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuIN_PROC_BROWSER_TEST_F(QuitWithAppsControllerInteractiveTest, QuitBehavior) {
545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scoped_refptr<QuitWithAppsController> controller =
555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      new QuitWithAppsController();
565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  const Notification* notification;
575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  message_center::MessageCenter* message_center =
585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      message_center::MessageCenter::Get();
59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // With no app windows open, ShouldQuit returns true.
61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(controller->ShouldQuit());
62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  notification = g_browser_process->notification_ui_manager()->FindById(
63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      QuitWithAppsController::kQuitWithAppsNotificationID);
64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(NULL, notification);
65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Open an app window.
67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ExtensionTestMessageListener listener("Launched", false);
68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  app_ = InstallAndLaunchPlatformApp("minimal_id");
69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ASSERT_TRUE(listener.WaitUntilSatisfied());
70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // One browser and one app window at this point.
725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_FALSE(chrome::BrowserIterator().done());
735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(apps::AppWindowRegistry::IsAppWindowRegisteredInAnyProfile(0));
745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // On the first quit, show notification.
765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_FALSE(controller->ShouldQuit());
775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(apps::AppWindowRegistry::IsAppWindowRegisteredInAnyProfile(0));
785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  notification = g_browser_process->notification_ui_manager()->FindById(
795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      QuitWithAppsController::kQuitWithAppsNotificationID);
805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  ASSERT_TRUE(notification);
815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // If notification was dismissed by click, show again on next quit.
835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  notification->delegate()->Click();
845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  message_center->RemoveAllNotifications(false);
855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_FALSE(controller->ShouldQuit());
865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(apps::AppWindowRegistry::IsAppWindowRegisteredInAnyProfile(0));
875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  notification = g_browser_process->notification_ui_manager()->FindById(
885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      QuitWithAppsController::kQuitWithAppsNotificationID);
895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  ASSERT_TRUE(notification);
905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_FALSE(chrome::BrowserIterator().done());
925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(apps::AppWindowRegistry::IsAppWindowRegisteredInAnyProfile(0));
935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // If notification is closed by user, don't show it next time.
955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  notification->delegate()->Close(true);
965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  message_center->RemoveAllNotifications(false);
975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_FALSE(controller->ShouldQuit());
985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(apps::AppWindowRegistry::IsAppWindowRegisteredInAnyProfile(0));
995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  notification = g_browser_process->notification_ui_manager()->FindById(
1005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      QuitWithAppsController::kQuitWithAppsNotificationID);
1015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ(NULL, notification);
1025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_FALSE(chrome::BrowserIterator().done());
1045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(apps::AppWindowRegistry::IsAppWindowRegisteredInAnyProfile(0));
1055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Quitting should not quit but close all browsers
1075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  content::WindowedNotificationObserver observer(
1085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      chrome::NOTIFICATION_BROWSER_CLOSED,
1095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      content::NotificationService::AllSources());
110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  chrome_browser_application_mac::Terminate();
1115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  observer.Wait();
1125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(chrome::BrowserIterator().done());
1145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(apps::AppWindowRegistry::IsAppWindowRegisteredInAnyProfile(0));
1155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Trying to quit while there are no browsers always shows notification.
1175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_FALSE(controller->ShouldQuit());
1185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  notification = g_browser_process->notification_ui_manager()->FindById(
1195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      QuitWithAppsController::kQuitWithAppsNotificationID);
1205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  ASSERT_TRUE(notification);
1215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Clicking "Quit All Apps." button closes all app windows. With no browsers
123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // open, this should also quit Chrome.
124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  content::WindowedNotificationObserver quit_observer(
125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      chrome::NOTIFICATION_APP_TERMINATING,
126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      content::NotificationService::AllSources());
1275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  notification->delegate()->ButtonClick(0);
1285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  message_center->RemoveAllNotifications(false);
1295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_FALSE(apps::AppWindowRegistry::IsAppWindowRegisteredInAnyProfile(0));
130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  quit_observer.Wait();
1315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
132