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