OLD | NEW |
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 "base/base64.h" | 7 #include "base/base64.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/path_service.h" | 10 #include "base/path_service.h" |
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
472 bool on_by_default = false; | 472 bool on_by_default = false; |
473 if (channel == chrome::VersionInfo::CHANNEL_UNKNOWN || | 473 if (channel == chrome::VersionInfo::CHANNEL_UNKNOWN || |
474 channel == chrome::VersionInfo::CHANNEL_CANARY || | 474 channel == chrome::VersionInfo::CHANNEL_CANARY || |
475 channel == chrome::VersionInfo::CHANNEL_DEV) { | 475 channel == chrome::VersionInfo::CHANNEL_DEV) { |
476 on_by_default = true; | 476 on_by_default = true; |
477 } | 477 } |
478 registry->RegisterBooleanPref( | 478 registry->RegisterBooleanPref( |
479 prefs::kGCMChannelEnabled, | 479 prefs::kGCMChannelEnabled, |
480 on_by_default, | 480 on_by_default, |
481 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | 481 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); |
| 482 registry->RegisterListPref( |
| 483 prefs::kGCMRegisteredAppIDs, |
| 484 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); |
482 } | 485 } |
483 | 486 |
484 GCMProfileService::GCMProfileService(Profile* profile) | 487 GCMProfileService::GCMProfileService(Profile* profile) |
485 : profile_(profile), | 488 : profile_(profile), |
486 gcm_client_ready_(false), | 489 gcm_client_ready_(false), |
487 testing_delegate_(NULL), | 490 testing_delegate_(NULL), |
488 weak_ptr_factory_(this) { | 491 weak_ptr_factory_(this) { |
489 DCHECK(!profile->IsOffTheRecord()); | 492 DCHECK(!profile->IsOffTheRecord()); |
490 } | 493 } |
491 | 494 |
(...skipping 15 matching lines...) Expand all Loading... |
507 chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL, | 510 chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL, |
508 content::Source<Profile>(profile_)); | 511 content::Source<Profile>(profile_)); |
509 registrar_.Add(this, | 512 registrar_.Add(this, |
510 chrome::NOTIFICATION_GOOGLE_SIGNED_OUT, | 513 chrome::NOTIFICATION_GOOGLE_SIGNED_OUT, |
511 content::Source<Profile>(profile_)); | 514 content::Source<Profile>(profile_)); |
512 registrar_.Add(this, | 515 registrar_.Add(this, |
513 chrome::NOTIFICATION_PROFILE_DESTROYED, | 516 chrome::NOTIFICATION_PROFILE_DESTROYED, |
514 content::Source<Profile>(profile_)); | 517 content::Source<Profile>(profile_)); |
515 // TODO(jianli): move extension specific logic out of GCMProfileService. | 518 // TODO(jianli): move extension specific logic out of GCMProfileService. |
516 registrar_.Add(this, | 519 registrar_.Add(this, |
517 chrome::NOTIFICATION_EXTENSION_LOADED, | |
518 content::Source<Profile>(profile_)); | |
519 registrar_.Add(this, | |
520 chrome:: NOTIFICATION_EXTENSION_UNINSTALLED, | 520 chrome:: NOTIFICATION_EXTENSION_UNINSTALLED, |
521 content::Source<Profile>(profile_)); | 521 content::Source<Profile>(profile_)); |
522 | 522 |
523 // In case that the profile has been signed in before GCMProfileService is | 523 // In case that the profile has been signed in before GCMProfileService is |
524 // created. | 524 // created. |
525 SigninManagerBase* manager = SigninManagerFactory::GetForProfile(profile_); | 525 SigninManagerBase* manager = SigninManagerFactory::GetForProfile(profile_); |
526 if (manager) { | 526 if (manager) { |
527 std::string username = manager->GetAuthenticatedUsername(); | 527 std::string username = manager->GetAuthenticatedUsername(); |
528 if (!username.empty()) | 528 if (!username.empty()) |
529 CheckIn(username); | 529 CheckIn(username); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
594 GCMClient::SUCCESS); | 594 GCMClient::SUCCESS); |
595 return; | 595 return; |
596 } | 596 } |
597 | 597 |
598 // Cache the sender IDs. The registration ID will be filled when the | 598 // Cache the sender IDs. The registration ID will be filled when the |
599 // registration completes. | 599 // registration completes. |
600 RegistrationInfo registration_info; | 600 RegistrationInfo registration_info; |
601 registration_info.sender_ids = normalized_sender_ids; | 601 registration_info.sender_ids = normalized_sender_ids; |
602 registration_info_map_[app_id] = registration_info; | 602 registration_info_map_[app_id] = registration_info; |
603 | 603 |
| 604 // Save the IDs of all registered apps such that we know what to remove from |
| 605 // the the app's state store when the profile is signed out. |
| 606 WriteRegisteredAppIDs(); |
| 607 |
604 content::BrowserThread::PostTask( | 608 content::BrowserThread::PostTask( |
605 content::BrowserThread::IO, | 609 content::BrowserThread::IO, |
606 FROM_HERE, | 610 FROM_HERE, |
607 base::Bind(&GCMProfileService::IOWorker::Register, | 611 base::Bind(&GCMProfileService::IOWorker::Register, |
608 io_worker_, | 612 io_worker_, |
609 app_id, | 613 app_id, |
610 normalized_sender_ids, | 614 normalized_sender_ids, |
611 cert)); | 615 cert)); |
612 } | 616 } |
613 | 617 |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
675 if (username_ != signin_details->username) | 679 if (username_ != signin_details->username) |
676 CheckIn(signin_details->username); | 680 CheckIn(signin_details->username); |
677 break; | 681 break; |
678 } | 682 } |
679 case chrome::NOTIFICATION_GOOGLE_SIGNED_OUT: | 683 case chrome::NOTIFICATION_GOOGLE_SIGNED_OUT: |
680 CheckOut(); | 684 CheckOut(); |
681 break; | 685 break; |
682 case chrome::NOTIFICATION_PROFILE_DESTROYED: | 686 case chrome::NOTIFICATION_PROFILE_DESTROYED: |
683 ResetGCMClient(); | 687 ResetGCMClient(); |
684 break; | 688 break; |
685 case chrome::NOTIFICATION_EXTENSION_LOADED: { | |
686 extensions::Extension* extension = | |
687 content::Details<extensions::Extension>(details).ptr(); | |
688 // No need to load the persisted registration info if the extension does | |
689 // not have the GCM permission. | |
690 if (extension->HasAPIPermission(extensions::APIPermission::kGcm)) | |
691 EnsureAppReady(extension->id()); | |
692 break; | |
693 } | |
694 case chrome:: NOTIFICATION_EXTENSION_UNINSTALLED: { | 689 case chrome:: NOTIFICATION_EXTENSION_UNINSTALLED: { |
695 extensions::Extension* extension = | 690 extensions::Extension* extension = |
696 content::Details<extensions::Extension>(details).ptr(); | 691 content::Details<extensions::Extension>(details).ptr(); |
697 Unregister(extension->id()); | 692 Unregister(extension->id()); |
698 break; | 693 break; |
699 } | 694 } |
700 default: | 695 default: |
701 NOTREACHED(); | 696 NOTREACHED(); |
702 } | 697 } |
703 } | 698 } |
704 | 699 |
705 void GCMProfileService::CheckIn(const std::string& username) { | 700 void GCMProfileService::CheckIn(const std::string& username) { |
706 DCHECK(!username.empty() && username_.empty()); | 701 DCHECK(!username.empty() && username_.empty()); |
707 username_ = username; | 702 username_ = username; |
708 | 703 |
709 DCHECK(!delayed_task_controller_); | 704 DCHECK(!delayed_task_controller_); |
710 delayed_task_controller_.reset(new DelayedTaskController); | 705 delayed_task_controller_.reset(new DelayedTaskController); |
711 | 706 |
| 707 // Load all register apps. |
| 708 ReadRegisteredAppIDs(); |
| 709 |
712 // Let the IO thread create and initialize GCMClient. | 710 // Let the IO thread create and initialize GCMClient. |
713 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter = | 711 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter = |
714 profile_->GetRequestContext(); | 712 profile_->GetRequestContext(); |
715 content::BrowserThread::PostTask( | 713 content::BrowserThread::PostTask( |
716 content::BrowserThread::IO, | 714 content::BrowserThread::IO, |
717 FROM_HERE, | 715 FROM_HERE, |
718 base::Bind(&GCMProfileService::IOWorker::Initialize, | 716 base::Bind(&GCMProfileService::IOWorker::Initialize, |
719 io_worker_, | 717 io_worker_, |
720 gcm_client_factory_.get(), | 718 gcm_client_factory_.get(), |
721 profile_->GetPath().Append(chrome::kGCMStoreDirname), | 719 profile_->GetPath().Append(chrome::kGCMStoreDirname), |
722 url_request_context_getter)); | 720 url_request_context_getter)); |
723 } | 721 } |
724 | 722 |
725 void GCMProfileService::CheckOut() { | 723 void GCMProfileService::CheckOut() { |
726 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 724 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
727 | 725 |
728 DCHECK(!username_.empty()); | 726 DCHECK(!username_.empty()); |
729 username_.clear(); | 727 username_.clear(); |
730 | 728 |
| 729 // Remove persisted data from app's state store. |
| 730 for (RegistrationInfoMap::const_iterator iter = |
| 731 registration_info_map_.begin(); |
| 732 iter != registration_info_map_.end(); ++iter) { |
| 733 DeleteRegistrationInfo(iter->first); |
| 734 } |
| 735 |
| 736 // Remove persisted data from prefs store. |
| 737 profile_->GetPrefs()->ClearPref(prefs::kGCMChannelEnabled); |
| 738 profile_->GetPrefs()->ClearPref(prefs::kGCMRegisteredAppIDs); |
| 739 |
731 gcm_client_ready_ = false; | 740 gcm_client_ready_ = false; |
732 delayed_task_controller_.reset(); | 741 delayed_task_controller_.reset(); |
733 register_callbacks_.clear(); | 742 register_callbacks_.clear(); |
734 send_callbacks_.clear(); | 743 send_callbacks_.clear(); |
735 registration_info_map_.clear(); | 744 registration_info_map_.clear(); |
736 | 745 |
737 content::BrowserThread::PostTask( | 746 content::BrowserThread::PostTask( |
738 content::BrowserThread::IO, | 747 content::BrowserThread::IO, |
739 FROM_HERE, | 748 FROM_HERE, |
740 base::Bind(&GCMProfileService::IOWorker::CheckOut, io_worker_)); | 749 base::Bind(&GCMProfileService::IOWorker::CheckOut, io_worker_)); |
(...skipping 21 matching lines...) Expand all Loading... |
762 DCHECK(register_callbacks_.find(app_id) == register_callbacks_.end()); | 771 DCHECK(register_callbacks_.find(app_id) == register_callbacks_.end()); |
763 | 772 |
764 // Remove the cached registration info. If not found, there is no need to | 773 // Remove the cached registration info. If not found, there is no need to |
765 // ask the server to unregister it. | 774 // ask the server to unregister it. |
766 RegistrationInfoMap::iterator registration_info_iter = | 775 RegistrationInfoMap::iterator registration_info_iter = |
767 registration_info_map_.find(app_id); | 776 registration_info_map_.find(app_id); |
768 if (registration_info_iter == registration_info_map_.end()) | 777 if (registration_info_iter == registration_info_map_.end()) |
769 return; | 778 return; |
770 registration_info_map_.erase(registration_info_iter); | 779 registration_info_map_.erase(registration_info_iter); |
771 | 780 |
| 781 // Update the persisted IDs of registered apps. |
| 782 WriteRegisteredAppIDs(); |
| 783 |
772 // Remove the persisted registration info. | 784 // Remove the persisted registration info. |
773 DeleteRegistrationInfo(app_id); | 785 DeleteRegistrationInfo(app_id); |
774 | 786 |
775 // No need to track the app any more. | 787 // No need to track the app any more. |
776 delayed_task_controller_->RemoveApp(app_id); | 788 delayed_task_controller_->RemoveApp(app_id); |
777 | 789 |
778 // Ask the server to unregister it. There could be a small chance that the | 790 // Ask the server to unregister it. There could be a small chance that the |
779 // unregister request fails. If this occurs, it does not bring any harm since | 791 // unregister request fails. If this occurs, it does not bring any harm since |
780 // we simply reject the messages/events received from the server. | 792 // we simply reject the messages/events received from the server. |
781 content::BrowserThread::PostTask( | 793 content::BrowserThread::PostTask( |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
890 const { | 902 const { |
891 if (testing_delegate_ && testing_delegate_->GetEventRouter()) | 903 if (testing_delegate_ && testing_delegate_->GetEventRouter()) |
892 return testing_delegate_->GetEventRouter(); | 904 return testing_delegate_->GetEventRouter(); |
893 #if defined(OS_ANDROID) | 905 #if defined(OS_ANDROID) |
894 return NULL; | 906 return NULL; |
895 #else | 907 #else |
896 return js_event_router_.get(); | 908 return js_event_router_.get(); |
897 #endif | 909 #endif |
898 } | 910 } |
899 | 911 |
| 912 void GCMProfileService::ReadRegisteredAppIDs() { |
| 913 const base::ListValue* app_id_list = |
| 914 profile_->GetPrefs()->GetList(prefs::kGCMRegisteredAppIDs); |
| 915 for (size_t i = 0; i < app_id_list->GetSize(); ++i) { |
| 916 std::string app_id; |
| 917 if (!app_id_list->GetString(i, &app_id)) |
| 918 continue; |
| 919 ReadRegistrationInfo(app_id); |
| 920 } |
| 921 } |
| 922 |
| 923 void GCMProfileService::WriteRegisteredAppIDs() { |
| 924 base::ListValue apps; |
| 925 for (RegistrationInfoMap::const_iterator iter = |
| 926 registration_info_map_.begin(); |
| 927 iter != registration_info_map_.end(); ++iter) { |
| 928 apps.Append(new base::StringValue(iter->first)); |
| 929 } |
| 930 profile_->GetPrefs()->Set(prefs::kGCMRegisteredAppIDs, apps); |
| 931 } |
| 932 |
900 void GCMProfileService::DeleteRegistrationInfo(const std::string& app_id) { | 933 void GCMProfileService::DeleteRegistrationInfo(const std::string& app_id) { |
901 extensions::StateStore* storage = | 934 extensions::StateStore* storage = |
902 extensions::ExtensionSystem::Get(profile_)->state_store(); | 935 extensions::ExtensionSystem::Get(profile_)->state_store(); |
903 DCHECK(storage); | 936 DCHECK(storage); |
904 | 937 |
905 storage->RemoveExtensionValue(app_id, kRegistrationKey); | 938 storage->RemoveExtensionValue(app_id, kRegistrationKey); |
906 } | 939 } |
907 | 940 |
908 void GCMProfileService::WriteRegistrationInfo(const std::string& app_id) { | 941 void GCMProfileService::WriteRegistrationInfo(const std::string& app_id) { |
909 extensions::StateStore* storage = | 942 extensions::StateStore* storage = |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
987 | 1020 |
988 return true; | 1021 return true; |
989 } | 1022 } |
990 | 1023 |
991 // static | 1024 // static |
992 const char* GCMProfileService::GetPersistentRegisterKeyForTesting() { | 1025 const char* GCMProfileService::GetPersistentRegisterKeyForTesting() { |
993 return kRegistrationKey; | 1026 return kRegistrationKey; |
994 } | 1027 } |
995 | 1028 |
996 } // namespace gcm | 1029 } // namespace gcm |
OLD | NEW |