Chromium Code Reviews| 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 <limits> | |
|
Nicolas Zea
2016/03/03 19:09:40
nit: not needed anymore
fgorski
2016/03/03 20:31:32
Done.
| |
| 7 #include <utility> | 8 #include <utility> |
| 8 | 9 |
| 9 #include "base/callback.h" | 10 #include "base/callback.h" |
| 10 #include "base/location.h" | 11 #include "base/location.h" |
| 11 #include "base/metrics/histogram.h" | 12 #include "base/metrics/histogram.h" |
| 12 #include "base/power_monitor/power_monitor.h" | 13 #include "base/power_monitor/power_monitor.h" |
| 13 #include "base/thread_task_runner_handle.h" | 14 #include "base/thread_task_runner_handle.h" |
| 14 #include "base/time/time.h" | 15 #include "base/time/time.h" |
| 15 #include "base/timer/timer.h" | 16 #include "base/timer/timer.h" |
| 16 #include "build/build_config.h" | 17 #include "build/build_config.h" |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 64 DCHECK(!send_heartbeat_callback.is_null()); | 65 DCHECK(!send_heartbeat_callback.is_null()); |
| 65 DCHECK(!trigger_reconnect_callback.is_null()); | 66 DCHECK(!trigger_reconnect_callback.is_null()); |
| 66 send_heartbeat_callback_ = send_heartbeat_callback; | 67 send_heartbeat_callback_ = send_heartbeat_callback; |
| 67 trigger_reconnect_callback_ = trigger_reconnect_callback; | 68 trigger_reconnect_callback_ = trigger_reconnect_callback; |
| 68 | 69 |
| 69 // Listen for system suspend and resume events. | 70 // Listen for system suspend and resume events. |
| 70 base::PowerMonitor* monitor = base::PowerMonitor::Get(); | 71 base::PowerMonitor* monitor = base::PowerMonitor::Get(); |
| 71 if (monitor) | 72 if (monitor) |
| 72 monitor->AddObserver(this); | 73 monitor->AddObserver(this); |
| 73 | 74 |
| 75 // Calculated the heartbeat interval just before we start the timer. | |
| 76 UpdateHeartbeatInterval(); | |
| 77 | |
| 74 // Kicks off the timer. | 78 // Kicks off the timer. |
| 75 waiting_for_ack_ = false; | 79 waiting_for_ack_ = false; |
| 76 RestartTimer(); | 80 RestartTimer(); |
| 77 } | 81 } |
| 78 | 82 |
| 79 void HeartbeatManager::Stop() { | 83 void HeartbeatManager::Stop() { |
| 80 heartbeat_expected_time_ = base::Time(); | 84 heartbeat_expected_time_ = base::Time(); |
| 81 heartbeat_interval_ms_ = 0; | 85 heartbeat_interval_ms_ = 0; |
| 82 heartbeat_timer_->Stop(); | 86 heartbeat_timer_->Stop(); |
| 83 waiting_for_ack_ = false; | 87 waiting_for_ack_ = false; |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 99 | 103 |
| 100 void HeartbeatManager::UpdateHeartbeatConfig( | 104 void HeartbeatManager::UpdateHeartbeatConfig( |
| 101 const mcs_proto::HeartbeatConfig& config) { | 105 const mcs_proto::HeartbeatConfig& config) { |
| 102 if (!config.IsInitialized() || | 106 if (!config.IsInitialized() || |
| 103 !config.has_interval_ms() || | 107 !config.has_interval_ms() || |
| 104 config.interval_ms() <= 0) { | 108 config.interval_ms() <= 0) { |
| 105 return; | 109 return; |
| 106 } | 110 } |
| 107 DVLOG(1) << "Updating server heartbeat interval to " << config.interval_ms(); | 111 DVLOG(1) << "Updating server heartbeat interval to " << config.interval_ms(); |
| 108 server_interval_ms_ = config.interval_ms(); | 112 server_interval_ms_ = config.interval_ms(); |
| 113 | |
| 114 // Make sure heartbeat interval is recalculated when new server interval is | |
| 115 // available. | |
| 116 UpdateHeartbeatInterval(); | |
| 109 } | 117 } |
| 110 | 118 |
| 111 base::TimeTicks HeartbeatManager::GetNextHeartbeatTime() const { | 119 base::TimeTicks HeartbeatManager::GetNextHeartbeatTime() const { |
| 112 if (heartbeat_timer_->IsRunning()) | 120 if (heartbeat_timer_->IsRunning()) |
| 113 return heartbeat_timer_->desired_run_time(); | 121 return heartbeat_timer_->desired_run_time(); |
| 114 else | 122 else |
| 115 return base::TimeTicks(); | 123 return base::TimeTicks(); |
| 116 } | 124 } |
| 117 | 125 |
| 118 void HeartbeatManager::UpdateHeartbeatTimer(scoped_ptr<base::Timer> timer) { | 126 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); | 167 ResetConnection(ConnectionFactory::HEARTBEAT_FAILURE); |
| 160 return; | 168 return; |
| 161 } | 169 } |
| 162 | 170 |
| 163 waiting_for_ack_ = true; | 171 waiting_for_ack_ = true; |
| 164 RestartTimer(); | 172 RestartTimer(); |
| 165 send_heartbeat_callback_.Run(); | 173 send_heartbeat_callback_.Run(); |
| 166 } | 174 } |
| 167 | 175 |
| 168 void HeartbeatManager::RestartTimer() { | 176 void HeartbeatManager::RestartTimer() { |
| 177 int interval_ms = heartbeat_interval_ms_; | |
| 169 if (!waiting_for_ack_) { | 178 if (!waiting_for_ack_) { |
|
Nicolas Zea
2016/03/03 19:09:40
nit: for readability, would be better to do:
if (w
fgorski
2016/03/03 20:31:32
Done.
| |
| 170 // Recalculate the timer interval based network type. | 179 DVLOG(1) << "Sending next heartbeat in " << interval_ms << " ms."; |
| 171 // Server interval takes precedence over client interval, even if the latter | |
| 172 // is less. | |
| 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 interval_ms = kHeartbeatAckDefaultMs; |
| 190 DVLOG(1) << "Resetting timer for ack with " | 182 DVLOG(1) << "Resetting timer for ack within " << interval_ms << " ms."; |
| 191 << heartbeat_interval_ms_ << " ms interval."; | |
| 192 } | 183 } |
| 193 | 184 |
| 194 heartbeat_expected_time_ = | 185 heartbeat_expected_time_ = |
| 195 base::Time::Now() + | 186 base::Time::Now() + base::TimeDelta::FromMilliseconds(interval_ms); |
| 196 base::TimeDelta::FromMilliseconds(heartbeat_interval_ms_); | |
| 197 heartbeat_timer_->Start(FROM_HERE, | 187 heartbeat_timer_->Start(FROM_HERE, |
| 198 base::TimeDelta::FromMilliseconds( | 188 base::TimeDelta::FromMilliseconds(interval_ms), |
| 199 heartbeat_interval_ms_), | 189 base::Bind(&HeartbeatManager::OnHeartbeatTriggered, |
| 200 base::Bind(&HeartbeatManager::OnHeartbeatTriggered, | 190 weak_ptr_factory_.GetWeakPtr())); |
| 201 weak_ptr_factory_.GetWeakPtr())); | |
| 202 | 191 |
| 203 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) | 192 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) |
| 204 // Windows, Mac, Android, iOS, and Chrome OS all provide a way to be notified | 193 // 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 | 194 // 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. | 195 // Linux so we need to poll to check for missed heartbeats. |
| 207 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 196 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| 208 FROM_HERE, | 197 FROM_HERE, |
| 209 base::Bind(&HeartbeatManager::CheckForMissedHeartbeat, | 198 base::Bind(&HeartbeatManager::CheckForMissedHeartbeat, |
| 210 weak_ptr_factory_.GetWeakPtr()), | 199 weak_ptr_factory_.GetWeakPtr()), |
| 211 base::TimeDelta::FromMilliseconds(kHeartbeatMissedCheckMs)); | 200 base::TimeDelta::FromMilliseconds(kHeartbeatMissedCheckMs)); |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 228 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) | 217 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) |
| 229 // Otherwise check again later. | 218 // Otherwise check again later. |
| 230 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 219 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| 231 FROM_HERE, | 220 FROM_HERE, |
| 232 base::Bind(&HeartbeatManager::CheckForMissedHeartbeat, | 221 base::Bind(&HeartbeatManager::CheckForMissedHeartbeat, |
| 233 weak_ptr_factory_.GetWeakPtr()), | 222 weak_ptr_factory_.GetWeakPtr()), |
| 234 base::TimeDelta::FromMilliseconds(kHeartbeatMissedCheckMs)); | 223 base::TimeDelta::FromMilliseconds(kHeartbeatMissedCheckMs)); |
| 235 #endif // defined(OS_LINUX) && !defined(OS_CHROMEOS) | 224 #endif // defined(OS_LINUX) && !defined(OS_CHROMEOS) |
| 236 } | 225 } |
| 237 | 226 |
| 227 void HeartbeatManager::UpdateHeartbeatInterval() { | |
| 228 // Server interval takes precedence over client interval, even if the latter | |
| 229 // is less. | |
| 230 if (server_interval_ms_ != 0) { | |
| 231 // If a server interval is set, it overrides any local one. | |
| 232 heartbeat_interval_ms_ = server_interval_ms_; | |
| 233 } else if (HasClientHeartbeatInterval() && | |
| 234 (client_interval_ms_ < heartbeat_interval_ms_ || | |
| 235 heartbeat_interval_ms_ == 0)) { | |
| 236 // Client interval might have been adjusted up, which should only take | |
| 237 // effect during a reconnection. | |
| 238 heartbeat_interval_ms_ = client_interval_ms_; | |
| 239 } else if (heartbeat_interval_ms_ == 0) { | |
| 240 // If interval is still 0, recalculate it based on network type. | |
| 241 heartbeat_interval_ms_ = GetDefaultHeartbeatInterval(); | |
| 242 } | |
|
fgorski
2016/03/03 17:10:35
zea@ perhaps we can have a DCHECK(heartbeat_interv
Nicolas Zea
2016/03/03 19:09:40
DCHECK_GT, but yes SGTM :)
| |
| 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 |