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" |
11 #include "base/files/file_path.h" | 11 #include "base/files/file_path.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/message_loop/message_loop_proxy.h" | 13 #include "base/message_loop/message_loop_proxy.h" |
14 #include "base/metrics/histogram.h" | 14 #include "base/metrics/histogram.h" |
15 #include "base/sequenced_task_runner.h" | 15 #include "base/sequenced_task_runner.h" |
16 #include "base/stl_util.h" | 16 #include "base/stl_util.h" |
17 #include "base/strings/string_number_conversions.h" | 17 #include "base/strings/string_number_conversions.h" |
18 #include "base/strings/string_piece.h" | 18 #include "base/strings/string_piece.h" |
| 19 #include "base/strings/string_tokenizer.h" |
19 #include "base/time/time.h" | 20 #include "base/time/time.h" |
20 #include "base/tracked_objects.h" | 21 #include "base/tracked_objects.h" |
21 #include "google_apis/gcm/base/encryptor.h" | 22 #include "google_apis/gcm/base/encryptor.h" |
22 #include "google_apis/gcm/base/mcs_message.h" | 23 #include "google_apis/gcm/base/mcs_message.h" |
23 #include "google_apis/gcm/base/mcs_util.h" | 24 #include "google_apis/gcm/base/mcs_util.h" |
24 #include "google_apis/gcm/protocol/mcs.pb.h" | 25 #include "google_apis/gcm/protocol/mcs.pb.h" |
25 #include "third_party/leveldatabase/src/include/leveldb/db.h" | 26 #include "third_party/leveldatabase/src/include/leveldb/db.h" |
26 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h" | 27 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h" |
27 | 28 |
28 namespace gcm { | 29 namespace gcm { |
(...skipping 27 matching lines...) Expand all Loading... |
56 // Used for limiting iteration. | 57 // Used for limiting iteration. |
57 const char kOutgoingMsgKeyEnd[] = "outgoing2-"; | 58 const char kOutgoingMsgKeyEnd[] = "outgoing2-"; |
58 // Lowest lexicographically ordered G-service settings key. | 59 // Lowest lexicographically ordered G-service settings key. |
59 // Used for prefixing G-services settings. | 60 // Used for prefixing G-services settings. |
60 const char kGServiceSettingKeyStart[] = "gservice1-"; | 61 const char kGServiceSettingKeyStart[] = "gservice1-"; |
61 // Key guaranteed to be higher than all G-services settings keys. | 62 // Key guaranteed to be higher than all G-services settings keys. |
62 // Used for limiting iteration. | 63 // Used for limiting iteration. |
63 const char kGServiceSettingKeyEnd[] = "gservice2-"; | 64 const char kGServiceSettingKeyEnd[] = "gservice2-"; |
64 // Key for digest of the last G-services settings update. | 65 // Key for digest of the last G-services settings update. |
65 const char kGServiceSettingsDigestKey[] = "gservices_digest"; | 66 const char kGServiceSettingsDigestKey[] = "gservices_digest"; |
| 67 // Key used to indicate how many accounts were last checked in with this device. |
| 68 const char kLastCheckinAccountsKey[] = "last_checkin_accounts_count"; |
66 // 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). |
67 const char kLastCheckinTimeKey[] = "last_checkin_time"; | 70 const char kLastCheckinTimeKey[] = "last_checkin_time"; |
68 | 71 |
69 std::string MakeRegistrationKey(const std::string& app_id) { | 72 std::string MakeRegistrationKey(const std::string& app_id) { |
70 return kRegistrationKeyStart + app_id; | 73 return kRegistrationKeyStart + app_id; |
71 } | 74 } |
72 | 75 |
73 std::string ParseRegistrationKey(const std::string& key) { | 76 std::string ParseRegistrationKey(const std::string& key) { |
74 return key.substr(arraysize(kRegistrationKeyStart) - 1); | 77 return key.substr(arraysize(kRegistrationKeyStart) - 1); |
75 } | 78 } |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 const UpdateCallback& callback); | 134 const UpdateCallback& callback); |
132 void RemoveOutgoingMessages( | 135 void RemoveOutgoingMessages( |
133 const PersistentIdList& persistent_ids, | 136 const PersistentIdList& persistent_ids, |
134 const base::Callback<void(bool, const AppIdToMessageCountMap&)> | 137 const base::Callback<void(bool, const AppIdToMessageCountMap&)> |
135 callback); | 138 callback); |
136 void AddUserSerialNumber(const std::string& username, | 139 void AddUserSerialNumber(const std::string& username, |
137 int64 serial_number, | 140 int64 serial_number, |
138 const UpdateCallback& callback); | 141 const UpdateCallback& callback); |
139 void RemoveUserSerialNumber(const std::string& username, | 142 void RemoveUserSerialNumber(const std::string& username, |
140 const UpdateCallback& callback); | 143 const UpdateCallback& callback); |
141 void SetLastCheckinTime(const base::Time& last_checkin_time, | 144 void SetLastCheckinInfo(const base::Time& time, |
| 145 const std::set<std::string>& accounts, |
142 const UpdateCallback& callback); | 146 const UpdateCallback& callback); |
143 void SetGServicesSettings( | 147 void SetGServicesSettings( |
144 const std::map<std::string, std::string>& settings, | 148 const std::map<std::string, std::string>& settings, |
145 const std::string& digest, | 149 const std::string& digest, |
146 const UpdateCallback& callback); | 150 const UpdateCallback& callback); |
147 | 151 |
148 private: | 152 private: |
149 friend class base::RefCountedThreadSafe<Backend>; | 153 friend class base::RefCountedThreadSafe<Backend>; |
150 ~Backend(); | 154 ~Backend(); |
151 | 155 |
152 bool LoadDeviceCredentials(uint64* android_id, uint64* security_token); | 156 bool LoadDeviceCredentials(uint64* android_id, uint64* security_token); |
153 bool LoadRegistrations(RegistrationInfoMap* registrations); | 157 bool LoadRegistrations(RegistrationInfoMap* registrations); |
154 bool LoadIncomingMessages(std::vector<std::string>* incoming_messages); | 158 bool LoadIncomingMessages(std::vector<std::string>* incoming_messages); |
155 bool LoadOutgoingMessages(OutgoingMessageMap* outgoing_messages); | 159 bool LoadOutgoingMessages(OutgoingMessageMap* outgoing_messages); |
156 bool LoadLastCheckinTime(base::Time* last_checkin_time); | 160 bool LoadLastCheckinInfo(base::Time* last_checkin_time, |
| 161 std::set<std::string>* accounts); |
157 bool LoadGServicesSettings(std::map<std::string, std::string>* settings, | 162 bool LoadGServicesSettings(std::map<std::string, std::string>* settings, |
158 std::string* digest); | 163 std::string* digest); |
159 | 164 |
160 const base::FilePath path_; | 165 const base::FilePath path_; |
161 scoped_refptr<base::SequencedTaskRunner> foreground_task_runner_; | 166 scoped_refptr<base::SequencedTaskRunner> foreground_task_runner_; |
162 scoped_ptr<Encryptor> encryptor_; | 167 scoped_ptr<Encryptor> encryptor_; |
163 | 168 |
164 scoped_ptr<leveldb::DB> db_; | 169 scoped_ptr<leveldb::DB> db_; |
165 }; | 170 }; |
166 | 171 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
199 base::Passed(&result))); | 204 base::Passed(&result))); |
200 return; | 205 return; |
201 } | 206 } |
202 db_.reset(db); | 207 db_.reset(db); |
203 | 208 |
204 if (!LoadDeviceCredentials(&result->device_android_id, | 209 if (!LoadDeviceCredentials(&result->device_android_id, |
205 &result->device_security_token) || | 210 &result->device_security_token) || |
206 !LoadRegistrations(&result->registrations) || | 211 !LoadRegistrations(&result->registrations) || |
207 !LoadIncomingMessages(&result->incoming_messages) || | 212 !LoadIncomingMessages(&result->incoming_messages) || |
208 !LoadOutgoingMessages(&result->outgoing_messages) || | 213 !LoadOutgoingMessages(&result->outgoing_messages) || |
209 !LoadLastCheckinTime(&result->last_checkin_time) || | 214 !LoadLastCheckinInfo(&result->last_checkin_time, |
| 215 &result->last_checkin_accounts) || |
210 !LoadGServicesSettings(&result->gservices_settings, | 216 !LoadGServicesSettings(&result->gservices_settings, |
211 &result->gservices_digest)) { | 217 &result->gservices_digest)) { |
212 result->device_android_id = 0; | 218 result->device_android_id = 0; |
213 result->device_security_token = 0; | 219 result->device_security_token = 0; |
214 result->registrations.clear(); | 220 result->registrations.clear(); |
215 result->incoming_messages.clear(); | 221 result->incoming_messages.clear(); |
216 result->outgoing_messages.clear(); | 222 result->outgoing_messages.clear(); |
217 result->gservices_settings.clear(); | 223 result->gservices_settings.clear(); |
218 result->gservices_digest.clear(); | 224 result->gservices_digest.clear(); |
219 result->last_checkin_time = base::Time::FromInternalValue(0LL); | 225 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)); | 484 removed_message_counts)); |
479 return; | 485 return; |
480 } | 486 } |
481 LOG(ERROR) << "LevelDB remove failed: " << s.ToString(); | 487 LOG(ERROR) << "LevelDB remove failed: " << s.ToString(); |
482 foreground_task_runner_->PostTask(FROM_HERE, | 488 foreground_task_runner_->PostTask(FROM_HERE, |
483 base::Bind(callback, | 489 base::Bind(callback, |
484 false, | 490 false, |
485 AppIdToMessageCountMap())); | 491 AppIdToMessageCountMap())); |
486 } | 492 } |
487 | 493 |
488 void GCMStoreImpl::Backend::SetLastCheckinTime( | 494 void GCMStoreImpl::Backend::SetLastCheckinInfo( |
489 const base::Time& last_checkin_time, | 495 const base::Time& time, |
| 496 const std::set<std::string>& accounts, |
490 const UpdateCallback& callback) { | 497 const UpdateCallback& callback) { |
| 498 leveldb::WriteBatch write_batch; |
| 499 |
| 500 int64 last_checkin_time_internal = time.ToInternalValue(); |
| 501 write_batch.Put(MakeSlice(kLastCheckinTimeKey), |
| 502 MakeSlice(base::Int64ToString(last_checkin_time_internal))); |
| 503 |
| 504 std::string serialized_accounts; |
| 505 for (std::set<std::string>::iterator iter = accounts.begin(); |
| 506 iter != accounts.end(); |
| 507 ++iter) { |
| 508 serialized_accounts += *iter; |
| 509 serialized_accounts += ","; |
| 510 } |
| 511 if (!serialized_accounts.empty()) |
| 512 serialized_accounts.erase(serialized_accounts.length() - 1); |
| 513 |
| 514 write_batch.Put(MakeSlice(kLastCheckinAccountsKey), |
| 515 MakeSlice(serialized_accounts)); |
| 516 |
491 leveldb::WriteOptions write_options; | 517 leveldb::WriteOptions write_options; |
492 write_options.sync = true; | 518 write_options.sync = true; |
493 | 519 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 | 520 |
500 if (!s.ok()) | 521 if (!s.ok()) |
501 LOG(ERROR) << "LevelDB set last checkin time failed: " << s.ToString(); | 522 LOG(ERROR) << "LevelDB set last checkin info failed: " << s.ToString(); |
502 foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, s.ok())); | 523 foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, s.ok())); |
503 } | 524 } |
504 | 525 |
505 void GCMStoreImpl::Backend::SetGServicesSettings( | 526 void GCMStoreImpl::Backend::SetGServicesSettings( |
506 const std::map<std::string, std::string>& settings, | 527 const std::map<std::string, std::string>& settings, |
507 const std::string& settings_digest, | 528 const std::string& settings_digest, |
508 const UpdateCallback& callback) { | 529 const UpdateCallback& callback) { |
509 leveldb::WriteBatch write_batch; | 530 leveldb::WriteBatch write_batch; |
510 | 531 |
511 // Remove all existing settings. | 532 // Remove all existing settings. |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
648 return false; | 669 return false; |
649 } | 670 } |
650 DVLOG(1) << "Found outgoing message with id " << id << " of type " | 671 DVLOG(1) << "Found outgoing message with id " << id << " of type " |
651 << base::IntToString(tag); | 672 << base::IntToString(tag); |
652 (*outgoing_messages)[id] = make_linked_ptr(message.release()); | 673 (*outgoing_messages)[id] = make_linked_ptr(message.release()); |
653 } | 674 } |
654 | 675 |
655 return true; | 676 return true; |
656 } | 677 } |
657 | 678 |
658 bool GCMStoreImpl::Backend::LoadLastCheckinTime( | 679 bool GCMStoreImpl::Backend::LoadLastCheckinInfo( |
659 base::Time* last_checkin_time) { | 680 base::Time* last_checkin_time, |
| 681 std::set<std::string>* accounts) { |
660 leveldb::ReadOptions read_options; | 682 leveldb::ReadOptions read_options; |
661 read_options.verify_checksums = true; | 683 read_options.verify_checksums = true; |
662 | 684 |
663 std::string result; | 685 std::string result; |
664 leveldb::Status s = db_->Get(read_options, | 686 leveldb::Status s = db_->Get(read_options, |
665 MakeSlice(kLastCheckinTimeKey), | 687 MakeSlice(kLastCheckinTimeKey), |
666 &result); | 688 &result); |
667 int64 time_internal = 0LL; | 689 int64 time_internal = 0LL; |
668 if (s.ok() && !base::StringToInt64(result, &time_internal)) | 690 if (s.ok() && !base::StringToInt64(result, &time_internal)) |
669 LOG(ERROR) << "Failed to restore last checkin time. Using default = 0."; | 691 LOG(ERROR) << "Failed to restore last checkin time. Using default = 0."; |
670 | 692 |
671 // In case we cannot read last checkin time, we default it to 0, as we don't | 693 // 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. | 694 // want that situation to cause the whole load to fail. |
673 *last_checkin_time = base::Time::FromInternalValue(time_internal); | 695 *last_checkin_time = base::Time::FromInternalValue(time_internal); |
674 | 696 |
| 697 accounts->clear(); |
| 698 s = db_->Get(read_options, MakeSlice(kLastCheckinAccountsKey), &result); |
| 699 if (!s.ok()) |
| 700 DVLOG(1) << "No accounts where stored during last run."; |
| 701 |
| 702 base::StringTokenizer t(result, ","); |
| 703 while (t.GetNext()) |
| 704 accounts->insert(t.token()); |
| 705 |
675 return true; | 706 return true; |
676 } | 707 } |
677 | 708 |
678 bool GCMStoreImpl::Backend::LoadGServicesSettings( | 709 bool GCMStoreImpl::Backend::LoadGServicesSettings( |
679 std::map<std::string, std::string>* settings, | 710 std::map<std::string, std::string>* settings, |
680 std::string* digest) { | 711 std::string* digest) { |
681 leveldb::ReadOptions read_options; | 712 leveldb::ReadOptions read_options; |
682 read_options.verify_checksums = true; | 713 read_options.verify_checksums = true; |
683 | 714 |
684 // Load all of the GServices settings. | 715 // Load all of the GServices settings. |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
870 blocking_task_runner_->PostTask( | 901 blocking_task_runner_->PostTask( |
871 FROM_HERE, | 902 FROM_HERE, |
872 base::Bind(&GCMStoreImpl::Backend::RemoveOutgoingMessages, | 903 base::Bind(&GCMStoreImpl::Backend::RemoveOutgoingMessages, |
873 backend_, | 904 backend_, |
874 persistent_ids, | 905 persistent_ids, |
875 base::Bind(&GCMStoreImpl::RemoveOutgoingMessagesContinuation, | 906 base::Bind(&GCMStoreImpl::RemoveOutgoingMessagesContinuation, |
876 weak_ptr_factory_.GetWeakPtr(), | 907 weak_ptr_factory_.GetWeakPtr(), |
877 callback))); | 908 callback))); |
878 } | 909 } |
879 | 910 |
880 void GCMStoreImpl::SetLastCheckinTime(const base::Time& last_checkin_time, | 911 void GCMStoreImpl::SetLastCheckinInfo(const base::Time& time, |
| 912 const std::set<std::string>& accounts, |
881 const UpdateCallback& callback) { | 913 const UpdateCallback& callback) { |
882 blocking_task_runner_->PostTask( | 914 blocking_task_runner_->PostTask( |
883 FROM_HERE, | 915 FROM_HERE, |
884 base::Bind(&GCMStoreImpl::Backend::SetLastCheckinTime, | 916 base::Bind(&GCMStoreImpl::Backend::SetLastCheckinInfo, |
885 backend_, | 917 backend_, |
886 last_checkin_time, | 918 time, |
| 919 accounts, |
887 callback)); | 920 callback)); |
888 } | 921 } |
889 | 922 |
890 void GCMStoreImpl::SetGServicesSettings( | 923 void GCMStoreImpl::SetGServicesSettings( |
891 const std::map<std::string, std::string>& settings, | 924 const std::map<std::string, std::string>& settings, |
892 const std::string& digest, | 925 const std::string& digest, |
893 const UpdateCallback& callback) { | 926 const UpdateCallback& callback) { |
894 blocking_task_runner_->PostTask( | 927 blocking_task_runner_->PostTask( |
895 FROM_HERE, | 928 FROM_HERE, |
896 base::Bind(&GCMStoreImpl::Backend::SetGServicesSettings, | 929 base::Bind(&GCMStoreImpl::Backend::SetGServicesSettings, |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
947 removed_message_counts.begin(); | 980 removed_message_counts.begin(); |
948 iter != removed_message_counts.end(); ++iter) { | 981 iter != removed_message_counts.end(); ++iter) { |
949 DCHECK_NE(app_message_counts_.count(iter->first), 0U); | 982 DCHECK_NE(app_message_counts_.count(iter->first), 0U); |
950 app_message_counts_[iter->first] -= iter->second; | 983 app_message_counts_[iter->first] -= iter->second; |
951 DCHECK_GE(app_message_counts_[iter->first], 0); | 984 DCHECK_GE(app_message_counts_[iter->first], 0); |
952 } | 985 } |
953 callback.Run(true); | 986 callback.Run(true); |
954 } | 987 } |
955 | 988 |
956 } // namespace gcm | 989 } // namespace gcm |
OLD | NEW |