Update ASan/Android runtime and setup script to LLVM r200682.
[chromium-blink-merge.git] / google_apis / gcm / engine / user_list.cc
blobf2d57dc10c5b677e39ca9ad1fcb1deda945abdc0
1 // Copyright 2014 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.
5 #include "google_apis/gcm/engine/user_list.h"
7 #include "base/bind.h"
8 #include "base/files/file_path.h"
9 #include "base/location.h"
10 #include "base/logging.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/message_loop/message_loop_proxy.h"
14 #include "base/sequenced_task_runner.h"
15 #include "base/strings/string_number_conversions.h"
16 #include "base/strings/string_piece.h"
17 #include "third_party/leveldatabase/src/include/leveldb/db.h"
19 namespace gcm {
20 const int64 kInvalidSerialNumber = -1;
22 UserList::UserInfo::UserInfo()
23 : serial_number(kInvalidSerialNumber),
24 // TODO(jianli): support setting active state.
25 active(true),
26 delegate(NULL) {
29 UserList::UserInfo::UserInfo(int64 serial_number)
30 : serial_number(serial_number),
31 active(true),
32 delegate(NULL) {
35 UserList::UserInfo::UserInfo(GCMClient::Delegate* delegate,
36 const SetDelegateCallback& callback)
37 : serial_number(kInvalidSerialNumber),
38 active(true),
39 delegate(delegate),
40 callback(callback) {
43 UserList::UserInfo::~UserInfo() {
46 UserList::UserList(GCMStore* gcm_store)
47 : initialized_(false),
48 next_serial_number_(kInvalidSerialNumber),
49 gcm_store_(gcm_store) {
52 UserList::~UserList() {
55 void UserList::Initialize(const GCMStore::SerialNumberMappings& result) {
56 DCHECK(!initialized_);
57 DCHECK_GT(result.next_serial_number, 0);
59 initialized_ = true;
60 next_serial_number_ = result.next_serial_number;
61 for (std::map<std::string, int64>::const_iterator iter =
62 result.user_serial_numbers.begin();
63 iter != result.user_serial_numbers.end();
64 ++iter) {
65 SetSerialNumber(iter->first, iter->second);
68 for (UserInfoMap::iterator iter = delegates_.begin();
69 iter != delegates_.end();
70 ++iter) {
71 // Process only users with delegate and callback present.
72 if (iter->second.delegate && !iter->second.callback.is_null()) {
73 if (iter->second.serial_number == kInvalidSerialNumber)
74 AssignSerialNumber(iter->first);
75 else
76 OnSerialNumberReady(iter);
81 void UserList::SetDelegate(const std::string& username,
82 GCMClient::Delegate* delegate,
83 const SetDelegateCallback& callback) {
84 DCHECK(!username.empty());
85 DCHECK(delegate);
87 UserInfoMap::iterator iter = delegates_.find(username);
88 if (iter != delegates_.end()) {
89 DCHECK(initialized_);
90 DCHECK(!iter->second.delegate);
91 iter->second.delegate = delegate;
92 iter->second.callback = callback;
93 } else {
94 delegates_.insert(
95 iter,
96 UserInfoMap::value_type(username, UserInfo(delegate, callback)));
99 if (initialized_) {
100 UserInfoMap::iterator iter = delegates_.find(username);
101 if (iter->second.serial_number == kInvalidSerialNumber)
102 AssignSerialNumber(iter->first);
103 else
104 OnSerialNumberReady(iter);
108 void UserList::AssignSerialNumber(const std::string& username) {
109 DCHECK(initialized_);
110 DCHECK_EQ(delegates_.count(username), 1UL);
111 DCHECK_EQ(delegates_[username].serial_number, kInvalidSerialNumber);
113 // Start by incrementing the |next_serial_number_| and persist it in the GCM
114 // store.
115 int64 serial_number = next_serial_number_++;
116 gcm_store_->SetNextSerialNumber(
117 serial_number,
118 base::Bind(&UserList::IncrementSerialNumberCompleted,
119 base::Unretained(this),
120 username,
121 serial_number));
124 void UserList::IncrementSerialNumberCompleted(const std::string& username,
125 int64 user_serial_number,
126 bool success) {
127 // TODO(fgorski): Introduce retry logic.
128 if (!success)
129 DCHECK(success) << "Updating the next serial number failed.";
131 SetSerialNumber(username, user_serial_number);
132 gcm_store_->AddUserSerialNumber(
133 username,
134 user_serial_number,
135 base::Bind(&UserList::AssignSerialNumberCompleted,
136 base::Unretained(this),
137 username));
140 void UserList::AssignSerialNumberCompleted(const std::string& username,
141 bool success) {
142 // TODO(fgorski): Introduce retry logic.
143 if (!success) {
144 DVLOG(1) << "It was not possible to persist username to serial number"
145 << " mapping for username: " << username;
146 return;
149 UserInfoMap::iterator iter = delegates_.find(username);
150 DCHECK(iter != delegates_.end());
151 OnSerialNumberReady(iter);
154 void UserList::OnSerialNumberReady(const UserInfoMap::iterator& iter) {
155 base::MessageLoop::current()->PostTask(
156 FROM_HERE,
157 base::Bind(iter->second.callback,
158 iter->first,
159 iter->second.serial_number));
160 iter->second.callback.Reset();
163 void UserList::SetSerialNumber(const std::string& username,
164 int64 serial_number) {
165 DCHECK(!username.empty());
166 DCHECK_GT(serial_number, 0L);
168 UserInfoMap::iterator iter = delegates_.find(username);
169 if (iter != delegates_.end()) {
170 DCHECK_EQ(iter->second.serial_number, kInvalidSerialNumber);
171 iter->second.serial_number = serial_number;
172 } else {
173 delegates_.insert(
174 iter, UserInfoMap::value_type(username, UserInfo(serial_number)));
178 GCMClient::Delegate* UserList::GetDelegateBySerialNumber(int64 serial_number)
179 const {
180 for (UserInfoMap::const_iterator iter = delegates_.begin();
181 iter != delegates_.end();
182 ++iter) {
183 if (iter->second.serial_number == serial_number)
184 return iter->second.delegate;
186 return NULL;
189 std::vector<GCMClient::Delegate*> UserList::GetAllDelegates() const {
190 std::vector<GCMClient::Delegate*> delegates;
191 for (UserInfoMap::const_iterator iter = delegates_.begin();
192 iter != delegates_.end(); ++iter) {
193 if (iter->second.delegate)
194 delegates.push_back(iter->second.delegate);
196 return delegates;
199 GCMClient::Delegate* UserList::GetDelegateByUsername(
200 const std::string& username) const {
201 UserInfoMap::const_iterator iter = delegates_.find(username);
202 return iter != delegates_.end() ? iter->second.delegate : NULL;
205 int64 UserList::GetSerialNumberForUsername(const std::string& username) const {
206 UserInfoMap::const_iterator iter = delegates_.find(username);
207 return iter != delegates_.end() ? iter->second.serial_number
208 : kInvalidSerialNumber;
211 std::vector<int64> UserList::GetAllActiveUserSerialNumbers() const {
212 std::vector<int64> user_serial_numbers;
213 for (UserInfoMap::const_iterator iter = delegates_.begin();
214 iter != delegates_.end(); ++iter) {
215 if (iter->second.active &&
216 iter->second.serial_number != kInvalidSerialNumber)
217 user_serial_numbers.push_back(iter->second.serial_number);
219 return user_serial_numbers;
222 } // namespace gcm