diff options
Diffstat (limited to 'google_apis')
-rw-r--r-- | google_apis/gcm/engine/checkin_request.cc | 12 | ||||
-rw-r--r-- | google_apis/gcm/engine/checkin_request.h | 3 | ||||
-rw-r--r-- | google_apis/gcm/engine/checkin_request_unittest.cc | 18 | ||||
-rw-r--r-- | google_apis/gcm/engine/gcm_store.h | 5 | ||||
-rw-r--r-- | google_apis/gcm/engine/gcm_store_impl.cc | 67 | ||||
-rw-r--r-- | google_apis/gcm/engine/gcm_store_impl.h | 3 | ||||
-rw-r--r-- | google_apis/gcm/engine/gcm_store_impl_unittest.cc | 9 | ||||
-rw-r--r-- | google_apis/gcm/tools/mcs_probe.cc | 7 |
8 files changed, 96 insertions, 28 deletions
diff --git a/google_apis/gcm/engine/checkin_request.cc b/google_apis/gcm/engine/checkin_request.cc index a555847..8ba65ad 100644 --- a/google_apis/gcm/engine/checkin_request.cc +++ b/google_apis/gcm/engine/checkin_request.cc @@ -80,10 +80,12 @@ void RecordCheckinStatusAndReportUMA(CheckinRequestStatus status, CheckinRequest::RequestInfo::RequestInfo( uint64 android_id, uint64 security_token, + const std::map<std::string, std::string>& account_tokens, const std::string& settings_digest, const checkin_proto::ChromeBuildProto& chrome_build_proto) : android_id(android_id), security_token(security_token), + account_tokens(account_tokens), settings_digest(settings_digest), chrome_build_proto(chrome_build_proto) { } @@ -127,6 +129,16 @@ void CheckinRequest::Start() { checkin->set_type(checkin_proto::DEVICE_CHROME_BROWSER); #endif + // Pack a map of email -> token mappings into a repeated field, where odd + // entries are email addresses, while even ones are respective OAuth2 tokens. + for (std::map<std::string, std::string>::const_iterator iter = + request_info_.account_tokens.begin(); + iter != request_info_.account_tokens.end(); + ++iter) { + request.add_account_cookie(iter->first); + request.add_account_cookie(iter->second); + } + std::string upload_data; CHECK(request.SerializeToString(&upload_data)); diff --git a/google_apis/gcm/engine/checkin_request.h b/google_apis/gcm/engine/checkin_request.h index ae4a7d4..c48f3c9 100644 --- a/google_apis/gcm/engine/checkin_request.h +++ b/google_apis/gcm/engine/checkin_request.h @@ -41,6 +41,7 @@ class GCM_EXPORT CheckinRequest : public net::URLFetcherDelegate { struct GCM_EXPORT RequestInfo { RequestInfo(uint64 android_id, uint64 security_token, + const std::map<std::string, std::string>& account_tokens, const std::string& settings_digest, const checkin_proto::ChromeBuildProto& chrome_build_proto); ~RequestInfo(); @@ -49,6 +50,8 @@ class GCM_EXPORT CheckinRequest : public net::URLFetcherDelegate { uint64 android_id; // Security token of the device. uint64 security_token; + // Map of account OAuth2 tokens keyed by emails. + std::map<std::string, std::string> account_tokens; // Digest of GServices settings on the device. std::string settings_digest; // Information of the Chrome build of this device. diff --git a/google_apis/gcm/engine/checkin_request_unittest.cc b/google_apis/gcm/engine/checkin_request_unittest.cc index 12e9a60..6f1c630 100644 --- a/google_apis/gcm/engine/checkin_request_unittest.cc +++ b/google_apis/gcm/engine/checkin_request_unittest.cc @@ -53,6 +53,8 @@ const char kCheckinURL[] = "http://foo.bar/checkin"; const char kChromeVersion[] = "Version String"; const uint64 kSecurityToken = 77; const char kSettingsDigest[] = "settings_digest"; +const char kEmailAddress[] = "test_user@gmail.com"; +const char kTokenValue[] = "token_value"; class CheckinRequestTest : public testing::Test { public: @@ -122,11 +124,14 @@ void CheckinRequestTest::CreateRequest(uint64 android_id, checkin_proto::ChromeBuildProto::CHANNEL_CANARY); chrome_build_proto_.set_chrome_version(kChromeVersion); - CheckinRequest::RequestInfo request_info( - android_id, - security_token, - kSettingsDigest, - chrome_build_proto_); + std::map<std::string, std::string> account_tokens; + account_tokens[kEmailAddress] = kTokenValue; + + CheckinRequest::RequestInfo request_info(android_id, + security_token, + account_tokens, + kSettingsDigest, + chrome_build_proto_); // Then create a request with that protobuf and specified android_id, // security_token. request_.reset(new CheckinRequest( @@ -199,6 +204,9 @@ TEST_F(CheckinRequestTest, FetcherDataAndURL) { request_proto.checkin().chrome_build().chrome_version()); EXPECT_EQ(chrome_build_proto_.channel(), request_proto.checkin().chrome_build().channel()); + EXPECT_EQ(2, request_proto.account_cookie_size()); + EXPECT_EQ(kEmailAddress, request_proto.account_cookie(0)); + EXPECT_EQ(kTokenValue, request_proto.account_cookie(1)); #if defined(CHROME_OS) EXPECT_EQ(checkin_proto::DEVICE_CHROME_OS, request_proto.checkin().type()); diff --git a/google_apis/gcm/engine/gcm_store.h b/google_apis/gcm/engine/gcm_store.h index 8b9891d0..ca02850 100644 --- a/google_apis/gcm/engine/gcm_store.h +++ b/google_apis/gcm/engine/gcm_store.h @@ -6,6 +6,7 @@ #define GOOGLE_APIS_GCM_ENGINE_GCM_STORE_H_ #include <map> +#include <set> #include <string> #include <vector> @@ -46,6 +47,7 @@ class GCM_EXPORT GCMStore { std::map<std::string, std::string> gservices_settings; std::string gservices_digest; base::Time last_checkin_time; + std::set<std::string> last_checkin_accounts; }; typedef std::vector<std::string> PersistentIdList; @@ -101,7 +103,8 @@ class GCM_EXPORT GCMStore { const UpdateCallback& callback) = 0; // Sets last device's checkin time. - virtual void SetLastCheckinTime(const base::Time& last_checkin_time, + virtual void SetLastCheckinInfo(const base::Time& time, + const std::set<std::string>& accounts, const UpdateCallback& callback) = 0; // G-service settings handling. diff --git a/google_apis/gcm/engine/gcm_store_impl.cc b/google_apis/gcm/engine/gcm_store_impl.cc index e27e82e..df35925 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)); } diff --git a/google_apis/gcm/engine/gcm_store_impl.h b/google_apis/gcm/engine/gcm_store_impl.h index f49509a..30ce411 100644 --- a/google_apis/gcm/engine/gcm_store_impl.h +++ b/google_apis/gcm/engine/gcm_store_impl.h @@ -77,7 +77,8 @@ class GCM_EXPORT GCMStoreImpl : public GCMStore { const UpdateCallback& callback) OVERRIDE; // Sets last device's checkin time. - virtual void SetLastCheckinTime(const base::Time& last_checkin_time, + virtual void SetLastCheckinInfo(const base::Time& time, + const std::set<std::string>& accounts, const UpdateCallback& callback) OVERRIDE; // G-service settings handling. diff --git a/google_apis/gcm/engine/gcm_store_impl_unittest.cc b/google_apis/gcm/engine/gcm_store_impl_unittest.cc index 7b9c893..ad4b024 100644 --- a/google_apis/gcm/engine/gcm_store_impl_unittest.cc +++ b/google_apis/gcm/engine/gcm_store_impl_unittest.cc @@ -142,7 +142,7 @@ TEST_F(GCMStoreImplTest, DeviceCredentials) { ASSERT_EQ(kDeviceToken, load_result->device_security_token); } -TEST_F(GCMStoreImplTest, LastCheckinTime) { +TEST_F(GCMStoreImplTest, LastCheckinInfo) { scoped_ptr<GCMStore> gcm_store(BuildGCMStore()); scoped_ptr<GCMStore::LoadResult> load_result; gcm_store->Load(base::Bind( @@ -150,9 +150,13 @@ TEST_F(GCMStoreImplTest, LastCheckinTime) { PumpLoop(); base::Time last_checkin_time = base::Time::Now(); + std::set<std::string> accounts; + accounts.insert("test_user1@gmail.com"); + accounts.insert("test_user2@gmail.com"); - gcm_store->SetLastCheckinTime( + gcm_store->SetLastCheckinInfo( last_checkin_time, + accounts, base::Bind(&GCMStoreImplTest::UpdateCallback, base::Unretained(this))); PumpLoop(); @@ -161,6 +165,7 @@ TEST_F(GCMStoreImplTest, LastCheckinTime) { &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result)); PumpLoop(); ASSERT_EQ(last_checkin_time, load_result->last_checkin_time); + ASSERT_EQ(accounts, load_result->last_checkin_accounts); } TEST_F(GCMStoreImplTest, GServicesSettings_ProtocolV2) { diff --git a/google_apis/gcm/tools/mcs_probe.cc b/google_apis/gcm/tools/mcs_probe.cc index 1bb0bc1..9e090fd 100644 --- a/google_apis/gcm/tools/mcs_probe.cc +++ b/google_apis/gcm/tools/mcs_probe.cc @@ -431,8 +431,11 @@ void MCSProbe::CheckIn() { checkin_proto::ChromeBuildProto::CHANNEL_CANARY); chrome_build_proto.set_chrome_version(kChromeVersion); - CheckinRequest::RequestInfo request_info( - 0, 0, std::string(), chrome_build_proto); + CheckinRequest::RequestInfo request_info(0, + 0, + std::map<std::string, std::string>(), + std::string(), + chrome_build_proto); checkin_request_.reset(new CheckinRequest( GServicesSettings::DefaultCheckinURL(), |