1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/proximity_auth/cryptauth/cryptauth_gcm_manager_impl.h"
8 #include "base/prefs/pref_service.h"
9 #include "base/strings/string_util.h"
10 #include "components/gcm_driver/gcm_driver.h"
11 #include "components/proximity_auth/cryptauth/pref_names.h"
12 #include "components/proximity_auth/logging/logging.h"
14 namespace proximity_auth
{
18 // The GCM app id identifies the client.
19 const char kCryptAuthGCMAppId
[] = "com.google.chrome.cryptauth";
21 // The GCM sender id identifies the CryptAuth server.
22 const char kCryptAuthGCMSenderId
[] = "381449029288";
24 // The 'registrationTickleType' key-value pair is present in GCM push
25 // messages. The values correspond to a server-side enum.
26 const char kRegistrationTickleTypeKey
[] = "registrationTickleType";
27 const char kRegistrationTickleTypeForceEnrollment
[] = "1";
28 const char kRegistrationTickleTypeUpdateEnrollment
[] = "2";
29 const char kRegistrationTickleTypeDevicesSync
[] = "3";
33 CryptAuthGCMManagerImpl::CryptAuthGCMManagerImpl(gcm::GCMDriver
* gcm_driver
,
34 PrefService
* pref_service
)
35 : gcm_driver_(gcm_driver
),
36 pref_service_(pref_service
),
37 registration_in_progress_(false),
38 weak_ptr_factory_(this) {
41 CryptAuthGCMManagerImpl::~CryptAuthGCMManagerImpl() {
42 if (gcm_driver_
->GetAppHandler(kCryptAuthGCMAppId
) == this)
43 gcm_driver_
->RemoveAppHandler(kCryptAuthGCMAppId
);
46 void CryptAuthGCMManagerImpl::StartListening() {
47 if (gcm_driver_
->GetAppHandler(kCryptAuthGCMAppId
) == this) {
48 PA_LOG(INFO
) << "GCM app handler already added";
52 gcm_driver_
->AddAppHandler(kCryptAuthGCMAppId
, this);
55 void CryptAuthGCMManagerImpl::RegisterWithGCM() {
56 if (registration_in_progress_
) {
57 PA_LOG(INFO
) << "GCM Registration is already in progress";
61 PA_LOG(INFO
) << "Beginning GCM registration...";
62 registration_in_progress_
= true;
64 std::vector
<std::string
> sender_ids(1, kCryptAuthGCMSenderId
);
65 gcm_driver_
->Register(
66 kCryptAuthGCMAppId
, sender_ids
,
67 base::Bind(&CryptAuthGCMManagerImpl::OnRegistrationCompleted
,
68 weak_ptr_factory_
.GetWeakPtr()));
71 std::string
CryptAuthGCMManagerImpl::GetRegistrationId() {
72 return pref_service_
->GetString(prefs::kCryptAuthGCMRegistrationId
);
75 void CryptAuthGCMManagerImpl::AddObserver(Observer
* observer
) {
76 observers_
.AddObserver(observer
);
79 void CryptAuthGCMManagerImpl::RemoveObserver(Observer
* observer
) {
80 observers_
.RemoveObserver(observer
);
83 void CryptAuthGCMManagerImpl::ShutdownHandler() {
86 void CryptAuthGCMManagerImpl::OnMessage(const std::string
& app_id
,
87 const gcm::IncomingMessage
& message
) {
88 std::vector
<std::string
> fields
;
89 for (const auto& kv
: message
.data
) {
90 fields
.push_back(std::string(kv
.first
) + ": " + std::string(kv
.second
));
93 PA_LOG(INFO
) << "GCM message received:\n"
94 << " sender_id: " << message
.sender_id
<< "\n"
95 << " collapse_key: " << message
.collapse_key
<< "\n"
96 << " data:\n " << base::JoinString(fields
, "\n ");
98 if (message
.data
.find(kRegistrationTickleTypeKey
) == message
.data
.end()) {
99 PA_LOG(WARNING
) << "GCM message does not contain 'registrationTickleType'.";
101 std::string tickle_type
= message
.data
.at(kRegistrationTickleTypeKey
);
102 if (tickle_type
== kRegistrationTickleTypeForceEnrollment
||
103 tickle_type
== kRegistrationTickleTypeUpdateEnrollment
) {
104 // These tickle types correspond to re-enrollment messages.
105 FOR_EACH_OBSERVER(Observer
, observers_
, OnReenrollMessage());
106 } else if (tickle_type
== kRegistrationTickleTypeDevicesSync
) {
107 FOR_EACH_OBSERVER(Observer
, observers_
, OnResyncMessage());
109 PA_LOG(WARNING
) << "Unknown tickle type in GCM message.";
114 void CryptAuthGCMManagerImpl::OnMessagesDeleted(const std::string
& app_id
) {
117 void CryptAuthGCMManagerImpl::OnSendError(
118 const std::string
& app_id
,
119 const gcm::GCMClient::SendErrorDetails
& details
) {
123 void CryptAuthGCMManagerImpl::OnSendAcknowledged(
124 const std::string
& app_id
,
125 const std::string
& message_id
) {
129 void CryptAuthGCMManagerImpl::OnRegistrationCompleted(
130 const std::string
& registration_id
,
131 gcm::GCMClient::Result result
) {
132 registration_in_progress_
= false;
133 if (result
!= gcm::GCMClient::SUCCESS
) {
134 PA_LOG(WARNING
) << "GCM registration failed with result="
135 << static_cast<int>(result
);
136 FOR_EACH_OBSERVER(Observer
, observers_
, OnGCMRegistrationResult(false));
140 PA_LOG(INFO
) << "GCM registration success, registration_id="
142 pref_service_
->SetString(prefs::kCryptAuthGCMRegistrationId
, registration_id
);
143 FOR_EACH_OBSERVER(Observer
, observers_
, OnGCMRegistrationResult(true));
146 } // namespace proximity_auth