0

Enable local printing via lacros-chrome

This CL introduces the LocalPrinterHandlerLacros class which
lacros-chrome uses for printing to local printers.

With it, printing to a local printer works properly in lacros although
the print preview UI used is the Linux one and does not yet incorporate
chromeos-specific changes.

Bug: b/179305359
Test: deploy_chrome --lacros --nostrip

Change-Id: I8155d48f38be2e5f44430ec5f33f40b325269d00
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2774933
Commit-Queue: Pranav Batra <batrapranav@chromium.org>
Reviewed-by: Rebekah Potter <rbpotter@chromium.org>
Reviewed-by: Alan Screen <awscreen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#879726}
This commit is contained in:
Pranav Batra
2021-05-06 07:38:38 +00:00
committed by Chromium LUCI CQ
parent f4228a4b66
commit ce12aa2728
16 changed files with 249 additions and 32 deletions

@@ -4759,6 +4759,12 @@ static_library("ui") {
"//services/device/public/mojom:usb",
]
if (is_chromeos_lacros) {
sources += [
"webui/print_preview/local_printer_handler_lacros.cc",
"webui/print_preview/local_printer_handler_lacros.h",
]
}
if (is_chromeos_ash) {
sources += [
"webui/print_preview/local_printer_handler_chromeos.cc",

@@ -0,0 +1,152 @@
// Copyright 2021 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/ui/webui/print_preview/local_printer_handler_lacros.h"
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "base/bind.h"
#include "base/logging.h"
#include "base/memory/scoped_refptr.h"
#include "base/metrics/histogram_functions.h"
#include "base/stl_util.h"
#include "base/values.h"
#include "chrome/browser/ui/webui/print_preview/print_preview_utils.h"
#include "chrome/common/printing/printer_capabilities.h"
#include "chromeos/crosapi/mojom/local_printer.mojom.h"
#include "chromeos/lacros/lacros_chrome_service_impl.h"
#include "content/public/browser/browser_thread.h"
#include "printing/backend/print_backend.h"
#include "printing/backend/print_backend_consts.h"
#include "printing/backend/printing_restrictions.h"
#include "printing/print_job_constants.h"
namespace printing {
namespace {
base::Value PrinterToValue(const crosapi::mojom::LocalDestinationInfo& p) {
base::Value value(base::Value::Type::DICTIONARY);
value.SetStringKey(kSettingDeviceName, p.device_name);
value.SetStringKey(kSettingPrinterName, p.printer_name);
value.SetStringKey(kSettingPrinterDescription, p.printer_description);
value.SetBoolKey(kCUPSEnterprisePrinter, p.configured_via_policy);
return value;
}
base::Value CapabilityToValue(crosapi::mojom::CapabilitiesResponsePtr ptr) {
if (!ptr)
return base::Value();
base::Value dict = AssemblePrinterSettings(
ptr->basic_info->device_name,
PrinterBasicInfo(
ptr->basic_info->device_name, ptr->basic_info->printer_name,
ptr->basic_info->printer_description, 0, false,
PrinterBasicInfoOptions{
{kCUPSEnterprisePrinter, ptr->basic_info->configured_via_policy
? kValueTrue
: kValueFalse}}),
PrinterSemanticCapsAndDefaults::Papers(), ptr->has_secure_protocol,
base::OptionalOrNullptr(ptr->capabilities));
base::Value policies(base::Value::Type::DICTIONARY);
policies.SetIntKey(kAllowedColorModes, ptr->allowed_color_modes);
policies.SetIntKey(kAllowedDuplexModes, ptr->allowed_duplex_modes);
policies.SetIntKey(kAllowedPinModes, ptr->allowed_pin_modes);
policies.SetIntKey(kDefaultColorMode,
static_cast<int>(ptr->default_color_mode));
policies.SetIntKey(kDefaultDuplexMode,
static_cast<int>(ptr->default_duplex_mode));
policies.SetIntKey(kDefaultPinMode, static_cast<int>(ptr->default_pin_mode));
dict.FindKey(kPrinter)->SetKey(kSettingPolicies, std::move(policies));
return dict;
}
void GetPrinters(
LocalPrinterHandlerLacros::AddedPrintersCallback callback,
LocalPrinterHandlerLacros::GetPrintersDoneCallback done_callback,
std::vector<crosapi::mojom::LocalDestinationInfoPtr> printers) {
if (printers.size()) {
base::ListValue list;
for (const crosapi::mojom::LocalDestinationInfoPtr& p : printers) {
// There is an implicit DCHECK(p) here.
list.Append(PrinterToValue(*p));
}
std::move(callback).Run(std::move(list));
}
std::move(done_callback).Run();
}
} // namespace
// static
std::unique_ptr<LocalPrinterHandlerLacros>
LocalPrinterHandlerLacros::CreateDefault(
content::WebContents* preview_web_contents) {
return base::WrapUnique(new LocalPrinterHandlerLacros(preview_web_contents));
}
LocalPrinterHandlerLacros::LocalPrinterHandlerLacros(
content::WebContents* preview_web_contents)
: preview_web_contents_(preview_web_contents),
service_(chromeos::LacrosChromeServiceImpl::Get()) {}
LocalPrinterHandlerLacros::~LocalPrinterHandlerLacros() = default;
void LocalPrinterHandlerLacros::Reset() {}
void LocalPrinterHandlerLacros::GetDefaultPrinter(
DefaultPrinterCallback callback) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
if (!service_->IsAvailable<crosapi::mojom::LocalPrinter>()) {
LOG(ERROR) << "Local printer not available";
std::move(callback).Run(std::string());
return;
}
// TODO(b/172229329): Add default printers to ChromeOS.
std::move(callback).Run(std::string());
}
void LocalPrinterHandlerLacros::StartGetPrinters(
AddedPrintersCallback callback,
GetPrintersDoneCallback done_callback) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
if (!service_->IsAvailable<crosapi::mojom::LocalPrinter>()) {
LOG(ERROR) << "Local printer not available";
std::move(done_callback).Run();
return;
}
service_->GetRemote<crosapi::mojom::LocalPrinter>()->GetPrinters(
base::BindOnce(GetPrinters, std::move(callback),
std::move(done_callback)));
}
void LocalPrinterHandlerLacros::StartGetCapability(
const std::string& device_name,
GetCapabilityCallback callback) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
if (!service_->IsAvailable<crosapi::mojom::LocalPrinter>()) {
LOG(ERROR) << "Local printer not available";
std::move(callback).Run(base::Value());
return;
}
service_->GetRemote<crosapi::mojom::LocalPrinter>()->GetCapability(
device_name, base::BindOnce(CapabilityToValue).Then(std::move(callback)));
}
void LocalPrinterHandlerLacros::StartPrint(
const std::u16string& job_title,
base::Value settings,
scoped_refptr<base::RefCountedMemory> print_data,
PrintCallback callback) {
size_t size_in_kb = print_data->size() / 1024;
base::UmaHistogramMemoryKB("Printing.CUPS.PrintDocumentSize", size_in_kb);
// TOOD: add support for printing.send_username_and_filename_enabled flag.
StartLocalPrint(std::move(settings), std::move(print_data),
preview_web_contents_, std::move(callback));
}
} // namespace printing

@@ -0,0 +1,52 @@
// Copyright 2021 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_UI_WEBUI_PRINT_PREVIEW_LOCAL_PRINTER_HANDLER_LACROS_H_
#define CHROME_BROWSER_UI_WEBUI_PRINT_PREVIEW_LOCAL_PRINTER_HANDLER_LACROS_H_
#include <memory>
#include <string>
#include "base/memory/scoped_refptr.h"
#include "base/values.h"
#include "chrome/browser/ui/webui/print_preview/printer_handler.h"
#include "chromeos/lacros/lacros_chrome_service_impl.h"
namespace content {
class WebContents;
}
namespace printing {
class LocalPrinterHandlerLacros : public PrinterHandler {
public:
static std::unique_ptr<LocalPrinterHandlerLacros> CreateDefault(
content::WebContents* preview_web_contents);
LocalPrinterHandlerLacros(const LocalPrinterHandlerLacros&) = delete;
LocalPrinterHandlerLacros& operator=(const LocalPrinterHandlerLacros&) =
delete;
~LocalPrinterHandlerLacros() override;
// PrinterHandler implementation.
void Reset() override;
void GetDefaultPrinter(DefaultPrinterCallback callback) override;
void StartGetPrinters(AddedPrintersCallback added_printers_callback,
GetPrintersDoneCallback done_callback) override;
void StartGetCapability(const std::string& destination_id,
GetCapabilityCallback callback) override;
void StartPrint(const std::u16string& job_title,
base::Value settings,
scoped_refptr<base::RefCountedMemory> print_data,
PrintCallback callback) override;
private:
explicit LocalPrinterHandlerLacros(
content::WebContents* preview_web_contents);
content::WebContents* const preview_web_contents_;
chromeos::LacrosChromeServiceImpl* const service_;
};
} // namespace printing
#endif // CHROME_BROWSER_UI_WEBUI_PRINT_PREVIEW_LOCAL_PRINTER_HANDLER_LACROS_H_

@@ -16,6 +16,8 @@
#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "chrome/browser/ui/webui/print_preview/local_printer_handler_chromeos.h"
#elif BUILDFLAG(IS_CHROMEOS_LACROS)
#include "chrome/browser/ui/webui/print_preview/local_printer_handler_lacros.h"
#else
#include "chrome/browser/ui/webui/print_preview/local_printer_handler_default.h"
#endif
@@ -35,6 +37,8 @@ std::unique_ptr<PrinterHandler> PrinterHandler::CreateForLocalPrinters(
#if BUILDFLAG(IS_CHROMEOS_ASH)
return LocalPrinterHandlerChromeos::CreateDefault(profile,
preview_web_contents);
#elif BUILDFLAG(IS_CHROMEOS_LACROS)
return LocalPrinterHandlerLacros::CreateDefault(preview_web_contents);
#else
return std::make_unique<LocalPrinterHandlerDefault>(preview_web_contents);
#endif

@@ -40,7 +40,7 @@ component("printing_base") {
"units.cc",
"units.h",
]
if (use_cups_ipp || is_chromeos_ash) {
if (use_cups_ipp || is_chromeos) {
sources += [
"printer_query_result.h",
"printer_status.cc",
@@ -146,7 +146,7 @@ component("printing") {
]
}
if (is_chromeos_ash) {
if (is_chromeos) {
sources += [
"printed_document_chromeos.cc",
"printing_context_no_system_dialog.cc",
@@ -154,7 +154,7 @@ component("printing") {
]
}
if (is_linux || is_chromeos_lacros) {
if (is_linux) {
sources += [
"printed_document_linux.cc",
"printing_context_linux.cc",
@@ -205,7 +205,7 @@ component("printing") {
if (use_cups) {
configs += [ ":cups" ]
if (is_chromeos_ash) {
if (is_chromeos) {
sources += [
"printing_context_chromeos.cc",
"printing_context_chromeos.h",
@@ -319,9 +319,11 @@ test("printing_unittests") {
sources += [ "backend/cups_ipp_helper_unittest.cc" ]
}
if (is_chromeos_ash) {
if (is_chromeos) {
sources += [ "printing_context_chromeos_unittest.cc" ]
} else {
}
if (!is_chromeos_ash) {
sources += [
"backend/cups_helper_unittest.cc",
"backend/print_backend_cups_unittest.cc",

@@ -4,11 +4,9 @@
import("//build/config/chromeos/ui_mode.gni")
import("//printing/buildflags/buildflags.gni")
if (use_cups && is_chromeos_ash) {
if (use_cups && is_chromeos) {
import("//printing/backend/tools/code_generator.gni")
}
if (use_cups_ipp && is_chromeos_ash) {
ipp_handler_map_path = "$target_gen_dir/backend/ipp_handler_map.cc"
ipp_code_generate("ipp_handlers_generate") {
@@ -48,7 +46,7 @@ component("backend") {
"//url",
]
if (is_chromeos_ash) {
if (is_chromeos) {
# PRINT_BACKEND_AVAILABLE disables the default dummy implementation
# print backend and enables a custom implementation instead.
defines += [ "PRINT_BACKEND_AVAILABLE" ]
@@ -110,7 +108,7 @@ component("backend") {
]
}
if (is_chromeos_ash) {
if (is_chromeos) {
deps += [ ":ipp_handlers_generate" ]
sources += [
@@ -119,7 +117,8 @@ component("backend") {
"ipp_handlers.h",
ipp_handler_map_path,
]
} else {
}
if (!is_chromeos_ash) {
# TODO(crbug.com/1062136): Remove the original CUPS backend for macOS
# when Cloud Print support is terminated. Follow up after Jan 1, 2021.
sources += [

@@ -24,7 +24,7 @@ constexpr char kIppPinEncryption[] = "job-password-encryption"; // PWG 5100.11
constexpr char kCollated[] = "separate-documents-collated-copies";
constexpr char kUncollated[] = "separate-documents-uncollated-copies";
#if BUILDFLAG(IS_CHROMEOS_ASH)
#if defined(OS_CHROMEOS)
constexpr char kIppDocumentAttributes[] =
"document-creation-attributes"; // PWG 5100.5
@@ -35,6 +35,6 @@ constexpr char kPinEncryptionNone[] = "none";
constexpr char kOptionFalse[] = "false";
constexpr char kOptionTrue[] = "true";
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
#endif // defined(OS_CHROMEOS)
} // namespace printing

@@ -25,7 +25,7 @@ COMPONENT_EXPORT(PRINT_BACKEND) extern const char kIppPinEncryption[];
COMPONENT_EXPORT(PRINT_BACKEND) extern const char kCollated[];
COMPONENT_EXPORT(PRINT_BACKEND) extern const char kUncollated[];
#if BUILDFLAG(IS_CHROMEOS_ASH)
#if defined(OS_CHROMEOS)
COMPONENT_EXPORT(PRINT_BACKEND) extern const char kIppDocumentAttributes[];
COMPONENT_EXPORT(PRINT_BACKEND) extern const char kIppJobAttributes[];
@@ -35,7 +35,7 @@ COMPONENT_EXPORT(PRINT_BACKEND) extern const char kPinEncryptionNone[];
COMPONENT_EXPORT(PRINT_BACKEND) extern const char kOptionFalse[];
COMPONENT_EXPORT(PRINT_BACKEND) extern const char kOptionTrue[];
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
#endif // defined(OS_CHROMEOS)
} // namespace printing

@@ -240,6 +240,7 @@ bool PrintBackendCUPS::IsValidPrinter(const std::string& printer_name) {
return !!GetNamedDest(printer_name);
}
#if !defined(OS_CHROMEOS)
scoped_refptr<PrintBackend> PrintBackend::CreateInstanceImpl(
const base::DictionaryValue* print_backend_settings,
const std::string& locale,
@@ -266,6 +267,7 @@ scoped_refptr<PrintBackend> PrintBackend::CreateInstanceImpl(
print_server_url, static_cast<http_encryption_t>(encryption),
cups_blocking == kValueTrue, locale);
}
#endif // !defined(OS_CHROMEOS)
int PrintBackendCUPS::GetDests(cups_dest_t** dests) {
// Default to the local print server (CUPS scheduler)

@@ -8,14 +8,14 @@
namespace printing {
#if BUILDFLAG(IS_CHROMEOS_ASH)
#if defined(OS_CHROMEOS)
const char kAllowedColorModes[] = "allowedColorModes";
const char kAllowedDuplexModes[] = "allowedDuplexModes";
const char kAllowedPinModes[] = "allowedPinModes";
const char kDefaultColorMode[] = "defaultColorMode";
const char kDefaultDuplexMode[] = "defaultDuplexMode";
const char kDefaultPinMode[] = "defaultPinMode";
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
#endif // defined(OS_CHROMEOS)
const char kPaperSizeName[] = "name";
const char kPaperSizeNameCustomOption[] = "custom";

@@ -8,13 +8,13 @@
#include "base/component_export.h"
#include "build/chromeos_buildflags.h"
#if BUILDFLAG(IS_CHROMEOS_ASH)
#if defined(OS_CHROMEOS)
#include "printing/mojom/print.mojom.h"
#endif
namespace printing {
#if BUILDFLAG(IS_CHROMEOS_ASH)
#if defined(OS_CHROMEOS)
// Allowed printing modes as a bitmask.
// This is used in pref file and should never change.
using ColorModeRestriction = mojom::ColorModeRestriction;
@@ -36,7 +36,7 @@ COMPONENT_EXPORT(PRINT_BACKEND) extern const char kAllowedPinModes[];
COMPONENT_EXPORT(PRINT_BACKEND) extern const char kDefaultColorMode[];
COMPONENT_EXPORT(PRINT_BACKEND) extern const char kDefaultDuplexMode[];
COMPONENT_EXPORT(PRINT_BACKEND) extern const char kDefaultPinMode[];
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
#endif // defined(OS_CHROMEOS)
// Allowed background graphics modes.
// This is used in pref file and should never change.

@@ -32,5 +32,5 @@ declare_args() {
declare_args() {
# Enable the CUPS IPP printing backend.
# TODO(crbug.com/226176): Remove this after CUPS PPD API calls are removed.
use_cups_ipp = use_cups && !(is_linux || is_chromeos_lacros)
use_cups_ipp = use_cups && !is_linux
}

@@ -10,7 +10,7 @@
#include "build/chromeos_buildflags.h"
#include "printing/units.h"
#if defined(USE_CUPS) && (defined(OS_MAC) || BUILDFLAG(IS_CHROMEOS_ASH))
#if defined(USE_CUPS) && (defined(OS_MAC) || defined(OS_CHROMEOS))
#include <cups/cups.h>
#endif
@@ -183,7 +183,7 @@ void GetColorModelForModel(mojom::ColorModel color_model,
// all ColorModel values are determinantly handled.
}
#if defined(OS_MAC) || BUILDFLAG(IS_CHROMEOS_ASH)
#if defined(OS_MAC) || defined(OS_CHROMEOS)
std::string GetIppColorModelForModel(mojom::ColorModel color_model) {
// Accept `kUnknownColorModel` for consistency with GetColorModelForModel().
if (color_model == mojom::ColorModel::kUnknownColorModel)
@@ -198,7 +198,7 @@ std::string GetIppColorModelForModel(mojom::ColorModel color_model) {
return is_color.value() ? CUPS_PRINT_COLOR_MODE_COLOR
: CUPS_PRINT_COLOR_MODE_MONOCHROME;
}
#endif // defined(OS_MAC) || BUILDFLAG(IS_CHROMEOS_ASH)
#endif // defined(OS_MAC) || defined(OS_CHROMEOS)
#endif // defined(USE_CUPS)
base::Optional<bool> IsColorModelSelected(mojom::ColorModel color_model) {
@@ -281,11 +281,11 @@ void PrintSettings::Clear() {
#if defined(OS_LINUX) || defined(OS_CHROMEOS)
advanced_settings_.clear();
#endif // defined(OS_LINUX) || defined(OS_CHROMEOS)
#if BUILDFLAG(IS_CHROMEOS_ASH)
#if defined(OS_CHROMEOS)
send_user_info_ = false;
username_.clear();
pin_value_.clear();
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
#endif // defined(OS_CHROMEOS)
}
void PrintSettings::SetPrinterPrintableArea(

@@ -45,7 +45,7 @@ void GetColorModelForModel(mojom::ColorModel color_model,
std::string* color_setting_name,
std::string* color_value);
#if defined(OS_MAC) || BUILDFLAG(IS_CHROMEOS_ASH)
#if defined(OS_MAC) || defined(OS_CHROMEOS)
// Convert from `color_model` to a print-color-mode value from PWG 5100.13.
COMPONENT_EXPORT(PRINTING)
std::string GetIppColorModelForModel(mojom::ColorModel color_model);
@@ -230,7 +230,7 @@ class COMPONENT_EXPORT(PRINTING) PrintSettings {
}
#endif // defined(OS_LINUX) || defined(OS_CHROMEOS)
#if BUILDFLAG(IS_CHROMEOS_ASH)
#if defined(OS_CHROMEOS)
void set_send_user_info(bool send_user_info) {
send_user_info_ = send_user_info;
}
@@ -327,7 +327,7 @@ class COMPONENT_EXPORT(PRINTING) PrintSettings {
AdvancedSettings advanced_settings_;
#endif // defined(OS_LINUX) || defined(OS_CHROMEOS)
#if BUILDFLAG(IS_CHROMEOS_ASH)
#if defined(OS_CHROMEOS)
// Whether to send user info.
bool send_user_info_;

@@ -146,7 +146,7 @@ PrintingContext::Result PrintingContext::UpdatePrintSettings(
job_settings.FindIntKey(kSettingPreviewPageCount).value_or(0));
}
#if BUILDFLAG(IS_CHROMEOS_ASH)
#if defined(OS_CHROMEOS)
PrintingContext::Result PrintingContext::UpdatePrintSettingsFromPOD(
std::unique_ptr<PrintSettings> job_settings) {
ResetSettings();

@@ -86,7 +86,7 @@ class COMPONENT_EXPORT(PRINTING) PrintingContext {
// settings information.
Result UpdatePrintSettings(base::Value job_settings);
#if BUILDFLAG(IS_CHROMEOS_ASH)
#if defined(OS_CHROMEOS)
// Updates Print Settings.
Result UpdatePrintSettingsFromPOD(
std::unique_ptr<PrintSettings> job_settings);