Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
|
fgorski
2015/05/13 18:32:39
2015
jianli
2015/05/13 22:42:56
Done.
| |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "components/gcm_driver/registration_info.h" | |
| 6 | |
| 7 #include "base/strings/string_util.h" | |
| 8 | |
| 9 namespace gcm { | |
| 10 | |
| 11 namespace { | |
| 12 const char kInsanceIDSerializationPrefix[] = "iid-"; | |
| 13 const int kInsanceIDSerializationPrefixLength = | |
| 14 sizeof(kInsanceIDSerializationPrefix) / sizeof(char) - 1; | |
| 15 } // namespace | |
| 16 | |
| 17 // static | |
| 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; | |
| 23 | |
| 24 if (StartsWithASCII(serialzied_key, kInsanceIDSerializationPrefix, true)) | |
| 25 registration.reset(new InstanceIDTokenInfo); | |
| 26 else | |
| 27 registration.reset(new GCMRegistrationInfo); | |
| 28 | |
| 29 if (!registration->Deserialize(serialzied_key, | |
| 30 serialzied_value, | |
| 31 registration_id)) | |
| 32 registration.reset(); | |
|
fgorski
2015/05/13 18:32:40
surround with {}
jianli
2015/05/13 22:42:56
Done.
| |
| 33 return registration.Pass(); | |
| 34 } | |
| 35 | |
| 36 RegistrationInfo::RegistrationInfo() { | |
| 37 } | |
| 38 | |
| 39 RegistrationInfo::~RegistrationInfo() { | |
| 40 } | |
| 41 | |
| 42 // static | |
| 43 const GCMRegistrationInfo* GCMRegistrationInfo::FromRegistrationInfo( | |
| 44 const RegistrationInfo* registration_info) { | |
| 45 if (!registration_info || registration_info->GetType() != GCM_REGISTRATION) | |
| 46 return NULL; | |
| 47 return static_cast<const GCMRegistrationInfo*>(registration_info); | |
| 48 } | |
| 49 | |
| 50 // static | |
| 51 GCMRegistrationInfo* GCMRegistrationInfo::FromRegistrationInfo( | |
| 52 RegistrationInfo* registration_info) { | |
| 53 if (!registration_info || registration_info->GetType() != GCM_REGISTRATION) | |
| 54 return NULL; | |
| 55 return static_cast<GCMRegistrationInfo*>(registration_info); | |
| 56 } | |
| 57 | |
| 58 GCMRegistrationInfo::GCMRegistrationInfo() { | |
| 59 } | |
| 60 | |
| 61 GCMRegistrationInfo::~GCMRegistrationInfo() { | |
| 62 } | |
| 63 | |
| 64 RegistrationInfo::RegistrationType GCMRegistrationInfo::GetType() const { | |
| 65 return GCM_REGISTRATION; | |
| 66 } | |
| 67 | |
| 68 std::string GCMRegistrationInfo::GetSerializedKey() const { | |
| 69 // Multiple registrations are not supported for legacy GCM. So the key is | |
| 70 // purely based on the application id. | |
| 71 return app_id; | |
| 72 } | |
| 73 | |
| 74 std::string GCMRegistrationInfo::GetSerializedValue( | |
| 75 const std::string& registration_id) const { | |
| 76 if (sender_ids.empty() || registration_id.empty()) | |
| 77 return std::string(); | |
| 78 | |
| 79 // Serialize as: | |
| 80 // sender1,sender2,...=reg_id | |
| 81 std::string value; | |
| 82 for (std::vector<std::string>::const_iterator iter = sender_ids.begin(); | |
| 83 iter != sender_ids.end(); ++iter) { | |
| 84 DCHECK(!iter->empty() && | |
| 85 iter->find(',') == std::string::npos && | |
| 86 iter->find('=') == std::string::npos); | |
| 87 if (!value.empty()) | |
| 88 value += ","; | |
| 89 value += *iter; | |
| 90 } | |
| 91 | |
| 92 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
| |
| 93 value += '='; | |
| 94 value += registration_id; | |
| 95 return value; | |
| 96 } | |
| 97 | |
| 98 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
| |
| 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()) | |
| 103 return false; | |
| 104 | |
| 105 // Application ID is same as the serialized key. | |
| 106 app_id = serialzied_key; | |
| 107 | |
| 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) | |
| 111 return false; | |
| 112 | |
| 113 std::string senders = serialzied_value.substr(0, pos); | |
| 114 std::string registration_id_str = serialzied_value.substr(pos + 1); | |
| 115 | |
| 116 Tokenize(senders, ",", &sender_ids); | |
| 117 | |
| 118 if (sender_ids.empty() || registration_id_str.empty()) { | |
| 119 sender_ids.clear(); | |
| 120 registration_id_str.clear(); | |
| 121 return false; | |
| 122 } | |
| 123 | |
| 124 if (registration_id) | |
| 125 *registration_id = registration_id_str; | |
| 126 | |
| 127 return true; | |
| 128 } | |
| 129 | |
| 130 // static | |
| 131 const InstanceIDTokenInfo* InstanceIDTokenInfo::FromRegistrationInfo( | |
| 132 const RegistrationInfo* registration_info) { | |
| 133 if (!registration_info || registration_info->GetType() != INSTANCE_ID_TOKEN) | |
| 134 return NULL; | |
| 135 return static_cast<const InstanceIDTokenInfo*>(registration_info); | |
| 136 } | |
| 137 | |
| 138 // static | |
| 139 InstanceIDTokenInfo* InstanceIDTokenInfo::FromRegistrationInfo( | |
| 140 RegistrationInfo* registration_info) { | |
| 141 if (!registration_info || registration_info->GetType() != INSTANCE_ID_TOKEN) | |
| 142 return NULL; | |
| 143 return static_cast<InstanceIDTokenInfo*>(registration_info); | |
| 144 } | |
| 145 | |
| 146 InstanceIDTokenInfo::InstanceIDTokenInfo() { | |
| 147 } | |
| 148 | |
| 149 InstanceIDTokenInfo::~InstanceIDTokenInfo() { | |
| 150 } | |
| 151 | |
| 152 RegistrationInfo::RegistrationType InstanceIDTokenInfo::GetType() const { | |
| 153 return INSTANCE_ID_TOKEN; | |
| 154 } | |
| 155 | |
| 156 std::string InstanceIDTokenInfo::GetSerializedKey() const { | |
| 157 DCHECK(authorized_entity.find(',') == std::string::npos && | |
| 158 scope.find(',') == std::string::npos); | |
| 159 | |
| 160 // Multiple registrations are supported for Instance ID. So the key is based | |
| 161 // on the combination of (app_id, authorized_entity, scope). | |
| 162 | |
| 163 // Adds a prefix to differentiate easily with GCM registration key. | |
| 164 std::string key(kInsanceIDSerializationPrefix); | |
| 165 key += app_id; | |
| 166 key += ","; | |
| 167 key += authorized_entity; | |
| 168 key += ","; | |
| 169 key += scope; | |
| 170 return key; | |
| 171 } | |
| 172 | |
| 173 std::string InstanceIDTokenInfo::GetSerializedValue( | |
| 174 const std::string& registration_id) const { | |
| 175 return registration_id; | |
| 176 } | |
| 177 | |
| 178 bool InstanceIDTokenInfo::Deserialize( | |
| 179 const std::string& serialized_key, | |
| 180 const std::string& serialized_value, | |
| 181 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
| |
| 182 if (serialized_key.empty() || serialized_value.empty()) | |
| 183 return false; | |
| 184 | |
| 185 if (!StartsWithASCII(serialized_key, kInsanceIDSerializationPrefix, true)) | |
| 186 return false; | |
| 187 | |
| 188 std::vector<std::string> fields; | |
| 189 Tokenize(serialized_key.substr(kInsanceIDSerializationPrefixLength), | |
| 190 ",", | |
| 191 &fields); | |
| 192 if (fields.size() != 3 || fields[0].empty() || | |
| 193 fields[1].empty() || fields[2].empty()) | |
| 194 return false; | |
|
fgorski
2015/05/13 18:32:40
{}
jianli
2015/05/13 22:42:56
Done.
| |
| 195 app_id = fields[0]; | |
| 196 authorized_entity = fields[1]; | |
| 197 scope = fields[2]; | |
| 198 | |
| 199 // Registration ID is same as the serialized value; | |
| 200 if (registration_id) | |
| 201 *registration_id = serialized_value; | |
| 202 | |
| 203 return true; | |
| 204 } | |
| 205 | |
| 206 bool RegistrationInfoComparer::operator()( | |
| 207 const linked_ptr<RegistrationInfo>& a, | |
| 208 const linked_ptr<RegistrationInfo>& b) const { | |
| 209 DCHECK(a.get() && b.get()); | |
| 210 | |
| 211 // For GCMRegistrationInfo, the comparison is based on app_id only. | |
| 212 // For InstanceIDTokenInfo, the comparison is bsaed on | |
| 213 // <app_id, authorized_entity, scope>. | |
| 214 if (a->app_id < b->app_id) | |
| 215 return true; | |
| 216 if (a->app_id > b->app_id) | |
| 217 return false; | |
| 218 | |
| 219 InstanceIDTokenInfo* iid_a = | |
| 220 InstanceIDTokenInfo::FromRegistrationInfo(a.get()); | |
| 221 InstanceIDTokenInfo* iid_b = | |
| 222 InstanceIDTokenInfo::FromRegistrationInfo(b.get()); | |
| 223 | |
| 224 // !iid_a && !iid_b => false. | |
| 225 // !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.
| |
| 226 if (!iid_a) | |
| 227 return iid_b != NULL; | |
| 228 | |
| 229 // iid_a && !iid_b => false. | |
| 230 if (!iid_b) | |
| 231 return false; | |
| 232 | |
| 233 // Otherwise, compare with authorized_entity and scope. | |
| 234 if (iid_a->authorized_entity < iid_b->authorized_entity) | |
| 235 return true; | |
| 236 if (iid_a->authorized_entity > iid_b->authorized_entity) | |
| 237 return false; | |
| 238 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.
| |
| 239 } | |
| 240 | |
| 241 bool ExistsGCMRegistrationInMap(const RegistrationInfoMap& map, | |
| 242 const std::string& app_id) { | |
| 243 scoped_ptr<GCMRegistrationInfo> gcm_registration(new GCMRegistrationInfo); | |
| 244 gcm_registration->app_id = app_id; | |
| 245 return map.count( | |
| 246 make_linked_ptr<RegistrationInfo>(gcm_registration.release())) > 0; | |
| 247 } | |
| 248 | |
| 249 } // namespace gcm | |
| OLD | NEW |