Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/gcm_driver/instance_id/instance_id_impl.h" | 5 #include "components/gcm_driver/instance_id/instance_id_impl.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include "base/base64.h" | 8 #include "base/base64.h" |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
| 12 #include "base/strings/string_number_conversions.h" | 12 #include "base/strings/string_number_conversions.h" |
| 13 #include "components/gcm_driver/gcm_driver_desktop.h" | 13 #include "components/gcm_driver/gcm_driver_desktop.h" |
| 14 #include "crypto/random.h" | 14 #include "crypto/random.h" |
| 15 | 15 |
| 16 namespace instance_id { | 16 namespace instance_id { |
| 17 | 17 |
| 18 namespace { | |
| 19 | |
| 20 InstanceID::Result GCMClientResultToInstanceIDResult( | |
| 21 gcm::GCMClient::Result result) { | |
| 22 switch (result) { | |
|
fgorski
2015/05/13 18:32:39
ASYNC_OPERATION_PENDING?
jianli
2015/05/13 22:42:56
Done.
| |
| 23 case gcm::GCMClient::SUCCESS: | |
| 24 return InstanceID::SUCCESS; | |
| 25 case gcm::GCMClient::INVALID_PARAMETER: | |
| 26 return InstanceID::INVALID_PARAMETER; | |
| 27 case gcm::GCMClient::GCM_DISABLED: | |
| 28 return InstanceID::DISABLED; | |
| 29 case gcm::GCMClient::NETWORK_ERROR: | |
| 30 return InstanceID::NETWORK_ERROR; | |
| 31 case gcm::GCMClient::SERVER_ERROR: | |
| 32 return InstanceID::SERVER_ERROR; | |
| 33 case gcm::GCMClient::UNKNOWN_ERROR: | |
| 34 return InstanceID::UNKNOWN_ERROR; | |
| 35 default: | |
| 36 NOTREACHED() << "Unexpected value of result cannot be converted: " | |
| 37 << result; | |
| 38 } | |
| 39 return InstanceID::UNKNOWN_ERROR; | |
| 40 } | |
| 41 | |
| 42 } // namespace | |
| 43 | |
| 18 // static | 44 // static |
| 19 InstanceID* InstanceID::Create(const std::string& app_id, | 45 InstanceID* InstanceID::Create(const std::string& app_id, |
| 20 gcm::GCMDriver* gcm_driver) { | 46 gcm::GCMDriver* gcm_driver) { |
| 21 return new InstanceIDImpl(app_id, gcm_driver); | 47 return new InstanceIDImpl(app_id, gcm_driver); |
| 22 } | 48 } |
| 23 | 49 |
| 24 InstanceIDImpl::InstanceIDImpl(const std::string& app_id, | 50 InstanceIDImpl::InstanceIDImpl(const std::string& app_id, |
| 25 gcm::GCMDriver* gcm_driver) | 51 gcm::GCMDriver* gcm_driver) |
| 26 : InstanceID(app_id), | 52 : InstanceID(app_id), |
| 27 gcm_driver_(gcm_driver), | 53 gcm_driver_(gcm_driver), |
| 28 load_from_store_(false), | 54 load_from_store_(false), |
| 29 weak_ptr_factory_(this) { | 55 weak_ptr_factory_(this) { |
| 30 gcm_driver_->GetInstanceIDStore()->GetInstanceIDData( | 56 GetInstanceIDHandler()->GetInstanceIDData( |
| 31 app_id, | 57 app_id, |
| 32 base::Bind(&InstanceIDImpl::GetInstanceIDDataCompleted, | 58 base::Bind(&InstanceIDImpl::GetInstanceIDDataCompleted, |
| 33 weak_ptr_factory_.GetWeakPtr())); | 59 weak_ptr_factory_.GetWeakPtr())); |
| 34 } | 60 } |
| 35 | 61 |
| 36 InstanceIDImpl::~InstanceIDImpl() { | 62 InstanceIDImpl::~InstanceIDImpl() { |
| 37 } | 63 } |
| 38 | 64 |
| 39 void InstanceIDImpl::GetID(const GetIDCallback& callback) { | 65 void InstanceIDImpl::GetID(const GetIDCallback& callback) { |
| 40 if (!delayed_task_controller_.CanRunTaskWithoutDelay()) { | 66 if (!delayed_task_controller_.CanRunTaskWithoutDelay()) { |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 68 void InstanceIDImpl::DoGetCreationTime( | 94 void InstanceIDImpl::DoGetCreationTime( |
| 69 const GetCreationTimeCallback& callback) { | 95 const GetCreationTimeCallback& callback) { |
| 70 callback.Run(creation_time_); | 96 callback.Run(creation_time_); |
| 71 } | 97 } |
| 72 | 98 |
| 73 void InstanceIDImpl::GetToken( | 99 void InstanceIDImpl::GetToken( |
| 74 const std::string& authorized_entity, | 100 const std::string& authorized_entity, |
| 75 const std::string& scope, | 101 const std::string& scope, |
| 76 const std::map<std::string, std::string>& options, | 102 const std::map<std::string, std::string>& options, |
| 77 const GetTokenCallback& callback) { | 103 const GetTokenCallback& callback) { |
| 78 NOTIMPLEMENTED(); | 104 if (!delayed_task_controller_.CanRunTaskWithoutDelay()) { |
| 105 delayed_task_controller_.AddTask( | |
| 106 base::Bind(&InstanceIDImpl::DoGetToken, | |
| 107 weak_ptr_factory_.GetWeakPtr(), | |
| 108 authorized_entity, | |
| 109 scope, | |
| 110 options, | |
| 111 callback)); | |
| 112 return; | |
| 113 } | |
| 114 | |
| 115 DoGetToken(authorized_entity, scope, options, callback); | |
| 116 } | |
| 117 | |
| 118 void InstanceIDImpl::DoGetToken( | |
| 119 const std::string& authorized_entity, | |
| 120 const std::string& scope, | |
| 121 const std::map<std::string, std::string>& options, | |
| 122 const GetTokenCallback& callback) { | |
| 123 EnsureIDGenerated(); | |
| 124 | |
| 125 GetInstanceIDHandler()->GetToken( | |
| 126 app_id(), | |
| 127 authorized_entity, | |
| 128 scope, | |
| 129 options, | |
| 130 base::Bind(&InstanceIDImpl::OnGetTokenCompleted, | |
| 131 weak_ptr_factory_.GetWeakPtr(), | |
| 132 callback)); | |
| 79 } | 133 } |
| 80 | 134 |
| 81 void InstanceIDImpl::DeleteToken(const std::string& authorized_entity, | 135 void InstanceIDImpl::DeleteToken(const std::string& authorized_entity, |
| 82 const std::string& scope, | 136 const std::string& scope, |
| 83 const DeleteTokenCallback& callback) { | 137 const DeleteTokenCallback& callback) { |
| 84 NOTIMPLEMENTED(); | 138 if (!delayed_task_controller_.CanRunTaskWithoutDelay()) { |
| 139 delayed_task_controller_.AddTask( | |
| 140 base::Bind(&InstanceIDImpl::DoDeleteToken, | |
| 141 weak_ptr_factory_.GetWeakPtr(), | |
| 142 authorized_entity, | |
| 143 scope, | |
| 144 callback)); | |
| 145 return; | |
| 146 } | |
| 147 | |
| 148 DoDeleteToken(authorized_entity, scope, callback); | |
| 149 } | |
| 150 | |
| 151 void InstanceIDImpl::DoDeleteToken( | |
| 152 const std::string& authorized_entity, | |
| 153 const std::string& scope, | |
| 154 const DeleteTokenCallback& callback) { | |
| 155 // Nothing to delete if the ID has not been generated. | |
| 156 if (id_.empty()) | |
| 157 callback.Run(InstanceID::SUCCESS); | |
| 158 | |
| 159 GetInstanceIDHandler()->DeleteToken( | |
| 160 app_id(), | |
| 161 authorized_entity, | |
| 162 scope, | |
| 163 base::Bind(&InstanceIDImpl::OnDeleteTokenCompleted, | |
| 164 weak_ptr_factory_.GetWeakPtr(), | |
| 165 callback)); | |
| 85 } | 166 } |
| 86 | 167 |
| 87 void InstanceIDImpl::DeleteID(const DeleteIDCallback& callback) { | 168 void InstanceIDImpl::DeleteID(const DeleteIDCallback& callback) { |
| 88 gcm_driver_->GetInstanceIDStore()->RemoveInstanceIDData(app_id()); | 169 GetInstanceIDHandler()->RemoveInstanceIDData(app_id()); |
| 89 | 170 |
| 90 id_.clear(); | 171 id_.clear(); |
| 91 creation_time_ = base::Time(); | 172 creation_time_ = base::Time(); |
| 92 | 173 |
| 93 base::MessageLoop::current()->PostTask( | 174 base::MessageLoop::current()->PostTask( |
| 94 FROM_HERE, | 175 FROM_HERE, |
| 95 base::Bind(callback, InstanceID::SUCCESS)); | 176 base::Bind(callback, InstanceID::SUCCESS)); |
| 96 } | 177 } |
| 97 | 178 |
| 179 void InstanceIDImpl::OnGetTokenCompleted(const GetTokenCallback& callback, | |
| 180 const std::string& token, | |
| 181 gcm::GCMClient::Result result) { | |
| 182 callback.Run(token, GCMClientResultToInstanceIDResult(result)); | |
| 183 } | |
| 184 | |
| 185 void InstanceIDImpl::OnDeleteTokenCompleted( | |
| 186 const DeleteTokenCallback& callback, | |
| 187 gcm::GCMClient::Result result) { | |
| 188 callback.Run(GCMClientResultToInstanceIDResult(result)); | |
| 189 } | |
| 190 | |
| 98 void InstanceIDImpl::GetInstanceIDDataCompleted( | 191 void InstanceIDImpl::GetInstanceIDDataCompleted( |
| 99 const std::string& instance_id_data) { | 192 const std::string& instance_id_data) { |
| 100 Deserialize(instance_id_data); | 193 Deserialize(instance_id_data); |
| 101 delayed_task_controller_.SetReady(); | 194 delayed_task_controller_.SetReady(); |
| 102 } | 195 } |
| 103 | 196 |
| 197 gcm::InstanceIDHandler* InstanceIDImpl::GetInstanceIDHandler() const { | |
| 198 gcm::InstanceIDHandler* handler = gcm_driver_->GetInstanceIDHandler(); | |
| 199 DCHECK(handler); | |
| 200 return handler; | |
| 201 } | |
| 202 | |
| 104 void InstanceIDImpl::EnsureIDGenerated() { | 203 void InstanceIDImpl::EnsureIDGenerated() { |
| 105 if (!id_.empty()) | 204 if (!id_.empty()) |
| 106 return; | 205 return; |
| 107 | 206 |
| 108 // Now produce the ID in the following steps: | 207 // Now produce the ID in the following steps: |
| 109 | 208 |
| 110 // 1) Generates the random number in 8 bytes which is required by the server. | 209 // 1) Generates the random number in 8 bytes which is required by the server. |
| 111 // We don't want to be strictly cryptographically secure. The server might | 210 // We don't want to be strictly cryptographically secure. The server might |
| 112 // reject the ID if there is a conflict or problem. | 211 // reject the ID if there is a conflict or problem. |
| 113 uint8 bytes[kInstanceIDByteLength]; | 212 uint8 bytes[kInstanceIDByteLength]; |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 124 base::Base64Encode( | 223 base::Base64Encode( |
| 125 base::StringPiece(reinterpret_cast<const char*>(bytes), sizeof(bytes)), | 224 base::StringPiece(reinterpret_cast<const char*>(bytes), sizeof(bytes)), |
| 126 &id_); | 225 &id_); |
| 127 std::replace(id_.begin(), id_.end(), '+', '-'); | 226 std::replace(id_.begin(), id_.end(), '+', '-'); |
| 128 std::replace(id_.begin(), id_.end(), '/', '_'); | 227 std::replace(id_.begin(), id_.end(), '/', '_'); |
| 129 id_.erase(std::remove(id_.begin(), id_.end(), '='), id_.end()); | 228 id_.erase(std::remove(id_.begin(), id_.end(), '='), id_.end()); |
| 130 | 229 |
| 131 creation_time_ = base::Time::Now(); | 230 creation_time_ = base::Time::Now(); |
| 132 | 231 |
| 133 // Save to the persistent store. | 232 // Save to the persistent store. |
| 134 gcm_driver_->GetInstanceIDStore()->AddInstanceIDData( | 233 GetInstanceIDHandler()->AddInstanceIDData( |
| 135 app_id(), SerializeAsString()); | 234 app_id(), SerializeAsString()); |
| 136 } | 235 } |
| 137 | 236 |
| 138 std::string InstanceIDImpl::SerializeAsString() const { | 237 std::string InstanceIDImpl::SerializeAsString() const { |
| 139 std::string serialized_data; | 238 std::string serialized_data; |
| 140 serialized_data += id_; | 239 serialized_data += id_; |
| 141 serialized_data += ","; | 240 serialized_data += ","; |
| 142 serialized_data += base::Int64ToString(creation_time_.ToInternalValue()); | 241 serialized_data += base::Int64ToString(creation_time_.ToInternalValue()); |
| 143 return serialized_data; | 242 return serialized_data; |
| 144 } | 243 } |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 156 | 255 |
| 157 int64 time_internal = 0LL; | 256 int64 time_internal = 0LL; |
| 158 if (!base::StringToInt64(serialized_data.substr(pos + 1), &time_internal)) { | 257 if (!base::StringToInt64(serialized_data.substr(pos + 1), &time_internal)) { |
| 159 DVLOG(1) << "Failed to deserialize the InstanceID data: " + serialized_data; | 258 DVLOG(1) << "Failed to deserialize the InstanceID data: " + serialized_data; |
| 160 return; | 259 return; |
| 161 } | 260 } |
| 162 creation_time_ = base::Time::FromInternalValue(time_internal); | 261 creation_time_ = base::Time::FromInternalValue(time_internal); |
| 163 } | 262 } |
| 164 | 263 |
| 165 } // namespace instance_id | 264 } // namespace instance_id |
| OLD | NEW |