| 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 4105e68518b6cd89dbce19c1c122554d82e9b367..ab68e4dc7d45c95d9352deea39010f8109a982be 100644
|
| --- a/google_apis/gcm/engine/gcm_store_impl.cc
|
| +++ b/google_apis/gcm/engine/gcm_store_impl.cc
|
| @@ -48,6 +48,7 @@ enum LoadStatus {
|
| LOADING_ACCOUNT_MAPPING_FAILED,
|
| LOADING_LAST_TOKEN_TIME_FAILED,
|
| LOADING_HEARTBEAT_INTERVALS_FAILED,
|
| + LOADING_INSTANCE_ID_DATA_FAILED,
|
|
|
| // NOTE: always keep this entry at the end. Add new status types only
|
| // immediately above this line. Make sure to update the corresponding
|
| @@ -107,6 +108,12 @@ const char kHeartbeatKeyStart[] = "heartbeat1-";
|
| const char kHeartbeatKeyEnd[] = "heartbeat2-";
|
| // Key used for last token fetch time.
|
| const char kLastTokenFetchTimeKey[] = "last_token_fetch_time";
|
| +// Lowest lexicographically ordered app ids.
|
| +// Used for prefixing app id.
|
| +const char kInstanceIDKeyStart[] = "iid1-";
|
| +// Key guaranteed to be higher than all app ids.
|
| +// Used for limiting iteration.
|
| +const char kInstanceIDKeyEnd[] = "iid2-";
|
|
|
| std::string MakeRegistrationKey(const std::string& app_id) {
|
| return kRegistrationKeyStart + app_id;
|
| @@ -152,6 +159,14 @@ std::string ParseHeartbeatKey(const std::string& key) {
|
| return key.substr(arraysize(kHeartbeatKeyStart) - 1);
|
| }
|
|
|
| +std::string MakeInstanceIDKey(const std::string& app_id) {
|
| + return kInstanceIDKeyStart + app_id;
|
| +}
|
| +
|
| +std::string ParseInstanceIDKey(const std::string& key) {
|
| + return key.substr(arraysize(kInstanceIDKeyStart) - 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.
|
| @@ -214,6 +229,11 @@ class GCMStoreImpl::Backend
|
| const UpdateCallback& callback);
|
| void RemoveHeartbeatInterval(const std::string& scope,
|
| const UpdateCallback& callback);
|
| + void AddInstanceIDData(const std::string& app_id,
|
| + const std::string& instance_id_data,
|
| + const UpdateCallback& callback);
|
| + void RemoveInstanceIDData(const std::string& app_id,
|
| + const UpdateCallback& callback);
|
| void SetValue(const std::string& key,
|
| const std::string& value,
|
| const UpdateCallback& callback);
|
| @@ -234,6 +254,7 @@ class GCMStoreImpl::Backend
|
| bool LoadAccountMappingInfo(AccountMappings* account_mappings);
|
| bool LoadLastTokenFetchTime(base::Time* last_token_fetch_time);
|
| bool LoadHeartbeatIntervals(std::map<std::string, int>* heartbeat_intervals);
|
| + bool LoadInstanceIDData(std::map<std::string, std::string>* instance_id_data);
|
|
|
| const base::FilePath path_;
|
| scoped_refptr<base::SequencedTaskRunner> foreground_task_runner_;
|
| @@ -297,6 +318,8 @@ LoadStatus GCMStoreImpl::Backend::OpenStoreAndLoadData(LoadResult* result) {
|
| return LOADING_LAST_TOKEN_TIME_FAILED;
|
| if (!LoadHeartbeatIntervals(&result->heartbeat_intervals))
|
| return LOADING_HEARTBEAT_INTERVALS_FAILED;
|
| + if (!LoadInstanceIDData(&result->instance_id_data))
|
| + return LOADING_INSTANCE_ID_DATA_FAILED;
|
|
|
| return LOADING_SUCCEEDED;
|
| }
|
| @@ -607,6 +630,28 @@ void GCMStoreImpl::Backend::SetLastCheckinInfo(
|
| foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, s.ok()));
|
| }
|
|
|
| +void GCMStoreImpl::AddInstanceIDData(const std::string& app_id,
|
| + const std::string& instance_id_data,
|
| + const UpdateCallback& callback) {
|
| + blocking_task_runner_->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&GCMStoreImpl::Backend::AddInstanceIDData,
|
| + backend_,
|
| + app_id,
|
| + instance_id_data,
|
| + callback));
|
| +}
|
| +
|
| +void GCMStoreImpl::RemoveInstanceIDData(const std::string& app_id,
|
| + const UpdateCallback& callback) {
|
| + blocking_task_runner_->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&GCMStoreImpl::Backend::RemoveInstanceIDData,
|
| + backend_,
|
| + app_id,
|
| + callback));
|
| +}
|
| +
|
| void GCMStoreImpl::Backend::SetGServicesSettings(
|
| const std::map<std::string, std::string>& settings,
|
| const std::string& settings_digest,
|
| @@ -757,6 +802,49 @@ void GCMStoreImpl::Backend::RemoveHeartbeatInterval(
|
| foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, s.ok()));
|
| }
|
|
|
| +void GCMStoreImpl::Backend::AddInstanceIDData(
|
| + const std::string& app_id,
|
| + const std::string& instance_id_data,
|
| + const UpdateCallback& callback) {
|
| + DVLOG(1) << "Adding Instance ID data.";
|
| + 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 key = MakeInstanceIDKey(app_id);
|
| + const leveldb::Status status = db_->Put(write_options,
|
| + MakeSlice(key),
|
| + MakeSlice(instance_id_data));
|
| + if (!status.ok())
|
| + LOG(ERROR) << "LevelDB put failed: " << status.ToString();
|
| + foreground_task_runner_->PostTask(
|
| + FROM_HERE, base::Bind(callback, status.ok()));
|
| +}
|
| +
|
| +void GCMStoreImpl::Backend::RemoveInstanceIDData(
|
| + const std::string& app_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 status =
|
| + db_->Delete(write_options, MakeSlice(MakeInstanceIDKey(app_id)));
|
| + if (!status.ok())
|
| + LOG(ERROR) << "LevelDB remove failed: " << status.ToString();
|
| + foreground_task_runner_->PostTask(
|
| + FROM_HERE, base::Bind(callback, status.ok()));
|
| +}
|
| +
|
| void GCMStoreImpl::Backend::SetValue(const std::string& key,
|
| const std::string& value,
|
| const UpdateCallback& callback) {
|
| @@ -1022,6 +1110,28 @@ bool GCMStoreImpl::Backend::LoadHeartbeatIntervals(
|
| return true;
|
| }
|
|
|
| +bool GCMStoreImpl::Backend::LoadInstanceIDData(
|
| + std::map<std::string, std::string>* instance_id_data) {
|
| + leveldb::ReadOptions read_options;
|
| + read_options.verify_checksums = true;
|
| +
|
| + scoped_ptr<leveldb::Iterator> iter(db_->NewIterator(read_options));
|
| + for (iter->Seek(MakeSlice(kInstanceIDKeyStart));
|
| + iter->Valid() && iter->key().ToString() < kInstanceIDKeyEnd;
|
| + iter->Next()) {
|
| + leveldb::Slice s = iter->value();
|
| + if (s.size() <= 1) {
|
| + LOG(ERROR) << "Error reading IID data with key " << s.ToString();
|
| + return false;
|
| + }
|
| + std::string app_id = ParseInstanceIDKey(iter->key().ToString());
|
| + DVLOG(1) << "Found IID data with app id " << app_id;
|
| + (*instance_id_data)[app_id] = s.ToString();
|
| + }
|
| +
|
| + return true;
|
| +}
|
| +
|
| GCMStoreImpl::GCMStoreImpl(
|
| const base::FilePath& path,
|
| scoped_refptr<base::SequencedTaskRunner> blocking_task_runner,
|
|
|