Home | History | Annotate | Download | only in apps
      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 
     27 namespace {
     28 
     29 class 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.
     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();
     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