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.
5 #include "apps/app_shim/app_shim_handler_mac.h"
9 #include "apps/shell_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"
25 void TerminateIfNoShellWindows() {
26 bool shell_windows_left
=
27 apps::ShellWindowRegistry::IsShellWindowRegisteredInAnyProfile(0);
28 if (!shell_windows_left
&& !AppListService::Get()->IsAppListVisible())
29 chrome::AttemptExit();
32 class AppShimHandlerRegistry
: public content::NotificationObserver
{
34 static AppShimHandlerRegistry
* GetInstance() {
35 return Singleton
<AppShimHandlerRegistry
,
36 LeakySingletonTraits
<AppShimHandlerRegistry
> >::get();
39 AppShimHandler
* GetForAppMode(const std::string
& app_mode_id
) const {
40 HandlerMap::const_iterator it
= handlers_
.find(app_mode_id
);
41 if (it
!= handlers_
.end())
44 return default_handler_
;
47 bool SetForAppMode(const std::string
& app_mode_id
, AppShimHandler
* handler
) {
48 bool inserted_or_removed
= handler
?
49 handlers_
.insert(HandlerMap::value_type(app_mode_id
, handler
)).second
:
50 handlers_
.erase(app_mode_id
) == 1;
51 DCHECK(inserted_or_removed
);
52 return inserted_or_removed
;
55 void SetDefaultHandler(AppShimHandler
* handler
) {
56 DCHECK_NE(default_handler_
== NULL
, handler
== NULL
);
57 default_handler_
= handler
;
60 void MaybeTerminate() {
61 if (!browser_opened_ever_
) {
62 // Post this to give ShellWindows a chance to remove themselves from the
64 base::MessageLoop::current()->PostTask(
66 base::Bind(&TerminateIfNoShellWindows
));
71 friend struct DefaultSingletonTraits
<AppShimHandlerRegistry
>;
72 typedef std::map
<std::string
, AppShimHandler
*> HandlerMap
;
74 AppShimHandlerRegistry()
75 : default_handler_(NULL
),
76 browser_opened_ever_(false) {
78 this, chrome::NOTIFICATION_BROWSER_OPENED
,
79 content::NotificationService::AllBrowserContextsAndSources());
82 virtual ~AppShimHandlerRegistry() {}
84 // content::NotificationObserver override:
87 const content::NotificationSource
& source
,
88 const content::NotificationDetails
& details
) OVERRIDE
{
89 DCHECK_EQ(chrome::NOTIFICATION_BROWSER_OPENED
, type
);
91 this, chrome::NOTIFICATION_BROWSER_OPENED
,
92 content::NotificationService::AllBrowserContextsAndSources());
93 browser_opened_ever_
= true;
97 AppShimHandler
* default_handler_
;
98 content::NotificationRegistrar registrar_
;
99 bool browser_opened_ever_
;
101 DISALLOW_COPY_AND_ASSIGN(AppShimHandlerRegistry
);
107 void AppShimHandler::RegisterHandler(const std::string
& app_mode_id
,
108 AppShimHandler
* handler
) {
110 AppShimHandlerRegistry::GetInstance()->SetForAppMode(app_mode_id
, handler
);
114 void AppShimHandler::RemoveHandler(const std::string
& app_mode_id
) {
115 AppShimHandlerRegistry::GetInstance()->SetForAppMode(app_mode_id
, NULL
);
119 AppShimHandler
* AppShimHandler::GetForAppMode(const std::string
& app_mode_id
) {
120 return AppShimHandlerRegistry::GetInstance()->GetForAppMode(app_mode_id
);
124 void AppShimHandler::SetDefaultHandler(AppShimHandler
* handler
) {
125 AppShimHandlerRegistry::GetInstance()->SetDefaultHandler(handler
);
129 void AppShimHandler::MaybeTerminate() {
130 AppShimHandlerRegistry::GetInstance()->MaybeTerminate();