Bring the browser window to the front when clicking on deprecated accelerator notific...
[chromium-blink-merge.git] / remoting / host / signaling_connector.cc
blob77f66ba02a6bc65ac53997361c95d5996d51d8e9
1 // Copyright (c) 2012 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.
5 #include "remoting/host/signaling_connector.h"
7 #include "base/bind.h"
8 #include "base/callback.h"
9 #include "base/strings/string_util.h"
10 #include "google_apis/google_api_keys.h"
11 #include "net/url_request/url_fetcher.h"
12 #include "net/url_request/url_request_context_getter.h"
13 #include "remoting/base/logging.h"
14 #include "remoting/host/dns_blackhole_checker.h"
16 namespace remoting {
18 namespace {
20 // The delay between reconnect attempts will increase exponentially up
21 // to the maximum specified here.
22 const int kMaxReconnectDelaySeconds = 10 * 60;
24 } // namespace
26 SignalingConnector::SignalingConnector(
27 XmppSignalStrategy* signal_strategy,
28 scoped_ptr<DnsBlackholeChecker> dns_blackhole_checker,
29 OAuthTokenGetter* oauth_token_getter,
30 const base::Closure& auth_failed_callback)
31 : signal_strategy_(signal_strategy),
32 auth_failed_callback_(auth_failed_callback),
33 dns_blackhole_checker_(dns_blackhole_checker.Pass()),
34 oauth_token_getter_(oauth_token_getter),
35 reconnect_attempts_(0) {
36 DCHECK(!auth_failed_callback_.is_null());
37 DCHECK(dns_blackhole_checker_.get());
38 net::NetworkChangeNotifier::AddConnectionTypeObserver(this);
39 net::NetworkChangeNotifier::AddIPAddressObserver(this);
40 signal_strategy_->AddListener(this);
41 ScheduleTryReconnect();
44 SignalingConnector::~SignalingConnector() {
45 signal_strategy_->RemoveListener(this);
46 net::NetworkChangeNotifier::RemoveConnectionTypeObserver(this);
47 net::NetworkChangeNotifier::RemoveIPAddressObserver(this);
50 void SignalingConnector::OnSignalStrategyStateChange(
51 SignalStrategy::State state) {
52 DCHECK(CalledOnValidThread());
54 if (state == SignalStrategy::CONNECTED) {
55 HOST_LOG << "Signaling connected. New JID: "
56 << signal_strategy_->GetLocalJid();
57 reconnect_attempts_ = 0;
58 } else if (state == SignalStrategy::DISCONNECTED) {
59 HOST_LOG << "Signaling disconnected.";
60 reconnect_attempts_++;
62 // If authentication failed then we have an invalid OAuth token,
63 // inform the upper layer about it.
64 if (signal_strategy_->GetError() == SignalStrategy::AUTHENTICATION_FAILED) {
65 auth_failed_callback_.Run();
66 } else {
67 ScheduleTryReconnect();
72 bool SignalingConnector::OnSignalStrategyIncomingStanza(
73 const buzz::XmlElement* stanza) {
74 return false;
77 void SignalingConnector::OnConnectionTypeChanged(
78 net::NetworkChangeNotifier::ConnectionType type) {
79 DCHECK(CalledOnValidThread());
80 if (type != net::NetworkChangeNotifier::CONNECTION_NONE &&
81 signal_strategy_->GetState() == SignalStrategy::DISCONNECTED) {
82 HOST_LOG << "Network state changed to online.";
83 ResetAndTryReconnect();
87 void SignalingConnector::OnIPAddressChanged() {
88 DCHECK(CalledOnValidThread());
89 if (signal_strategy_->GetState() == SignalStrategy::DISCONNECTED) {
90 HOST_LOG << "IP address has changed.";
91 ResetAndTryReconnect();
95 void SignalingConnector::OnAccessToken(OAuthTokenGetter::Status status,
96 const std::string& user_email,
97 const std::string& access_token) {
98 DCHECK(CalledOnValidThread());
100 if (status == OAuthTokenGetter::AUTH_ERROR) {
101 auth_failed_callback_.Run();
102 return;
103 } else if (status == OAuthTokenGetter::NETWORK_ERROR) {
104 OnNetworkError();
105 return;
108 DCHECK_EQ(status, OAuthTokenGetter::SUCCESS);
109 HOST_LOG << "Received user info.";
111 signal_strategy_->SetAuthInfo(user_email, access_token);
113 // Now that we've refreshed the token and verified that it's for the correct
114 // user account, try to connect using the new token.
115 DCHECK_EQ(signal_strategy_->GetState(), SignalStrategy::DISCONNECTED);
116 signal_strategy_->Connect();
119 void SignalingConnector::OnNetworkError() {
120 DCHECK(CalledOnValidThread());
121 reconnect_attempts_++;
122 ScheduleTryReconnect();
125 void SignalingConnector::ScheduleTryReconnect() {
126 DCHECK(CalledOnValidThread());
127 if (timer_.IsRunning() || net::NetworkChangeNotifier::IsOffline())
128 return;
129 int delay_s = std::min(1 << reconnect_attempts_,
130 kMaxReconnectDelaySeconds);
131 timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(delay_s),
132 this, &SignalingConnector::TryReconnect);
135 void SignalingConnector::ResetAndTryReconnect() {
136 DCHECK(CalledOnValidThread());
137 signal_strategy_->Disconnect();
138 reconnect_attempts_ = 0;
139 timer_.Stop();
140 ScheduleTryReconnect();
143 void SignalingConnector::TryReconnect() {
144 DCHECK(CalledOnValidThread());
145 DCHECK(dns_blackhole_checker_.get());
147 // This will check if this machine is allowed to access the chromoting
148 // host talkgadget.
149 dns_blackhole_checker_->CheckForDnsBlackhole(
150 base::Bind(&SignalingConnector::OnDnsBlackholeCheckerDone,
151 base::Unretained(this)));
154 void SignalingConnector::OnDnsBlackholeCheckerDone(bool allow) {
155 DCHECK(CalledOnValidThread());
157 // Unable to access the host talkgadget. Don't allow the connection, but
158 // schedule a reconnect in case this is a transient problem rather than
159 // an outright block.
160 if (!allow) {
161 reconnect_attempts_++;
162 HOST_LOG << "Talkgadget check failed. Scheduling reconnect. Attempt "
163 << reconnect_attempts_;
164 ScheduleTryReconnect();
165 return;
168 if (signal_strategy_->GetState() == SignalStrategy::DISCONNECTED) {
169 HOST_LOG << "Attempting to connect signaling.";
170 oauth_token_getter_->CallWithToken(
171 base::Bind(&SignalingConnector::OnAccessToken, AsWeakPtr()));
175 } // namespace remoting