Chromium Code Reviews| Index: google_apis/gcm/gcm_client_impl.cc |
| diff --git a/google_apis/gcm/gcm_client_impl.cc b/google_apis/gcm/gcm_client_impl.cc |
| index 5663eae1aead7fd2dd604d4d2da0f05d0007fc36..e11893d754039532c04a16cd002a1598c94e8356 100644 |
| --- a/google_apis/gcm/gcm_client_impl.cc |
| +++ b/google_apis/gcm/gcm_client_impl.cc |
| @@ -115,8 +115,9 @@ GCMClientImpl::GCMClientImpl() |
| : state_(UNINITIALIZED), |
| clock_(new base::DefaultClock()), |
| url_request_context_getter_(NULL), |
| - pending_registrations_deleter_(&pending_registrations_), |
| - pending_unregistrations_deleter_(&pending_unregistrations_), |
| + pending_registration_requests_deleter_(&pending_registration_requests_), |
| + pending_unregistration_requests_deleter_( |
| + &pending_unregistration_requests_), |
| weak_ptr_factory_(this) { |
| } |
| @@ -163,6 +164,8 @@ void GCMClientImpl::OnLoadCompleted(scoped_ptr<GCMStore::LoadResult> result) { |
| return; |
| } |
| + registrations_ = result->registrations; |
| + |
| device_checkin_info_.android_id = result->device_android_id; |
| device_checkin_info_.secret = result->device_security_token; |
| InitializeMCSClient(result.Pass()); |
| @@ -284,11 +287,16 @@ void GCMClientImpl::SetDeviceCredentialsCallback(bool success) { |
| DCHECK(success); |
| } |
| +void GCMClientImpl::UpdateRegistrationCallback(bool success) { |
| + // TODO(fgorski): This is one of the signals that store needs a rebuild. |
| + DCHECK(success); |
| +} |
| + |
| void GCMClientImpl::Stop() { |
| device_checkin_info_.Reset(); |
| mcs_client_.reset(); |
| checkin_request_.reset(); |
| - pending_registrations_.clear(); |
| + pending_registration_requests_.clear(); |
| state_ = INITIALIZED; |
| gcm_store_->Close(); |
| } |
| @@ -302,33 +310,49 @@ void GCMClientImpl::CheckOut() { |
| void GCMClientImpl::Register(const std::string& app_id, |
| const std::vector<std::string>& sender_ids) { |
| DCHECK_EQ(state_, READY); |
| + |
| + // If the same sender ids is provided, return the cached registration ID |
| + // directly. |
| + RegistrationInfoMap::const_iterator registrations_iter = |
| + registrations_.find(app_id); |
| + if (registrations_iter != registrations_.end() && |
| + registrations_iter->second.sender_ids == sender_ids) { |
| + delegate_->OnRegisterFinished( |
| + app_id, registrations_iter->second.registration_id, SUCCESS); |
| + return; |
| + } |
| + |
| RegistrationRequest::RequestInfo request_info( |
| device_checkin_info_.android_id, |
| device_checkin_info_.secret, |
| app_id, |
| sender_ids); |
| - DCHECK_EQ(0u, pending_registrations_.count(app_id)); |
| + DCHECK_EQ(0u, pending_registration_requests_.count(app_id)); |
| RegistrationRequest* registration_request = |
| new RegistrationRequest(request_info, |
| kDefaultBackoffPolicy, |
| base::Bind(&GCMClientImpl::OnRegisterCompleted, |
| weak_ptr_factory_.GetWeakPtr(), |
| - app_id), |
| + app_id, |
| + sender_ids), |
| kMaxRegistrationRetries, |
| url_request_context_getter_); |
| - pending_registrations_[app_id] = registration_request; |
| + pending_registration_requests_[app_id] = registration_request; |
| registration_request->Start(); |
| } |
| -void GCMClientImpl::OnRegisterCompleted(const std::string& app_id, |
| - RegistrationRequest::Status status, |
| - const std::string& registration_id) { |
| +void GCMClientImpl::OnRegisterCompleted( |
| + const std::string& app_id, |
| + const std::vector<std::string>& sender_ids, |
| + RegistrationRequest::Status status, |
| + const std::string& registration_id) { |
| DCHECK(delegate_); |
| Result result; |
| - PendingRegistrations::iterator iter = pending_registrations_.find(app_id); |
| - if (iter == pending_registrations_.end()) |
| + PendingRegistrationRequests::iterator iter = |
| + pending_registration_requests_.find(app_id); |
| + if (iter == pending_registration_requests_.end()) |
| result = UNKNOWN_ERROR; |
| else if (status == RegistrationRequest::INVALID_SENDER) |
| result = INVALID_PARAMETER; |
| @@ -337,20 +361,42 @@ void GCMClientImpl::OnRegisterCompleted(const std::string& app_id, |
| else |
| result = SUCCESS; |
| + if (result == SUCCESS) { |
| + // Cache it. |
| + RegistrationInfo registration; |
| + registration.sender_ids = sender_ids; |
| + registration.registration_id = registration_id; |
| + registrations_[app_id] = registration; |
| + |
| + // Save it in the persistent store. |
| + gcm_store_->AddRegistration( |
| + app_id, |
| + registration, |
| + base::Bind(&GCMClientImpl::UpdateRegistrationCallback, |
| + weak_ptr_factory_.GetWeakPtr())); |
| + } |
| + |
| delegate_->OnRegisterFinished( |
| app_id, result == SUCCESS ? registration_id : std::string(), result); |
| - if (iter != pending_registrations_.end()) { |
| + if (iter != pending_registration_requests_.end()) { |
| delete iter->second; |
| - pending_registrations_.erase(iter); |
| + pending_registration_requests_.erase(iter); |
| } |
| } |
| void GCMClientImpl::Unregister(const std::string& app_id) { |
| DCHECK_EQ(state_, READY); |
| - if (pending_unregistrations_.count(app_id) == 1) |
| + if (pending_unregistration_requests_.count(app_id) == 1) |
| return; |
| + // Remove from the cache and persistent store. |
| + registrations_.erase(app_id); |
| + gcm_store_->RemoveRegistration( |
| + app_id, |
| + base::Bind(&GCMClientImpl::UpdateRegistrationCallback, |
| + weak_ptr_factory_.GetWeakPtr())); |
| + |
| UnregistrationRequest::RequestInfo request_info( |
| device_checkin_info_.android_id, |
| device_checkin_info_.secret, |
| @@ -364,7 +410,7 @@ void GCMClientImpl::Unregister(const std::string& app_id) { |
| weak_ptr_factory_.GetWeakPtr(), |
| app_id), |
| url_request_context_getter_); |
| - pending_unregistrations_[app_id] = unregistration_request; |
| + pending_unregistration_requests_[app_id] = unregistration_request; |
| unregistration_request->Start(); |
| } |
| @@ -377,12 +423,13 @@ void GCMClientImpl::OnUnregisterCompleted( |
| app_id, |
| status == UnregistrationRequest::SUCCESS ? SUCCESS : SERVER_ERROR); |
| - PendingUnregistrations::iterator iter = pending_unregistrations_.find(app_id); |
| - if (iter == pending_unregistrations_.end()) |
| + PendingUnregistrationRequests::iterator iter = |
| + pending_unregistration_requests_.find(app_id); |
| + if (iter == pending_unregistration_requests_.end()) |
| return; |
| delete iter->second; |
| - pending_unregistrations_.erase(iter); |
| + pending_unregistration_requests_.erase(iter); |
| } |
| void GCMClientImpl::OnGCMStoreDestroyed(bool success) { |
| @@ -539,13 +586,24 @@ void GCMClientImpl::HandleIncomingMessage(const gcm::MCSMessage& message) { |
| void GCMClientImpl::HandleIncomingDataMessage( |
| const mcs_proto::DataMessageStanza& data_message_stanza, |
| MessageData& message_data) { |
| + std::string app_id = data_message_stanza.category(); |
| + |
| + // 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
|
| + // message. |
| + RegistrationInfoMap::iterator iter = registrations_.find(app_id); |
| + if (iter == registrations_.end() || |
| + std::find(iter->second.sender_ids.begin(), |
| + iter->second.sender_ids.end(), |
| + data_message_stanza.from()) == iter->second.sender_ids.end()) { |
| + return; |
| + } |
| + |
| IncomingMessage incoming_message; |
| incoming_message.sender_id = data_message_stanza.from(); |
| if (data_message_stanza.has_token()) |
| incoming_message.collapse_key = data_message_stanza.token(); |
| incoming_message.data = message_data; |
| - delegate_->OnMessageReceived(data_message_stanza.category(), |
| - incoming_message); |
| + delegate_->OnMessageReceived(app_id, incoming_message); |
| } |
| void GCMClientImpl::HandleIncomingSendError( |