| 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 <stdio.h> |
| 8 #include <string> | 8 #include <string> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 35 const char kServiceDomainNameDefault[] = "my-privet-device.local"; | 35 const char kServiceDomainNameDefault[] = "my-privet-device.local"; |
| 36 | 36 |
| 37 const char kPrinterName[] = "Google GCP2.0 Prototype"; | 37 const char kPrinterName[] = "Google GCP2.0 Prototype"; |
| 38 const char kPrinterDescription[] = "Printer emulator"; | 38 const char kPrinterDescription[] = "Printer emulator"; |
| 39 | 39 |
| 40 const char kUserConfirmationTitle[] = "Confirm registration: type 'y' if you " | 40 const char kUserConfirmationTitle[] = "Confirm registration: type 'y' if you " |
| 41 "agree and any other to discard\n"; | 41 "agree and any other to discard\n"; |
| 42 const int64 kUserConfirmationTimeout = 30; // in seconds | 42 const int64 kUserConfirmationTimeout = 30; // in seconds |
| 43 | 43 |
| 44 const uint32 kReconnectTimeout = 5; // in seconds | 44 const uint32 kReconnectTimeout = 5; // in seconds |
| 45 const uint32 kPrintJobsTimeout = 10; // in seconds | 45 |
| 46 const double kTimeToNextAccessTokenUpdate = 0.8; // relatively to living time. |
| 46 | 47 |
| 47 const char kCdd[] = | 48 const char kCdd[] = |
| 48 "{\n" | 49 "{\n" |
| 49 " 'version': '1.0',\n" | 50 " 'version': '1.0',\n" |
| 50 " 'printer': {\n" | 51 " 'printer': {\n" |
| 51 " 'vendor_capability': [\n" | 52 " 'vendor_capability': [\n" |
| 52 " {\n" | 53 " {\n" |
| 53 " 'id': 'psk:MediaType',\n" | 54 " 'id': 'psk:MediaType',\n" |
| 54 " 'display_name': 'Media Type',\n" | 55 " 'display_name': 'Media Type',\n" |
| 55 " 'type': 'SELECT',\n" | 56 " 'type': 'SELECT',\n" |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 if (iter->address.size() == expected_address_size && | 92 if (iter->address.size() == expected_address_size && |
| 92 (interface_name.empty() || interface_name == iter->name)) { | 93 (interface_name.empty() || interface_name == iter->name)) { |
| 93 LOG(INFO) << net::IPAddressToString(iter->address); | 94 LOG(INFO) << net::IPAddressToString(iter->address); |
| 94 return iter->address; | 95 return iter->address; |
| 95 } | 96 } |
| 96 } | 97 } |
| 97 | 98 |
| 98 return net::IPAddressNumber(); | 99 return net::IPAddressNumber(); |
| 99 } | 100 } |
| 100 | 101 |
| 102 scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner() { |
| 103 return base::MessageLoop::current()->message_loop_proxy(); |
| 104 } |
| 105 |
| 101 } // namespace | 106 } // namespace |
| 102 | 107 |
| 103 using cloud_print_response_parser::Job; | 108 using cloud_print_response_parser::Job; |
| 104 | 109 |
| 105 Printer::RegistrationInfo::RegistrationInfo() | 110 Printer::RegistrationInfo::RegistrationInfo() |
| 106 : state(DEV_REG_UNREGISTERED), | 111 : state(DEV_REG_UNREGISTERED), |
| 107 confirmation_state(CONFIRMATION_PENDING) { | 112 confirmation_state(CONFIRMATION_PENDING) { |
| 108 } | 113 } |
| 109 | 114 |
| 110 Printer::RegistrationInfo::~RegistrationInfo() { | 115 Printer::RegistrationInfo::~RegistrationInfo() { |
| 111 } | 116 } |
| 112 | 117 |
| 113 Printer::Printer() : http_server_(this), connection_state_(OFFLINE) { | 118 Printer::Printer() |
| 119 : http_server_(this), |
| 120 connection_state_(OFFLINE), |
| 121 on_idle_posted_(false), |
| 122 pending_local_settings_check_(false), |
| 123 pending_print_jobs_check_(false) { |
| 114 } | 124 } |
| 115 | 125 |
| 116 Printer::~Printer() { | 126 Printer::~Printer() { |
| 117 Stop(); | 127 Stop(); |
| 118 } | 128 } |
| 119 | 129 |
| 120 bool Printer::Start() { | 130 bool Printer::Start() { |
| 121 if (IsOnline()) | 131 if (IsRunning()) |
| 122 return true; | 132 return true; |
| 123 | 133 |
| 124 // TODO(maksymb): Add switch for command line to control interface name. | 134 // TODO(maksymb): Add switch for command line to control interface name. |
| 125 net::IPAddressNumber ip = GetLocalIp("", false); | 135 net::IPAddressNumber ip = GetLocalIp("", false); |
| 126 if (ip.empty()) { | 136 if (ip.empty()) { |
| 127 LOG(ERROR) << "No local IP found. Cannot start printer."; | 137 LOG(ERROR) << "No local IP found. Cannot start printer."; |
| 128 return false; | 138 return false; |
| 129 } | 139 } |
| 130 VLOG(1) << "Local address: " << net::IPAddressToString(ip); | 140 VLOG(1) << "Local address: " << net::IPAddressToString(ip); |
| 131 | 141 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 145 command_line_reader::ReadDomainName(kServiceDomainNameDefault); | 155 command_line_reader::ReadDomainName(kServiceDomainNameDefault); |
| 146 if (!dns_server_.Start( | 156 if (!dns_server_.Start( |
| 147 ServiceParameters(kServiceType, service_name_prefix, service_domain_name, | 157 ServiceParameters(kServiceType, service_name_prefix, service_domain_name, |
| 148 ip, port), | 158 ip, port), |
| 149 command_line_reader::ReadTtl(kTtlDefault), | 159 command_line_reader::ReadTtl(kTtlDefault), |
| 150 CreateTxt())) { | 160 CreateTxt())) { |
| 151 http_server_.Shutdown(); | 161 http_server_.Shutdown(); |
| 152 return false; | 162 return false; |
| 153 } | 163 } |
| 154 | 164 |
| 155 // Creating Cloud Requester. | 165 print_job_handler_.reset(new PrintJobHandler); |
| 156 requester_.reset( | |
| 157 new CloudPrintRequester( | |
| 158 base::MessageLoop::current()->message_loop_proxy(), | |
| 159 this)); | |
| 160 | |
| 161 xtoken_ = XPrivetToken(); | 166 xtoken_ = XPrivetToken(); |
| 162 starttime_ = base::Time::Now(); | 167 starttime_ = base::Time::Now(); |
| 163 | 168 |
| 164 print_job_handler_.reset(new PrintJobHandler); | 169 TryConnect(); |
| 165 connection_state_ = CONNECTING; | |
| 166 WakeUp(); | |
| 167 | |
| 168 return true; | 170 return true; |
| 169 } | 171 } |
| 170 | 172 |
| 171 bool Printer::IsOnline() const { | 173 bool Printer::IsRunning() const { |
| 172 return requester_; | 174 return print_job_handler_; |
| 173 } | |
| 174 | |
| 175 void Printer::WakeUp() { | |
| 176 VLOG(3) << "Function: " << __FUNCTION__; | |
| 177 | |
| 178 if (!IsRegistered()) | |
| 179 return; | |
| 180 | |
| 181 FetchPrintJobs(); | |
| 182 } | 175 } |
| 183 | 176 |
| 184 void Printer::Stop() { | 177 void Printer::Stop() { |
| 185 dns_server_.Shutdown(); | 178 dns_server_.Shutdown(); |
| 186 http_server_.Shutdown(); | 179 http_server_.Shutdown(); |
| 187 requester_.reset(); | 180 requester_.reset(); |
| 188 print_job_handler_.reset(); | 181 print_job_handler_.reset(); |
| 182 xmpp_listener_.reset(); |
| 183 } |
| 184 |
| 185 void Printer::OnAuthError() { |
| 186 access_token_update_ = base::Time::Now(); |
| 187 ChangeState(OFFLINE); |
| 188 // TODO(maksymb): Implement *instant* updating of access_token. |
| 189 } |
| 190 |
| 191 std::string Printer::GetAccessToken() { |
| 192 return access_token_; |
| 189 } | 193 } |
| 190 | 194 |
| 191 PrivetHttpServer::RegistrationErrorStatus Printer::RegistrationStart( | 195 PrivetHttpServer::RegistrationErrorStatus Printer::RegistrationStart( |
| 192 const std::string& user) { | 196 const std::string& user) { |
| 193 PrivetHttpServer::RegistrationErrorStatus status = CheckCommonRegErrors(user); | 197 PrivetHttpServer::RegistrationErrorStatus status = CheckCommonRegErrors(user); |
| 194 if (status != PrivetHttpServer::REG_ERROR_OK) | 198 if (status != PrivetHttpServer::REG_ERROR_OK) |
| 195 return status; | 199 return status; |
| 196 | 200 |
| 197 if (reg_info_.state != RegistrationInfo::DEV_REG_UNREGISTERED) | 201 if (reg_info_.state != RegistrationInfo::DEV_REG_UNREGISTERED) |
| 198 return PrivetHttpServer::REG_ERROR_INVALID_ACTION; | 202 return PrivetHttpServer::REG_ERROR_INVALID_ACTION; |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 PrivetHttpServer::RegistrationErrorStatus status = CheckCommonRegErrors(user); | 282 PrivetHttpServer::RegistrationErrorStatus status = CheckCommonRegErrors(user); |
| 279 if (status != PrivetHttpServer::REG_ERROR_OK && | 283 if (status != PrivetHttpServer::REG_ERROR_OK && |
| 280 status != PrivetHttpServer::REG_ERROR_SERVER_ERROR) { | 284 status != PrivetHttpServer::REG_ERROR_SERVER_ERROR) { |
| 281 return status; | 285 return status; |
| 282 } | 286 } |
| 283 | 287 |
| 284 if (reg_info_.state == RegistrationInfo::DEV_REG_UNREGISTERED) | 288 if (reg_info_.state == RegistrationInfo::DEV_REG_UNREGISTERED) |
| 285 return PrivetHttpServer::REG_ERROR_INVALID_ACTION; | 289 return PrivetHttpServer::REG_ERROR_INVALID_ACTION; |
| 286 | 290 |
| 287 reg_info_ = RegistrationInfo(); | 291 reg_info_ = RegistrationInfo(); |
| 288 requester_.reset(new CloudPrintRequester( | 292 requester_.reset(new CloudPrintRequester(GetTaskRunner(), this)); |
| 289 base::MessageLoop::current()->message_loop_proxy(), | |
| 290 this)); // Forget all old queries. | |
| 291 | 293 |
| 292 return PrivetHttpServer::REG_ERROR_OK; | 294 return PrivetHttpServer::REG_ERROR_OK; |
| 293 } | 295 } |
| 294 | 296 |
| 295 void Printer::GetRegistrationServerError(std::string* description) { | 297 void Printer::GetRegistrationServerError(std::string* description) { |
| 296 DCHECK_EQ(reg_info_.state, RegistrationInfo::DEV_REG_REGISTRATION_ERROR) << | 298 DCHECK_EQ(reg_info_.state, RegistrationInfo::DEV_REG_REGISTRATION_ERROR) << |
| 297 "Method shouldn't be called when not needed."; | 299 "Method shouldn't be called when not needed."; |
| 298 | 300 |
| 299 *description = reg_info_.error_description; | 301 *description = reg_info_.error_description; |
| 300 } | 302 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 335 void Printer::OnRegistrationStartResponseParsed( | 337 void Printer::OnRegistrationStartResponseParsed( |
| 336 const std::string& registration_token, | 338 const std::string& registration_token, |
| 337 const std::string& complete_invite_url, | 339 const std::string& complete_invite_url, |
| 338 const std::string& device_id) { | 340 const std::string& device_id) { |
| 339 reg_info_.state = RegistrationInfo::DEV_REG_REGISTRATION_CLAIM_TOKEN_READY; | 341 reg_info_.state = RegistrationInfo::DEV_REG_REGISTRATION_CLAIM_TOKEN_READY; |
| 340 reg_info_.device_id = device_id; | 342 reg_info_.device_id = device_id; |
| 341 reg_info_.registration_token = registration_token; | 343 reg_info_.registration_token = registration_token; |
| 342 reg_info_.complete_invite_url = complete_invite_url; | 344 reg_info_.complete_invite_url = complete_invite_url; |
| 343 } | 345 } |
| 344 | 346 |
| 345 void Printer::OnGetAuthCodeResponseParsed(const std::string& refresh_token) { | 347 void Printer::OnGetAuthCodeResponseParsed(const std::string& refresh_token, |
| 348 const std::string& access_token, |
| 349 int access_token_expires_in_seconds) { |
| 346 reg_info_.state = RegistrationInfo::DEV_REG_REGISTERED; | 350 reg_info_.state = RegistrationInfo::DEV_REG_REGISTERED; |
| 347 reg_info_.refresh_token = refresh_token; | 351 reg_info_.refresh_token = refresh_token; |
| 348 SaveToFile(base::FilePath(kPrinterStatePath)); | 352 RememberAccessToken(access_token, access_token_expires_in_seconds); |
| 349 FetchPrintJobs(); | 353 |
| 354 ConnectXmpp(); |
| 355 } |
| 356 |
| 357 void Printer::OnAccesstokenReceviced(const std::string& access_token, |
| 358 int expires_in_seconds) { |
| 359 VLOG(3) << "Function: " << __FUNCTION__; |
| 360 RememberAccessToken(access_token, expires_in_seconds); |
| 361 switch (connection_state_) { |
| 362 case ONLINE: |
| 363 PostOnIdle(); |
| 364 break; |
| 365 |
| 366 case CONNECTING: |
| 367 TryConnect(); |
| 368 break; |
| 369 |
| 370 default: |
| 371 NOTREACHED(); |
| 372 } |
| 373 } |
| 374 |
| 375 void Printer::OnXmppJidReceived(const std::string& xmpp_jid) { |
| 376 reg_info_.xmpp_jid = xmpp_jid; |
| 350 } | 377 } |
| 351 | 378 |
| 352 void Printer::OnRegistrationError(const std::string& description) { | 379 void Printer::OnRegistrationError(const std::string& description) { |
| 353 LOG(ERROR) << "server_error: " << description; | 380 LOG(ERROR) << "server_error: " << description; |
| 354 | 381 |
| 355 // TODO(maksymb): Implement waiting after error and timeout of registration. | 382 // TODO(maksymb): Implement waiting after error and timeout of registration. |
| 356 reg_info_.state = RegistrationInfo::DEV_REG_REGISTRATION_ERROR; | 383 reg_info_.state = RegistrationInfo::DEV_REG_REGISTRATION_ERROR; |
| 357 reg_info_.error_description = description; | 384 reg_info_.error_description = description; |
| 358 } | 385 } |
| 359 | 386 |
| 387 void Printer::OnNetworkError() { |
| 388 VLOG(3) << "Function: " << __FUNCTION__; |
| 389 ChangeState(OFFLINE); |
| 390 } |
| 391 |
| 360 void Printer::OnServerError(const std::string& description) { | 392 void Printer::OnServerError(const std::string& description) { |
| 361 VLOG(3) << "Function: " << __FUNCTION__; | 393 VLOG(3) << "Function: " << __FUNCTION__; |
| 362 LOG(ERROR) << "Server error: " << description; | 394 LOG(ERROR) << "Server error: " << description; |
| 363 | 395 |
| 364 PostDelayedWakeUp(base::TimeDelta::FromSeconds(kReconnectTimeout)); | |
| 365 } | |
| 366 | |
| 367 void Printer::OnNetworkError() { | |
| 368 VLOG(3) << "Function: " << __FUNCTION__; | |
| 369 ChangeState(OFFLINE); | 396 ChangeState(OFFLINE); |
| 370 PostDelayedWakeUp(base::TimeDelta::FromSeconds(kReconnectTimeout)); | |
| 371 } | 397 } |
| 372 | 398 |
| 373 void Printer::OnPrintJobsAvailable(const std::vector<Job>& jobs) { | 399 void Printer::OnPrintJobsAvailable(const std::vector<Job>& jobs) { |
| 374 VLOG(3) << "Function: " << __FUNCTION__; | 400 VLOG(3) << "Function: " << __FUNCTION__; |
| 375 ChangeState(ONLINE); | |
| 376 | 401 |
| 377 LOG(INFO) << "Available printjobs: " << jobs.size(); | 402 LOG(INFO) << "Available printjobs: " << jobs.size(); |
| 378 | 403 |
| 379 if (jobs.empty()) { | 404 if (jobs.empty()) { |
| 380 PostDelayedWakeUp(base::TimeDelta::FromSeconds(kPrintJobsTimeout)); | 405 pending_print_jobs_check_ = false; |
| 406 PostOnIdle(); |
| 381 return; | 407 return; |
| 382 } | 408 } |
| 383 | 409 |
| 384 // TODO(maksymb): After finishing XMPP add 'Printjobs available' flag. | 410 LOG(INFO) << "Downloading printjob."; |
| 385 LOG(INFO) << "Downloading first printjob."; | |
| 386 requester_->RequestPrintJob(jobs[0]); | 411 requester_->RequestPrintJob(jobs[0]); |
| 387 return; | 412 return; |
| 388 } | 413 } |
| 389 | 414 |
| 390 void Printer::OnPrintJobDownloaded(const Job& job) { | 415 void Printer::OnPrintJobDownloaded(const Job& job) { |
| 391 VLOG(3) << "Function: " << __FUNCTION__; | 416 VLOG(3) << "Function: " << __FUNCTION__; |
| 392 print_job_handler_->SavePrintJob( | 417 print_job_handler_->SavePrintJob( |
| 393 job.file, | 418 job.file, |
| 394 job.ticket, | 419 job.ticket, |
| 395 base::StringPrintf("%s.%s", job.create_time.c_str(), job.job_id.c_str()), | 420 base::StringPrintf("%s.%s", job.create_time.c_str(), job.job_id.c_str()), |
| 396 job.title); | 421 job.title); |
| 397 requester_->SendPrintJobDone(job.job_id); | 422 requester_->SendPrintJobDone(job.job_id); |
| 398 } | 423 } |
| 399 | 424 |
| 400 void Printer::OnPrintJobDone() { | 425 void Printer::OnPrintJobDone() { |
| 401 VLOG(3) << "Function: " << __FUNCTION__; | 426 VLOG(3) << "Function: " << __FUNCTION__; |
| 402 // TODO(maksymb): Replace PostTask with with XMPP notifications. | 427 PostOnIdle(); |
| 403 PostWakeUp(); | 428 } |
| 429 |
| 430 void Printer::OnXmppConnected() { |
| 431 pending_local_settings_check_ = true; |
| 432 pending_print_jobs_check_ = true; |
| 433 ChangeState(ONLINE); |
| 434 PostOnIdle(); |
| 435 } |
| 436 |
| 437 void Printer::OnXmppAuthError() { |
| 438 OnAuthError(); |
| 439 } |
| 440 |
| 441 void Printer::OnXmppNetworkError() { |
| 442 ChangeState(OFFLINE); |
| 443 } |
| 444 |
| 445 void Printer::OnXmppNewPrintJob(const std::string& device_id) { |
| 446 DCHECK_EQ(reg_info_.device_id, device_id) << "Data should contain printer_id"; |
| 447 pending_print_jobs_check_ = true; |
| 448 } |
| 449 |
| 450 void Printer::OnXmppNewLocalSettings(const std::string& device_id) { |
| 451 DCHECK_EQ(reg_info_.device_id, device_id) << "Data should contain printer_id"; |
| 452 NOTIMPLEMENTED(); |
| 453 } |
| 454 |
| 455 void Printer::OnXmppDeleteNotification(const std::string& device_id) { |
| 456 DCHECK_EQ(reg_info_.device_id, device_id) << "Data should contain printer_id"; |
| 457 NOTIMPLEMENTED(); |
| 458 } |
| 459 |
| 460 void Printer::TryConnect() { |
| 461 VLOG(3) << "Function: " << __FUNCTION__; |
| 462 |
| 463 ChangeState(CONNECTING); |
| 464 if (!requester_) |
| 465 requester_.reset(new CloudPrintRequester(GetTaskRunner(), this)); |
| 466 |
| 467 if (IsRegistered()) { |
| 468 if (access_token_update_ < base::Time::Now()) { |
| 469 requester_->UpdateAccesstoken(reg_info_.refresh_token); |
| 470 } else { |
| 471 ConnectXmpp(); |
| 472 } |
| 473 } else { |
| 474 // TODO(maksymb): Ping google.com to check connection state. |
| 475 ChangeState(ONLINE); |
| 476 } |
| 477 } |
| 478 |
| 479 void Printer::ConnectXmpp() { |
| 480 xmpp_listener_.reset( |
| 481 new CloudPrintXmppListener(reg_info_.xmpp_jid, GetTaskRunner(), this)); |
| 482 xmpp_listener_->Connect(access_token_); |
| 483 } |
| 484 |
| 485 void Printer::OnIdle() { |
| 486 DCHECK(IsRegistered()); |
| 487 DCHECK(on_idle_posted_) << "Instant call is not allowed"; |
| 488 on_idle_posted_ = false; |
| 489 |
| 490 if (connection_state_ != ONLINE) |
| 491 return; |
| 492 |
| 493 if (access_token_update_ < base::Time::Now()) { |
| 494 requester_->UpdateAccesstoken(reg_info_.refresh_token); |
| 495 return; |
| 496 } |
| 497 |
| 498 // TODO(maksymb): Check if privet-accesstoken was requested. |
| 499 |
| 500 // TODO(maksymb): Check if local-printing was requested. |
| 501 |
| 502 if (pending_local_settings_check_) { |
| 503 GetLocalSettings(); |
| 504 return; |
| 505 } |
| 506 |
| 507 if (pending_print_jobs_check_) { |
| 508 FetchPrintJobs(); |
| 509 return; |
| 510 } |
| 511 |
| 512 base::MessageLoop::current()->PostDelayedTask( |
| 513 FROM_HERE, |
| 514 base::Bind(&Printer::PostOnIdle, AsWeakPtr()), |
| 515 base::TimeDelta::FromMilliseconds(1000)); |
| 516 } |
| 517 |
| 518 void Printer::GetLocalSettings() { |
| 519 DCHECK(IsRegistered()); |
| 520 |
| 521 pending_local_settings_check_ = false; |
| 522 PostOnIdle(); |
| 523 } |
| 524 |
| 525 void Printer::FetchPrintJobs() { |
| 526 VLOG(3) << "Function: " << __FUNCTION__; |
| 527 |
| 528 DCHECK(IsRegistered()); |
| 529 requester_->FetchPrintJobs(reg_info_.device_id); |
| 530 } |
| 531 |
| 532 void Printer::RememberAccessToken(const std::string& access_token, |
| 533 int expires_in_seconds) { |
| 534 using base::Time; |
| 535 using base::TimeDelta; |
| 536 access_token_ = access_token; |
| 537 int64 time_to_update = static_cast<int64>(expires_in_seconds * |
| 538 kTimeToNextAccessTokenUpdate); |
| 539 access_token_update_ = Time::Now() + TimeDelta::FromSeconds(time_to_update); |
| 540 VLOG(1) << "Current access_token: " << access_token; |
| 541 SaveToFile(base::FilePath(kPrinterStatePath)); |
| 404 } | 542 } |
| 405 | 543 |
| 406 PrivetHttpServer::RegistrationErrorStatus Printer::CheckCommonRegErrors( | 544 PrivetHttpServer::RegistrationErrorStatus Printer::CheckCommonRegErrors( |
| 407 const std::string& user) const { | 545 const std::string& user) const { |
| 408 DCHECK(!IsRegistered()); | 546 DCHECK(!IsRegistered()); |
| 409 | 547 |
| 410 if (reg_info_.state != RegistrationInfo::DEV_REG_UNREGISTERED && | 548 if (reg_info_.state != RegistrationInfo::DEV_REG_UNREGISTERED && |
| 411 user != reg_info_.user) { | 549 user != reg_info_.user) { |
| 412 return PrivetHttpServer::REG_ERROR_DEVICE_BUSY; | 550 return PrivetHttpServer::REG_ERROR_DEVICE_BUSY; |
| 413 } | 551 } |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 453 txt.push_back("ty=" + std::string(kPrinterName)); | 591 txt.push_back("ty=" + std::string(kPrinterName)); |
| 454 txt.push_back("note=" + std::string(kPrinterDescription)); | 592 txt.push_back("note=" + std::string(kPrinterDescription)); |
| 455 txt.push_back("url=" + std::string(kCloudPrintUrl)); | 593 txt.push_back("url=" + std::string(kCloudPrintUrl)); |
| 456 txt.push_back("type=printer"); | 594 txt.push_back("type=printer"); |
| 457 txt.push_back("id=" + reg_info_.device_id); | 595 txt.push_back("id=" + reg_info_.device_id); |
| 458 txt.push_back("cs=" + ConnectionStateToString(connection_state_)); | 596 txt.push_back("cs=" + ConnectionStateToString(connection_state_)); |
| 459 | 597 |
| 460 return txt; | 598 return txt; |
| 461 } | 599 } |
| 462 | 600 |
| 463 void Printer::FetchPrintJobs() { | |
| 464 VLOG(3) << "Function: " << __FUNCTION__; | |
| 465 | |
| 466 if (!IsRegistered()) | |
| 467 return; | |
| 468 | |
| 469 if (requester_->IsBusy()) { | |
| 470 PostDelayedWakeUp(base::TimeDelta::FromSeconds(kReconnectTimeout)); | |
| 471 } else { | |
| 472 requester_->FetchPrintJobs(reg_info_.refresh_token, reg_info_.device_id); | |
| 473 } | |
| 474 } | |
| 475 | |
| 476 void Printer::SaveToFile(const base::FilePath& file_path) const { | 601 void Printer::SaveToFile(const base::FilePath& file_path) const { |
| 477 base::DictionaryValue json; | 602 base::DictionaryValue json; |
| 478 // TODO(maksymb): Get rid of in-place constants. | 603 // TODO(maksymb): Get rid of in-place constants. |
| 479 if (IsRegistered()) { | 604 if (IsRegistered()) { |
| 480 json.SetBoolean("registered", true); | 605 json.SetBoolean("registered", true); |
| 481 json.SetString("user", reg_info_.user); | 606 json.SetString("user", reg_info_.user); |
| 482 json.SetString("device_id", reg_info_.device_id); | 607 json.SetString("device_id", reg_info_.device_id); |
| 483 json.SetString("refresh_token", reg_info_.refresh_token); | 608 json.SetString("refresh_token", reg_info_.refresh_token); |
| 609 json.SetString("xmpp_jid", reg_info_.xmpp_jid); |
| 610 json.SetString("access_token", access_token_); |
| 611 json.SetInteger("access_token_update", |
| 612 static_cast<int>(access_token_update_.ToTimeT())); |
| 484 } else { | 613 } else { |
| 485 json.SetBoolean("registered", false); | 614 json.SetBoolean("registered", false); |
| 486 } | 615 } |
| 487 | 616 |
| 488 std::string json_str; | 617 std::string json_str; |
| 489 base::JSONWriter::WriteWithOptions(&json, | 618 base::JSONWriter::WriteWithOptions(&json, |
| 490 base::JSONWriter::OPTIONS_PRETTY_PRINT, | 619 base::JSONWriter::OPTIONS_PRETTY_PRINT, |
| 491 &json_str); | 620 &json_str); |
| 492 if (!file_util::WriteFile(file_path, json_str.data(), | 621 if (!file_util::WriteFile(file_path, json_str.data(), |
| 493 static_cast<int>(json_str.size()))) { | 622 static_cast<int>(json_str.size()))) { |
| 494 LOG(ERROR) << "Cannot write state."; | 623 LOG(ERROR) << "Cannot write state."; |
| 495 } | 624 } |
| 496 LOG(INFO) << "State written to file."; | 625 LOG(INFO) << "State written to file."; |
| 497 } | 626 } |
| 498 | 627 |
| 499 bool Printer::LoadFromFile(const base::FilePath& file_path) { | 628 bool Printer::LoadFromFile(const base::FilePath& file_path) { |
| 500 if (!base::PathExists(file_path)) { | 629 if (!base::PathExists(file_path)) |
| 501 LOG(INFO) << "Registration info is not found. Printer is unregistered."; | |
| 502 return false; | 630 return false; |
| 503 } | |
| 504 | 631 |
| 505 LOG(INFO) << "Loading registration info from file."; | 632 LOG(INFO) << "Loading registration info from file."; |
| 506 std::string json_str; | 633 std::string json_str; |
| 507 if (!file_util::ReadFileToString(file_path, &json_str)) { | 634 if (!file_util::ReadFileToString(file_path, &json_str)) { |
| 508 LOG(ERROR) << "Cannot open file."; | 635 LOG(ERROR) << "Cannot open file."; |
| 509 return false; | 636 return false; |
| 510 } | 637 } |
| 511 | 638 |
| 512 scoped_ptr<base::Value> json_val(base::JSONReader::Read(json_str)); | 639 scoped_ptr<base::Value> json_val(base::JSONReader::Read(json_str)); |
| 513 base::DictionaryValue* json = NULL; | 640 base::DictionaryValue* json = NULL; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 538 LOG(ERROR) << "Cannot parse |device_id|."; | 665 LOG(ERROR) << "Cannot parse |device_id|."; |
| 539 return false; | 666 return false; |
| 540 } | 667 } |
| 541 | 668 |
| 542 std::string refresh_token; | 669 std::string refresh_token; |
| 543 if (!json->GetString("refresh_token", &refresh_token)) { | 670 if (!json->GetString("refresh_token", &refresh_token)) { |
| 544 LOG(ERROR) << "Cannot parse |refresh_token|."; | 671 LOG(ERROR) << "Cannot parse |refresh_token|."; |
| 545 return false; | 672 return false; |
| 546 } | 673 } |
| 547 | 674 |
| 675 std::string xmpp_jid; |
| 676 if (!json->GetString("xmpp_jid", &xmpp_jid)) { |
| 677 LOG(ERROR) << "Cannot parse |xmpp_jid|."; |
| 678 return false; |
| 679 } |
| 680 |
| 681 std::string access_token; |
| 682 if (!json->GetString("access_token", &access_token)) { |
| 683 LOG(ERROR) << "Cannot parse |access_token|."; |
| 684 return false; |
| 685 } |
| 686 |
| 687 int access_token_update; |
| 688 if (!json->GetInteger("access_token_update", &access_token_update)) { |
| 689 LOG(ERROR) << "Cannot parse |access_token_update|."; |
| 690 return false; |
| 691 } |
| 692 |
| 548 reg_info_ = RegistrationInfo(); | 693 reg_info_ = RegistrationInfo(); |
| 549 reg_info_.state = RegistrationInfo::DEV_REG_REGISTERED; | 694 reg_info_.state = RegistrationInfo::DEV_REG_REGISTERED; |
| 550 reg_info_.user = user; | 695 reg_info_.user = user; |
| 551 reg_info_.device_id = device_id; | 696 reg_info_.device_id = device_id; |
| 552 reg_info_.refresh_token = refresh_token; | 697 reg_info_.refresh_token = refresh_token; |
| 698 reg_info_.xmpp_jid = xmpp_jid; |
| 699 using base::Time; |
| 700 access_token_ = access_token; |
| 701 access_token_update_ = Time::FromTimeT(access_token_update); |
| 553 | 702 |
| 554 return true; | 703 return true; |
| 555 } | 704 } |
| 556 | 705 |
| 557 void Printer::PostWakeUp() { | 706 void Printer::PostOnIdle() { |
| 558 VLOG(3) << "Function: " << __FUNCTION__; | 707 VLOG(3) << "Function: " << __FUNCTION__; |
| 708 DCHECK(!on_idle_posted_) << "Only one instance can be posted."; |
| 709 on_idle_posted_ = true; |
| 710 |
| 559 base::MessageLoop::current()->PostTask( | 711 base::MessageLoop::current()->PostTask( |
| 560 FROM_HERE, | 712 FROM_HERE, |
| 561 base::Bind(&Printer::WakeUp, AsWeakPtr())); | 713 base::Bind(&Printer::OnIdle, AsWeakPtr())); |
| 562 } | |
| 563 | |
| 564 void Printer::PostDelayedWakeUp(const base::TimeDelta& delay) { | |
| 565 VLOG(3) << "Function: " << __FUNCTION__; | |
| 566 base::MessageLoop::current()->PostDelayedTask( | |
| 567 FROM_HERE, | |
| 568 base::Bind(&Printer::WakeUp, AsWeakPtr()), | |
| 569 delay); | |
| 570 } | 714 } |
| 571 | 715 |
| 572 PrivetHttpServer::RegistrationErrorStatus | 716 PrivetHttpServer::RegistrationErrorStatus |
| 573 Printer::ConfirmationToRegistrationError( | 717 Printer::ConfirmationToRegistrationError( |
| 574 RegistrationInfo::ConfirmationState state) { | 718 RegistrationInfo::ConfirmationState state) { |
| 575 switch (state) { | 719 switch (state) { |
| 576 case RegistrationInfo::CONFIRMATION_PENDING: | 720 case RegistrationInfo::CONFIRMATION_PENDING: |
| 577 return PrivetHttpServer::REG_ERROR_PENDING_USER_ACTION; | 721 return PrivetHttpServer::REG_ERROR_PENDING_USER_ACTION; |
| 578 case RegistrationInfo::CONFIRMATION_DISCARDED: | 722 case RegistrationInfo::CONFIRMATION_DISCARDED: |
| 579 return PrivetHttpServer::REG_ERROR_USER_CANCEL; | 723 return PrivetHttpServer::REG_ERROR_USER_CANCEL; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 602 default: | 746 default: |
| 603 NOTREACHED(); | 747 NOTREACHED(); |
| 604 return ""; | 748 return ""; |
| 605 } | 749 } |
| 606 } | 750 } |
| 607 | 751 |
| 608 bool Printer::ChangeState(ConnectionState new_state) { | 752 bool Printer::ChangeState(ConnectionState new_state) { |
| 609 if (connection_state_ == new_state) | 753 if (connection_state_ == new_state) |
| 610 return false; | 754 return false; |
| 611 | 755 |
| 612 VLOG(1) << "Printer is now " << ConnectionStateToString(new_state); | |
| 613 connection_state_ = new_state; | 756 connection_state_ = new_state; |
| 757 LOG(INFO) << base::StringPrintf( |
| 758 "Printer is now %s (%s)", |
| 759 ConnectionStateToString(connection_state_).c_str(), |
| 760 IsRegistered() ? "registered" : "unregistered"); |
| 761 |
| 614 dns_server_.UpdateMetadata(CreateTxt()); | 762 dns_server_.UpdateMetadata(CreateTxt()); |
| 763 |
| 764 switch (connection_state_) { |
| 765 case CONNECTING: |
| 766 break; |
| 767 |
| 768 case ONLINE: |
| 769 break; |
| 770 |
| 771 case OFFLINE: |
| 772 requester_.reset(); |
| 773 xmpp_listener_.reset(); |
| 774 base::MessageLoop::current()->PostDelayedTask( |
| 775 FROM_HERE, |
| 776 base::Bind(&Printer::TryConnect, AsWeakPtr()), |
| 777 base::TimeDelta::FromSeconds(kReconnectTimeout)); |
| 778 |
| 779 case NOT_CONFIGURED: |
| 780 break; |
| 781 |
| 782 default: |
| 783 NOTREACHED(); |
| 784 } |
| 785 |
| 615 return true; | 786 return true; |
| 616 } | 787 } |
| 617 | 788 |
| OLD | NEW |