Chromium Code Reviews| Index: chrome/browser/chromeos/policy/heartbeat_scheduler.cc |
| diff --git a/chrome/browser/chromeos/policy/heartbeat_scheduler.cc b/chrome/browser/chromeos/policy/heartbeat_scheduler.cc |
| index a9109649dd59ef2996603b2b0f252dc59fa7615e..8473e8fef6e9af3e2ca8693bdcbfc136c40e1138 100644 |
| --- a/chrome/browser/chromeos/policy/heartbeat_scheduler.cc |
| +++ b/chrome/browser/chromeos/policy/heartbeat_scheduler.cc |
| @@ -20,6 +20,9 @@ namespace { |
| const int kMinHeartbeatIntervalMs = 30 * 1000; // 30 seconds |
| const int kMaxHeartbeatIntervalMs = 24 * 60 * 60 * 1000; // 24 hours |
| +// Minimum time between two consecutive upstream notification signs up. |
| +const int kMinimumSignupIntervalMs = 3 * 60 * 1000; |
| + |
| // Our sender ID we send up with all of our GCM messages. |
| const char* kHeartbeatGCMAppID = "com.google.chromeos.monitoring"; |
| @@ -27,15 +30,27 @@ const char* kHeartbeatGCMAppID = "com.google.chromeos.monitoring"; |
| const char* kHeartbeatGCMDestinationID = "1013309121859"; |
| const char* kHeartbeatGCMSenderSuffix = "@google.com"; |
| -const char* kMonitoringMessageTypeKey = "type"; |
| +// Destination of upstream notification sign up message. |
| +const char* kUpstreamNotificationSignUpDestinationID = |
| + "https://gcm.googleapis.com/gcm/gcm.event_tracker"; |
| + |
| +// A bit mask, listening events of upstream notification. |
| +const char* kUpstreamNotificationSignUpListeningEvents = |
| + "3"; // START | DISCONNECTED |
| + |
| +const char* kGcmMessageTypeKey = "type"; |
| const char* kHeartbeatTimestampKey = "timestamp"; |
| const char* kHeartbeatDomainNameKey = "domain_name"; |
| const char* kHeartbeatDeviceIDKey = "device_id"; |
| const char* kHeartbeatTypeValue = "hb"; |
| +const char* kUpstreamNotificationNotifyKey = "notify"; |
| // If we get an error registering with GCM, try again in two minutes. |
| const int64 kRegistrationRetryDelayMs = 2 * 60 * 1000; |
| +const char* kHeartbeatSchedulerScope = |
| + "policy.heartbeat_scheduler.upstream_notification"; |
| + |
| // Returns the destination ID for GCM heartbeats. |
| std::string GetDestinationID() { |
| std::string receiver_id = kHeartbeatGCMDestinationID; |
| @@ -212,9 +227,12 @@ void HeartbeatScheduler::RefreshHeartbeatSettings() { |
| // value because CrosSettings can become untrusted at arbitrary times and we |
| // want to use the last trusted value). |
| int frequency; |
| - if (settings->GetInteger(chromeos::kHeartbeatFrequency, &frequency)) |
| + if (settings->GetInteger(chromeos::kHeartbeatFrequency, &frequency)) { |
|
Andrew T Wilson (Slow)
2015/11/20 16:37:34
So, shouldn't we call AddHeartbeatInterval() even
binjin
2015/11/20 22:56:48
Done.
|
| heartbeat_interval_ = EnsureValidHeartbeatInterval( |
| base::TimeDelta::FromMilliseconds(frequency)); |
| + gcm_driver_->AddHeartbeatInterval(kHeartbeatSchedulerScope, |
| + heartbeat_interval_.InMilliseconds()); |
| + } |
| bool enabled; |
| if (settings->GetBoolean(chromeos::kHeartbeatEnabled, &enabled)) |
| @@ -241,7 +259,9 @@ void HeartbeatScheduler::ShutdownGCM() { |
| registration_id_.clear(); |
| if (registered_app_handler_) { |
| registered_app_handler_ = false; |
| + gcm_driver_->RemoveHeartbeatInterval(kHeartbeatSchedulerScope); |
| gcm_driver_->RemoveAppHandler(kHeartbeatGCMAppID); |
| + gcm_driver_->RemoveConnectionObserver(this); |
| } |
| } |
| @@ -274,6 +294,7 @@ void HeartbeatScheduler::ScheduleNextHeartbeat() { |
| // a GCM connection. |
| registered_app_handler_ = true; |
| gcm_driver_->AddAppHandler(kHeartbeatGCMAppID, this); |
| + gcm_driver_->AddConnectionObserver(this); |
| registration_helper_.reset(new HeartbeatRegistrationHelper( |
| gcm_driver_, task_runner_)); |
| registration_helper_->Register( |
| @@ -308,6 +329,7 @@ void HeartbeatScheduler::OnRegistrationComplete( |
| registration_id, |
| base::Bind(&HeartbeatScheduler::OnGcmIdUpdateRequestSent, |
| weak_factory_.GetWeakPtr())); |
| + SignUpUpstreamNotification(); |
| } |
| // Now that GCM registration is complete, start sending heartbeats. |
| @@ -328,7 +350,7 @@ void HeartbeatScheduler::SendHeartbeat() { |
| // https://developer.chrome.com/apps/cloudMessaging#send_messages |
| message.id = base::Int64ToString( |
| base::Time::NowFromSystemTime().ToInternalValue()); |
| - message.data[kMonitoringMessageTypeKey] = kHeartbeatTypeValue; |
| + message.data[kGcmMessageTypeKey] = kHeartbeatTypeValue; |
| message.data[kHeartbeatTimestampKey] = base::Int64ToString( |
| base::Time::NowFromSystemTime().ToJavaTime()); |
| message.data[kHeartbeatDomainNameKey] = enrollment_domain_; |
| @@ -340,6 +362,33 @@ void HeartbeatScheduler::SendHeartbeat() { |
| weak_factory_.GetWeakPtr())); |
| } |
| +void HeartbeatScheduler::SignUpUpstreamNotification() { |
| + DCHECK(gcm_driver_); |
| + |
| + if (registration_id_.empty()) |
| + return; |
| + |
| + base::TimeDelta since_last_sign_up = |
|
Andrew T Wilson (Slow)
2015/11/20 16:37:34
Let's just remove this logic + the member var last
binjin
2015/11/20 22:56:48
Done.
|
| + base::TimeTicks::Now() - last_upstream_notification_signup_time_; |
| + |
| + if (!last_upstream_notification_signup_time_.is_null() && |
| + since_last_sign_up < |
| + base::TimeDelta::FromMilliseconds(kMinimumSignupIntervalMs)) { |
| + return; |
| + } |
| + |
| + gcm::OutgoingMessage message; |
| + message.id = |
| + base::Int64ToString(base::Time::NowFromSystemTime().ToInternalValue()); |
| + message.data[kGcmMessageTypeKey] = kUpstreamNotificationSignUpListeningEvents; |
| + message.data[kUpstreamNotificationNotifyKey] = |
| + GetDestinationID() + kHeartbeatGCMSenderSuffix; |
| + gcm_driver_->Send(kHeartbeatGCMAppID, |
| + kUpstreamNotificationSignUpDestinationID, message, |
| + base::Bind(&HeartbeatScheduler::OnUpstreamNotificationSent, |
| + weak_factory_.GetWeakPtr())); |
| +} |
| + |
| void HeartbeatScheduler::OnHeartbeatSent(const std::string& message_id, |
| gcm::GCMClient::Result result) { |
| DVLOG(1) << "Monitoring heartbeat sent - result = " << result; |
| @@ -351,6 +400,15 @@ void HeartbeatScheduler::OnHeartbeatSent(const std::string& message_id, |
| ScheduleNextHeartbeat(); |
| } |
| +void HeartbeatScheduler::OnUpstreamNotificationSent( |
| + const std::string& message_id, |
| + gcm::GCMClient::Result result) { |
| + DVLOG(1) << "Upstream notification signup message sent - result = " << result; |
| + DLOG_IF(ERROR, result != gcm::GCMClient::SUCCESS) |
| + << "Error sending upstream notification signup message: " << result; |
| + last_upstream_notification_signup_time_ = base::TimeTicks::Now(); |
| +} |
| + |
| HeartbeatScheduler::~HeartbeatScheduler() { |
| ShutdownGCM(); |
| } |
| @@ -385,6 +443,10 @@ void HeartbeatScheduler::OnSendAcknowledged(const std::string& app_id, |
| DVLOG(1) << "Heartbeat sent with message_id: " << message_id; |
| } |
| +void HeartbeatScheduler::OnConnected(const net::IPEndPoint&) { |
| + SignUpUpstreamNotification(); |
| +} |
| + |
| void HeartbeatScheduler::OnGcmIdUpdateRequestSent(bool success) { |
| // TODO(binjin): Handle the failure, probably by exponential backoff. |
| LOG_IF(WARNING, !success) << "Failed to send GCM id to DM server"; |