Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(282)

Side by Side Diff: components/gcm_driver/instance_id/instance_id_impl.cc

Issue 1137463003: Support getting and deleting token for Instance ID. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Patch to land Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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) {
23 case gcm::GCMClient::SUCCESS:
24 return InstanceID::SUCCESS;
25 case gcm::GCMClient::INVALID_PARAMETER:
26 return InstanceID::INVALID_PARAMETER;
27 case gcm::GCMClient::ASYNC_OPERATION_PENDING:
28 return InstanceID::ASYNC_OPERATION_PENDING;
29 case gcm::GCMClient::GCM_DISABLED:
30 return InstanceID::DISABLED;
31 case gcm::GCMClient::NETWORK_ERROR:
32 return InstanceID::NETWORK_ERROR;
33 case gcm::GCMClient::SERVER_ERROR:
34 return InstanceID::SERVER_ERROR;
35 case gcm::GCMClient::UNKNOWN_ERROR:
36 return InstanceID::UNKNOWN_ERROR;
37 default:
38 NOTREACHED() << "Unexpected value of result cannot be converted: "
39 << result;
40 }
41 return InstanceID::UNKNOWN_ERROR;
42 }
43
44 } // namespace
45
18 // static 46 // static
19 InstanceID* InstanceID::Create(const std::string& app_id, 47 InstanceID* InstanceID::Create(const std::string& app_id,
20 gcm::GCMDriver* gcm_driver) { 48 gcm::GCMDriver* gcm_driver) {
21 return new InstanceIDImpl(app_id, gcm_driver); 49 return new InstanceIDImpl(app_id, gcm_driver);
22 } 50 }
23 51
24 InstanceIDImpl::InstanceIDImpl(const std::string& app_id, 52 InstanceIDImpl::InstanceIDImpl(const std::string& app_id,
25 gcm::GCMDriver* gcm_driver) 53 gcm::GCMDriver* gcm_driver)
26 : InstanceID(app_id), 54 : InstanceID(app_id),
27 gcm_driver_(gcm_driver), 55 gcm_driver_(gcm_driver),
28 load_from_store_(false), 56 load_from_store_(false),
29 weak_ptr_factory_(this) { 57 weak_ptr_factory_(this) {
30 gcm_driver_->GetInstanceIDStore()->GetInstanceIDData( 58 GetInstanceIDHandler()->GetInstanceIDData(
31 app_id, 59 app_id,
32 base::Bind(&InstanceIDImpl::GetInstanceIDDataCompleted, 60 base::Bind(&InstanceIDImpl::GetInstanceIDDataCompleted,
33 weak_ptr_factory_.GetWeakPtr())); 61 weak_ptr_factory_.GetWeakPtr()));
34 } 62 }
35 63
36 InstanceIDImpl::~InstanceIDImpl() { 64 InstanceIDImpl::~InstanceIDImpl() {
37 } 65 }
38 66
39 void InstanceIDImpl::GetID(const GetIDCallback& callback) { 67 void InstanceIDImpl::GetID(const GetIDCallback& callback) {
40 if (!delayed_task_controller_.CanRunTaskWithoutDelay()) { 68 if (!delayed_task_controller_.CanRunTaskWithoutDelay()) {
(...skipping 27 matching lines...) Expand all
68 void InstanceIDImpl::DoGetCreationTime( 96 void InstanceIDImpl::DoGetCreationTime(
69 const GetCreationTimeCallback& callback) { 97 const GetCreationTimeCallback& callback) {
70 callback.Run(creation_time_); 98 callback.Run(creation_time_);
71 } 99 }
72 100
73 void InstanceIDImpl::GetToken( 101 void InstanceIDImpl::GetToken(
74 const std::string& authorized_entity, 102 const std::string& authorized_entity,
75 const std::string& scope, 103 const std::string& scope,
76 const std::map<std::string, std::string>& options, 104 const std::map<std::string, std::string>& options,
77 const GetTokenCallback& callback) { 105 const GetTokenCallback& callback) {
78 NOTIMPLEMENTED(); 106 if (!delayed_task_controller_.CanRunTaskWithoutDelay()) {
107 delayed_task_controller_.AddTask(
108 base::Bind(&InstanceIDImpl::DoGetToken,
109 weak_ptr_factory_.GetWeakPtr(),
110 authorized_entity,
111 scope,
112 options,
113 callback));
114 return;
115 }
116
117 DoGetToken(authorized_entity, scope, options, callback);
118 }
119
120 void InstanceIDImpl::DoGetToken(
121 const std::string& authorized_entity,
122 const std::string& scope,
123 const std::map<std::string, std::string>& options,
124 const GetTokenCallback& callback) {
125 EnsureIDGenerated();
126
127 GetInstanceIDHandler()->GetToken(
128 app_id(),
129 authorized_entity,
130 scope,
131 options,
132 base::Bind(&InstanceIDImpl::OnGetTokenCompleted,
133 weak_ptr_factory_.GetWeakPtr(),
134 callback));
79 } 135 }
80 136
81 void InstanceIDImpl::DeleteToken(const std::string& authorized_entity, 137 void InstanceIDImpl::DeleteToken(const std::string& authorized_entity,
82 const std::string& scope, 138 const std::string& scope,
83 const DeleteTokenCallback& callback) { 139 const DeleteTokenCallback& callback) {
84 NOTIMPLEMENTED(); 140 if (!delayed_task_controller_.CanRunTaskWithoutDelay()) {
141 delayed_task_controller_.AddTask(
142 base::Bind(&InstanceIDImpl::DoDeleteToken,
143 weak_ptr_factory_.GetWeakPtr(),
144 authorized_entity,
145 scope,
146 callback));
147 return;
148 }
149
150 DoDeleteToken(authorized_entity, scope, callback);
151 }
152
153 void InstanceIDImpl::DoDeleteToken(
154 const std::string& authorized_entity,
155 const std::string& scope,
156 const DeleteTokenCallback& callback) {
157 // Nothing to delete if the ID has not been generated.
158 if (id_.empty()) {
159 callback.Run(InstanceID::SUCCESS);
160 return;
161 }
162
163 GetInstanceIDHandler()->DeleteToken(
164 app_id(),
165 authorized_entity,
166 scope,
167 base::Bind(&InstanceIDImpl::OnDeleteTokenCompleted,
168 weak_ptr_factory_.GetWeakPtr(),
169 callback));
85 } 170 }
86 171
87 void InstanceIDImpl::DeleteID(const DeleteIDCallback& callback) { 172 void InstanceIDImpl::DeleteID(const DeleteIDCallback& callback) {
88 gcm_driver_->GetInstanceIDStore()->RemoveInstanceIDData(app_id()); 173 if (!delayed_task_controller_.CanRunTaskWithoutDelay()) {
174 delayed_task_controller_.AddTask(
175 base::Bind(&InstanceIDImpl::DoDeleteID,
176 weak_ptr_factory_.GetWeakPtr(),
177 callback));
178 return;
179 }
180
181 DoDeleteID(callback);
182 }
183
184 void InstanceIDImpl::DoDeleteID(const DeleteIDCallback& callback) {
185 // Nothing to do if ID has not been generated.
186 if (id_.empty()) {
187 callback.Run(InstanceID::SUCCESS);
188 return;
189 }
190
191 GetInstanceIDHandler()->DeleteToken(
192 app_id(),
193 "*",
194 "*",
195 base::Bind(&InstanceIDImpl::OnDeleteIDCompleted,
196 weak_ptr_factory_.GetWeakPtr(),
197 callback));
198
199 GetInstanceIDHandler()->RemoveInstanceIDData(app_id());
89 200
90 id_.clear(); 201 id_.clear();
91 creation_time_ = base::Time(); 202 creation_time_ = base::Time();
203 }
92 204
93 base::MessageLoop::current()->PostTask( 205 void InstanceIDImpl::OnGetTokenCompleted(const GetTokenCallback& callback,
94 FROM_HERE, 206 const std::string& token,
95 base::Bind(callback, InstanceID::SUCCESS)); 207 gcm::GCMClient::Result result) {
208 callback.Run(token, GCMClientResultToInstanceIDResult(result));
209 }
210
211 void InstanceIDImpl::OnDeleteTokenCompleted(
212 const DeleteTokenCallback& callback,
213 gcm::GCMClient::Result result) {
214 callback.Run(GCMClientResultToInstanceIDResult(result));
215 }
216
217 void InstanceIDImpl::OnDeleteIDCompleted(
218 const DeleteIDCallback& callback,
219 gcm::GCMClient::Result result) {
220 callback.Run(GCMClientResultToInstanceIDResult(result));
96 } 221 }
97 222
98 void InstanceIDImpl::GetInstanceIDDataCompleted( 223 void InstanceIDImpl::GetInstanceIDDataCompleted(
99 const std::string& instance_id_data) { 224 const std::string& instance_id,
100 Deserialize(instance_id_data); 225 const std::string& extra_data) {
226 id_ = instance_id;
227
228 if (extra_data.empty()) {
229 creation_time_ = base::Time();
230 } else {
231 int64 time_internal = 0LL;
232 if (!base::StringToInt64(extra_data, &time_internal)) {
233 DVLOG(1) << "Failed to parse the time data: " + extra_data;
234 return;
235 }
236 creation_time_ = base::Time::FromInternalValue(time_internal);
237 }
238
101 delayed_task_controller_.SetReady(); 239 delayed_task_controller_.SetReady();
102 } 240 }
103 241
242 gcm::InstanceIDHandler* InstanceIDImpl::GetInstanceIDHandler() const {
243 gcm::InstanceIDHandler* handler = gcm_driver_->GetInstanceIDHandler();
244 DCHECK(handler);
245 return handler;
246 }
247
104 void InstanceIDImpl::EnsureIDGenerated() { 248 void InstanceIDImpl::EnsureIDGenerated() {
105 if (!id_.empty()) 249 if (!id_.empty())
106 return; 250 return;
107 251
108 // Now produce the ID in the following steps: 252 // Now produce the ID in the following steps:
109 253
110 // 1) Generates the random number in 8 bytes which is required by the server. 254 // 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 255 // We don't want to be strictly cryptographically secure. The server might
112 // reject the ID if there is a conflict or problem. 256 // reject the ID if there is a conflict or problem.
113 uint8 bytes[kInstanceIDByteLength]; 257 uint8 bytes[kInstanceIDByteLength];
(...skipping 10 matching lines...) Expand all
124 base::Base64Encode( 268 base::Base64Encode(
125 base::StringPiece(reinterpret_cast<const char*>(bytes), sizeof(bytes)), 269 base::StringPiece(reinterpret_cast<const char*>(bytes), sizeof(bytes)),
126 &id_); 270 &id_);
127 std::replace(id_.begin(), id_.end(), '+', '-'); 271 std::replace(id_.begin(), id_.end(), '+', '-');
128 std::replace(id_.begin(), id_.end(), '/', '_'); 272 std::replace(id_.begin(), id_.end(), '/', '_');
129 id_.erase(std::remove(id_.begin(), id_.end(), '='), id_.end()); 273 id_.erase(std::remove(id_.begin(), id_.end(), '='), id_.end());
130 274
131 creation_time_ = base::Time::Now(); 275 creation_time_ = base::Time::Now();
132 276
133 // Save to the persistent store. 277 // Save to the persistent store.
134 gcm_driver_->GetInstanceIDStore()->AddInstanceIDData( 278 GetInstanceIDHandler()->AddInstanceIDData(
135 app_id(), SerializeAsString()); 279 app_id(),
136 } 280 id_,
137 281 base::Int64ToString(creation_time_.ToInternalValue()));
138 std::string InstanceIDImpl::SerializeAsString() const {
139 std::string serialized_data;
140 serialized_data += id_;
141 serialized_data += ",";
142 serialized_data += base::Int64ToString(creation_time_.ToInternalValue());
143 return serialized_data;
144 }
145
146 void InstanceIDImpl::Deserialize(const std::string& serialized_data) {
147 if (serialized_data.empty())
148 return;
149 std::size_t pos = serialized_data.find(',');
150 if (pos == std::string::npos) {
151 DVLOG(1) << "Failed to deserialize the InstanceID data: " + serialized_data;
152 return;
153 }
154
155 id_ = serialized_data.substr(0, pos);
156
157 int64 time_internal = 0LL;
158 if (!base::StringToInt64(serialized_data.substr(pos + 1), &time_internal)) {
159 DVLOG(1) << "Failed to deserialize the InstanceID data: " + serialized_data;
160 return;
161 }
162 creation_time_ = base::Time::FromInternalValue(time_internal);
163 } 282 }
164 283
165 } // namespace instance_id 284 } // namespace instance_id
OLDNEW
« no previous file with comments | « components/gcm_driver/instance_id/instance_id_impl.h ('k') | components/gcm_driver/registration_info.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698