Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(91)

Side by Side Diff: chrome/browser/sync/notifier/communicator/auto_reconnect.cc

Issue 1956001: Moved XMPP notifier library from chrome/browser/sync to chrome/common.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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 "chrome/browser/sync/notifier/communicator/auto_reconnect.h"
6
7 #include "chrome/browser/sync/notifier/base/network_status_detector_task.h"
8 #include "chrome/browser/sync/notifier/base/time.h"
9 #include "chrome/browser/sync/notifier/base/timer.h"
10 #include "talk/base/common.h"
11
12 namespace notifier {
13
14 const int kResetReconnectInfoDelaySec = 2;
15
16 AutoReconnect::AutoReconnect(talk_base::Task* parent,
17 NetworkStatusDetectorTask* network_status)
18 : reconnect_interval_ns_(0),
19 reconnect_timer_(NULL),
20 delayed_reset_timer_(NULL),
21 parent_(parent),
22 is_idle_(false) {
23 SetupReconnectInterval();
24 if (network_status) {
25 network_status->SignalNetworkStateDetected.connect(
26 this, &AutoReconnect::OnNetworkStateDetected);
27 }
28 }
29
30 void AutoReconnect::OnNetworkStateDetected(bool was_alive, bool is_alive) {
31 if (is_retrying() && !was_alive && is_alive) {
32 // Reconnect in 1 to 9 seconds (vary the time a little to try to avoid
33 // spikey behavior on network hiccups).
34 StartReconnectTimerWithInterval((rand() % 9 + 1) * kSecsTo100ns);
35 }
36 }
37
38 int AutoReconnect::seconds_until() const {
39 if (!is_retrying() || !reconnect_timer_->get_timeout_time()) {
40 return 0;
41 }
42 int64 time_until_100ns =
43 reconnect_timer_->get_timeout_time() - GetCurrent100NSTime();
44 if (time_until_100ns < 0) {
45 return 0;
46 }
47
48 // Do a ceiling on the value (to avoid returning before its time).
49 int64 result = (time_until_100ns + kSecsTo100ns - 1) / kSecsTo100ns;
50 return static_cast<int>(result);
51 }
52
53 void AutoReconnect::StartReconnectTimer() {
54 StartReconnectTimerWithInterval(reconnect_interval_ns_);
55 }
56
57 void AutoReconnect::StartReconnectTimerWithInterval(time64 interval_ns) {
58 // Don't call StopReconnectTimer because we don't want other classes to
59 // detect that the intermediate state of the timer being stopped.
60 // (We're avoiding the call to SignalTimerStartStop while reconnect_timer_ is
61 // NULL).
62 if (reconnect_timer_) {
63 reconnect_timer_->Abort();
64 reconnect_timer_ = NULL;
65 }
66 reconnect_timer_ = new Timer(parent_,
67 static_cast<int>(interval_ns / kSecsTo100ns),
68 false); // Repeat.
69 reconnect_timer_->SignalTimeout.connect(this,
70 &AutoReconnect::DoReconnect);
71 SignalTimerStartStop();
72 }
73
74 void AutoReconnect::DoReconnect() {
75 reconnect_timer_ = NULL;
76
77 // If timed out again, double autoreconnect time up to 30 minutes.
78 reconnect_interval_ns_ *= 2;
79 if (reconnect_interval_ns_ > 30 * kMinsTo100ns) {
80 reconnect_interval_ns_ = 30 * kMinsTo100ns;
81 }
82 SignalStartConnection();
83 }
84
85 void AutoReconnect::StopReconnectTimer() {
86 if (reconnect_timer_) {
87 reconnect_timer_->Abort();
88 reconnect_timer_ = NULL;
89 SignalTimerStartStop();
90 }
91 }
92
93 void AutoReconnect::StopDelayedResetTimer() {
94 if (delayed_reset_timer_) {
95 delayed_reset_timer_->Abort();
96 delayed_reset_timer_ = NULL;
97 }
98 }
99
100 void AutoReconnect::ResetState() {
101 StopDelayedResetTimer();
102 StopReconnectTimer();
103 SetupReconnectInterval();
104 }
105
106 void AutoReconnect::SetupReconnectInterval() {
107 if (is_idle_) {
108 // If we were idle, start the timer over again (120 - 360 seconds).
109 reconnect_interval_ns_ = (rand() % 240 + 120) * kSecsTo100ns;
110 } else {
111 // If we weren't idle, try the connection 5 - 25 seconds later.
112 reconnect_interval_ns_ = (rand() % 20 + 5) * kSecsTo100ns;
113 }
114 }
115
116 void AutoReconnect::OnPowerSuspend(bool suspended) {
117 if (suspended) {
118 // When the computer comes back on, ensure that the reconnect happens
119 // quickly (5 - 25 seconds).
120 reconnect_interval_ns_ = (rand() % 20 + 5) * kSecsTo100ns;
121 }
122 }
123
124 void AutoReconnect::OnClientStateChange(Login::ConnectionState state) {
125 // On any state change, stop the reset timer.
126 StopDelayedResetTimer();
127 switch (state) {
128 case Login::STATE_RETRYING:
129 // Do nothing.
130 break;
131
132 case Login::STATE_CLOSED:
133 // When the user has been logged out and no auto-reconnect is happening,
134 // then the autoreconnect intervals should be reset.
135 ResetState();
136 break;
137
138 case Login::STATE_OPENING:
139 StopReconnectTimer();
140 break;
141
142 case Login::STATE_OPENED:
143 // Reset autoreconnect timeout sequence after being connected for a bit
144 // of time. This helps in the case that we are connecting briefly and
145 // then getting disconnect like when an account hits an abuse limit.
146 StopReconnectTimer();
147 delayed_reset_timer_ = new Timer(parent_,
148 kResetReconnectInfoDelaySec,
149 false); // Repeat.
150 delayed_reset_timer_->SignalTimeout.connect(this,
151 &AutoReconnect::ResetState);
152 break;
153 }
154 }
155
156 } // namespace notifier
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698