summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorsanjeevr@chromium.org <sanjeevr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-12 19:25:07 +0000
committersanjeevr@chromium.org <sanjeevr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-12 19:25:07 +0000
commit1d0ee423b6a0bb307c7c19fe28c95d8761691e9a (patch)
tree5766edd6b8b8a7b2eb3942e75008388a0ecfeff0 /chrome
parentb90b874fe7023537531fbd08df403694e3e3a520 (diff)
downloadchromium_src-1d0ee423b6a0bb307c7c19fe28c95d8761691e9a.zip
chromium_src-1d0ee423b6a0bb307c7c19fe28c95d8761691e9a.tar.gz
chromium_src-1d0ee423b6a0bb307c7c19fe28c95d8761691e9a.tar.bz2
Created a new process type called the service process to host background tasks such as the Cloud Print Proxy.
BUG=None. TEST=None. Review URL: http://codereview.chromium.org/2001009 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@47055 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/app/chrome_dll_main.cc16
-rw-r--r--chrome/app/dummy_main_functions.cc4
-rw-r--r--chrome/chrome.gyp30
-rw-r--r--chrome/common/chrome_switches.cc16
-rw-r--r--chrome/common/chrome_switches.h4
-rw-r--r--chrome/common/sandbox_init_wrapper_mac.cc3
-rw-r--r--chrome/service/cloud_print/cloud_print_proxy.cc32
-rw-r--r--chrome/service/cloud_print/cloud_print_proxy.h43
-rw-r--r--chrome/service/gaia/service_gaia_authenticator.cc86
-rw-r--r--chrome/service/gaia/service_gaia_authenticator.h57
-rw-r--r--chrome/service/net/service_url_request_context.cc55
-rw-r--r--chrome/service/net/service_url_request_context.h78
-rw-r--r--chrome/service/service_main.cc34
-rw-r--r--chrome/service/service_process.cc48
-rw-r--r--chrome/service/service_process.h57
15 files changed, 560 insertions, 3 deletions
diff --git a/chrome/app/chrome_dll_main.cc b/chrome/app/chrome_dll_main.cc
index c1077ac..ba4b481 100644
--- a/chrome/app/chrome_dll_main.cc
+++ b/chrome/app/chrome_dll_main.cc
@@ -103,6 +103,7 @@ extern int ZygoteMain(const MainFunctionParams&);
#if defined(_WIN64)
extern int NaClBrokerMain(const MainFunctionParams&);
#endif
+extern int ServiceProcessMain(const MainFunctionParams&);
#if defined(OS_WIN)
// TODO(erikkay): isn't this already defined somewhere?
@@ -263,7 +264,8 @@ static void AdjustLinuxOOMScore(const std::string& process_type) {
score = kPluginScore;
} else if (process_type == switches::kUtilityProcess ||
process_type == switches::kWorkerProcess ||
- process_type == switches::kGpuProcess) {
+ process_type == switches::kGpuProcess ||
+ process_type == switches::kServiceProcess) {
score = kMiscScore;
} else if (process_type == switches::kProfileImportProcess) {
NOTIMPLEMENTED();
@@ -367,6 +369,14 @@ bool SubprocessNeedsResourceBundle(const std::string& process_type) {
process_type == switches::kUtilityProcess;
}
+// Returns true if this process is a child of the browser process.
+bool SubprocessIsBrowserChild(const std::string& process_type) {
+ if (process_type.empty() || process_type == switches::kServiceProcess) {
+ return false;
+ }
+ return true;
+}
+
#if defined(OS_MACOSX)
// Update the name shown in Activity Monitor so users are less likely to ask
// why Chrome has so many processes.
@@ -513,7 +523,7 @@ int ChromeMain(int argc, char** argv) {
base::ProcessId browser_pid;
if (process_type.empty()) {
browser_pid = base::GetCurrentProcId();
- } else {
+ } else if (SubprocessIsBrowserChild(process_type)) {
#if defined(OS_WIN)
std::wstring channel_name =
parsed_command_line.GetSwitchValue(switches::kProcessChannelID);
@@ -780,6 +790,8 @@ int ChromeMain(int argc, char** argv) {
#else
NOTIMPLEMENTED();
#endif
+ } else if (process_type == switches::kServiceProcess) {
+ rv = ServiceProcessMain(main_params);
} else if (process_type.empty()) {
#if defined(OS_LINUX)
const char* sandbox_binary = NULL;
diff --git a/chrome/app/dummy_main_functions.cc b/chrome/app/dummy_main_functions.cc
index c8b7c5e..a6e325e 100644
--- a/chrome/app/dummy_main_functions.cc
+++ b/chrome/app/dummy_main_functions.cc
@@ -42,3 +42,7 @@ int DiagnosticsMain(const CommandLine& command_line) {
int GpuMain(const MainFunctionParams&) {
return ResultCodes::BAD_PROCESS_TYPE;
}
+
+int ServiceProcessMain(const MainFunctionParams& parameters) {
+ return ResultCodes::BAD_PROCESS_TYPE;
+}
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 6283e37..1684e2d 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -30,6 +30,7 @@
'utility',
'profile_import',
'worker',
+ 'service',
'../printing/printing.gyp:printing',
'../webkit/webkit.gyp:inspector_resources',
],
@@ -973,6 +974,35 @@
}],
],
},
+ {
+ 'target_name': 'service',
+ 'type': '<(library)',
+ 'msvs_guid': '2DA87614-55C5-4E56-A17E-0CD099786197',
+ 'dependencies': [
+ '../base/base.gyp:base',
+ ],
+ 'sources': [
+ 'service/service_main.cc',
+ 'service/service_process.cc',
+ 'service/service_process.h',
+ 'service/cloud_print/cloud_print_proxy.cc',
+ 'service/cloud_print/cloud_print_proxy.h',
+ 'service/gaia/service_gaia_authenticator.cc',
+ 'service/gaia/service_gaia_authenticator.h',
+ 'service/net/service_url_request_context.cc',
+ 'service/net/service_url_request_context.h',
+ ],
+ 'include_dirs': [
+ '..',
+ ],
+ 'conditions': [
+ ['OS=="linux"', {
+ 'dependencies': [
+ '../build/linux/system.gyp:gtk',
+ ],
+ }],
+ ],
+ },
],
'conditions': [
['OS=="mac"',
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index 3cc7620..0e488c3 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -75,6 +75,9 @@ const char kBrowserSubprocessPath[] = "browser-subprocess-path";
// as a dependent process of the Chrome Frame plugin.
const char kChromeFrame[] = "chrome-frame";
+// The unique id to be used for this cloud print proxy instance.
+const char kCloudPrintProxyId[] = "cloud-print-proxy-id";
+
// The Country we should use. This is normally obtained from the operating
// system during first run and cached in the preferences afterwards. This is a
// string value, the 2 letter code from ISO 3166-1.
@@ -250,6 +253,13 @@ const char kEnableAuthNegotiatePort[] = "enable-auth-negotiate-port";
// Enables the benchmarking extensions.
const char kEnableBenchmarking[] = "enable-benchmarking";
+// This applies only when the process type is "service". Enables the
+// Cloud Print Proxy component within the service process.
+const char kEnableCloudPrintProxy[] = "enable-cloud-print-proxy";
+
+// Enables the Cloud Print dialog hosting code.
+const char kEnableCloudPrint[] = "enable-cloud-print";
+
// Enables extension APIs that are in development.
const char kEnableExperimentalExtensionApis[] =
"enable-experimental-extension-apis";
@@ -680,6 +690,12 @@ const char kSdchFilter[] = "enable-sdch";
// from the omnibox.
const char kSearchInOmniboxHint[] = "search-in-omnibox-hint";
+// Causes the process to run as a service process.
+const char kServiceProcess[] = "service";
+
+// The LSID of the account to use for the service process.
+const char kServiceAccountLsid[] = "service-account-lsid";
+
// See kHideIcons.
const char kShowIcons[] = "show-icons";
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index e4fda04..a52b316 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -37,6 +37,7 @@ extern const char kBrowserAssertTest[];
extern const char kBrowserCrashTest[];
extern const char kBrowserSubprocessPath[];
extern const char kChromeFrame[];
+extern const char kCloudPrintProxyId[];
extern const char kCountry[];
extern const char kDebugPrint[];
extern const char kDiagnostics[];
@@ -86,6 +87,7 @@ extern const char kDumpHistogramsOnExit[];
extern const char kEnableAeroPeekTabs[];
extern const char kEnableAuthNegotiatePort[];
extern const char kEnableBenchmarking[];
+extern const char kEnableCloudPrintProxy[];
extern const char kEnableExperimentalExtensionApis[];
extern const char kEnableExperimentalWebGL[];
extern const char kEnableExtensionApps[];
@@ -192,6 +194,8 @@ extern const char kRestoreLastSession[];
extern const char kSafePlugins[];
extern const char kSdchFilter[];
extern const char kSearchInOmniboxHint[];
+extern const char kServiceProcess[];
+extern const char kServiceAccountLsid[];
extern const char kShowCompositedLayerBorders[];
extern const char kShowIcons[];
extern const char kShowPaintRects[];
diff --git a/chrome/common/sandbox_init_wrapper_mac.cc b/chrome/common/sandbox_init_wrapper_mac.cc
index 17acce8..998fe64 100644
--- a/chrome/common/sandbox_init_wrapper_mac.cc
+++ b/chrome/common/sandbox_init_wrapper_mac.cc
@@ -59,7 +59,8 @@ bool SandboxInitWrapper::InitializeSandbox(const CommandLine& command_line,
sandbox_process_type = sandbox::SANDBOX_TYPE_NACL_LOADER;
} else if ((process_type == switches::kPluginProcess) ||
(process_type == switches::kProfileImportProcess) ||
- (process_type == switches::kGpuProcess)) {
+ (process_type == switches::kGpuProcess) ||
+ (process_type == switches::kServiceProcess)) {
return true;
} else {
// Failsafe: If you hit an unreached here, is your new process type in need
diff --git a/chrome/service/cloud_print/cloud_print_proxy.cc b/chrome/service/cloud_print/cloud_print_proxy.cc
new file mode 100644
index 0000000..ea6139b
--- /dev/null
+++ b/chrome/service/cloud_print/cloud_print_proxy.cc
@@ -0,0 +1,32 @@
+// 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 "chrome/service/cloud_print/cloud_print_proxy.h"
+
+CloudPrintProxy::CloudPrintProxy() {
+}
+
+CloudPrintProxy::~CloudPrintProxy() {
+ Shutdown();
+}
+
+void CloudPrintProxy::Initialize() {
+}
+
+
+void CloudPrintProxy::EnableForUser(const std::string& lsid,
+ const std::string& proxy_id) {
+}
+
+void CloudPrintProxy::DisableForUser() {
+ Shutdown();
+}
+
+void CloudPrintProxy::HandlePrinterNotification(
+ const std::string& printer_id) {
+}
+
+void CloudPrintProxy::Shutdown() {
+}
+
diff --git a/chrome/service/cloud_print/cloud_print_proxy.h b/chrome/service/cloud_print/cloud_print_proxy.h
new file mode 100644
index 0000000..0f67d7f
--- /dev/null
+++ b/chrome/service/cloud_print/cloud_print_proxy.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.
+
+#ifndef CHROME_SERVICE_CLOUD_PRINT_CLOUD_PRINT_PROXY_H_
+#define CHROME_SERVICE_CLOUD_PRINT_CLOUD_PRINT_PROXY_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/scoped_ptr.h"
+
+// TODO(sanjeevr): Integrate this with the CloudPrintProxyBackend. This needs to
+// happen after the cloud_print related files are moved to chrome/service.
+
+// CloudPrintProxy is the layer between the service process UI thread
+// and the cloud print proxy backend.
+class CloudPrintProxy {
+ public:
+ explicit CloudPrintProxy();
+ virtual ~CloudPrintProxy();
+
+ // Initializes the object. This should be called every time an object of this
+ // class is constructed.
+ void Initialize();
+
+ // Enables/disables cloud printing for the user
+ virtual void EnableForUser(const std::string& lsid,
+ const std::string& proxy_id);
+ virtual void DisableForUser();
+
+ // Notification received from the server for a particular printer.
+ // We need to inform the backend to look for jobs for this printer.
+ void HandlePrinterNotification(const std::string& printer_id);
+
+ protected:
+ void Shutdown();
+
+ DISALLOW_COPY_AND_ASSIGN(CloudPrintProxy);
+};
+
+#endif // CHROME_SERVICE_CLOUD_PRINT_CLOUD_PRINT_PROXY_H_
+
diff --git a/chrome/service/gaia/service_gaia_authenticator.cc b/chrome/service/gaia/service_gaia_authenticator.cc
new file mode 100644
index 0000000..55dfff2
--- /dev/null
+++ b/chrome/service/gaia/service_gaia_authenticator.cc
@@ -0,0 +1,86 @@
+// 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 "chrome/service/gaia/service_gaia_authenticator.h"
+
+#include "base/message_loop_proxy.h"
+#include "chrome/service/net/service_url_request_context.h"
+#include "googleurl/src/gurl.h"
+
+ServiceGaiaAuthenticator::ServiceGaiaAuthenticator(
+ const std::string& user_agent, const std::string& service_id,
+ const std::string& gaia_url,
+ base::MessageLoopProxy* io_message_loop_proxy)
+ : gaia::GaiaAuthenticator(user_agent, service_id, gaia_url),
+ http_post_completed_(false, false),
+ io_message_loop_proxy_(io_message_loop_proxy),
+ http_response_code_(0) {
+}
+
+ServiceGaiaAuthenticator::~ServiceGaiaAuthenticator() {
+}
+
+bool ServiceGaiaAuthenticator::Post(const GURL& url,
+ const std::string& post_body,
+ unsigned long* response_code,
+ std::string* response_body) {
+ DCHECK(url.SchemeIsSecure());
+ DCHECK(io_message_loop_proxy_);
+ io_message_loop_proxy_->PostTask(
+ FROM_HERE,
+ NewRunnableMethod(this, &ServiceGaiaAuthenticator::DoPost, url,
+ post_body));
+ if (!http_post_completed_.Wait()) // Block until network request completes.
+ NOTREACHED(); // See OnURLFetchComplete.
+
+ *response_code = static_cast<int>(http_response_code_);
+ *response_body = response_data_;
+ return true;
+}
+
+// TODO(sanjeevr): This is a placeholder implementation. Need to move this logic
+// to a common location within the service process so that it can be resued by
+// other classes needing a backoff delay calculation.
+int ServiceGaiaAuthenticator::GetBackoffDelaySeconds(
+ int current_backoff_delay) {
+ const int kMaxBackoffDelaySeconds = 60 * 60; // (1 hour)
+ int ret = 0;
+ if (0 == current_backoff_delay) {
+ ret = 1;
+ } else {
+ ret = current_backoff_delay * 2;
+ }
+ if (ret > kMaxBackoffDelaySeconds) {
+ ret = kMaxBackoffDelaySeconds;
+ }
+ return ret;
+}
+
+void ServiceGaiaAuthenticator::DoPost(const GURL& post_url,
+ const std::string& post_body) {
+ DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
+ request_.reset(new URLFetcher(post_url, URLFetcher::POST, this));
+ ServiceURLRequestContextGetter* context_getter =
+ new ServiceURLRequestContextGetter();
+ request_->set_request_context(context_getter);
+ request_->set_upload_data("application/x-www-form-urlencoded", post_body);
+ request_->Start();
+}
+
+// URLFetcher::Delegate implementation
+void ServiceGaiaAuthenticator::OnURLFetchComplete(
+ const URLFetcher *source, const GURL &url, const URLRequestStatus &status,
+ int response_code, const ResponseCookies &cookies,
+ const std::string &data) {
+ DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
+ http_response_code_ = response_code;
+ response_data_ = data;
+ // Add an extra reference because we want http_post_completed_ to remain
+ // valid until after Signal() returns.
+ scoped_refptr<ServiceGaiaAuthenticator> keep_alive(this);
+ // Wake the blocked thread in Post.
+ http_post_completed_.Signal();
+ // WARNING: DONT DO ANYTHING AFTER THIS CALL! |this| may be deleted!
+}
+
diff --git a/chrome/service/gaia/service_gaia_authenticator.h b/chrome/service/gaia/service_gaia_authenticator.h
new file mode 100644
index 0000000..aedc302
--- /dev/null
+++ b/chrome/service/gaia/service_gaia_authenticator.h
@@ -0,0 +1,57 @@
+// 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_GAIA_SERVICE_GAIA_AUTHENTICATOR_H_
+#define CHROME_SERVICE_GAIA_SERVICE_GAIA_AUTHENTICATOR_H_
+
+#include <string>
+
+#include "base/ref_counted.h"
+#include "base/waitable_event.h"
+#include "chrome/common/net/url_fetcher.h"
+#include "chrome/common/net/gaia/gaia_authenticator.h"
+
+namespace base {
+class MessageLoopProxy;
+}
+
+// A GaiaAuthenticator implementation to be used in the service process (where
+// we cannot rely on the existence of a Profile)
+class ServiceGaiaAuthenticator
+ : public base::RefCountedThreadSafe<ServiceGaiaAuthenticator>,
+ public URLFetcher::Delegate,
+ public gaia::GaiaAuthenticator {
+ public:
+ ServiceGaiaAuthenticator(const std::string& user_agent,
+ const std::string& service_id,
+ const std::string& gaia_url,
+ base::MessageLoopProxy* io_message_loop_proxy);
+ ~ServiceGaiaAuthenticator();
+
+ // URLFetcher::Delegate implementation.
+ void OnURLFetchComplete(const URLFetcher *source, const GURL &url,
+ const URLRequestStatus &status, int response_code,
+ const ResponseCookies &cookies,
+ const std::string &data);
+
+ protected:
+ // GaiaAuthenticator overrides.
+ virtual bool Post(const GURL& url, const std::string& post_body,
+ unsigned long* response_code, std::string* response_body);
+ virtual int GetBackoffDelaySeconds(int current_backoff_delay);
+
+ private:
+ void DoPost(const GURL& post_url, const std::string& post_body);
+
+ base::WaitableEvent http_post_completed_;
+ scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_;
+ int http_response_code_;
+ std::string response_data_;
+ scoped_ptr<URLFetcher> request_;
+
+ DISALLOW_COPY_AND_ASSIGN(ServiceGaiaAuthenticator);
+};
+
+#endif // CHROME_SERVICE_GAIA_SERVICE_GAIA_AUTHENTICATOR_H_
+
diff --git a/chrome/service/net/service_url_request_context.cc b/chrome/service/net/service_url_request_context.cc
new file mode 100644
index 0000000..ab5e61a
--- /dev/null
+++ b/chrome/service/net/service_url_request_context.cc
@@ -0,0 +1,55 @@
+// 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 "chrome/service/net/service_url_request_context.h"
+
+#include "chrome/service/service_process.h"
+#include "net/base/cookie_monster.h"
+#include "net/base/cookie_policy.h"
+#include "net/base/host_resolver.h"
+#include "net/base/ssl_config_service_defaults.h"
+#include "net/ftp/ftp_network_layer.h"
+#include "net/http/http_auth_handler_factory.h"
+#include "net/http/http_cache.h"
+#include "net/http/http_network_layer.h"
+#include "net/proxy/proxy_service.h"
+
+ServiceURLRequestContextGetter::ServiceURLRequestContextGetter()
+ : io_message_loop_proxy_(
+ g_service_process->io_thread()->message_loop_proxy()) {
+}
+
+ServiceURLRequestContext::ServiceURLRequestContext() {
+ host_resolver_ = net::CreateSystemHostResolver(NULL);
+ DCHECK(g_service_process);
+ // TODO(sanjeevr): Change CreateSystemProxyConfigService to accept a
+ // MessageLoopProxy* instead of MessageLoop*.
+ // Also this needs to be created on the UI thread on Linux. Fix this.
+ net::ProxyConfigService * proxy_config_service =
+ net::ProxyService::CreateSystemProxyConfigService(
+ g_service_process->io_thread()->message_loop(),
+ g_service_process->file_thread()->message_loop());
+ proxy_service_ = net::ProxyService::Create(proxy_config_service, false, this,
+ NULL, NULL, NULL);
+ ftp_transaction_factory_ = new net::FtpNetworkLayer(host_resolver_);
+ ssl_config_service_ = new net::SSLConfigServiceDefaults;
+ http_auth_handler_factory_ = net::HttpAuthHandlerFactory::CreateDefault();
+ http_transaction_factory_ = new net::HttpCache(
+ net::HttpNetworkLayer::CreateFactory(NULL, host_resolver_,
+ proxy_service_,
+ ssl_config_service_,
+ http_auth_handler_factory_),
+ disk_cache::CreateInMemoryCacheBackend(0));
+ // In-memory cookie store.
+ cookie_store_ = new net::CookieMonster(NULL, NULL);
+ accept_language_ = "en-us,fr";
+ accept_charset_ = "iso-8859-1,*,utf-8";
+}
+
+ServiceURLRequestContext::~ServiceURLRequestContext() {
+ delete ftp_transaction_factory_;
+ delete http_transaction_factory_;
+ delete http_auth_handler_factory_;
+}
+
diff --git a/chrome/service/net/service_url_request_context.h b/chrome/service/net/service_url_request_context.h
new file mode 100644
index 0000000..90c9733
--- /dev/null
+++ b/chrome/service/net/service_url_request_context.h
@@ -0,0 +1,78 @@
+// 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_NET_SERVICE_URL_REQUEST_CONTEXT_H_
+#define CHROME_SERVICE_NET_SERVICE_URL_REQUEST_CONTEXT_H_
+
+#include <string>
+
+#include "base/message_loop_proxy.h"
+#include "chrome/common/net/url_request_context_getter.h"
+#include "net/base/cookie_monster.h"
+#include "net/base/cookie_policy.h"
+#include "net/base/host_resolver.h"
+#include "net/base/ssl_config_service_defaults.h"
+#include "net/disk_cache/disk_cache.h"
+#include "net/ftp/ftp_network_layer.h"
+#include "net/http/http_auth_handler_factory.h"
+#include "net/http/http_cache.h"
+#include "net/http/http_network_layer.h"
+#include "net/proxy/proxy_service.h"
+#include "net/url_request/url_request_context.h"
+
+// Subclass of URLRequestContext which can be used to store extra information
+// for requests. This subclass is meant to be used in the service process where
+// the profile is not available.
+//
+class ServiceURLRequestContext : public URLRequestContext {
+ public:
+ ServiceURLRequestContext();
+ void set_cookie_policy(net::CookiePolicy* policy) {
+ cookie_policy_ = policy;
+ }
+ void set_user_agent(const std::string& ua) {
+ user_agent_ = ua;
+ }
+
+ // URLRequestContext overrides
+ virtual const std::string& GetUserAgent(const GURL& url) const {
+ // If the user agent is set explicitly return that, otherwise call the
+ // base class method to return default value.
+ return user_agent_.empty() ?
+ URLRequestContext::GetUserAgent(url) : user_agent_;
+ }
+
+ protected:
+ virtual ~ServiceURLRequestContext();
+
+ private:
+ std::string user_agent_;
+};
+
+class ServiceURLRequestContextGetter : public URLRequestContextGetter {
+ public:
+ ServiceURLRequestContextGetter();
+
+ virtual URLRequestContext* GetURLRequestContext() {
+ if (!url_request_context_)
+ url_request_context_ = new ServiceURLRequestContext();
+ return url_request_context_;
+ }
+ virtual scoped_refptr<base::MessageLoopProxy> GetIOMessageLoopProxy() {
+ return io_message_loop_proxy_;
+ }
+
+ void set_user_agent(const std::string& ua) {
+ user_agent_ = ua;
+ }
+ private:
+ ~ServiceURLRequestContextGetter() {}
+
+ std::string user_agent_;
+ scoped_refptr<URLRequestContext> url_request_context_;
+ scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_;
+};
+
+#endif // CHROME_SERVICE_NET_SERVICE_URL_REQUEST_CONTEXT_H_
+
diff --git a/chrome/service/service_main.cc b/chrome/service/service_main.cc
new file mode 100644
index 0000000..44ca8eb
--- /dev/null
+++ b/chrome/service/service_main.cc
@@ -0,0 +1,34 @@
+// 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 "base/message_loop.h"
+#include "chrome/common/chrome_constants.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/common/main_function_params.h"
+#include "chrome/service/cloud_print/cloud_print_proxy.h"
+#include "chrome/service/service_process.h"
+
+// Mainline routine for running as the service process.
+int ServiceProcessMain(const MainFunctionParams& parameters) {
+ MessageLoopForUI main_message_loop;
+ std::wstring app_name = chrome::kBrowserAppName;
+ PlatformThread::SetName(WideToASCII(app_name + L"_ServiceMain").c_str());
+
+ ServiceProcess service_process;
+ service_process.Initialize();
+ if (parameters.command_line_.HasSwitch(switches::kEnableCloudPrintProxy)) {
+ std::string lsid =
+ parameters.command_line_.GetSwitchValueASCII(
+ switches::kServiceAccountLsid);
+ std::string proxy_id =
+ parameters.command_line_.GetSwitchValueASCII(
+ switches::kCloudPrintProxyId);
+ service_process.cloud_print_proxy()->EnableForUser(lsid, proxy_id);
+ }
+ MessageLoop::current()->Run();
+ service_process.Teardown();
+
+ return 0;
+}
+
diff --git a/chrome/service/service_process.cc b/chrome/service/service_process.cc
new file mode 100644
index 0000000..41bfe8d
--- /dev/null
+++ b/chrome/service/service_process.cc
@@ -0,0 +1,48 @@
+// 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 "chrome/service/service_process.h"
+
+#include "chrome/service/cloud_print/cloud_print_proxy.h"
+
+ServiceProcess* g_service_process = NULL;
+
+ServiceProcess::ServiceProcess() {
+ DCHECK(!g_service_process);
+ g_service_process = this;
+}
+
+bool ServiceProcess::Initialize() {
+ base::Thread::Options options;
+ options.message_loop_type = MessageLoop::TYPE_IO;
+ io_thread_.reset(new base::Thread("ServiceProcess_IO"));
+ file_thread_.reset(new base::Thread("ServiceProcess_File"));
+ if (!io_thread_->StartWithOptions(options) ||
+ !file_thread_->StartWithOptions(options)) {
+ NOTREACHED();
+ Teardown();
+ return false;
+ }
+ return true;
+}
+
+bool ServiceProcess::Teardown() {
+ io_thread_.reset();
+ file_thread_.reset();
+ return true;
+}
+
+CloudPrintProxy* ServiceProcess::cloud_print_proxy() {
+ if (!cloud_print_proxy_.get()) {
+ cloud_print_proxy_.reset(new CloudPrintProxy());
+ cloud_print_proxy_->Initialize();
+ }
+ return cloud_print_proxy_.get();
+}
+
+ServiceProcess::~ServiceProcess() {
+ Teardown();
+ g_service_process = NULL;
+}
+
diff --git a/chrome/service/service_process.h b/chrome/service/service_process.h
new file mode 100644
index 0000000..9d980dd
--- /dev/null
+++ b/chrome/service/service_process.h
@@ -0,0 +1,57 @@
+// 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_PROCESS_H_
+#define CHROME_SERVICE_SERVICE_PROCESS_H_
+
+
+#include "base/thread.h"
+
+class CloudPrintProxy;
+
+// The ServiceProcess does not inherit from ChildProcess because this
+// process can live independently of the browser process.
+class ServiceProcess {
+ public:
+ ServiceProcess();
+ ~ServiceProcess();
+
+ bool Initialize();
+ bool Teardown();
+ // TODO(sanjeevr): Change various parts of the code such as
+ // net::ProxyService::CreateSystemProxyConfigService to take in
+ // MessageLoopProxy* instead of MessageLoop*. When we have done that, we can
+ // remove the io_thread() and file_thread() accessors and replace them with
+ // io_message_loop_proxy() and file_message_loop_proxy() respectively.
+
+ // Returns the thread that we perform I/O coordination on (network requests,
+ // communication with renderers, etc.
+ // NOTE: You should ONLY use this to pass to IPC or other objects which must
+ // need a MessageLoop*. If you just want to post a task, use the thread's
+ // message_loop_proxy() as it takes care of checking that a thread is still
+ // alive, race conditions, lifetime differences etc.
+ // If you still must use this, need to check the return value for NULL.
+ base::Thread* io_thread() const {
+ return io_thread_.get();
+ }
+ // Returns the thread that we perform random file operations on. For code
+ // that wants to do I/O operations (not network requests or even file: URL
+ // requests), this is the thread to use to avoid blocking the UI thread.
+ base::Thread* file_thread() const {
+ return file_thread_.get();
+ }
+ CloudPrintProxy* cloud_print_proxy();
+
+ private:
+ scoped_ptr<base::Thread> io_thread_;
+ scoped_ptr<base::Thread> file_thread_;
+ scoped_ptr<CloudPrintProxy> cloud_print_proxy_;
+
+ DISALLOW_COPY_AND_ASSIGN(ServiceProcess);
+};
+
+extern ServiceProcess* g_service_process;
+
+#endif // CHROME_SERVICE_SERVICE_PROCESS_H_
+