Chromium Code Reviews| 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 |