cfbf4ffe1ec426795d681bf965b30a87bea3aeca
[platform/framework/web/crosswalk.git] / src / apps / app_shim / app_shim_handler_mac.cc
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 "apps/app_shim/app_shim_handler_mac.h"
6
7 #include <map>
8
9 #include "apps/app_window_registry.h"
10 #include "base/bind.h"
11 #include "base/logging.h"
12 #include "base/memory/singleton.h"
13 #include "base/message_loop/message_loop.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       apps::AppWindowRegistry::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_opened_ever_) {
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  private:
73   friend struct DefaultSingletonTraits<AppShimHandlerRegistry>;
74   typedef std::map<std::string, AppShimHandler*> HandlerMap;
75
76   AppShimHandlerRegistry()
77       : default_handler_(NULL),
78         browser_opened_ever_(false) {
79     registrar_.Add(
80         this, chrome::NOTIFICATION_BROWSER_OPENED,
81         content::NotificationService::AllBrowserContextsAndSources());
82   }
83
84   virtual ~AppShimHandlerRegistry() {}
85
86   // content::NotificationObserver override:
87   virtual void Observe(
88       int type,
89       const content::NotificationSource& source,
90       const content::NotificationDetails& details) OVERRIDE {
91     DCHECK_EQ(chrome::NOTIFICATION_BROWSER_OPENED, type);
92     registrar_.Remove(
93         this, chrome::NOTIFICATION_BROWSER_OPENED,
94         content::NotificationService::AllBrowserContextsAndSources());
95     browser_opened_ever_ = true;
96   }
97
98   HandlerMap handlers_;
99   AppShimHandler* default_handler_;
100   content::NotificationRegistrar registrar_;
101   bool browser_opened_ever_;
102
103   DISALLOW_COPY_AND_ASSIGN(AppShimHandlerRegistry);
104 };
105
106 }  // namespace
107
108 // static
109 void AppShimHandler::RegisterHandler(const std::string& app_mode_id,
110                                      AppShimHandler* handler) {
111   DCHECK(handler);
112   AppShimHandlerRegistry::GetInstance()->SetForAppMode(app_mode_id, handler);
113 }
114
115 // static
116 void AppShimHandler::RemoveHandler(const std::string& app_mode_id) {
117   AppShimHandlerRegistry::GetInstance()->SetForAppMode(app_mode_id, NULL);
118 }
119
120 // static
121 AppShimHandler* AppShimHandler::GetForAppMode(const std::string& app_mode_id) {
122   return AppShimHandlerRegistry::GetInstance()->GetForAppMode(app_mode_id);
123 }
124
125 // static
126 void AppShimHandler::SetDefaultHandler(AppShimHandler* handler) {
127   AppShimHandlerRegistry::GetInstance()->SetDefaultHandler(handler);
128 }
129
130 // static
131 void AppShimHandler::MaybeTerminate() {
132   AppShimHandlerRegistry::GetInstance()->MaybeTerminate();
133 }
134
135 }  // namespace apps