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

Side by Side Diff: chrome/browser/services/gcm/gcm_profile_service.cc

Issue 165993005: [GCM] Make sure GCM checkout logic is invoked when the profile is signed out (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix linux_tsan 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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 "chrome/browser/services/gcm/gcm_profile_service.h" 5 #include "chrome/browser/services/gcm/gcm_profile_service.h"
6 6
7 #include <string> 7 #include <string>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/base64.h" 10 #include "base/base64.h"
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 for (size_t i = 0; i < task_queue->tasks.size(); ++i) 229 for (size_t i = 0; i < task_queue->tasks.size(); ++i)
230 task_queue->tasks[i].Run(); 230 task_queue->tasks[i].Run();
231 task_queue->tasks.clear(); 231 task_queue->tasks.clear();
232 } 232 }
233 233
234 class GCMProfileService::IOWorker 234 class GCMProfileService::IOWorker
235 : public GCMClient::Delegate, 235 : public GCMClient::Delegate,
236 public base::RefCountedThreadSafe<GCMProfileService::IOWorker>{ 236 public base::RefCountedThreadSafe<GCMProfileService::IOWorker>{
237 public: 237 public:
238 // Called on UI thread. 238 // Called on UI thread.
239 explicit IOWorker(const base::WeakPtr<GCMProfileService>& service); 239 explicit IOWorker(const base::WeakPtr<GCMProfileService>& service);
Nicolas Zea 2014/02/26 02:26:37 is |service| here still necessary?
jianli 2014/02/26 19:04:25 Yes, it is not needed. Removed.
240 240
241 // Overridden from GCMClient::Delegate: 241 // Overridden from GCMClient::Delegate:
242 // Called on IO thread. 242 // Called on IO thread.
243 virtual void OnRegisterFinished(const std::string& app_id, 243 virtual void OnRegisterFinished(const std::string& app_id,
244 const std::string& registration_id, 244 const std::string& registration_id,
245 GCMClient::Result result) OVERRIDE; 245 GCMClient::Result result) OVERRIDE;
246 virtual void OnUnregisterFinished(const std::string& app_id, 246 virtual void OnUnregisterFinished(const std::string& app_id,
247 bool success) OVERRIDE; 247 bool success) OVERRIDE;
248 virtual void OnSendFinished(const std::string& app_id, 248 virtual void OnSendFinished(const std::string& app_id,
249 const std::string& message_id, 249 const std::string& message_id,
250 GCMClient::Result result) OVERRIDE; 250 GCMClient::Result result) OVERRIDE;
251 virtual void OnMessageReceived( 251 virtual void OnMessageReceived(
252 const std::string& app_id, 252 const std::string& app_id,
253 const GCMClient::IncomingMessage& message) OVERRIDE; 253 const GCMClient::IncomingMessage& message) OVERRIDE;
254 virtual void OnMessagesDeleted(const std::string& app_id) OVERRIDE; 254 virtual void OnMessagesDeleted(const std::string& app_id) OVERRIDE;
255 virtual void OnMessageSendError(const std::string& app_id, 255 virtual void OnMessageSendError(const std::string& app_id,
256 const std::string& message_id, 256 const std::string& message_id,
257 GCMClient::Result result) OVERRIDE; 257 GCMClient::Result result) OVERRIDE;
258 virtual void OnGCMReady() OVERRIDE; 258 virtual void OnGCMReady() OVERRIDE;
259 259
260 // Called on IO thread. 260 // Called on IO thread.
261 void Initialize(GCMClientFactory* gcm_client_factory, 261 void Initialize(scoped_ptr<GCMClientFactory> gcm_client_factory,
262 const base::FilePath& store_path, 262 const base::FilePath& store_path,
263 const std::vector<std::string>& account_ids, 263 const std::vector<std::string>& account_ids,
264 const scoped_refptr<net::URLRequestContextGetter>& 264 const scoped_refptr<net::URLRequestContextGetter>&
265 url_request_context_getter); 265 url_request_context_getter);
266 void Reset(); 266 void Reset();
267 void Load(const base::WeakPtr<GCMProfileService>& service);
267 void CheckOut(); 268 void CheckOut();
268 void Register(const std::string& app_id, 269 void Register(const std::string& app_id,
269 const std::vector<std::string>& sender_ids, 270 const std::vector<std::string>& sender_ids,
270 const std::string& cert); 271 const std::string& cert);
271 void Unregister(const std::string& app_id); 272 void Unregister(const std::string& app_id);
272 void Send(const std::string& app_id, 273 void Send(const std::string& app_id,
273 const std::string& receiver_id, 274 const std::string& receiver_id,
274 const GCMClient::OutgoingMessage& message); 275 const GCMClient::OutgoingMessage& message);
275 276
277 // For testing purpose. Can be called from UI thread. Use with care.
278 GCMClient* gcm_client_for_testing() const { return gcm_client_.get(); }
279
276 private: 280 private:
277 friend class base::RefCountedThreadSafe<IOWorker>; 281 friend class base::RefCountedThreadSafe<IOWorker>;
278 virtual ~IOWorker(); 282 virtual ~IOWorker();
279 283
280 const base::WeakPtr<GCMProfileService> service_; 284 base::WeakPtr<GCMProfileService> service_;
281 285
282 scoped_ptr<GCMClient> gcm_client_; 286 scoped_ptr<GCMClient> gcm_client_;
283 }; 287 };
284 288
285 GCMProfileService::IOWorker::IOWorker( 289 GCMProfileService::IOWorker::IOWorker(
286 const base::WeakPtr<GCMProfileService>& service) 290 const base::WeakPtr<GCMProfileService>& service)
287 : service_(service) { 291 : service_(service) {
288 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 292 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
289 } 293 }
290 294
291 GCMProfileService::IOWorker::~IOWorker() { 295 GCMProfileService::IOWorker::~IOWorker() {
292 } 296 }
293 297
294 void GCMProfileService::IOWorker::Initialize( 298 void GCMProfileService::IOWorker::Initialize(
295 GCMClientFactory* gcm_client_factory, 299 scoped_ptr<GCMClientFactory> gcm_client_factory,
296 const base::FilePath& store_path, 300 const base::FilePath& store_path,
297 const std::vector<std::string>& account_ids, 301 const std::vector<std::string>& account_ids,
298 const scoped_refptr<net::URLRequestContextGetter>& 302 const scoped_refptr<net::URLRequestContextGetter>&
299 url_request_context_getter) { 303 url_request_context_getter) {
300 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); 304 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
301 305
302 gcm_client_ = gcm_client_factory->BuildInstance().Pass(); 306 gcm_client_ = gcm_client_factory->BuildInstance().Pass();
303 307
304 checkin_proto::ChromeBuildProto chrome_build_proto; 308 checkin_proto::ChromeBuildProto chrome_build_proto;
305 chrome_build_proto.set_platform(GetPlatform()); 309 chrome_build_proto.set_platform(GetPlatform());
(...skipping 10 matching lines...) Expand all
316 gcm_client_->Initialize(chrome_build_proto, 320 gcm_client_->Initialize(chrome_build_proto,
317 store_path, 321 store_path,
318 account_ids, 322 account_ids,
319 blocking_task_runner, 323 blocking_task_runner,
320 url_request_context_getter, 324 url_request_context_getter,
321 this); 325 this);
322 326
323 content::BrowserThread::PostTask( 327 content::BrowserThread::PostTask(
324 content::BrowserThread::UI, 328 content::BrowserThread::UI,
325 FROM_HERE, 329 FROM_HERE,
326 base::Bind(&GCMProfileService::FinishInitializationOnUI, 330 base::Bind(&GCMProfileService::FinishInitializationOnUI, service_));
327 service_,
328 gcm_client_->IsReady()));
329 } 331 }
330 332
331 void GCMProfileService::IOWorker::Reset() { 333 void GCMProfileService::IOWorker::Reset() {
332 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); 334 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
333 335
334 // GCMClient instance must be destroyed from the same thread where it was 336 // GCMClient instance must be destroyed from the same thread where it was
335 // created. 337 // created.
336 gcm_client_.reset(); 338 gcm_client_.reset();
337 } 339 }
338 340
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
416 } 418 }
417 419
418 void GCMProfileService::IOWorker::OnGCMReady() { 420 void GCMProfileService::IOWorker::OnGCMReady() {
419 content::BrowserThread::PostTask( 421 content::BrowserThread::PostTask(
420 content::BrowserThread::UI, 422 content::BrowserThread::UI,
421 FROM_HERE, 423 FROM_HERE,
422 base::Bind(&GCMProfileService::GCMClientReady, 424 base::Bind(&GCMProfileService::GCMClientReady,
423 service_)); 425 service_));
424 } 426 }
425 427
428 void GCMProfileService::IOWorker::Load(
429 const base::WeakPtr<GCMProfileService>& service) {
430 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
431
432 service_ = service;
433 gcm_client_->Load();
434 }
435
426 void GCMProfileService::IOWorker::CheckOut() { 436 void GCMProfileService::IOWorker::CheckOut() {
427 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); 437 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
428 438
429 gcm_client_->CheckOut(); 439 gcm_client_->CheckOut();
430 gcm_client_.reset(); 440
441 // Note that we still need to keep GCMClient instance alive since the profile
442 // might be signed in again.
431 } 443 }
432 444
433 void GCMProfileService::IOWorker::Register( 445 void GCMProfileService::IOWorker::Register(
434 const std::string& app_id, 446 const std::string& app_id,
435 const std::vector<std::string>& sender_ids, 447 const std::vector<std::string>& sender_ids,
436 const std::string& cert) { 448 const std::string& cert) {
437 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); 449 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
438 450
439 gcm_client_->Register(app_id, cert, sender_ids); 451 gcm_client_->Register(app_id, cert, sender_ids);
440 } 452 }
(...skipping 16 matching lines...) Expand all
457 GCMProfileService::RegistrationInfo::RegistrationInfo() { 469 GCMProfileService::RegistrationInfo::RegistrationInfo() {
458 } 470 }
459 471
460 GCMProfileService::RegistrationInfo::~RegistrationInfo() { 472 GCMProfileService::RegistrationInfo::~RegistrationInfo() {
461 } 473 }
462 474
463 bool GCMProfileService::RegistrationInfo::IsValid() const { 475 bool GCMProfileService::RegistrationInfo::IsValid() const {
464 return !sender_ids.empty() && !registration_id.empty(); 476 return !sender_ids.empty() && !registration_id.empty();
465 } 477 }
466 478
467 bool GCMProfileService::enable_gcm_for_testing_ = false; 479 // static
480 GCMProfileService::GCMEnabledState GCMProfileService::GetGCMEnabledState(
481 Profile* profile) {
482 const base::Value* gcm_enabled_value =
483 profile->GetPrefs()->GetUserPrefValue(prefs::kGCMChannelEnabled);
484 if (!gcm_enabled_value)
485 return ENABLED_FOR_APPS;
468 486
469 // static 487 bool gcm_enabled = false;
470 bool GCMProfileService::IsGCMEnabled(Profile* profile) { 488 if (!gcm_enabled_value->GetAsBoolean(&gcm_enabled))
471 // GCM is not enabled in incognito mode. 489 return ENABLED_FOR_APPS;
472 if (profile->IsOffTheRecord())
473 return false;
474 490
475 if (enable_gcm_for_testing_) 491 return gcm_enabled ? ALWAYS_ENABLED : ALWAYS_DISABLED;
476 return true;
477
478 return profile->GetPrefs()->GetBoolean(prefs::kGCMChannelEnabled);
479 } 492 }
480 493
481 // static 494 // static
482 void GCMProfileService::RegisterProfilePrefs( 495 void GCMProfileService::RegisterProfilePrefs(
483 user_prefs::PrefRegistrySyncable* registry) { 496 user_prefs::PrefRegistrySyncable* registry) {
484 // GCM support is only enabled by default for Canary/Dev/Custom builds. 497 // GCM support is only enabled by default for Canary/Dev/Custom builds.
485 chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel(); 498 chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
486 bool on_by_default = false; 499 bool on_by_default = false;
487 if (channel == chrome::VersionInfo::CHANNEL_UNKNOWN || 500 if (channel == chrome::VersionInfo::CHANNEL_UNKNOWN ||
488 channel == chrome::VersionInfo::CHANNEL_CANARY || 501 channel == chrome::VersionInfo::CHANNEL_CANARY ||
(...skipping 15 matching lines...) Expand all
504 testing_delegate_(NULL), 517 testing_delegate_(NULL),
505 weak_ptr_factory_(this) { 518 weak_ptr_factory_(this) {
506 DCHECK(!profile->IsOffTheRecord()); 519 DCHECK(!profile->IsOffTheRecord());
507 } 520 }
508 521
509 GCMProfileService::~GCMProfileService() { 522 GCMProfileService::~GCMProfileService() {
510 } 523 }
511 524
512 void GCMProfileService::Initialize( 525 void GCMProfileService::Initialize(
513 scoped_ptr<GCMClientFactory> gcm_client_factory) { 526 scoped_ptr<GCMClientFactory> gcm_client_factory) {
514 gcm_client_factory_ = gcm_client_factory.Pass();
515
516 // This has to be done first since CheckIn depends on it.
517 io_worker_ = new IOWorker(weak_ptr_factory_.GetWeakPtr());
518
519 #if !defined(OS_ANDROID)
520 js_event_router_.reset(new extensions::GcmJsEventRouter(profile_));
521 #endif
522
523 registrar_.Add(this, 527 registrar_.Add(this,
524 chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL, 528 chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL,
525 content::Source<Profile>(profile_)); 529 content::Source<Profile>(profile_));
526 registrar_.Add(this, 530 registrar_.Add(this,
527 chrome::NOTIFICATION_GOOGLE_SIGNED_OUT, 531 chrome::NOTIFICATION_GOOGLE_SIGNED_OUT,
528 content::Source<Profile>(profile_)); 532 content::Source<Profile>(profile_));
529 registrar_.Add(this, 533 registrar_.Add(this,
530 chrome::NOTIFICATION_PROFILE_DESTROYED, 534 chrome::NOTIFICATION_PROFILE_DESTROYED,
531 content::Source<Profile>(profile_)); 535 content::Source<Profile>(profile_));
532 // TODO(jianli): move extension specific logic out of GCMProfileService. 536 // TODO(jianli): move extension specific logic out of GCMProfileService.
533 registrar_.Add(this, 537 registrar_.Add(this,
534 chrome:: NOTIFICATION_EXTENSION_UNINSTALLED, 538 chrome:: NOTIFICATION_EXTENSION_UNINSTALLED,
535 content::Source<Profile>(profile_)); 539 content::Source<Profile>(profile_));
536 540
537 // In case that the profile has been signed in before GCMProfileService is 541 // Get the list of available accounts.
538 // created. 542 std::vector<std::string> account_ids;
539 SigninManagerBase* manager = SigninManagerFactory::GetForProfile(profile_); 543 #if !defined(OS_ANDROID)
540 if (manager) { 544 account_ids =
541 std::string username = manager->GetAuthenticatedUsername(); 545 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_)->GetAccounts();
542 if (!username.empty()) 546 #endif
543 CheckIn(username); 547
544 } 548 // Create and initialize the GCMClient. Note that this does not initiate the
549 // GCM check-in.
550 io_worker_ = new IOWorker(weak_ptr_factory_.GetWeakPtr());
551 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter =
552 profile_->GetRequestContext();
553 content::BrowserThread::PostTask(
554 content::BrowserThread::IO,
555 FROM_HERE,
556 base::Bind(&GCMProfileService::IOWorker::Initialize,
557 io_worker_,
558 base::Passed(&gcm_client_factory),
559 profile_->GetPath().Append(chrome::kGCMStoreDirname),
560 account_ids,
561 url_request_context_getter));
545 } 562 }
546 563
547 void GCMProfileService::Register(const std::string& app_id, 564 void GCMProfileService::Register(const std::string& app_id,
548 const std::vector<std::string>& sender_ids, 565 const std::vector<std::string>& sender_ids,
549 const std::string& cert, 566 const std::string& cert,
550 RegisterCallback callback) { 567 RegisterCallback callback) {
551 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 568 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
552 DCHECK(!app_id.empty() && !sender_ids.empty() && !callback.is_null()); 569 DCHECK(!app_id.empty() && !sender_ids.empty() && !callback.is_null());
553 570
571 // Ensure that check-in has been done.
572 EnsureLoaded();
573
554 // If the profile was not signed in, bail out. 574 // If the profile was not signed in, bail out.
555 if (username_.empty()) { 575 if (username_.empty()) {
556 callback.Run(std::string(), GCMClient::NOT_SIGNED_IN); 576 callback.Run(std::string(), GCMClient::NOT_SIGNED_IN);
557 return; 577 return;
558 } 578 }
559 579
560 // If previous register operation is still in progress, bail out. 580 // If previous register operation is still in progress, bail out.
561 if (register_callbacks_.find(app_id) != register_callbacks_.end()) { 581 if (register_callbacks_.find(app_id) != register_callbacks_.end()) {
562 callback.Run(std::string(), GCMClient::ASYNC_OPERATION_PENDING); 582 callback.Run(std::string(), GCMClient::ASYNC_OPERATION_PENDING);
563 return; 583 return;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
629 cert)); 649 cert));
630 } 650 }
631 651
632 void GCMProfileService::Send(const std::string& app_id, 652 void GCMProfileService::Send(const std::string& app_id,
633 const std::string& receiver_id, 653 const std::string& receiver_id,
634 const GCMClient::OutgoingMessage& message, 654 const GCMClient::OutgoingMessage& message,
635 SendCallback callback) { 655 SendCallback callback) {
636 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 656 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
637 DCHECK(!app_id.empty() && !receiver_id.empty() && !callback.is_null()); 657 DCHECK(!app_id.empty() && !receiver_id.empty() && !callback.is_null());
638 658
659 // Ensure that check-in has been done.
660 EnsureLoaded();
661
639 // If the profile was not signed in, bail out. 662 // If the profile was not signed in, bail out.
640 if (username_.empty()) { 663 if (username_.empty()) {
641 callback.Run(std::string(), GCMClient::NOT_SIGNED_IN); 664 callback.Run(std::string(), GCMClient::NOT_SIGNED_IN);
642 return; 665 return;
643 } 666 }
644 667
645 // If the message with send ID is still in progress, bail out. 668 // If the message with send ID is still in progress, bail out.
646 std::pair<std::string, std::string> key(app_id, message.id); 669 std::pair<std::string, std::string> key(app_id, message.id);
647 if (send_callbacks_.find(key) != send_callbacks_.end()) { 670 if (send_callbacks_.find(key) != send_callbacks_.end()) {
648 callback.Run(message.id, GCMClient::INVALID_PARAMETER); 671 callback.Run(message.id, GCMClient::INVALID_PARAMETER);
(...skipping 24 matching lines...) Expand all
673 content::BrowserThread::PostTask( 696 content::BrowserThread::PostTask(
674 content::BrowserThread::IO, 697 content::BrowserThread::IO,
675 FROM_HERE, 698 FROM_HERE,
676 base::Bind(&GCMProfileService::IOWorker::Send, 699 base::Bind(&GCMProfileService::IOWorker::Send,
677 io_worker_, 700 io_worker_,
678 app_id, 701 app_id,
679 receiver_id, 702 receiver_id,
680 message)); 703 message));
681 } 704 }
682 705
706 GCMClient* GCMProfileService::GetGCMClientForTesting() const {
707 return io_worker_ ? io_worker_->gcm_client_for_testing() : NULL;
708 }
709
683 void GCMProfileService::Observe(int type, 710 void GCMProfileService::Observe(int type,
684 const content::NotificationSource& source, 711 const content::NotificationSource& source,
685 const content::NotificationDetails& details) { 712 const content::NotificationDetails& details) {
686 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 713 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
687 714
688 switch (type) { 715 switch (type) {
689 case chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL: { 716 case chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL: {
690 const GoogleServiceSigninSuccessDetails* signin_details = 717 if (GetGCMEnabledState(profile_) == ALWAYS_ENABLED)
691 content::Details<GoogleServiceSigninSuccessDetails>(details).ptr(); 718 EnsureLoaded();
692 // This could be called multiple times when the password changed.
693 if (username_ != signin_details->username)
694 CheckIn(signin_details->username);
695 break; 719 break;
696 } 720 }
697 case chrome::NOTIFICATION_GOOGLE_SIGNED_OUT: 721 case chrome::NOTIFICATION_GOOGLE_SIGNED_OUT:
698 CheckOut(); 722 CheckOut();
699 break; 723 break;
700 case chrome::NOTIFICATION_PROFILE_DESTROYED: 724 case chrome::NOTIFICATION_PROFILE_DESTROYED:
701 ResetGCMClient(); 725 ResetGCMClient();
702 break; 726 break;
703 case chrome:: NOTIFICATION_EXTENSION_UNINSTALLED: { 727 case chrome:: NOTIFICATION_EXTENSION_UNINSTALLED:
704 extensions::Extension* extension = 728 if (!username_.empty()) {
705 content::Details<extensions::Extension>(details).ptr(); 729 extensions::Extension* extension =
706 Unregister(extension->id()); 730 content::Details<extensions::Extension>(details).ptr();
731 Unregister(extension->id());
732 }
707 break; 733 break;
708 }
709 default: 734 default:
710 NOTREACHED(); 735 NOTREACHED();
711 } 736 }
712 } 737 }
713 738
714 void GCMProfileService::CheckIn(const std::string& username) { 739 void GCMProfileService::EnsureLoaded() {
715 DCHECK(!username.empty() && username_.empty()); 740 SigninManagerBase* manager = SigninManagerFactory::GetForProfile(profile_);
741 if (!manager)
742 return;
743 std::string username = manager->GetAuthenticatedUsername();
744 if (username.empty())
745 return;
746
747 // CheckIn could be called more than once when:
748 // 1) The password changes.
749 // 2) Register/send function calls it to ensure CheckIn is done.
750 if (username_ == username)
751 return;
716 username_ = username; 752 username_ = username;
717 753
754 #if !defined(OS_ANDROID)
755 if (!js_event_router_)
756 js_event_router_.reset(new extensions::GcmJsEventRouter(profile_));
757 #endif
758
718 DCHECK(!delayed_task_controller_); 759 DCHECK(!delayed_task_controller_);
719 delayed_task_controller_.reset(new DelayedTaskController); 760 delayed_task_controller_.reset(new DelayedTaskController);
720 761
721 // Load all register apps. 762 // Load all the registered apps.
722 ReadRegisteredAppIDs(); 763 ReadRegisteredAppIDs();
723 764
724 // Get the list of available accounts. 765 // This will load the data from the gcm store and trigger the check-in if
725 std::vector<std::string> account_ids; 766 // the persisted check-in info is not found.
726 #if !defined(OS_ANDROID) 767 // Note that we need to pass weak pointer again since the existing weak
727 account_ids = 768 // pointer in IOWorker might have been invalidated when check-out occurs.
728 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_)->GetAccounts();
729 #endif
730
731 // Let the IO thread create and initialize GCMClient.
732 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter =
733 profile_->GetRequestContext();
734 content::BrowserThread::PostTask( 769 content::BrowserThread::PostTask(
735 content::BrowserThread::IO, 770 content::BrowserThread::IO,
736 FROM_HERE, 771 FROM_HERE,
737 base::Bind(&GCMProfileService::IOWorker::Initialize, 772 base::Bind(&GCMProfileService::IOWorker::Load,
738 io_worker_, 773 io_worker_,
739 gcm_client_factory_.get(), 774 weak_ptr_factory_.GetWeakPtr()));
740 profile_->GetPath().Append(chrome::kGCMStoreDirname),
741 account_ids,
742 url_request_context_getter));
743 } 775 }
744 776
745 void GCMProfileService::CheckOut() { 777 void GCMProfileService::CheckOut() {
746 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 778 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
747 779
748 DCHECK(!username_.empty()); 780 // We still proceed with the check-out logic even if the check-in is not
781 // initiated in the current session. This will make sure that all the
782 // persisted data written previously will get purged.
749 username_.clear(); 783 username_.clear();
750 784
785 // Remove all the queued tasks since they no longer make sense after
786 // check-out.
787 weak_ptr_factory_.InvalidateWeakPtrs();
788
751 // Remove persisted data from app's state store. 789 // Remove persisted data from app's state store.
752 for (RegistrationInfoMap::const_iterator iter = 790 for (RegistrationInfoMap::const_iterator iter =
753 registration_info_map_.begin(); 791 registration_info_map_.begin();
754 iter != registration_info_map_.end(); ++iter) { 792 iter != registration_info_map_.end(); ++iter) {
755 DeleteRegistrationInfo(iter->first); 793 DeleteRegistrationInfo(iter->first);
756 } 794 }
757 795
758 // Remove persisted data from prefs store. 796 // Remove persisted data from prefs store.
759 profile_->GetPrefs()->ClearPref(prefs::kGCMChannelEnabled);
760 profile_->GetPrefs()->ClearPref(prefs::kGCMRegisteredAppIDs); 797 profile_->GetPrefs()->ClearPref(prefs::kGCMRegisteredAppIDs);
761 798
762 gcm_client_ready_ = false; 799 gcm_client_ready_ = false;
763 delayed_task_controller_.reset(); 800 delayed_task_controller_.reset();
764 register_callbacks_.clear(); 801 register_callbacks_.clear();
765 send_callbacks_.clear(); 802 send_callbacks_.clear();
766 registration_info_map_.clear(); 803 registration_info_map_.clear();
767 804
768 content::BrowserThread::PostTask( 805 content::BrowserThread::PostTask(
769 content::BrowserThread::IO, 806 content::BrowserThread::IO,
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
895 GCMClient::Result result) { 932 GCMClient::Result result) {
896 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 933 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
897 934
898 // Drop the event if signed out. 935 // Drop the event if signed out.
899 if (username_.empty()) 936 if (username_.empty())
900 return; 937 return;
901 938
902 GetEventRouter(app_id)->OnSendError(app_id, message_id, result); 939 GetEventRouter(app_id)->OnSendError(app_id, message_id, result);
903 } 940 }
904 941
905 void GCMProfileService::FinishInitializationOnUI(bool ready) { 942 void GCMProfileService::FinishInitializationOnUI() {
906 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 943 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
907 944
908 gcm_client_ready_ = ready; 945 // Initiates the check-in if the rollout signal indicates yes.
909 if (gcm_client_ready_) 946 if (GetGCMEnabledState(profile_) == ALWAYS_ENABLED)
910 delayed_task_controller_->SetGCMReady(); 947 EnsureLoaded();
911 } 948 }
912 949
913 void GCMProfileService::GCMClientReady() { 950 void GCMProfileService::GCMClientReady() {
914 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 951 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
915 952
916 if (gcm_client_ready_) 953 if (gcm_client_ready_)
917 return; 954 return;
918 gcm_client_ready_ = true; 955 gcm_client_ready_ = true;
919 956
920 delayed_task_controller_->SetGCMReady(); 957 delayed_task_controller_->SetGCMReady();
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
1042 1079
1043 return true; 1080 return true;
1044 } 1081 }
1045 1082
1046 // static 1083 // static
1047 const char* GCMProfileService::GetPersistentRegisterKeyForTesting() { 1084 const char* GCMProfileService::GetPersistentRegisterKeyForTesting() {
1048 return kRegistrationKey; 1085 return kRegistrationKey;
1049 } 1086 }
1050 1087
1051 } // namespace gcm 1088 } // namespace gcm
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698