summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
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_