diff options
author | maksymb@chromium.org <maksymb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-16 10:22:58 +0000 |
---|---|---|
committer | maksymb@chromium.org <maksymb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-16 10:22:58 +0000 |
commit | b2d467cc630c6c0c9c8d004e610c704bb8ac07b9 (patch) | |
tree | 85fb288f9f7114eddc69da17cf31bf36f121a683 /cloud_print | |
parent | 3371e50258c7966c4f0c9570c9e18d78305ba0b9 (diff) | |
download | chromium_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.cc | 94 | ||||
-rw-r--r-- | cloud_print/gcp20/prototype/cloud_print_requester.h | 26 | ||||
-rw-r--r-- | cloud_print/gcp20/prototype/cloud_print_response_parser.cc | 71 | ||||
-rw-r--r-- | cloud_print/gcp20/prototype/cloud_print_response_parser.h | 17 | ||||
-rw-r--r-- | cloud_print/gcp20/prototype/cloud_print_xmpp_listener.cc | 4 | ||||
-rw-r--r-- | cloud_print/gcp20/prototype/cloud_print_xmpp_listener.h | 2 | ||||
-rw-r--r-- | cloud_print/gcp20/prototype/gcp20_device.gyp | 1 | ||||
-rw-r--r-- | cloud_print/gcp20/prototype/local_settings.h | 31 | ||||
-rw-r--r-- | cloud_print/gcp20/prototype/printer.cc | 191 | ||||
-rw-r--r-- | cloud_print/gcp20/prototype/printer.h | 31 |
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", ¤t)) { + *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); }; |