Commit c15aea67 authored by Alan Screen's avatar Alan Screen Committed by Chromium LUCI CQ

Add FetchCapabilities to print backend service

Incorporate support for retrieving a printer's basic info, user defined
papers, and semantic capabilities and defaults from the utility service.
This combined collection of information is needed when preparing for
print preview, so it reduces overhead and latency to enable these to all
be collected with one mojom call instead of needing a chain of calls to
assemble the data.

Bug: 809738
Change-Id: I75518dca30f0113cadc7971ba2a87658aca7176b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2578698Reviewed-by: default avatarEmily Stark <estark@chromium.org>
Reviewed-by: default avatarRebekah Potter <rbpotter@chromium.org>
Reviewed-by: default avatarGabriel Charette <gab@chromium.org>
Reviewed-by: default avatarDaniel Hosseinian <dhoss@chromium.org>
Commit-Queue: Alan Screen <awscreen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#841347}
parent 32e6258a
......@@ -11,6 +11,7 @@
#include "base/location.h"
#include "base/macros.h"
#include "base/threading/hang_watcher.h"
#include "build/build_config.h"
// -----------------------------------------------------------------------------
// Usage documentation
......@@ -228,6 +229,9 @@ class ScopedIPCSupport;
}
namespace printing {
class LocalPrinterHandlerDefault;
#if defined(OS_MAC)
class PrintBackendServiceImpl;
#endif
class PrintJobWorker;
class PrinterQuery;
}
......@@ -399,6 +403,9 @@ class BASE_EXPORT ScopedAllowBlocking {
friend class module_installer::ScopedAllowModulePakLoad;
friend class mojo::CoreLibraryInitializer;
friend class printing::LocalPrinterHandlerDefault;
#if defined(OS_MAC)
friend class printing::PrintBackendServiceImpl;
#endif
friend class printing::PrintJobWorker;
friend class resource_coordinator::TabManagerDelegate; // crbug.com/778703
friend class web::WebSubThread;
......
......@@ -110,6 +110,21 @@ class PrintBackendBrowserTest : public InProcessBrowserTest {
CheckForQuit();
}
void OnDidFetchCapabilities(
base::Optional<PrinterBasicInfo>* capture_printer_info,
base::Optional<PrinterSemanticCapsAndDefaults::Papers>*
capture_user_defined_papers,
base::Optional<PrinterSemanticCapsAndDefaults>* capture_printer_caps,
const base::Optional<PrinterBasicInfo>& printer_info,
const base::Optional<PrinterSemanticCapsAndDefaults::Papers>&
user_defined_papers,
const base::Optional<PrinterSemanticCapsAndDefaults>& printer_caps) {
*capture_printer_info = printer_info;
*capture_user_defined_papers = user_defined_papers;
*capture_printer_caps = printer_caps;
CheckForQuit();
}
// The following are helper functions for having a wait loop in the test and
// exit when expected messages are received. Expect to only have to wait for
// one message.
......@@ -209,4 +224,37 @@ IN_PROC_BROWSER_TEST_F(PrintBackendBrowserTest,
EXPECT_FALSE(printer_caps.has_value());
}
IN_PROC_BROWSER_TEST_F(PrintBackendBrowserTest, FetchCapabilities) {
base::Optional<PrinterBasicInfo> printer_info;
base::Optional<PrinterSemanticCapsAndDefaults::Papers> user_defined_papers;
base::Optional<PrinterSemanticCapsAndDefaults> printer_caps;
DoInitAndSetupTestData();
// Safe to use base::Unretained(this) since waiting locally on the callback
// forces a shorter lifetime than `this`.
GetPrintBackendService()->FetchCapabilities(
kDefaultPrinterName,
base::BindOnce(&PrintBackendBrowserTest::OnDidFetchCapabilities,
base::Unretained(this), &printer_info,
&user_defined_papers, &printer_caps));
WaitUntilCallbackReceived();
EXPECT_TRUE(printer_info.has_value());
EXPECT_TRUE(user_defined_papers.has_value());
EXPECT_TRUE(printer_caps.has_value());
EXPECT_TRUE(printer_info->is_default);
EXPECT_EQ(printer_caps->copies_max, kCopiesMax);
// Requesting for an invalid printer should not return capabilities.
GetPrintBackendService()->FetchCapabilities(
kInvalidPrinterName,
base::BindOnce(&PrintBackendBrowserTest::OnDidFetchCapabilities,
base::Unretained(this), &printer_info,
&user_defined_papers, &printer_caps));
WaitUntilCallbackReceived();
EXPECT_FALSE(printer_info.has_value());
EXPECT_FALSE(user_defined_papers.has_value());
EXPECT_FALSE(printer_caps.has_value());
}
} // namespace printing
......@@ -10,10 +10,16 @@
#include "base/logging.h"
#include "base/notreached.h"
#include "base/optional.h"
#include "build/build_config.h"
#include "chrome/services/printing/public/mojom/print_backend_service.mojom.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "printing/backend/print_backend.h"
#if defined(OS_MAC)
#include "base/threading/thread_restrictions.h"
#include "chrome/common/printing/printer_capabilities_mac.h"
#endif
namespace printing {
PrintBackendServiceImpl::PrintBackendServiceImpl(
......@@ -58,4 +64,52 @@ void PrintBackendServiceImpl::GetPrinterSemanticCapsAndDefaults(
std::move(callback).Run(std::move(printer_caps));
}
void PrintBackendServiceImpl::FetchCapabilities(
const std::string& printer_name,
mojom::PrintBackendService::FetchCapabilitiesCallback callback) {
if (!print_backend_) {
std::move(callback).Run(base::nullopt, base::nullopt, base::nullopt);
return;
}
PrinterSemanticCapsAndDefaults::Papers user_defined_papers;
#if defined(OS_MAC)
{
// Blocking is needed here for when macOS reads paper sizes from file.
//
// Fetching capabilities in the browser process happens from the thread
// pool with the MayBlock() trait for macOS. However this call can also
// run from a utility process's main thread where blocking is not
// implicitly allowed. In order to preserve ordering, the utility process
// must process this synchronously by blocking.
//
// TODO(crbug.com/1163635): Investigate whether utility process main
// thread should be allowed to block like in-process workers are.
base::ScopedAllowBlocking allow_blocking;
user_defined_papers = GetMacCustomPaperSizes();
}
#endif
PrinterBasicInfo printer_info;
bool result =
print_backend_->GetPrinterBasicInfo(printer_name, &printer_info);
if (!result) {
DLOG(ERROR) << "GetPrinterBasicInfo failed, last error is "
<< logging::GetLastSystemErrorCode();
std::move(callback).Run(base::nullopt, base::nullopt, base::nullopt);
return;
}
PrinterSemanticCapsAndDefaults caps;
result =
print_backend_->GetPrinterSemanticCapsAndDefaults(printer_name, &caps);
if (!result) {
DLOG(ERROR) << "GetPrinterSemanticCapsAndDefaults failed, last error is "
<< logging::GetLastSystemErrorCode();
std::move(callback).Run(base::nullopt, base::nullopt, base::nullopt);
return;
}
std::move(callback).Run(std::move(printer_info),
std::move(user_defined_papers), std::move(caps));
}
} // namespace printing
......@@ -32,6 +32,10 @@ class PrintBackendServiceImpl : public mojom::PrintBackendService {
base::OnceCallback<void(const base::Optional<std::string>& printer_name)>;
using GetPrinterSemanticCapsAndDefaultsCallback = base::OnceCallback<void(
base::Optional<PrinterSemanticCapsAndDefaults> printer_caps)>;
using FetchCapabilitiesCallback = base::OnceCallback<void(
base::Optional<PrinterBasicInfo>,
base::Optional<PrinterSemanticCapsAndDefaults::Papers>,
base::Optional<PrinterSemanticCapsAndDefaults>)>;
// mojom::PrintBackendService implementation:
void Init(const std::string& locale) override;
......@@ -42,6 +46,9 @@ class PrintBackendServiceImpl : public mojom::PrintBackendService {
const std::string& printer_name,
mojom::PrintBackendService::GetPrinterSemanticCapsAndDefaultsCallback
callback) override;
void FetchCapabilities(
const std::string& printer_name,
mojom::PrintBackendService::FetchCapabilitiesCallback callback) override;
scoped_refptr<PrintBackend> print_backend_;
......
......@@ -23,4 +23,13 @@ interface PrintBackendService {
// No value provided for `printer_caps` if there is a failure.
GetPrinterSemanticCapsAndDefaults(string printer_name)
=> (PrinterSemanticCapsAndDefaults? printer_caps);
// Gets the basic info, paper sizes, and semantic capabilities and defaults
// for a specific printer.
// No value for `printer_info`, `user_defined_papers`, and `printer_caps` if
// there is a failure.
FetchCapabilities(string printer_name)
=> (PrinterBasicInfo? printer_info,
array<Paper>? user_defined_papers,
PrinterSemanticCapsAndDefaults? printer_caps);
};
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