Chromium Code Reviews| Index: components/gcm_driver/gcm_client_impl.cc |
| diff --git a/components/gcm_driver/gcm_client_impl.cc b/components/gcm_driver/gcm_client_impl.cc |
| index 6b1c980f00ff8441153b58afde58881516509f0c..236b240cbba7e9e1146585e1a0ef246dc6529f1f 100644 |
| --- a/components/gcm_driver/gcm_client_impl.cc |
| +++ b/components/gcm_driver/gcm_client_impl.cc |
| @@ -9,7 +9,7 @@ |
| #include "base/logging.h" |
| #include "base/memory/scoped_ptr.h" |
| #include "base/message_loop/message_loop.h" |
| -#include "base/metrics/histogram.h" |
| +#include "base/metrics/histogram_macros.h" |
| #include "base/sequenced_task_runner.h" |
| #include "base/stl_util.h" |
| #include "base/strings/string_number_conversions.h" |
| @@ -58,6 +58,15 @@ enum OutgoingMessageTTLCategory { |
| TTL_CATEGORY_COUNT |
| }; |
| +enum ResetStoreError { |
| + DESTROYING_STORE_FAILED, |
| + INFINITE_STORE_RESET, |
| + // NOTE: always keep this entry at the end. Add new value only immediately |
| + // above this line. Make sure to update the corresponding histogram enum |
| + // accordingly. |
| + RESET_STORE_ERROR_COUNT |
| +}; |
| + |
| const int kMaxRegistrationRetries = 5; |
| const char kMessageTypeDataMessage[] = "gcm"; |
| const char kMessageTypeDeletedMessagesKey[] = "deleted_messages"; |
| @@ -179,6 +188,10 @@ void RecordOutgoingMessageToUMA( |
| TTL_CATEGORY_COUNT); |
| } |
| +void RecordResetStoreErrorToUMA(ResetStoreError error) { |
| + UMA_HISTOGRAM_ENUMERATION("GCM.ResetStore", error, RESET_STORE_ERROR_COUNT); |
|
Alexei Svitkine (slow)
2015/02/10 19:51:24
Nit: Indent 2 less.
jianli
2015/02/10 21:11:53
Done.
|
| +} |
| + |
| } // namespace |
| GCMInternalsBuilder::GCMInternalsBuilder() {} |
| @@ -245,6 +258,7 @@ GCMClientImpl::GCMClientImpl(scoped_ptr<GCMInternalsBuilder> internals_builder) |
| delegate_(NULL), |
| start_mode_(DELAYED_START), |
| clock_(internals_builder_->BuildClock()), |
| + gcm_store_reset_(false), |
| url_request_context_getter_(NULL), |
| pending_registration_requests_deleter_(&pending_registration_requests_), |
| pending_unregistration_requests_deleter_( |
| @@ -316,9 +330,10 @@ void GCMClientImpl::OnLoadCompleted(scoped_ptr<GCMStore::LoadResult> result) { |
| DCHECK_EQ(LOADING, state_); |
| if (!result->success) { |
| - ResetState(); |
| + ResetStore(); |
| return; |
| } |
| + gcm_store_reset_ = false; |
| registrations_ = result->registrations; |
| device_checkin_info_.android_id = result->device_android_id; |
| @@ -426,9 +441,21 @@ void GCMClientImpl::StartMCSLogin() { |
| device_checkin_info_.secret); |
| } |
| -void GCMClientImpl::ResetState() { |
| - state_ = UNINITIALIZED; |
| - // TODO(fgorski): reset all of the necessart objects and start over. |
| +void GCMClientImpl::ResetStore() { |
| + DCHECK_EQ(LOADING, state_); |
| + |
| + // If already being reset, don't do it again. We want to prevent from |
| + // resetting and loading from the store again and again. |
| + if (gcm_store_reset_) { |
| + RecordResetStoreErrorToUMA(INFINITE_STORE_RESET); |
| + state_ = UNINITIALIZED; |
| + return; |
| + } |
| + gcm_store_reset_ = true; |
| + |
| + // Destroy the GCM store to start over. |
| + gcm_store_->Destroy(base::Bind(&GCMClientImpl::ResetStoreCallback, |
| + weak_ptr_factory_.GetWeakPtr())); |
| } |
| void GCMClientImpl::SetAccountTokens( |
| @@ -627,6 +654,18 @@ void GCMClientImpl::IgnoreWriteResultCallback(bool success) { |
| // sync_intergration_tests are not broken. |
| } |
| +void GCMClientImpl::ResetStoreCallback(bool success) { |
| + if (!success) { |
| + LOG(ERROR) << "Failed to reset GCM store"; |
| + RecordResetStoreErrorToUMA(DESTROYING_STORE_FAILED); |
| + state_ = UNINITIALIZED; |
| + return; |
| + } |
| + |
| + state_ = INITIALIZED; |
| + Start(start_mode_); |
| +} |
| + |
| void GCMClientImpl::Stop() { |
| // TODO(fgorski): Perhaps we should make a distinction between a Stop and a |
| // Shutdown. |