OLD | NEW |
---|---|
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "google_apis/gcm/engine/connection_factory_impl.h" | 5 #include "google_apis/gcm/engine/connection_factory_impl.h" |
6 | 6 |
7 #include "base/message_loop/message_loop.h" | 7 #include "base/message_loop/message_loop.h" |
8 #include "base/metrics/histogram.h" | 8 #include "base/metrics/histogram.h" |
9 #include "base/metrics/sparse_histogram.h" | 9 #include "base/metrics/sparse_histogram.h" |
10 #include "google_apis/gcm/engine/connection_handler_impl.h" | 10 #include "google_apis/gcm/engine/connection_handler_impl.h" |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
52 last_successful_endpoint_(0), | 52 last_successful_endpoint_(0), |
53 backoff_policy_(backoff_policy), | 53 backoff_policy_(backoff_policy), |
54 network_session_(network_session), | 54 network_session_(network_session), |
55 bound_net_log_( | 55 bound_net_log_( |
56 net::BoundNetLog::Make(net_log, net::NetLog::SOURCE_SOCKET)), | 56 net::BoundNetLog::Make(net_log, net::NetLog::SOURCE_SOCKET)), |
57 pac_request_(NULL), | 57 pac_request_(NULL), |
58 connecting_(false), | 58 connecting_(false), |
59 waiting_for_backoff_(false), | 59 waiting_for_backoff_(false), |
60 logging_in_(false), | 60 logging_in_(false), |
61 recorder_(recorder), | 61 recorder_(recorder), |
62 listener_(NULL), | |
62 weak_ptr_factory_(this) { | 63 weak_ptr_factory_(this) { |
63 DCHECK_GE(mcs_endpoints_.size(), 1U); | 64 DCHECK_GE(mcs_endpoints_.size(), 1U); |
64 } | 65 } |
65 | 66 |
66 ConnectionFactoryImpl::~ConnectionFactoryImpl() { | 67 ConnectionFactoryImpl::~ConnectionFactoryImpl() { |
67 net::NetworkChangeNotifier::RemoveIPAddressObserver(this); | 68 net::NetworkChangeNotifier::RemoveIPAddressObserver(this); |
68 net::NetworkChangeNotifier::RemoveConnectionTypeObserver(this); | 69 net::NetworkChangeNotifier::RemoveConnectionTypeObserver(this); |
69 if (pac_request_) { | 70 if (pac_request_) { |
70 network_session_->proxy_service()->CancelPacRequest(pac_request_); | 71 network_session_->proxy_service()->CancelPacRequest(pac_request_); |
71 pac_request_ = NULL; | 72 pac_request_ = NULL; |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
133 | 134 |
134 DVLOG(1) << "Attempting connection to MCS endpoint."; | 135 DVLOG(1) << "Attempting connection to MCS endpoint."; |
135 waiting_for_backoff_ = false; | 136 waiting_for_backoff_ = false; |
136 ConnectImpl(); | 137 ConnectImpl(); |
137 } | 138 } |
138 | 139 |
139 bool ConnectionFactoryImpl::IsEndpointReachable() const { | 140 bool ConnectionFactoryImpl::IsEndpointReachable() const { |
140 return connection_handler_ && connection_handler_->CanSendMessage(); | 141 return connection_handler_ && connection_handler_->CanSendMessage(); |
141 } | 142 } |
142 | 143 |
144 std::string ConnectionFactoryImpl::GetConnectionStateString() const { | |
145 if (IsEndpointReachable()) | |
146 return "CONNECTED"; | |
fgorski
2014/06/05 00:03:11
the list of bool variables begs for a state enum..
Nicolas Zea
2014/06/05 20:17:27
The problem is that they are not mutually exclusiv
| |
147 if (logging_in_) | |
148 return "LOGGING IN"; | |
149 if (connecting_) | |
150 return "CONNECTING"; | |
151 if (waiting_for_backoff_) | |
152 return "WAITING FOR BACKOFF"; | |
153 return "NOT CONNECTED"; | |
154 } | |
155 | |
143 void ConnectionFactoryImpl::SignalConnectionReset( | 156 void ConnectionFactoryImpl::SignalConnectionReset( |
144 ConnectionResetReason reason) { | 157 ConnectionResetReason reason) { |
145 // A failure can trigger multiple resets, so no need to do anything if a | 158 // A failure can trigger multiple resets, so no need to do anything if a |
146 // connection is already in progress. | 159 // connection is already in progress. |
147 if (connecting_) { | 160 if (connecting_) { |
148 DVLOG(1) << "Connection in progress, ignoring reset."; | 161 DVLOG(1) << "Connection in progress, ignoring reset."; |
149 return; | 162 return; |
150 } | 163 } |
151 | 164 |
165 if (listener_) | |
166 listener_->OnDisconnected(); | |
167 | |
152 UMA_HISTOGRAM_ENUMERATION("GCM.ConnectionResetReason", | 168 UMA_HISTOGRAM_ENUMERATION("GCM.ConnectionResetReason", |
153 reason, | 169 reason, |
154 CONNECTION_RESET_COUNT); | 170 CONNECTION_RESET_COUNT); |
155 recorder_->RecordConnectionResetSignaled(reason); | 171 recorder_->RecordConnectionResetSignaled(reason); |
156 if (!last_login_time_.is_null()) { | 172 if (!last_login_time_.is_null()) { |
157 UMA_HISTOGRAM_CUSTOM_TIMES("GCM.ConnectionUpTime", | 173 UMA_HISTOGRAM_CUSTOM_TIMES("GCM.ConnectionUpTime", |
158 NowTicks() - last_login_time_, | 174 NowTicks() - last_login_time_, |
159 base::TimeDelta::FromSeconds(1), | 175 base::TimeDelta::FromSeconds(1), |
160 base::TimeDelta::FromHours(24), | 176 base::TimeDelta::FromHours(24), |
161 50); | 177 50); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
195 DCHECK(!connecting_); | 211 DCHECK(!connecting_); |
196 DCHECK(!waiting_for_backoff_); | 212 DCHECK(!waiting_for_backoff_); |
197 | 213 |
198 // At this point the last login time has been consumed or deemed irrelevant, | 214 // At this point the last login time has been consumed or deemed irrelevant, |
199 // reset it. | 215 // reset it. |
200 last_login_time_ = base::TimeTicks(); | 216 last_login_time_ = base::TimeTicks(); |
201 | 217 |
202 Connect(); | 218 Connect(); |
203 } | 219 } |
204 | 220 |
221 void ConnectionFactoryImpl::SetConnectionListener( | |
222 ConnectionListener* listener) { | |
223 listener_ = listener; | |
224 } | |
225 | |
205 base::TimeTicks ConnectionFactoryImpl::NextRetryAttempt() const { | 226 base::TimeTicks ConnectionFactoryImpl::NextRetryAttempt() const { |
206 if (!backoff_entry_) | 227 if (!backoff_entry_) |
207 return base::TimeTicks(); | 228 return base::TimeTicks(); |
208 return backoff_entry_->GetReleaseTime(); | 229 return backoff_entry_->GetReleaseTime(); |
209 } | 230 } |
210 | 231 |
211 void ConnectionFactoryImpl::OnConnectionTypeChanged( | 232 void ConnectionFactoryImpl::OnConnectionTypeChanged( |
212 net::NetworkChangeNotifier::ConnectionType type) { | 233 net::NetworkChangeNotifier::ConnectionType type) { |
213 if (type == net::NetworkChangeNotifier::CONNECTION_NONE) | 234 if (type == net::NetworkChangeNotifier::CONNECTION_NONE) |
214 return; | 235 return; |
(...skipping 12 matching lines...) Expand all Loading... | |
227 } | 248 } |
228 | 249 |
229 GURL ConnectionFactoryImpl::GetCurrentEndpoint() const { | 250 GURL ConnectionFactoryImpl::GetCurrentEndpoint() const { |
230 // Note that IsEndpointReachable() returns false anytime connecting_ is true, | 251 // Note that IsEndpointReachable() returns false anytime connecting_ is true, |
231 // so while connecting this always uses |next_endpoint_|. | 252 // so while connecting this always uses |next_endpoint_|. |
232 if (IsEndpointReachable()) | 253 if (IsEndpointReachable()) |
233 return mcs_endpoints_[last_successful_endpoint_]; | 254 return mcs_endpoints_[last_successful_endpoint_]; |
234 return mcs_endpoints_[next_endpoint_]; | 255 return mcs_endpoints_[next_endpoint_]; |
235 } | 256 } |
236 | 257 |
258 net::IPEndPoint ConnectionFactoryImpl::GetCurrentIP() { | |
259 if (!socket_handle_.socket()) | |
260 return net::IPEndPoint(); | |
261 | |
262 net::IPEndPoint ip_endpoint; | |
263 int result = socket_handle_.socket()->GetPeerAddress(&ip_endpoint); | |
264 if (result != net::OK) | |
265 return net::IPEndPoint(); | |
266 | |
267 return ip_endpoint; | |
268 } | |
269 | |
237 void ConnectionFactoryImpl::ConnectImpl() { | 270 void ConnectionFactoryImpl::ConnectImpl() { |
238 DCHECK(!IsEndpointReachable()); | 271 DCHECK(!IsEndpointReachable()); |
239 DCHECK(!socket_handle_.socket()); | 272 DCHECK(!socket_handle_.socket()); |
240 | 273 |
241 connecting_ = true; | 274 connecting_ = true; |
242 GURL current_endpoint = GetCurrentEndpoint(); | 275 GURL current_endpoint = GetCurrentEndpoint(); |
243 recorder_->RecordConnectionInitiated(current_endpoint.host()); | 276 recorder_->RecordConnectionInitiated(current_endpoint.host()); |
244 int status = network_session_->proxy_service()->ResolveProxy( | 277 int status = network_session_->proxy_service()->ResolveProxy( |
245 current_endpoint, | 278 current_endpoint, |
246 &proxy_info_, | 279 &proxy_info_, |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
341 } | 374 } |
342 | 375 |
343 // Handshake complete, reset backoff. If the login failed with an error, | 376 // Handshake complete, reset backoff. If the login failed with an error, |
344 // the client should invoke SignalConnectionReset(LOGIN_FAILURE), which will | 377 // the client should invoke SignalConnectionReset(LOGIN_FAILURE), which will |
345 // restore the previous backoff. | 378 // restore the previous backoff. |
346 DVLOG(1) << "Handshake complete."; | 379 DVLOG(1) << "Handshake complete."; |
347 last_login_time_ = NowTicks(); | 380 last_login_time_ = NowTicks(); |
348 previous_backoff_.swap(backoff_entry_); | 381 previous_backoff_.swap(backoff_entry_); |
349 backoff_entry_->Reset(); | 382 backoff_entry_->Reset(); |
350 logging_in_ = false; | 383 logging_in_ = false; |
384 | |
385 if (listener_) | |
386 listener_->OnConnected(GetCurrentEndpoint(), GetCurrentIP()); | |
351 } | 387 } |
352 | 388 |
353 // This has largely been copied from | 389 // This has largely been copied from |
354 // HttpStreamFactoryImpl::Job::DoResolveProxyComplete. This should be | 390 // HttpStreamFactoryImpl::Job::DoResolveProxyComplete. This should be |
355 // refactored into some common place. | 391 // refactored into some common place. |
356 void ConnectionFactoryImpl::OnProxyResolveDone(int status) { | 392 void ConnectionFactoryImpl::OnProxyResolveDone(int status) { |
357 pac_request_ = NULL; | 393 pac_request_ = NULL; |
358 DVLOG(1) << "Proxy resolution status: " << status; | 394 DVLOG(1) << "Proxy resolution status: " << status; |
359 | 395 |
360 DCHECK_NE(status, net::ERR_IO_PENDING); | 396 DCHECK_NE(status, net::ERR_IO_PENDING); |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
493 // the destroyed socket. | 529 // the destroyed socket. |
494 if (connection_handler_) | 530 if (connection_handler_) |
495 connection_handler_->Reset(); | 531 connection_handler_->Reset(); |
496 | 532 |
497 if (socket_handle_.socket() && socket_handle_.socket()->IsConnected()) | 533 if (socket_handle_.socket() && socket_handle_.socket()->IsConnected()) |
498 socket_handle_.socket()->Disconnect(); | 534 socket_handle_.socket()->Disconnect(); |
499 socket_handle_.Reset(); | 535 socket_handle_.Reset(); |
500 } | 536 } |
501 | 537 |
502 } // namespace gcm | 538 } // namespace gcm |
OLD | NEW |