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 "chrome/browser/apps/app_shim/extension_app_shim_handler_mac.h" | 5 #include "chrome/browser/apps/app_shim/extension_app_shim_handler_mac.h" |
6 | 6 |
7 #include "apps/app_lifetime_monitor_factory.h" | 7 #include "apps/app_lifetime_monitor_factory.h" |
8 #include "apps/launcher.h" | 8 #include "apps/launcher.h" |
9 #include "base/files/file_path.h" | 9 #include "base/files/file_path.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "chrome/browser/apps/app_shim/app_shim_host_manager_mac.h" | 11 #include "chrome/browser/apps/app_shim/app_shim_host_manager_mac.h" |
12 #include "chrome/browser/browser_process.h" | 12 #include "chrome/browser/browser_process.h" |
13 #include "chrome/browser/chrome_notification_types.h" | 13 #include "chrome/browser/chrome_notification_types.h" |
14 #include "chrome/browser/extensions/launch_util.h" | |
14 #include "chrome/browser/profiles/profile.h" | 15 #include "chrome/browser/profiles/profile.h" |
15 #include "chrome/browser/profiles/profile_manager.h" | 16 #include "chrome/browser/profiles/profile_manager.h" |
17 #include "chrome/browser/ui/browser_list.h" | |
18 #include "chrome/browser/ui/browser_window.h" | |
16 #include "chrome/browser/ui/extensions/application_launch.h" | 19 #include "chrome/browser/ui/extensions/application_launch.h" |
17 #include "chrome/browser/ui/extensions/extension_enable_flow.h" | 20 #include "chrome/browser/ui/extensions/extension_enable_flow.h" |
18 #include "chrome/browser/ui/extensions/extension_enable_flow_delegate.h" | 21 #include "chrome/browser/ui/extensions/extension_enable_flow_delegate.h" |
19 #include "chrome/browser/web_applications/web_app_mac.h" | 22 #include "chrome/browser/web_applications/web_app_mac.h" |
20 #include "chrome/common/extensions/extension_constants.h" | 23 #include "chrome/common/extensions/extension_constants.h" |
21 #include "chrome/common/extensions/extension_metrics.h" | 24 #include "chrome/common/extensions/extension_metrics.h" |
22 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h" | 25 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h" |
23 #include "chrome/common/mac/app_shim_messages.h" | 26 #include "chrome/common/mac/app_shim_messages.h" |
24 #include "components/crx_file/id_util.h" | 27 #include "components/crx_file/id_util.h" |
25 #include "content/public/browser/notification_details.h" | 28 #include "content/public/browser/notification_details.h" |
26 #include "content/public/browser/notification_service.h" | 29 #include "content/public/browser/notification_service.h" |
27 #include "content/public/browser/notification_source.h" | 30 #include "content/public/browser/notification_source.h" |
28 #include "extensions/browser/app_window/app_window.h" | 31 #include "extensions/browser/app_window/app_window.h" |
29 #include "extensions/browser/app_window/app_window_registry.h" | 32 #include "extensions/browser/app_window/app_window_registry.h" |
30 #include "extensions/browser/app_window/native_app_window.h" | 33 #include "extensions/browser/app_window/native_app_window.h" |
31 #include "extensions/browser/extension_host.h" | 34 #include "extensions/browser/extension_host.h" |
35 #include "extensions/browser/extension_prefs.h" | |
32 #include "extensions/browser/extension_registry.h" | 36 #include "extensions/browser/extension_registry.h" |
33 #include "extensions/common/constants.h" | 37 #include "extensions/common/constants.h" |
34 #include "ui/base/cocoa/focus_window_set.h" | 38 #include "ui/base/cocoa/focus_window_set.h" |
35 | 39 |
36 using extensions::AppWindow; | 40 using extensions::AppWindow; |
37 using extensions::AppWindowRegistry; | 41 using extensions::AppWindowRegistry; |
38 using extensions::ExtensionRegistry; | 42 using extensions::ExtensionRegistry; |
39 | 43 |
40 namespace { | 44 namespace { |
41 | 45 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
75 ++it) { | 79 ++it) { |
76 native_windows.insert((*it)->GetNativeWindow()); | 80 native_windows.insert((*it)->GetNativeWindow()); |
77 } | 81 } |
78 // Allow workspace switching. For the browser process, we can reasonably rely | 82 // Allow workspace switching. For the browser process, we can reasonably rely |
79 // on OS X to switch spaces for us and honor relevant user settings. But shims | 83 // on OS X to switch spaces for us and honor relevant user settings. But shims |
80 // don't have windows, so we have to do it ourselves. | 84 // don't have windows, so we have to do it ourselves. |
81 ui::FocusWindowSet(native_windows); | 85 ui::FocusWindowSet(native_windows); |
82 return true; | 86 return true; |
83 } | 87 } |
84 | 88 |
89 bool FocusHostedAppWindows(std::set<Browser*>& browsers) { | |
90 if (browsers.empty()) | |
91 return false; | |
92 | |
93 std::set<gfx::NativeWindow> native_windows; | |
94 for (const Browser* browser : browsers) | |
95 native_windows.insert(browser->window()->GetNativeWindow()); | |
96 | |
97 ui::FocusWindowSet(native_windows); | |
98 return true; | |
99 } | |
100 | |
85 // Attempts to launch a packaged app, prompting the user to enable it if | 101 // Attempts to launch a packaged app, prompting the user to enable it if |
86 // necessary. The prompt is shown in its own window. | 102 // necessary. The prompt is shown in its own window. |
87 // This class manages its own lifetime. | 103 // This class manages its own lifetime. |
88 class EnableViaPrompt : public ExtensionEnableFlowDelegate { | 104 class EnableViaPrompt : public ExtensionEnableFlowDelegate { |
89 public: | 105 public: |
90 EnableViaPrompt(Profile* profile, | 106 EnableViaPrompt(Profile* profile, |
91 const std::string& extension_id, | 107 const std::string& extension_id, |
92 const base::Callback<void()>& callback) | 108 const base::Callback<void()>& callback) |
93 : profile_(profile), | 109 : profile_(profile), |
94 extension_id_(extension_id), | 110 extension_id_(extension_id), |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
161 AppWindowList ExtensionAppShimHandler::Delegate::GetWindows( | 177 AppWindowList ExtensionAppShimHandler::Delegate::GetWindows( |
162 Profile* profile, | 178 Profile* profile, |
163 const std::string& extension_id) { | 179 const std::string& extension_id) { |
164 return AppWindowRegistry::Get(profile)->GetAppWindowsForApp(extension_id); | 180 return AppWindowRegistry::Get(profile)->GetAppWindowsForApp(extension_id); |
165 } | 181 } |
166 | 182 |
167 const extensions::Extension* | 183 const extensions::Extension* |
168 ExtensionAppShimHandler::Delegate::GetAppExtension( | 184 ExtensionAppShimHandler::Delegate::GetAppExtension( |
169 Profile* profile, | 185 Profile* profile, |
170 const std::string& extension_id) { | 186 const std::string& extension_id) { |
171 ExtensionRegistry* registry = ExtensionRegistry::Get(profile); | 187 return ExtensionAppShimHandler::GetAppExtension(profile, extension_id); |
172 const extensions::Extension* extension = | |
173 registry->GetExtensionById(extension_id, ExtensionRegistry::ENABLED); | |
174 return extension && | |
175 (extension->is_platform_app() || extension->is_hosted_app()) | |
176 ? extension | |
177 : NULL; | |
178 } | 188 } |
179 | 189 |
180 void ExtensionAppShimHandler::Delegate::EnableExtension( | 190 void ExtensionAppShimHandler::Delegate::EnableExtension( |
181 Profile* profile, | 191 Profile* profile, |
182 const std::string& extension_id, | 192 const std::string& extension_id, |
183 const base::Callback<void()>& callback) { | 193 const base::Callback<void()>& callback) { |
184 (new EnableViaPrompt(profile, extension_id, callback))->Run(); | 194 (new EnableViaPrompt(profile, extension_id, callback))->Run(); |
185 } | 195 } |
186 | 196 |
187 void ExtensionAppShimHandler::Delegate::LaunchApp( | 197 void ExtensionAppShimHandler::Delegate::LaunchApp( |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
222 : delegate_(new Delegate), | 232 : delegate_(new Delegate), |
223 weak_factory_(this) { | 233 weak_factory_(this) { |
224 // This is instantiated in BrowserProcessImpl::PreMainMessageLoopRun with | 234 // This is instantiated in BrowserProcessImpl::PreMainMessageLoopRun with |
225 // AppShimHostManager. Since PROFILE_CREATED is not fired until | 235 // AppShimHostManager. Since PROFILE_CREATED is not fired until |
226 // ProfileManager::GetLastUsedProfile/GetLastOpenedProfiles, this should catch | 236 // ProfileManager::GetLastUsedProfile/GetLastOpenedProfiles, this should catch |
227 // notifications for all profiles. | 237 // notifications for all profiles. |
228 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CREATED, | 238 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CREATED, |
229 content::NotificationService::AllBrowserContextsAndSources()); | 239 content::NotificationService::AllBrowserContextsAndSources()); |
230 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, | 240 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, |
231 content::NotificationService::AllBrowserContextsAndSources()); | 241 content::NotificationService::AllBrowserContextsAndSources()); |
242 registrar_.Add(this, chrome::NOTIFICATION_BROWSER_WINDOW_READY, | |
243 content::NotificationService::AllBrowserContextsAndSources()); | |
244 BrowserList::AddObserver(this); | |
232 } | 245 } |
233 | 246 |
234 ExtensionAppShimHandler::~ExtensionAppShimHandler() {} | 247 ExtensionAppShimHandler::~ExtensionAppShimHandler() { |
248 BrowserList::RemoveObserver(this); | |
249 } | |
235 | 250 |
236 AppShimHandler::Host* ExtensionAppShimHandler::FindHost( | 251 AppShimHandler::Host* ExtensionAppShimHandler::FindHost( |
237 Profile* profile, | 252 Profile* profile, |
238 const std::string& app_id) { | 253 const std::string& app_id) { |
239 HostMap::iterator it = hosts_.find(make_pair(profile, app_id)); | 254 HostMap::iterator it = hosts_.find(make_pair(profile, app_id)); |
240 return it == hosts_.end() ? NULL : it->second; | 255 return it == hosts_.end() ? NULL : it->second; |
241 } | 256 } |
242 | 257 |
258 void ExtensionAppShimHandler::SetHostedAppHidden(Profile* profile, | |
259 const std::string& app_id, | |
260 bool hidden) { | |
261 const AppBrowserMap::iterator it = app_browser_windows_.find(app_id); | |
262 if (it == app_browser_windows_.end()) | |
263 return; | |
264 | |
265 for (const Browser* browser : it->second) { | |
266 if (web_app::GetExtensionIdFromApplicationName(browser->app_name()) != | |
267 app_id) { | |
268 continue; | |
269 } | |
270 | |
271 if (hidden) | |
272 browser->window()->Hide(); | |
273 else | |
274 browser->window()->Show(); | |
275 } | |
276 } | |
277 | |
278 // static | |
279 const extensions::Extension* ExtensionAppShimHandler::GetAppExtension( | |
280 Profile* profile, | |
281 const std::string& extension_id) { | |
282 if (!profile) | |
283 return NULL; | |
284 | |
285 ExtensionRegistry* registry = ExtensionRegistry::Get(profile); | |
286 const extensions::Extension* extension = | |
287 registry->GetExtensionById(extension_id, ExtensionRegistry::ENABLED); | |
288 return extension && | |
289 (extension->is_platform_app() || extension->is_hosted_app()) | |
290 ? extension | |
291 : NULL; | |
292 } | |
293 | |
294 // static | |
295 const extensions::Extension* ExtensionAppShimHandler::GetAppForBrowser( | |
296 Browser* browser) { | |
297 if (!browser || !browser->is_app()) | |
jackhou1
2014/12/12 04:42:49
Blank line after return.
mitchellj
2014/12/14 22:28:57
Done.
| |
298 return NULL; | |
299 return GetAppExtension( | |
300 browser->profile(), | |
301 web_app::GetExtensionIdFromApplicationName(browser->app_name())); | |
302 } | |
303 | |
243 // static | 304 // static |
244 void ExtensionAppShimHandler::QuitAppForWindow(AppWindow* app_window) { | 305 void ExtensionAppShimHandler::QuitAppForWindow(AppWindow* app_window) { |
245 ExtensionAppShimHandler* handler = GetInstance(); | 306 ExtensionAppShimHandler* handler = GetInstance(); |
246 Host* host = handler->FindHost( | 307 Host* host = handler->FindHost( |
247 Profile::FromBrowserContext(app_window->browser_context()), | 308 Profile::FromBrowserContext(app_window->browser_context()), |
248 app_window->extension_id()); | 309 app_window->extension_id()); |
249 if (host) { | 310 if (host) { |
250 handler->OnShimQuit(host); | 311 handler->OnShimQuit(host); |
251 } else { | 312 } else { |
252 // App shims might be disabled or the shim is still starting up. | 313 // App shims might be disabled or the shim is still starting up. |
253 AppWindowRegistry::Get( | 314 AppWindowRegistry::Get( |
254 Profile::FromBrowserContext(app_window->browser_context())) | 315 Profile::FromBrowserContext(app_window->browser_context())) |
255 ->CloseAllAppWindowsForApp(app_window->extension_id()); | 316 ->CloseAllAppWindowsForApp(app_window->extension_id()); |
256 } | 317 } |
257 } | 318 } |
258 | 319 |
320 // static | |
321 void ExtensionAppShimHandler::QuitHostedAppForWindow( | |
322 Profile* profile, | |
323 const std::string& app_id) { | |
324 ExtensionAppShimHandler* handler = GetInstance(); | |
325 Host* host = handler->FindHost(Profile::FromBrowserContext(profile), app_id); | |
326 if (host) | |
327 handler->OnShimQuit(host); | |
328 else | |
329 handler->CloseBrowsersForApp(app_id); | |
330 } | |
331 | |
259 void ExtensionAppShimHandler::HideAppForWindow(AppWindow* app_window) { | 332 void ExtensionAppShimHandler::HideAppForWindow(AppWindow* app_window) { |
260 ExtensionAppShimHandler* handler = GetInstance(); | 333 ExtensionAppShimHandler* handler = GetInstance(); |
261 Profile* profile = Profile::FromBrowserContext(app_window->browser_context()); | 334 Profile* profile = Profile::FromBrowserContext(app_window->browser_context()); |
262 Host* host = handler->FindHost(profile, app_window->extension_id()); | 335 Host* host = handler->FindHost(profile, app_window->extension_id()); |
263 if (host) | 336 if (host) |
264 host->OnAppHide(); | 337 host->OnAppHide(); |
265 else | 338 else |
266 SetAppHidden(profile, app_window->extension_id(), true); | 339 SetAppHidden(profile, app_window->extension_id(), true); |
267 } | 340 } |
268 | 341 |
342 void ExtensionAppShimHandler::HideHostedApp(Profile* profile, | |
343 const std::string& app_id) { | |
344 ExtensionAppShimHandler* handler = GetInstance(); | |
345 Host* host = handler->FindHost(profile, app_id); | |
346 if (host) | |
347 host->OnAppHide(); | |
348 else | |
349 handler->SetHostedAppHidden(profile, app_id, true); | |
350 } | |
351 | |
269 void ExtensionAppShimHandler::FocusAppForWindow(AppWindow* app_window) { | 352 void ExtensionAppShimHandler::FocusAppForWindow(AppWindow* app_window) { |
270 ExtensionAppShimHandler* handler = GetInstance(); | 353 ExtensionAppShimHandler* handler = GetInstance(); |
271 Profile* profile = Profile::FromBrowserContext(app_window->browser_context()); | 354 Profile* profile = Profile::FromBrowserContext(app_window->browser_context()); |
272 const std::string& app_id = app_window->extension_id(); | 355 const std::string& app_id = app_window->extension_id(); |
273 Host* host = handler->FindHost(profile, app_id); | 356 Host* host = handler->FindHost(profile, app_id); |
274 if (host) { | 357 if (host) { |
275 handler->OnShimFocus(host, | 358 handler->OnShimFocus(host, |
276 APP_SHIM_FOCUS_NORMAL, | 359 APP_SHIM_FOCUS_NORMAL, |
277 std::vector<base::FilePath>()); | 360 std::vector<base::FilePath>()); |
278 } else { | 361 } else { |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
361 // Return now. OnAppLaunchComplete will be called when the app is activated. | 444 // Return now. OnAppLaunchComplete will be called when the app is activated. |
362 } | 445 } |
363 | 446 |
364 // static | 447 // static |
365 ExtensionAppShimHandler* ExtensionAppShimHandler::GetInstance() { | 448 ExtensionAppShimHandler* ExtensionAppShimHandler::GetInstance() { |
366 return g_browser_process->platform_part() | 449 return g_browser_process->platform_part() |
367 ->app_shim_host_manager() | 450 ->app_shim_host_manager() |
368 ->extension_app_shim_handler(); | 451 ->extension_app_shim_handler(); |
369 } | 452 } |
370 | 453 |
454 void ExtensionAppShimHandler::CloseBrowsersForApp(const std::string& app_id) { | |
455 AppBrowserMap::iterator it = app_browser_windows_.find(app_id); | |
456 if (it == app_browser_windows_.end()) | |
457 return; | |
458 | |
459 for (const Browser* browser : it->second) | |
460 browser->window()->Close(); | |
461 } | |
462 | |
371 void ExtensionAppShimHandler::OnProfileLoaded( | 463 void ExtensionAppShimHandler::OnProfileLoaded( |
372 Host* host, | 464 Host* host, |
373 AppShimLaunchType launch_type, | 465 AppShimLaunchType launch_type, |
374 const std::vector<base::FilePath>& files, | 466 const std::vector<base::FilePath>& files, |
375 Profile* profile) { | 467 Profile* profile) { |
376 const std::string& app_id = host->GetAppId(); | 468 const std::string& app_id = host->GetAppId(); |
377 | 469 |
378 // The first host to claim this (profile, app_id) becomes the main host. | 470 // The first host to claim this (profile, app_id) becomes the main host. |
379 // For any others, focus or relaunch the app. | 471 // For any others, focus or relaunch the app. |
380 if (!hosts_.insert(make_pair(make_pair(profile, app_id), host)).second) { | 472 if (!hosts_.insert(make_pair(make_pair(profile, app_id), host)).second) { |
(...skipping 11 matching lines...) Expand all Loading... | |
392 } | 484 } |
393 | 485 |
394 // TODO(jeremya): Handle the case that launching the app fails. Probably we | 486 // TODO(jeremya): Handle the case that launching the app fails. Probably we |
395 // need to watch for 'app successfully launched' or at least 'background page | 487 // need to watch for 'app successfully launched' or at least 'background page |
396 // exists/was created' and time out with failure if we don't see that sign of | 488 // exists/was created' and time out with failure if we don't see that sign of |
397 // life within a certain window. | 489 // life within a certain window. |
398 const extensions::Extension* extension = | 490 const extensions::Extension* extension = |
399 delegate_->GetAppExtension(profile, app_id); | 491 delegate_->GetAppExtension(profile, app_id); |
400 if (extension) { | 492 if (extension) { |
401 delegate_->LaunchApp(profile, extension, files); | 493 delegate_->LaunchApp(profile, extension, files); |
402 // If it's a hosted app, just kill it immediately after opening for now. | 494 // If it's a hosted app that opens in a tab, let the shim terminate |
403 if (extension->is_hosted_app()) | 495 // immediately. |
496 if (extension->is_hosted_app() && | |
497 extensions::GetLaunchType(extensions::ExtensionPrefs::Get(profile), | |
498 extension) == | |
499 extensions::LAUNCH_TYPE_REGULAR) { | |
404 host->OnAppLaunchComplete(APP_SHIM_LAUNCH_DUPLICATE_HOST); | 500 host->OnAppLaunchComplete(APP_SHIM_LAUNCH_DUPLICATE_HOST); |
501 } | |
405 return; | 502 return; |
406 } | 503 } |
407 | 504 |
408 delegate_->EnableExtension( | 505 delegate_->EnableExtension( |
409 profile, app_id, | 506 profile, app_id, |
410 base::Bind(&ExtensionAppShimHandler::OnExtensionEnabled, | 507 base::Bind(&ExtensionAppShimHandler::OnExtensionEnabled, |
411 weak_factory_.GetWeakPtr(), | 508 weak_factory_.GetWeakPtr(), |
412 host->GetProfilePath(), app_id, files)); | 509 host->GetProfilePath(), app_id, files)); |
413 } | 510 } |
414 | 511 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
447 } | 544 } |
448 } | 545 } |
449 | 546 |
450 void ExtensionAppShimHandler::OnShimFocus( | 547 void ExtensionAppShimHandler::OnShimFocus( |
451 Host* host, | 548 Host* host, |
452 AppShimFocusType focus_type, | 549 AppShimFocusType focus_type, |
453 const std::vector<base::FilePath>& files) { | 550 const std::vector<base::FilePath>& files) { |
454 DCHECK(delegate_->ProfileExistsForPath(host->GetProfilePath())); | 551 DCHECK(delegate_->ProfileExistsForPath(host->GetProfilePath())); |
455 Profile* profile = delegate_->ProfileForPath(host->GetProfilePath()); | 552 Profile* profile = delegate_->ProfileForPath(host->GetProfilePath()); |
456 | 553 |
457 const AppWindowList windows = | 554 bool windows_focused; |
458 delegate_->GetWindows(profile, host->GetAppId()); | 555 const std::string& app_id = host->GetAppId(); |
459 bool windows_focused = FocusWindows(windows); | 556 if (delegate_->GetAppExtension(profile, app_id)->is_hosted_app()) { |
557 AppBrowserMap::iterator it = app_browser_windows_.find(app_id); | |
558 if (it == app_browser_windows_.end()) | |
559 return; | |
560 | |
561 windows_focused = FocusHostedAppWindows(it->second); | |
562 } else { | |
563 const AppWindowList windows = | |
564 delegate_->GetWindows(profile, host->GetAppId()); | |
565 windows_focused = FocusWindows(windows); | |
566 } | |
460 | 567 |
461 if (focus_type == APP_SHIM_FOCUS_NORMAL || | 568 if (focus_type == APP_SHIM_FOCUS_NORMAL || |
462 (focus_type == APP_SHIM_FOCUS_REOPEN && windows_focused)) { | 569 (focus_type == APP_SHIM_FOCUS_REOPEN && windows_focused)) { |
463 return; | 570 return; |
464 } | 571 } |
465 | 572 |
466 const extensions::Extension* extension = | 573 const extensions::Extension* extension = |
467 delegate_->GetAppExtension(profile, host->GetAppId()); | 574 delegate_->GetAppExtension(profile, host->GetAppId()); |
468 if (extension) { | 575 if (extension) { |
469 delegate_->LaunchApp(profile, extension, files); | 576 delegate_->LaunchApp(profile, extension, files); |
470 } else { | 577 } else { |
471 // Extensions may have been uninstalled or disabled since the shim | 578 // Extensions may have been uninstalled or disabled since the shim |
472 // started. | 579 // started. |
473 host->OnAppClosed(); | 580 host->OnAppClosed(); |
474 } | 581 } |
475 } | 582 } |
476 | 583 |
477 void ExtensionAppShimHandler::OnShimSetHidden(Host* host, bool hidden) { | 584 void ExtensionAppShimHandler::OnShimSetHidden(Host* host, bool hidden) { |
478 DCHECK(delegate_->ProfileExistsForPath(host->GetProfilePath())); | 585 DCHECK(delegate_->ProfileExistsForPath(host->GetProfilePath())); |
479 Profile* profile = delegate_->ProfileForPath(host->GetProfilePath()); | 586 Profile* profile = delegate_->ProfileForPath(host->GetProfilePath()); |
480 | 587 |
481 SetAppHidden(profile, host->GetAppId(), hidden); | 588 const std::string& app_id = host->GetAppId(); |
589 if (delegate_->GetAppExtension(profile, app_id)->is_hosted_app()) | |
590 SetHostedAppHidden(profile, app_id, hidden); | |
591 else | |
592 SetAppHidden(profile, app_id, hidden); | |
482 } | 593 } |
483 | 594 |
484 void ExtensionAppShimHandler::OnShimQuit(Host* host) { | 595 void ExtensionAppShimHandler::OnShimQuit(Host* host) { |
485 DCHECK(delegate_->ProfileExistsForPath(host->GetProfilePath())); | 596 DCHECK(delegate_->ProfileExistsForPath(host->GetProfilePath())); |
486 Profile* profile = delegate_->ProfileForPath(host->GetProfilePath()); | 597 Profile* profile = delegate_->ProfileForPath(host->GetProfilePath()); |
487 | 598 |
488 const std::string& app_id = host->GetAppId(); | 599 const std::string& app_id = host->GetAppId(); |
489 const AppWindowList windows = delegate_->GetWindows(profile, app_id); | 600 if (delegate_->GetAppExtension(profile, app_id)->is_hosted_app()) |
490 for (AppWindowRegistry::const_iterator it = windows.begin(); | 601 CloseBrowsersForApp(app_id); |
491 it != windows.end(); | 602 else { |
492 ++it) { | 603 const AppWindowList windows = delegate_->GetWindows(profile, app_id); |
493 (*it)->GetBaseWindow()->Close(); | 604 for (AppWindowRegistry::const_iterator it = windows.begin(); |
605 it != windows.end(); ++it) { | |
606 (*it)->GetBaseWindow()->Close(); | |
607 } | |
494 } | 608 } |
495 // Once the last window closes, flow will end up in OnAppDeactivated via | 609 // Once the last window closes, flow will end up in OnAppDeactivated via |
496 // AppLifetimeMonitor. | 610 // AppLifetimeMonitor. |
611 // Otherwise, once the last window closes for a hosted app, OnBrowserRemoved | |
612 // will call OnAppDeactivated. | |
497 } | 613 } |
498 | 614 |
499 void ExtensionAppShimHandler::set_delegate(Delegate* delegate) { | 615 void ExtensionAppShimHandler::set_delegate(Delegate* delegate) { |
500 delegate_.reset(delegate); | 616 delegate_.reset(delegate); |
501 } | 617 } |
502 | 618 |
503 void ExtensionAppShimHandler::Observe( | 619 void ExtensionAppShimHandler::Observe( |
504 int type, | 620 int type, |
505 const content::NotificationSource& source, | 621 const content::NotificationSource& source, |
506 const content::NotificationDetails& details) { | 622 const content::NotificationDetails& details) { |
507 Profile* profile = content::Source<Profile>(source).ptr(); | |
508 if (profile->IsOffTheRecord()) | |
509 return; | |
510 | |
511 switch (type) { | 623 switch (type) { |
512 case chrome::NOTIFICATION_PROFILE_CREATED: { | 624 case chrome::NOTIFICATION_PROFILE_CREATED: { |
625 Profile* profile = content::Source<Profile>(source).ptr(); | |
626 if (profile->IsOffTheRecord()) | |
627 return; | |
628 | |
513 AppLifetimeMonitorFactory::GetForProfile(profile)->AddObserver(this); | 629 AppLifetimeMonitorFactory::GetForProfile(profile)->AddObserver(this); |
514 break; | 630 break; |
515 } | 631 } |
516 case chrome::NOTIFICATION_PROFILE_DESTROYED: { | 632 case chrome::NOTIFICATION_PROFILE_DESTROYED: { |
633 Profile* profile = content::Source<Profile>(source).ptr(); | |
634 if (profile->IsOffTheRecord()) | |
635 return; | |
636 | |
517 AppLifetimeMonitorFactory::GetForProfile(profile)->RemoveObserver(this); | 637 AppLifetimeMonitorFactory::GetForProfile(profile)->RemoveObserver(this); |
518 // Shut down every shim associated with this profile. | 638 // Shut down every shim associated with this profile. |
519 for (HostMap::iterator it = hosts_.begin(); it != hosts_.end(); ) { | 639 for (HostMap::iterator it = hosts_.begin(); it != hosts_.end(); ) { |
520 // Increment the iterator first as OnAppClosed may call back to | 640 // Increment the iterator first as OnAppClosed may call back to |
521 // OnShimClose and invalidate the iterator. | 641 // OnShimClose and invalidate the iterator. |
522 HostMap::iterator current = it++; | 642 HostMap::iterator current = it++; |
523 if (profile->IsSameProfile(current->first.first)) { | 643 if (profile->IsSameProfile(current->first.first)) { |
524 Host* host = current->second; | 644 Host* host = current->second; |
525 host->OnAppClosed(); | 645 host->OnAppClosed(); |
526 } | 646 } |
527 } | 647 } |
528 break; | 648 break; |
529 } | 649 } |
650 case chrome::NOTIFICATION_BROWSER_WINDOW_READY: { | |
651 Browser* browser = content::Source<Browser>(source).ptr(); | |
652 // Don't keep track of browsers that are not associated with an app. | |
653 std::string app_id = | |
jackhou1
2014/12/12 04:42:49
No need for this, you can use extension->id() belo
mitchellj
2014/12/14 22:28:57
Done.
| |
654 web_app::GetExtensionIdFromApplicationName(browser->app_name()); | |
655 const extensions::Extension* extension = GetAppForBrowser(browser); | |
656 if (!extension) | |
657 return; | |
658 | |
659 BrowserSet& browsers = app_browser_windows_[app_id]; | |
660 browsers.insert(browser); | |
661 if (browsers.size() == 1) | |
662 OnAppActivated(browser->profile(), app_id); | |
663 | |
664 break; | |
665 } | |
530 default: { | 666 default: { |
531 NOTREACHED(); // Unexpected notification. | 667 NOTREACHED(); // Unexpected notification. |
532 break; | 668 break; |
533 } | 669 } |
534 } | 670 } |
535 } | 671 } |
536 | 672 |
537 void ExtensionAppShimHandler::OnAppStart(Profile* profile, | 673 void ExtensionAppShimHandler::OnAppStart(Profile* profile, |
538 const std::string& app_id) {} | 674 const std::string& app_id) {} |
539 | 675 |
(...skipping 22 matching lines...) Expand all Loading... | |
562 | 698 |
563 if (hosts_.empty()) | 699 if (hosts_.empty()) |
564 delegate_->MaybeTerminate(); | 700 delegate_->MaybeTerminate(); |
565 } | 701 } |
566 | 702 |
567 void ExtensionAppShimHandler::OnAppStop(Profile* profile, | 703 void ExtensionAppShimHandler::OnAppStop(Profile* profile, |
568 const std::string& app_id) {} | 704 const std::string& app_id) {} |
569 | 705 |
570 void ExtensionAppShimHandler::OnChromeTerminating() {} | 706 void ExtensionAppShimHandler::OnChromeTerminating() {} |
571 | 707 |
708 // The BrowserWindow may be NULL when this is called. | |
709 // Therefore we listen for the notification | |
710 // chrome::NOTIFICATION_BROWSER_WINDOW_READY and then call OnAppActivated. | |
711 // If this notification is removed, check that OnBrowserAdded is called after | |
712 // the BrowserWindow is ready. | |
713 void ExtensionAppShimHandler::OnBrowserAdded(Browser* browser) { | |
714 } | |
715 | |
716 void ExtensionAppShimHandler::OnBrowserRemoved(Browser* browser) { | |
717 std::string app_id = | |
jackhou1
2014/12/12 04:42:49
Same here.
mitchellj
2014/12/14 22:28:57
Done.
| |
718 web_app::GetExtensionIdFromApplicationName(browser->app_name()); | |
719 const extensions::Extension* extension = GetAppForBrowser(browser); | |
720 if (!extension) | |
721 return; | |
722 | |
723 AppBrowserMap::iterator it = app_browser_windows_.find(app_id); | |
724 if (it != app_browser_windows_.end()) { | |
725 BrowserSet& browsers = it->second; | |
726 browsers.erase(browser); | |
727 if (browsers.empty()) | |
728 OnAppDeactivated(browser->profile(), app_id); | |
729 } | |
730 } | |
731 | |
572 } // namespace apps | 732 } // namespace apps |
OLD | NEW |