summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authortapted <tapted@chromium.org>2014-09-24 16:50:50 -0700
committerCommit bot <commit-bot@chromium.org>2014-09-24 23:51:09 +0000
commit63829f711468110d04c7464acf92c3e7ab3c13d7 (patch)
treef57c59b72f62d1ae05d3fbbd11963d69deeef6aa /apps
parent18112c74cee064411a29cfdc3f3464b653b4a67a (diff)
downloadchromium_src-63829f711468110d04c7464acf92c3e7ab3c13d7.zip
chromium_src-63829f711468110d04c7464acf92c3e7ab3c13d7.tar.gz
chromium_src-63829f711468110d04c7464acf92c3e7ab3c13d7.tar.bz2
Mac: Give app_shim code a nicer home
App Shims are small .app bundles for Mac, which run in their own process to provide packaged apps with an OSX Dock icon, using IPC to communicate with the browser process. Most of the app_shim code currently lives in src/apps/app_shim, but app shims are very much a browser feature, so it doesn't belong there. It's causing DEPS problems for athena efforts. This CL moves most of apps/app_shim to chrome/browser/apps/app_shim (c/b/apps didn't exist until a few months after src/apps/app_shim). The shim itself (i.e. chrome_main_app_mode_mac.mm) doesn't run in the browser process - it has its own, shim process. Those parts are moved to a new folder: src/chrome/app_shim, consolidating files currently spread across src/apps/app_shim and src/chrome/app. app_shim_launch.h and app_shim_messages.h are used in both the shim process and the browser process. They're moved to chrome/common/mac. Summary of changes: {apps => chrome/browser/apps}/app_shim/* except {apps => chrome}/app_shim/chrome_main_app_mode_mac.mm {apps/app_shim => chrome/common/mac}/app_shim_launch.h {apps/app_shim => chrome/common/mac}/app_shim_messages.h app_shim.gypi renamed to browser_app_shim.gypi chrome/app_shim/app_shim.gypi added and chrome/{app => app_shim}/app_mode-Info.plist chrome/{app => app_shim}/app_mode_loader_mac.mm - apps/app_shim/DEPS now just generated_resources.h - 'app_mode_app' target moved from chrome.gyp to app_shim.gypi BUG=266705 Review URL: https://codereview.chromium.org/585123004 Cr-Commit-Position: refs/heads/master@{#296576}
Diffstat (limited to 'apps')
-rw-r--r--apps/app_shim/DEPS19
-rw-r--r--apps/app_shim/OWNERS1
-rw-r--r--apps/app_shim/app_shim.gypi36
-rw-r--r--apps/app_shim/app_shim_handler_mac.cc156
-rw-r--r--apps/app_shim/app_shim_handler_mac.h96
-rw-r--r--apps/app_shim/app_shim_host_mac.cc130
-rw-r--r--apps/app_shim/app_shim_host_mac.h86
-rw-r--r--apps/app_shim/app_shim_host_mac_unittest.cc175
-rw-r--r--apps/app_shim/app_shim_host_manager_browsertest_mac.mm287
-rw-r--r--apps/app_shim/app_shim_host_manager_mac.h73
-rw-r--r--apps/app_shim/app_shim_host_manager_mac.mm168
-rw-r--r--apps/app_shim/app_shim_interactive_uitest_mac.mm407
-rw-r--r--apps/app_shim/app_shim_launch.h57
-rw-r--r--apps/app_shim/app_shim_messages.h71
-rw-r--r--apps/app_shim/app_shim_quit_interactive_uitest_mac.mm132
-rw-r--r--apps/app_shim/chrome_main_app_mode_mac.mm693
-rw-r--r--apps/app_shim/extension_app_shim_handler_mac.cc557
-rw-r--r--apps/app_shim/extension_app_shim_handler_mac.h159
-rw-r--r--apps/app_shim/extension_app_shim_handler_mac_unittest.cc396
-rw-r--r--apps/app_shim/test/app_shim_host_manager_test_api_mac.cc26
-rw-r--r--apps/app_shim/test/app_shim_host_manager_test_api_mac.h38
-rw-r--r--apps/app_shim/unix_domain_socket_acceptor.cc90
-rw-r--r--apps/app_shim/unix_domain_socket_acceptor.h57
23 files changed, 0 insertions, 3910 deletions
diff --git a/apps/app_shim/DEPS b/apps/app_shim/DEPS
deleted file mode 100644
index ec27f8a..0000000
--- a/apps/app_shim/DEPS
+++ /dev/null
@@ -1,19 +0,0 @@
-include_rules = [
- # TODO(benwells): move this whole folder out of apps and review these.
- # See http://crbug.com/266705.
- "+chrome/browser/browser_process.h",
- "+chrome/browser/ui/app_list/app_list_service.h",
- "+chrome/browser/ui/app_list/app_list_util.h",
- "+chrome/browser/ui/extensions/application_launch.h",
- "+chrome/browser/ui/extensions/extension_enable_flow.h",
- "+chrome/browser/ui/extensions/extension_enable_flow_delegate.h",
- "+chrome/browser/ui/webui/ntp/core_app_launcher_handler.h",
- "+chrome/browser/web_applications/web_app_mac.h",
- "+chrome/common/chrome_constants.h",
- "+chrome/common/chrome_paths.h",
- "+chrome/common/chrome_version_info.h",
- "+chrome/common/extensions/extension_constants.h",
- "+chrome/common/mac/app_mode_common.h",
- "+components/crx_file",
- "+grit/generated_resources.h",
-]
diff --git a/apps/app_shim/OWNERS b/apps/app_shim/OWNERS
deleted file mode 100644
index 13c6f49..0000000
--- a/apps/app_shim/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-tapted@chromium.org
diff --git a/apps/app_shim/app_shim.gypi b/apps/app_shim/app_shim.gypi
deleted file mode 100644
index 51a729a..0000000
--- a/apps/app_shim/app_shim.gypi
+++ /dev/null
@@ -1,36 +0,0 @@
-# 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.
-
-{
- 'targets': [
- {
- 'target_name': 'app_shim',
- 'type': 'static_library',
- # Since app_shim and browser depend on each other, we omit the dependency
- # on browser here.
- 'dependencies': [
- '../chrome/chrome_resources.gyp:chrome_strings',
- '../content/content.gyp:content_common',
- '../skia/skia.gyp:skia',
- ],
- 'include_dirs': [
- '<(INTERMEDIATE_DIR)',
- '<(grit_out_dir)',
- ],
- 'sources': [
- 'app_shim_handler_mac.cc',
- 'app_shim_handler_mac.h',
- 'app_shim_host_mac.cc',
- 'app_shim_host_mac.h',
- 'app_shim_host_manager_mac.h',
- 'app_shim_host_manager_mac.mm',
- 'chrome_main_app_mode_mac.mm',
- 'extension_app_shim_handler_mac.cc',
- 'extension_app_shim_handler_mac.h',
- 'unix_domain_socket_acceptor.cc',
- 'unix_domain_socket_acceptor.h',
- ],
- },
- ], # targets
-}
diff --git a/apps/app_shim/app_shim_handler_mac.cc b/apps/app_shim/app_shim_handler_mac.cc
deleted file mode 100644
index 3153bd4..0000000
--- a/apps/app_shim/app_shim_handler_mac.cc
+++ /dev/null
@@ -1,156 +0,0 @@
-// 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/app_shim_handler_mac.h"
-
-#include <map>
-
-#include "base/bind.h"
-#include "base/logging.h"
-#include "base/memory/singleton.h"
-#include "base/message_loop/message_loop.h"
-#include "chrome/browser/chrome_notification_types.h"
-#include "chrome/browser/lifetime/application_lifetime.h"
-#include "chrome/browser/ui/app_list/app_list_service.h"
-#include "content/public/browser/notification_observer.h"
-#include "content/public/browser/notification_registrar.h"
-#include "content/public/browser/notification_service.h"
-#include "extensions/browser/app_window/app_window_registry.h"
-
-namespace apps {
-
-namespace {
-
-void TerminateIfNoAppWindows() {
- bool app_windows_left =
- extensions::AppWindowRegistry::IsAppWindowRegisteredInAnyProfile(0);
- if (!app_windows_left &&
- !AppListService::Get(chrome::HOST_DESKTOP_TYPE_NATIVE)
- ->IsAppListVisible()) {
- chrome::AttemptExit();
- }
-}
-
-class AppShimHandlerRegistry : public content::NotificationObserver {
- public:
- static AppShimHandlerRegistry* GetInstance() {
- return Singleton<AppShimHandlerRegistry,
- LeakySingletonTraits<AppShimHandlerRegistry> >::get();
- }
-
- AppShimHandler* GetForAppMode(const std::string& app_mode_id) const {
- HandlerMap::const_iterator it = handlers_.find(app_mode_id);
- if (it != handlers_.end())
- return it->second;
-
- return default_handler_;
- }
-
- bool SetForAppMode(const std::string& app_mode_id, AppShimHandler* handler) {
- bool inserted_or_removed = handler ?
- handlers_.insert(HandlerMap::value_type(app_mode_id, handler)).second :
- handlers_.erase(app_mode_id) == 1;
- DCHECK(inserted_or_removed);
- return inserted_or_removed;
- }
-
- void SetDefaultHandler(AppShimHandler* handler) {
- DCHECK_NE(default_handler_ == NULL, handler == NULL);
- default_handler_ = handler;
- }
-
- void MaybeTerminate() {
- if (!browser_session_running_) {
- // Post this to give AppWindows a chance to remove themselves from the
- // registry.
- base::MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&TerminateIfNoAppWindows));
- }
- }
-
- bool ShouldRestoreSession() {
- return !browser_session_running_;
- }
-
- private:
- friend struct DefaultSingletonTraits<AppShimHandlerRegistry>;
- typedef std::map<std::string, AppShimHandler*> HandlerMap;
-
- AppShimHandlerRegistry()
- : default_handler_(NULL),
- browser_session_running_(false) {
- registrar_.Add(
- this, chrome::NOTIFICATION_BROWSER_OPENED,
- content::NotificationService::AllBrowserContextsAndSources());
- registrar_.Add(
- this, chrome::NOTIFICATION_CLOSE_ALL_BROWSERS_REQUEST,
- content::NotificationService::AllBrowserContextsAndSources());
- registrar_.Add(
- this, chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED,
- content::NotificationService::AllBrowserContextsAndSources());
- }
-
- virtual ~AppShimHandlerRegistry() {}
-
- // content::NotificationObserver override:
- virtual void Observe(
- int type,
- const content::NotificationSource& source,
- const content::NotificationDetails& details) OVERRIDE {
- switch (type) {
- case chrome::NOTIFICATION_BROWSER_OPENED:
- case chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED:
- browser_session_running_ = true;
- break;
- case chrome::NOTIFICATION_CLOSE_ALL_BROWSERS_REQUEST:
- browser_session_running_ = false;
- break;
- default:
- NOTREACHED();
- }
- }
-
- HandlerMap handlers_;
- AppShimHandler* default_handler_;
- content::NotificationRegistrar registrar_;
- bool browser_session_running_;
-
- DISALLOW_COPY_AND_ASSIGN(AppShimHandlerRegistry);
-};
-
-} // namespace
-
-// static
-void AppShimHandler::RegisterHandler(const std::string& app_mode_id,
- AppShimHandler* handler) {
- DCHECK(handler);
- AppShimHandlerRegistry::GetInstance()->SetForAppMode(app_mode_id, handler);
-}
-
-// static
-void AppShimHandler::RemoveHandler(const std::string& app_mode_id) {
- AppShimHandlerRegistry::GetInstance()->SetForAppMode(app_mode_id, NULL);
-}
-
-// static
-AppShimHandler* AppShimHandler::GetForAppMode(const std::string& app_mode_id) {
- return AppShimHandlerRegistry::GetInstance()->GetForAppMode(app_mode_id);
-}
-
-// static
-void AppShimHandler::SetDefaultHandler(AppShimHandler* handler) {
- AppShimHandlerRegistry::GetInstance()->SetDefaultHandler(handler);
-}
-
-// static
-void AppShimHandler::MaybeTerminate() {
- AppShimHandlerRegistry::GetInstance()->MaybeTerminate();
-}
-
-// static
-bool AppShimHandler::ShouldRestoreSession() {
- return AppShimHandlerRegistry::GetInstance()->ShouldRestoreSession();
-}
-
-} // namespace apps
diff --git a/apps/app_shim/app_shim_handler_mac.h b/apps/app_shim/app_shim_handler_mac.h
deleted file mode 100644
index 2cc3425..0000000
--- a/apps/app_shim/app_shim_handler_mac.h
+++ /dev/null
@@ -1,96 +0,0 @@
-// 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.
-
-#ifndef APPS_APP_SHIM_APP_SHIM_HANDLER_MAC_H_
-#define APPS_APP_SHIM_APP_SHIM_HANDLER_MAC_H_
-
-#include <string>
-#include <vector>
-
-#include "apps/app_shim/app_shim_launch.h"
-#include "base/files/file_path.h"
-
-namespace apps {
-
-// Registrar, and interface for services that can handle interactions with OSX
-// shim processes.
-class AppShimHandler {
- public:
- class Host {
- public:
- // Invoked when the app is successfully launched.
- virtual void OnAppLaunchComplete(AppShimLaunchResult result) = 0;
- // Invoked when the app is closed in the browser process.
- virtual void OnAppClosed() = 0;
- // Invoked when the app should be hidden.
- virtual void OnAppHide() = 0;
- // Invoked when the app is requesting user attention.
- virtual void OnAppRequestUserAttention(AppShimAttentionType type) = 0;
-
- // Allows the handler to determine which app this host corresponds to.
- virtual base::FilePath GetProfilePath() const = 0;
- virtual std::string GetAppId() const = 0;
-
- protected:
- virtual ~Host() {}
- };
-
- // Register a handler for an |app_mode_id|.
- static void RegisterHandler(const std::string& app_mode_id,
- AppShimHandler* handler);
-
- // Remove a handler for an |app_mode_id|.
- static void RemoveHandler(const std::string& app_mode_id);
-
- // Returns the handler registered for the given |app_mode_id|. If there is
- // none registered, it returns the default handler or NULL if there is no
- // default handler.
- static AppShimHandler* GetForAppMode(const std::string& app_mode_id);
-
- // Sets the default handler to return when there is no app-specific handler.
- // Setting this to NULL removes the default handler.
- static void SetDefaultHandler(AppShimHandler* handler);
-
- // Terminate Chrome if a browser window has never been opened, there are no
- // shell windows, and the app list is not visible.
- static void MaybeTerminate();
-
- // Whether browser sessions should be restored right now. This is true if
- // the browser has been quit but kept alive because Chrome Apps are still
- // running.
- static bool ShouldRestoreSession();
-
- // Invoked by the shim host when the shim process is launched. The handler
- // must call OnAppLaunchComplete to inform the shim of the result.
- // |launch_type| indicates the type of launch.
- // |files|, if non-empty, holds an array of files paths given as arguments, or
- // dragged onto the app bundle or dock icon.
- virtual void OnShimLaunch(Host* host,
- AppShimLaunchType launch_type,
- const std::vector<base::FilePath>& files) = 0;
-
- // Invoked by the shim host when the connection to the shim process is closed.
- virtual void OnShimClose(Host* host) = 0;
-
- // Invoked by the shim host when the shim process receives a focus event.
- // |files|, if non-empty, holds an array of files dragged onto the app bundle
- // or dock icon.
- virtual void OnShimFocus(Host* host,
- AppShimFocusType focus_type,
- const std::vector<base::FilePath>& files) = 0;
-
- // Invoked by the shim host when the shim process is hidden or shown.
- virtual void OnShimSetHidden(Host* host, bool hidden) = 0;
-
- // Invoked by the shim host when the shim process receives a quit event.
- virtual void OnShimQuit(Host* host) = 0;
-
- protected:
- AppShimHandler() {}
- virtual ~AppShimHandler() {}
-};
-
-} // namespace apps
-
-#endif // APPS_APP_SHIM_APP_SHIM_HANDLER_MAC_H_
diff --git a/apps/app_shim/app_shim_host_mac.cc b/apps/app_shim/app_shim_host_mac.cc
deleted file mode 100644
index b8a6b90..0000000
--- a/apps/app_shim/app_shim_host_mac.cc
+++ /dev/null
@@ -1,130 +0,0 @@
-// 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/app_shim_host_mac.h"
-
-#include "apps/app_shim/app_shim_handler_mac.h"
-#include "apps/app_shim/app_shim_messages.h"
-#include "base/bind.h"
-#include "base/files/file_path.h"
-#include "base/logging.h"
-#include "content/public/browser/browser_thread.h"
-#include "ipc/ipc_channel_proxy.h"
-
-AppShimHost::AppShimHost() : initial_launch_finished_(false) {}
-
-AppShimHost::~AppShimHost() {
- DCHECK(CalledOnValidThread());
- apps::AppShimHandler* handler = apps::AppShimHandler::GetForAppMode(app_id_);
- if (handler)
- handler->OnShimClose(this);
-}
-
-void AppShimHost::ServeChannel(const IPC::ChannelHandle& handle) {
- DCHECK(CalledOnValidThread());
- DCHECK(!channel_.get());
- channel_ = IPC::ChannelProxy::Create(
- handle,
- IPC::Channel::MODE_SERVER,
- this,
- content::BrowserThread::GetMessageLoopProxyForThread(
- content::BrowserThread::IO).get());
-}
-
-base::FilePath AppShimHost::GetProfilePath() const {
- return profile_path_;
-}
-
-std::string AppShimHost::GetAppId() const {
- return app_id_;
-}
-
-bool AppShimHost::OnMessageReceived(const IPC::Message& message) {
- DCHECK(CalledOnValidThread());
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(AppShimHost, message)
- IPC_MESSAGE_HANDLER(AppShimHostMsg_LaunchApp, OnLaunchApp)
- IPC_MESSAGE_HANDLER(AppShimHostMsg_FocusApp, OnFocus)
- IPC_MESSAGE_HANDLER(AppShimHostMsg_SetAppHidden, OnSetHidden)
- IPC_MESSAGE_HANDLER(AppShimHostMsg_QuitApp, OnQuit)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
-
- return handled;
-}
-
-void AppShimHost::OnChannelError() {
- Close();
-}
-
-bool AppShimHost::Send(IPC::Message* message) {
- DCHECK(channel_.get());
- return channel_->Send(message);
-}
-
-void AppShimHost::OnLaunchApp(const base::FilePath& profile_dir,
- const std::string& app_id,
- apps::AppShimLaunchType launch_type,
- const std::vector<base::FilePath>& files) {
- DCHECK(CalledOnValidThread());
- DCHECK(profile_path_.empty());
- // Only one app launch message per channel.
- if (!profile_path_.empty())
- return;
-
- profile_path_ = profile_dir;
- app_id_ = app_id;
-
- apps::AppShimHandler* handler = apps::AppShimHandler::GetForAppMode(app_id_);
- if (handler)
- handler->OnShimLaunch(this, launch_type, files);
- // |handler| can only be NULL after AppShimHostManager is destroyed. Since
- // this only happens at shutdown, do nothing here.
-}
-
-void AppShimHost::OnFocus(apps::AppShimFocusType focus_type,
- const std::vector<base::FilePath>& files) {
- DCHECK(CalledOnValidThread());
- apps::AppShimHandler* handler = apps::AppShimHandler::GetForAppMode(app_id_);
- if (handler)
- handler->OnShimFocus(this, focus_type, files);
-}
-
-void AppShimHost::OnSetHidden(bool hidden) {
- DCHECK(CalledOnValidThread());
- apps::AppShimHandler* handler = apps::AppShimHandler::GetForAppMode(app_id_);
- if (handler)
- handler->OnShimSetHidden(this, hidden);
-}
-
-void AppShimHost::OnQuit() {
- DCHECK(CalledOnValidThread());
- apps::AppShimHandler* handler = apps::AppShimHandler::GetForAppMode(app_id_);
- if (handler)
- handler->OnShimQuit(this);
-}
-
-void AppShimHost::OnAppLaunchComplete(apps::AppShimLaunchResult result) {
- if (!initial_launch_finished_) {
- Send(new AppShimMsg_LaunchApp_Done(result));
- initial_launch_finished_ = true;
- }
-}
-
-void AppShimHost::OnAppClosed() {
- Close();
-}
-
-void AppShimHost::OnAppHide() {
- Send(new AppShimMsg_Hide);
-}
-
-void AppShimHost::OnAppRequestUserAttention(apps::AppShimAttentionType type) {
- Send(new AppShimMsg_SetUserAttention(type));
-}
-
-void AppShimHost::Close() {
- DCHECK(CalledOnValidThread());
- delete this;
-}
diff --git a/apps/app_shim/app_shim_host_mac.h b/apps/app_shim/app_shim_host_mac.h
deleted file mode 100644
index 5b3f00e..0000000
--- a/apps/app_shim/app_shim_host_mac.h
+++ /dev/null
@@ -1,86 +0,0 @@
-// 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.
-
-#ifndef APPS_APP_SHIM_APP_SHIM_HOST_MAC_H_
-#define APPS_APP_SHIM_APP_SHIM_HOST_MAC_H_
-
-#include <string>
-#include <vector>
-
-#include "apps/app_shim/app_shim_handler_mac.h"
-#include "base/files/file_path.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/threading/non_thread_safe.h"
-#include "ipc/ipc_listener.h"
-#include "ipc/ipc_sender.h"
-
-namespace IPC {
-struct ChannelHandle;
-class ChannelProxy;
-class Message;
-} // namespace IPC
-
-// This is the counterpart to AppShimController in
-// chrome/app/chrome_main_app_mode_mac.mm. The AppShimHost owns itself, and is
-// destroyed when the app it corresponds to is closed or when the channel
-// connected to the app shim is closed.
-class AppShimHost : public IPC::Listener,
- public IPC::Sender,
- public apps::AppShimHandler::Host,
- public base::NonThreadSafe {
- public:
- AppShimHost();
- virtual ~AppShimHost();
-
- // Creates a new server-side IPC channel at |handle|, which should contain a
- // file descriptor of a channel created by an UnixDomainSocketAcceptor,
- // and begins listening for messages on it.
- void ServeChannel(const IPC::ChannelHandle& handle);
-
- protected:
- // IPC::Listener implementation.
- virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
- virtual void OnChannelError() OVERRIDE;
-
- // IPC::Sender implementation.
- virtual bool Send(IPC::Message* message) OVERRIDE;
-
- private:
- // The app shim process is requesting to be associated with the given profile
- // and app_id. Once the profile and app_id are stored, and all future
- // messages from the app shim relate to this app. The app is launched
- // immediately if |launch_now| is true.
- void OnLaunchApp(const base::FilePath& profile_dir,
- const std::string& app_id,
- apps::AppShimLaunchType launch_type,
- const std::vector<base::FilePath>& files);
-
- // Called when the app shim process notifies that the app was focused.
- void OnFocus(apps::AppShimFocusType focus_type,
- const std::vector<base::FilePath>& files);
-
- void OnSetHidden(bool hidden);
-
- // Called when the app shim process notifies that the app should quit.
- void OnQuit();
-
- // apps::AppShimHandler::Host overrides:
- virtual void OnAppLaunchComplete(apps::AppShimLaunchResult result) OVERRIDE;
- virtual void OnAppClosed() OVERRIDE;
- virtual void OnAppHide() OVERRIDE;
- virtual void OnAppRequestUserAttention(
- apps::AppShimAttentionType type) OVERRIDE;
- virtual base::FilePath GetProfilePath() const OVERRIDE;
- virtual std::string GetAppId() const OVERRIDE;
-
- // Closes the channel and destroys the AppShimHost.
- void Close();
-
- scoped_ptr<IPC::ChannelProxy> channel_;
- std::string app_id_;
- base::FilePath profile_path_;
- bool initial_launch_finished_;
-};
-
-#endif // APPS_APP_SHIM_APP_SHIM_HOST_MAC_H_
diff --git a/apps/app_shim/app_shim_host_mac_unittest.cc b/apps/app_shim/app_shim_host_mac_unittest.cc
deleted file mode 100644
index b4b56fb6..0000000
--- a/apps/app_shim/app_shim_host_mac_unittest.cc
+++ /dev/null
@@ -1,175 +0,0 @@
-// 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/app_shim_host_mac.h"
-
-#include <vector>
-
-#include "apps/app_shim/app_shim_messages.h"
-#include "base/basictypes.h"
-#include "base/memory/scoped_vector.h"
-#include "ipc/ipc_message.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace {
-
-class TestingAppShimHost : public AppShimHost {
- public:
- TestingAppShimHost() {}
- virtual ~TestingAppShimHost() {}
-
- bool ReceiveMessage(IPC::Message* message);
-
- const std::vector<IPC::Message*>& sent_messages() {
- return sent_messages_.get();
- }
-
- protected:
- virtual bool Send(IPC::Message* message) OVERRIDE;
-
- private:
- ScopedVector<IPC::Message> sent_messages_;
-
- DISALLOW_COPY_AND_ASSIGN(TestingAppShimHost);
-};
-
-bool TestingAppShimHost::ReceiveMessage(IPC::Message* message) {
- bool handled = OnMessageReceived(*message);
- delete message;
- return handled;
-}
-
-bool TestingAppShimHost::Send(IPC::Message* message) {
- sent_messages_.push_back(message);
- return true;
-}
-
-const char kTestAppId[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
-const char kTestProfileDir[] = "Profile 1";
-
-class AppShimHostTest : public testing::Test,
- public apps::AppShimHandler {
- public:
- AppShimHostTest() : launch_result_(apps::APP_SHIM_LAUNCH_SUCCESS),
- launch_count_(0),
- launch_now_count_(0),
- close_count_(0),
- focus_count_(0),
- quit_count_(0) {}
-
- TestingAppShimHost* host() { return host_.get(); }
-
- void LaunchApp(apps::AppShimLaunchType launch_type) {
- EXPECT_TRUE(host()->ReceiveMessage(
- new AppShimHostMsg_LaunchApp(base::FilePath(kTestProfileDir),
- kTestAppId,
- launch_type,
- std::vector<base::FilePath>())));
- }
-
- apps::AppShimLaunchResult GetLaunchResult() {
- EXPECT_EQ(1u, host()->sent_messages().size());
- IPC::Message* message = host()->sent_messages()[0];
- EXPECT_EQ(AppShimMsg_LaunchApp_Done::ID, message->type());
- AppShimMsg_LaunchApp_Done::Param param;
- AppShimMsg_LaunchApp_Done::Read(message, &param);
- return param.a;
- }
-
- void SimulateDisconnect() {
- implicit_cast<IPC::Listener*>(host_.release())->OnChannelError();
- }
-
- protected:
- virtual void OnShimLaunch(Host* host,
- apps::AppShimLaunchType launch_type,
- const std::vector<base::FilePath>& file) OVERRIDE {
- ++launch_count_;
- if (launch_type == apps::APP_SHIM_LAUNCH_NORMAL)
- ++launch_now_count_;
- host->OnAppLaunchComplete(launch_result_);
- }
-
- virtual void OnShimClose(Host* host) OVERRIDE { ++close_count_; }
-
- virtual void OnShimFocus(Host* host,
- apps::AppShimFocusType focus_type,
- const std::vector<base::FilePath>& file) OVERRIDE {
- ++focus_count_;
- }
-
- virtual void OnShimSetHidden(Host* host, bool hidden) OVERRIDE {}
-
- virtual void OnShimQuit(Host* host) OVERRIDE { ++quit_count_; }
-
- apps::AppShimLaunchResult launch_result_;
- int launch_count_;
- int launch_now_count_;
- int close_count_;
- int focus_count_;
- int quit_count_;
-
- private:
- virtual void SetUp() OVERRIDE {
- testing::Test::SetUp();
- host_.reset(new TestingAppShimHost());
- }
-
- scoped_ptr<TestingAppShimHost> host_;
-
- DISALLOW_COPY_AND_ASSIGN(AppShimHostTest);
-};
-
-
-} // namespace
-
-TEST_F(AppShimHostTest, TestLaunchAppWithHandler) {
- apps::AppShimHandler::RegisterHandler(kTestAppId, this);
- LaunchApp(apps::APP_SHIM_LAUNCH_NORMAL);
- EXPECT_EQ(kTestAppId,
- implicit_cast<apps::AppShimHandler::Host*>(host())->GetAppId());
- EXPECT_EQ(apps::APP_SHIM_LAUNCH_SUCCESS, GetLaunchResult());
- EXPECT_EQ(1, launch_count_);
- EXPECT_EQ(1, launch_now_count_);
- EXPECT_EQ(0, focus_count_);
- EXPECT_EQ(0, close_count_);
-
- // A second OnAppLaunchComplete is ignored.
- implicit_cast<apps::AppShimHandler::Host*>(host())->
- OnAppLaunchComplete(apps::APP_SHIM_LAUNCH_APP_NOT_FOUND);
- EXPECT_EQ(apps::APP_SHIM_LAUNCH_SUCCESS, GetLaunchResult());
-
- EXPECT_TRUE(host()->ReceiveMessage(
- new AppShimHostMsg_FocusApp(apps::APP_SHIM_FOCUS_NORMAL,
- std::vector<base::FilePath>())));
- EXPECT_EQ(1, focus_count_);
-
- EXPECT_TRUE(host()->ReceiveMessage(new AppShimHostMsg_QuitApp()));
- EXPECT_EQ(1, quit_count_);
-
- SimulateDisconnect();
- EXPECT_EQ(1, close_count_);
- apps::AppShimHandler::RemoveHandler(kTestAppId);
-}
-
-TEST_F(AppShimHostTest, TestNoLaunchNow) {
- apps::AppShimHandler::RegisterHandler(kTestAppId, this);
- LaunchApp(apps::APP_SHIM_LAUNCH_REGISTER_ONLY);
- EXPECT_EQ(kTestAppId,
- implicit_cast<apps::AppShimHandler::Host*>(host())->GetAppId());
- EXPECT_EQ(apps::APP_SHIM_LAUNCH_SUCCESS, GetLaunchResult());
- EXPECT_EQ(1, launch_count_);
- EXPECT_EQ(0, launch_now_count_);
- EXPECT_EQ(0, focus_count_);
- EXPECT_EQ(0, close_count_);
- apps::AppShimHandler::RemoveHandler(kTestAppId);
-}
-
-TEST_F(AppShimHostTest, TestFailLaunch) {
- apps::AppShimHandler::RegisterHandler(kTestAppId, this);
- launch_result_ = apps::APP_SHIM_LAUNCH_APP_NOT_FOUND;
- LaunchApp(apps::APP_SHIM_LAUNCH_NORMAL);
- EXPECT_EQ(apps::APP_SHIM_LAUNCH_APP_NOT_FOUND, GetLaunchResult());
- apps::AppShimHandler::RemoveHandler(kTestAppId);
-}
diff --git a/apps/app_shim/app_shim_host_manager_browsertest_mac.mm b/apps/app_shim/app_shim_host_manager_browsertest_mac.mm
deleted file mode 100644
index 0ab7003..0000000
--- a/apps/app_shim/app_shim_host_manager_browsertest_mac.mm
+++ /dev/null
@@ -1,287 +0,0 @@
-// 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/app_shim_host_manager_mac.h"
-
-#include <unistd.h>
-
-#include "apps/app_shim/app_shim_messages.h"
-#include "apps/app_shim/test/app_shim_host_manager_test_api_mac.h"
-#include "base/files/file_path.h"
-#include "base/logging.h"
-#include "base/path_service.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/common/chrome_paths.h"
-#include "chrome/common/chrome_version_info.h"
-#include "chrome/common/mac/app_mode_common.h"
-#include "chrome/test/base/in_process_browser_test.h"
-#include "content/public/test/test_utils.h"
-#include "ipc/ipc_channel_proxy.h"
-#include "ipc/ipc_listener.h"
-#include "ipc/ipc_message.h"
-
-namespace {
-
-const char kTestAppMode[] = "test_app";
-
-// A test version of the AppShimController IPC client in chrome_main_app_mode.
-class TestShimClient : public IPC::Listener {
- public:
- TestShimClient();
- virtual ~TestShimClient();
-
- template <class T>
- void Send(const T& message) {
- channel_->Send(message);
- }
-
- private:
- // IPC::Listener overrides:
- virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
- virtual void OnChannelError() OVERRIDE;
-
- base::Thread io_thread_;
- scoped_ptr<IPC::ChannelProxy> channel_;
-
- DISALLOW_COPY_AND_ASSIGN(TestShimClient);
-};
-
-TestShimClient::TestShimClient() : io_thread_("TestShimClientIO") {
- base::Thread::Options io_thread_options;
- io_thread_options.message_loop_type = base::MessageLoop::TYPE_IO;
- io_thread_.StartWithOptions(io_thread_options);
-
- base::FilePath user_data_dir;
- CHECK(PathService::Get(chrome::DIR_USER_DATA, &user_data_dir));
- base::FilePath symlink_path =
- user_data_dir.Append(app_mode::kAppShimSocketSymlinkName);
-
- base::FilePath socket_path;
- CHECK(base::ReadSymbolicLink(symlink_path, &socket_path));
- app_mode::VerifySocketPermissions(socket_path);
-
- IPC::ChannelHandle handle(socket_path.value());
- channel_ = IPC::ChannelProxy::Create(handle,
- IPC::Channel::MODE_NAMED_CLIENT,
- this,
- io_thread_.message_loop_proxy().get());
-}
-
-TestShimClient::~TestShimClient() {}
-
-bool TestShimClient::OnMessageReceived(const IPC::Message& message) {
- return true;
-}
-
-void TestShimClient::OnChannelError() {
- // Client should not get any channel errors for the current set of tests.
- PLOG(FATAL) << "ChannelError";
-}
-
-// Browser Test for AppShimHostManager to test IPC interactions across the
-// UNIX domain socket.
-class AppShimHostManagerBrowserTest : public InProcessBrowserTest,
- public apps::AppShimHandler {
- public:
- AppShimHostManagerBrowserTest();
- virtual ~AppShimHostManagerBrowserTest();
-
- protected:
- // Wait for OnShimLaunch, then send a quit, and wait for the response. Used to
- // test launch behavior.
- void RunAndExitGracefully();
-
- // InProcessBrowserTest overrides:
- virtual void SetUpOnMainThread() OVERRIDE;
- virtual void TearDownOnMainThread() OVERRIDE;
-
- // AppShimHandler overrides:
- virtual void OnShimLaunch(apps::AppShimHandler::Host* host,
- apps::AppShimLaunchType launch_type,
- const std::vector<base::FilePath>& files) OVERRIDE;
- virtual void OnShimClose(apps::AppShimHandler::Host* host) OVERRIDE {}
- virtual void OnShimFocus(apps::AppShimHandler::Host* host,
- apps::AppShimFocusType focus_type,
- const std::vector<base::FilePath>& files) OVERRIDE {}
- virtual void OnShimSetHidden(apps::AppShimHandler::Host* host,
- bool hidden) OVERRIDE {}
- virtual void OnShimQuit(apps::AppShimHandler::Host* host) OVERRIDE;
-
- scoped_ptr<TestShimClient> test_client_;
- std::vector<base::FilePath> last_launch_files_;
- apps::AppShimLaunchType last_launch_type_;
-
-private:
- scoped_refptr<content::MessageLoopRunner> runner_;
-
- int launch_count_;
- int quit_count_;
-
- DISALLOW_COPY_AND_ASSIGN(AppShimHostManagerBrowserTest);
-};
-
-AppShimHostManagerBrowserTest::AppShimHostManagerBrowserTest()
- : last_launch_type_(apps::APP_SHIM_LAUNCH_NUM_TYPES),
- launch_count_(0),
- quit_count_(0) {
-}
-
-AppShimHostManagerBrowserTest::~AppShimHostManagerBrowserTest() {
-}
-
-void AppShimHostManagerBrowserTest::RunAndExitGracefully() {
- runner_ = new content::MessageLoopRunner();
- EXPECT_EQ(0, launch_count_);
- runner_->Run(); // Will stop in OnShimLaunch().
- EXPECT_EQ(1, launch_count_);
-
- runner_ = new content::MessageLoopRunner();
- test_client_->Send(new AppShimHostMsg_QuitApp);
- EXPECT_EQ(0, quit_count_);
- runner_->Run(); // Will stop in OnShimQuit().
- EXPECT_EQ(1, quit_count_);
-
- test_client_.reset();
-}
-
-void AppShimHostManagerBrowserTest::SetUpOnMainThread() {
- // Can't do this in the constructor, it needs a BrowserProcess.
- apps::AppShimHandler::RegisterHandler(kTestAppMode, this);
-}
-
-void AppShimHostManagerBrowserTest::TearDownOnMainThread() {
- apps::AppShimHandler::RemoveHandler(kTestAppMode);
-}
-
-void AppShimHostManagerBrowserTest::OnShimLaunch(
- apps::AppShimHandler::Host* host,
- apps::AppShimLaunchType launch_type,
- const std::vector<base::FilePath>& files) {
- host->OnAppLaunchComplete(apps::APP_SHIM_LAUNCH_SUCCESS);
- ++launch_count_;
- last_launch_type_ = launch_type;
- last_launch_files_ = files;
- runner_->Quit();
-}
-
-void AppShimHostManagerBrowserTest::OnShimQuit(
- apps::AppShimHandler::Host* host) {
- ++quit_count_;
- runner_->Quit();
-}
-
-// Test regular launch, which would ask Chrome to launch the app.
-IN_PROC_BROWSER_TEST_F(AppShimHostManagerBrowserTest, LaunchNormal) {
- test_client_.reset(new TestShimClient());
- test_client_->Send(new AppShimHostMsg_LaunchApp(
- browser()->profile()->GetPath(),
- kTestAppMode,
- apps::APP_SHIM_LAUNCH_NORMAL,
- std::vector<base::FilePath>()));
-
- RunAndExitGracefully();
- EXPECT_EQ(apps::APP_SHIM_LAUNCH_NORMAL, last_launch_type_);
- EXPECT_TRUE(last_launch_files_.empty());
-}
-
-// Test register-only launch, used when Chrome has already launched the app.
-IN_PROC_BROWSER_TEST_F(AppShimHostManagerBrowserTest, LaunchRegisterOnly) {
- test_client_.reset(new TestShimClient());
- test_client_->Send(new AppShimHostMsg_LaunchApp(
- browser()->profile()->GetPath(),
- kTestAppMode,
- apps::APP_SHIM_LAUNCH_REGISTER_ONLY,
- std::vector<base::FilePath>()));
-
- RunAndExitGracefully();
- EXPECT_EQ(apps::APP_SHIM_LAUNCH_REGISTER_ONLY, last_launch_type_);
- EXPECT_TRUE(last_launch_files_.empty());
-}
-
-// Ensure the domain socket can be created in a fresh user data dir.
-IN_PROC_BROWSER_TEST_F(AppShimHostManagerBrowserTest,
- PRE_ReCreate) {
- test::AppShimHostManagerTestApi test_api(
- g_browser_process->platform_part()->app_shim_host_manager());
- EXPECT_TRUE(test_api.acceptor());
-}
-
-// Ensure the domain socket can be re-created after a prior browser process has
-// quit.
-IN_PROC_BROWSER_TEST_F(AppShimHostManagerBrowserTest,
- ReCreate) {
- test::AppShimHostManagerTestApi test_api(
- g_browser_process->platform_part()->app_shim_host_manager());
- EXPECT_TRUE(test_api.acceptor());
-}
-
-// Tests for the files created by AppShimHostManager.
-class AppShimHostManagerBrowserTestSocketFiles
- : public AppShimHostManagerBrowserTest {
- public:
- AppShimHostManagerBrowserTestSocketFiles() {}
-
- protected:
- base::FilePath directory_in_tmp_;
- base::FilePath symlink_path_;
- base::FilePath version_path_;
-
- private:
- virtual bool SetUpUserDataDirectory() OVERRIDE;
- virtual void TearDownInProcessBrowserTestFixture() OVERRIDE;
-
- DISALLOW_COPY_AND_ASSIGN(AppShimHostManagerBrowserTestSocketFiles);
-};
-
-bool AppShimHostManagerBrowserTestSocketFiles::SetUpUserDataDirectory() {
- // Create an existing symlink. It should be replaced by AppShimHostManager.
- base::FilePath user_data_dir;
- EXPECT_TRUE(PathService::Get(chrome::DIR_USER_DATA, &user_data_dir));
- symlink_path_ = user_data_dir.Append(app_mode::kAppShimSocketSymlinkName);
- base::FilePath temp_dir;
- PathService::Get(base::DIR_TEMP, &temp_dir);
- EXPECT_TRUE(base::CreateSymbolicLink(temp_dir.Append("chrome-XXXXXX"),
- symlink_path_));
-
- // Create an invalid RunningChromeVersion file.
- version_path_ =
- user_data_dir.Append(app_mode::kRunningChromeVersionSymlinkName);
- EXPECT_TRUE(base::CreateSymbolicLink(base::FilePath("invalid_version"),
- version_path_));
- return AppShimHostManagerBrowserTest::SetUpUserDataDirectory();
-}
-
-void AppShimHostManagerBrowserTestSocketFiles::
- TearDownInProcessBrowserTestFixture() {
- // Check that created files have been deleted.
- EXPECT_FALSE(base::PathExists(directory_in_tmp_));
- EXPECT_FALSE(base::PathExists(symlink_path_));
- EXPECT_FALSE(base::PathExists(version_path_));
-}
-
-IN_PROC_BROWSER_TEST_F(AppShimHostManagerBrowserTestSocketFiles,
- ReplacesSymlinkAndCleansUpFiles) {
- // Get the directory created by AppShimHostManager.
- test::AppShimHostManagerTestApi test_api(
- g_browser_process->platform_part()->app_shim_host_manager());
- directory_in_tmp_ = test_api.directory_in_tmp();
-
- // Check that socket files have been created.
- EXPECT_TRUE(base::PathExists(directory_in_tmp_));
- EXPECT_TRUE(base::PathExists(symlink_path_));
-
- // Check that the symlink has been replaced.
- base::FilePath socket_path;
- ASSERT_TRUE(base::ReadSymbolicLink(symlink_path_, &socket_path));
- EXPECT_EQ(app_mode::kAppShimSocketShortName, socket_path.BaseName().value());
-
- // Check that the RunningChromeVersion file is correctly written.
- base::FilePath version;
- EXPECT_TRUE(base::ReadSymbolicLink(version_path_, &version));
- EXPECT_EQ(chrome::VersionInfo().Version(), version.value());
-}
-
-} // namespace
diff --git a/apps/app_shim/app_shim_host_manager_mac.h b/apps/app_shim/app_shim_host_manager_mac.h
deleted file mode 100644
index 037c4f2..0000000
--- a/apps/app_shim/app_shim_host_manager_mac.h
+++ /dev/null
@@ -1,73 +0,0 @@
-// 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.
-
-#ifndef APPS_APP_SHIM_APP_SHIM_HOST_MANAGER_MAC_H_
-#define APPS_APP_SHIM_APP_SHIM_HOST_MANAGER_MAC_H_
-
-#include "apps/app_shim/extension_app_shim_handler_mac.h"
-#include "apps/app_shim/unix_domain_socket_acceptor.h"
-#include "base/memory/ref_counted.h"
-#include "content/public/browser/browser_thread.h"
-
-namespace base {
-class FilePath;
-}
-
-namespace test {
-class AppShimHostManagerTestApi;
-}
-
-// The AppShimHostManager receives connections from app shims on a UNIX
-// socket (|acceptor_|) and creates a helper object to manage the connection.
-class AppShimHostManager : public apps::UnixDomainSocketAcceptor::Delegate,
- public base::RefCountedThreadSafe<
- AppShimHostManager,
- content::BrowserThread::DeleteOnUIThread> {
- public:
- AppShimHostManager();
-
- // Init passes this AppShimHostManager to PostTask which requires it to have
- // a non-zero refcount. Therefore, Init cannot be called in the constructor
- // since the refcount is zero at that point.
- void Init();
-
- apps::ExtensionAppShimHandler* extension_app_shim_handler() {
- return &extension_app_shim_handler_;
- }
-
- private:
- friend class base::RefCountedThreadSafe<AppShimHostManager>;
- friend struct content::BrowserThread::DeleteOnThread<
- content::BrowserThread::UI>;
- friend class base::DeleteHelper<AppShimHostManager>;
- friend class test::AppShimHostManagerTestApi;
- virtual ~AppShimHostManager();
-
- // UnixDomainSocketAcceptor::Delegate implementation.
- virtual void OnClientConnected(const IPC::ChannelHandle& handle) OVERRIDE;
- virtual void OnListenError() OVERRIDE;
-
- // The |acceptor_| must be created on a thread which allows blocking I/O, so
- // part of the initialization of this class must be carried out on the file
- // thread.
- void InitOnFileThread();
-
- // Called on the IO thread to begin listening for connections from app shims.
- void ListenOnIOThread();
-
- // The AppShimHostManager is only initialized if the Chrome process
- // successfully took the singleton lock. This prevents subsequent processes
- // from deleting existing app shim socket files.
- bool did_init_;
-
- base::FilePath directory_in_tmp_;
-
- scoped_ptr<apps::UnixDomainSocketAcceptor> acceptor_;
-
- apps::ExtensionAppShimHandler extension_app_shim_handler_;
-
- DISALLOW_COPY_AND_ASSIGN(AppShimHostManager);
-};
-
-#endif // APPS_APP_SHIM_APP_SHIM_HOST_MANAGER_MAC_H_
diff --git a/apps/app_shim/app_shim_host_manager_mac.mm b/apps/app_shim/app_shim_host_manager_mac.mm
deleted file mode 100644
index 6ea9ef1..0000000
--- a/apps/app_shim/app_shim_host_manager_mac.mm
+++ /dev/null
@@ -1,168 +0,0 @@
-// 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/app_shim_host_manager_mac.h"
-
-#include <unistd.h>
-
-#include "apps/app_shim/app_shim_handler_mac.h"
-#include "apps/app_shim/app_shim_host_mac.h"
-#include "base/base64.h"
-#include "base/bind.h"
-#include "base/command_line.h"
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "base/logging.h"
-#include "base/path_service.h"
-#include "base/sha1.h"
-#include "base/strings/string_util.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/common/chrome_paths.h"
-#include "chrome/common/chrome_switches.h"
-#include "chrome/common/chrome_version_info.h"
-#include "chrome/common/mac/app_mode_common.h"
-
-using content::BrowserThread;
-
-namespace {
-
-void CreateAppShimHost(const IPC::ChannelHandle& handle) {
- // AppShimHost takes ownership of itself.
- (new AppShimHost)->ServeChannel(handle);
-}
-
-base::FilePath GetDirectoryInTmpTemplate(const base::FilePath& user_data_dir) {
- base::FilePath temp_dir;
- CHECK(PathService::Get(base::DIR_TEMP, &temp_dir));
- // Check that it's shorter than the IPC socket length (104) minus the
- // intermediate folder ("/chrome-XXXXXX/") and kAppShimSocketShortName.
- DCHECK_GT(83u, temp_dir.value().length());
- return temp_dir.Append("chrome-XXXXXX");
-}
-
-void DeleteSocketFiles(const base::FilePath& directory_in_tmp,
- const base::FilePath& symlink_path,
- const base::FilePath& version_path) {
- // Delete in reverse order of creation.
- if (!version_path.empty())
- base::DeleteFile(version_path, false);
- if (!symlink_path.empty())
- base::DeleteFile(symlink_path, false);
- if (!directory_in_tmp.empty())
- base::DeleteFile(directory_in_tmp, true);
-}
-
-} // namespace
-
-AppShimHostManager::AppShimHostManager()
- : did_init_(false) {}
-
-void AppShimHostManager::Init() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- DCHECK(!did_init_);
- did_init_ = true;
- apps::AppShimHandler::SetDefaultHandler(&extension_app_shim_handler_);
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- base::Bind(&AppShimHostManager::InitOnFileThread, this));
-}
-
-AppShimHostManager::~AppShimHostManager() {
- acceptor_.reset();
- if (!did_init_)
- return;
-
- apps::AppShimHandler::SetDefaultHandler(NULL);
- base::FilePath user_data_dir;
- base::FilePath symlink_path;
- base::FilePath version_path;
- if (PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)) {
- symlink_path = user_data_dir.Append(app_mode::kAppShimSocketSymlinkName);
- version_path =
- user_data_dir.Append(app_mode::kRunningChromeVersionSymlinkName);
- }
- BrowserThread::PostTask(
- BrowserThread::FILE,
- FROM_HERE,
- base::Bind(
- &DeleteSocketFiles, directory_in_tmp_, symlink_path, version_path));
-}
-
-void AppShimHostManager::InitOnFileThread() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- base::FilePath user_data_dir;
- if (!PathService::Get(chrome::DIR_USER_DATA, &user_data_dir))
- return;
-
- // The socket path must be shorter than 104 chars (IPC::kMaxSocketNameLength).
- // To accommodate this, we use a short path in /tmp/ that is generated from a
- // hash of the user data dir.
- std::string directory_string =
- GetDirectoryInTmpTemplate(user_data_dir).value();
-
- // mkdtemp() replaces trailing X's randomly and creates the directory.
- if (!mkdtemp(&directory_string[0])) {
- PLOG(ERROR) << directory_string;
- return;
- }
-
- directory_in_tmp_ = base::FilePath(directory_string);
- // Check that the directory was created with the correct permissions.
- int dir_mode = 0;
- if (!base::GetPosixFilePermissions(directory_in_tmp_, &dir_mode) ||
- dir_mode != base::FILE_PERMISSION_USER_MASK) {
- NOTREACHED();
- return;
- }
-
- // UnixDomainSocketAcceptor creates the socket immediately.
- base::FilePath socket_path =
- directory_in_tmp_.Append(app_mode::kAppShimSocketShortName);
- acceptor_.reset(new apps::UnixDomainSocketAcceptor(socket_path, this));
-
- // Create a symlink to the socket in the user data dir. This lets the shim
- // process started from Finder find the actual socket path by following the
- // symlink with ::readlink().
- base::FilePath symlink_path =
- user_data_dir.Append(app_mode::kAppShimSocketSymlinkName);
- base::DeleteFile(symlink_path, false);
- base::CreateSymbolicLink(socket_path, symlink_path);
-
- // Create a symlink containing the current version string. This allows the
- // shim to load the same framework version as the currently running Chrome
- // process.
- base::FilePath version_path =
- user_data_dir.Append(app_mode::kRunningChromeVersionSymlinkName);
- base::DeleteFile(version_path, false);
- base::CreateSymbolicLink(base::FilePath(chrome::VersionInfo().Version()),
- version_path);
-
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::Bind(&AppShimHostManager::ListenOnIOThread, this));
-}
-
-void AppShimHostManager::ListenOnIOThread() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- if (!acceptor_->Listen()) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(&AppShimHostManager::OnListenError, this));
- }
-}
-
-void AppShimHostManager::OnClientConnected(
- const IPC::ChannelHandle& handle) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(&CreateAppShimHost, handle));
-}
-
-void AppShimHostManager::OnListenError() {
- // TODO(tapted): Set a timeout and attempt to reconstruct the channel. Until
- // cases where the error could occur are better known, just reset the acceptor
- // to allow failure to be communicated via the test API.
- acceptor_.reset();
-}
diff --git a/apps/app_shim/app_shim_interactive_uitest_mac.mm b/apps/app_shim/app_shim_interactive_uitest_mac.mm
deleted file mode 100644
index 0519143..0000000
--- a/apps/app_shim/app_shim_interactive_uitest_mac.mm
+++ /dev/null
@@ -1,407 +0,0 @@
-// Copyright 2014 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.
-
-#import <Cocoa/Cocoa.h>
-#include <vector>
-
-#include "apps/app_shim/app_shim_handler_mac.h"
-#include "apps/app_shim/app_shim_host_manager_mac.h"
-#include "apps/app_shim/extension_app_shim_handler_mac.h"
-#include "apps/switches.h"
-#include "base/auto_reset.h"
-#include "base/callback.h"
-#include "base/files/file_path_watcher.h"
-#include "base/mac/foundation_util.h"
-#include "base/mac/launch_services_util.h"
-#include "base/mac/mac_util.h"
-#include "base/mac/scoped_nsobject.h"
-#include "base/path_service.h"
-#include "base/process/launch.h"
-#include "base/strings/sys_string_conversions.h"
-#include "base/test/test_timeouts.h"
-#include "chrome/browser/apps/app_browsertest_util.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/web_applications/web_app_mac.h"
-#include "chrome/common/chrome_paths.h"
-#include "chrome/common/chrome_switches.h"
-#include "chrome/common/mac/app_mode_common.h"
-#include "content/public/test/test_utils.h"
-#include "extensions/browser/app_window/native_app_window.h"
-#include "extensions/browser/extension_registry.h"
-#include "extensions/test/extension_test_message_listener.h"
-#import "ui/events/test/cocoa_test_event_utils.h"
-
-namespace {
-
-// General end-to-end test for app shims.
-class AppShimInteractiveTest : public extensions::PlatformAppBrowserTest {
- protected:
- AppShimInteractiveTest()
- : auto_reset_(&g_app_shims_allow_update_and_launch_in_tests, true) {}
-
- private:
- // Temporarily enable app shims.
- base::AutoReset<bool> auto_reset_;
-
- DISALLOW_COPY_AND_ASSIGN(AppShimInteractiveTest);
-};
-
-// Watches for changes to a file. This is designed to be used from the the UI
-// thread.
-class WindowedFilePathWatcher
- : public base::RefCountedThreadSafe<WindowedFilePathWatcher> {
- public:
- WindowedFilePathWatcher(const base::FilePath& path)
- : path_(path), observed_(false) {
- content::BrowserThread::PostTask(
- content::BrowserThread::FILE,
- FROM_HERE,
- base::Bind(&WindowedFilePathWatcher::Watch, this));
- }
-
- void Wait() {
- if (observed_)
- return;
-
- run_loop_.reset(new base::RunLoop);
- run_loop_->Run();
- }
-
- protected:
- friend class base::RefCountedThreadSafe<WindowedFilePathWatcher>;
- virtual ~WindowedFilePathWatcher() {}
-
- void Watch() {
- watcher_.reset(new base::FilePathWatcher);
- watcher_->Watch(path_.DirName(),
- false,
- base::Bind(&WindowedFilePathWatcher::Observe, this));
- }
-
- void Observe(const base::FilePath& path, bool error) {
- DCHECK(!error);
- if (base::PathExists(path_)) {
- watcher_.reset();
- content::BrowserThread::PostTask(
- content::BrowserThread::UI,
- FROM_HERE,
- base::Bind(&WindowedFilePathWatcher::StopRunLoop, this));
- }
- }
-
- void StopRunLoop() {
- observed_ = true;
- if (run_loop_.get())
- run_loop_->Quit();
- }
-
- private:
- const base::FilePath path_;
- scoped_ptr<base::FilePathWatcher> watcher_;
- bool observed_;
- scoped_ptr<base::RunLoop> run_loop_;
-
- DISALLOW_COPY_AND_ASSIGN(WindowedFilePathWatcher);
-};
-
-// Watches for an app shim to connect.
-class WindowedAppShimLaunchObserver : public apps::AppShimHandler {
- public:
- WindowedAppShimLaunchObserver(const std::string& app_id)
- : app_mode_id_(app_id),
- observed_(false) {
- apps::AppShimHandler::RegisterHandler(app_id, this);
- }
-
- void Wait() {
- if (observed_)
- return;
-
- run_loop_.reset(new base::RunLoop);
- run_loop_->Run();
- }
-
- // AppShimHandler overrides:
- virtual void OnShimLaunch(Host* host,
- apps::AppShimLaunchType launch_type,
- const std::vector<base::FilePath>& files) OVERRIDE {
- // Remove self and pass through to the default handler.
- apps::AppShimHandler::RemoveHandler(app_mode_id_);
- apps::AppShimHandler::GetForAppMode(app_mode_id_)
- ->OnShimLaunch(host, launch_type, files);
- observed_ = true;
- if (run_loop_.get())
- run_loop_->Quit();
- }
- virtual void OnShimClose(Host* host) OVERRIDE {}
- virtual void OnShimFocus(Host* host,
- apps::AppShimFocusType focus_type,
- const std::vector<base::FilePath>& files) OVERRIDE {}
- virtual void OnShimSetHidden(Host* host, bool hidden) OVERRIDE {}
- virtual void OnShimQuit(Host* host) OVERRIDE {}
-
- private:
- std::string app_mode_id_;
- bool observed_;
- scoped_ptr<base::RunLoop> run_loop_;
-
- DISALLOW_COPY_AND_ASSIGN(WindowedAppShimLaunchObserver);
-};
-
-NSString* GetBundleID(const base::FilePath& shim_path) {
- base::FilePath plist_path = shim_path.Append("Contents").Append("Info.plist");
- NSMutableDictionary* plist = [NSMutableDictionary
- dictionaryWithContentsOfFile:base::mac::FilePathToNSString(plist_path)];
- return [plist objectForKey:base::mac::CFToNSCast(kCFBundleIdentifierKey)];
-}
-
-bool HasAppShimHost(Profile* profile, const std::string& app_id) {
- return g_browser_process->platform_part()
- ->app_shim_host_manager()
- ->extension_app_shim_handler()
- ->FindHost(profile, app_id);
-}
-
-} // namespace
-
-// Watches for NSNotifications from the shared workspace.
-@interface WindowedNSNotificationObserver : NSObject {
- @private
- base::scoped_nsobject<NSString> bundleId_;
- BOOL notificationReceived_;
- scoped_ptr<base::RunLoop> runLoop_;
-}
-
-- (id)initForNotification:(NSString*)name
- andBundleId:(NSString*)bundleId;
-- (void)observe:(NSNotification*)notification;
-- (void)wait;
-@end
-
-@implementation WindowedNSNotificationObserver
-
-- (id)initForNotification:(NSString*)name
- andBundleId:(NSString*)bundleId {
- if (self = [super init]) {
- bundleId_.reset([[bundleId copy] retain]);
- [[[NSWorkspace sharedWorkspace] notificationCenter]
- addObserver:self
- selector:@selector(observe:)
- name:name
- object:nil];
- }
- return self;
-}
-
-- (void)observe:(NSNotification*)notification {
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-
- NSRunningApplication* application =
- [[notification userInfo] objectForKey:NSWorkspaceApplicationKey];
- if (![[application bundleIdentifier] isEqualToString:bundleId_])
- return;
-
- [[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self];
- notificationReceived_ = YES;
- if (runLoop_.get())
- runLoop_->Quit();
-}
-
-- (void)wait {
- if (notificationReceived_)
- return;
-
- runLoop_.reset(new base::RunLoop);
- runLoop_->Run();
-}
-
-@end
-
-namespace apps {
-
-// Shims require static libraries http://crbug.com/386024.
-#if defined(COMPONENT_BUILD)
-#define MAYBE_Launch DISABLED_Launch
-#define MAYBE_RebuildShim DISABLED_RebuildShim
-#else
-#define MAYBE_Launch Launch
-#define MAYBE_RebuildShim RebuildShim
-#endif
-
-// Test that launching the shim for an app starts the app, and vice versa.
-// These two cases are combined because the time to run the test is dominated
-// by loading the extension and creating the shim.
-IN_PROC_BROWSER_TEST_F(AppShimInteractiveTest, MAYBE_Launch) {
- // Install the app.
- const extensions::Extension* app = InstallPlatformApp("minimal");
-
- // Use a WebAppShortcutCreator to get the path.
- web_app::WebAppShortcutCreator shortcut_creator(
- web_app::GetWebAppDataDirectory(profile()->GetPath(), app->id(), GURL()),
- web_app::ShortcutInfoForExtensionAndProfile(app, profile()),
- extensions::FileHandlersInfo());
- base::FilePath shim_path = shortcut_creator.GetInternalShortcutPath();
- EXPECT_FALSE(base::PathExists(shim_path));
-
- // Create the internal app shim by simulating an app update. FilePathWatcher
- // is used to wait for file operations on the shim to be finished before
- // attempting to launch it. Since all of the file operations are done in the
- // same event on the FILE thread, everything will be done by the time the
- // watcher's callback is executed.
- scoped_refptr<WindowedFilePathWatcher> file_watcher =
- new WindowedFilePathWatcher(shim_path);
- web_app::UpdateAllShortcuts(base::string16(), profile(), app);
- file_watcher->Wait();
- ASSERT_TRUE(base::PathExists(shim_path));
- NSString* bundle_id = GetBundleID(shim_path);
-
- // Case 1: Launch the app, it should start the shim.
- {
- base::scoped_nsobject<WindowedNSNotificationObserver> ns_observer;
- ns_observer.reset([[WindowedNSNotificationObserver alloc]
- initForNotification:NSWorkspaceDidLaunchApplicationNotification
- andBundleId:bundle_id]);
- WindowedAppShimLaunchObserver observer(app->id());
- LaunchPlatformApp(app);
- [ns_observer wait];
- observer.Wait();
-
- EXPECT_TRUE(GetFirstAppWindow());
- EXPECT_TRUE(HasAppShimHost(profile(), app->id()));
-
- // Quitting the shim will eventually cause it to quit. It actually
- // intercepts the -terminate, sends an AppShimHostMsg_QuitApp to Chrome,
- // and returns NSTerminateLater. Chrome responds by closing all windows of
- // the app. Once all windows are closed, Chrome closes the IPC channel,
- // which causes the shim to actually terminate.
- NSArray* running_shim = [NSRunningApplication
- runningApplicationsWithBundleIdentifier:bundle_id];
- ASSERT_EQ(1u, [running_shim count]);
-
- ns_observer.reset([[WindowedNSNotificationObserver alloc]
- initForNotification:NSWorkspaceDidTerminateApplicationNotification
- andBundleId:bundle_id]);
- [base::mac::ObjCCastStrict<NSRunningApplication>(
- [running_shim objectAtIndex:0]) terminate];
- [ns_observer wait];
-
- EXPECT_FALSE(GetFirstAppWindow());
- EXPECT_FALSE(HasAppShimHost(profile(), app->id()));
- }
-
- // Case 2: Launch the shim, it should start the app.
- {
- ExtensionTestMessageListener launched_listener("Launched", false);
- CommandLine shim_cmdline(CommandLine::NO_PROGRAM);
- shim_cmdline.AppendSwitch(app_mode::kLaunchedForTest);
- ProcessSerialNumber shim_psn;
- ASSERT_TRUE(base::mac::OpenApplicationWithPath(
- shim_path, shim_cmdline, kLSLaunchDefaults, &shim_psn));
- ASSERT_TRUE(launched_listener.WaitUntilSatisfied());
-
- ASSERT_TRUE(GetFirstAppWindow());
- EXPECT_TRUE(HasAppShimHost(profile(), app->id()));
-
- // If the window is closed, the shim should quit.
- pid_t shim_pid;
- EXPECT_EQ(noErr, GetProcessPID(&shim_psn, &shim_pid));
- GetFirstAppWindow()->GetBaseWindow()->Close();
- ASSERT_TRUE(
- base::WaitForSingleProcess(shim_pid, TestTimeouts::action_timeout()));
-
- EXPECT_FALSE(GetFirstAppWindow());
- EXPECT_FALSE(HasAppShimHost(profile(), app->id()));
- }
-}
-
-#if defined(ARCH_CPU_64_BITS)
-
-// Tests that a 32 bit shim attempting to launch 64 bit Chrome will eventually
-// be rebuilt.
-IN_PROC_BROWSER_TEST_F(AppShimInteractiveTest, MAYBE_RebuildShim) {
- // Get the 32 bit shim.
- base::FilePath test_data_dir;
- PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir);
- base::FilePath shim_path_32 =
- test_data_dir.Append("app_shim").Append("app_shim_32_bit.app");
- EXPECT_TRUE(base::PathExists(shim_path_32));
-
- // Install test app.
- const extensions::Extension* app = InstallPlatformApp("minimal");
-
- // Use WebAppShortcutCreator to create a 64 bit shim.
- web_app::WebAppShortcutCreator shortcut_creator(
- web_app::GetWebAppDataDirectory(profile()->GetPath(), app->id(), GURL()),
- web_app::ShortcutInfoForExtensionAndProfile(app, profile()),
- extensions::FileHandlersInfo());
- shortcut_creator.UpdateShortcuts();
- base::FilePath shim_path = shortcut_creator.GetInternalShortcutPath();
- NSMutableDictionary* plist_64 = [NSMutableDictionary
- dictionaryWithContentsOfFile:base::mac::FilePathToNSString(
- shim_path.Append("Contents").Append("Info.plist"))];
-
- // Copy 32 bit shim to where it's expected to be.
- // CopyDirectory doesn't seem to work when copying and renaming in one go.
- ASSERT_TRUE(base::DeleteFile(shim_path, true));
- ASSERT_TRUE(base::PathExists(shim_path.DirName()));
- ASSERT_TRUE(base::CopyDirectory(shim_path_32, shim_path.DirName(), true));
- ASSERT_TRUE(base::Move(shim_path.DirName().Append(shim_path_32.BaseName()),
- shim_path));
- ASSERT_TRUE(base::PathExists(
- shim_path.Append("Contents").Append("MacOS").Append("app_mode_loader")));
-
- // Fix up the plist so that it matches the installed test app.
- NSString* plist_path = base::mac::FilePathToNSString(
- shim_path.Append("Contents").Append("Info.plist"));
- NSMutableDictionary* plist =
- [NSMutableDictionary dictionaryWithContentsOfFile:plist_path];
-
- NSArray* keys_to_copy = @[
- base::mac::CFToNSCast(kCFBundleIdentifierKey),
- base::mac::CFToNSCast(kCFBundleNameKey),
- app_mode::kCrAppModeShortcutIDKey,
- app_mode::kCrAppModeUserDataDirKey,
- app_mode::kBrowserBundleIDKey
- ];
- for (NSString* key in keys_to_copy) {
- [plist setObject:[plist_64 objectForKey:key]
- forKey:key];
- }
- [plist writeToFile:plist_path
- atomically:YES];
-
- base::mac::RemoveQuarantineAttribute(shim_path);
-
- // Launch the shim, it should start the app and ultimately connect over IPC.
- // This actually happens in multiple launches of the shim:
- // (1) The shim will fail and instead launch Chrome with --app-id so that the
- // app starts.
- // (2) Chrome launches the shim in response to an app starting, this time the
- // shim launches Chrome with --app-shim-error, which causes Chrome to
- // rebuild the shim.
- // (3) After rebuilding, Chrome again launches the shim and expects it to
- // behave normally.
- ExtensionTestMessageListener launched_listener("Launched", false);
- CommandLine shim_cmdline(CommandLine::NO_PROGRAM);
- ASSERT_TRUE(base::mac::OpenApplicationWithPath(
- shim_path, shim_cmdline, kLSLaunchDefaults, NULL));
-
- // Wait for the app to start (1). At this point there is no shim host.
- ASSERT_TRUE(launched_listener.WaitUntilSatisfied());
- EXPECT_FALSE(HasAppShimHost(profile(), app->id()));
-
- // Wait for the rebuilt shim to connect (3). This does not race with the app
- // starting (1) because Chrome only launches the shim (2) after the app
- // starts. Then Chrome must handle --app-shim-error on the UI thread before
- // the shim is rebuilt.
- WindowedAppShimLaunchObserver(app->id()).Wait();
-
- EXPECT_TRUE(GetFirstAppWindow());
- EXPECT_TRUE(HasAppShimHost(profile(), app->id()));
-}
-
-#endif // defined(ARCH_CPU_64_BITS)
-
-} // namespace apps
diff --git a/apps/app_shim/app_shim_launch.h b/apps/app_shim/app_shim_launch.h
deleted file mode 100644
index 61f87da..0000000
--- a/apps/app_shim/app_shim_launch.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// 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.
-
-#ifndef APPS_APP_SHIM_APP_SHIM_LAUNCH_H_
-#define APPS_APP_SHIM_APP_SHIM_LAUNCH_H_
-
-namespace apps {
-
-enum AppShimLaunchType {
- // Process the app shim's LaunchAppmessage and associate the shim with the
- // given profile and app id.
- APP_SHIM_LAUNCH_REGISTER_ONLY = 0,
- // Do the above and launch the app.
- APP_SHIM_LAUNCH_NORMAL,
- // Counter and end marker.
- APP_SHIM_LAUNCH_NUM_TYPES
-};
-
-enum AppShimLaunchResult {
- // App launched successfully.
- APP_SHIM_LAUNCH_SUCCESS = 0,
- // There is already a host registered for this app.
- APP_SHIM_LAUNCH_DUPLICATE_HOST,
- // The profile was not found.
- APP_SHIM_LAUNCH_PROFILE_NOT_FOUND,
- // The app was not found.
- APP_SHIM_LAUNCH_APP_NOT_FOUND,
- // Counter and end marker.
- APP_SHIM_LAUNCH_NUM_RESULTS
-};
-
-enum AppShimFocusType {
- // Just focus the app.
- APP_SHIM_FOCUS_NORMAL = 0,
- // Focus the app or launch it if it has no windows open.
- APP_SHIM_FOCUS_REOPEN,
- // Open the given file in the app.
- APP_SHIM_FOCUS_OPEN_FILES,
- // Counter and end marker.
- APP_SHIM_FOCUS_NUM_TYPES
-};
-
-enum AppShimAttentionType {
- // Removes any active attention request.
- APP_SHIM_ATTENTION_CANCEL = 0,
- // Bounces the shim in the dock briefly.
- APP_SHIM_ATTENTION_INFORMATIONAL,
- // Bounces the shim in the dock continuously.
- APP_SHIM_ATTENTION_CRITICAL,
- // Counter and end marker.
- APP_SHIM_ATTENTION_NUM_TYPES
-};
-
-} // namespace apps
-
-#endif // APPS_APP_SHIM_APP_SHIM_LAUNCH_H_
diff --git a/apps/app_shim/app_shim_messages.h b/apps/app_shim/app_shim_messages.h
deleted file mode 100644
index 4fcbbd8..0000000
--- a/apps/app_shim/app_shim_messages.h
+++ /dev/null
@@ -1,71 +0,0 @@
-// 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.
-
-// Multiply-included message file, hence no include guard.
-
-#include <string>
-#include <vector>
-
-#include "apps/app_shim/app_shim_launch.h"
-#include "base/files/file_path.h"
-#include "ipc/ipc_message_macros.h"
-#include "ipc/ipc_message_utils.h"
-#include "ipc/param_traits_macros.h"
-
-#define IPC_MESSAGE_START AppShimMsgStart
-
-IPC_ENUM_TRAITS_MAX_VALUE(apps::AppShimLaunchType,
- apps::APP_SHIM_LAUNCH_NUM_TYPES - 1)
-IPC_ENUM_TRAITS_MAX_VALUE(apps::AppShimLaunchResult,
- apps::APP_SHIM_LAUNCH_NUM_RESULTS - 1)
-IPC_ENUM_TRAITS_MAX_VALUE(apps::AppShimFocusType,
- apps::APP_SHIM_FOCUS_NUM_TYPES - 1)
-IPC_ENUM_TRAITS_MAX_VALUE(apps::AppShimAttentionType,
- apps::APP_SHIM_ATTENTION_NUM_TYPES - 1)
-
-// IMPORTANT: Since app shims could be running a newer framework version to the
-// currently running Chrome, any changes to these IPCs must maintain the same
-// order and format. I.e. Only add to the bottom, don't delete any.
-
-// Signals that a previous LaunchApp message has been processed, and lets the
-// app shim process know whether it was registered successfully.
-IPC_MESSAGE_CONTROL1(AppShimMsg_LaunchApp_Done,
- apps::AppShimLaunchResult /* launch result */)
-
-// Instructs the shim to hide the app.
-IPC_MESSAGE_CONTROL0(AppShimMsg_Hide)
-
-// Deprecated. Do not delete.
-IPC_MESSAGE_CONTROL0(AppShimMsg_RequestUserAttention)
-
-// Signals to the main Chrome process that a shim has started. Indicates the
-// profile and app_id that the shim should be associated with and whether to
-// launch the app immediately.
-IPC_MESSAGE_CONTROL4(AppShimHostMsg_LaunchApp,
- base::FilePath /* profile dir */,
- std::string /* app id */,
- apps::AppShimLaunchType /* launch type */,
- std::vector<base::FilePath> /* files */)
-
-// Sent when the user has indicated a desire to focus the app, either by
-// clicking on the app's icon in the dock or by selecting it with Cmd+Tab. In
-// response, Chrome brings the app's windows to the foreground, or relaunches
-// if the focus type indicates a reopen and there are no open windows.
-IPC_MESSAGE_CONTROL2(AppShimHostMsg_FocusApp,
- apps::AppShimFocusType /* focus type */,
- std::vector<base::FilePath> /* files */)
-
-// Sent when the app shim is hidden or unhidden.
-IPC_MESSAGE_CONTROL1(AppShimHostMsg_SetAppHidden,
- bool /* hidden */)
-
-// Sent when the shim process receives a request to terminate. Once all of the
-// app's windows have closed, and the extension is unloaded, the AppShimHost
-// closes the channel. The shim process then completes the terminate request
-// and exits.
-IPC_MESSAGE_CONTROL0(AppShimHostMsg_QuitApp)
-
-// Instructs the shim to request or cancel user attention.
-IPC_MESSAGE_CONTROL1(AppShimMsg_SetUserAttention,
- apps::AppShimAttentionType /* attention_type */)
diff --git a/apps/app_shim/app_shim_quit_interactive_uitest_mac.mm b/apps/app_shim/app_shim_quit_interactive_uitest_mac.mm
deleted file mode 100644
index 04fdbdb..0000000
--- a/apps/app_shim/app_shim_quit_interactive_uitest_mac.mm
+++ /dev/null
@@ -1,132 +0,0 @@
-// 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.
-
-// Tests behavior when quitting apps with app shims.
-
-#import <Cocoa/Cocoa.h>
-#include <vector>
-
-#include "apps/app_shim/app_shim_host_manager_mac.h"
-#include "apps/app_shim/extension_app_shim_handler_mac.h"
-#include "apps/switches.h"
-#include "chrome/browser/apps/app_browsertest_util.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/browser_shutdown.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_switches.h"
-#include "chrome/test/base/interactive_test_utils.h"
-#include "content/public/test/test_utils.h"
-#include "extensions/browser/extension_registry.h"
-#include "extensions/test/extension_test_message_listener.h"
-#include "ui/events/test/cocoa_test_event_utils.h"
-
-using extensions::PlatformAppBrowserTest;
-
-namespace apps {
-
-namespace {
-
-class FakeHost : public apps::AppShimHandler::Host {
- public:
- FakeHost(const base::FilePath& profile_path,
- const std::string& app_id,
- ExtensionAppShimHandler* handler)
- : profile_path_(profile_path),
- app_id_(app_id),
- handler_(handler) {}
-
- virtual void OnAppLaunchComplete(AppShimLaunchResult result) OVERRIDE {}
- virtual void OnAppClosed() OVERRIDE {
- handler_->OnShimClose(this);
- }
- virtual void OnAppHide() OVERRIDE {}
- virtual void OnAppRequestUserAttention(AppShimAttentionType type) OVERRIDE {}
- virtual base::FilePath GetProfilePath() const OVERRIDE {
- return profile_path_;
- }
- virtual std::string GetAppId() const OVERRIDE { return app_id_; }
-
- private:
- base::FilePath profile_path_;
- std::string app_id_;
- ExtensionAppShimHandler* handler_;
-
- DISALLOW_COPY_AND_ASSIGN(FakeHost);
-};
-
-// Starts an app without a browser window using --load_and_launch_app and
-// --silent_launch.
-class AppShimQuitTest : public PlatformAppBrowserTest {
- protected:
- AppShimQuitTest() {}
-
- void SetUpAppShim() {
- ASSERT_EQ(0u, [[NSApp windows] count]);
- ExtensionTestMessageListener launched_listener("Launched", false);
- ASSERT_TRUE(launched_listener.WaitUntilSatisfied());
- ASSERT_EQ(1u, [[NSApp windows] count]);
-
- handler_ = g_browser_process->platform_part()->app_shim_host_manager()->
- extension_app_shim_handler();
-
- // Attach a host for the app.
- extensions::ExtensionRegistry* registry =
- extensions::ExtensionRegistry::Get(profile());
- extension_id_ =
- GetExtensionByPath(&registry->enabled_extensions(), app_path_)->id();
- host_.reset(new FakeHost(profile()->GetPath().BaseName(),
- extension_id_,
- handler_));
- handler_->OnShimLaunch(host_.get(),
- APP_SHIM_LAUNCH_REGISTER_ONLY,
- std::vector<base::FilePath>());
- EXPECT_EQ(host_.get(), handler_->FindHost(profile(), extension_id_));
-
- // Focus the app window.
- NSWindow* window = [[NSApp windows] objectAtIndex:0];
- EXPECT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(window));
- content::RunAllPendingInMessageLoop();
- }
-
- virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
- PlatformAppBrowserTest::SetUpCommandLine(command_line);
- // Simulate an app shim initiated launch, i.e. launch app but not browser.
- app_path_ = test_data_dir_
- .AppendASCII("platform_apps")
- .AppendASCII("minimal");
- command_line->AppendSwitchNative(apps::kLoadAndLaunchApp,
- app_path_.value());
- command_line->AppendSwitch(switches::kSilentLaunch);
- }
-
- base::FilePath app_path_;
- ExtensionAppShimHandler* handler_;
- std::string extension_id_;
- scoped_ptr<FakeHost> host_;
-
- DISALLOW_COPY_AND_ASSIGN(AppShimQuitTest);
-};
-
-} // namespace
-
-// Test that closing an app with Cmd+Q when no browsers have ever been open
-// terminates Chrome.
-IN_PROC_BROWSER_TEST_F(AppShimQuitTest, QuitWithKeyEvent) {
- SetUpAppShim();
-
- // Simulate a Cmd+Q event.
- NSWindow* window = [[NSApp windows] objectAtIndex:0];
- NSEvent* event = cocoa_test_event_utils::KeyEventWithKeyCode(
- 0, 'q', NSKeyDown, NSCommandKeyMask);
- [window postEvent:event
- atStart:NO];
-
- // This will time out if the event above does not terminate Chrome.
- content::RunMessageLoop();
-
- EXPECT_FALSE(handler_->FindHost(profile(), extension_id_));
- EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
-}
-
-} // namespace apps
diff --git a/apps/app_shim/chrome_main_app_mode_mac.mm b/apps/app_shim/chrome_main_app_mode_mac.mm
deleted file mode 100644
index 21e3fe2..0000000
--- a/apps/app_shim/chrome_main_app_mode_mac.mm
+++ /dev/null
@@ -1,693 +0,0 @@
-// 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.
-
-// On Mac, one can't make shortcuts with command-line arguments. Instead, we
-// produce small app bundles which locate the Chromium framework and load it,
-// passing the appropriate data. This is the entry point into the framework for
-// those app bundles.
-
-#import <Cocoa/Cocoa.h>
-#include <vector>
-
-#include "apps/app_shim/app_shim_messages.h"
-#include "base/at_exit.h"
-#include "base/command_line.h"
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "base/logging.h"
-#include "base/mac/bundle_locations.h"
-#include "base/mac/foundation_util.h"
-#include "base/mac/launch_services_util.h"
-#include "base/mac/mac_logging.h"
-#include "base/mac/mac_util.h"
-#include "base/mac/scoped_nsautorelease_pool.h"
-#include "base/mac/scoped_nsobject.h"
-#include "base/mac/sdk_forward_declarations.h"
-#include "base/message_loop/message_loop.h"
-#include "base/path_service.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/sys_string_conversions.h"
-#include "base/threading/thread.h"
-#include "chrome/common/chrome_constants.h"
-#include "chrome/common/chrome_paths.h"
-#include "chrome/common/chrome_switches.h"
-#include "chrome/common/mac/app_mode_common.h"
-#include "grit/generated_resources.h"
-#include "ipc/ipc_channel_proxy.h"
-#include "ipc/ipc_listener.h"
-#include "ipc/ipc_message.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "ui/base/resource/resource_bundle.h"
-
-namespace {
-
-// Timeout in seconds to wait for a reply for the initial Apple Event. Note that
-// kAEDefaultTimeout on Mac is "about one minute" according to Apple's
-// documentation, but is no longer supported for asynchronous Apple Events.
-const int kPingChromeTimeoutSeconds = 60;
-
-const app_mode::ChromeAppModeInfo* g_info;
-base::Thread* g_io_thread = NULL;
-
-} // namespace
-
-class AppShimController;
-
-// An application delegate to catch user interactions and send the appropriate
-// IPC messages to Chrome.
-@interface AppShimDelegate : NSObject<NSApplicationDelegate> {
- @private
- AppShimController* appShimController_; // Weak, initially NULL.
- BOOL terminateNow_;
- BOOL terminateRequested_;
- std::vector<base::FilePath> filesToOpenAtStartup_;
-}
-
-// The controller is initially NULL. Setting it indicates to the delegate that
-// the controller has finished initialization.
-- (void)setController:(AppShimController*)controller;
-
-// Gets files that were queued because the controller was not ready.
-// Returns whether any FilePaths were added to |out|.
-- (BOOL)getFilesToOpenAtStartup:(std::vector<base::FilePath>*)out;
-
-// If the controller is ready, this sends a FocusApp with the files to open.
-// Otherwise, this adds the files to |filesToOpenAtStartup_|.
-// Takes an array of NSString*.
-- (void)openFiles:(NSArray*)filename;
-
-// Terminate immediately. This is necessary as we override terminate: to send
-// a QuitApp message.
-- (void)terminateNow;
-
-@end
-
-// The AppShimController is responsible for communication with the main Chrome
-// process, and generally controls the lifetime of the app shim process.
-class AppShimController : public IPC::Listener {
- public:
- AppShimController();
- virtual ~AppShimController();
-
- // Called when the main Chrome process responds to the Apple Event ping that
- // was sent, or when the ping fails (if |success| is false).
- void OnPingChromeReply(bool success);
-
- // Called |kPingChromeTimeoutSeconds| after startup, to allow a timeout on the
- // ping event to be detected.
- void OnPingChromeTimeout();
-
- // Connects to Chrome and sends a LaunchApp message.
- void Init();
-
- // Create a channel from |socket_path| and send a LaunchApp message.
- void CreateChannelAndSendLaunchApp(const base::FilePath& socket_path);
-
- // Builds main menu bar items.
- void SetUpMenu();
-
- void SendSetAppHidden(bool hidden);
-
- void SendQuitApp();
-
- // Called when the app is activated, e.g. by clicking on it in the dock, by
- // dropping a file on the dock icon, or by Cmd+Tabbing to it.
- // Returns whether the message was sent.
- bool SendFocusApp(apps::AppShimFocusType focus_type,
- const std::vector<base::FilePath>& files);
-
- private:
- // IPC::Listener implemetation.
- virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
- virtual void OnChannelError() OVERRIDE;
-
- // If Chrome failed to launch the app, |success| will be false and the app
- // shim process should die.
- void OnLaunchAppDone(apps::AppShimLaunchResult result);
-
- // Hide this app.
- void OnHide();
-
- // Requests user attention.
- void OnRequestUserAttention();
- void OnSetUserAttention(apps::AppShimAttentionType attention_type);
-
- // Terminates the app shim process.
- void Close();
-
- base::FilePath user_data_dir_;
- scoped_ptr<IPC::ChannelProxy> channel_;
- base::scoped_nsobject<AppShimDelegate> delegate_;
- bool launch_app_done_;
- bool ping_chrome_reply_received_;
- NSInteger attention_request_id_;
-
- DISALLOW_COPY_AND_ASSIGN(AppShimController);
-};
-
-AppShimController::AppShimController()
- : delegate_([[AppShimDelegate alloc] init]),
- launch_app_done_(false),
- ping_chrome_reply_received_(false),
- attention_request_id_(0) {
- // Since AppShimController is created before the main message loop starts,
- // NSApp will not be set, so use sharedApplication.
- [[NSApplication sharedApplication] setDelegate:delegate_];
-}
-
-AppShimController::~AppShimController() {
- // Un-set the delegate since NSApplication does not retain it.
- [[NSApplication sharedApplication] setDelegate:nil];
-}
-
-void AppShimController::OnPingChromeReply(bool success) {
- ping_chrome_reply_received_ = true;
- if (!success) {
- [NSApp terminate:nil];
- return;
- }
-
- Init();
-}
-
-void AppShimController::OnPingChromeTimeout() {
- if (!ping_chrome_reply_received_)
- [NSApp terminate:nil];
-}
-
-void AppShimController::Init() {
- DCHECK(g_io_thread);
-
- SetUpMenu();
-
- // Chrome will relaunch shims when relaunching apps.
- if (base::mac::IsOSLionOrLater())
- [NSApp disableRelaunchOnLogin];
-
- // The user_data_dir for shims actually contains the app_data_path.
- // I.e. <user_data_dir>/<profile_dir>/Web Applications/_crx_extensionid/
- user_data_dir_ = g_info->user_data_dir.DirName().DirName().DirName();
- CHECK(!user_data_dir_.empty());
-
- base::FilePath symlink_path =
- user_data_dir_.Append(app_mode::kAppShimSocketSymlinkName);
-
- base::FilePath socket_path;
- if (!base::ReadSymbolicLink(symlink_path, &socket_path)) {
- // The path in the user data dir is not a symlink, try connecting directly.
- CreateChannelAndSendLaunchApp(symlink_path);
- return;
- }
-
- app_mode::VerifySocketPermissions(socket_path);
-
- CreateChannelAndSendLaunchApp(socket_path);
-}
-
-void AppShimController::CreateChannelAndSendLaunchApp(
- const base::FilePath& socket_path) {
- IPC::ChannelHandle handle(socket_path.value());
- channel_ = IPC::ChannelProxy::Create(handle,
- IPC::Channel::MODE_NAMED_CLIENT,
- this,
- g_io_thread->message_loop_proxy().get());
-
- bool launched_by_chrome =
- CommandLine::ForCurrentProcess()->HasSwitch(
- app_mode::kLaunchedByChromeProcessId);
- apps::AppShimLaunchType launch_type = launched_by_chrome ?
- apps::APP_SHIM_LAUNCH_REGISTER_ONLY : apps::APP_SHIM_LAUNCH_NORMAL;
-
- [delegate_ setController:this];
-
- std::vector<base::FilePath> files;
- [delegate_ getFilesToOpenAtStartup:&files];
-
- channel_->Send(new AppShimHostMsg_LaunchApp(
- g_info->profile_dir, g_info->app_mode_id, launch_type, files));
-}
-
-void AppShimController::SetUpMenu() {
- NSString* title = base::SysUTF16ToNSString(g_info->app_mode_name);
-
- // Create a main menu since [NSApp mainMenu] is nil.
- base::scoped_nsobject<NSMenu> main_menu([[NSMenu alloc] initWithTitle:title]);
-
- // The title of the first item is replaced by OSX with the name of the app and
- // bold styling. Create a dummy item for this and make it hidden.
- NSMenuItem* dummy_item = [main_menu addItemWithTitle:title
- action:nil
- keyEquivalent:@""];
- base::scoped_nsobject<NSMenu> dummy_submenu(
- [[NSMenu alloc] initWithTitle:title]);
- [dummy_item setSubmenu:dummy_submenu];
- [dummy_item setHidden:YES];
-
- // Construct an unbolded app menu, to match how it appears in the Chrome menu
- // bar when the app is focused.
- NSMenuItem* item = [main_menu addItemWithTitle:title
- action:nil
- keyEquivalent:@""];
- base::scoped_nsobject<NSMenu> submenu([[NSMenu alloc] initWithTitle:title]);
- [item setSubmenu:submenu];
-
- // Add a quit entry.
- NSString* quit_localized_string =
- l10n_util::GetNSStringF(IDS_EXIT_MAC, g_info->app_mode_name);
- [submenu addItemWithTitle:quit_localized_string
- action:@selector(terminate:)
- keyEquivalent:@"q"];
-
- // Add File, Edit, and Window menus. These are just here to make the
- // transition smoother, i.e. from another application to the shim then to
- // Chrome.
- [main_menu addItemWithTitle:l10n_util::GetNSString(IDS_FILE_MENU_MAC)
- action:nil
- keyEquivalent:@""];
- [main_menu addItemWithTitle:l10n_util::GetNSString(IDS_EDIT_MENU_MAC)
- action:nil
- keyEquivalent:@""];
- [main_menu addItemWithTitle:l10n_util::GetNSString(IDS_WINDOW_MENU_MAC)
- action:nil
- keyEquivalent:@""];
-
- [NSApp setMainMenu:main_menu];
-}
-
-void AppShimController::SendQuitApp() {
- channel_->Send(new AppShimHostMsg_QuitApp);
-}
-
-bool AppShimController::OnMessageReceived(const IPC::Message& message) {
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(AppShimController, message)
- IPC_MESSAGE_HANDLER(AppShimMsg_LaunchApp_Done, OnLaunchAppDone)
- IPC_MESSAGE_HANDLER(AppShimMsg_Hide, OnHide)
- IPC_MESSAGE_HANDLER(AppShimMsg_RequestUserAttention, OnRequestUserAttention)
- IPC_MESSAGE_HANDLER(AppShimMsg_SetUserAttention, OnSetUserAttention)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
-
- return handled;
-}
-
-void AppShimController::OnChannelError() {
- Close();
-}
-
-void AppShimController::OnLaunchAppDone(apps::AppShimLaunchResult result) {
- if (result != apps::APP_SHIM_LAUNCH_SUCCESS) {
- Close();
- return;
- }
-
- std::vector<base::FilePath> files;
- if ([delegate_ getFilesToOpenAtStartup:&files])
- SendFocusApp(apps::APP_SHIM_FOCUS_OPEN_FILES, files);
-
- launch_app_done_ = true;
-}
-
-void AppShimController::OnHide() {
- [NSApp hide:nil];
-}
-
-void AppShimController::OnRequestUserAttention() {
- OnSetUserAttention(apps::APP_SHIM_ATTENTION_INFORMATIONAL);
-}
-
-void AppShimController::OnSetUserAttention(
- apps::AppShimAttentionType attention_type) {
- switch (attention_type) {
- case apps::APP_SHIM_ATTENTION_CANCEL:
- [NSApp cancelUserAttentionRequest:attention_request_id_];
- attention_request_id_ = 0;
- break;
- case apps::APP_SHIM_ATTENTION_CRITICAL:
- attention_request_id_ = [NSApp requestUserAttention:NSCriticalRequest];
- break;
- case apps::APP_SHIM_ATTENTION_INFORMATIONAL:
- attention_request_id_ =
- [NSApp requestUserAttention:NSInformationalRequest];
- break;
- case apps::APP_SHIM_ATTENTION_NUM_TYPES:
- NOTREACHED();
- }
-}
-
-void AppShimController::Close() {
- [delegate_ terminateNow];
-}
-
-bool AppShimController::SendFocusApp(apps::AppShimFocusType focus_type,
- const std::vector<base::FilePath>& files) {
- if (launch_app_done_) {
- channel_->Send(new AppShimHostMsg_FocusApp(focus_type, files));
- return true;
- }
-
- return false;
-}
-
-void AppShimController::SendSetAppHidden(bool hidden) {
- channel_->Send(new AppShimHostMsg_SetAppHidden(hidden));
-}
-
-@implementation AppShimDelegate
-
-- (BOOL)getFilesToOpenAtStartup:(std::vector<base::FilePath>*)out {
- if (filesToOpenAtStartup_.empty())
- return NO;
-
- out->insert(out->end(),
- filesToOpenAtStartup_.begin(),
- filesToOpenAtStartup_.end());
- filesToOpenAtStartup_.clear();
- return YES;
-}
-
-- (void)setController:(AppShimController*)controller {
- appShimController_ = controller;
-}
-
-- (void)openFiles:(NSArray*)filenames {
- std::vector<base::FilePath> filePaths;
- for (NSString* filename in filenames)
- filePaths.push_back(base::mac::NSStringToFilePath(filename));
-
- // If the AppShimController is ready, try to send a FocusApp. If that fails,
- // (e.g. if launching has not finished), enqueue the files.
- if (appShimController_ &&
- appShimController_->SendFocusApp(apps::APP_SHIM_FOCUS_OPEN_FILES,
- filePaths)) {
- return;
- }
-
- filesToOpenAtStartup_.insert(filesToOpenAtStartup_.end(),
- filePaths.begin(),
- filePaths.end());
-}
-
-- (BOOL)application:(NSApplication*)app
- openFile:(NSString*)filename {
- [self openFiles:@[filename]];
- return YES;
-}
-
-- (void)application:(NSApplication*)app
- openFiles:(NSArray*)filenames {
- [self openFiles:filenames];
- [app replyToOpenOrPrint:NSApplicationDelegateReplySuccess];
-}
-
-- (BOOL)applicationOpenUntitledFile:(NSApplication*)app {
- if (appShimController_) {
- return appShimController_->SendFocusApp(apps::APP_SHIM_FOCUS_REOPEN,
- std::vector<base::FilePath>());
- }
-
- return NO;
-}
-
-- (void)applicationWillBecomeActive:(NSNotification*)notification {
- if (appShimController_) {
- appShimController_->SendFocusApp(apps::APP_SHIM_FOCUS_NORMAL,
- std::vector<base::FilePath>());
- }
-}
-
-- (NSApplicationTerminateReply)
- applicationShouldTerminate:(NSApplication*)sender {
- if (terminateNow_ || !appShimController_)
- return NSTerminateNow;
-
- appShimController_->SendQuitApp();
- // Wait for the channel to close before terminating.
- terminateRequested_ = YES;
- return NSTerminateLater;
-}
-
-- (void)applicationWillHide:(NSNotification*)notification {
- if (appShimController_)
- appShimController_->SendSetAppHidden(true);
-}
-
-- (void)applicationWillUnhide:(NSNotification*)notification {
- if (appShimController_)
- appShimController_->SendSetAppHidden(false);
-}
-
-- (void)terminateNow {
- if (terminateRequested_) {
- [NSApp replyToApplicationShouldTerminate:NSTerminateNow];
- return;
- }
-
- terminateNow_ = YES;
- [NSApp terminate:nil];
-}
-
-@end
-
-//-----------------------------------------------------------------------------
-
-// A ReplyEventHandler is a helper class to send an Apple Event to a process
-// and call a callback when the reply returns.
-//
-// This is used to 'ping' the main Chrome process -- once Chrome has sent back
-// an Apple Event reply, it's guaranteed that it has opened the IPC channel
-// that the app shim will connect to.
-@interface ReplyEventHandler : NSObject {
- base::Callback<void(bool)> onReply_;
- AEDesc replyEvent_;
-}
-// Sends an Apple Event to the process identified by |psn|, and calls |replyFn|
-// when the reply is received. Internally this creates a ReplyEventHandler,
-// which will delete itself once the reply event has been received.
-+ (void)pingProcess:(const ProcessSerialNumber&)psn
- andCall:(base::Callback<void(bool)>)replyFn;
-@end
-
-@interface ReplyEventHandler (PrivateMethods)
-// Initialise the reply event handler. Doesn't register any handlers until
-// |-pingProcess:| is called. |replyFn| is the function to be called when the
-// Apple Event reply arrives.
-- (id)initWithCallback:(base::Callback<void(bool)>)replyFn;
-
-// Sends an Apple Event ping to the process identified by |psn| and registers
-// to listen for a reply.
-- (void)pingProcess:(const ProcessSerialNumber&)psn;
-
-// Called when a response is received from the target process for the ping sent
-// by |-pingProcess:|.
-- (void)message:(NSAppleEventDescriptor*)event
- withReply:(NSAppleEventDescriptor*)reply;
-
-// Calls |onReply_|, passing it |success| to specify whether the ping was
-// successful.
-- (void)closeWithSuccess:(bool)success;
-@end
-
-@implementation ReplyEventHandler
-+ (void)pingProcess:(const ProcessSerialNumber&)psn
- andCall:(base::Callback<void(bool)>)replyFn {
- // The object will release itself when the reply arrives, or possibly earlier
- // if an unrecoverable error occurs.
- ReplyEventHandler* handler =
- [[ReplyEventHandler alloc] initWithCallback:replyFn];
- [handler pingProcess:psn];
-}
-@end
-
-@implementation ReplyEventHandler (PrivateMethods)
-- (id)initWithCallback:(base::Callback<void(bool)>)replyFn {
- if ((self = [super init])) {
- onReply_ = replyFn;
- }
- return self;
-}
-
-- (void)pingProcess:(const ProcessSerialNumber&)psn {
- // Register the reply listener.
- NSAppleEventManager* em = [NSAppleEventManager sharedAppleEventManager];
- [em setEventHandler:self
- andSelector:@selector(message:withReply:)
- forEventClass:'aevt'
- andEventID:'ansr'];
- // Craft the Apple Event to send.
- NSAppleEventDescriptor* target = [NSAppleEventDescriptor
- descriptorWithDescriptorType:typeProcessSerialNumber
- bytes:&psn
- length:sizeof(psn)];
- NSAppleEventDescriptor* initial_event =
- [NSAppleEventDescriptor
- appleEventWithEventClass:app_mode::kAEChromeAppClass
- eventID:app_mode::kAEChromeAppPing
- targetDescriptor:target
- returnID:kAutoGenerateReturnID
- transactionID:kAnyTransactionID];
-
- // Note that AESendMessage effectively ignores kAEDefaultTimeout, because this
- // call does not pass kAEWantReceipt (which is deprecated and unsupported on
- // Mac). Instead, rely on OnPingChromeTimeout().
- OSStatus status = AESendMessage(
- [initial_event aeDesc], &replyEvent_, kAEQueueReply, kAEDefaultTimeout);
- if (status != noErr) {
- OSSTATUS_LOG(ERROR, status) << "AESendMessage";
- [self closeWithSuccess:false];
- }
-}
-
-- (void)message:(NSAppleEventDescriptor*)event
- withReply:(NSAppleEventDescriptor*)reply {
- [self closeWithSuccess:true];
-}
-
-- (void)closeWithSuccess:(bool)success {
- onReply_.Run(success);
- NSAppleEventManager* em = [NSAppleEventManager sharedAppleEventManager];
- [em removeEventHandlerForEventClass:'aevt' andEventID:'ansr'];
- [self release];
-}
-@end
-
-//-----------------------------------------------------------------------------
-
-extern "C" {
-
-// |ChromeAppModeStart()| is the point of entry into the framework from the app
-// mode loader.
-__attribute__((visibility("default")))
-int ChromeAppModeStart(const app_mode::ChromeAppModeInfo* info);
-
-} // extern "C"
-
-int ChromeAppModeStart(const app_mode::ChromeAppModeInfo* info) {
- CommandLine::Init(info->argc, info->argv);
-
- base::mac::ScopedNSAutoreleasePool scoped_pool;
- base::AtExitManager exit_manager;
- chrome::RegisterPathProvider();
-
- if (info->major_version < app_mode::kCurrentChromeAppModeInfoMajorVersion) {
- RAW_LOG(ERROR, "App Mode Loader too old.");
- return 1;
- }
- if (info->major_version > app_mode::kCurrentChromeAppModeInfoMajorVersion) {
- RAW_LOG(ERROR, "Browser Framework too old to load App Shortcut.");
- return 1;
- }
-
- g_info = info;
-
- // Set bundle paths. This loads the bundles.
- base::mac::SetOverrideOuterBundlePath(g_info->chrome_outer_bundle_path);
- base::mac::SetOverrideFrameworkBundlePath(
- g_info->chrome_versioned_path.Append(chrome::kFrameworkName));
-
- // Calculate the preferred locale used by Chrome.
- // We can't use l10n_util::OverrideLocaleWithCocoaLocale() because it calls
- // [base::mac::OuterBundle() preferredLocalizations] which gets localizations
- // from the bundle of the running app (i.e. it is equivalent to
- // [[NSBundle mainBundle] preferredLocalizations]) instead of the target
- // bundle.
- NSArray* preferred_languages = [NSLocale preferredLanguages];
- NSArray* supported_languages = [base::mac::OuterBundle() localizations];
- std::string preferred_localization;
- for (NSString* language in preferred_languages) {
- if ([supported_languages containsObject:language]) {
- preferred_localization = base::SysNSStringToUTF8(language);
- break;
- }
- }
- std::string locale = l10n_util::NormalizeLocale(
- l10n_util::GetApplicationLocale(preferred_localization));
-
- // Load localized strings.
- ui::ResourceBundle::InitSharedInstanceWithLocale(
- locale, NULL, ui::ResourceBundle::DO_NOT_LOAD_COMMON_RESOURCES);
-
- // Launch the IO thread.
- base::Thread::Options io_thread_options;
- io_thread_options.message_loop_type = base::MessageLoop::TYPE_IO;
- base::Thread *io_thread = new base::Thread("CrAppShimIO");
- io_thread->StartWithOptions(io_thread_options);
- g_io_thread = io_thread;
-
- // Find already running instances of Chrome.
- pid_t pid = -1;
- std::string chrome_process_id = CommandLine::ForCurrentProcess()->
- GetSwitchValueASCII(app_mode::kLaunchedByChromeProcessId);
- if (!chrome_process_id.empty()) {
- if (!base::StringToInt(chrome_process_id, &pid))
- LOG(FATAL) << "Invalid PID: " << chrome_process_id;
- } else {
- NSString* chrome_bundle_id = [base::mac::OuterBundle() bundleIdentifier];
- NSArray* existing_chrome = [NSRunningApplication
- runningApplicationsWithBundleIdentifier:chrome_bundle_id];
- if ([existing_chrome count] > 0)
- pid = [[existing_chrome objectAtIndex:0] processIdentifier];
- }
-
- AppShimController controller;
- base::MessageLoopForUI main_message_loop;
- main_message_loop.set_thread_name("MainThread");
- base::PlatformThread::SetName("CrAppShimMain");
-
- // In tests, launching Chrome does nothing, and we won't get a ping response,
- // so just assume the socket exists.
- if (pid == -1 &&
- !CommandLine::ForCurrentProcess()->HasSwitch(
- app_mode::kLaunchedForTest)) {
- // Launch Chrome if it isn't already running.
- ProcessSerialNumber psn;
- CommandLine command_line(CommandLine::NO_PROGRAM);
- command_line.AppendSwitch(switches::kSilentLaunch);
-
- // If the shim is the app launcher, pass --show-app-list when starting a new
- // Chrome process to inform startup codepaths and load the correct profile.
- if (info->app_mode_id == app_mode::kAppListModeId) {
- command_line.AppendSwitch(switches::kShowAppList);
- } else {
- command_line.AppendSwitchPath(switches::kProfileDirectory,
- info->profile_dir);
- }
-
- bool success =
- base::mac::OpenApplicationWithPath(base::mac::OuterBundlePath(),
- command_line,
- kLSLaunchDefaults,
- &psn);
- if (!success)
- return 1;
-
- base::Callback<void(bool)> on_ping_chrome_reply =
- base::Bind(&AppShimController::OnPingChromeReply,
- base::Unretained(&controller));
-
- // This code abuses the fact that Apple Events sent before the process is
- // fully initialized don't receive a reply until its run loop starts. Once
- // the reply is received, Chrome will have opened its IPC port, guaranteed.
- [ReplyEventHandler pingProcess:psn
- andCall:on_ping_chrome_reply];
-
- main_message_loop.PostDelayedTask(
- FROM_HERE,
- base::Bind(&AppShimController::OnPingChromeTimeout,
- base::Unretained(&controller)),
- base::TimeDelta::FromSeconds(kPingChromeTimeoutSeconds));
- } else {
- // Chrome already running. Proceed to init. This could still fail if Chrome
- // is still starting up or shutting down, but the process will exit quickly,
- // which is preferable to waiting for the Apple Event to timeout after one
- // minute.
- main_message_loop.PostTask(
- FROM_HERE,
- base::Bind(&AppShimController::Init,
- base::Unretained(&controller)));
- }
-
- main_message_loop.Run();
- return 0;
-}
diff --git a/apps/app_shim/extension_app_shim_handler_mac.cc b/apps/app_shim/extension_app_shim_handler_mac.cc
deleted file mode 100644
index 8e90324..0000000
--- a/apps/app_shim/extension_app_shim_handler_mac.cc
+++ /dev/null
@@ -1,557 +0,0 @@
-// 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_lifetime_monitor_factory.h"
-#include "apps/app_shim/app_shim_host_manager_mac.h"
-#include "apps/app_shim/app_shim_messages.h"
-#include "apps/launcher.h"
-#include "base/files/file_path.h"
-#include "base/logging.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/chrome_notification_types.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/profiles/profile_manager.h"
-#include "chrome/browser/ui/extensions/extension_enable_flow.h"
-#include "chrome/browser/ui/extensions/extension_enable_flow_delegate.h"
-#include "chrome/browser/ui/webui/ntp/core_app_launcher_handler.h"
-#include "chrome/browser/web_applications/web_app_mac.h"
-#include "chrome/common/extensions/extension_constants.h"
-#include "components/crx_file/id_util.h"
-#include "content/public/browser/notification_details.h"
-#include "content/public/browser/notification_service.h"
-#include "content/public/browser/notification_source.h"
-#include "extensions/browser/app_window/app_window.h"
-#include "extensions/browser/app_window/app_window_registry.h"
-#include "extensions/browser/app_window/native_app_window.h"
-#include "extensions/browser/extension_host.h"
-#include "extensions/browser/extension_registry.h"
-#include "ui/base/cocoa/focus_window_set.h"
-
-using extensions::AppWindow;
-using extensions::AppWindowRegistry;
-using extensions::ExtensionRegistry;
-
-namespace {
-
-typedef AppWindowRegistry::AppWindowList AppWindowList;
-
-void ProfileLoadedCallback(base::Callback<void(Profile*)> callback,
- Profile* profile,
- Profile::CreateStatus status) {
- if (status == Profile::CREATE_STATUS_INITIALIZED) {
- callback.Run(profile);
- return;
- }
-
- // This should never get an error since it only loads existing profiles.
- DCHECK_EQ(Profile::CREATE_STATUS_CREATED, status);
-}
-
-void SetAppHidden(Profile* profile, const std::string& app_id, bool hidden) {
- AppWindowList windows =
- AppWindowRegistry::Get(profile)->GetAppWindowsForApp(app_id);
- for (AppWindowList::const_reverse_iterator it = windows.rbegin();
- it != windows.rend();
- ++it) {
- if (hidden)
- (*it)->GetBaseWindow()->HideWithApp();
- else
- (*it)->GetBaseWindow()->ShowWithApp();
- }
-}
-
-bool FocusWindows(const AppWindowList& windows) {
- if (windows.empty())
- return false;
-
- std::set<gfx::NativeWindow> native_windows;
- for (AppWindowList::const_iterator it = windows.begin(); it != windows.end();
- ++it) {
- native_windows.insert((*it)->GetNativeWindow());
- }
- // Allow workspace switching. For the browser process, we can reasonably rely
- // on OS X to switch spaces for us and honor relevant user settings. But shims
- // don't have windows, so we have to do it ourselves.
- ui::FocusWindowSet(native_windows);
- return true;
-}
-
-// Attempts to launch a packaged app, prompting the user to enable it if
-// necessary. The prompt is shown in its own window.
-// This class manages its own lifetime.
-class EnableViaPrompt : public ExtensionEnableFlowDelegate {
- public:
- EnableViaPrompt(Profile* profile,
- const std::string& extension_id,
- const base::Callback<void()>& callback)
- : profile_(profile),
- extension_id_(extension_id),
- callback_(callback) {
- }
-
- virtual ~EnableViaPrompt() {
- }
-
- void Run() {
- flow_.reset(new ExtensionEnableFlow(profile_, extension_id_, this));
- flow_->StartForCurrentlyNonexistentWindow(
- base::Callback<gfx::NativeWindow(void)>());
- }
-
- private:
- // ExtensionEnableFlowDelegate overrides.
- virtual void ExtensionEnableFlowFinished() OVERRIDE {
- callback_.Run();
- delete this;
- }
-
- virtual void ExtensionEnableFlowAborted(bool user_initiated) OVERRIDE {
- callback_.Run();
- delete this;
- }
-
- Profile* profile_;
- std::string extension_id_;
- base::Callback<void()> callback_;
- scoped_ptr<ExtensionEnableFlow> flow_;
-
- DISALLOW_COPY_AND_ASSIGN(EnableViaPrompt);
-};
-
-} // namespace
-
-namespace apps {
-
-bool ExtensionAppShimHandler::Delegate::ProfileExistsForPath(
- const base::FilePath& path) {
- ProfileManager* profile_manager = g_browser_process->profile_manager();
- // Check for the profile name in the profile info cache to ensure that we
- // never access any directory that isn't a known profile.
- base::FilePath full_path = profile_manager->user_data_dir().Append(path);
- ProfileInfoCache& cache = profile_manager->GetProfileInfoCache();
- return cache.GetIndexOfProfileWithPath(full_path) != std::string::npos;
-}
-
-Profile* ExtensionAppShimHandler::Delegate::ProfileForPath(
- const base::FilePath& path) {
- ProfileManager* profile_manager = g_browser_process->profile_manager();
- base::FilePath full_path = profile_manager->user_data_dir().Append(path);
- Profile* profile = profile_manager->GetProfileByPath(full_path);
-
- // Use IsValidProfile to check if the profile has been created.
- return profile && profile_manager->IsValidProfile(profile) ? profile : NULL;
-}
-
-void ExtensionAppShimHandler::Delegate::LoadProfileAsync(
- const base::FilePath& path,
- base::Callback<void(Profile*)> callback) {
- ProfileManager* profile_manager = g_browser_process->profile_manager();
- base::FilePath full_path = profile_manager->user_data_dir().Append(path);
- profile_manager->CreateProfileAsync(
- full_path,
- base::Bind(&ProfileLoadedCallback, callback),
- base::string16(), base::string16(), std::string());
-}
-
-AppWindowList ExtensionAppShimHandler::Delegate::GetWindows(
- Profile* profile,
- const std::string& extension_id) {
- return AppWindowRegistry::Get(profile)->GetAppWindowsForApp(extension_id);
-}
-
-const extensions::Extension*
-ExtensionAppShimHandler::Delegate::GetAppExtension(
- Profile* profile,
- const std::string& extension_id) {
- ExtensionRegistry* registry = ExtensionRegistry::Get(profile);
- const extensions::Extension* extension =
- registry->GetExtensionById(extension_id, ExtensionRegistry::ENABLED);
- return extension && extension->is_platform_app() ? extension : NULL;
-}
-
-void ExtensionAppShimHandler::Delegate::EnableExtension(
- Profile* profile,
- const std::string& extension_id,
- const base::Callback<void()>& callback) {
- (new EnableViaPrompt(profile, extension_id, callback))->Run();
-}
-
-void ExtensionAppShimHandler::Delegate::LaunchApp(
- Profile* profile,
- const extensions::Extension* extension,
- const std::vector<base::FilePath>& files) {
- CoreAppLauncherHandler::RecordAppLaunchType(
- extension_misc::APP_LAUNCH_CMD_LINE_APP, extension->GetType());
- if (files.empty()) {
- apps::LaunchPlatformApp(profile, extension);
- } else {
- for (std::vector<base::FilePath>::const_iterator it = files.begin();
- it != files.end(); ++it) {
- apps::LaunchPlatformAppWithPath(profile, extension, *it);
- }
- }
-}
-
-void ExtensionAppShimHandler::Delegate::LaunchShim(
- Profile* profile,
- const extensions::Extension* extension) {
- web_app::MaybeLaunchShortcut(
- web_app::ShortcutInfoForExtensionAndProfile(extension, profile));
-}
-
-void ExtensionAppShimHandler::Delegate::MaybeTerminate() {
- AppShimHandler::MaybeTerminate();
-}
-
-ExtensionAppShimHandler::ExtensionAppShimHandler()
- : delegate_(new Delegate),
- weak_factory_(this) {
- // This is instantiated in BrowserProcessImpl::PreMainMessageLoopRun with
- // AppShimHostManager. Since PROFILE_CREATED is not fired until
- // ProfileManager::GetLastUsedProfile/GetLastOpenedProfiles, this should catch
- // notifications for all profiles.
- registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CREATED,
- content::NotificationService::AllBrowserContextsAndSources());
- registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED,
- content::NotificationService::AllBrowserContextsAndSources());
-}
-
-ExtensionAppShimHandler::~ExtensionAppShimHandler() {}
-
-AppShimHandler::Host* ExtensionAppShimHandler::FindHost(
- Profile* profile,
- const std::string& app_id) {
- HostMap::iterator it = hosts_.find(make_pair(profile, app_id));
- return it == hosts_.end() ? NULL : it->second;
-}
-
-// static
-void ExtensionAppShimHandler::QuitAppForWindow(AppWindow* app_window) {
- ExtensionAppShimHandler* handler = GetInstance();
- Host* host = handler->FindHost(
- Profile::FromBrowserContext(app_window->browser_context()),
- app_window->extension_id());
- if (host) {
- handler->OnShimQuit(host);
- } else {
- // App shims might be disabled or the shim is still starting up.
- AppWindowRegistry::Get(
- Profile::FromBrowserContext(app_window->browser_context()))
- ->CloseAllAppWindowsForApp(app_window->extension_id());
- }
-}
-
-void ExtensionAppShimHandler::HideAppForWindow(AppWindow* app_window) {
- ExtensionAppShimHandler* handler = GetInstance();
- Profile* profile = Profile::FromBrowserContext(app_window->browser_context());
- Host* host = handler->FindHost(profile, app_window->extension_id());
- if (host)
- host->OnAppHide();
- else
- SetAppHidden(profile, app_window->extension_id(), true);
-}
-
-void ExtensionAppShimHandler::FocusAppForWindow(AppWindow* app_window) {
- ExtensionAppShimHandler* handler = GetInstance();
- Profile* profile = Profile::FromBrowserContext(app_window->browser_context());
- const std::string& app_id = app_window->extension_id();
- Host* host = handler->FindHost(profile, app_id);
- if (host) {
- handler->OnShimFocus(host,
- APP_SHIM_FOCUS_NORMAL,
- std::vector<base::FilePath>());
- } else {
- FocusWindows(AppWindowRegistry::Get(profile)->GetAppWindowsForApp(app_id));
- }
-}
-
-// static
-bool ExtensionAppShimHandler::ActivateAndRequestUserAttentionForWindow(
- AppWindow* app_window) {
- ExtensionAppShimHandler* handler = GetInstance();
- Profile* profile = Profile::FromBrowserContext(app_window->browser_context());
- Host* host = handler->FindHost(profile, app_window->extension_id());
- if (host) {
- // Bring the window to the front without showing it.
- AppWindowRegistry::Get(profile)->AppWindowActivated(app_window);
- host->OnAppRequestUserAttention(APP_SHIM_ATTENTION_INFORMATIONAL);
- return true;
- } else {
- // Just show the app.
- SetAppHidden(profile, app_window->extension_id(), false);
- return false;
- }
-}
-
-// static
-void ExtensionAppShimHandler::RequestUserAttentionForWindow(
- AppWindow* app_window,
- AppShimAttentionType attention_type) {
- ExtensionAppShimHandler* handler = GetInstance();
- Profile* profile = Profile::FromBrowserContext(app_window->browser_context());
- Host* host = handler->FindHost(profile, app_window->extension_id());
- if (host)
- host->OnAppRequestUserAttention(attention_type);
-}
-
-// static
-void ExtensionAppShimHandler::OnChromeWillHide() {
- // Send OnAppHide to all the shims so that they go into the hidden state.
- // This is necessary so that when the shim is next focused, it will know to
- // unhide.
- ExtensionAppShimHandler* handler = GetInstance();
- for (HostMap::iterator it = handler->hosts_.begin();
- it != handler->hosts_.end();
- ++it) {
- it->second->OnAppHide();
- }
-}
-
-void ExtensionAppShimHandler::OnShimLaunch(
- Host* host,
- AppShimLaunchType launch_type,
- const std::vector<base::FilePath>& files) {
- const std::string& app_id = host->GetAppId();
- DCHECK(crx_file::id_util::IdIsValid(app_id));
-
- const base::FilePath& profile_path = host->GetProfilePath();
- DCHECK(!profile_path.empty());
-
- if (!delegate_->ProfileExistsForPath(profile_path)) {
- // User may have deleted the profile this shim was originally created for.
- // TODO(jackhou): Add some UI for this case and remove the LOG.
- LOG(ERROR) << "Requested directory is not a known profile '"
- << profile_path.value() << "'.";
- host->OnAppLaunchComplete(APP_SHIM_LAUNCH_PROFILE_NOT_FOUND);
- return;
- }
-
- Profile* profile = delegate_->ProfileForPath(profile_path);
-
- if (profile) {
- OnProfileLoaded(host, launch_type, files, profile);
- return;
- }
-
- // If the profile is not loaded, this must have been a launch by the shim.
- // Load the profile asynchronously, the host will be registered in
- // OnProfileLoaded.
- DCHECK_EQ(APP_SHIM_LAUNCH_NORMAL, launch_type);
- delegate_->LoadProfileAsync(
- profile_path,
- base::Bind(&ExtensionAppShimHandler::OnProfileLoaded,
- weak_factory_.GetWeakPtr(),
- host, launch_type, files));
-
- // Return now. OnAppLaunchComplete will be called when the app is activated.
-}
-
-// static
-ExtensionAppShimHandler* ExtensionAppShimHandler::GetInstance() {
- return g_browser_process->platform_part()
- ->app_shim_host_manager()
- ->extension_app_shim_handler();
-}
-
-void ExtensionAppShimHandler::OnProfileLoaded(
- Host* host,
- AppShimLaunchType launch_type,
- const std::vector<base::FilePath>& files,
- Profile* profile) {
- const std::string& app_id = host->GetAppId();
-
- // The first host to claim this (profile, app_id) becomes the main host.
- // For any others, focus or relaunch the app.
- if (!hosts_.insert(make_pair(make_pair(profile, app_id), host)).second) {
- OnShimFocus(host,
- launch_type == APP_SHIM_LAUNCH_NORMAL ?
- APP_SHIM_FOCUS_REOPEN : APP_SHIM_FOCUS_NORMAL,
- files);
- host->OnAppLaunchComplete(APP_SHIM_LAUNCH_DUPLICATE_HOST);
- return;
- }
-
- if (launch_type != APP_SHIM_LAUNCH_NORMAL) {
- host->OnAppLaunchComplete(APP_SHIM_LAUNCH_SUCCESS);
- return;
- }
-
- // 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.
- const extensions::Extension* extension =
- delegate_->GetAppExtension(profile, app_id);
- if (extension) {
- delegate_->LaunchApp(profile, extension, files);
- return;
- }
-
- delegate_->EnableExtension(
- profile, app_id,
- base::Bind(&ExtensionAppShimHandler::OnExtensionEnabled,
- weak_factory_.GetWeakPtr(),
- host->GetProfilePath(), app_id, files));
-}
-
-void ExtensionAppShimHandler::OnExtensionEnabled(
- const base::FilePath& profile_path,
- const std::string& app_id,
- const std::vector<base::FilePath>& files) {
- Profile* profile = delegate_->ProfileForPath(profile_path);
- if (!profile)
- return;
-
- const extensions::Extension* extension =
- delegate_->GetAppExtension(profile, app_id);
- if (!extension || !delegate_->ProfileExistsForPath(profile_path)) {
- // If !extension, the extension doesn't exist, or was not re-enabled.
- // If the profile doesn't exist, it may have been deleted during the enable
- // prompt. In this case, NOTIFICATION_PROFILE_DESTROYED may not be fired
- // until later, so respond to the host now.
- Host* host = FindHost(profile, app_id);
- if (host)
- host->OnAppLaunchComplete(APP_SHIM_LAUNCH_APP_NOT_FOUND);
- return;
- }
-
- delegate_->LaunchApp(profile, extension, files);
-}
-
-
-void ExtensionAppShimHandler::OnShimClose(Host* host) {
- // This might be called when shutting down. Don't try to look up the profile
- // since profile_manager might not be around.
- for (HostMap::iterator it = hosts_.begin(); it != hosts_.end(); ) {
- HostMap::iterator current = it++;
- if (current->second == host)
- hosts_.erase(current);
- }
-}
-
-void ExtensionAppShimHandler::OnShimFocus(
- Host* host,
- AppShimFocusType focus_type,
- const std::vector<base::FilePath>& files) {
- DCHECK(delegate_->ProfileExistsForPath(host->GetProfilePath()));
- Profile* profile = delegate_->ProfileForPath(host->GetProfilePath());
-
- const AppWindowList windows =
- delegate_->GetWindows(profile, host->GetAppId());
- bool windows_focused = FocusWindows(windows);
-
- if (focus_type == APP_SHIM_FOCUS_NORMAL ||
- (focus_type == APP_SHIM_FOCUS_REOPEN && windows_focused)) {
- return;
- }
-
- const extensions::Extension* extension =
- delegate_->GetAppExtension(profile, host->GetAppId());
- if (extension) {
- delegate_->LaunchApp(profile, extension, files);
- } else {
- // Extensions may have been uninstalled or disabled since the shim
- // started.
- host->OnAppClosed();
- }
-}
-
-void ExtensionAppShimHandler::OnShimSetHidden(Host* host, bool hidden) {
- DCHECK(delegate_->ProfileExistsForPath(host->GetProfilePath()));
- Profile* profile = delegate_->ProfileForPath(host->GetProfilePath());
-
- SetAppHidden(profile, host->GetAppId(), hidden);
-}
-
-void ExtensionAppShimHandler::OnShimQuit(Host* host) {
- DCHECK(delegate_->ProfileExistsForPath(host->GetProfilePath()));
- Profile* profile = delegate_->ProfileForPath(host->GetProfilePath());
-
- const std::string& app_id = host->GetAppId();
- const AppWindowList windows = delegate_->GetWindows(profile, app_id);
- for (AppWindowRegistry::const_iterator it = windows.begin();
- it != windows.end();
- ++it) {
- (*it)->GetBaseWindow()->Close();
- }
- // Once the last window closes, flow will end up in OnAppDeactivated via
- // AppLifetimeMonitor.
-}
-
-void ExtensionAppShimHandler::set_delegate(Delegate* delegate) {
- delegate_.reset(delegate);
-}
-
-void ExtensionAppShimHandler::Observe(
- int type,
- const content::NotificationSource& source,
- const content::NotificationDetails& details) {
- Profile* profile = content::Source<Profile>(source).ptr();
- if (profile->IsOffTheRecord())
- return;
-
- switch (type) {
- case chrome::NOTIFICATION_PROFILE_CREATED: {
- AppLifetimeMonitorFactory::GetForProfile(profile)->AddObserver(this);
- break;
- }
- case chrome::NOTIFICATION_PROFILE_DESTROYED: {
- AppLifetimeMonitorFactory::GetForProfile(profile)->RemoveObserver(this);
- // Shut down every shim associated with this profile.
- for (HostMap::iterator it = hosts_.begin(); it != hosts_.end(); ) {
- // Increment the iterator first as OnAppClosed may call back to
- // OnShimClose and invalidate the iterator.
- HostMap::iterator current = it++;
- if (profile->IsSameProfile(current->first.first)) {
- Host* host = current->second;
- host->OnAppClosed();
- }
- }
- break;
- }
- default: {
- NOTREACHED(); // Unexpected notification.
- break;
- }
- }
-}
-
-void ExtensionAppShimHandler::OnAppStart(Profile* profile,
- const std::string& app_id) {}
-
-void ExtensionAppShimHandler::OnAppActivated(Profile* profile,
- const std::string& app_id) {
- const extensions::Extension* extension =
- delegate_->GetAppExtension(profile, app_id);
- if (!extension)
- return;
-
- Host* host = FindHost(profile, app_id);
- if (host) {
- host->OnAppLaunchComplete(APP_SHIM_LAUNCH_SUCCESS);
- OnShimFocus(host, APP_SHIM_FOCUS_NORMAL, std::vector<base::FilePath>());
- return;
- }
-
- delegate_->LaunchShim(profile, extension);
-}
-
-void ExtensionAppShimHandler::OnAppDeactivated(Profile* profile,
- const std::string& app_id) {
- Host* host = FindHost(profile, app_id);
- if (host)
- host->OnAppClosed();
-
- if (hosts_.empty())
- delegate_->MaybeTerminate();
-}
-
-void ExtensionAppShimHandler::OnAppStop(Profile* profile,
- const std::string& app_id) {}
-
-void ExtensionAppShimHandler::OnChromeTerminating() {}
-
-} // namespace apps
diff --git a/apps/app_shim/extension_app_shim_handler_mac.h b/apps/app_shim/extension_app_shim_handler_mac.h
deleted file mode 100644
index 6bebb04..0000000
--- a/apps/app_shim/extension_app_shim_handler_mac.h
+++ /dev/null
@@ -1,159 +0,0 @@
-// 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.
-
-#ifndef APPS_APP_SHIM_EXTENSION_APP_SHIM_HANDLER_MAC_H_
-#define APPS_APP_SHIM_EXTENSION_APP_SHIM_HANDLER_MAC_H_
-
-#include <map>
-#include <string>
-#include <vector>
-
-#include "apps/app_lifetime_monitor.h"
-#include "apps/app_shim/app_shim_handler_mac.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/memory/weak_ptr.h"
-#include "content/public/browser/notification_observer.h"
-#include "content/public/browser/notification_registrar.h"
-#include "extensions/browser/app_window/app_window_registry.h"
-
-class Profile;
-
-namespace base {
-class FilePath;
-}
-
-namespace content {
-class WebContents;
-}
-
-namespace extensions {
-class AppWindow;
-class Extension;
-}
-
-namespace apps {
-
-// This app shim handler that handles events for app shims that correspond to an
-// extension.
-class ExtensionAppShimHandler : public AppShimHandler,
- public content::NotificationObserver,
- public AppLifetimeMonitor::Observer {
- public:
- class Delegate {
- public:
- virtual ~Delegate() {}
-
- virtual bool ProfileExistsForPath(const base::FilePath& path);
- virtual Profile* ProfileForPath(const base::FilePath& path);
- virtual void LoadProfileAsync(const base::FilePath& path,
- base::Callback<void(Profile*)> callback);
-
- virtual extensions::AppWindowRegistry::AppWindowList GetWindows(
- Profile* profile,
- const std::string& extension_id);
-
- virtual const extensions::Extension* GetAppExtension(
- Profile* profile, const std::string& extension_id);
- virtual void EnableExtension(Profile* profile,
- const std::string& extension_id,
- const base::Callback<void()>& callback);
- virtual void LaunchApp(Profile* profile,
- const extensions::Extension* extension,
- const std::vector<base::FilePath>& files);
- virtual void LaunchShim(Profile* profile,
- const extensions::Extension* extension);
-
- virtual void MaybeTerminate();
- };
-
- ExtensionAppShimHandler();
- virtual ~ExtensionAppShimHandler();
-
- AppShimHandler::Host* FindHost(Profile* profile, const std::string& app_id);
-
- static void QuitAppForWindow(extensions::AppWindow* app_window);
-
- static void HideAppForWindow(extensions::AppWindow* app_window);
-
- static void FocusAppForWindow(extensions::AppWindow* app_window);
-
- // Brings the window to the front without showing it and instructs the shim to
- // request user attention. If there is no shim, show the app and return false.
- static bool ActivateAndRequestUserAttentionForWindow(
- extensions::AppWindow* app_window);
-
- // Instructs the shim to request user attention. Returns false if there is no
- // shim for this window.
- static void RequestUserAttentionForWindow(
- extensions::AppWindow* app_window,
- AppShimAttentionType attention_type);
-
- // Called by AppControllerMac when Chrome hides.
- static void OnChromeWillHide();
-
- // AppShimHandler overrides:
- virtual void OnShimLaunch(Host* host,
- AppShimLaunchType launch_type,
- const std::vector<base::FilePath>& files) OVERRIDE;
- virtual void OnShimClose(Host* host) OVERRIDE;
- virtual void OnShimFocus(Host* host,
- AppShimFocusType focus_type,
- const std::vector<base::FilePath>& files) OVERRIDE;
- virtual void OnShimSetHidden(Host* host, bool hidden) OVERRIDE;
- virtual void OnShimQuit(Host* host) OVERRIDE;
-
- // AppLifetimeMonitor::Observer overrides:
- virtual void OnAppStart(Profile* profile, const std::string& app_id) OVERRIDE;
- virtual void OnAppActivated(Profile* profile,
- const std::string& app_id) OVERRIDE;
- virtual void OnAppDeactivated(Profile* profile,
- const std::string& app_id) OVERRIDE;
- virtual void OnAppStop(Profile* profile, const std::string& app_id) OVERRIDE;
- virtual void OnChromeTerminating() OVERRIDE;
-
- // content::NotificationObserver overrides:
- virtual void Observe(int type,
- const content::NotificationSource& source,
- const content::NotificationDetails& details) OVERRIDE;
-
- protected:
- typedef std::map<std::pair<Profile*, std::string>, AppShimHandler::Host*>
- HostMap;
-
- // Exposed for testing.
- void set_delegate(Delegate* delegate);
- HostMap& hosts() { return hosts_; }
- content::NotificationRegistrar& registrar() { return registrar_; }
-
- private:
- // Helper function to get the instance on the browser process.
- static ExtensionAppShimHandler* GetInstance();
-
- // This is passed to Delegate::LoadProfileAsync for shim-initiated launches
- // where the profile was not yet loaded.
- void OnProfileLoaded(Host* host,
- AppShimLaunchType launch_type,
- const std::vector<base::FilePath>& files,
- Profile* profile);
-
- // This is passed to Delegate::EnableViaPrompt for shim-initiated launches
- // where the extension is disabled.
- void OnExtensionEnabled(const base::FilePath& profile_path,
- const std::string& app_id,
- const std::vector<base::FilePath>& files);
-
- scoped_ptr<Delegate> delegate_;
-
- HostMap hosts_;
-
- content::NotificationRegistrar registrar_;
-
- base::WeakPtrFactory<ExtensionAppShimHandler> weak_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(ExtensionAppShimHandler);
-};
-
-} // namespace apps
-
-#endif // APPS_APP_SHIM_EXTENSION_APP_SHIM_HANDLER_MAC_H_
diff --git a/apps/app_shim/extension_app_shim_handler_mac_unittest.cc b/apps/app_shim/extension_app_shim_handler_mac_unittest.cc
deleted file mode 100644
index 27791d9..0000000
--- a/apps/app_shim/extension_app_shim_handler_mac_unittest.cc
+++ /dev/null
@@ -1,396 +0,0 @@
-// 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 <vector>
-
-#include "apps/app_shim/app_shim_host_mac.h"
-#include "base/memory/scoped_ptr.h"
-#include "chrome/browser/chrome_notification_types.h"
-#include "chrome/test/base/testing_profile.h"
-#include "content/public/browser/notification_service.h"
-#include "extensions/common/extension.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace apps {
-
-using extensions::Extension;
-typedef extensions::AppWindowRegistry::AppWindowList AppWindowList;
-
-using ::testing::_;
-using ::testing::Invoke;
-using ::testing::Return;
-using ::testing::WithArgs;
-
-class MockDelegate : public ExtensionAppShimHandler::Delegate {
- public:
- virtual ~MockDelegate() {}
-
- MOCK_METHOD1(ProfileExistsForPath, bool(const base::FilePath&));
- MOCK_METHOD1(ProfileForPath, Profile*(const base::FilePath&));
- MOCK_METHOD2(LoadProfileAsync,
- void(const base::FilePath&,
- base::Callback<void(Profile*)>));
-
- MOCK_METHOD2(GetWindows, AppWindowList(Profile*, const std::string&));
-
- MOCK_METHOD2(GetAppExtension, const Extension*(Profile*, const std::string&));
- MOCK_METHOD3(EnableExtension, void(Profile*,
- const std::string&,
- const base::Callback<void()>&));
- MOCK_METHOD3(LaunchApp,
- void(Profile*,
- const Extension*,
- const std::vector<base::FilePath>&));
- MOCK_METHOD2(LaunchShim, void(Profile*, const Extension*));
-
- MOCK_METHOD0(MaybeTerminate, void());
-
- void CaptureLoadProfileCallback(
- const base::FilePath& path,
- base::Callback<void(Profile*)> callback) {
- callbacks_[path] = callback;
- }
-
- bool RunLoadProfileCallback(
- const base::FilePath& path,
- Profile* profile) {
- callbacks_[path].Run(profile);
- return callbacks_.erase(path);
- }
-
- void RunCallback(const base::Callback<void()>& callback) {
- callback.Run();
- }
-
- private:
- std::map<base::FilePath,
- base::Callback<void(Profile*)> > callbacks_;
-};
-
-class TestingExtensionAppShimHandler : public ExtensionAppShimHandler {
- public:
- TestingExtensionAppShimHandler(Delegate* delegate) {
- set_delegate(delegate);
- }
- virtual ~TestingExtensionAppShimHandler() {}
-
- MOCK_METHOD3(OnShimFocus,
- void(Host* host,
- AppShimFocusType,
- const std::vector<base::FilePath>& files));
-
- void RealOnShimFocus(Host* host,
- AppShimFocusType focus_type,
- const std::vector<base::FilePath>& files) {
- ExtensionAppShimHandler::OnShimFocus(host, focus_type, files);
- }
-
- AppShimHandler::Host* FindHost(Profile* profile,
- const std::string& app_id) {
- HostMap::const_iterator it = hosts().find(make_pair(profile, app_id));
- return it == hosts().end() ? NULL : it->second;
- }
-
- content::NotificationRegistrar& GetRegistrar() { return registrar(); }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(TestingExtensionAppShimHandler);
-};
-
-const char kTestAppIdA[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
-const char kTestAppIdB[] = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
-
-class FakeHost : public apps::AppShimHandler::Host {
- public:
- FakeHost(const base::FilePath& profile_path,
- const std::string& app_id,
- TestingExtensionAppShimHandler* handler)
- : profile_path_(profile_path),
- app_id_(app_id),
- handler_(handler),
- close_count_(0) {}
-
- MOCK_METHOD1(OnAppLaunchComplete, void(AppShimLaunchResult));
-
- virtual void OnAppClosed() OVERRIDE {
- handler_->OnShimClose(this);
- ++close_count_;
- }
- virtual void OnAppHide() OVERRIDE {}
- virtual void OnAppRequestUserAttention(AppShimAttentionType type) OVERRIDE {}
- virtual base::FilePath GetProfilePath() const OVERRIDE {
- return profile_path_;
- }
- virtual std::string GetAppId() const OVERRIDE { return app_id_; }
-
- int close_count() { return close_count_; }
-
- private:
- base::FilePath profile_path_;
- std::string app_id_;
- TestingExtensionAppShimHandler* handler_;
- int close_count_;
-
- DISALLOW_COPY_AND_ASSIGN(FakeHost);
-};
-
-class ExtensionAppShimHandlerTest : public testing::Test {
- protected:
- ExtensionAppShimHandlerTest()
- : delegate_(new MockDelegate),
- handler_(new TestingExtensionAppShimHandler(delegate_)),
- profile_path_a_("Profile A"),
- profile_path_b_("Profile B"),
- host_aa_(profile_path_a_, kTestAppIdA, handler_.get()),
- host_ab_(profile_path_a_, kTestAppIdB, handler_.get()),
- host_bb_(profile_path_b_, kTestAppIdB, handler_.get()),
- host_aa_duplicate_(profile_path_a_, kTestAppIdA, handler_.get()) {
- base::FilePath extension_path("/fake/path");
- base::DictionaryValue manifest;
- manifest.SetString("name", "Fake Name");
- manifest.SetString("version", "1");
- std::string error;
- extension_a_ = Extension::Create(
- extension_path, extensions::Manifest::INTERNAL, manifest,
- Extension::NO_FLAGS, kTestAppIdA, &error);
- EXPECT_TRUE(extension_a_.get()) << error;
-
- extension_b_ = Extension::Create(
- extension_path, extensions::Manifest::INTERNAL, manifest,
- Extension::NO_FLAGS, kTestAppIdB, &error);
- EXPECT_TRUE(extension_b_.get()) << error;
-
- EXPECT_CALL(*delegate_, ProfileExistsForPath(profile_path_a_))
- .WillRepeatedly(Return(true));
- EXPECT_CALL(*delegate_, ProfileForPath(profile_path_a_))
- .WillRepeatedly(Return(&profile_a_));
- EXPECT_CALL(*delegate_, ProfileExistsForPath(profile_path_b_))
- .WillRepeatedly(Return(true));
- EXPECT_CALL(*delegate_, ProfileForPath(profile_path_b_))
- .WillRepeatedly(Return(&profile_b_));
-
- // In most tests, we don't care about the result of GetWindows, it just
- // needs to be non-empty.
- AppWindowList app_window_list;
- app_window_list.push_back(static_cast<extensions::AppWindow*>(NULL));
- EXPECT_CALL(*delegate_, GetWindows(_, _))
- .WillRepeatedly(Return(app_window_list));
-
- EXPECT_CALL(*delegate_, GetAppExtension(_, kTestAppIdA))
- .WillRepeatedly(Return(extension_a_.get()));
- EXPECT_CALL(*delegate_, GetAppExtension(_, kTestAppIdB))
- .WillRepeatedly(Return(extension_b_.get()));
- EXPECT_CALL(*delegate_, LaunchApp(_, _, _))
- .WillRepeatedly(Return());
- }
-
- void NormalLaunch(AppShimHandler::Host* host) {
- handler_->OnShimLaunch(host,
- APP_SHIM_LAUNCH_NORMAL,
- std::vector<base::FilePath>());
- }
-
- void RegisterOnlyLaunch(AppShimHandler::Host* host) {
- handler_->OnShimLaunch(host,
- APP_SHIM_LAUNCH_REGISTER_ONLY,
- std::vector<base::FilePath>());
- }
-
- MockDelegate* delegate_;
- scoped_ptr<TestingExtensionAppShimHandler> handler_;
- base::FilePath profile_path_a_;
- base::FilePath profile_path_b_;
- TestingProfile profile_a_;
- TestingProfile profile_b_;
- FakeHost host_aa_;
- FakeHost host_ab_;
- FakeHost host_bb_;
- FakeHost host_aa_duplicate_;
- scoped_refptr<Extension> extension_a_;
- scoped_refptr<Extension> extension_b_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(ExtensionAppShimHandlerTest);
-};
-
-TEST_F(ExtensionAppShimHandlerTest, LaunchProfileNotFound) {
- // Bad profile path.
- EXPECT_CALL(*delegate_, ProfileExistsForPath(profile_path_a_))
- .WillOnce(Return(false))
- .WillRepeatedly(Return(true));
- EXPECT_CALL(host_aa_, OnAppLaunchComplete(APP_SHIM_LAUNCH_PROFILE_NOT_FOUND));
- NormalLaunch(&host_aa_);
-}
-
-TEST_F(ExtensionAppShimHandlerTest, LaunchAppNotFound) {
- // App not found.
- EXPECT_CALL(*delegate_, GetAppExtension(&profile_a_, kTestAppIdA))
- .WillRepeatedly(Return(static_cast<const Extension*>(NULL)));
- EXPECT_CALL(*delegate_, EnableExtension(&profile_a_, kTestAppIdA, _))
- .WillOnce(WithArgs<2>(Invoke(delegate_, &MockDelegate::RunCallback)));
- EXPECT_CALL(host_aa_, OnAppLaunchComplete(APP_SHIM_LAUNCH_APP_NOT_FOUND));
- NormalLaunch(&host_aa_);
-}
-
-TEST_F(ExtensionAppShimHandlerTest, LaunchAppNotEnabled) {
- // App not found.
- EXPECT_CALL(*delegate_, GetAppExtension(&profile_a_, kTestAppIdA))
- .WillOnce(Return(static_cast<const Extension*>(NULL)))
- .WillRepeatedly(Return(extension_a_.get()));
- EXPECT_CALL(*delegate_, EnableExtension(&profile_a_, kTestAppIdA, _))
- .WillOnce(WithArgs<2>(Invoke(delegate_, &MockDelegate::RunCallback)));
- NormalLaunch(&host_aa_);
-}
-
-TEST_F(ExtensionAppShimHandlerTest, LaunchAndCloseShim) {
- // Normal startup.
- NormalLaunch(&host_aa_);
- EXPECT_EQ(&host_aa_, handler_->FindHost(&profile_a_, kTestAppIdA));
-
- NormalLaunch(&host_ab_);
- EXPECT_EQ(&host_ab_, handler_->FindHost(&profile_a_, kTestAppIdB));
-
- std::vector<base::FilePath> some_file(1, base::FilePath("some_file"));
- EXPECT_CALL(*delegate_,
- LaunchApp(&profile_b_, extension_b_.get(), some_file));
- handler_->OnShimLaunch(&host_bb_, APP_SHIM_LAUNCH_NORMAL, some_file);
- EXPECT_EQ(&host_bb_, handler_->FindHost(&profile_b_, kTestAppIdB));
-
- // Activation when there is a registered shim finishes launch with success and
- // focuses the app.
- EXPECT_CALL(host_aa_, OnAppLaunchComplete(APP_SHIM_LAUNCH_SUCCESS));
- EXPECT_CALL(*handler_, OnShimFocus(&host_aa_, APP_SHIM_FOCUS_NORMAL, _));
- handler_->OnAppActivated(&profile_a_, kTestAppIdA);
-
- // Starting and closing a second host just focuses the app.
- EXPECT_CALL(*handler_, OnShimFocus(&host_aa_duplicate_,
- APP_SHIM_FOCUS_REOPEN,
- some_file));
- EXPECT_CALL(host_aa_duplicate_,
- OnAppLaunchComplete(APP_SHIM_LAUNCH_DUPLICATE_HOST));
- handler_->OnShimLaunch(&host_aa_duplicate_,
- APP_SHIM_LAUNCH_NORMAL,
- some_file);
- EXPECT_EQ(&host_aa_, handler_->FindHost(&profile_a_, kTestAppIdA));
- handler_->OnShimClose(&host_aa_duplicate_);
- EXPECT_EQ(&host_aa_, handler_->FindHost(&profile_a_, kTestAppIdA));
-
- // Normal close.
- handler_->OnShimClose(&host_aa_);
- EXPECT_FALSE(handler_->FindHost(&profile_a_, kTestAppIdA));
-
- // Closing the second host afterward does nothing.
- handler_->OnShimClose(&host_aa_duplicate_);
- EXPECT_FALSE(handler_->FindHost(&profile_a_, kTestAppIdA));
-}
-
-TEST_F(ExtensionAppShimHandlerTest, AppLifetime) {
- // When the app activates, if there is no shim, start one.
- EXPECT_CALL(*delegate_, LaunchShim(&profile_a_, extension_a_.get()));
- handler_->OnAppActivated(&profile_a_, kTestAppIdA);
-
- // Normal shim launch adds an entry in the map.
- // App should not be launched here, but return success to the shim.
- EXPECT_CALL(*delegate_,
- LaunchApp(&profile_a_, extension_a_.get(), _))
- .Times(0);
- EXPECT_CALL(host_aa_, OnAppLaunchComplete(APP_SHIM_LAUNCH_SUCCESS));
- RegisterOnlyLaunch(&host_aa_);
- EXPECT_EQ(&host_aa_, handler_->FindHost(&profile_a_, kTestAppIdA));
-
- // Return no app windows for OnShimFocus and OnShimQuit.
- AppWindowList app_window_list;
- EXPECT_CALL(*delegate_, GetWindows(&profile_a_, kTestAppIdA))
- .WillRepeatedly(Return(app_window_list));
-
- // Non-reopen focus does nothing.
- EXPECT_CALL(*handler_, OnShimFocus(&host_aa_, APP_SHIM_FOCUS_NORMAL, _))
- .WillOnce(Invoke(handler_.get(),
- &TestingExtensionAppShimHandler::RealOnShimFocus));
- EXPECT_CALL(*delegate_,
- LaunchApp(&profile_a_, extension_a_.get(), _))
- .Times(0);
- handler_->OnShimFocus(&host_aa_,
- APP_SHIM_FOCUS_NORMAL,
- std::vector<base::FilePath>());
-
- // Reopen focus launches the app.
- EXPECT_CALL(*handler_, OnShimFocus(&host_aa_, APP_SHIM_FOCUS_REOPEN, _))
- .WillOnce(Invoke(handler_.get(),
- &TestingExtensionAppShimHandler::RealOnShimFocus));
- std::vector<base::FilePath> some_file(1, base::FilePath("some_file"));
- EXPECT_CALL(*delegate_,
- LaunchApp(&profile_a_, extension_a_.get(), some_file));
- handler_->OnShimFocus(&host_aa_, APP_SHIM_FOCUS_REOPEN, some_file);
-
- // Quit just closes all the windows. This tests that it doesn't terminate,
- // but we expect closing all windows triggers a OnAppDeactivated from
- // AppLifetimeMonitor.
- handler_->OnShimQuit(&host_aa_);
-
- // Closing all windows closes the shim and checks if Chrome should be
- // terminated.
- EXPECT_CALL(*delegate_, MaybeTerminate())
- .WillOnce(Return());
- handler_->OnAppDeactivated(&profile_a_, kTestAppIdA);
- EXPECT_EQ(1, host_aa_.close_count());
-}
-
-TEST_F(ExtensionAppShimHandlerTest, MaybeTerminate) {
- // Launch shims, adding entries in the map.
- EXPECT_CALL(host_aa_, OnAppLaunchComplete(APP_SHIM_LAUNCH_SUCCESS));
- RegisterOnlyLaunch(&host_aa_);
- EXPECT_EQ(&host_aa_, handler_->FindHost(&profile_a_, kTestAppIdA));
-
- EXPECT_CALL(host_ab_, OnAppLaunchComplete(APP_SHIM_LAUNCH_SUCCESS));
- RegisterOnlyLaunch(&host_ab_);
- EXPECT_EQ(&host_ab_, handler_->FindHost(&profile_a_, kTestAppIdB));
-
- // Return empty window list.
- AppWindowList app_window_list;
- EXPECT_CALL(*delegate_, GetWindows(_, _))
- .WillRepeatedly(Return(app_window_list));
-
- // Quitting when there's another shim should not terminate.
- EXPECT_CALL(*delegate_, MaybeTerminate())
- .Times(0);
- handler_->OnAppDeactivated(&profile_a_, kTestAppIdA);
-
- // Quitting when it's the last shim should terminate.
- EXPECT_CALL(*delegate_, MaybeTerminate());
- handler_->OnAppDeactivated(&profile_a_, kTestAppIdB);
-}
-
-TEST_F(ExtensionAppShimHandlerTest, RegisterOnly) {
- // For an APP_SHIM_LAUNCH_REGISTER_ONLY, don't launch the app.
- EXPECT_CALL(*delegate_, LaunchApp(_, _, _))
- .Times(0);
- EXPECT_CALL(host_aa_, OnAppLaunchComplete(APP_SHIM_LAUNCH_SUCCESS));
- RegisterOnlyLaunch(&host_aa_);
- EXPECT_TRUE(handler_->FindHost(&profile_a_, kTestAppIdA));
-
- // Close the shim, removing the entry in the map.
- handler_->OnShimClose(&host_aa_);
- EXPECT_FALSE(handler_->FindHost(&profile_a_, kTestAppIdA));
-}
-
-TEST_F(ExtensionAppShimHandlerTest, LoadProfile) {
- // If the profile is not loaded when an OnShimLaunch arrives, return false
- // and load the profile asynchronously. Launch the app when the profile is
- // ready.
- EXPECT_CALL(*delegate_, ProfileForPath(profile_path_a_))
- .WillOnce(Return(static_cast<Profile*>(NULL)))
- .WillRepeatedly(Return(&profile_a_));
- EXPECT_CALL(*delegate_, LoadProfileAsync(profile_path_a_, _))
- .WillOnce(Invoke(delegate_, &MockDelegate::CaptureLoadProfileCallback));
- NormalLaunch(&host_aa_);
- EXPECT_FALSE(handler_->FindHost(&profile_a_, kTestAppIdA));
- delegate_->RunLoadProfileCallback(profile_path_a_, &profile_a_);
- EXPECT_TRUE(handler_->FindHost(&profile_a_, kTestAppIdA));
-}
-
-} // namespace apps
diff --git a/apps/app_shim/test/app_shim_host_manager_test_api_mac.cc b/apps/app_shim/test/app_shim_host_manager_test_api_mac.cc
deleted file mode 100644
index 6fbdd8c..0000000
--- a/apps/app_shim/test/app_shim_host_manager_test_api_mac.cc
+++ /dev/null
@@ -1,26 +0,0 @@
-// 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/test/app_shim_host_manager_test_api_mac.h"
-
-#include "apps/app_shim/app_shim_host_manager_mac.h"
-#include "base/files/file_path.h"
-
-namespace test {
-
-AppShimHostManagerTestApi::AppShimHostManagerTestApi(
- AppShimHostManager* host_manager)
- : host_manager_(host_manager) {
- DCHECK(host_manager_);
-}
-
-apps::UnixDomainSocketAcceptor* AppShimHostManagerTestApi::acceptor() {
- return host_manager_->acceptor_.get();
-}
-
-const base::FilePath& AppShimHostManagerTestApi::directory_in_tmp() {
- return host_manager_->directory_in_tmp_;
-}
-
-} // namespace test
diff --git a/apps/app_shim/test/app_shim_host_manager_test_api_mac.h b/apps/app_shim/test/app_shim_host_manager_test_api_mac.h
deleted file mode 100644
index b42e389..0000000
--- a/apps/app_shim/test/app_shim_host_manager_test_api_mac.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// 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.
-
-#ifndef APPS_APP_SHIM_TEST_APP_SHIM_HOST_MANAGER_TEST_API_MAC_H
-#define APPS_APP_SHIM_TEST_APP_SHIM_HOST_MANAGER_TEST_API_MAC_H
-
-#include "base/basictypes.h"
-
-class AppShimHostManager;
-
-namespace base {
-class FilePath;
-}
-
-namespace apps {
-class UnixDomainSocketAcceptor;
-}
-
-namespace test {
-
-class AppShimHostManagerTestApi {
- public:
- explicit AppShimHostManagerTestApi(AppShimHostManager* host_manager);
-
- apps::UnixDomainSocketAcceptor* acceptor();
-
- const base::FilePath& directory_in_tmp();
-
- private:
- AppShimHostManager* host_manager_; // Not owned.
-
- DISALLOW_COPY_AND_ASSIGN(AppShimHostManagerTestApi);
-};
-
-} // namespace test
-
-#endif // APPS_APP_SHIM_TEST_APP_SHIM_HOST_MANAGER_TEST_API_MAC_H
diff --git a/apps/app_shim/unix_domain_socket_acceptor.cc b/apps/app_shim/unix_domain_socket_acceptor.cc
deleted file mode 100644
index f5cda65..0000000
--- a/apps/app_shim/unix_domain_socket_acceptor.cc
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2014 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/unix_domain_socket_acceptor.h"
-
-#include "base/files/file_util.h"
-#include "base/files/scoped_file.h"
-#include "base/logging.h"
-#include "ipc/unix_domain_socket_util.h"
-
-namespace apps {
-
-UnixDomainSocketAcceptor::UnixDomainSocketAcceptor(const base::FilePath& path,
- Delegate* delegate)
- : path_(path), delegate_(delegate), listen_fd_(-1) {
- DCHECK(delegate_);
- CreateSocket();
-}
-
-UnixDomainSocketAcceptor::~UnixDomainSocketAcceptor() {
- Close();
-}
-
-bool UnixDomainSocketAcceptor::CreateSocket() {
- DCHECK(listen_fd_ < 0);
-
- // Create the socket.
- return IPC::CreateServerUnixDomainSocket(path_, &listen_fd_);
-}
-
-bool UnixDomainSocketAcceptor::Listen() {
- if (listen_fd_ < 0)
- return false;
-
- // Watch the fd for connections, and turn any connections into
- // active sockets.
- base::MessageLoopForIO::current()->WatchFileDescriptor(
- listen_fd_,
- true,
- base::MessageLoopForIO::WATCH_READ,
- &server_listen_connection_watcher_,
- this);
- return true;
-}
-
-// Called by libevent when we can read from the fd without blocking.
-void UnixDomainSocketAcceptor::OnFileCanReadWithoutBlocking(int fd) {
- DCHECK(fd == listen_fd_);
- int new_fd = -1;
- if (!IPC::ServerAcceptConnection(listen_fd_, &new_fd)) {
- Close();
- delegate_->OnListenError();
- return;
- }
- base::ScopedFD scoped_fd(new_fd);
-
- if (!scoped_fd.is_valid()) {
- // The accept() failed, but not in such a way that the factory needs to be
- // shut down.
- return;
- }
-
- // Verify that the IPC channel peer is running as the same user.
- if (!IPC::IsPeerAuthorized(scoped_fd.get()))
- return;
-
- IPC::ChannelHandle handle(std::string(),
- base::FileDescriptor(scoped_fd.release(), true));
- delegate_->OnClientConnected(handle);
-}
-
-void UnixDomainSocketAcceptor::OnFileCanWriteWithoutBlocking(int fd) {
- NOTREACHED() << "Listen fd should never be writable.";
-}
-
-void UnixDomainSocketAcceptor::Close() {
- if (listen_fd_ < 0)
- return;
- if (IGNORE_EINTR(close(listen_fd_)) < 0)
- PLOG(ERROR) << "close";
- listen_fd_ = -1;
- if (unlink(path_.value().c_str()) < 0)
- PLOG(ERROR) << "unlink";
-
- // Unregister libevent for the listening socket and close it.
- server_listen_connection_watcher_.StopWatchingFileDescriptor();
-}
-
-} // namespace apps
diff --git a/apps/app_shim/unix_domain_socket_acceptor.h b/apps/app_shim/unix_domain_socket_acceptor.h
deleted file mode 100644
index 64ee306..0000000
--- a/apps/app_shim/unix_domain_socket_acceptor.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef APPS_APP_SHIM_UNIX_DOMAIN_SOCKET_ACCEPTOR_H_
-#define APPS_APP_SHIM_UNIX_DOMAIN_SOCKET_ACCEPTOR_H_
-
-#include "base/files/file_path.h"
-#include "base/message_loop/message_loop.h"
-#include "ipc/ipc_channel_handle.h"
-
-namespace apps {
-
-// A UnixDomainSocketAcceptor listens on a UNIX domain socket. When a
-// client connects to the socket, it accept()s the connection and
-// passes the new FD to the delegate. The delegate is then responsible
-// for creating a new IPC::Channel for the FD.
-class UnixDomainSocketAcceptor : public base::MessageLoopForIO::Watcher {
- public:
- class Delegate {
- public:
- // Called when a client connects to the factory. It is the delegate's
- // responsibility to create an IPC::Channel for the handle, or else close
- // the file descriptor contained therein.
- virtual void OnClientConnected(const IPC::ChannelHandle& handle) = 0;
-
- // Called when an error occurs and the channel is closed.
- virtual void OnListenError() = 0;
- };
-
- UnixDomainSocketAcceptor(const base::FilePath& path, Delegate* delegate);
-
- virtual ~UnixDomainSocketAcceptor();
-
- // Call this to start listening on the socket.
- bool Listen();
-
- // Close and unlink the socket, and stop accepting connections.
- void Close();
-
- private:
- bool CreateSocket();
- virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE;
- virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE;
-
- base::MessageLoopForIO::FileDescriptorWatcher
- server_listen_connection_watcher_;
- base::FilePath path_;
- Delegate* delegate_;
- int listen_fd_;
-
- DISALLOW_COPY_AND_ASSIGN(UnixDomainSocketAcceptor);
-};
-
-} // namespace apps
-
-#endif // APPS_APP_SHIM_UNIX_DOMAIN_SOCKET_ACCEPTOR_H_