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

Unified Diff: components/gcm_driver/gcm_client_impl.cc

Issue 378643002: [GCM] Check-in with signed in accounts associates device to user (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Update to the code to prevent test crashes. Created 6 years, 5 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 | « components/gcm_driver/gcm_client_impl.h ('k') | components/gcm_driver/gcm_client_impl_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: components/gcm_driver/gcm_client_impl.cc
diff --git a/components/gcm_driver/gcm_client_impl.cc b/components/gcm_driver/gcm_client_impl.cc
index e36d36c79735e46432bac2d1fb6764b0de917f43..2000403b63bc72239410ee6627d104210c4117cd 100644
--- a/components/gcm_driver/gcm_client_impl.cc
+++ b/components/gcm_driver/gcm_client_impl.cc
@@ -247,6 +247,31 @@ scoped_ptr<ConnectionFactory> GCMInternalsBuilder::BuildConnectionFactory(
recorder));
}
+GCMClientImpl::CheckinInfo::CheckinInfo()
+ : android_id(0), secret(0), accounts_set(false) {
+}
+
+GCMClientImpl::CheckinInfo::~CheckinInfo() {
+}
+
+void GCMClientImpl::CheckinInfo::SnapshotCheckinAccounts() {
+ last_checkin_accounts.clear();
+ for (std::map<std::string, std::string>::iterator iter =
+ account_tokens.begin();
+ iter != account_tokens.end();
+ ++iter) {
+ last_checkin_accounts.insert(iter->first);
+ }
+}
+
+void GCMClientImpl::CheckinInfo::Reset() {
+ android_id = 0;
+ secret = 0;
+ accounts_set = false;
+ account_tokens.clear();
+ last_checkin_accounts.clear();
+}
+
GCMClientImpl::GCMClientImpl(scoped_ptr<GCMInternalsBuilder> internals_builder)
: internals_builder_(internals_builder.Pass()),
state_(UNINITIALIZED),
@@ -314,6 +339,14 @@ void GCMClientImpl::OnLoadCompleted(scoped_ptr<GCMStore::LoadResult> result) {
registrations_ = result->registrations;
device_checkin_info_.android_id = result->device_android_id;
device_checkin_info_.secret = result->device_security_token;
+ device_checkin_info_.last_checkin_accounts = result->last_checkin_accounts;
+ // A case where there were previously no accounts reported with checkin is
+ // considered to be the same as when the list of accounts is empty. It enables
+ // scheduling a periodic checkin for devices with no signed in users
+ // immediately after restart, while keeping |accounts_set == false| delays the
+ // checkin until the list of accounts is set explicitly.
+ if (result->last_checkin_accounts.size() == 0)
+ device_checkin_info_.accounts_set = true;
last_checkin_time_ = result->last_checkin_time;
gservices_settings_.UpdateFromLoadResult(*result);
InitializeMCSClient(result.Pass());
@@ -363,6 +396,9 @@ void GCMClientImpl::OnFirstTimeDeviceCheckinCompleted(
device_checkin_info_.android_id = checkin_info.android_id;
device_checkin_info_.secret = checkin_info.secret;
+ // If accounts were not set by now, we can consider them set (to empty list)
+ // to make sure periodic checkins get scheduled after initial checkin.
+ device_checkin_info_.accounts_set = true;
gcm_store_->SetDeviceCredentials(
checkin_info.android_id, checkin_info.secret,
base::Bind(&GCMClientImpl::SetDeviceCredentialsCallback,
@@ -390,6 +426,43 @@ void GCMClientImpl::ResetState() {
// TODO(fgorski): reset all of the necessart objects and start over.
}
+void GCMClientImpl::SetAccountsForCheckin(
+ const std::map<std::string, std::string>& account_tokens) {
+ bool accounts_set_before = device_checkin_info_.accounts_set;
+ device_checkin_info_.account_tokens = account_tokens;
+ device_checkin_info_.accounts_set = true;
+
+ DVLOG(1) << "Set account called with: " << account_tokens.size()
+ << " accounts.";
+
+ if (state_ != READY && state_ != INITIAL_DEVICE_CHECKIN)
+ return;
+
+ bool account_removed = false;
+ for (std::set<std::string>::iterator iter =
+ device_checkin_info_.last_checkin_accounts.begin();
+ iter != device_checkin_info_.last_checkin_accounts.end();
+ ++iter) {
+ if (account_tokens.find(*iter) == account_tokens.end())
+ account_removed = true;
+ }
+
+ // Checkin will be forced when any of the accounts was removed during the
+ // current Chrome session or if there has been an account removed between the
+ // restarts of Chrome. If there is a checkin in progress, it will be canceled.
+ // We only force checkin when user signs out. When there is a new account
+ // signed in, the periodic checkin will take care of adding the association in
+ // reasonable time.
+ if (account_removed) {
+ DVLOG(1) << "Detected that account has been removed. Forcing checkin.";
+ checkin_request_.reset();
+ StartCheckin();
+ } else if (!accounts_set_before) {
+ SchedulePeriodicCheckin();
+ DVLOG(1) << "Accounts set for the first time. Scheduled periodic checkin.";
+ }
+}
+
void GCMClientImpl::StartCheckin() {
// Make sure no checkin is in progress.
if (checkin_request_.get())
@@ -399,6 +472,7 @@ void GCMClientImpl::StartCheckin() {
ToCheckinProtoVersion(chrome_build_info_, &chrome_build_proto);
CheckinRequest::RequestInfo request_info(device_checkin_info_.android_id,
device_checkin_info_.secret,
+ device_checkin_info_.account_tokens,
gservices_settings_.digest(),
chrome_build_proto);
checkin_request_.reset(
@@ -409,6 +483,9 @@ void GCMClientImpl::StartCheckin() {
weak_ptr_factory_.GetWeakPtr()),
url_request_context_getter_,
&recorder_));
+ // Taking a snapshot of the accounts count here, as there might be an asynch
+ // update of the account tokens while checkin is in progress.
+ device_checkin_info_.SnapshotCheckinAccounts();
checkin_request_->Start();
}
@@ -448,9 +525,10 @@ void GCMClientImpl::OnCheckinCompleted(
}
last_checkin_time_ = clock_->Now();
- gcm_store_->SetLastCheckinTime(
+ gcm_store_->SetLastCheckinInfo(
last_checkin_time_,
- base::Bind(&GCMClientImpl::SetLastCheckinTimeCallback,
+ device_checkin_info_.last_checkin_accounts,
+ base::Bind(&GCMClientImpl::SetLastCheckinInfoCallback,
weak_ptr_factory_.GetWeakPtr()));
SchedulePeriodicCheckin();
}
@@ -462,7 +540,7 @@ void GCMClientImpl::SetGServicesSettingsCallback(bool success) {
void GCMClientImpl::SchedulePeriodicCheckin() {
// Make sure no checkin is in progress.
- if (checkin_request_.get())
+ if (checkin_request_.get() || !device_checkin_info_.accounts_set)
return;
// There should be only one periodic checkin pending at a time. Removing
@@ -485,7 +563,7 @@ base::TimeDelta GCMClientImpl::GetTimeToNextCheckin() const {
clock_->Now();
}
-void GCMClientImpl::SetLastCheckinTimeCallback(bool success) {
+void GCMClientImpl::SetLastCheckinInfoCallback(bool success) {
// TODO(fgorski): This is one of the signals that store needs a rebuild.
DCHECK(success);
}
« no previous file with comments | « components/gcm_driver/gcm_client_impl.h ('k') | components/gcm_driver/gcm_client_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698