OLD | NEW |
| (Empty) |
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 "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/chrome_notification_types.h" | |
14 #include "chrome/browser/lifetime/application_lifetime.h" | |
15 #include "chrome/browser/ui/app_list/app_list_service.h" | |
16 #include "content/public/browser/notification_observer.h" | |
17 #include "content/public/browser/notification_registrar.h" | |
18 #include "content/public/browser/notification_service.h" | |
19 #include "extensions/browser/app_window/app_window_registry.h" | |
20 | |
21 namespace apps { | |
22 | |
23 namespace { | |
24 | |
25 void TerminateIfNoAppWindows() { | |
26 bool app_windows_left = | |
27 extensions::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_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 | |
OLD | NEW |