summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsanjeevr@chromium.org <sanjeevr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-07-31 07:57:00 +0000
committersanjeevr@chromium.org <sanjeevr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-07-31 07:57:00 +0000
commit38fe1964640f28c273b2a68a564b7c47a68f8b01 (patch)
tree872c11ad9630842dc2a39b6bbe64877bcd41f0d0
parent6364aad5c4a477197165def0a06f118acd422744 (diff)
downloadchromium_src-38fe1964640f28c273b2a68a564b7c47a68f8b01.zip
chromium_src-38fe1964640f28c273b2a68a564b7c47a68f8b01.tar.gz
chromium_src-38fe1964640f28c273b2a68a564b7c47a68f8b01.tar.bz2
Added an IPC server in the service process to listen to commands. This is not used yet.
BUG=None TEST=None for now since this code is not enabled. Review URL: http://codereview.chromium.org/3041036 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@54440 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/chrome.gyp2
-rw-r--r--chrome/chrome_common.gypi2
-rw-r--r--chrome/common/service_messages.h14
-rw-r--r--chrome/common/service_messages_internal.h43
-rw-r--r--chrome/service/service_ipc_server.cc85
-rw-r--r--chrome/service/service_ipc_server.h56
-rw-r--r--chrome/service/service_main.cc24
-rw-r--r--chrome/service/service_process.cc50
-rw-r--r--chrome/service/service_process.h20
-rw-r--r--ipc/ipc_message_utils.h2
10 files changed, 263 insertions, 35 deletions
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index e9d737cf..89f2882 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -1069,6 +1069,8 @@
'sources': [
'service/service_child_process_host.cc',
'service/service_child_process_host.h',
+ 'service/service_ipc_server.cc',
+ 'service/service_ipc_server.h',
'service/service_main.cc',
'service/service_process.cc',
'service/service_process.h',
diff --git a/chrome/chrome_common.gypi b/chrome/chrome_common.gypi
index 91cb66b..6f0491a 100644
--- a/chrome/chrome_common.gypi
+++ b/chrome/chrome_common.gypi
@@ -257,6 +257,8 @@
'common/resource_dispatcher.h',
'common/security_filter_peer.cc',
'common/security_filter_peer.h',
+ 'common/service_messages.h',
+ 'common/services_messages_internal.h',
'common/socket_stream_dispatcher.cc',
'common/socket_stream_dispatcher.h',
'common/spellcheck_common.cc',
diff --git a/chrome/common/service_messages.h b/chrome/common/service_messages.h
new file mode 100644
index 0000000..d514bff
--- /dev/null
+++ b/chrome/common/service_messages.h
@@ -0,0 +1,14 @@
+// Copyright (c) 2010 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 CHROME_COMMON_SERVICE_MESSAGES_H_
+#define CHROME_COMMON_SERVICE_MESSAGES_H_
+
+#include "ipc/ipc_message_utils.h"
+
+#define MESSAGES_INTERNAL_FILE "chrome/common/service_messages_internal.h"
+#include "ipc/ipc_message_macros.h"
+
+#endif // CHROME_COMMON_SERVICE_MESSAGES_H_
+
diff --git a/chrome/common/service_messages_internal.h b/chrome/common/service_messages_internal.h
new file mode 100644
index 0000000..4968db0
--- /dev/null
+++ b/chrome/common/service_messages_internal.h
@@ -0,0 +1,43 @@
+// Copyright (c) 2010 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 <string>
+
+// This header is meant to be included in multiple passes, hence no traditional
+// header guard.
+// See ipc_message_macros.h for explanation of the macros and passes.
+
+// This file needs to be included again, even though we're actually included
+// from it via utility_messages.h.
+#include "ipc/ipc_message_macros.h"
+
+//------------------------------------------------------------------------------
+// Service process messages:
+// These are messages from the browser to the service process.
+IPC_BEGIN_MESSAGES(Service)
+
+ // Tell the service process to enable the cloud proxy passing in the lsid
+ // of the account to be used.
+ IPC_MESSAGE_CONTROL1(ServiceMsg_EnableCloudPrintProxy,
+ std::string /* lsid */)
+ // Tell the service process to enable the cloud proxy passing in specific
+ // tokens to be used.
+ IPC_MESSAGE_CONTROL2(ServiceMsg_EnableCloudPrintProxyWithTokens,
+ std::string, /* token for cloudprint service */
+ std::string /* token for Google Talk service */)
+ // Tell the service process to disable the cloud proxy.
+ IPC_MESSAGE_CONTROL0(ServiceMsg_DisableCloudPrintProxy)
+
+IPC_END_MESSAGES(Service)
+
+//------------------------------------------------------------------------------
+// Service process host messages:
+// These are messages from the service process to the browser.
+IPC_BEGIN_MESSAGES(ServiceHost)
+
+ // Sent when the cloud print proxy has an authentication error.
+ IPC_MESSAGE_CONTROL0(ServiceHostMsg_CloudPrintProxy_AuthError)
+
+IPC_END_MESSAGES(ServiceHost)
+
diff --git a/chrome/service/service_ipc_server.cc b/chrome/service/service_ipc_server.cc
new file mode 100644
index 0000000..2199d00
--- /dev/null
+++ b/chrome/service/service_ipc_server.cc
@@ -0,0 +1,85 @@
+// Copyright (c) 2009 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 "chrome/service/service_ipc_server.h"
+
+#include "chrome/common/service_messages.h"
+#include "chrome/service/cloud_print/cloud_print_proxy.h"
+#include "chrome/service/service_process.h"
+#include "ipc/ipc_logging.h"
+
+ServiceIPCServer::ServiceIPCServer(const std::string& channel_name)
+ : channel_name_(channel_name) {
+}
+
+bool ServiceIPCServer::Init() {
+ channel_.reset(new IPC::SyncChannel(channel_name_,
+ IPC::Channel::MODE_SERVER, this, NULL,
+ g_service_process->io_thread()->message_loop(), true,
+ g_service_process->shutdown_event()));
+#ifdef IPC_MESSAGE_LOG_ENABLED
+ IPC::Logging::current()->SetIPCSender(this);
+#endif
+
+ sync_message_filter_ =
+ new IPC::SyncMessageFilter(g_service_process->shutdown_event());
+ channel_->AddFilter(sync_message_filter_.get());
+ return true;
+}
+
+ServiceIPCServer::~ServiceIPCServer() {
+#ifdef IPC_MESSAGE_LOG_ENABLED
+ IPC::Logging::current()->SetIPCSender(NULL);
+#endif
+
+ channel_->RemoveFilter(sync_message_filter_.get());
+
+ // The ChannelProxy object caches a pointer to the IPC thread, so need to
+ // reset it as it's not guaranteed to outlive this object.
+ // NOTE: this also has the side-effect of not closing the main IPC channel to
+ // the browser process. This is needed because this is the signal that the
+ // browser uses to know that this process has died, so we need it to be alive
+ // until this process is shut down, and the OS closes the handle
+ // automatically. We used to watch the object handle on Windows to do this,
+ // but it wasn't possible to do so on POSIX.
+ channel_->ClearIPCMessageLoop();
+}
+
+void ServiceIPCServer::OnChannelError() {
+}
+
+bool ServiceIPCServer::Send(IPC::Message* msg) {
+ if (!channel_.get()) {
+ delete msg;
+ return false;
+ }
+
+ return channel_->Send(msg);
+}
+
+void ServiceIPCServer::OnMessageReceived(const IPC::Message& msg) {
+ IPC_BEGIN_MESSAGE_MAP(ServiceIPCServer, msg)
+ IPC_MESSAGE_HANDLER(ServiceMsg_EnableCloudPrintProxy,
+ OnEnableCloudPrintProxy)
+ IPC_MESSAGE_HANDLER(ServiceMsg_EnableCloudPrintProxyWithTokens,
+ OnEnableCloudPrintProxyWithTokens)
+ IPC_MESSAGE_HANDLER(ServiceMsg_DisableCloudPrintProxy,
+ OnDisableCloudPrintProxy)
+ IPC_END_MESSAGE_MAP()
+}
+
+void ServiceIPCServer::OnEnableCloudPrintProxy(const std::string& lsid) {
+ g_service_process->GetCloudPrintProxy()->EnableForUser(lsid);
+}
+
+void ServiceIPCServer::OnEnableCloudPrintProxyWithTokens(
+ const std::string& cloud_print_token, const std::string& talk_token) {
+ // TODO(sanjeevr): Implement this.
+ NOTIMPLEMENTED();
+}
+
+void ServiceIPCServer::OnDisableCloudPrintProxy() {
+ g_service_process->GetCloudPrintProxy()->DisableForUser();
+}
+
diff --git a/chrome/service/service_ipc_server.h b/chrome/service/service_ipc_server.h
new file mode 100644
index 0000000..9e9b355
--- /dev/null
+++ b/chrome/service/service_ipc_server.h
@@ -0,0 +1,56 @@
+// Copyright (c) 2010 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 CHROME_SERVICE_SERVICE_IPC_SERVER_H_
+#define CHROME_SERVICE_SERVICE_IPC_SERVER_H_
+
+#include <string>
+
+#include "base/scoped_ptr.h"
+#include "ipc/ipc_sync_channel.h"
+#include "ipc/ipc_sync_message_filter.h"
+#include "ipc/ipc_message.h"
+
+// This class handles IPC commands for the service process.
+class ServiceIPCServer : public IPC::Channel::Listener,
+ public IPC::Message::Sender {
+ public:
+ explicit ServiceIPCServer(const std::string& channel_name);
+ virtual ~ServiceIPCServer();
+
+ bool Init();
+
+ // IPC::Message::Sender implementation.
+ virtual bool Send(IPC::Message* msg);
+
+ IPC::SyncChannel* channel() { return channel_.get(); }
+
+ // Safe to call on any thread, as long as it's guaranteed that the thread's
+ // lifetime is less than the main thread.
+ IPC::SyncMessageFilter* sync_message_filter() { return sync_message_filter_; }
+
+
+ private:
+ // IPC::Channel::Listener implementation:
+ virtual void OnMessageReceived(const IPC::Message& msg);
+ virtual void OnChannelError();
+
+ // IPC message handlers.
+ void OnEnableCloudPrintProxy(const std::string& lsid);
+ void OnEnableCloudPrintProxyWithTokens(const std::string& cloud_print_token,
+ const std::string& talk_token);
+ void OnDisableCloudPrintProxy();
+
+ std::string channel_name_;
+ scoped_ptr<IPC::SyncChannel> channel_;
+
+ // Allows threads other than the main thread to send sync messages.
+ scoped_refptr<IPC::SyncMessageFilter> sync_message_filter_;
+
+
+ DISALLOW_COPY_AND_ASSIGN(ServiceIPCServer);
+};
+
+#endif // CHROME_SERVICE_SERVICE_IPC_SERVER_H_
+
diff --git a/chrome/service/service_main.cc b/chrome/service/service_main.cc
index 2f09489..e44521e 100644
--- a/chrome/service/service_main.cc
+++ b/chrome/service/service_main.cc
@@ -4,10 +4,8 @@
#include "base/message_loop.h"
#include "base/path_service.h"
-#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
-#include "chrome/common/json_pref_store.h"
#include "chrome/common/main_function_params.h"
#include "chrome/common/sandbox_policy.h"
#include "chrome/service/cloud_print/cloud_print_proxy.h"
@@ -44,29 +42,12 @@ int ServiceProcessMain(const MainFunctionParams& parameters) {
ServiceProcess service_process;
service_process.Initialize();
- // TODO(sanjeevr): The interface to start individual services such as the
- // cloud print proxy needs to change from a command-line interface to an
- // IPC interface. There will be eventually only one service process to handle
- // requests from multiple Chrome browser profiles. The path of the user data
- // directory will be passed in to the command and there will be one instance
- // of services such as the cloud print proxy per requesting profile.
- FilePath user_data_dir;
- PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
- FilePath pref_path = user_data_dir.Append(chrome::kServiceStateFileName);
- scoped_ptr<JsonPrefStore> service_prefs(
- new JsonPrefStore(
- pref_path,
- service_process.file_thread()->message_loop_proxy()));
- service_prefs->ReadPrefs();
-
// Enable Cloud Print if needed.
if (parameters.command_line_.HasSwitch(switches::kEnableCloudPrintProxy)) {
std::string lsid =
parameters.command_line_.GetSwitchValueASCII(
switches::kServiceAccountLsid);
- CloudPrintProxy* cloud_print_proxy =
- service_process.CreateCloudPrintProxy(service_prefs.get());
- cloud_print_proxy->EnableForUser(lsid);
+ service_process.GetCloudPrintProxy()->EnableForUser(lsid);
}
#if defined(ENABLE_REMOTING)
@@ -74,6 +55,8 @@ int ServiceProcessMain(const MainFunctionParams& parameters) {
// TODO(hclam): Merge this config file with Cloud Printing.
// TODO(hclam): There is only start but not stop of the chromoting host
// process.
+ FilePath user_data_dir;
+ PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
FilePath chromoting_config_path =
user_data_dir.Append(FILE_PATH_LITERAL(".ChromotingConfig.json"));
scoped_refptr<remoting::JsonHostConfig> chromoting_config;
@@ -107,7 +90,6 @@ int ServiceProcessMain(const MainFunctionParams& parameters) {
#endif
MessageLoop::current()->Run();
- service_prefs->WritePrefs();
service_process.Teardown();
return 0;
diff --git a/chrome/service/service_process.cc b/chrome/service/service_process.cc
index 33d2dfe..60229d6 100644
--- a/chrome/service/service_process.cc
+++ b/chrome/service/service_process.cc
@@ -4,8 +4,15 @@
#include "chrome/service/service_process.h"
-#include "base/stl_util-inl.h"
+#include <algorithm>
+
+#include "base/path_service.h"
+#include "base/utf_string_conversions.h"
+#include "chrome/common/chrome_constants.h"
+#include "chrome/common/chrome_paths.h"
+#include "chrome/common/json_pref_store.h"
#include "chrome/service/cloud_print/cloud_print_proxy.h"
+#include "chrome/service/service_ipc_server.h"
#include "net/base/network_change_notifier.h"
#if defined(ENABLE_REMOTING)
@@ -28,7 +35,7 @@
ServiceProcess* g_service_process = NULL;
-ServiceProcess::ServiceProcess() {
+ServiceProcess::ServiceProcess() : shutdown_event_(true, false) {
DCHECK(!g_service_process);
g_service_process = this;
}
@@ -45,25 +52,49 @@ bool ServiceProcess::Initialize() {
Teardown();
return false;
}
+ FilePath user_data_dir;
+ PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
+ FilePath pref_path = user_data_dir.Append(chrome::kServiceStateFileName);
+ service_prefs_.reset(new JsonPrefStore(pref_path,
+ file_thread_->message_loop_proxy()));
+ service_prefs_->ReadPrefs();
+ // TODO(sanjeevr): We need to actually figure out the right way to determine
+ // a channel name. The below is to facilitate testing only.
+#if defined(OS_WIN)
+ std::string channel_name = WideToUTF8(user_data_dir.value());
+#elif defined(OS_POSIX)
+ std::string channel_name = user_data_dir.value();
+#endif // defined(OS_WIN)
+
+ std::replace(channel_name.begin(), channel_name.end(), '\\', '!');
+ channel_name.append("_service_ipc");
+ ipc_server_.reset(new ServiceIPCServer(channel_name));
+ ipc_server_->Init();
return true;
}
bool ServiceProcess::Teardown() {
+ service_prefs_->WritePrefs();
+ service_prefs_.reset();
+ cloud_print_proxy_.reset();
+ ipc_server_.reset();
+ // Signal this event before shutting down the service process. That way all
+ // background threads can cleanup.
+ shutdown_event_.Signal();
io_thread_.reset();
file_thread_.reset();
- STLDeleteElements(&cloud_print_proxy_list_);
// The NetworkChangeNotifier must be destroyed after all other threads that
// might use it have been shut down.
network_change_notifier_.reset();
return true;
}
-CloudPrintProxy* ServiceProcess::CreateCloudPrintProxy(
- JsonPrefStore* service_prefs) {
- CloudPrintProxy* cloud_print_proxy = new CloudPrintProxy();
- cloud_print_proxy->Initialize(service_prefs);
- cloud_print_proxy_list_.push_back(cloud_print_proxy);
- return cloud_print_proxy;
+CloudPrintProxy* ServiceProcess::GetCloudPrintProxy() {
+ if (!cloud_print_proxy_.get()) {
+ cloud_print_proxy_.reset(new CloudPrintProxy());
+ cloud_print_proxy_->Initialize(service_prefs_.get());
+ }
+ return cloud_print_proxy_.get();
}
#if defined(ENABLE_REMOTING)
@@ -94,6 +125,5 @@ remoting::ChromotingHost* ServiceProcess::CreateChromotingHost(
ServiceProcess::~ServiceProcess() {
Teardown();
- DCHECK(cloud_print_proxy_list_.size() == 0);
g_service_process = NULL;
}
diff --git a/chrome/service/service_process.h b/chrome/service/service_process.h
index cf86736..ce476c6 100644
--- a/chrome/service/service_process.h
+++ b/chrome/service/service_process.h
@@ -6,14 +6,14 @@
#define CHROME_SERVICE_SERVICE_PROCESS_H_
#pragma once
-#include <vector>
-
#include "base/ref_counted.h"
#include "base/scoped_ptr.h"
#include "base/thread.h"
+#include "base/waitable_event.h"
class CloudPrintProxy;
class JsonPrefStore;
+class ServiceIPCServer;
namespace net {
class NetworkChangeNotifier;
}
@@ -55,7 +55,15 @@ class ServiceProcess {
base::Thread* file_thread() const {
return file_thread_.get();
}
- CloudPrintProxy* CreateCloudPrintProxy(JsonPrefStore* service_prefs);
+
+ // A global event object that is signalled when the main thread's message
+ // loop exits. This gives background threads a way to observe the main
+ // thread shutting down.
+ base::WaitableEvent* shutdown_event() {
+ return &shutdown_event_;
+ }
+
+ CloudPrintProxy* GetCloudPrintProxy();
#if defined(ENABLE_REMOTING)
remoting::ChromotingHost* CreateChromotingHost(
remoting::ChromotingHostContext* context,
@@ -66,7 +74,11 @@ class ServiceProcess {
scoped_ptr<net::NetworkChangeNotifier> network_change_notifier_;
scoped_ptr<base::Thread> io_thread_;
scoped_ptr<base::Thread> file_thread_;
- std::vector<CloudPrintProxy*> cloud_print_proxy_list_;
+ scoped_ptr<CloudPrintProxy> cloud_print_proxy_;
+ scoped_ptr<JsonPrefStore> service_prefs_;
+ scoped_ptr<ServiceIPCServer> ipc_server_;
+ // An event that will be signalled when we shutdown.
+ base::WaitableEvent shutdown_event_;
DISALLOW_COPY_AND_ASSIGN(ServiceProcess);
};
diff --git a/ipc/ipc_message_utils.h b/ipc/ipc_message_utils.h
index 1aab1b3..0da59c4 100644
--- a/ipc/ipc_message_utils.h
+++ b/ipc/ipc_message_utils.h
@@ -58,6 +58,8 @@ enum IPCMessageStart {
GpuMsgStart,
GpuHostMsgStart,
GpuChannelMsgStart,
+ ServiceMsgStart,
+ ServiceHostMsgStart,
// NOTE: When you add a new message class, also update
// IPCStatusView::IPCStatusView to ensure logging works.
LastMsgIndex