Index: cloud_print/gcp20/prototype/printer.cc |
diff --git a/cloud_print/gcp20/prototype/printer.cc b/cloud_print/gcp20/prototype/printer.cc |
index 8b94d92996fba977ad2796816704510ad95e1271..b7da5e7bd712df1ff707321216f7dc0f89fc0785 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" |
@@ -22,6 +24,8 @@ |
const char kPrinterStatePath[] = "printer_state.json"; |
+typedef std::vector<Printjob> PrintjobList; |
+ |
namespace { |
const char kServiceType[] = "_privet._tcp.local"; |
@@ -35,6 +39,9 @@ const char kUserConfirmationTitle[] = "Confirm registration: type 'y' if you " |
"agree and any other to discard"; |
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" |
@@ -99,7 +106,7 @@ Printer::RegistrationInfo::RegistrationInfo() |
Printer::RegistrationInfo::~RegistrationInfo() { |
} |
-Printer::Printer() : http_server_(this) { |
+Printer::Printer() : http_server_(this), connection_state_(OFFLINE) { |
} |
Printer::~Printer() { |
@@ -146,6 +153,11 @@ bool Printer::Start() { |
xtoken_ = XPrivetToken(); |
starttime_ = base::Time::Now(); |
+ printjob_handler_.reset(new PrintjobHandler); |
+ connection_state_ = CONNECTING; |
+ if (IsRegistered()) |
+ WakeUp(); |
+ |
return true; |
} |
@@ -153,10 +165,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(); |
+ printjob_handler_.reset(); |
} |
PrivetHttpServer::RegistrationErrorStatus Printer::RegistrationStart( |
@@ -177,22 +199,14 @@ PrivetHttpServer::RegistrationErrorStatus Printer::RegistrationStart( |
base::TimeDelta::FromSeconds(kUserConfirmationTimeout); |
base::MessageLoop::current()->PostTask( |
FROM_HERE, |
- base::Bind(&Printer::WaitUserConfirmation, |
- base::Unretained(this), valid_until)); |
+ base::Bind(&Printer::WaitUserConfirmation, this->AsWeakPtr(), |
Vitaly Buka (NO REVIEWS)
2013/07/22 03:57:31
remote this->
maksymb
2013/07/22 22:56:53
Done.
|
+ valid_until)); |
requester_->StartRegistration(GenerateProxyId(), kPrinterName, user, kCdd); |
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, |
@@ -275,7 +289,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"; |
@@ -290,6 +304,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, |
@@ -304,6 +326,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) { |
@@ -314,6 +337,53 @@ 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<Printjob>& printjobs) { |
+ LOG_IF(INFO, kFunctionVebose) << "Function: " << __FUNCTION__; |
+ ChangeState(ONLINE); |
+ |
+ LOG(INFO) << "Available printjobs: " << printjobs.size(); |
+ |
+ if (printjobs.empty()) { |
+ PostDelayedWakeUp(base::TimeDelta::FromSeconds(kPrintjobsTimeout)); |
+ return; |
+ } |
+ |
+ // TODO(maksymb): After finishing XMPP add 'Printjobs available' flag. |
+ LOG(INFO) << "Downloading first printjob."; |
+ requester_->RequestPrintjob(printjobs[0]); |
+ return; |
+} |
+ |
+void Printer::OnPrintjobDownloaded(const Printjob& printjob) { |
+ LOG_IF(INFO, kFunctionVebose) << "Function: " << __FUNCTION__; |
+ printjob_handler_->SavePrintjob( |
+ printjob.file, |
+ printjob.ticket, |
+ base::StringPrintf("%s.%s", |
+ printjob.create_time.c_str(), printjob.jobid.c_str()), |
+ printjob.title); |
+ requester_->SendPrintjobDone(printjob.jobid); |
+} |
+ |
+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()); |
@@ -350,7 +420,7 @@ void Printer::WaitUserConfirmation(base::Time valid_until) { |
base::MessageLoop::current()->PostDelayedTask( |
FROM_HERE, |
- base::Bind(&Printer::WaitUserConfirmation, base::Unretained(this), |
+ base::Bind(&Printer::WaitUserConfirmation, this->AsWeakPtr(), |
valid_until), |
base::TimeDelta::FromMilliseconds(100)); |
} |
@@ -367,11 +437,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. |
@@ -453,6 +536,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, this->AsWeakPtr())); |
+} |
+ |
+void Printer::PostDelayedWakeUp(const base::TimeDelta& delay) { |
+ LOG_IF(INFO, kFunctionVebose) << "Function: " << __FUNCTION__; |
+ base::MessageLoop::current()->PostDelayedTask( |
+ FROM_HERE, |
+ base::Bind(&Printer::WakeUp, this->AsWeakPtr()), |
+ delay); |
+} |
+ |
PrivetHttpServer::RegistrationErrorStatus |
Printer::ConfirmationToRegistrationError( |
RegistrationInfo::ConfirmationState state) { |
@@ -472,3 +570,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; |
+} |
+ |