Upstream version 5.34.98.0
[platform/framework/web/crosswalk.git] / src / google_apis / gcm / engine / user_list.cc
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.
4
5 #include "google_apis/gcm/engine/user_list.h"
6
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"
18
19 namespace gcm {
20 const int64 kInvalidSerialNumber = -1;
21
22 UserList::UserInfo::UserInfo()
23     : serial_number(kInvalidSerialNumber),
24       delegate(NULL) {
25 }
26
27 UserList::UserInfo::UserInfo(int64 serial_number)
28     : serial_number(serial_number),
29       delegate(NULL) {
30 }
31
32 UserList::UserInfo::UserInfo(GCMClient::Delegate* delegate,
33                              const SetDelegateCallback& callback)
34     : serial_number(kInvalidSerialNumber),
35       delegate(delegate),
36       callback(callback) {
37 }
38
39 UserList::UserInfo::~UserInfo() {
40 }
41
42 UserList::UserList(GCMStore* gcm_store)
43     : initialized_(false),
44       next_serial_number_(kInvalidSerialNumber),
45       gcm_store_(gcm_store) {
46 }
47
48 UserList::~UserList() {
49 }
50
51 void UserList::Initialize(const GCMStore::SerialNumberMappings& result) {
52   DCHECK(!initialized_);
53   DCHECK_GT(result.next_serial_number, 0);
54
55   initialized_ = true;
56   next_serial_number_ = result.next_serial_number;
57   for (std::map<std::string, int64>::const_iterator iter =
58            result.user_serial_numbers.begin();
59        iter != result.user_serial_numbers.end();
60        ++iter) {
61     SetSerialNumber(iter->first, iter->second);
62   }
63
64   for (UserInfoMap::iterator iter = delegates_.begin();
65        iter != delegates_.end();
66        ++iter) {
67     // Process only users with delegate and callback present.
68     if (iter->second.delegate && !iter->second.callback.is_null()) {
69       if (iter->second.serial_number == kInvalidSerialNumber)
70         AssignSerialNumber(iter->first);
71       else
72         OnSerialNumberReady(iter);
73     }
74   }
75 }
76
77 void UserList::SetDelegate(const std::string& username,
78                            GCMClient::Delegate* delegate,
79                            const SetDelegateCallback& callback) {
80   DCHECK(!username.empty());
81   DCHECK(delegate);
82
83   UserInfoMap::iterator iter = delegates_.find(username);
84   if (iter != delegates_.end()) {
85     DCHECK(initialized_);
86     DCHECK(!iter->second.delegate);
87     iter->second.delegate = delegate;
88     iter->second.callback = callback;
89   } else {
90     delegates_.insert(
91         iter,
92         UserInfoMap::value_type(username, UserInfo(delegate, callback)));
93   }
94
95   if (initialized_) {
96     UserInfoMap::iterator iter = delegates_.find(username);
97     if (iter->second.serial_number == kInvalidSerialNumber)
98       AssignSerialNumber(iter->first);
99     else
100       OnSerialNumberReady(iter);
101   }
102 }
103
104 void UserList::AssignSerialNumber(const std::string& username) {
105   DCHECK(initialized_);
106   DCHECK_EQ(delegates_.count(username), 1UL);
107   DCHECK_EQ(delegates_[username].serial_number, kInvalidSerialNumber);
108
109   // Start by incrementing the |next_serial_number_| and persist it in the GCM
110   // store.
111   int64 serial_number = next_serial_number_++;
112   gcm_store_->SetNextSerialNumber(
113       serial_number,
114       base::Bind(&UserList::IncrementSerialNumberCompleted,
115                  base::Unretained(this),
116                  username,
117                  serial_number));
118 }
119
120 void UserList::IncrementSerialNumberCompleted(const std::string& username,
121                                               int64 user_serial_number,
122                                               bool success) {
123   // TODO(fgorski): Introduce retry logic.
124   if (!success)
125     DCHECK(success) << "Updating the next serial number failed.";
126
127   SetSerialNumber(username, user_serial_number);
128   gcm_store_->AddUserSerialNumber(
129       username,
130       user_serial_number,
131       base::Bind(&UserList::AssignSerialNumberCompleted,
132                  base::Unretained(this),
133                  username));
134 }
135
136 void UserList::AssignSerialNumberCompleted(const std::string& username,
137                                            bool success) {
138   // TODO(fgorski): Introduce retry logic.
139   if (!success) {
140     DVLOG(1) << "It was not possible to persist username to serial number"
141              << " mapping for username: " << username;
142     return;
143   }
144
145   UserInfoMap::iterator iter = delegates_.find(username);
146   DCHECK(iter != delegates_.end());
147   OnSerialNumberReady(iter);
148 }
149
150 void UserList::OnSerialNumberReady(const UserInfoMap::iterator& iter) {
151   base::MessageLoop::current()->PostTask(
152       FROM_HERE,
153       base::Bind(iter->second.callback,
154                  iter->first,
155                  iter->second.serial_number));
156   iter->second.callback.Reset();
157 }
158
159 void UserList::SetSerialNumber(const std::string& username,
160                                int64 serial_number) {
161   DCHECK(!username.empty());
162   DCHECK_GT(serial_number, 0L);
163
164   UserInfoMap::iterator iter = delegates_.find(username);
165   if (iter != delegates_.end()) {
166     DCHECK_EQ(iter->second.serial_number, kInvalidSerialNumber);
167     iter->second.serial_number = serial_number;
168   } else {
169     delegates_.insert(
170         iter, UserInfoMap::value_type(username, UserInfo(serial_number)));
171   }
172 }
173
174 GCMClient::Delegate* UserList::GetDelegateBySerialNumber(int64 serial_number)
175     const {
176   for (UserInfoMap::const_iterator iter = delegates_.begin();
177        iter != delegates_.end();
178        ++iter) {
179     if (iter->second.serial_number == serial_number)
180       return iter->second.delegate;
181   }
182   return NULL;
183 }
184
185 GCMClient::Delegate* UserList::GetDelegateByUsername(
186     const std::string& username) const {
187   UserInfoMap::const_iterator iter = delegates_.find(username);
188   return iter != delegates_.end() ? iter->second.delegate : NULL;
189 }
190
191 int64 UserList::GetSerialNumberForUsername(const std::string& username) const {
192   UserInfoMap::const_iterator iter = delegates_.find(username);
193   return iter != delegates_.end() ? iter->second.serial_number
194                                   : kInvalidSerialNumber;
195 }
196
197 }  // namespace gcm