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 |