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..a78bbe291def0f700f5a1563835f621a977cad8e 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" |
| @@ -88,6 +90,7 @@ class CloudPrintProxyBackend::Core |
| notifier::NotificationsDisabledReason reason) OVERRIDE; |
| virtual void OnIncomingNotification( |
| const notifier::Notification& notification) OVERRIDE; |
| + virtual void OnPingResponse() OVERRIDE; |
| private: |
| friend class base::RefCountedThreadSafe<Core>; |
| @@ -119,6 +122,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 +150,13 @@ 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 a task to ping xmpp server has been scheduled. |
| + bool xmpp_ping_scheduled_; |
| + // Number of XMPP pings pending reply from the server. |
| + int pending_xmpp_pings_; |
| // Connector settings. |
| ConnectorSettings settings_; |
| + std::string robot_email_; |
| scoped_ptr<CloudPrintTokenStore> token_store_; |
| DISALLOW_COPY_AND_ASSIGN(Core); |
| @@ -240,7 +252,9 @@ 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_scheduled_(false), |
| + pending_xmpp_pings_(kDefaultXmppPingTimeoutSecs) { |
|
akalin
2012/10/25 00:10:13
is this really the right constant to use?
gene
2012/10/25 00:43:26
Good catch! Too many redesigns :)
|
| settings_.CopyFrom(settings); |
| } |
| @@ -305,6 +319,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 +365,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 +446,53 @@ void CloudPrintProxyBackend::Core::ScheduleJobPoll() { |
| } |
| } |
| +void CloudPrintProxyBackend::Core::PingXmppServer() { |
| + xmpp_ping_scheduled_ = false; |
| + |
| + if (!push_client_.get()) |
| + return; |
| + |
| + push_client_->SendPing(); |
| + |
| + pending_xmpp_pings_++; |
| + if (pending_xmpp_pings_ >= kMaxFailedXmppPings) { |
| + // Check ping status is we a close to the limit. |
|
akalin
2012/10/25 00:10:13
fix typos in comment
gene
2012/10/25 00:43:26
Done.
|
| + 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 (!settings_.xmpp_ping_enabled()) |
| + return; |
| + |
| + if (!xmpp_ping_scheduled_) { |
| + base::TimeDelta interval = base::TimeDelta::FromSeconds( |
| + base::RandInt(settings_.xmpp_ping_timeout_sec() * 0.9, |
|
akalin
2012/10/25 00:10:13
might want to do an additive interval, since if th
gene
2012/10/25 00:43:26
Actually there is a minimal timeout value that sho
|
| + settings_.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 +539,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 +560,10 @@ void CloudPrintProxyBackend::Core::OnNotificationsDisabled( |
| void CloudPrintProxyBackend::Core::OnIncomingNotification( |
| const notifier::Notification& notification) { |
| + // Since we got some notification from the server, |
| + // reset pending ping counter to 0. |
| + pending_xmpp_pings_ = 0; |
| + |
| DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop()); |
| VLOG(1) << "CP_CONNECTOR: Incoming notification."; |
| if (0 == base::strcasecmp(kCloudPrintPushNotificationsSource, |
| @@ -501,3 +571,8 @@ void CloudPrintProxyBackend::Core::OnIncomingNotification( |
| HandlePrinterNotification(notification.data); |
| } |
| +void CloudPrintProxyBackend::Core::OnPingResponse() { |
| + pending_xmpp_pings_ = 0; |
| + VLOG(1) << "CP_CONNECTOR: Ping response received."; |
| +} |
| + |