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

Unified Diff: google_apis/gcm/engine/user_list.cc

Issue 135303002: Adding a user list (to be consumed by GCM Client Implementation) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixing Win64 compilation issue and adding comments to test 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « google_apis/gcm/engine/user_list.h ('k') | google_apis/gcm/engine/user_list_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: google_apis/gcm/engine/user_list.cc
diff --git a/google_apis/gcm/engine/user_list.cc b/google_apis/gcm/engine/user_list.cc
new file mode 100644
index 0000000000000000000000000000000000000000..829c66f34291fb5ef4d8dbb0ef5e2d7a076eea16
--- /dev/null
+++ b/google_apis/gcm/engine/user_list.cc
@@ -0,0 +1,197 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "google_apis/gcm/engine/user_list.h"
+
+#include "base/bind.h"
+#include "base/files/file_path.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/message_loop/message_loop.h"
+#include "base/message_loop/message_loop_proxy.h"
+#include "base/sequenced_task_runner.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_piece.h"
+#include "third_party/leveldatabase/src/include/leveldb/db.h"
+
+namespace gcm {
+const int64 kInvalidSerialNumber = -1;
+
+UserList::UserInfo::UserInfo()
+ : serial_number(kInvalidSerialNumber),
+ delegate(NULL) {
+}
+
+UserList::UserInfo::UserInfo(int64 serial_number)
+ : serial_number(serial_number),
+ delegate(NULL) {
+}
+
+UserList::UserInfo::UserInfo(GCMClient::Delegate* delegate,
+ const SetDelegateCallback& callback)
+ : serial_number(kInvalidSerialNumber),
+ delegate(delegate),
+ callback(callback) {
+}
+
+UserList::UserInfo::~UserInfo() {
+}
+
+UserList::UserList(GCMStore* gcm_store)
+ : initialized_(false),
+ next_serial_number_(kInvalidSerialNumber),
+ gcm_store_(gcm_store) {
+}
+
+UserList::~UserList() {
+}
+
+void UserList::Initialize(const GCMStore::SerialNumberMappings& result) {
+ DCHECK(!initialized_);
+ DCHECK_GT(result.next_serial_number, 0);
+
+ initialized_ = true;
+ next_serial_number_ = result.next_serial_number;
+ for (std::map<std::string, int64>::const_iterator iter =
+ result.user_serial_numbers.begin();
+ iter != result.user_serial_numbers.end();
+ ++iter) {
+ SetSerialNumber(iter->first, iter->second);
+ }
+
+ for (UserInfoMap::iterator iter = delegates_.begin();
+ iter != delegates_.end();
+ ++iter) {
+ // Process only users with delegate and callback present.
+ if (iter->second.delegate && !iter->second.callback.is_null()) {
+ if (iter->second.serial_number == kInvalidSerialNumber)
+ AssignSerialNumber(iter->first);
+ else
+ OnSerialNumberReady(iter);
+ }
+ }
+}
+
+void UserList::SetDelegate(const std::string& username,
+ GCMClient::Delegate* delegate,
+ const SetDelegateCallback& callback) {
+ DCHECK(!username.empty());
+ DCHECK(delegate);
+
+ UserInfoMap::iterator iter = delegates_.find(username);
+ if (iter != delegates_.end()) {
+ DCHECK(initialized_);
+ DCHECK(!iter->second.delegate);
+ iter->second.delegate = delegate;
+ iter->second.callback = callback;
+ } else {
+ delegates_.insert(
+ iter,
+ UserInfoMap::value_type(username, UserInfo(delegate, callback)));
+ }
+
+ if (initialized_) {
+ UserInfoMap::iterator iter = delegates_.find(username);
+ if (iter->second.serial_number == kInvalidSerialNumber)
+ AssignSerialNumber(iter->first);
+ else
+ OnSerialNumberReady(iter);
+ }
+}
+
+void UserList::AssignSerialNumber(const std::string& username) {
+ DCHECK(initialized_);
+ DCHECK_EQ(delegates_.count(username), 1UL);
+ DCHECK_EQ(delegates_[username].serial_number, kInvalidSerialNumber);
+
+ // Start by incrementing the |next_serial_number_| and persist it in the GCM
+ // store.
+ int64 serial_number = next_serial_number_++;
+ gcm_store_->SetNextSerialNumber(
+ serial_number,
+ base::Bind(&UserList::IncrementSerialNumberCompleted,
+ base::Unretained(this),
+ username,
+ serial_number));
+}
+
+void UserList::IncrementSerialNumberCompleted(const std::string& username,
+ int64 user_serial_number,
+ bool success) {
+ // TODO(fgorski): Introduce retry logic.
+ if (!success)
+ DCHECK(success) << "Updating the next serial number failed.";
+
+ SetSerialNumber(username, user_serial_number);
+ gcm_store_->AddUserSerialNumber(
+ username,
+ user_serial_number,
+ base::Bind(&UserList::AssignSerialNumberCompleted,
+ base::Unretained(this),
+ username));
+}
+
+void UserList::AssignSerialNumberCompleted(const std::string& username,
+ bool success) {
+ // TODO(fgorski): Introduce retry logic.
+ if (!success) {
+ DVLOG(1) << "It was not possible to persist username to serial number"
+ << " mapping for username: " << username;
+ return;
+ }
+
+ UserInfoMap::iterator iter = delegates_.find(username);
+ DCHECK(iter != delegates_.end());
+ OnSerialNumberReady(iter);
+}
+
+void UserList::OnSerialNumberReady(const UserInfoMap::iterator& iter) {
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE,
+ base::Bind(iter->second.callback,
+ iter->first,
+ iter->second.serial_number));
+ iter->second.callback.Reset();
+}
+
+void UserList::SetSerialNumber(const std::string& username,
+ int64 serial_number) {
+ DCHECK(!username.empty());
+ DCHECK_GT(serial_number, 0L);
+
+ UserInfoMap::iterator iter = delegates_.find(username);
+ if (iter != delegates_.end()) {
+ DCHECK_EQ(iter->second.serial_number, kInvalidSerialNumber);
+ iter->second.serial_number = serial_number;
+ } else {
+ delegates_.insert(
+ iter, UserInfoMap::value_type(username, UserInfo(serial_number)));
+ }
+}
+
+GCMClient::Delegate* UserList::GetDelegateBySerialNumber(int64 serial_number)
+ const {
+ for (UserInfoMap::const_iterator iter = delegates_.begin();
+ iter != delegates_.end();
+ ++iter) {
+ if (iter->second.serial_number == serial_number)
+ return iter->second.delegate;
+ }
+ return NULL;
+}
+
+GCMClient::Delegate* UserList::GetDelegateByUsername(
+ const std::string& username) const {
+ UserInfoMap::const_iterator iter = delegates_.find(username);
+ return iter != delegates_.end() ? iter->second.delegate : NULL;
+}
+
+int64 UserList::GetSerialNumberForUsername(const std::string& username) const {
+ UserInfoMap::const_iterator iter = delegates_.find(username);
+ return iter != delegates_.end() ? iter->second.serial_number
+ : kInvalidSerialNumber;
+}
+
+} // namespace gcm
« no previous file with comments | « google_apis/gcm/engine/user_list.h ('k') | google_apis/gcm/engine/user_list_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698