| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/service_process/service_process_control.h" | 5 #include "chrome/browser/service_process/service_process_control.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
| 11 #include "base/metrics/histogram_base.h" | 11 #include "base/metrics/histogram_base.h" |
| 12 #include "base/metrics/histogram_delta_serialization.h" | 12 #include "base/metrics/histogram_delta_serialization.h" |
| 13 #include "base/process/kill.h" | 13 #include "base/process/kill.h" |
| 14 #include "base/process/launch.h" | 14 #include "base/process/launch.h" |
| 15 #include "base/stl_util.h" | 15 #include "base/stl_util.h" |
| 16 #include "base/threading/thread.h" | 16 #include "base/threading/thread.h" |
| 17 #include "base/threading/thread_restrictions.h" | 17 #include "base/threading/thread_restrictions.h" |
| 18 #include "chrome/browser/browser_process.h" | 18 #include "chrome/browser/browser_process.h" |
| 19 #include "chrome/browser/chrome_notification_types.h" | 19 #include "chrome/browser/chrome_notification_types.h" |
| 20 #include "chrome/browser/upgrade_detector.h" | 20 #include "chrome/browser/upgrade_detector.h" |
| 21 #include "chrome/common/chrome_switches.h" | |
| 22 #include "chrome/common/service_messages.h" | 21 #include "chrome/common/service_messages.h" |
| 23 #include "chrome/common/service_process_util.h" | 22 #include "chrome/common/service_process_util.h" |
| 24 #include "components/cloud_devices/common/cloud_devices_switches.h" | |
| 25 #include "content/public/browser/browser_thread.h" | 23 #include "content/public/browser/browser_thread.h" |
| 26 #include "content/public/browser/notification_service.h" | 24 #include "content/public/browser/notification_service.h" |
| 27 #include "content/public/common/child_process_host.h" | |
| 28 #include "google_apis/gaia/gaia_switches.h" | |
| 29 #include "ui/base/ui_base_switches.h" | |
| 30 | 25 |
| 31 using content::BrowserThread; | 26 using content::BrowserThread; |
| 32 using content::ChildProcessHost; | |
| 33 | 27 |
| 34 // ServiceProcessControl implementation. | 28 // ServiceProcessControl implementation. |
| 35 ServiceProcessControl::ServiceProcessControl() { | 29 ServiceProcessControl::ServiceProcessControl() { |
| 36 } | 30 } |
| 37 | 31 |
| 38 ServiceProcessControl::~ServiceProcessControl() { | 32 ServiceProcessControl::~ServiceProcessControl() { |
| 39 } | 33 } |
| 40 | 34 |
| 41 void ServiceProcessControl::ConnectInternal() { | 35 void ServiceProcessControl::ConnectInternal() { |
| 42 // If the channel has already been established then we run the task | 36 // If the channel has already been established then we run the task |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 | 105 |
| 112 // If the service process is already running then connects to it. | 106 // If the service process is already running then connects to it. |
| 113 if (CheckServiceProcessReady()) { | 107 if (CheckServiceProcessReady()) { |
| 114 ConnectInternal(); | 108 ConnectInternal(); |
| 115 return; | 109 return; |
| 116 } | 110 } |
| 117 | 111 |
| 118 UMA_HISTOGRAM_ENUMERATION("CloudPrint.ServiceEvents", SERVICE_EVENT_LAUNCH, | 112 UMA_HISTOGRAM_ENUMERATION("CloudPrint.ServiceEvents", SERVICE_EVENT_LAUNCH, |
| 119 SERVICE_EVENT_MAX); | 113 SERVICE_EVENT_MAX); |
| 120 | 114 |
| 121 // A service process should have a different mechanism for starting, but now | 115 scoped_ptr<base::CommandLine> cmd_line(CreateServiceProcessCommandLine()); |
| 122 // we start it as if it is a child process. | |
| 123 | |
| 124 #if defined(OS_LINUX) | |
| 125 int flags = ChildProcessHost::CHILD_ALLOW_SELF; | |
| 126 #else | |
| 127 int flags = ChildProcessHost::CHILD_NORMAL; | |
| 128 #endif | |
| 129 | |
| 130 base::FilePath exe_path = ChildProcessHost::GetChildPath(flags); | |
| 131 if (exe_path.empty()) | |
| 132 NOTREACHED() << "Unable to get service process binary name."; | |
| 133 | |
| 134 CommandLine* cmd_line = new CommandLine(exe_path); | |
| 135 cmd_line->AppendSwitchASCII(switches::kProcessType, | |
| 136 switches::kServiceProcess); | |
| 137 | |
| 138 static const char* const kSwitchesToCopy[] = { | |
| 139 switches::kCloudPrintSetupProxy, | |
| 140 switches::kCloudPrintURL, | |
| 141 switches::kCloudPrintXmppEndpoint, | |
| 142 #if defined(OS_WIN) | |
| 143 switches::kEnableCloudPrintXps, | |
| 144 #endif | |
| 145 switches::kEnableLogging, | |
| 146 switches::kIgnoreUrlFetcherCertRequests, | |
| 147 switches::kLang, | |
| 148 switches::kLoggingLevel, | |
| 149 switches::kLsoUrl, | |
| 150 switches::kNoServiceAutorun, | |
| 151 switches::kUserDataDir, | |
| 152 switches::kV, | |
| 153 switches::kVModule, | |
| 154 switches::kWaitForDebugger, | |
| 155 }; | |
| 156 cmd_line->CopySwitchesFrom(*CommandLine::ForCurrentProcess(), | |
| 157 kSwitchesToCopy, | |
| 158 arraysize(kSwitchesToCopy)); | |
| 159 | |
| 160 // And then start the process asynchronously. | 116 // And then start the process asynchronously. |
| 161 launcher_ = new Launcher(this, cmd_line); | 117 launcher_ = new Launcher(this, cmd_line.Pass()); |
| 162 launcher_->Run(base::Bind(&ServiceProcessControl::OnProcessLaunched, | 118 launcher_->Run(base::Bind(&ServiceProcessControl::OnProcessLaunched, |
| 163 base::Unretained(this))); | 119 base::Unretained(this))); |
| 164 } | 120 } |
| 165 | 121 |
| 166 void ServiceProcessControl::Disconnect() { | 122 void ServiceProcessControl::Disconnect() { |
| 167 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 123 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 168 channel_.reset(); | 124 channel_.reset(); |
| 169 } | 125 } |
| 170 | 126 |
| 171 void ServiceProcessControl::OnProcessLaunched() { | 127 void ServiceProcessControl::OnProcessLaunched() { |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 349 bool ret = Send(new ServiceMsg_Shutdown()); | 305 bool ret = Send(new ServiceMsg_Shutdown()); |
| 350 channel_.reset(); | 306 channel_.reset(); |
| 351 return ret; | 307 return ret; |
| 352 } | 308 } |
| 353 | 309 |
| 354 // static | 310 // static |
| 355 ServiceProcessControl* ServiceProcessControl::GetInstance() { | 311 ServiceProcessControl* ServiceProcessControl::GetInstance() { |
| 356 return Singleton<ServiceProcessControl>::get(); | 312 return Singleton<ServiceProcessControl>::get(); |
| 357 } | 313 } |
| 358 | 314 |
| 359 ServiceProcessControl::Launcher::Launcher(ServiceProcessControl* process, | 315 ServiceProcessControl::Launcher::Launcher( |
| 360 CommandLine* cmd_line) | 316 ServiceProcessControl* process, |
| 317 scoped_ptr<base::CommandLine> cmd_line) |
| 361 : process_(process), | 318 : process_(process), |
| 362 cmd_line_(cmd_line), | 319 cmd_line_(cmd_line.Pass()), |
| 363 launched_(false), | 320 launched_(false), |
| 364 retry_count_(0), | 321 retry_count_(0), |
| 365 process_handle_(base::kNullProcessHandle) { | 322 process_handle_(base::kNullProcessHandle) { |
| 366 } | 323 } |
| 367 | 324 |
| 368 // Execute the command line to start the process asynchronously. | 325 // Execute the command line to start the process asynchronously. |
| 369 // After the command is executed, |task| is called with the process handle on | 326 // After the command is executed, |task| is called with the process handle on |
| 370 // the UI thread. | 327 // the UI thread. |
| 371 void ServiceProcessControl::Launcher::Run(const base::Closure& task) { | 328 void ServiceProcessControl::Launcher::Run(const base::Closure& task) { |
| 372 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 329 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 428 if (base::LaunchProcess(*cmd_line_, options, &process_handle_)) { | 385 if (base::LaunchProcess(*cmd_line_, options, &process_handle_)) { |
| 429 BrowserThread::PostTask( | 386 BrowserThread::PostTask( |
| 430 BrowserThread::IO, FROM_HERE, | 387 BrowserThread::IO, FROM_HERE, |
| 431 base::Bind(&Launcher::DoDetectLaunched, this)); | 388 base::Bind(&Launcher::DoDetectLaunched, this)); |
| 432 } else { | 389 } else { |
| 433 BrowserThread::PostTask( | 390 BrowserThread::PostTask( |
| 434 BrowserThread::UI, FROM_HERE, base::Bind(&Launcher::Notify, this)); | 391 BrowserThread::UI, FROM_HERE, base::Bind(&Launcher::Notify, this)); |
| 435 } | 392 } |
| 436 } | 393 } |
| 437 #endif // !OS_MACOSX | 394 #endif // !OS_MACOSX |
| OLD | NEW |