Commit d96dd555 authored by skau's avatar skau Committed by Commit bot

Interrogate PpdProvider from PrintPreview.

Make use of the PpdCache from PrintPreview.  Setup downloading ppds from
the quirks server.

BUG=662755
TEST=Setup a printer.  Log out.  Rename ppd file.  Open printer from print
preview.

Review-Url: https://codereview.chromium.org/2542363002
Cr-Commit-Position: refs/heads/master@{#437718}
parent 26309371
......@@ -1152,6 +1152,8 @@ source_set("chromeos") {
"printing/cups_print_job_notification_manager.h",
"printing/fake_cups_print_job_manager.cc",
"printing/fake_cups_print_job_manager.h",
"printing/ppd_provider_factory.cc",
"printing/ppd_provider_factory.h",
"printing/printer_pref_manager.cc",
"printing/printer_pref_manager.h",
"printing/printer_pref_manager_factory.cc",
......
// Copyright 2016 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 "chrome/browser/chromeos/printing/ppd_provider_factory.h"
#include <memory>
#include "base/files/file_path.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profiles/profile.h"
#include "chromeos/printing/ppd_cache.h"
#include "chromeos/printing/ppd_provider.h"
#include "content/public/browser/browser_thread.h"
#include "google_apis/google_api_keys.h"
#include "net/url_request/url_request_context_getter.h"
namespace chromeos {
namespace printing {
std::unique_ptr<PpdProvider> CreateProvider(Profile* profile) {
base::FilePath ppd_cache_path =
profile->GetPath().Append(FILE_PATH_LITERAL("PPDCache"));
return PpdProvider::Create(google_apis::GetAPIKey(),
g_browser_process->system_request_context(),
content::BrowserThread::GetTaskRunnerForThread(
content::BrowserThread::FILE),
PpdCache::Create(ppd_cache_path));
}
} // namespace printing
} // namespace chromeos
// Copyright 2016 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 CHROME_BROWSER_CHROMEOS_PRINTING_PPD_PROVIDER_FACTORY_H_
#define CHROME_BROWSER_CHROMEOS_PRINTING_PPD_PROVIDER_FACTORY_H_
#include <memory>
class Profile;
namespace chromeos {
namespace printing {
class PpdProvider;
std::unique_ptr<PpdProvider> CreateProvider(Profile* profile);
} // namespace printing
} // namsepace chromeos
#endif // CHROME_BROWSER_CHROMEOS_PRINTING_PPD_PROVIDER_FACTORY_H_
......@@ -518,7 +518,8 @@ PrintPreviewHandler::PrintPreviewHandler()
manage_cloud_printers_dialog_request_count_(0),
reported_failed_preview_(false),
has_logged_printers_count_(false),
gaia_cookie_manager_service_(NULL),
gaia_cookie_manager_service_(nullptr),
printer_backend_proxy_(nullptr),
weak_factory_(this) {
ReportUserActionHistogram(PREVIEW_STARTED);
}
......@@ -611,11 +612,27 @@ PrintPreviewUI* PrintPreviewHandler::print_preview_ui() const {
return static_cast<PrintPreviewUI*>(web_ui()->GetController());
}
printing::PrinterBackendProxy* PrintPreviewHandler::printer_backend_proxy() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (!printer_backend_proxy_) {
#if defined(OS_CHROMEOS)
// ChromeOS stores printer information in printer prefs which requires a
// profile. Other plaforms retrieve printer information from OS resources.
printer_backend_proxy_ =
printing::PrinterBackendProxy::Create(Profile::FromWebUI(web_ui()));
#else
printer_backend_proxy_ = printing::PrinterBackendProxy::Create();
#endif
}
return printer_backend_proxy_.get();
}
void PrintPreviewHandler::HandleGetPrinters(const base::ListValue* /*args*/) {
VLOG(1) << "Enumerate printers start";
printing::EnumeratePrinters(Profile::FromWebUI(web_ui()),
base::Bind(&PrintPreviewHandler::SetupPrinterList,
weak_factory_.GetWeakPtr()));
printer_backend_proxy()->EnumeratePrinters(base::Bind(
&PrintPreviewHandler::SetupPrinterList, weak_factory_.GetWeakPtr()));
}
void PrintPreviewHandler::HandleGetPrivetPrinters(const base::ListValue* args) {
......@@ -1029,8 +1046,8 @@ void PrintPreviewHandler::HandleGetPrinterCapabilities(
base::Bind(&PrintPreviewHandler::SendPrinterCapabilities,
weak_factory_.GetWeakPtr(), printer_name);
printing::ConfigurePrinterAndFetchCapabilities(Profile::FromWebUI(web_ui()),
printer_name, cb);
printer_backend_proxy()->ConfigurePrinterAndFetchCapabilities(printer_name,
cb);
}
void PrintPreviewHandler::OnSigninComplete() {
......@@ -1152,11 +1169,8 @@ void PrintPreviewHandler::HandleGetInitialSettings(
const base::ListValue* /*args*/) {
// Send before SendInitialSettings() to allow cloud printer auto select.
SendCloudPrintEnabled();
base::PostTaskAndReplyWithResult(
BrowserThread::GetBlockingPool(), FROM_HERE,
base::Bind(&printing::GetDefaultPrinterOnBlockingPoolThread),
base::Bind(&PrintPreviewHandler::SendInitialSettings,
weak_factory_.GetWeakPtr()));
printer_backend_proxy()->GetDefaultPrinter(base::Bind(
&PrintPreviewHandler::SendInitialSettings, weak_factory_.GetWeakPtr()));
}
void PrintPreviewHandler::HandleForceOpenNewTab(const base::ListValue* args) {
......
......@@ -41,6 +41,10 @@ namespace gfx {
class Size;
}
namespace printing {
class PrinterBackendProxy;
}
// The handler for Javascript messages related to the print preview dialog.
class PrintPreviewHandler
: public content::WebUIMessageHandler,
......@@ -111,6 +115,8 @@ class PrintPreviewHandler
PrintPreviewUI* print_preview_ui() const;
printing::PrinterBackendProxy* printer_backend_proxy();
// Gets the list of printers. |args| is unused.
void HandleGetPrinters(const base::ListValue* args);
......@@ -380,6 +386,10 @@ class PrintPreviewHandler
// notify the test if it was a successful save, only that it was attempted.
base::Closure pdf_file_saved_closure_;
// Proxy for calls to the print backend. Lazily initialized since web_ui() is
// not available at construction time.
std::unique_ptr<printing::PrinterBackendProxy> printer_backend_proxy_;
base::WeakPtrFactory<PrintPreviewHandler> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(PrintPreviewHandler);
......
......@@ -52,8 +52,6 @@ std::unique_ptr<base::DictionaryValue> FetchCapabilitiesOnBlockingPool(
return GetSettingsOnBlockingPool(device_name, basic_info);
}
} // namespace
std::string GetDefaultPrinterOnBlockingPoolThread() {
DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
......@@ -65,21 +63,50 @@ std::string GetDefaultPrinterOnBlockingPoolThread() {
return default_printer;
}
void EnumeratePrinters(Profile* /* profile */,
const EnumeratePrintersCallback& cb) {
// Default implementation of PrinterBackendProxy. Makes calls directly to
// the print backend on the appropriate thread.
class PrinterBackendProxyDefault : public PrinterBackendProxy {
public:
PrinterBackendProxyDefault() {}
~PrinterBackendProxyDefault() override {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
}
void GetDefaultPrinter(const DefaultPrinterCallback& cb) override {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
base::PostTaskAndReplyWithResult(
content::BrowserThread::GetBlockingPool(), FROM_HERE,
base::Bind(&GetDefaultPrinterOnBlockingPoolThread), cb);
}
void EnumeratePrinters(const EnumeratePrintersCallback& cb) override {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
base::PostTaskAndReplyWithResult(
content::BrowserThread::GetBlockingPool(), FROM_HERE,
base::Bind(&EnumeratePrintersOnBlockingPoolThread), cb);
}
}
void ConfigurePrinterAndFetchCapabilities(Profile* /* profile */,
void ConfigurePrinterAndFetchCapabilities(
const std::string& device_name,
const PrinterSetupCallback& cb) {
const PrinterSetupCallback& cb) override {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
base::PostTaskAndReplyWithResult(
content::BrowserThread::GetBlockingPool(), FROM_HERE,
base::Bind(&FetchCapabilitiesOnBlockingPool, device_name), cb);
}
private:
DISALLOW_COPY_AND_ASSIGN(PrinterBackendProxyDefault);
};
} // namespace
std::unique_ptr<PrinterBackendProxy> PrinterBackendProxy::Create() {
return base::MakeUnique<PrinterBackendProxyDefault>();
}
} // namespace printing
......@@ -12,28 +12,45 @@
#include "base/values.h"
#include "printing/backend/print_backend.h"
#if defined(OS_CHROMEOS)
class Profile;
#endif
namespace printing {
using DefaultPrinterCallback =
base::Callback<void(const std::string& printer_name)>;
using EnumeratePrintersCallback = base::Callback<void(const PrinterList&)>;
using PrinterSetupCallback =
base::Callback<void(std::unique_ptr<base::DictionaryValue>)>;
// Returns the name of the default printer.
std::string GetDefaultPrinterOnBlockingPoolThread();
// Retrieves printers for display in the print dialog and calls |cb| with the
// list. This method expects to be called on the UI thread.
void EnumeratePrinters(Profile* profile, const EnumeratePrintersCallback& cb);
// Verifies printer setup if needed then retrieves printer capabilities for
// |printer_name|. |cb| is called with the capabilities dictionary or nullptr
// if one of the steps failed.
void ConfigurePrinterAndFetchCapabilities(Profile* profile,
base::Callback<void(std::unique_ptr<base::DictionaryValue> settings)>;
class PrinterBackendProxy {
public:
#if defined(OS_CHROMEOS)
static std::unique_ptr<PrinterBackendProxy> Create(Profile* profile);
#else
static std::unique_ptr<PrinterBackendProxy> Create();
#endif
virtual ~PrinterBackendProxy() = default;
// Returns the name of the default printer through |cb|. This method expects
// to be called on the UI thread.
virtual void GetDefaultPrinter(const DefaultPrinterCallback& cb) = 0;
// Retrieves printers for display in the print dialog and calls |cb| with the
// list. This method expects to be called on the UI thread.
virtual void EnumeratePrinters(const EnumeratePrintersCallback& cb) = 0;
// Verifies printer setup if needed then retrieves printer capabilities for
// |printer_name|. |cb| is called with the capabilities dictionary or nullptr
// if one of the steps failed.
virtual void ConfigurePrinterAndFetchCapabilities(
const std::string& printer_name,
const PrinterSetupCallback& cb);
const PrinterSetupCallback& cb) = 0;
};
} // namespace printing
......
......@@ -12,6 +12,7 @@
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/values.h"
#include "chrome/browser/chromeos/printing/ppd_provider_factory.h"
#include "chrome/browser/chromeos/printing/printer_pref_manager.h"
#include "chrome/browser/chromeos/printing/printer_pref_manager_factory.h"
#include "chrome/browser/profiles/profile.h"
......@@ -19,6 +20,7 @@
#include "chrome/common/chrome_switches.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/debug_daemon_client.h"
#include "chromeos/printing/ppd_provider.h"
#include "chromeos/printing/printer_configuration.h"
#include "content/public/browser/browser_thread.h"
#include "printing/backend/print_backend_consts.h"
......@@ -44,6 +46,14 @@ printing::PrinterBasicInfo ToBasicInfo(const chromeos::Printer& printer) {
return basic_info;
}
void AddPrintersToList(
const std::vector<std::unique_ptr<chromeos::Printer>>& printers,
PrinterList* list) {
for (const auto& printer : printers) {
list->push_back(ToBasicInfo(*printer));
}
}
void FetchCapabilities(std::unique_ptr<chromeos::Printer> printer,
const PrinterSetupCallback& cb) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
......@@ -66,7 +76,7 @@ void HandlePrinterSetup(std::unique_ptr<chromeos::Printer> printer,
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
if (result != SetupResult::SUCCESS) {
LOG(WARNING) << "Print setup failed";
LOG(WARNING) << "Print setup failed: " << result;
// TODO(skau): Open printer settings if this is resolvable.
PostCallbackError(cb);
return;
......@@ -96,20 +106,60 @@ void OnPrinterAddError(const PrinterSetupCallback& cb) {
PostCallbackError(cb);
}
std::string GetPPDPath(const chromeos::Printer& printer) {
// TODO(skau): Consult the PPD Provider for the correct file path.
return printer.ppd_reference().user_supplied_ppd_url;
void AddPrinter(std::unique_ptr<chromeos::Printer> printer,
const std::string& ppd_path,
bool ipp_everywhere,
const PrinterSetupCallback& cb) {
// Always push configuration to CUPS. It may need an update.
const std::string printer_name = printer->id();
const std::string printer_uri = printer->uri();
chromeos::DBusThreadManager::Get()->GetDebugDaemonClient()->CupsAddPrinter(
printer_name, printer_uri, ppd_path, ipp_everywhere,
base::Bind(&OnPrinterAddResult, base::Passed(&printer), cb),
base::Bind(&OnPrinterAddError, cb));
}
} // namespace
void PPDResolve(std::unique_ptr<chromeos::Printer> printer,
const PrinterSetupCallback& cb,
chromeos::printing::PpdProvider::CallbackResultCode result,
base::FilePath path) {
switch (result) {
case chromeos::printing::PpdProvider::SUCCESS: {
DCHECK(!path.empty());
AddPrinter(std::move(printer), path.value() /* ppd path */,
false /* non-ipp-everywhere */, cb);
break;
}
case chromeos::printing::PpdProvider::NOT_FOUND:
HandlePrinterSetup(std::move(printer), PPD_NOT_FOUND, cb);
break;
default:
HandlePrinterSetup(std::move(printer), FAILURE, cb);
break;
}
}
std::string GetDefaultPrinterOnBlockingPoolThread() {
DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
class PrinterBackendProxyChromeos : public PrinterBackendProxy {
public:
explicit PrinterBackendProxyChromeos(Profile* profile) {
prefs_ = chromeos::PrinterPrefManagerFactory::GetForBrowserContext(profile);
ppd_provider_ = chromeos::printing::CreateProvider(profile);
}
~PrinterBackendProxyChromeos() override {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
}
void GetDefaultPrinter(const DefaultPrinterCallback& cb) override {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
// TODO(crbug.com/660898): Add default printers to ChromeOS.
return "";
}
void EnumeratePrinters(Profile* profile, const EnumeratePrintersCallback& cb) {
content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
base::Bind(cb, ""));
};
void EnumeratePrinters(const EnumeratePrintersCallback& cb) override {
// PrinterPrefManager is not thread safe and must be called from the UI
// thread.
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
......@@ -118,41 +168,52 @@ void EnumeratePrinters(Profile* profile, const EnumeratePrintersCallback& cb) {
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableNativeCups)) {
chromeos::PrinterPrefManager* prefs =
chromeos::PrinterPrefManagerFactory::GetForBrowserContext(profile);
std::vector<std::unique_ptr<chromeos::Printer>> printers =
prefs->GetPrinters();
for (const std::unique_ptr<chromeos::Printer>& printer : printers) {
printer_list.push_back(ToBasicInfo(*printer));
}
AddPrintersToList(prefs_->GetPrinters(), &printer_list);
}
cb.Run(printer_list);
}
content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
base::Bind(cb, printer_list));
};
void ConfigurePrinterAndFetchCapabilities(Profile* profile,
void ConfigurePrinterAndFetchCapabilities(
const std::string& printer_name,
const PrinterSetupCallback& cb) {
const PrinterSetupCallback& cb) override {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
chromeos::PrinterPrefManager* prefs =
chromeos::PrinterPrefManagerFactory::GetForBrowserContext(profile);
std::unique_ptr<chromeos::Printer> printer = prefs->GetPrinter(printer_name);
std::unique_ptr<chromeos::Printer> printer =
prefs_->GetPrinter(printer_name);
if (!printer) {
// If the printer was removed, the lookup will fail.
content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
base::Bind(cb, nullptr));
return;
}
// Check if configuration is viable.
bool ipp_everywhere = printer->IsIppEverywhere();
std::string ppd_path = GetPPDPath(*printer);
if (!ipp_everywhere && ppd_path.empty()) {
HandlePrinterSetup(std::move(printer), PPD_NOT_FOUND, cb);
if (printer->IsIppEverywhere()) {
// ChromeOS registers printer by GUID rather than display name.
AddPrinter(std::move(printer), "" /* empty ppd path */,
true /* ipp everywhere */, cb);
return;
}
// Always push configuration to CUPS. It may need an update.
std::string printer_uri = printer->uri();
chromeos::DBusThreadManager::Get()->GetDebugDaemonClient()->CupsAddPrinter(
printer_name, printer_uri, ppd_path, ipp_everywhere,
base::Bind(&OnPrinterAddResult, base::Passed(&printer), cb),
base::Bind(&OnPrinterAddError, cb));
// Ref taken because printer is moved.
const chromeos::Printer::PpdReference& ppd_ref = printer->ppd_reference();
ppd_provider_->Resolve(ppd_ref,
base::Bind(&PPDResolve, base::Passed(&printer), cb));
};
private:
chromeos::PrinterPrefManager* prefs_;
std::unique_ptr<chromeos::printing::PpdProvider> ppd_provider_;
DISALLOW_COPY_AND_ASSIGN(PrinterBackendProxyChromeos);
};
} // namespace
std::unique_ptr<PrinterBackendProxy> PrinterBackendProxy::Create(
Profile* profile) {
return base::MakeUnique<PrinterBackendProxyChromeos>(profile);
}
} // namespace printing
......@@ -15,6 +15,7 @@
#include "base/threading/sequenced_task_runner_handle.h"
#include "base/values.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/printing/ppd_provider_factory.h"
#include "chrome/browser/chromeos/printing/printer_pref_manager_factory.h"
#include "chrome/browser/download/download_prefs.h"
#include "chrome/browser/profiles/profile.h"
......@@ -80,13 +81,7 @@ CupsPrintersHandler::CupsPrintersHandler(content::WebUI* webui)
: printer_discoverer_(nullptr),
profile_(Profile::FromWebUI(webui)),
weak_factory_(this) {
base::FilePath ppd_cache_path =
profile_->GetPath().Append(FILE_PATH_LITERAL("PPDCache"));
ppd_provider_ = chromeos::printing::PpdProvider::Create(
google_apis::GetAPIKey(), g_browser_process->system_request_context(),
content::BrowserThread::GetTaskRunnerForThread(
content::BrowserThread::FILE),
chromeos::printing::PpdCache::Create(ppd_cache_path));
ppd_provider_ = printing::CreateProvider(profile_);
}
CupsPrintersHandler::~CupsPrintersHandler() {}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment