Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "google_apis/gcm/gcm_client_impl.h" | 5 #include "google_apis/gcm/gcm_client_impl.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/files/file_path.h" | 8 #include "base/files/file_path.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 108 return DATA_MESSAGE; | 108 return DATA_MESSAGE; |
| 109 return UNKNOWN; | 109 return UNKNOWN; |
| 110 } | 110 } |
| 111 | 111 |
| 112 } // namespace | 112 } // namespace |
| 113 | 113 |
| 114 GCMClientImpl::GCMClientImpl() | 114 GCMClientImpl::GCMClientImpl() |
| 115 : state_(UNINITIALIZED), | 115 : state_(UNINITIALIZED), |
| 116 clock_(new base::DefaultClock()), | 116 clock_(new base::DefaultClock()), |
| 117 url_request_context_getter_(NULL), | 117 url_request_context_getter_(NULL), |
| 118 pending_registrations_deleter_(&pending_registrations_), | 118 pending_registration_requests_deleter_(&pending_registration_requests_), |
| 119 pending_unregistrations_deleter_(&pending_unregistrations_), | 119 pending_unregistration_requests_deleter_( |
| 120 &pending_unregistration_requests_), | |
| 120 weak_ptr_factory_(this) { | 121 weak_ptr_factory_(this) { |
| 121 } | 122 } |
| 122 | 123 |
| 123 GCMClientImpl::~GCMClientImpl() { | 124 GCMClientImpl::~GCMClientImpl() { |
| 124 } | 125 } |
| 125 | 126 |
| 126 void GCMClientImpl::Initialize( | 127 void GCMClientImpl::Initialize( |
| 127 const checkin_proto::ChromeBuildProto& chrome_build_proto, | 128 const checkin_proto::ChromeBuildProto& chrome_build_proto, |
| 128 const base::FilePath& path, | 129 const base::FilePath& path, |
| 129 const std::vector<std::string>& account_ids, | 130 const std::vector<std::string>& account_ids, |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 156 } | 157 } |
| 157 | 158 |
| 158 void GCMClientImpl::OnLoadCompleted(scoped_ptr<GCMStore::LoadResult> result) { | 159 void GCMClientImpl::OnLoadCompleted(scoped_ptr<GCMStore::LoadResult> result) { |
| 159 DCHECK_EQ(LOADING, state_); | 160 DCHECK_EQ(LOADING, state_); |
| 160 | 161 |
| 161 if (!result->success) { | 162 if (!result->success) { |
| 162 ResetState(); | 163 ResetState(); |
| 163 return; | 164 return; |
| 164 } | 165 } |
| 165 | 166 |
| 167 registrations_ = result->registrations; | |
| 168 | |
| 166 device_checkin_info_.android_id = result->device_android_id; | 169 device_checkin_info_.android_id = result->device_android_id; |
| 167 device_checkin_info_.secret = result->device_security_token; | 170 device_checkin_info_.secret = result->device_security_token; |
| 168 InitializeMCSClient(result.Pass()); | 171 InitializeMCSClient(result.Pass()); |
| 169 if (!device_checkin_info_.IsValid()) { | 172 if (!device_checkin_info_.IsValid()) { |
| 170 device_checkin_info_.Reset(); | 173 device_checkin_info_.Reset(); |
| 171 state_ = INITIAL_DEVICE_CHECKIN; | 174 state_ = INITIAL_DEVICE_CHECKIN; |
| 172 StartCheckin(device_checkin_info_); | 175 StartCheckin(device_checkin_info_); |
| 173 return; | 176 return; |
| 174 } | 177 } |
| 175 | 178 |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 277 // TODO(fgorski): Reset the checkin timer. | 280 // TODO(fgorski): Reset the checkin timer. |
| 278 } | 281 } |
| 279 } | 282 } |
| 280 } | 283 } |
| 281 | 284 |
| 282 void GCMClientImpl::SetDeviceCredentialsCallback(bool success) { | 285 void GCMClientImpl::SetDeviceCredentialsCallback(bool success) { |
| 283 // TODO(fgorski): This is one of the signals that store needs a rebuild. | 286 // TODO(fgorski): This is one of the signals that store needs a rebuild. |
| 284 DCHECK(success); | 287 DCHECK(success); |
| 285 } | 288 } |
| 286 | 289 |
| 290 void GCMClientImpl::UpdateRegistrationCallback(bool success) { | |
| 291 // TODO(fgorski): This is one of the signals that store needs a rebuild. | |
| 292 DCHECK(success); | |
| 293 } | |
| 294 | |
| 287 void GCMClientImpl::Stop() { | 295 void GCMClientImpl::Stop() { |
| 288 device_checkin_info_.Reset(); | 296 device_checkin_info_.Reset(); |
| 289 mcs_client_.reset(); | 297 mcs_client_.reset(); |
| 290 checkin_request_.reset(); | 298 checkin_request_.reset(); |
| 291 pending_registrations_.clear(); | 299 pending_registration_requests_.clear(); |
| 292 state_ = INITIALIZED; | 300 state_ = INITIALIZED; |
| 293 gcm_store_->Close(); | 301 gcm_store_->Close(); |
| 294 } | 302 } |
| 295 | 303 |
| 296 void GCMClientImpl::CheckOut() { | 304 void GCMClientImpl::CheckOut() { |
| 297 Stop(); | 305 Stop(); |
| 298 gcm_store_->Destroy(base::Bind(&GCMClientImpl::OnGCMStoreDestroyed, | 306 gcm_store_->Destroy(base::Bind(&GCMClientImpl::OnGCMStoreDestroyed, |
| 299 weak_ptr_factory_.GetWeakPtr())); | 307 weak_ptr_factory_.GetWeakPtr())); |
| 300 } | 308 } |
| 301 | 309 |
| 302 void GCMClientImpl::Register(const std::string& app_id, | 310 void GCMClientImpl::Register(const std::string& app_id, |
| 303 const std::vector<std::string>& sender_ids) { | 311 const std::vector<std::string>& sender_ids) { |
| 304 DCHECK_EQ(state_, READY); | 312 DCHECK_EQ(state_, READY); |
| 313 | |
| 314 // If the same sender ids is provided, return the cached registration ID | |
| 315 // directly. | |
| 316 RegistrationInfoMap::const_iterator registrations_iter = | |
| 317 registrations_.find(app_id); | |
| 318 if (registrations_iter != registrations_.end() && | |
| 319 registrations_iter->second.sender_ids == sender_ids) { | |
| 320 delegate_->OnRegisterFinished( | |
| 321 app_id, registrations_iter->second.registration_id, SUCCESS); | |
| 322 return; | |
| 323 } | |
| 324 | |
| 305 RegistrationRequest::RequestInfo request_info( | 325 RegistrationRequest::RequestInfo request_info( |
| 306 device_checkin_info_.android_id, | 326 device_checkin_info_.android_id, |
| 307 device_checkin_info_.secret, | 327 device_checkin_info_.secret, |
| 308 app_id, | 328 app_id, |
| 309 sender_ids); | 329 sender_ids); |
| 310 DCHECK_EQ(0u, pending_registrations_.count(app_id)); | 330 DCHECK_EQ(0u, pending_registration_requests_.count(app_id)); |
| 311 | 331 |
| 312 RegistrationRequest* registration_request = | 332 RegistrationRequest* registration_request = |
| 313 new RegistrationRequest(request_info, | 333 new RegistrationRequest(request_info, |
| 314 kDefaultBackoffPolicy, | 334 kDefaultBackoffPolicy, |
| 315 base::Bind(&GCMClientImpl::OnRegisterCompleted, | 335 base::Bind(&GCMClientImpl::OnRegisterCompleted, |
| 316 weak_ptr_factory_.GetWeakPtr(), | 336 weak_ptr_factory_.GetWeakPtr(), |
| 317 app_id), | 337 app_id, |
| 338 sender_ids), | |
| 318 kMaxRegistrationRetries, | 339 kMaxRegistrationRetries, |
| 319 url_request_context_getter_); | 340 url_request_context_getter_); |
| 320 pending_registrations_[app_id] = registration_request; | 341 pending_registration_requests_[app_id] = registration_request; |
| 321 registration_request->Start(); | 342 registration_request->Start(); |
| 322 } | 343 } |
| 323 | 344 |
| 324 void GCMClientImpl::OnRegisterCompleted(const std::string& app_id, | 345 void GCMClientImpl::OnRegisterCompleted( |
| 325 RegistrationRequest::Status status, | 346 const std::string& app_id, |
| 326 const std::string& registration_id) { | 347 const std::vector<std::string>& sender_ids, |
| 348 RegistrationRequest::Status status, | |
| 349 const std::string& registration_id) { | |
| 327 DCHECK(delegate_); | 350 DCHECK(delegate_); |
| 328 | 351 |
| 329 Result result; | 352 Result result; |
| 330 PendingRegistrations::iterator iter = pending_registrations_.find(app_id); | 353 PendingRegistrationRequests::iterator iter = |
| 331 if (iter == pending_registrations_.end()) | 354 pending_registration_requests_.find(app_id); |
| 355 if (iter == pending_registration_requests_.end()) | |
| 332 result = UNKNOWN_ERROR; | 356 result = UNKNOWN_ERROR; |
| 333 else if (status == RegistrationRequest::INVALID_SENDER) | 357 else if (status == RegistrationRequest::INVALID_SENDER) |
| 334 result = INVALID_PARAMETER; | 358 result = INVALID_PARAMETER; |
| 335 else if (registration_id.empty()) | 359 else if (registration_id.empty()) |
| 336 result = SERVER_ERROR; | 360 result = SERVER_ERROR; |
| 337 else | 361 else |
| 338 result = SUCCESS; | 362 result = SUCCESS; |
| 339 | 363 |
| 364 if (result == SUCCESS) { | |
| 365 // Cache it. | |
| 366 RegistrationInfo registration; | |
| 367 registration.sender_ids = sender_ids; | |
| 368 registration.registration_id = registration_id; | |
| 369 registrations_[app_id] = registration; | |
| 370 | |
| 371 // Save it in the persistent store. | |
| 372 gcm_store_->AddRegistration( | |
| 373 app_id, | |
| 374 registration, | |
| 375 base::Bind(&GCMClientImpl::UpdateRegistrationCallback, | |
| 376 weak_ptr_factory_.GetWeakPtr())); | |
| 377 } | |
| 378 | |
| 340 delegate_->OnRegisterFinished( | 379 delegate_->OnRegisterFinished( |
| 341 app_id, result == SUCCESS ? registration_id : std::string(), result); | 380 app_id, result == SUCCESS ? registration_id : std::string(), result); |
| 342 | 381 |
| 343 if (iter != pending_registrations_.end()) { | 382 if (iter != pending_registration_requests_.end()) { |
| 344 delete iter->second; | 383 delete iter->second; |
| 345 pending_registrations_.erase(iter); | 384 pending_registration_requests_.erase(iter); |
| 346 } | 385 } |
| 347 } | 386 } |
| 348 | 387 |
| 349 void GCMClientImpl::Unregister(const std::string& app_id) { | 388 void GCMClientImpl::Unregister(const std::string& app_id) { |
| 350 DCHECK_EQ(state_, READY); | 389 DCHECK_EQ(state_, READY); |
| 351 if (pending_unregistrations_.count(app_id) == 1) | 390 if (pending_unregistration_requests_.count(app_id) == 1) |
| 352 return; | 391 return; |
| 353 | 392 |
| 393 // Remove from the cache and persistent store. | |
| 394 registrations_.erase(app_id); | |
| 395 gcm_store_->RemoveRegistration( | |
| 396 app_id, | |
| 397 base::Bind(&GCMClientImpl::UpdateRegistrationCallback, | |
| 398 weak_ptr_factory_.GetWeakPtr())); | |
| 399 | |
| 354 UnregistrationRequest::RequestInfo request_info( | 400 UnregistrationRequest::RequestInfo request_info( |
| 355 device_checkin_info_.android_id, | 401 device_checkin_info_.android_id, |
| 356 device_checkin_info_.secret, | 402 device_checkin_info_.secret, |
| 357 app_id); | 403 app_id); |
| 358 | 404 |
| 359 UnregistrationRequest* unregistration_request = | 405 UnregistrationRequest* unregistration_request = |
| 360 new UnregistrationRequest( | 406 new UnregistrationRequest( |
| 361 request_info, | 407 request_info, |
| 362 kDefaultBackoffPolicy, | 408 kDefaultBackoffPolicy, |
| 363 base::Bind(&GCMClientImpl::OnUnregisterCompleted, | 409 base::Bind(&GCMClientImpl::OnUnregisterCompleted, |
| 364 weak_ptr_factory_.GetWeakPtr(), | 410 weak_ptr_factory_.GetWeakPtr(), |
| 365 app_id), | 411 app_id), |
| 366 url_request_context_getter_); | 412 url_request_context_getter_); |
| 367 pending_unregistrations_[app_id] = unregistration_request; | 413 pending_unregistration_requests_[app_id] = unregistration_request; |
| 368 unregistration_request->Start(); | 414 unregistration_request->Start(); |
| 369 } | 415 } |
| 370 | 416 |
| 371 void GCMClientImpl::OnUnregisterCompleted( | 417 void GCMClientImpl::OnUnregisterCompleted( |
| 372 const std::string& app_id, | 418 const std::string& app_id, |
| 373 UnregistrationRequest::Status status) { | 419 UnregistrationRequest::Status status) { |
| 374 DVLOG(1) << "Unregister completed for app: " << app_id | 420 DVLOG(1) << "Unregister completed for app: " << app_id |
| 375 << " with " << (status ? "success." : "failure."); | 421 << " with " << (status ? "success." : "failure."); |
| 376 delegate_->OnUnregisterFinished( | 422 delegate_->OnUnregisterFinished( |
| 377 app_id, | 423 app_id, |
| 378 status == UnregistrationRequest::SUCCESS ? SUCCESS : SERVER_ERROR); | 424 status == UnregistrationRequest::SUCCESS ? SUCCESS : SERVER_ERROR); |
| 379 | 425 |
| 380 PendingUnregistrations::iterator iter = pending_unregistrations_.find(app_id); | 426 PendingUnregistrationRequests::iterator iter = |
| 381 if (iter == pending_unregistrations_.end()) | 427 pending_unregistration_requests_.find(app_id); |
| 428 if (iter == pending_unregistration_requests_.end()) | |
| 382 return; | 429 return; |
| 383 | 430 |
| 384 delete iter->second; | 431 delete iter->second; |
| 385 pending_unregistrations_.erase(iter); | 432 pending_unregistration_requests_.erase(iter); |
| 386 } | 433 } |
| 387 | 434 |
| 388 void GCMClientImpl::OnGCMStoreDestroyed(bool success) { | 435 void GCMClientImpl::OnGCMStoreDestroyed(bool success) { |
| 389 DLOG_IF(ERROR, !success) << "GCM store failed to be destroyed!"; | 436 DLOG_IF(ERROR, !success) << "GCM store failed to be destroyed!"; |
| 390 UMA_HISTOGRAM_BOOLEAN("GCM.StoreDestroySucceeded", success); | 437 UMA_HISTOGRAM_BOOLEAN("GCM.StoreDestroySucceeded", success); |
| 391 } | 438 } |
| 392 | 439 |
| 393 void GCMClientImpl::Send(const std::string& app_id, | 440 void GCMClientImpl::Send(const std::string& app_id, |
| 394 const std::string& receiver_id, | 441 const std::string& receiver_id, |
| 395 const OutgoingMessage& message) { | 442 const OutgoingMessage& message) { |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 532 default: // Treat default the same as UNKNOWN. | 579 default: // Treat default the same as UNKNOWN. |
| 533 DVLOG(1) << "Unknown message_type received. Message ignored. " | 580 DVLOG(1) << "Unknown message_type received. Message ignored. " |
| 534 << "App ID: " << data_message_stanza.category() << "."; | 581 << "App ID: " << data_message_stanza.category() << "."; |
| 535 break; | 582 break; |
| 536 } | 583 } |
| 537 } | 584 } |
| 538 | 585 |
| 539 void GCMClientImpl::HandleIncomingDataMessage( | 586 void GCMClientImpl::HandleIncomingDataMessage( |
| 540 const mcs_proto::DataMessageStanza& data_message_stanza, | 587 const mcs_proto::DataMessageStanza& data_message_stanza, |
| 541 MessageData& message_data) { | 588 MessageData& message_data) { |
| 589 std::string app_id = data_message_stanza.category(); | |
| 590 | |
| 591 // Dropping the message when the app is not registered for the sender of the | |
|
Nicolas Zea
2014/03/21 19:52:40
nit: Dropping -> Drop
| |
| 592 // message. | |
| 593 RegistrationInfoMap::iterator iter = registrations_.find(app_id); | |
| 594 if (iter == registrations_.end() || | |
| 595 std::find(iter->second.sender_ids.begin(), | |
| 596 iter->second.sender_ids.end(), | |
| 597 data_message_stanza.from()) == iter->second.sender_ids.end()) { | |
| 598 return; | |
| 599 } | |
| 600 | |
| 542 IncomingMessage incoming_message; | 601 IncomingMessage incoming_message; |
| 543 incoming_message.sender_id = data_message_stanza.from(); | 602 incoming_message.sender_id = data_message_stanza.from(); |
| 544 if (data_message_stanza.has_token()) | 603 if (data_message_stanza.has_token()) |
| 545 incoming_message.collapse_key = data_message_stanza.token(); | 604 incoming_message.collapse_key = data_message_stanza.token(); |
| 546 incoming_message.data = message_data; | 605 incoming_message.data = message_data; |
| 547 delegate_->OnMessageReceived(data_message_stanza.category(), | 606 delegate_->OnMessageReceived(app_id, incoming_message); |
| 548 incoming_message); | |
| 549 } | 607 } |
| 550 | 608 |
| 551 void GCMClientImpl::HandleIncomingSendError( | 609 void GCMClientImpl::HandleIncomingSendError( |
| 552 const mcs_proto::DataMessageStanza& data_message_stanza, | 610 const mcs_proto::DataMessageStanza& data_message_stanza, |
| 553 MessageData& message_data) { | 611 MessageData& message_data) { |
| 554 SendErrorDetails send_error_details; | 612 SendErrorDetails send_error_details; |
| 555 send_error_details.additional_data = message_data; | 613 send_error_details.additional_data = message_data; |
| 556 send_error_details.result = SERVER_ERROR; | 614 send_error_details.result = SERVER_ERROR; |
| 557 | 615 |
| 558 MessageData::iterator iter = | 616 MessageData::iterator iter = |
| 559 send_error_details.additional_data.find(kSendErrorMessageIdKey); | 617 send_error_details.additional_data.find(kSendErrorMessageIdKey); |
| 560 if (iter != send_error_details.additional_data.end()) { | 618 if (iter != send_error_details.additional_data.end()) { |
| 561 send_error_details.message_id = iter->second; | 619 send_error_details.message_id = iter->second; |
| 562 send_error_details.additional_data.erase(iter); | 620 send_error_details.additional_data.erase(iter); |
| 563 } | 621 } |
| 564 | 622 |
| 565 delegate_->OnMessageSendError(data_message_stanza.category(), | 623 delegate_->OnMessageSendError(data_message_stanza.category(), |
| 566 send_error_details); | 624 send_error_details); |
| 567 } | 625 } |
| 568 | 626 |
| 569 void GCMClientImpl::SetMCSClientForTesting(scoped_ptr<MCSClient> mcs_client) { | 627 void GCMClientImpl::SetMCSClientForTesting(scoped_ptr<MCSClient> mcs_client) { |
| 570 mcs_client_ = mcs_client.Pass(); | 628 mcs_client_ = mcs_client.Pass(); |
| 571 } | 629 } |
| 572 | 630 |
| 573 } // namespace gcm | 631 } // namespace gcm |
| OLD | NEW |