Commit fc3b4b69 authored by Matt Menard's avatar Matt Menard Committed by Chromium LUCI CQ

Create PrintServerStore for destination-dialog

Adds PrintServerStore to manage print servers and their associated
printers in the destination-dialog element.

Bug: b:168650771
Change-Id: Ic89abf70bfb6acf05bf3c090882b5487a18caf84
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2538282
Commit-Queue: Matt Menard <mattme@google.com>
Reviewed-by: default avatarRebekah Potter <rbpotter@chromium.org>
Cr-Commit-Position: refs/heads/master@{#833031}
parent 16f6e742
......@@ -111,8 +111,9 @@ preprocess_if_expr("preprocess") {
if (is_chromeos_ash) {
in_files += [
"native_layer_cros.js",
"data/print_server_store.js",
"data/printer_status_cros.js",
"native_layer_cros.js",
]
}
}
......@@ -247,6 +248,10 @@ js_library("print_preview") {
"ui:app",
"ui:settings_select",
]
if (is_chromeos) {
deps += [ "data:print_server_store" ]
}
}
js_library("print_preview_utils") {
......
......@@ -30,6 +30,10 @@ js_type_check("closure_compile_module") {
":state",
":user_manager",
]
if (is_chromeos) {
deps += [ ":print_server_store" ]
}
}
js_library("cdd") {
......@@ -65,6 +69,15 @@ js_library("invitation_store") {
]
}
if (is_chromeos) {
js_library("print_server_store") {
deps = [
"..:native_layer_cros",
"//ui/webui/resources/js/cr:event_target.m",
]
}
}
js_library("local_parsers") {
deps = [
":destination",
......
// Copyright 2020 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.
import {NativeEventTarget as EventTarget} from 'chrome://resources/js/cr/event_target.m.js';
import {NativeLayerCros, NativeLayerCrosImpl, PrintServer, PrintServersConfig} from '../native_layer_cros.js';
export class PrintServerStore extends EventTarget {
/**
* A data store that stores print servers and dispatches events when the
* data store changes.
* @param {function(string, !Function):void} addListenerCallback Function
* to call to add Web UI listeners in PrintServerStore constructor.
*/
constructor(addListenerCallback) {
super();
/**
* Used to fetch print servers.
* @private {!NativeLayerCros}
*/
this.nativeLayer_ = NativeLayerCrosImpl.getInstance();
/**
* All available print servers mapped by name.
* @private {!Map<string, !Array<!PrintServer>>}
*/
this.printServersByName_ = new Map();
/**
* Whether in single print server fetching mode.
* @private {boolean}
*/
this.isSingleServerFetchingMode_ = false;
addListenerCallback(
'print-servers-config-changed',
printServersConfig =>
this.onPrintServersConfigChanged_(printServersConfig));
addListenerCallback(
'server-printers-loading',
isLoading => this.onServerPrintersLoading_(isLoading));
}
/**
* Selects the print server(s) with the corresponding name.
* @param {string} printServerName Name of the print server(s).
*/
choosePrintServers(printServerName) {
const printServers = this.printServersByName_.get(printServerName);
this.nativeLayer_.choosePrintServers(
printServers ? printServers.map(printServer => printServer.id) : []);
}
/**
* Gets the currently available print servers and fetching mode.
* @return {!Promise<!PrintServersConfig>} The print servers configuration.
*/
getPrintServersConfig() {
return this.nativeLayer_.getPrintServersConfig();
}
/**
* Called when new print servers and fetching mode are available.
* @param {!PrintServersConfig} printServersConfig The print servers
* configuration.
*/
onPrintServersConfigChanged_(printServersConfig) {
this.isSingleServerFetchingMode_ =
printServersConfig.isSingleServerFetchingMode;
this.printServersByName_ = new Map();
for (const printServer of printServersConfig.printServers) {
if (this.printServersByName_.has(printServer.name)) {
this.printServersByName_.get(printServer.name).push(printServer);
} else {
this.printServersByName_.set(printServer.name, [printServer]);
}
}
const eventData = {
printServerNames: Array.from(this.printServersByName_.keys()),
isSingleServerFetchingMode: this.isSingleServerFetchingMode_
};
this.dispatchEvent(new CustomEvent(
PrintServerStore.EventType.PRINT_SERVERS_CHANGED, {detail: eventData}));
}
/**
* Called when print server printers loading status has changed.
* @param {boolean} isLoading Whether server printers are loading
*/
onServerPrintersLoading_(isLoading) {
this.dispatchEvent(new CustomEvent(
PrintServerStore.EventType.SERVER_PRINTERS_LOADING,
{detail: isLoading}));
}
}
/**
* Event types dispatched by the print server store.
* @enum {string}
*/
PrintServerStore.EventType = {
PRINT_SERVERS_CHANGED: 'PrintServerStore.PRINT_SERVERS_CHANGED',
SERVER_PRINTERS_LOADING: 'PrintServerStore.SERVER_PRINTERS_LOADING',
};
......@@ -20,6 +20,22 @@ import {PrinterStatus, PrinterStatusReason} from './data/printer_status_cros.js'
*/
export let PrinterSetupResponse;
/**
* @typedef {{
* id: string,
* name: string,
* }}
*/
export let PrintServer;
/**
* @typedef {{
* printServers: !Array<!PrintServer>,
* isSingleServerFetchingMode: boolean,
* }}
*/
export let PrintServersConfig;
/**
* An interface to the Chrome OS platform specific part of the native Chromium
* printing system layer.
......@@ -72,6 +88,20 @@ export class NativeLayerCros {
* canceled.
*/
recordPrinterStatusHistogram(statusReason, didUserAttemptPrint) {}
/**
* Selects all print servers with ids in |printServerIds| to query for their
* printers.
* @param {!Array<string>} printServerIds
*/
choosePrintServers(printServerIds) {}
/**
* Gets the available print servers and whether we are in single server
* fetching mode.
* @return {!Promise<!PrintServersConfig>}
*/
getPrintServersConfig() {}
}
/** @implements {NativeLayerCros} */
......@@ -125,6 +155,16 @@ export class NativeLayerCrosImpl {
'metricsHandler:recordBooleanHistogram',
[histogram, didUserAttemptPrint]);
}
/** @override */
choosePrintServers(printServerIds) {
chrome.send('choosePrintServers', [printServerIds]);
}
/** @override */
getPrintServersConfig() {
return sendWithPromise('getPrintServersConfig');
}
}
addSingletonGetter(NativeLayerCrosImpl);
......@@ -24,6 +24,9 @@ export {CustomMarginsOrientation, Margins, MarginsSetting, MarginsType} from './
export {MeasurementSystem, MeasurementSystemUnitType} from './data/measurement_system.js';
export {DuplexMode, DuplexType, getInstance, whenReady} from './data/model.js';
// <if expr="chromeos">
export {PrintServerStore} from './data/print_server_store.js';
// </if>
// <if expr="chromeos">
export {PrinterState, PrinterStatus, PrinterStatusReason, PrinterStatusSeverity} from './data/printer_status_cros.js';
// </if>
export {ScalingType} from './data/scaling.js';
......@@ -31,7 +34,7 @@ export {Size} from './data/size.js';
export {Error, State} from './data/state.js';
export {BackgroundGraphicsModeRestriction, CapabilitiesResponse, NativeInitialSettings, NativeLayer, NativeLayerImpl} from './native_layer.js';
// <if expr="chromeos">
export {NativeLayerCros, NativeLayerCrosImpl, PrinterSetupResponse} from './native_layer_cros.js';
export {NativeLayerCros, NativeLayerCrosImpl, PrinterSetupResponse, PrintServer, PrintServersConfig} from './native_layer_cros.js';
// </if>
export {getSelectDropdownBackground} from './print_preview_utils.js';
export {DEFAULT_MAX_COPIES} from './ui/copies_settings.js';
......
......@@ -97,6 +97,7 @@ js_type_check("closure_compile") {
":destination_select_test_cros",
":destination_settings_test_cros",
":native_layer_cros_stub",
":print_server_store_test",
]
} else {
deps += [
......@@ -524,3 +525,17 @@ js_library("media_size_settings_test") {
]
externs_list = [ "$externs_path/mocha-2.5.js" ]
}
if (is_chromeos) {
js_library("print_server_store_test") {
deps = [
":native_layer_cros_stub",
"..:chai_assert",
"..:test_util.m",
"//chrome/browser/resources/print_preview:print_preview",
"//ui/webui/resources/js:assert.m",
"//ui/webui/resources/js:cr.m",
]
externs_list = [ "$externs_path/mocha-2.5.js" ]
}
}
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import {NativeLayerCros, NativeLayerCrosImpl, PrinterSetupResponse} from 'chrome://print/print_preview.js';
import {NativeLayerCros, NativeLayerCrosImpl, PrinterSetupResponse, PrintServer, PrintServersConfig} from 'chrome://print/print_preview.js';
import {assert} from 'chrome://resources/js/assert.m.js';
import {PromiseResolver} from 'chrome://resources/js/promise_resolver.m.js';
......@@ -25,6 +25,8 @@ export class NativeLayerCrosStub extends TestBrowserProxy {
'getEulaUrl',
'requestPrinterStatusUpdate',
'setupPrinter',
'choosePrintServers',
'getPrintServersConfig',
]);
/**
......@@ -55,6 +57,12 @@ export class NativeLayerCrosStub extends TestBrowserProxy {
/** @private {number} */
this.multiplePrinterStatusRequestsCount_ = 0;
/** @private {!PrintServersConfig} */
this.printServersConfig_ = {
printServers: [],
isSingleServerFetchingMode: false
};
}
/** @override */
......@@ -134,4 +142,15 @@ export class NativeLayerCrosStub extends TestBrowserProxy {
/** @override */
recordPrinterStatusHistogram(statusReason, didUserAttemptPrint) {}
/** @override */
choosePrintServers(printServerIds) {
this.methodCalled('choosePrintServers', printServerIds);
}
/** @override */
getPrintServersConfig() {
this.methodCalled('getPrintServersConfig');
return Promise.resolve(this.printServersConfig_);
}
}
......@@ -660,6 +660,37 @@ TEST_F('PrintPreviewDestinationStoreTestCros', 'DriveNotMounted', function() {
});
GEN('#endif');
GEN('#if defined(OS_CHROMEOS)');
// eslint-disable-next-line no-var
var PrintPreviewPrintServerStoreTestCros = class extends PrintPreviewTest {
/** @override */
get browsePreload() {
return 'chrome://print/test_loader.html?module=print_preview/print_server_store_test.js';
}
/** @override */
get suiteName() {
return print_server_store_test.suiteName;
}
};
TEST_F(
'PrintPreviewPrintServerStoreTestCros', 'ChoosePrintServers', function() {
this.runMochaTest(print_server_store_test.TestNames.ChoosePrintServers);
});
TEST_F(
'PrintPreviewPrintServerStoreTestCros', 'PrintServersChanged', function() {
this.runMochaTest(print_server_store_test.TestNames.PrintServersChanged);
});
TEST_F(
'PrintPreviewPrintServerStoreTestCros', 'ServerPrintersLoading',
function() {
this.runMochaTest(
print_server_store_test.TestNames.ServerPrintersLoading);
});
GEN('#endif');
GEN('#if !defined(OS_CHROMEOS)');
// eslint-disable-next-line no-var
var PrintPreviewDestinationDialogTest = class extends PrintPreviewTest {
......
// Copyright 2020 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.
import {PrinterType, PrintServerStore} from 'chrome://print/print_preview.js';
import {assert} from 'chrome://resources/js/assert.m.js';
import {addWebUIListener, removeWebUIListener, WebUIListener, webUIListenerCallback} from 'chrome://resources/js/cr.m.js';
import {assertDeepEquals, assertTrue} from '../chai_assert.js';
import {eventToPromise} from '../test_util.m.js';
import {NativeLayerCrosStub, setNativeLayerCrosInstance} from './native_layer_cros_stub.js';
window.print_server_store_test = {};
const print_server_store_test = window.print_server_store_test;
print_server_store_test.suiteName = 'PrintServerStoreTest';
/** @enum {string} */
print_server_store_test.TestNames = {
PrintServersChanged: 'print servers changed',
ServerPrintersLoading: 'server printers loading',
ChoosePrintServers: 'choose print servers',
};
suite(print_server_store_test.suiteName, function() {
/** @type {!PrintServerStore} */
let printServerStore;
/** @type {!NativeLayerCrosStub} */
let nativeLayerCros;
/** @type {!Array<WebUIListener>} */
let listeners;
const addListener = function() {
listeners.push(addWebUIListener(...arguments));
};
/** @override */
setup(function() {
listeners = [];
nativeLayerCros = setNativeLayerCrosInstance();
printServerStore = new PrintServerStore(addListener);
});
/** @override */
teardown(function() {
listeners.forEach(removeWebUIListener);
});
// Tests that print servers with the selected name are selected by ID is the
// native layer choosePrintServers is called.
test(
assert(print_server_store_test.TestNames.ChoosePrintServers),
async () => {
const printServers = [
{id: 'user-server1', name: 'Print Server 1'},
{id: 'device-server2', name: 'Print Server 2'},
{id: 'user-server2', name: 'Print Server 2'},
{id: 'user-server4', name: 'Print Server 3'},
];
const printServersConfig = {
printServers: printServers,
isSingleServerFetchingMode: true
};
webUIListenerCallback(
'print-servers-config-changed', printServersConfig);
const pendingPrintServerIds =
nativeLayerCros.whenCalled('choosePrintServers');
printServerStore.choosePrintServers('Print Server 2');
assertDeepEquals(
['device-server2', 'user-server2'], await pendingPrintServerIds);
});
// Tests that print servers and fetching mode are updated when
// PRINT_SERVERS_CHANGED occurs.
test(
assert(print_server_store_test.TestNames.PrintServersChanged),
async () => {
const printServers = [
{id: 'server1', name: 'Print Server 1'},
{id: 'server2', name: 'Print Server 2'}
];
const whenPrintServersChangedEvent = eventToPromise(
PrintServerStore.EventType.PRINT_SERVERS_CHANGED, printServerStore);
const printServersConfig = {
printServers: printServers,
isSingleServerFetchingMode: true
};
webUIListenerCallback(
'print-servers-config-changed', printServersConfig);
const printServersChangedEvent = await whenPrintServersChangedEvent;
assertDeepEquals(
['Print Server 1', 'Print Server 2'],
printServersChangedEvent.detail.printServerNames);
assertTrue(printServersChangedEvent.detail.isSingleServerFetchingMode);
});
// Tests that an event is dispatched are updated when SERVER_PRINTERS_LOADING
// is called.
test(
assert(print_server_store_test.TestNames.ServerPrintersLoading),
async () => {
const whenServerPrintersLoadedEvent = eventToPromise(
PrintServerStore.EventType.SERVER_PRINTERS_LOADING,
printServerStore);
webUIListenerCallback('server-printers-loading', true);
const serverPrintersLoadedEvent = await whenServerPrintersLoadedEvent;
assertTrue(serverPrintersLoadedEvent.detail);
});
});
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