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

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

Issue 1137463003: Support getting and deleting token for Instance ID. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Patch to land Created 5 years, 6 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 "base/bind.h" 7 #include "base/bind.h"
8 #include "base/files/file_path.h" 8 #include "base/files/file_path.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
11 #include "base/message_loop/message_loop.h" 11 #include "base/message_loop/message_loop.h"
12 #include "base/metrics/histogram_macros.h" 12 #include "base/metrics/histogram_macros.h"
13 #include "base/sequenced_task_runner.h" 13 #include "base/sequenced_task_runner.h"
14 #include "base/stl_util.h" 14 #include "base/stl_util.h"
15 #include "base/strings/string_number_conversions.h" 15 #include "base/strings/string_number_conversions.h"
16 #include "base/strings/stringprintf.h" 16 #include "base/strings/stringprintf.h"
17 #include "base/time/default_clock.h" 17 #include "base/time/default_clock.h"
18 #include "base/timer/timer.h" 18 #include "base/timer/timer.h"
19 #include "components/gcm_driver/gcm_account_mapper.h" 19 #include "components/gcm_driver/gcm_account_mapper.h"
20 #include "components/gcm_driver/gcm_backoff_policy.h" 20 #include "components/gcm_driver/gcm_backoff_policy.h"
21 #include "google_apis/gcm/base/encryptor.h" 21 #include "google_apis/gcm/base/encryptor.h"
22 #include "google_apis/gcm/base/mcs_message.h" 22 #include "google_apis/gcm/base/mcs_message.h"
23 #include "google_apis/gcm/base/mcs_util.h" 23 #include "google_apis/gcm/base/mcs_util.h"
24 #include "google_apis/gcm/engine/checkin_request.h" 24 #include "google_apis/gcm/engine/checkin_request.h"
25 #include "google_apis/gcm/engine/connection_factory_impl.h" 25 #include "google_apis/gcm/engine/connection_factory_impl.h"
26 #include "google_apis/gcm/engine/gcm_registration_request_handler.h"
26 #include "google_apis/gcm/engine/gcm_store_impl.h" 27 #include "google_apis/gcm/engine/gcm_store_impl.h"
28 #include "google_apis/gcm/engine/gcm_unregistration_request_handler.h"
29 #include "google_apis/gcm/engine/instance_id_delete_token_request_handler.h"
30 #include "google_apis/gcm/engine/instance_id_get_token_request_handler.h"
27 #include "google_apis/gcm/monitoring/gcm_stats_recorder.h" 31 #include "google_apis/gcm/monitoring/gcm_stats_recorder.h"
28 #include "google_apis/gcm/protocol/checkin.pb.h" 32 #include "google_apis/gcm/protocol/checkin.pb.h"
29 #include "google_apis/gcm/protocol/mcs.pb.h" 33 #include "google_apis/gcm/protocol/mcs.pb.h"
30 #include "net/http/http_network_session.h" 34 #include "net/http/http_network_session.h"
31 #include "net/http/http_transaction_factory.h" 35 #include "net/http/http_transaction_factory.h"
32 #include "net/url_request/url_request_context.h" 36 #include "net/url_request/url_request_context.h"
33 #include "url/gurl.h" 37 #include "url/gurl.h"
34 38
35 namespace gcm { 39 namespace gcm {
36 40
(...skipping 23 matching lines...) Expand all
60 64
61 enum ResetStoreError { 65 enum ResetStoreError {
62 DESTROYING_STORE_FAILED, 66 DESTROYING_STORE_FAILED,
63 INFINITE_STORE_RESET, 67 INFINITE_STORE_RESET,
64 // NOTE: always keep this entry at the end. Add new value only immediately 68 // NOTE: always keep this entry at the end. Add new value only immediately
65 // above this line. Make sure to update the corresponding histogram enum 69 // above this line. Make sure to update the corresponding histogram enum
66 // accordingly. 70 // accordingly.
67 RESET_STORE_ERROR_COUNT 71 RESET_STORE_ERROR_COUNT
68 }; 72 };
69 73
74 const char kGCMScope[] = "GCM";
70 const int kMaxRegistrationRetries = 5; 75 const int kMaxRegistrationRetries = 5;
71 const char kMessageTypeDataMessage[] = "gcm"; 76 const char kMessageTypeDataMessage[] = "gcm";
72 const char kMessageTypeDeletedMessagesKey[] = "deleted_messages"; 77 const char kMessageTypeDeletedMessagesKey[] = "deleted_messages";
73 const char kMessageTypeKey[] = "message_type"; 78 const char kMessageTypeKey[] = "message_type";
74 const char kMessageTypeSendErrorKey[] = "send_error"; 79 const char kMessageTypeSendErrorKey[] = "send_error";
75 const char kSendErrorMessageIdKey[] = "google.message_id"; 80 const char kSendErrorMessageIdKey[] = "google.message_id";
76 const char kSendMessageFromValue[] = "gcm@chrome.com"; 81 const char kSendMessageFromValue[] = "gcm@chrome.com";
77 const int64 kDefaultUserSerialNumber = 0LL; 82 const int64 kDefaultUserSerialNumber = 0LL;
78 83
79 GCMClient::Result ToGCMClientResult(MCSClient::MessageSendStatus status) { 84 GCMClient::Result ToGCMClientResult(MCSClient::MessageSendStatus status) {
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 MessageType DecodeMessageType(const std::string& value) { 167 MessageType DecodeMessageType(const std::string& value) {
163 if (kMessageTypeDeletedMessagesKey == value) 168 if (kMessageTypeDeletedMessagesKey == value)
164 return DELETED_MESSAGES; 169 return DELETED_MESSAGES;
165 if (kMessageTypeSendErrorKey == value) 170 if (kMessageTypeSendErrorKey == value)
166 return SEND_ERROR; 171 return SEND_ERROR;
167 if (kMessageTypeDataMessage == value) 172 if (kMessageTypeDataMessage == value)
168 return DATA_MESSAGE; 173 return DATA_MESSAGE;
169 return UNKNOWN; 174 return UNKNOWN;
170 } 175 }
171 176
177 int ConstructGCMVersion(const std::string& chrome_version) {
178 // Major Chrome version is passed as GCM version.
179 size_t pos = chrome_version.find('.');
180 if (pos == std::string::npos) {
181 NOTREACHED();
182 return 0;
183 }
184
185 int gcm_version = 0;
186 base::StringToInt(
187 base::StringPiece(chrome_version.c_str(), pos), &gcm_version);
188 return gcm_version;
189 }
190
191 std::string SerializeInstanceIDData(const std::string& instance_id,
192 const std::string& extra_data) {
193 DCHECK(!instance_id.empty() && !extra_data.empty());
194 DCHECK(instance_id.find(',') == std::string::npos);
195 return instance_id + "," + extra_data;
196 }
197
198 bool DeserializeInstanceIDData(const std::string& serialized_data,
199 std::string* instance_id,
200 std::string* extra_data) {
201 DCHECK(instance_id && extra_data);
202 std::size_t pos = serialized_data.find(',');
203 if (pos == std::string::npos)
204 return false;
205 *instance_id = serialized_data.substr(0, pos);
206 *extra_data = serialized_data.substr(pos + 1);
207 return !instance_id->empty() && !extra_data->empty();
208 }
209
172 void RecordOutgoingMessageToUMA( 210 void RecordOutgoingMessageToUMA(
173 const gcm::GCMClient::OutgoingMessage& message) { 211 const gcm::GCMClient::OutgoingMessage& message) {
174 OutgoingMessageTTLCategory ttl_category; 212 OutgoingMessageTTLCategory ttl_category;
175 if (message.time_to_live == 0) 213 if (message.time_to_live == 0)
176 ttl_category = TTL_ZERO; 214 ttl_category = TTL_ZERO;
177 else if (message.time_to_live <= 60 ) 215 else if (message.time_to_live <= 60 )
178 ttl_category = TTL_LESS_THAN_OR_EQUAL_TO_ONE_MINUTE; 216 ttl_category = TTL_LESS_THAN_OR_EQUAL_TO_ONE_MINUTE;
179 else if (message.time_to_live <= 60 * 60) 217 else if (message.time_to_live <= 60 * 60)
180 ttl_category = TTL_LESS_THAN_OR_EQUAL_TO_ONE_HOUR; 218 ttl_category = TTL_LESS_THAN_OR_EQUAL_TO_ONE_HOUR;
181 else if (message.time_to_live <= 24 * 60 * 60) 219 else if (message.time_to_live <= 24 * 60 * 60)
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 366
329 void GCMClientImpl::OnLoadCompleted(scoped_ptr<GCMStore::LoadResult> result) { 367 void GCMClientImpl::OnLoadCompleted(scoped_ptr<GCMStore::LoadResult> result) {
330 DCHECK_EQ(LOADING, state_); 368 DCHECK_EQ(LOADING, state_);
331 369
332 if (!result->success) { 370 if (!result->success) {
333 ResetStore(); 371 ResetStore();
334 return; 372 return;
335 } 373 }
336 gcm_store_reset_ = false; 374 gcm_store_reset_ = false;
337 375
338 registrations_ = result->registrations;
339 device_checkin_info_.android_id = result->device_android_id; 376 device_checkin_info_.android_id = result->device_android_id;
340 device_checkin_info_.secret = result->device_security_token; 377 device_checkin_info_.secret = result->device_security_token;
341 device_checkin_info_.last_checkin_accounts = result->last_checkin_accounts; 378 device_checkin_info_.last_checkin_accounts = result->last_checkin_accounts;
342 // A case where there were previously no accounts reported with checkin is 379 // A case where there were previously no accounts reported with checkin is
343 // considered to be the same as when the list of accounts is empty. It enables 380 // considered to be the same as when the list of accounts is empty. It enables
344 // scheduling a periodic checkin for devices with no signed in users 381 // scheduling a periodic checkin for devices with no signed in users
345 // immediately after restart, while keeping |accounts_set == false| delays the 382 // immediately after restart, while keeping |accounts_set == false| delays the
346 // checkin until the list of accounts is set explicitly. 383 // checkin until the list of accounts is set explicitly.
347 if (result->last_checkin_accounts.size() == 0) 384 if (result->last_checkin_accounts.size() == 0)
348 device_checkin_info_.accounts_set = true; 385 device_checkin_info_.accounts_set = true;
349 last_checkin_time_ = result->last_checkin_time; 386 last_checkin_time_ = result->last_checkin_time;
350 gservices_settings_.UpdateFromLoadResult(*result); 387 gservices_settings_.UpdateFromLoadResult(*result);
351 instance_id_data_ = result->instance_id_data; 388
389 for (auto iter = result->registrations.begin();
390 iter != result->registrations.end();
391 ++iter) {
392 std::string registration_id;
393 scoped_ptr<RegistrationInfo> registration =
394 RegistrationInfo::BuildFromString(
395 iter->first, iter->second, &registration_id);
396 // TODO(jianli): Add UMA to track the error case.
397 if (registration.get())
398 registrations_[make_linked_ptr(registration.release())] = registration_id;
399 }
400
401 for (auto iter = result->instance_id_data.begin();
402 iter != result->instance_id_data.end();
403 ++iter) {
404 std::string instance_id;
405 std::string extra_data;
406 if (DeserializeInstanceIDData(iter->second, &instance_id, &extra_data))
407 instance_id_data_[iter->first] = std::make_pair(instance_id, extra_data);
408 }
409
352 load_result_ = result.Pass(); 410 load_result_ = result.Pass();
353 state_ = LOADED; 411 state_ = LOADED;
354 412
355 // Don't initiate the GCM connection when GCM is in delayed start mode and 413 // Don't initiate the GCM connection when GCM is in delayed start mode and
356 // not any standalone app has registered GCM yet. 414 // not any standalone app has registered GCM yet.
357 if (start_mode_ == DELAYED_START && !HasStandaloneRegisteredApp()) 415 if (start_mode_ == DELAYED_START && !HasStandaloneRegisteredApp())
358 return; 416 return;
359 417
360 StartGCM(); 418 StartGCM();
361 } 419 }
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
525 base::Bind(&GCMClientImpl::IgnoreWriteResultCallback, 583 base::Bind(&GCMClientImpl::IgnoreWriteResultCallback,
526 weak_ptr_factory_.GetWeakPtr())); 584 weak_ptr_factory_.GetWeakPtr()));
527 } 585 }
528 586
529 void GCMClientImpl::UpdateHeartbeatTimer(scoped_ptr<base::Timer> timer) { 587 void GCMClientImpl::UpdateHeartbeatTimer(scoped_ptr<base::Timer> timer) {
530 DCHECK(mcs_client_); 588 DCHECK(mcs_client_);
531 mcs_client_->UpdateHeartbeatTimer(timer.Pass()); 589 mcs_client_->UpdateHeartbeatTimer(timer.Pass());
532 } 590 }
533 591
534 void GCMClientImpl::AddInstanceIDData(const std::string& app_id, 592 void GCMClientImpl::AddInstanceIDData(const std::string& app_id,
535 const std::string& instance_id_data) { 593 const std::string& instance_id,
536 instance_id_data_[app_id] = instance_id_data; 594 const std::string& extra_data) {
595 instance_id_data_[app_id] = std::make_pair(instance_id, extra_data);
537 gcm_store_->AddInstanceIDData( 596 gcm_store_->AddInstanceIDData(
538 app_id, 597 app_id,
539 instance_id_data, 598 SerializeInstanceIDData(instance_id, extra_data),
540 base::Bind(&GCMClientImpl::IgnoreWriteResultCallback, 599 base::Bind(&GCMClientImpl::IgnoreWriteResultCallback,
541 weak_ptr_factory_.GetWeakPtr())); 600 weak_ptr_factory_.GetWeakPtr()));
542 } 601 }
543 602
544 void GCMClientImpl::RemoveInstanceIDData(const std::string& app_id) { 603 void GCMClientImpl::RemoveInstanceIDData(const std::string& app_id) {
545 instance_id_data_.erase(app_id); 604 instance_id_data_.erase(app_id);
546 gcm_store_->RemoveInstanceIDData( 605 gcm_store_->RemoveInstanceIDData(
547 app_id, 606 app_id,
548 base::Bind(&GCMClientImpl::IgnoreWriteResultCallback, 607 base::Bind(&GCMClientImpl::IgnoreWriteResultCallback,
549 weak_ptr_factory_.GetWeakPtr())); 608 weak_ptr_factory_.GetWeakPtr()));
550 } 609 }
551 610
552 std::string GCMClientImpl::GetInstanceIDData(const std::string& app_id) { 611 void GCMClientImpl::GetInstanceIDData(const std::string& app_id,
612 std::string* instance_id,
613 std::string* extra_data) {
614 DCHECK(instance_id && extra_data);
615
553 auto iter = instance_id_data_.find(app_id); 616 auto iter = instance_id_data_.find(app_id);
554 if (iter == instance_id_data_.end()) 617 if (iter == instance_id_data_.end())
555 return std::string(); 618 return;
556 return iter->second; 619 *instance_id = iter->second.first;
620 *extra_data = iter->second.second;
557 } 621 }
558 622
559 void GCMClientImpl::AddHeartbeatInterval(const std::string& scope, 623 void GCMClientImpl::AddHeartbeatInterval(const std::string& scope,
560 int interval_ms) { 624 int interval_ms) {
561 DCHECK(mcs_client_); 625 DCHECK(mcs_client_);
562 mcs_client_->AddHeartbeatInterval(scope, interval_ms); 626 mcs_client_->AddHeartbeatInterval(scope, interval_ms);
563 } 627 }
564 628
565 void GCMClientImpl::RemoveHeartbeatInterval(const std::string& scope) { 629 void GCMClientImpl::RemoveHeartbeatInterval(const std::string& scope) {
566 DCHECK(mcs_client_); 630 DCHECK(mcs_client_);
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
714 delegate_->OnDisconnected(); 778 delegate_->OnDisconnected();
715 mcs_client_.reset(); 779 mcs_client_.reset();
716 checkin_request_.reset(); 780 checkin_request_.reset();
717 // Delete all of the pending registration and unregistration requests. 781 // Delete all of the pending registration and unregistration requests.
718 STLDeleteValues(&pending_registration_requests_); 782 STLDeleteValues(&pending_registration_requests_);
719 STLDeleteValues(&pending_unregistration_requests_); 783 STLDeleteValues(&pending_unregistration_requests_);
720 state_ = INITIALIZED; 784 state_ = INITIALIZED;
721 gcm_store_->Close(); 785 gcm_store_->Close();
722 } 786 }
723 787
724 void GCMClientImpl::Register(const std::string& app_id, 788 void GCMClientImpl::Register(
725 const std::vector<std::string>& sender_ids) { 789 const linked_ptr<RegistrationInfo>& registration_info) {
726 DCHECK_EQ(state_, READY); 790 DCHECK_EQ(state_, READY);
727 791
728 // If the same sender ids is provided, return the cached registration ID 792 // Find and use the cached registration ID.
729 // directly.
730 RegistrationInfoMap::const_iterator registrations_iter = 793 RegistrationInfoMap::const_iterator registrations_iter =
731 registrations_.find(app_id); 794 registrations_.find(registration_info);
732 if (registrations_iter != registrations_.end() && 795 if (registrations_iter != registrations_.end()) {
733 registrations_iter->second->sender_ids == sender_ids) { 796 bool matched = true;
734 delegate_->OnRegisterFinished( 797
735 app_id, registrations_iter->second->registration_id, SUCCESS); 798 // For GCM registration, we also match the sender IDs since multiple
736 return; 799 // registrations are not supported.
800 const GCMRegistrationInfo* gcm_registration_info =
801 GCMRegistrationInfo::FromRegistrationInfo(registration_info.get());
802 if (gcm_registration_info) {
803 const GCMRegistrationInfo* cached_gcm_registration_info =
804 GCMRegistrationInfo::FromRegistrationInfo(
805 registrations_iter->first.get());
806 DCHECK(cached_gcm_registration_info);
807 if (cached_gcm_registration_info &&
808 gcm_registration_info->sender_ids !=
809 cached_gcm_registration_info->sender_ids) {
810 matched = false;
811 }
812 }
813
814 if (matched) {
815 delegate_->OnRegisterFinished(
816 registration_info, registrations_iter->second, SUCCESS);
817 return;
818 }
819 }
820
821 scoped_ptr<RegistrationRequest::CustomRequestHandler> request_handler;
822 std::string source_to_record;
823
824 const GCMRegistrationInfo* gcm_registration_info =
825 GCMRegistrationInfo::FromRegistrationInfo(registration_info.get());
826 if (gcm_registration_info) {
827 std::string senders;
828 for (auto iter = gcm_registration_info->sender_ids.begin();
829 iter != gcm_registration_info->sender_ids.end();
830 ++iter) {
831 if (!senders.empty())
832 senders.append(",");
833 senders.append(*iter);
834 }
835 UMA_HISTOGRAM_COUNTS("GCM.RegistrationSenderIdCount",
836 gcm_registration_info->sender_ids.size());
837
838 request_handler.reset(new GCMRegistrationRequestHandler(senders));
839 source_to_record = senders;
840 }
841
842 const InstanceIDTokenInfo* instance_id_token_info =
843 InstanceIDTokenInfo::FromRegistrationInfo(registration_info.get());
844 if (instance_id_token_info) {
845 auto instance_id_iter = instance_id_data_.find(registration_info->app_id);
846 DCHECK(instance_id_iter != instance_id_data_.end());
847
848 request_handler.reset(new InstanceIDGetTokenRequestHandler(
849 instance_id_iter->second.first,
850 instance_id_token_info->authorized_entity,
851 instance_id_token_info->scope,
852 ConstructGCMVersion(chrome_build_info_.version),
853 instance_id_token_info->options));
854 source_to_record = instance_id_token_info->authorized_entity;
737 } 855 }
738 856
739 RegistrationRequest::RequestInfo request_info( 857 RegistrationRequest::RequestInfo request_info(
740 device_checkin_info_.android_id, 858 device_checkin_info_.android_id,
741 device_checkin_info_.secret, 859 device_checkin_info_.secret,
742 app_id, 860 registration_info->app_id);
743 sender_ids);
744 DCHECK_EQ(0u, pending_registration_requests_.count(app_id));
745 861
746 RegistrationRequest* registration_request = 862 RegistrationRequest* registration_request =
747 new RegistrationRequest(gservices_settings_.GetRegistrationURL(), 863 new RegistrationRequest(gservices_settings_.GetRegistrationURL(),
748 request_info, 864 request_info,
865 request_handler.Pass(),
749 GetGCMBackoffPolicy(), 866 GetGCMBackoffPolicy(),
750 base::Bind(&GCMClientImpl::OnRegisterCompleted, 867 base::Bind(&GCMClientImpl::OnRegisterCompleted,
751 weak_ptr_factory_.GetWeakPtr(), 868 weak_ptr_factory_.GetWeakPtr(),
752 app_id, 869 registration_info),
753 sender_ids),
754 kMaxRegistrationRetries, 870 kMaxRegistrationRetries,
755 url_request_context_getter_, 871 url_request_context_getter_,
756 &recorder_); 872 &recorder_,
757 pending_registration_requests_[app_id] = registration_request; 873 source_to_record);
874 pending_registration_requests_[registration_info] = registration_request;
758 registration_request->Start(); 875 registration_request->Start();
759 } 876 }
760 877
761 void GCMClientImpl::OnRegisterCompleted( 878 void GCMClientImpl::OnRegisterCompleted(
762 const std::string& app_id, 879 const linked_ptr<RegistrationInfo>& registration_info,
763 const std::vector<std::string>& sender_ids,
764 RegistrationRequest::Status status, 880 RegistrationRequest::Status status,
765 const std::string& registration_id) { 881 const std::string& registration_id) {
766 DCHECK(delegate_); 882 DCHECK(delegate_);
767 883
768 Result result; 884 Result result;
769 PendingRegistrationRequests::iterator iter = 885 PendingRegistrationRequests::iterator iter =
770 pending_registration_requests_.find(app_id); 886 pending_registration_requests_.find(registration_info);
771 if (iter == pending_registration_requests_.end()) 887 if (iter == pending_registration_requests_.end())
772 result = UNKNOWN_ERROR; 888 result = UNKNOWN_ERROR;
773 else if (status == RegistrationRequest::INVALID_SENDER) 889 else if (status == RegistrationRequest::INVALID_SENDER)
774 result = INVALID_PARAMETER; 890 result = INVALID_PARAMETER;
775 else if (registration_id.empty()) 891 else if (registration_id.empty())
776 result = SERVER_ERROR; 892 result = SERVER_ERROR;
777 else 893 else
778 result = SUCCESS; 894 result = SUCCESS;
779 895
780 if (result == SUCCESS) { 896 if (result == SUCCESS) {
781 // Cache it. 897 // Cache it.
782 linked_ptr<RegistrationInfo> registration(new RegistrationInfo); 898 registrations_[registration_info] = registration_id;
783 registration->sender_ids = sender_ids;
784 registration->registration_id = registration_id;
785 registrations_[app_id] = registration;
786 899
787 // Save it in the persistent store. 900 // Save it in the persistent store.
788 gcm_store_->AddRegistration( 901 gcm_store_->AddRegistration(
789 app_id, 902 registration_info->GetSerializedKey(),
790 registration, 903 registration_info->GetSerializedValue(registration_id),
791 base::Bind(&GCMClientImpl::UpdateRegistrationCallback, 904 base::Bind(&GCMClientImpl::UpdateRegistrationCallback,
792 weak_ptr_factory_.GetWeakPtr())); 905 weak_ptr_factory_.GetWeakPtr()));
793 } 906 }
794 907
795 delegate_->OnRegisterFinished( 908 delegate_->OnRegisterFinished(
796 app_id, result == SUCCESS ? registration_id : std::string(), result); 909 registration_info,
910 result == SUCCESS ? registration_id : std::string(),
911 result);
797 912
798 if (iter != pending_registration_requests_.end()) { 913 if (iter != pending_registration_requests_.end()) {
799 delete iter->second; 914 delete iter->second;
800 pending_registration_requests_.erase(iter); 915 pending_registration_requests_.erase(iter);
801 } 916 }
802 } 917 }
803 918
804 void GCMClientImpl::Unregister(const std::string& app_id) { 919 void GCMClientImpl::Unregister(
920 const linked_ptr<RegistrationInfo>& registration_info) {
805 DCHECK_EQ(state_, READY); 921 DCHECK_EQ(state_, READY);
806 if (pending_unregistration_requests_.count(app_id) == 1) 922 if (pending_unregistration_requests_.count(registration_info) == 1)
807 return; 923 return;
808 924
809 // Remove from the cache and persistent store. 925 // Remove from the cache and persistent store.
810 registrations_.erase(app_id); 926 registrations_.erase(registration_info);
811 gcm_store_->RemoveRegistration( 927 gcm_store_->RemoveRegistration(
812 app_id, 928 registration_info->GetSerializedKey(),
813 base::Bind(&GCMClientImpl::UpdateRegistrationCallback, 929 base::Bind(&GCMClientImpl::UpdateRegistrationCallback,
814 weak_ptr_factory_.GetWeakPtr())); 930 weak_ptr_factory_.GetWeakPtr()));
815 931
932 scoped_ptr<UnregistrationRequest::CustomRequestHandler> request_handler;
933
934 const GCMRegistrationInfo* gcm_registration_info =
935 GCMRegistrationInfo::FromRegistrationInfo(registration_info.get());
936 if (gcm_registration_info) {
937 request_handler.reset(
938 new GCMUnregistrationRequestHandler(registration_info->app_id));
939 }
940
941 const InstanceIDTokenInfo* instance_id_token_info =
942 InstanceIDTokenInfo::FromRegistrationInfo(registration_info.get());
943 if (instance_id_token_info) {
944 auto instance_id_iter = instance_id_data_.find(registration_info->app_id);
945 DCHECK(instance_id_iter != instance_id_data_.end());
946
947 request_handler.reset(new InstanceIDDeleteTokenRequestHandler(
948 instance_id_iter->second.first,
949 instance_id_token_info->authorized_entity,
950 instance_id_token_info->scope,
951 ConstructGCMVersion(chrome_build_info_.version)));
952 }
953
816 UnregistrationRequest::RequestInfo request_info( 954 UnregistrationRequest::RequestInfo request_info(
817 device_checkin_info_.android_id, 955 device_checkin_info_.android_id,
818 device_checkin_info_.secret, 956 device_checkin_info_.secret,
819 app_id); 957 registration_info->app_id);
820 958
821 UnregistrationRequest* unregistration_request = new UnregistrationRequest( 959 UnregistrationRequest* unregistration_request = new UnregistrationRequest(
822 gservices_settings_.GetRegistrationURL(), 960 gservices_settings_.GetRegistrationURL(),
823 request_info, 961 request_info,
962 request_handler.Pass(),
824 GetGCMBackoffPolicy(), 963 GetGCMBackoffPolicy(),
825 base::Bind(&GCMClientImpl::OnUnregisterCompleted, 964 base::Bind(&GCMClientImpl::OnUnregisterCompleted,
826 weak_ptr_factory_.GetWeakPtr(), 965 weak_ptr_factory_.GetWeakPtr(),
827 app_id), 966 registration_info),
828 url_request_context_getter_, 967 url_request_context_getter_,
829 &recorder_); 968 &recorder_);
830 pending_unregistration_requests_[app_id] = unregistration_request; 969 pending_unregistration_requests_[registration_info] = unregistration_request;
831 unregistration_request->Start(); 970 unregistration_request->Start();
832 } 971 }
833 972
834 void GCMClientImpl::OnUnregisterCompleted( 973 void GCMClientImpl::OnUnregisterCompleted(
835 const std::string& app_id, 974 const linked_ptr<RegistrationInfo>& registration_info,
836 UnregistrationRequest::Status status) { 975 UnregistrationRequest::Status status) {
837 DVLOG(1) << "Unregister completed for app: " << app_id 976 DVLOG(1) << "Unregister completed for app: " << registration_info->app_id
838 << " with " << (status ? "success." : "failure."); 977 << " with " << (status ? "success." : "failure.");
839 delegate_->OnUnregisterFinished( 978 delegate_->OnUnregisterFinished(
840 app_id, 979 registration_info,
841 status == UnregistrationRequest::SUCCESS ? SUCCESS : SERVER_ERROR); 980 status == UnregistrationRequest::SUCCESS ? SUCCESS : SERVER_ERROR);
842 981
843 PendingUnregistrationRequests::iterator iter = 982 PendingUnregistrationRequests::iterator iter =
844 pending_unregistration_requests_.find(app_id); 983 pending_unregistration_requests_.find(registration_info);
845 if (iter == pending_unregistration_requests_.end()) 984 if (iter == pending_unregistration_requests_.end())
846 return; 985 return;
847 986
848 delete iter->second; 987 delete iter->second;
849 pending_unregistration_requests_.erase(iter); 988 pending_unregistration_requests_.erase(iter);
850 } 989 }
851 990
852 void GCMClientImpl::OnGCMStoreDestroyed(bool success) { 991 void GCMClientImpl::OnGCMStoreDestroyed(bool success) {
853 DLOG_IF(ERROR, !success) << "GCM store failed to be destroyed!"; 992 DLOG_IF(ERROR, !success) << "GCM store failed to be destroyed!";
854 UMA_HISTOGRAM_BOOLEAN("GCM.StoreDestroySucceeded", success); 993 UMA_HISTOGRAM_BOOLEAN("GCM.StoreDestroySucceeded", success);
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
922 if (mcs_client_.get()) { 1061 if (mcs_client_.get()) {
923 stats.send_queue_size = mcs_client_->GetSendQueueSize(); 1062 stats.send_queue_size = mcs_client_->GetSendQueueSize();
924 stats.resend_queue_size = mcs_client_->GetResendQueueSize(); 1063 stats.resend_queue_size = mcs_client_->GetResendQueueSize();
925 } 1064 }
926 if (device_checkin_info_.android_id > 0) 1065 if (device_checkin_info_.android_id > 0)
927 stats.android_id = device_checkin_info_.android_id; 1066 stats.android_id = device_checkin_info_.android_id;
928 recorder_.CollectActivities(&stats.recorded_activities); 1067 recorder_.CollectActivities(&stats.recorded_activities);
929 1068
930 for (RegistrationInfoMap::const_iterator it = registrations_.begin(); 1069 for (RegistrationInfoMap::const_iterator it = registrations_.begin();
931 it != registrations_.end(); ++it) { 1070 it != registrations_.end(); ++it) {
932 stats.registered_app_ids.push_back(it->first); 1071 stats.registered_app_ids.push_back(it->first->app_id);
933 } 1072 }
934 return stats; 1073 return stats;
935 } 1074 }
936 1075
937 void GCMClientImpl::OnActivityRecorded() { 1076 void GCMClientImpl::OnActivityRecorded() {
938 delegate_->OnActivityRecorded(); 1077 delegate_->OnActivityRecorded();
939 } 1078 }
940 1079
941 void GCMClientImpl::OnConnected(const GURL& current_server, 1080 void GCMClientImpl::OnConnected(const GURL& current_server,
942 const net::IPEndPoint& ip_endpoint) { 1081 const net::IPEndPoint& ip_endpoint) {
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
1040 DVLOG(1) << "Unknown message_type received. Message ignored. " 1179 DVLOG(1) << "Unknown message_type received. Message ignored. "
1041 << "App ID: " << data_message_stanza.category() << "."; 1180 << "App ID: " << data_message_stanza.category() << ".";
1042 break; 1181 break;
1043 } 1182 }
1044 } 1183 }
1045 1184
1046 void GCMClientImpl::HandleIncomingDataMessage( 1185 void GCMClientImpl::HandleIncomingDataMessage(
1047 const mcs_proto::DataMessageStanza& data_message_stanza, 1186 const mcs_proto::DataMessageStanza& data_message_stanza,
1048 MessageData& message_data) { 1187 MessageData& message_data) {
1049 std::string app_id = data_message_stanza.category(); 1188 std::string app_id = data_message_stanza.category();
1189 std::string sender = data_message_stanza.from();
1050 1190
1051 // Drop the message when the app is not registered for the sender of the 1191 // Drop the message when the app is not registered for the sender of the
1052 // message. 1192 // message.
1053 RegistrationInfoMap::iterator iter = registrations_.find(app_id); 1193 bool registered = false;
1054 bool not_registered = 1194
1055 iter == registrations_.end() || 1195 // First, find among all GCM registrations.
1056 std::find(iter->second->sender_ids.begin(), 1196 scoped_ptr<GCMRegistrationInfo> gcm_registration(new GCMRegistrationInfo);
1057 iter->second->sender_ids.end(), 1197 gcm_registration->app_id = app_id;
1058 data_message_stanza.from()) == iter->second->sender_ids.end(); 1198 auto gcm_registration_iter = registrations_.find(
1059 recorder_.RecordDataMessageReceived(app_id, data_message_stanza.from(), 1199 make_linked_ptr<RegistrationInfo>(gcm_registration.release()));
1060 data_message_stanza.ByteSize(), !not_registered, 1200 if (gcm_registration_iter != registrations_.end()) {
1201 GCMRegistrationInfo* cached_gcm_registration =
1202 GCMRegistrationInfo::FromRegistrationInfo(
1203 gcm_registration_iter->first.get());
1204 if (cached_gcm_registration &&
1205 std::find(cached_gcm_registration->sender_ids.begin(),
1206 cached_gcm_registration->sender_ids.end(),
1207 sender) != cached_gcm_registration->sender_ids.end()) {
1208 registered = true;
1209 }
1210 }
1211
1212 // Then, find among all InstanceID registrations.
1213 if (!registered) {
1214 scoped_ptr<InstanceIDTokenInfo> instance_id_token(new InstanceIDTokenInfo);
1215 instance_id_token->app_id = app_id;
1216 instance_id_token->authorized_entity = sender;
1217 instance_id_token->scope = kGCMScope;
1218 auto instance_id_token_iter = registrations_.find(
1219 make_linked_ptr<RegistrationInfo>(instance_id_token.release()));
1220 if (instance_id_token_iter != registrations_.end())
1221 registered = true;
1222 }
1223
1224 recorder_.RecordDataMessageReceived(app_id, sender,
1225 data_message_stanza.ByteSize(), registered,
1061 GCMStatsRecorder::DATA_MESSAGE); 1226 GCMStatsRecorder::DATA_MESSAGE);
1062 if (not_registered) { 1227 if (!registered)
1063 return; 1228 return;
1064 }
1065 1229
1066 IncomingMessage incoming_message; 1230 IncomingMessage incoming_message;
1067 incoming_message.sender_id = data_message_stanza.from(); 1231 incoming_message.sender_id = data_message_stanza.from();
1068 if (data_message_stanza.has_token()) 1232 if (data_message_stanza.has_token())
1069 incoming_message.collapse_key = data_message_stanza.token(); 1233 incoming_message.collapse_key = data_message_stanza.token();
1070 incoming_message.data = message_data; 1234 incoming_message.data = message_data;
1071 delegate_->OnMessageReceived(app_id, incoming_message); 1235 delegate_->OnMessageReceived(app_id, incoming_message);
1072 } 1236 }
1073 1237
1074 void GCMClientImpl::HandleIncomingSendError( 1238 void GCMClientImpl::HandleIncomingSendError(
(...skipping 17 matching lines...) Expand all
1092 delegate_->OnMessageSendError(data_message_stanza.category(), 1256 delegate_->OnMessageSendError(data_message_stanza.category(),
1093 send_error_details); 1257 send_error_details);
1094 } 1258 }
1095 1259
1096 bool GCMClientImpl::HasStandaloneRegisteredApp() const { 1260 bool GCMClientImpl::HasStandaloneRegisteredApp() const {
1097 if (registrations_.empty()) 1261 if (registrations_.empty())
1098 return false; 1262 return false;
1099 // Note that account mapper is not counted as a standalone app since it is 1263 // Note that account mapper is not counted as a standalone app since it is
1100 // automatically started when other app uses GCM. 1264 // automatically started when other app uses GCM.
1101 return registrations_.size() > 1 || 1265 return registrations_.size() > 1 ||
1102 !registrations_.count(kGCMAccountMapperAppId); 1266 !ExistsGCMRegistrationInMap(registrations_, kGCMAccountMapperAppId);
1103 } 1267 }
1104 1268
1105 } // namespace gcm 1269 } // 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