Index: components/gcm_driver/gcm_client_impl.cc |
diff --git a/components/gcm_driver/gcm_client_impl.cc b/components/gcm_driver/gcm_client_impl.cc |
index 8fb162da91764c46d2ecfe98333e021929fb5018..8e343a1d0b11e488f466080b46b0e3c996479269 100644 |
--- a/components/gcm_driver/gcm_client_impl.cc |
+++ b/components/gcm_driver/gcm_client_impl.cc |
@@ -67,6 +67,7 @@ enum ResetStoreError { |
RESET_STORE_ERROR_COUNT |
}; |
+const char kGCMScope[] = "GCM"; |
const int kMaxRegistrationRetries = 5; |
const char kMessageTypeDataMessage[] = "gcm"; |
const char kMessageTypeDeletedMessagesKey[] = "deleted_messages"; |
@@ -335,7 +336,6 @@ void GCMClientImpl::OnLoadCompleted(scoped_ptr<GCMStore::LoadResult> result) { |
} |
gcm_store_reset_ = false; |
- registrations_ = result->registrations; |
device_checkin_info_.android_id = result->device_android_id; |
device_checkin_info_.secret = result->device_security_token; |
device_checkin_info_.last_checkin_accounts = result->last_checkin_accounts; |
@@ -348,7 +348,20 @@ void GCMClientImpl::OnLoadCompleted(scoped_ptr<GCMStore::LoadResult> result) { |
device_checkin_info_.accounts_set = true; |
last_checkin_time_ = result->last_checkin_time; |
gservices_settings_.UpdateFromLoadResult(*result); |
+ |
+ for (auto iter = result->registrations.begin(); |
+ iter != result->registrations.end(); |
+ ++iter) { |
+ std::string registration_id; |
+ scoped_ptr<RegistrationInfo> registration = |
+ RegistrationInfo::BuildFromString( |
+ iter->first, iter->second, ®istration_id); |
+ if (registration.get()) |
fgorski
2015/05/13 18:32:38
else?
jianli
2015/05/13 22:42:56
If we can get registration, it means that either t
|
+ registrations_[make_linked_ptr(registration.release())] = registration_id; |
+ } |
+ |
instance_id_data_ = result->instance_id_data; |
+ |
load_result_ = result.Pass(); |
state_ = LOADED; |
@@ -710,53 +723,63 @@ void GCMClientImpl::Stop() { |
gcm_store_->Close(); |
} |
-void GCMClientImpl::Register(const std::string& app_id, |
- const std::vector<std::string>& sender_ids) { |
+void GCMClientImpl::Register( |
+ const linked_ptr<RegistrationInfo>& registration_info) { |
DCHECK_EQ(state_, READY); |
- // If the same sender ids is provided, return the cached registration ID |
- // directly. |
+ // Find and use the cached registration ID. |
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; |
- } |
+ registrations_.find(registration_info); |
+ if (registrations_iter != registrations_.end()) { |
+ bool matched = true; |
+ |
+ // For GCM registration, we also match the sender IDs since multiple |
+ // registrations are not supported. |
+ const GCMRegistrationInfo* gcm_registration_info = |
+ GCMRegistrationInfo::FromRegistrationInfo(registration_info.get()); |
+ if (gcm_registration_info) { |
+ const GCMRegistrationInfo* cached_gcm_registration_info = |
+ GCMRegistrationInfo::FromRegistrationInfo( |
+ registrations_iter->first.get()); |
+ DCHECK(cached_gcm_registration_info); |
+ if (cached_gcm_registration_info && |
+ gcm_registration_info->sender_ids != |
+ cached_gcm_registration_info->sender_ids) { |
+ matched = false; |
+ } |
+ } |
- RegistrationRequest::RequestInfo request_info( |
- device_checkin_info_.android_id, |
- device_checkin_info_.secret, |
- app_id, |
- sender_ids); |
- DCHECK_EQ(0u, pending_registration_requests_.count(app_id)); |
+ if (matched) { |
+ delegate_->OnRegisterFinished( |
+ registration_info, registrations_iter->second, SUCCESS); |
+ return; |
+ } |
+ } |
RegistrationRequest* registration_request = |
- new RegistrationRequest(gservices_settings_.GetRegistrationURL(), |
- request_info, |
- GetGCMBackoffPolicy(), |
- base::Bind(&GCMClientImpl::OnRegisterCompleted, |
- weak_ptr_factory_.GetWeakPtr(), |
- app_id, |
- sender_ids), |
- kMaxRegistrationRetries, |
- url_request_context_getter_, |
- &recorder_); |
- pending_registration_requests_[app_id] = registration_request; |
+ new RegistrationRequest( |
+ gservices_settings_.GetRegistrationURL(), |
+ BuildRegistrationRequestInfo(*registration_info).Pass(), |
+ GetGCMBackoffPolicy(), |
+ base::Bind(&GCMClientImpl::OnRegisterCompleted, |
+ weak_ptr_factory_.GetWeakPtr(), |
+ registration_info), |
+ kMaxRegistrationRetries, |
+ url_request_context_getter_, |
+ &recorder_); |
+ pending_registration_requests_[registration_info] = registration_request; |
registration_request->Start(); |
} |
void GCMClientImpl::OnRegisterCompleted( |
- const std::string& app_id, |
- const std::vector<std::string>& sender_ids, |
+ const linked_ptr<RegistrationInfo>& registration_info, |
RegistrationRequest::Status status, |
const std::string& registration_id) { |
DCHECK(delegate_); |
Result result; |
PendingRegistrationRequests::iterator iter = |
- pending_registration_requests_.find(app_id); |
+ pending_registration_requests_.find(registration_info); |
if (iter == pending_registration_requests_.end()) |
result = UNKNOWN_ERROR; |
else if (status == RegistrationRequest::INVALID_SENDER) |
fgorski
2015/05/13 18:32:38
Are there any new cases on the server side? Could
jianli
2015/05/13 22:42:56
Confirmed that no new cases.
|
@@ -768,21 +791,20 @@ void GCMClientImpl::OnRegisterCompleted( |
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; |
+ registrations_[registration_info] = registration_id; |
// Save it in the persistent store. |
gcm_store_->AddRegistration( |
- app_id, |
- registration, |
+ registration_info->GetSerializedKey(), |
+ registration_info->GetSerializedValue(registration_id), |
base::Bind(&GCMClientImpl::UpdateRegistrationCallback, |
weak_ptr_factory_.GetWeakPtr())); |
} |
delegate_->OnRegisterFinished( |
- app_id, result == SUCCESS ? registration_id : std::string(), result); |
+ registration_info, |
+ result == SUCCESS ? registration_id : std::string(), |
+ result); |
if (iter != pending_registration_requests_.end()) { |
delete iter->second; |
@@ -790,47 +812,43 @@ void GCMClientImpl::OnRegisterCompleted( |
} |
} |
-void GCMClientImpl::Unregister(const std::string& app_id) { |
+void GCMClientImpl::Unregister( |
+ const linked_ptr<RegistrationInfo>& registration_info) { |
DCHECK_EQ(state_, READY); |
- if (pending_unregistration_requests_.count(app_id) == 1) |
+ if (pending_unregistration_requests_.count(registration_info) == 1) |
return; |
// Remove from the cache and persistent store. |
- registrations_.erase(app_id); |
+ registrations_.erase(registration_info); |
gcm_store_->RemoveRegistration( |
- app_id, |
+ registration_info->GetSerializedKey(), |
base::Bind(&GCMClientImpl::UpdateRegistrationCallback, |
weak_ptr_factory_.GetWeakPtr())); |
- UnregistrationRequest::RequestInfo request_info( |
- device_checkin_info_.android_id, |
- device_checkin_info_.secret, |
- app_id); |
- |
UnregistrationRequest* unregistration_request = new UnregistrationRequest( |
gservices_settings_.GetRegistrationURL(), |
- request_info, |
+ BuildUnregistrationRequestInfo(*registration_info).Pass(), |
GetGCMBackoffPolicy(), |
base::Bind(&GCMClientImpl::OnUnregisterCompleted, |
weak_ptr_factory_.GetWeakPtr(), |
- app_id), |
+ registration_info), |
url_request_context_getter_, |
&recorder_); |
- pending_unregistration_requests_[app_id] = unregistration_request; |
+ pending_unregistration_requests_[registration_info] = unregistration_request; |
unregistration_request->Start(); |
} |
void GCMClientImpl::OnUnregisterCompleted( |
- const std::string& app_id, |
+ const linked_ptr<RegistrationInfo>& registration_info, |
UnregistrationRequest::Status status) { |
- DVLOG(1) << "Unregister completed for app: " << app_id |
+ DVLOG(1) << "Unregister completed for app: " << registration_info->app_id |
<< " with " << (status ? "success." : "failure."); |
delegate_->OnUnregisterFinished( |
- app_id, |
+ registration_info, |
status == UnregistrationRequest::SUCCESS ? SUCCESS : SERVER_ERROR); |
PendingUnregistrationRequests::iterator iter = |
- pending_unregistration_requests_.find(app_id); |
+ pending_unregistration_requests_.find(registration_info); |
if (iter == pending_unregistration_requests_.end()) |
return; |
@@ -892,6 +910,70 @@ std::string GCMClientImpl::GetStateString() const { |
} |
} |
+scoped_ptr<RegistrationRequest::RequestInfo> |
+GCMClientImpl::BuildRegistrationRequestInfo( |
+ const RegistrationInfo& registration_info) const { |
+ const GCMRegistrationInfo* gcm_registration_info = |
+ GCMRegistrationInfo::FromRegistrationInfo(®istration_info); |
+ if (gcm_registration_info) { |
+ scoped_ptr<RegistrationRequest::GCMRequestInfo> request_info( |
+ new RegistrationRequest::GCMRequestInfo); |
+ request_info->chrome_version = chrome_build_info_.version; |
+ request_info->android_id = device_checkin_info_.android_id; |
+ request_info->security_token = device_checkin_info_.secret; |
+ request_info->app_id = registration_info.app_id; |
+ request_info->sender_ids = gcm_registration_info->sender_ids; |
+ return request_info.Pass(); |
+ } |
+ |
+ const InstanceIDTokenInfo* instance_id_token_info = |
+ InstanceIDTokenInfo::FromRegistrationInfo(®istration_info); |
+ if (!instance_id_token_info) |
+ return scoped_ptr<RegistrationRequest::RequestInfo>(); |
+ |
+ scoped_ptr<RegistrationRequest::InstanceIDRequestInfo> request_info( |
+ new RegistrationRequest::InstanceIDRequestInfo); |
+ request_info->chrome_version = chrome_build_info_.version; |
+ request_info->android_id = device_checkin_info_.android_id; |
+ request_info->security_token = device_checkin_info_.secret; |
+ request_info->app_id = registration_info.app_id; |
+ request_info->authorized_entity = instance_id_token_info->authorized_entity; |
+ request_info->scope = instance_id_token_info->scope; |
+ request_info->options = instance_id_token_info->options; |
+ return request_info.Pass(); |
+} |
+ |
+scoped_ptr<UnregistrationRequest::RequestInfo> |
+GCMClientImpl::BuildUnregistrationRequestInfo( |
fgorski
2015/05/13 18:32:39
Looks like this code belongs in registration_info
jianli
2015/05/13 22:42:56
To move these codes into registration_info, we wil
|
+ const RegistrationInfo& registration_info) const { |
+ const GCMRegistrationInfo* gcm_registration_info = |
+ GCMRegistrationInfo::FromRegistrationInfo(®istration_info); |
+ if (gcm_registration_info) { |
+ scoped_ptr<UnregistrationRequest::GCMRequestInfo> request_info( |
+ new UnregistrationRequest::GCMRequestInfo); |
+ request_info->chrome_version = chrome_build_info_.version; |
+ request_info->android_id = device_checkin_info_.android_id; |
+ request_info->security_token = device_checkin_info_.secret; |
+ request_info->app_id = registration_info.app_id; |
+ return request_info.Pass(); |
+ } |
+ |
+ const InstanceIDTokenInfo* instance_id_token_info = |
+ InstanceIDTokenInfo::FromRegistrationInfo(®istration_info); |
+ if (!instance_id_token_info) |
+ return scoped_ptr<UnregistrationRequest::RequestInfo>(); |
+ |
+ scoped_ptr<UnregistrationRequest::InstanceIDRequestInfo> request_info( |
+ new UnregistrationRequest::InstanceIDRequestInfo); |
+ request_info->chrome_version = chrome_build_info_.version; |
+ request_info->android_id = device_checkin_info_.android_id; |
+ request_info->security_token = device_checkin_info_.secret; |
+ request_info->app_id = registration_info.app_id; |
+ request_info->authorized_entity = instance_id_token_info->authorized_entity; |
+ request_info->scope = instance_id_token_info->scope; |
+ return request_info.Pass(); |
+} |
+ |
void GCMClientImpl::SetRecording(bool recording) { |
recorder_.SetRecording(recording); |
} |
@@ -918,7 +1000,7 @@ GCMClient::GCMStatistics GCMClientImpl::GetStatistics() const { |
for (RegistrationInfoMap::const_iterator it = registrations_.begin(); |
it != registrations_.end(); ++it) { |
- stats.registered_app_ids.push_back(it->first); |
+ stats.registered_app_ids.push_back(it->first->app_id); |
} |
return stats; |
} |
@@ -1036,21 +1118,45 @@ void GCMClientImpl::HandleIncomingDataMessage( |
const mcs_proto::DataMessageStanza& data_message_stanza, |
MessageData& message_data) { |
std::string app_id = data_message_stanza.category(); |
+ std::string sender = data_message_stanza.from(); |
// Drop the message when the app is not registered for the sender of the |
// message. |
- RegistrationInfoMap::iterator iter = registrations_.find(app_id); |
- bool not_registered = |
- iter == registrations_.end() || |
- std::find(iter->second->sender_ids.begin(), |
- iter->second->sender_ids.end(), |
- data_message_stanza.from()) == iter->second->sender_ids.end(); |
- recorder_.RecordDataMessageReceived(app_id, data_message_stanza.from(), |
- data_message_stanza.ByteSize(), !not_registered, |
+ bool registered = false; |
+ |
+ // First, find among all GCM registrations. |
+ scoped_ptr<GCMRegistrationInfo> gcm_registration(new GCMRegistrationInfo); |
+ gcm_registration->app_id = app_id; |
+ auto gcm_registration_iter = registrations_.find( |
+ make_linked_ptr<RegistrationInfo>(gcm_registration.release())); |
+ if (gcm_registration_iter != registrations_.end()) { |
+ GCMRegistrationInfo* cached_gcm_registration = |
+ GCMRegistrationInfo::FromRegistrationInfo( |
+ gcm_registration_iter->first.get()); |
+ if (cached_gcm_registration && |
+ std::find(cached_gcm_registration->sender_ids.begin(), |
+ cached_gcm_registration->sender_ids.end(), |
+ sender) != cached_gcm_registration->sender_ids.end()) |
+ registered = true; |
fgorski
2015/05/13 18:32:38
surround with {} because of multi-line condition
jianli
2015/05/13 22:42:56
Done.
|
+ } |
+ |
+ // Then, find among all InstanceID registrations. |
+ if (!registered) { |
+ scoped_ptr<InstanceIDTokenInfo> instance_id_token(new InstanceIDTokenInfo); |
+ instance_id_token->app_id = app_id; |
+ instance_id_token->authorized_entity = sender; |
+ instance_id_token->scope = kGCMScope; |
+ auto instance_id_token_iter = registrations_.find( |
+ make_linked_ptr<RegistrationInfo>(instance_id_token.release())); |
+ if (instance_id_token_iter != registrations_.end()) |
+ registered = true; |
+ } |
+ |
+ recorder_.RecordDataMessageReceived(app_id, sender, |
+ data_message_stanza.ByteSize(), registered, |
GCMStatsRecorder::DATA_MESSAGE); |
- if (not_registered) { |
+ if (!registered) |
return; |
- } |
IncomingMessage incoming_message; |
incoming_message.sender_id = data_message_stanza.from(); |
@@ -1088,7 +1194,7 @@ bool GCMClientImpl::HasStandaloneRegisteredApp() const { |
// Note that account mapper is not counted as a standalone app since it is |
// automatically started when other app uses GCM. |
return registrations_.size() > 1 || |
- !registrations_.count(kGCMAccountMapperAppId); |
+ !ExistsGCMRegistrationInMap(registrations_, kGCMAccountMapperAppId); |
fgorski
2015/05/13 18:32:39
Where is that defined?
jianli
2015/05/13 22:42:56
In registration_info.h
|
} |
} // namespace gcm |