| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "google_apis/gcm/engine/heartbeat_manager.h" | 5 #include "google_apis/gcm/engine/heartbeat_manager.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/callback.h" | 9 #include "base/callback.h" |
| 10 #include "base/location.h" | 10 #include "base/location.h" |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 64 DCHECK(!send_heartbeat_callback.is_null()); | 64 DCHECK(!send_heartbeat_callback.is_null()); |
| 65 DCHECK(!trigger_reconnect_callback.is_null()); | 65 DCHECK(!trigger_reconnect_callback.is_null()); |
| 66 send_heartbeat_callback_ = send_heartbeat_callback; | 66 send_heartbeat_callback_ = send_heartbeat_callback; |
| 67 trigger_reconnect_callback_ = trigger_reconnect_callback; | 67 trigger_reconnect_callback_ = trigger_reconnect_callback; |
| 68 | 68 |
| 69 // Listen for system suspend and resume events. | 69 // Listen for system suspend and resume events. |
| 70 base::PowerMonitor* monitor = base::PowerMonitor::Get(); | 70 base::PowerMonitor* monitor = base::PowerMonitor::Get(); |
| 71 if (monitor) | 71 if (monitor) |
| 72 monitor->AddObserver(this); | 72 monitor->AddObserver(this); |
| 73 | 73 |
| 74 // Calculated the heartbeat interval just before we start the timer. |
| 75 UpdateHeartbeatInterval(); |
| 76 |
| 74 // Kicks off the timer. | 77 // Kicks off the timer. |
| 75 waiting_for_ack_ = false; | 78 waiting_for_ack_ = false; |
| 76 RestartTimer(); | 79 RestartTimer(); |
| 77 } | 80 } |
| 78 | 81 |
| 79 void HeartbeatManager::Stop() { | 82 void HeartbeatManager::Stop() { |
| 80 heartbeat_expected_time_ = base::Time(); | 83 heartbeat_expected_time_ = base::Time(); |
| 81 heartbeat_interval_ms_ = 0; | 84 heartbeat_interval_ms_ = 0; |
| 82 heartbeat_timer_->Stop(); | 85 heartbeat_timer_->Stop(); |
| 83 waiting_for_ack_ = false; | 86 waiting_for_ack_ = false; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 99 | 102 |
| 100 void HeartbeatManager::UpdateHeartbeatConfig( | 103 void HeartbeatManager::UpdateHeartbeatConfig( |
| 101 const mcs_proto::HeartbeatConfig& config) { | 104 const mcs_proto::HeartbeatConfig& config) { |
| 102 if (!config.IsInitialized() || | 105 if (!config.IsInitialized() || |
| 103 !config.has_interval_ms() || | 106 !config.has_interval_ms() || |
| 104 config.interval_ms() <= 0) { | 107 config.interval_ms() <= 0) { |
| 105 return; | 108 return; |
| 106 } | 109 } |
| 107 DVLOG(1) << "Updating server heartbeat interval to " << config.interval_ms(); | 110 DVLOG(1) << "Updating server heartbeat interval to " << config.interval_ms(); |
| 108 server_interval_ms_ = config.interval_ms(); | 111 server_interval_ms_ = config.interval_ms(); |
| 112 |
| 113 // Make sure heartbeat interval is recalculated when new server interval is |
| 114 // available. |
| 115 UpdateHeartbeatInterval(); |
| 109 } | 116 } |
| 110 | 117 |
| 111 base::TimeTicks HeartbeatManager::GetNextHeartbeatTime() const { | 118 base::TimeTicks HeartbeatManager::GetNextHeartbeatTime() const { |
| 112 if (heartbeat_timer_->IsRunning()) | 119 if (heartbeat_timer_->IsRunning()) |
| 113 return heartbeat_timer_->desired_run_time(); | 120 return heartbeat_timer_->desired_run_time(); |
| 114 else | 121 else |
| 115 return base::TimeTicks(); | 122 return base::TimeTicks(); |
| 116 } | 123 } |
| 117 | 124 |
| 118 void HeartbeatManager::UpdateHeartbeatTimer(scoped_ptr<base::Timer> timer) { | 125 void HeartbeatManager::UpdateHeartbeatTimer(scoped_ptr<base::Timer> timer) { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 159 ResetConnection(ConnectionFactory::HEARTBEAT_FAILURE); | 166 ResetConnection(ConnectionFactory::HEARTBEAT_FAILURE); |
| 160 return; | 167 return; |
| 161 } | 168 } |
| 162 | 169 |
| 163 waiting_for_ack_ = true; | 170 waiting_for_ack_ = true; |
| 164 RestartTimer(); | 171 RestartTimer(); |
| 165 send_heartbeat_callback_.Run(); | 172 send_heartbeat_callback_.Run(); |
| 166 } | 173 } |
| 167 | 174 |
| 168 void HeartbeatManager::RestartTimer() { | 175 void HeartbeatManager::RestartTimer() { |
| 169 if (!waiting_for_ack_) { | 176 int interval_ms = heartbeat_interval_ms_; |
| 170 // Recalculate the timer interval based network type. | 177 if (waiting_for_ack_) { |
| 171 // Server interval takes precedence over client interval, even if the latter | 178 interval_ms = kHeartbeatAckDefaultMs; |
| 172 // is less. | 179 DVLOG(1) << "Resetting timer for ack within " << interval_ms << " ms."; |
| 173 if (server_interval_ms_ != 0) { | |
| 174 // If a server interval is set, it overrides any local one. | |
| 175 heartbeat_interval_ms_ = server_interval_ms_; | |
| 176 } else if (HasClientHeartbeatInterval()) { | |
| 177 // Client interval might have been adjusted up, which should only take | |
| 178 // effect during a reconnection. | |
| 179 if (client_interval_ms_ < heartbeat_interval_ms_ || | |
| 180 heartbeat_interval_ms_ == 0) { | |
| 181 heartbeat_interval_ms_ = client_interval_ms_; | |
| 182 } | |
| 183 } else { | |
| 184 heartbeat_interval_ms_ = GetDefaultHeartbeatInterval(); | |
| 185 } | |
| 186 DVLOG(1) << "Sending next heartbeat in " | |
| 187 << heartbeat_interval_ms_ << " ms."; | |
| 188 } else { | 180 } else { |
| 189 heartbeat_interval_ms_ = kHeartbeatAckDefaultMs; | 181 DVLOG(1) << "Sending next heartbeat in " << interval_ms << " ms."; |
| 190 DVLOG(1) << "Resetting timer for ack with " | |
| 191 << heartbeat_interval_ms_ << " ms interval."; | |
| 192 } | 182 } |
| 193 | 183 |
| 194 heartbeat_expected_time_ = | 184 heartbeat_expected_time_ = |
| 195 base::Time::Now() + | 185 base::Time::Now() + base::TimeDelta::FromMilliseconds(interval_ms); |
| 196 base::TimeDelta::FromMilliseconds(heartbeat_interval_ms_); | |
| 197 heartbeat_timer_->Start(FROM_HERE, | 186 heartbeat_timer_->Start(FROM_HERE, |
| 198 base::TimeDelta::FromMilliseconds( | 187 base::TimeDelta::FromMilliseconds(interval_ms), |
| 199 heartbeat_interval_ms_), | 188 base::Bind(&HeartbeatManager::OnHeartbeatTriggered, |
| 200 base::Bind(&HeartbeatManager::OnHeartbeatTriggered, | 189 weak_ptr_factory_.GetWeakPtr())); |
| 201 weak_ptr_factory_.GetWeakPtr())); | |
| 202 | 190 |
| 203 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) | 191 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) |
| 204 // Windows, Mac, Android, iOS, and Chrome OS all provide a way to be notified | 192 // Windows, Mac, Android, iOS, and Chrome OS all provide a way to be notified |
| 205 // when the system is suspending or resuming. The only one that does not is | 193 // when the system is suspending or resuming. The only one that does not is |
| 206 // Linux so we need to poll to check for missed heartbeats. | 194 // Linux so we need to poll to check for missed heartbeats. |
| 207 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 195 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| 208 FROM_HERE, | 196 FROM_HERE, |
| 209 base::Bind(&HeartbeatManager::CheckForMissedHeartbeat, | 197 base::Bind(&HeartbeatManager::CheckForMissedHeartbeat, |
| 210 weak_ptr_factory_.GetWeakPtr()), | 198 weak_ptr_factory_.GetWeakPtr()), |
| 211 base::TimeDelta::FromMilliseconds(kHeartbeatMissedCheckMs)); | 199 base::TimeDelta::FromMilliseconds(kHeartbeatMissedCheckMs)); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 228 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) | 216 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) |
| 229 // Otherwise check again later. | 217 // Otherwise check again later. |
| 230 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 218 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| 231 FROM_HERE, | 219 FROM_HERE, |
| 232 base::Bind(&HeartbeatManager::CheckForMissedHeartbeat, | 220 base::Bind(&HeartbeatManager::CheckForMissedHeartbeat, |
| 233 weak_ptr_factory_.GetWeakPtr()), | 221 weak_ptr_factory_.GetWeakPtr()), |
| 234 base::TimeDelta::FromMilliseconds(kHeartbeatMissedCheckMs)); | 222 base::TimeDelta::FromMilliseconds(kHeartbeatMissedCheckMs)); |
| 235 #endif // defined(OS_LINUX) && !defined(OS_CHROMEOS) | 223 #endif // defined(OS_LINUX) && !defined(OS_CHROMEOS) |
| 236 } | 224 } |
| 237 | 225 |
| 226 void HeartbeatManager::UpdateHeartbeatInterval() { |
| 227 // Server interval takes precedence over client interval, even if the latter |
| 228 // is less. |
| 229 if (server_interval_ms_ != 0) { |
| 230 // If a server interval is set, it overrides any local one. |
| 231 heartbeat_interval_ms_ = server_interval_ms_; |
| 232 } else if (HasClientHeartbeatInterval() && |
| 233 (client_interval_ms_ < heartbeat_interval_ms_ || |
| 234 heartbeat_interval_ms_ == 0)) { |
| 235 // Client interval might have been adjusted up, which should only take |
| 236 // effect during a reconnection. |
| 237 heartbeat_interval_ms_ = client_interval_ms_; |
| 238 } else if (heartbeat_interval_ms_ == 0) { |
| 239 // If interval is still 0, recalculate it based on network type. |
| 240 heartbeat_interval_ms_ = GetDefaultHeartbeatInterval(); |
| 241 } |
| 242 DCHECK_GT(heartbeat_interval_ms_, 0); |
| 243 } |
| 244 |
| 238 int HeartbeatManager::GetDefaultHeartbeatInterval() { | 245 int HeartbeatManager::GetDefaultHeartbeatInterval() { |
| 239 // For unknown connections, use the longer cellular heartbeat interval. | 246 // For unknown connections, use the longer cellular heartbeat interval. |
| 240 int heartbeat_interval_ms = kCellHeartbeatDefaultMs; | 247 int heartbeat_interval_ms = kCellHeartbeatDefaultMs; |
| 241 if (net::NetworkChangeNotifier::GetConnectionType() == | 248 if (net::NetworkChangeNotifier::GetConnectionType() == |
| 242 net::NetworkChangeNotifier::CONNECTION_WIFI || | 249 net::NetworkChangeNotifier::CONNECTION_WIFI || |
| 243 net::NetworkChangeNotifier::GetConnectionType() == | 250 net::NetworkChangeNotifier::GetConnectionType() == |
| 244 net::NetworkChangeNotifier::CONNECTION_ETHERNET) { | 251 net::NetworkChangeNotifier::CONNECTION_ETHERNET) { |
| 245 heartbeat_interval_ms = kWifiHeartbeatDefaultMs; | 252 heartbeat_interval_ms = kWifiHeartbeatDefaultMs; |
| 246 } | 253 } |
| 247 return heartbeat_interval_ms; | 254 return heartbeat_interval_ms; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 286 interval <= max_heartbeat_interval; | 293 interval <= max_heartbeat_interval; |
| 287 } | 294 } |
| 288 | 295 |
| 289 void HeartbeatManager::ResetConnection( | 296 void HeartbeatManager::ResetConnection( |
| 290 ConnectionFactory::ConnectionResetReason reason) { | 297 ConnectionFactory::ConnectionResetReason reason) { |
| 291 Stop(); | 298 Stop(); |
| 292 trigger_reconnect_callback_.Run(reason); | 299 trigger_reconnect_callback_.Run(reason); |
| 293 } | 300 } |
| 294 | 301 |
| 295 } // namespace gcm | 302 } // namespace gcm |
| OLD | NEW |