OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "apps/app_shim/extension_app_shim_handler_mac.h" | 5 #include "apps/app_shim/extension_app_shim_handler_mac.h" |
6 | 6 |
7 #include "apps/app_shim/app_shim_messages.h" | 7 #include "apps/app_shim/app_shim_messages.h" |
8 #include "base/files/file_path.h" | 8 #include "base/files/file_path.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "chrome/browser/extensions/extension_host.h" | 10 #include "chrome/browser/extensions/extension_host.h" |
11 #include "chrome/browser/extensions/extension_service.h" | 11 #include "chrome/browser/extensions/extension_service.h" |
12 #include "chrome/browser/extensions/extension_system.h" | 12 #include "chrome/browser/extensions/extension_system.h" |
13 #include "chrome/browser/extensions/shell_window_registry.h" | 13 #include "chrome/browser/extensions/shell_window_registry.h" |
14 #include "chrome/browser/ui/extensions/application_launch.h" | 14 #include "chrome/browser/ui/extensions/application_launch.h" |
15 #include "chrome/browser/ui/extensions/native_app_window.h" | 15 #include "chrome/browser/ui/extensions/native_app_window.h" |
16 #include "chrome/browser/ui/extensions/shell_window.h" | 16 #include "chrome/browser/ui/extensions/shell_window.h" |
| 17 #include "chrome/browser/ui/web_applications/web_app_ui.h" |
| 18 #include "chrome/browser/web_applications/web_app_mac.h" |
17 #include "ui/base/cocoa/focus_window_set.h" | 19 #include "ui/base/cocoa/focus_window_set.h" |
18 | 20 |
19 namespace apps { | 21 namespace apps { |
20 | 22 |
21 ExtensionAppShimHandler::ExtensionAppShimHandler() {} | 23 ExtensionAppShimHandler::ExtensionAppShimHandler() { |
| 24 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_CREATED, |
| 25 content::NotificationService::AllBrowserContextsAndSources()); |
| 26 } |
22 | 27 |
23 ExtensionAppShimHandler::~ExtensionAppShimHandler() { | 28 ExtensionAppShimHandler::~ExtensionAppShimHandler() { |
24 for (HostMap::iterator it = hosts_.begin(); it != hosts_.end(); ) { | 29 for (HostMap::iterator it = hosts_.begin(); it != hosts_.end(); ) { |
25 // Increment the iterator first as OnAppClosed may call back to OnShimClose | 30 // Increment the iterator first as OnAppClosed may call back to OnShimClose |
26 // and invalidate the iterator. | 31 // and invalidate the iterator. |
27 it++->second->OnAppClosed(); | 32 it++->second->OnAppClosed(); |
28 } | 33 } |
29 } | 34 } |
30 | 35 |
31 bool ExtensionAppShimHandler::OnShimLaunch(Host* host) { | 36 bool ExtensionAppShimHandler::OnShimLaunch(Host* host, |
| 37 AppShimLaunchType launch_type) { |
32 Profile* profile = host->GetProfile(); | 38 Profile* profile = host->GetProfile(); |
33 DCHECK(profile); | 39 DCHECK(profile); |
34 | 40 |
35 const std::string& app_id = host->GetAppId(); | 41 const std::string& app_id = host->GetAppId(); |
36 if (!extensions::Extension::IdIsValid(app_id)) { | 42 if (!extensions::Extension::IdIsValid(app_id)) { |
37 LOG(ERROR) << "Bad app ID from app shim launch message."; | 43 LOG(ERROR) << "Bad app ID from app shim launch message."; |
38 return false; | 44 return false; |
39 } | 45 } |
40 | 46 |
41 if (!LaunchApp(profile, app_id)) | 47 if (!LaunchApp(profile, app_id, launch_type)) |
42 return false; | 48 return false; |
43 | 49 |
44 // The first host to claim this (profile, app_id) becomes the main host. | 50 // The first host to claim this (profile, app_id) becomes the main host. |
45 // For any others, we launch the app but return false. | 51 // For any others, we focus the app and return false. |
46 if (!hosts_.insert(make_pair(make_pair(profile, app_id), host)).second) | 52 if (!hosts_.insert(make_pair(make_pair(profile, app_id), host)).second) { |
| 53 OnShimFocus(host); |
47 return false; | 54 return false; |
| 55 } |
48 | 56 |
49 if (!registrar_.IsRegistered( | 57 if (!registrar_.IsRegistered( |
50 this, chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED, | 58 this, chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED, |
51 content::Source<Profile>(profile))) { | 59 content::Source<Profile>(profile))) { |
52 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED, | 60 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED, |
53 content::Source<Profile>(profile)); | 61 content::Source<Profile>(profile)); |
54 } | 62 } |
55 | 63 |
56 return true; | 64 return true; |
57 } | 65 } |
(...skipping 30 matching lines...) Expand all Loading... |
88 extensions::ShellWindowRegistry::ShellWindowList windows = | 96 extensions::ShellWindowRegistry::ShellWindowList windows = |
89 extensions::ShellWindowRegistry::Get(host->GetProfile())-> | 97 extensions::ShellWindowRegistry::Get(host->GetProfile())-> |
90 GetShellWindowsForApp(host->GetAppId()); | 98 GetShellWindowsForApp(host->GetAppId()); |
91 for (extensions::ShellWindowRegistry::const_iterator it = windows.begin(); | 99 for (extensions::ShellWindowRegistry::const_iterator it = windows.begin(); |
92 it != windows.end(); ++it) { | 100 it != windows.end(); ++it) { |
93 (*it)->GetBaseWindow()->Close(); | 101 (*it)->GetBaseWindow()->Close(); |
94 } | 102 } |
95 } | 103 } |
96 | 104 |
97 bool ExtensionAppShimHandler::LaunchApp(Profile* profile, | 105 bool ExtensionAppShimHandler::LaunchApp(Profile* profile, |
98 const std::string& app_id) { | 106 const std::string& app_id, |
| 107 AppShimLaunchType launch_type) { |
99 extensions::ExtensionSystem* extension_system = | 108 extensions::ExtensionSystem* extension_system = |
100 extensions::ExtensionSystem::Get(profile); | 109 extensions::ExtensionSystem::Get(profile); |
101 ExtensionServiceInterface* extension_service = | 110 ExtensionServiceInterface* extension_service = |
102 extension_system->extension_service(); | 111 extension_system->extension_service(); |
103 const extensions::Extension* extension = | 112 const extensions::Extension* extension = |
104 extension_service->GetExtensionById(app_id, false); | 113 extension_service->GetExtensionById(app_id, false); |
105 if (!extension) { | 114 if (!extension) { |
106 LOG(ERROR) << "Attempted to launch nonexistent app with id '" | 115 LOG(ERROR) << "Attempted to launch nonexistent app with id '" |
107 << app_id << "'."; | 116 << app_id << "'."; |
108 return false; | 117 return false; |
109 } | 118 } |
| 119 |
| 120 if (launch_type == APP_SHIM_LAUNCH_REGISTER_ONLY) |
| 121 return true; |
| 122 |
110 // TODO(jeremya): Handle the case that launching the app fails. Probably we | 123 // TODO(jeremya): Handle the case that launching the app fails. Probably we |
111 // need to watch for 'app successfully launched' or at least 'background page | 124 // need to watch for 'app successfully launched' or at least 'background page |
112 // exists/was created' and time out with failure if we don't see that sign of | 125 // exists/was created' and time out with failure if we don't see that sign of |
113 // life within a certain window. | 126 // life within a certain window. |
114 chrome::OpenApplication(chrome::AppLaunchParams( | 127 chrome::OpenApplication(chrome::AppLaunchParams( |
115 profile, extension, NEW_FOREGROUND_TAB)); | 128 profile, extension, NEW_FOREGROUND_TAB)); |
116 return true; | 129 return true; |
117 } | 130 } |
118 | 131 |
119 void ExtensionAppShimHandler::Observe( | 132 void ExtensionAppShimHandler::Observe( |
120 int type, | 133 int type, |
121 const content::NotificationSource& source, | 134 const content::NotificationSource& source, |
122 const content::NotificationDetails& details) { | 135 const content::NotificationDetails& details) { |
123 Profile* profile = content::Source<Profile>(source).ptr(); | 136 Profile* profile = content::Source<Profile>(source).ptr(); |
| 137 extensions::ExtensionHost* extension_host = |
| 138 content::Details<extensions::ExtensionHost>(details).ptr(); |
124 switch (type) { | 139 switch (type) { |
125 case chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED: { | 140 case chrome::NOTIFICATION_EXTENSION_HOST_CREATED: |
126 extensions::ExtensionHost* extension_host = | 141 StartShim(profile, extension_host->extension()); |
127 content::Details<extensions::ExtensionHost>(details).ptr(); | 142 break; |
| 143 case chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED: |
128 CloseShim(profile, extension_host->extension_id()); | 144 CloseShim(profile, extension_host->extension_id()); |
129 break; | 145 break; |
130 } | |
131 default: | 146 default: |
132 NOTREACHED(); // Unexpected notification. | 147 NOTREACHED(); // Unexpected notification. |
133 break; | 148 break; |
134 } | 149 } |
135 } | 150 } |
136 | 151 |
| 152 void ExtensionAppShimHandler::StartShim( |
| 153 Profile* profile, |
| 154 const extensions::Extension* extension) { |
| 155 if (!extension->is_platform_app()) |
| 156 return; |
| 157 |
| 158 if (hosts_.count(make_pair(profile, extension->id()))) |
| 159 return; |
| 160 |
| 161 web_app::MaybeLaunchShortcut( |
| 162 web_app::ShortcutInfoForExtensionAndProfile(extension, profile)); |
| 163 } |
| 164 |
137 void ExtensionAppShimHandler::CloseShim(Profile* profile, | 165 void ExtensionAppShimHandler::CloseShim(Profile* profile, |
138 const std::string& app_id) { | 166 const std::string& app_id) { |
139 HostMap::const_iterator it = hosts_.find(make_pair(profile, app_id)); | 167 HostMap::const_iterator it = hosts_.find(make_pair(profile, app_id)); |
140 if (it != hosts_.end()) | 168 if (it != hosts_.end()) |
141 it->second->OnAppClosed(); | 169 it->second->OnAppClosed(); |
142 } | 170 } |
143 | 171 |
144 } // namespace apps | 172 } // namespace apps |
OLD | NEW |