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..5bdde6e8d63b3f05e1660d182b5a232e92cc955f |
--- /dev/null |
+++ b/google_apis/gcm/engine/user_list.cc |
@@ -0,0 +1,156 @@ |
+// 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_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 { |
+const int64 kSerialNumberMissing = -1; |
+} // namespace |
+ |
+namespace gcm { |
+ |
+UserList::UserDelegate::UserDelegate(const std::string& username, |
+ GCMClient::Delegate* delegate) |
+ : username(username), |
+ serial_number(kSerialNumberMissing), |
+ delegate(delegate) {} |
+ |
+UserList::UserDelegate::UserDelegate(const std::string& username, |
+ int64 serial_number) |
+ : username(username), serial_number(serial_number), delegate(NULL) {} |
jianli
2014/01/13 19:19:55
nit: try not to put everything in one line such th
fgorski
2014/01/14 22:25:42
Done. However "git cl format" reverts that change.
|
+ |
+UserList::UserDelegate::~UserDelegate() {} |
jianli
2014/01/13 19:19:55
nit: try not to put {} in one line such that we ca
fgorski
2014/01/14 22:25:42
Done. Again "git cl format" does that, not me.
|
+ |
+UserList::UserList(GCMStore* gcm_store) : gcm_store_(gcm_store) {} |
Nicolas Zea
2014/01/13 19:26:06
initialize next_serial_number_ to 0 (or possibly -
fgorski
2014/01/14 22:25:42
Done.
|
+ |
+UserList::~UserList() {} |
+ |
+void UserList::Initialize(const GCMStore::LoadResult& result) { |
+ if (result.success) { |
jianli
2014/01/13 19:19:55
nit: It would be better to return upon error first
fgorski
2014/01/14 22:25:42
Removed the checked as we no longer have access to
|
+ 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); |
+ } |
+ } else { |
+ LOG(ERROR) << "Loading of GCM User List completed with error."; |
+ } |
+} |
+ |
+void UserList::AddDelegate(const std::string& username, |
+ GCMClient::Delegate* delegate) { |
+ DCHECK(!username.empty()); |
+ DCHECK(delegate); |
+ |
+ DelegateList::iterator iter = GetByUsernameForUpdate(username); |
+ if (iter == delegates_.end()) |
jianli
2014/01/13 19:19:55
nit: if you add brackets for one part, you'd bette
fgorski
2014/01/14 22:25:42
Done.
|
+ delegates_.insert(iter, UserDelegate(username, delegate)); |
+ else { |
+ DCHECK(!iter->delegate); |
+ iter->delegate = delegate; |
+ } |
+} |
+ |
+void UserList::AddSerialNumber(const std::string& username, |
+ int64 serial_number, |
+ const GCMStore::UpdateCallback& callback) { |
+ SetSerialNumber(username, serial_number); |
+ gcm_store_->AddUserSerialNumber(username, serial_number, callback); |
+} |
+ |
+GCMClient::Delegate* UserList::GetDelegateBySerialNumber(int64 serial_number) |
+ const { |
+ for (DelegateList::const_iterator iter = delegates_.begin(); |
+ iter != delegates_.end(); |
+ ++iter) { |
+ if (iter->serial_number == serial_number) |
+ return iter->delegate; |
+ } |
+ return NULL; |
+} |
+ |
+GCMClient::Delegate* UserList::GetDelegateByUsername( |
+ const std::string& username) const { |
+ DelegateList::const_iterator iter = GetByUsername(username); |
+ if (iter != delegates_.end()) |
+ return iter->delegate; |
+ return NULL; |
+} |
+ |
+bool UserList::GetSerialNumberForUsername(const std::string& username, |
+ int64* serial_number) const { |
+ DelegateList::const_iterator iter = GetByUsername(username); |
+ if (iter == delegates_.end() || iter->serial_number == kSerialNumberMissing) |
+ return false; |
+ *serial_number = iter->serial_number; |
+ return true; |
+} |
+ |
+int64 UserList::GetNextSerialNumber() { |
+ int64 serial_number = next_serial_number_++; |
+ gcm_store_->SetNextSerialNumber( |
+ serial_number, |
+ base::Bind(&UserList::NextSerialNumberUpdateCompleted, |
+ base::Unretained(this))); |
+ return serial_number; |
+} |
+ |
+UserList::DelegateList::const_iterator UserList::GetByUsername( |
+ const std::string& username) const { |
+ for (DelegateList::const_iterator iter = delegates_.begin(); |
+ iter != delegates_.end(); |
+ ++iter) { |
+ if (iter->username == username) |
+ return iter; |
+ } |
+ return delegates_.end(); |
+} |
+ |
+UserList::DelegateList::iterator UserList::GetByUsernameForUpdate( |
+ const std::string& username) { |
+ for (DelegateList::iterator iter = delegates_.begin(); |
+ iter != delegates_.end(); |
+ ++iter) { |
+ if (iter->username == username) |
+ return iter; |
+ } |
+ return delegates_.end(); |
+} |
+ |
+void UserList::NextSerialNumberUpdateCompleted(bool success) { |
+ // TODO(fgorski) We could retry the update if it is unsuccessful. |
+ // I should change the callback to a method that gives a pair: success, and |
+ // assigned serial_number, that way the registration can ensure not to have |
+ // collisions. Fetcher is expected to be slower anyway. |
+ DCHECK(success) << "Updating the next serial number failed."; |
+} |
+ |
+void UserList::SetSerialNumber(const std::string& username, |
+ int64 serial_number) { |
+ DCHECK(!username.empty()); |
+ DCHECK_GT(serial_number, 0L); |
+ |
+ DelegateList::iterator iter = GetByUsernameForUpdate(username); |
+ if (iter == delegates_.end()) { |
+ delegates_.insert(iter, UserDelegate(username, serial_number)); |
+ } else { |
+ DCHECK_EQ(iter->serial_number, kSerialNumberMissing); |
+ iter->serial_number = serial_number; |
+ } |
+} |
+ |
+} // namespace gcm |