| 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..ad02a4d80d36cc04ba0624dfb2a59f3239980447 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.
|
| + linked_ptr<RegistrationInfo> registration(new RegistrationInfo);
|
| + 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();
|
| +
|
| + // Drop the message when the app is not registered for the sender of the
|
| + // 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(
|
|
|