Chromium Code Reviews| 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 "components/gcm_driver/gcm_client_impl.h" | 5 #include "components/gcm_driver/gcm_client_impl.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/files/file_path.h" | 8 #include "base/files/file_path.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
| 11 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
| 12 #include "base/metrics/histogram.h" | 12 #include "base/metrics/histogram.h" |
|
Alexei Svitkine (slow)
2015/02/10 13:47:06
Nit: Change this to histogram_macros.h instead.
jianli
2015/02/10 19:45:14
Done.
| |
| 13 #include "base/sequenced_task_runner.h" | 13 #include "base/sequenced_task_runner.h" |
| 14 #include "base/stl_util.h" | 14 #include "base/stl_util.h" |
| 15 #include "base/strings/string_number_conversions.h" | 15 #include "base/strings/string_number_conversions.h" |
| 16 #include "base/strings/stringprintf.h" | 16 #include "base/strings/stringprintf.h" |
| 17 #include "base/time/default_clock.h" | 17 #include "base/time/default_clock.h" |
| 18 #include "base/timer/timer.h" | 18 #include "base/timer/timer.h" |
| 19 #include "components/gcm_driver/gcm_account_mapper.h" | 19 #include "components/gcm_driver/gcm_account_mapper.h" |
| 20 #include "components/gcm_driver/gcm_backoff_policy.h" | 20 #include "components/gcm_driver/gcm_backoff_policy.h" |
| 21 #include "google_apis/gcm/base/encryptor.h" | 21 #include "google_apis/gcm/base/encryptor.h" |
| 22 #include "google_apis/gcm/base/mcs_message.h" | 22 #include "google_apis/gcm/base/mcs_message.h" |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 51 TTL_LESS_THAN_OR_EQUAL_TO_ONE_DAY, | 51 TTL_LESS_THAN_OR_EQUAL_TO_ONE_DAY, |
| 52 TTL_LESS_THAN_OR_EQUAL_TO_ONE_WEEK, | 52 TTL_LESS_THAN_OR_EQUAL_TO_ONE_WEEK, |
| 53 TTL_MORE_THAN_ONE_WEEK, | 53 TTL_MORE_THAN_ONE_WEEK, |
| 54 TTL_MAXIMUM, | 54 TTL_MAXIMUM, |
| 55 // NOTE: always keep this entry at the end. Add new TTL category only | 55 // NOTE: always keep this entry at the end. Add new TTL category only |
| 56 // immediately above this line. Make sure to update the corresponding | 56 // immediately above this line. Make sure to update the corresponding |
| 57 // histogram enum accordingly. | 57 // histogram enum accordingly. |
| 58 TTL_CATEGORY_COUNT | 58 TTL_CATEGORY_COUNT |
| 59 }; | 59 }; |
| 60 | 60 |
| 61 enum ResetStoreError { | |
| 62 DESTROYING_STORE_FAILED, | |
| 63 INFINITE_STORE_RESET, | |
| 64 // NOTE: always keep this entry at the end. Add new value only immediately | |
| 65 // above this line. Make sure to update the corresponding histogram enum | |
| 66 // accordingly. | |
| 67 RESET_STORE_ERROR_COUNT | |
| 68 }; | |
| 69 | |
| 61 const int kMaxRegistrationRetries = 5; | 70 const int kMaxRegistrationRetries = 5; |
| 62 const char kMessageTypeDataMessage[] = "gcm"; | 71 const char kMessageTypeDataMessage[] = "gcm"; |
| 63 const char kMessageTypeDeletedMessagesKey[] = "deleted_messages"; | 72 const char kMessageTypeDeletedMessagesKey[] = "deleted_messages"; |
| 64 const char kMessageTypeKey[] = "message_type"; | 73 const char kMessageTypeKey[] = "message_type"; |
| 65 const char kMessageTypeSendErrorKey[] = "send_error"; | 74 const char kMessageTypeSendErrorKey[] = "send_error"; |
| 66 const char kSendErrorMessageIdKey[] = "google.message_id"; | 75 const char kSendErrorMessageIdKey[] = "google.message_id"; |
| 67 const char kSendMessageFromValue[] = "gcm@chrome.com"; | 76 const char kSendMessageFromValue[] = "gcm@chrome.com"; |
| 68 const int64 kDefaultUserSerialNumber = 0LL; | 77 const int64 kDefaultUserSerialNumber = 0LL; |
| 69 | 78 |
| 70 GCMClient::Result ToGCMClientResult(MCSClient::MessageSendStatus status) { | 79 GCMClient::Result ToGCMClientResult(MCSClient::MessageSendStatus status) { |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 238 account_tokens.clear(); | 247 account_tokens.clear(); |
| 239 last_checkin_accounts.clear(); | 248 last_checkin_accounts.clear(); |
| 240 } | 249 } |
| 241 | 250 |
| 242 GCMClientImpl::GCMClientImpl(scoped_ptr<GCMInternalsBuilder> internals_builder) | 251 GCMClientImpl::GCMClientImpl(scoped_ptr<GCMInternalsBuilder> internals_builder) |
| 243 : internals_builder_(internals_builder.Pass()), | 252 : internals_builder_(internals_builder.Pass()), |
| 244 state_(UNINITIALIZED), | 253 state_(UNINITIALIZED), |
| 245 delegate_(NULL), | 254 delegate_(NULL), |
| 246 start_mode_(DELAYED_START), | 255 start_mode_(DELAYED_START), |
| 247 clock_(internals_builder_->BuildClock()), | 256 clock_(internals_builder_->BuildClock()), |
| 257 gcm_store_reset_(false), | |
| 248 url_request_context_getter_(NULL), | 258 url_request_context_getter_(NULL), |
| 249 pending_registration_requests_deleter_(&pending_registration_requests_), | 259 pending_registration_requests_deleter_(&pending_registration_requests_), |
| 250 pending_unregistration_requests_deleter_( | 260 pending_unregistration_requests_deleter_( |
| 251 &pending_unregistration_requests_), | 261 &pending_unregistration_requests_), |
| 252 periodic_checkin_ptr_factory_(this), | 262 periodic_checkin_ptr_factory_(this), |
| 253 weak_ptr_factory_(this) { | 263 weak_ptr_factory_(this) { |
| 254 } | 264 } |
| 255 | 265 |
| 256 GCMClientImpl::~GCMClientImpl() { | 266 GCMClientImpl::~GCMClientImpl() { |
| 257 } | 267 } |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 309 // Once the loading is completed, the check-in will be initiated. | 319 // Once the loading is completed, the check-in will be initiated. |
| 310 gcm_store_->Load(base::Bind(&GCMClientImpl::OnLoadCompleted, | 320 gcm_store_->Load(base::Bind(&GCMClientImpl::OnLoadCompleted, |
| 311 weak_ptr_factory_.GetWeakPtr())); | 321 weak_ptr_factory_.GetWeakPtr())); |
| 312 state_ = LOADING; | 322 state_ = LOADING; |
| 313 } | 323 } |
| 314 | 324 |
| 315 void GCMClientImpl::OnLoadCompleted(scoped_ptr<GCMStore::LoadResult> result) { | 325 void GCMClientImpl::OnLoadCompleted(scoped_ptr<GCMStore::LoadResult> result) { |
| 316 DCHECK_EQ(LOADING, state_); | 326 DCHECK_EQ(LOADING, state_); |
| 317 | 327 |
| 318 if (!result->success) { | 328 if (!result->success) { |
| 319 ResetState(); | 329 ResetStore(); |
| 320 return; | 330 return; |
| 321 } | 331 } |
| 332 gcm_store_reset_ = false; | |
| 322 | 333 |
| 323 registrations_ = result->registrations; | 334 registrations_ = result->registrations; |
| 324 device_checkin_info_.android_id = result->device_android_id; | 335 device_checkin_info_.android_id = result->device_android_id; |
| 325 device_checkin_info_.secret = result->device_security_token; | 336 device_checkin_info_.secret = result->device_security_token; |
| 326 device_checkin_info_.last_checkin_accounts = result->last_checkin_accounts; | 337 device_checkin_info_.last_checkin_accounts = result->last_checkin_accounts; |
| 327 // A case where there were previously no accounts reported with checkin is | 338 // A case where there were previously no accounts reported with checkin is |
| 328 // considered to be the same as when the list of accounts is empty. It enables | 339 // considered to be the same as when the list of accounts is empty. It enables |
| 329 // scheduling a periodic checkin for devices with no signed in users | 340 // scheduling a periodic checkin for devices with no signed in users |
| 330 // immediately after restart, while keeping |accounts_set == false| delays the | 341 // immediately after restart, while keeping |accounts_set == false| delays the |
| 331 // checkin until the list of accounts is set explicitly. | 342 // checkin until the list of accounts is set explicitly. |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 419 delegate_->OnGCMReady(account_mappings, last_token_fetch_time); | 430 delegate_->OnGCMReady(account_mappings, last_token_fetch_time); |
| 420 } | 431 } |
| 421 | 432 |
| 422 void GCMClientImpl::StartMCSLogin() { | 433 void GCMClientImpl::StartMCSLogin() { |
| 423 DCHECK_EQ(READY, state_); | 434 DCHECK_EQ(READY, state_); |
| 424 DCHECK(device_checkin_info_.IsValid()); | 435 DCHECK(device_checkin_info_.IsValid()); |
| 425 mcs_client_->Login(device_checkin_info_.android_id, | 436 mcs_client_->Login(device_checkin_info_.android_id, |
| 426 device_checkin_info_.secret); | 437 device_checkin_info_.secret); |
| 427 } | 438 } |
| 428 | 439 |
| 429 void GCMClientImpl::ResetState() { | 440 void GCMClientImpl::ResetStore() { |
| 430 state_ = UNINITIALIZED; | 441 DCHECK_EQ(LOADING, state_); |
| 431 // TODO(fgorski): reset all of the necessart objects and start over. | 442 |
| 443 // If already being reset, don't do it again. We want to prevent from | |
| 444 // resetting and loading from the store again and again. | |
| 445 if (gcm_store_reset_) { | |
| 446 UMA_HISTOGRAM_ENUMERATION( | |
| 447 "GCM.ResetStore", INFINITE_STORE_RESET, RESET_STORE_ERROR_COUNT); | |
|
Alexei Svitkine (slow)
2015/02/10 13:47:06
Nit: Make a function in the anon namespace for thi
jianli
2015/02/10 19:45:14
Done.
| |
| 448 state_ = UNINITIALIZED; | |
| 449 return; | |
| 450 } | |
| 451 gcm_store_reset_ = true; | |
| 452 | |
| 453 // Destroy the GCM store to start over. | |
| 454 gcm_store_->Destroy(base::Bind(&GCMClientImpl::ResetStoreCallback, | |
| 455 weak_ptr_factory_.GetWeakPtr())); | |
| 432 } | 456 } |
| 433 | 457 |
| 434 void GCMClientImpl::SetAccountTokens( | 458 void GCMClientImpl::SetAccountTokens( |
| 435 const std::vector<AccountTokenInfo>& account_tokens) { | 459 const std::vector<AccountTokenInfo>& account_tokens) { |
| 436 device_checkin_info_.account_tokens.clear(); | 460 device_checkin_info_.account_tokens.clear(); |
| 437 for (std::vector<AccountTokenInfo>::const_iterator iter = | 461 for (std::vector<AccountTokenInfo>::const_iterator iter = |
| 438 account_tokens.begin(); | 462 account_tokens.begin(); |
| 439 iter != account_tokens.end(); | 463 iter != account_tokens.end(); |
| 440 ++iter) { | 464 ++iter) { |
| 441 device_checkin_info_.account_tokens[iter->email] = iter->access_token; | 465 device_checkin_info_.account_tokens[iter->email] = iter->access_token; |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 620 | 644 |
| 621 void GCMClientImpl::DefaultStoreCallback(bool success) { | 645 void GCMClientImpl::DefaultStoreCallback(bool success) { |
| 622 DCHECK(success); | 646 DCHECK(success); |
| 623 } | 647 } |
| 624 | 648 |
| 625 void GCMClientImpl::IgnoreWriteResultCallback(bool success) { | 649 void GCMClientImpl::IgnoreWriteResultCallback(bool success) { |
| 626 // TODO(fgorski): Ignoring the write result for now to make sure | 650 // TODO(fgorski): Ignoring the write result for now to make sure |
| 627 // sync_intergration_tests are not broken. | 651 // sync_intergration_tests are not broken. |
| 628 } | 652 } |
| 629 | 653 |
| 654 void GCMClientImpl::ResetStoreCallback(bool success) { | |
| 655 UMA_HISTOGRAM_ENUMERATION( | |
| 656 "GCM.ResetStore", DESTROYING_STORE_FAILED, RESET_STORE_ERROR_COUNT); | |
|
Nicolas Zea
2015/02/10 18:59:46
Why is this saying we failed? Shouldn't that be de
jianli
2015/02/10 19:45:14
My bad. It should be placed within if block.
| |
| 657 | |
| 658 if (!success) { | |
| 659 LOG(ERROR) << "Failed to reset GCM store"; | |
| 660 state_ = UNINITIALIZED; | |
| 661 return; | |
| 662 } | |
| 663 | |
| 664 state_ = INITIALIZED; | |
| 665 Start(start_mode_); | |
| 666 } | |
| 667 | |
| 630 void GCMClientImpl::Stop() { | 668 void GCMClientImpl::Stop() { |
| 631 // TODO(fgorski): Perhaps we should make a distinction between a Stop and a | 669 // TODO(fgorski): Perhaps we should make a distinction between a Stop and a |
| 632 // Shutdown. | 670 // Shutdown. |
| 633 DVLOG(1) << "Stopping the GCM Client"; | 671 DVLOG(1) << "Stopping the GCM Client"; |
| 634 weak_ptr_factory_.InvalidateWeakPtrs(); | 672 weak_ptr_factory_.InvalidateWeakPtrs(); |
| 635 periodic_checkin_ptr_factory_.InvalidateWeakPtrs(); | 673 periodic_checkin_ptr_factory_.InvalidateWeakPtrs(); |
| 636 device_checkin_info_.Reset(); | 674 device_checkin_info_.Reset(); |
| 637 connection_factory_.reset(); | 675 connection_factory_.reset(); |
| 638 delegate_->OnDisconnected(); | 676 delegate_->OnDisconnected(); |
| 639 mcs_client_.reset(); | 677 mcs_client_.reset(); |
| (...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1020 bool GCMClientImpl::HasStandaloneRegisteredApp() const { | 1058 bool GCMClientImpl::HasStandaloneRegisteredApp() const { |
| 1021 if (registrations_.empty()) | 1059 if (registrations_.empty()) |
| 1022 return false; | 1060 return false; |
| 1023 // Note that account mapper is not counted as a standalone app since it is | 1061 // Note that account mapper is not counted as a standalone app since it is |
| 1024 // automatically started when other app uses GCM. | 1062 // automatically started when other app uses GCM. |
| 1025 return registrations_.size() > 1 || | 1063 return registrations_.size() > 1 || |
| 1026 !registrations_.count(kGCMAccountMapperAppId); | 1064 !registrations_.count(kGCMAccountMapperAppId); |
| 1027 } | 1065 } |
| 1028 | 1066 |
| 1029 } // namespace gcm | 1067 } // namespace gcm |
| OLD | NEW |