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( |