Chromium Code Reviews| 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); | |
|
gene
2013/07/18 09:56:46
Why don't you just printf(kUserConfirmationTitle);
maksymb
2013/07/22 19:52:16
Done.
| |
| 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, | |
| 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; | |
|
gene
2013/07/18 09:56:46
I think it should be different errors if registrat
maksymb
2013/07/22 19:52:16
Added comments.
| |
| 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), | |
| 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 |