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