OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "cloud_print/gcp20/prototype/printer.h" | 5 #include "cloud_print/gcp20/prototype/printer.h" |
6 | 6 |
7 #include <stdio.h> | |
7 #include <string> | 8 #include <string> |
8 #include <vector> | 9 #include <vector> |
9 | 10 |
10 #include "base/command_line.h" | 11 #include "base/command_line.h" |
11 #include "base/file_util.h" | 12 #include "base/file_util.h" |
12 #include "base/guid.h" | 13 #include "base/guid.h" |
13 #include "base/json/json_reader.h" | 14 #include "base/json/json_reader.h" |
14 #include "base/json/json_writer.h" | 15 #include "base/json/json_writer.h" |
15 #include "base/strings/string_number_conversions.h" | 16 #include "base/strings/string_number_conversions.h" |
16 #include "cloud_print/gcp20/prototype/command_line_reader.h" | 17 #include "cloud_print/gcp20/prototype/command_line_reader.h" |
17 #include "cloud_print/gcp20/prototype/service_parameters.h" | 18 #include "cloud_print/gcp20/prototype/service_parameters.h" |
19 #include "cloud_print/gcp20/prototype/special_io.h" | |
18 #include "net/base/net_util.h" | 20 #include "net/base/net_util.h" |
19 #include "net/base/url_util.h" | 21 #include "net/base/url_util.h" |
20 | 22 |
21 const char* kPrinterStatePath = "printer_state.json"; | 23 const char kPrinterStatePath[] = "printer_state.json"; |
22 | 24 |
23 namespace { | 25 namespace { |
24 | 26 |
25 const char* kServiceType = "_privet._tcp.local"; | 27 const char kServiceType[] = "_privet._tcp.local"; |
26 const char* kServiceNamePrefix = "first_gcp20_device"; | 28 const char kServiceNamePrefix[] = "first_gcp20_device"; |
27 const char* kServiceDomainName = "my-privet-device.local"; | 29 const char kServiceDomainName[] = "my-privet-device.local"; |
28 | 30 |
29 const char* kPrinterName = "Google GCP2.0 Prototype"; | 31 const char kPrinterName[] = "Google GCP2.0 Prototype"; |
30 const char* kPrinterDescription = "Printer emulator"; | 32 const char kPrinterDescription[] = "Printer emulator"; |
31 | 33 |
32 const char* kCdd = | 34 const char kUserConfirmationTitle[] = "Confirm registration: type 'y' if you " |
35 "agree and any other to discard"; | |
36 const uint kUserConfirmationTimeout = 30; // in seconds | |
37 | |
38 const char kCdd[] = | |
33 "{\n" | 39 "{\n" |
34 " 'version': '1.0',\n" | 40 " 'version': '1.0',\n" |
35 " 'printer': {\n" | 41 " 'printer': {\n" |
36 " 'vendor_capability': [\n" | 42 " 'vendor_capability': [\n" |
37 " {\n" | 43 " {\n" |
38 " 'id': 'psk:MediaType',\n" | 44 " 'id': 'psk:MediaType',\n" |
39 " 'display_name': 'Media Type',\n" | 45 " 'display_name': 'Media Type',\n" |
40 " 'type': 'SELECT',\n" | 46 " 'type': 'SELECT',\n" |
41 " 'select_cap': {\n" | 47 " 'select_cap': {\n" |
42 " 'option': [\n" | 48 " 'option': [\n" |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
78 LOG(INFO) << net::IPAddressToString(iter->address); | 84 LOG(INFO) << net::IPAddressToString(iter->address); |
79 return iter->address; | 85 return iter->address; |
80 } | 86 } |
81 } | 87 } |
82 | 88 |
83 return net::IPAddressNumber(); | 89 return net::IPAddressNumber(); |
84 } | 90 } |
85 | 91 |
86 } // namespace | 92 } // namespace |
87 | 93 |
88 Printer::RegistrationInfo::RegistrationInfo() : state(DEV_REG_UNREGISTERED) { | 94 Printer::RegistrationInfo::RegistrationInfo() |
95 : state(DEV_REG_UNREGISTERED), | |
96 confirmation_state(CONFIRMATION_PENDING) { | |
89 } | 97 } |
90 | 98 |
91 Printer::RegistrationInfo::~RegistrationInfo() { | 99 Printer::RegistrationInfo::~RegistrationInfo() { |
92 } | 100 } |
93 | 101 |
94 Printer::Printer() : http_server_(this) { | 102 Printer::Printer() : http_server_(this) { |
95 } | 103 } |
96 | 104 |
97 Printer::~Printer() { | 105 Printer::~Printer() { |
98 Stop(); | 106 Stop(); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
157 if (status != PrivetHttpServer::REG_ERROR_OK) | 165 if (status != PrivetHttpServer::REG_ERROR_OK) |
158 return status; | 166 return status; |
159 | 167 |
160 if (reg_info_.state != RegistrationInfo::DEV_REG_UNREGISTERED) | 168 if (reg_info_.state != RegistrationInfo::DEV_REG_UNREGISTERED) |
161 return PrivetHttpServer::REG_ERROR_INVALID_ACTION; | 169 return PrivetHttpServer::REG_ERROR_INVALID_ACTION; |
162 | 170 |
163 reg_info_ = RegistrationInfo(); | 171 reg_info_ = RegistrationInfo(); |
164 reg_info_.user = user; | 172 reg_info_.user = user; |
165 reg_info_.state = RegistrationInfo::DEV_REG_REGISTRATION_STARTED; | 173 reg_info_.state = RegistrationInfo::DEV_REG_REGISTRATION_STARTED; |
166 | 174 |
175 printf("%s\n", kUserConfirmationTitle); | |
176 base::Time valid_until = base::Time::Now() + | |
177 base::TimeDelta::FromSeconds(kUserConfirmationTimeout); | |
178 base::MessageLoop::current()->PostTask( | |
179 FROM_HERE, | |
180 base::Bind(&Printer::WaitUserConfirmation, | |
Vitaly Buka (NO REVIEWS)
2013/07/22 04:01:23
can't use unretained here
maksymb
2013/07/22 19:52:16
Done.
| |
181 base::Unretained(this), valid_until)); | |
182 | |
167 requester_->StartRegistration(GenerateProxyId(), kPrinterName, user, kCdd); | 183 requester_->StartRegistration(GenerateProxyId(), kPrinterName, user, kCdd); |
168 | 184 |
169 return PrivetHttpServer::REG_ERROR_OK; | 185 return PrivetHttpServer::REG_ERROR_OK; |
170 } | 186 } |
171 | 187 |
172 bool Printer::CheckXPrivetTokenHeader(const std::string& token) const { | 188 bool Printer::CheckXPrivetTokenHeader(const std::string& token) const { |
173 return xtoken_.CheckValidXToken(token); | 189 return xtoken_.CheckValidXToken(token); |
174 } | 190 } |
175 | 191 |
176 bool Printer::IsRegistered() const { | 192 bool Printer::IsRegistered() const { |
177 return reg_info_.state == RegistrationInfo::DEV_REG_REGISTERED; | 193 return reg_info_.state == RegistrationInfo::DEV_REG_REGISTERED; |
178 } | 194 } |
179 | 195 |
180 PrivetHttpServer::RegistrationErrorStatus Printer::RegistrationGetClaimToken( | 196 PrivetHttpServer::RegistrationErrorStatus Printer::RegistrationGetClaimToken( |
181 const std::string& user, | 197 const std::string& user, |
182 std::string* token, | 198 std::string* token, |
183 std::string* claim_url) { | 199 std::string* claim_url) { |
184 PrivetHttpServer::RegistrationErrorStatus status = CheckCommonRegErrors(user); | 200 PrivetHttpServer::RegistrationErrorStatus status = CheckCommonRegErrors(user); |
185 if (status != PrivetHttpServer::REG_ERROR_OK) | 201 if (status != PrivetHttpServer::REG_ERROR_OK) |
186 return status; | 202 return status; |
187 | 203 |
188 // TODO(maksymb): Add user confirmation. | 204 if (reg_info_.state != RegistrationInfo::DEV_REG_REGISTRATION_STARTED && |
205 reg_info_.state != | |
206 RegistrationInfo::DEV_REG_REGISTRATION_CLAIM_TOKEN_READY) | |
207 return PrivetHttpServer::REG_ERROR_INVALID_ACTION; | |
208 | |
209 if (reg_info_.confirmation_state != RegistrationInfo::CONFIRMATION_CONFIRMED) | |
210 return ConfirmationToRegistrationError(reg_info_.confirmation_state); | |
189 | 211 |
190 if (reg_info_.state == RegistrationInfo::DEV_REG_REGISTRATION_STARTED) | 212 if (reg_info_.state == RegistrationInfo::DEV_REG_REGISTRATION_STARTED) |
191 return PrivetHttpServer::REG_ERROR_DEVICE_BUSY; | 213 return PrivetHttpServer::REG_ERROR_DEVICE_BUSY; |
192 | 214 |
193 if (reg_info_.state == | 215 *token = reg_info_.registration_token; |
194 RegistrationInfo::DEV_REG_REGISTRATION_CLAIM_TOKEN_READY) { | 216 *claim_url = reg_info_.complete_invite_url; |
195 *token = reg_info_.registration_token; | 217 return PrivetHttpServer::REG_ERROR_OK; |
196 *claim_url = reg_info_.complete_invite_url; | |
197 return PrivetHttpServer::REG_ERROR_OK; | |
198 } | |
199 | |
200 return PrivetHttpServer::REG_ERROR_INVALID_ACTION; | |
201 } | 218 } |
202 | 219 |
203 PrivetHttpServer::RegistrationErrorStatus Printer::RegistrationComplete( | 220 PrivetHttpServer::RegistrationErrorStatus Printer::RegistrationComplete( |
204 const std::string& user, | 221 const std::string& user, |
205 std::string* device_id) { | 222 std::string* device_id) { |
206 PrivetHttpServer::RegistrationErrorStatus status = CheckCommonRegErrors(user); | 223 PrivetHttpServer::RegistrationErrorStatus status = CheckCommonRegErrors(user); |
207 if (status != PrivetHttpServer::REG_ERROR_OK) | 224 if (status != PrivetHttpServer::REG_ERROR_OK) |
208 return status; | 225 return status; |
209 | 226 |
210 if (reg_info_.state != | 227 if (reg_info_.state != |
211 RegistrationInfo::DEV_REG_REGISTRATION_CLAIM_TOKEN_READY) { | 228 RegistrationInfo::DEV_REG_REGISTRATION_CLAIM_TOKEN_READY) { |
212 return PrivetHttpServer::REG_ERROR_INVALID_ACTION; | 229 return PrivetHttpServer::REG_ERROR_INVALID_ACTION; |
213 } | 230 } |
214 | 231 |
232 if (reg_info_.confirmation_state != RegistrationInfo::CONFIRMATION_CONFIRMED) | |
233 return ConfirmationToRegistrationError(reg_info_.confirmation_state); | |
234 | |
215 reg_info_.state = RegistrationInfo::DEV_REG_REGISTRATION_COMPLETING; | 235 reg_info_.state = RegistrationInfo::DEV_REG_REGISTRATION_COMPLETING; |
216 requester_->CompleteRegistration(); | 236 requester_->CompleteRegistration(); |
217 | |
218 *device_id = reg_info_.device_id; | 237 *device_id = reg_info_.device_id; |
219 | 238 |
220 return PrivetHttpServer::REG_ERROR_OK; | 239 return PrivetHttpServer::REG_ERROR_OK; |
221 } | 240 } |
222 | 241 |
223 PrivetHttpServer::RegistrationErrorStatus Printer::RegistrationCancel( | 242 PrivetHttpServer::RegistrationErrorStatus Printer::RegistrationCancel( |
224 const std::string& user) { | 243 const std::string& user) { |
225 PrivetHttpServer::RegistrationErrorStatus status = CheckCommonRegErrors(user); | 244 PrivetHttpServer::RegistrationErrorStatus status = CheckCommonRegErrors(user); |
226 if (status != PrivetHttpServer::REG_ERROR_OK && | 245 if (status != PrivetHttpServer::REG_ERROR_OK && |
227 status != PrivetHttpServer::REG_ERROR_SERVER_ERROR) { | 246 status != PrivetHttpServer::REG_ERROR_SERVER_ERROR) { |
228 return status; | 247 return status; |
229 } | 248 } |
230 | 249 |
231 if (reg_info_.state == RegistrationInfo::DEV_REG_UNREGISTERED) | 250 if (reg_info_.state == RegistrationInfo::DEV_REG_UNREGISTERED) |
232 return PrivetHttpServer::REG_ERROR_INVALID_ACTION; | 251 return PrivetHttpServer::REG_ERROR_INVALID_ACTION; |
233 | 252 |
234 reg_info_ = RegistrationInfo(); | 253 reg_info_ = RegistrationInfo(); |
254 requester_.reset(new CloudPrintRequester( | |
255 base::MessageLoop::current()->message_loop_proxy(), | |
256 this)); // Forget all old queries. | |
257 | |
235 return PrivetHttpServer::REG_ERROR_OK; | 258 return PrivetHttpServer::REG_ERROR_OK; |
236 } | 259 } |
237 | 260 |
238 void Printer::GetRegistrationServerError(std::string* description) { | 261 void Printer::GetRegistrationServerError(std::string* description) { |
239 DCHECK_EQ(reg_info_.state, RegistrationInfo::DEV_REG_REGISTRATION_ERROR) << | 262 DCHECK_EQ(reg_info_.state, RegistrationInfo::DEV_REG_REGISTRATION_ERROR) << |
240 "Method shouldn't be called when not needed."; | 263 "Method shouldn't be called when not needed."; |
241 | 264 |
242 *description = reg_info_.error_description; | 265 *description = reg_info_.error_description; |
243 } | 266 } |
244 | 267 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
299 user != reg_info_.user) { | 322 user != reg_info_.user) { |
300 return PrivetHttpServer::REG_ERROR_DEVICE_BUSY; | 323 return PrivetHttpServer::REG_ERROR_DEVICE_BUSY; |
301 } | 324 } |
302 | 325 |
303 if (reg_info_.state == RegistrationInfo::DEV_REG_REGISTRATION_ERROR) | 326 if (reg_info_.state == RegistrationInfo::DEV_REG_REGISTRATION_ERROR) |
304 return PrivetHttpServer::REG_ERROR_SERVER_ERROR; | 327 return PrivetHttpServer::REG_ERROR_SERVER_ERROR; |
305 | 328 |
306 return PrivetHttpServer::REG_ERROR_OK; | 329 return PrivetHttpServer::REG_ERROR_OK; |
307 } | 330 } |
308 | 331 |
332 void Printer::WaitUserConfirmation(base::Time valid_until) { | |
333 if (base::Time::Now() > valid_until) { | |
334 reg_info_.confirmation_state = RegistrationInfo::CONFIRMATION_TIMEOUT; | |
335 LOG(INFO) << "Confirmation timeout reached."; | |
336 return; | |
337 } | |
338 | |
339 if (kbhit()) { | |
340 int c = getche(); | |
341 if (c == 'y' || c == 'Y') { | |
342 reg_info_.confirmation_state = RegistrationInfo::CONFIRMATION_CONFIRMED; | |
343 LOG(INFO) << "Registration confirmed by user."; | |
344 } else { | |
345 reg_info_.confirmation_state = RegistrationInfo::CONFIRMATION_DISCARDED; | |
346 LOG(INFO) << "Registration discarded by user."; | |
347 } | |
348 return; | |
349 } | |
350 | |
351 base::MessageLoop::current()->PostDelayedTask( | |
352 FROM_HERE, | |
353 base::Bind(&Printer::WaitUserConfirmation, base::Unretained(this), | |
Vitaly Buka (NO REVIEWS)
2013/07/22 04:01:23
can't use unretained here
maksymb
2013/07/22 19:52:16
Done.
| |
354 valid_until), | |
355 base::TimeDelta::FromMilliseconds(100)); | |
356 } | |
357 | |
309 std::string Printer::GenerateProxyId() const { | 358 std::string Printer::GenerateProxyId() const { |
310 return "{" + base::GenerateGUID() +"}"; | 359 return "{" + base::GenerateGUID() +"}"; |
311 } | 360 } |
312 | 361 |
313 std::vector<std::string> Printer::CreateTxt() const { | 362 std::vector<std::string> Printer::CreateTxt() const { |
314 std::vector<std::string> txt; | 363 std::vector<std::string> txt; |
315 txt.push_back("txtvers=1"); | 364 txt.push_back("txtvers=1"); |
316 txt.push_back("ty=" + std::string(kPrinterName)); | 365 txt.push_back("ty=" + std::string(kPrinterName)); |
317 txt.push_back("note=" + std::string(kPrinterDescription)); | 366 txt.push_back("note=" + std::string(kPrinterDescription)); |
318 txt.push_back("url=" + std::string(kCloudPrintUrl)); | 367 txt.push_back("url=" + std::string(kCloudPrintUrl)); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
397 | 446 |
398 reg_info_ = RegistrationInfo(); | 447 reg_info_ = RegistrationInfo(); |
399 reg_info_.state = RegistrationInfo::DEV_REG_REGISTERED; | 448 reg_info_.state = RegistrationInfo::DEV_REG_REGISTERED; |
400 reg_info_.user = user; | 449 reg_info_.user = user; |
401 reg_info_.device_id = device_id; | 450 reg_info_.device_id = device_id; |
402 reg_info_.refresh_token = refresh_token; | 451 reg_info_.refresh_token = refresh_token; |
403 | 452 |
404 return true; | 453 return true; |
405 } | 454 } |
406 | 455 |
456 PrivetHttpServer::RegistrationErrorStatus | |
457 Printer::ConfirmationToRegistrationError( | |
458 RegistrationInfo::ConfirmationState state) { | |
459 switch (state) { | |
460 case RegistrationInfo::CONFIRMATION_PENDING: | |
461 return PrivetHttpServer::REG_ERROR_PENDING_USER_ACTION; | |
462 case RegistrationInfo::CONFIRMATION_DISCARDED: | |
463 return PrivetHttpServer::REG_ERROR_USER_CANCEL; | |
464 case RegistrationInfo::CONFIRMATION_CONFIRMED: | |
465 NOTREACHED(); | |
466 return PrivetHttpServer::REG_ERROR_OK; | |
467 case RegistrationInfo::CONFIRMATION_TIMEOUT: | |
468 return PrivetHttpServer::REG_ERROR_CONFIRMATION_TIMEOUT; | |
469 default: | |
470 NOTREACHED(); | |
471 return PrivetHttpServer::REG_ERROR_OK; | |
472 } | |
473 } | |
474 | |
OLD | NEW |