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 |