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 |