| 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 <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include "base/base64.h" | 10 #include "base/base64.h" |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/logging.h" | 12 #include "base/logging.h" |
| 13 #include "base/memory/scoped_ptr.h" | 13 #include "base/memory/scoped_ptr.h" |
| 14 #include "base/message_loop/message_loop.h" | 14 #include "base/message_loop/message_loop.h" |
| 15 #include "base/strings/string_number_conversions.h" | 15 #include "base/strings/string_number_conversions.h" |
| 16 #include "components/gcm_driver/gcm_driver_desktop.h" | 16 #include "components/gcm_driver/gcm_driver.h" |
| 17 #include "crypto/random.h" | 17 #include "crypto/random.h" |
| 18 | 18 |
| 19 namespace instance_id { | 19 namespace instance_id { |
| 20 | 20 |
| 21 namespace { | 21 namespace { |
| 22 | 22 |
| 23 InstanceID::Result GCMClientResultToInstanceIDResult( | 23 InstanceID::Result GCMClientResultToInstanceIDResult( |
| 24 gcm::GCMClient::Result result) { | 24 gcm::GCMClient::Result result) { |
| 25 switch (result) { | 25 switch (result) { |
| 26 case gcm::GCMClient::SUCCESS: | 26 case gcm::GCMClient::SUCCESS: |
| (...skipping 14 matching lines...) Expand all Loading... |
| 41 NOTREACHED() << "Unexpected value of result cannot be converted: " | 41 NOTREACHED() << "Unexpected value of result cannot be converted: " |
| 42 << result; | 42 << result; |
| 43 } | 43 } |
| 44 return InstanceID::UNKNOWN_ERROR; | 44 return InstanceID::UNKNOWN_ERROR; |
| 45 } | 45 } |
| 46 | 46 |
| 47 } // namespace | 47 } // namespace |
| 48 | 48 |
| 49 // static | 49 // static |
| 50 scoped_ptr<InstanceID> InstanceID::Create(const std::string& app_id, | 50 scoped_ptr<InstanceID> InstanceID::Create(const std::string& app_id, |
| 51 gcm::GCMDriver* gcm_driver) { | 51 gcm::InstanceIDHandler* handler) { |
| 52 return make_scoped_ptr(new InstanceIDImpl(app_id, gcm_driver)); | 52 return make_scoped_ptr(new InstanceIDImpl(app_id, handler)); |
| 53 } | 53 } |
| 54 | 54 |
| 55 InstanceIDImpl::InstanceIDImpl(const std::string& app_id, | 55 InstanceIDImpl::InstanceIDImpl(const std::string& app_id, |
| 56 gcm::GCMDriver* gcm_driver) | 56 gcm::InstanceIDHandler* handler) |
| 57 : InstanceID(app_id), | 57 : InstanceID(app_id, handler), weak_ptr_factory_(this) { |
| 58 gcm_driver_(gcm_driver), | 58 handler->GetInstanceIDData( |
| 59 weak_ptr_factory_(this) { | 59 app_id, base::Bind(&InstanceIDImpl::GetInstanceIDDataCompleted, |
| 60 GetInstanceIDHandler()->GetInstanceIDData( | 60 weak_ptr_factory_.GetWeakPtr())); |
| 61 app_id, | |
| 62 base::Bind(&InstanceIDImpl::GetInstanceIDDataCompleted, | |
| 63 weak_ptr_factory_.GetWeakPtr())); | |
| 64 } | 61 } |
| 65 | 62 |
| 66 InstanceIDImpl::~InstanceIDImpl() { | 63 InstanceIDImpl::~InstanceIDImpl() { |
| 67 } | 64 } |
| 68 | 65 |
| 69 void InstanceIDImpl::GetID(const GetIDCallback& callback) { | 66 void InstanceIDImpl::GetID(const GetIDCallback& callback) { |
| 70 if (!delayed_task_controller_.CanRunTaskWithoutDelay()) { | 67 if (!delayed_task_controller_.CanRunTaskWithoutDelay()) { |
| 71 delayed_task_controller_.AddTask( | 68 delayed_task_controller_.AddTask( |
| 72 base::Bind(&InstanceIDImpl::DoGetID, | 69 base::Bind(&InstanceIDImpl::DoGetID, |
| 73 weak_ptr_factory_.GetWeakPtr(), | 70 weak_ptr_factory_.GetWeakPtr(), |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 122 DoGetToken(authorized_entity, scope, options, callback); | 119 DoGetToken(authorized_entity, scope, options, callback); |
| 123 } | 120 } |
| 124 | 121 |
| 125 void InstanceIDImpl::DoGetToken( | 122 void InstanceIDImpl::DoGetToken( |
| 126 const std::string& authorized_entity, | 123 const std::string& authorized_entity, |
| 127 const std::string& scope, | 124 const std::string& scope, |
| 128 const std::map<std::string, std::string>& options, | 125 const std::map<std::string, std::string>& options, |
| 129 const GetTokenCallback& callback) { | 126 const GetTokenCallback& callback) { |
| 130 EnsureIDGenerated(); | 127 EnsureIDGenerated(); |
| 131 | 128 |
| 132 GetInstanceIDHandler()->GetToken( | 129 handler()->GetToken(app_id(), authorized_entity, scope, options, |
| 133 app_id(), | 130 base::Bind(&InstanceIDImpl::OnGetTokenCompleted, |
| 134 authorized_entity, | 131 weak_ptr_factory_.GetWeakPtr(), callback)); |
| 135 scope, | |
| 136 options, | |
| 137 base::Bind(&InstanceIDImpl::OnGetTokenCompleted, | |
| 138 weak_ptr_factory_.GetWeakPtr(), | |
| 139 callback)); | |
| 140 } | 132 } |
| 141 | 133 |
| 142 void InstanceIDImpl::DeleteToken(const std::string& authorized_entity, | 134 void InstanceIDImpl::DeleteToken(const std::string& authorized_entity, |
| 143 const std::string& scope, | 135 const std::string& scope, |
| 144 const DeleteTokenCallback& callback) { | 136 const DeleteTokenCallback& callback) { |
| 145 DCHECK(!authorized_entity.empty()); | 137 DCHECK(!authorized_entity.empty()); |
| 146 DCHECK(!scope.empty()); | 138 DCHECK(!scope.empty()); |
| 147 | 139 |
| 148 if (!delayed_task_controller_.CanRunTaskWithoutDelay()) { | 140 if (!delayed_task_controller_.CanRunTaskWithoutDelay()) { |
| 149 delayed_task_controller_.AddTask( | 141 delayed_task_controller_.AddTask( |
| (...skipping 11 matching lines...) Expand all Loading... |
| 161 void InstanceIDImpl::DoDeleteToken( | 153 void InstanceIDImpl::DoDeleteToken( |
| 162 const std::string& authorized_entity, | 154 const std::string& authorized_entity, |
| 163 const std::string& scope, | 155 const std::string& scope, |
| 164 const DeleteTokenCallback& callback) { | 156 const DeleteTokenCallback& callback) { |
| 165 // Nothing to delete if the ID has not been generated. | 157 // Nothing to delete if the ID has not been generated. |
| 166 if (id_.empty()) { | 158 if (id_.empty()) { |
| 167 callback.Run(InstanceID::INVALID_PARAMETER); | 159 callback.Run(InstanceID::INVALID_PARAMETER); |
| 168 return; | 160 return; |
| 169 } | 161 } |
| 170 | 162 |
| 171 GetInstanceIDHandler()->DeleteToken( | 163 handler()->DeleteToken(app_id(), authorized_entity, scope, |
| 172 app_id(), | 164 base::Bind(&InstanceIDImpl::OnDeleteTokenCompleted, |
| 173 authorized_entity, | 165 weak_ptr_factory_.GetWeakPtr(), callback)); |
| 174 scope, | |
| 175 base::Bind(&InstanceIDImpl::OnDeleteTokenCompleted, | |
| 176 weak_ptr_factory_.GetWeakPtr(), | |
| 177 callback)); | |
| 178 } | 166 } |
| 179 | 167 |
| 180 void InstanceIDImpl::DeleteID(const DeleteIDCallback& callback) { | 168 void InstanceIDImpl::DeleteID(const DeleteIDCallback& callback) { |
| 181 if (!delayed_task_controller_.CanRunTaskWithoutDelay()) { | 169 if (!delayed_task_controller_.CanRunTaskWithoutDelay()) { |
| 182 delayed_task_controller_.AddTask( | 170 delayed_task_controller_.AddTask( |
| 183 base::Bind(&InstanceIDImpl::DoDeleteID, | 171 base::Bind(&InstanceIDImpl::DoDeleteID, |
| 184 weak_ptr_factory_.GetWeakPtr(), | 172 weak_ptr_factory_.GetWeakPtr(), |
| 185 callback)); | 173 callback)); |
| 186 return; | 174 return; |
| 187 } | 175 } |
| 188 | 176 |
| 189 DoDeleteID(callback); | 177 DoDeleteID(callback); |
| 190 } | 178 } |
| 191 | 179 |
| 192 void InstanceIDImpl::DoDeleteID(const DeleteIDCallback& callback) { | 180 void InstanceIDImpl::DoDeleteID(const DeleteIDCallback& callback) { |
| 193 // Nothing to do if ID has not been generated. | 181 // Nothing to do if ID has not been generated. |
| 194 if (id_.empty()) { | 182 if (id_.empty()) { |
| 195 callback.Run(InstanceID::SUCCESS); | 183 callback.Run(InstanceID::SUCCESS); |
| 196 return; | 184 return; |
| 197 } | 185 } |
| 198 | 186 |
| 199 GetInstanceIDHandler()->DeleteAllTokensForApp( | 187 handler()->DeleteAllTokensForApp( |
| 200 app_id(), | 188 app_id(), base::Bind(&InstanceIDImpl::OnDeleteIDCompleted, |
| 201 base::Bind(&InstanceIDImpl::OnDeleteIDCompleted, | 189 weak_ptr_factory_.GetWeakPtr(), callback)); |
| 202 weak_ptr_factory_.GetWeakPtr(), | |
| 203 callback)); | |
| 204 | 190 |
| 205 GetInstanceIDHandler()->RemoveInstanceIDData(app_id()); | 191 handler()->RemoveInstanceIDData(app_id()); |
| 206 | 192 |
| 207 id_.clear(); | 193 id_.clear(); |
| 208 creation_time_ = base::Time(); | 194 creation_time_ = base::Time(); |
| 209 } | 195 } |
| 210 | 196 |
| 211 void InstanceIDImpl::OnGetTokenCompleted(const GetTokenCallback& callback, | 197 void InstanceIDImpl::OnGetTokenCompleted(const GetTokenCallback& callback, |
| 212 const std::string& token, | 198 const std::string& token, |
| 213 gcm::GCMClient::Result result) { | 199 gcm::GCMClient::Result result) { |
| 214 callback.Run(token, GCMClientResultToInstanceIDResult(result)); | 200 callback.Run(token, GCMClientResultToInstanceIDResult(result)); |
| 215 } | 201 } |
| (...skipping 22 matching lines...) Expand all Loading... |
| 238 if (!base::StringToInt64(extra_data, &time_internal)) { | 224 if (!base::StringToInt64(extra_data, &time_internal)) { |
| 239 DVLOG(1) << "Failed to parse the time data: " + extra_data; | 225 DVLOG(1) << "Failed to parse the time data: " + extra_data; |
| 240 return; | 226 return; |
| 241 } | 227 } |
| 242 creation_time_ = base::Time::FromInternalValue(time_internal); | 228 creation_time_ = base::Time::FromInternalValue(time_internal); |
| 243 } | 229 } |
| 244 | 230 |
| 245 delayed_task_controller_.SetReady(); | 231 delayed_task_controller_.SetReady(); |
| 246 } | 232 } |
| 247 | 233 |
| 248 gcm::InstanceIDHandler* InstanceIDImpl::GetInstanceIDHandler() const { | |
| 249 gcm::InstanceIDHandler* handler = gcm_driver_->GetInstanceIDHandler(); | |
| 250 DCHECK(handler); | |
| 251 return handler; | |
| 252 } | |
| 253 | |
| 254 void InstanceIDImpl::EnsureIDGenerated() { | 234 void InstanceIDImpl::EnsureIDGenerated() { |
| 255 if (!id_.empty()) | 235 if (!id_.empty()) |
| 256 return; | 236 return; |
| 257 | 237 |
| 258 // Now produce the ID in the following steps: | 238 // Now produce the ID in the following steps: |
| 259 | 239 |
| 260 // 1) Generates the random number in 8 bytes which is required by the server. | 240 // 1) Generates the random number in 8 bytes which is required by the server. |
| 261 // We don't want to be strictly cryptographically secure. The server might | 241 // We don't want to be strictly cryptographically secure. The server might |
| 262 // reject the ID if there is a conflict or problem. | 242 // reject the ID if there is a conflict or problem. |
| 263 uint8_t bytes[kInstanceIDByteLength]; | 243 uint8_t bytes[kInstanceIDByteLength]; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 274 base::Base64Encode( | 254 base::Base64Encode( |
| 275 base::StringPiece(reinterpret_cast<const char*>(bytes), sizeof(bytes)), | 255 base::StringPiece(reinterpret_cast<const char*>(bytes), sizeof(bytes)), |
| 276 &id_); | 256 &id_); |
| 277 std::replace(id_.begin(), id_.end(), '+', '-'); | 257 std::replace(id_.begin(), id_.end(), '+', '-'); |
| 278 std::replace(id_.begin(), id_.end(), '/', '_'); | 258 std::replace(id_.begin(), id_.end(), '/', '_'); |
| 279 id_.erase(std::remove(id_.begin(), id_.end(), '='), id_.end()); | 259 id_.erase(std::remove(id_.begin(), id_.end(), '='), id_.end()); |
| 280 | 260 |
| 281 creation_time_ = base::Time::Now(); | 261 creation_time_ = base::Time::Now(); |
| 282 | 262 |
| 283 // Save to the persistent store. | 263 // Save to the persistent store. |
| 284 GetInstanceIDHandler()->AddInstanceIDData( | 264 handler()->AddInstanceIDData( |
| 285 app_id(), | 265 app_id(), id_, base::Int64ToString(creation_time_.ToInternalValue())); |
| 286 id_, | |
| 287 base::Int64ToString(creation_time_.ToInternalValue())); | |
| 288 } | 266 } |
| 289 | 267 |
| 290 } // namespace instance_id | 268 } // namespace instance_id |
| OLD | NEW |