Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(50)

Side by Side Diff: google_apis/gcm/engine/rmq_store.cc

Issue 121743002: Renaming RMQStore to GCMStore and breaking out its interface (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Adding a GCM_EXPORT directive to GCMStoreImpl Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « google_apis/gcm/engine/rmq_store.h ('k') | google_apis/gcm/engine/rmq_store_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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
OLDNEW
« no previous file with comments | « google_apis/gcm/engine/rmq_store.h ('k') | google_apis/gcm/engine/rmq_store_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698