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

Side by Side 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: Version storing last checked in accounts 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/gcm_driver/gcm_client_impl.h" 5 #include "components/gcm_driver/gcm_client_impl.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/files/file_path.h" 8 #include "base/files/file_path.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 net::NetLog* net_log, 240 net::NetLog* net_log,
241 GCMStatsRecorder* recorder) { 241 GCMStatsRecorder* recorder) {
242 return make_scoped_ptr<ConnectionFactory>( 242 return make_scoped_ptr<ConnectionFactory>(
243 new ConnectionFactoryImpl(endpoints, 243 new ConnectionFactoryImpl(endpoints,
244 backoff_policy, 244 backoff_policy,
245 network_session, 245 network_session,
246 net_log, 246 net_log,
247 recorder)); 247 recorder));
248 } 248 }
249 249
250 GCMClientImpl::CheckinInfo::CheckinInfo()
251 : android_id(0), secret(0), accounts_set(false) {
252 }
253
254 GCMClientImpl::CheckinInfo::~CheckinInfo() {
255 }
256
257 void GCMClientImpl::CheckinInfo::SnapshotCheckinAccounts() {
258 last_checkin_accounts.clear();
259 for (std::map<std::string, std::string>::iterator iter =
260 account_tokens.begin();
261 iter != account_tokens.end();
262 ++iter) {
263 last_checkin_accounts.insert(iter->first);
264 }
265 }
266
267 void GCMClientImpl::CheckinInfo::Reset() {
268 android_id = 0;
269 secret = 0;
270 accounts_set = false;
271 account_tokens.clear();
272 last_checkin_accounts.clear();
273 }
274
250 GCMClientImpl::GCMClientImpl(scoped_ptr<GCMInternalsBuilder> internals_builder) 275 GCMClientImpl::GCMClientImpl(scoped_ptr<GCMInternalsBuilder> internals_builder)
251 : internals_builder_(internals_builder.Pass()), 276 : internals_builder_(internals_builder.Pass()),
252 state_(UNINITIALIZED), 277 state_(UNINITIALIZED),
253 delegate_(NULL), 278 delegate_(NULL),
254 clock_(internals_builder_->BuildClock()), 279 clock_(internals_builder_->BuildClock()),
255 url_request_context_getter_(NULL), 280 url_request_context_getter_(NULL),
256 pending_registration_requests_deleter_(&pending_registration_requests_), 281 pending_registration_requests_deleter_(&pending_registration_requests_),
257 pending_unregistration_requests_deleter_( 282 pending_unregistration_requests_deleter_(
258 &pending_unregistration_requests_), 283 &pending_unregistration_requests_),
259 periodic_checkin_ptr_factory_(this), 284 periodic_checkin_ptr_factory_(this),
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 DCHECK_EQ(LOADING, state_); 332 DCHECK_EQ(LOADING, state_);
308 333
309 if (!result->success) { 334 if (!result->success) {
310 ResetState(); 335 ResetState();
311 return; 336 return;
312 } 337 }
313 338
314 registrations_ = result->registrations; 339 registrations_ = result->registrations;
315 device_checkin_info_.android_id = result->device_android_id; 340 device_checkin_info_.android_id = result->device_android_id;
316 device_checkin_info_.secret = result->device_security_token; 341 device_checkin_info_.secret = result->device_security_token;
342 device_checkin_info_.last_checkin_accounts = result->last_checkin_accounts;
343 // A case where there were previously no accounts reported with checkin is
344 // considered to be the same as when the list of accounts is empty. It enables
345 // scheduling a periodic checkin for devices with no signed in users
346 // immediately after restart, while keeping |accounts_set == false| delays the
347 // checkin until the list of accounts is set explicitly.
348 if (result->last_checkin_accounts.size() == 0)
349 device_checkin_info_.accounts_set = true;
317 last_checkin_time_ = result->last_checkin_time; 350 last_checkin_time_ = result->last_checkin_time;
318 gservices_settings_.UpdateFromLoadResult(*result); 351 gservices_settings_.UpdateFromLoadResult(*result);
319 InitializeMCSClient(result.Pass()); 352 InitializeMCSClient(result.Pass());
320 353
321 if (device_checkin_info_.IsValid()) { 354 if (device_checkin_info_.IsValid()) {
322 SchedulePeriodicCheckin(); 355 SchedulePeriodicCheckin();
323 OnReady(); 356 OnReady();
324 return; 357 return;
325 } 358 }
326 359
(...skipping 29 matching lines...) Expand all
356 weak_ptr_factory_.GetWeakPtr()), 389 weak_ptr_factory_.GetWeakPtr()),
357 result.Pass()); 390 result.Pass());
358 } 391 }
359 392
360 void GCMClientImpl::OnFirstTimeDeviceCheckinCompleted( 393 void GCMClientImpl::OnFirstTimeDeviceCheckinCompleted(
361 const CheckinInfo& checkin_info) { 394 const CheckinInfo& checkin_info) {
362 DCHECK(!device_checkin_info_.IsValid()); 395 DCHECK(!device_checkin_info_.IsValid());
363 396
364 device_checkin_info_.android_id = checkin_info.android_id; 397 device_checkin_info_.android_id = checkin_info.android_id;
365 device_checkin_info_.secret = checkin_info.secret; 398 device_checkin_info_.secret = checkin_info.secret;
399 // If accounts were not set by now, we can consider them set (to empty list)
400 // to make sure periodic checkins get scheduled after initial checkin.
401 device_checkin_info_.accounts_set = true;
366 gcm_store_->SetDeviceCredentials( 402 gcm_store_->SetDeviceCredentials(
367 checkin_info.android_id, checkin_info.secret, 403 checkin_info.android_id, checkin_info.secret,
368 base::Bind(&GCMClientImpl::SetDeviceCredentialsCallback, 404 base::Bind(&GCMClientImpl::SetDeviceCredentialsCallback,
369 weak_ptr_factory_.GetWeakPtr())); 405 weak_ptr_factory_.GetWeakPtr()));
370 406
371 OnReady(); 407 OnReady();
372 } 408 }
373 409
374 void GCMClientImpl::OnReady() { 410 void GCMClientImpl::OnReady() {
375 state_ = READY; 411 state_ = READY;
376 StartMCSLogin(); 412 StartMCSLogin();
377 413
378 delegate_->OnGCMReady(); 414 delegate_->OnGCMReady();
379 } 415 }
380 416
381 void GCMClientImpl::StartMCSLogin() { 417 void GCMClientImpl::StartMCSLogin() {
382 DCHECK_EQ(READY, state_); 418 DCHECK_EQ(READY, state_);
383 DCHECK(device_checkin_info_.IsValid()); 419 DCHECK(device_checkin_info_.IsValid());
384 mcs_client_->Login(device_checkin_info_.android_id, 420 mcs_client_->Login(device_checkin_info_.android_id,
385 device_checkin_info_.secret); 421 device_checkin_info_.secret);
386 } 422 }
387 423
388 void GCMClientImpl::ResetState() { 424 void GCMClientImpl::ResetState() {
389 state_ = UNINITIALIZED; 425 state_ = UNINITIALIZED;
390 // TODO(fgorski): reset all of the necessart objects and start over. 426 // TODO(fgorski): reset all of the necessart objects and start over.
391 } 427 }
392 428
429 void GCMClientImpl::SetAccountsForCheckin(
430 const std::map<std::string, std::string>& account_tokens) {
431 bool accounts_set_before = device_checkin_info_.accounts_set;
432 device_checkin_info_.account_tokens = account_tokens;
433 device_checkin_info_.accounts_set = true;
434
435 DVLOG(1) << "Set account called with: " << account_tokens.size()
436 << " accounts.";
437
438 if (state_ != READY && state_ != INITIAL_DEVICE_CHECKIN)
439 return;
440
441 bool account_removed = false;
442 for (std::set<std::string>::iterator iter =
443 device_checkin_info_.last_checkin_accounts.begin();
444 iter != device_checkin_info_.last_checkin_accounts.end();
445 ++iter) {
446 if (account_tokens.find(*iter) == account_tokens.end())
447 account_removed = true;
448 }
449
450 // Checkin will be forced when any of the accounts was removed during the
451 // current Chrome session or if there has been an account removed between the
452 // restarts of Chrome. If there is a checkin in progress, it will be canceled.
Nicolas Zea 2014/07/16 20:53:54 Comment about why we don't perform a checkin if an
fgorski 2014/07/17 03:35:35 Done.
453 if (account_removed) {
454 DVLOG(1) << "Detecting that account has been removed, forcing checkin.";
Nicolas Zea 2014/07/16 20:53:54 nit: Detecting -> Detected
fgorski 2014/07/17 03:35:34 Done.
455 checkin_request_.reset();
456 StartCheckin();
457 } else if (!accounts_set_before) {
458 SchedulePeriodicCheckin();
459 DVLOG(1) << "Scheduled periodic checkin.";
460 }
461 }
462
393 void GCMClientImpl::StartCheckin() { 463 void GCMClientImpl::StartCheckin() {
394 // Make sure no checkin is in progress. 464 // Make sure no checkin is in progress.
395 if (checkin_request_.get()) 465 if (checkin_request_.get())
396 return; 466 return;
397 467
398 checkin_proto::ChromeBuildProto chrome_build_proto; 468 checkin_proto::ChromeBuildProto chrome_build_proto;
399 ToCheckinProtoVersion(chrome_build_info_, &chrome_build_proto); 469 ToCheckinProtoVersion(chrome_build_info_, &chrome_build_proto);
400 CheckinRequest::RequestInfo request_info(device_checkin_info_.android_id, 470 CheckinRequest::RequestInfo request_info(device_checkin_info_.android_id,
401 device_checkin_info_.secret, 471 device_checkin_info_.secret,
472 device_checkin_info_.account_tokens,
402 gservices_settings_.digest(), 473 gservices_settings_.digest(),
403 chrome_build_proto); 474 chrome_build_proto);
404 checkin_request_.reset( 475 checkin_request_.reset(
405 new CheckinRequest(gservices_settings_.GetCheckinURL(), 476 new CheckinRequest(gservices_settings_.GetCheckinURL(),
406 request_info, 477 request_info,
407 kDefaultBackoffPolicy, 478 kDefaultBackoffPolicy,
408 base::Bind(&GCMClientImpl::OnCheckinCompleted, 479 base::Bind(&GCMClientImpl::OnCheckinCompleted,
409 weak_ptr_factory_.GetWeakPtr()), 480 weak_ptr_factory_.GetWeakPtr()),
410 url_request_context_getter_, 481 url_request_context_getter_,
411 &recorder_)); 482 &recorder_));
483 // Taking a snapshot of the accounts count here, as there might be an asynch
484 // update of the account tokens while checkin is in progress.
485 device_checkin_info_.SnapshotCheckinAccounts();
412 checkin_request_->Start(); 486 checkin_request_->Start();
413 } 487 }
414 488
415 void GCMClientImpl::OnCheckinCompleted( 489 void GCMClientImpl::OnCheckinCompleted(
416 const checkin_proto::AndroidCheckinResponse& checkin_response) { 490 const checkin_proto::AndroidCheckinResponse& checkin_response) {
417 checkin_request_.reset(); 491 checkin_request_.reset();
418 492
419 if (!checkin_response.has_android_id() || 493 if (!checkin_response.has_android_id() ||
420 !checkin_response.has_security_token()) { 494 !checkin_response.has_security_token()) {
421 // TODO(fgorski): I don't think a retry here will help, we should probably 495 // TODO(fgorski): I don't think a retry here will help, we should probably
(...skipping 19 matching lines...) Expand all
441 // First update G-services settings, as something might have changed. 515 // First update G-services settings, as something might have changed.
442 if (gservices_settings_.UpdateFromCheckinResponse(checkin_response)) { 516 if (gservices_settings_.UpdateFromCheckinResponse(checkin_response)) {
443 gcm_store_->SetGServicesSettings( 517 gcm_store_->SetGServicesSettings(
444 gservices_settings_.settings_map(), 518 gservices_settings_.settings_map(),
445 gservices_settings_.digest(), 519 gservices_settings_.digest(),
446 base::Bind(&GCMClientImpl::SetGServicesSettingsCallback, 520 base::Bind(&GCMClientImpl::SetGServicesSettingsCallback,
447 weak_ptr_factory_.GetWeakPtr())); 521 weak_ptr_factory_.GetWeakPtr()));
448 } 522 }
449 523
450 last_checkin_time_ = clock_->Now(); 524 last_checkin_time_ = clock_->Now();
451 gcm_store_->SetLastCheckinTime( 525 gcm_store_->SetLastCheckinInfo(
452 last_checkin_time_, 526 last_checkin_time_,
453 base::Bind(&GCMClientImpl::SetLastCheckinTimeCallback, 527 device_checkin_info_.last_checkin_accounts,
528 base::Bind(&GCMClientImpl::SetLastCheckinInfoCallback,
454 weak_ptr_factory_.GetWeakPtr())); 529 weak_ptr_factory_.GetWeakPtr()));
455 SchedulePeriodicCheckin(); 530 SchedulePeriodicCheckin();
456 } 531 }
457 } 532 }
458 533
459 void GCMClientImpl::SetGServicesSettingsCallback(bool success) { 534 void GCMClientImpl::SetGServicesSettingsCallback(bool success) {
460 DCHECK(success); 535 DCHECK(success);
461 } 536 }
462 537
463 void GCMClientImpl::SchedulePeriodicCheckin() { 538 void GCMClientImpl::SchedulePeriodicCheckin() {
464 // Make sure no checkin is in progress. 539 // Make sure no checkin is in progress.
465 if (checkin_request_.get()) 540 if (checkin_request_.get() || !device_checkin_info_.accounts_set)
466 return; 541 return;
467 542
468 // There should be only one periodic checkin pending at a time. Removing 543 // There should be only one periodic checkin pending at a time. Removing
469 // pending periodic checkin to schedule a new one. 544 // pending periodic checkin to schedule a new one.
470 periodic_checkin_ptr_factory_.InvalidateWeakPtrs(); 545 periodic_checkin_ptr_factory_.InvalidateWeakPtrs();
471 546
472 base::TimeDelta time_to_next_checkin = GetTimeToNextCheckin(); 547 base::TimeDelta time_to_next_checkin = GetTimeToNextCheckin();
473 if (time_to_next_checkin < base::TimeDelta()) 548 if (time_to_next_checkin < base::TimeDelta())
474 time_to_next_checkin = base::TimeDelta(); 549 time_to_next_checkin = base::TimeDelta();
475 550
476 base::MessageLoop::current()->PostDelayedTask( 551 base::MessageLoop::current()->PostDelayedTask(
477 FROM_HERE, 552 FROM_HERE,
478 base::Bind(&GCMClientImpl::StartCheckin, 553 base::Bind(&GCMClientImpl::StartCheckin,
479 periodic_checkin_ptr_factory_.GetWeakPtr()), 554 periodic_checkin_ptr_factory_.GetWeakPtr()),
480 time_to_next_checkin); 555 time_to_next_checkin);
481 } 556 }
482 557
483 base::TimeDelta GCMClientImpl::GetTimeToNextCheckin() const { 558 base::TimeDelta GCMClientImpl::GetTimeToNextCheckin() const {
484 return last_checkin_time_ + gservices_settings_.GetCheckinInterval() - 559 return last_checkin_time_ + gservices_settings_.GetCheckinInterval() -
485 clock_->Now(); 560 clock_->Now();
486 } 561 }
487 562
488 void GCMClientImpl::SetLastCheckinTimeCallback(bool success) { 563 void GCMClientImpl::SetLastCheckinInfoCallback(bool success) {
489 // TODO(fgorski): This is one of the signals that store needs a rebuild. 564 // TODO(fgorski): This is one of the signals that store needs a rebuild.
490 DCHECK(success); 565 DCHECK(success);
491 } 566 }
492 567
493 void GCMClientImpl::SetDeviceCredentialsCallback(bool success) { 568 void GCMClientImpl::SetDeviceCredentialsCallback(bool success) {
494 // TODO(fgorski): This is one of the signals that store needs a rebuild. 569 // TODO(fgorski): This is one of the signals that store needs a rebuild.
495 DCHECK(success); 570 DCHECK(success);
496 } 571 }
497 572
498 void GCMClientImpl::UpdateRegistrationCallback(bool success) { 573 void GCMClientImpl::UpdateRegistrationCallback(bool success) {
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after
882 957
883 recorder_.RecordIncomingSendError( 958 recorder_.RecordIncomingSendError(
884 data_message_stanza.category(), 959 data_message_stanza.category(),
885 data_message_stanza.to(), 960 data_message_stanza.to(),
886 data_message_stanza.id()); 961 data_message_stanza.id());
887 delegate_->OnMessageSendError(data_message_stanza.category(), 962 delegate_->OnMessageSendError(data_message_stanza.category(),
888 send_error_details); 963 send_error_details);
889 } 964 }
890 965
891 } // namespace gcm 966 } // namespace gcm
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698