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/gcm_driver/registration_info.h"
7 #include "base/strings/string_util.h"
12 const char kInsanceIDSerializationPrefix
[] = "iid-";
13 const int kInsanceIDSerializationPrefixLength
=
14 sizeof(kInsanceIDSerializationPrefix
) / sizeof(char) - 1;
18 scoped_ptr
<RegistrationInfo
> RegistrationInfo::BuildFromString(
19 const std::string
& serialzied_key
,
20 const std::string
& serialzied_value
,
21 std::string
* registration_id
) {
22 scoped_ptr
<RegistrationInfo
> registration
;
24 if (base::StartsWithASCII(serialzied_key
, kInsanceIDSerializationPrefix
,
26 registration
.reset(new InstanceIDTokenInfo
);
28 registration
.reset(new GCMRegistrationInfo
);
30 if (!registration
->Deserialize(serialzied_key
,
35 return registration
.Pass();
38 RegistrationInfo::RegistrationInfo() {
41 RegistrationInfo::~RegistrationInfo() {
45 const GCMRegistrationInfo
* GCMRegistrationInfo::FromRegistrationInfo(
46 const RegistrationInfo
* registration_info
) {
47 if (!registration_info
|| registration_info
->GetType() != GCM_REGISTRATION
)
49 return static_cast<const GCMRegistrationInfo
*>(registration_info
);
53 GCMRegistrationInfo
* GCMRegistrationInfo::FromRegistrationInfo(
54 RegistrationInfo
* registration_info
) {
55 if (!registration_info
|| registration_info
->GetType() != GCM_REGISTRATION
)
57 return static_cast<GCMRegistrationInfo
*>(registration_info
);
60 GCMRegistrationInfo::GCMRegistrationInfo() {
63 GCMRegistrationInfo::~GCMRegistrationInfo() {
66 RegistrationInfo::RegistrationType
GCMRegistrationInfo::GetType() const {
67 return GCM_REGISTRATION
;
70 std::string
GCMRegistrationInfo::GetSerializedKey() const {
71 // Multiple registrations are not supported for legacy GCM. So the key is
72 // purely based on the application id.
76 std::string
GCMRegistrationInfo::GetSerializedValue(
77 const std::string
& registration_id
) const {
78 if (sender_ids
.empty() || registration_id
.empty())
82 // sender1,sender2,...=reg_id
84 for (std::vector
<std::string
>::const_iterator iter
= sender_ids
.begin();
85 iter
!= sender_ids
.end(); ++iter
) {
86 DCHECK(!iter
->empty() &&
87 iter
->find(',') == std::string::npos
&&
88 iter
->find('=') == std::string::npos
);
95 value
+= registration_id
;
99 bool GCMRegistrationInfo::Deserialize(
100 const std::string
& serialzied_key
,
101 const std::string
& serialzied_value
,
102 std::string
* registration_id
) {
103 if (serialzied_key
.empty() || serialzied_value
.empty())
106 // Application ID is same as the serialized key.
107 app_id
= serialzied_key
;
109 // Sender IDs and registration ID are constructed from the serialized value.
110 size_t pos
= serialzied_value
.find('=');
111 if (pos
== std::string::npos
)
114 std::string senders
= serialzied_value
.substr(0, pos
);
115 std::string registration_id_str
= serialzied_value
.substr(pos
+ 1);
117 Tokenize(senders
, ",", &sender_ids
);
119 if (sender_ids
.empty() || registration_id_str
.empty()) {
121 registration_id_str
.clear();
126 *registration_id
= registration_id_str
;
132 const InstanceIDTokenInfo
* InstanceIDTokenInfo::FromRegistrationInfo(
133 const RegistrationInfo
* registration_info
) {
134 if (!registration_info
|| registration_info
->GetType() != INSTANCE_ID_TOKEN
)
136 return static_cast<const InstanceIDTokenInfo
*>(registration_info
);
140 InstanceIDTokenInfo
* InstanceIDTokenInfo::FromRegistrationInfo(
141 RegistrationInfo
* registration_info
) {
142 if (!registration_info
|| registration_info
->GetType() != INSTANCE_ID_TOKEN
)
144 return static_cast<InstanceIDTokenInfo
*>(registration_info
);
147 InstanceIDTokenInfo::InstanceIDTokenInfo() {
150 InstanceIDTokenInfo::~InstanceIDTokenInfo() {
153 RegistrationInfo::RegistrationType
InstanceIDTokenInfo::GetType() const {
154 return INSTANCE_ID_TOKEN
;
157 std::string
InstanceIDTokenInfo::GetSerializedKey() const {
158 DCHECK(authorized_entity
.find(',') == std::string::npos
&&
159 scope
.find(',') == std::string::npos
);
161 // Multiple registrations are supported for Instance ID. So the key is based
162 // on the combination of (app_id, authorized_entity, scope).
164 // Adds a prefix to differentiate easily with GCM registration key.
165 std::string
key(kInsanceIDSerializationPrefix
);
168 key
+= authorized_entity
;
174 std::string
InstanceIDTokenInfo::GetSerializedValue(
175 const std::string
& registration_id
) const {
176 return registration_id
;
179 bool InstanceIDTokenInfo::Deserialize(
180 const std::string
& serialized_key
,
181 const std::string
& serialized_value
,
182 std::string
* registration_id
) {
183 if (serialized_key
.empty() || serialized_value
.empty())
186 if (!base::StartsWithASCII(serialized_key
, kInsanceIDSerializationPrefix
,
190 std::vector
<std::string
> fields
;
191 Tokenize(serialized_key
.substr(kInsanceIDSerializationPrefixLength
),
194 if (fields
.size() != 3 || fields
[0].empty() ||
195 fields
[1].empty() || fields
[2].empty()) {
199 authorized_entity
= fields
[1];
202 // Registration ID is same as the serialized value;
204 *registration_id
= serialized_value
;
209 bool RegistrationInfoComparer::operator()(
210 const linked_ptr
<RegistrationInfo
>& a
,
211 const linked_ptr
<RegistrationInfo
>& b
) const {
212 DCHECK(a
.get() && b
.get());
214 // For GCMRegistrationInfo, the comparison is based on app_id only.
215 // For InstanceIDTokenInfo, the comparison is bsaed on
216 // <app_id, authorized_entity, scope>.
217 if (a
->app_id
< b
->app_id
)
219 if (a
->app_id
> b
->app_id
)
222 InstanceIDTokenInfo
* iid_a
=
223 InstanceIDTokenInfo::FromRegistrationInfo(a
.get());
224 InstanceIDTokenInfo
* iid_b
=
225 InstanceIDTokenInfo::FromRegistrationInfo(b
.get());
227 // !iid_a && !iid_b => false.
228 // !iid_a && iid_b => true.
229 // This makes GCM record is sorted before InstanceID record.
231 return iid_b
!= NULL
;
233 // iid_a && !iid_b => false.
237 // Otherwise, compare with authorized_entity and scope.
238 if (iid_a
->authorized_entity
< iid_b
->authorized_entity
)
240 if (iid_a
->authorized_entity
> iid_b
->authorized_entity
)
242 return iid_a
->scope
< iid_b
->scope
;
245 bool ExistsGCMRegistrationInMap(const RegistrationInfoMap
& map
,
246 const std::string
& app_id
) {
247 scoped_ptr
<GCMRegistrationInfo
> gcm_registration(new GCMRegistrationInfo
);
248 gcm_registration
->app_id
= app_id
;
250 make_linked_ptr
<RegistrationInfo
>(gcm_registration
.release())) > 0;