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

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

Issue 215363007: [GCM] Adding basic G-services handling (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressing the feedback Created 6 years, 9 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
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 7f272870d808cffb0c2134867fa4b9be205b6bef..4496f15dbbcf14f7b9e5fc4a4014438682bed7dc 100644
--- a/google_apis/gcm/engine/gcm_store_impl.cc
+++ b/google_apis/gcm/engine/gcm_store_impl.cc
@@ -16,12 +16,14 @@
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
+#include "base/time/time.h"
#include "base/tracked_objects.h"
#include "components/os_crypt/os_crypt.h"
#include "google_apis/gcm/base/mcs_message.h"
#include "google_apis/gcm/base/mcs_util.h"
#include "google_apis/gcm/protocol/mcs.pb.h"
#include "third_party/leveldatabase/src/include/leveldb/db.h"
+#include "third_party/leveldatabase/src/include/leveldb/write_batch.h"
namespace gcm {
@@ -53,6 +55,14 @@ const char kOutgoingMsgKeyStart[] = "outgoing1-";
// Key guaranteed to be higher than all outgoing message keys.
// Used for limiting iteration.
const char kOutgoingMsgKeyEnd[] = "outgoing2-";
+// Lowest lexicographically ordered G service settings key.
+// Used for prefixing G services settings.
+const char kGServiceSettingKeyStart[] = "Gservice1-";
+// Key guaranteed to be higher than all G services settings keys.
+// Used for limiting iteration.
+const char kGServiceSettingKeyEnd[] = "Gservice2-";
+// Key used to timestamp last checkin (marked with G services settings update).
+const char kLastCheckinTimeKey[] = "last_checkin_time";
std::string MakeRegistrationKey(const std::string& app_id) {
return kRegistrationKeyStart + app_id;
@@ -74,6 +84,14 @@ std::string ParseOutgoingKey(const std::string& key) {
return key.substr(arraysize(kOutgoingMsgKeyStart) - 1);
}
+std::string MakeGServiceSettingKey(const std::string& setting_name) {
+ return kGServiceSettingKeyStart + setting_name;
+}
+
+std::string ParseGServiceSettingKey(const std::string& key) {
+ return key.substr(arraysize(kGServiceSettingKeyStart) - 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.
@@ -118,6 +136,11 @@ class GCMStoreImpl::Backend
void RemoveUserSerialNumber(const std::string& username,
const UpdateCallback& callback);
void SetNextSerialNumber(int64 serial_number, const UpdateCallback& callback);
+ void UpdateGServicesSettings(
+ const std::vector<std::string>& settings_to_remove,
+ const std::map<std::string, std::string>& settings_to_add,
+ const base::Time& last_checkin_time,
+ const UpdateCallback& callback);
private:
friend class base::RefCountedThreadSafe<Backend>;
@@ -127,6 +150,8 @@ class GCMStoreImpl::Backend
bool LoadRegistrations(RegistrationInfoMap* registrations);
bool LoadIncomingMessages(std::vector<std::string>* incoming_messages);
bool LoadOutgoingMessages(OutgoingMessageMap* outgoing_messages);
+ bool LoadGServicesSettings(std::map<std::string, std::string>* settings,
+ base::Time* last_checkin_time);
const base::FilePath path_;
scoped_refptr<base::SequencedTaskRunner> foreground_task_runner_;
@@ -171,12 +196,15 @@ void GCMStoreImpl::Backend::Load(const LoadCallback& callback) {
&result->device_security_token) ||
!LoadRegistrations(&result->registrations) ||
!LoadIncomingMessages(&result->incoming_messages) ||
- !LoadOutgoingMessages(&result->outgoing_messages)) {
+ !LoadOutgoingMessages(&result->outgoing_messages) ||
+ !LoadGServicesSettings(&result->g_services_settings,
+ &result->last_checkin_time)) {
result->device_android_id = 0;
result->device_security_token = 0;
result->registrations.clear();
result->incoming_messages.clear();
result->outgoing_messages.clear();
+ result->last_checkin_time = base::Time::FromInternalValue(0LL);
foreground_task_runner_->PostTask(FROM_HERE,
base::Bind(callback,
base::Passed(&result)));
@@ -445,6 +473,43 @@ void GCMStoreImpl::Backend::RemoveOutgoingMessages(
AppIdToMessageCountMap()));
}
+void GCMStoreImpl::Backend::UpdateGServicesSettings(
+ const std::vector<std::string>& settings_to_remove,
+ const std::map<std::string, std::string>& settings_to_add,
+ const base::Time& last_checkin_time,
+ const UpdateCallback& callback) {
+ leveldb::WriteBatch write_batch;
+
+ // Delete settings to remove.
+ for (std::vector<std::string>::const_iterator iter =
+ settings_to_remove.begin();
+ iter != settings_to_remove.end(); ++iter) {
+ write_batch.Delete(MakeSlice(MakeGServiceSettingKey(*iter)));
+ }
+
+ // Add settings to add.
+ for (std::map<std::string, std::string>::const_iterator iter =
+ settings_to_add.begin();
+ iter != settings_to_add.end(); ++iter) {
+ write_batch.Put(MakeSlice(MakeGServiceSettingKey(iter->first)),
+ MakeSlice(iter->second));
+ }
+
+ // Update last checkin time. (To Now)
Nicolas Zea 2014/03/28 22:56:53 nit: remove (To Now), which makes it seem like you
fgorski 2014/03/29 01:09:33 Done.
+ int64 last_checkin_time_internal = last_checkin_time.ToInternalValue();
+ write_batch.Put(MakeSlice(kLastCheckinTimeKey),
+ MakeSlice(base::Int64ToString(last_checkin_time_internal)));
+
+ // Write it all in batch.
+ leveldb::WriteOptions write_options;
+ write_options.sync = true;
+
+ leveldb::Status s = db_->Write(write_options, &write_batch);
+ if (!s.ok())
+ LOG(ERROR) << "LevelDB GService Settings update 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;
@@ -560,6 +625,46 @@ bool GCMStoreImpl::Backend::LoadOutgoingMessages(
return true;
}
+bool GCMStoreImpl::Backend::LoadGServicesSettings(
+ std::map<std::string, std::string>* settings,
+ base::Time* last_checkin_time) {
+ leveldb::ReadOptions read_options;
+ read_options.verify_checksums = true;
+
+ scoped_ptr<leveldb::Iterator> iter(db_->NewIterator(read_options));
+ for (iter->Seek(MakeSlice(kGServiceSettingKeyStart));
+ iter->Valid() && iter->key().ToString() < kGServiceSettingKeyEnd;
+ iter->Next()) {
+ std::string value = iter->value().ToString();
+ if (value.empty()) {
+ LOG(ERROR) << "Error reading GService Settings " << value;
+ return false;
+ }
+ std::string id = ParseGServiceSettingKey(iter->key().ToString());
+ (*settings)[id] = value;
+ DVLOG(1) << "Found G Service setting with key: " << id
+ << ", and value: " << value;
+ }
+
+ std::string result;
+ leveldb::Status s = db_->Get(read_options,
+ MakeSlice(kLastCheckinTimeKey),
+ &result);
+ int64 time_internal = 0LL;
+ if (s.ok()) {
+ if (!base::StringToInt64(result, &time_internal)) {
+ LOG(ERROR) << "Failed to restore last checkin time.";
+ return false;
+ }
+ }
+
+ // In case we cannot read last checkin time, we default it to 0, as we don't
+ // want that situation to cause the whole load to fail.
+ *last_checkin_time = base::Time::FromInternalValue(time_internal);
+
+ return true;
+}
+
GCMStoreImpl::GCMStoreImpl(
bool use_mock_keychain,
const base::FilePath& path,
@@ -734,6 +839,21 @@ void GCMStoreImpl::RemoveOutgoingMessages(
callback)));
}
+void GCMStoreImpl::UpdateGServicesSettings(
+ const std::vector<std::string>& settings_to_remove,
+ const std::map<std::string, std::string>& settings_to_add,
+ const base::Time& last_checkin_time,
+ const UpdateCallback& callback) {
+ blocking_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&GCMStoreImpl::Backend::UpdateGServicesSettings,
+ backend_,
+ settings_to_remove,
+ settings_to_add,
+ last_checkin_time,
+ callback));
+}
+
void GCMStoreImpl::LoadContinuation(const LoadCallback& callback,
scoped_ptr<LoadResult> result) {
if (!result->success) {

Powered by Google App Engine
This is Rietveld 408576698