mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 21:01:08 +00:00
Bug 1663652 part 1 - Implement combined CreateDefaultSettings and GetPaperList interface for nsPrinterBase r=emilio,mstriemer
This also changes the frontend to use this interface. This will be a bit less efficient in the general case, as it will serialize the PaperList and DefaultSettings fetches. But most of the large delays seem to occur when the print server is slow to respond, and ultimately using a single live connection for both these requests when possible (particularly with CUPS) should improve the total latency when the printer or print server is not available, or is very slow. Differential Revision: https://phabricator.services.mozilla.com/D93688
This commit is contained in:
parent
9dea4325b4
commit
1fbcb914c4
@ -24,9 +24,8 @@ async function run() {
|
||||
isnot(printer.name, "", "Printer name should never be empty.");
|
||||
|
||||
info(printer.name);
|
||||
|
||||
let paperList = await printer.paperList;
|
||||
for (let paper of paperList) {
|
||||
let printerInfo = await printer.printerInfo;
|
||||
for (let paper of printerInfo.paperList) {
|
||||
paper.QueryInterface(Ci.nsIPaper);
|
||||
|
||||
info(`${paper.name}: ${paper.width}x${paper.height}`);
|
||||
|
@ -22,7 +22,8 @@ async function run() {
|
||||
printer.QueryInterface(Ci.nsIPrinter);
|
||||
info(printer.name);
|
||||
|
||||
const settings = await printer.createDefaultSettings();
|
||||
const printerInfo = await printer.printerInfo;
|
||||
const settings = printerInfo.defaultSettings;
|
||||
settings.QueryInterface(Ci.nsIPrintSettings);
|
||||
|
||||
is(typeof settings.printerName, "string", "Printer name should be a string.");
|
||||
|
@ -981,24 +981,26 @@ var PrintSettingsViewProxy = {
|
||||
|
||||
// Await the async printer data.
|
||||
if (printerInfo.printer) {
|
||||
let basePrinterInfo;
|
||||
try {
|
||||
[
|
||||
printerInfo.supportsColor,
|
||||
printerInfo.supportsMonochrome,
|
||||
printerInfo.paperList,
|
||||
printerInfo.defaultSettings,
|
||||
basePrinterInfo,
|
||||
] = await Promise.all([
|
||||
printerInfo.printer.supportsColor,
|
||||
printerInfo.printer.supportsMonochrome,
|
||||
printerInfo.printer.paperList,
|
||||
// get a set of default settings for this printer
|
||||
printerInfo.printer.createDefaultSettings(),
|
||||
printerInfo.printer.printerInfo,
|
||||
]);
|
||||
} catch (e) {
|
||||
this.reportPrintingError("PRINTER_SETTINGS");
|
||||
throw e;
|
||||
}
|
||||
printerInfo.defaultSettings.QueryInterface(Ci.nsIPrintSettings);
|
||||
basePrinterInfo.QueryInterface(Ci.nsIPrinterInfo);
|
||||
basePrinterInfo.defaultSettings.QueryInterface(Ci.nsIPrintSettings);
|
||||
|
||||
printerInfo.paperList = basePrinterInfo.paperList;
|
||||
printerInfo.defaultSettings = basePrinterInfo.defaultSettings;
|
||||
} else if (printerName == PrintUtils.SAVE_TO_PDF_PRINTER) {
|
||||
// The Mozilla PDF pseudo-printer has no actual nsIPrinter implementation
|
||||
printerInfo.defaultSettings = PSSVC.newPrintSettings;
|
||||
|
@ -6,8 +6,7 @@
|
||||
add_task(async function testSanityCheckPaperList() {
|
||||
const mockPrinterName = "Fake Printer";
|
||||
await PrintHelper.withTestPage(async helper => {
|
||||
let printer = helper.addMockPrinter(mockPrinterName);
|
||||
printer.paperList = Promise.resolve([
|
||||
let paperList = [
|
||||
PrintHelper.createMockPaper({
|
||||
id: "regular",
|
||||
name: "Regular Paper",
|
||||
@ -18,7 +17,8 @@ add_task(async function testSanityCheckPaperList() {
|
||||
width: 720,
|
||||
height: 1224,
|
||||
}),
|
||||
]);
|
||||
];
|
||||
helper.addMockPrinter(mockPrinterName, paperList);
|
||||
await helper.startPrint();
|
||||
await helper.dispatchSettingsChange({ printerName: mockPrinterName });
|
||||
await helper.awaitAnimationFrame();
|
||||
|
@ -179,28 +179,26 @@ class PrintHelper {
|
||||
};
|
||||
}
|
||||
|
||||
addMockPrinter(name = "Mock Printer") {
|
||||
addMockPrinter(name = "Mock Printer", paperList = []) {
|
||||
let PSSVC = Cc["@mozilla.org/gfx/printsettings-service;1"].getService(
|
||||
Ci.nsIPrintSettingsService
|
||||
);
|
||||
let defaultSettings = {
|
||||
printerName: name,
|
||||
toFileName: "",
|
||||
outputFormat: Ci.nsIPrintSettings.kOutputFormatNative,
|
||||
printToFile: false,
|
||||
};
|
||||
|
||||
let defaultSettings = PSSVC.newPrintSettings;
|
||||
defaultSettings.printerName = name;
|
||||
defaultSettings.toFileName = "";
|
||||
defaultSettings.outputFormat = Ci.nsIPrintSettings.kOutputFormatNative;
|
||||
defaultSettings.printToFile = false;
|
||||
|
||||
let printer = {
|
||||
name,
|
||||
supportsColor: Promise.resolve(true),
|
||||
supportsMonochrome: Promise.resolve(true),
|
||||
paperList: Promise.resolve([]),
|
||||
createDefaultSettings: () => {
|
||||
let settings = PSSVC.newPrintSettings;
|
||||
for (let [key, value] of Object.entries(defaultSettings)) {
|
||||
settings[key] = value;
|
||||
}
|
||||
return settings;
|
||||
},
|
||||
printerInfo: Promise.resolve({
|
||||
paperList,
|
||||
defaultSettings,
|
||||
QueryInterface: ChromeUtils.generateQI([Ci.nsIPrinterInfo]),
|
||||
}),
|
||||
QueryInterface: ChromeUtils.generateQI([Ci.nsIPrinter]),
|
||||
};
|
||||
|
||||
|
@ -4,8 +4,22 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsIPaper.idl"
|
||||
#include "nsIPrintSettings.idl"
|
||||
#include "nsISupports.idl"
|
||||
|
||||
[scriptable, uuid(855ae9dd-62a4-64aa-9c60-b1078ff028f1)]
|
||||
interface nsIPrinterInfo : nsISupports
|
||||
{
|
||||
/**
|
||||
* An array of nsIPaper instances that represents the available paper sizes.
|
||||
*/
|
||||
readonly attribute Array<nsIPaper> paperList;
|
||||
/**
|
||||
* nsIPrintSettings object containing the default settings for a printer.
|
||||
*/
|
||||
readonly attribute nsIPrintSettings defaultSettings;
|
||||
};
|
||||
|
||||
[scriptable, uuid(d2dde9bb-df86-469c-bfcc-fd95a44b1db8)]
|
||||
interface nsIPrinter : nsISupports
|
||||
{
|
||||
@ -23,20 +37,12 @@ interface nsIPrinter : nsISupports
|
||||
readonly attribute AString systemName;
|
||||
|
||||
/**
|
||||
* Creates a Promise that will resolve to an nsIPrintSettings object containing
|
||||
* the default settings for this printer. For convenience, a new, mutable
|
||||
* nsIPrintSettings object is created for each call.
|
||||
* Returns a Promise that resolves to a nsIPrinterInfo.
|
||||
* This will contain the default printer settings, and the list of paper
|
||||
* sizes supported by the printer.
|
||||
*/
|
||||
[implicit_jscontext]
|
||||
Promise createDefaultSettings();
|
||||
|
||||
/**
|
||||
* Returns a Promise that resolves to an array of
|
||||
* nsIPaper instances with the list of available paper
|
||||
* sizes.
|
||||
*/
|
||||
[implicit_jscontext]
|
||||
readonly attribute Promise paperList;
|
||||
readonly attribute Promise printerInfo;
|
||||
|
||||
/**
|
||||
* Returns a Promise that resolves to true or false to indicate whether this
|
||||
|
@ -23,13 +23,55 @@ using mozilla::gfx::MarginDouble;
|
||||
// correct size.
|
||||
static constexpr double kPaperSizePointsEpsilon = 4.0;
|
||||
|
||||
void nsPrinterBase::CachePrintSettingsInitializer(
|
||||
const PrintSettingsInitializer& aInitializer) {
|
||||
if (mPrintSettingsInitializer.isNothing()) {
|
||||
mPrintSettingsInitializer.emplace(aInitializer);
|
||||
// Basic implementation of nsIPrinterInfo
|
||||
class nsPrinterInfo : public nsIPrinterInfo {
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS(nsPrinterInfo)
|
||||
NS_DECL_NSIPRINTERINFO
|
||||
nsPrinterInfo() = delete;
|
||||
nsPrinterInfo(nsPrinterBase& aPrinter,
|
||||
const nsPrinterBase::PrinterInfo& aPrinterInfo)
|
||||
: mDefaultSettings(
|
||||
CreatePlatformPrintSettings(aPrinterInfo.mDefaultSettings)) {
|
||||
mPaperList.SetCapacity(aPrinterInfo.mPaperList.Length());
|
||||
for (const PaperInfo& info : aPrinterInfo.mPaperList) {
|
||||
mPaperList.AppendElement(MakeRefPtr<nsPaper>(aPrinter, info));
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
virtual ~nsPrinterInfo() = default;
|
||||
|
||||
nsTArray<RefPtr<nsIPaper>> mPaperList;
|
||||
RefPtr<nsIPrintSettings> mDefaultSettings;
|
||||
};
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrinterInfo::GetPaperList(nsTArray<RefPtr<nsIPaper>>& aPaperList) {
|
||||
aPaperList = mPaperList.Clone();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrinterInfo::GetDefaultSettings(nsIPrintSettings** aDefaultSettings) {
|
||||
NS_ENSURE_ARG_POINTER(aDefaultSettings);
|
||||
MOZ_ASSERT(mDefaultSettings);
|
||||
RefPtr<nsIPrintSettings> settings = mDefaultSettings;
|
||||
settings.forget(aDefaultSettings);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION(nsPrinterInfo, mPaperList, mDefaultSettings)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsPrinterInfo)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIPrinterInfo)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIPrinterInfo)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsPrinterInfo)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsPrinterInfo)
|
||||
|
||||
template <typename Index, Index Size, typename Value>
|
||||
inline void ImplCycleCollectionTraverse(
|
||||
nsCycleCollectionTraversalCallback& aCallback,
|
||||
@ -72,11 +114,16 @@ void ResolveOrReject(Promise& aPromise, nsPrinterBase& aPrinter,
|
||||
template <>
|
||||
void ResolveOrReject(Promise& aPromise, nsPrinterBase& aPrinter,
|
||||
const PrintSettingsInitializer& aResult) {
|
||||
aPrinter.CachePrintSettingsInitializer(aResult);
|
||||
aPromise.MaybeResolve(
|
||||
RefPtr<nsIPrintSettings>(CreatePlatformPrintSettings(aResult)));
|
||||
}
|
||||
|
||||
template <>
|
||||
void ResolveOrReject(Promise& aPromise, nsPrinterBase& aPrinter,
|
||||
const nsPrinterBase::PrinterInfo& aResult) {
|
||||
aPromise.MaybeResolve(MakeRefPtr<nsPrinterInfo>(aPrinter, aResult));
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
template <typename T, typename... Args>
|
||||
@ -89,40 +136,12 @@ nsresult nsPrinterBase::AsyncPromiseAttributeGetter(
|
||||
nsLiteralCString>
|
||||
attributeKeys{"SupportsDuplex"_ns, "SupportsColor"_ns,
|
||||
"SupportsMonochrome"_ns, "SupportsCollation"_ns,
|
||||
"PaperList"_ns};
|
||||
"PrinterInfo"_ns};
|
||||
return mozilla::AsyncPromiseAttributeGetter(
|
||||
*this, mAsyncAttributePromises[aAttribute], aCx, aResultPromise,
|
||||
attributeKeys[aAttribute], aBackgroundTask, std::forward<Args>(aArgs)...);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrinterBase::CreateDefaultSettings(JSContext* aCx,
|
||||
Promise** aResultPromise) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
NS_ENSURE_ARG_POINTER(aResultPromise);
|
||||
|
||||
if (mPrintSettingsInitializer.isSome()) {
|
||||
ErrorResult rv;
|
||||
RefPtr<dom::Promise> promise =
|
||||
dom::Promise::Create(xpc::CurrentNativeGlobal(aCx), rv);
|
||||
|
||||
if (MOZ_UNLIKELY(rv.Failed())) {
|
||||
*aResultPromise = nullptr;
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
|
||||
RefPtr<nsIPrintSettings> settings(
|
||||
CreatePlatformPrintSettings(mPrintSettingsInitializer.ref()));
|
||||
promise->MaybeResolve(settings);
|
||||
|
||||
promise.forget(aResultPromise);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return PrintBackgroundTaskPromise(*this, aCx, aResultPromise,
|
||||
"DefaultSettings"_ns,
|
||||
&nsPrinterBase::DefaultSettings);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrinterBase::GetSupportsDuplex(JSContext* aCx,
|
||||
Promise** aResultPromise) {
|
||||
return AsyncPromiseAttributeGetter(aCx, aResultPromise,
|
||||
@ -151,11 +170,11 @@ NS_IMETHODIMP nsPrinterBase::GetSupportsCollation(JSContext* aCx,
|
||||
&nsPrinterBase::SupportsCollation);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrinterBase::GetPaperList(JSContext* aCx,
|
||||
NS_IMETHODIMP nsPrinterBase::GetPrinterInfo(JSContext* aCx,
|
||||
Promise** aResultPromise) {
|
||||
return AsyncPromiseAttributeGetter(aCx, aResultPromise,
|
||||
AsyncAttribute::PaperList,
|
||||
&nsPrinterBase::PaperList);
|
||||
AsyncAttribute::PrinterInfo,
|
||||
&nsPrinterBase::CreatePrinterInfo);
|
||||
}
|
||||
|
||||
void nsPrinterBase::QueryMarginsForPaper(Promise& aPromise,
|
||||
@ -180,6 +199,10 @@ nsPrinterBase::nsPrinterBase(const CommonPaperInfoArray* aPaperInfoArray)
|
||||
}
|
||||
nsPrinterBase::~nsPrinterBase() = default;
|
||||
|
||||
nsPrinterBase::PrinterInfo nsPrinterBase::CreatePrinterInfo() const {
|
||||
return PrinterInfo{PaperList(), DefaultSettings()};
|
||||
}
|
||||
|
||||
const PaperInfo* nsPrinterBase::FindCommonPaperSize(
|
||||
const gfx::SizeDouble& aSize) const {
|
||||
for (const PaperInfo& paper : *mCommonPaperInfo) {
|
||||
|
@ -31,12 +31,11 @@ class nsPrinterBase : public nsIPrinter {
|
||||
using MarginDouble = mozilla::gfx::MarginDouble;
|
||||
using PrintSettingsInitializer = mozilla::PrintSettingsInitializer;
|
||||
|
||||
NS_IMETHOD CreateDefaultSettings(JSContext*, Promise**) final;
|
||||
NS_IMETHOD GetSupportsDuplex(JSContext*, Promise**) final;
|
||||
NS_IMETHOD GetSupportsColor(JSContext*, Promise**) final;
|
||||
NS_IMETHOD GetSupportsMonochrome(JSContext*, Promise**) final;
|
||||
NS_IMETHOD GetSupportsCollation(JSContext*, Promise**) final;
|
||||
NS_IMETHOD GetPaperList(JSContext*, Promise**) final;
|
||||
NS_IMETHOD GetPrinterInfo(JSContext*, Promise**) final;
|
||||
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS(nsPrinterBase)
|
||||
@ -57,6 +56,12 @@ class nsPrinterBase : public nsIPrinter {
|
||||
void CachePrintSettingsInitializer(
|
||||
const PrintSettingsInitializer& aInitializer);
|
||||
|
||||
// Data to pass through to create the nsPrinterInfo
|
||||
struct PrinterInfo {
|
||||
nsTArray<mozilla::PaperInfo> mPaperList;
|
||||
PrintSettingsInitializer mDefaultSettings;
|
||||
};
|
||||
|
||||
private:
|
||||
enum class AsyncAttribute {
|
||||
// If you change this list you must update attributeKeys in
|
||||
@ -65,7 +70,7 @@ class nsPrinterBase : public nsIPrinter {
|
||||
SupportsColor,
|
||||
SupportsMonochrome,
|
||||
SupportsCollation,
|
||||
PaperList,
|
||||
PrinterInfo,
|
||||
// Just a guard.
|
||||
Last,
|
||||
};
|
||||
@ -79,13 +84,6 @@ class nsPrinterBase : public nsIPrinter {
|
||||
BackgroundTask<T, Args...>,
|
||||
Args... aArgs);
|
||||
|
||||
/**
|
||||
* A cache to store the result of DefaultSettings() to ensure
|
||||
* that subsequent calls to CreateDefaultSettings() will not
|
||||
* have to spawn another background task to fetch the same info.
|
||||
*/
|
||||
Maybe<PrintSettingsInitializer> mPrintSettingsInitializer;
|
||||
|
||||
protected:
|
||||
nsPrinterBase(const mozilla::CommonPaperInfoArray* aPaperInfoArray);
|
||||
virtual ~nsPrinterBase();
|
||||
@ -99,6 +97,7 @@ class nsPrinterBase : public nsIPrinter {
|
||||
virtual bool SupportsCollation() const = 0;
|
||||
virtual nsTArray<mozilla::PaperInfo> PaperList() const = 0;
|
||||
virtual MarginDouble GetMarginsForPaper(nsString aPaperId) const = 0;
|
||||
virtual PrinterInfo CreatePrinterInfo() const;
|
||||
// Searches our built-in list of commonly used PWG paper sizes for a matching,
|
||||
// localized PaperInfo. Returns null if there is no matching size.
|
||||
const mozilla::PaperInfo* FindCommonPaperSize(
|
||||
|
Loading…
Reference in New Issue
Block a user