Chromium Code Reviews| 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::kGCMApps, | |
| 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, | |
|
fgorski
2014/02/13 00:20:12
please edit the CL description to cover why you ar
jianli
2014/02/13 00:32:48
Done.
| |
| 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::kGCMApps); | |
| 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 |
| 772 // Remove the persisted registration info. | 781 // Remove the persisted registration info. |
|
fgorski
2014/02/13 00:20:12
WriteRegisteredAppIDs from here as well, given tha
jianli
2014/02/13 00:32:48
Good catch. Done.
| |
| 773 DeleteRegistrationInfo(app_id); | 782 DeleteRegistrationInfo(app_id); |
| 774 | 783 |
| 775 // No need to track the app any more. | 784 // No need to track the app any more. |
| 776 delayed_task_controller_->RemoveApp(app_id); | 785 delayed_task_controller_->RemoveApp(app_id); |
| 777 | 786 |
| 778 // Ask the server to unregister it. There could be a small chance that the | 787 // 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 | 788 // unregister request fails. If this occurs, it does not bring any harm since |
| 780 // we simply reject the messages/events received from the server. | 789 // we simply reject the messages/events received from the server. |
| 781 content::BrowserThread::PostTask( | 790 content::BrowserThread::PostTask( |
| 782 content::BrowserThread::IO, | 791 content::BrowserThread::IO, |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 890 const { | 899 const { |
| 891 if (testing_delegate_ && testing_delegate_->GetEventRouter()) | 900 if (testing_delegate_ && testing_delegate_->GetEventRouter()) |
| 892 return testing_delegate_->GetEventRouter(); | 901 return testing_delegate_->GetEventRouter(); |
| 893 #if defined(OS_ANDROID) | 902 #if defined(OS_ANDROID) |
| 894 return NULL; | 903 return NULL; |
| 895 #else | 904 #else |
| 896 return js_event_router_.get(); | 905 return js_event_router_.get(); |
| 897 #endif | 906 #endif |
| 898 } | 907 } |
| 899 | 908 |
| 909 void GCMProfileService::ReadRegisteredAppIDs() { | |
| 910 const base::ListValue* app_id_list = | |
| 911 profile_->GetPrefs()->GetList(prefs::kGCMApps); | |
| 912 for (size_t i = 0; i < app_id_list->GetSize(); ++i) { | |
| 913 std::string app_id; | |
| 914 if (!app_id_list->GetString(i, &app_id)) | |
| 915 continue; | |
| 916 ReadRegistrationInfo(app_id); | |
| 917 } | |
| 918 } | |
| 919 | |
| 920 void GCMProfileService::WriteRegisteredAppIDs() { | |
| 921 base::ListValue apps; | |
| 922 for (RegistrationInfoMap::const_iterator iter = | |
| 923 registration_info_map_.begin(); | |
| 924 iter != registration_info_map_.end(); ++iter) { | |
| 925 apps.Append(new base::StringValue(iter->first)); | |
| 926 } | |
| 927 profile_->GetPrefs()->Set(prefs::kGCMApps, apps); | |
| 928 } | |
| 929 | |
| 900 void GCMProfileService::DeleteRegistrationInfo(const std::string& app_id) { | 930 void GCMProfileService::DeleteRegistrationInfo(const std::string& app_id) { |
| 901 extensions::StateStore* storage = | 931 extensions::StateStore* storage = |
| 902 extensions::ExtensionSystem::Get(profile_)->state_store(); | 932 extensions::ExtensionSystem::Get(profile_)->state_store(); |
| 903 DCHECK(storage); | 933 DCHECK(storage); |
| 904 | 934 |
| 905 storage->RemoveExtensionValue(app_id, kRegistrationKey); | 935 storage->RemoveExtensionValue(app_id, kRegistrationKey); |
| 906 } | 936 } |
| 907 | 937 |
| 908 void GCMProfileService::WriteRegistrationInfo(const std::string& app_id) { | 938 void GCMProfileService::WriteRegistrationInfo(const std::string& app_id) { |
| 909 extensions::StateStore* storage = | 939 extensions::StateStore* storage = |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 987 | 1017 |
| 988 return true; | 1018 return true; |
| 989 } | 1019 } |
| 990 | 1020 |
| 991 // static | 1021 // static |
| 992 const char* GCMProfileService::GetPersistentRegisterKeyForTesting() { | 1022 const char* GCMProfileService::GetPersistentRegisterKeyForTesting() { |
| 993 return kRegistrationKey; | 1023 return kRegistrationKey; |
| 994 } | 1024 } |
| 995 | 1025 |
| 996 } // namespace gcm | 1026 } // namespace gcm |
| OLD | NEW |