OLD | NEW |
| (Empty) |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "google_apis/gcm/engine/rmq_store.h" | |
6 | |
7 #include "base/basictypes.h" | |
8 #include "base/bind.h" | |
9 #include "base/callback.h" | |
10 #include "base/files/file_path.h" | |
11 #include "base/logging.h" | |
12 #include "base/message_loop/message_loop_proxy.h" | |
13 #include "base/sequenced_task_runner.h" | |
14 #include "base/stl_util.h" | |
15 #include "base/strings/string_number_conversions.h" | |
16 #include "base/strings/string_piece.h" | |
17 #include "base/tracked_objects.h" | |
18 #include "components/webdata/encryptor/encryptor.h" | |
19 #include "google_apis/gcm/base/mcs_message.h" | |
20 #include "google_apis/gcm/base/mcs_util.h" | |
21 #include "google_apis/gcm/protocol/mcs.pb.h" | |
22 #include "third_party/leveldatabase/src/include/leveldb/db.h" | |
23 | |
24 namespace gcm { | |
25 | |
26 namespace { | |
27 | |
28 // ---- LevelDB keys. ---- | |
29 // Key for this device's android id. | |
30 const char kDeviceAIDKey[] = "device_aid_key"; | |
31 // Key for this device's android security token. | |
32 const char kDeviceTokenKey[] = "device_token_key"; | |
33 // Lowest lexicographically ordered incoming message key. | |
34 // Used for prefixing messages. | |
35 const char kIncomingMsgKeyStart[] = "incoming1-"; | |
36 // Key guaranteed to be higher than all incoming message keys. | |
37 // Used for limiting iteration. | |
38 const char kIncomingMsgKeyEnd[] = "incoming2-"; | |
39 // Key for next serial number assigned to the user. | |
40 const char kNextSerialNumberKey[] = "next_serial_number_key"; | |
41 // Lowest lexicographically ordered outgoing message key. | |
42 // Used for prefixing outgoing messages. | |
43 const char kOutgoingMsgKeyStart[] = "outgoing1-"; | |
44 // Key guaranteed to be higher than all outgoing message keys. | |
45 // Used for limiting iteration. | |
46 const char kOutgoingMsgKeyEnd[] = "outgoing2-"; | |
47 // Lowest lexicographically ordered username. | |
48 // Used for prefixing username to serial number mappings. | |
49 const char kUserSerialNumberKeyStart[] = "user1-"; | |
50 // Key guaranteed to be higher than all usernames. | |
51 // Used for limiting iteration. | |
52 const char kUserSerialNumberKeyEnd[] = "user2-"; | |
53 | |
54 // Value indicating that serial number was not assigned. | |
55 const int64 kSerialNumberMissing = -1LL; | |
56 | |
57 std::string MakeIncomingKey(const std::string& persistent_id) { | |
58 return kIncomingMsgKeyStart + persistent_id; | |
59 } | |
60 | |
61 std::string MakeOutgoingKey(const std::string& persistent_id) { | |
62 return kOutgoingMsgKeyStart + persistent_id; | |
63 } | |
64 | |
65 std::string MakeUserSerialNumberKey(const std::string& username) { | |
66 return kUserSerialNumberKeyStart + username; | |
67 } | |
68 | |
69 std::string ParseOutgoingKey(const std::string& key) { | |
70 return key.substr(arraysize(kOutgoingMsgKeyStart) - 1); | |
71 } | |
72 | |
73 std::string ParseUsername(const std::string& key) { | |
74 return key.substr(arraysize(kUserSerialNumberKeyStart) - 1); | |
75 } | |
76 | |
77 leveldb::Slice MakeSlice(const base::StringPiece& s) { | |
78 return leveldb::Slice(s.begin(), s.size()); | |
79 } | |
80 | |
81 } // namespace | |
82 | |
83 class RMQStore::Backend : public base::RefCountedThreadSafe<RMQStore::Backend> { | |
84 public: | |
85 Backend(const base::FilePath& path, | |
86 scoped_refptr<base::SequencedTaskRunner> foreground_runner); | |
87 | |
88 // Blocking implementations of RMQStore methods. | |
89 void Load(const LoadCallback& callback); | |
90 void Destroy(const UpdateCallback& callback); | |
91 void SetDeviceCredentials(uint64 device_android_id, | |
92 uint64 device_security_token, | |
93 const UpdateCallback& callback); | |
94 void AddIncomingMessage(const std::string& persistent_id, | |
95 const UpdateCallback& callback); | |
96 void RemoveIncomingMessages(const PersistentIdList& persistent_ids, | |
97 const UpdateCallback& callback); | |
98 void AddOutgoingMessage(const std::string& persistent_id, | |
99 const MCSMessage& message, | |
100 const UpdateCallback& callback); | |
101 void RemoveOutgoingMessages(const PersistentIdList& persistent_ids, | |
102 const UpdateCallback& callback); | |
103 void AddUserSerialNumber(const std::string& username, | |
104 int64 serial_number, | |
105 const UpdateCallback& callback); | |
106 void RemoveUserSerialNumber(const std::string& username, | |
107 const UpdateCallback& callback); | |
108 void SetNextSerialNumber(int64 serial_number, const UpdateCallback& callback); | |
109 | |
110 private: | |
111 friend class base::RefCountedThreadSafe<Backend>; | |
112 ~Backend(); | |
113 | |
114 bool LoadDeviceCredentials(uint64* android_id, uint64* security_token); | |
115 bool LoadIncomingMessages(std::vector<std::string>* incoming_messages); | |
116 bool LoadOutgoingMessages( | |
117 std::map<std::string, google::protobuf::MessageLite*>* outgoing_messages); | |
118 bool LoadNextSerialNumber(int64* next_serial_number); | |
119 bool LoadUserSerialNumberMap( | |
120 std::map<std::string, int64>* user_serial_number_map); | |
121 | |
122 const base::FilePath path_; | |
123 scoped_refptr<base::SequencedTaskRunner> foreground_task_runner_; | |
124 | |
125 scoped_ptr<leveldb::DB> db_; | |
126 }; | |
127 | |
128 RMQStore::Backend::Backend( | |
129 const base::FilePath& path, | |
130 scoped_refptr<base::SequencedTaskRunner> foreground_task_runner) | |
131 : path_(path), | |
132 foreground_task_runner_(foreground_task_runner) { | |
133 } | |
134 | |
135 RMQStore::Backend::~Backend() { | |
136 } | |
137 | |
138 void RMQStore::Backend::Load(const LoadCallback& callback) { | |
139 LoadResult result; | |
140 | |
141 leveldb::Options options; | |
142 options.create_if_missing = true; | |
143 leveldb::DB* db; | |
144 leveldb::Status status = leveldb::DB::Open(options, | |
145 path_.AsUTF8Unsafe(), | |
146 &db); | |
147 if (!status.ok()) { | |
148 LOG(ERROR) << "Failed to open database " << path_.value() | |
149 << ": " << status.ToString(); | |
150 foreground_task_runner_->PostTask(FROM_HERE, | |
151 base::Bind(callback, result)); | |
152 return; | |
153 } | |
154 db_.reset(db); | |
155 | |
156 if (!LoadDeviceCredentials(&result.device_android_id, | |
157 &result.device_security_token) || | |
158 !LoadIncomingMessages(&result.incoming_messages) || | |
159 !LoadOutgoingMessages(&result.outgoing_messages) || | |
160 !LoadNextSerialNumber(&result.next_serial_number) || | |
161 !LoadUserSerialNumberMap(&result.user_serial_numbers)) { | |
162 result.device_android_id = 0; | |
163 result.device_security_token = 0; | |
164 result.incoming_messages.clear(); | |
165 STLDeleteContainerPairSecondPointers(result.outgoing_messages.begin(), | |
166 result.outgoing_messages.end()); | |
167 result.outgoing_messages.clear(); | |
168 foreground_task_runner_->PostTask(FROM_HERE, | |
169 base::Bind(callback, result)); | |
170 return; | |
171 } | |
172 | |
173 DVLOG(1) << "Succeeded in loading " << result.incoming_messages.size() | |
174 << " unacknowledged incoming messages and " | |
175 << result.outgoing_messages.size() | |
176 << " unacknowledged outgoing messages."; | |
177 result.success = true; | |
178 foreground_task_runner_->PostTask(FROM_HERE, | |
179 base::Bind(callback, result)); | |
180 return; | |
181 } | |
182 | |
183 void RMQStore::Backend::Destroy(const UpdateCallback& callback) { | |
184 DVLOG(1) << "Destroying RMQ store."; | |
185 const leveldb::Status s = | |
186 leveldb::DestroyDB(path_.AsUTF8Unsafe(), | |
187 leveldb::Options()); | |
188 if (s.ok()) { | |
189 foreground_task_runner_->PostTask(FROM_HERE, | |
190 base::Bind(callback, true)); | |
191 return; | |
192 } | |
193 LOG(ERROR) << "Destroy failed."; | |
194 foreground_task_runner_->PostTask(FROM_HERE, | |
195 base::Bind(callback, false)); | |
196 } | |
197 | |
198 void RMQStore::Backend::SetDeviceCredentials(uint64 device_android_id, | |
199 uint64 device_security_token, | |
200 const UpdateCallback& callback) { | |
201 DVLOG(1) << "Saving device credentials with AID " << device_android_id; | |
202 leveldb::WriteOptions write_options; | |
203 write_options.sync = true; | |
204 | |
205 std::string encrypted_token; | |
206 Encryptor::EncryptString(base::Uint64ToString(device_security_token), | |
207 &encrypted_token); | |
208 leveldb::Status s = | |
209 db_->Put(write_options, | |
210 MakeSlice(kDeviceAIDKey), | |
211 MakeSlice(base::Uint64ToString(device_android_id))); | |
212 if (s.ok()) { | |
213 s = db_->Put(write_options, | |
214 MakeSlice(kDeviceTokenKey), | |
215 MakeSlice(encrypted_token)); | |
216 } | |
217 if (s.ok()) { | |
218 foreground_task_runner_->PostTask(FROM_HERE, | |
219 base::Bind(callback, true)); | |
220 return; | |
221 } | |
222 LOG(ERROR) << "LevelDB put failed: " << s.ToString(); | |
223 foreground_task_runner_->PostTask(FROM_HERE, | |
224 base::Bind(callback, false)); | |
225 } | |
226 | |
227 void RMQStore::Backend::AddIncomingMessage(const std::string& persistent_id, | |
228 const UpdateCallback& callback) { | |
229 DVLOG(1) << "Saving incoming message with id " << persistent_id; | |
230 leveldb::WriteOptions write_options; | |
231 write_options.sync = true; | |
232 | |
233 const leveldb::Status s = | |
234 db_->Put(write_options, | |
235 MakeSlice(MakeIncomingKey(persistent_id)), | |
236 MakeSlice(persistent_id)); | |
237 if (s.ok()) { | |
238 foreground_task_runner_->PostTask(FROM_HERE, | |
239 base::Bind(callback, true)); | |
240 return; | |
241 } | |
242 LOG(ERROR) << "LevelDB put failed: " << s.ToString(); | |
243 foreground_task_runner_->PostTask(FROM_HERE, | |
244 base::Bind(callback, false)); | |
245 } | |
246 | |
247 void RMQStore::Backend::RemoveIncomingMessages( | |
248 const PersistentIdList& persistent_ids, | |
249 const UpdateCallback& callback) { | |
250 leveldb::WriteOptions write_options; | |
251 write_options.sync = true; | |
252 | |
253 leveldb::Status s; | |
254 for (PersistentIdList::const_iterator iter = persistent_ids.begin(); | |
255 iter != persistent_ids.end(); ++iter){ | |
256 DVLOG(1) << "Removing incoming message with id " << *iter; | |
257 s = db_->Delete(write_options, | |
258 MakeSlice(MakeIncomingKey(*iter))); | |
259 if (!s.ok()) | |
260 break; | |
261 } | |
262 if (s.ok()) { | |
263 foreground_task_runner_->PostTask(FROM_HERE, | |
264 base::Bind(callback, true)); | |
265 return; | |
266 } | |
267 LOG(ERROR) << "LevelDB remove failed: " << s.ToString(); | |
268 foreground_task_runner_->PostTask(FROM_HERE, | |
269 base::Bind(callback, false)); | |
270 } | |
271 | |
272 void RMQStore::Backend::AddOutgoingMessage( | |
273 const std::string& persistent_id, | |
274 const MCSMessage& message, | |
275 const UpdateCallback& callback) { | |
276 DVLOG(1) << "Saving outgoing message with id " << persistent_id; | |
277 leveldb::WriteOptions write_options; | |
278 write_options.sync = true; | |
279 | |
280 std::string data = static_cast<char>(message.tag()) + | |
281 message.SerializeAsString(); | |
282 const leveldb::Status s = | |
283 db_->Put(write_options, | |
284 MakeSlice(MakeOutgoingKey(persistent_id)), | |
285 MakeSlice(data)); | |
286 if (s.ok()) { | |
287 foreground_task_runner_->PostTask(FROM_HERE, | |
288 base::Bind(callback, true)); | |
289 return; | |
290 } | |
291 LOG(ERROR) << "LevelDB put failed: " << s.ToString(); | |
292 foreground_task_runner_->PostTask(FROM_HERE, | |
293 base::Bind(callback, false)); | |
294 | |
295 } | |
296 | |
297 void RMQStore::Backend::RemoveOutgoingMessages( | |
298 const PersistentIdList& persistent_ids, | |
299 const UpdateCallback& callback) { | |
300 leveldb::WriteOptions write_options; | |
301 write_options.sync = true; | |
302 | |
303 leveldb::Status s; | |
304 for (PersistentIdList::const_iterator iter = persistent_ids.begin(); | |
305 iter != persistent_ids.end(); ++iter){ | |
306 DVLOG(1) << "Removing outgoing message with id " << *iter; | |
307 s = db_->Delete(write_options, | |
308 MakeSlice(MakeOutgoingKey(*iter))); | |
309 if (!s.ok()) | |
310 break; | |
311 } | |
312 if (s.ok()) { | |
313 foreground_task_runner_->PostTask(FROM_HERE, | |
314 base::Bind(callback, true)); | |
315 return; | |
316 } | |
317 LOG(ERROR) << "LevelDB remove failed: " << s.ToString(); | |
318 foreground_task_runner_->PostTask(FROM_HERE, | |
319 base::Bind(callback, false)); | |
320 } | |
321 | |
322 void RMQStore::Backend::AddUserSerialNumber(const std::string& username, | |
323 int64 serial_number, | |
324 const UpdateCallback& callback) { | |
325 DVLOG(1) << "Saving username to serial number mapping for user: " << username; | |
326 leveldb::WriteOptions write_options; | |
327 write_options.sync = true; | |
328 | |
329 const leveldb::Status status = | |
330 db_->Put(write_options, | |
331 MakeSlice(MakeUserSerialNumberKey(username)), | |
332 MakeSlice(base::Int64ToString(serial_number))); | |
333 if (status.ok()) { | |
334 foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, true)); | |
335 return; | |
336 } | |
337 LOG(ERROR) << "LevelDB put failed: " << status.ToString(); | |
338 foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); | |
339 } | |
340 | |
341 void RMQStore::Backend::RemoveUserSerialNumber(const std::string& username, | |
342 const UpdateCallback& callback) { | |
343 leveldb::WriteOptions write_options; | |
344 write_options.sync = true; | |
345 | |
346 leveldb::Status status = db_->Delete(write_options, MakeSlice(username)); | |
347 if (status.ok()) { | |
348 foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, true)); | |
349 return; | |
350 } | |
351 LOG(ERROR) << "LevelDB remove failed: " << status.ToString(); | |
352 foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); | |
353 } | |
354 | |
355 void RMQStore::Backend::SetNextSerialNumber(int64 next_serial_number, | |
356 const UpdateCallback& callback) { | |
357 DVLOG(1) << "Updating the value of next user serial number to: " | |
358 << next_serial_number; | |
359 leveldb::WriteOptions write_options; | |
360 write_options.sync = true; | |
361 | |
362 const leveldb::Status status = | |
363 db_->Put(write_options, | |
364 MakeSlice(kNextSerialNumberKey), | |
365 MakeSlice(base::Int64ToString(next_serial_number))); | |
366 if (status.ok()) { | |
367 foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, true)); | |
368 return; | |
369 } | |
370 LOG(ERROR) << "LevelDB put failed: " << status.ToString(); | |
371 foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); | |
372 } | |
373 | |
374 bool RMQStore::Backend::LoadDeviceCredentials(uint64* android_id, | |
375 uint64* security_token) { | |
376 leveldb::ReadOptions read_options; | |
377 read_options.verify_checksums = true; | |
378 | |
379 std::string result; | |
380 leveldb::Status s = db_->Get(read_options, | |
381 MakeSlice(kDeviceAIDKey), | |
382 &result); | |
383 if (s.ok()) { | |
384 if (!base::StringToUint64(result, android_id)) { | |
385 LOG(ERROR) << "Failed to restore device id."; | |
386 return false; | |
387 } | |
388 result.clear(); | |
389 s = db_->Get(read_options, | |
390 MakeSlice(kDeviceTokenKey), | |
391 &result); | |
392 } | |
393 if (s.ok()) { | |
394 std::string decrypted_token; | |
395 Encryptor::DecryptString(result, &decrypted_token); | |
396 if (!base::StringToUint64(decrypted_token, security_token)) { | |
397 LOG(ERROR) << "Failed to restore security token."; | |
398 return false; | |
399 } | |
400 return true; | |
401 } | |
402 | |
403 if (s.IsNotFound()) { | |
404 DVLOG(1) << "No credentials found."; | |
405 return true; | |
406 } | |
407 | |
408 LOG(ERROR) << "Error reading credentials from store."; | |
409 return false; | |
410 } | |
411 | |
412 bool RMQStore::Backend::LoadIncomingMessages( | |
413 std::vector<std::string>* incoming_messages) { | |
414 leveldb::ReadOptions read_options; | |
415 read_options.verify_checksums = true; | |
416 | |
417 scoped_ptr<leveldb::Iterator> iter(db_->NewIterator(read_options)); | |
418 for (iter->Seek(MakeSlice(kIncomingMsgKeyStart)); | |
419 iter->Valid() && iter->key().ToString() < kIncomingMsgKeyEnd; | |
420 iter->Next()) { | |
421 leveldb::Slice s = iter->value(); | |
422 if (s.empty()) { | |
423 LOG(ERROR) << "Error reading incoming message with key " | |
424 << iter->key().ToString(); | |
425 return false; | |
426 } | |
427 DVLOG(1) << "Found incoming message with id " << s.ToString(); | |
428 incoming_messages->push_back(s.ToString()); | |
429 } | |
430 | |
431 return true; | |
432 } | |
433 | |
434 bool RMQStore::Backend::LoadOutgoingMessages( | |
435 std::map<std::string, google::protobuf::MessageLite*>* | |
436 outgoing_messages) { | |
437 leveldb::ReadOptions read_options; | |
438 read_options.verify_checksums = true; | |
439 | |
440 scoped_ptr<leveldb::Iterator> iter(db_->NewIterator(read_options)); | |
441 for (iter->Seek(MakeSlice(kOutgoingMsgKeyStart)); | |
442 iter->Valid() && iter->key().ToString() < kOutgoingMsgKeyEnd; | |
443 iter->Next()) { | |
444 leveldb::Slice s = iter->value(); | |
445 if (s.size() <= 1) { | |
446 LOG(ERROR) << "Error reading incoming message with key " << s.ToString(); | |
447 return false; | |
448 } | |
449 uint8 tag = iter->value().data()[0]; | |
450 std::string id = ParseOutgoingKey(iter->key().ToString()); | |
451 scoped_ptr<google::protobuf::MessageLite> message( | |
452 BuildProtobufFromTag(tag)); | |
453 if (!message.get() || | |
454 !message->ParseFromString(iter->value().ToString().substr(1))) { | |
455 LOG(ERROR) << "Failed to parse outgoing message with id " | |
456 << id << " and tag " << tag; | |
457 return false; | |
458 } | |
459 DVLOG(1) << "Found outgoing message with id " << id << " of type " | |
460 << base::IntToString(tag); | |
461 (*outgoing_messages)[id] = message.release(); | |
462 } | |
463 | |
464 return true; | |
465 } | |
466 | |
467 bool RMQStore::Backend::LoadNextSerialNumber(int64* next_serial_number) { | |
468 leveldb::ReadOptions read_options; | |
469 read_options.verify_checksums = true; | |
470 | |
471 std::string result; | |
472 leveldb::Status status = db_->Get(read_options, | |
473 MakeSlice(kNextSerialNumberKey), | |
474 &result); | |
475 if (status.ok()) { | |
476 if (!base::StringToInt64(result, next_serial_number)) { | |
477 LOG(ERROR) << "Failed to restore the next serial number."; | |
478 return false; | |
479 } | |
480 return true; | |
481 } | |
482 | |
483 if (status.IsNotFound()) { | |
484 DVLOG(1) << "No next serial number found."; | |
485 return true; | |
486 } | |
487 | |
488 LOG(ERROR) << "Error when reading the next serial number."; | |
489 return false; | |
490 } | |
491 | |
492 bool RMQStore::Backend::LoadUserSerialNumberMap( | |
493 std::map<std::string, int64>* user_serial_number_map) { | |
494 leveldb::ReadOptions read_options; | |
495 read_options.verify_checksums = true; | |
496 | |
497 scoped_ptr<leveldb::Iterator> iter(db_->NewIterator(read_options)); | |
498 for (iter->Seek(MakeSlice(kUserSerialNumberKeyStart)); | |
499 iter->Valid() && iter->key().ToString() < kUserSerialNumberKeyEnd; | |
500 iter->Next()) { | |
501 std::string username = ParseUsername(iter->key().ToString()); | |
502 if (username.empty()) { | |
503 LOG(ERROR) << "Error reading username. It should not be empty."; | |
504 return false; | |
505 } | |
506 std::string serial_number_string = iter->value().ToString(); | |
507 int64 serial_number = kSerialNumberMissing; | |
508 if (!base::StringToInt64(serial_number_string, &serial_number)) { | |
509 LOG(ERROR) << "Error reading user serial number for user: " << username; | |
510 return false; | |
511 } | |
512 | |
513 (*user_serial_number_map)[username] = serial_number; | |
514 } | |
515 | |
516 return true; | |
517 } | |
518 | |
519 RMQStore::LoadResult::LoadResult() | |
520 : success(false), | |
521 device_android_id(0), | |
522 device_security_token(0), | |
523 next_serial_number(1LL) { | |
524 } | |
525 RMQStore::LoadResult::~LoadResult() {} | |
526 | |
527 RMQStore::RMQStore( | |
528 const base::FilePath& path, | |
529 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner) | |
530 : backend_(new Backend(path, base::MessageLoopProxy::current())), | |
531 blocking_task_runner_(blocking_task_runner) { | |
532 } | |
533 | |
534 RMQStore::~RMQStore() { | |
535 } | |
536 | |
537 void RMQStore::Load(const LoadCallback& callback) { | |
538 blocking_task_runner_->PostTask(FROM_HERE, | |
539 base::Bind(&RMQStore::Backend::Load, | |
540 backend_, | |
541 callback)); | |
542 } | |
543 | |
544 void RMQStore::Destroy(const UpdateCallback& callback) { | |
545 blocking_task_runner_->PostTask( | |
546 FROM_HERE, | |
547 base::Bind(&RMQStore::Backend::Destroy, | |
548 backend_, | |
549 callback)); | |
550 } | |
551 | |
552 void RMQStore::SetDeviceCredentials(uint64 device_android_id, | |
553 uint64 device_security_token, | |
554 const UpdateCallback& callback) { | |
555 blocking_task_runner_->PostTask( | |
556 FROM_HERE, | |
557 base::Bind(&RMQStore::Backend::SetDeviceCredentials, | |
558 backend_, | |
559 device_android_id, | |
560 device_security_token, | |
561 callback)); | |
562 } | |
563 | |
564 void RMQStore::AddIncomingMessage(const std::string& persistent_id, | |
565 const UpdateCallback& callback) { | |
566 blocking_task_runner_->PostTask( | |
567 FROM_HERE, | |
568 base::Bind(&RMQStore::Backend::AddIncomingMessage, | |
569 backend_, | |
570 persistent_id, | |
571 callback)); | |
572 } | |
573 | |
574 void RMQStore::RemoveIncomingMessage(const std::string& persistent_id, | |
575 const UpdateCallback& callback) { | |
576 blocking_task_runner_->PostTask( | |
577 FROM_HERE, | |
578 base::Bind(&RMQStore::Backend::RemoveIncomingMessages, | |
579 backend_, | |
580 PersistentIdList(1, persistent_id), | |
581 callback)); | |
582 } | |
583 | |
584 void RMQStore::RemoveIncomingMessages(const PersistentIdList& persistent_ids, | |
585 const UpdateCallback& callback) { | |
586 blocking_task_runner_->PostTask( | |
587 FROM_HERE, | |
588 base::Bind(&RMQStore::Backend::RemoveIncomingMessages, | |
589 backend_, | |
590 persistent_ids, | |
591 callback)); | |
592 } | |
593 | |
594 void RMQStore::AddOutgoingMessage(const std::string& persistent_id, | |
595 const MCSMessage& message, | |
596 const UpdateCallback& callback) { | |
597 blocking_task_runner_->PostTask( | |
598 FROM_HERE, | |
599 base::Bind(&RMQStore::Backend::AddOutgoingMessage, | |
600 backend_, | |
601 persistent_id, | |
602 message, | |
603 callback)); | |
604 } | |
605 | |
606 void RMQStore::RemoveOutgoingMessage(const std::string& persistent_id, | |
607 const UpdateCallback& callback) { | |
608 blocking_task_runner_->PostTask( | |
609 FROM_HERE, | |
610 base::Bind(&RMQStore::Backend::RemoveOutgoingMessages, | |
611 backend_, | |
612 PersistentIdList(1, persistent_id), | |
613 callback)); | |
614 } | |
615 | |
616 void RMQStore::RemoveOutgoingMessages(const PersistentIdList& persistent_ids, | |
617 const UpdateCallback& callback) { | |
618 blocking_task_runner_->PostTask( | |
619 FROM_HERE, | |
620 base::Bind(&RMQStore::Backend::RemoveOutgoingMessages, | |
621 backend_, | |
622 persistent_ids, | |
623 callback)); | |
624 } | |
625 | |
626 void RMQStore::SetNextSerialNumber(int64 next_serial_number, | |
627 const UpdateCallback& callback) { | |
628 blocking_task_runner_->PostTask( | |
629 FROM_HERE, | |
630 base::Bind(&RMQStore::Backend::SetNextSerialNumber, | |
631 backend_, | |
632 next_serial_number, | |
633 callback)); | |
634 } | |
635 | |
636 void RMQStore::AddUserSerialNumber(const std::string& username, | |
637 int64 serial_number, | |
638 const UpdateCallback& callback) { | |
639 blocking_task_runner_->PostTask( | |
640 FROM_HERE, | |
641 base::Bind(&RMQStore::Backend::AddUserSerialNumber, | |
642 backend_, | |
643 username, | |
644 serial_number, | |
645 callback)); | |
646 } | |
647 | |
648 void RMQStore::RemoveUserSerialNumber(const std::string& username, | |
649 const UpdateCallback& callback) { | |
650 blocking_task_runner_->PostTask( | |
651 FROM_HERE, | |
652 base::Bind(&RMQStore::Backend::RemoveUserSerialNumber, | |
653 backend_, | |
654 username, | |
655 callback)); | |
656 } | |
657 | |
658 } // namespace gcm | |
OLD | NEW |