Commit ad4d07fb authored by Gavin Williams's avatar Gavin Williams Committed by Commit Bot

Move printer status helpers to common file

Printer status icons will be showed on Print Preview Destination Dialog
on CrOS so need to move some of the common functionality out of
destination_select_cros to reduce duplication.

Moving the |printerStatusMap| to destination_settings allows the
dropdown and dialog to share the same printer status cache.

Bug: 1123754
Change-Id: I367c875bd673ac9bab5297cc52de1f0f24fbe71e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2387138
Commit-Queue: Gavin Williams <gavinwill@chromium.org>
Reviewed-by: default avatarRebekah Potter <rbpotter@chromium.org>
Cr-Commit-Position: refs/heads/master@{#804423}
parent 88f63bcd
......@@ -38,6 +38,27 @@ export const PrinterStatusSeverity = {
ERROR: 3,
};
/**
* Enumeration giving a local Chrome OS printer 3 different state possibilities
* depending on its current status.
* @enum {number}
*/
export const PrinterState = {
GOOD: 0,
ERROR: 1,
UNKNOWN: 2,
};
/**
* Enumeration used to choose styling based on whether this icon is located in
* the destination display or the destination dropdown.
* @enum {number}
*/
export const IconLocation = {
DISPLAY: 0,
DROPDOWN: 1,
};
/**
* A container for the results of a printer status query. A printer status query
* can return multiple error reasons. |timestamp| is set at the time of status
......@@ -71,3 +92,51 @@ export const ERROR_STRING_KEY_MAP = new Map([
[PrinterStatusReason.STOPPED, 'printerStatusStopped'],
[PrinterStatusReason.TRAY_MISSING, 'printerStatusTrayMissing'],
]);
/**
* A |printerStatus| can have multiple status reasons so this function's
* responsibility is to determine which status reason is most relevant to
* surface to the user. Any status reason with a severity of WARNING or ERROR
* will get highest precedence since this usually means the printer is in a
* bad state. NO_ERROR status reason is the next highest precedence so the
* printer can be shown as available whenever possible.
* @param {!PrinterStatus} printerStatus
* @return {!PrinterStatusReason} Status reason extracted from |printerStatus|.
*/
export function getStatusReasonFromPrinterStatus(printerStatus) {
if (!printerStatus.printerId) {
return PrinterStatusReason.UNKNOWN_REASON;
}
let seenNoErrorReason = false;
for (const statusReason of printerStatus.statusReasons) {
const reason = statusReason.reason;
const severity = statusReason.severity;
if (reason !== PrinterStatusReason.UNKNOWN_REASON &&
(severity === PrinterStatusSeverity.WARNING ||
severity === PrinterStatusSeverity.ERROR)) {
return reason;
}
seenNoErrorReason =
seenNoErrorReason || reason === PrinterStatusReason.NO_ERROR;
}
return seenNoErrorReason ? PrinterStatusReason.NO_ERROR :
PrinterStatusReason.UNKNOWN_REASON;
}
/**
* @param {?PrinterStatusReason} printerStatusReason
* @return {number}
*/
export function computePrinterState(printerStatusReason) {
if (!printerStatusReason ||
printerStatusReason === PrinterStatusReason.UNKNOWN_REASON) {
return PrinterState.UNKNOWN;
}
if (printerStatusReason === PrinterStatusReason.NO_ERROR) {
return PrinterState.GOOD;
}
return PrinterState.ERROR;
}
\ No newline at end of file
......@@ -22,7 +22,7 @@ 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 {PrinterStatus, PrinterStatusReason, PrinterStatusSeverity} from './data/printer_status_cros.js';
export {PrinterState, PrinterStatus, PrinterStatusReason, PrinterStatusSeverity} from './data/printer_status_cros.js';
// </if>
export {ScalingType} from './data/scaling.js';
export {Size} from './data/size.js';
......@@ -33,8 +33,5 @@ export {DEFAULT_MAX_COPIES} from './ui/copies_settings.js';
export {DestinationState} from './ui/destination_settings.js';
export {PDFPlugin, PluginProxy, PluginProxyImpl} from './ui/plugin_proxy.js';
export {PreviewAreaState} from './ui/preview_area.js';
// <if expr="chromeos">
export {PrinterState} from './ui/printer_status_icon_cros.js';
// </if>
export {SelectBehavior} from './ui/select_behavior.js';
export {SelectOption} from './ui/settings_select.js';
......@@ -9,14 +9,13 @@ import 'chrome://resources/polymer/v3_0/iron-dropdown/iron-dropdown.js';
import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
import './print_preview_vars_css.js';
import './printer_status_icon_cros.js';
import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js';
import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
import {Destination, DestinationOrigin} from '../data/destination.js';
import {ERROR_STRING_KEY_MAP, PrinterStatusReason} from '../data/printer_status_cros.js';
import {IconLocation, PrinterState} from './printer_status_icon_cros.js';
import {computePrinterState, ERROR_STRING_KEY_MAP, IconLocation, PrinterState, PrinterStatusReason} from '../data/printer_status_cros.js';
Polymer({
is: 'print-preview-destination-dropdown-cros',
......@@ -267,14 +266,7 @@ Polymer({
* @private
*/
computePrinterState_(printerStatusReason) {
if (!printerStatusReason ||
printerStatusReason === PrinterStatusReason.UNKNOWN_REASON) {
return PrinterState.UNKNOWN;
}
if (printerStatusReason === PrinterStatusReason.NO_ERROR) {
return PrinterState.GOOD;
}
return PrinterState.ERROR;
return computePrinterState(printerStatusReason);
},
/**
......
......@@ -22,7 +22,7 @@ import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
import {Base, html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
import {CloudOrigins, Destination, DestinationOrigin, PDF_DESTINATION_KEY, RecentDestination, SAVE_TO_DRIVE_CROS_DESTINATION_KEY} from '../data/destination.js';
import {ERROR_STRING_KEY_MAP, PrinterStatus, PrinterStatusReason, PrinterStatusSeverity} from '../data/printer_status_cros.js';
import {ERROR_STRING_KEY_MAP, getStatusReasonFromPrinterStatus, PrinterStatus, PrinterStatusReason, PrinterStatusSeverity} from '../data/printer_status_cros.js';
import {NativeLayer, NativeLayerImpl} from '../native_layer.js';
import {getSelectDropdownBackground} from '../print_preview_utils.js';
......@@ -58,6 +58,9 @@ Polymer({
pdfPrinterDisabled: Boolean,
/** @type {!Map<string, string>} */
statusRequestedMap: Object,
/** @type {!Array<!Destination>} */
recentDestinationList: {
type: Array,
......@@ -100,15 +103,6 @@ Polymer({
readOnly: true,
},
/**
* The key for this map is a destination.id and the value is a
* destination.key. This map is needed to track which destinations have had
* statuses requested while also giving quick look up of destination id to
* the corresponding destination key.
* @private {!Map<string, string>}
*/
statusRequestedMap_: Map,
/** @private */
isCurrentDestinationCrosLocal_: {
type: Boolean,
......@@ -137,15 +131,6 @@ Polymer({
meta_: /** @type {!IronMetaElement} */ (
Base.create('iron-meta', {type: 'iconset'})),
/** @override */
attached() {
if (!this.printerStatusFlagEnabled_) {
return;
}
this.statusRequestedMap_ = new Map();
},
focus() {
if (this.printerStatusFlagEnabled_) {
this.$$('#dropdown').$$('#destination-dropdown').focus();
......@@ -255,14 +240,14 @@ Polymer({
for (const destination of this.recentDestinationList) {
if (destination.origin !== DestinationOrigin.CROS ||
this.statusRequestedMap_.has(destination.id)) {
this.statusRequestedMap.has(destination.id)) {
continue;
}
NativeLayerImpl.getInstance()
.requestPrinterStatusUpdate(destination.id)
.then(status => this.onPrinterStatusReceived_(status));
this.statusRequestedMap_.set(destination.id, destination.key);
this.statusRequestedMap.set(destination.id, destination.key);
}
},
......@@ -278,8 +263,7 @@ Polymer({
return;
}
const destinationKey =
this.statusRequestedMap_.get(printerStatus.printerId);
const destinationKey = this.statusRequestedMap.get(printerStatus.printerId);
if (!destinationKey) {
return;
}
......@@ -292,12 +276,11 @@ Polymer({
return;
}
const statusReason = this.getStatusReasonFromPrinterStatus_(printerStatus);
const statusReason = getStatusReasonFromPrinterStatus(printerStatus);
if (!statusReason) {
return;
}
this.recentDestinationList[indexFound].printerStatusReason = statusReason;
// Set the new printer status reason then use notifyPath to trigger the
// dropdown printer status icons to recalculate their badge color.
......@@ -311,44 +294,6 @@ Polymer({
}
},
/**
* A |printerStatus| can have multiple status reasons so this function's
* responsibility is to determine which status reason is most relevant to
* surface to the user. Any status reason with a severity of WARNING or ERROR
* will get highest precedence since this usually means the printer is in a
* bad state. NO_ERROR status reason is the next highest precedence so the
* printer can be shown as available whenever possible.
* @param {!PrinterStatus} printerStatus
* @return {!PrinterStatusReason} Status reason extracted from
* |printerStatus|.
* @private
*/
getStatusReasonFromPrinterStatus_(printerStatus) {
assert(this.printerStatusFlagEnabled_);
if (!printerStatus.printerId) {
return PrinterStatusReason.UNKNOWN_REASON;
}
let seenNoErrorReason = false;
for (const statusReason of printerStatus.statusReasons) {
const reason = statusReason.reason;
const severity = statusReason.severity;
if (reason !== PrinterStatusReason.UNKNOWN_REASON &&
(severity === PrinterStatusSeverity.WARNING ||
severity === PrinterStatusSeverity.ERROR)) {
return reason;
}
if (reason === PrinterStatusReason.NO_ERROR) {
seenNoErrorReason = true;
}
}
return seenNoErrorReason ? PrinterStatusReason.NO_ERROR :
PrinterStatusReason.UNKNOWN_REASON;
},
/**
* @return {string} An error status for the current destination. If no error
* status exists, an empty string.
......
......@@ -36,7 +36,8 @@
no-destinations="[[noDestinations_]]"
pdf-printer-disabled="[[pdfPrinterDisabled_]]"
recent-destination-list="[[displayedDestinations_]]"
on-selected-option-change="onSelectedDestinationOptionChange_">
on-selected-option-change="onSelectedDestinationOptionChange_"
status-requested-map="[[statusRequestedMap_]]">
</print-preview-destination-select-cros>
</if>
<cr-lazy-render id="destinationDialog">
......
......@@ -22,6 +22,7 @@ import '../strings.m.js';
import {assert} from 'chrome://resources/js/assert.m.js';
import {EventTracker} from 'chrome://resources/js/event_tracker.m.js';
import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js';
import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
import {WebUIListenerBehavior} from 'chrome://resources/js/web_ui_listener_behavior.m.js';
import {beforeNextRender, html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
......@@ -153,6 +154,26 @@ Polymer({
/** @private {!Array<string>} */
users_: Array,
// <if expr="chromeos">
/** @private */
printerStatusFlagEnabled_: {
type: Boolean,
value() {
return loadTimeData.getBoolean('showPrinterStatus');
},
readOnly: true,
},
/**
* The key for this map is a destination.id and the value is a
* destination.key. This map is needed to track which destinations have had
* statuses requested while also giving quick look up of destination id to
* the corresponding destination key.
* @private {!Map<string, string>}
*/
statusRequestedMap_: Object,
// </if>
},
/** @private {string} */
......@@ -191,6 +212,10 @@ Polymer({
this.destinationStore_,
DestinationStore.EventType.DESTINATION_EULA_READY,
this.updateDestinationEulaUrl_.bind(this));
if (this.printerStatusFlagEnabled_) {
this.statusRequestedMap_ = new Map();
}
// </if>
},
......
......@@ -7,26 +7,7 @@ import './icons.js';
import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
/**
* Enumeration giving a local Chrome OS printer 3 different state possibilities
* depending on its current status.
* @enum {number}
*/
export const PrinterState = {
GOOD: 0,
ERROR: 1,
UNKNOWN: 2,
};
/**
* Enumeration used to choose styling based on whether this icon is located in
* the destination display or the destination dropdown.
* @enum {number}
*/
export const IconLocation = {
DISPLAY: 0,
DROPDOWN: 1,
};
import {IconLocation, PrinterState} from '../data/printer_status_cros.js';
Polymer({
is: 'printer-status-icon-cros',
......
......@@ -154,6 +154,7 @@ suite(printer_status_test_cros.suiteName, function() {
destinationSelect =
/** @type {!PrintPreviewDestinationSelectCrosElement} */
(document.createElement('print-preview-destination-select-cros'));
destinationSelect.statusRequestedMap = new Map();
document.body.appendChild(destinationSelect);
});
......
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