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 |