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 (StartsWithASCII(serialzied_key
, kInsanceIDSerializationPrefix
, true))
25 registration
.reset(new InstanceIDTokenInfo
);
27 registration
.reset(new GCMRegistrationInfo
);
29 if (!registration
->Deserialize(serialzied_key
,
34 return registration
.Pass();
37 RegistrationInfo::RegistrationInfo() {
40 RegistrationInfo::~RegistrationInfo() {
44 const GCMRegistrationInfo
* GCMRegistrationInfo::FromRegistrationInfo(
45 const RegistrationInfo
* registration_info
) {
46 if (!registration_info
|| registration_info
->GetType() != GCM_REGISTRATION
)
48 return static_cast<const GCMRegistrationInfo
*>(registration_info
);
52 GCMRegistrationInfo
* GCMRegistrationInfo::FromRegistrationInfo(
53 RegistrationInfo
* registration_info
) {
54 if (!registration_info
|| registration_info
->GetType() != GCM_REGISTRATION
)
56 return static_cast<GCMRegistrationInfo
*>(registration_info
);
59 GCMRegistrationInfo::GCMRegistrationInfo() {
62 GCMRegistrationInfo::~GCMRegistrationInfo() {
65 RegistrationInfo::RegistrationType
GCMRegistrationInfo::GetType() const {
66 return GCM_REGISTRATION
;
69 std::string
GCMRegistrationInfo::GetSerializedKey() const {
70 // Multiple registrations are not supported for legacy GCM. So the key is
71 // purely based on the application id.
75 std::string
GCMRegistrationInfo::GetSerializedValue(
76 const std::string
& registration_id
) const {
77 if (sender_ids
.empty() || registration_id
.empty())
81 // sender1,sender2,...=reg_id
83 for (std::vector
<std::string
>::const_iterator iter
= sender_ids
.begin();
84 iter
!= sender_ids
.end(); ++iter
) {
85 DCHECK(!iter
->empty() &&
86 iter
->find(',') == std::string::npos
&&
87 iter
->find('=') == std::string::npos
);
94 value
+= registration_id
;
98 bool GCMRegistrationInfo::Deserialize(
99 const std::string
& serialzied_key
,
100 const std::string
& serialzied_value
,
101 std::string
* registration_id
) {
102 if (serialzied_key
.empty() || serialzied_value
.empty())
105 // Application ID is same as the serialized key.
106 app_id
= serialzied_key
;
108 // Sender IDs and registration ID are constructed from the serialized value.
109 size_t pos
= serialzied_value
.find('=');
110 if (pos
== std::string::npos
)
113 std::string senders
= serialzied_value
.substr(0, pos
);
114 std::string registration_id_str
= serialzied_value
.substr(pos
+ 1);
116 Tokenize(senders
, ",", &sender_ids
);
118 if (sender_ids
.empty() || registration_id_str
.empty()) {
120 registration_id_str
.clear();
125 *registration_id
= registration_id_str
;
131 const InstanceIDTokenInfo
* InstanceIDTokenInfo::FromRegistrationInfo(
132 const RegistrationInfo
* registration_info
) {
133 if (!registration_info
|| registration_info
->GetType() != INSTANCE_ID_TOKEN
)
135 return static_cast<const InstanceIDTokenInfo
*>(registration_info
);
139 InstanceIDTokenInfo
* InstanceIDTokenInfo::FromRegistrationInfo(
140 RegistrationInfo
* registration_info
) {
141 if (!registration_info
|| registration_info
->GetType() != INSTANCE_ID_TOKEN
)
143 return static_cast<InstanceIDTokenInfo
*>(registration_info
);
146 InstanceIDTokenInfo::InstanceIDTokenInfo() {
149 InstanceIDTokenInfo::~InstanceIDTokenInfo() {
152 RegistrationInfo::RegistrationType
InstanceIDTokenInfo::GetType() const {
153 return INSTANCE_ID_TOKEN
;
156 std::string
InstanceIDTokenInfo::GetSerializedKey() const {
157 DCHECK(authorized_entity
.find(',') == std::string::npos
&&
158 scope
.find(',') == std::string::npos
);
160 // Multiple registrations are supported for Instance ID. So the key is based
161 // on the combination of (app_id, authorized_entity, scope).
163 // Adds a prefix to differentiate easily with GCM registration key.
164 std::string
key(kInsanceIDSerializationPrefix
);
167 key
+= authorized_entity
;
173 std::string
InstanceIDTokenInfo::GetSerializedValue(
174 const std::string
& registration_id
) const {
175 return registration_id
;
178 bool InstanceIDTokenInfo::Deserialize(
179 const std::string
& serialized_key
,
180 const std::string
& serialized_value
,
181 std::string
* registration_id
) {
182 if (serialized_key
.empty() || serialized_value
.empty())
185 if (!StartsWithASCII(serialized_key
, kInsanceIDSerializationPrefix
, true))
188 std::vector
<std::string
> fields
;
189 Tokenize(serialized_key
.substr(kInsanceIDSerializationPrefixLength
),
192 if (fields
.size() != 3 || fields
[0].empty() ||
193 fields
[1].empty() || fields
[2].empty()) {
197 authorized_entity
= fields
[1];
200 // Registration ID is same as the serialized value;
202 *registration_id
= serialized_value
;
207 bool RegistrationInfoComparer::operator()(
208 const linked_ptr
<RegistrationInfo
>& a
,
209 const linked_ptr
<RegistrationInfo
>& b
) const {
210 DCHECK(a
.get() && b
.get());
212 // For GCMRegistrationInfo, the comparison is based on app_id only.
213 // For InstanceIDTokenInfo, the comparison is bsaed on
214 // <app_id, authorized_entity, scope>.
215 if (a
->app_id
< b
->app_id
)
217 if (a
->app_id
> b
->app_id
)
220 InstanceIDTokenInfo
* iid_a
=
221 InstanceIDTokenInfo::FromRegistrationInfo(a
.get());
222 InstanceIDTokenInfo
* iid_b
=
223 InstanceIDTokenInfo::FromRegistrationInfo(b
.get());
225 // !iid_a && !iid_b => false.
226 // !iid_a && iid_b => true.
227 // This makes GCM record is sorted before InstanceID record.
229 return iid_b
!= NULL
;
231 // iid_a && !iid_b => false.
235 // Otherwise, compare with authorized_entity and scope.
236 if (iid_a
->authorized_entity
< iid_b
->authorized_entity
)
238 if (iid_a
->authorized_entity
> iid_b
->authorized_entity
)
240 return iid_a
->scope
< iid_b
->scope
;
243 bool ExistsGCMRegistrationInMap(const RegistrationInfoMap
& map
,
244 const std::string
& app_id
) {
245 scoped_ptr
<GCMRegistrationInfo
> gcm_registration(new GCMRegistrationInfo
);
246 gcm_registration
->app_id
= app_id
;
248 make_linked_ptr
<RegistrationInfo
>(gcm_registration
.release())) > 0;