OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "base/base64.h" | 5 #include "base/base64.h" |
6 #include "base/i18n/time_formatting.h" | 6 #include "base/i18n/time_formatting.h" |
7 #include "base/metrics/histogram.h" | 7 #include "base/metrics/histogram.h" |
8 #include "base/sha1.h" | 8 #include "base/sha1.h" |
9 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 } | 148 } |
149 | 149 |
150 GCMNetworkChannel::GCMNetworkChannel( | 150 GCMNetworkChannel::GCMNetworkChannel( |
151 scoped_refptr<net::URLRequestContextGetter> request_context_getter, | 151 scoped_refptr<net::URLRequestContextGetter> request_context_getter, |
152 scoped_ptr<GCMNetworkChannelDelegate> delegate) | 152 scoped_ptr<GCMNetworkChannelDelegate> delegate) |
153 : request_context_getter_(request_context_getter), | 153 : request_context_getter_(request_context_getter), |
154 delegate_(delegate.Pass()), | 154 delegate_(delegate.Pass()), |
155 register_backoff_entry_(new net::BackoffEntry(&kRegisterBackoffPolicy)), | 155 register_backoff_entry_(new net::BackoffEntry(&kRegisterBackoffPolicy)), |
156 diagnostic_info_(this), | 156 diagnostic_info_(this), |
157 weak_factory_(this) { | 157 weak_factory_(this) { |
| 158 net::NetworkChangeNotifier::AddNetworkChangeObserver(this); |
158 delegate_->Initialize(); | 159 delegate_->Initialize(); |
159 Register(); | 160 Register(); |
160 } | 161 } |
161 | 162 |
162 GCMNetworkChannel::~GCMNetworkChannel() { | 163 GCMNetworkChannel::~GCMNetworkChannel() { |
| 164 net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this); |
163 } | 165 } |
164 | 166 |
165 void GCMNetworkChannel::UpdateCredentials( | 167 void GCMNetworkChannel::UpdateCredentials( |
166 const std::string& email, | 168 const std::string& email, |
167 const std::string& token) { | 169 const std::string& token) { |
168 // Do nothing. We get access token by requesting it for every message. | 170 // Do nothing. We get access token by requesting it for every message. |
169 } | 171 } |
170 | 172 |
171 void GCMNetworkChannel::RequestDetailedStatus( | 173 void GCMNetworkChannel::RequestDetailedStatus( |
172 base::Callback<void(const base::DictionaryValue&)> callback) { | 174 base::Callback<void(const base::DictionaryValue&)> callback) { |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
254 // Nothing to do. | 256 // Nothing to do. |
255 return; | 257 return; |
256 } | 258 } |
257 | 259 |
258 if (error.state() != GoogleServiceAuthError::NONE) { | 260 if (error.state() != GoogleServiceAuthError::NONE) { |
259 // Requesting access token failed. Persistent errors will be reported by | 261 // Requesting access token failed. Persistent errors will be reported by |
260 // token service. Just drop this request, cacheinvalidations will retry | 262 // token service. Just drop this request, cacheinvalidations will retry |
261 // sending message and at that time we'll retry requesting access token. | 263 // sending message and at that time we'll retry requesting access token. |
262 DVLOG(1) << "RequestAccessToken failed: " << error.ToString(); | 264 DVLOG(1) << "RequestAccessToken failed: " << error.ToString(); |
263 RecordOutgoingMessageStatus(ACCESS_TOKEN_FAILURE); | 265 RecordOutgoingMessageStatus(ACCESS_TOKEN_FAILURE); |
| 266 // Message won't get sent because of connection failure. Let's retry once |
| 267 // connection is restored. |
| 268 if (error.state() == GoogleServiceAuthError::CONNECTION_FAILED) |
| 269 NotifyStateChange(TRANSIENT_INVALIDATION_ERROR); |
264 cached_message_.clear(); | 270 cached_message_.clear(); |
265 return; | 271 return; |
266 } | 272 } |
267 DCHECK(!token.empty()); | 273 DCHECK(!token.empty()); |
268 // Save access token in case POST fails and we need to invalidate it. | 274 // Save access token in case POST fails and we need to invalidate it. |
269 access_token_ = token; | 275 access_token_ = token; |
270 | 276 |
271 DVLOG(2) << "Got access token, sending message"; | 277 DVLOG(2) << "Got access token, sending message"; |
272 fetcher_.reset(net::URLFetcher::Create( | 278 fetcher_.reset(net::URLFetcher::Create( |
273 BuildUrl(registration_id_), net::URLFetcher::POST, this)); | 279 BuildUrl(registration_id_), net::URLFetcher::POST, this)); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
330 fetcher->GetResponseCode() == net::HTTP_UNAUTHORIZED) { | 336 fetcher->GetResponseCode() == net::HTTP_UNAUTHORIZED) { |
331 DVLOG(1) << "URLFetcher failure: HTTP_UNAUTHORIZED"; | 337 DVLOG(1) << "URLFetcher failure: HTTP_UNAUTHORIZED"; |
332 delegate_->InvalidateToken(access_token_); | 338 delegate_->InvalidateToken(access_token_); |
333 } | 339 } |
334 | 340 |
335 if (!status.is_success() || | 341 if (!status.is_success() || |
336 (fetcher->GetResponseCode() != net::HTTP_OK && | 342 (fetcher->GetResponseCode() != net::HTTP_OK && |
337 fetcher->GetResponseCode() != net::HTTP_NO_CONTENT)) { | 343 fetcher->GetResponseCode() != net::HTTP_NO_CONTENT)) { |
338 DVLOG(1) << "URLFetcher failure"; | 344 DVLOG(1) << "URLFetcher failure"; |
339 RecordOutgoingMessageStatus(POST_FAILURE); | 345 RecordOutgoingMessageStatus(POST_FAILURE); |
| 346 NotifyStateChange(TRANSIENT_INVALIDATION_ERROR); |
340 return; | 347 return; |
341 } | 348 } |
342 | 349 |
343 RecordOutgoingMessageStatus(OUTGOING_MESSAGE_SUCCESS); | 350 RecordOutgoingMessageStatus(OUTGOING_MESSAGE_SUCCESS); |
| 351 NotifyStateChange(INVALIDATIONS_ENABLED); |
344 DVLOG(2) << "URLFetcher success"; | 352 DVLOG(2) << "URLFetcher success"; |
345 } | 353 } |
346 | 354 |
| 355 void GCMNetworkChannel::OnNetworkChanged( |
| 356 net::NetworkChangeNotifier::ConnectionType connection_type) { |
| 357 // Network connection is restored. Let's notify cacheinvalidations so it has |
| 358 // chance to retry. |
| 359 if (connection_type != net::NetworkChangeNotifier::CONNECTION_NONE) |
| 360 NotifyStateChange(INVALIDATIONS_ENABLED); |
| 361 } |
| 362 |
347 GURL GCMNetworkChannel::BuildUrl(const std::string& registration_id) { | 363 GURL GCMNetworkChannel::BuildUrl(const std::string& registration_id) { |
348 DCHECK(!registration_id.empty()); | 364 DCHECK(!registration_id.empty()); |
349 | 365 |
350 #if !defined(ANDROID) | 366 #if !defined(ANDROID) |
351 ipc::invalidation::EndpointId endpoint_id; | 367 ipc::invalidation::EndpointId endpoint_id; |
352 endpoint_id.set_c2dm_registration_id(registration_id); | 368 endpoint_id.set_c2dm_registration_id(registration_id); |
353 endpoint_id.set_client_key(std::string()); | 369 endpoint_id.set_client_key(std::string()); |
354 endpoint_id.set_package_name(kCacheInvalidationPackageName); | 370 endpoint_id.set_package_name(kCacheInvalidationPackageName); |
355 endpoint_id.mutable_channel_version()->set_major_version( | 371 endpoint_id.mutable_channel_version()->set_major_version( |
356 ipc::invalidation::INITIAL); | 372 ipc::invalidation::INITIAL); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
396 size_t padded_size = (input.size() + 3) - (input.size() + 3) % 4; | 412 size_t padded_size = (input.size() + 3) - (input.size() + 3) % 4; |
397 std::string padded_input(input); | 413 std::string padded_input(input); |
398 padded_input.resize(padded_size, '='); | 414 padded_input.resize(padded_size, '='); |
399 // Convert to standard base64 alphabet. | 415 // Convert to standard base64 alphabet. |
400 base::ReplaceChars(padded_input, "-", "+", &padded_input); | 416 base::ReplaceChars(padded_input, "-", "+", &padded_input); |
401 base::ReplaceChars(padded_input, "_", "/", &padded_input); | 417 base::ReplaceChars(padded_input, "_", "/", &padded_input); |
402 return base::Base64Decode(padded_input, output); | 418 return base::Base64Decode(padded_input, output); |
403 } | 419 } |
404 | 420 |
405 } // namespace syncer | 421 } // namespace syncer |
OLD | NEW |