| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "jingle/notifier/communicator/auto_reconnect.h" | |
| 6 | |
| 7 #include "base/rand_util.h" | |
| 8 #include "jingle/notifier/communicator/login.h" | |
| 9 | |
| 10 namespace notifier { | |
| 11 | |
| 12 const int kResetReconnectInfoDelaySec = 2; | |
| 13 | |
| 14 AutoReconnect::AutoReconnect() | |
| 15 : reconnect_timer_started_(false), | |
| 16 is_idle_(false) { | |
| 17 SetupReconnectInterval(); | |
| 18 } | |
| 19 | |
| 20 void AutoReconnect::NetworkStateChanged(bool is_alive) { | |
| 21 if (is_retrying() && is_alive) { | |
| 22 // Reconnect in 1 to 9 seconds (vary the time a little to try to avoid | |
| 23 // spikey behavior on network hiccups). | |
| 24 StartReconnectTimerWithInterval( | |
| 25 base::TimeDelta::FromSeconds(base::RandInt(1, 9))); | |
| 26 } | |
| 27 } | |
| 28 | |
| 29 void AutoReconnect::StartReconnectTimer() { | |
| 30 StartReconnectTimerWithInterval(reconnect_interval_); | |
| 31 } | |
| 32 | |
| 33 void AutoReconnect::StartReconnectTimerWithInterval( | |
| 34 base::TimeDelta interval) { | |
| 35 // Don't call StopReconnectTimer because we don't want other classes to | |
| 36 // detect that the intermediate state of the timer being stopped. | |
| 37 // (We're avoiding the call to SignalTimerStartStop while reconnect_timer_ is | |
| 38 // NULL). | |
| 39 reconnect_timer_.Stop(); | |
| 40 reconnect_timer_.Start(interval, this, &AutoReconnect::DoReconnect); | |
| 41 reconnect_timer_started_ = true; | |
| 42 SignalTimerStartStop(); | |
| 43 } | |
| 44 | |
| 45 void AutoReconnect::DoReconnect() { | |
| 46 reconnect_timer_started_ = false; | |
| 47 | |
| 48 // If timed out again, double autoreconnect time up to 30 minutes. | |
| 49 reconnect_interval_ *= 2; | |
| 50 if (reconnect_interval_ > base::TimeDelta::FromMinutes(30)) { | |
| 51 reconnect_interval_ = base::TimeDelta::FromMinutes(30); | |
| 52 } | |
| 53 SignalStartConnection(); | |
| 54 } | |
| 55 | |
| 56 void AutoReconnect::StopReconnectTimer() { | |
| 57 if (reconnect_timer_started_) { | |
| 58 reconnect_timer_started_ = false; | |
| 59 reconnect_timer_.Stop(); | |
| 60 SignalTimerStartStop(); | |
| 61 } | |
| 62 } | |
| 63 | |
| 64 void AutoReconnect::StopDelayedResetTimer() { | |
| 65 delayed_reset_timer_.Stop(); | |
| 66 } | |
| 67 | |
| 68 void AutoReconnect::ResetState() { | |
| 69 StopDelayedResetTimer(); | |
| 70 StopReconnectTimer(); | |
| 71 SetupReconnectInterval(); | |
| 72 } | |
| 73 | |
| 74 void AutoReconnect::SetupReconnectInterval() { | |
| 75 if (is_idle_) { | |
| 76 // If we were idle, start the timer over again (120 - 360 seconds). | |
| 77 reconnect_interval_ = | |
| 78 base::TimeDelta::FromSeconds(base::RandInt(120, 360)); | |
| 79 } else { | |
| 80 // If we weren't idle, try the connection 5 - 25 seconds later. | |
| 81 reconnect_interval_ = | |
| 82 base::TimeDelta::FromSeconds(base::RandInt(5, 25)); | |
| 83 } | |
| 84 } | |
| 85 | |
| 86 void AutoReconnect::OnPowerSuspend(bool suspended) { | |
| 87 if (suspended) { | |
| 88 // When the computer comes back on, ensure that the reconnect happens | |
| 89 // quickly (5 - 25 seconds). | |
| 90 reconnect_interval_ = | |
| 91 base::TimeDelta::FromSeconds(base::RandInt(5, 25)); | |
| 92 } | |
| 93 } | |
| 94 | |
| 95 void AutoReconnect::OnClientStateChange(LoginConnectionState state) { | |
| 96 // On any state change, stop the reset timer. | |
| 97 StopDelayedResetTimer(); | |
| 98 switch (state) { | |
| 99 case STATE_RETRYING: | |
| 100 // Do nothing. | |
| 101 break; | |
| 102 | |
| 103 case STATE_CLOSED: | |
| 104 // When the user has been logged out and no auto-reconnect is happening, | |
| 105 // then the autoreconnect intervals should be reset. | |
| 106 ResetState(); | |
| 107 break; | |
| 108 | |
| 109 case STATE_OPENING: | |
| 110 StopReconnectTimer(); | |
| 111 break; | |
| 112 | |
| 113 case STATE_OPENED: | |
| 114 // Reset autoreconnect timeout sequence after being connected for a bit | |
| 115 // of time. This helps in the case that we are connecting briefly and | |
| 116 // then getting disconnect like when an account hits an abuse limit. | |
| 117 StopReconnectTimer(); | |
| 118 delayed_reset_timer_.Start( | |
| 119 base::TimeDelta::FromSeconds(kResetReconnectInfoDelaySec), | |
| 120 this, &AutoReconnect::ResetState); | |
| 121 break; | |
| 122 } | |
| 123 } | |
| 124 | |
| 125 } // namespace notifier | |
| OLD | NEW |