summaryrefslogtreecommitdiffstats
path: root/cloud_print
diff options
context:
space:
mode:
authormaksymb@chromium.org <maksymb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-02 18:58:41 +0000
committermaksymb@chromium.org <maksymb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-02 18:58:41 +0000
commitaa138039b70d0cdc8f039f0e1c683d98d1681665 (patch)
tree979d5a54053d327b1432bb7a35252566d06ae284 /cloud_print
parent55a3456c3b3b53f3908bd30aad776afc97e057b9 (diff)
downloadchromium_src-aa138039b70d0cdc8f039f0e1c683d98d1681665.zip
chromium_src-aa138039b70d0cdc8f039f0e1c683d98d1681665.tar.gz
chromium_src-aa138039b70d0cdc8f039f0e1c683d98d1681665.tar.bz2
GCP2.0 Device: XMPP (without pings).
BUG= Review URL: https://chromiumcodereview.appspot.com/20238002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@215334 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cloud_print')
-rw-r--r--cloud_print/gcp20/prototype/cloud_print_requester.cc89
-rw-r--r--cloud_print/gcp20/prototype/cloud_print_requester.h30
-rw-r--r--cloud_print/gcp20/prototype/cloud_print_response_parser.cc10
-rw-r--r--cloud_print/gcp20/prototype/cloud_print_response_parser.h3
-rw-r--r--cloud_print/gcp20/prototype/cloud_print_url_request_context_getter.cc37
-rw-r--r--cloud_print/gcp20/prototype/cloud_print_url_request_context_getter.h36
-rw-r--r--cloud_print/gcp20/prototype/cloud_print_xmpp_listener.cc108
-rw-r--r--cloud_print/gcp20/prototype/cloud_print_xmpp_listener.h96
-rw-r--r--cloud_print/gcp20/prototype/gcp20_device.cc16
-rw-r--r--cloud_print/gcp20/prototype/gcp20_device.gyp7
-rw-r--r--cloud_print/gcp20/prototype/printer.cc309
-rw-r--r--cloud_print/gcp20/prototype/printer.h79
12 files changed, 659 insertions, 161 deletions
diff --git a/cloud_print/gcp20/prototype/cloud_print_requester.cc b/cloud_print/gcp20/prototype/cloud_print_requester.cc
index f0d1926..1154d62 100644
--- a/cloud_print/gcp20/prototype/cloud_print_requester.cc
+++ b/cloud_print/gcp20/prototype/cloud_print_requester.cc
@@ -9,13 +9,13 @@
#include "base/message_loop/message_loop.h"
#include "base/rand_util.h"
#include "base/strings/stringprintf.h"
+#include "cloud_print/gcp20/prototype/cloud_print_url_request_context_getter.h"
#include "google_apis/google_api_keys.h"
#include "net/base/mime_util.h"
#include "net/base/url_util.h"
+#include "net/http/http_status_code.h"
#include "net/proxy/proxy_config_service_fixed.h"
#include "net/url_request/url_request_context.h"
-#include "net/url_request/url_request_context_builder.h"
-#include "net/url_request/url_request_context_getter.h"
#include "url/gurl.h"
const char kCloudPrintUrl[] = "https://www.google.com/cloudprint";
@@ -51,44 +51,6 @@ GURL CreateControlUrl(const std::string& job_id, const std::string& status) {
using cloud_print_response_parser::Job;
-// Used to return a dummy context, which lives on the message loop
-// given in the constructor.
-class CloudPrintURLRequestContextGetter : public net::URLRequestContextGetter {
- public:
- // |task_runner| must not be NULL.
- explicit CloudPrintURLRequestContextGetter(
- scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
- DCHECK(task_runner);
- network_task_runner_ = task_runner;
- }
-
- // URLRequestContextGetter implementation.
- virtual net::URLRequestContext* GetURLRequestContext() OVERRIDE {
- if (!context_) {
- net::URLRequestContextBuilder builder;
-#if defined(OS_LINUX) || defined(OS_ANDROID)
- builder.set_proxy_config_service(
- new net::ProxyConfigServiceFixed(net::ProxyConfig()));
-#endif // defined(OS_LINUX) || defined(OS_ANDROID)
- context_.reset(builder.Build());
- }
- return context_.get();
- }
-
- virtual scoped_refptr<base::SingleThreadTaskRunner>
- GetNetworkTaskRunner() const OVERRIDE {
- return network_task_runner_;
- }
-
- protected:
- virtual ~CloudPrintURLRequestContextGetter() {}
-
- scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_;
- scoped_ptr<net::URLRequestContext> context_;
-
- DISALLOW_COPY_AND_ASSIGN(CloudPrintURLRequestContextGetter);
-};
-
CloudPrintRequester::CloudPrintRequester(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
Delegate* delegate)
@@ -143,33 +105,29 @@ void CloudPrintRequester::StartRegistration(const std::string& proxy_id,
data,
data_mimetype,
base::Bind(&CloudPrintRequester::ParseRegisterStart, AsWeakPtr()));
- request_->Run(access_token_, context_getter_);
+ request_->Run(delegate_->GetAccessToken(), context_getter_);
}
void CloudPrintRequester::CompleteRegistration() {
request_ = CreateGet(
GURL(polling_url_ + oauth_client_info_.client_id),
base::Bind(&CloudPrintRequester::ParseRegisterComplete, AsWeakPtr()));
- request_->Run(access_token_, context_getter_);
+ request_->Run(delegate_->GetAccessToken(), context_getter_);
}
-void CloudPrintRequester::FetchPrintJobs(const std::string& refresh_token,
- const std::string& device_id) {
+void CloudPrintRequester::FetchPrintJobs(const std::string& device_id) {
VLOG(3) << "Function: " << __FUNCTION__;
if (IsBusy())
return;
- if (access_token_.empty()) {
- UpdateAccesstoken(refresh_token);
- return;
- }
+ DCHECK(!delegate_->GetAccessToken().empty());
VLOG(3) << "Function: " << __FUNCTION__ <<
": request created";
request_ = CreateGet(
CreateFetchUrl(device_id),
base::Bind(&CloudPrintRequester::ParseFetch, AsWeakPtr()));
- request_->Run(access_token_, context_getter_);
+ request_->Run(delegate_->GetAccessToken(), context_getter_);
}
void CloudPrintRequester::UpdateAccesstoken(const std::string& refresh_token) {
@@ -178,7 +136,6 @@ void CloudPrintRequester::UpdateAccesstoken(const std::string& refresh_token) {
gaia_.reset(new gaia::GaiaOAuthClient(context_getter_.get()));
gaia_->RefreshToken(oauth_client_info_, refresh_token,
std::vector<std::string>(), kGaiaMaxRetries, this);
- delegate_->OnServerError("Access token requested.");
}
void CloudPrintRequester::RequestPrintJob(const Job& job) {
@@ -187,7 +144,7 @@ void CloudPrintRequester::RequestPrintJob(const Job& job) {
request_ = CreateGet(
CreateControlUrl(current_print_job_->job_id, "IN_PROGRESS"),
base::Bind(&CloudPrintRequester::ParsePrintJobInProgress, AsWeakPtr()));
- request_->Run(access_token_, context_getter_);
+ request_->Run(delegate_->GetAccessToken(), context_getter_);
}
void CloudPrintRequester::SendPrintJobDone(const std::string& job_id) {
@@ -195,7 +152,7 @@ void CloudPrintRequester::SendPrintJobDone(const std::string& job_id) {
request_ = CreateGet(
CreateControlUrl(job_id, "DONE"),
base::Bind(&CloudPrintRequester::ParsePrintJobDone, AsWeakPtr()));
- request_->Run(access_token_, context_getter_);
+ request_->Run(delegate_->GetAccessToken(), context_getter_);
}
void CloudPrintRequester::OnFetchComplete(const std::string& response) {
@@ -212,6 +169,8 @@ void CloudPrintRequester::OnFetchError(const std::string& server_api,
EraseRequest();
current_print_job_.reset();
delegate_->OnServerError("Fetch error");
+
+ // TODO(maksymb): |server_api| and other
NOTIMPLEMENTED();
}
@@ -227,8 +186,8 @@ void CloudPrintRequester::OnGetTokensResponse(const std::string& refresh_token,
int expires_in_seconds) {
VLOG(3) << "Function: " << __FUNCTION__;
gaia_.reset();
- access_token_ = access_token;
- delegate_->OnGetAuthCodeResponseParsed(refresh_token);
+ delegate_->OnGetAuthCodeResponseParsed(refresh_token,
+ access_token, expires_in_seconds);
}
void CloudPrintRequester::OnRefreshTokenResponse(
@@ -236,20 +195,24 @@ void CloudPrintRequester::OnRefreshTokenResponse(
int expires_in_seconds) {
VLOG(3) << "Function: " << __FUNCTION__;
gaia_.reset();
- access_token_ = access_token;
- LOG(INFO) << "New accesstoken: " << access_token;
+ delegate_->OnAccesstokenReceviced(access_token, expires_in_seconds);
}
void CloudPrintRequester::OnOAuthError() {
VLOG(3) << "Function: " << __FUNCTION__;
gaia_.reset();
- NOTIMPLEMENTED();
+ delegate_->OnAuthError();
}
void CloudPrintRequester::OnNetworkError(int response_code) {
VLOG(3) << "Function: " << __FUNCTION__;
gaia_.reset();
- NOTIMPLEMENTED();
+
+ if (response_code == net::HTTP_FORBIDDEN) {
+ // TODO(maksymb): delegate_->OnPrinterDeleted();
+ } else {
+ delegate_->OnNetworkError();
+ }
}
scoped_ptr<CloudPrintRequest> CloudPrintRequester::CreateGet(
@@ -308,12 +271,16 @@ void CloudPrintRequester::ParseRegisterComplete(const std::string& response) {
std::string error_description;
std::string authorization_code;
+ std::string xmpp_jid;
bool success = cloud_print_response_parser::ParseRegisterCompleteResponse(
response,
&error_description,
- &authorization_code);
+ &authorization_code,
+ &xmpp_jid);
if (success) {
+ delegate_->OnXmppJidReceived(xmpp_jid);
+
gaia_.reset(new gaia::GaiaOAuthClient(context_getter_.get()));
gaia_->GetTokensFromAuthCode(oauth_client_info_, authorization_code,
kGaiaMaxRetries, this);
@@ -348,7 +315,7 @@ void CloudPrintRequester::ParseGetPrintJobTicket(const std::string& response) {
GURL(current_print_job_->file_url),
base::Bind(&CloudPrintRequester::ParseGetPrintJobData, AsWeakPtr()));
request_->AddHeader("Accept: \"application/pdf\"");
- request_->Run(access_token_, context_getter_);
+ request_->Run(delegate_->GetAccessToken(), context_getter_);
}
void CloudPrintRequester::ParseGetPrintJobData(const std::string& response) {
@@ -370,6 +337,6 @@ void CloudPrintRequester::ParsePrintJobInProgress(const std::string& response) {
request_ = CreateGet(
GURL(current_print_job_->ticket_url),
base::Bind(&CloudPrintRequester::ParseGetPrintJobTicket, AsWeakPtr()));
- request_->Run(access_token_, context_getter_);
+ request_->Run(delegate_->GetAccessToken(), context_getter_);
}
diff --git a/cloud_print/gcp20/prototype/cloud_print_requester.h b/cloud_print/gcp20/prototype/cloud_print_requester.h
index 49031ad..f9c2487 100644
--- a/cloud_print/gcp20/prototype/cloud_print_requester.h
+++ b/cloud_print/gcp20/prototype/cloud_print_requester.h
@@ -18,6 +18,7 @@
class CloudPrintURLRequestContextGetter;
class GURL;
+class URLRequestContextGetter;
extern const char kCloudPrintUrl[];
@@ -41,7 +42,16 @@ class CloudPrintRequester : public base::SupportsWeakPtr<CloudPrintRequester>,
// Invoked when server respond for registration-getAuthCode query and
// response is successfully parsed.
virtual void OnGetAuthCodeResponseParsed(
- const std::string& refresh_token) = 0;
+ const std::string& refresh_token,
+ const std::string& access_token,
+ int access_token_expires_in_seconds) = 0;
+
+ // Invoked when XMPP JID was received and it has to be saved.
+ virtual void OnXmppJidReceived(const std::string& xmpp_jid) = 0;
+
+ // Invoked when access_token was received after UpdateAccesstoken() call.
+ virtual void OnAccesstokenReceviced(const std::string& access_token,
+ int expires_in_seconds) = 0;
// Invoked when server respond with |"success" = false| or we cannot parse
// response.
@@ -53,6 +63,12 @@ class CloudPrintRequester : public base::SupportsWeakPtr<CloudPrintRequester>,
// Invoked when server error is received or cannot parse json response.
virtual void OnServerError(const std::string& description) = 0;
+ // Invoked when authorization failed.
+ virtual void OnAuthError() = 0;
+
+ // Invoked when access_token is needed.
+ virtual std::string GetAccessToken() = 0;
+
// Invoked when fetch response was received.
virtual void OnPrintJobsAvailable(
const std::vector<cloud_print_response_parser::Job>& jobs) = 0;
@@ -65,7 +81,7 @@ class CloudPrintRequester : public base::SupportsWeakPtr<CloudPrintRequester>,
virtual void OnPrintJobDone() = 0;
};
- // Creates and initializes objects.
+ // Creates and initializes object.
CloudPrintRequester(scoped_refptr<base::SingleThreadTaskRunner> task_runner,
Delegate* delegate);
@@ -84,8 +100,7 @@ class CloudPrintRequester : public base::SupportsWeakPtr<CloudPrintRequester>,
void CompleteRegistration();
// Creates request for fetching printjobs.
- void FetchPrintJobs(const std::string& refresh_token,
- const std::string& device_id);
+ void FetchPrintJobs(const std::string& device_id);
// Creates request for updating accesstoken.
// TODO(maksymb): Handle expiration of accesstoken.
@@ -159,15 +174,12 @@ class CloudPrintRequester : public base::SupportsWeakPtr<CloudPrintRequester>,
// CloudPrint server responses.
scoped_ptr<cloud_print_response_parser::Job> current_print_job_;
- // Privet context getter.
- scoped_refptr<CloudPrintURLRequestContextGetter> context_getter_;
+ // CloudPrint context getter.
+ scoped_refptr<net::URLRequestContextGetter> context_getter_;
// URL for completing registration and receiving OAuth account.
std::string polling_url_;
- // Last valid access_token.
- std::string access_token_;
-
// OAuth client information (client_id, client_secret, etc).
gaia::OAuthClientInfo oauth_client_info_;
diff --git a/cloud_print/gcp20/prototype/cloud_print_response_parser.cc b/cloud_print/gcp20/prototype/cloud_print_response_parser.cc
index d4da3c3..367a994 100644
--- a/cloud_print/gcp20/prototype/cloud_print_response_parser.cc
+++ b/cloud_print/gcp20/prototype/cloud_print_response_parser.cc
@@ -116,7 +116,8 @@ bool ParseRegisterStartResponse(const std::string& response,
bool ParseRegisterCompleteResponse(const std::string& response,
std::string* error_description,
- std::string* authorization_code_result) {
+ std::string* authorization_code_result,
+ std::string* xmpp_jid_result) {
scoped_ptr<base::Value> json(base::JSONReader::Read(response));
base::DictionaryValue* response_dictionary = NULL;
if (!GetJsonDictinaryAndCheckSuccess(json.get(), error_description,
@@ -131,7 +132,14 @@ bool ParseRegisterCompleteResponse(const std::string& response,
return false;
}
+ std::string xmpp_jid;
+ if (!response_dictionary->GetString("xmpp_jid", &xmpp_jid)) {
+ *error_description = "Cannot parse xmpp jid.";
+ return false;
+ }
+
*authorization_code_result = authorization_code;
+ *xmpp_jid_result = xmpp_jid;
return true;
}
diff --git a/cloud_print/gcp20/prototype/cloud_print_response_parser.h b/cloud_print/gcp20/prototype/cloud_print_response_parser.h
index b691934..5c7254f 100644
--- a/cloud_print/gcp20/prototype/cloud_print_response_parser.h
+++ b/cloud_print/gcp20/prototype/cloud_print_response_parser.h
@@ -48,7 +48,8 @@ bool ParseRegisterStartResponse(const std::string& response,
// when parsing is failed.
bool ParseRegisterCompleteResponse(const std::string& response,
std::string* error_description,
- std::string* authorization_code_result);
+ std::string* authorization_code_result,
+ std::string* xmpp_jid_result);
// Parses CloudPrint fetch response to out parameters.
// Returns |true| on success. Callback is called with description as a parameter
diff --git a/cloud_print/gcp20/prototype/cloud_print_url_request_context_getter.cc b/cloud_print/gcp20/prototype/cloud_print_url_request_context_getter.cc
new file mode 100644
index 0000000..b6bfae9
--- /dev/null
+++ b/cloud_print/gcp20/prototype/cloud_print_url_request_context_getter.cc
@@ -0,0 +1,37 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cloud_print/gcp20/prototype/cloud_print_url_request_context_getter.h"
+
+#include "net/proxy/proxy_config_service_fixed.h"
+#include "net/url_request/url_request_context.h"
+#include "net/url_request/url_request_context_builder.h"
+
+CloudPrintURLRequestContextGetter::CloudPrintURLRequestContextGetter(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
+ DCHECK(task_runner);
+ network_task_runner_ = task_runner;
+}
+
+CloudPrintURLRequestContextGetter::~CloudPrintURLRequestContextGetter() {
+}
+
+net::URLRequestContext*
+CloudPrintURLRequestContextGetter::GetURLRequestContext() {
+ if (!context_) {
+ net::URLRequestContextBuilder builder;
+#if defined(OS_LINUX) || defined(OS_ANDROID)
+ builder.set_proxy_config_service(
+ new net::ProxyConfigServiceFixed(net::ProxyConfig()));
+#endif // defined(OS_LINUX) || defined(OS_ANDROID)
+ context_.reset(builder.Build());
+ }
+ return context_.get();
+}
+
+scoped_refptr<base::SingleThreadTaskRunner>
+CloudPrintURLRequestContextGetter::GetNetworkTaskRunner() const {
+ return network_task_runner_;
+}
+
diff --git a/cloud_print/gcp20/prototype/cloud_print_url_request_context_getter.h b/cloud_print/gcp20/prototype/cloud_print_url_request_context_getter.h
new file mode 100644
index 0000000..efe6719
--- /dev/null
+++ b/cloud_print/gcp20/prototype/cloud_print_url_request_context_getter.h
@@ -0,0 +1,36 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CLOUD_PRINT_GCP20_PROTOTYPE_CLOUD_PRINT_URL_REQUEST_CONTEXT_GETTER_H_
+#define CLOUD_PRINT_GCP20_PROTOTYPE_CLOUD_PRINT_URL_REQUEST_CONTEXT_GETTER_H_
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+#include "net/url_request/url_request_context_getter.h"
+
+// Used to return a dummy context, which lives on the message loop
+// given in the constructor.
+class CloudPrintURLRequestContextGetter : public net::URLRequestContextGetter {
+ public:
+ // |task_runner| must not be NULL.
+ explicit CloudPrintURLRequestContextGetter(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner);
+
+ // URLRequestContextGetter implementation.
+ virtual net::URLRequestContext* GetURLRequestContext() OVERRIDE;
+
+ virtual scoped_refptr<base::SingleThreadTaskRunner>
+ GetNetworkTaskRunner() const OVERRIDE;
+
+ private:
+ virtual ~CloudPrintURLRequestContextGetter();
+
+ scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_;
+ scoped_ptr<net::URLRequestContext> context_;
+
+ DISALLOW_COPY_AND_ASSIGN(CloudPrintURLRequestContextGetter);
+};
+
+#endif // CLOUD_PRINT_GCP20_PROTOTYPE_CLOUD_PRINT_URL_REQUEST_CONTEXT_GETTER_H_
+
diff --git a/cloud_print/gcp20/prototype/cloud_print_xmpp_listener.cc b/cloud_print/gcp20/prototype/cloud_print_xmpp_listener.cc
new file mode 100644
index 0000000..bcf7dcc
--- /dev/null
+++ b/cloud_print/gcp20/prototype/cloud_print_xmpp_listener.cc
@@ -0,0 +1,108 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cloud_print/gcp20/prototype/cloud_print_xmpp_listener.h"
+
+#include "base/logging.h"
+#include "base/single_thread_task_runner.h"
+#include "cloud_print/gcp20/prototype/cloud_print_url_request_context_getter.h"
+#include "jingle/notifier/base/notifier_options.h"
+#include "jingle/notifier/listener/push_client.h"
+
+namespace {
+
+const char kCloudPrintPushNotificationsSource[] = "cloudprint.google.com";
+
+// Splits message into two parts (e.g. '<device_id>/delete' will be splitted
+// into '<device_id>' and '/delete').
+void TokenizeXmppMessage(const std::string& message, std::string* device_id,
+ std::string* path) {
+ std::string::size_type pos = message.find('/');
+ if (pos != std::string::npos) {
+ *device_id = message.substr(0, pos);
+ *path = message.substr(pos);
+ } else {
+ *device_id = message;
+ path->clear();
+ }
+}
+
+} // namespace
+
+CloudPrintXmppListener::CloudPrintXmppListener(
+ const std::string& robot_email,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ Delegate* delegate)
+ : robot_email_(robot_email),
+ context_getter_(new CloudPrintURLRequestContextGetter(task_runner)),
+ delegate_(delegate) {
+}
+
+CloudPrintXmppListener::~CloudPrintXmppListener() {
+ push_client_->RemoveObserver(this);
+ push_client_.reset();
+}
+
+void CloudPrintXmppListener::Connect(const std::string& access_token) {
+ push_client_.reset();
+ access_token_ = access_token;
+
+ notifier::NotifierOptions options;
+ options.request_context_getter = context_getter_;
+ options.auth_mechanism = "X-OAUTH2";
+ options.try_ssltcp_first = true;
+ push_client_ = notifier::PushClient::CreateDefault(options);
+
+ notifier::Subscription subscription;
+ subscription.channel = kCloudPrintPushNotificationsSource;
+ subscription.from = kCloudPrintPushNotificationsSource;
+
+ notifier::SubscriptionList list;
+ list.push_back(subscription);
+
+ push_client_->UpdateSubscriptions(list);
+ push_client_->AddObserver(this);
+ push_client_->UpdateCredentials(robot_email_, access_token_);
+}
+
+void CloudPrintXmppListener::OnNotificationsEnabled() {
+ delegate_->OnXmppConnected();
+}
+
+void CloudPrintXmppListener::OnNotificationsDisabled(
+ notifier::NotificationsDisabledReason reason) {
+ switch (reason) {
+ case notifier::NOTIFICATION_CREDENTIALS_REJECTED:
+ delegate_->OnXmppAuthError();
+ break;
+ case notifier::TRANSIENT_NOTIFICATION_ERROR:
+ delegate_->OnXmppNetworkError();
+ break;
+ default:
+ NOTREACHED() << "XMPP failed with unexpected reason code: " << reason;
+ }
+}
+
+void CloudPrintXmppListener::OnIncomingNotification(
+ const notifier::Notification& notification) {
+ std::string device_id;
+ std::string path;
+ TokenizeXmppMessage(notification.data, &device_id, &path);
+
+ if (path.empty() || path == "/") {
+ delegate_->OnXmppNewPrintJob(device_id);
+ } else if (path == "/update_settings") {
+ delegate_->OnXmppNewLocalSettings(device_id);
+ } else if (path == "/delete") {
+ delegate_->OnXmppDeleteNotification(device_id);
+ } else {
+ LOG(ERROR) << "Cannot parse XMPP notification: " << notification.data;
+ }
+}
+
+void CloudPrintXmppListener::OnPingResponse() {
+ // TODO(maksymb): Implement pings
+ NOTIMPLEMENTED();
+}
+
diff --git a/cloud_print/gcp20/prototype/cloud_print_xmpp_listener.h b/cloud_print/gcp20/prototype/cloud_print_xmpp_listener.h
new file mode 100644
index 0000000..843ba89
--- /dev/null
+++ b/cloud_print/gcp20/prototype/cloud_print_xmpp_listener.h
@@ -0,0 +1,96 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CLOUD_PRINT_GCP20_PROTOTYPE_CLOUD_PRINT_XMPP_LISTENER_H_
+#define CLOUD_PRINT_GCP20_PROTOTYPE_CLOUD_PRINT_XMPP_LISTENER_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "jingle/notifier/listener/push_client_observer.h"
+
+namespace base {
+
+class SingleThreadTaskRunner;
+
+} // namespace base
+
+namespace net {
+
+class URLRequestContextGetter;
+
+} // namespace net
+
+namespace notifier {
+
+class PushClient;
+
+} // namespace notifier
+
+class CloudPrintXmppListener: public notifier::PushClientObserver {
+ public:
+ class Delegate {
+ public:
+ virtual ~Delegate() {}
+
+ // Invoked when XMPP connection was established.
+ virtual void OnXmppConnected() = 0;
+
+ // Invoked when server rejected our credentials.
+ virtual void OnXmppAuthError() = 0;
+
+ // Invoked when server is unavailable.
+ virtual void OnXmppNetworkError() = 0;
+
+ // Invoked when new printjob was received.
+ virtual void OnXmppNewPrintJob(const std::string& device_id) = 0;
+
+ // Invoked when local settings was updated.
+ virtual void OnXmppNewLocalSettings(const std::string& device_id) = 0;
+
+ // Invoked when printer was deleted from server.
+ virtual void OnXmppDeleteNotification(const std::string& device_id) = 0;
+ };
+
+ CloudPrintXmppListener(
+ const std::string& robot_email,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ Delegate* delegate);
+
+ virtual ~CloudPrintXmppListener();
+
+ // Connects to the server.
+ void Connect(const std::string& access_token);
+
+ private:
+ // notifier::PushClientObserver methods:
+ virtual void OnNotificationsEnabled() OVERRIDE;
+ virtual void OnNotificationsDisabled(
+ notifier::NotificationsDisabledReason reason) OVERRIDE;
+ virtual void OnIncomingNotification(
+ const notifier::Notification& notification) OVERRIDE;
+ virtual void OnPingResponse() OVERRIDE;
+
+ // Is used for reconnection when number of retries is now exhausted.
+ void ReconnectInternal();
+
+ // Credentials:
+ std::string robot_email_;
+ std::string access_token_;
+
+ scoped_refptr<net::URLRequestContextGetter> context_getter_;
+
+ // Internal listener.
+ scoped_ptr<notifier::PushClient> push_client_;
+
+ Delegate* delegate_;
+
+ DISALLOW_COPY_AND_ASSIGN(CloudPrintXmppListener);
+};
+
+#endif // CLOUD_PRINT_GCP20_PROTOTYPE_CLOUD_PRINT_XMPP_LISTENER_H_
+
diff --git a/cloud_print/gcp20/prototype/gcp20_device.cc b/cloud_print/gcp20/prototype/gcp20_device.cc
index d58adc5..31025ab 100644
--- a/cloud_print/gcp20/prototype/gcp20_device.cc
+++ b/cloud_print/gcp20/prototype/gcp20_device.cc
@@ -22,10 +22,19 @@ void StartPrinter(Printer* printer) {
}
base::RunLoop* g_runner = NULL;
+Printer* g_printer = NULL;
void OnAbort(int val) {
- if (g_runner)
- g_runner->Quit();
+ if (g_runner) {
+ g_printer->Stop(); // TODO(maksymb): Make this call in safe place call:
+ // |OnAbort| is called from different thread.
+ g_printer = NULL;
+
+ g_runner->Quit(); // Always do after printer.Stop() to make sure XMPP will
+ // be disabled fully before |Quit| will be called
+ // (XMPP disables itself via MessageLoop call).
+ g_runner = NULL;
+ }
}
} // namespace
@@ -45,10 +54,9 @@ int main(int argc, char* argv[]) {
base::MessageLoop::current()->PostTask(FROM_HERE,
base::Bind(&StartPrinter, &printer));
base::RunLoop runner;
+ g_printer = &printer;
g_runner = &runner;
runner.Run();
- g_runner = NULL;
- printer.Stop();
return 0;
}
diff --git a/cloud_print/gcp20/prototype/gcp20_device.gyp b/cloud_print/gcp20/prototype/gcp20_device.gyp
index e6f1777..b2e526f 100644
--- a/cloud_print/gcp20/prototype/gcp20_device.gyp
+++ b/cloud_print/gcp20/prototype/gcp20_device.gyp
@@ -22,17 +22,22 @@
'<(DEPTH)/base/base.gyp:base',
'<(DEPTH)/base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations',
'<(DEPTH)/google_apis/google_apis.gyp:google_apis',
+ '<(DEPTH)/jingle/jingle.gyp:notifier',
'<(DEPTH)/net/net.gyp:http_server',
'<(DEPTH)/net/net.gyp:net',
'<(DEPTH)/url/url.gyp:url_lib',
],
'sources': [
- 'cloud_print_response_parser.cc',
+ 'cloud_print_response_parser.cc',
'cloud_print_response_parser.h',
'cloud_print_request.cc',
'cloud_print_request.h',
'cloud_print_requester.cc',
'cloud_print_requester.h',
+ 'cloud_print_url_request_context_getter.cc',
+ 'cloud_print_url_request_context_getter.h',
+ 'cloud_print_xmpp_listener.cc',
+ 'cloud_print_xmpp_listener.h',
'conio_posix.cc',
'conio_posix.h',
'command_line_reader.cc',
diff --git a/cloud_print/gcp20/prototype/printer.cc b/cloud_print/gcp20/prototype/printer.cc
index 2a0086b..b6ff2c41 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;
}
diff --git a/cloud_print/gcp20/prototype/printer.h b/cloud_print/gcp20/prototype/printer.h
index 3f402b9..7b1ba50 100644
--- a/cloud_print/gcp20/prototype/printer.h
+++ b/cloud_print/gcp20/prototype/printer.h
@@ -11,6 +11,7 @@
#include "base/files/file_path.h"
#include "base/memory/weak_ptr.h"
#include "cloud_print/gcp20/prototype/cloud_print_requester.h"
+#include "cloud_print/gcp20/prototype/cloud_print_xmpp_listener.h"
#include "cloud_print/gcp20/prototype/dns_sd_server.h"
#include "cloud_print/gcp20/prototype/print_job_handler.h"
#include "cloud_print/gcp20/prototype/privet_http_server.h"
@@ -21,7 +22,8 @@ extern const base::FilePath::CharType kPrinterStatePath[];
// This class maintains work of DNS-SD server, HTTP server and others.
class Printer : public base::SupportsWeakPtr<Printer>,
public PrivetHttpServer::Delegate,
- public CloudPrintRequester::Delegate {
+ public CloudPrintRequester::Delegate,
+ public CloudPrintXmppListener::Delegate {
public:
// Constructs uninitialized object.
Printer();
@@ -33,10 +35,7 @@ class Printer : public base::SupportsWeakPtr<Printer>,
bool Start();
// Returns true if printer was started.
- bool IsOnline() const;
-
- // Method for trying to reconnecting to server.
- void WakeUp();
+ bool IsRunning() const;
// Stops all servers.
void Stop();
@@ -69,6 +68,7 @@ class Printer : public base::SupportsWeakPtr<Printer>,
std::string user;
std::string refresh_token;
std::string device_id;
+ std::string xmpp_jid;
RegistrationState state;
ConfirmationState confirmation_state;
@@ -116,16 +116,55 @@ class Printer : public base::SupportsWeakPtr<Printer>,
const std::string& complete_invite_url,
const std::string& device_id) OVERRIDE;
virtual void OnGetAuthCodeResponseParsed(
- const std::string& refresh_token) OVERRIDE;
+ const std::string& refresh_token,
+ const std::string& access_token,
+ int access_token_expires_in_seconds) OVERRIDE;
+ virtual void OnXmppJidReceived(const std::string& xmpp_jid) OVERRIDE;
+ virtual void OnAccesstokenReceviced(const std::string& access_token,
+ int expires_in_seconds) OVERRIDE;
virtual void OnRegistrationError(const std::string& description) OVERRIDE;
- virtual void OnServerError(const std::string& description) OVERRIDE;
virtual void OnNetworkError() OVERRIDE;
+ virtual void OnServerError(const std::string& description) OVERRIDE;
+ virtual void OnAuthError() OVERRIDE;
+ virtual std::string GetAccessToken() OVERRIDE;
virtual void OnPrintJobsAvailable(
const std::vector<cloud_print_response_parser::Job>& jobs) OVERRIDE;
virtual void OnPrintJobDownloaded(
const cloud_print_response_parser::Job& job) OVERRIDE;
virtual void OnPrintJobDone() OVERRIDE;
+ // CloudPrintXmppListener::Delegate methods:
+ virtual void OnXmppConnected() OVERRIDE;
+ virtual void OnXmppAuthError() OVERRIDE;
+ virtual void OnXmppNetworkError() OVERRIDE;
+ virtual void OnXmppNewPrintJob(const std::string& device_id) OVERRIDE;
+ virtual void OnXmppNewLocalSettings(const std::string& device_id) OVERRIDE;
+ virtual void OnXmppDeleteNotification(const std::string& device_id) OVERRIDE;
+
+ // Method for trying to reconnecting to server on start or after network fail.
+ void TryConnect();
+
+ // Connects XMPP.
+ void ConnectXmpp();
+
+ // Method to handle pending events.
+ // Do *NOT* call this method instantly. Only with |PostOnIdle|.
+ void OnIdle();
+
+ // Method for checking printer status.
+ // (e.g. printjobs, local settings, deleted status).
+ void CheckPendingUpdates();
+
+ // Ask CloudPrint server for new local sendings.
+ void GetLocalSettings();
+
+ // Ask CloudPrint server for printjobs.
+ void FetchPrintJobs();
+
+ // Saves |access_token| and calculates time for next update.
+ void RememberAccessToken(const std::string& access_token,
+ int expires_in_seconds);
+
// Checks if register call is called correctly (|user| is correct,
// error is no set etc). Returns |false| if error status is put into |status|.
// Otherwise no error was occurred.
@@ -141,18 +180,12 @@ class Printer : public base::SupportsWeakPtr<Printer>,
// Creates data for DNS TXT respond.
std::vector<std::string> CreateTxt() const;
- // Ask CloudPrint server for printjobs.
- void FetchPrintJobs();
-
// Saving and loading registration info from file.
void SaveToFile(const base::FilePath& file_path) const;
bool LoadFromFile(const base::FilePath& file_path);
- // Adds |WakeUp| method to the MessageLoop.
- void PostWakeUp();
-
- // Adds |WakeUp| method to the MessageLoop with certain |delay|.
- void PostDelayedWakeUp(const base::TimeDelta& delay);
+ // Adds |OnIdle| method to the MessageLoop.
+ void PostOnIdle();
// Converts errors.
PrivetHttpServer::RegistrationErrorStatus ConfirmationToRegistrationError(
@@ -177,13 +210,29 @@ class Printer : public base::SupportsWeakPtr<Printer>,
// Contains CloudPrint client.
scoped_ptr<CloudPrintRequester> requester_;
+ // XMPP Listener.
+ scoped_ptr<CloudPrintXmppListener> xmpp_listener_;
+
XPrivetToken xtoken_;
scoped_ptr<PrintJobHandler> print_job_handler_;
+ // Last valid |access_token|.
+ std::string access_token_;
+ base::Time access_token_update_;
+
// Uses for calculating uptime.
base::Time starttime_;
+ // Used for preventing two and more OnIdle posted in message loop.
+ bool on_idle_posted_;
+
+ // Contains |true| if Printer has to check pending local settings.
+ bool pending_local_settings_check_;
+
+ // Contains |true| if Printer has to check available printjobs.
+ bool pending_print_jobs_check_;
+
DISALLOW_COPY_AND_ASSIGN(Printer);
};