Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(249)

Side by Side Diff: components/gcm_driver/gcm_client_impl.cc

Issue 2111973002: Add support for GCM subtypes to desktop Instance ID implementation (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@iid9push
Patch Set: Remove channel from product_category_for_subtypes, and address nits Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "components/gcm_driver/gcm_client_impl.h" 5 #include "components/gcm_driver/gcm_client_impl.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <memory> 9 #include <memory>
10 #include <utility> 10 #include <utility>
11 11
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/files/file_path.h" 13 #include "base/files/file_path.h"
14 #include "base/location.h" 14 #include "base/location.h"
15 #include "base/logging.h" 15 #include "base/logging.h"
16 #include "base/memory/ptr_util.h" 16 #include "base/memory/ptr_util.h"
17 #include "base/metrics/histogram_macros.h" 17 #include "base/metrics/histogram_macros.h"
18 #include "base/sequenced_task_runner.h" 18 #include "base/sequenced_task_runner.h"
19 #include "base/single_thread_task_runner.h" 19 #include "base/single_thread_task_runner.h"
20 #include "base/stl_util.h" 20 #include "base/stl_util.h"
21 #include "base/strings/string_number_conversions.h" 21 #include "base/strings/string_number_conversions.h"
22 #include "base/strings/stringprintf.h" 22 #include "base/strings/stringprintf.h"
23 #include "base/threading/thread_task_runner_handle.h" 23 #include "base/threading/thread_task_runner_handle.h"
24 #include "base/time/default_clock.h" 24 #include "base/time/default_clock.h"
25 #include "base/timer/timer.h" 25 #include "base/timer/timer.h"
26 #include "components/crx_file/id_util.h"
26 #include "components/gcm_driver/gcm_account_mapper.h" 27 #include "components/gcm_driver/gcm_account_mapper.h"
27 #include "components/gcm_driver/gcm_backoff_policy.h" 28 #include "components/gcm_driver/gcm_backoff_policy.h"
28 #include "google_apis/gcm/base/encryptor.h" 29 #include "google_apis/gcm/base/encryptor.h"
29 #include "google_apis/gcm/base/mcs_message.h" 30 #include "google_apis/gcm/base/mcs_message.h"
30 #include "google_apis/gcm/base/mcs_util.h" 31 #include "google_apis/gcm/base/mcs_util.h"
31 #include "google_apis/gcm/engine/checkin_request.h" 32 #include "google_apis/gcm/engine/checkin_request.h"
32 #include "google_apis/gcm/engine/connection_factory_impl.h" 33 #include "google_apis/gcm/engine/connection_factory_impl.h"
33 #include "google_apis/gcm/engine/gcm_registration_request_handler.h" 34 #include "google_apis/gcm/engine/gcm_registration_request_handler.h"
34 #include "google_apis/gcm/engine/gcm_store_impl.h" 35 #include "google_apis/gcm/engine/gcm_store_impl.h"
35 #include "google_apis/gcm/engine/gcm_unregistration_request_handler.h" 36 #include "google_apis/gcm/engine/gcm_unregistration_request_handler.h"
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 }; 80 };
80 81
81 const char kGCMScope[] = "GCM"; 82 const char kGCMScope[] = "GCM";
82 const int kMaxRegistrationRetries = 5; 83 const int kMaxRegistrationRetries = 5;
83 const int kMaxUnregistrationRetries = 5; 84 const int kMaxUnregistrationRetries = 5;
84 const char kMessageTypeDataMessage[] = "gcm"; 85 const char kMessageTypeDataMessage[] = "gcm";
85 const char kMessageTypeDeletedMessagesKey[] = "deleted_messages"; 86 const char kMessageTypeDeletedMessagesKey[] = "deleted_messages";
86 const char kMessageTypeKey[] = "message_type"; 87 const char kMessageTypeKey[] = "message_type";
87 const char kMessageTypeSendErrorKey[] = "send_error"; 88 const char kMessageTypeSendErrorKey[] = "send_error";
88 const char kSendErrorMessageIdKey[] = "google.message_id"; 89 const char kSendErrorMessageIdKey[] = "google.message_id";
90 const char kSubtypeKey[] = "subtype";
89 const char kSendMessageFromValue[] = "gcm@chrome.com"; 91 const char kSendMessageFromValue[] = "gcm@chrome.com";
90 const int64_t kDefaultUserSerialNumber = 0LL; 92 const int64_t kDefaultUserSerialNumber = 0LL;
91 const int kDestroyGCMStoreDelayMS = 5 * 60 * 1000; // 5 minutes. 93 const int kDestroyGCMStoreDelayMS = 5 * 60 * 1000; // 5 minutes.
92 94
93 GCMClient::Result ToGCMClientResult(MCSClient::MessageSendStatus status) { 95 GCMClient::Result ToGCMClientResult(MCSClient::MessageSendStatus status) {
94 switch (status) { 96 switch (status) {
95 case MCSClient::QUEUED: 97 case MCSClient::QUEUED:
96 return GCMClient::SUCCESS; 98 return GCMClient::SUCCESS;
97 case MCSClient::QUEUE_SIZE_LIMIT_REACHED: 99 case MCSClient::QUEUE_SIZE_LIMIT_REACHED:
98 return GCMClient::NETWORK_ERROR; 100 return GCMClient::NETWORK_ERROR;
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 std::string* extra_data) { 211 std::string* extra_data) {
210 DCHECK(instance_id && extra_data); 212 DCHECK(instance_id && extra_data);
211 std::size_t pos = serialized_data.find(','); 213 std::size_t pos = serialized_data.find(',');
212 if (pos == std::string::npos) 214 if (pos == std::string::npos)
213 return false; 215 return false;
214 *instance_id = serialized_data.substr(0, pos); 216 *instance_id = serialized_data.substr(0, pos);
215 *extra_data = serialized_data.substr(pos + 1); 217 *extra_data = serialized_data.substr(pos + 1);
216 return !instance_id->empty() && !extra_data->empty(); 218 return !instance_id->empty() && !extra_data->empty();
217 } 219 }
218 220
221 bool InstanceIDUsesSubtypeForAppId(const std::string& app_id) {
222 // Always use subtypes with Instance ID, except for Chrome Apps/Extensions.
223 return !crx_file::id_util::IdIsValid(app_id);
224 }
225
219 void RecordOutgoingMessageToUMA(const gcm::OutgoingMessage& message) { 226 void RecordOutgoingMessageToUMA(const gcm::OutgoingMessage& message) {
220 OutgoingMessageTTLCategory ttl_category; 227 OutgoingMessageTTLCategory ttl_category;
221 if (message.time_to_live == 0) 228 if (message.time_to_live == 0)
222 ttl_category = TTL_ZERO; 229 ttl_category = TTL_ZERO;
223 else if (message.time_to_live <= 60 ) 230 else if (message.time_to_live <= 60 )
224 ttl_category = TTL_LESS_THAN_OR_EQUAL_TO_ONE_MINUTE; 231 ttl_category = TTL_LESS_THAN_OR_EQUAL_TO_ONE_MINUTE;
225 else if (message.time_to_live <= 60 * 60) 232 else if (message.time_to_live <= 60 * 60)
226 ttl_category = TTL_LESS_THAN_OR_EQUAL_TO_ONE_HOUR; 233 ttl_category = TTL_LESS_THAN_OR_EQUAL_TO_ONE_HOUR;
227 else if (message.time_to_live <= 24 * 60 * 60) 234 else if (message.time_to_live <= 24 * 60 * 60)
228 ttl_category = TTL_LESS_THAN_OR_EQUAL_TO_ONE_DAY; 235 ttl_category = TTL_LESS_THAN_OR_EQUAL_TO_ONE_DAY;
(...skipping 614 matching lines...) Expand 10 before | Expand all | Expand 10 after
843 checkin_request_.reset(); 850 checkin_request_.reset();
844 // Delete all of the pending registration and unregistration requests. 851 // Delete all of the pending registration and unregistration requests.
845 pending_registration_requests_.clear(); 852 pending_registration_requests_.clear();
846 pending_unregistration_requests_.clear(); 853 pending_unregistration_requests_.clear();
847 } 854 }
848 855
849 void GCMClientImpl::Register( 856 void GCMClientImpl::Register(
850 const linked_ptr<RegistrationInfo>& registration_info) { 857 const linked_ptr<RegistrationInfo>& registration_info) {
851 DCHECK_EQ(state_, READY); 858 DCHECK_EQ(state_, READY);
852 859
860 // Registrations should never pass as an app_id the special category used
861 // internally when registering with a subtype. See security note in
862 // GCMClientImpl::HandleIncomingMessage.
863 CHECK_NE(registration_info->app_id,
864 chrome_build_info_.product_category_for_subtypes);
865
853 // Find and use the cached registration ID. 866 // Find and use the cached registration ID.
854 RegistrationInfoMap::const_iterator registrations_iter = 867 RegistrationInfoMap::const_iterator registrations_iter =
855 registrations_.find(registration_info); 868 registrations_.find(registration_info);
856 if (registrations_iter != registrations_.end()) { 869 if (registrations_iter != registrations_.end()) {
857 bool matched = true; 870 bool matched = true;
858 871
859 // For GCM registration, we also match the sender IDs since multiple 872 // For GCM registration, we also match the sender IDs since multiple
860 // registrations are not supported. 873 // registrations are not supported.
861 const GCMRegistrationInfo* gcm_registration_info = 874 const GCMRegistrationInfo* gcm_registration_info =
862 GCMRegistrationInfo::FromRegistrationInfo(registration_info.get()); 875 GCMRegistrationInfo::FromRegistrationInfo(registration_info.get());
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
909 request_handler.reset(new InstanceIDGetTokenRequestHandler( 922 request_handler.reset(new InstanceIDGetTokenRequestHandler(
910 instance_id_iter->second.first, 923 instance_id_iter->second.first,
911 instance_id_token_info->authorized_entity, 924 instance_id_token_info->authorized_entity,
912 instance_id_token_info->scope, 925 instance_id_token_info->scope,
913 ConstructGCMVersion(chrome_build_info_.version), 926 ConstructGCMVersion(chrome_build_info_.version),
914 instance_id_token_info->options)); 927 instance_id_token_info->options));
915 source_to_record = instance_id_token_info->authorized_entity + "/" + 928 source_to_record = instance_id_token_info->authorized_entity + "/" +
916 instance_id_token_info->scope; 929 instance_id_token_info->scope;
917 } 930 }
918 931
919 RegistrationRequest::RequestInfo request_info( 932 bool use_subtype = instance_id_token_info &&
920 device_checkin_info_.android_id, 933 InstanceIDUsesSubtypeForAppId(registration_info->app_id);
921 device_checkin_info_.secret, 934 std::string category = use_subtype
922 registration_info->app_id); 935 ? chrome_build_info_.product_category_for_subtypes
936 : registration_info->app_id;
937 std::string subtype = use_subtype ? registration_info->app_id : std::string();
938 RegistrationRequest::RequestInfo request_info(device_checkin_info_.android_id,
939 device_checkin_info_.secret,
940 category, subtype);
923 941
924 std::unique_ptr<RegistrationRequest> registration_request( 942 std::unique_ptr<RegistrationRequest> registration_request(
925 new RegistrationRequest( 943 new RegistrationRequest(
926 gservices_settings_.GetRegistrationURL(), request_info, 944 gservices_settings_.GetRegistrationURL(), request_info,
927 std::move(request_handler), GetGCMBackoffPolicy(), 945 std::move(request_handler), GetGCMBackoffPolicy(),
928 base::Bind(&GCMClientImpl::OnRegisterCompleted, 946 base::Bind(&GCMClientImpl::OnRegisterCompleted,
929 weak_ptr_factory_.GetWeakPtr(), registration_info), 947 weak_ptr_factory_.GetWeakPtr(), registration_info),
930 kMaxRegistrationRetries, url_request_context_getter_, &recorder_, 948 kMaxRegistrationRetries, url_request_context_getter_, &recorder_,
931 source_to_record)); 949 source_to_record));
932 registration_request->Start(); 950 registration_request->Start();
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
995 const InstanceIDTokenInfo* instance_id_token_info = 1013 const InstanceIDTokenInfo* instance_id_token_info =
996 InstanceIDTokenInfo::FromRegistrationInfo(registration_info.get()); 1014 InstanceIDTokenInfo::FromRegistrationInfo(registration_info.get());
997 if (instance_id_token_info) { 1015 if (instance_id_token_info) {
998 auto instance_id_iter = instance_id_data_.find(registration_info->app_id); 1016 auto instance_id_iter = instance_id_data_.find(registration_info->app_id);
999 if (instance_id_iter == instance_id_data_.end()) { 1017 if (instance_id_iter == instance_id_data_.end()) {
1000 // This should not be reached since we should not delete tokens when 1018 // This should not be reached since we should not delete tokens when
1001 // an InstanceID has not been created yet. 1019 // an InstanceID has not been created yet.
1002 NOTREACHED(); 1020 NOTREACHED();
1003 return; 1021 return;
1004 } 1022 }
1023
1005 request_handler.reset(new InstanceIDDeleteTokenRequestHandler( 1024 request_handler.reset(new InstanceIDDeleteTokenRequestHandler(
1006 instance_id_iter->second.first, 1025 instance_id_iter->second.first,
1007 instance_id_token_info->authorized_entity, 1026 instance_id_token_info->authorized_entity,
1008 instance_id_token_info->scope, 1027 instance_id_token_info->scope,
1009 ConstructGCMVersion(chrome_build_info_.version))); 1028 ConstructGCMVersion(chrome_build_info_.version)));
1010 source_to_record = instance_id_token_info->authorized_entity + "/" + 1029 source_to_record = instance_id_token_info->authorized_entity + "/" +
1011 instance_id_token_info->scope; 1030 instance_id_token_info->scope;
1012 } 1031 }
1013 1032
1014 // Remove the registration/token(s) from the cache and the store. 1033 // Remove the registration/token(s) from the cache and the store.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1050 return; 1069 return;
1051 } 1070 }
1052 registrations_.erase(iter); 1071 registrations_.erase(iter);
1053 1072
1054 gcm_store_->RemoveRegistration( 1073 gcm_store_->RemoveRegistration(
1055 registration_info->GetSerializedKey(), 1074 registration_info->GetSerializedKey(),
1056 base::Bind(&GCMClientImpl::UpdateRegistrationCallback, 1075 base::Bind(&GCMClientImpl::UpdateRegistrationCallback,
1057 weak_ptr_factory_.GetWeakPtr())); 1076 weak_ptr_factory_.GetWeakPtr()));
1058 } 1077 }
1059 1078
1079 bool use_subtype = instance_id_token_info &&
1080 InstanceIDUsesSubtypeForAppId(registration_info->app_id);
1081 std::string category = use_subtype
1082 ? chrome_build_info_.product_category_for_subtypes
1083 : registration_info->app_id;
1084 std::string subtype = use_subtype ? registration_info->app_id : std::string();
1060 UnregistrationRequest::RequestInfo request_info( 1085 UnregistrationRequest::RequestInfo request_info(
1061 device_checkin_info_.android_id, 1086 device_checkin_info_.android_id, device_checkin_info_.secret, category,
1062 device_checkin_info_.secret, 1087 subtype);
1063 registration_info->app_id);
1064 1088
1065 std::unique_ptr<UnregistrationRequest> unregistration_request( 1089 std::unique_ptr<UnregistrationRequest> unregistration_request(
1066 new UnregistrationRequest( 1090 new UnregistrationRequest(
1067 gservices_settings_.GetRegistrationURL(), request_info, 1091 gservices_settings_.GetRegistrationURL(), request_info,
1068 std::move(request_handler), GetGCMBackoffPolicy(), 1092 std::move(request_handler), GetGCMBackoffPolicy(),
1069 base::Bind(&GCMClientImpl::OnUnregisterCompleted, 1093 base::Bind(&GCMClientImpl::OnUnregisterCompleted,
1070 weak_ptr_factory_.GetWeakPtr(), registration_info), 1094 weak_ptr_factory_.GetWeakPtr(), registration_info),
1071 kMaxUnregistrationRetries, url_request_context_getter_, &recorder_, 1095 kMaxUnregistrationRetries, url_request_context_getter_, &recorder_,
1072 source_to_record)); 1096 source_to_record));
1073 unregistration_request->Start(); 1097 unregistration_request->Start();
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
1253 } 1277 }
1254 1278
1255 void GCMClientImpl::HandleIncomingMessage(const gcm::MCSMessage& message) { 1279 void GCMClientImpl::HandleIncomingMessage(const gcm::MCSMessage& message) {
1256 DCHECK(delegate_); 1280 DCHECK(delegate_);
1257 1281
1258 const mcs_proto::DataMessageStanza& data_message_stanza = 1282 const mcs_proto::DataMessageStanza& data_message_stanza =
1259 reinterpret_cast<const mcs_proto::DataMessageStanza&>( 1283 reinterpret_cast<const mcs_proto::DataMessageStanza&>(
1260 message.GetProtobuf()); 1284 message.GetProtobuf());
1261 DCHECK_EQ(data_message_stanza.device_user_id(), kDefaultUserSerialNumber); 1285 DCHECK_EQ(data_message_stanza.device_user_id(), kDefaultUserSerialNumber);
1262 1286
1263 // Copying all the data from the stanza to a MessageData object. When present, 1287 // Copy all the data from the stanza to a MessageData object. When present,
1264 // keys like kMessageTypeKey or kSendErrorMessageIdKey will be filtered out 1288 // keys like kSubtypeKey, kMessageTypeKey or kSendErrorMessageIdKey will be
1265 // later. 1289 // filtered out later.
1266 MessageData message_data; 1290 MessageData message_data;
1267 for (int i = 0; i < data_message_stanza.app_data_size(); ++i) { 1291 for (int i = 0; i < data_message_stanza.app_data_size(); ++i) {
1268 std::string key = data_message_stanza.app_data(i).key(); 1292 std::string key = data_message_stanza.app_data(i).key();
1269 message_data[key] = data_message_stanza.app_data(i).value(); 1293 message_data[key] = data_message_stanza.app_data(i).value();
1270 } 1294 }
1271 1295
1296 std::string subtype;
1297 auto subtype_iter = message_data.find(kSubtypeKey);
1298 if (subtype_iter != message_data.end()) {
1299 subtype = subtype_iter->second;
1300 message_data.erase(subtype_iter);
1301 }
1302
1303 // SECURITY NOTE: Subtypes received from GCM *cannot* be trusted for
1304 // registrations without a subtype (as the sender can pass any subtype they
1305 // want). They can however be trusted for registrations that are known to have
1306 // a subtype (as GCM overwrites anything passed by the sender).
1307 //
1308 // So a given Chrome profile always passes a fixed string called
1309 // |product_category_for_subtypes| (of the form "com.chrome.macosx") as the
1310 // category when registering with a subtype, and incoming subtypes are only
1311 // trusted for that category.
1312 //
1313 // TODO(johnme): Remove this check if GCM starts sending the subtype in a
1314 // field that's guaranteed to be trusted (b/18198485).
1315 //
1316 // (On Android, all registrations made by Chrome on behalf of third-party
1317 // apps/extensions/websites have always had a subtype, so such a check is not
1318 // necessary - or possible, since category is fixed to the true package name).
1319 bool subtype_is_trusted = data_message_stanza.category() ==
1320 chrome_build_info_.product_category_for_subtypes;
1321 bool use_subtype = subtype_is_trusted && !subtype.empty();
1322 std::string app_id = use_subtype ? subtype : data_message_stanza.category();
1323
1272 MessageType message_type = DATA_MESSAGE; 1324 MessageType message_type = DATA_MESSAGE;
1273 MessageData::iterator iter = message_data.find(kMessageTypeKey); 1325 MessageData::iterator type_iter = message_data.find(kMessageTypeKey);
1274 if (iter != message_data.end()) { 1326 if (type_iter != message_data.end()) {
1275 message_type = DecodeMessageType(iter->second); 1327 message_type = DecodeMessageType(type_iter->second);
1276 message_data.erase(iter); 1328 message_data.erase(type_iter);
1277 } 1329 }
1278 1330
1279 switch (message_type) { 1331 switch (message_type) {
1280 case DATA_MESSAGE: 1332 case DATA_MESSAGE:
1281 HandleIncomingDataMessage(data_message_stanza, message_data); 1333 HandleIncomingDataMessage(app_id, use_subtype, data_message_stanza,
1334 message_data);
1282 break; 1335 break;
1283 case DELETED_MESSAGES: 1336 case DELETED_MESSAGES:
1284 recorder_.RecordDataMessageReceived(data_message_stanza.category(), 1337 recorder_.RecordDataMessageReceived(app_id, data_message_stanza.from(),
1285 data_message_stanza.from(), 1338 data_message_stanza.ByteSize(), true,
1286 data_message_stanza.ByteSize(),
1287 true,
1288 GCMStatsRecorder::DELETED_MESSAGES); 1339 GCMStatsRecorder::DELETED_MESSAGES);
1289 delegate_->OnMessagesDeleted(data_message_stanza.category()); 1340 delegate_->OnMessagesDeleted(app_id);
1290 break; 1341 break;
1291 case SEND_ERROR: 1342 case SEND_ERROR:
1292 HandleIncomingSendError(data_message_stanza, message_data); 1343 HandleIncomingSendError(app_id, data_message_stanza, message_data);
1293 break; 1344 break;
1294 case UNKNOWN: 1345 case UNKNOWN:
1295 default: // Treat default the same as UNKNOWN. 1346 default: // Treat default the same as UNKNOWN.
1296 DVLOG(1) << "Unknown message_type received. Message ignored. " 1347 DVLOG(1) << "Unknown message_type received. Message ignored. "
1297 << "App ID: " << data_message_stanza.category() << "."; 1348 << "App ID: " << app_id << ".";
1298 break; 1349 break;
1299 } 1350 }
1300 } 1351 }
1301 1352
1302 void GCMClientImpl::HandleIncomingDataMessage( 1353 void GCMClientImpl::HandleIncomingDataMessage(
1354 const std::string& app_id,
1355 bool was_subtype,
1303 const mcs_proto::DataMessageStanza& data_message_stanza, 1356 const mcs_proto::DataMessageStanza& data_message_stanza,
1304 MessageData& message_data) { 1357 MessageData& message_data) {
1305 std::string app_id = data_message_stanza.category();
1306 std::string sender = data_message_stanza.from(); 1358 std::string sender = data_message_stanza.from();
1307 1359
1308 // Drop the message when the app is not registered for the sender of the 1360 // Drop the message when the app is not registered for the sender of the
1309 // message. 1361 // message.
1310 bool registered = false; 1362 bool registered = false;
1311 1363
1312 // First, find among all GCM registrations. 1364 // First, find among all GCM registrations.
1313 std::unique_ptr<GCMRegistrationInfo> gcm_registration( 1365 std::unique_ptr<GCMRegistrationInfo> gcm_registration(
1314 new GCMRegistrationInfo); 1366 new GCMRegistrationInfo);
1315 gcm_registration->app_id = app_id; 1367 gcm_registration->app_id = app_id;
1316 auto gcm_registration_iter = registrations_.find( 1368 auto gcm_registration_iter = registrations_.find(
1317 make_linked_ptr<RegistrationInfo>(gcm_registration.release())); 1369 make_linked_ptr<RegistrationInfo>(gcm_registration.release()));
1318 if (gcm_registration_iter != registrations_.end()) { 1370 if (gcm_registration_iter != registrations_.end()) {
1319 GCMRegistrationInfo* cached_gcm_registration = 1371 GCMRegistrationInfo* cached_gcm_registration =
1320 GCMRegistrationInfo::FromRegistrationInfo( 1372 GCMRegistrationInfo::FromRegistrationInfo(
1321 gcm_registration_iter->first.get()); 1373 gcm_registration_iter->first.get());
1322 if (cached_gcm_registration && 1374 if (cached_gcm_registration &&
1323 std::find(cached_gcm_registration->sender_ids.begin(), 1375 std::find(cached_gcm_registration->sender_ids.begin(),
1324 cached_gcm_registration->sender_ids.end(), 1376 cached_gcm_registration->sender_ids.end(),
1325 sender) != cached_gcm_registration->sender_ids.end()) { 1377 sender) != cached_gcm_registration->sender_ids.end()) {
1326 registered = true; 1378 if (was_subtype)
1379 DLOG(ERROR) << "GCM message for non-IID " << app_id << " used subtype";
1380 else
1381 registered = true;
1327 } 1382 }
1328 } 1383 }
1329 1384
1330 // Then, find among all InstanceID registrations. 1385 // Then, find among all InstanceID registrations.
1331 if (!registered) { 1386 if (!registered) {
1332 std::unique_ptr<InstanceIDTokenInfo> instance_id_token( 1387 std::unique_ptr<InstanceIDTokenInfo> instance_id_token(
1333 new InstanceIDTokenInfo); 1388 new InstanceIDTokenInfo);
1334 instance_id_token->app_id = app_id; 1389 instance_id_token->app_id = app_id;
1335 instance_id_token->authorized_entity = sender; 1390 instance_id_token->authorized_entity = sender;
1336 instance_id_token->scope = kGCMScope; 1391 instance_id_token->scope = kGCMScope;
1337 auto instance_id_token_iter = registrations_.find( 1392 auto instance_id_token_iter = registrations_.find(
1338 make_linked_ptr<RegistrationInfo>(instance_id_token.release())); 1393 make_linked_ptr<RegistrationInfo>(instance_id_token.release()));
1339 if (instance_id_token_iter != registrations_.end()) 1394 if (instance_id_token_iter != registrations_.end()) {
1340 registered = true; 1395 if (was_subtype != InstanceIDUsesSubtypeForAppId(app_id)) {
1396 DLOG(ERROR) << "GCM message for " << app_id
1397 << " incorrectly had was_subtype = " << was_subtype;
1398 } else {
1399 registered = true;
1400 }
1401 }
1341 } 1402 }
1342 1403
1343 recorder_.RecordDataMessageReceived(app_id, sender, 1404 recorder_.RecordDataMessageReceived(app_id, sender,
1344 data_message_stanza.ByteSize(), registered, 1405 data_message_stanza.ByteSize(), registered,
1345 GCMStatsRecorder::DATA_MESSAGE); 1406 GCMStatsRecorder::DATA_MESSAGE);
1346 if (!registered) 1407 if (!registered)
1347 return; 1408 return;
1348 1409
1349 IncomingMessage incoming_message; 1410 IncomingMessage incoming_message;
1350 incoming_message.sender_id = data_message_stanza.from(); 1411 incoming_message.sender_id = data_message_stanza.from();
1351 if (data_message_stanza.has_token()) 1412 if (data_message_stanza.has_token())
1352 incoming_message.collapse_key = data_message_stanza.token(); 1413 incoming_message.collapse_key = data_message_stanza.token();
1353 incoming_message.data = message_data; 1414 incoming_message.data = message_data;
1354 incoming_message.raw_data = data_message_stanza.raw_data(); 1415 incoming_message.raw_data = data_message_stanza.raw_data();
1355 1416
1356 delegate_->OnMessageReceived(app_id, incoming_message); 1417 delegate_->OnMessageReceived(app_id, incoming_message);
1357 } 1418 }
1358 1419
1359 void GCMClientImpl::HandleIncomingSendError( 1420 void GCMClientImpl::HandleIncomingSendError(
1421 const std::string& app_id,
1360 const mcs_proto::DataMessageStanza& data_message_stanza, 1422 const mcs_proto::DataMessageStanza& data_message_stanza,
1361 MessageData& message_data) { 1423 MessageData& message_data) {
1362 SendErrorDetails send_error_details; 1424 SendErrorDetails send_error_details;
1363 send_error_details.additional_data = message_data; 1425 send_error_details.additional_data = message_data;
1364 send_error_details.result = SERVER_ERROR; 1426 send_error_details.result = SERVER_ERROR;
1365 1427
1366 MessageData::iterator iter = 1428 MessageData::iterator iter =
1367 send_error_details.additional_data.find(kSendErrorMessageIdKey); 1429 send_error_details.additional_data.find(kSendErrorMessageIdKey);
1368 if (iter != send_error_details.additional_data.end()) { 1430 if (iter != send_error_details.additional_data.end()) {
1369 send_error_details.message_id = iter->second; 1431 send_error_details.message_id = iter->second;
1370 send_error_details.additional_data.erase(iter); 1432 send_error_details.additional_data.erase(iter);
1371 } 1433 }
1372 1434
1373 recorder_.RecordIncomingSendError( 1435 recorder_.RecordIncomingSendError(app_id, data_message_stanza.to(),
1374 data_message_stanza.category(), 1436 data_message_stanza.id());
1375 data_message_stanza.to(), 1437 delegate_->OnMessageSendError(app_id, send_error_details);
1376 data_message_stanza.id());
1377 delegate_->OnMessageSendError(data_message_stanza.category(),
1378 send_error_details);
1379 } 1438 }
1380 1439
1381 bool GCMClientImpl::HasStandaloneRegisteredApp() const { 1440 bool GCMClientImpl::HasStandaloneRegisteredApp() const {
1382 if (registrations_.empty()) 1441 if (registrations_.empty())
1383 return false; 1442 return false;
1384 // Note that account mapper is not counted as a standalone app since it is 1443 // Note that account mapper is not counted as a standalone app since it is
1385 // automatically started when other app uses GCM. 1444 // automatically started when other app uses GCM.
1386 return registrations_.size() > 1 || 1445 return registrations_.size() > 1 ||
1387 !ExistsGCMRegistrationInMap(registrations_, kGCMAccountMapperAppId); 1446 !ExistsGCMRegistrationInMap(registrations_, kGCMAccountMapperAppId);
1388 } 1447 }
1389 1448
1390 } // namespace gcm 1449 } // namespace gcm
OLDNEW
« no previous file with comments | « components/gcm_driver/gcm_client_impl.h ('k') | components/gcm_driver/gcm_client_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698