[AndroidWebViewShell] Replace rebaseline script with a new version using test_runner.py
[chromium-blink-merge.git] / components / gcm_driver / registration_info.cc
blob90bf4e34894777eaa8942ac8a7f56f6fce1ad904
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_split.h"
8 #include "base/strings/string_util.h"
10 namespace gcm {
12 namespace {
13 const char kInsanceIDSerializationPrefix[] = "iid-";
14 const int kInsanceIDSerializationPrefixLength =
15 sizeof(kInsanceIDSerializationPrefix) / sizeof(char) - 1;
16 } // namespace
18 // static
19 scoped_ptr<RegistrationInfo> RegistrationInfo::BuildFromString(
20 const std::string& serialzied_key,
21 const std::string& serialzied_value,
22 std::string* registration_id) {
23 scoped_ptr<RegistrationInfo> registration;
25 if (base::StartsWithASCII(serialzied_key, kInsanceIDSerializationPrefix,
26 true))
27 registration.reset(new InstanceIDTokenInfo);
28 else
29 registration.reset(new GCMRegistrationInfo);
31 if (!registration->Deserialize(serialzied_key,
32 serialzied_value,
33 registration_id)) {
34 registration.reset();
36 return registration.Pass();
39 RegistrationInfo::RegistrationInfo() {
42 RegistrationInfo::~RegistrationInfo() {
45 // static
46 const GCMRegistrationInfo* GCMRegistrationInfo::FromRegistrationInfo(
47 const RegistrationInfo* registration_info) {
48 if (!registration_info || registration_info->GetType() != GCM_REGISTRATION)
49 return NULL;
50 return static_cast<const GCMRegistrationInfo*>(registration_info);
53 // static
54 GCMRegistrationInfo* GCMRegistrationInfo::FromRegistrationInfo(
55 RegistrationInfo* registration_info) {
56 if (!registration_info || registration_info->GetType() != GCM_REGISTRATION)
57 return NULL;
58 return static_cast<GCMRegistrationInfo*>(registration_info);
61 GCMRegistrationInfo::GCMRegistrationInfo() {
64 GCMRegistrationInfo::~GCMRegistrationInfo() {
67 RegistrationInfo::RegistrationType GCMRegistrationInfo::GetType() const {
68 return GCM_REGISTRATION;
71 std::string GCMRegistrationInfo::GetSerializedKey() const {
72 // Multiple registrations are not supported for legacy GCM. So the key is
73 // purely based on the application id.
74 return app_id;
77 std::string GCMRegistrationInfo::GetSerializedValue(
78 const std::string& registration_id) const {
79 if (sender_ids.empty() || registration_id.empty())
80 return std::string();
82 // Serialize as:
83 // sender1,sender2,...=reg_id
84 std::string value;
85 for (std::vector<std::string>::const_iterator iter = sender_ids.begin();
86 iter != sender_ids.end(); ++iter) {
87 DCHECK(!iter->empty() &&
88 iter->find(',') == std::string::npos &&
89 iter->find('=') == std::string::npos);
90 if (!value.empty())
91 value += ",";
92 value += *iter;
95 value += '=';
96 value += registration_id;
97 return value;
100 bool GCMRegistrationInfo::Deserialize(
101 const std::string& serialzied_key,
102 const std::string& serialzied_value,
103 std::string* registration_id) {
104 if (serialzied_key.empty() || serialzied_value.empty())
105 return false;
107 // Application ID is same as the serialized key.
108 app_id = serialzied_key;
110 // Sender IDs and registration ID are constructed from the serialized value.
111 size_t pos = serialzied_value.find('=');
112 if (pos == std::string::npos)
113 return false;
115 std::string senders = serialzied_value.substr(0, pos);
116 std::string registration_id_str = serialzied_value.substr(pos + 1);
118 sender_ids = base::SplitString(
119 senders, ",", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
120 if (sender_ids.empty() || registration_id_str.empty()) {
121 sender_ids.clear();
122 registration_id_str.clear();
123 return false;
126 if (registration_id)
127 *registration_id = registration_id_str;
129 return true;
132 // static
133 const InstanceIDTokenInfo* InstanceIDTokenInfo::FromRegistrationInfo(
134 const RegistrationInfo* registration_info) {
135 if (!registration_info || registration_info->GetType() != INSTANCE_ID_TOKEN)
136 return NULL;
137 return static_cast<const InstanceIDTokenInfo*>(registration_info);
140 // static
141 InstanceIDTokenInfo* InstanceIDTokenInfo::FromRegistrationInfo(
142 RegistrationInfo* registration_info) {
143 if (!registration_info || registration_info->GetType() != INSTANCE_ID_TOKEN)
144 return NULL;
145 return static_cast<InstanceIDTokenInfo*>(registration_info);
148 InstanceIDTokenInfo::InstanceIDTokenInfo() {
151 InstanceIDTokenInfo::~InstanceIDTokenInfo() {
154 RegistrationInfo::RegistrationType InstanceIDTokenInfo::GetType() const {
155 return INSTANCE_ID_TOKEN;
158 std::string InstanceIDTokenInfo::GetSerializedKey() const {
159 DCHECK(authorized_entity.find(',') == std::string::npos &&
160 scope.find(',') == std::string::npos);
162 // Multiple registrations are supported for Instance ID. So the key is based
163 // on the combination of (app_id, authorized_entity, scope).
165 // Adds a prefix to differentiate easily with GCM registration key.
166 std::string key(kInsanceIDSerializationPrefix);
167 key += app_id;
168 key += ",";
169 key += authorized_entity;
170 key += ",";
171 key += scope;
172 return key;
175 std::string InstanceIDTokenInfo::GetSerializedValue(
176 const std::string& registration_id) const {
177 return registration_id;
180 bool InstanceIDTokenInfo::Deserialize(
181 const std::string& serialized_key,
182 const std::string& serialized_value,
183 std::string* registration_id) {
184 if (serialized_key.empty() || serialized_value.empty())
185 return false;
187 if (!base::StartsWithASCII(serialized_key, kInsanceIDSerializationPrefix,
188 true))
189 return false;
191 std::vector<std::string> fields = base::SplitString(
192 serialized_key.substr(kInsanceIDSerializationPrefixLength),
193 ",", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
194 if (fields.size() != 3 || fields[0].empty() ||
195 fields[1].empty() || fields[2].empty()) {
196 return false;
198 app_id = fields[0];
199 authorized_entity = fields[1];
200 scope = fields[2];
202 // Registration ID is same as the serialized value;
203 if (registration_id)
204 *registration_id = serialized_value;
206 return true;
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)
218 return true;
219 if (a->app_id > b->app_id)
220 return false;
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.
230 if (!iid_a)
231 return iid_b != NULL;
233 // iid_a && !iid_b => false.
234 if (!iid_b)
235 return false;
237 // Otherwise, compare with authorized_entity and scope.
238 if (iid_a->authorized_entity < iid_b->authorized_entity)
239 return true;
240 if (iid_a->authorized_entity > iid_b->authorized_entity)
241 return false;
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;
249 return map.count(
250 make_linked_ptr<RegistrationInfo>(gcm_registration.release())) > 0;
253 } // namespace gcm