Chromium Code Reviews| Index: chrome/service/cloud_print/cloud_print_proxy_backend.cc |
| diff --git a/chrome/service/cloud_print/cloud_print_proxy_backend.cc b/chrome/service/cloud_print/cloud_print_proxy_backend.cc |
| index 16d7211f39ed6a2a3b007e7def6bdd0e6addfc67..d2760e516253c8783c8a185abc85885e24341e36 100644 |
| --- a/chrome/service/cloud_print/cloud_print_proxy_backend.cc |
| +++ b/chrome/service/cloud_print/cloud_print_proxy_backend.cc |
| @@ -8,10 +8,12 @@ |
| #include <vector> |
| #include "base/bind.h" |
| +#include "base/command_line.h" |
| #include "base/compiler_specific.h" |
| #include "base/file_util.h" |
| #include "base/rand_util.h" |
| #include "base/values.h" |
| +#include "chrome/common/chrome_switches.h" |
| #include "chrome/service/cloud_print/cloud_print_auth.h" |
| #include "chrome/service/cloud_print/cloud_print_connector.h" |
| #include "chrome/service/cloud_print/cloud_print_consts.h" |
| @@ -119,6 +121,10 @@ class CloudPrintProxyBackend::Core |
| // Schedules a task to poll for jobs. Does nothing if a task is already |
| // scheduled. |
| void ScheduleJobPoll(); |
| + void PingXmppServer(); |
| + void ScheduleXmppPing(); |
| + void CheckXmppPingStatus(); |
| + |
| CloudPrintTokenStore* GetTokenStore(); |
| // Our parent CloudPrintProxyBackend |
| @@ -143,8 +149,17 @@ class CloudPrintProxyBackend::Core |
| bool job_poll_scheduled_; |
| // Indicates whether we should poll for jobs when we lose XMPP connection. |
| bool enable_job_poll_; |
| + // Indicates whether we should ping XMPP connection. |
| + bool xmpp_ping_enabled_; |
| + // Indicates timeout between XMPP pings. ) if XMPP pings are disabled. |
|
Vitaly Buka (NO REVIEWS)
2012/10/22 20:52:53
")"?
gene
2012/10/22 21:44:12
Done.
|
| + int xmpp_ping_timeout_sec_; |
| + // Indicates whether a task to ping xmpp server has been scheduled. |
| + bool xmpp_ping_scheduled_; |
|
Vitaly Buka (NO REVIEWS)
2012/10/22 20:52:53
you should use xmpp_ping_timeout_sec_ and xmpp_pin
gene
2012/10/22 21:44:12
unfortunately not :(.
current run-time settings ma
|
| + // Number of XMPP pings pending reply from the server. |
| + int pending_xmpp_pings_; |
| // Connector settings. |
| ConnectorSettings settings_; |
| + std::string robot_email_; |
|
Vitaly Buka (NO REVIEWS)
2012/10/22 20:52:53
Not sure, but maybe better solution if you remove
gene
2012/10/22 21:44:12
not sure what you mean here, lets discuss offline
|
| scoped_ptr<CloudPrintTokenStore> token_store_; |
| DISALLOW_COPY_AND_ASSIGN(Core); |
| @@ -240,8 +255,18 @@ CloudPrintProxyBackend::Core::Core( |
| oauth_client_info_(oauth_client_info), |
| notifications_enabled_(false), |
| job_poll_scheduled_(false), |
| - enable_job_poll_(enable_job_poll) { |
| + enable_job_poll_(enable_job_poll), |
| + xmpp_ping_timeout_sec_(0), |
| + xmpp_ping_scheduled_(false), |
| + xmpp_ping_enabled_(false), |
| + pending_xmpp_pings_(kDefaultXmppPingTimeoutSecs) { |
| settings_.CopyFrom(settings); |
| + xmpp_ping_enabled_ = settings_.xmpp_ping_enabled(); |
| + xmpp_ping_timeout_sec_ = settings_.xmpp_ping_timeout_sec(); |
| + if (xmpp_ping_timeout_sec_ < kMinimumXmppPingTimeoutSecs) { |
| + VLOG(1) << "CP_CONNECTOR: XMPP ping timeout is less then minimal value"; |
|
Vitaly Buka (NO REVIEWS)
2012/10/22 20:52:53
LOG(WARNING) ?
Vitaly Buka (NO REVIEWS)
2012/10/22 20:52:53
ConnectorSettings::InitFrom is best place to valid
gene
2012/10/22 21:44:12
Done.
|
| + xmpp_ping_timeout_sec_ = kMinimumXmppPingTimeoutSecs; |
| + } |
| } |
| void CloudPrintProxyBackend::Core::CreateAuthAndConnector() { |
| @@ -305,6 +330,7 @@ void CloudPrintProxyBackend::Core::OnAuthenticationComplete( |
| CloudPrintTokenStore* token_store = GetTokenStore(); |
| bool first_time = token_store->token().empty(); |
| token_store->SetToken(access_token); |
| + robot_email_ = robot_email; |
| // Let the frontend know that we have authenticated. |
| backend_->frontend_loop_->PostTask( |
| FROM_HERE, |
| @@ -350,6 +376,7 @@ void CloudPrintProxyBackend::Core::InitNotifications( |
| const std::string& access_token) { |
| DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop()); |
| + pending_xmpp_pings_ = 0; |
| notifier::NotifierOptions notifier_options; |
| notifier_options.request_context_getter = |
| g_service_process->GetServiceURLRequestContextGetter(); |
| @@ -430,6 +457,55 @@ void CloudPrintProxyBackend::Core::ScheduleJobPoll() { |
| } |
| } |
| +void CloudPrintProxyBackend::Core::PingXmppServer() { |
| + xmpp_ping_scheduled_ = false; |
| + |
| + if (!push_client_.get()) |
| + return; |
| + |
| + notifier::Notification notification; |
| + notification.ping = true; |
| + push_client_->SendNotification(notification); |
| + |
| + pending_xmpp_pings_++; |
| + if (pending_xmpp_pings_ >= kMaxFailedXmppPings) { |
| + // Check ping status is we a close to the limit. |
| + MessageLoop::current()->PostDelayedTask( |
| + FROM_HERE, |
| + base::Bind(&CloudPrintProxyBackend::Core::CheckXmppPingStatus, this), |
| + base::TimeDelta::FromSeconds(kXmppPingCheckIntervalSecs)); |
| + } |
| + |
| + // Schedule next ping if needed. |
| + if (notifications_enabled_) |
| + ScheduleXmppPing(); |
| +} |
| + |
| +void CloudPrintProxyBackend::Core::ScheduleXmppPing() { |
| + if (!xmpp_ping_enabled_) |
| + return; |
| + |
| + if (!xmpp_ping_scheduled_) { |
| + base::TimeDelta interval = base::TimeDelta::FromSeconds( |
| + base::RandInt(xmpp_ping_timeout_sec_ * 0.9, |
| + xmpp_ping_timeout_sec_ * 1.1)); |
| + MessageLoop::current()->PostDelayedTask( |
| + FROM_HERE, |
| + base::Bind(&CloudPrintProxyBackend::Core::PingXmppServer, this), |
| + interval); |
| + xmpp_ping_scheduled_ = true; |
| + } |
| +} |
| + |
| +void CloudPrintProxyBackend::Core::CheckXmppPingStatus() { |
| + if (pending_xmpp_pings_ >= kMaxFailedXmppPings) { |
| + // Reconnect to XMPP. |
| + pending_xmpp_pings_ = 0; |
| + push_client_.reset(); |
| + InitNotifications(robot_email_, GetTokenStore()->token()); |
| + } |
| +} |
| + |
| CloudPrintTokenStore* CloudPrintProxyBackend::Core::GetTokenStore() { |
| DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop()); |
| if (!token_store_.get()) |
| @@ -476,6 +552,9 @@ void CloudPrintProxyBackend::Core::OnNotificationsEnabled() { |
| // Note that ScheduleJobPoll will not schedule again if a job poll task is |
| // already scheduled. |
| ScheduleJobPoll(); |
| + |
| + // Schedule periodic ping for XMPP notification channel. |
| + ScheduleXmppPing(); |
| } |
| void CloudPrintProxyBackend::Core::OnNotificationsDisabled( |
| @@ -494,6 +573,15 @@ void CloudPrintProxyBackend::Core::OnNotificationsDisabled( |
| void CloudPrintProxyBackend::Core::OnIncomingNotification( |
| const notifier::Notification& notification) { |
| + // Since we got some notification from the server (message or ping), |
| + // reset pending ping counter to 0. |
| + pending_xmpp_pings_ = 0; |
| + |
| + if (notification.ping) { |
| + VLOG(1) << "CP_CONNECTOR: Ping notification received."; |
| + return; |
| + } |
| + |
| DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop()); |
| VLOG(1) << "CP_CONNECTOR: Incoming notification."; |
| if (0 == base::strcasecmp(kCloudPrintPushNotificationsSource, |