| 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" |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 index = task_list->erase(index); | 83 index = task_list->erase(index); |
| 84 } | 84 } |
| 85 } | 85 } |
| 86 | 86 |
| 87 bool ServiceProcessControl::IsConnected() const { | 87 bool ServiceProcessControl::IsConnected() const { |
| 88 return channel_ != NULL; | 88 return channel_ != NULL; |
| 89 } | 89 } |
| 90 | 90 |
| 91 void ServiceProcessControl::Launch(const base::Closure& success_task, | 91 void ServiceProcessControl::Launch(const base::Closure& success_task, |
| 92 const base::Closure& failure_task) { | 92 const base::Closure& failure_task) { |
| 93 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 93 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 94 | 94 |
| 95 base::Closure failure = failure_task; | 95 base::Closure failure = failure_task; |
| 96 if (!success_task.is_null()) | 96 if (!success_task.is_null()) |
| 97 connect_success_tasks_.push_back(success_task); | 97 connect_success_tasks_.push_back(success_task); |
| 98 | 98 |
| 99 if (!failure.is_null()) | 99 if (!failure.is_null()) |
| 100 connect_failure_tasks_.push_back(failure); | 100 connect_failure_tasks_.push_back(failure); |
| 101 | 101 |
| 102 // If we already in the process of launching, then we are done. | 102 // If we already in the process of launching, then we are done. |
| 103 if (launcher_.get()) | 103 if (launcher_.get()) |
| 104 return; | 104 return; |
| 105 | 105 |
| 106 // If the service process is already running then connects to it. | 106 // If the service process is already running then connects to it. |
| 107 if (CheckServiceProcessReady()) { | 107 if (CheckServiceProcessReady()) { |
| 108 ConnectInternal(); | 108 ConnectInternal(); |
| 109 return; | 109 return; |
| 110 } | 110 } |
| 111 | 111 |
| 112 UMA_HISTOGRAM_ENUMERATION("CloudPrint.ServiceEvents", SERVICE_EVENT_LAUNCH, | 112 UMA_HISTOGRAM_ENUMERATION("CloudPrint.ServiceEvents", SERVICE_EVENT_LAUNCH, |
| 113 SERVICE_EVENT_MAX); | 113 SERVICE_EVENT_MAX); |
| 114 | 114 |
| 115 scoped_ptr<base::CommandLine> cmd_line(CreateServiceProcessCommandLine()); | 115 scoped_ptr<base::CommandLine> cmd_line(CreateServiceProcessCommandLine()); |
| 116 // And then start the process asynchronously. | 116 // And then start the process asynchronously. |
| 117 launcher_ = new Launcher(cmd_line.Pass()); | 117 launcher_ = new Launcher(cmd_line.Pass()); |
| 118 launcher_->Run(base::Bind(&ServiceProcessControl::OnProcessLaunched, | 118 launcher_->Run(base::Bind(&ServiceProcessControl::OnProcessLaunched, |
| 119 base::Unretained(this))); | 119 base::Unretained(this))); |
| 120 } | 120 } |
| 121 | 121 |
| 122 void ServiceProcessControl::Disconnect() { | 122 void ServiceProcessControl::Disconnect() { |
| 123 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 123 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 124 channel_.reset(); | 124 channel_.reset(); |
| 125 } | 125 } |
| 126 | 126 |
| 127 void ServiceProcessControl::OnProcessLaunched() { | 127 void ServiceProcessControl::OnProcessLaunched() { |
| 128 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 128 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 129 if (launcher_->launched()) { | 129 if (launcher_->launched()) { |
| 130 UMA_HISTOGRAM_ENUMERATION("CloudPrint.ServiceEvents", | 130 UMA_HISTOGRAM_ENUMERATION("CloudPrint.ServiceEvents", |
| 131 SERVICE_EVENT_LAUNCHED, SERVICE_EVENT_MAX); | 131 SERVICE_EVENT_LAUNCHED, SERVICE_EVENT_MAX); |
| 132 // After we have successfully created the service process we try to connect | 132 // After we have successfully created the service process we try to connect |
| 133 // to it. The launch task is transfered to a connect task. | 133 // to it. The launch task is transfered to a connect task. |
| 134 ConnectInternal(); | 134 ConnectInternal(); |
| 135 } else { | 135 } else { |
| 136 UMA_HISTOGRAM_ENUMERATION("CloudPrint.ServiceEvents", | 136 UMA_HISTOGRAM_ENUMERATION("CloudPrint.ServiceEvents", |
| 137 SERVICE_EVENT_LAUNCH_FAILED, SERVICE_EVENT_MAX); | 137 SERVICE_EVENT_LAUNCH_FAILED, SERVICE_EVENT_MAX); |
| 138 // If we don't have process handle that means launching the service process | 138 // If we don't have process handle that means launching the service process |
| (...skipping 11 matching lines...) Expand all Loading... |
| 150 IPC_MESSAGE_HANDLER(ServiceHostMsg_CloudPrintProxy_Info, | 150 IPC_MESSAGE_HANDLER(ServiceHostMsg_CloudPrintProxy_Info, |
| 151 OnCloudPrintProxyInfo) | 151 OnCloudPrintProxyInfo) |
| 152 IPC_MESSAGE_HANDLER(ServiceHostMsg_Histograms, OnHistograms) | 152 IPC_MESSAGE_HANDLER(ServiceHostMsg_Histograms, OnHistograms) |
| 153 IPC_MESSAGE_HANDLER(ServiceHostMsg_Printers, OnPrinters) | 153 IPC_MESSAGE_HANDLER(ServiceHostMsg_Printers, OnPrinters) |
| 154 IPC_MESSAGE_UNHANDLED(handled = false) | 154 IPC_MESSAGE_UNHANDLED(handled = false) |
| 155 IPC_END_MESSAGE_MAP() | 155 IPC_END_MESSAGE_MAP() |
| 156 return handled; | 156 return handled; |
| 157 } | 157 } |
| 158 | 158 |
| 159 void ServiceProcessControl::OnChannelConnected(int32 peer_pid) { | 159 void ServiceProcessControl::OnChannelConnected(int32 peer_pid) { |
| 160 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 160 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 161 | 161 |
| 162 UMA_HISTOGRAM_ENUMERATION("CloudPrint.ServiceEvents", | 162 UMA_HISTOGRAM_ENUMERATION("CloudPrint.ServiceEvents", |
| 163 SERVICE_EVENT_CHANNEL_CONNECTED, SERVICE_EVENT_MAX); | 163 SERVICE_EVENT_CHANNEL_CONNECTED, SERVICE_EVENT_MAX); |
| 164 | 164 |
| 165 // We just established a channel with the service process. Notify it if an | 165 // We just established a channel with the service process. Notify it if an |
| 166 // upgrade is available. | 166 // upgrade is available. |
| 167 if (UpgradeDetector::GetInstance()->notify_upgrade()) { | 167 if (UpgradeDetector::GetInstance()->notify_upgrade()) { |
| 168 Send(new ServiceMsg_UpdateAvailable); | 168 Send(new ServiceMsg_UpdateAvailable); |
| 169 } else { | 169 } else { |
| 170 if (registrar_.IsEmpty()) | 170 if (registrar_.IsEmpty()) |
| 171 registrar_.Add(this, chrome::NOTIFICATION_UPGRADE_RECOMMENDED, | 171 registrar_.Add(this, chrome::NOTIFICATION_UPGRADE_RECOMMENDED, |
| 172 content::NotificationService::AllSources()); | 172 content::NotificationService::AllSources()); |
| 173 } | 173 } |
| 174 RunConnectDoneTasks(); | 174 RunConnectDoneTasks(); |
| 175 } | 175 } |
| 176 | 176 |
| 177 void ServiceProcessControl::OnChannelError() { | 177 void ServiceProcessControl::OnChannelError() { |
| 178 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 178 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 179 | 179 |
| 180 UMA_HISTOGRAM_ENUMERATION("CloudPrint.ServiceEvents", | 180 UMA_HISTOGRAM_ENUMERATION("CloudPrint.ServiceEvents", |
| 181 SERVICE_EVENT_CHANNEL_ERROR, SERVICE_EVENT_MAX); | 181 SERVICE_EVENT_CHANNEL_ERROR, SERVICE_EVENT_MAX); |
| 182 | 182 |
| 183 channel_.reset(); | 183 channel_.reset(); |
| 184 RunConnectDoneTasks(); | 184 RunConnectDoneTasks(); |
| 185 } | 185 } |
| 186 | 186 |
| 187 bool ServiceProcessControl::Send(IPC::Message* message) { | 187 bool ServiceProcessControl::Send(IPC::Message* message) { |
| 188 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 188 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 189 if (!channel_.get()) | 189 if (!channel_.get()) |
| 190 return false; | 190 return false; |
| 191 return channel_->Send(message); | 191 return channel_->Send(message); |
| 192 } | 192 } |
| 193 | 193 |
| 194 // content::NotificationObserver implementation. | 194 // content::NotificationObserver implementation. |
| 195 void ServiceProcessControl::Observe( | 195 void ServiceProcessControl::Observe( |
| 196 int type, | 196 int type, |
| 197 const content::NotificationSource& source, | 197 const content::NotificationSource& source, |
| 198 const content::NotificationDetails& details) { | 198 const content::NotificationDetails& details) { |
| 199 if (type == chrome::NOTIFICATION_UPGRADE_RECOMMENDED) { | 199 if (type == chrome::NOTIFICATION_UPGRADE_RECOMMENDED) { |
| 200 Send(new ServiceMsg_UpdateAvailable); | 200 Send(new ServiceMsg_UpdateAvailable); |
| 201 } | 201 } |
| 202 } | 202 } |
| 203 | 203 |
| 204 void ServiceProcessControl::OnCloudPrintProxyInfo( | 204 void ServiceProcessControl::OnCloudPrintProxyInfo( |
| 205 const cloud_print::CloudPrintProxyInfo& proxy_info) { | 205 const cloud_print::CloudPrintProxyInfo& proxy_info) { |
| 206 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 206 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 207 UMA_HISTOGRAM_ENUMERATION("CloudPrint.ServiceEvents", | 207 UMA_HISTOGRAM_ENUMERATION("CloudPrint.ServiceEvents", |
| 208 SERVICE_EVENT_INFO_REPLY, SERVICE_EVENT_MAX); | 208 SERVICE_EVENT_INFO_REPLY, SERVICE_EVENT_MAX); |
| 209 if (!cloud_print_info_callback_.is_null()) { | 209 if (!cloud_print_info_callback_.is_null()) { |
| 210 cloud_print_info_callback_.Run(proxy_info); | 210 cloud_print_info_callback_.Run(proxy_info); |
| 211 cloud_print_info_callback_.Reset(); | 211 cloud_print_info_callback_.Reset(); |
| 212 } | 212 } |
| 213 } | 213 } |
| 214 | 214 |
| 215 void ServiceProcessControl::OnHistograms( | 215 void ServiceProcessControl::OnHistograms( |
| 216 const std::vector<std::string>& pickled_histograms) { | 216 const std::vector<std::string>& pickled_histograms) { |
| 217 UMA_HISTOGRAM_ENUMERATION("CloudPrint.ServiceEvents", | 217 UMA_HISTOGRAM_ENUMERATION("CloudPrint.ServiceEvents", |
| 218 SERVICE_EVENT_HISTOGRAMS_REPLY, SERVICE_EVENT_MAX); | 218 SERVICE_EVENT_HISTOGRAMS_REPLY, SERVICE_EVENT_MAX); |
| 219 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 219 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 220 base::HistogramDeltaSerialization::DeserializeAndAddSamples( | 220 base::HistogramDeltaSerialization::DeserializeAndAddSamples( |
| 221 pickled_histograms); | 221 pickled_histograms); |
| 222 RunHistogramsCallback(); | 222 RunHistogramsCallback(); |
| 223 } | 223 } |
| 224 | 224 |
| 225 void ServiceProcessControl::RunHistogramsCallback() { | 225 void ServiceProcessControl::RunHistogramsCallback() { |
| 226 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 226 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 227 if (!histograms_callback_.is_null()) { | 227 if (!histograms_callback_.is_null()) { |
| 228 histograms_callback_.Run(); | 228 histograms_callback_.Run(); |
| 229 histograms_callback_.Reset(); | 229 histograms_callback_.Reset(); |
| 230 } | 230 } |
| 231 histograms_timeout_callback_.Cancel(); | 231 histograms_timeout_callback_.Cancel(); |
| 232 } | 232 } |
| 233 | 233 |
| 234 void ServiceProcessControl::OnPrinters( | 234 void ServiceProcessControl::OnPrinters( |
| 235 const std::vector<std::string>& printers) { | 235 const std::vector<std::string>& printers) { |
| 236 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 236 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 237 UMA_HISTOGRAM_ENUMERATION( | 237 UMA_HISTOGRAM_ENUMERATION( |
| 238 "CloudPrint.ServiceEvents", SERVICE_PRINTERS_REPLY, SERVICE_EVENT_MAX); | 238 "CloudPrint.ServiceEvents", SERVICE_PRINTERS_REPLY, SERVICE_EVENT_MAX); |
| 239 UMA_HISTOGRAM_COUNTS_10000("CloudPrint.AvailablePrinters", printers.size()); | 239 UMA_HISTOGRAM_COUNTS_10000("CloudPrint.AvailablePrinters", printers.size()); |
| 240 if (!printers_callback_.is_null()) { | 240 if (!printers_callback_.is_null()) { |
| 241 printers_callback_.Run(printers); | 241 printers_callback_.Run(printers); |
| 242 printers_callback_.Reset(); | 242 printers_callback_.Reset(); |
| 243 } | 243 } |
| 244 } | 244 } |
| 245 | 245 |
| 246 bool ServiceProcessControl::GetCloudPrintProxyInfo( | 246 bool ServiceProcessControl::GetCloudPrintProxyInfo( |
| 247 const CloudPrintProxyInfoCallback& cloud_print_info_callback) { | 247 const CloudPrintProxyInfoCallback& cloud_print_info_callback) { |
| 248 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 248 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 249 DCHECK(!cloud_print_info_callback.is_null()); | 249 DCHECK(!cloud_print_info_callback.is_null()); |
| 250 cloud_print_info_callback_.Reset(); | 250 cloud_print_info_callback_.Reset(); |
| 251 UMA_HISTOGRAM_ENUMERATION("CloudPrint.ServiceEvents", | 251 UMA_HISTOGRAM_ENUMERATION("CloudPrint.ServiceEvents", |
| 252 SERVICE_EVENT_INFO_REQUEST, SERVICE_EVENT_MAX); | 252 SERVICE_EVENT_INFO_REQUEST, SERVICE_EVENT_MAX); |
| 253 if (!Send(new ServiceMsg_GetCloudPrintProxyInfo())) | 253 if (!Send(new ServiceMsg_GetCloudPrintProxyInfo())) |
| 254 return false; | 254 return false; |
| 255 cloud_print_info_callback_ = cloud_print_info_callback; | 255 cloud_print_info_callback_ = cloud_print_info_callback; |
| 256 return true; | 256 return true; |
| 257 } | 257 } |
| 258 | 258 |
| 259 bool ServiceProcessControl::GetHistograms( | 259 bool ServiceProcessControl::GetHistograms( |
| 260 const base::Closure& histograms_callback, | 260 const base::Closure& histograms_callback, |
| 261 const base::TimeDelta& timeout) { | 261 const base::TimeDelta& timeout) { |
| 262 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 262 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 263 DCHECK(!histograms_callback.is_null()); | 263 DCHECK(!histograms_callback.is_null()); |
| 264 histograms_callback_.Reset(); | 264 histograms_callback_.Reset(); |
| 265 | 265 |
| 266 #if defined(OS_MACOSX) | 266 #if defined(OS_MACOSX) |
| 267 // TODO(vitalybuka): Investigate why it crashes MAC http://crbug.com/406227. | 267 // TODO(vitalybuka): Investigate why it crashes MAC http://crbug.com/406227. |
| 268 return false; | 268 return false; |
| 269 #endif // OS_MACOSX | 269 #endif // OS_MACOSX |
| 270 | 270 |
| 271 // If the service process is already running then connect to it. | 271 // If the service process is already running then connect to it. |
| 272 if (!CheckServiceProcessReady()) | 272 if (!CheckServiceProcessReady()) |
| (...skipping 14 matching lines...) Expand all Loading... |
| 287 BrowserThread::PostDelayedTask(BrowserThread::UI, FROM_HERE, | 287 BrowserThread::PostDelayedTask(BrowserThread::UI, FROM_HERE, |
| 288 histograms_timeout_callback_.callback(), | 288 histograms_timeout_callback_.callback(), |
| 289 timeout); | 289 timeout); |
| 290 | 290 |
| 291 histograms_callback_ = histograms_callback; | 291 histograms_callback_ = histograms_callback; |
| 292 return true; | 292 return true; |
| 293 } | 293 } |
| 294 | 294 |
| 295 bool ServiceProcessControl::GetPrinters( | 295 bool ServiceProcessControl::GetPrinters( |
| 296 const PrintersCallback& printers_callback) { | 296 const PrintersCallback& printers_callback) { |
| 297 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 297 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 298 DCHECK(!printers_callback.is_null()); | 298 DCHECK(!printers_callback.is_null()); |
| 299 printers_callback_.Reset(); | 299 printers_callback_.Reset(); |
| 300 UMA_HISTOGRAM_ENUMERATION( | 300 UMA_HISTOGRAM_ENUMERATION( |
| 301 "CloudPrint.ServiceEvents", SERVICE_PRINTERS_REQUEST, SERVICE_EVENT_MAX); | 301 "CloudPrint.ServiceEvents", SERVICE_PRINTERS_REQUEST, SERVICE_EVENT_MAX); |
| 302 if (!Send(new ServiceMsg_GetPrinters())) | 302 if (!Send(new ServiceMsg_GetPrinters())) |
| 303 return false; | 303 return false; |
| 304 printers_callback_ = printers_callback; | 304 printers_callback_ = printers_callback; |
| 305 return true; | 305 return true; |
| 306 } | 306 } |
| 307 | 307 |
| 308 bool ServiceProcessControl::Shutdown() { | 308 bool ServiceProcessControl::Shutdown() { |
| 309 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 309 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 310 bool ret = Send(new ServiceMsg_Shutdown()); | 310 bool ret = Send(new ServiceMsg_Shutdown()); |
| 311 channel_.reset(); | 311 channel_.reset(); |
| 312 return ret; | 312 return ret; |
| 313 } | 313 } |
| 314 | 314 |
| 315 // static | 315 // static |
| 316 ServiceProcessControl* ServiceProcessControl::GetInstance() { | 316 ServiceProcessControl* ServiceProcessControl::GetInstance() { |
| 317 return Singleton<ServiceProcessControl>::get(); | 317 return Singleton<ServiceProcessControl>::get(); |
| 318 } | 318 } |
| 319 | 319 |
| 320 ServiceProcessControl::Launcher::Launcher( | 320 ServiceProcessControl::Launcher::Launcher( |
| 321 scoped_ptr<base::CommandLine> cmd_line) | 321 scoped_ptr<base::CommandLine> cmd_line) |
| 322 : cmd_line_(cmd_line.Pass()), | 322 : cmd_line_(cmd_line.Pass()), |
| 323 launched_(false), | 323 launched_(false), |
| 324 retry_count_(0) { | 324 retry_count_(0) { |
| 325 } | 325 } |
| 326 | 326 |
| 327 // Execute the command line to start the process asynchronously. | 327 // Execute the command line to start the process asynchronously. |
| 328 // After the command is executed, |task| is called with the process handle on | 328 // After the command is executed, |task| is called with the process handle on |
| 329 // the UI thread. | 329 // the UI thread. |
| 330 void ServiceProcessControl::Launcher::Run(const base::Closure& task) { | 330 void ServiceProcessControl::Launcher::Run(const base::Closure& task) { |
| 331 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 331 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 332 notify_task_ = task; | 332 notify_task_ = task; |
| 333 BrowserThread::PostTask(BrowserThread::PROCESS_LAUNCHER, FROM_HERE, | 333 BrowserThread::PostTask(BrowserThread::PROCESS_LAUNCHER, FROM_HERE, |
| 334 base::Bind(&Launcher::DoRun, this)); | 334 base::Bind(&Launcher::DoRun, this)); |
| 335 } | 335 } |
| 336 | 336 |
| 337 ServiceProcessControl::Launcher::~Launcher() { | 337 ServiceProcessControl::Launcher::~Launcher() { |
| 338 } | 338 } |
| 339 | 339 |
| 340 | 340 |
| 341 void ServiceProcessControl::Launcher::Notify() { | 341 void ServiceProcessControl::Launcher::Notify() { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 379 if (process_.IsValid()) { | 379 if (process_.IsValid()) { |
| 380 BrowserThread::PostTask( | 380 BrowserThread::PostTask( |
| 381 BrowserThread::IO, FROM_HERE, | 381 BrowserThread::IO, FROM_HERE, |
| 382 base::Bind(&Launcher::DoDetectLaunched, this)); | 382 base::Bind(&Launcher::DoDetectLaunched, this)); |
| 383 } else { | 383 } else { |
| 384 BrowserThread::PostTask( | 384 BrowserThread::PostTask( |
| 385 BrowserThread::UI, FROM_HERE, base::Bind(&Launcher::Notify, this)); | 385 BrowserThread::UI, FROM_HERE, base::Bind(&Launcher::Notify, this)); |
| 386 } | 386 } |
| 387 } | 387 } |
| 388 #endif // !OS_MACOSX | 388 #endif // !OS_MACOSX |
| OLD | NEW |