summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
-rw-r--r--apps/app_shim/app_shim.gypi2
-rw-r--r--apps/app_shim/app_shim_host_mac.h4
-rw-r--r--apps/app_shim/app_shim_host_manager_browsertest_mac.mm4
-rw-r--r--apps/app_shim/app_shim_host_manager_mac.h18
-rw-r--r--apps/app_shim/app_shim_host_manager_mac.mm12
-rw-r--r--apps/app_shim/test/app_shim_host_manager_test_api_mac.cc4
-rw-r--r--apps/app_shim/test/app_shim_host_manager_test_api_mac.h6
-rw-r--r--apps/app_shim/unix_domain_socket_acceptor.cc90
-rw-r--r--apps/app_shim/unix_domain_socket_acceptor.h57
9 files changed, 173 insertions, 24 deletions
diff --git a/apps/app_shim/app_shim.gypi b/apps/app_shim/app_shim.gypi
index b08e698..51a729a 100644
--- a/apps/app_shim/app_shim.gypi
+++ b/apps/app_shim/app_shim.gypi
@@ -28,6 +28,8 @@
'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_host_mac.h b/apps/app_shim/app_shim_host_mac.h
index 606ea87..63828f7 100644
--- a/apps/app_shim/app_shim_host_mac.h
+++ b/apps/app_shim/app_shim_host_mac.h
@@ -34,8 +34,8 @@ class AppShimHost : public IPC::Listener,
virtual ~AppShimHost();
// Creates a new server-side IPC channel at |handle|, which should contain a
- // file descriptor of a channel created by an IPC::ChannelFactory, and begins
- // listening for messages on it.
+ // file descriptor of a channel created by an UnixDomainSocketAcceptor,
+ // and begins listening for messages on it.
void ServeChannel(const IPC::ChannelHandle& handle);
protected:
diff --git a/apps/app_shim/app_shim_host_manager_browsertest_mac.mm b/apps/app_shim/app_shim_host_manager_browsertest_mac.mm
index efd2278..3e92cbf 100644
--- a/apps/app_shim/app_shim_host_manager_browsertest_mac.mm
+++ b/apps/app_shim/app_shim_host_manager_browsertest_mac.mm
@@ -205,7 +205,7 @@ 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.factory());
+ EXPECT_TRUE(test_api.acceptor());
}
// Ensure the domain socket can be re-created after a prior browser process has
@@ -214,7 +214,7 @@ IN_PROC_BROWSER_TEST_F(AppShimHostManagerBrowserTest,
ReCreate) {
test::AppShimHostManagerTestApi test_api(
g_browser_process->platform_part()->app_shim_host_manager());
- EXPECT_TRUE(test_api.factory());
+ EXPECT_TRUE(test_api.acceptor());
}
// Tests for the files created by AppShimHostManager.
diff --git a/apps/app_shim/app_shim_host_manager_mac.h b/apps/app_shim/app_shim_host_manager_mac.h
index 0e3a9d2..037c4f2 100644
--- a/apps/app_shim/app_shim_host_manager_mac.h
+++ b/apps/app_shim/app_shim_host_manager_mac.h
@@ -6,9 +6,9 @@
#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"
-#include "ipc/ipc_channel_factory.h"
namespace base {
class FilePath;
@@ -19,11 +19,11 @@ class AppShimHostManagerTestApi;
}
// The AppShimHostManager receives connections from app shims on a UNIX
-// socket (|factory_|) and creates a helper object to manage the connection.
-class AppShimHostManager
- : public IPC::ChannelFactory::Delegate,
- public base::RefCountedThreadSafe<
- AppShimHostManager, content::BrowserThread::DeleteOnUIThread> {
+// 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();
@@ -44,11 +44,11 @@ class AppShimHostManager
friend class test::AppShimHostManagerTestApi;
virtual ~AppShimHostManager();
- // IPC::ChannelFactory::Delegate implementation.
+ // UnixDomainSocketAcceptor::Delegate implementation.
virtual void OnClientConnected(const IPC::ChannelHandle& handle) OVERRIDE;
virtual void OnListenError() OVERRIDE;
- // The |factory_| must be created on a thread which allows blocking I/O, so
+ // 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();
@@ -63,7 +63,7 @@ class AppShimHostManager
base::FilePath directory_in_tmp_;
- scoped_ptr<IPC::ChannelFactory> factory_;
+ scoped_ptr<apps::UnixDomainSocketAcceptor> acceptor_;
apps::ExtensionAppShimHandler extension_app_shim_handler_;
diff --git a/apps/app_shim/app_shim_host_manager_mac.mm b/apps/app_shim/app_shim_host_manager_mac.mm
index 769b166..799d32d 100644
--- a/apps/app_shim/app_shim_host_manager_mac.mm
+++ b/apps/app_shim/app_shim_host_manager_mac.mm
@@ -64,7 +64,7 @@ void AppShimHostManager::Init() {
}
AppShimHostManager::~AppShimHostManager() {
- factory_.reset();
+ acceptor_.reset();
if (!did_init_)
return;
@@ -105,10 +105,10 @@ void AppShimHostManager::InitOnFileThread() {
return;
}
- // IPC::ChannelFactory creates the socket immediately.
+ // UnixDomainSocketAcceptor creates the socket immediately.
base::FilePath socket_path =
directory_in_tmp_.Append(app_mode::kAppShimSocketShortName);
- factory_.reset(new IPC::ChannelFactory(socket_path, this));
+ 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
@@ -125,7 +125,7 @@ void AppShimHostManager::InitOnFileThread() {
void AppShimHostManager::ListenOnIOThread() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- if (!factory_->Listen()) {
+ if (!acceptor_->Listen()) {
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(&AppShimHostManager::OnListenError, this));
@@ -142,7 +142,7 @@ void AppShimHostManager::OnClientConnected(
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 factory
+ // cases where the error could occur are better known, just reset the acceptor
// to allow failure to be communicated via the test API.
- factory_.reset();
+ acceptor_.reset();
}
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
index 67c6544..6fbdd8c 100644
--- 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
@@ -15,8 +15,8 @@ AppShimHostManagerTestApi::AppShimHostManagerTestApi(
DCHECK(host_manager_);
}
-IPC::ChannelFactory* AppShimHostManagerTestApi::factory() {
- return host_manager_->factory_.get();
+apps::UnixDomainSocketAcceptor* AppShimHostManagerTestApi::acceptor() {
+ return host_manager_->acceptor_.get();
}
const base::FilePath& AppShimHostManagerTestApi::directory_in_tmp() {
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
index c6851666..b42e389 100644
--- 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
@@ -13,8 +13,8 @@ namespace base {
class FilePath;
}
-namespace IPC {
-class ChannelFactory;
+namespace apps {
+class UnixDomainSocketAcceptor;
}
namespace test {
@@ -23,7 +23,7 @@ class AppShimHostManagerTestApi {
public:
explicit AppShimHostManagerTestApi(AppShimHostManager* host_manager);
- IPC::ChannelFactory* factory();
+ apps::UnixDomainSocketAcceptor* acceptor();
const base::FilePath& directory_in_tmp();
diff --git a/apps/app_shim/unix_domain_socket_acceptor.cc b/apps/app_shim/unix_domain_socket_acceptor.cc
new file mode 100644
index 0000000..f837a16
--- /dev/null
+++ b/apps/app_shim/unix_domain_socket_acceptor.cc
@@ -0,0 +1,90 @@
+// 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/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
new file mode 100644
index 0000000..64ee306
--- /dev/null
+++ b/apps/app_shim/unix_domain_socket_acceptor.h
@@ -0,0 +1,57 @@
+// 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_