diff options
Diffstat (limited to 'jingle')
-rw-r--r-- | jingle/jingle.gyp | 2 | ||||
-rw-r--r-- | jingle/notifier/communicator/auto_reconnect.cc | 125 | ||||
-rw-r--r-- | jingle/notifier/communicator/auto_reconnect.h | 67 | ||||
-rw-r--r-- | jingle/notifier/communicator/connection_options.cc | 1 | ||||
-rw-r--r-- | jingle/notifier/communicator/connection_options.h | 3 | ||||
-rw-r--r-- | jingle/notifier/communicator/login.cc | 291 | ||||
-rw-r--r-- | jingle/notifier/communicator/login.h | 82 | ||||
-rw-r--r-- | jingle/notifier/communicator/login_connection_state.h | 8 | ||||
-rw-r--r-- | jingle/notifier/communicator/single_login_attempt.cc | 6 | ||||
-rw-r--r-- | jingle/notifier/communicator/single_login_attempt.h | 2 | ||||
-rw-r--r-- | jingle/notifier/listener/mediator_thread_impl.cc | 18 |
11 files changed, 97 insertions, 508 deletions
diff --git a/jingle/jingle.gyp b/jingle/jingle.gyp index e950c46..b3edc24 100644 --- a/jingle/jingle.gyp +++ b/jingle/jingle.gyp @@ -23,8 +23,6 @@ 'notifier/base/static_assert.h', 'notifier/base/task_pump.cc', 'notifier/base/task_pump.h', - 'notifier/communicator/auto_reconnect.cc', - 'notifier/communicator/auto_reconnect.h', 'notifier/communicator/connection_options.cc', 'notifier/communicator/connection_options.h', 'notifier/communicator/connection_settings.cc', diff --git a/jingle/notifier/communicator/auto_reconnect.cc b/jingle/notifier/communicator/auto_reconnect.cc deleted file mode 100644 index 4b16e93..0000000 --- a/jingle/notifier/communicator/auto_reconnect.cc +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "jingle/notifier/communicator/auto_reconnect.h" - -#include "base/rand_util.h" -#include "jingle/notifier/communicator/login.h" - -namespace notifier { - -const int kResetReconnectInfoDelaySec = 2; - -AutoReconnect::AutoReconnect() - : reconnect_timer_started_(false), - is_idle_(false) { - SetupReconnectInterval(); -} - -void AutoReconnect::NetworkStateChanged(bool is_alive) { - if (is_retrying() && is_alive) { - // Reconnect in 1 to 9 seconds (vary the time a little to try to avoid - // spikey behavior on network hiccups). - StartReconnectTimerWithInterval( - base::TimeDelta::FromSeconds(base::RandInt(1, 9))); - } -} - -void AutoReconnect::StartReconnectTimer() { - StartReconnectTimerWithInterval(reconnect_interval_); -} - -void AutoReconnect::StartReconnectTimerWithInterval( - base::TimeDelta interval) { - // Don't call StopReconnectTimer because we don't want other classes to - // detect that the intermediate state of the timer being stopped. - // (We're avoiding the call to SignalTimerStartStop while reconnect_timer_ is - // NULL). - reconnect_timer_.Stop(); - reconnect_timer_.Start(interval, this, &AutoReconnect::DoReconnect); - reconnect_timer_started_ = true; - SignalTimerStartStop(); -} - -void AutoReconnect::DoReconnect() { - reconnect_timer_started_ = false; - - // If timed out again, double autoreconnect time up to 30 minutes. - reconnect_interval_ *= 2; - if (reconnect_interval_ > base::TimeDelta::FromMinutes(30)) { - reconnect_interval_ = base::TimeDelta::FromMinutes(30); - } - SignalStartConnection(); -} - -void AutoReconnect::StopReconnectTimer() { - if (reconnect_timer_started_) { - reconnect_timer_started_ = false; - reconnect_timer_.Stop(); - SignalTimerStartStop(); - } -} - -void AutoReconnect::StopDelayedResetTimer() { - delayed_reset_timer_.Stop(); -} - -void AutoReconnect::ResetState() { - StopDelayedResetTimer(); - StopReconnectTimer(); - SetupReconnectInterval(); -} - -void AutoReconnect::SetupReconnectInterval() { - if (is_idle_) { - // If we were idle, start the timer over again (120 - 360 seconds). - reconnect_interval_ = - base::TimeDelta::FromSeconds(base::RandInt(120, 360)); - } else { - // If we weren't idle, try the connection 5 - 25 seconds later. - reconnect_interval_ = - base::TimeDelta::FromSeconds(base::RandInt(5, 25)); - } -} - -void AutoReconnect::OnPowerSuspend(bool suspended) { - if (suspended) { - // When the computer comes back on, ensure that the reconnect happens - // quickly (5 - 25 seconds). - reconnect_interval_ = - base::TimeDelta::FromSeconds(base::RandInt(5, 25)); - } -} - -void AutoReconnect::OnClientStateChange(LoginConnectionState state) { - // On any state change, stop the reset timer. - StopDelayedResetTimer(); - switch (state) { - case STATE_RETRYING: - // Do nothing. - break; - - case STATE_CLOSED: - // When the user has been logged out and no auto-reconnect is happening, - // then the autoreconnect intervals should be reset. - ResetState(); - break; - - case STATE_OPENING: - StopReconnectTimer(); - break; - - case STATE_OPENED: - // Reset autoreconnect timeout sequence after being connected for a bit - // of time. This helps in the case that we are connecting briefly and - // then getting disconnect like when an account hits an abuse limit. - StopReconnectTimer(); - delayed_reset_timer_.Start( - base::TimeDelta::FromSeconds(kResetReconnectInfoDelaySec), - this, &AutoReconnect::ResetState); - break; - } -} - -} // namespace notifier diff --git a/jingle/notifier/communicator/auto_reconnect.h b/jingle/notifier/communicator/auto_reconnect.h deleted file mode 100644 index 6b2fa09..0000000 --- a/jingle/notifier/communicator/auto_reconnect.h +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef JINGLE_NOTIFIER_COMMUNICATOR_AUTO_RECONNECT_H_ -#define JINGLE_NOTIFIER_COMMUNICATOR_AUTO_RECONNECT_H_ - -#include <string> - -#include "base/time.h" -#include "base/timer.h" -#include "jingle/notifier/communicator/login_connection_state.h" -#include "talk/base/sigslot.h" - -namespace notifier { - -class AutoReconnect : public sigslot::has_slots<> { - public: - AutoReconnect(); - void StartReconnectTimer(); - void StopReconnectTimer(); - void OnClientStateChange(LoginConnectionState state); - - void NetworkStateChanged(bool is_alive); - - // Callback when power is suspended. - void OnPowerSuspend(bool suspended); - - void set_idle(bool idle) { - is_idle_ = idle; - } - - // Returns true if the auto-retry is to be done (pending a countdown). - bool is_retrying() const { - return reconnect_timer_started_; - } - - sigslot::signal0<> SignalTimerStartStop; - sigslot::signal0<> SignalStartConnection; - - private: - void StartReconnectTimerWithInterval(base::TimeDelta interval); - void DoReconnect(); - void ResetState(); - void SetupReconnectInterval(); - void StopDelayedResetTimer(); - - base::TimeDelta reconnect_interval_; - bool reconnect_timer_started_; - base::OneShotTimer<AutoReconnect> reconnect_timer_; - base::OneShotTimer<AutoReconnect> delayed_reset_timer_; - - bool is_idle_; - DISALLOW_COPY_AND_ASSIGN(AutoReconnect); -}; - -// Wait 2 seconds until after we actually connect to reset reconnect related -// items. -// -// The reason for this delay is to avoid the situation in which buzz is trying -// to block the client due to abuse and the client responses by going into -// rapid reconnect mode, which makes the problem more severe. -extern const int kResetReconnectInfoDelaySec; - -} // namespace notifier - -#endif // JINGLE_NOTIFIER_COMMUNICATOR_AUTO_RECONNECT_H_ diff --git a/jingle/notifier/communicator/connection_options.cc b/jingle/notifier/communicator/connection_options.cc index fe52d7f..c103127 100644 --- a/jingle/notifier/communicator/connection_options.cc +++ b/jingle/notifier/communicator/connection_options.cc @@ -8,7 +8,6 @@ namespace notifier { ConnectionOptions::ConnectionOptions() : autodetect_proxy_(true), - auto_reconnect_(true), proxy_port_(0), use_proxy_auth_(0), allow_unverified_certs_(false) { diff --git a/jingle/notifier/communicator/connection_options.h b/jingle/notifier/communicator/connection_options.h index de09910..4f24b44 100644 --- a/jingle/notifier/communicator/connection_options.h +++ b/jingle/notifier/communicator/connection_options.h @@ -17,7 +17,6 @@ class ConnectionOptions { ConnectionOptions(); bool autodetect_proxy() const { return autodetect_proxy_; } - bool auto_reconnect() const { return auto_reconnect_; } const std::string& proxy_host() const { return proxy_host_; } int proxy_port() const { return proxy_port_; } bool use_proxy_auth() const { return use_proxy_auth_; } @@ -26,7 +25,6 @@ class ConnectionOptions { bool allow_unverified_certs() const { return allow_unverified_certs_; } void set_autodetect_proxy(bool f) { autodetect_proxy_ = f; } - void set_auto_reconnect(bool f) { auto_reconnect_ = f; } void set_proxy_host(const std::string& val) { proxy_host_ = val; } void set_proxy_port(int val) { proxy_port_ = val; } void set_use_proxy_auth(bool f) { use_proxy_auth_ = f; } @@ -41,7 +39,6 @@ class ConnectionOptions { private: bool autodetect_proxy_; - bool auto_reconnect_; std::string proxy_host_; int proxy_port_; bool use_proxy_auth_; diff --git a/jingle/notifier/communicator/login.cc b/jingle/notifier/communicator/login.cc index 7cf4952..7d3c4c8 100644 --- a/jingle/notifier/communicator/login.cc +++ b/jingle/notifier/communicator/login.cc @@ -7,8 +7,8 @@ #include "jingle/notifier/communicator/login.h" #include "base/logging.h" +#include "base/rand_util.h" #include "base/time.h" -#include "jingle/notifier/communicator/auto_reconnect.h" #include "jingle/notifier/communicator/connection_options.h" #include "jingle/notifier/communicator/login_settings.h" #include "jingle/notifier/communicator/product_info.h" @@ -31,9 +31,6 @@ namespace notifier { // Redirect valid for 5 minutes. static const int kRedirectTimeoutMinutes = 5; -// Disconnect if network stays down for more than 10 seconds. -static const int kDisconnectionDelaySecs = 10; - Login::Login(talk_base::TaskParent* parent, bool use_chrome_async_socket, const buzz::XmppClientSettings& user_settings, @@ -43,8 +40,7 @@ Login::Login(talk_base::TaskParent* parent, ServerInformation* server_list, int server_count, talk_base::FirewallManager* firewall, - bool proxy_only, - bool previous_login_successful) + bool proxy_only) : parent_(parent), use_chrome_async_socket_(use_chrome_async_socket), login_settings_(new LoginSettings(user_settings, @@ -55,38 +51,15 @@ Login::Login(talk_base::TaskParent* parent, server_count, firewall, proxy_only)), + state_(STATE_DISCONNECTED), single_attempt_(NULL), - successful_connection_(previous_login_successful), - state_(STATE_OPENING), - redirect_port_(0), - unexpected_disconnect_occurred_(false), - google_host_(user_settings.host()), - google_user_(user_settings.user()) { - // Hook up all the signals and observers. + redirect_port_(0) { net::NetworkChangeNotifier::AddObserver(this); - auto_reconnect_.SignalStartConnection.connect(this, - &Login::StartConnection); - auto_reconnect_.SignalTimerStartStop.connect( - this, - &Login::OnAutoReconnectTimerChange); - SignalClientStateChange.connect(&auto_reconnect_, - &AutoReconnect::OnClientStateChange); - SignalIdleChange.connect(&auto_reconnect_, - &AutoReconnect::set_idle); - SignalPowerSuspended.connect(&auto_reconnect_, - &AutoReconnect::OnPowerSuspend); - - // Then check the initial state of the connection. - CheckConnection(); + ResetReconnectState(); } -// Defined so that the destructors are executed here (and the corresponding -// classes don't need to be included in the header file). Login::~Login() { - if (single_attempt_) { - single_attempt_->Abort(); - single_attempt_ = NULL; - } + Disconnect(); net::NetworkChangeNotifier::RemoveObserver(this); } @@ -103,126 +76,68 @@ void Login::StartConnection() { login_settings_->clear_server_override(); } - if (single_attempt_) { - single_attempt_->Abort(); - single_attempt_ = NULL; - } + Disconnect(); + + LOG(INFO) << "Starting connection..."; + single_attempt_ = new SingleLoginAttempt(parent_, login_settings_.get(), use_chrome_async_socket_, - successful_connection_); + true); // Do the signaling hook-ups. - single_attempt_->SignalLoginFailure.connect(this, &Login::OnLoginFailure); - single_attempt_->SignalRedirect.connect(this, &Login::OnRedirect); - single_attempt_->SignalClientStateChange.connect( - this, - &Login::OnClientStateChange); single_attempt_->SignalUnexpectedDisconnect.connect( this, - &Login::OnUnexpectedDisconnect); + &Login::TryReconnect); + single_attempt_->SignalNeedAutoReconnect.connect( + this, + &Login::TryReconnect); + single_attempt_->SignalLoginFailure.connect(this, &Login::OnLoginFailure); single_attempt_->SignalLogoff.connect( this, - &Login::OnLogoff); - single_attempt_->SignalNeedAutoReconnect.connect( + &Login::Disconnect); + single_attempt_->SignalRedirect.connect(this, &Login::OnRedirect); + single_attempt_->SignalClientStateChange.connect( this, - &Login::DoAutoReconnect); + &Login::OnClientStateChange); SignalLogInput.repeat(single_attempt_->SignalLogInput); SignalLogOutput.repeat(single_attempt_->SignalLogOutput); single_attempt_->Start(); } -const std::string& Login::google_host() const { - return google_host_; -} - -const std::string& Login::google_user() const { - return google_user_; -} - -const talk_base::ProxyInfo& Login::proxy() const { - return proxy_info_; -} - void Login::OnLoginFailure(const LoginFailure& failure) { - auto_reconnect_.StopReconnectTimer(); - HandleClientStateChange(STATE_CLOSED); SignalLoginFailure(failure); + TryReconnect(); } -void Login::OnLogoff() { - HandleClientStateChange(STATE_CLOSED); -} - -void Login::OnClientStateChange(buzz::XmppEngine::State state) { - LoginConnectionState new_state = STATE_CLOSED; - - switch (state) { - case buzz::XmppEngine::STATE_NONE: - case buzz::XmppEngine::STATE_CLOSED: - // Ignore the closed state (because we may be trying the next dns entry). - // - // But we go to this state for other signals when there is no retry - // happening. - new_state = state_; - break; - - case buzz::XmppEngine::STATE_START: - case buzz::XmppEngine::STATE_OPENING: - new_state = STATE_OPENING; - break; +void Login::OnRedirect(const std::string& redirect_server, int redirect_port) { + DCHECK_NE(redirect_port_, 0); - case buzz::XmppEngine::STATE_OPEN: - new_state = STATE_OPENED; - break; + redirect_time_ = base::Time::Now(); + redirect_server_ = redirect_server; + redirect_port_ = redirect_port; - default: - DCHECK(false); - break; - } - HandleClientStateChange(new_state); + // Drop the current connection, and start the login process again. + StartConnection(); } -void Login::HandleClientStateChange(LoginConnectionState new_state) { - // Do we need to transition between the retrying and closed states? - if (auto_reconnect_.is_retrying()) { - if (new_state == STATE_CLOSED) { - new_state = STATE_RETRYING; - } - } else { - if (new_state == STATE_RETRYING) { - new_state = STATE_CLOSED; - } +void Login::OnClientStateChange(buzz::XmppEngine::State state) { + // We only care about when we're connected. + if (state == buzz::XmppEngine::STATE_OPEN) { + ResetReconnectState(); + ChangeState(STATE_CONNECTED); } +} - if (new_state != state_) { +void Login::ChangeState(LoginConnectionState new_state) { + if (state_ != new_state) { state_ = new_state; - reset_unexpected_timer_.Stop(); - - if (state_ == STATE_OPENED) { - successful_connection_ = true; - - google_host_ = single_attempt_->xmpp_client()->jid().domain(); - google_user_ = single_attempt_->xmpp_client()->jid().node(); - proxy_info_ = single_attempt_->proxy(); - - reset_unexpected_timer_.Start( - base::TimeDelta::FromSeconds(kResetReconnectInfoDelaySec), - this, &Login::ResetUnexpectedDisconnect); - } + LOG(INFO) << "Signalling new state " << state_; SignalClientStateChange(state_); } } -void Login::OnAutoReconnectTimerChange() { - if (!single_attempt_ || !single_attempt_->xmpp_client()) { - HandleClientStateChange(STATE_CLOSED); - return; - } - OnClientStateChange(single_attempt_->xmpp_client()->GetState()); -} - buzz::XmppClient* Login::xmpp_client() { if (!single_attempt_) { return NULL; @@ -230,122 +145,48 @@ buzz::XmppClient* Login::xmpp_client() { return single_attempt_->xmpp_client(); } -void Login::UseNextConnection() { - if (!single_attempt_) { - // Just in case, there is an obscure case that causes this to get called - // when there is no single_attempt_. - return; - } - single_attempt_->UseNextConnection(); -} - -void Login::UseCurrentConnection() { - if (!single_attempt_) { - // Just in case, there is an obscure case that causes this to get called - // when there is no single_attempt_. - return; - } - single_attempt_->UseCurrentConnection(); -} - -void Login::OnRedirect(const std::string& redirect_server, int redirect_port) { - DCHECK_NE(redirect_port_, 0); - - redirect_time_ = base::Time::Now(); - redirect_server_ = redirect_server; - redirect_port_ = redirect_port; - - // Drop the current connection, and start the login process again. - StartConnection(); -} - -void Login::OnUnexpectedDisconnect() { - reset_unexpected_timer_.Stop(); - - // Start the login process again. - if (unexpected_disconnect_occurred_) { - // If we already have received an unexpected disconnect recently, then our - // account may have be jailed due to abuse, so we shouldn't make the - // situation worse by trying really hard to reconnect. Instead, we'll do - // the autoreconnect route, which has exponential back-off. - DoAutoReconnect(); - return; - } - StartConnection(); - unexpected_disconnect_occurred_ = true; -} - -void Login::ResetUnexpectedDisconnect() { - unexpected_disconnect_occurred_ = false; +void Login::OnIPAddressChanged() { + LOG(INFO) << "Detected IP address change"; + // Reconnect in 1 to 9 seconds (vary the time a little to try to + // avoid spikey behavior on network hiccups). + reconnect_interval_ = base::TimeDelta::FromSeconds(base::RandInt(1, 9)); + TryReconnect(); } -void Login::DoAutoReconnect() { - bool allow_auto_reconnect = - login_settings_->connection_options().auto_reconnect(); - // Start the reconnect time before aborting the connection to ensure that - // AutoReconnect::is_retrying() is true, so that the Login doesn't - // transition to the CLOSED state (which would cause the reconnection timer - // to reset and not double). - if (allow_auto_reconnect) { - auto_reconnect_.StartReconnectTimer(); - } - +void Login::Disconnect() { if (single_attempt_) { + LOG(INFO) << "Disconnecting"; single_attempt_->Abort(); single_attempt_ = NULL; } - - if (!allow_auto_reconnect) { - HandleClientStateChange(STATE_CLOSED); - return; - } + ChangeState(STATE_DISCONNECTED); } -void Login::OnIPAddressChanged() { - LOG(INFO) << "IP address change detected"; - CheckConnection(); +void Login::ResetReconnectState() { + reconnect_interval_ = + base::TimeDelta::FromSeconds(base::RandInt(5, 25)); + reconnect_timer_.Stop(); } -void Login::CheckConnection() { - // We don't check the connection if we're using ChromeAsyncSocket, - // as this code requires a libjingle thread to be running. This - // code will go away in a future cleanup CL, anyway. - if (!use_chrome_async_socket_) { - LOG(INFO) << "Checking connection"; - talk_base::PhysicalSocketServer physical; - scoped_ptr<talk_base::Socket> socket(physical.CreateSocket(SOCK_STREAM)); - bool alive = - !socket->Connect(talk_base::SocketAddress("talk.google.com", 5222)); - LOG(INFO) << "Network is " << (alive ? "alive" : "not alive"); - if (alive) { - // Our connection is up. If we have a disconnect timer going, - // stop it so we don't disconnect. - disconnect_timer_.Stop(); - } else { - // Our network connection is down. Start the disconnect timer if - // it's not already going. Don't disconnect immediately to avoid - // constant connection/disconnection due to flaky network - // interfaces. - if (!disconnect_timer_.IsRunning()) { - disconnect_timer_.Start( - base::TimeDelta::FromSeconds(kDisconnectionDelaySecs), - this, &Login::OnDisconnectTimeout); - } - } - auto_reconnect_.NetworkStateChanged(alive); - } +void Login::TryReconnect() { + DCHECK_GT(reconnect_interval_.InSeconds(), 0); + Disconnect(); + reconnect_timer_.Stop(); + LOG(INFO) << "Reconnecting in " + << reconnect_interval_.InSeconds() << " seconds"; + reconnect_timer_.Start( + reconnect_interval_, this, &Login::DoReconnect); } -void Login::OnDisconnectTimeout() { - if (state_ != STATE_OPENED) { - return; +void Login::DoReconnect() { + // Double reconnect time up to 30 minutes. + const base::TimeDelta kMaxReconnectInterval = + base::TimeDelta::FromMinutes(30); + reconnect_interval_ *= 2; + if (reconnect_interval_ > kMaxReconnectInterval) { + reconnect_interval_ = kMaxReconnectInterval; } - - if (single_attempt_) { - single_attempt_->Abort(); - single_attempt_ = NULL; - } - + LOG(INFO) << "Reconnecting..."; StartConnection(); } diff --git a/jingle/notifier/communicator/login.h b/jingle/notifier/communicator/login.h index 29dc9e3..d555a8a 100644 --- a/jingle/notifier/communicator/login.h +++ b/jingle/notifier/communicator/login.h @@ -10,7 +10,6 @@ #include "base/time.h" #include "base/timer.h" #include "jingle/notifier/base/sigslotrepeater.h" -#include "jingle/notifier/communicator/auto_reconnect.h" #include "jingle/notifier/communicator/login_connection_state.h" #include "net/base/network_change_notifier.h" #include "talk/base/proxyinfo.h" @@ -58,44 +57,14 @@ class Login : public net::NetworkChangeNotifier::Observer, ServerInformation* server_list, int server_count, talk_base::FirewallManager* firewall, - bool proxy_only, - bool previous_login_successful); + bool proxy_only); virtual ~Login(); - LoginConnectionState connection_state() const { - return state_; - } - void StartConnection(); - void UseNextConnection(); - void UseCurrentConnection(); - buzz::XmppClient* xmpp_client(); - - // Start the auto-reconnect. It may not do the auto-reconnect if - // auto-reconnect is turned off. - void DoAutoReconnect(); - - const LoginSettings& login_settings() const { - return *(login_settings_.get()); - } - - // Returns the best guess at the host responsible for the account (which we - // use to determine if it is a dasher account or not). - // - // After login this may return a more accurate answer, which accounts for - // open sign-up accounts. - const std::string& google_host() const; - // Analogous to google_host but for the user account ("fred" in - // "fred@gmail.com"). - const std::string& google_user() const; - - // Returns the proxy that is being used to connect (or the default proxy - // information if all attempted connections failed). - // - // Do not call until StartConnection has been called. - const talk_base::ProxyInfo& proxy() const; + buzz::XmppClient* xmpp_client(); + // net::NetworkChangeNotifier::Observer implementation. virtual void OnIPAddressChanged(); sigslot::signal1<LoginConnectionState> SignalClientStateChange; @@ -103,47 +72,44 @@ class Login : public net::NetworkChangeNotifier::Observer, sigslot::signal1<const LoginFailure&> SignalLoginFailure; sigslot::repeater2<const char*, int> SignalLogInput; sigslot::repeater2<const char*, int> SignalLogOutput; - sigslot::repeater1<bool> SignalIdleChange; - - // The creator should hook this up to a signal that indicates when the power - // is being suspended. - sigslot::repeater1<bool> SignalPowerSuspended; private: - void CheckConnection(); - - void OnRedirect(const std::string& redirect_server, int redirect_port); - void OnUnexpectedDisconnect(); - void OnClientStateChange(buzz::XmppEngine::State state); void OnLoginFailure(const LoginFailure& failure); void OnLogoff(); - void OnAutoReconnectTimerChange(); + void OnRedirect(const std::string& redirect_server, int redirect_port); + void OnClientStateChange(buzz::XmppEngine::State state); + + void ChangeState(LoginConnectionState new_state); + + // Abort any existing connection. + void Disconnect(); - void HandleClientStateChange(LoginConnectionState new_state); - void ResetUnexpectedDisconnect(); + // Stops any existing reconnect timer and sets an initial reconnect + // interval. + void ResetReconnectState(); - void OnDisconnectTimeout(); + // Tries to reconnect in some point in the future. If called + // repeatedly, will wait longer and longer until reconnecting. + void TryReconnect(); + + // The actual function (called by |reconnect_timer_|) that does the + // reconnection. + void DoReconnect(); talk_base::TaskParent* parent_; bool use_chrome_async_socket_; scoped_ptr<LoginSettings> login_settings_; - AutoReconnect auto_reconnect_; + LoginConnectionState state_; SingleLoginAttempt* single_attempt_; - bool successful_connection_; - LoginConnectionState state_; + // reconnection state. + base::TimeDelta reconnect_interval_; + base::OneShotTimer<Login> reconnect_timer_; // server redirect information base::Time redirect_time_; std::string redirect_server_; int redirect_port_; - bool unexpected_disconnect_occurred_; - base::OneShotTimer<Login> reset_unexpected_timer_; - std::string google_host_; - std::string google_user_; - talk_base::ProxyInfo proxy_info_; - - base::OneShotTimer<Login> disconnect_timer_; DISALLOW_COPY_AND_ASSIGN(Login); }; diff --git a/jingle/notifier/communicator/login_connection_state.h b/jingle/notifier/communicator/login_connection_state.h index db90451..d4c6470 100644 --- a/jingle/notifier/communicator/login_connection_state.h +++ b/jingle/notifier/communicator/login_connection_state.h @@ -11,12 +11,8 @@ namespace notifier { enum LoginConnectionState { - STATE_CLOSED, - // Same as the closed state but indicates that a countdown is - // happening for auto-retrying the connection. - STATE_RETRYING, - STATE_OPENING, - STATE_OPENED, + STATE_DISCONNECTED, + STATE_CONNECTED, }; } // namespace notifier diff --git a/jingle/notifier/communicator/single_login_attempt.cc b/jingle/notifier/communicator/single_login_attempt.cc index 8f1e26f..69dd21e 100644 --- a/jingle/notifier/communicator/single_login_attempt.cc +++ b/jingle/notifier/communicator/single_login_attempt.cc @@ -99,10 +99,6 @@ SingleLoginAttempt::~SingleLoginAttempt() { DCHECK(!client_); } -bool SingleLoginAttempt::auto_reconnect() const { - return login_settings_->connection_options().auto_reconnect(); -} - const talk_base::ProxyInfo& SingleLoginAttempt::proxy() const { DCHECK(connection_generator_.get()); return connection_generator_->proxy(); @@ -157,7 +153,7 @@ void SingleLoginAttempt::OnAttemptedAllConnections( LOG(INFO) << "Connection failed with error " << code_; // We were connected and we had a problem. - if (successful_connection_ && auto_reconnect()) { + if (successful_connection_) { SignalNeedAutoReconnect(); // Expect to be deleted at this point. return; diff --git a/jingle/notifier/communicator/single_login_attempt.h b/jingle/notifier/communicator/single_login_attempt.h index 582615d..8b4f93b 100644 --- a/jingle/notifier/communicator/single_login_attempt.h +++ b/jingle/notifier/communicator/single_login_attempt.h @@ -118,8 +118,6 @@ class SingleLoginAttempt : public talk_base::Task, public sigslot::has_slots<> { void OnAttemptedAllConnections(bool successfully_resolved_dns, int first_dns_error); - bool auto_reconnect() const; - bool use_chrome_async_socket_; buzz::XmppEngine::State state_; buzz::XmppEngine::Error code_; diff --git a/jingle/notifier/listener/mediator_thread_impl.cc b/jingle/notifier/listener/mediator_thread_impl.cc index 402346e..bdbbf5b 100644 --- a/jingle/notifier/listener/mediator_thread_impl.cc +++ b/jingle/notifier/listener/mediator_thread_impl.cc @@ -206,12 +206,7 @@ void MediatorThreadImpl::DoLogin( NULL, // Both the proxy and a non-proxy route // will be attempted. - false, - // |previous_login_successful| is true - // because we have already done a - // successful gaia login at this point - // through another mechanism. - true)); + false)); login_->SignalClientStateChange.connect( this, &MediatorThreadImpl::OnClientStateChangeMessage); @@ -332,21 +327,16 @@ void MediatorThreadImpl::OnClientStateChangeMessageOnParentThread( LoginConnectionState state) { DCHECK_EQ(MessageLoop::current(), parent_message_loop_); switch (state) { - case STATE_CLOSED: - if (delegate_) { - delegate_->OnConnectionStateChange(false); - } - break; - case STATE_RETRYING: - case STATE_OPENING: + case STATE_DISCONNECTED: LOG(INFO) << "P2P: Thread trying to connect."; // Maybe first time logon, maybe intermediate network disruption. Assume // the server went down, and lost our subscription for updates. if (delegate_) { + delegate_->OnConnectionStateChange(false); delegate_->OnSubscriptionStateChange(false); } break; - case STATE_OPENED: + case STATE_CONNECTED: if (delegate_) { delegate_->OnConnectionStateChange(true); } |