Home | History | Annotate | Download | only in app_shim
      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 "chrome/browser/apps/app_shim/app_shim_handler_mac.h"
      6 
      7 #include <map>
      8 
      9 #include "base/bind.h"
     10 #include "base/logging.h"
     11 #include "base/memory/singleton.h"
     12 #include "base/message_loop/message_loop.h"
     13 #include "chrome/browser/apps/app_window_registry_util.h"
     14 #include "chrome/browser/chrome_notification_types.h"
     15 #include "chrome/browser/lifetime/application_lifetime.h"
     16 #include "chrome/browser/ui/app_list/app_list_service.h"
     17 #include "content/public/browser/notification_observer.h"
     18 #include "content/public/browser/notification_registrar.h"
     19 #include "content/public/browser/notification_service.h"
     20 
     21 namespace apps {
     22 
     23 namespace {
     24 
     25 void TerminateIfNoAppWindows() {
     26   bool app_windows_left =
     27       AppWindowRegistryUtil::IsAppWindowRegisteredInAnyProfile(0);
     28   if (!app_windows_left &&
     29       !AppListService::Get(chrome::HOST_DESKTOP_TYPE_NATIVE)
     30            ->IsAppListVisible()) {
     31     chrome::AttemptExit();
     32   }
     33 }
     34 
     35 class AppShimHandlerRegistry : public content::NotificationObserver {
     36  public:
     37   static AppShimHandlerRegistry* GetInstance() {
     38     return Singleton<AppShimHandlerRegistry,
     39                      LeakySingletonTraits<AppShimHandlerRegistry> >::get();
     40   }
     41 
     42   AppShimHandler* GetForAppMode(const std::string& app_mode_id) const {
     43     HandlerMap::const_iterator it = handlers_.find(app_mode_id);
     44     if (it != handlers_.end())
     45       return it->second;
     46 
     47     return default_handler_;
     48   }
     49 
     50   bool SetForAppMode(const std::string& app_mode_id, AppShimHandler* handler) {
     51     bool inserted_or_removed = handler ?
     52         handlers_.insert(HandlerMap::value_type(app_mode_id, handler)).second :
     53         handlers_.erase(app_mode_id) == 1;
     54     DCHECK(inserted_or_removed);
     55     return inserted_or_removed;
     56   }
     57 
     58   void SetDefaultHandler(AppShimHandler* handler) {
     59     DCHECK_NE(default_handler_ == NULL, handler == NULL);
     60     default_handler_ = handler;
     61   }
     62 
     63   void MaybeTerminate() {
     64     if (!browser_session_running_) {
     65       // Post this to give AppWindows a chance to remove themselves from the
     66       // registry.
     67       base::MessageLoop::current()->PostTask(
     68           FROM_HERE, base::Bind(&TerminateIfNoAppWindows));
     69     }
     70   }
     71 
     72   bool ShouldRestoreSession() {
     73     return !browser_session_running_;
     74   }
     75 
     76  private:
     77   friend struct DefaultSingletonTraits<AppShimHandlerRegistry>;
     78   typedef std::map<std::string, AppShimHandler*> HandlerMap;
     79 
     80   AppShimHandlerRegistry()
     81       : default_handler_(NULL),
     82         browser_session_running_(false) {
     83     registrar_.Add(
     84         this, chrome::NOTIFICATION_BROWSER_OPENED,
     85         content::NotificationService::AllBrowserContextsAndSources());
     86     registrar_.Add(
     87         this, chrome::NOTIFICATION_CLOSE_ALL_BROWSERS_REQUEST,
     88         content::NotificationService::AllBrowserContextsAndSources());
     89     registrar_.Add(
     90         this, chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED,
     91         content::NotificationService::AllBrowserContextsAndSources());
     92   }
     93 
     94   virtual ~AppShimHandlerRegistry() {}
     95 
     96   // content::NotificationObserver override:
     97   virtual void Observe(
     98       int type,
     99       const content::NotificationSource& source,
    100       const content::NotificationDetails& details) OVERRIDE {
    101     switch (type) {
    102       case chrome::NOTIFICATION_BROWSER_OPENED:
    103       case chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED:
    104         browser_session_running_ = true;
    105         break;
    106       case chrome::NOTIFICATION_CLOSE_ALL_BROWSERS_REQUEST:
    107         browser_session_running_ = false;
    108         break;
    109       default:
    110         NOTREACHED();
    111     }
    112   }
    113 
    114   HandlerMap handlers_;
    115   AppShimHandler* default_handler_;
    116   content::NotificationRegistrar registrar_;
    117   bool browser_session_running_;
    118 
    119   DISALLOW_COPY_AND_ASSIGN(AppShimHandlerRegistry);
    120 };
    121 
    122 }  // namespace
    123 
    124 // static
    125 void AppShimHandler::RegisterHandler(const std::string& app_mode_id,
    126                                      AppShimHandler* handler) {
    127   DCHECK(handler);
    128   AppShimHandlerRegistry::GetInstance()->SetForAppMode(app_mode_id, handler);
    129 }
    130 
    131 // static
    132 void AppShimHandler::RemoveHandler(const std::string& app_mode_id) {
    133   AppShimHandlerRegistry::GetInstance()->SetForAppMode(app_mode_id, NULL);
    134 }
    135 
    136 // static
    137 AppShimHandler* AppShimHandler::GetForAppMode(const std::string& app_mode_id) {
    138   return AppShimHandlerRegistry::GetInstance()->GetForAppMode(app_mode_id);
    139 }
    140 
    141 // static
    142 void AppShimHandler::SetDefaultHandler(AppShimHandler* handler) {
    143   AppShimHandlerRegistry::GetInstance()->SetDefaultHandler(handler);
    144 }
    145 
    146 // static
    147 void AppShimHandler::MaybeTerminate() {
    148   AppShimHandlerRegistry::GetInstance()->MaybeTerminate();
    149 }
    150 
    151 // static
    152 bool AppShimHandler::ShouldRestoreSession() {
    153   return AppShimHandlerRegistry::GetInstance()->ShouldRestoreSession();
    154 }
    155 
    156 }  // namespace apps
    157