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/logging.h" | 8 #include "base/logging.h" |
9 #include "base/prefs/pref_service.h" | 9 #include "base/prefs/pref_service.h" |
10 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
(...skipping 20 matching lines...) Expand all Loading... | |
31 const char kRegistrationKey[] = "gcm.registration"; | 31 const char kRegistrationKey[] = "gcm.registration"; |
32 const char kSendersKey[] = "senders"; | 32 const char kSendersKey[] = "senders"; |
33 const char kRegistrationIDKey[] = "reg_id"; | 33 const char kRegistrationIDKey[] = "reg_id"; |
34 | 34 |
35 // Helper class to save tasks to run until we're ready to execute them. | 35 // Helper class to save tasks to run until we're ready to execute them. |
36 class GCMProfileService::DelayedTaskController { | 36 class GCMProfileService::DelayedTaskController { |
37 public: | 37 public: |
38 DelayedTaskController(); | 38 DelayedTaskController(); |
39 ~DelayedTaskController(); | 39 ~DelayedTaskController(); |
40 | 40 |
41 // Adds an app to non-ready list that queue all tasks to invoke until ready. | 41 // Adds an app to the tracking list. It will be first marked as non-ready. |
fgorski
2014/01/09 22:06:55
nit: I think "not ready" would be the proper phras
| |
42 // Tasks will be queued for delay execution until the app is marked as ready. | |
42 void AddApp(const std::string& app_id); | 43 void AddApp(const std::string& app_id); |
43 | 44 |
45 // Removes the app from the tracking list. | |
46 void RemoveApp(const std::string& app_id); | |
47 | |
44 // Adds a task that will be invoked once we're ready. | 48 // Adds a task that will be invoked once we're ready. |
45 void AddTask(const std::string& app_id, base::Closure task); | 49 void AddTask(const std::string& app_id, base::Closure task); |
46 | 50 |
47 // Marks that GCMClient is ready. | 51 // Marks that GCMClient is ready. |
48 void SetGCMClientReady(); | 52 void SetGCMClientReady(); |
49 | 53 |
50 // Marks that the app is ready to have operations performed. | 54 // Marks that the app is ready to have operations performed. |
51 void SetAppReady(const std::string& app_id); | 55 void SetAppReady(const std::string& app_id); |
52 | 56 |
53 // Returns true if it is ready to perform operations for an app. | 57 // Returns true if it is ready to perform operations for an app. |
54 bool CanRunTaskWithoutDelay(const std::string& app_id) const; | 58 bool CanRunTaskWithoutDelay(const std::string& app_id) const; |
55 | 59 |
60 // Returns true if the app has been tracked for readyness. | |
fgorski
2014/01/09 22:06:55
s/readyness/readiness/
| |
61 bool IsAppTracked(const std::string& app_id) const; | |
62 | |
56 private: | 63 private: |
57 struct AppTaskQueue { | 64 struct AppTaskQueue { |
58 AppTaskQueue(); | 65 AppTaskQueue(); |
59 ~AppTaskQueue(); | 66 ~AppTaskQueue(); |
60 | 67 |
61 // The flag that indicates if GCMProfileService completes loading the | 68 // The flag that indicates if GCMProfileService completes loading the |
62 // persistent data for the app. | 69 // persistent data for the app. |
63 bool ready; | 70 bool ready; |
64 | 71 |
65 // Tasks to be invoked upon ready. | 72 // Tasks to be invoked upon ready. |
(...skipping 27 matching lines...) Expand all Loading... | |
93 delete iter->second; | 100 delete iter->second; |
94 } | 101 } |
95 } | 102 } |
96 | 103 |
97 void GCMProfileService::DelayedTaskController::AddApp( | 104 void GCMProfileService::DelayedTaskController::AddApp( |
98 const std::string& app_id) { | 105 const std::string& app_id) { |
99 DCHECK(delayed_task_map_.find(app_id) == delayed_task_map_.end()); | 106 DCHECK(delayed_task_map_.find(app_id) == delayed_task_map_.end()); |
100 delayed_task_map_[app_id] = new AppTaskQueue; | 107 delayed_task_map_[app_id] = new AppTaskQueue; |
101 } | 108 } |
102 | 109 |
110 void GCMProfileService::DelayedTaskController::RemoveApp( | |
111 const std::string& app_id) { | |
112 delayed_task_map_.erase(app_id); | |
113 } | |
114 | |
103 void GCMProfileService::DelayedTaskController::AddTask( | 115 void GCMProfileService::DelayedTaskController::AddTask( |
104 const std::string& app_id, base::Closure task) { | 116 const std::string& app_id, base::Closure task) { |
105 DelayedTaskMap::const_iterator iter = delayed_task_map_.find(app_id); | 117 DelayedTaskMap::const_iterator iter = delayed_task_map_.find(app_id); |
106 DCHECK(iter != delayed_task_map_.end()); | 118 DCHECK(iter != delayed_task_map_.end()); |
107 iter->second->tasks.push_back(task); | 119 iter->second->tasks.push_back(task); |
108 } | 120 } |
109 | 121 |
110 void GCMProfileService::DelayedTaskController::SetGCMClientReady() { | 122 void GCMProfileService::DelayedTaskController::SetGCMClientReady() { |
111 gcm_client_ready_ = true; | 123 gcm_client_ready_ = true; |
112 | 124 |
(...skipping 29 matching lines...) Expand all Loading... | |
142 bool GCMProfileService::DelayedTaskController::CanRunTaskWithoutDelay( | 154 bool GCMProfileService::DelayedTaskController::CanRunTaskWithoutDelay( |
143 const std::string& app_id) const { | 155 const std::string& app_id) const { |
144 if (!gcm_client_ready_) | 156 if (!gcm_client_ready_) |
145 return false; | 157 return false; |
146 DelayedTaskMap::const_iterator iter = delayed_task_map_.find(app_id); | 158 DelayedTaskMap::const_iterator iter = delayed_task_map_.find(app_id); |
147 if (iter == delayed_task_map_.end()) | 159 if (iter == delayed_task_map_.end()) |
148 return true; | 160 return true; |
149 return iter->second->ready; | 161 return iter->second->ready; |
150 } | 162 } |
151 | 163 |
164 bool GCMProfileService::DelayedTaskController::IsAppTracked( | |
165 const std::string& app_id) const { | |
166 return delayed_task_map_.find(app_id) != delayed_task_map_.end(); | |
167 } | |
168 | |
152 void GCMProfileService::DelayedTaskController::RunTasks( | 169 void GCMProfileService::DelayedTaskController::RunTasks( |
153 AppTaskQueue* task_queue) { | 170 AppTaskQueue* task_queue) { |
154 DCHECK(gcm_client_ready_ && task_queue->ready); | 171 DCHECK(gcm_client_ready_ && task_queue->ready); |
155 | 172 |
156 for (size_t i = 0; i < task_queue->tasks.size(); ++i) | 173 for (size_t i = 0; i < task_queue->tasks.size(); ++i) |
157 task_queue->tasks[i].Run(); | 174 task_queue->tasks[i].Run(); |
158 task_queue->tasks.clear(); | 175 task_queue->tasks.clear(); |
159 } | 176 } |
160 | 177 |
161 class GCMProfileService::IOWorker | 178 class GCMProfileService::IOWorker |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
407 GCMProfileService::RegistrationInfo::~RegistrationInfo() { | 424 GCMProfileService::RegistrationInfo::~RegistrationInfo() { |
408 } | 425 } |
409 | 426 |
410 bool GCMProfileService::RegistrationInfo::IsValid() const { | 427 bool GCMProfileService::RegistrationInfo::IsValid() const { |
411 return !sender_ids.empty() && !registration_id.empty(); | 428 return !sender_ids.empty() && !registration_id.empty(); |
412 } | 429 } |
413 | 430 |
414 bool GCMProfileService::enable_gcm_for_testing_ = false; | 431 bool GCMProfileService::enable_gcm_for_testing_ = false; |
415 | 432 |
416 // static | 433 // static |
417 bool GCMProfileService::IsGCMEnabled() { | 434 bool GCMProfileService::IsGCMEnabled(Profile* profile) { |
435 // GCM is not enabled in incognito mode. | |
436 if (profile->IsOffTheRecord()) | |
437 return false; | |
438 | |
418 if (enable_gcm_for_testing_) | 439 if (enable_gcm_for_testing_) |
419 return true; | 440 return true; |
420 | 441 |
421 // GCM support is only enabled for Canary/Dev builds. | 442 // GCM support is only enabled for Canary/Dev builds. |
422 chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel(); | 443 chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel(); |
423 return channel == chrome::VersionInfo::CHANNEL_UNKNOWN || | 444 return channel == chrome::VersionInfo::CHANNEL_UNKNOWN || |
424 channel == chrome::VersionInfo::CHANNEL_CANARY || | 445 channel == chrome::VersionInfo::CHANNEL_CANARY || |
425 channel == chrome::VersionInfo::CHANNEL_DEV; | 446 channel == chrome::VersionInfo::CHANNEL_DEV; |
426 } | 447 } |
427 | 448 |
428 // static | 449 // static |
429 void GCMProfileService::RegisterProfilePrefs( | 450 void GCMProfileService::RegisterProfilePrefs( |
430 user_prefs::PrefRegistrySyncable* registry) { | 451 user_prefs::PrefRegistrySyncable* registry) { |
431 registry->RegisterUint64Pref( | 452 registry->RegisterUint64Pref( |
432 prefs::kGCMUserAccountID, | 453 prefs::kGCMUserAccountID, |
433 0, | 454 0, |
434 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | 455 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); |
435 registry->RegisterStringPref( | 456 registry->RegisterStringPref( |
436 prefs::kGCMUserToken, | 457 prefs::kGCMUserToken, |
437 "", | 458 "", |
438 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | 459 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); |
439 } | 460 } |
440 | 461 |
441 GCMProfileService::GCMProfileService(Profile* profile) | 462 GCMProfileService::GCMProfileService(Profile* profile) |
442 : profile_(profile), | 463 : profile_(profile), |
443 testing_delegate_(NULL), | 464 testing_delegate_(NULL), |
444 weak_ptr_factory_(this) { | 465 weak_ptr_factory_(this) { |
466 DCHECK(!profile->IsOffTheRecord()); | |
445 Init(); | 467 Init(); |
446 } | 468 } |
447 | 469 |
448 GCMProfileService::GCMProfileService(Profile* profile, | 470 GCMProfileService::GCMProfileService(Profile* profile, |
449 TestingDelegate* testing_delegate) | 471 TestingDelegate* testing_delegate) |
450 : profile_(profile), | 472 : profile_(profile), |
451 testing_delegate_(testing_delegate), | 473 testing_delegate_(testing_delegate), |
452 weak_ptr_factory_(this) { | 474 weak_ptr_factory_(this) { |
453 Init(); | 475 Init(); |
454 } | 476 } |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
717 // ask the server to unregister it. | 739 // ask the server to unregister it. |
718 RegistrationInfoMap::iterator registration_info_iter = | 740 RegistrationInfoMap::iterator registration_info_iter = |
719 registration_info_map_.find(app_id); | 741 registration_info_map_.find(app_id); |
720 if (registration_info_iter == registration_info_map_.end()) | 742 if (registration_info_iter == registration_info_map_.end()) |
721 return; | 743 return; |
722 registration_info_map_.erase(registration_info_iter); | 744 registration_info_map_.erase(registration_info_iter); |
723 | 745 |
724 // Remove the persisted registration info. | 746 // Remove the persisted registration info. |
725 DeleteRegistrationInfo(app_id); | 747 DeleteRegistrationInfo(app_id); |
726 | 748 |
749 // No need to track the app any more. | |
750 delayed_task_controller_->RemoveApp(app_id); | |
751 | |
727 // Ask the server to unregister it. There could be a small chance that the | 752 // Ask the server to unregister it. There could be a small chance that the |
728 // unregister request fails. If this occurs, it does not bring any harm since | 753 // unregister request fails. If this occurs, it does not bring any harm since |
729 // we simply reject the messages/events received from the server. | 754 // we simply reject the messages/events received from the server. |
730 content::BrowserThread::PostTask( | 755 content::BrowserThread::PostTask( |
731 content::BrowserThread::IO, | 756 content::BrowserThread::IO, |
732 FROM_HERE, | 757 FROM_HERE, |
733 base::Bind(&GCMProfileService::IOWorker::Unregister, | 758 base::Bind(&GCMProfileService::IOWorker::Unregister, |
734 io_worker_, | 759 io_worker_, |
735 app_id)); | 760 app_id)); |
736 } | 761 } |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
879 new base::DictionaryValue()); | 904 new base::DictionaryValue()); |
880 registration_info_dict->Set(kSendersKey, senders_list.release()); | 905 registration_info_dict->Set(kSendersKey, senders_list.release()); |
881 registration_info_dict->SetString(kRegistrationIDKey, | 906 registration_info_dict->SetString(kRegistrationIDKey, |
882 registration_info.registration_id); | 907 registration_info.registration_id); |
883 | 908 |
884 storage->SetExtensionValue( | 909 storage->SetExtensionValue( |
885 app_id, kRegistrationKey, registration_info_dict.PassAs<base::Value>()); | 910 app_id, kRegistrationKey, registration_info_dict.PassAs<base::Value>()); |
886 } | 911 } |
887 | 912 |
888 void GCMProfileService::ReadRegistrationInfo(const std::string& app_id) { | 913 void GCMProfileService::ReadRegistrationInfo(const std::string& app_id) { |
914 // This function can be called more than once when the app is allowed in | |
915 // incognito and the extension service reloads the app. | |
916 if (delayed_task_controller_->IsAppTracked(app_id)) | |
917 return; | |
918 | |
919 delayed_task_controller_->AddApp(app_id); | |
920 | |
889 extensions::StateStore* storage = | 921 extensions::StateStore* storage = |
890 extensions::ExtensionSystem::Get(profile_)->state_store(); | 922 extensions::ExtensionSystem::Get(profile_)->state_store(); |
891 DCHECK(storage); | 923 DCHECK(storage); |
892 | |
893 delayed_task_controller_->AddApp(app_id); | |
894 | |
895 storage->GetExtensionValue( | 924 storage->GetExtensionValue( |
896 app_id, | 925 app_id, |
897 kRegistrationKey, | 926 kRegistrationKey, |
898 base::Bind( | 927 base::Bind( |
899 &GCMProfileService::ReadRegistrationInfoFinished, | 928 &GCMProfileService::ReadRegistrationInfoFinished, |
900 weak_ptr_factory_.GetWeakPtr(), | 929 weak_ptr_factory_.GetWeakPtr(), |
901 app_id)); | 930 app_id)); |
902 } | 931 } |
903 | 932 |
904 void GCMProfileService::ReadRegistrationInfoFinished( | 933 void GCMProfileService::ReadRegistrationInfoFinished( |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
939 | 968 |
940 return true; | 969 return true; |
941 } | 970 } |
942 | 971 |
943 // static | 972 // static |
944 const char* GCMProfileService::GetPersistentRegisterKeyForTesting() { | 973 const char* GCMProfileService::GetPersistentRegisterKeyForTesting() { |
945 return kRegistrationKey; | 974 return kRegistrationKey; |
946 } | 975 } |
947 | 976 |
948 } // namespace gcm | 977 } // namespace gcm |
OLD | NEW |