diff options
author | Torne (Richard Coles) <torne@google.com> | 2013-05-29 14:40:03 +0100 |
---|---|---|
committer | Torne (Richard Coles) <torne@google.com> | 2013-05-29 14:40:03 +0100 |
commit | 90dce4d38c5ff5333bea97d859d4e484e27edf0c (patch) | |
tree | 9c51c7dd97d24b15befa97a3482c51851e5383a1 /apps/app_shim/extension_app_shim_handler_mac.cc | |
parent | 1515035f5917d10d363b0888a3615d581ad8b83f (diff) | |
download | chromium_org-90dce4d38c5ff5333bea97d859d4e484e27edf0c.tar.gz |
Merge from Chromium at DEPS revision r202854
This commit was generated by merge_to_master.py.
Change-Id: Idca323f71ef844a9e04f454d4f070b1e398f2deb
Diffstat (limited to 'apps/app_shim/extension_app_shim_handler_mac.cc')
-rw-r--r-- | apps/app_shim/extension_app_shim_handler_mac.cc | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/apps/app_shim/extension_app_shim_handler_mac.cc b/apps/app_shim/extension_app_shim_handler_mac.cc new file mode 100644 index 0000000000..9d31d694c0 --- /dev/null +++ b/apps/app_shim/extension_app_shim_handler_mac.cc @@ -0,0 +1,130 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "apps/app_shim/extension_app_shim_handler_mac.h" + +#include "apps/app_shim/app_shim_messages.h" +#include "base/files/file_path.h" +#include "base/logging.h" +#include "chrome/browser/extensions/extension_host.h" +#include "chrome/browser/extensions/extension_service.h" +#include "chrome/browser/extensions/extension_system.h" +#include "chrome/browser/extensions/shell_window_registry.h" +#include "chrome/browser/ui/extensions/application_launch.h" +#include "chrome/browser/ui/extensions/shell_window.h" +#include "ui/base/cocoa/focus_window_set.h" + +namespace apps { + +ExtensionAppShimHandler::ExtensionAppShimHandler() {} + +ExtensionAppShimHandler::~ExtensionAppShimHandler() { + for (HostMap::iterator it = hosts_.begin(); it != hosts_.end(); ) { + // Increment the iterator first as OnAppClosed may call back to OnShimClose + // and invalidate the iterator. + it++->second->OnAppClosed(); + } +} + +bool ExtensionAppShimHandler::OnShimLaunch(Host* host) { + Profile* profile = host->GetProfile(); + DCHECK(profile); + + const std::string& app_id = host->GetAppId(); + if (!extensions::Extension::IdIsValid(app_id)) { + LOG(ERROR) << "Bad app ID from app shim launch message."; + return false; + } + + if (!LaunchApp(profile, app_id)) + return false; + + // The first host to claim this (profile, app_id) becomes the main host. + // For any others, we launch the app but return false. + if (!hosts_.insert(make_pair(make_pair(profile, app_id), host)).second) + return false; + + if (!registrar_.IsRegistered( + this, chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED, + content::Source<Profile>(profile))) { + registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED, + content::Source<Profile>(profile)); + } + + return true; +} + +void ExtensionAppShimHandler::OnShimClose(Host* host) { + HostMap::iterator it = hosts_.find(make_pair(host->GetProfile(), + host->GetAppId())); + // Any hosts other than the main host will still call OnShimClose, so ignore + // them. + if (it != hosts_.end() && it->second == host) + hosts_.erase(it); +} + +void ExtensionAppShimHandler::OnShimFocus(Host* host) { + if (!host->GetProfile()) + return; + + extensions::ShellWindowRegistry* registry = + extensions::ShellWindowRegistry::Get(host->GetProfile()); + const extensions::ShellWindowRegistry::ShellWindowList windows = + registry->GetShellWindowsForApp(host->GetAppId()); + std::set<gfx::NativeWindow> native_windows; + for (extensions::ShellWindowRegistry::const_iterator i = windows.begin(); + i != windows.end(); ++i) { + native_windows.insert((*i)->GetNativeWindow()); + } + ui::FocusWindowSet(native_windows); +} + +bool ExtensionAppShimHandler::LaunchApp(Profile* profile, + const std::string& app_id) { + extensions::ExtensionSystem* extension_system = + extensions::ExtensionSystem::Get(profile); + ExtensionServiceInterface* extension_service = + extension_system->extension_service(); + const extensions::Extension* extension = + extension_service->GetExtensionById(app_id, false); + if (!extension) { + LOG(ERROR) << "Attempted to launch nonexistent app with id '" + << app_id << "'."; + return false; + } + // TODO(jeremya): Handle the case that launching the app fails. Probably we + // need to watch for 'app successfully launched' or at least 'background page + // exists/was created' and time out with failure if we don't see that sign of + // life within a certain window. + chrome::OpenApplication(chrome::AppLaunchParams( + profile, extension, NEW_FOREGROUND_TAB)); + return true; +} + +void ExtensionAppShimHandler::Observe( + int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) { + Profile* profile = content::Source<Profile>(source).ptr(); + switch (type) { + case chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED: { + extensions::ExtensionHost* extension_host = + content::Details<extensions::ExtensionHost>(details).ptr(); + CloseShim(profile, extension_host->extension_id()); + break; + } + default: + NOTREACHED(); // Unexpected notification. + break; + } +} + +void ExtensionAppShimHandler::CloseShim(Profile* profile, + const std::string& app_id) { + HostMap::const_iterator it = hosts_.find(make_pair(profile, app_id)); + if (it != hosts_.end()) + it->second->OnAppClosed(); +} + +} // namespace apps |