Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Unified Diff: cloud_print/gcp20/prototype/printer.cc

Issue 20238002: GCP2.0 Device: XMPP (without pings). (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@DEPS-jingle
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « cloud_print/gcp20/prototype/printer.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cloud_print/gcp20/prototype/printer.cc
diff --git a/cloud_print/gcp20/prototype/printer.cc b/cloud_print/gcp20/prototype/printer.cc
index 2a0086b3b9f31405fefc8dc547d55d2c656f85ff..b6ff2c4182f0753c45cae9e038fd5e91f77b6e4f 100644
--- a/cloud_print/gcp20/prototype/printer.cc
+++ b/cloud_print/gcp20/prototype/printer.cc
@@ -42,7 +42,8 @@ const char kUserConfirmationTitle[] = "Confirm registration: type 'y' if you "
const int64 kUserConfirmationTimeout = 30; // in seconds
const uint32 kReconnectTimeout = 5; // in seconds
-const uint32 kPrintJobsTimeout = 10; // in seconds
+
+const double kTimeToNextAccessTokenUpdate = 0.8; // relatively to living time.
const char kCdd[] =
"{\n"
@@ -98,6 +99,10 @@ net::IPAddressNumber GetLocalIp(const std::string& interface_name,
return net::IPAddressNumber();
}
+scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner() {
+ return base::MessageLoop::current()->message_loop_proxy();
+}
+
} // namespace
using cloud_print_response_parser::Job;
@@ -110,7 +115,12 @@ Printer::RegistrationInfo::RegistrationInfo()
Printer::RegistrationInfo::~RegistrationInfo() {
}
-Printer::Printer() : http_server_(this), connection_state_(OFFLINE) {
+Printer::Printer()
+ : http_server_(this),
+ connection_state_(OFFLINE),
+ on_idle_posted_(false),
+ pending_local_settings_check_(false),
+ pending_print_jobs_check_(false) {
}
Printer::~Printer() {
@@ -118,7 +128,7 @@ Printer::~Printer() {
}
bool Printer::Start() {
- if (IsOnline())
+ if (IsRunning())
return true;
// TODO(maksymb): Add switch for command line to control interface name.
@@ -152,33 +162,16 @@ bool Printer::Start() {
return false;
}
- // Creating Cloud Requester.
- requester_.reset(
- new CloudPrintRequester(
- base::MessageLoop::current()->message_loop_proxy(),
- this));
-
+ print_job_handler_.reset(new PrintJobHandler);
xtoken_ = XPrivetToken();
starttime_ = base::Time::Now();
- print_job_handler_.reset(new PrintJobHandler);
- connection_state_ = CONNECTING;
- WakeUp();
-
+ TryConnect();
return true;
}
-bool Printer::IsOnline() const {
- return requester_;
-}
-
-void Printer::WakeUp() {
- VLOG(3) << "Function: " << __FUNCTION__;
-
- if (!IsRegistered())
- return;
-
- FetchPrintJobs();
+bool Printer::IsRunning() const {
+ return print_job_handler_;
}
void Printer::Stop() {
@@ -186,6 +179,17 @@ void Printer::Stop() {
http_server_.Shutdown();
requester_.reset();
print_job_handler_.reset();
+ xmpp_listener_.reset();
+}
+
+void Printer::OnAuthError() {
+ access_token_update_ = base::Time::Now();
+ ChangeState(OFFLINE);
+ // TODO(maksymb): Implement *instant* updating of access_token.
+}
+
+std::string Printer::GetAccessToken() {
+ return access_token_;
}
PrivetHttpServer::RegistrationErrorStatus Printer::RegistrationStart(
@@ -285,9 +289,7 @@ PrivetHttpServer::RegistrationErrorStatus Printer::RegistrationCancel(
return PrivetHttpServer::REG_ERROR_INVALID_ACTION;
reg_info_ = RegistrationInfo();
- requester_.reset(new CloudPrintRequester(
- base::MessageLoop::current()->message_loop_proxy(),
- this)); // Forget all old queries.
+ requester_.reset(new CloudPrintRequester(GetTaskRunner(), this));
return PrivetHttpServer::REG_ERROR_OK;
}
@@ -342,11 +344,36 @@ void Printer::OnRegistrationStartResponseParsed(
reg_info_.complete_invite_url = complete_invite_url;
}
-void Printer::OnGetAuthCodeResponseParsed(const std::string& refresh_token) {
+void Printer::OnGetAuthCodeResponseParsed(const std::string& refresh_token,
+ const std::string& access_token,
+ int access_token_expires_in_seconds) {
reg_info_.state = RegistrationInfo::DEV_REG_REGISTERED;
reg_info_.refresh_token = refresh_token;
- SaveToFile(base::FilePath(kPrinterStatePath));
- FetchPrintJobs();
+ RememberAccessToken(access_token, access_token_expires_in_seconds);
+
+ ConnectXmpp();
+}
+
+void Printer::OnAccesstokenReceviced(const std::string& access_token,
+ int expires_in_seconds) {
+ VLOG(3) << "Function: " << __FUNCTION__;
+ RememberAccessToken(access_token, expires_in_seconds);
+ switch (connection_state_) {
+ case ONLINE:
+ PostOnIdle();
+ break;
+
+ case CONNECTING:
+ TryConnect();
+ break;
+
+ default:
+ NOTREACHED();
+ }
+}
+
+void Printer::OnXmppJidReceived(const std::string& xmpp_jid) {
+ reg_info_.xmpp_jid = xmpp_jid;
}
void Printer::OnRegistrationError(const std::string& description) {
@@ -357,32 +384,30 @@ void Printer::OnRegistrationError(const std::string& description) {
reg_info_.error_description = description;
}
-void Printer::OnServerError(const std::string& description) {
+void Printer::OnNetworkError() {
VLOG(3) << "Function: " << __FUNCTION__;
- LOG(ERROR) << "Server error: " << description;
-
- PostDelayedWakeUp(base::TimeDelta::FromSeconds(kReconnectTimeout));
+ ChangeState(OFFLINE);
}
-void Printer::OnNetworkError() {
+void Printer::OnServerError(const std::string& description) {
VLOG(3) << "Function: " << __FUNCTION__;
+ LOG(ERROR) << "Server error: " << description;
+
ChangeState(OFFLINE);
- PostDelayedWakeUp(base::TimeDelta::FromSeconds(kReconnectTimeout));
}
void Printer::OnPrintJobsAvailable(const std::vector<Job>& jobs) {
VLOG(3) << "Function: " << __FUNCTION__;
- ChangeState(ONLINE);
LOG(INFO) << "Available printjobs: " << jobs.size();
if (jobs.empty()) {
- PostDelayedWakeUp(base::TimeDelta::FromSeconds(kPrintJobsTimeout));
+ pending_print_jobs_check_ = false;
+ PostOnIdle();
return;
}
- // TODO(maksymb): After finishing XMPP add 'Printjobs available' flag.
- LOG(INFO) << "Downloading first printjob.";
+ LOG(INFO) << "Downloading printjob.";
requester_->RequestPrintJob(jobs[0]);
return;
}
@@ -399,8 +424,121 @@ void Printer::OnPrintJobDownloaded(const Job& job) {
void Printer::OnPrintJobDone() {
VLOG(3) << "Function: " << __FUNCTION__;
- // TODO(maksymb): Replace PostTask with with XMPP notifications.
- PostWakeUp();
+ PostOnIdle();
+}
+
+void Printer::OnXmppConnected() {
+ pending_local_settings_check_ = true;
+ pending_print_jobs_check_ = true;
+ ChangeState(ONLINE);
+ PostOnIdle();
+}
+
+void Printer::OnXmppAuthError() {
+ OnAuthError();
+}
+
+void Printer::OnXmppNetworkError() {
+ ChangeState(OFFLINE);
+}
+
+void Printer::OnXmppNewPrintJob(const std::string& device_id) {
+ DCHECK_EQ(reg_info_.device_id, device_id) << "Data should contain printer_id";
+ pending_print_jobs_check_ = true;
+}
+
+void Printer::OnXmppNewLocalSettings(const std::string& device_id) {
+ DCHECK_EQ(reg_info_.device_id, device_id) << "Data should contain printer_id";
+ NOTIMPLEMENTED();
+}
+
+void Printer::OnXmppDeleteNotification(const std::string& device_id) {
+ DCHECK_EQ(reg_info_.device_id, device_id) << "Data should contain printer_id";
+ NOTIMPLEMENTED();
+}
+
+void Printer::TryConnect() {
+ VLOG(3) << "Function: " << __FUNCTION__;
+
+ ChangeState(CONNECTING);
+ if (!requester_)
+ requester_.reset(new CloudPrintRequester(GetTaskRunner(), this));
+
+ if (IsRegistered()) {
+ if (access_token_update_ < base::Time::Now()) {
+ requester_->UpdateAccesstoken(reg_info_.refresh_token);
+ } else {
+ ConnectXmpp();
+ }
+ } else {
+ // TODO(maksymb): Ping google.com to check connection state.
+ ChangeState(ONLINE);
+ }
+}
+
+void Printer::ConnectXmpp() {
+ xmpp_listener_.reset(
+ new CloudPrintXmppListener(reg_info_.xmpp_jid, GetTaskRunner(), this));
+ xmpp_listener_->Connect(access_token_);
+}
+
+void Printer::OnIdle() {
+ DCHECK(IsRegistered());
+ DCHECK(on_idle_posted_) << "Instant call is not allowed";
+ on_idle_posted_ = false;
+
+ if (connection_state_ != ONLINE)
+ return;
+
+ if (access_token_update_ < base::Time::Now()) {
+ requester_->UpdateAccesstoken(reg_info_.refresh_token);
+ return;
+ }
+
+ // TODO(maksymb): Check if privet-accesstoken was requested.
+
+ // TODO(maksymb): Check if local-printing was requested.
+
+ if (pending_local_settings_check_) {
+ GetLocalSettings();
+ return;
+ }
+
+ if (pending_print_jobs_check_) {
+ FetchPrintJobs();
+ return;
+ }
+
+ base::MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ base::Bind(&Printer::PostOnIdle, AsWeakPtr()),
+ base::TimeDelta::FromMilliseconds(1000));
+}
+
+void Printer::GetLocalSettings() {
+ DCHECK(IsRegistered());
+
+ pending_local_settings_check_ = false;
+ PostOnIdle();
+}
+
+void Printer::FetchPrintJobs() {
+ VLOG(3) << "Function: " << __FUNCTION__;
+
+ DCHECK(IsRegistered());
+ requester_->FetchPrintJobs(reg_info_.device_id);
+}
+
+void Printer::RememberAccessToken(const std::string& access_token,
+ int expires_in_seconds) {
+ using base::Time;
+ using base::TimeDelta;
+ access_token_ = access_token;
+ int64 time_to_update = static_cast<int64>(expires_in_seconds *
+ kTimeToNextAccessTokenUpdate);
+ access_token_update_ = Time::Now() + TimeDelta::FromSeconds(time_to_update);
+ VLOG(1) << "Current access_token: " << access_token;
+ SaveToFile(base::FilePath(kPrinterStatePath));
}
PrivetHttpServer::RegistrationErrorStatus Printer::CheckCommonRegErrors(
@@ -460,19 +598,6 @@ std::vector<std::string> Printer::CreateTxt() const {
return txt;
}
-void Printer::FetchPrintJobs() {
- VLOG(3) << "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 base::FilePath& file_path) const {
base::DictionaryValue json;
// TODO(maksymb): Get rid of in-place constants.
@@ -481,6 +606,10 @@ void Printer::SaveToFile(const base::FilePath& file_path) const {
json.SetString("user", reg_info_.user);
json.SetString("device_id", reg_info_.device_id);
json.SetString("refresh_token", reg_info_.refresh_token);
+ json.SetString("xmpp_jid", reg_info_.xmpp_jid);
+ json.SetString("access_token", access_token_);
+ json.SetInteger("access_token_update",
+ static_cast<int>(access_token_update_.ToTimeT()));
} else {
json.SetBoolean("registered", false);
}
@@ -497,10 +626,8 @@ void Printer::SaveToFile(const base::FilePath& file_path) const {
}
bool Printer::LoadFromFile(const base::FilePath& file_path) {
- if (!base::PathExists(file_path)) {
- LOG(INFO) << "Registration info is not found. Printer is unregistered.";
+ if (!base::PathExists(file_path))
return false;
- }
LOG(INFO) << "Loading registration info from file.";
std::string json_str;
@@ -545,28 +672,45 @@ bool Printer::LoadFromFile(const base::FilePath& file_path) {
return false;
}
+ std::string xmpp_jid;
+ if (!json->GetString("xmpp_jid", &xmpp_jid)) {
+ LOG(ERROR) << "Cannot parse |xmpp_jid|.";
+ return false;
+ }
+
+ std::string access_token;
+ if (!json->GetString("access_token", &access_token)) {
+ LOG(ERROR) << "Cannot parse |access_token|.";
+ return false;
+ }
+
+ int access_token_update;
+ if (!json->GetInteger("access_token_update", &access_token_update)) {
+ LOG(ERROR) << "Cannot parse |access_token_update|.";
+ return false;
+ }
+
reg_info_ = RegistrationInfo();
reg_info_.state = RegistrationInfo::DEV_REG_REGISTERED;
reg_info_.user = user;
reg_info_.device_id = device_id;
reg_info_.refresh_token = refresh_token;
+ reg_info_.xmpp_jid = xmpp_jid;
+ using base::Time;
+ access_token_ = access_token;
+ access_token_update_ = Time::FromTimeT(access_token_update);
return true;
}
-void Printer::PostWakeUp() {
+void Printer::PostOnIdle() {
VLOG(3) << "Function: " << __FUNCTION__;
- base::MessageLoop::current()->PostTask(
- FROM_HERE,
- base::Bind(&Printer::WakeUp, AsWeakPtr()));
-}
+ DCHECK(!on_idle_posted_) << "Only one instance can be posted.";
+ on_idle_posted_ = true;
-void Printer::PostDelayedWakeUp(const base::TimeDelta& delay) {
- VLOG(3) << "Function: " << __FUNCTION__;
- base::MessageLoop::current()->PostDelayedTask(
+ base::MessageLoop::current()->PostTask(
FROM_HERE,
- base::Bind(&Printer::WakeUp, AsWeakPtr()),
- delay);
+ base::Bind(&Printer::OnIdle, AsWeakPtr()));
}
PrivetHttpServer::RegistrationErrorStatus
@@ -609,9 +753,36 @@ 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;
+ LOG(INFO) << base::StringPrintf(
+ "Printer is now %s (%s)",
+ ConnectionStateToString(connection_state_).c_str(),
+ IsRegistered() ? "registered" : "unregistered");
+
dns_server_.UpdateMetadata(CreateTxt());
+
+ switch (connection_state_) {
+ case CONNECTING:
+ break;
+
+ case ONLINE:
+ break;
+
+ case OFFLINE:
+ requester_.reset();
+ xmpp_listener_.reset();
+ base::MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ base::Bind(&Printer::TryConnect, AsWeakPtr()),
+ base::TimeDelta::FromSeconds(kReconnectTimeout));
+
+ case NOT_CONFIGURED:
+ break;
+
+ default:
+ NOTREACHED();
+ }
+
return true;
}
« no previous file with comments | « cloud_print/gcp20/prototype/printer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698