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..c598437807b73b6fb3c6685ce2edb764099b252d 100644 |
--- a/chrome/browser/chromeos/policy/heartbeat_scheduler.cc |
+++ b/chrome/browser/chromeos/policy/heartbeat_scheduler.cc |
@@ -27,15 +27,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 = |
+ "7"; // START | DISCONNECTED | HEARTBEAT |
+ |
+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 +224,13 @@ 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)) { |
heartbeat_interval_ = EnsureValidHeartbeatInterval( |
base::TimeDelta::FromMilliseconds(frequency)); |
+ } |
+ |
+ gcm_driver_->AddHeartbeatInterval(kHeartbeatSchedulerScope, |
+ heartbeat_interval_.InMilliseconds()); |
bool enabled; |
if (settings->GetBoolean(chromeos::kHeartbeatEnabled, &enabled)) |
@@ -241,7 +257,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 +292,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 +327,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 +348,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 +360,24 @@ void HeartbeatScheduler::SendHeartbeat() { |
weak_factory_.GetWeakPtr())); |
} |
+void HeartbeatScheduler::SignUpUpstreamNotification() { |
+ DCHECK(gcm_driver_); |
+ |
+ if (registration_id_.empty()) |
+ 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 +389,14 @@ 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; |
+} |
+ |
HeartbeatScheduler::~HeartbeatScheduler() { |
ShutdownGCM(); |
} |
@@ -385,6 +431,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"; |