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/file_util.h" | 10 #include "base/file_util.h" |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
56 // Used for limiting iteration. | 56 // Used for limiting iteration. |
57 const char kOutgoingMsgKeyEnd[] = "outgoing2-"; | 57 const char kOutgoingMsgKeyEnd[] = "outgoing2-"; |
58 // Lowest lexicographically ordered G-service settings key. | 58 // Lowest lexicographically ordered G-service settings key. |
59 // Used for prefixing G-services settings. | 59 // Used for prefixing G-services settings. |
60 const char kGServiceSettingKeyStart[] = "gservice1-"; | 60 const char kGServiceSettingKeyStart[] = "gservice1-"; |
61 // Key guaranteed to be higher than all G-services settings keys. | 61 // Key guaranteed to be higher than all G-services settings keys. |
62 // Used for limiting iteration. | 62 // Used for limiting iteration. |
63 const char kGServiceSettingKeyEnd[] = "gservice2-"; | 63 const char kGServiceSettingKeyEnd[] = "gservice2-"; |
64 // Key for digest of the last G-services settings update. | 64 // Key for digest of the last G-services settings update. |
65 const char kGServiceSettingsDigestKey[] = "gservices_digest"; | 65 const char kGServiceSettingsDigestKey[] = "gservices_digest"; |
| 66 // Key used to indicate how many accounts were last checked in with this device. |
| 67 const char kLastCheckinAccountsKey[] = "last_checkin_accounts_count"; |
66 // Key used to timestamp last checkin (marked with G services settings update). | 68 // Key used to timestamp last checkin (marked with G services settings update). |
67 const char kLastCheckinTimeKey[] = "last_checkin_time"; | 69 const char kLastCheckinTimeKey[] = "last_checkin_time"; |
68 | 70 |
69 std::string MakeRegistrationKey(const std::string& app_id) { | 71 std::string MakeRegistrationKey(const std::string& app_id) { |
70 return kRegistrationKeyStart + app_id; | 72 return kRegistrationKeyStart + app_id; |
71 } | 73 } |
72 | 74 |
73 std::string ParseRegistrationKey(const std::string& key) { | 75 std::string ParseRegistrationKey(const std::string& key) { |
74 return key.substr(arraysize(kRegistrationKeyStart) - 1); | 76 return key.substr(arraysize(kRegistrationKeyStart) - 1); |
75 } | 77 } |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 const UpdateCallback& callback); | 133 const UpdateCallback& callback); |
132 void RemoveOutgoingMessages( | 134 void RemoveOutgoingMessages( |
133 const PersistentIdList& persistent_ids, | 135 const PersistentIdList& persistent_ids, |
134 const base::Callback<void(bool, const AppIdToMessageCountMap&)> | 136 const base::Callback<void(bool, const AppIdToMessageCountMap&)> |
135 callback); | 137 callback); |
136 void AddUserSerialNumber(const std::string& username, | 138 void AddUserSerialNumber(const std::string& username, |
137 int64 serial_number, | 139 int64 serial_number, |
138 const UpdateCallback& callback); | 140 const UpdateCallback& callback); |
139 void RemoveUserSerialNumber(const std::string& username, | 141 void RemoveUserSerialNumber(const std::string& username, |
140 const UpdateCallback& callback); | 142 const UpdateCallback& callback); |
141 void SetLastCheckinTime(const base::Time& last_checkin_time, | 143 void SetLastCheckinInfo(const base::Time& last_checkin_time, |
| 144 uint64 accounts_count, |
142 const UpdateCallback& callback); | 145 const UpdateCallback& callback); |
143 void SetGServicesSettings( | 146 void SetGServicesSettings( |
144 const std::map<std::string, std::string>& settings, | 147 const std::map<std::string, std::string>& settings, |
145 const std::string& digest, | 148 const std::string& digest, |
146 const UpdateCallback& callback); | 149 const UpdateCallback& callback); |
147 | 150 |
148 private: | 151 private: |
149 friend class base::RefCountedThreadSafe<Backend>; | 152 friend class base::RefCountedThreadSafe<Backend>; |
150 ~Backend(); | 153 ~Backend(); |
151 | 154 |
152 bool LoadDeviceCredentials(uint64* android_id, uint64* security_token); | 155 bool LoadDeviceCredentials(uint64* android_id, uint64* security_token); |
153 bool LoadRegistrations(RegistrationInfoMap* registrations); | 156 bool LoadRegistrations(RegistrationInfoMap* registrations); |
154 bool LoadIncomingMessages(std::vector<std::string>* incoming_messages); | 157 bool LoadIncomingMessages(std::vector<std::string>* incoming_messages); |
155 bool LoadOutgoingMessages(OutgoingMessageMap* outgoing_messages); | 158 bool LoadOutgoingMessages(OutgoingMessageMap* outgoing_messages); |
156 bool LoadLastCheckinTime(base::Time* last_checkin_time); | 159 bool LoadLastCheckinInfo(base::Time* last_checkin_time, |
| 160 uint64* accounts_count); |
157 bool LoadGServicesSettings(std::map<std::string, std::string>* settings, | 161 bool LoadGServicesSettings(std::map<std::string, std::string>* settings, |
158 std::string* digest); | 162 std::string* digest); |
159 | 163 |
160 const base::FilePath path_; | 164 const base::FilePath path_; |
161 scoped_refptr<base::SequencedTaskRunner> foreground_task_runner_; | 165 scoped_refptr<base::SequencedTaskRunner> foreground_task_runner_; |
162 scoped_ptr<Encryptor> encryptor_; | 166 scoped_ptr<Encryptor> encryptor_; |
163 | 167 |
164 scoped_ptr<leveldb::DB> db_; | 168 scoped_ptr<leveldb::DB> db_; |
165 }; | 169 }; |
166 | 170 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
199 base::Passed(&result))); | 203 base::Passed(&result))); |
200 return; | 204 return; |
201 } | 205 } |
202 db_.reset(db); | 206 db_.reset(db); |
203 | 207 |
204 if (!LoadDeviceCredentials(&result->device_android_id, | 208 if (!LoadDeviceCredentials(&result->device_android_id, |
205 &result->device_security_token) || | 209 &result->device_security_token) || |
206 !LoadRegistrations(&result->registrations) || | 210 !LoadRegistrations(&result->registrations) || |
207 !LoadIncomingMessages(&result->incoming_messages) || | 211 !LoadIncomingMessages(&result->incoming_messages) || |
208 !LoadOutgoingMessages(&result->outgoing_messages) || | 212 !LoadOutgoingMessages(&result->outgoing_messages) || |
209 !LoadLastCheckinTime(&result->last_checkin_time) || | 213 !LoadLastCheckinInfo(&result->last_checkin_time, |
| 214 &result->accounts_count) || |
210 !LoadGServicesSettings(&result->gservices_settings, | 215 !LoadGServicesSettings(&result->gservices_settings, |
211 &result->gservices_digest)) { | 216 &result->gservices_digest)) { |
212 result->device_android_id = 0; | 217 result->device_android_id = 0; |
213 result->device_security_token = 0; | 218 result->device_security_token = 0; |
214 result->registrations.clear(); | 219 result->registrations.clear(); |
215 result->incoming_messages.clear(); | 220 result->incoming_messages.clear(); |
216 result->outgoing_messages.clear(); | 221 result->outgoing_messages.clear(); |
217 result->gservices_settings.clear(); | 222 result->gservices_settings.clear(); |
218 result->gservices_digest.clear(); | 223 result->gservices_digest.clear(); |
219 result->last_checkin_time = base::Time::FromInternalValue(0LL); | 224 result->last_checkin_time = base::Time::FromInternalValue(0LL); |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
478 removed_message_counts)); | 483 removed_message_counts)); |
479 return; | 484 return; |
480 } | 485 } |
481 LOG(ERROR) << "LevelDB remove failed: " << s.ToString(); | 486 LOG(ERROR) << "LevelDB remove failed: " << s.ToString(); |
482 foreground_task_runner_->PostTask(FROM_HERE, | 487 foreground_task_runner_->PostTask(FROM_HERE, |
483 base::Bind(callback, | 488 base::Bind(callback, |
484 false, | 489 false, |
485 AppIdToMessageCountMap())); | 490 AppIdToMessageCountMap())); |
486 } | 491 } |
487 | 492 |
488 void GCMStoreImpl::Backend::SetLastCheckinTime( | 493 void GCMStoreImpl::Backend::SetLastCheckinInfo( |
489 const base::Time& last_checkin_time, | 494 const base::Time& last_checkin_time, |
| 495 uint64 accounts_count, |
490 const UpdateCallback& callback) { | 496 const UpdateCallback& callback) { |
| 497 leveldb::WriteBatch write_batch; |
| 498 |
| 499 int64 last_checkin_time_internal = last_checkin_time.ToInternalValue(); |
| 500 write_batch.Put(MakeSlice(kLastCheckinTimeKey), |
| 501 MakeSlice(base::Int64ToString(last_checkin_time_internal))); |
| 502 |
| 503 write_batch.Put(MakeSlice(kLastCheckinAccountsKey), |
| 504 MakeSlice(base::Uint64ToString(accounts_count))); |
| 505 |
491 leveldb::WriteOptions write_options; | 506 leveldb::WriteOptions write_options; |
492 write_options.sync = true; | 507 write_options.sync = true; |
493 | 508 const leveldb::Status s = db_->Write(write_options, &write_batch); |
494 int64 last_checkin_time_internal = last_checkin_time.ToInternalValue(); | |
495 const leveldb::Status s = | |
496 db_->Put(write_options, | |
497 MakeSlice(kLastCheckinTimeKey), | |
498 MakeSlice(base::Int64ToString(last_checkin_time_internal))); | |
499 | 509 |
500 if (!s.ok()) | 510 if (!s.ok()) |
501 LOG(ERROR) << "LevelDB set last checkin time failed: " << s.ToString(); | 511 LOG(ERROR) << "LevelDB set last checkin info failed: " << s.ToString(); |
502 foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, s.ok())); | 512 foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, s.ok())); |
503 } | 513 } |
504 | 514 |
505 void GCMStoreImpl::Backend::SetGServicesSettings( | 515 void GCMStoreImpl::Backend::SetGServicesSettings( |
506 const std::map<std::string, std::string>& settings, | 516 const std::map<std::string, std::string>& settings, |
507 const std::string& settings_digest, | 517 const std::string& settings_digest, |
508 const UpdateCallback& callback) { | 518 const UpdateCallback& callback) { |
509 leveldb::WriteBatch write_batch; | 519 leveldb::WriteBatch write_batch; |
510 | 520 |
511 // Remove all existing settings. | 521 // Remove all existing settings. |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
648 return false; | 658 return false; |
649 } | 659 } |
650 DVLOG(1) << "Found outgoing message with id " << id << " of type " | 660 DVLOG(1) << "Found outgoing message with id " << id << " of type " |
651 << base::IntToString(tag); | 661 << base::IntToString(tag); |
652 (*outgoing_messages)[id] = make_linked_ptr(message.release()); | 662 (*outgoing_messages)[id] = make_linked_ptr(message.release()); |
653 } | 663 } |
654 | 664 |
655 return true; | 665 return true; |
656 } | 666 } |
657 | 667 |
658 bool GCMStoreImpl::Backend::LoadLastCheckinTime( | 668 bool GCMStoreImpl::Backend::LoadLastCheckinInfo(base::Time* last_checkin_time, |
659 base::Time* last_checkin_time) { | 669 uint64* accounts_count) { |
660 leveldb::ReadOptions read_options; | 670 leveldb::ReadOptions read_options; |
661 read_options.verify_checksums = true; | 671 read_options.verify_checksums = true; |
662 | 672 |
663 std::string result; | 673 std::string result; |
664 leveldb::Status s = db_->Get(read_options, | 674 leveldb::Status s = db_->Get(read_options, |
665 MakeSlice(kLastCheckinTimeKey), | 675 MakeSlice(kLastCheckinTimeKey), |
666 &result); | 676 &result); |
667 int64 time_internal = 0LL; | 677 int64 time_internal = 0LL; |
668 if (s.ok() && !base::StringToInt64(result, &time_internal)) | 678 if (s.ok() && !base::StringToInt64(result, &time_internal)) |
669 LOG(ERROR) << "Failed to restore last checkin time. Using default = 0."; | 679 LOG(ERROR) << "Failed to restore last checkin time. Using default = 0."; |
670 | 680 |
671 // In case we cannot read last checkin time, we default it to 0, as we don't | 681 // In case we cannot read last checkin time, we default it to 0, as we don't |
672 // want that situation to cause the whole load to fail. | 682 // want that situation to cause the whole load to fail. |
673 *last_checkin_time = base::Time::FromInternalValue(time_internal); | 683 *last_checkin_time = base::Time::FromInternalValue(time_internal); |
674 | 684 |
| 685 s = db_->Get(read_options, MakeSlice(kLastCheckinAccountsKey), &result); |
| 686 if (s.ok() && !base::StringToUint64(result, accounts_count)) { |
| 687 DVLOG(1) << "Last account count not set. Defaulting to 0."; |
| 688 *accounts_count = 0; |
| 689 } |
| 690 |
675 return true; | 691 return true; |
676 } | 692 } |
677 | 693 |
678 bool GCMStoreImpl::Backend::LoadGServicesSettings( | 694 bool GCMStoreImpl::Backend::LoadGServicesSettings( |
679 std::map<std::string, std::string>* settings, | 695 std::map<std::string, std::string>* settings, |
680 std::string* digest) { | 696 std::string* digest) { |
681 leveldb::ReadOptions read_options; | 697 leveldb::ReadOptions read_options; |
682 read_options.verify_checksums = true; | 698 read_options.verify_checksums = true; |
683 | 699 |
684 // Load all of the GServices settings. | 700 // Load all of the GServices settings. |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
870 blocking_task_runner_->PostTask( | 886 blocking_task_runner_->PostTask( |
871 FROM_HERE, | 887 FROM_HERE, |
872 base::Bind(&GCMStoreImpl::Backend::RemoveOutgoingMessages, | 888 base::Bind(&GCMStoreImpl::Backend::RemoveOutgoingMessages, |
873 backend_, | 889 backend_, |
874 persistent_ids, | 890 persistent_ids, |
875 base::Bind(&GCMStoreImpl::RemoveOutgoingMessagesContinuation, | 891 base::Bind(&GCMStoreImpl::RemoveOutgoingMessagesContinuation, |
876 weak_ptr_factory_.GetWeakPtr(), | 892 weak_ptr_factory_.GetWeakPtr(), |
877 callback))); | 893 callback))); |
878 } | 894 } |
879 | 895 |
880 void GCMStoreImpl::SetLastCheckinTime(const base::Time& last_checkin_time, | 896 void GCMStoreImpl::SetLastCheckinInfo(const base::Time& last_checkin_time, |
| 897 uint64 accounts_count, |
881 const UpdateCallback& callback) { | 898 const UpdateCallback& callback) { |
882 blocking_task_runner_->PostTask( | 899 blocking_task_runner_->PostTask( |
883 FROM_HERE, | 900 FROM_HERE, |
884 base::Bind(&GCMStoreImpl::Backend::SetLastCheckinTime, | 901 base::Bind(&GCMStoreImpl::Backend::SetLastCheckinInfo, |
885 backend_, | 902 backend_, |
886 last_checkin_time, | 903 last_checkin_time, |
| 904 accounts_count, |
887 callback)); | 905 callback)); |
888 } | 906 } |
889 | 907 |
890 void GCMStoreImpl::SetGServicesSettings( | 908 void GCMStoreImpl::SetGServicesSettings( |
891 const std::map<std::string, std::string>& settings, | 909 const std::map<std::string, std::string>& settings, |
892 const std::string& digest, | 910 const std::string& digest, |
893 const UpdateCallback& callback) { | 911 const UpdateCallback& callback) { |
894 blocking_task_runner_->PostTask( | 912 blocking_task_runner_->PostTask( |
895 FROM_HERE, | 913 FROM_HERE, |
896 base::Bind(&GCMStoreImpl::Backend::SetGServicesSettings, | 914 base::Bind(&GCMStoreImpl::Backend::SetGServicesSettings, |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
947 removed_message_counts.begin(); | 965 removed_message_counts.begin(); |
948 iter != removed_message_counts.end(); ++iter) { | 966 iter != removed_message_counts.end(); ++iter) { |
949 DCHECK_NE(app_message_counts_.count(iter->first), 0U); | 967 DCHECK_NE(app_message_counts_.count(iter->first), 0U); |
950 app_message_counts_[iter->first] -= iter->second; | 968 app_message_counts_[iter->first] -= iter->second; |
951 DCHECK_GE(app_message_counts_[iter->first], 0); | 969 DCHECK_GE(app_message_counts_[iter->first], 0); |
952 } | 970 } |
953 callback.Run(true); | 971 callback.Run(true); |
954 } | 972 } |
955 | 973 |
956 } // namespace gcm | 974 } // namespace gcm |
OLD | NEW |