| OLD | NEW |
| 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 "google_apis/gcm/engine/gcm_store_impl.h" | 5 #include "google_apis/gcm/engine/gcm_store_impl.h" |
| 6 | 6 |
| 7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "base/bind.h" | 8 #include "base/bind.h" |
| 9 #include "base/callback.h" | 9 #include "base/callback.h" |
| 10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 67 // Key used to indicate how many accounts were last checked in with this device. | 67 // Key used to indicate how many accounts were last checked in with this device. |
| 68 const char kLastCheckinAccountsKey[] = "last_checkin_accounts_count"; | 68 const char kLastCheckinAccountsKey[] = "last_checkin_accounts_count"; |
| 69 // Key used to timestamp last checkin (marked with G services settings update). | 69 // Key used to timestamp last checkin (marked with G services settings update). |
| 70 const char kLastCheckinTimeKey[] = "last_checkin_time"; | 70 const char kLastCheckinTimeKey[] = "last_checkin_time"; |
| 71 // Lowest lexicographically ordered account key. | 71 // Lowest lexicographically ordered account key. |
| 72 // Used for prefixing account information. | 72 // Used for prefixing account information. |
| 73 const char kAccountKeyStart[] = "account1-"; | 73 const char kAccountKeyStart[] = "account1-"; |
| 74 // Key guaranteed to be higher than all account keys. | 74 // Key guaranteed to be higher than all account keys. |
| 75 // Used for limiting iteration. | 75 // Used for limiting iteration. |
| 76 const char kAccountKeyEnd[] = "account2-"; | 76 const char kAccountKeyEnd[] = "account2-"; |
| 77 // Key used for last token fetch time. |
| 78 const char kLastTokenFetchTimeKey[] = "last_token_fetch_time"; |
| 77 | 79 |
| 78 std::string MakeRegistrationKey(const std::string& app_id) { | 80 std::string MakeRegistrationKey(const std::string& app_id) { |
| 79 return kRegistrationKeyStart + app_id; | 81 return kRegistrationKeyStart + app_id; |
| 80 } | 82 } |
| 81 | 83 |
| 82 std::string ParseRegistrationKey(const std::string& key) { | 84 std::string ParseRegistrationKey(const std::string& key) { |
| 83 return key.substr(arraysize(kRegistrationKeyStart) - 1); | 85 return key.substr(arraysize(kRegistrationKeyStart) - 1); |
| 84 } | 86 } |
| 85 | 87 |
| 86 std::string MakeIncomingKey(const std::string& persistent_id) { | 88 std::string MakeIncomingKey(const std::string& persistent_id) { |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 159 const std::set<std::string>& accounts, | 161 const std::set<std::string>& accounts, |
| 160 const UpdateCallback& callback); | 162 const UpdateCallback& callback); |
| 161 void SetGServicesSettings( | 163 void SetGServicesSettings( |
| 162 const std::map<std::string, std::string>& settings, | 164 const std::map<std::string, std::string>& settings, |
| 163 const std::string& digest, | 165 const std::string& digest, |
| 164 const UpdateCallback& callback); | 166 const UpdateCallback& callback); |
| 165 void AddAccountMapping(const AccountMapping& account_mapping, | 167 void AddAccountMapping(const AccountMapping& account_mapping, |
| 166 const UpdateCallback& callback); | 168 const UpdateCallback& callback); |
| 167 void RemoveAccountMapping(const std::string& account_id, | 169 void RemoveAccountMapping(const std::string& account_id, |
| 168 const UpdateCallback& callback); | 170 const UpdateCallback& callback); |
| 171 void SetLastTokenFetchTime(const base::Time& time, |
| 172 const UpdateCallback& callback); |
| 169 | 173 |
| 170 private: | 174 private: |
| 171 friend class base::RefCountedThreadSafe<Backend>; | 175 friend class base::RefCountedThreadSafe<Backend>; |
| 172 ~Backend(); | 176 ~Backend(); |
| 173 | 177 |
| 174 bool LoadDeviceCredentials(uint64* android_id, uint64* security_token); | 178 bool LoadDeviceCredentials(uint64* android_id, uint64* security_token); |
| 175 bool LoadRegistrations(RegistrationInfoMap* registrations); | 179 bool LoadRegistrations(RegistrationInfoMap* registrations); |
| 176 bool LoadIncomingMessages(std::vector<std::string>* incoming_messages); | 180 bool LoadIncomingMessages(std::vector<std::string>* incoming_messages); |
| 177 bool LoadOutgoingMessages(OutgoingMessageMap* outgoing_messages); | 181 bool LoadOutgoingMessages(OutgoingMessageMap* outgoing_messages); |
| 178 bool LoadLastCheckinInfo(base::Time* last_checkin_time, | 182 bool LoadLastCheckinInfo(base::Time* last_checkin_time, |
| 179 std::set<std::string>* accounts); | 183 std::set<std::string>* accounts); |
| 180 bool LoadGServicesSettings(std::map<std::string, std::string>* settings, | 184 bool LoadGServicesSettings(std::map<std::string, std::string>* settings, |
| 181 std::string* digest); | 185 std::string* digest); |
| 182 bool LoadAccountMappingInfo(AccountMappings* account_mappings); | 186 bool LoadAccountMappingInfo(AccountMappings* account_mappings); |
| 187 bool LoadLastTokenFetchTime(base::Time* last_token_fetch_time); |
| 183 | 188 |
| 184 const base::FilePath path_; | 189 const base::FilePath path_; |
| 185 scoped_refptr<base::SequencedTaskRunner> foreground_task_runner_; | 190 scoped_refptr<base::SequencedTaskRunner> foreground_task_runner_; |
| 186 scoped_ptr<Encryptor> encryptor_; | 191 scoped_ptr<Encryptor> encryptor_; |
| 187 | 192 |
| 188 scoped_ptr<leveldb::DB> db_; | 193 scoped_ptr<leveldb::DB> db_; |
| 189 }; | 194 }; |
| 190 | 195 |
| 191 GCMStoreImpl::Backend::Backend( | 196 GCMStoreImpl::Backend::Backend( |
| 192 const base::FilePath& path, | 197 const base::FilePath& path, |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 227 | 232 |
| 228 if (!LoadDeviceCredentials(&result->device_android_id, | 233 if (!LoadDeviceCredentials(&result->device_android_id, |
| 229 &result->device_security_token) || | 234 &result->device_security_token) || |
| 230 !LoadRegistrations(&result->registrations) || | 235 !LoadRegistrations(&result->registrations) || |
| 231 !LoadIncomingMessages(&result->incoming_messages) || | 236 !LoadIncomingMessages(&result->incoming_messages) || |
| 232 !LoadOutgoingMessages(&result->outgoing_messages) || | 237 !LoadOutgoingMessages(&result->outgoing_messages) || |
| 233 !LoadLastCheckinInfo(&result->last_checkin_time, | 238 !LoadLastCheckinInfo(&result->last_checkin_time, |
| 234 &result->last_checkin_accounts) || | 239 &result->last_checkin_accounts) || |
| 235 !LoadGServicesSettings(&result->gservices_settings, | 240 !LoadGServicesSettings(&result->gservices_settings, |
| 236 &result->gservices_digest) || | 241 &result->gservices_digest) || |
| 237 !LoadAccountMappingInfo(&result->account_mappings)) { | 242 !LoadAccountMappingInfo(&result->account_mappings) || |
| 243 !LoadLastTokenFetchTime(&result->last_token_fetch_time)) { |
| 238 result->Reset(); | 244 result->Reset(); |
| 239 foreground_task_runner_->PostTask(FROM_HERE, | 245 foreground_task_runner_->PostTask(FROM_HERE, |
| 240 base::Bind(callback, | 246 base::Bind(callback, |
| 241 base::Passed(&result))); | 247 base::Passed(&result))); |
| 242 return; | 248 return; |
| 243 } | 249 } |
| 244 | 250 |
| 245 // Only record histograms if GCM had already been set up for this device. | 251 // Only record histograms if GCM had already been set up for this device. |
| 246 if (result->device_android_id != 0 && result->device_security_token != 0) { | 252 if (result->device_android_id != 0 && result->device_security_token != 0) { |
| 247 int64 file_size = 0; | 253 int64 file_size = 0; |
| (...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 611 write_options.sync = true; | 617 write_options.sync = true; |
| 612 | 618 |
| 613 leveldb::Status s = | 619 leveldb::Status s = |
| 614 db_->Delete(write_options, MakeSlice(MakeAccountKey(account_id))); | 620 db_->Delete(write_options, MakeSlice(MakeAccountKey(account_id))); |
| 615 | 621 |
| 616 if (!s.ok()) | 622 if (!s.ok()) |
| 617 LOG(ERROR) << "LevelDB removal of account mapping failed: " << s.ToString(); | 623 LOG(ERROR) << "LevelDB removal of account mapping failed: " << s.ToString(); |
| 618 foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, s.ok())); | 624 foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, s.ok())); |
| 619 } | 625 } |
| 620 | 626 |
| 627 void GCMStoreImpl::Backend::SetLastTokenFetchTime( |
| 628 const base::Time& time, |
| 629 const UpdateCallback& callback) { |
| 630 DVLOG(1) << "Setting last token fetching time."; |
| 631 if (!db_.get()) { |
| 632 LOG(ERROR) << "GCMStore db doesn't exist."; |
| 633 foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); |
| 634 return; |
| 635 } |
| 636 |
| 637 leveldb::WriteOptions write_options; |
| 638 write_options.sync = true; |
| 639 |
| 640 const leveldb::Status s = |
| 641 db_->Put(write_options, |
| 642 MakeSlice(kLastTokenFetchTimeKey), |
| 643 MakeSlice(base::Int64ToString(time.ToInternalValue()))); |
| 644 |
| 645 if (!s.ok()) |
| 646 LOG(ERROR) << "LevelDB setting last token fetching time: " << s.ToString(); |
| 647 foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, s.ok())); |
| 648 } |
| 649 |
| 621 bool GCMStoreImpl::Backend::LoadDeviceCredentials(uint64* android_id, | 650 bool GCMStoreImpl::Backend::LoadDeviceCredentials(uint64* android_id, |
| 622 uint64* security_token) { | 651 uint64* security_token) { |
| 623 leveldb::ReadOptions read_options; | 652 leveldb::ReadOptions read_options; |
| 624 read_options.verify_checksums = true; | 653 read_options.verify_checksums = true; |
| 625 | 654 |
| 626 std::string result; | 655 std::string result; |
| 627 leveldb::Status s = db_->Get(read_options, MakeSlice(kDeviceAIDKey), &result); | 656 leveldb::Status s = db_->Get(read_options, MakeSlice(kDeviceAIDKey), &result); |
| 628 if (s.ok()) { | 657 if (s.ok()) { |
| 629 if (!base::StringToUint64(result, android_id)) { | 658 if (!base::StringToUint64(result, android_id)) { |
| 630 LOG(ERROR) << "Failed to restore device id."; | 659 LOG(ERROR) << "Failed to restore device id."; |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 807 << account_mapping.account_id; | 836 << account_mapping.account_id; |
| 808 return false; | 837 return false; |
| 809 } | 838 } |
| 810 DVLOG(1) << "Found account mapping with ID: " << account_mapping.account_id; | 839 DVLOG(1) << "Found account mapping with ID: " << account_mapping.account_id; |
| 811 account_mappings->push_back(account_mapping); | 840 account_mappings->push_back(account_mapping); |
| 812 } | 841 } |
| 813 | 842 |
| 814 return true; | 843 return true; |
| 815 } | 844 } |
| 816 | 845 |
| 846 bool GCMStoreImpl::Backend::LoadLastTokenFetchTime( |
| 847 base::Time* last_token_fetch_time) { |
| 848 leveldb::ReadOptions read_options; |
| 849 read_options.verify_checksums = true; |
| 850 |
| 851 std::string result; |
| 852 leveldb::Status s = |
| 853 db_->Get(read_options, MakeSlice(kLastTokenFetchTimeKey), &result); |
| 854 int64 time_internal = 0LL; |
| 855 if (s.ok() && !base::StringToInt64(result, &time_internal)) |
| 856 LOG(ERROR) << "Failed to restore last checkin time. Using default = 0."; |
| 857 |
| 858 // In case we cannot read last token fetching time, we default it to 0. |
| 859 *last_token_fetch_time = base::Time::FromInternalValue(time_internal); |
| 860 |
| 861 return true; |
| 862 } |
| 863 |
| 817 GCMStoreImpl::GCMStoreImpl( | 864 GCMStoreImpl::GCMStoreImpl( |
| 818 const base::FilePath& path, | 865 const base::FilePath& path, |
| 819 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner, | 866 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner, |
| 820 scoped_ptr<Encryptor> encryptor) | 867 scoped_ptr<Encryptor> encryptor) |
| 821 : backend_(new Backend(path, | 868 : backend_(new Backend(path, |
| 822 base::MessageLoopProxy::current(), | 869 base::MessageLoopProxy::current(), |
| 823 encryptor.Pass())), | 870 encryptor.Pass())), |
| 824 blocking_task_runner_(blocking_task_runner), | 871 blocking_task_runner_(blocking_task_runner), |
| 825 weak_ptr_factory_(this) { | 872 weak_ptr_factory_(this) { |
| 826 } | 873 } |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1026 void GCMStoreImpl::RemoveAccountMapping(const std::string& account_id, | 1073 void GCMStoreImpl::RemoveAccountMapping(const std::string& account_id, |
| 1027 const UpdateCallback& callback) { | 1074 const UpdateCallback& callback) { |
| 1028 blocking_task_runner_->PostTask( | 1075 blocking_task_runner_->PostTask( |
| 1029 FROM_HERE, | 1076 FROM_HERE, |
| 1030 base::Bind(&GCMStoreImpl::Backend::RemoveAccountMapping, | 1077 base::Bind(&GCMStoreImpl::Backend::RemoveAccountMapping, |
| 1031 backend_, | 1078 backend_, |
| 1032 account_id, | 1079 account_id, |
| 1033 callback)); | 1080 callback)); |
| 1034 } | 1081 } |
| 1035 | 1082 |
| 1083 void GCMStoreImpl::SetLastTokenFetchTime(const base::Time& time, |
| 1084 const UpdateCallback& callback) { |
| 1085 blocking_task_runner_->PostTask( |
| 1086 FROM_HERE, |
| 1087 base::Bind(&GCMStoreImpl::Backend::SetLastTokenFetchTime, |
| 1088 backend_, |
| 1089 time, |
| 1090 callback)); |
| 1091 } |
| 1092 |
| 1036 void GCMStoreImpl::LoadContinuation(const LoadCallback& callback, | 1093 void GCMStoreImpl::LoadContinuation(const LoadCallback& callback, |
| 1037 scoped_ptr<LoadResult> result) { | 1094 scoped_ptr<LoadResult> result) { |
| 1038 if (!result->success) { | 1095 if (!result->success) { |
| 1039 callback.Run(result.Pass()); | 1096 callback.Run(result.Pass()); |
| 1040 return; | 1097 return; |
| 1041 } | 1098 } |
| 1042 int num_throttled_apps = 0; | 1099 int num_throttled_apps = 0; |
| 1043 for (OutgoingMessageMap::const_iterator | 1100 for (OutgoingMessageMap::const_iterator |
| 1044 iter = result->outgoing_messages.begin(); | 1101 iter = result->outgoing_messages.begin(); |
| 1045 iter != result->outgoing_messages.end(); ++iter) { | 1102 iter != result->outgoing_messages.end(); ++iter) { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1080 removed_message_counts.begin(); | 1137 removed_message_counts.begin(); |
| 1081 iter != removed_message_counts.end(); ++iter) { | 1138 iter != removed_message_counts.end(); ++iter) { |
| 1082 DCHECK_NE(app_message_counts_.count(iter->first), 0U); | 1139 DCHECK_NE(app_message_counts_.count(iter->first), 0U); |
| 1083 app_message_counts_[iter->first] -= iter->second; | 1140 app_message_counts_[iter->first] -= iter->second; |
| 1084 DCHECK_GE(app_message_counts_[iter->first], 0); | 1141 DCHECK_GE(app_message_counts_[iter->first], 0); |
| 1085 } | 1142 } |
| 1086 callback.Run(true); | 1143 callback.Run(true); |
| 1087 } | 1144 } |
| 1088 | 1145 |
| 1089 } // namespace gcm | 1146 } // namespace gcm |
| OLD | NEW |