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