| 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..31f412d409238adc72910de5ee1cd6aa2f10fd9e
|
| --- /dev/null
|
| +++ b/components/gcm_driver/registration_info.cc
|
| @@ -0,0 +1,251 @@
|
| +// Copyright 2015 The Chromium Authors. All rights reserved.
|
| +// 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();
|
| + }
|
| + 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;
|
| + }
|
| +
|
| + value += '=';
|
| + value += registration_id;
|
| + return value;
|
| +}
|
| +
|
| +bool GCMRegistrationInfo::Deserialize(
|
| + 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) {
|
| + 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;
|
| + }
|
| + 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.
|
| + // This makes GCM record is sorted before InstanceID record.
|
| + 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;
|
| +}
|
| +
|
| +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
|
|
|