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 17 matching lines...) Expand all Loading... |
28 namespace { | 28 namespace { |
29 | 29 |
30 // Limit to the number of outstanding messages per app. | 30 // Limit to the number of outstanding messages per app. |
31 const int kMessagesPerAppLimit = 20; | 31 const int kMessagesPerAppLimit = 20; |
32 | 32 |
33 // ---- LevelDB keys. ---- | 33 // ---- LevelDB keys. ---- |
34 // Key for this device's android id. | 34 // Key for this device's android id. |
35 const char kDeviceAIDKey[] = "device_aid_key"; | 35 const char kDeviceAIDKey[] = "device_aid_key"; |
36 // Key for this device's android security token. | 36 // Key for this device's android security token. |
37 const char kDeviceTokenKey[] = "device_token_key"; | 37 const char kDeviceTokenKey[] = "device_token_key"; |
| 38 // Lowest lexicographically ordered app ids. |
| 39 // Used for prefixing app id. |
| 40 const char kRegistrationKeyStart[] = "reg1-"; |
| 41 // Key guaranteed to be higher than all app ids. |
| 42 // Used for limiting iteration. |
| 43 const char kRegistrationKeyEnd[] = "reg2-"; |
38 // Lowest lexicographically ordered incoming message key. | 44 // Lowest lexicographically ordered incoming message key. |
39 // Used for prefixing messages. | 45 // Used for prefixing messages. |
40 const char kIncomingMsgKeyStart[] = "incoming1-"; | 46 const char kIncomingMsgKeyStart[] = "incoming1-"; |
41 // Key guaranteed to be higher than all incoming message keys. | 47 // Key guaranteed to be higher than all incoming message keys. |
42 // Used for limiting iteration. | 48 // Used for limiting iteration. |
43 const char kIncomingMsgKeyEnd[] = "incoming2-"; | 49 const char kIncomingMsgKeyEnd[] = "incoming2-"; |
44 // Key for next serial number assigned to the user. | |
45 const char kNextSerialNumberKey[] = "next_serial_number_key"; | |
46 // Lowest lexicographically ordered outgoing message key. | 50 // Lowest lexicographically ordered outgoing message key. |
47 // Used for prefixing outgoing messages. | 51 // Used for prefixing outgoing messages. |
48 const char kOutgoingMsgKeyStart[] = "outgoing1-"; | 52 const char kOutgoingMsgKeyStart[] = "outgoing1-"; |
49 // Key guaranteed to be higher than all outgoing message keys. | 53 // Key guaranteed to be higher than all outgoing message keys. |
50 // Used for limiting iteration. | 54 // Used for limiting iteration. |
51 const char kOutgoingMsgKeyEnd[] = "outgoing2-"; | 55 const char kOutgoingMsgKeyEnd[] = "outgoing2-"; |
52 // Lowest lexicographically ordered username. | |
53 // Used for prefixing username to serial number mappings. | |
54 const char kUserSerialNumberKeyStart[] = "user1-"; | |
55 // Key guaranteed to be higher than all usernames. | |
56 // Used for limiting iteration. | |
57 const char kUserSerialNumberKeyEnd[] = "user2-"; | |
58 | 56 |
59 // Value indicating that serial number was not assigned. | 57 std::string MakeRegistrationKey(const std::string& app_id) { |
60 const int64 kSerialNumberMissing = -1LL; | 58 return kRegistrationKeyStart + app_id; |
| 59 } |
| 60 |
| 61 std::string ParseRegistrationKey(const std::string& key) { |
| 62 return key.substr(arraysize(kRegistrationKeyStart) - 1); |
| 63 } |
61 | 64 |
62 std::string MakeIncomingKey(const std::string& persistent_id) { | 65 std::string MakeIncomingKey(const std::string& persistent_id) { |
63 return kIncomingMsgKeyStart + persistent_id; | 66 return kIncomingMsgKeyStart + persistent_id; |
64 } | 67 } |
65 | 68 |
66 std::string MakeOutgoingKey(const std::string& persistent_id) { | 69 std::string MakeOutgoingKey(const std::string& persistent_id) { |
67 return kOutgoingMsgKeyStart + persistent_id; | 70 return kOutgoingMsgKeyStart + persistent_id; |
68 } | 71 } |
69 | 72 |
70 std::string MakeUserSerialNumberKey(const std::string& username) { | |
71 return kUserSerialNumberKeyStart + username; | |
72 } | |
73 | |
74 std::string ParseOutgoingKey(const std::string& key) { | 73 std::string ParseOutgoingKey(const std::string& key) { |
75 return key.substr(arraysize(kOutgoingMsgKeyStart) - 1); | 74 return key.substr(arraysize(kOutgoingMsgKeyStart) - 1); |
76 } | 75 } |
77 | 76 |
78 std::string ParseUsername(const std::string& key) { | |
79 return key.substr(arraysize(kUserSerialNumberKeyStart) - 1); | |
80 } | |
81 | |
82 // Note: leveldb::Slice keeps a pointer to the data in |s|, which must therefore | 77 // Note: leveldb::Slice keeps a pointer to the data in |s|, which must therefore |
83 // outlive the slice. | 78 // outlive the slice. |
84 // For example: MakeSlice(MakeOutgoingKey(x)) is invalid. | 79 // For example: MakeSlice(MakeOutgoingKey(x)) is invalid. |
85 leveldb::Slice MakeSlice(const base::StringPiece& s) { | 80 leveldb::Slice MakeSlice(const base::StringPiece& s) { |
86 return leveldb::Slice(s.begin(), s.size()); | 81 return leveldb::Slice(s.begin(), s.size()); |
87 } | 82 } |
88 | 83 |
89 } // namespace | 84 } // namespace |
90 | 85 |
91 class GCMStoreImpl::Backend | 86 class GCMStoreImpl::Backend |
92 : public base::RefCountedThreadSafe<GCMStoreImpl::Backend> { | 87 : public base::RefCountedThreadSafe<GCMStoreImpl::Backend> { |
93 public: | 88 public: |
94 Backend(const base::FilePath& path, | 89 Backend(const base::FilePath& path, |
95 scoped_refptr<base::SequencedTaskRunner> foreground_runner); | 90 scoped_refptr<base::SequencedTaskRunner> foreground_runner); |
96 | 91 |
97 // Blocking implementations of GCMStoreImpl methods. | 92 // Blocking implementations of GCMStoreImpl methods. |
98 void Load(const LoadCallback& callback); | 93 void Load(const LoadCallback& callback); |
99 void Close(); | 94 void Close(); |
100 void Destroy(const UpdateCallback& callback); | 95 void Destroy(const UpdateCallback& callback); |
101 void SetDeviceCredentials(uint64 device_android_id, | 96 void SetDeviceCredentials(uint64 device_android_id, |
102 uint64 device_security_token, | 97 uint64 device_security_token, |
103 const UpdateCallback& callback); | 98 const UpdateCallback& callback); |
| 99 void AddRegistration(const std::string& app_id, |
| 100 const linked_ptr<RegistrationInfo>& registration, |
| 101 const UpdateCallback& callback); |
| 102 void RemoveRegistration(const std::string& app_id, |
| 103 const UpdateCallback& callback); |
104 void AddIncomingMessage(const std::string& persistent_id, | 104 void AddIncomingMessage(const std::string& persistent_id, |
105 const UpdateCallback& callback); | 105 const UpdateCallback& callback); |
106 void RemoveIncomingMessages(const PersistentIdList& persistent_ids, | 106 void RemoveIncomingMessages(const PersistentIdList& persistent_ids, |
107 const UpdateCallback& callback); | 107 const UpdateCallback& callback); |
108 void AddOutgoingMessage(const std::string& persistent_id, | 108 void AddOutgoingMessage(const std::string& persistent_id, |
109 const MCSMessage& message, | 109 const MCSMessage& message, |
110 const UpdateCallback& callback); | 110 const UpdateCallback& callback); |
111 void RemoveOutgoingMessages( | 111 void RemoveOutgoingMessages( |
112 const PersistentIdList& persistent_ids, | 112 const PersistentIdList& persistent_ids, |
113 const base::Callback<void(bool, const AppIdToMessageCountMap&)> | 113 const base::Callback<void(bool, const AppIdToMessageCountMap&)> |
114 callback); | 114 callback); |
115 void AddUserSerialNumber(const std::string& username, | 115 void AddUserSerialNumber(const std::string& username, |
116 int64 serial_number, | 116 int64 serial_number, |
117 const UpdateCallback& callback); | 117 const UpdateCallback& callback); |
118 void RemoveUserSerialNumber(const std::string& username, | 118 void RemoveUserSerialNumber(const std::string& username, |
119 const UpdateCallback& callback); | 119 const UpdateCallback& callback); |
120 void SetNextSerialNumber(int64 serial_number, const UpdateCallback& callback); | 120 void SetNextSerialNumber(int64 serial_number, const UpdateCallback& callback); |
121 | 121 |
122 private: | 122 private: |
123 friend class base::RefCountedThreadSafe<Backend>; | 123 friend class base::RefCountedThreadSafe<Backend>; |
124 ~Backend(); | 124 ~Backend(); |
125 | 125 |
126 bool LoadDeviceCredentials(uint64* android_id, uint64* security_token); | 126 bool LoadDeviceCredentials(uint64* android_id, uint64* security_token); |
| 127 bool LoadRegistrations(RegistrationInfoMap* registrations); |
127 bool LoadIncomingMessages(std::vector<std::string>* incoming_messages); | 128 bool LoadIncomingMessages(std::vector<std::string>* incoming_messages); |
128 bool LoadOutgoingMessages(OutgoingMessageMap* outgoing_messages); | 129 bool LoadOutgoingMessages(OutgoingMessageMap* outgoing_messages); |
129 bool LoadNextSerialNumber(int64* next_serial_number); | |
130 bool LoadUserSerialNumberMap( | |
131 std::map<std::string, int64>* user_serial_number_map); | |
132 | 130 |
133 const base::FilePath path_; | 131 const base::FilePath path_; |
134 scoped_refptr<base::SequencedTaskRunner> foreground_task_runner_; | 132 scoped_refptr<base::SequencedTaskRunner> foreground_task_runner_; |
135 | 133 |
136 scoped_ptr<leveldb::DB> db_; | 134 scoped_ptr<leveldb::DB> db_; |
137 }; | 135 }; |
138 | 136 |
139 GCMStoreImpl::Backend::Backend( | 137 GCMStoreImpl::Backend::Backend( |
140 const base::FilePath& path, | 138 const base::FilePath& path, |
141 scoped_refptr<base::SequencedTaskRunner> foreground_task_runner) | 139 scoped_refptr<base::SequencedTaskRunner> foreground_task_runner) |
(...skipping 22 matching lines...) Expand all Loading... |
164 << status.ToString(); | 162 << status.ToString(); |
165 foreground_task_runner_->PostTask(FROM_HERE, | 163 foreground_task_runner_->PostTask(FROM_HERE, |
166 base::Bind(callback, | 164 base::Bind(callback, |
167 base::Passed(&result))); | 165 base::Passed(&result))); |
168 return; | 166 return; |
169 } | 167 } |
170 db_.reset(db); | 168 db_.reset(db); |
171 | 169 |
172 if (!LoadDeviceCredentials(&result->device_android_id, | 170 if (!LoadDeviceCredentials(&result->device_android_id, |
173 &result->device_security_token) || | 171 &result->device_security_token) || |
| 172 !LoadRegistrations(&result->registrations) || |
174 !LoadIncomingMessages(&result->incoming_messages) || | 173 !LoadIncomingMessages(&result->incoming_messages) || |
175 !LoadOutgoingMessages(&result->outgoing_messages) || | 174 !LoadOutgoingMessages(&result->outgoing_messages)) { |
176 !LoadNextSerialNumber( | |
177 &result->serial_number_mappings.next_serial_number) || | |
178 !LoadUserSerialNumberMap( | |
179 &result->serial_number_mappings.user_serial_numbers)) { | |
180 result->device_android_id = 0; | 175 result->device_android_id = 0; |
181 result->device_security_token = 0; | 176 result->device_security_token = 0; |
| 177 result->registrations.clear(); |
182 result->incoming_messages.clear(); | 178 result->incoming_messages.clear(); |
183 result->outgoing_messages.clear(); | 179 result->outgoing_messages.clear(); |
184 foreground_task_runner_->PostTask(FROM_HERE, | 180 foreground_task_runner_->PostTask(FROM_HERE, |
185 base::Bind(callback, | 181 base::Bind(callback, |
186 base::Passed(&result))); | 182 base::Passed(&result))); |
187 return; | 183 return; |
188 } | 184 } |
189 | 185 |
190 // Only record histograms if GCM had already been set up for this device. | 186 // Only record histograms if GCM had already been set up for this device. |
191 if (result->device_android_id != 0 && result->device_security_token != 0) { | 187 if (result->device_android_id != 0 && result->device_security_token != 0) { |
192 int64 file_size = 0; | 188 int64 file_size = 0; |
193 if (base::GetFileSize(path_, &file_size)) { | 189 if (base::GetFileSize(path_, &file_size)) { |
194 UMA_HISTOGRAM_COUNTS("GCM.StoreSizeKB", | 190 UMA_HISTOGRAM_COUNTS("GCM.StoreSizeKB", |
195 static_cast<int>(file_size / 1024)); | 191 static_cast<int>(file_size / 1024)); |
196 } | 192 } |
| 193 UMA_HISTOGRAM_COUNTS("GCM.RestoredRegistrations", |
| 194 result->registrations.size()); |
197 UMA_HISTOGRAM_COUNTS("GCM.RestoredOutgoingMessages", | 195 UMA_HISTOGRAM_COUNTS("GCM.RestoredOutgoingMessages", |
198 result->outgoing_messages.size()); | 196 result->outgoing_messages.size()); |
199 UMA_HISTOGRAM_COUNTS("GCM.RestoredIncomingMessages", | 197 UMA_HISTOGRAM_COUNTS("GCM.RestoredIncomingMessages", |
200 result->incoming_messages.size()); | 198 result->incoming_messages.size()); |
201 UMA_HISTOGRAM_COUNTS( | |
202 "GCM.NumUsers", | |
203 result->serial_number_mappings.user_serial_numbers.size()); | |
204 } | 199 } |
205 | 200 |
206 DVLOG(1) << "Succeeded in loading " << result->incoming_messages.size() | 201 DVLOG(1) << "Succeeded in loading " << result->registrations.size() |
| 202 << " registrations, " |
| 203 << result->incoming_messages.size() |
207 << " unacknowledged incoming messages and " | 204 << " unacknowledged incoming messages and " |
208 << result->outgoing_messages.size() | 205 << result->outgoing_messages.size() |
209 << " unacknowledged outgoing messages."; | 206 << " unacknowledged outgoing messages."; |
210 result->success = true; | 207 result->success = true; |
211 foreground_task_runner_->PostTask(FROM_HERE, | 208 foreground_task_runner_->PostTask(FROM_HERE, |
212 base::Bind(callback, | 209 base::Bind(callback, |
213 base::Passed(&result))); | 210 base::Passed(&result))); |
214 return; | 211 return; |
215 } | 212 } |
216 | 213 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
259 write_options, MakeSlice(kDeviceTokenKey), MakeSlice(encrypted_token)); | 256 write_options, MakeSlice(kDeviceTokenKey), MakeSlice(encrypted_token)); |
260 } | 257 } |
261 if (s.ok()) { | 258 if (s.ok()) { |
262 foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, true)); | 259 foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, true)); |
263 return; | 260 return; |
264 } | 261 } |
265 LOG(ERROR) << "LevelDB put failed: " << s.ToString(); | 262 LOG(ERROR) << "LevelDB put failed: " << s.ToString(); |
266 foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); | 263 foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); |
267 } | 264 } |
268 | 265 |
| 266 void GCMStoreImpl::Backend::AddRegistration( |
| 267 const std::string& app_id, |
| 268 const linked_ptr<RegistrationInfo>& registration, |
| 269 const UpdateCallback& callback) { |
| 270 DVLOG(1) << "Saving registration info for app: " << app_id; |
| 271 if (!db_.get()) { |
| 272 LOG(ERROR) << "GCMStore db doesn't exist."; |
| 273 foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); |
| 274 return; |
| 275 } |
| 276 leveldb::WriteOptions write_options; |
| 277 write_options.sync = true; |
| 278 |
| 279 std::string key = MakeRegistrationKey(app_id); |
| 280 std::string value = registration->SerializeAsString(); |
| 281 const leveldb::Status status = db_->Put(write_options, |
| 282 MakeSlice(key), |
| 283 MakeSlice(value)); |
| 284 if (status.ok()) { |
| 285 foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, true)); |
| 286 return; |
| 287 } |
| 288 LOG(ERROR) << "LevelDB put failed: " << status.ToString(); |
| 289 foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); |
| 290 } |
| 291 |
| 292 void GCMStoreImpl::Backend::RemoveRegistration(const std::string& app_id, |
| 293 const UpdateCallback& callback) { |
| 294 if (!db_.get()) { |
| 295 LOG(ERROR) << "GCMStore db doesn't exist."; |
| 296 foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); |
| 297 return; |
| 298 } |
| 299 leveldb::WriteOptions write_options; |
| 300 write_options.sync = true; |
| 301 |
| 302 leveldb::Status status = db_->Delete(write_options, MakeSlice(app_id)); |
| 303 if (status.ok()) { |
| 304 foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, true)); |
| 305 return; |
| 306 } |
| 307 LOG(ERROR) << "LevelDB remove failed: " << status.ToString(); |
| 308 foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); |
| 309 } |
| 310 |
269 void GCMStoreImpl::Backend::AddIncomingMessage(const std::string& persistent_id, | 311 void GCMStoreImpl::Backend::AddIncomingMessage(const std::string& persistent_id, |
270 const UpdateCallback& callback) { | 312 const UpdateCallback& callback) { |
271 DVLOG(1) << "Saving incoming message with id " << persistent_id; | 313 DVLOG(1) << "Saving incoming message with id " << persistent_id; |
272 if (!db_.get()) { | 314 if (!db_.get()) { |
273 LOG(ERROR) << "GCMStore db doesn't exist."; | 315 LOG(ERROR) << "GCMStore db doesn't exist."; |
274 foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); | 316 foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); |
275 return; | 317 return; |
276 } | 318 } |
277 | 319 |
278 leveldb::WriteOptions write_options; | 320 leveldb::WriteOptions write_options; |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
396 removed_message_counts)); | 438 removed_message_counts)); |
397 return; | 439 return; |
398 } | 440 } |
399 LOG(ERROR) << "LevelDB remove failed: " << s.ToString(); | 441 LOG(ERROR) << "LevelDB remove failed: " << s.ToString(); |
400 foreground_task_runner_->PostTask(FROM_HERE, | 442 foreground_task_runner_->PostTask(FROM_HERE, |
401 base::Bind(callback, | 443 base::Bind(callback, |
402 false, | 444 false, |
403 AppIdToMessageCountMap())); | 445 AppIdToMessageCountMap())); |
404 } | 446 } |
405 | 447 |
406 void GCMStoreImpl::Backend::AddUserSerialNumber( | |
407 const std::string& username, | |
408 int64 serial_number, | |
409 const UpdateCallback& callback) { | |
410 DVLOG(1) << "Saving username to serial number mapping for user: " << username; | |
411 if (!db_.get()) { | |
412 LOG(ERROR) << "GCMStore db doesn't exist."; | |
413 foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); | |
414 return; | |
415 } | |
416 leveldb::WriteOptions write_options; | |
417 write_options.sync = true; | |
418 | |
419 std::string key = MakeUserSerialNumberKey(username); | |
420 std::string serial_number_str = base::Int64ToString(serial_number); | |
421 const leveldb::Status status = | |
422 db_->Put(write_options, | |
423 MakeSlice(key), | |
424 MakeSlice(serial_number_str)); | |
425 if (status.ok()) { | |
426 foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, true)); | |
427 return; | |
428 } | |
429 LOG(ERROR) << "LevelDB put failed: " << status.ToString(); | |
430 foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); | |
431 } | |
432 | |
433 void GCMStoreImpl::Backend::RemoveUserSerialNumber( | |
434 const std::string& username, | |
435 const UpdateCallback& callback) { | |
436 if (!db_.get()) { | |
437 LOG(ERROR) << "GCMStore db doesn't exist."; | |
438 foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); | |
439 return; | |
440 } | |
441 leveldb::WriteOptions write_options; | |
442 write_options.sync = true; | |
443 | |
444 leveldb::Status status = db_->Delete(write_options, MakeSlice(username)); | |
445 if (status.ok()) { | |
446 foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, true)); | |
447 return; | |
448 } | |
449 LOG(ERROR) << "LevelDB remove failed: " << status.ToString(); | |
450 foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); | |
451 } | |
452 | |
453 void GCMStoreImpl::Backend::SetNextSerialNumber( | |
454 int64 next_serial_number, | |
455 const UpdateCallback& callback) { | |
456 DVLOG(1) << "Updating the value of next user serial number to: " | |
457 << next_serial_number; | |
458 if (!db_.get()) { | |
459 LOG(ERROR) << "GCMStore db doesn't exist."; | |
460 foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); | |
461 return; | |
462 } | |
463 leveldb::WriteOptions write_options; | |
464 write_options.sync = true; | |
465 | |
466 std::string serial_number_str = base::Int64ToString(next_serial_number); | |
467 const leveldb::Status status = | |
468 db_->Put(write_options, | |
469 MakeSlice(kNextSerialNumberKey), | |
470 MakeSlice(serial_number_str)); | |
471 if (status.ok()) { | |
472 foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, true)); | |
473 return; | |
474 } | |
475 LOG(ERROR) << "LevelDB put failed: " << status.ToString(); | |
476 foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); | |
477 } | |
478 | |
479 bool GCMStoreImpl::Backend::LoadDeviceCredentials(uint64* android_id, | 448 bool GCMStoreImpl::Backend::LoadDeviceCredentials(uint64* android_id, |
480 uint64* security_token) { | 449 uint64* security_token) { |
481 leveldb::ReadOptions read_options; | 450 leveldb::ReadOptions read_options; |
482 read_options.verify_checksums = true; | 451 read_options.verify_checksums = true; |
483 | 452 |
484 std::string result; | 453 std::string result; |
485 leveldb::Status s = db_->Get(read_options, MakeSlice(kDeviceAIDKey), &result); | 454 leveldb::Status s = db_->Get(read_options, MakeSlice(kDeviceAIDKey), &result); |
486 if (s.ok()) { | 455 if (s.ok()) { |
487 if (!base::StringToUint64(result, android_id)) { | 456 if (!base::StringToUint64(result, android_id)) { |
488 LOG(ERROR) << "Failed to restore device id."; | 457 LOG(ERROR) << "Failed to restore device id."; |
(...skipping 14 matching lines...) Expand all Loading... |
503 | 472 |
504 if (s.IsNotFound()) { | 473 if (s.IsNotFound()) { |
505 DVLOG(1) << "No credentials found."; | 474 DVLOG(1) << "No credentials found."; |
506 return true; | 475 return true; |
507 } | 476 } |
508 | 477 |
509 LOG(ERROR) << "Error reading credentials from store."; | 478 LOG(ERROR) << "Error reading credentials from store."; |
510 return false; | 479 return false; |
511 } | 480 } |
512 | 481 |
| 482 bool GCMStoreImpl::Backend::LoadRegistrations( |
| 483 RegistrationInfoMap* registrations) { |
| 484 leveldb::ReadOptions read_options; |
| 485 read_options.verify_checksums = true; |
| 486 |
| 487 scoped_ptr<leveldb::Iterator> iter(db_->NewIterator(read_options)); |
| 488 for (iter->Seek(MakeSlice(kRegistrationKeyStart)); |
| 489 iter->Valid() && iter->key().ToString() < kRegistrationKeyEnd; |
| 490 iter->Next()) { |
| 491 leveldb::Slice s = iter->value(); |
| 492 if (s.size() <= 1) { |
| 493 LOG(ERROR) << "Error reading registration with key " << s.ToString(); |
| 494 return false; |
| 495 } |
| 496 std::string app_id = ParseRegistrationKey(iter->key().ToString()); |
| 497 linked_ptr<RegistrationInfo> registration(new RegistrationInfo); |
| 498 if (!registration->ParseFromString(iter->value().ToString())) { |
| 499 LOG(ERROR) << "Failed to parse registration with app id " << app_id; |
| 500 return false; |
| 501 } |
| 502 DVLOG(1) << "Found registration with app id " << app_id; |
| 503 (*registrations)[app_id] = registration; |
| 504 } |
| 505 |
| 506 return true; |
| 507 } |
| 508 |
513 bool GCMStoreImpl::Backend::LoadIncomingMessages( | 509 bool GCMStoreImpl::Backend::LoadIncomingMessages( |
514 std::vector<std::string>* incoming_messages) { | 510 std::vector<std::string>* incoming_messages) { |
515 leveldb::ReadOptions read_options; | 511 leveldb::ReadOptions read_options; |
516 read_options.verify_checksums = true; | 512 read_options.verify_checksums = true; |
517 | 513 |
518 scoped_ptr<leveldb::Iterator> iter(db_->NewIterator(read_options)); | 514 scoped_ptr<leveldb::Iterator> iter(db_->NewIterator(read_options)); |
519 for (iter->Seek(MakeSlice(kIncomingMsgKeyStart)); | 515 for (iter->Seek(MakeSlice(kIncomingMsgKeyStart)); |
520 iter->Valid() && iter->key().ToString() < kIncomingMsgKeyEnd; | 516 iter->Valid() && iter->key().ToString() < kIncomingMsgKeyEnd; |
521 iter->Next()) { | 517 iter->Next()) { |
522 leveldb::Slice s = iter->value(); | 518 leveldb::Slice s = iter->value(); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
557 return false; | 553 return false; |
558 } | 554 } |
559 DVLOG(1) << "Found outgoing message with id " << id << " of type " | 555 DVLOG(1) << "Found outgoing message with id " << id << " of type " |
560 << base::IntToString(tag); | 556 << base::IntToString(tag); |
561 (*outgoing_messages)[id] = make_linked_ptr(message.release()); | 557 (*outgoing_messages)[id] = make_linked_ptr(message.release()); |
562 } | 558 } |
563 | 559 |
564 return true; | 560 return true; |
565 } | 561 } |
566 | 562 |
567 bool GCMStoreImpl::Backend::LoadNextSerialNumber(int64* next_serial_number) { | |
568 leveldb::ReadOptions read_options; | |
569 read_options.verify_checksums = true; | |
570 | |
571 std::string result; | |
572 leveldb::Status status = | |
573 db_->Get(read_options, MakeSlice(kNextSerialNumberKey), &result); | |
574 if (status.ok()) { | |
575 if (!base::StringToInt64(result, next_serial_number)) { | |
576 LOG(ERROR) << "Failed to restore the next serial number."; | |
577 return false; | |
578 } | |
579 return true; | |
580 } | |
581 | |
582 if (status.IsNotFound()) { | |
583 DVLOG(1) << "No next serial number found."; | |
584 return true; | |
585 } | |
586 | |
587 LOG(ERROR) << "Error when reading the next serial number."; | |
588 return false; | |
589 } | |
590 | |
591 bool GCMStoreImpl::Backend::LoadUserSerialNumberMap( | |
592 std::map<std::string, int64>* user_serial_number_map) { | |
593 leveldb::ReadOptions read_options; | |
594 read_options.verify_checksums = true; | |
595 | |
596 scoped_ptr<leveldb::Iterator> iter(db_->NewIterator(read_options)); | |
597 for (iter->Seek(MakeSlice(kUserSerialNumberKeyStart)); | |
598 iter->Valid() && iter->key().ToString() < kUserSerialNumberKeyEnd; | |
599 iter->Next()) { | |
600 std::string username = ParseUsername(iter->key().ToString()); | |
601 if (username.empty()) { | |
602 LOG(ERROR) << "Error reading username. It should not be empty."; | |
603 return false; | |
604 } | |
605 std::string serial_number_string = iter->value().ToString(); | |
606 int64 serial_number = kSerialNumberMissing; | |
607 if (!base::StringToInt64(serial_number_string, &serial_number)) { | |
608 LOG(ERROR) << "Error reading user serial number for user: " << username; | |
609 return false; | |
610 } | |
611 | |
612 (*user_serial_number_map)[username] = serial_number; | |
613 } | |
614 | |
615 return true; | |
616 } | |
617 | |
618 GCMStoreImpl::GCMStoreImpl( | 563 GCMStoreImpl::GCMStoreImpl( |
619 bool use_mock_keychain, | 564 bool use_mock_keychain, |
620 const base::FilePath& path, | 565 const base::FilePath& path, |
621 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner) | 566 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner) |
622 : backend_(new Backend(path, base::MessageLoopProxy::current())), | 567 : backend_(new Backend(path, base::MessageLoopProxy::current())), |
623 blocking_task_runner_(blocking_task_runner), | 568 blocking_task_runner_(blocking_task_runner), |
624 weak_ptr_factory_(this) { | 569 weak_ptr_factory_(this) { |
625 // On OSX, prevent the Keychain permissions popup during unit tests. | 570 // On OSX, prevent the Keychain permissions popup during unit tests. |
626 #if defined(OS_MACOSX) | 571 #if defined(OS_MACOSX) |
627 OSCrypt::UseMockKeychain(use_mock_keychain); | 572 OSCrypt::UseMockKeychain(use_mock_keychain); |
(...skipping 29 matching lines...) Expand all Loading... |
657 const UpdateCallback& callback) { | 602 const UpdateCallback& callback) { |
658 blocking_task_runner_->PostTask( | 603 blocking_task_runner_->PostTask( |
659 FROM_HERE, | 604 FROM_HERE, |
660 base::Bind(&GCMStoreImpl::Backend::SetDeviceCredentials, | 605 base::Bind(&GCMStoreImpl::Backend::SetDeviceCredentials, |
661 backend_, | 606 backend_, |
662 device_android_id, | 607 device_android_id, |
663 device_security_token, | 608 device_security_token, |
664 callback)); | 609 callback)); |
665 } | 610 } |
666 | 611 |
| 612 void GCMStoreImpl::AddRegistration( |
| 613 const std::string& app_id, |
| 614 const linked_ptr<RegistrationInfo>& registration, |
| 615 const UpdateCallback& callback) { |
| 616 blocking_task_runner_->PostTask( |
| 617 FROM_HERE, |
| 618 base::Bind(&GCMStoreImpl::Backend::AddRegistration, |
| 619 backend_, |
| 620 app_id, |
| 621 registration, |
| 622 callback)); |
| 623 } |
| 624 |
| 625 void GCMStoreImpl::RemoveRegistration(const std::string& app_id, |
| 626 const UpdateCallback& callback) { |
| 627 blocking_task_runner_->PostTask( |
| 628 FROM_HERE, |
| 629 base::Bind(&GCMStoreImpl::Backend::RemoveRegistration, |
| 630 backend_, |
| 631 app_id, |
| 632 callback)); |
| 633 } |
| 634 |
667 void GCMStoreImpl::AddIncomingMessage(const std::string& persistent_id, | 635 void GCMStoreImpl::AddIncomingMessage(const std::string& persistent_id, |
668 const UpdateCallback& callback) { | 636 const UpdateCallback& callback) { |
669 blocking_task_runner_->PostTask( | 637 blocking_task_runner_->PostTask( |
670 FROM_HERE, | 638 FROM_HERE, |
671 base::Bind(&GCMStoreImpl::Backend::AddIncomingMessage, | 639 base::Bind(&GCMStoreImpl::Backend::AddIncomingMessage, |
672 backend_, | 640 backend_, |
673 persistent_id, | 641 persistent_id, |
674 callback)); | 642 callback)); |
675 } | 643 } |
676 | 644 |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
759 blocking_task_runner_->PostTask( | 727 blocking_task_runner_->PostTask( |
760 FROM_HERE, | 728 FROM_HERE, |
761 base::Bind(&GCMStoreImpl::Backend::RemoveOutgoingMessages, | 729 base::Bind(&GCMStoreImpl::Backend::RemoveOutgoingMessages, |
762 backend_, | 730 backend_, |
763 persistent_ids, | 731 persistent_ids, |
764 base::Bind(&GCMStoreImpl::RemoveOutgoingMessagesContinuation, | 732 base::Bind(&GCMStoreImpl::RemoveOutgoingMessagesContinuation, |
765 weak_ptr_factory_.GetWeakPtr(), | 733 weak_ptr_factory_.GetWeakPtr(), |
766 callback))); | 734 callback))); |
767 } | 735 } |
768 | 736 |
769 void GCMStoreImpl::SetNextSerialNumber(int64 next_serial_number, | |
770 const UpdateCallback& callback) { | |
771 blocking_task_runner_->PostTask( | |
772 FROM_HERE, | |
773 base::Bind(&GCMStoreImpl::Backend::SetNextSerialNumber, | |
774 backend_, | |
775 next_serial_number, | |
776 callback)); | |
777 } | |
778 | |
779 void GCMStoreImpl::AddUserSerialNumber(const std::string& username, | |
780 int64 serial_number, | |
781 const UpdateCallback& callback) { | |
782 blocking_task_runner_->PostTask( | |
783 FROM_HERE, | |
784 base::Bind(&GCMStoreImpl::Backend::AddUserSerialNumber, | |
785 backend_, | |
786 username, | |
787 serial_number, | |
788 callback)); | |
789 } | |
790 | |
791 void GCMStoreImpl::RemoveUserSerialNumber(const std::string& username, | |
792 const UpdateCallback& callback) { | |
793 blocking_task_runner_->PostTask( | |
794 FROM_HERE, | |
795 base::Bind(&GCMStoreImpl::Backend::RemoveUserSerialNumber, | |
796 backend_, | |
797 username, | |
798 callback)); | |
799 } | |
800 | |
801 void GCMStoreImpl::LoadContinuation(const LoadCallback& callback, | 737 void GCMStoreImpl::LoadContinuation(const LoadCallback& callback, |
802 scoped_ptr<LoadResult> result) { | 738 scoped_ptr<LoadResult> result) { |
803 if (!result->success) { | 739 if (!result->success) { |
804 callback.Run(result.Pass()); | 740 callback.Run(result.Pass()); |
805 return; | 741 return; |
806 } | 742 } |
807 int num_throttled_apps = 0; | 743 int num_throttled_apps = 0; |
808 for (OutgoingMessageMap::const_iterator | 744 for (OutgoingMessageMap::const_iterator |
809 iter = result->outgoing_messages.begin(); | 745 iter = result->outgoing_messages.begin(); |
810 iter != result->outgoing_messages.end(); ++iter) { | 746 iter != result->outgoing_messages.end(); ++iter) { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
845 removed_message_counts.begin(); | 781 removed_message_counts.begin(); |
846 iter != removed_message_counts.end(); ++iter) { | 782 iter != removed_message_counts.end(); ++iter) { |
847 DCHECK_NE(app_message_counts_.count(iter->first), 0U); | 783 DCHECK_NE(app_message_counts_.count(iter->first), 0U); |
848 app_message_counts_[iter->first] -= iter->second; | 784 app_message_counts_[iter->first] -= iter->second; |
849 DCHECK_GE(app_message_counts_[iter->first], 0); | 785 DCHECK_GE(app_message_counts_[iter->first], 0); |
850 } | 786 } |
851 callback.Run(true); | 787 callback.Run(true); |
852 } | 788 } |
853 | 789 |
854 } // namespace gcm | 790 } // namespace gcm |
OLD | NEW |