Chromium Code Reviews| 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" |
| 22 #include "chrome/browser/ui/tabs/tab_strip_model.h" | |
| 19 #include "chrome/browser/web_applications/web_app_mac.h" | 23 #include "chrome/browser/web_applications/web_app_mac.h" |
| 20 #include "chrome/common/extensions/extension_constants.h" | 24 #include "chrome/common/extensions/extension_constants.h" |
| 21 #include "chrome/common/extensions/extension_metrics.h" | 25 #include "chrome/common/extensions/extension_metrics.h" |
| 22 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h" | 26 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h" |
| 23 #include "chrome/common/mac/app_shim_messages.h" | 27 #include "chrome/common/mac/app_shim_messages.h" |
| 24 #include "components/crx_file/id_util.h" | 28 #include "components/crx_file/id_util.h" |
| 25 #include "content/public/browser/notification_details.h" | 29 #include "content/public/browser/notification_details.h" |
| 26 #include "content/public/browser/notification_service.h" | 30 #include "content/public/browser/notification_service.h" |
| 27 #include "content/public/browser/notification_source.h" | 31 #include "content/public/browser/notification_source.h" |
| 28 #include "extensions/browser/app_window/app_window.h" | 32 #include "extensions/browser/app_window/app_window.h" |
| 29 #include "extensions/browser/app_window/app_window_registry.h" | 33 #include "extensions/browser/app_window/app_window_registry.h" |
| 30 #include "extensions/browser/app_window/native_app_window.h" | 34 #include "extensions/browser/app_window/native_app_window.h" |
| 31 #include "extensions/browser/extension_host.h" | 35 #include "extensions/browser/extension_host.h" |
| 36 #include "extensions/browser/extension_prefs.h" | |
| 32 #include "extensions/browser/extension_registry.h" | 37 #include "extensions/browser/extension_registry.h" |
| 33 #include "extensions/common/constants.h" | 38 #include "extensions/common/constants.h" |
| 34 #include "ui/base/cocoa/focus_window_set.h" | 39 #include "ui/base/cocoa/focus_window_set.h" |
| 35 | 40 |
| 36 using extensions::AppWindow; | 41 using extensions::AppWindow; |
| 37 using extensions::AppWindowRegistry; | 42 using extensions::AppWindowRegistry; |
| 38 using extensions::ExtensionRegistry; | 43 using extensions::ExtensionRegistry; |
| 39 | 44 |
| 40 namespace { | 45 namespace { |
| 41 | 46 |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 59 for (AppWindowList::const_reverse_iterator it = windows.rbegin(); | 64 for (AppWindowList::const_reverse_iterator it = windows.rbegin(); |
| 60 it != windows.rend(); | 65 it != windows.rend(); |
| 61 ++it) { | 66 ++it) { |
| 62 if (hidden) | 67 if (hidden) |
| 63 (*it)->GetBaseWindow()->HideWithApp(); | 68 (*it)->GetBaseWindow()->HideWithApp(); |
| 64 else | 69 else |
| 65 (*it)->GetBaseWindow()->ShowWithApp(); | 70 (*it)->GetBaseWindow()->ShowWithApp(); |
| 66 } | 71 } |
| 67 } | 72 } |
| 68 | 73 |
| 74 void SetHostedAppHidden(Profile* profile, | |
|
jackhou1
2014/12/11 02:43:18
Maybe make this a method of ExtensionAppShimHandle
mitchellj
2014/12/12 00:03:45
Done.
| |
| 75 const std::string& app_id, | |
| 76 bool hidden) { | |
| 77 const BrowserList* browser_list = | |
| 78 BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_NATIVE); | |
| 79 | |
| 80 for (BrowserList::const_iterator it = browser_list->begin(); | |
|
jackhou1
2014/12/11 02:43:18
You can use C++11's range-based for-loops now:
fo
mitchellj
2014/12/12 00:03:45
Done.
| |
| 81 it != browser_list->end(); ++it) { | |
| 82 Browser* browser = *it; | |
| 83 | |
| 84 if (!browser->is_app() || | |
| 85 web_app::GetExtensionIdFromApplicationName(browser->app_name()) != | |
| 86 app_id) { | |
| 87 continue; | |
| 88 } | |
| 89 | |
| 90 TabStripModel* tab_strip = browser->tab_strip_model(); | |
| 91 for (int index = 0; index < tab_strip->count(); index++) { | |
| 92 if (hidden) | |
|
jackhou1
2014/12/11 02:43:18
Do you need this loop? It doesn't look like this b
mitchellj
2014/12/12 00:03:45
Done.
| |
| 93 browser->window()->Hide(); | |
| 94 else | |
| 95 browser->window()->Show(); | |
| 96 } | |
| 97 } | |
| 98 } | |
| 99 | |
| 69 bool FocusWindows(const AppWindowList& windows) { | 100 bool FocusWindows(const AppWindowList& windows) { |
| 70 if (windows.empty()) | 101 if (windows.empty()) |
| 71 return false; | 102 return false; |
| 72 | 103 |
| 73 std::set<gfx::NativeWindow> native_windows; | 104 std::set<gfx::NativeWindow> native_windows; |
| 74 for (AppWindowList::const_iterator it = windows.begin(); it != windows.end(); | 105 for (AppWindowList::const_iterator it = windows.begin(); it != windows.end(); |
| 75 ++it) { | 106 ++it) { |
| 76 native_windows.insert((*it)->GetNativeWindow()); | 107 native_windows.insert((*it)->GetNativeWindow()); |
| 77 } | 108 } |
| 78 // Allow workspace switching. For the browser process, we can reasonably rely | 109 // 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 | 110 // 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. | 111 // don't have windows, so we have to do it ourselves. |
| 81 ui::FocusWindowSet(native_windows); | 112 ui::FocusWindowSet(native_windows); |
| 82 return true; | 113 return true; |
| 83 } | 114 } |
| 84 | 115 |
| 116 bool FocusHostedAppWindows(std::vector<content::WebContents*>& windows) { | |
|
jackhou1
2014/12/11 02:43:18
Just pass in the BrowserSet here. You can get the
mitchellj
2014/12/12 00:03:45
Done.
| |
| 117 if (windows.empty()) | |
| 118 return false; | |
| 119 | |
| 120 std::set<gfx::NativeWindow> native_windows; | |
| 121 for (std::vector<content::WebContents*>::const_iterator it = windows.begin(); | |
| 122 it != windows.end(); ++it) { | |
| 123 native_windows.insert((*it)->GetTopLevelNativeWindow()); | |
| 124 } | |
| 125 | |
| 126 ui::FocusWindowSet(native_windows); | |
| 127 return true; | |
| 128 } | |
| 129 | |
| 85 // Attempts to launch a packaged app, prompting the user to enable it if | 130 // Attempts to launch a packaged app, prompting the user to enable it if |
| 86 // necessary. The prompt is shown in its own window. | 131 // necessary. The prompt is shown in its own window. |
| 87 // This class manages its own lifetime. | 132 // This class manages its own lifetime. |
| 88 class EnableViaPrompt : public ExtensionEnableFlowDelegate { | 133 class EnableViaPrompt : public ExtensionEnableFlowDelegate { |
| 89 public: | 134 public: |
| 90 EnableViaPrompt(Profile* profile, | 135 EnableViaPrompt(Profile* profile, |
| 91 const std::string& extension_id, | 136 const std::string& extension_id, |
| 92 const base::Callback<void()>& callback) | 137 const base::Callback<void()>& callback) |
| 93 : profile_(profile), | 138 : profile_(profile), |
| 94 extension_id_(extension_id), | 139 extension_id_(extension_id), |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 222 : delegate_(new Delegate), | 267 : delegate_(new Delegate), |
| 223 weak_factory_(this) { | 268 weak_factory_(this) { |
| 224 // This is instantiated in BrowserProcessImpl::PreMainMessageLoopRun with | 269 // This is instantiated in BrowserProcessImpl::PreMainMessageLoopRun with |
| 225 // AppShimHostManager. Since PROFILE_CREATED is not fired until | 270 // AppShimHostManager. Since PROFILE_CREATED is not fired until |
| 226 // ProfileManager::GetLastUsedProfile/GetLastOpenedProfiles, this should catch | 271 // ProfileManager::GetLastUsedProfile/GetLastOpenedProfiles, this should catch |
| 227 // notifications for all profiles. | 272 // notifications for all profiles. |
| 228 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CREATED, | 273 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CREATED, |
| 229 content::NotificationService::AllBrowserContextsAndSources()); | 274 content::NotificationService::AllBrowserContextsAndSources()); |
| 230 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, | 275 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, |
| 231 content::NotificationService::AllBrowserContextsAndSources()); | 276 content::NotificationService::AllBrowserContextsAndSources()); |
| 277 BrowserList::AddObserver(this); | |
| 232 } | 278 } |
| 233 | 279 |
| 234 ExtensionAppShimHandler::~ExtensionAppShimHandler() {} | 280 ExtensionAppShimHandler::~ExtensionAppShimHandler() { |
| 281 BrowserList::RemoveObserver(this); | |
| 282 } | |
| 235 | 283 |
| 236 AppShimHandler::Host* ExtensionAppShimHandler::FindHost( | 284 AppShimHandler::Host* ExtensionAppShimHandler::FindHost( |
| 237 Profile* profile, | 285 Profile* profile, |
| 238 const std::string& app_id) { | 286 const std::string& app_id) { |
| 239 HostMap::iterator it = hosts_.find(make_pair(profile, app_id)); | 287 HostMap::iterator it = hosts_.find(make_pair(profile, app_id)); |
| 240 return it == hosts_.end() ? NULL : it->second; | 288 return it == hosts_.end() ? NULL : it->second; |
| 241 } | 289 } |
| 242 | 290 |
| 243 // static | 291 // static |
| 244 void ExtensionAppShimHandler::QuitAppForWindow(AppWindow* app_window) { | 292 void ExtensionAppShimHandler::QuitAppForWindow(AppWindow* app_window) { |
| 245 ExtensionAppShimHandler* handler = GetInstance(); | 293 ExtensionAppShimHandler* handler = GetInstance(); |
| 246 Host* host = handler->FindHost( | 294 Host* host = handler->FindHost( |
| 247 Profile::FromBrowserContext(app_window->browser_context()), | 295 Profile::FromBrowserContext(app_window->browser_context()), |
| 248 app_window->extension_id()); | 296 app_window->extension_id()); |
| 249 if (host) { | 297 if (host) { |
| 250 handler->OnShimQuit(host); | 298 handler->OnShimQuit(host); |
| 251 } else { | 299 } else { |
| 252 // App shims might be disabled or the shim is still starting up. | 300 // App shims might be disabled or the shim is still starting up. |
| 253 AppWindowRegistry::Get( | 301 AppWindowRegistry::Get( |
| 254 Profile::FromBrowserContext(app_window->browser_context())) | 302 Profile::FromBrowserContext(app_window->browser_context())) |
| 255 ->CloseAllAppWindowsForApp(app_window->extension_id()); | 303 ->CloseAllAppWindowsForApp(app_window->extension_id()); |
| 256 } | 304 } |
| 257 } | 305 } |
| 258 | 306 |
| 307 // static | |
| 308 void ExtensionAppShimHandler::QuitHostedAppForWindow( | |
| 309 Browser* browser, | |
| 310 const extensions::Extension* extension) { | |
| 311 ExtensionAppShimHandler* handler = GetInstance(); | |
| 312 Host* host = handler->FindHost( | |
| 313 Profile::FromBrowserContext(browser->profile()), extension->id()); | |
| 314 if (host && extension->is_hosted_app()) { | |
| 315 handler->OnShimQuit(host); | |
| 316 } | |
| 317 } | |
| 318 | |
| 259 void ExtensionAppShimHandler::HideAppForWindow(AppWindow* app_window) { | 319 void ExtensionAppShimHandler::HideAppForWindow(AppWindow* app_window) { |
| 260 ExtensionAppShimHandler* handler = GetInstance(); | 320 ExtensionAppShimHandler* handler = GetInstance(); |
| 261 Profile* profile = Profile::FromBrowserContext(app_window->browser_context()); | 321 Profile* profile = Profile::FromBrowserContext(app_window->browser_context()); |
| 262 Host* host = handler->FindHost(profile, app_window->extension_id()); | 322 Host* host = handler->FindHost(profile, app_window->extension_id()); |
| 263 if (host) | 323 if (host) |
| 264 host->OnAppHide(); | 324 host->OnAppHide(); |
| 265 else | 325 else |
| 266 SetAppHidden(profile, app_window->extension_id(), true); | 326 SetAppHidden(profile, app_window->extension_id(), true); |
| 267 } | 327 } |
| 268 | 328 |
| 329 void ExtensionAppShimHandler::HideHostedApp(Profile* profile, | |
| 330 const std::string& app_id) { | |
| 331 ExtensionAppShimHandler* handler = GetInstance(); | |
| 332 Host* host = handler->FindHost(profile, app_id); | |
| 333 if (host) | |
| 334 host->OnAppHide(); | |
| 335 else | |
| 336 SetHostedAppHidden(profile, app_id, true); | |
| 337 } | |
| 338 | |
| 269 void ExtensionAppShimHandler::FocusAppForWindow(AppWindow* app_window) { | 339 void ExtensionAppShimHandler::FocusAppForWindow(AppWindow* app_window) { |
| 270 ExtensionAppShimHandler* handler = GetInstance(); | 340 ExtensionAppShimHandler* handler = GetInstance(); |
| 271 Profile* profile = Profile::FromBrowserContext(app_window->browser_context()); | 341 Profile* profile = Profile::FromBrowserContext(app_window->browser_context()); |
| 272 const std::string& app_id = app_window->extension_id(); | 342 const std::string& app_id = app_window->extension_id(); |
| 273 Host* host = handler->FindHost(profile, app_id); | 343 Host* host = handler->FindHost(profile, app_id); |
| 274 if (host) { | 344 if (host) { |
| 275 handler->OnShimFocus(host, | 345 handler->OnShimFocus(host, |
| 276 APP_SHIM_FOCUS_NORMAL, | 346 APP_SHIM_FOCUS_NORMAL, |
| 277 std::vector<base::FilePath>()); | 347 std::vector<base::FilePath>()); |
| 278 } else { | 348 } else { |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 392 } | 462 } |
| 393 | 463 |
| 394 // TODO(jeremya): Handle the case that launching the app fails. Probably we | 464 // 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 | 465 // 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 | 466 // exists/was created' and time out with failure if we don't see that sign of |
| 397 // life within a certain window. | 467 // life within a certain window. |
| 398 const extensions::Extension* extension = | 468 const extensions::Extension* extension = |
| 399 delegate_->GetAppExtension(profile, app_id); | 469 delegate_->GetAppExtension(profile, app_id); |
| 400 if (extension) { | 470 if (extension) { |
| 401 delegate_->LaunchApp(profile, extension, files); | 471 delegate_->LaunchApp(profile, extension, files); |
| 402 // If it's a hosted app, just kill it immediately after opening for now. | 472 // If it's a hosted app and a tabbed application, kill it immediately. |
|
jackhou1
2014/12/11 02:43:18
s/kill it immediately/let the shim terminate immed
mitchellj
2014/12/12 00:03:45
Acknowledged.
| |
| 403 if (extension->is_hosted_app()) | 473 if (extension->is_hosted_app()) { |
| 404 host->OnAppLaunchComplete(APP_SHIM_LAUNCH_DUPLICATE_HOST); | 474 if (extensions::GetLaunchType(extensions::ExtensionPrefs::Get(profile), |
| 475 extension) == | |
| 476 extensions::LAUNCH_TYPE_REGULAR) { | |
| 477 host->OnAppLaunchComplete(APP_SHIM_LAUNCH_DUPLICATE_HOST); | |
| 478 } else { | |
| 479 host->OnAppLaunchComplete(APP_SHIM_LAUNCH_SUCCESS); | |
|
jackhou1
2014/12/11 02:43:18
Instead of sending APP_SHIM_LAUNCH_SUCCESS here, h
mitchellj
2014/12/12 00:03:45
Done.
| |
| 480 } | |
| 481 } | |
| 405 return; | 482 return; |
| 406 } | 483 } |
| 407 | 484 |
| 408 delegate_->EnableExtension( | 485 delegate_->EnableExtension( |
| 409 profile, app_id, | 486 profile, app_id, |
| 410 base::Bind(&ExtensionAppShimHandler::OnExtensionEnabled, | 487 base::Bind(&ExtensionAppShimHandler::OnExtensionEnabled, |
| 411 weak_factory_.GetWeakPtr(), | 488 weak_factory_.GetWeakPtr(), |
| 412 host->GetProfilePath(), app_id, files)); | 489 host->GetProfilePath(), app_id, files)); |
| 413 } | 490 } |
| 414 | 491 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 447 } | 524 } |
| 448 } | 525 } |
| 449 | 526 |
| 450 void ExtensionAppShimHandler::OnShimFocus( | 527 void ExtensionAppShimHandler::OnShimFocus( |
| 451 Host* host, | 528 Host* host, |
| 452 AppShimFocusType focus_type, | 529 AppShimFocusType focus_type, |
| 453 const std::vector<base::FilePath>& files) { | 530 const std::vector<base::FilePath>& files) { |
| 454 DCHECK(delegate_->ProfileExistsForPath(host->GetProfilePath())); | 531 DCHECK(delegate_->ProfileExistsForPath(host->GetProfilePath())); |
| 455 Profile* profile = delegate_->ProfileForPath(host->GetProfilePath()); | 532 Profile* profile = delegate_->ProfileForPath(host->GetProfilePath()); |
| 456 | 533 |
| 457 const AppWindowList windows = | 534 bool windows_focused; |
| 458 delegate_->GetWindows(profile, host->GetAppId()); | 535 const std::string& app_id = host->GetAppId(); |
| 459 bool windows_focused = FocusWindows(windows); | 536 if (delegate_->GetAppExtension(profile, app_id)->is_hosted_app()) { |
| 537 std::vector<content::WebContents*> items; | |
| 538 AppBrowserMap::iterator it = app_browser_windows_.find(app_id); | |
| 539 if (it == app_browser_windows_.end()) | |
| 540 return; | |
| 541 | |
| 542 BrowserSet& browsers = it->second; | |
| 543 for (BrowserSet::const_iterator it = browsers.begin(); it != browsers.end(); | |
| 544 ++it) { | |
| 545 Browser* browser = *it; | |
| 546 TabStripModel* tab_strip = browser->tab_strip_model(); | |
| 547 for (int index = 0; index < tab_strip->count(); index++) { | |
| 548 content::WebContents* web_contents = tab_strip->GetWebContentsAt(index); | |
| 549 items.push_back(web_contents); | |
| 550 } | |
| 551 } | |
| 552 windows_focused = FocusHostedAppWindows(items); | |
| 553 } else { | |
| 554 const AppWindowList windows = | |
| 555 delegate_->GetWindows(profile, host->GetAppId()); | |
| 556 windows_focused = FocusWindows(windows); | |
| 557 } | |
| 460 | 558 |
| 461 if (focus_type == APP_SHIM_FOCUS_NORMAL || | 559 if (focus_type == APP_SHIM_FOCUS_NORMAL || |
| 462 (focus_type == APP_SHIM_FOCUS_REOPEN && windows_focused)) { | 560 (focus_type == APP_SHIM_FOCUS_REOPEN && windows_focused)) { |
| 463 return; | 561 return; |
| 464 } | 562 } |
| 465 | 563 |
| 466 const extensions::Extension* extension = | 564 const extensions::Extension* extension = |
| 467 delegate_->GetAppExtension(profile, host->GetAppId()); | 565 delegate_->GetAppExtension(profile, host->GetAppId()); |
| 468 if (extension) { | 566 if (extension) { |
| 469 delegate_->LaunchApp(profile, extension, files); | 567 delegate_->LaunchApp(profile, extension, files); |
| 470 } else { | 568 } else { |
| 471 // Extensions may have been uninstalled or disabled since the shim | 569 // Extensions may have been uninstalled or disabled since the shim |
| 472 // started. | 570 // started. |
| 473 host->OnAppClosed(); | 571 host->OnAppClosed(); |
| 474 } | 572 } |
| 475 } | 573 } |
| 476 | 574 |
| 477 void ExtensionAppShimHandler::OnShimSetHidden(Host* host, bool hidden) { | 575 void ExtensionAppShimHandler::OnShimSetHidden(Host* host, bool hidden) { |
| 478 DCHECK(delegate_->ProfileExistsForPath(host->GetProfilePath())); | 576 DCHECK(delegate_->ProfileExistsForPath(host->GetProfilePath())); |
| 479 Profile* profile = delegate_->ProfileForPath(host->GetProfilePath()); | 577 Profile* profile = delegate_->ProfileForPath(host->GetProfilePath()); |
| 480 | 578 |
| 481 SetAppHidden(profile, host->GetAppId(), hidden); | 579 const std::string& app_id = host->GetAppId(); |
| 580 if (delegate_->GetAppExtension(profile, app_id)->is_hosted_app()) { | |
| 581 SetHostedAppHidden(profile, app_id, hidden); | |
| 582 } else { | |
| 583 SetAppHidden(profile, app_id, hidden); | |
| 584 } | |
| 482 } | 585 } |
| 483 | 586 |
| 484 void ExtensionAppShimHandler::OnShimQuit(Host* host) { | 587 void ExtensionAppShimHandler::OnShimQuit(Host* host) { |
| 485 DCHECK(delegate_->ProfileExistsForPath(host->GetProfilePath())); | 588 DCHECK(delegate_->ProfileExistsForPath(host->GetProfilePath())); |
| 486 Profile* profile = delegate_->ProfileForPath(host->GetProfilePath()); | 589 Profile* profile = delegate_->ProfileForPath(host->GetProfilePath()); |
| 487 | 590 |
| 488 const std::string& app_id = host->GetAppId(); | 591 const std::string& app_id = host->GetAppId(); |
| 489 const AppWindowList windows = delegate_->GetWindows(profile, app_id); | 592 if (delegate_->GetAppExtension(profile, app_id)->is_hosted_app()) { |
| 490 for (AppWindowRegistry::const_iterator it = windows.begin(); | 593 std::vector<content::WebContents*> items; |
| 491 it != windows.end(); | 594 AppBrowserMap::iterator it = app_browser_windows_.find(app_id); |
| 492 ++it) { | 595 if (it == app_browser_windows_.end()) |
| 493 (*it)->GetBaseWindow()->Close(); | 596 return; |
| 597 | |
| 598 const BrowserSet& browsers = it->second; | |
| 599 for (BrowserSet::const_iterator it = browsers.begin(); it != browsers.end(); | |
| 600 ++it) { | |
| 601 Browser* browser = *it; | |
| 602 TabStripModel* tab_strip = browser->tab_strip_model(); | |
|
jackhou1
2014/12/11 02:43:18
I think you can just call BrowserWindow::Close().
mitchellj
2014/12/12 00:03:45
Done.
| |
| 603 for (int index = 0; index < tab_strip->count(); index++) { | |
| 604 content::WebContents* web_contents = tab_strip->GetWebContentsAt(index); | |
| 605 web_contents->Close(); | |
| 606 } | |
| 607 } | |
| 608 } else { | |
| 609 const AppWindowList windows = delegate_->GetWindows(profile, app_id); | |
| 610 for (AppWindowRegistry::const_iterator it = windows.begin(); | |
| 611 it != windows.end(); ++it) { | |
| 612 (*it)->GetBaseWindow()->Close(); | |
| 613 } | |
| 494 } | 614 } |
| 495 // Once the last window closes, flow will end up in OnAppDeactivated via | 615 // Once the last window closes, flow will end up in OnAppDeactivated via |
| 496 // AppLifetimeMonitor. | 616 // AppLifetimeMonitor. |
| 617 // Otherwise, once the last window closes for a hosted app, OnBrowserRevmoed | |
|
jackhou1
2014/12/11 02:43:18
s/Revmoed/Removed/
mitchellj
2014/12/12 00:03:45
Done.
| |
| 618 // will call OnAppDeactivated. | |
| 497 } | 619 } |
| 498 | 620 |
| 499 void ExtensionAppShimHandler::set_delegate(Delegate* delegate) { | 621 void ExtensionAppShimHandler::set_delegate(Delegate* delegate) { |
| 500 delegate_.reset(delegate); | 622 delegate_.reset(delegate); |
| 501 } | 623 } |
| 502 | 624 |
| 503 void ExtensionAppShimHandler::Observe( | 625 void ExtensionAppShimHandler::Observe( |
| 504 int type, | 626 int type, |
| 505 const content::NotificationSource& source, | 627 const content::NotificationSource& source, |
| 506 const content::NotificationDetails& details) { | 628 const content::NotificationDetails& details) { |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 562 | 684 |
| 563 if (hosts_.empty()) | 685 if (hosts_.empty()) |
| 564 delegate_->MaybeTerminate(); | 686 delegate_->MaybeTerminate(); |
| 565 } | 687 } |
| 566 | 688 |
| 567 void ExtensionAppShimHandler::OnAppStop(Profile* profile, | 689 void ExtensionAppShimHandler::OnAppStop(Profile* profile, |
| 568 const std::string& app_id) {} | 690 const std::string& app_id) {} |
| 569 | 691 |
| 570 void ExtensionAppShimHandler::OnChromeTerminating() {} | 692 void ExtensionAppShimHandler::OnChromeTerminating() {} |
| 571 | 693 |
| 694 void ExtensionAppShimHandler::OnBrowserAdded(Browser* browser) { | |
| 695 // Don't keep track of browsers that are not associated with an app. | |
| 696 if (!browser->is_app()) | |
| 697 return; | |
| 698 | |
| 699 std::string app_id = | |
| 700 web_app::GetExtensionIdFromApplicationName(browser->app_name()); | |
| 701 BrowserSet& browsers = app_browser_windows_[app_id]; | |
| 702 browsers.insert(browser); | |
|
jackhou1
2014/12/11 02:43:18
You should make this call OnAppActivated if it is
mitchellj
2014/12/12 00:03:45
Done. I ran into a problem where calling OnAppActi
| |
| 703 } | |
| 704 | |
| 705 void ExtensionAppShimHandler::OnBrowserRemoved(Browser* browser) { | |
| 706 if (!browser->is_app()) | |
|
jackhou1
2014/12/11 02:43:18
I think we should be consistent about checking bot
mitchellj
2014/12/12 00:03:45
Done.
| |
| 707 return; | |
| 708 | |
| 709 std::string app_id = | |
| 710 web_app::GetExtensionIdFromApplicationName(browser->app_name()); | |
| 711 AppBrowserMap::iterator it = app_browser_windows_.find(app_id); | |
| 712 if (it != app_browser_windows_.end()) { | |
| 713 BrowserSet& browsers = it->second; | |
| 714 browsers.erase(browser); | |
| 715 if (browsers.empty()) | |
| 716 OnAppDeactivated(browser->profile(), app_id); | |
| 717 } | |
| 718 } | |
| 719 | |
| 572 } // namespace apps | 720 } // namespace apps |
| OLD | NEW |