OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/gcm_driver/gcm_account_mapper.h" | 5 #include "components/gcm_driver/gcm_account_mapper.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/guid.h" | 8 #include "base/guid.h" |
9 #include "base/time/clock.h" | 9 #include "base/time/clock.h" |
10 #include "base/time/default_clock.h" | 10 #include "base/time/default_clock.h" |
(...skipping 29 matching lines...) Expand all Loading... | |
40 : gcm_driver_(gcm_driver), | 40 : gcm_driver_(gcm_driver), |
41 clock_(new base::DefaultClock), | 41 clock_(new base::DefaultClock), |
42 initialized_(false), | 42 initialized_(false), |
43 weak_ptr_factory_(this) { | 43 weak_ptr_factory_(this) { |
44 } | 44 } |
45 | 45 |
46 GCMAccountMapper::~GCMAccountMapper() { | 46 GCMAccountMapper::~GCMAccountMapper() { |
47 } | 47 } |
48 | 48 |
49 void GCMAccountMapper::Initialize( | 49 void GCMAccountMapper::Initialize( |
50 const std::vector<AccountMapping>& account_mappings, | 50 const std::vector<AccountMapping>& account_mappings) { |
51 const std::string& registration_id) { | |
52 DCHECK(!initialized_); | 51 DCHECK(!initialized_); |
53 initialized_ = true; | 52 initialized_ = true; |
54 registration_id_ = registration_id; | |
55 | |
56 accounts_ = account_mappings; | 53 accounts_ = account_mappings; |
57 | |
58 gcm_driver_->AddAppHandler(kGCMAccountMapperAppId, this); | 54 gcm_driver_->AddAppHandler(kGCMAccountMapperAppId, this); |
59 | 55 Register(); |
60 // TODO(fgorski): if no registration ID, get registration ID. | |
61 } | 56 } |
62 | 57 |
63 void GCMAccountMapper::SetAccountTokens( | 58 void GCMAccountMapper::SetAccountTokens( |
64 const std::vector<GCMClient::AccountTokenInfo> account_tokens) { | 59 const std::vector<GCMClient::AccountTokenInfo> account_tokens) { |
65 DCHECK(initialized_); | 60 // If account mapper is not ready to handle tasks yet, save the lastest |
Nicolas Zea
2014/09/18 17:35:14
nit: lastest -> latest
fgorski
2014/09/18 18:08:53
Done.
| |
61 // account tokens and return. | |
62 if (!IsReady()) { | |
63 pending_account_tokens_ = account_tokens; | |
64 return; | |
65 } | |
66 | 66 |
67 // Start from removing the old tokens, from all of the known accounts. | 67 // Start from removing the old tokens, from all of the known accounts. |
68 for (AccountMappings::iterator iter = accounts_.begin(); | 68 for (AccountMappings::iterator iter = accounts_.begin(); |
69 iter != accounts_.end(); | 69 iter != accounts_.end(); |
70 ++iter) { | 70 ++iter) { |
71 iter->access_token.clear(); | 71 iter->access_token.clear(); |
72 } | 72 } |
73 | 73 |
74 // Update the internal collection of mappings with the new tokens. | 74 // Update the internal collection of mappings with the new tokens. |
75 for (std::vector<GCMClient::AccountTokenInfo>::const_iterator token_iter = | 75 for (std::vector<GCMClient::AccountTokenInfo>::const_iterator token_iter = |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
207 account_mapping_it->last_message_id.clear(); | 207 account_mapping_it->last_message_id.clear(); |
208 | 208 |
209 gcm_driver_->UpdateAccountMapping(*account_mapping_it); | 209 gcm_driver_->UpdateAccountMapping(*account_mapping_it); |
210 } | 210 } |
211 } | 211 } |
212 | 212 |
213 bool GCMAccountMapper::CanHandle(const std::string& app_id) const { | 213 bool GCMAccountMapper::CanHandle(const std::string& app_id) const { |
214 return app_id.compare(kGCMAccountMapperAppId) == 0; | 214 return app_id.compare(kGCMAccountMapperAppId) == 0; |
215 } | 215 } |
216 | 216 |
217 bool GCMAccountMapper::IsReady() { | |
218 return initialized_ && !registration_id_.empty(); | |
219 } | |
220 | |
217 void GCMAccountMapper::SendAddMappingMessage(AccountMapping& account_mapping) { | 221 void GCMAccountMapper::SendAddMappingMessage(AccountMapping& account_mapping) { |
218 CreateAndSendMessage(account_mapping); | 222 CreateAndSendMessage(account_mapping); |
219 } | 223 } |
220 | 224 |
221 void GCMAccountMapper::SendRemoveMappingMessage( | 225 void GCMAccountMapper::SendRemoveMappingMessage( |
222 AccountMapping& account_mapping) { | 226 AccountMapping& account_mapping) { |
223 // We want to persist an account that is being removed as quickly as possible | 227 // We want to persist an account that is being removed as quickly as possible |
224 // as well as clean up the last message information. | 228 // as well as clean up the last message information. |
225 if (account_mapping.status != AccountMapping::REMOVING) { | 229 if (account_mapping.status != AccountMapping::REMOVING) { |
226 account_mapping.status = AccountMapping::REMOVING; | 230 account_mapping.status = AccountMapping::REMOVING; |
(...skipping 23 matching lines...) Expand all Loading... | |
250 } | 254 } |
251 | 255 |
252 gcm_driver_->Send(kGCMAccountMapperAppId, | 256 gcm_driver_->Send(kGCMAccountMapperAppId, |
253 kGCMAccountMapperSenderId, | 257 kGCMAccountMapperSenderId, |
254 outgoing_message, | 258 outgoing_message, |
255 base::Bind(&GCMAccountMapper::OnSendFinished, | 259 base::Bind(&GCMAccountMapper::OnSendFinished, |
256 weak_ptr_factory_.GetWeakPtr(), | 260 weak_ptr_factory_.GetWeakPtr(), |
257 account_mapping.account_id)); | 261 account_mapping.account_id)); |
258 } | 262 } |
259 | 263 |
260 | |
261 void GCMAccountMapper::OnSendFinished(const std::string& account_id, | 264 void GCMAccountMapper::OnSendFinished(const std::string& account_id, |
262 const std::string& message_id, | 265 const std::string& message_id, |
263 GCMClient::Result result) { | 266 GCMClient::Result result) { |
264 // TODO(fgorski): Add another attempt, in case the QUEUE is not full. | 267 // TODO(fgorski): Add another attempt, in case the QUEUE is not full. |
265 if (result != GCMClient::SUCCESS) | 268 if (result != GCMClient::SUCCESS) |
266 return; | 269 return; |
267 | 270 |
268 AccountMapping* account_mapping = FindMappingByAccountId(account_id); | 271 AccountMapping* account_mapping = FindMappingByAccountId(account_id); |
269 DCHECK(account_mapping); | 272 DCHECK(account_mapping); |
270 | 273 |
271 // If we are dealing with account with status NEW, it is the first time | 274 // If we are dealing with account with status NEW, it is the first time |
272 // mapping, and we should mark it as ADDING. | 275 // mapping, and we should mark it as ADDING. |
273 if (account_mapping->status == AccountMapping::NEW) { | 276 if (account_mapping->status == AccountMapping::NEW) { |
274 account_mapping->status = AccountMapping::ADDING; | 277 account_mapping->status = AccountMapping::ADDING; |
275 account_mapping->status_change_timestamp = clock_->Now(); | 278 account_mapping->status_change_timestamp = clock_->Now(); |
276 } | 279 } |
277 | 280 |
278 account_mapping->last_message_id = message_id; | 281 account_mapping->last_message_id = message_id; |
279 | 282 |
280 gcm_driver_->UpdateAccountMapping(*account_mapping); | 283 gcm_driver_->UpdateAccountMapping(*account_mapping); |
281 } | 284 } |
282 | 285 |
286 void GCMAccountMapper::Register() { | |
Nicolas Zea
2014/09/18 17:35:14
nit: dcheck !registration_id_? Or do we want to ha
Nicolas Zea
2014/09/18 17:36:10
Come to think of it, do we have any logic to preve
fgorski
2014/09/18 18:08:53
Yes, the async operation pending will be issued im
fgorski
2014/09/18 18:08:53
Done.
| |
287 std::vector<std::string> sender_ids; | |
288 sender_ids.push_back(kGCMAccountMapperSenderId); | |
289 gcm_driver_->Register(kGCMAccountMapperAppId, | |
290 sender_ids, | |
291 base::Bind(&GCMAccountMapper::OnRegisterFinished, | |
292 weak_ptr_factory_.GetWeakPtr())); | |
293 } | |
294 | |
295 void GCMAccountMapper::OnRegisterFinished(const std::string& registration_id, | |
296 GCMClient::Result result) { | |
297 if (result == GCMClient::SUCCESS) | |
298 registration_id_ = registration_id; | |
299 | |
300 if (IsReady()) { | |
301 if (!pending_account_tokens_.empty()) { | |
302 SetAccountTokens(pending_account_tokens_); | |
303 pending_account_tokens_.clear(); | |
304 } | |
305 } else { | |
306 if (result != GCMClient::ASYNC_OPERATION_PENDING) | |
307 Register(); | |
Nicolas Zea
2014/09/18 17:35:14
how many times will we retry?
fgorski
2014/09/18 18:08:53
Register implements back-off, so it does not matte
Nicolas Zea
2014/09/19 17:41:58
Does the bail approach mean retry when new tokens
| |
308 } | |
309 } | |
310 | |
283 bool GCMAccountMapper::CanTriggerUpdate( | 311 bool GCMAccountMapper::CanTriggerUpdate( |
284 const base::Time& last_update_time) const { | 312 const base::Time& last_update_time) const { |
285 return last_update_time + | 313 return last_update_time + |
286 base::TimeDelta::FromHours(kGCMUpdateIntervalHours - | 314 base::TimeDelta::FromHours(kGCMUpdateIntervalHours - |
287 kGCMUpdateEarlyStartHours) < | 315 kGCMUpdateEarlyStartHours) < |
288 clock_->Now(); | 316 clock_->Now(); |
289 } | 317 } |
290 | 318 |
291 bool GCMAccountMapper::IsLastStatusChangeOlderThanTTL( | 319 bool GCMAccountMapper::IsLastStatusChangeOlderThanTTL( |
292 const AccountMapping& account_mapping) const { | 320 const AccountMapping& account_mapping) const { |
(...skipping 25 matching lines...) Expand all Loading... | |
318 } | 346 } |
319 | 347 |
320 return accounts_.end(); | 348 return accounts_.end(); |
321 } | 349 } |
322 | 350 |
323 void GCMAccountMapper::SetClockForTesting(scoped_ptr<base::Clock> clock) { | 351 void GCMAccountMapper::SetClockForTesting(scoped_ptr<base::Clock> clock) { |
324 clock_ = clock.Pass(); | 352 clock_ = clock.Pass(); |
325 } | 353 } |
326 | 354 |
327 } // namespace gcm | 355 } // namespace gcm |
OLD | NEW |