| 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 |