| 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 GetRegistration(); |
| 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 latest |
| 61 // account tokens and return. |
| 62 if (!IsReady()) { |
| 63 pending_account_tokens_ = account_tokens; |
| 64 // If mapper is initialized, but still does not have registration ID, |
| 65 // maybe the registration gave up. Retrying in case. |
| 66 if (initialized_) |
| 67 GetRegistration(); |
| 68 return; |
| 69 } |
| 66 | 70 |
| 67 // Start from removing the old tokens, from all of the known accounts. | 71 // Start from removing the old tokens, from all of the known accounts. |
| 68 for (AccountMappings::iterator iter = accounts_.begin(); | 72 for (AccountMappings::iterator iter = accounts_.begin(); |
| 69 iter != accounts_.end(); | 73 iter != accounts_.end(); |
| 70 ++iter) { | 74 ++iter) { |
| 71 iter->access_token.clear(); | 75 iter->access_token.clear(); |
| 72 } | 76 } |
| 73 | 77 |
| 74 // Update the internal collection of mappings with the new tokens. | 78 // Update the internal collection of mappings with the new tokens. |
| 75 for (std::vector<GCMClient::AccountTokenInfo>::const_iterator token_iter = | 79 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(); | 211 account_mapping_it->last_message_id.clear(); |
| 208 | 212 |
| 209 gcm_driver_->UpdateAccountMapping(*account_mapping_it); | 213 gcm_driver_->UpdateAccountMapping(*account_mapping_it); |
| 210 } | 214 } |
| 211 } | 215 } |
| 212 | 216 |
| 213 bool GCMAccountMapper::CanHandle(const std::string& app_id) const { | 217 bool GCMAccountMapper::CanHandle(const std::string& app_id) const { |
| 214 return app_id.compare(kGCMAccountMapperAppId) == 0; | 218 return app_id.compare(kGCMAccountMapperAppId) == 0; |
| 215 } | 219 } |
| 216 | 220 |
| 221 bool GCMAccountMapper::IsReady() { |
| 222 return initialized_ && !registration_id_.empty(); |
| 223 } |
| 224 |
| 217 void GCMAccountMapper::SendAddMappingMessage(AccountMapping& account_mapping) { | 225 void GCMAccountMapper::SendAddMappingMessage(AccountMapping& account_mapping) { |
| 218 CreateAndSendMessage(account_mapping); | 226 CreateAndSendMessage(account_mapping); |
| 219 } | 227 } |
| 220 | 228 |
| 221 void GCMAccountMapper::SendRemoveMappingMessage( | 229 void GCMAccountMapper::SendRemoveMappingMessage( |
| 222 AccountMapping& account_mapping) { | 230 AccountMapping& account_mapping) { |
| 223 // We want to persist an account that is being removed as quickly as possible | 231 // We want to persist an account that is being removed as quickly as possible |
| 224 // as well as clean up the last message information. | 232 // as well as clean up the last message information. |
| 225 if (account_mapping.status != AccountMapping::REMOVING) { | 233 if (account_mapping.status != AccountMapping::REMOVING) { |
| 226 account_mapping.status = AccountMapping::REMOVING; | 234 account_mapping.status = AccountMapping::REMOVING; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 250 } | 258 } |
| 251 | 259 |
| 252 gcm_driver_->Send(kGCMAccountMapperAppId, | 260 gcm_driver_->Send(kGCMAccountMapperAppId, |
| 253 kGCMAccountMapperSenderId, | 261 kGCMAccountMapperSenderId, |
| 254 outgoing_message, | 262 outgoing_message, |
| 255 base::Bind(&GCMAccountMapper::OnSendFinished, | 263 base::Bind(&GCMAccountMapper::OnSendFinished, |
| 256 weak_ptr_factory_.GetWeakPtr(), | 264 weak_ptr_factory_.GetWeakPtr(), |
| 257 account_mapping.account_id)); | 265 account_mapping.account_id)); |
| 258 } | 266 } |
| 259 | 267 |
| 260 | |
| 261 void GCMAccountMapper::OnSendFinished(const std::string& account_id, | 268 void GCMAccountMapper::OnSendFinished(const std::string& account_id, |
| 262 const std::string& message_id, | 269 const std::string& message_id, |
| 263 GCMClient::Result result) { | 270 GCMClient::Result result) { |
| 264 // TODO(fgorski): Add another attempt, in case the QUEUE is not full. | 271 // TODO(fgorski): Add another attempt, in case the QUEUE is not full. |
| 265 if (result != GCMClient::SUCCESS) | 272 if (result != GCMClient::SUCCESS) |
| 266 return; | 273 return; |
| 267 | 274 |
| 268 AccountMapping* account_mapping = FindMappingByAccountId(account_id); | 275 AccountMapping* account_mapping = FindMappingByAccountId(account_id); |
| 269 DCHECK(account_mapping); | 276 DCHECK(account_mapping); |
| 270 | 277 |
| 271 // If we are dealing with account with status NEW, it is the first time | 278 // If we are dealing with account with status NEW, it is the first time |
| 272 // mapping, and we should mark it as ADDING. | 279 // mapping, and we should mark it as ADDING. |
| 273 if (account_mapping->status == AccountMapping::NEW) { | 280 if (account_mapping->status == AccountMapping::NEW) { |
| 274 account_mapping->status = AccountMapping::ADDING; | 281 account_mapping->status = AccountMapping::ADDING; |
| 275 account_mapping->status_change_timestamp = clock_->Now(); | 282 account_mapping->status_change_timestamp = clock_->Now(); |
| 276 } | 283 } |
| 277 | 284 |
| 278 account_mapping->last_message_id = message_id; | 285 account_mapping->last_message_id = message_id; |
| 279 | 286 |
| 280 gcm_driver_->UpdateAccountMapping(*account_mapping); | 287 gcm_driver_->UpdateAccountMapping(*account_mapping); |
| 281 } | 288 } |
| 282 | 289 |
| 290 void GCMAccountMapper::GetRegistration() { |
| 291 DCHECK(registration_id_.empty()); |
| 292 std::vector<std::string> sender_ids; |
| 293 sender_ids.push_back(kGCMAccountMapperSenderId); |
| 294 gcm_driver_->Register(kGCMAccountMapperAppId, |
| 295 sender_ids, |
| 296 base::Bind(&GCMAccountMapper::OnRegisterFinished, |
| 297 weak_ptr_factory_.GetWeakPtr())); |
| 298 } |
| 299 |
| 300 void GCMAccountMapper::OnRegisterFinished(const std::string& registration_id, |
| 301 GCMClient::Result result) { |
| 302 if (result == GCMClient::SUCCESS) |
| 303 registration_id_ = registration_id; |
| 304 |
| 305 if (IsReady()) { |
| 306 if (!pending_account_tokens_.empty()) { |
| 307 SetAccountTokens(pending_account_tokens_); |
| 308 pending_account_tokens_.clear(); |
| 309 } |
| 310 } |
| 311 } |
| 312 |
| 283 bool GCMAccountMapper::CanTriggerUpdate( | 313 bool GCMAccountMapper::CanTriggerUpdate( |
| 284 const base::Time& last_update_time) const { | 314 const base::Time& last_update_time) const { |
| 285 return last_update_time + | 315 return last_update_time + |
| 286 base::TimeDelta::FromHours(kGCMUpdateIntervalHours - | 316 base::TimeDelta::FromHours(kGCMUpdateIntervalHours - |
| 287 kGCMUpdateEarlyStartHours) < | 317 kGCMUpdateEarlyStartHours) < |
| 288 clock_->Now(); | 318 clock_->Now(); |
| 289 } | 319 } |
| 290 | 320 |
| 291 bool GCMAccountMapper::IsLastStatusChangeOlderThanTTL( | 321 bool GCMAccountMapper::IsLastStatusChangeOlderThanTTL( |
| 292 const AccountMapping& account_mapping) const { | 322 const AccountMapping& account_mapping) const { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 318 } | 348 } |
| 319 | 349 |
| 320 return accounts_.end(); | 350 return accounts_.end(); |
| 321 } | 351 } |
| 322 | 352 |
| 323 void GCMAccountMapper::SetClockForTesting(scoped_ptr<base::Clock> clock) { | 353 void GCMAccountMapper::SetClockForTesting(scoped_ptr<base::Clock> clock) { |
| 324 clock_ = clock.Pass(); | 354 clock_ = clock.Pass(); |
| 325 } | 355 } |
| 326 | 356 |
| 327 } // namespace gcm | 357 } // namespace gcm |
| OLD | NEW |