Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1658)

Unified Diff: google_apis/gcm/engine/gcm_store_impl.cc

Issue 429073002: [GCM] Persistence of account mappings. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixing the gn build Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « google_apis/gcm/engine/gcm_store_impl.h ('k') | google_apis/gcm/engine/gcm_store_impl_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 df35925a5bc0ea6ca51ca4cf08e3db85c2e2223b..3764d0fbb5a3f6d3be3ef798b1d017d0427097f6 100644
--- a/google_apis/gcm/engine/gcm_store_impl.cc
+++ b/google_apis/gcm/engine/gcm_store_impl.cc
@@ -68,6 +68,12 @@ const char kGServiceSettingsDigestKey[] = "gservices_digest";
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";
+// Lowest lexicographically ordered account key.
+// Used for prefixing account information.
+const char kAccountKeyStart[] = "account1-";
+// Key guaranteed to be higher than all account keys.
+// Used for limiting iteration.
+const char kAccountKeyEnd[] = "account2-";
std::string MakeRegistrationKey(const std::string& app_id) {
return kRegistrationKeyStart + app_id;
@@ -97,6 +103,14 @@ std::string ParseGServiceSettingKey(const std::string& key) {
return key.substr(arraysize(kGServiceSettingKeyStart) - 1);
}
+std::string MakeAccountKey(const std::string& account_id) {
+ return kAccountKeyStart + account_id;
+}
+
+std::string ParseAccountKey(const std::string& key) {
+ return key.substr(arraysize(kAccountKeyStart) - 1);
+}
+
// Note: leveldb::Slice keeps a pointer to the data in |s|, which must therefore
// outlive the slice.
// For example: MakeSlice(MakeOutgoingKey(x)) is invalid.
@@ -148,6 +162,10 @@ class GCMStoreImpl::Backend
const std::map<std::string, std::string>& settings,
const std::string& digest,
const UpdateCallback& callback);
+ void AddAccountMapping(const AccountInfo& account_info,
+ const UpdateCallback& callback);
+ void RemoveAccountMapping(const std::string& account_id,
+ const UpdateCallback& callback);
private:
friend class base::RefCountedThreadSafe<Backend>;
@@ -161,6 +179,7 @@ class GCMStoreImpl::Backend
std::set<std::string>* accounts);
bool LoadGServicesSettings(std::map<std::string, std::string>* settings,
std::string* digest);
+ bool LoadAccountMappingInfo(AccountInfoMap* account_infos);
const base::FilePath path_;
scoped_refptr<base::SequencedTaskRunner> foreground_task_runner_;
@@ -214,15 +233,9 @@ void GCMStoreImpl::Backend::Load(const LoadCallback& callback) {
!LoadLastCheckinInfo(&result->last_checkin_time,
&result->last_checkin_accounts) ||
!LoadGServicesSettings(&result->gservices_settings,
- &result->gservices_digest)) {
- result->device_android_id = 0;
- result->device_security_token = 0;
- result->registrations.clear();
- result->incoming_messages.clear();
- result->outgoing_messages.clear();
- result->gservices_settings.clear();
- result->gservices_digest.clear();
- result->last_checkin_time = base::Time::FromInternalValue(0LL);
+ &result->gservices_digest) ||
+ !LoadAccountMappingInfo(&result->account_infos)) {
+ result->Reset();
foreground_task_runner_->PostTask(FROM_HERE,
base::Bind(callback,
base::Passed(&result)));
@@ -561,6 +574,48 @@ void GCMStoreImpl::Backend::SetGServicesSettings(
foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, s.ok()));
}
+void GCMStoreImpl::Backend::AddAccountMapping(const AccountInfo& account_info,
+ const UpdateCallback& callback) {
+ DVLOG(1) << "Saving account info for account with email: "
+ << account_info.email;
+ if (!db_.get()) {
+ LOG(ERROR) << "GCMStore db doesn't exist.";
+ foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false));
+ return;
+ }
+
+ leveldb::WriteOptions write_options;
+ write_options.sync = true;
+
+ std::string data = account_info.SerializeAsString();
+ std::string key = MakeAccountKey(account_info.account_id);
+ const leveldb::Status s =
+ db_->Put(write_options, MakeSlice(key), MakeSlice(data));
+ if (!s.ok())
+ LOG(ERROR) << "LevelDB adding account mapping failed: " << s.ToString();
+ foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, s.ok()));
+}
+
+void GCMStoreImpl::Backend::RemoveAccountMapping(
+ const std::string& account_id,
+ const UpdateCallback& callback) {
+ if (!db_.get()) {
+ LOG(ERROR) << "GCMStore db doesn't exist.";
+ foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false));
+ return;
+ }
+
+ leveldb::WriteOptions write_options;
+ write_options.sync = true;
+
+ leveldb::Status s =
+ db_->Delete(write_options, MakeSlice(MakeAccountKey(account_id)));
+
+ if (!s.ok())
+ LOG(ERROR) << "LevelDB removal of account mapping failed: " << s.ToString();
+ foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, s.ok()));
+}
+
bool GCMStoreImpl::Backend::LoadDeviceCredentials(uint64* android_id,
uint64* security_token) {
leveldb::ReadOptions read_options;
@@ -734,6 +789,29 @@ bool GCMStoreImpl::Backend::LoadGServicesSettings(
return true;
}
+bool GCMStoreImpl::Backend::LoadAccountMappingInfo(
+ AccountInfoMap* account_infos) {
+ leveldb::ReadOptions read_options;
+ read_options.verify_checksums = true;
+
+ scoped_ptr<leveldb::Iterator> iter(db_->NewIterator(read_options));
+ for (iter->Seek(MakeSlice(kAccountKeyStart));
+ iter->Valid() && iter->key().ToString() < kAccountKeyEnd;
+ iter->Next()) {
+ AccountInfo account_info;
+ account_info.account_id = ParseAccountKey(iter->key().ToString());
+ if (!account_info.ParseFromString(iter->value().ToString())) {
+ DVLOG(1) << "Failed to parse account info with ID: "
+ << account_info.account_id;
+ return false;
+ }
+ DVLOG(1) << "Found account mapping with ID: " << account_info.account_id;
+ (*account_infos)[account_info.account_id] = account_info;
+ }
+
+ return true;
+}
+
GCMStoreImpl::GCMStoreImpl(
const base::FilePath& path,
scoped_refptr<base::SequencedTaskRunner> blocking_task_runner,
@@ -933,6 +1011,26 @@ void GCMStoreImpl::SetGServicesSettings(
callback));
}
+void GCMStoreImpl::AddAccountMapping(const AccountInfo& account_info,
+ const UpdateCallback& callback) {
+ blocking_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&GCMStoreImpl::Backend::AddAccountMapping,
+ backend_,
+ account_info,
+ callback));
+}
+
+void GCMStoreImpl::RemoveAccountMapping(const std::string& account_id,
+ const UpdateCallback& callback) {
+ blocking_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&GCMStoreImpl::Backend::RemoveAccountMapping,
+ backend_,
+ account_id,
+ callback));
+}
+
void GCMStoreImpl::LoadContinuation(const LoadCallback& callback,
scoped_ptr<LoadResult> result) {
if (!result->success) {
« no previous file with comments | « google_apis/gcm/engine/gcm_store_impl.h ('k') | google_apis/gcm/engine/gcm_store_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698