diff options
author | fgorski@chromium.org <fgorski@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-10 21:10:22 +0000 |
---|---|---|
committer | fgorski@chromium.org <fgorski@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-10 21:10:22 +0000 |
commit | 2c4d4cd81117ee0dc4d9e119b210228117362653 (patch) | |
tree | 640fbdbd297636a2ecdc6e79033d87dd555aec17 /google_apis | |
parent | 7dc9e3fd0fdaaa0b5bfe75f2c7dbe5ab94be8cb2 (diff) | |
download | chromium_src-2c4d4cd81117ee0dc4d9e119b210228117362653.zip chromium_src-2c4d4cd81117ee0dc4d9e119b210228117362653.tar.gz chromium_src-2c4d4cd81117ee0dc4d9e119b210228117362653.tar.bz2 |
Adding basic G-services handling
* extracting CheckinRequest::RequestInfo to better manage checkin parameters
* adding G-services settings digest to RequestInfo of the checkin (will be sent with checkin request)
* extracting G-services settings from checkin response
* storing and loading of the G-services settings in GCM Store
This patch relands https://codereview.chromium.org/215363007/ after all
of the trybots, buildbots and CQ have been updated to run gcm_unit_tests
TBR=zea@chromium.org,jianli@chromium.org
BUG=359254
Review URL: https://codereview.chromium.org/233103003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@263079 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'google_apis')
-rw-r--r-- | google_apis/gcm/engine/checkin_request.cc | 42 | ||||
-rw-r--r-- | google_apis/gcm/engine/checkin_request.h | 45 | ||||
-rw-r--r-- | google_apis/gcm/engine/checkin_request_unittest.cc | 37 | ||||
-rw-r--r-- | google_apis/gcm/engine/gcm_store.h | 10 | ||||
-rw-r--r-- | google_apis/gcm/engine/gcm_store_impl.cc | 108 | ||||
-rw-r--r-- | google_apis/gcm/engine/gcm_store_impl.h | 6 | ||||
-rw-r--r-- | google_apis/gcm/engine/gcm_store_impl_unittest.cc | 50 | ||||
-rw-r--r-- | google_apis/gcm/gcm_client_impl.cc | 33 | ||||
-rw-r--r-- | google_apis/gcm/gcm_client_impl.h | 15 | ||||
-rw-r--r-- | google_apis/gcm/tools/mcs_probe.cc | 31 |
10 files changed, 298 insertions, 79 deletions
diff --git a/google_apis/gcm/engine/checkin_request.cc b/google_apis/gcm/engine/checkin_request.cc index 94a6fc9..7addbeb 100644 --- a/google_apis/gcm/engine/checkin_request.cc +++ b/google_apis/gcm/engine/checkin_request.cc @@ -46,21 +46,30 @@ void RecordCheckinStatusToUMA(CheckinRequestStatus status) { } // namespace -CheckinRequest::CheckinRequest( - const CheckinRequestCallback& callback, - const net::BackoffEntry::Policy& backoff_policy, - const checkin_proto::ChromeBuildProto& chrome_build_proto, +CheckinRequest::RequestInfo::RequestInfo( uint64 android_id, uint64 security_token, + const std::string& settings_digest, const std::vector<std::string>& account_ids, + const checkin_proto::ChromeBuildProto& chrome_build_proto) + : android_id(android_id), + security_token(security_token), + settings_digest(settings_digest), + account_ids(account_ids), + chrome_build_proto(chrome_build_proto) { +} + +CheckinRequest::RequestInfo::~RequestInfo() {} + +CheckinRequest::CheckinRequest( + const RequestInfo& request_info, + const net::BackoffEntry::Policy& backoff_policy, + const CheckinRequestCallback& callback, net::URLRequestContextGetter* request_context_getter) : request_context_getter_(request_context_getter), callback_(callback), backoff_entry_(&backoff_policy), - chrome_build_proto_(chrome_build_proto), - android_id_(android_id), - security_token_(security_token), - account_ids_(account_ids), + request_info_(request_info), weak_ptr_factory_(this) { } @@ -70,21 +79,24 @@ void CheckinRequest::Start() { DCHECK(!url_fetcher_.get()); checkin_proto::AndroidCheckinRequest request; - request.set_id(android_id_); - request.set_security_token(security_token_); + request.set_id(request_info_.android_id); + request.set_security_token(request_info_.security_token); request.set_user_serial_number(kDefaultUserSerialNumber); request.set_version(kRequestVersionValue); + if (!request_info_.settings_digest.empty()) + request.set_digest(request_info_.settings_digest); checkin_proto::AndroidCheckinProto* checkin = request.mutable_checkin(); - checkin->mutable_chrome_build()->CopyFrom(chrome_build_proto_); + checkin->mutable_chrome_build()->CopyFrom(request_info_.chrome_build_proto); #if defined(CHROME_OS) checkin->set_type(checkin_proto::DEVICE_CHROME_OS); #else checkin->set_type(checkin_proto::DEVICE_CHROME_BROWSER); #endif - for (std::vector<std::string>::const_iterator iter = account_ids_.begin(); - iter != account_ids_.end(); + for (std::vector<std::string>::const_iterator iter = + request_info_.account_ids.begin(); + iter != request_info_.account_ids.end(); ++iter) { request.add_account_cookie("[" + *iter + "]"); } @@ -141,7 +153,7 @@ void CheckinRequest::OnURLFetchComplete(const net::URLFetcher* source) { << response_status << ". Checkin failed."; RecordCheckinStatusToUMA(response_status == net::HTTP_BAD_REQUEST ? HTTP_BAD_REQUEST : HTTP_UNAUTHORIZED); - callback_.Run(0,0); + callback_.Run(response_proto); return; } @@ -167,7 +179,7 @@ void CheckinRequest::OnURLFetchComplete(const net::URLFetcher* source) { } RecordCheckinStatusToUMA(SUCCESS); - callback_.Run(response_proto.android_id(), response_proto.security_token()); + callback_.Run(response_proto); } } // namespace gcm diff --git a/google_apis/gcm/engine/checkin_request.h b/google_apis/gcm/engine/checkin_request.h index e11089a..1d706a7 100644 --- a/google_apis/gcm/engine/checkin_request.h +++ b/google_apis/gcm/engine/checkin_request.h @@ -12,7 +12,7 @@ #include "base/callback.h" #include "base/memory/weak_ptr.h" #include "google_apis/gcm/base/gcm_export.h" -#include "google_apis/gcm/protocol/android_checkin.pb.h" +#include "google_apis/gcm/protocol/checkin.pb.h" #include "net/base/backoff_entry.h" #include "net/url_request/url_fetcher_delegate.h" @@ -28,17 +28,35 @@ namespace gcm { // check-ins. class GCM_EXPORT CheckinRequest : public net::URLFetcherDelegate { public: - // A callback function for the checkin request, accepting |android_id| and - // |security_token|. - typedef base::Callback<void(uint64 android_id, uint64 security_token)> - CheckinRequestCallback; - - CheckinRequest(const CheckinRequestCallback& callback, + // A callback function for the checkin request, accepting |checkin_response| + // protobuf. + typedef base::Callback<void(const checkin_proto::AndroidCheckinResponse& + checkin_response)> CheckinRequestCallback; + + // Checkin request details. + struct GCM_EXPORT RequestInfo { + RequestInfo(uint64 android_id, + uint64 security_token, + const std::string& settings_digest, + const std::vector<std::string>& account_ids, + const checkin_proto::ChromeBuildProto& chrome_build_proto); + ~RequestInfo(); + + // Android ID of the device. + uint64 android_id; + // Security token of the device. + uint64 security_token; + // Digest of GServices settings on the device. + std::string settings_digest; + // Account IDs of GAIA accounts related to this device. + std::vector<std::string> account_ids; + // Information of the Chrome build of this device. + checkin_proto::ChromeBuildProto chrome_build_proto; + }; + + CheckinRequest(const RequestInfo& request_info, const net::BackoffEntry::Policy& backoff_policy, - const checkin_proto::ChromeBuildProto& chrome_build_proto, - uint64 android_id, - uint64 security_token, - const std::vector<std::string>& account_ids, + const CheckinRequestCallback& callback, net::URLRequestContextGetter* request_context_getter); virtual ~CheckinRequest(); @@ -57,10 +75,7 @@ class GCM_EXPORT CheckinRequest : public net::URLFetcherDelegate { net::BackoffEntry backoff_entry_; scoped_ptr<net::URLFetcher> url_fetcher_; - const checkin_proto::ChromeBuildProto chrome_build_proto_; - const uint64 android_id_; - const uint64 security_token_; - const std::vector<std::string> account_ids_; + const RequestInfo request_info_; base::WeakPtrFactory<CheckinRequest> weak_ptr_factory_; diff --git a/google_apis/gcm/engine/checkin_request_unittest.cc b/google_apis/gcm/engine/checkin_request_unittest.cc index 0142e0c..e750df0 100644 --- a/google_apis/gcm/engine/checkin_request_unittest.cc +++ b/google_apis/gcm/engine/checkin_request_unittest.cc @@ -51,6 +51,7 @@ const uint64 kBlankAndroidId = 999999UL; const uint64 kBlankSecurityToken = 999999UL; const char kChromeVersion[] = "Version String"; const uint64 kSecurityToken = 77; +const char kSettingsDigest[] = "settings_digest"; class CheckinRequestTest : public testing::Test { public: @@ -65,7 +66,8 @@ class CheckinRequestTest : public testing::Test { CheckinRequestTest(); virtual ~CheckinRequestTest(); - void FetcherCallback(uint64 android_id, uint64 security_token); + void FetcherCallback( + const checkin_proto::AndroidCheckinResponse& response); void CreateRequest(uint64 android_id, uint64 security_token); @@ -102,11 +104,13 @@ CheckinRequestTest::CheckinRequestTest() CheckinRequestTest::~CheckinRequestTest() {} -void CheckinRequestTest::FetcherCallback(uint64 android_id, - uint64 security_token) { +void CheckinRequestTest::FetcherCallback( + const checkin_proto::AndroidCheckinResponse& checkin_response) { callback_called_ = true; - android_id_ = android_id; - security_token_ = security_token; + if (checkin_response.has_android_id()) + android_id_ = checkin_response.android_id(); + if (checkin_response.has_security_token()) + security_token_ = checkin_response.security_token(); } void CheckinRequestTest::CreateRequest(uint64 android_id, @@ -117,15 +121,19 @@ void CheckinRequestTest::CreateRequest(uint64 android_id, chrome_build_proto_.set_channel( checkin_proto::ChromeBuildProto::CHANNEL_CANARY); chrome_build_proto_.set_chrome_version(kChromeVersion); + + CheckinRequest::RequestInfo request_info( + android_id, + security_token, + kSettingsDigest, + account_ids_, + chrome_build_proto_); // Then create a request with that protobuf and specified android_id, // security_token. request_.reset(new CheckinRequest( - base::Bind(&CheckinRequestTest::FetcherCallback, base::Unretained(this)), + request_info, kDefaultBackoffPolicy, - chrome_build_proto_, - android_id, - security_token, - account_ids_, + base::Bind(&CheckinRequestTest::FetcherCallback, base::Unretained(this)), url_request_context_getter_.get())); // Setting android_id_ and security_token_ to blank value, not used elsewhere @@ -198,6 +206,7 @@ TEST_F(CheckinRequestTest, FetcherData) { request_proto.checkin().type()); #endif + EXPECT_EQ(kSettingsDigest, request_proto.digest()); EXPECT_EQ(1, request_proto.account_cookie_size()); EXPECT_EQ("[account_id]", request_proto.account_cookie(0)); } @@ -244,8 +253,8 @@ TEST_F(CheckinRequestTest, ResponseHttpStatusUnauthorized) { CompleteFetch(); EXPECT_TRUE(callback_called_); - EXPECT_EQ(0u, android_id_); - EXPECT_EQ(0u, security_token_); + EXPECT_EQ(kBlankAndroidId, android_id_); + EXPECT_EQ(kBlankSecurityToken, security_token_); } TEST_F(CheckinRequestTest, ResponseHttpStatusBadRequest) { @@ -256,8 +265,8 @@ TEST_F(CheckinRequestTest, ResponseHttpStatusBadRequest) { CompleteFetch(); EXPECT_TRUE(callback_called_); - EXPECT_EQ(0u, android_id_); - EXPECT_EQ(0u, security_token_); + EXPECT_EQ(kBlankAndroidId, android_id_); + EXPECT_EQ(kBlankSecurityToken, security_token_); } TEST_F(CheckinRequestTest, ResponseHttpStatusNotOK) { diff --git a/google_apis/gcm/engine/gcm_store.h b/google_apis/gcm/engine/gcm_store.h index ccf480b..1b15e56b 100644 --- a/google_apis/gcm/engine/gcm_store.h +++ b/google_apis/gcm/engine/gcm_store.h @@ -48,6 +48,8 @@ class GCM_EXPORT GCMStore { RegistrationInfoMap registrations; std::vector<std::string> incoming_messages; OutgoingMessageMap outgoing_messages; + std::map<std::string, std::string> gservices_settings; + std::string gservices_digest; base::Time last_checkin_time; }; @@ -107,6 +109,14 @@ class GCM_EXPORT GCMStore { virtual void SetLastCheckinTime(const base::Time& last_checkin_time, const UpdateCallback& callback) = 0; + // G-service settings handling. + // Persists |settings| and |settings_digest|. It completely replaces the + // existing data. + virtual void SetGServicesSettings( + const std::map<std::string, std::string>& settings, + const std::string& settings_digest, + const UpdateCallback& callback) = 0; + private: DISALLOW_COPY_AND_ASSIGN(GCMStore); }; diff --git a/google_apis/gcm/engine/gcm_store_impl.cc b/google_apis/gcm/engine/gcm_store_impl.cc index 3a74127..2738c43 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 for digest of the last G-services settings update. +const char kGServiceSettingsDigestKey[] = "gservices_digest"; // Key used to timestamp last checkin (marked with G services settings update). const char kLastCheckinTimeKey[] = "last_checkin_time"; @@ -76,6 +86,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. @@ -121,6 +139,10 @@ class GCMStoreImpl::Backend const UpdateCallback& callback); void SetLastCheckinTime(const base::Time& last_checkin_time, const UpdateCallback& callback); + void SetGServicesSettings( + const std::map<std::string, std::string>& settings, + const std::string& digest, + const UpdateCallback& callback); private: friend class base::RefCountedThreadSafe<Backend>; @@ -131,6 +153,8 @@ class GCMStoreImpl::Backend bool LoadIncomingMessages(std::vector<std::string>* incoming_messages); bool LoadOutgoingMessages(OutgoingMessageMap* outgoing_messages); bool LoadLastCheckinTime(base::Time* last_checkin_time); + bool LoadGServicesSettings(std::map<std::string, std::string>* settings, + std::string* digest); const base::FilePath path_; scoped_refptr<base::SequencedTaskRunner> foreground_task_runner_; @@ -176,12 +200,16 @@ void GCMStoreImpl::Backend::Load(const LoadCallback& callback) { !LoadRegistrations(&result->registrations) || !LoadIncomingMessages(&result->incoming_messages) || !LoadOutgoingMessages(&result->outgoing_messages) || - !LoadLastCheckinTime(&result->last_checkin_time)) { + !LoadLastCheckinTime(&result->last_checkin_time) || + !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); foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, @@ -465,7 +493,44 @@ void GCMStoreImpl::Backend::SetLastCheckinTime( if (!s.ok()) LOG(ERROR) << "LevelDB set last checkin time failed: " << s.ToString(); + foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, s.ok())); +} + +void GCMStoreImpl::Backend::SetGServicesSettings( + const std::map<std::string, std::string>& settings, + const std::string& settings_digest, + const UpdateCallback& callback) { + leveldb::WriteBatch write_batch; + + // Remove all existing settings. + 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()) { + write_batch.Delete(iter->key()); + } + + // Add the new settings. + for (std::map<std::string, std::string>::const_iterator iter = + settings.begin(); + iter != settings.end(); ++iter) { + write_batch.Put(MakeSlice(MakeGServiceSettingKey(iter->first)), + MakeSlice(iter->second)); + } + + // Update the settings digest. + write_batch.Put(MakeSlice(kGServiceSettingsDigestKey), + MakeSlice(settings_digest)); + + // Write it all in a 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())); } @@ -604,6 +669,34 @@ bool GCMStoreImpl::Backend::LoadLastCheckinTime( return true; } +bool GCMStoreImpl::Backend::LoadGServicesSettings( + std::map<std::string, std::string>* settings, + std::string* digest) { + leveldb::ReadOptions read_options; + read_options.verify_checksums = true; + + // Load all of the GServices settings. + 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; + } + + // Load the settings digest. It's ok if it is empty. + db_->Get(read_options, MakeSlice(kGServiceSettingsDigestKey), digest); + + return true; +} + GCMStoreImpl::GCMStoreImpl( bool use_mock_keychain, const base::FilePath& path, @@ -788,6 +881,19 @@ void GCMStoreImpl::SetLastCheckinTime(const base::Time& last_checkin_time, callback)); } +void GCMStoreImpl::SetGServicesSettings( + const std::map<std::string, std::string>& settings, + const std::string& digest, + const UpdateCallback& callback) { + blocking_task_runner_->PostTask( + FROM_HERE, + base::Bind(&GCMStoreImpl::Backend::SetGServicesSettings, + backend_, + settings, + digest, + callback)); +} + void GCMStoreImpl::LoadContinuation(const LoadCallback& callback, scoped_ptr<LoadResult> result) { if (!result->success) { diff --git a/google_apis/gcm/engine/gcm_store_impl.h b/google_apis/gcm/engine/gcm_store_impl.h index a08a72c..ebf6c57 100644 --- a/google_apis/gcm/engine/gcm_store_impl.h +++ b/google_apis/gcm/engine/gcm_store_impl.h @@ -78,6 +78,12 @@ class GCM_EXPORT GCMStoreImpl : public GCMStore { virtual void SetLastCheckinTime(const base::Time& last_checkin_time, const UpdateCallback& callback) OVERRIDE; + // G-service settings handling. + virtual void SetGServicesSettings( + const std::map<std::string, std::string>& settings, + const std::string& settings_digest, + const UpdateCallback& callback) OVERRIDE; + private: typedef std::map<std::string, int> AppIdToMessageCountMap; diff --git a/google_apis/gcm/engine/gcm_store_impl_unittest.cc b/google_apis/gcm/engine/gcm_store_impl_unittest.cc index af5fc3a..a4010e2 100644 --- a/google_apis/gcm/engine/gcm_store_impl_unittest.cc +++ b/google_apis/gcm/engine/gcm_store_impl_unittest.cc @@ -108,6 +108,7 @@ TEST_F(GCMStoreImplTest, LoadNew) { EXPECT_EQ(0U, load_result->device_security_token); EXPECT_TRUE(load_result->incoming_messages.empty()); EXPECT_TRUE(load_result->outgoing_messages.empty()); + EXPECT_TRUE(load_result->gservices_settings.empty()); EXPECT_EQ(base::Time::FromInternalValue(0LL), load_result->last_checkin_time); } @@ -151,10 +152,57 @@ TEST_F(GCMStoreImplTest, LastCheckinTime) { gcm_store->Load(base::Bind( &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result)); PumpLoop(); - ASSERT_EQ(last_checkin_time, load_result->last_checkin_time); } +TEST_F(GCMStoreImplTest, GServicesSettings_ProtocolV2) { + scoped_ptr<GCMStore> gcm_store(BuildGCMStore()); + scoped_ptr<GCMStore::LoadResult> load_result; + gcm_store->Load(base::Bind( + &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result)); + PumpLoop(); + + std::map<std::string, std::string> settings; + settings["checkin_interval"] = "12345"; + settings["mcs_port"] = "438"; + settings["checkin_url"] = "http://checkin.google.com"; + std::string digest = "digest1"; + + gcm_store->SetGServicesSettings( + settings, + digest, + base::Bind(&GCMStoreImplTest::UpdateCallback, base::Unretained(this))); + PumpLoop(); + + gcm_store = BuildGCMStore().Pass(); + gcm_store->Load(base::Bind( + &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result)); + PumpLoop(); + + ASSERT_EQ(settings, load_result->gservices_settings); + ASSERT_EQ(digest, load_result->gservices_digest); + + // Remove some, and add some. + settings.clear(); + settings["checkin_interval"] = "54321"; + settings["registration_url"] = "http://registration.google.com"; + digest = "digest2"; + + gcm_store->SetGServicesSettings( + settings, + digest, + base::Bind(&GCMStoreImplTest::UpdateCallback, base::Unretained(this))); + PumpLoop(); + + gcm_store = BuildGCMStore().Pass(); + gcm_store->Load(base::Bind( + &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result)); + PumpLoop(); + + ASSERT_EQ(settings, load_result->gservices_settings); + ASSERT_EQ(digest, load_result->gservices_digest); +} + TEST_F(GCMStoreImplTest, Registrations) { scoped_ptr<GCMStore> gcm_store(BuildGCMStore()); scoped_ptr<GCMStore::LoadResult> load_result; diff --git a/google_apis/gcm/gcm_client_impl.cc b/google_apis/gcm/gcm_client_impl.cc index 9aaa043..d7d87e0 100644 --- a/google_apis/gcm/gcm_client_impl.cc +++ b/google_apis/gcm/gcm_client_impl.cc @@ -11,6 +11,7 @@ #include "base/message_loop/message_loop.h" #include "base/metrics/histogram.h" #include "base/sequenced_task_runner.h" +#include "base/strings/string_number_conversions.h" #include "base/time/default_clock.h" #include "google_apis/gcm/base/mcs_message.h" #include "google_apis/gcm/base/mcs_util.h" @@ -285,32 +286,36 @@ void GCMClientImpl::ResetState() { } void GCMClientImpl::StartCheckin() { + CheckinRequest::RequestInfo request_info( + device_checkin_info_.android_id, + device_checkin_info_.secret, + std::string(), + account_ids_, + chrome_build_proto_); checkin_request_.reset( - new CheckinRequest(base::Bind(&GCMClientImpl::OnCheckinCompleted, - weak_ptr_factory_.GetWeakPtr()), + new CheckinRequest(request_info, kDefaultBackoffPolicy, - chrome_build_proto_, - device_checkin_info_.android_id, - device_checkin_info_.secret, - account_ids_, + base::Bind(&GCMClientImpl::OnCheckinCompleted, + weak_ptr_factory_.GetWeakPtr()), url_request_context_getter_)); checkin_request_->Start(); } -void GCMClientImpl::OnCheckinCompleted(uint64 android_id, - uint64 security_token) { +void GCMClientImpl::OnCheckinCompleted( + const checkin_proto::AndroidCheckinResponse& checkin_response) { checkin_request_.reset(); - CheckinInfo checkin_info; - checkin_info.android_id = android_id; - checkin_info.secret = security_token; - - if (!checkin_info.IsValid()) { - // TODO(fgorski): I don't think a retry here will help, we should probalby + if (!checkin_response.has_android_id() || + !checkin_response.has_security_token()) { + // TODO(fgorski): I don't think a retry here will help, we should probably // start over. By checking in with (0, 0). return; } + CheckinInfo checkin_info; + checkin_info.android_id = checkin_response.android_id(); + checkin_info.secret = checkin_response.security_token(); + if (state_ == INITIAL_DEVICE_CHECKIN) { OnFirstTimeDeviceCheckinCompleted(checkin_info); } else { diff --git a/google_apis/gcm/gcm_client_impl.h b/google_apis/gcm/gcm_client_impl.h index 0349270..7458c70 100644 --- a/google_apis/gcm/gcm_client_impl.h +++ b/google_apis/gcm/gcm_client_impl.h @@ -19,7 +19,7 @@ #include "google_apis/gcm/engine/registration_request.h" #include "google_apis/gcm/engine/unregistration_request.h" #include "google_apis/gcm/gcm_client.h" -#include "google_apis/gcm/protocol/android_checkin.pb.h" +#include "google_apis/gcm/protocol/checkin.pb.h" #include "net/base/net_log.h" #include "net/url_request/url_request_context_getter.h" @@ -163,13 +163,12 @@ class GCM_EXPORT GCMClientImpl : public GCMClient { // Starts a first time device checkin. void StartCheckin(); - // Completes the device checkin request. - // |android_id| and |security_token| are expected to be non-zero or an error - // is triggered. Function also cleans up the pending checkin. - void OnCheckinCompleted(uint64 android_id, - uint64 security_token); - // Schedules next device checkin, based on |last_checkin_time| and default - // checkin interval. + // Completes the device checkin request by parsing the |checkin_response|. + // Function also cleans up the pending checkin. + void OnCheckinCompleted( + const checkin_proto::AndroidCheckinResponse& checkin_response); + // Schedules next device checkin, based on |last_checkin_time| and + // checkin_interval specified in GServices settings. void SchedulePeriodicCheckin(const base::Time& last_checkin_time); // Callback for setting last checkin time in the |gcm_store_|. void SetLastCheckinTimeCallback(bool success); diff --git a/google_apis/gcm/tools/mcs_probe.cc b/google_apis/gcm/tools/mcs_probe.cc index 157a73f..3f48762 100644 --- a/google_apis/gcm/tools/mcs_probe.cc +++ b/google_apis/gcm/tools/mcs_probe.cc @@ -210,7 +210,8 @@ class MCSProbe { void LoadCallback(scoped_ptr<GCMStore::LoadResult> load_result); void UpdateCallback(bool success); void ErrorCallback(); - void OnCheckInCompleted(uint64 android_id, uint64 secret); + void OnCheckInCompleted( + const checkin_proto::AndroidCheckinResponse& checkin_response); void StartMCSLogin(); base::DefaultClock clock_; @@ -424,24 +425,32 @@ void MCSProbe::CheckIn() { chrome_build_proto.set_channel( checkin_proto::ChromeBuildProto::CHANNEL_CANARY); chrome_build_proto.set_chrome_version(kChromeVersion); + + CheckinRequest::RequestInfo request_info( + 0, 0, std::string(), std::vector<std::string>(), chrome_build_proto); + checkin_request_.reset(new CheckinRequest( - base::Bind(&MCSProbe::OnCheckInCompleted, base::Unretained(this)), + request_info, kDefaultBackoffPolicy, - chrome_build_proto, - 0, - 0, - std::vector<std::string>(), + base::Bind(&MCSProbe::OnCheckInCompleted, base::Unretained(this)), url_request_context_getter_.get())); checkin_request_->Start(); } -void MCSProbe::OnCheckInCompleted(uint64 android_id, uint64 secret) { +void MCSProbe::OnCheckInCompleted( + const checkin_proto::AndroidCheckinResponse& checkin_response) { + bool success = checkin_response.has_android_id() && + checkin_response.android_id() != 0UL && + checkin_response.has_security_token() && + checkin_response.security_token() != 0UL; LOG(INFO) << "Check-in request completion " - << (android_id ? "success!" : "failure!"); - if (!android_id || !secret) + << (success ? "success!" : "failure!"); + + if (!success) return; - android_id_ = android_id; - secret_ = secret; + + android_id_ = checkin_response.android_id(); + secret_ = checkin_response.security_token(); gcm_store_->SetDeviceCredentials(android_id_, secret_, |