Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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 { | |
| 20 const int64 kSerialNumberMissing = -1; | |
| 21 } // namespace | |
| 22 | |
| 23 namespace gcm { | |
| 24 | |
| 25 UserList::UserInfo::UserInfo() | |
| 26 : serial_number(kSerialNumberMissing), | |
| 27 delegate(NULL) { | |
| 28 } | |
| 29 | |
| 30 UserList::UserInfo::UserInfo(int64 serial_number) | |
| 31 : serial_number(serial_number), | |
| 32 delegate(NULL) { | |
| 33 } | |
| 34 | |
| 35 UserList::UserInfo::UserInfo(GCMClient::Delegate* delegate, | |
| 36 const SetDelegateCallback callback) | |
| 37 : serial_number(kSerialNumberMissing), | |
| 38 delegate(delegate), | |
| 39 callback(callback) { | |
| 40 } | |
| 41 | |
| 42 UserList::UserInfo::~UserInfo() { | |
| 43 } | |
| 44 | |
| 45 UserList::UserList(GCMStore* gcm_store) | |
| 46 : initialized_(false), | |
| 47 next_serial_number_(kSerialNumberMissing), | |
| 48 gcm_store_(gcm_store) { | |
| 49 } | |
| 50 | |
| 51 UserList::~UserList() { | |
| 52 } | |
| 53 | |
| 54 void UserList::Initialize(const GCMStore::SerialNumberMappings& result) { | |
| 55 DCHECK(!initialized_); | |
| 56 DCHECK_GT(result.next_serial_number, 0); | |
| 57 | |
| 58 next_serial_number_ = result.next_serial_number; | |
| 59 for (std::map<std::string, int64>::const_iterator iter = | |
| 60 result.user_serial_numbers.begin(); | |
| 61 iter != result.user_serial_numbers.end(); | |
| 62 ++iter) { | |
| 63 SetSerialNumber(iter->first, iter->second); | |
| 64 } | |
| 65 initialized_ = true; | |
| 66 | |
| 67 for (UserInfoMap::iterator iter = delegates_.begin(); | |
| 68 iter != delegates_.end(); | |
| 69 ++iter) { | |
| 70 // Process only users with delegate and callback present. | |
| 71 if (iter->second.delegate && !iter->second.callback.is_null()) { | |
| 72 if (iter->second.serial_number == kSerialNumberMissing) | |
| 73 AssignSerialNumber(iter->first); | |
| 74 else | |
| 75 RespondWithSerialNumber(iter); | |
| 76 } | |
| 77 } | |
| 78 } | |
| 79 | |
| 80 void UserList::SetDelegate(const std::string& username, | |
| 81 GCMClient::Delegate* delegate, | |
| 82 const SetDelegateCallback& callback) { | |
| 83 DCHECK(!username.empty()); | |
| 84 DCHECK(delegate); | |
| 85 | |
| 86 UserInfoMap::iterator iter = delegates_.find(username); | |
| 87 if (iter != delegates_.end()) { | |
| 88 DCHECK(initialized_); | |
| 89 DCHECK(!iter->second.delegate); | |
| 90 iter->second.delegate = delegate; | |
| 91 iter->second.callback = callback; | |
| 92 } else { | |
| 93 delegates_.insert( | |
| 94 iter, | |
| 95 UserInfoMap::value_type(username, UserInfo(delegate, callback))); | |
| 96 } | |
| 97 | |
| 98 if (initialized_) { | |
| 99 UserInfoMap::iterator iter = delegates_.find(username); | |
| 100 if (iter->second.serial_number == kSerialNumberMissing) | |
| 101 AssignSerialNumber(iter->first); | |
| 102 else | |
| 103 RespondWithSerialNumber(iter); | |
| 104 } | |
| 105 } | |
| 106 | |
| 107 void UserList::AssignSerialNumber(const std::string& username) { | |
| 108 DCHECK(initialized_); | |
| 109 DCHECK_EQ(delegates_.count(username), 1UL); | |
| 110 DCHECK_EQ(delegates_[username].serial_number, kSerialNumberMissing); | |
| 111 | |
| 112 // Start by incrementing the |next_serial_number_| and persist it in the GCM | |
| 113 // store. | |
| 114 int64 serial_number = next_serial_number_++; | |
|
Nicolas Zea
2014/01/14 23:56:42
this needs to be pre-increment right?
fgorski
2014/01/15 01:29:21
next serial number is the next that is going to be
| |
| 115 gcm_store_->SetNextSerialNumber( | |
| 116 serial_number, | |
| 117 base::Bind(&UserList::IncrementSerialNumberCompleted, | |
| 118 base::Unretained(this), | |
| 119 username, | |
| 120 serial_number)); | |
| 121 } | |
| 122 | |
| 123 void UserList::IncrementSerialNumberCompleted(const std::string& username, | |
| 124 int64 user_serial_number, | |
| 125 bool success) { | |
| 126 // TODO(fgorski): Introduce retry logic. | |
|
Nicolas Zea
2014/01/14 23:56:42
I don't know that we want to retry on persistence
fgorski
2014/01/15 01:29:21
So a DCHECK?
| |
| 127 if (!success) | |
| 128 DCHECK(success) << "Updating the next serial number failed."; | |
| 129 | |
| 130 SetSerialNumber(username, user_serial_number); | |
| 131 gcm_store_->AddUserSerialNumber( | |
|
Nicolas Zea
2014/01/14 23:56:42
should this and SetNextSerialNumber be combined in
fgorski
2014/01/15 01:29:21
We could consider that. (Separate patch though.)
| |
| 132 username, | |
| 133 user_serial_number, | |
| 134 base::Bind(&UserList::AssignSerialNumberCompleted, | |
| 135 base::Unretained(this), | |
| 136 username)); | |
| 137 } | |
| 138 | |
| 139 void UserList::AssignSerialNumberCompleted(const std::string& username, | |
| 140 bool success) { | |
| 141 // TODO(fgorski): Introduce retry logic. | |
| 142 if (!success) { | |
| 143 DVLOG(1) << "It was not possible to persist username to serial number" | |
| 144 << " mapping for username: " << username; | |
|
Nicolas Zea
2014/01/14 23:56:42
Perhaps respond with a -1 or something?
fgorski
2014/01/15 01:29:21
I realized that the serial number part of the resp
| |
| 145 return; | |
| 146 } | |
| 147 | |
| 148 UserInfoMap::iterator iter = delegates_.find(username); | |
| 149 DCHECK(iter != delegates_.end()); | |
| 150 RespondWithSerialNumber(iter); | |
| 151 } | |
| 152 | |
| 153 void UserList::RespondWithSerialNumber(UserInfoMap::iterator& iter) { | |
| 154 base::MessageLoop::current()->PostTask( | |
| 155 FROM_HERE, | |
| 156 base::Bind(iter->second.callback, | |
| 157 iter->first, | |
| 158 iter->second.serial_number)); | |
| 159 iter->second.callback.Reset(); | |
| 160 } | |
| 161 | |
| 162 void UserList::SetSerialNumber(const std::string& username, | |
| 163 int64 serial_number) { | |
| 164 DCHECK(!username.empty()); | |
| 165 DCHECK_GT(serial_number, 0L); | |
| 166 | |
| 167 UserInfoMap::iterator iter = delegates_.find(username); | |
| 168 if (iter != delegates_.end()) { | |
| 169 DCHECK_EQ(iter->second.serial_number, kSerialNumberMissing); | |
| 170 iter->second.serial_number = serial_number; | |
| 171 } else { | |
| 172 delegates_.insert( | |
| 173 iter, UserInfoMap::value_type(username, UserInfo(serial_number))); | |
| 174 } | |
| 175 } | |
| 176 | |
| 177 GCMClient::Delegate* UserList::GetDelegateBySerialNumber(int64 serial_number) | |
| 178 const { | |
| 179 for (UserInfoMap::const_iterator iter = delegates_.begin(); | |
| 180 iter != delegates_.end(); | |
| 181 ++iter) { | |
| 182 if (iter->second.serial_number == serial_number) | |
| 183 return iter->second.delegate; | |
| 184 } | |
| 185 return NULL; | |
| 186 } | |
| 187 | |
| 188 GCMClient::Delegate* UserList::GetDelegateByUsername( | |
| 189 const std::string& username) const { | |
| 190 UserInfoMap::const_iterator iter = delegates_.find(username); | |
| 191 if (iter != delegates_.end()) | |
| 192 return iter->second.delegate; | |
| 193 return NULL; | |
|
jianli
2014/01/15 01:07:09
nit: return iter != delegates_.end() ? iter->secon
fgorski
2014/01/15 20:42:47
Done.
| |
| 194 } | |
| 195 | |
| 196 bool UserList::GetSerialNumberForUsername(const std::string& username, | |
| 197 int64* serial_number) const { | |
| 198 UserInfoMap::const_iterator iter = delegates_.find(username); | |
| 199 if (iter != delegates_.end() && | |
| 200 iter->second.serial_number != kSerialNumberMissing) { | |
| 201 *serial_number = iter->second.serial_number; | |
| 202 return true; | |
| 203 } | |
| 204 *serial_number = kSerialNumberMissing; | |
| 205 return false; | |
| 206 } | |
| 207 | |
| 208 } // namespace gcm | |
| OLD | NEW |