Chromium Code Reviews| Index: components/gcm_driver/registration_info.cc |
| diff --git a/components/gcm_driver/registration_info.cc b/components/gcm_driver/registration_info.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..aa298f775744e2126fcc1bf87c60f62c8ebe7707 |
| --- /dev/null |
| +++ b/components/gcm_driver/registration_info.cc |
| @@ -0,0 +1,249 @@ |
| +// Copyright 2014 The Chromium Authors. All rights reserved. |
|
fgorski
2015/05/13 18:32:39
2015
jianli
2015/05/13 22:42:56
Done.
|
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "components/gcm_driver/registration_info.h" |
| + |
| +#include "base/strings/string_util.h" |
| + |
| +namespace gcm { |
| + |
| +namespace { |
| +const char kInsanceIDSerializationPrefix[] = "iid-"; |
| +const int kInsanceIDSerializationPrefixLength = |
| + sizeof(kInsanceIDSerializationPrefix) / sizeof(char) - 1; |
| +} // namespace |
| + |
| +// static |
| +scoped_ptr<RegistrationInfo> RegistrationInfo::BuildFromString( |
| + const std::string& serialzied_key, |
| + const std::string& serialzied_value, |
| + std::string* registration_id) { |
| + scoped_ptr<RegistrationInfo> registration; |
| + |
| + if (StartsWithASCII(serialzied_key, kInsanceIDSerializationPrefix, true)) |
| + registration.reset(new InstanceIDTokenInfo); |
| + else |
| + registration.reset(new GCMRegistrationInfo); |
| + |
| + if (!registration->Deserialize(serialzied_key, |
| + serialzied_value, |
| + registration_id)) |
| + registration.reset(); |
|
fgorski
2015/05/13 18:32:40
surround with {}
jianli
2015/05/13 22:42:56
Done.
|
| + return registration.Pass(); |
| +} |
| + |
| +RegistrationInfo::RegistrationInfo() { |
| +} |
| + |
| +RegistrationInfo::~RegistrationInfo() { |
| +} |
| + |
| +// static |
| +const GCMRegistrationInfo* GCMRegistrationInfo::FromRegistrationInfo( |
| + const RegistrationInfo* registration_info) { |
| + if (!registration_info || registration_info->GetType() != GCM_REGISTRATION) |
| + return NULL; |
| + return static_cast<const GCMRegistrationInfo*>(registration_info); |
| +} |
| + |
| +// static |
| +GCMRegistrationInfo* GCMRegistrationInfo::FromRegistrationInfo( |
| + RegistrationInfo* registration_info) { |
| + if (!registration_info || registration_info->GetType() != GCM_REGISTRATION) |
| + return NULL; |
| + return static_cast<GCMRegistrationInfo*>(registration_info); |
| +} |
| + |
| +GCMRegistrationInfo::GCMRegistrationInfo() { |
| +} |
| + |
| +GCMRegistrationInfo::~GCMRegistrationInfo() { |
| +} |
| + |
| +RegistrationInfo::RegistrationType GCMRegistrationInfo::GetType() const { |
| + return GCM_REGISTRATION; |
| +} |
| + |
| +std::string GCMRegistrationInfo::GetSerializedKey() const { |
| + // Multiple registrations are not supported for legacy GCM. So the key is |
| + // purely based on the application id. |
| + return app_id; |
| +} |
| + |
| +std::string GCMRegistrationInfo::GetSerializedValue( |
| + const std::string& registration_id) const { |
| + if (sender_ids.empty() || registration_id.empty()) |
| + return std::string(); |
| + |
| + // Serialize as: |
| + // sender1,sender2,...=reg_id |
| + std::string value; |
| + for (std::vector<std::string>::const_iterator iter = sender_ids.begin(); |
| + iter != sender_ids.end(); ++iter) { |
| + DCHECK(!iter->empty() && |
| + iter->find(',') == std::string::npos && |
| + iter->find('=') == std::string::npos); |
| + if (!value.empty()) |
| + value += ","; |
| + value += *iter; |
| + } |
| + |
| + DCHECK(registration_id.find('=') == std::string::npos); |
|
fgorski
2015/05/13 18:32:39
are we sure that is the case?
Even if it had =, w
jianli
2015/05/13 22:42:56
I don't think registration ID will contain '='. Bu
|
| + value += '='; |
| + value += registration_id; |
| + return value; |
| +} |
| + |
| +bool GCMRegistrationInfo::Deserialize( |
|
fgorski
2015/05/13 18:32:40
Will this deserialize what we have in store today?
jianli
2015/05/13 22:42:56
Yes. We still serialize and deserialize GCM regist
|
| + const std::string& serialzied_key, |
| + const std::string& serialzied_value, |
| + std::string* registration_id) { |
| + if (serialzied_key.empty() || serialzied_value.empty()) |
| + return false; |
| + |
| + // Application ID is same as the serialized key. |
| + app_id = serialzied_key; |
| + |
| + // Sender IDs and registration ID are constructed from the serialized value. |
| + size_t pos = serialzied_value.find('='); |
| + if (pos == std::string::npos) |
| + return false; |
| + |
| + std::string senders = serialzied_value.substr(0, pos); |
| + std::string registration_id_str = serialzied_value.substr(pos + 1); |
| + |
| + Tokenize(senders, ",", &sender_ids); |
| + |
| + if (sender_ids.empty() || registration_id_str.empty()) { |
| + sender_ids.clear(); |
| + registration_id_str.clear(); |
| + return false; |
| + } |
| + |
| + if (registration_id) |
| + *registration_id = registration_id_str; |
| + |
| + return true; |
| +} |
| + |
| +// static |
| +const InstanceIDTokenInfo* InstanceIDTokenInfo::FromRegistrationInfo( |
| + const RegistrationInfo* registration_info) { |
| + if (!registration_info || registration_info->GetType() != INSTANCE_ID_TOKEN) |
| + return NULL; |
| + return static_cast<const InstanceIDTokenInfo*>(registration_info); |
| +} |
| + |
| +// static |
| +InstanceIDTokenInfo* InstanceIDTokenInfo::FromRegistrationInfo( |
| + RegistrationInfo* registration_info) { |
| + if (!registration_info || registration_info->GetType() != INSTANCE_ID_TOKEN) |
| + return NULL; |
| + return static_cast<InstanceIDTokenInfo*>(registration_info); |
| +} |
| + |
| +InstanceIDTokenInfo::InstanceIDTokenInfo() { |
| +} |
| + |
| +InstanceIDTokenInfo::~InstanceIDTokenInfo() { |
| +} |
| + |
| +RegistrationInfo::RegistrationType InstanceIDTokenInfo::GetType() const { |
| + return INSTANCE_ID_TOKEN; |
| +} |
| + |
| +std::string InstanceIDTokenInfo::GetSerializedKey() const { |
| + DCHECK(authorized_entity.find(',') == std::string::npos && |
| + scope.find(',') == std::string::npos); |
| + |
| + // Multiple registrations are supported for Instance ID. So the key is based |
| + // on the combination of (app_id, authorized_entity, scope). |
| + |
| + // Adds a prefix to differentiate easily with GCM registration key. |
| + std::string key(kInsanceIDSerializationPrefix); |
| + key += app_id; |
| + key += ","; |
| + key += authorized_entity; |
| + key += ","; |
| + key += scope; |
| + return key; |
| +} |
| + |
| +std::string InstanceIDTokenInfo::GetSerializedValue( |
| + const std::string& registration_id) const { |
| + return registration_id; |
| +} |
| + |
| +bool InstanceIDTokenInfo::Deserialize( |
| + const std::string& serialized_key, |
| + const std::string& serialized_value, |
| + std::string* registration_id) { |
|
fgorski
2015/05/13 18:32:39
nit: token?
jianli
2015/05/13 22:42:56
I rather still call it registration_id since it is
|
| + if (serialized_key.empty() || serialized_value.empty()) |
| + return false; |
| + |
| + if (!StartsWithASCII(serialized_key, kInsanceIDSerializationPrefix, true)) |
| + return false; |
| + |
| + std::vector<std::string> fields; |
| + Tokenize(serialized_key.substr(kInsanceIDSerializationPrefixLength), |
| + ",", |
| + &fields); |
| + if (fields.size() != 3 || fields[0].empty() || |
| + fields[1].empty() || fields[2].empty()) |
| + return false; |
|
fgorski
2015/05/13 18:32:40
{}
jianli
2015/05/13 22:42:56
Done.
|
| + app_id = fields[0]; |
| + authorized_entity = fields[1]; |
| + scope = fields[2]; |
| + |
| + // Registration ID is same as the serialized value; |
| + if (registration_id) |
| + *registration_id = serialized_value; |
| + |
| + return true; |
| +} |
| + |
| +bool RegistrationInfoComparer::operator()( |
| + const linked_ptr<RegistrationInfo>& a, |
| + const linked_ptr<RegistrationInfo>& b) const { |
| + DCHECK(a.get() && b.get()); |
| + |
| + // For GCMRegistrationInfo, the comparison is based on app_id only. |
| + // For InstanceIDTokenInfo, the comparison is bsaed on |
| + // <app_id, authorized_entity, scope>. |
| + if (a->app_id < b->app_id) |
| + return true; |
| + if (a->app_id > b->app_id) |
| + return false; |
| + |
| + InstanceIDTokenInfo* iid_a = |
| + InstanceIDTokenInfo::FromRegistrationInfo(a.get()); |
| + InstanceIDTokenInfo* iid_b = |
| + InstanceIDTokenInfo::FromRegistrationInfo(b.get()); |
| + |
| + // !iid_a && !iid_b => false. |
| + // !iid_a && iid_b => true. |
|
fgorski
2015/05/13 18:32:40
add comment: GCM registrationID sort before instan
jianli
2015/05/13 22:42:56
Done.
|
| + if (!iid_a) |
| + return iid_b != NULL; |
| + |
| + // iid_a && !iid_b => false. |
| + if (!iid_b) |
| + return false; |
| + |
| + // Otherwise, compare with authorized_entity and scope. |
| + if (iid_a->authorized_entity < iid_b->authorized_entity) |
| + return true; |
| + if (iid_a->authorized_entity > iid_b->authorized_entity) |
| + return false; |
| + return iid_a->scope > iid_b->scope; |
|
fgorski
2015/05/13 18:32:40
why not <, which would be natural way of doing it?
jianli
2015/05/13 22:42:56
It should be <. Sorry for my typo.
|
| +} |
| + |
| +bool ExistsGCMRegistrationInMap(const RegistrationInfoMap& map, |
| + const std::string& app_id) { |
| + scoped_ptr<GCMRegistrationInfo> gcm_registration(new GCMRegistrationInfo); |
| + gcm_registration->app_id = app_id; |
| + return map.count( |
| + make_linked_ptr<RegistrationInfo>(gcm_registration.release())) > 0; |
| +} |
| + |
| +} // namespace gcm |