diff options
author | sanjeevr@chromium.org <sanjeevr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-31 07:57:00 +0000 |
---|---|---|
committer | sanjeevr@chromium.org <sanjeevr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-31 07:57:00 +0000 |
commit | 38fe1964640f28c273b2a68a564b7c47a68f8b01 (patch) | |
tree | 872c11ad9630842dc2a39b6bbe64877bcd41f0d0 | |
parent | 6364aad5c4a477197165def0a06f118acd422744 (diff) | |
download | chromium_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.gyp | 2 | ||||
-rw-r--r-- | chrome/chrome_common.gypi | 2 | ||||
-rw-r--r-- | chrome/common/service_messages.h | 14 | ||||
-rw-r--r-- | chrome/common/service_messages_internal.h | 43 | ||||
-rw-r--r-- | chrome/service/service_ipc_server.cc | 85 | ||||
-rw-r--r-- | chrome/service/service_ipc_server.h | 56 | ||||
-rw-r--r-- | chrome/service/service_main.cc | 24 | ||||
-rw-r--r-- | chrome/service/service_process.cc | 50 | ||||
-rw-r--r-- | chrome/service/service_process.h | 20 | ||||
-rw-r--r-- | ipc/ipc_message_utils.h | 2 |
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 |