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/service/cloud_print/cloud_print_proxy_backend.h" | 5 #include "chrome/service/cloud_print/cloud_print_proxy_backend.h" |
6 | 6 |
7 #include <map> | 7 #include <map> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
12 #include "base/compiler_specific.h" | 12 #include "base/compiler_specific.h" |
| 13 #include "base/location.h" |
13 #include "base/metrics/histogram.h" | 14 #include "base/metrics/histogram.h" |
14 #include "base/rand_util.h" | 15 #include "base/rand_util.h" |
| 16 #include "base/single_thread_task_runner.h" |
15 #include "base/strings/string_util.h" | 17 #include "base/strings/string_util.h" |
| 18 #include "base/thread_task_runner_handle.h" |
16 #include "base/values.h" | 19 #include "base/values.h" |
17 #include "chrome/common/cloud_print/cloud_print_constants.h" | 20 #include "chrome/common/cloud_print/cloud_print_constants.h" |
18 #include "chrome/service/cloud_print/cloud_print_auth.h" | 21 #include "chrome/service/cloud_print/cloud_print_auth.h" |
19 #include "chrome/service/cloud_print/cloud_print_connector.h" | 22 #include "chrome/service/cloud_print/cloud_print_connector.h" |
20 #include "chrome/service/cloud_print/cloud_print_service_helpers.h" | 23 #include "chrome/service/cloud_print/cloud_print_service_helpers.h" |
21 #include "chrome/service/cloud_print/cloud_print_token_store.h" | 24 #include "chrome/service/cloud_print/cloud_print_token_store.h" |
22 #include "chrome/service/cloud_print/connector_settings.h" | 25 #include "chrome/service/cloud_print/connector_settings.h" |
23 #include "chrome/service/net/service_url_request_context_getter.h" | 26 #include "chrome/service/net/service_url_request_context_getter.h" |
24 #include "chrome/service/service_process.h" | 27 #include "chrome/service/service_process.h" |
25 #include "components/cloud_devices/common/cloud_devices_switches.h" | 28 #include "components/cloud_devices/common/cloud_devices_switches.h" |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
165 DCHECK(frontend_); | 168 DCHECK(frontend_); |
166 core_ = new Core(this, settings, oauth_client_info, enable_job_poll); | 169 core_ = new Core(this, settings, oauth_client_info, enable_job_poll); |
167 } | 170 } |
168 | 171 |
169 CloudPrintProxyBackend::~CloudPrintProxyBackend() { DCHECK(!core_.get()); } | 172 CloudPrintProxyBackend::~CloudPrintProxyBackend() { DCHECK(!core_.get()); } |
170 | 173 |
171 bool CloudPrintProxyBackend::InitializeWithToken( | 174 bool CloudPrintProxyBackend::InitializeWithToken( |
172 const std::string& cloud_print_token) { | 175 const std::string& cloud_print_token) { |
173 if (!core_thread_.Start()) | 176 if (!core_thread_.Start()) |
174 return false; | 177 return false; |
175 core_thread_.message_loop()->PostTask( | 178 core_thread_.task_runner()->PostTask( |
176 FROM_HERE, | 179 FROM_HERE, |
177 base::Bind(&CloudPrintProxyBackend::Core::DoInitializeWithToken, | 180 base::Bind(&CloudPrintProxyBackend::Core::DoInitializeWithToken, |
178 core_.get(), cloud_print_token)); | 181 core_.get(), cloud_print_token)); |
179 return true; | 182 return true; |
180 } | 183 } |
181 | 184 |
182 bool CloudPrintProxyBackend::InitializeWithRobotToken( | 185 bool CloudPrintProxyBackend::InitializeWithRobotToken( |
183 const std::string& robot_oauth_refresh_token, | 186 const std::string& robot_oauth_refresh_token, |
184 const std::string& robot_email) { | 187 const std::string& robot_email) { |
185 if (!core_thread_.Start()) | 188 if (!core_thread_.Start()) |
186 return false; | 189 return false; |
187 core_thread_.message_loop()->PostTask( | 190 core_thread_.task_runner()->PostTask( |
188 FROM_HERE, | 191 FROM_HERE, |
189 base::Bind(&CloudPrintProxyBackend::Core::DoInitializeWithRobotToken, | 192 base::Bind(&CloudPrintProxyBackend::Core::DoInitializeWithRobotToken, |
190 core_.get(), robot_oauth_refresh_token, robot_email)); | 193 core_.get(), robot_oauth_refresh_token, robot_email)); |
191 return true; | 194 return true; |
192 } | 195 } |
193 | 196 |
194 bool CloudPrintProxyBackend::InitializeWithRobotAuthCode( | 197 bool CloudPrintProxyBackend::InitializeWithRobotAuthCode( |
195 const std::string& robot_oauth_auth_code, | 198 const std::string& robot_oauth_auth_code, |
196 const std::string& robot_email) { | 199 const std::string& robot_email) { |
197 if (!core_thread_.Start()) | 200 if (!core_thread_.Start()) |
198 return false; | 201 return false; |
199 core_thread_.message_loop()->PostTask( | 202 core_thread_.task_runner()->PostTask( |
200 FROM_HERE, | 203 FROM_HERE, |
201 base::Bind(&CloudPrintProxyBackend::Core::DoInitializeWithRobotAuthCode, | 204 base::Bind(&CloudPrintProxyBackend::Core::DoInitializeWithRobotAuthCode, |
202 core_.get(), robot_oauth_auth_code, robot_email)); | 205 core_.get(), robot_oauth_auth_code, robot_email)); |
203 return true; | 206 return true; |
204 } | 207 } |
205 | 208 |
206 void CloudPrintProxyBackend::Shutdown() { | 209 void CloudPrintProxyBackend::Shutdown() { |
207 core_thread_.message_loop()->PostTask( | 210 core_thread_.task_runner()->PostTask( |
208 FROM_HERE, | 211 FROM_HERE, |
209 base::Bind(&CloudPrintProxyBackend::Core::DoShutdown, core_.get())); | 212 base::Bind(&CloudPrintProxyBackend::Core::DoShutdown, core_.get())); |
210 core_thread_.Stop(); | 213 core_thread_.Stop(); |
211 core_ = NULL; // Releases reference to core_. | 214 core_ = NULL; // Releases reference to core_. |
212 } | 215 } |
213 | 216 |
214 void CloudPrintProxyBackend::UnregisterPrinters() { | 217 void CloudPrintProxyBackend::UnregisterPrinters() { |
215 core_thread_.message_loop()->PostTask( | 218 core_thread_.task_runner()->PostTask( |
216 FROM_HERE, | 219 FROM_HERE, base::Bind(&CloudPrintProxyBackend::Core::DoUnregisterPrinters, |
217 base::Bind(&CloudPrintProxyBackend::Core::DoUnregisterPrinters, | 220 core_.get())); |
218 core_.get())); | |
219 } | 221 } |
220 | 222 |
221 CloudPrintProxyBackend::Core::Core( | 223 CloudPrintProxyBackend::Core::Core( |
222 CloudPrintProxyBackend* backend, | 224 CloudPrintProxyBackend* backend, |
223 const ConnectorSettings& settings, | 225 const ConnectorSettings& settings, |
224 const gaia::OAuthClientInfo& oauth_client_info, | 226 const gaia::OAuthClientInfo& oauth_client_info, |
225 bool enable_job_poll) | 227 bool enable_job_poll) |
226 : backend_(backend), | 228 : backend_(backend), |
227 oauth_client_info_(oauth_client_info), | 229 oauth_client_info_(oauth_client_info), |
228 notifications_enabled_(false), | 230 notifications_enabled_(false), |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
275 void CloudPrintProxyBackend::Core::OnAuthenticationComplete( | 277 void CloudPrintProxyBackend::Core::OnAuthenticationComplete( |
276 const std::string& access_token, | 278 const std::string& access_token, |
277 const std::string& robot_oauth_refresh_token, | 279 const std::string& robot_oauth_refresh_token, |
278 const std::string& robot_email, | 280 const std::string& robot_email, |
279 const std::string& user_email) { | 281 const std::string& user_email) { |
280 CloudPrintTokenStore* token_store = GetTokenStore(); | 282 CloudPrintTokenStore* token_store = GetTokenStore(); |
281 bool first_time = token_store->token().empty(); | 283 bool first_time = token_store->token().empty(); |
282 token_store->SetToken(access_token); | 284 token_store->SetToken(access_token); |
283 robot_email_ = robot_email; | 285 robot_email_ = robot_email; |
284 // Let the frontend know that we have authenticated. | 286 // Let the frontend know that we have authenticated. |
285 backend_->frontend_loop_->PostTask( | 287 backend_->frontend_loop_->task_runner()->PostTask( |
286 FROM_HERE, | 288 FROM_HERE, |
287 base::Bind(&Core::NotifyAuthenticated, this, robot_oauth_refresh_token, | 289 base::Bind(&Core::NotifyAuthenticated, this, robot_oauth_refresh_token, |
288 robot_email, user_email)); | 290 robot_email, user_email)); |
289 if (first_time) { | 291 if (first_time) { |
290 InitNotifications(robot_email, access_token); | 292 InitNotifications(robot_email, access_token); |
291 } else { | 293 } else { |
292 // If we are refreshing a token, update the XMPP token too. | 294 // If we are refreshing a token, update the XMPP token too. |
293 DCHECK(push_client_.get()); | 295 DCHECK(push_client_.get()); |
294 push_client_->UpdateCredentials(robot_email, access_token); | 296 push_client_->UpdateCredentials(robot_email, access_token); |
295 } | 297 } |
296 // Start cloud print connector if needed. | 298 // Start cloud print connector if needed. |
297 if (!connector_->IsRunning()) { | 299 if (!connector_->IsRunning()) { |
298 if (!connector_->Start()) { | 300 if (!connector_->Start()) { |
299 // Let the frontend know that we do not have a print system. | 301 // Let the frontend know that we do not have a print system. |
300 backend_->frontend_loop_->PostTask( | 302 backend_->frontend_loop_->task_runner()->PostTask( |
301 FROM_HERE, base::Bind(&Core::NotifyPrintSystemUnavailable, this)); | 303 FROM_HERE, base::Bind(&Core::NotifyPrintSystemUnavailable, this)); |
302 } | 304 } |
303 } | 305 } |
304 } | 306 } |
305 | 307 |
306 void CloudPrintProxyBackend::Core::OnInvalidCredentials() { | 308 void CloudPrintProxyBackend::Core::OnInvalidCredentials() { |
307 DCHECK(base::MessageLoop::current() == backend_->core_thread_.message_loop()); | 309 DCHECK(base::MessageLoop::current() == backend_->core_thread_.message_loop()); |
308 VLOG(1) << "CP_CONNECTOR: Auth Error"; | 310 VLOG(1) << "CP_CONNECTOR: Auth Error"; |
309 backend_->frontend_loop_->PostTask( | 311 backend_->frontend_loop_->task_runner()->PostTask( |
310 FROM_HERE, base::Bind(&Core::NotifyAuthenticationFailed, this)); | 312 FROM_HERE, base::Bind(&Core::NotifyAuthenticationFailed, this)); |
311 } | 313 } |
312 | 314 |
313 void CloudPrintProxyBackend::Core::OnAuthFailed() { | 315 void CloudPrintProxyBackend::Core::OnAuthFailed() { |
314 VLOG(1) << "CP_CONNECTOR: Authentication failed in connector."; | 316 VLOG(1) << "CP_CONNECTOR: Authentication failed in connector."; |
315 // Let's stop connecter and refresh token. We'll restart connecter once | 317 // Let's stop connecter and refresh token. We'll restart connecter once |
316 // new token available. | 318 // new token available. |
317 if (connector_->IsRunning()) | 319 if (connector_->IsRunning()) |
318 connector_->Stop(); | 320 connector_->Stop(); |
319 | 321 |
320 // Refresh Auth token. | 322 // Refresh Auth token. |
321 auth_->RefreshAccessToken(); | 323 auth_->RefreshAccessToken(); |
322 } | 324 } |
323 | 325 |
324 void CloudPrintProxyBackend::Core::OnXmppPingUpdated(int ping_timeout) { | 326 void CloudPrintProxyBackend::Core::OnXmppPingUpdated(int ping_timeout) { |
325 settings_.SetXmppPingTimeoutSec(ping_timeout); | 327 settings_.SetXmppPingTimeoutSec(ping_timeout); |
326 backend_->frontend_loop_->PostTask( | 328 backend_->frontend_loop_->task_runner()->PostTask( |
327 FROM_HERE, | 329 FROM_HERE, base::Bind(&Core::NotifyXmppPingUpdated, this, ping_timeout)); |
328 base::Bind(&Core::NotifyXmppPingUpdated, this, ping_timeout)); | |
329 } | 330 } |
330 | 331 |
331 void CloudPrintProxyBackend::Core::InitNotifications( | 332 void CloudPrintProxyBackend::Core::InitNotifications( |
332 const std::string& robot_email, | 333 const std::string& robot_email, |
333 const std::string& access_token) { | 334 const std::string& access_token) { |
334 DCHECK(base::MessageLoop::current() == backend_->core_thread_.message_loop()); | 335 DCHECK(base::MessageLoop::current() == backend_->core_thread_.message_loop()); |
335 | 336 |
336 pending_xmpp_pings_ = 0; | 337 pending_xmpp_pings_ = 0; |
337 notifier::NotifierOptions notifier_options; | 338 notifier::NotifierOptions notifier_options; |
338 notifier_options.request_context_getter = | 339 notifier_options.request_context_getter = |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
372 } | 373 } |
373 | 374 |
374 void CloudPrintProxyBackend::Core::DoUnregisterPrinters() { | 375 void CloudPrintProxyBackend::Core::DoUnregisterPrinters() { |
375 DCHECK(base::MessageLoop::current() == backend_->core_thread_.message_loop()); | 376 DCHECK(base::MessageLoop::current() == backend_->core_thread_.message_loop()); |
376 | 377 |
377 std::string access_token = GetTokenStore()->token(); | 378 std::string access_token = GetTokenStore()->token(); |
378 | 379 |
379 std::list<std::string> printer_ids; | 380 std::list<std::string> printer_ids; |
380 connector_->GetPrinterIds(&printer_ids); | 381 connector_->GetPrinterIds(&printer_ids); |
381 | 382 |
382 backend_->frontend_loop_->PostTask( | 383 backend_->frontend_loop_->task_runner()->PostTask( |
383 FROM_HERE, | 384 FROM_HERE, base::Bind(&Core::NotifyUnregisterPrinters, this, access_token, |
384 base::Bind(&Core::NotifyUnregisterPrinters, | 385 printer_ids)); |
385 this, access_token, printer_ids)); | |
386 } | 386 } |
387 | 387 |
388 void CloudPrintProxyBackend::Core::HandlePrinterNotification( | 388 void CloudPrintProxyBackend::Core::HandlePrinterNotification( |
389 const std::string& notification) { | 389 const std::string& notification) { |
390 DCHECK(base::MessageLoop::current() == backend_->core_thread_.message_loop()); | 390 DCHECK(base::MessageLoop::current() == backend_->core_thread_.message_loop()); |
391 | 391 |
392 size_t pos = notification.rfind(kNotificationUpdateSettings); | 392 size_t pos = notification.rfind(kNotificationUpdateSettings); |
393 if (pos == std::string::npos) { | 393 if (pos == std::string::npos) { |
394 VLOG(1) << "CP_CONNECTOR: Handle printer notification, id: " | 394 VLOG(1) << "CP_CONNECTOR: Handle printer notification, id: " |
395 << notification; | 395 << notification; |
(...skipping 16 matching lines...) Expand all Loading... |
412 // If we don't have notifications and job polling is enabled, poll again | 412 // If we don't have notifications and job polling is enabled, poll again |
413 // after a while. | 413 // after a while. |
414 if (!notifications_enabled_ && enable_job_poll_) | 414 if (!notifications_enabled_ && enable_job_poll_) |
415 ScheduleJobPoll(); | 415 ScheduleJobPoll(); |
416 } | 416 } |
417 | 417 |
418 void CloudPrintProxyBackend::Core::ScheduleJobPoll() { | 418 void CloudPrintProxyBackend::Core::ScheduleJobPoll() { |
419 if (!job_poll_scheduled_) { | 419 if (!job_poll_scheduled_) { |
420 base::TimeDelta interval = base::TimeDelta::FromSeconds( | 420 base::TimeDelta interval = base::TimeDelta::FromSeconds( |
421 base::RandInt(kMinJobPollIntervalSecs, kMaxJobPollIntervalSecs)); | 421 base::RandInt(kMinJobPollIntervalSecs, kMaxJobPollIntervalSecs)); |
422 base::MessageLoop::current()->PostDelayedTask( | 422 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
423 FROM_HERE, | 423 FROM_HERE, base::Bind(&CloudPrintProxyBackend::Core::PollForJobs, this), |
424 base::Bind(&CloudPrintProxyBackend::Core::PollForJobs, this), | |
425 interval); | 424 interval); |
426 job_poll_scheduled_ = true; | 425 job_poll_scheduled_ = true; |
427 } | 426 } |
428 } | 427 } |
429 | 428 |
430 void CloudPrintProxyBackend::Core::PingXmppServer() { | 429 void CloudPrintProxyBackend::Core::PingXmppServer() { |
431 xmpp_ping_scheduled_ = false; | 430 xmpp_ping_scheduled_ = false; |
432 | 431 |
433 if (!push_client_.get()) | 432 if (!push_client_.get()) |
434 return; | 433 return; |
435 | 434 |
436 push_client_->SendPing(); | 435 push_client_->SendPing(); |
437 | 436 |
438 pending_xmpp_pings_++; | 437 pending_xmpp_pings_++; |
439 if (pending_xmpp_pings_ >= kMaxFailedXmppPings) { | 438 if (pending_xmpp_pings_ >= kMaxFailedXmppPings) { |
440 // Check ping status when we close to the limit. | 439 // Check ping status when we close to the limit. |
441 base::MessageLoop::current()->PostDelayedTask( | 440 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
442 FROM_HERE, | 441 FROM_HERE, |
443 base::Bind(&CloudPrintProxyBackend::Core::CheckXmppPingStatus, this), | 442 base::Bind(&CloudPrintProxyBackend::Core::CheckXmppPingStatus, this), |
444 base::TimeDelta::FromSeconds(kXmppPingCheckIntervalSecs)); | 443 base::TimeDelta::FromSeconds(kXmppPingCheckIntervalSecs)); |
445 } | 444 } |
446 | 445 |
447 // Schedule next ping if needed. | 446 // Schedule next ping if needed. |
448 if (notifications_enabled_) | 447 if (notifications_enabled_) |
449 ScheduleXmppPing(); | 448 ScheduleXmppPing(); |
450 } | 449 } |
451 | 450 |
452 void CloudPrintProxyBackend::Core::ScheduleXmppPing() { | 451 void CloudPrintProxyBackend::Core::ScheduleXmppPing() { |
453 // settings_.xmpp_ping_enabled() is obsolete, we are now control | 452 // settings_.xmpp_ping_enabled() is obsolete, we are now control |
454 // XMPP pings from Cloud Print server. | 453 // XMPP pings from Cloud Print server. |
455 if (!xmpp_ping_scheduled_) { | 454 if (!xmpp_ping_scheduled_) { |
456 base::TimeDelta interval = base::TimeDelta::FromSeconds( | 455 base::TimeDelta interval = base::TimeDelta::FromSeconds( |
457 base::RandInt(settings_.xmpp_ping_timeout_sec() * 0.9, | 456 base::RandInt(settings_.xmpp_ping_timeout_sec() * 0.9, |
458 settings_.xmpp_ping_timeout_sec() * 1.1)); | 457 settings_.xmpp_ping_timeout_sec() * 1.1)); |
459 base::MessageLoop::current()->PostDelayedTask( | 458 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
460 FROM_HERE, | 459 FROM_HERE, |
461 base::Bind(&CloudPrintProxyBackend::Core::PingXmppServer, this), | 460 base::Bind(&CloudPrintProxyBackend::Core::PingXmppServer, this), |
462 interval); | 461 interval); |
463 xmpp_ping_scheduled_ = true; | 462 xmpp_ping_scheduled_ = true; |
464 } | 463 } |
465 } | 464 } |
466 | 465 |
467 void CloudPrintProxyBackend::Core::CheckXmppPingStatus() { | 466 void CloudPrintProxyBackend::Core::CheckXmppPingStatus() { |
468 if (pending_xmpp_pings_ >= kMaxFailedXmppPings) { | 467 if (pending_xmpp_pings_ >= kMaxFailedXmppPings) { |
469 UMA_HISTOGRAM_COUNTS_100("CloudPrint.XmppPingTry", 99); // Max on fail. | 468 UMA_HISTOGRAM_COUNTS_100("CloudPrint.XmppPingTry", 99); // Max on fail. |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
556 HandlePrinterNotification(notification.data); | 555 HandlePrinterNotification(notification.data); |
557 } | 556 } |
558 | 557 |
559 void CloudPrintProxyBackend::Core::OnPingResponse() { | 558 void CloudPrintProxyBackend::Core::OnPingResponse() { |
560 UMA_HISTOGRAM_COUNTS_100("CloudPrint.XmppPingTry", pending_xmpp_pings_); | 559 UMA_HISTOGRAM_COUNTS_100("CloudPrint.XmppPingTry", pending_xmpp_pings_); |
561 pending_xmpp_pings_ = 0; | 560 pending_xmpp_pings_ = 0; |
562 VLOG(1) << "CP_CONNECTOR: Ping response received."; | 561 VLOG(1) << "CP_CONNECTOR: Ping response received."; |
563 } | 562 } |
564 | 563 |
565 } // namespace cloud_print | 564 } // namespace cloud_print |
OLD | NEW |