| Index: cloud_print/gcp20/prototype/printer.cc
|
| diff --git a/cloud_print/gcp20/prototype/printer.cc b/cloud_print/gcp20/prototype/printer.cc
|
| index 756ad7ca6613e26f8a956ce0eb3f058bb1bddd37..5edbe97fe316944210eb8fe8cd9153b120494d7b 100644
|
| --- a/cloud_print/gcp20/prototype/printer.cc
|
| +++ b/cloud_print/gcp20/prototype/printer.cc
|
| @@ -8,12 +8,14 @@
|
| #include <string>
|
| #include <vector>
|
|
|
| +#include "base/bind.h"
|
| #include "base/command_line.h"
|
| #include "base/file_util.h"
|
| #include "base/guid.h"
|
| #include "base/json/json_reader.h"
|
| #include "base/json/json_writer.h"
|
| #include "base/strings/string_number_conversions.h"
|
| +#include "base/strings/stringprintf.h"
|
| #include "cloud_print/gcp20/prototype/command_line_reader.h"
|
| #include "cloud_print/gcp20/prototype/service_parameters.h"
|
| #include "cloud_print/gcp20/prototype/special_io.h"
|
| @@ -36,6 +38,9 @@ const char kUserConfirmationTitle[] = "Confirm registration: type 'y' if you "
|
| "agree and any other to discard\n";
|
| const uint kUserConfirmationTimeout = 30; // in seconds
|
|
|
| +const uint32 kReconnectTimeout = 5; // in seconds
|
| +const uint32 kPrintJobsTimeout = 10; // in seconds
|
| +
|
| const char kCdd[] =
|
| "{\n"
|
| " 'version': '1.0',\n"
|
| @@ -92,6 +97,8 @@ net::IPAddressNumber GetLocalIp(const std::string& interface_name,
|
|
|
| } // namespace
|
|
|
| +using cloud_print_response_parser::Job;
|
| +
|
| Printer::RegistrationInfo::RegistrationInfo()
|
| : state(DEV_REG_UNREGISTERED),
|
| confirmation_state(CONFIRMATION_PENDING) {
|
| @@ -100,7 +107,7 @@ Printer::RegistrationInfo::RegistrationInfo()
|
| Printer::RegistrationInfo::~RegistrationInfo() {
|
| }
|
|
|
| -Printer::Printer() : http_server_(this) {
|
| +Printer::Printer() : http_server_(this), connection_state_(OFFLINE) {
|
| }
|
|
|
| Printer::~Printer() {
|
| @@ -147,6 +154,11 @@ bool Printer::Start() {
|
| xtoken_ = XPrivetToken();
|
| starttime_ = base::Time::Now();
|
|
|
| + print_job_handler_.reset(new PrintJobHandler);
|
| + connection_state_ = CONNECTING;
|
| + if (IsRegistered())
|
| + WakeUp();
|
| +
|
| return true;
|
| }
|
|
|
| @@ -154,10 +166,20 @@ bool Printer::IsOnline() const {
|
| return requester_;
|
| }
|
|
|
| +void Printer::WakeUp() {
|
| + LOG_IF(INFO, kFunctionVebose) << "Function: " << __FUNCTION__;
|
| +
|
| + if (!IsRegistered())
|
| + return;
|
| +
|
| + FetchPrintJobs();
|
| +}
|
| +
|
| void Printer::Stop() {
|
| dns_server_.Shutdown();
|
| http_server_.Shutdown();
|
| requester_.reset();
|
| + print_job_handler_.reset();
|
| }
|
|
|
| PrivetHttpServer::RegistrationErrorStatus Printer::RegistrationStart(
|
| @@ -185,14 +207,6 @@ PrivetHttpServer::RegistrationErrorStatus Printer::RegistrationStart(
|
| return PrivetHttpServer::REG_ERROR_OK;
|
| }
|
|
|
| -bool Printer::CheckXPrivetTokenHeader(const std::string& token) const {
|
| - return xtoken_.CheckValidXToken(token);
|
| -}
|
| -
|
| -bool Printer::IsRegistered() const {
|
| - return reg_info_.state == RegistrationInfo::DEV_REG_REGISTERED;
|
| -}
|
| -
|
| PrivetHttpServer::RegistrationErrorStatus Printer::RegistrationGetClaimToken(
|
| const std::string& user,
|
| std::string* token,
|
| @@ -284,7 +298,7 @@ void Printer::CreateInfo(PrivetHttpServer::DeviceInfo* info) {
|
| info->url = kCloudPrintUrl;
|
| info->id = reg_info_.device_id;
|
| info->device_state = "idle";
|
| - info->connection_state = "offline";
|
| + info->connection_state = ConnectionStateToString(connection_state_);
|
| info->manufacturer = "Google";
|
| info->model = "Prototype";
|
| info->serial_number = "2.3.5.7.13.17.19.31.61.89.107.127.521.607.1279.2203";
|
| @@ -299,6 +313,14 @@ void Printer::CreateInfo(PrivetHttpServer::DeviceInfo* info) {
|
| info->type.push_back("printer");
|
| }
|
|
|
| +bool Printer::IsRegistered() const {
|
| + return reg_info_.state == RegistrationInfo::DEV_REG_REGISTERED;
|
| +}
|
| +
|
| +bool Printer::CheckXPrivetTokenHeader(const std::string& token) const {
|
| + return xtoken_.CheckValidXToken(token);
|
| +}
|
| +
|
| void Printer::OnRegistrationStartResponseParsed(
|
| const std::string& registration_token,
|
| const std::string& complete_invite_url,
|
| @@ -313,6 +335,7 @@ void Printer::OnGetAuthCodeResponseParsed(const std::string& refresh_token) {
|
| reg_info_.state = RegistrationInfo::DEV_REG_REGISTERED;
|
| reg_info_.refresh_token = refresh_token;
|
| SaveToFile(kPrinterStatePath);
|
| + FetchPrintJobs();
|
| }
|
|
|
| void Printer::OnRegistrationError(const std::string& description) {
|
| @@ -323,6 +346,52 @@ void Printer::OnRegistrationError(const std::string& description) {
|
| reg_info_.error_description = description;
|
| }
|
|
|
| +void Printer::OnServerError(const std::string& description) {
|
| + LOG_IF(INFO, kFunctionVebose) << "Function: " << __FUNCTION__;
|
| + LOG(ERROR) << "Server error: " << description;
|
| +
|
| + PostDelayedWakeUp(base::TimeDelta::FromSeconds(kReconnectTimeout));
|
| +}
|
| +
|
| +void Printer::OnNetworkError() {
|
| + LOG_IF(INFO, kFunctionVebose) << "Function: " << __FUNCTION__;
|
| + ChangeState(OFFLINE);
|
| + PostDelayedWakeUp(base::TimeDelta::FromSeconds(kReconnectTimeout));
|
| +}
|
| +
|
| +void Printer::OnPrintJobsAvailable(const std::vector<Job>& jobs) {
|
| + LOG_IF(INFO, kFunctionVebose) << "Function: " << __FUNCTION__;
|
| + ChangeState(ONLINE);
|
| +
|
| + LOG(INFO) << "Available printjobs: " << jobs.size();
|
| +
|
| + if (jobs.empty()) {
|
| + PostDelayedWakeUp(base::TimeDelta::FromSeconds(kPrintJobsTimeout));
|
| + return;
|
| + }
|
| +
|
| + // TODO(maksymb): After finishing XMPP add 'Printjobs available' flag.
|
| + LOG(INFO) << "Downloading first printjob.";
|
| + requester_->RequestPrintJob(jobs[0]);
|
| + return;
|
| +}
|
| +
|
| +void Printer::OnPrintJobDownloaded(const Job& job) {
|
| + LOG_IF(INFO, kFunctionVebose) << "Function: " << __FUNCTION__;
|
| + print_job_handler_->SavePrintJob(
|
| + job.file,
|
| + job.ticket,
|
| + base::StringPrintf("%s.%s", job.create_time.c_str(), job.job_id.c_str()),
|
| + job.title);
|
| + requester_->SendPrintJobDone(job.job_id);
|
| +}
|
| +
|
| +void Printer::OnPrintJobDone() {
|
| + LOG_IF(INFO, kFunctionVebose) << "Function: " << __FUNCTION__;
|
| + // TODO(maksymb): Replace PostTask with with XMPP notifications.
|
| + PostWakeUp();
|
| +}
|
| +
|
| PrivetHttpServer::RegistrationErrorStatus Printer::CheckCommonRegErrors(
|
| const std::string& user) const {
|
| DCHECK(!IsRegistered());
|
| @@ -375,11 +444,24 @@ std::vector<std::string> Printer::CreateTxt() const {
|
| txt.push_back("url=" + std::string(kCloudPrintUrl));
|
| txt.push_back("type=printer");
|
| txt.push_back("id=" + reg_info_.device_id);
|
| - txt.push_back("cs=offline");
|
| + txt.push_back("cs=" + ConnectionStateToString(connection_state_));
|
|
|
| return txt;
|
| }
|
|
|
| +void Printer::FetchPrintJobs() {
|
| + LOG_IF(INFO, kFunctionVebose) << "Function: " << __FUNCTION__;
|
| +
|
| + if (!IsRegistered())
|
| + return;
|
| +
|
| + if (requester_->IsBusy()) {
|
| + PostDelayedWakeUp(base::TimeDelta::FromSeconds(kReconnectTimeout));
|
| + } else {
|
| + requester_->FetchPrintJobs(reg_info_.refresh_token, reg_info_.device_id);
|
| + }
|
| +}
|
| +
|
| void Printer::SaveToFile(const std::string& filename) const {
|
| base::DictionaryValue json;
|
| // TODO(maksymb): Get rid of in-place constants.
|
| @@ -461,6 +543,21 @@ bool Printer::LoadFromFile(const std::string& filename) {
|
| return true;
|
| }
|
|
|
| +void Printer::PostWakeUp() {
|
| + LOG_IF(INFO, kFunctionVebose) << "Function: " << __FUNCTION__;
|
| + base::MessageLoop::current()->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&Printer::WakeUp, AsWeakPtr()));
|
| +}
|
| +
|
| +void Printer::PostDelayedWakeUp(const base::TimeDelta& delay) {
|
| + LOG_IF(INFO, kFunctionVebose) << "Function: " << __FUNCTION__;
|
| + base::MessageLoop::current()->PostDelayedTask(
|
| + FROM_HERE,
|
| + base::Bind(&Printer::WakeUp, AsWeakPtr()),
|
| + delay);
|
| +}
|
| +
|
| PrivetHttpServer::RegistrationErrorStatus
|
| Printer::ConfirmationToRegistrationError(
|
| RegistrationInfo::ConfirmationState state) {
|
| @@ -480,3 +577,27 @@ PrivetHttpServer::RegistrationErrorStatus
|
| }
|
| }
|
|
|
| +std::string Printer::ConnectionStateToString(ConnectionState state) const {
|
| + if (state == OFFLINE)
|
| + return "offline";
|
| + if (state == ONLINE)
|
| + return "online";
|
| + if (state == CONNECTING)
|
| + return "connecting";
|
| + if (state == NOT_CONFIGURED)
|
| + return "not-configured";
|
| +
|
| + NOTREACHED();
|
| + return "";
|
| +}
|
| +
|
| +bool Printer::ChangeState(ConnectionState new_state) {
|
| + if (connection_state_ == new_state)
|
| + return false;
|
| +
|
| + VLOG(1) << "Printer is now " << ConnectionStateToString(new_state);
|
| + connection_state_ = new_state;
|
| + dns_server_.UpdateMetadata(CreateTxt());
|
| + return true;
|
| +}
|
| +
|
|
|