| Index: google_apis/gcm/engine/gcm_store_impl.cc
|
| diff --git a/google_apis/gcm/engine/gcm_store_impl.cc b/google_apis/gcm/engine/gcm_store_impl.cc
|
| index e27e82e6ce273b4fa8f2805185e4b29364418801..df35925a5bc0ea6ca51ca4cf08e3db85c2e2223b 100644
|
| --- a/google_apis/gcm/engine/gcm_store_impl.cc
|
| +++ b/google_apis/gcm/engine/gcm_store_impl.cc
|
| @@ -16,6 +16,7 @@
|
| #include "base/stl_util.h"
|
| #include "base/strings/string_number_conversions.h"
|
| #include "base/strings/string_piece.h"
|
| +#include "base/strings/string_tokenizer.h"
|
| #include "base/time/time.h"
|
| #include "base/tracked_objects.h"
|
| #include "google_apis/gcm/base/encryptor.h"
|
| @@ -63,6 +64,8 @@ const char kGServiceSettingKeyStart[] = "gservice1-";
|
| const char kGServiceSettingKeyEnd[] = "gservice2-";
|
| // Key for digest of the last G-services settings update.
|
| const char kGServiceSettingsDigestKey[] = "gservices_digest";
|
| +// Key used to indicate how many accounts were last checked in with this device.
|
| +const char kLastCheckinAccountsKey[] = "last_checkin_accounts_count";
|
| // Key used to timestamp last checkin (marked with G services settings update).
|
| const char kLastCheckinTimeKey[] = "last_checkin_time";
|
|
|
| @@ -138,7 +141,8 @@ class GCMStoreImpl::Backend
|
| const UpdateCallback& callback);
|
| void RemoveUserSerialNumber(const std::string& username,
|
| const UpdateCallback& callback);
|
| - void SetLastCheckinTime(const base::Time& last_checkin_time,
|
| + void SetLastCheckinInfo(const base::Time& time,
|
| + const std::set<std::string>& accounts,
|
| const UpdateCallback& callback);
|
| void SetGServicesSettings(
|
| const std::map<std::string, std::string>& settings,
|
| @@ -153,7 +157,8 @@ class GCMStoreImpl::Backend
|
| bool LoadRegistrations(RegistrationInfoMap* registrations);
|
| bool LoadIncomingMessages(std::vector<std::string>* incoming_messages);
|
| bool LoadOutgoingMessages(OutgoingMessageMap* outgoing_messages);
|
| - bool LoadLastCheckinTime(base::Time* last_checkin_time);
|
| + bool LoadLastCheckinInfo(base::Time* last_checkin_time,
|
| + std::set<std::string>* accounts);
|
| bool LoadGServicesSettings(std::map<std::string, std::string>* settings,
|
| std::string* digest);
|
|
|
| @@ -206,7 +211,8 @@ void GCMStoreImpl::Backend::Load(const LoadCallback& callback) {
|
| !LoadRegistrations(&result->registrations) ||
|
| !LoadIncomingMessages(&result->incoming_messages) ||
|
| !LoadOutgoingMessages(&result->outgoing_messages) ||
|
| - !LoadLastCheckinTime(&result->last_checkin_time) ||
|
| + !LoadLastCheckinInfo(&result->last_checkin_time,
|
| + &result->last_checkin_accounts) ||
|
| !LoadGServicesSettings(&result->gservices_settings,
|
| &result->gservices_digest)) {
|
| result->device_android_id = 0;
|
| @@ -485,20 +491,35 @@ void GCMStoreImpl::Backend::RemoveOutgoingMessages(
|
| AppIdToMessageCountMap()));
|
| }
|
|
|
| -void GCMStoreImpl::Backend::SetLastCheckinTime(
|
| - const base::Time& last_checkin_time,
|
| +void GCMStoreImpl::Backend::SetLastCheckinInfo(
|
| + const base::Time& time,
|
| + const std::set<std::string>& accounts,
|
| const UpdateCallback& callback) {
|
| + leveldb::WriteBatch write_batch;
|
| +
|
| + int64 last_checkin_time_internal = time.ToInternalValue();
|
| + write_batch.Put(MakeSlice(kLastCheckinTimeKey),
|
| + MakeSlice(base::Int64ToString(last_checkin_time_internal)));
|
| +
|
| + std::string serialized_accounts;
|
| + for (std::set<std::string>::iterator iter = accounts.begin();
|
| + iter != accounts.end();
|
| + ++iter) {
|
| + serialized_accounts += *iter;
|
| + serialized_accounts += ",";
|
| + }
|
| + if (!serialized_accounts.empty())
|
| + serialized_accounts.erase(serialized_accounts.length() - 1);
|
| +
|
| + write_batch.Put(MakeSlice(kLastCheckinAccountsKey),
|
| + MakeSlice(serialized_accounts));
|
| +
|
| leveldb::WriteOptions write_options;
|
| write_options.sync = true;
|
| -
|
| - int64 last_checkin_time_internal = last_checkin_time.ToInternalValue();
|
| - const leveldb::Status s =
|
| - db_->Put(write_options,
|
| - MakeSlice(kLastCheckinTimeKey),
|
| - MakeSlice(base::Int64ToString(last_checkin_time_internal)));
|
| + const leveldb::Status s = db_->Write(write_options, &write_batch);
|
|
|
| if (!s.ok())
|
| - LOG(ERROR) << "LevelDB set last checkin time failed: " << s.ToString();
|
| + LOG(ERROR) << "LevelDB set last checkin info failed: " << s.ToString();
|
| foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, s.ok()));
|
| }
|
|
|
| @@ -655,8 +676,9 @@ bool GCMStoreImpl::Backend::LoadOutgoingMessages(
|
| return true;
|
| }
|
|
|
| -bool GCMStoreImpl::Backend::LoadLastCheckinTime(
|
| - base::Time* last_checkin_time) {
|
| +bool GCMStoreImpl::Backend::LoadLastCheckinInfo(
|
| + base::Time* last_checkin_time,
|
| + std::set<std::string>* accounts) {
|
| leveldb::ReadOptions read_options;
|
| read_options.verify_checksums = true;
|
|
|
| @@ -672,6 +694,15 @@ bool GCMStoreImpl::Backend::LoadLastCheckinTime(
|
| // want that situation to cause the whole load to fail.
|
| *last_checkin_time = base::Time::FromInternalValue(time_internal);
|
|
|
| + accounts->clear();
|
| + s = db_->Get(read_options, MakeSlice(kLastCheckinAccountsKey), &result);
|
| + if (!s.ok())
|
| + DVLOG(1) << "No accounts where stored during last run.";
|
| +
|
| + base::StringTokenizer t(result, ",");
|
| + while (t.GetNext())
|
| + accounts->insert(t.token());
|
| +
|
| return true;
|
| }
|
|
|
| @@ -877,13 +908,15 @@ void GCMStoreImpl::RemoveOutgoingMessages(
|
| callback)));
|
| }
|
|
|
| -void GCMStoreImpl::SetLastCheckinTime(const base::Time& last_checkin_time,
|
| +void GCMStoreImpl::SetLastCheckinInfo(const base::Time& time,
|
| + const std::set<std::string>& accounts,
|
| const UpdateCallback& callback) {
|
| blocking_task_runner_->PostTask(
|
| FROM_HERE,
|
| - base::Bind(&GCMStoreImpl::Backend::SetLastCheckinTime,
|
| + base::Bind(&GCMStoreImpl::Backend::SetLastCheckinInfo,
|
| backend_,
|
| - last_checkin_time,
|
| + time,
|
| + accounts,
|
| callback));
|
| }
|
|
|
|
|