summaryrefslogtreecommitdiff
path: root/apps/app_shim/extension_app_shim_handler_mac.cc
diff options
context:
space:
mode:
authorTorne (Richard Coles) <torne@google.com>2013-05-29 14:40:03 +0100
committerTorne (Richard Coles) <torne@google.com>2013-05-29 14:40:03 +0100
commit90dce4d38c5ff5333bea97d859d4e484e27edf0c (patch)
tree9c51c7dd97d24b15befa97a3482c51851e5383a1 /apps/app_shim/extension_app_shim_handler_mac.cc
parent1515035f5917d10d363b0888a3615d581ad8b83f (diff)
downloadchromium_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.cc130
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