summaryrefslogtreecommitdiffstats
path: root/cloud_print
diff options
context:
space:
mode:
authormaksymb@chromium.org <maksymb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-16 10:22:58 +0000
committermaksymb@chromium.org <maksymb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-16 10:22:58 +0000
commitb2d467cc630c6c0c9c8d004e610c704bb8ac07b9 (patch)
tree85fb288f9f7114eddc69da17cf31bf36f121a683 /cloud_print
parent3371e50258c7966c4f0c9570c9e18d78305ba0b9 (diff)
downloadchromium_src-b2d467cc630c6c0c9c8d004e610c704bb8ac07b9.zip
chromium_src-b2d467cc630c6c0c9c8d004e610c704bb8ac07b9.tar.gz
chromium_src-b2d467cc630c6c0c9c8d004e610c704bb8ac07b9.tar.bz2
GCP2.0 Device: Local settings management.
BUG= Review URL: https://chromiumcodereview.appspot.com/22555003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@217989 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cloud_print')
-rw-r--r--cloud_print/gcp20/prototype/cloud_print_requester.cc94
-rw-r--r--cloud_print/gcp20/prototype/cloud_print_requester.h26
-rw-r--r--cloud_print/gcp20/prototype/cloud_print_response_parser.cc71
-rw-r--r--cloud_print/gcp20/prototype/cloud_print_response_parser.h17
-rw-r--r--cloud_print/gcp20/prototype/cloud_print_xmpp_listener.cc4
-rw-r--r--cloud_print/gcp20/prototype/cloud_print_xmpp_listener.h2
-rw-r--r--cloud_print/gcp20/prototype/gcp20_device.gyp1
-rw-r--r--cloud_print/gcp20/prototype/local_settings.h31
-rw-r--r--cloud_print/gcp20/prototype/printer.cc191
-rw-r--r--cloud_print/gcp20/prototype/printer.h31
10 files changed, 409 insertions, 59 deletions
diff --git a/cloud_print/gcp20/prototype/cloud_print_requester.cc b/cloud_print/gcp20/prototype/cloud_print_requester.cc
index 1910b7f..ec40489 100644
--- a/cloud_print/gcp20/prototype/cloud_print_requester.cc
+++ b/cloud_print/gcp20/prototype/cloud_print_requester.cc
@@ -5,12 +5,14 @@
#include "cloud_print/gcp20/prototype/cloud_print_requester.h"
#include "base/bind.h"
+#include "base/json/json_writer.h"
#include "base/md5.h"
#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/escape.h"
#include "net/base/mime_util.h"
#include "net/base/url_util.h"
#include "net/http/http_status_code.h"
@@ -27,6 +29,11 @@ const char kPrinterNameValue[] = "printer";
const char kPrinterCapsValue[] = "capabilities";
const char kPrinterCapsHashValue[] = "capsHash";
const char kPrinterUserValue[] = "user";
+const char kPrinterGcpVersion[] = "gcp_version";
+const char kPrinterLocalSettings[] = "local_settings";
+
+// TODO(maksymb): Replace GCP Version with "2.0" once GCP Server will support it
+const char kGcpVersion[] = "1.5";
const int kGaiaMaxRetries = 3;
@@ -47,6 +54,35 @@ GURL CreateControlUrl(const std::string& job_id, const std::string& status) {
return url;
}
+GURL CreatePrinterUrl(const std::string& device_id) {
+ GURL url(std::string(kCloudPrintUrl) + "/printer");
+ url = net::AppendQueryParameter(url, "printerid", device_id);
+ return url;
+}
+
+GURL CreateUpdateUrl(const std::string& device_id) {
+ GURL url(std::string(kCloudPrintUrl) + "/update");
+ url = net::AppendQueryParameter(url, "printerid", device_id);
+ return url;
+}
+
+std::string LocalSettingsToJson(const LocalSettings& settings) {
+ base::DictionaryValue dictionary;
+ scoped_ptr<base::DictionaryValue> current(new DictionaryValue);
+
+ // TODO(maksymb): Formalize text as constants.
+ current->SetBoolean("local_discovery", settings.local_discovery);
+ current->SetBoolean("access_token_enabled", settings.access_token_enabled);
+ current->SetBoolean("printer/local_printing_enabled",
+ settings.local_printing_enabled);
+ current->SetInteger("xmpp_timeout_value", settings.xmpp_timeout_value);
+ dictionary.Set("current", current.release());
+
+ std::string local_settings;
+ base::JSONWriter::Write(&dictionary, &local_settings);
+ return local_settings;
+}
+
} // namespace
using cloud_print_response_parser::Job;
@@ -73,6 +109,7 @@ bool CloudPrintRequester::IsBusy() const {
void CloudPrintRequester::StartRegistration(const std::string& proxy_id,
const std::string& device_name,
const std::string& user,
+ const LocalSettings& settings,
const std::string& cdd) {
std::string mime_boundary;
int r1 = base::RandInt(0, kint32max);
@@ -98,6 +135,11 @@ void CloudPrintRequester::StartRegistration(const std::string& proxy_id,
mime_boundary, std::string(), &data);
net::AddMultipartValueForUpload(kPrinterUserValue, user,
mime_boundary, std::string(), &data);
+ net::AddMultipartValueForUpload(kPrinterGcpVersion, kGcpVersion,
+ mime_boundary, std::string(), &data);
+ net::AddMultipartValueForUpload(kPrinterLocalSettings,
+ LocalSettingsToJson(settings),
+ mime_boundary, std::string(), &data);
net::AddMultipartFinalDelimiterForUpload(mime_boundary, &data);
request_ = CreatePost(
@@ -155,6 +197,33 @@ void CloudPrintRequester::SendPrintJobDone(const std::string& job_id) {
request_->Run(delegate_->GetAccessToken(), context_getter_);
}
+void CloudPrintRequester::RequestLocalSettings(const std::string& device_id) {
+ VLOG(3) << "Function: " << __FUNCTION__;
+ request_ = CreateGet(
+ CreatePrinterUrl(device_id),
+ base::Bind(&CloudPrintRequester::ParseLocalSettings, AsWeakPtr()));
+ request_->Run(delegate_->GetAccessToken(), context_getter_);
+}
+
+void CloudPrintRequester::SendLocalSettings(
+ const std::string& device_id,
+ const LocalSettings& settings) {
+ VLOG(3) << "Function: " << __FUNCTION__;
+
+ std::string data_mimetype = "application/x-www-form-urlencoded";
+ std::string data = base::StringPrintf(
+ "%s=%s",
+ kPrinterLocalSettings,
+ net::EscapeUrlEncodedData(LocalSettingsToJson(settings), false).c_str());
+
+ request_ = CreatePost(
+ CreateUpdateUrl(device_id),
+ data, data_mimetype,
+ base::Bind(&CloudPrintRequester::ParseLocalSettingUpdated, AsWeakPtr()));
+ request_->Run(delegate_->GetAccessToken(), context_getter_);
+}
+
+
void CloudPrintRequester::OnFetchComplete(const std::string& response) {
VLOG(3) << "Function: " << __FUNCTION__;
ParserCallback callback = parser_callback_;
@@ -345,3 +414,28 @@ void CloudPrintRequester::ParsePrintJobInProgress(const std::string& response) {
request_->Run(delegate_->GetAccessToken(), context_getter_);
}
+void CloudPrintRequester::ParseLocalSettings(const std::string& response) {
+ VLOG(3) << "Function: " << __FUNCTION__;
+
+ std::string error_description;
+ LocalSettings settings;
+ LocalSettings::State state;
+
+ bool success = cloud_print_response_parser::ParseLocalSettingsResponse(
+ response,
+ &error_description,
+ &state,
+ &settings);
+
+ if (success) {
+ delegate_->OnLocalSettingsReceived(state, settings);
+ } else {
+ delegate_->OnServerError(error_description);
+ }
+}
+
+void CloudPrintRequester::ParseLocalSettingUpdated(
+ const std::string& response) {
+ delegate_->OnLocalSettingsUpdated();
+}
+
diff --git a/cloud_print/gcp20/prototype/cloud_print_requester.h b/cloud_print/gcp20/prototype/cloud_print_requester.h
index 8e1e46c..ff8306b 100644
--- a/cloud_print/gcp20/prototype/cloud_print_requester.h
+++ b/cloud_print/gcp20/prototype/cloud_print_requester.h
@@ -14,6 +14,7 @@
#include "base/values.h"
#include "cloud_print/gcp20/prototype/cloud_print_request.h"
#include "cloud_print/gcp20/prototype/cloud_print_response_parser.h"
+#include "cloud_print/gcp20/prototype/local_settings.h"
#include "google_apis/gaia/gaia_oauth_client.h"
class CloudPrintURLRequestContextGetter;
@@ -79,6 +80,14 @@ class CloudPrintRequester : public base::SupportsWeakPtr<CloudPrintRequester>,
// Invoked when printjob is marked as done on CloudPrint server.
virtual void OnPrintJobDone() = 0;
+
+ // Invoked when local settings response was received.
+ virtual void OnLocalSettingsReceived(
+ LocalSettings::State state,
+ const LocalSettings& settings) = 0;
+
+ // Invoked when CURRENT local settings was updated on server.
+ virtual void OnLocalSettingsUpdated() = 0;
};
// Creates and initializes object.
@@ -94,7 +103,9 @@ class CloudPrintRequester : public base::SupportsWeakPtr<CloudPrintRequester>,
// Creates query to server for starting registration.
void StartRegistration(const std::string& proxy_id,
const std::string& device_name,
- const std::string& user, const std::string& cdd);
+ const std::string& user,
+ const LocalSettings& settings,
+ const std::string& cdd);
// Creates request for completing registration and receiving refresh token.
void CompleteRegistration();
@@ -112,6 +123,13 @@ class CloudPrintRequester : public base::SupportsWeakPtr<CloudPrintRequester>,
// Reports server that printjob has been printed.
void SendPrintJobDone(const std::string& job_id);
+ // Requests /printer API to receive local settings.
+ void RequestLocalSettings(const std::string& device_id);
+
+ // Updates local settings on server.
+ void SendLocalSettings(const std::string& device_id,
+ const LocalSettings& settings);
+
private:
typedef base::Callback<void(const std::string&)> ParserCallback;
@@ -166,6 +184,12 @@ class CloudPrintRequester : public base::SupportsWeakPtr<CloudPrintRequester>,
// Invoked after marking printjob as IN_PROGRESS.
void ParsePrintJobInProgress(const std::string& response);
+ // Invoked after receiving local_settings.
+ void ParseLocalSettings(const std::string& response);
+
+ // Invoked after updating current local_settings.
+ void ParseLocalSettingUpdated(const std::string& response);
+
// |request| contains |NULL| if no server response is awaiting. Otherwise wait
// until callback will be called will be called and close connection.
scoped_ptr<CloudPrintRequest> request_;
diff --git a/cloud_print/gcp20/prototype/cloud_print_response_parser.cc b/cloud_print/gcp20/prototype/cloud_print_response_parser.cc
index bc2742b..66bcd85 100644
--- a/cloud_print/gcp20/prototype/cloud_print_response_parser.cc
+++ b/cloud_print/gcp20/prototype/cloud_print_response_parser.cc
@@ -197,7 +197,78 @@ bool ParseFetchResponse(const std::string& response,
}
*list = job_list;
+ return true;
+}
+
+bool ParseLocalSettingsResponse(const std::string& response,
+ std::string* error_description,
+ LocalSettings::State* state,
+ LocalSettings* settings) {
+ scoped_ptr<base::Value> json(base::JSONReader::Read(response));
+ base::DictionaryValue* response_dictionary = NULL;
+ bool json_success;
+ std::string message;
+ if (!GetJsonDictinaryAndCheckSuccess(json.get(), error_description,
+ &json_success, &message,
+ &response_dictionary)) {
+ return false;
+ }
+
+ if (!json_success) { // Let's suppose our printer was deleted.
+ *state = LocalSettings::PRINTER_DELETED;
+ return true;
+ }
+
+ base::ListValue* list = NULL;
+ if (!response_dictionary->GetList("printers", &list)) {
+ *error_description = "No printers list specified.";
+ return false;
+ }
+
+ base::DictionaryValue* printer = NULL;
+ if (!list->GetDictionary(0, &printer)) {
+ *error_description = "Printers list is empty or printer is not dictionary.";
+ return false;
+ }
+
+ base::DictionaryValue* local_settings_dict = NULL;
+ if (!printer->GetDictionary("local_settings", &local_settings_dict)) {
+ *error_description = "No local_settings found.";
+ return false;
+ }
+
+ base::DictionaryValue* current = NULL;
+ if (!local_settings_dict->GetDictionary("current", &current)) {
+ *error_description = "No *current* local settings found.";
+ return false;
+ }
+
+ LocalSettings::State settings_state;
+ base::DictionaryValue* pending = NULL;
+ base::DictionaryValue* settings_to_parse = NULL;
+ if (local_settings_dict->GetDictionary("pending", &pending)) {
+ settings_to_parse = pending;
+ settings_state = LocalSettings::PENDING;
+ } else {
+ settings_to_parse = current;
+ settings_state = LocalSettings::CURRENT;
+ }
+
+ LocalSettings local_settings;
+ if (!settings_to_parse->GetBoolean("local_discovery",
+ &local_settings.local_discovery) ||
+ !settings_to_parse->GetBoolean("access_token_enabled",
+ &local_settings.access_token_enabled) ||
+ !settings_to_parse->GetBoolean("printer/local_printing_enabled",
+ &local_settings.local_printing_enabled) ||
+ !settings_to_parse->GetInteger("xmpp_timeout_value",
+ &local_settings.xmpp_timeout_value)) {
+ *error_description = "Cannot parse local_settings info.";
+ return false;
+ }
+ *state = settings_state;
+ *settings = local_settings;
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 97a4c26..c32d932 100644
--- a/cloud_print/gcp20/prototype/cloud_print_response_parser.h
+++ b/cloud_print/gcp20/prototype/cloud_print_response_parser.h
@@ -9,6 +9,7 @@
#include <vector>
#include "base/callback.h"
+#include "cloud_print/gcp20/prototype/local_settings.h"
namespace base {
@@ -34,8 +35,7 @@ struct Job {
};
// Parses CloudPrint register start response to out parameters.
-// Returns |true| on success. Callback is called with description as a parameter
-// when parsing is failed.
+// Returns |true| on success.
bool ParseRegisterStartResponse(const std::string& response,
std::string* error_description,
std::string* polling_url,
@@ -44,20 +44,25 @@ bool ParseRegisterStartResponse(const std::string& response,
std::string* device_id);
// Parses CloudPrint register complete response to out parameters.
-// Returns |true| on success. Callback is called with description as a parameter
-// when parsing is failed.
+// Returns |true| on success.
bool ParseRegisterCompleteResponse(const std::string& response,
std::string* error_description,
std::string* authorization_code,
std::string* xmpp_jid);
// Parses CloudPrint fetch response to out parameters.
-// Returns |true| on success. Callback is called with description as a parameter
-// when parsing is failed.
+// Returns |true| on success.
bool ParseFetchResponse(const std::string& response,
std::string* error_description,
std::vector<Job>* list);
+// Parses CloudPrint printer response to get Local Settings.
+// Returns |true| on success.
+bool ParseLocalSettingsResponse(const std::string& response,
+ std::string* error_description,
+ LocalSettings::State* state,
+ LocalSettings* settings);
+
} // namespace cloud_print_response_parser
#endif // CLOUD_PRINT_GCP20_PROTOTYPE_CLOUD_PRINT_RESPONSE_PARSER_H_
diff --git a/cloud_print/gcp20/prototype/cloud_print_xmpp_listener.cc b/cloud_print/gcp20/prototype/cloud_print_xmpp_listener.cc
index 6ad90230..6c7c235 100644
--- a/cloud_print/gcp20/prototype/cloud_print_xmpp_listener.cc
+++ b/cloud_print/gcp20/prototype/cloud_print_xmpp_listener.cc
@@ -61,7 +61,7 @@ CloudPrintXmppListener::~CloudPrintXmppListener() {
void CloudPrintXmppListener::Connect(const std::string& access_token) {
access_token_ = access_token;
ping_responses_pending_ = 0;
- ping_scheduled_ = 0;
+ ping_scheduled_ = false;
notifier::NotifierOptions options;
options.request_context_getter = context_getter_;
@@ -81,7 +81,7 @@ void CloudPrintXmppListener::Connect(const std::string& access_token) {
push_client_->UpdateCredentials(robot_email_, access_token_);
}
-void CloudPrintXmppListener::set_standard_ping_interval(int interval) {
+void CloudPrintXmppListener::set_ping_interval(int interval) {
standard_ping_interval_ = interval;
}
diff --git a/cloud_print/gcp20/prototype/cloud_print_xmpp_listener.h b/cloud_print/gcp20/prototype/cloud_print_xmpp_listener.h
index 7c612fe..b2cf2b8 100644
--- a/cloud_print/gcp20/prototype/cloud_print_xmpp_listener.h
+++ b/cloud_print/gcp20/prototype/cloud_print_xmpp_listener.h
@@ -71,7 +71,7 @@ class CloudPrintXmppListener
void Connect(const std::string& access_token);
// Update ping interval when new local_settings was received.
- void set_standard_ping_interval(int interval);
+ void set_ping_interval(int interval);
private:
// notifier::PushClientObserver methods:
diff --git a/cloud_print/gcp20/prototype/gcp20_device.gyp b/cloud_print/gcp20/prototype/gcp20_device.gyp
index b2e526f..d618069 100644
--- a/cloud_print/gcp20/prototype/gcp20_device.gyp
+++ b/cloud_print/gcp20/prototype/gcp20_device.gyp
@@ -48,6 +48,7 @@
'dns_response_builder.h',
'dns_sd_server.cc',
'dns_sd_server.h',
+ 'local_settings.h',
'print_job_handler.cc',
'print_job_handler.h',
'printer.cc',
diff --git a/cloud_print/gcp20/prototype/local_settings.h b/cloud_print/gcp20/prototype/local_settings.h
new file mode 100644
index 0000000..b2ec58f
--- /dev/null
+++ b/cloud_print/gcp20/prototype/local_settings.h
@@ -0,0 +1,31 @@
+// 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_LOCAL_SETTINGS_H_
+#define CLOUD_PRINT_GCP20_PROTOTYPE_LOCAL_SETTINGS_H_
+
+// Contains local settings.
+struct LocalSettings {
+ enum State {
+ CURRENT,
+ PENDING,
+ PRINTER_DELETED,
+ };
+
+ LocalSettings()
+ : local_discovery(true),
+ access_token_enabled(false),
+ local_printing_enabled(false),
+ xmpp_timeout_value(300) {
+ }
+ ~LocalSettings() {}
+
+ bool local_discovery;
+ bool access_token_enabled;
+ bool local_printing_enabled;
+ int xmpp_timeout_value;
+};
+
+#endif // CLOUD_PRINT_GCP20_PROTOTYPE_LOCAL_SETTINGS_H_
+
diff --git a/cloud_print/gcp20/prototype/printer.cc b/cloud_print/gcp20/prototype/printer.cc
index 02813ab..4b49cf29 100644
--- a/cloud_print/gcp20/prototype/printer.cc
+++ b/cloud_print/gcp20/prototype/printer.cc
@@ -17,6 +17,7 @@
#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/local_settings.h"
#include "cloud_print/gcp20/prototype/service_parameters.h"
#include "cloud_print/gcp20/prototype/special_io.h"
#include "net/base/net_util.h"
@@ -28,7 +29,6 @@ namespace {
const uint16 kHttpPortDefault = 10101;
const uint32 kTtlDefault = 60*60; // in seconds
-const int kXmppPingIntervalDefault = 5*60; // in seconds
const char kServiceType[] = "_privet._tcp.local";
const char kServiceNamePrefixDefault[] = "first_gcp20_device";
@@ -91,7 +91,6 @@ net::IPAddressNumber GetLocalIp(const std::string& interface_name,
iter != interfaces.end(); ++iter) {
if (iter->address.size() == expected_address_size &&
(interface_name.empty() || interface_name == iter->name)) {
- LOG(INFO) << net::IPAddressToString(iter->address);
return iter->address;
}
}
@@ -120,7 +119,8 @@ Printer::Printer()
connection_state_(OFFLINE),
on_idle_posted_(false),
pending_local_settings_check_(false),
- pending_print_jobs_check_(false) {
+ pending_print_jobs_check_(false),
+ pending_deletion_(false) {
}
Printer::~Printer() {
@@ -131,35 +131,17 @@ bool Printer::Start() {
if (IsRunning())
return true;
- // TODO(maksymb): Add switch for command line to control interface name.
- net::IPAddressNumber ip = GetLocalIp("", false);
- if (ip.empty()) {
- LOG(ERROR) << "No local IP found. Cannot start printer.";
- return false;
- }
- VLOG(1) << "Local address: " << net::IPAddressToString(ip);
-
- uint16 port = command_line_reader::ReadHttpPort(kHttpPortDefault);
-
- // Starting HTTP server.
- if (!http_server_.Start(port))
- return false;
-
if (!LoadFromFile())
reg_info_ = RegistrationInfo();
- // Starting DNS-SD server.
- std::string service_name_prefix =
- command_line_reader::ReadServiceNamePrefix(kServiceNamePrefixDefault);
- std::string service_domain_name =
- command_line_reader::ReadDomainName(kServiceDomainNameDefault);
- if (!dns_server_.Start(
- ServiceParameters(kServiceType, service_name_prefix, service_domain_name,
- ip, port),
- command_line_reader::ReadTtl(kTtlDefault),
- CreateTxt())) {
- http_server_.Shutdown();
- return false;
+ if (local_settings_.local_discovery) {
+ if (!StartHttpServer())
+ return false;
+
+ if (!StartDnsServer()) {
+ http_server_.Shutdown();
+ return false;
+ }
}
print_job_handler_.reset(new PrintJobHandler);
@@ -175,6 +157,8 @@ bool Printer::IsRunning() const {
}
void Printer::Stop() {
+ if (!IsRunning())
+ return;
dns_server_.Shutdown();
http_server_.Shutdown();
requester_.reset();
@@ -228,7 +212,8 @@ PrivetHttpServer::RegistrationErrorStatus Printer::RegistrationStart(
base::Bind(&Printer::WaitUserConfirmation, AsWeakPtr(), valid_until));
}
- requester_->StartRegistration(GenerateProxyId(), kPrinterName, user, kCdd);
+ requester_->StartRegistration(GenerateProxyId(), kPrinterName, user,
+ local_settings_, kCdd);
return PrivetHttpServer::REG_ERROR_OK;
}
@@ -446,6 +431,33 @@ void Printer::OnPrintJobDone() {
PostOnIdle();
}
+void Printer::OnLocalSettingsReceived(LocalSettings::State state,
+ const LocalSettings& settings) {
+ pending_local_settings_check_ = false;
+ switch (state) {
+ case LocalSettings::CURRENT:
+ LOG(INFO) << "No new local settings";
+ PostOnIdle();
+ break;
+ case LocalSettings::PENDING:
+ LOG(INFO) << "New local settings were received";
+ ApplyLocalSettings(settings);
+ break;
+ case LocalSettings::PRINTER_DELETED:
+ LOG(WARNING) << "Printer was deleted on server";
+ pending_deletion_ = true;
+ PostOnIdle();
+ break;
+
+ default:
+ NOTREACHED();
+ }
+}
+
+void Printer::OnLocalSettingsUpdated() {
+ PostOnIdle();
+}
+
void Printer::OnXmppConnected() {
pending_local_settings_check_ = true;
pending_print_jobs_check_ = true;
@@ -468,12 +480,12 @@ void Printer::OnXmppNewPrintJob(const std::string& device_id) {
void Printer::OnXmppNewLocalSettings(const std::string& device_id) {
DCHECK_EQ(reg_info_.device_id, device_id) << "Data should contain printer_id";
- NOTIMPLEMENTED();
+ pending_local_settings_check_ = true;
}
void Printer::OnXmppDeleteNotification(const std::string& device_id) {
DCHECK_EQ(reg_info_.device_id, device_id) << "Data should contain printer_id";
- NOTIMPLEMENTED();
+ pending_deletion_ = true;
}
void Printer::TryConnect() {
@@ -497,7 +509,8 @@ void Printer::TryConnect() {
void Printer::ConnectXmpp() {
xmpp_listener_.reset(
- new CloudPrintXmppListener(reg_info_.xmpp_jid, kXmppPingIntervalDefault,
+ new CloudPrintXmppListener(reg_info_.xmpp_jid,
+ local_settings_.xmpp_timeout_value,
GetTaskRunner(), this));
xmpp_listener_->Connect(access_token_);
}
@@ -510,6 +523,11 @@ void Printer::OnIdle() {
if (connection_state_ != ONLINE)
return;
+ if (pending_deletion_) {
+ OnPrinterDeleted();
+ return;
+ }
+
if (access_token_update_ < base::Time::Now()) {
requester_->UpdateAccesstoken(reg_info_.refresh_token);
return;
@@ -517,8 +535,6 @@ void Printer::OnIdle() {
// TODO(maksymb): Check if privet-accesstoken was requested.
- // TODO(maksymb): Check if local-printing was requested.
-
if (pending_local_settings_check_) {
GetLocalSettings();
return;
@@ -535,18 +551,46 @@ void Printer::OnIdle() {
base::TimeDelta::FromMilliseconds(1000));
}
+void Printer::FetchPrintJobs() {
+ VLOG(3) << "Function: " << __FUNCTION__;
+ DCHECK(IsRegistered());
+ requester_->FetchPrintJobs(reg_info_.device_id);
+}
+
void Printer::GetLocalSettings() {
+ VLOG(3) << "Function: " << __FUNCTION__;
DCHECK(IsRegistered());
+ requester_->RequestLocalSettings(reg_info_.device_id);
+}
- pending_local_settings_check_ = false;
- PostOnIdle();
+void Printer::ApplyLocalSettings(const LocalSettings& settings) {
+ local_settings_ = settings;
+ SaveToFile();
+
+ if (local_settings_.local_discovery) {
+ StartDnsServer();
+ StartHttpServer();
+ } else {
+ dns_server_.Shutdown();
+ http_server_.Shutdown();
+ }
+
+ xmpp_listener_->set_ping_interval(local_settings_.xmpp_timeout_value);
+
+ requester_->SendLocalSettings(reg_info_.device_id, local_settings_);
}
-void Printer::FetchPrintJobs() {
- VLOG(3) << "Function: " << __FUNCTION__;
+void Printer::OnPrinterDeleted() {
+ pending_deletion_ = false;
- DCHECK(IsRegistered());
- requester_->FetchPrintJobs(reg_info_.device_id);
+ reg_info_ = RegistrationInfo();
+ access_token_.clear();
+ access_token_update_ = base::Time();
+ local_settings_ = LocalSettings();
+
+ SaveToFile();
+ Stop();
+ Start();
}
void Printer::RememberAccessToken(const std::string& access_token,
@@ -647,6 +691,17 @@ void Printer::SaveToFile() const {
json.SetString("access_token", access_token_);
json.SetInteger("access_token_update",
static_cast<int>(access_token_update_.ToTimeT()));
+
+ scoped_ptr<base::DictionaryValue> local_settings(new DictionaryValue);
+ local_settings->SetBoolean("local_discovery",
+ local_settings_.local_discovery);
+ local_settings->SetBoolean("access_token_enabled",
+ local_settings_.access_token_enabled);
+ local_settings->SetBoolean("printer/local_printing_enabled",
+ local_settings_.local_printing_enabled);
+ local_settings->SetInteger("xmpp_timeout_value",
+ local_settings_.xmpp_timeout_value);
+ json.Set("local_settings", local_settings.release());
} else {
json.SetBoolean("registered", false);
}
@@ -732,15 +787,33 @@ bool Printer::LoadFromFile() {
return false;
}
+ LocalSettings local_settings;
+ base::DictionaryValue* settings_dict;
+ if (!json->GetDictionary("local_settings", &settings_dict)) {
+ LOG(ERROR) << "Cannot read |local_settings|. Reset to default.";
+ } else {
+ if (!settings_dict->GetBoolean("local_discovery",
+ &local_settings.local_discovery) ||
+ !settings_dict->GetBoolean("access_token_enabled",
+ &local_settings.access_token_enabled) ||
+ !settings_dict->GetBoolean("printer/local_printing_enabled",
+ &local_settings.local_printing_enabled) ||
+ !settings_dict->GetInteger("xmpp_timeout_value",
+ &local_settings.xmpp_timeout_value)) {
+ LOG(ERROR) << "Cannot parse |local_settings|. Reset to default.";
+ local_settings = LocalSettings();
+ }
+ }
+
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);
+ access_token_update_ = base::Time::FromTimeT(access_token_update);
+ local_settings_ = local_settings;
return true;
}
@@ -774,6 +847,38 @@ void Printer::InvalidateRegistrationExpiration() {
registration_expiration_ = base::Time();
}
+bool Printer::StartHttpServer() {
+ DCHECK(local_settings_.local_discovery);
+ using command_line_reader::ReadHttpPort;
+ return http_server_.Start(ReadHttpPort(kHttpPortDefault));
+}
+
+bool Printer::StartDnsServer() {
+ DCHECK(local_settings_.local_discovery);
+
+ // TODO(maksymb): Add switch for command line to control interface name.
+ net::IPAddressNumber ip = GetLocalIp("", false);
+ if (ip.empty()) {
+ LOG(ERROR) << "No local IP found. Cannot start printer.";
+ return false;
+ }
+ VLOG(1) << "Local address: " << net::IPAddressToString(ip);
+
+ uint16 port = command_line_reader::ReadHttpPort(kHttpPortDefault);
+
+ std::string service_name_prefix =
+ command_line_reader::ReadServiceNamePrefix(kServiceNamePrefixDefault);
+ std::string service_domain_name =
+ command_line_reader::ReadDomainName(kServiceDomainNameDefault);
+
+ ServiceParameters params(kServiceType, service_name_prefix,
+ service_domain_name, ip, port);
+
+ return dns_server_.Start(params,
+ command_line_reader::ReadTtl(kTtlDefault),
+ CreateTxt());
+}
+
PrivetHttpServer::RegistrationErrorStatus
Printer::ConfirmationToRegistrationError(
RegistrationInfo::ConfirmationState state) {
diff --git a/cloud_print/gcp20/prototype/printer.h b/cloud_print/gcp20/prototype/printer.h
index b4ee260..46a6348 100644
--- a/cloud_print/gcp20/prototype/printer.h
+++ b/cloud_print/gcp20/prototype/printer.h
@@ -132,6 +132,10 @@ class Printer : public base::SupportsWeakPtr<Printer>,
virtual void OnPrintJobDownloaded(
const cloud_print_response_parser::Job& job) OVERRIDE;
virtual void OnPrintJobDone() OVERRIDE;
+ virtual void OnLocalSettingsReceived(
+ LocalSettings::State state,
+ const LocalSettings& settings) OVERRIDE;
+ virtual void OnLocalSettingsUpdated() OVERRIDE;
// CloudPrintXmppListener::Delegate methods:
virtual void OnXmppConnected() OVERRIDE;
@@ -151,15 +155,17 @@ class Printer : public base::SupportsWeakPtr<Printer>,
// 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 Cloud Print server for printjobs.
+ void FetchPrintJobs();
- // Ask CloudPrint server for new local sendings.
+ // Ask Cloud Print server for new local sendings.
void GetLocalSettings();
- // Ask CloudPrint server for printjobs.
- void FetchPrintJobs();
+ // Applies new local settings to printer.
+ void ApplyLocalSettings(const LocalSettings& settings);
+
+ // Used for erasing all printer info.
+ void OnPrinterDeleted();
// Saves |access_token| and calculates time for next update.
void RememberAccessToken(const std::string& access_token,
@@ -199,6 +205,11 @@ class Printer : public base::SupportsWeakPtr<Printer>,
// Deletes registration expiration at all.
void InvalidateRegistrationExpiration();
+ // Methods to start HTTP and DNS-SD servers. Return |true| if servers
+ // were started.
+ bool StartHttpServer();
+ bool StartDnsServer();
+
// Converts errors.
PrivetHttpServer::RegistrationErrorStatus ConfirmationToRegistrationError(
RegistrationInfo::ConfirmationState state);
@@ -213,8 +224,13 @@ class Printer : public base::SupportsWeakPtr<Printer>,
// was changed (otherwise state was the same).
bool ChangeState(ConnectionState new_state);
+ // TODO(maksymb): Encapsulate reg_info, local_settings and other state
+ // member variables to struct.
+
RegistrationInfo reg_info_;
+ LocalSettings local_settings_;
+
// Contains DNS-SD server.
DnsSdServer dns_server_;
@@ -253,6 +269,9 @@ class Printer : public base::SupportsWeakPtr<Printer>,
// Contains |true| if Printer has to check available printjobs.
bool pending_print_jobs_check_;
+ // Contains |true| if Printer has to be deleted.
+ bool pending_deletion_;
+
DISALLOW_COPY_AND_ASSIGN(Printer);
};