Commit 79cefbe8 authored by Mark Striemer's avatar Mark Striemer
Browse files

Bug 1676388 - Part 1: Don't update to new printer settings if printer has since changed r=sfoster

When changing printers one of them could be slower than another. If you change
to a slow printer and back to an already loaded/fast printer then the slow
printer shouldn't overwrite the settings once it finally loads.

Example: Start print on PDF printer, switch to a physical printer and back to PDF. If
the physical printer had to be contacted to pull settings this operation could take
a few seconds, at which point the settings from the physical printer could overwrite
the PDF printer settings.

Differential Revision: https://phabricator.services.mozilla.com/D99135
parent 70311ae3
......@@ -387,6 +387,7 @@ var PrintEventHandler = {
},
async refreshSettings(printerName) {
this.currentPrinterName = printerName;
let currentPrinter;
try {
currentPrinter = await PrintSettingsViewProxy.resolvePropertiesForPrinter(
......@@ -396,6 +397,12 @@ var PrintEventHandler = {
this.reportPrintingError("PRINTER_PROPERTIES");
throw e;
}
if (this.currentPrinterName != printerName) {
// Refresh settings could take a while, if the destination has changed
// then we don't want to update the settings after all.
return {};
}
this.settings = currentPrinter.settings;
this.defaultSettings = currentPrinter.defaultSettings;
......@@ -553,9 +560,14 @@ var PrintEventHandler = {
"onUserSettingsChange, changing to printerName:",
changedSettings.printerName
);
let { printerName } = changedSettings;
// Treat a printerName change separately, because it involves a settings
// object switch and we don't want to set the new name on the old settings.
changedSettings = await this.refreshSettings(changedSettings.printerName);
changedSettings = await this.refreshSettings(printerName);
if (printerName != this.currentPrinterName) {
// Don't continue this update if the printer changed again.
return;
}
} else {
changedSettings = this.getSettingsToUpdate();
}
......@@ -1338,6 +1350,10 @@ var PrintSettingsViewProxy = {
break;
}
case "printerName":
// Can't set printerName, settings objects belong to a specific printer.
break;
case "printBackgrounds":
target.printBGImages = value;
target.printBGColors = value;
......
......@@ -4,6 +4,7 @@ support-files =
simplifyArticleSample.html
[browser_cancel_close_print.js]
[browser_destination_change.js]
[browser_empty_paper_sizes.js]
[browser_modal_print.js]
......
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
let pdfPrinterName = "Mozilla Save to PDF";
let fastPrinterName = "Fast";
let slowPrinterName = "Slow";
async function setupPrinters(helper) {
helper.addMockPrinter(fastPrinterName);
let resolvePrinterInfo;
helper.addMockPrinter({
name: slowPrinterName,
printerInfoPromise: new Promise(resolve => {
resolvePrinterInfo = resolve;
}),
});
await SpecialPowers.pushPrefEnv({
set: [["print.printer_Slow.print_orientation", 1]],
});
return resolvePrinterInfo;
}
async function changeDestination(helper, dir) {
let picker = helper.get("printer-picker");
let changed = BrowserTestUtils.waitForEvent(picker, "change");
picker.focus();
EventUtils.sendKey("space", helper.win);
EventUtils.sendKey(dir, helper.win);
EventUtils.sendKey("return", helper.win);
await changed;
}
add_task(async function testSlowDestinationChange() {
await PrintHelper.withTestPage(async helper => {
let resolvePrinterInfo = await setupPrinters(helper);
await helper.startPrint();
let destinationPicker = helper.get("printer-picker");
info("Changing to fast printer should change settings");
await helper.assertSettingsChanged(
{ printerName: pdfPrinterName, orientation: 0 },
{ printerName: fastPrinterName, orientation: 0 },
async () => {
await changeDestination(helper, "down");
is(destinationPicker.value, fastPrinterName, "Fast printer selected");
// Wait one frame so the print settings promises resolve.
await helper.awaitAnimationFrame();
}
);
info("Changing to slow printer should not change settings yet");
await helper.assertSettingsNotChanged(
{ printerName: fastPrinterName, orientation: 0 },
async () => {
await changeDestination(helper, "down");
is(destinationPicker.value, slowPrinterName, "Slow printer selected");
// Wait one frame, since the settings are blocked on resolvePrinterInfo
// the settings shouldn't change.
await helper.awaitAnimationFrame();
}
);
await helper.assertSettingsChanged(
{ printerName: fastPrinterName, orientation: 0 },
{ printerName: slowPrinterName, orientation: 1 },
async () => {
resolvePrinterInfo();
await helper.waitForSettingsEvent();
}
);
await helper.closeDialog();
});
});
add_task(async function testSwitchAwayFromSlowDestination() {
await PrintHelper.withTestPage(async helper => {
let resolvePrinterInfo = await setupPrinters(helper);
await helper.startPrint();
let destinationPicker = helper.get("printer-picker");
// Load the fast printer.
await helper.waitForSettingsEvent(async () => {
await changeDestination(helper, "down");
});
// "Load" the slow printer.
await changeDestination(helper, "down");
is(destinationPicker.value, slowPrinterName, "Slow printer selected");
// Wait an animation frame, since there's no settings event.
await helper.awaitAnimationFrame();
// Switch back to the fast printer.
await helper.waitForSettingsEvent(async () => {
await changeDestination(helper, "up");
});
helper.assertSettingsMatch({
printerName: fastPrinterName,
orientation: 0,
});
// Let the slow printer settings resolve, the orientation shouldn't change.
resolvePrinterInfo();
// Wait so the settings event can trigger, if this case isn't handled.
await helper.awaitAnimationFrame();
helper.assertSettingsMatch({
printerName: fastPrinterName,
orientation: 0,
});
await helper.closeDialog();
});
});
......@@ -18,7 +18,7 @@ add_task(async function testSanityCheckPaperList() {
height: 1224,
}),
];
helper.addMockPrinter(mockPrinterName, paperList);
helper.addMockPrinter({ name: mockPrinterName, paperList });
await helper.startPrint();
await helper.dispatchSettingsChange({ printerName: mockPrinterName });
await helper.awaitAnimationFrame();
......
......@@ -194,7 +194,15 @@ class PrintHelper {
};
}
addMockPrinter(name = "Mock Printer", paperList = []) {
addMockPrinter(opts = {}) {
if (typeof opts == "string") {
opts = { name: opts };
}
let {
name = "Mock Printer",
paperList = [],
printerInfoPromise = Promise.resolve(),
} = opts;
let PSSVC = Cc["@mozilla.org/gfx/printsettings-service;1"].getService(
Ci.nsIPrintSettingsService
);
......@@ -209,11 +217,11 @@ class PrintHelper {
name,
supportsColor: Promise.resolve(true),
supportsMonochrome: Promise.resolve(true),
printerInfo: Promise.resolve({
printerInfo: printerInfoPromise.then(() => ({
paperList,
defaultSettings,
QueryInterface: ChromeUtils.generateQI([Ci.nsIPrinterInfo]),
}),
})),
QueryInterface: ChromeUtils.generateQI([Ci.nsIPrinter]),
};
......
Supports Markdown
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