0

Refactor printing restriction policies: color, duplex, pin

Migrate Chrome OS printing restriction policies to be consistent with
other printing policies.

Mojo fields are moved from CapabilitiesResponse to Policies in
local_printer.mojom.
C++ logic is moved from LocalPrinterHandlerChromeos to
PrintPreviewHandler
JavaScript structures are moved from Destination.Policies to
NativeInitialSettings.Policies. All related logic and browser tests were
also updated.

Bug: b/172223138,crrev.com/1234467
Change-Id: I3665c7b4a2e68bd8d4a73d66d8bea4027939af34
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3054054
Reviewed-by: Rebekah Potter <rbpotter@chromium.org>
Reviewed-by: Roland Bock <rbock@google.com>
Reviewed-by: Erik Chen <erikchen@chromium.org>
Reviewed-by: Chris Palmer <palmer@chromium.org>
Commit-Queue: Jan Kopański <jkopanski@google.com>
Cr-Commit-Position: refs/heads/master@{#907882}
This commit is contained in:
Jan Kopanski
2021-08-03 08:27:01 +00:00
committed by Chromium LUCI CQ
parent 447e92cc1e
commit 43fbda13a3
24 changed files with 788 additions and 396 deletions

@@ -82,17 +82,12 @@ mojom::CapabilitiesResponsePtr OnSetUpPrinter(
const absl::optional<printing::PrinterSemanticCapsAndDefaults>& caps) { const absl::optional<printing::PrinterSemanticCapsAndDefaults>& caps) {
return mojom::CapabilitiesResponse::New( return mojom::CapabilitiesResponse::New(
LocalPrinterAsh::PrinterToMojom(printer), printer.HasSecureProtocol(), LocalPrinterAsh::PrinterToMojom(printer), printer.HasSecureProtocol(),
caps, prefs->GetInteger(prefs::kPrintingAllowedColorModes), caps, // comment to prevent git cl format
prefs->GetInteger(prefs::kPrintingAllowedDuplexModes), 0, 0, 0, // deprecated
static_cast<printing::mojom::PinModeRestriction>( printing::mojom::PinModeRestriction::kUnset, // deprecated
prefs->GetInteger(prefs::kPrintingAllowedPinModes)), printing::mojom::ColorModeRestriction::kUnset, // deprecated
static_cast<printing::mojom::ColorModeRestriction>( printing::mojom::DuplexModeRestriction::kUnset, // deprecated
prefs->GetInteger(prefs::kPrintingColorDefault)), printing::mojom::PinModeRestriction::kUnset); // deprecated
static_cast<printing::mojom::DuplexModeRestriction>(
prefs->GetInteger(prefs::kPrintingDuplexDefault)),
static_cast<printing::mojom::PinModeRestriction>(
prefs->GetInteger(prefs::kPrintingPinDefault)),
0); // deprecated
} }
} // namespace } // namespace
@@ -385,6 +380,7 @@ void LocalPrinterAsh::GetPolicies(GetPoliciesCallback callback) {
Profile* profile = GetProfile(); Profile* profile = GetProfile();
PrefService* prefs = profile->GetPrefs(); PrefService* prefs = profile->GetPrefs();
mojom::PoliciesPtr policies = mojom::Policies::New(); mojom::PoliciesPtr policies = mojom::Policies::New();
if (prefs->HasPrefPath(prefs::kPrintHeaderFooter)) { if (prefs->HasPrefPath(prefs::kPrintHeaderFooter)) {
(prefs->IsManagedPreference(prefs::kPrintHeaderFooter) (prefs->IsManagedPreference(prefs::kPrintHeaderFooter)
? policies->print_header_footer_allowed ? policies->print_header_footer_allowed
@@ -393,6 +389,7 @@ void LocalPrinterAsh::GetPolicies(GetPoliciesCallback callback) {
? mojom::Policies::OptionalBool::kTrue ? mojom::Policies::OptionalBool::kTrue
: mojom::Policies::OptionalBool::kFalse; : mojom::Policies::OptionalBool::kFalse;
} }
if (prefs->HasPrefPath(prefs::kPrintingAllowedBackgroundGraphicsModes)) { if (prefs->HasPrefPath(prefs::kPrintingAllowedBackgroundGraphicsModes)) {
policies->allowed_background_graphics_modes = policies->allowed_background_graphics_modes =
static_cast<mojom::Policies::BackgroundGraphicsModeRestriction>( static_cast<mojom::Policies::BackgroundGraphicsModeRestriction>(
@@ -403,6 +400,7 @@ void LocalPrinterAsh::GetPolicies(GetPoliciesCallback callback) {
static_cast<mojom::Policies::BackgroundGraphicsModeRestriction>( static_cast<mojom::Policies::BackgroundGraphicsModeRestriction>(
prefs->GetInteger(prefs::kPrintingBackgroundGraphicsDefault)); prefs->GetInteger(prefs::kPrintingBackgroundGraphicsDefault));
} }
policies->paper_size_default = printing::ParsePaperSizeDefault(*prefs); policies->paper_size_default = printing::ParsePaperSizeDefault(*prefs);
if (prefs->HasPrefPath(prefs::kPrintingMaxSheetsAllowed)) { if (prefs->HasPrefPath(prefs::kPrintingMaxSheetsAllowed)) {
int max_sheets = prefs->GetInteger(prefs::kPrintingMaxSheetsAllowed); int max_sheets = prefs->GetInteger(prefs::kPrintingMaxSheetsAllowed);
@@ -411,6 +409,30 @@ void LocalPrinterAsh::GetPolicies(GetPoliciesCallback callback) {
policies->max_sheets_allowed_has_value = true; policies->max_sheets_allowed_has_value = true;
} }
} }
if (prefs->HasPrefPath(prefs::kPrintingAllowedColorModes))
policies->allowed_color_modes =
prefs->GetInteger(prefs::kPrintingAllowedColorModes);
if (prefs->HasPrefPath(prefs::kPrintingAllowedDuplexModes))
policies->allowed_duplex_modes =
prefs->GetInteger(prefs::kPrintingAllowedDuplexModes);
if (prefs->HasPrefPath(prefs::kPrintingAllowedPinModes))
policies->allowed_pin_modes =
static_cast<printing::mojom::PinModeRestriction>(
prefs->GetInteger(prefs::kPrintingAllowedPinModes));
if (prefs->HasPrefPath(prefs::kPrintingColorDefault))
policies->default_color_mode =
static_cast<printing::mojom::ColorModeRestriction>(
prefs->GetInteger(prefs::kPrintingColorDefault));
if (prefs->HasPrefPath(prefs::kPrintingDuplexDefault))
policies->default_duplex_mode =
static_cast<printing::mojom::DuplexModeRestriction>(
prefs->GetInteger(prefs::kPrintingDuplexDefault));
if (prefs->HasPrefPath(prefs::kPrintingPinDefault))
policies->default_pin_mode =
static_cast<printing::mojom::PinModeRestriction>(
prefs->GetInteger(prefs::kPrintingPinDefault));
std::move(callback).Run(std::move(policies)); std::move(callback).Run(std::move(policies));
} }

@@ -458,22 +458,6 @@ TEST_F(LocalPrinterAshTest, GetPrinters) {
// Tests that fetching capabilities for an existing installed printer is // Tests that fetching capabilities for an existing installed printer is
// successful. // successful.
TEST_P(LocalPrinterAshProcessScopeTest, GetCapabilityValidPrinter) { TEST_P(LocalPrinterAshProcessScopeTest, GetCapabilityValidPrinter) {
auto* prefs = GetPrefs();
// printing::mojom::ColorModeRestriction::kMonochrome |
// printing::mojom::ColorModeRestriction::kColor
prefs->SetInteger(prefs::kPrintingAllowedColorModes, 3);
// printing::mojom::DuplexModeRestriction::kSimplex |
// printing::mojom::DuplexModeRestriction::kDuplex
prefs->SetInteger(prefs::kPrintingAllowedDuplexModes, 7);
// printing::mojom::PinModeRestriction::kPin
prefs->SetInteger(prefs::kPrintingAllowedPinModes, 1);
// printing::mojom::ColorModeRestriction::kColor
prefs->SetInteger(prefs::kPrintingColorDefault, 2);
// printing::mojom::DuplexModeRestriction::kSimplex
prefs->SetInteger(prefs::kPrintingDuplexDefault, 1);
// printing::mojom::PinModeRestriction::kNoPin
prefs->SetInteger(prefs::kPrintingPinDefault, 2);
Printer saved_printer = Printer saved_printer =
CreateTestPrinter("printer1", "saved", "description1"); CreateTestPrinter("printer1", "saved", "description1");
printers_manager().AddPrinter(saved_printer, PrinterClass::kSaved); printers_manager().AddPrinter(saved_printer, PrinterClass::kSaved);
@@ -499,21 +483,6 @@ TEST_P(LocalPrinterAshProcessScopeTest, GetCapabilityValidPrinter) {
ASSERT_TRUE(fetched_caps->basic_info->uri); ASSERT_TRUE(fetched_caps->basic_info->uri);
EXPECT_EQ(kPrinterUri, *fetched_caps->basic_info->uri); EXPECT_EQ(kPrinterUri, *fetched_caps->basic_info->uri);
// printing::mojom::ColorModeRestriction::kMonochrome |
// printing::mojom::ColorModeRestriction::kColor
EXPECT_EQ(3, fetched_caps->allowed_color_modes);
// printing::mojom::DuplexModeRestriction::kSimplex |
// printing::mojom::DuplexModeRestriction::kDuplex
EXPECT_EQ(7, fetched_caps->allowed_duplex_modes);
EXPECT_EQ(printing::mojom::PinModeRestriction::kPin,
fetched_caps->allowed_pin_modes);
EXPECT_EQ(printing::mojom::ColorModeRestriction::kColor,
fetched_caps->default_color_mode);
EXPECT_EQ(printing::mojom::DuplexModeRestriction::kSimplex,
fetched_caps->default_duplex_mode);
EXPECT_EQ(printing::mojom::PinModeRestriction::kNoPin,
fetched_caps->default_pin_mode);
ASSERT_TRUE(fetched_caps->capabilities); ASSERT_TRUE(fetched_caps->capabilities);
EXPECT_EQ(kPapers, fetched_caps->capabilities->papers); EXPECT_EQ(kPapers, fetched_caps->capabilities->papers);
} }
@@ -859,6 +828,55 @@ TEST_F(LocalPrinterAshTest, GetPolicies_PrintHeaderFooter_ManagedEnabled) {
policies->print_header_footer_default); policies->print_header_footer_default);
} }
TEST_F(LocalPrinterAshTest, GetPolicies_Color) {
const uint32_t expected_allowed_color_modes = static_cast<uint32_t>(
static_cast<int32_t>(printing::mojom::ColorModeRestriction::kMonochrome) |
static_cast<int32_t>(printing::mojom::ColorModeRestriction::kColor));
auto* prefs = GetPrefs();
prefs->SetInteger(prefs::kPrintingAllowedColorModes, 3);
prefs->SetInteger(prefs::kPrintingColorDefault, 2);
crosapi::mojom::PoliciesPtr policies;
local_printer_ash()->GetPolicies(base::BindOnce(base::BindLambdaForTesting(
[&](crosapi::mojom::PoliciesPtr data) { policies = std::move(data); })));
EXPECT_EQ(expected_allowed_color_modes, policies->allowed_color_modes);
EXPECT_EQ(printing::mojom::ColorModeRestriction::kColor,
policies->default_color_mode);
}
TEST_F(LocalPrinterAshTest, GetPolicies_Duplex) {
const uint32_t expected_allowed_duplex_modes = static_cast<uint32_t>(
static_cast<int32_t>(printing::mojom::DuplexModeRestriction::kSimplex) |
static_cast<int32_t>(printing::mojom::DuplexModeRestriction::kDuplex));
auto* prefs = GetPrefs();
prefs->SetInteger(prefs::kPrintingAllowedDuplexModes, 7);
prefs->SetInteger(prefs::kPrintingDuplexDefault, 1);
crosapi::mojom::PoliciesPtr policies;
local_printer_ash()->GetPolicies(base::BindOnce(base::BindLambdaForTesting(
[&](crosapi::mojom::PoliciesPtr data) { policies = std::move(data); })));
EXPECT_EQ(expected_allowed_duplex_modes, policies->allowed_duplex_modes);
EXPECT_EQ(printing::mojom::DuplexModeRestriction::kSimplex,
policies->default_duplex_mode);
}
TEST_F(LocalPrinterAshTest, GetPolicies_Pin) {
auto* prefs = GetPrefs();
prefs->SetInteger(prefs::kPrintingAllowedPinModes, 1);
prefs->SetInteger(prefs::kPrintingPinDefault, 2);
crosapi::mojom::PoliciesPtr policies;
local_printer_ash()->GetPolicies(base::BindOnce(base::BindLambdaForTesting(
[&](crosapi::mojom::PoliciesPtr data) { policies = std::move(data); })));
EXPECT_EQ(printing::mojom::PinModeRestriction::kPin,
policies->allowed_pin_modes);
EXPECT_EQ(printing::mojom::PinModeRestriction::kNoPin,
policies->default_pin_mode);
}
TEST_F(LocalPrinterAshTest, GetUsernamePerPolicy_Allowed) { TEST_F(LocalPrinterAshTest, GetUsernamePerPolicy_Allowed) {
SetUsername("user@email.com"); SetUsername("user@email.com");
GetPrefs()->SetBoolean(prefs::kPrintingSendUsernameAndFilenameEnabled, true); GetPrefs()->SetBoolean(prefs::kPrintingSendUsernameAndFilenameEnabled, true);

@@ -94,7 +94,6 @@ preprocess_if_expr("preprocess") {
"data/coordinate2d.js", "data/coordinate2d.js",
"data/destination.js", "data/destination.js",
"data/destination_match.js", "data/destination_match.js",
"data/destination_policies.js",
"data/destination_store.js", "data/destination_store.js",
"data/document_info.js", "data/document_info.js",
"data/local_parsers.js", "data/local_parsers.js",
@@ -327,7 +326,6 @@ js_library("native_layer") {
js_library("native_layer_cros") { js_library("native_layer_cros") {
deps = [ deps = [
"data:destination_policies",
"data:printer_status_cros", "data:printer_status_cros",
"//ui/webui/resources/js:assert.m", "//ui/webui/resources/js:assert.m",
"//ui/webui/resources/js:cr.m", "//ui/webui/resources/js:cr.m",

@@ -14,7 +14,6 @@ js_type_check("closure_compile_module") {
":coordinate2d", ":coordinate2d",
":destination", ":destination",
":destination_match", ":destination_match",
":destination_policies",
":destination_store", ":destination_store",
":document_info", ":document_info",
":local_parsers", ":local_parsers",
@@ -37,9 +36,6 @@ js_type_check("closure_compile_module") {
js_library("cdd") { js_library("cdd") {
} }
js_library("destination_policies") {
}
js_library("destination_store") { js_library("destination_store") {
deps = [ deps = [
":cdd", ":cdd",
@@ -72,7 +68,6 @@ js_library("local_parsers") {
deps = [ deps = [
":destination", ":destination",
":destination_match", ":destination_match",
":destination_policies",
"..:native_layer", "..:native_layer",
"//ui/webui/resources/js:cr.m", "//ui/webui/resources/js:cr.m",
] ]
@@ -100,10 +95,7 @@ js_library("destination") {
] ]
if (is_chromeos) { if (is_chromeos) {
deps += [ deps += [ "..:native_layer_cros" ]
":destination_policies",
"..:native_layer_cros",
]
} }
} }

@@ -12,7 +12,6 @@ import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
import {NativeLayerCrosImpl} from '../native_layer_cros.js'; import {NativeLayerCrosImpl} from '../native_layer_cros.js';
import {Cdd} from './cdd.js'; import {Cdd} from './cdd.js';
import {ColorModeRestriction, DestinationPolicies, DuplexModeRestriction, PinModeRestriction} from './destination_policies.js';
import {getStatusReasonFromPrinterStatus, PrinterStatus, PrinterStatusReason} from './printer_status_cros.js'; import {getStatusReasonFromPrinterStatus, PrinterStatus, PrinterStatusReason} from './printer_status_cros.js';
// </if> // </if>
@@ -185,7 +184,6 @@ export class Destination {
* description: (string|undefined), * description: (string|undefined),
* certificateStatus: * certificateStatus:
* (DestinationCertificateStatus|undefined), * (DestinationCertificateStatus|undefined),
* policies: (DestinationPolicies|undefined),
* }=} opt_params Optional * }=} opt_params Optional
* parameters for the destination. * parameters for the destination.
*/ */
@@ -226,12 +224,6 @@ export class Destination {
*/ */
this.capabilities_ = null; this.capabilities_ = null;
/**
* Policies affecting the destination.
* @private {?DestinationPolicies}
*/
this.policies_ = (opt_params && opt_params.policies) || null;
/** /**
* Whether the destination is owned by the user. * Whether the destination is owned by the user.
* @private {boolean} * @private {boolean}
@@ -499,21 +491,6 @@ export class Destination {
} }
// <if expr="chromeos or lacros"> // <if expr="chromeos or lacros">
/**
* @return {?DestinationPolicies} Print policies affecting the destination.
*/
get policies() {
return this.policies_;
}
/**
* @param {?DestinationPolicies} policies Print policies affecting the
* destination.
*/
set policies(policies) {
this.policies_ = policies;
}
/** @return {string} The EULA URL for a the destination */ /** @return {string} The EULA URL for a the destination */
get eulaUrl() { get eulaUrl() {
return this.eulaUrl_; return this.eulaUrl_;
@@ -808,37 +785,6 @@ export class Destination {
null; null;
} }
// <if expr="chromeos or lacros">
/**
* @return {?ColorModeRestriction} Color mode set by policy.
*/
get colorPolicy() {
return this.policies && this.policies.allowedColorModes ?
this.policies.allowedColorModes :
null;
}
/**
* @return {?DuplexModeRestriction} Duplex modes allowed by
* policy.
*/
get duplexPolicy() {
return this.policies && this.policies.allowedDuplexModes ?
this.policies.allowedDuplexModes :
null;
}
/**
* @return {?PinModeRestriction} Pin mode allowed by policy.
*/
get pinPolicy() {
return this.policies && this.policies.allowedPinModes ?
this.policies.allowedPinModes :
null;
}
// </if>
/** @return {boolean} Whether the printer supports copies. */ /** @return {boolean} Whether the printer supports copies. */
get hasCopiesCapability() { get hasCopiesCapability() {
const capability = this.copiesCapability_(); const capability = this.copiesCapability_();
@@ -868,32 +814,6 @@ export class Destination {
return hasColor && hasMonochrome; return hasColor && hasMonochrome;
} }
// <if expr="chromeos or lacros">
/**
* @return {?ColorModeRestriction} Value of default color
* setting given by policy.
*/
get defaultColorPolicy() {
return this.policies && this.policies.defaultColorMode;
}
/**
* @return {?DuplexModeRestriction} Value of default duplex
* setting given by policy.
*/
get defaultDuplexPolicy() {
return this.policies && this.policies.defaultDuplexMode;
}
/**
* @return {?PinModeRestriction} Value of default pin setting
* given by policy.
*/
get defaultPinPolicy() {
return this.policies && this.policies.defaultPinMode;
}
// </if>
/** /**
* @param {boolean} isColor Whether to use a color printing mode. * @param {boolean} isColor Whether to use a color printing mode.
* @return {Object} Selected color option. * @return {Object} Selected color option.

@@ -1,54 +0,0 @@
// Copyright 2019 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.
/**
* Enumeration of color mode restrictions used by Chromium.
* This has to coincide with |printing::ColorModeRestriction| as defined in
* printing/backend/printing_restrictions.h
* @enum {number}
*/
export const ColorModeRestriction = {
UNSET: 0x0,
MONOCHROME: 0x1,
COLOR: 0x2,
};
/**
* Enumeration of duplex mode restrictions used by Chromium.
* This has to coincide with |printing::DuplexModeRestriction| as defined in
* printing/backend/printing_restrictions.h
* @enum {number}
*/
export const DuplexModeRestriction = {
UNSET: 0x0,
SIMPLEX: 0x1,
LONG_EDGE: 0x2,
SHORT_EDGE: 0x4,
DUPLEX: 0x6,
};
/**
* Enumeration of PIN printing mode restrictions used by Chromium.
* This has to coincide with |printing::PinModeRestriction| as defined in
* printing/backend/printing_restrictions.h
* @enum {number}
*/
export const PinModeRestriction = {
UNSET: 0,
PIN: 1,
NO_PIN: 2,
};
/**
* Policies affecting a destination.
* @typedef {{
* allowedColorModes: ?ColorModeRestriction,
* allowedDuplexModes: ?DuplexModeRestriction,
* allowedPinMode: ?PinModeRestriction,
* defaultColorMode: ?ColorModeRestriction,
* defaultDuplexMode: ?DuplexModeRestriction,
* defaultPinMode: ?PinModeRestriction,
* }}
*/
export let DestinationPolicies;

@@ -1099,9 +1099,6 @@ export class DestinationStore extends EventTarget {
parseDestination(originToType(origin), assert(settingsInfo.printer))); parseDestination(originToType(origin), assert(settingsInfo.printer)));
} }
if (dest) { if (dest) {
if (settingsInfo.printer && settingsInfo.printer.policies) {
dest.policies = settingsInfo.printer.policies;
}
if ((origin === DestinationOrigin.LOCAL || if ((origin === DestinationOrigin.LOCAL ||
origin === DestinationOrigin.CROS) && origin === DestinationOrigin.CROS) &&
dest.capabilities) { dest.capabilities) {

@@ -7,9 +7,6 @@ import {isChromeOS, isLacros} from 'chrome://resources/js/cr.m.js';
import {Destination, DestinationConnectionStatus, DestinationOrigin, DestinationProvisionalType, DestinationType} from './destination.js'; import {Destination, DestinationConnectionStatus, DestinationOrigin, DestinationProvisionalType, DestinationType} from './destination.js';
import {PrinterType} from './destination_match.js'; import {PrinterType} from './destination_match.js';
// <if expr="chromeos or lacros">
import {DestinationPolicies} from './destination_policies.js';
// </if>
/** /**
* @typedef {{ * @typedef {{
@@ -18,7 +15,6 @@ import {DestinationPolicies} from './destination_policies.js';
* printerDescription: (string | undefined), * printerDescription: (string | undefined),
* cupsEnterprisePrinter: (boolean | undefined), * cupsEnterprisePrinter: (boolean | undefined),
* printerOptions: (Object | undefined), * printerOptions: (Object | undefined),
* policies: (DestinationPolicies | undefined),
* }} * }}
*/ */
export let LocalDestinationInfo; export let LocalDestinationInfo;
@@ -81,7 +77,6 @@ function parseLocalDestination(destinationInfo) {
const options = { const options = {
description: destinationInfo.printerDescription, description: destinationInfo.printerDescription,
isEnterprisePrinter: destinationInfo.cupsEnterprisePrinter, isEnterprisePrinter: destinationInfo.cupsEnterprisePrinter,
policies: destinationInfo.policies,
}; };
if (destinationInfo.printerOptions) { if (destinationInfo.printerOptions) {
// Convert options into cloud print tags format. // Convert options into cloud print tags format.

@@ -8,13 +8,10 @@ import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
import {PromiseResolver} from 'chrome://resources/js/promise_resolver.m.js'; import {PromiseResolver} from 'chrome://resources/js/promise_resolver.m.js';
import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
import {BackgroundGraphicsModeRestriction, Policies} from '../native_layer.js'; import {BackgroundGraphicsModeRestriction, ColorModeRestriction, DuplexModeRestriction, PinModeRestriction, Policies} from '../native_layer.js';
import {Cdd, CddCapabilities, VendorCapability} from './cdd.js'; import {Cdd, CddCapabilities, VendorCapability} from './cdd.js';
import {Destination, DestinationOrigin, DestinationType, RecentDestination} from './destination.js'; import {Destination, DestinationOrigin, DestinationType, RecentDestination} from './destination.js';
import {getPrinterTypeForDestination, PrinterType} from './destination_match.js'; import {getPrinterTypeForDestination, PrinterType} from './destination_match.js';
// <if expr="chromeos or lacros">
import {ColorModeRestriction, DuplexModeRestriction, PinModeRestriction} from './destination_policies.js';
// </if>
import {DocumentSettings} from './document_info.js'; import {DocumentSettings} from './document_info.js';
import {CustomMarginsOrientation, Margins, MarginsSetting, MarginsType} from './margins.js'; import {CustomMarginsOrientation, Margins, MarginsSetting, MarginsType} from './margins.js';
import {ScalingType} from './scaling.js'; import {ScalingType} from './scaling.js';
@@ -112,6 +109,9 @@ export let PolicyEntry;
* cssBackground: (PolicyEntry | undefined), * cssBackground: (PolicyEntry | undefined),
* mediaSize: (PolicyEntry | undefined), * mediaSize: (PolicyEntry | undefined),
* sheets: (number | undefined), * sheets: (number | undefined),
* color: (PolicyEntry | undefined),
* duplex: (PolicyEntry | undefined),
* pin: (PolicyEntry | undefined),
* }} * }}
*/ */
export let PolicySettings; export let PolicySettings;
@@ -1108,6 +1108,33 @@ export class PrintPreviewModelElement extends PolymerElement {
} }
break; break;
} }
case 'color': {
const value = allowedMode ? allowedMode : defaultMode;
if (value !== undefined) {
this.setPolicySetting_(
settingName, value, !!allowedMode,
/*applyOnDestinationUpdate=*/ false);
}
break;
}
case 'duplex': {
const value = allowedMode ? allowedMode : defaultMode;
if (value !== undefined) {
this.setPolicySetting_(
settingName, value, !!allowedMode,
/*applyOnDestinationUpdate=*/ false);
}
break;
}
case 'pin': {
const value = allowedMode ? allowedMode : defaultMode;
if (value !== undefined) {
this.setPolicySetting_(
settingName, value, !!allowedMode,
/*applyOnDestinationUpdate=*/ false);
}
break;
}
default: default:
break; break;
} }
@@ -1140,6 +1167,14 @@ export class PrintPreviewModelElement extends PolymerElement {
applyOnDestinationUpdate: false applyOnDestinationUpdate: false
}; };
} }
['color', 'duplex', 'pin'].forEach(settingName => {
if (!policies[settingName]) {
return;
}
const defaultMode = policies[settingName].defaultMode;
const allowedMode = policies[settingName].allowedMode;
this.configurePolicySetting_(settingName, allowedMode, defaultMode);
});
// </if> // </if>
} }
@@ -1202,6 +1237,42 @@ export class PrintPreviewModelElement extends PolymerElement {
this.maxSheets = this.policySettings_['sheets'].value; this.maxSheets = this.policySettings_['sheets'].value;
continue; continue;
} }
if (settingName === 'color') {
this.set(
'settings.color.value',
policy.value === ColorModeRestriction.COLOR);
this.set('settings.color.setByPolicy', policy.managed);
continue;
}
if (settingName === 'duplex') {
let setDuplexTypeByPolicy = false;
this.set(
'settings.duplex.value',
policy.value !== DuplexModeRestriction.SIMPLEX);
if (policy.value === DuplexModeRestriction.SHORT_EDGE) {
this.set('settings.duplexShortEdge.value', true);
setDuplexTypeByPolicy = true;
} else if (policy.value === DuplexModeRestriction.LONG_EDGE) {
this.set('settings.duplexShortEdge.value', false);
setDuplexTypeByPolicy = true;
}
this.set('settings.duplex.setByPolicy', policy.managed);
this.set(
'settings.duplexShortEdge.setByPolicy',
policy.managed && setDuplexTypeByPolicy);
continue;
}
if (settingName === 'pin') {
if (policy.value === PinModeRestriction.NO_PIN && policy.managed) {
this.set('settings.pin.available', false);
this.set('settings.pinValue.available', false);
} else {
this.set(
'settings.pin.value', policy.value === PinModeRestriction.PIN);
}
this.set('settings.pin.setByPolicy', policy.managed);
continue;
}
// </if> // </if>
if (policy.value !== undefined && !policy.applyOnDestinationUpdate) { if (policy.value !== undefined && !policy.applyOnDestinationUpdate) {
this.setSetting(settingName, policy.value, true); this.setSetting(settingName, policy.value, true);
@@ -1213,58 +1284,11 @@ export class PrintPreviewModelElement extends PolymerElement {
} }
} }
// TODO (crbug.com/1069802): Migrate these policies from Destination.policies
// to NativeInitialSettings.policies.
/** /**
* Restricts settings and applies defaults as defined by policy applicable to * Restricts settings and applies defaults as defined by policy applicable to
* current destination. * current destination.
*/ */
applyDestinationSpecificPolicies() { applyDestinationSpecificPolicies() {
// <if expr="chromeos or lacros">
const colorPolicy = this.destination.colorPolicy;
const colorValue =
colorPolicy ? colorPolicy : this.destination.defaultColorPolicy;
if (colorValue) {
// |this.setSetting| does nothing if policy is present.
// We want to set the value nevertheless so we call |this.set| directly.
this.set(
'settings.color.value', colorValue === ColorModeRestriction.COLOR);
}
this.set('settings.color.setByPolicy', !!colorPolicy);
const duplexPolicy = this.destination.duplexPolicy;
const duplexValue =
duplexPolicy ? duplexPolicy : this.destination.defaultDuplexPolicy;
let setDuplexTypeByPolicy = false;
if (duplexValue) {
this.set(
'settings.duplex.value',
duplexValue !== DuplexModeRestriction.SIMPLEX);
if (duplexValue === DuplexModeRestriction.SHORT_EDGE) {
this.set('settings.duplexShortEdge.value', true);
setDuplexTypeByPolicy = true;
} else if (duplexValue === DuplexModeRestriction.LONG_EDGE) {
this.set('settings.duplexShortEdge.value', false);
setDuplexTypeByPolicy = true;
}
}
this.set('settings.duplex.setByPolicy', !!duplexPolicy);
this.set(
'settings.duplexShortEdge.setByPolicy',
!!duplexPolicy && setDuplexTypeByPolicy);
const pinPolicy = this.destination.pinPolicy;
if (pinPolicy === PinModeRestriction.NO_PIN) {
this.set('settings.pin.available', false);
this.set('settings.pinValue.available', false);
}
const pinValue = pinPolicy ? pinPolicy : this.destination.defaultPinPolicy;
if (pinValue) {
this.set('settings.pin.value', pinValue === PinModeRestriction.PIN);
}
this.set('settings.pin.setByPolicy', !!pinPolicy);
// </if>
if (this.settings.mediaSize.available && this.policySettings_) { if (this.settings.mediaSize.available && this.policySettings_) {
const mediaSizePolicy = this.policySettings_['mediaSize'] && const mediaSizePolicy = this.policySettings_['mediaSize'] &&
this.policySettings_['mediaSize'].value; this.policySettings_['mediaSize'].value;

@@ -6,7 +6,6 @@ import {assert} from 'chrome://resources/js/assert.m.js';
import {addSingletonGetter, sendWithPromise} from 'chrome://resources/js/cr.m.js'; import {addSingletonGetter, sendWithPromise} from 'chrome://resources/js/cr.m.js';
import {Cdd} from './data/cdd.js'; import {Cdd} from './data/cdd.js';
import {Destination} from './data/destination.js';
import {PrinterType} from './data/destination_match.js'; import {PrinterType} from './data/destination_match.js';
import {LocalDestinationInfo, PrivetPrinterDescription} from './data/local_parsers.js'; import {LocalDestinationInfo, PrivetPrinterDescription} from './data/local_parsers.js';
import {MeasurementSystemUnitType} from './data/measurement_system.js'; import {MeasurementSystemUnitType} from './data/measurement_system.js';
@@ -35,6 +34,44 @@ export const BackgroundGraphicsModeRestriction = {
DISABLED: 2, DISABLED: 2,
}; };
/**
* Enumeration of color mode restrictions used by Chromium.
* This has to coincide with |printing::ColorModeRestriction| as defined in
* printing/backend/printing_restrictions.h
* @enum {number}
*/
export const ColorModeRestriction = {
UNSET: 0x0,
MONOCHROME: 0x1,
COLOR: 0x2,
};
/**
* Enumeration of duplex mode restrictions used by Chromium.
* This has to coincide with |printing::DuplexModeRestriction| as defined in
* printing/backend/printing_restrictions.h
* @enum {number}
*/
export const DuplexModeRestriction = {
UNSET: 0x0,
SIMPLEX: 0x1,
LONG_EDGE: 0x2,
SHORT_EDGE: 0x4,
DUPLEX: 0x6,
};
/**
* Enumeration of PIN printing mode restrictions used by Chromium.
* This has to coincide with |printing::PinModeRestriction| as defined in
* printing/backend/printing_restrictions.h
* @enum {number}
*/
export const PinModeRestriction = {
UNSET: 0,
PIN: 1,
NO_PIN: 2,
};
/** /**
* Policies affecting print settings values and availability. * Policies affecting print settings values and availability.
* @typedef {{ * @typedef {{
@@ -54,7 +91,19 @@ export const BackgroundGraphicsModeRestriction = {
* } | undefined), * } | undefined),
* sheets: ({ * sheets: ({
* value: (number | undefined), * value: (number | undefined),
* } | undefined) * } | undefined),
* color: ({
* allowedMode: (ColorModeRestriction | undefined),
* defaultMode: (ColorModeRestriction | undefined),
* } | undefined),
* duplex: ({
* allowedMode: (DuplexModeRestriction | undefined),
* defaultMode: (DuplexModeRestriction | undefined),
* } | undefined),
* pin: ({
* allowedMode: (PinModeRestriction | undefined),
* defaultMode: (PinModeRestriction | undefined),
* } | undefined),
* }} * }}
*/ */
export let Policies; export let Policies;

@@ -6,7 +6,6 @@ import {assert} from 'chrome://resources/js/assert.m.js';
import {addSingletonGetter, sendWithPromise} from 'chrome://resources/js/cr.m.js'; import {addSingletonGetter, sendWithPromise} from 'chrome://resources/js/cr.m.js';
import {Cdd} from './data/cdd.js'; import {Cdd} from './data/cdd.js';
import {DestinationPolicies} from './data/destination_policies.js';
import {ProvisionalDestinationInfo} from './data/local_parsers.js'; import {ProvisionalDestinationInfo} from './data/local_parsers.js';
import {PrinterStatus, PrinterStatusReason} from './data/printer_status_cros.js'; import {PrinterStatus, PrinterStatusReason} from './data/printer_status_cros.js';
@@ -14,7 +13,6 @@ import {PrinterStatus, PrinterStatusReason} from './data/printer_status_cros.js'
* @typedef {{ * @typedef {{
* printerId: string, * printerId: string,
* capabilities: !Cdd, * capabilities: !Cdd,
* policies: (DestinationPolicies | undefined),
* }} * }}
*/ */
export let PrinterSetupResponse; export let PrinterSetupResponse;

@@ -13,9 +13,6 @@ export {ColorMode, createDestinationKey, Destination, DestinationCertificateStat
export {SAVE_TO_DRIVE_CROS_DESTINATION_KEY} from './data/destination.js'; export {SAVE_TO_DRIVE_CROS_DESTINATION_KEY} from './data/destination.js';
// </if> // </if>
export {PrinterType} from './data/destination_match.js'; export {PrinterType} from './data/destination_match.js';
// <if expr="chromeos or lacros">
export {ColorModeRestriction, DuplexModeRestriction, PinModeRestriction} from './data/destination_policies.js';
// </if>
export {DestinationErrorType, DestinationStore} from './data/destination_store.js'; export {DestinationErrorType, DestinationStore} from './data/destination_store.js';
export {PageLayoutInfo} from './data/document_info.js'; export {PageLayoutInfo} from './data/document_info.js';
export {LocalDestinationInfo, ProvisionalDestinationInfo} from './data/local_parsers.js'; export {LocalDestinationInfo, ProvisionalDestinationInfo} from './data/local_parsers.js';
@@ -31,7 +28,7 @@ export {PrinterState, PrinterStatus, PrinterStatusReason, PrinterStatusSeverity}
export {ScalingType} from './data/scaling.js'; export {ScalingType} from './data/scaling.js';
export {Size} from './data/size.js'; export {Size} from './data/size.js';
export {Error, State} from './data/state.js'; export {Error, State} from './data/state.js';
export {BackgroundGraphicsModeRestriction, CapabilitiesResponse, NativeInitialSettings, NativeLayer, NativeLayerImpl} from './native_layer.js'; export {BackgroundGraphicsModeRestriction, CapabilitiesResponse, ColorModeRestriction, DuplexModeRestriction, NativeInitialSettings, NativeLayer, NativeLayerImpl, PinModeRestriction} from './native_layer.js';
// <if expr="chromeos or lacros"> // <if expr="chromeos or lacros">
export {NativeLayerCros, NativeLayerCrosImpl, PrinterSetupResponse, PrintServer, PrintServersConfig} from './native_layer_cros.js'; export {NativeLayerCros, NativeLayerCrosImpl, PrinterSetupResponse, PrintServer, PrintServersConfig} from './native_layer_cros.js';
// </if> // </if>

@@ -300,9 +300,6 @@ Polymer({
this.destinationInConfiguring_ = null; this.destinationInConfiguring_ = null;
listItem.onConfigureComplete(true); listItem.onConfigureComplete(true);
destination.capabilities = response.capabilities; destination.capabilities = response.capabilities;
if (response.policies) {
destination.policies = response.policies;
}
this.selectDestination_(destination); this.selectDestination_(destination);
// After destination is selected, start fetching for the EULA // After destination is selected, start fetching for the EULA
// URL. // URL.

@@ -118,17 +118,24 @@ base::Value LocalPrinterHandlerChromeos::CapabilityToValue(
: kValueFalse}}), : kValueFalse}}),
PrinterSemanticCapsAndDefaults::Papers(), caps->has_secure_protocol, PrinterSemanticCapsAndDefaults::Papers(), caps->has_secure_protocol,
base::OptionalOrNullptr(caps->capabilities)); base::OptionalOrNullptr(caps->capabilities));
// TODO(b/195001379, jkopanski): This block of code should be removed once
// Ash Chrome M94 is on stable channel.
base::Value policies(base::Value::Type::DICTIONARY); base::Value policies(base::Value::Type::DICTIONARY);
policies.SetIntKey(kAllowedColorModes, caps->allowed_color_modes); policies.SetIntKey(kAllowedColorModes, caps->allowed_color_modes_deprecated);
policies.SetIntKey(kAllowedDuplexModes, caps->allowed_duplex_modes); policies.SetIntKey(kAllowedDuplexModes,
policies.SetIntKey(kAllowedPinModes, caps->allowed_duplex_modes_deprecated);
static_cast<int>(caps->allowed_pin_modes)); policies.SetIntKey(
kAllowedPinModes,
static_cast<int>(caps->allowed_pin_modes_deprecated_version_1));
policies.SetIntKey(kDefaultColorMode, policies.SetIntKey(kDefaultColorMode,
static_cast<int>(caps->default_color_mode)); static_cast<int>(caps->default_color_mode_deprecated));
policies.SetIntKey(kDefaultDuplexMode, policies.SetIntKey(kDefaultDuplexMode,
static_cast<int>(caps->default_duplex_mode)); static_cast<int>(caps->default_duplex_mode_deprecated));
policies.SetIntKey(kDefaultPinMode, static_cast<int>(caps->default_pin_mode)); policies.SetIntKey(kDefaultPinMode,
static_cast<int>(caps->default_pin_mode_deprecated));
dict.FindKey(kPrinter)->SetKey(kSettingPolicies, std::move(policies)); dict.FindKey(kPrinter)->SetKey(kSettingPolicies, std::move(policies));
return dict; return dict;
} }

@@ -159,12 +159,21 @@ TEST(LocalPrinterHandlerChromeos, CapabilityToValue) {
auto caps = crosapi::mojom::CapabilitiesResponse::New(); auto caps = crosapi::mojom::CapabilitiesResponse::New();
caps->basic_info = crosapi::mojom::LocalDestinationInfo::New( caps->basic_info = crosapi::mojom::LocalDestinationInfo::New(
"device_name", "printer_name", "printer_description", false); "device_name", "printer_name", "printer_description", false);
caps->allowed_color_modes = 1;
caps->allowed_duplex_modes = 2; // TODO(b/195001379, jkopanski): This block of code should be removed once
caps->allowed_pin_modes = printing::mojom::PinModeRestriction::kPin; // Ash Chrome M94 is on stable channel. Also remove associated "policies"
caps->default_color_mode = printing::mojom::ColorModeRestriction::kColor; // field in kExpectedValue below.
caps->default_duplex_mode = printing::mojom::DuplexModeRestriction::kSimplex; caps->allowed_color_modes_deprecated = 1;
caps->default_pin_mode = printing::mojom::PinModeRestriction::kNoPin; caps->allowed_duplex_modes_deprecated = 2;
caps->allowed_pin_modes_deprecated_version_1 =
printing::mojom::PinModeRestriction::kPin;
caps->default_color_mode_deprecated =
printing::mojom::ColorModeRestriction::kColor;
caps->default_duplex_mode_deprecated =
printing::mojom::DuplexModeRestriction::kSimplex;
caps->default_pin_mode_deprecated =
printing::mojom::PinModeRestriction::kNoPin;
const base::Value kExpectedValue = *base::JSONReader::Read(R"({ const base::Value kExpectedValue = *base::JSONReader::Read(R"({
"printer": { "printer": {
"cupsEnterprisePrinter": false, "cupsEnterprisePrinter": false,
@@ -190,12 +199,21 @@ TEST(LocalPrinterHandlerChromeos, CapabilityToValue_ConfiguredViaPolicy) {
auto caps = crosapi::mojom::CapabilitiesResponse::New(); auto caps = crosapi::mojom::CapabilitiesResponse::New();
caps->basic_info = crosapi::mojom::LocalDestinationInfo::New( caps->basic_info = crosapi::mojom::LocalDestinationInfo::New(
"device_name", "printer_name", "printer_description", true); "device_name", "printer_name", "printer_description", true);
caps->allowed_color_modes = 1;
caps->allowed_duplex_modes = 2; // TODO(b/195001379, jkopanski): This block of code should be removed once
caps->allowed_pin_modes = printing::mojom::PinModeRestriction::kPin; // Ash Chrome M94 is on stable channel. Also remove associated "policies"
caps->default_color_mode = printing::mojom::ColorModeRestriction::kColor; // field in kExpectedValue below.
caps->default_duplex_mode = printing::mojom::DuplexModeRestriction::kSimplex; caps->allowed_color_modes_deprecated = 1;
caps->default_pin_mode = printing::mojom::PinModeRestriction::kNoPin; caps->allowed_duplex_modes_deprecated = 2;
caps->allowed_pin_modes_deprecated_version_1 =
printing::mojom::PinModeRestriction::kPin;
caps->default_color_mode_deprecated =
printing::mojom::ColorModeRestriction::kColor;
caps->default_duplex_mode_deprecated =
printing::mojom::DuplexModeRestriction::kSimplex;
caps->default_pin_mode_deprecated =
printing::mojom::PinModeRestriction::kNoPin;
const base::Value kExpectedValue = *base::JSONReader::Read(R"({ const base::Value kExpectedValue = *base::JSONReader::Read(R"({
"printer": { "printer": {
"cupsEnterprisePrinter": true, "cupsEnterprisePrinter": true,

@@ -181,6 +181,12 @@ const char kMediaSize[] = "mediaSize";
const char kValue[] = "value"; const char kValue[] = "value";
// Name of a dictionary pref holding the policy value for the sheets number. // Name of a dictionary pref holding the policy value for the sheets number.
const char kSheets[] = "sheets"; const char kSheets[] = "sheets";
// Name of a dictionary pref holding the policy value for the color setting.
const char kColor[] = "color";
// Name of a dictionary pref holding the policy value for the duplex setting.
const char kDuplex[] = "duplex";
// Name of a dictionary pref holding the policy value for the pin setting.
const char kPin[] = "pin";
#endif // defined(OS_CHROMEOS) #endif // defined(OS_CHROMEOS)
// Name of a dictionary field indicating whether the 'Save to PDF' destination // Name of a dictionary field indicating whether the 'Save to PDF' destination
// is disabled. // is disabled.
@@ -300,6 +306,36 @@ base::Value PoliciesToValue(crosapi::mojom::PoliciesPtr ptr) {
policies.SetKey(kSheets, std::move(sheets_policy)); policies.SetKey(kSheets, std::move(sheets_policy));
} }
base::Value color_policy(base::Value::Type::DICTIONARY);
if (ptr->allowed_color_modes)
color_policy.SetIntKey(kAllowedMode,
static_cast<int>(ptr->allowed_color_modes));
if (ptr->default_color_mode != printing::mojom::ColorModeRestriction::kUnset)
color_policy.SetIntKey(kDefaultMode,
static_cast<int>(ptr->default_color_mode));
if (!color_policy.DictEmpty())
policies.SetKey(kColor, std::move(color_policy));
base::Value duplex_policy(base::Value::Type::DICTIONARY);
if (ptr->allowed_duplex_modes)
duplex_policy.SetIntKey(kAllowedMode,
static_cast<int>(ptr->allowed_duplex_modes));
if (ptr->default_duplex_mode !=
printing::mojom::DuplexModeRestriction::kUnset)
duplex_policy.SetIntKey(kDefaultMode,
static_cast<int>(ptr->default_duplex_mode));
if (!duplex_policy.DictEmpty())
policies.SetKey(kDuplex, std::move(duplex_policy));
base::Value pin_policy(base::Value::Type::DICTIONARY);
if (ptr->allowed_pin_modes != printing::mojom::PinModeRestriction::kUnset)
pin_policy.SetIntKey(kAllowedMode,
static_cast<int>(ptr->allowed_pin_modes));
if (ptr->default_pin_mode != printing::mojom::PinModeRestriction::kUnset)
pin_policy.SetIntKey(kDefaultMode, static_cast<int>(ptr->default_pin_mode));
if (!pin_policy.DictEmpty())
policies.SetKey(kPin, std::move(pin_policy));
return policies; return policies;
} }

@@ -986,6 +986,91 @@ TEST_F(PrintPreviewHandlerTest, InitialSettingsMaxSheetsAllowedPolicy) {
ValidateInitialSettingsValuePolicy(*web_ui()->call_data().back(), "sheets", ValidateInitialSettingsValuePolicy(*web_ui()->call_data().back(), "sheets",
base::Value(2)); base::Value(2));
} }
TEST_F(PrintPreviewHandlerTest, InitialSettingsEnableColorAndMonochrome) {
#if BUILDFLAG(IS_CHROMEOS_LACROS)
crosapi::mojom::Policies policies;
policies.allowed_color_modes = 3;
SetPolicies(policies);
#else
// Set a pref that should take priority over StickySettings.
prefs()->SetInteger(prefs::kPrintingAllowedColorModes, 3);
#endif
Initialize();
ValidateInitialSettingsAllowedDefaultModePolicy(
*web_ui()->call_data().back(), "color", base::Value(3), absl::nullopt);
}
TEST_F(PrintPreviewHandlerTest, InitialSettingsDefaultColor) {
#if BUILDFLAG(IS_CHROMEOS_LACROS)
crosapi::mojom::Policies policies;
policies.default_color_mode = printing::mojom::ColorModeRestriction::kColor;
SetPolicies(policies);
#else
// Set a pref that should take priority over StickySettings.
prefs()->SetInteger(prefs::kPrintingColorDefault, 2);
#endif
Initialize();
ValidateInitialSettingsAllowedDefaultModePolicy(
*web_ui()->call_data().back(), "color", absl::nullopt, base::Value(2));
}
TEST_F(PrintPreviewHandlerTest, InitialSettingsEnableSimplexAndDuplex) {
#if BUILDFLAG(IS_CHROMEOS_LACROS)
crosapi::mojom::Policies policies;
policies.allowed_duplex_modes = 7;
SetPolicies(policies);
#else
// Set a pref that should take priority over StickySettings.
prefs()->SetInteger(prefs::kPrintingAllowedDuplexModes, 7);
#endif
Initialize();
ValidateInitialSettingsAllowedDefaultModePolicy(
*web_ui()->call_data().back(), "duplex", base::Value(7), absl::nullopt);
}
TEST_F(PrintPreviewHandlerTest, InitialSettingsDefaultSimplex) {
#if BUILDFLAG(IS_CHROMEOS_LACROS)
crosapi::mojom::Policies policies;
policies.default_duplex_mode =
printing::mojom::DuplexModeRestriction::kSimplex;
SetPolicies(policies);
#else
// Set a pref that should take priority over StickySettings.
prefs()->SetInteger(prefs::kPrintingDuplexDefault, 1);
#endif
Initialize();
ValidateInitialSettingsAllowedDefaultModePolicy(
*web_ui()->call_data().back(), "duplex", absl::nullopt, base::Value(1));
}
TEST_F(PrintPreviewHandlerTest, InitialSettingsRestrictPin) {
#if BUILDFLAG(IS_CHROMEOS_LACROS)
crosapi::mojom::Policies policies;
policies.allowed_pin_modes = printing::mojom::PinModeRestriction::kPin;
SetPolicies(policies);
#else
// Set a pref that should take priority over StickySettings.
prefs()->SetInteger(prefs::kPrintingAllowedPinModes, 1);
#endif
Initialize();
ValidateInitialSettingsAllowedDefaultModePolicy(
*web_ui()->call_data().back(), "pin", base::Value(1), absl::nullopt);
}
TEST_F(PrintPreviewHandlerTest, InitialSettingsDefaultNoPin) {
#if BUILDFLAG(IS_CHROMEOS_LACROS)
crosapi::mojom::Policies policies;
policies.default_pin_mode = printing::mojom::PinModeRestriction::kNoPin;
SetPolicies(policies);
#else
// Set a pref that should take priority over StickySettings.
prefs()->SetInteger(prefs::kPrintingPinDefault, 2);
#endif
Initialize();
ValidateInitialSettingsAllowedDefaultModePolicy(
*web_ui()->call_data().back(), "pin", absl::nullopt, base::Value(2));
}
#endif // defined(OS_CHROMEOS) #endif // defined(OS_CHROMEOS)
TEST_F(PrintPreviewHandlerTest, GetPrinters) { TEST_F(PrintPreviewHandlerTest, GetPrinters) {

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import {ColorModeRestriction, Destination, DestinationConnectionStatus, DestinationOrigin, DestinationStore, DestinationType, DuplexModeRestriction, NativeLayer, NativeLayerCrosImpl, NativeLayerImpl} from 'chrome://print/print_preview.js'; import {Destination, DestinationConnectionStatus, DestinationOrigin, DestinationStore, DestinationType, NativeLayerCrosImpl, NativeLayerImpl} from 'chrome://print/print_preview.js';
import {assert} from 'chrome://resources/js/assert.m.js'; import {assert} from 'chrome://resources/js/assert.m.js';
import {NativeEventTarget as EventTarget} from 'chrome://resources/js/cr/event_target.m.js'; import {NativeEventTarget as EventTarget} from 'chrome://resources/js/cr/event_target.m.js';
import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
@@ -173,42 +173,4 @@ suite(destination_search_test_chromeos.suiteName, function() {
// Verify that the destination has been selected. // Verify that the destination has been selected.
assertEquals(printerId, destinationStore.selectedDestination.id); assertEquals(printerId, destinationStore.selectedDestination.id);
}); });
// Tests that if policies are set correctly if they are present
// for a destination.
test(
assert(destination_search_test_chromeos.TestNames
.ReceiveSuccessfulSetupWithPolicies),
function() {
const destId = '00112233DEADBEEF';
const response = {
printerId: destId,
capabilities: getCddTemplate(destId).capabilities,
policies: {
allowedColorModes: ColorModeRestriction.MONOCHROME,
allowedDuplexModes: DuplexModeRestriction.DUPLEX,
allowedPinMode: null,
defaultColorMode: null,
defaultDuplexMode: null,
defaultPinMode: null,
},
};
nativeLayerCros.setSetupPrinterResponse(response);
requestSetup(destId);
return nativeLayerCros.whenCalled('setupPrinter')
.then(function(actualId) {
assertEquals(destId, actualId);
const selectedDestination = destinationStore.selectedDestination;
assertNotEquals(null, selectedDestination);
assertEquals(destId, selectedDestination.id);
assertNotEquals(null, selectedDestination.capabilities);
assertNotEquals(null, selectedDestination.policies);
assertEquals(
ColorModeRestriction.MONOCHROME,
selectedDestination.policies.allowedColorModes);
assertEquals(
DuplexModeRestriction.DUPLEX,
selectedDestination.policies.allowedDuplexModes);
});
});
}); });

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import {CloudPrintInterfaceEventType, Destination, DestinationConnectionStatus, DestinationErrorType, DestinationOrigin, DestinationStore, DestinationType, LocalDestinationInfo, makeRecentDestination, NativeInitialSettings, NativeLayer, NativeLayerImpl, PluginProxy, PrinterType} from 'chrome://print/print_preview.js'; import {CloudPrintInterfaceEventType, Destination, DestinationConnectionStatus, DestinationErrorType, DestinationOrigin, DestinationStore, DestinationType, LocalDestinationInfo, makeRecentDestination, NativeInitialSettings, NativeLayerImpl, PrinterType} from 'chrome://print/print_preview.js';
import {assert} from 'chrome://resources/js/assert.m.js'; import {assert} from 'chrome://resources/js/assert.m.js';
import {isChromeOS, isLacros} from 'chrome://resources/js/cr.m.js'; import {isChromeOS, isLacros} from 'chrome://resources/js/cr.m.js';
import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
@@ -578,21 +578,10 @@ suite(destination_store_test.suiteName, function() {
assertEquals( assertEquals(
Destination.GooglePromotedId.SAVE_AS_PDF, Destination.GooglePromotedId.SAVE_AS_PDF,
destinationStore.selectedDestination.id); destinationStore.selectedDestination.id);
// Update destination with ID 1 so that it has policies.
const localDestinationInfo = { const localDestinationInfo = {
deviceName: id1, deviceName: id1,
printerName: name1 printerName: name1
}; };
if (isChromeOS || isLacros) {
localDestinationInfo.policies = {
allowedColorModes: 0x1, // ColorModeRestriction.MONOCHROME
defaultColorMode: 0x1, // ColorModeRestriction.MONOCHROME
allowedPinMode: null,
defaultPinMode: null,
allowedDuplexModes: null,
defaultDuplexMode: null,
};
}
// Typecast localDestinationInfo to work around the fact that // Typecast localDestinationInfo to work around the fact that
// policy types are only defined on Chrome OS. // policy types are only defined on Chrome OS.
nativeLayer.setLocalDestinationCapabilities({ nativeLayer.setLocalDestinationCapabilities({
@@ -608,9 +597,6 @@ suite(destination_store_test.suiteName, function() {
destinationStore.destinations().find(d => d.id === id1); destinationStore.destinations().find(d => d.id === id1);
// No capabilities or policies yet. // No capabilities or policies yet.
assertFalse(!!destination.capabilities); assertFalse(!!destination.capabilities);
if (isChromeOS || isLacros) {
assertEquals(null, destination.policies);
}
destinationStore.selectDestination(destination); destinationStore.selectDestination(destination);
return nativeLayer.whenCalled('getPrinterCapabilities'); return nativeLayer.whenCalled('getPrinterCapabilities');
}) })
@@ -618,10 +604,6 @@ suite(destination_store_test.suiteName, function() {
assertEquals(destination, destinationStore.selectedDestination); assertEquals(destination, destinationStore.selectedDestination);
// Capabilities are updated. // Capabilities are updated.
assertTrue(!!destination.capabilities); assertTrue(!!destination.capabilities);
if (isChromeOS || isLacros) {
// Policies are updated.
assertTrue(!!destination.policies);
}
}); });
}); });

@@ -14,8 +14,7 @@ suite('ModelSettingsPolicyTest', function() {
/** @type {!PrintPreviewModelElement} */ /** @type {!PrintPreviewModelElement} */
let model; let model;
/** @override */ function setupModel() {
setup(function() {
document.body.innerHTML = ''; document.body.innerHTML = '';
model = /** @type {!PrintPreviewModelElement} */ ( model = /** @type {!PrintPreviewModelElement} */ (
document.createElement('print-preview-model')); document.createElement('print-preview-model'));
@@ -43,13 +42,9 @@ suite('ModelSettingsPolicyTest', function() {
model.set( model.set(
'destination.capabilities', 'destination.capabilities',
getCddTemplate(model.destination.id).capabilities); getCddTemplate(model.destination.id).capabilities);
}); }
test('color managed', function() { test('color managed', function() {
// Remove color capability.
let capabilities = getCddTemplate(model.destination.id).capabilities;
delete capabilities.printer.color;
[{ [{
// Policy has no effect, setting unavailable // Policy has no effect, setting unavailable
colorCap: {option: [{type: 'STANDARD_COLOR', is_default: true}]}, colorCap: {option: [{type: 'STANDARD_COLOR', is_default: true}]},
@@ -99,18 +94,37 @@ suite('ModelSettingsPolicyTest', function() {
expectedAvailable: true, expectedAvailable: true,
expectedManaged: false, expectedManaged: false,
expectedEnforced: false, expectedEnforced: false,
},
{
// Default defined by policy but setting is modifiable (same as the case
// above but with swapped defaults).
colorCap: {
option: [
{type: 'STANDARD_MONOCHROME'},
{type: 'STANDARD_COLOR', is_default: true}
]
},
colorDefault: ColorModeRestriction.MONOCHROME,
expectedValue: false,
expectedAvailable: true,
expectedManaged: false,
expectedEnforced: false,
}].forEach(subtestParams => { }].forEach(subtestParams => {
capabilities = getCddTemplate(model.destination.id).capabilities; setupModel();
// Remove color capability.
const capabilities = getCddTemplate(model.destination.id).capabilities;
capabilities.printer.color = subtestParams.colorCap; capabilities.printer.color = subtestParams.colorCap;
const policies = { const policies = {
allowedColorModes: subtestParams.colorPolicy, color: {
defaultColorMode: subtestParams.colorDefault, allowedMode: subtestParams.colorPolicy,
defaultMode: subtestParams.colorDefault,
}
}; };
// In practice |capabilities| are always set after |policies| and
// observers only check for |capabilities|, so the order is important.
model.set('destination.policies', policies);
model.set('destination.capabilities', capabilities); model.set('destination.capabilities', capabilities);
model.applyDestinationSpecificPolicies(); model.setPolicySettings(policies);
model.applyStickySettings();
assertEquals(subtestParams.expectedValue, model.getSettingValue('color')); assertEquals(subtestParams.expectedValue, model.getSettingValue('color'));
assertEquals( assertEquals(
subtestParams.expectedAvailable, model.settings.color.available); subtestParams.expectedAvailable, model.settings.color.available);
@@ -121,10 +135,6 @@ suite('ModelSettingsPolicyTest', function() {
}); });
test('duplex managed', function() { test('duplex managed', function() {
// Remove duplex capability.
let capabilities = getCddTemplate(model.destination.id).capabilities;
delete capabilities.printer.duplex;
[{ [{
// Policy has no effect. // Policy has no effect.
duplexCap: {option: [{type: 'NO_DUPLEX', is_default: true}]}, duplexCap: {option: [{type: 'NO_DUPLEX', is_default: true}]},
@@ -206,17 +216,21 @@ suite('ModelSettingsPolicyTest', function() {
expectedShortEdgeAvailable: true, expectedShortEdgeAvailable: true,
expectedShortEdgeEnforced: false, expectedShortEdgeEnforced: false,
}].forEach(subtestParams => { }].forEach(subtestParams => {
capabilities = getCddTemplate('FooPrinter').capabilities; setupModel();
// Remove duplex capability.
const capabilities = getCddTemplate(model.destination.id).capabilities;
capabilities.printer.duplex = subtestParams.duplexCap; capabilities.printer.duplex = subtestParams.duplexCap;
const policies = { const policies = {
allowedDuplexModes: subtestParams.duplexPolicy, duplex: {
defaultDuplexMode: subtestParams.duplexDefault, allowedMode: subtestParams.duplexPolicy,
defaultMode: subtestParams.duplexDefault,
}
}; };
// In practice |capabilities| are always set after |policies| and
// observers only check for |capabilities|, so the order is important.
model.set('destination.policies', policies);
model.set('destination.capabilities', capabilities); model.set('destination.capabilities', capabilities);
model.applyDestinationSpecificPolicies(); model.setPolicySettings(policies);
model.applyStickySettings();
assertEquals( assertEquals(
subtestParams.expectedValue, model.getSettingValue('duplex')); subtestParams.expectedValue, model.getSettingValue('duplex'));
assertEquals( assertEquals(
@@ -237,14 +251,6 @@ suite('ModelSettingsPolicyTest', function() {
}); });
test('pin managed', function() { test('pin managed', function() {
// Remove pin capability.
let capabilities = getCddTemplate(model.destination.id).capabilities;
delete capabilities.printer.pin;
// Make device enterprise managed since pin setting is available only on
// managed devices.
loadTimeData.overrideValues({isEnterpriseManaged: true});
[{ [{
// No policies, settings is modifiable. // No policies, settings is modifiable.
pinCap: {supported: true}, pinCap: {supported: true},
@@ -312,17 +318,24 @@ suite('ModelSettingsPolicyTest', function() {
expectedManaged: false, expectedManaged: false,
expectedEnforced: false, expectedEnforced: false,
}].forEach(subtestParams => { }].forEach(subtestParams => {
capabilities = getCddTemplate(model.destination.id).capabilities; setupModel();
// Make device enterprise managed since pin setting is available only on
// managed devices.
loadTimeData.overrideValues({isEnterpriseManaged: true});
// Remove pin capability.
const capabilities = getCddTemplate(model.destination.id).capabilities;
capabilities.printer.pin = subtestParams.pinCap; capabilities.printer.pin = subtestParams.pinCap;
const policies = { const policies = {
allowedPinModes: subtestParams.pinPolicy, pin: {
defaultPinMode: subtestParams.pinDefault, allowedMode: subtestParams.pinPolicy,
defaultMode: subtestParams.pinDefault,
}
}; };
// In practice |capabilities| are always set after |policies| and
// observers only check for |capabilities|, so the order is important.
model.set('destination.policies', policies);
model.set('destination.capabilities', capabilities); model.set('destination.capabilities', capabilities);
model.applyDestinationSpecificPolicies(); model.setPolicySettings(policies);
model.applyStickySettings();
assertEquals(subtestParams.expectedValue, model.getSettingValue('pin')); assertEquals(subtestParams.expectedValue, model.getSettingValue('pin'));
assertEquals( assertEquals(
subtestParams.expectedAvailable, model.settings.pin.available); subtestParams.expectedAvailable, model.settings.pin.available);

@@ -2,11 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import {BackgroundGraphicsModeRestriction, NativeLayer, NativeLayerImpl, PluginProxyImpl, PrintPreviewPluralStringProxyImpl} from 'chrome://print/print_preview.js'; import {BackgroundGraphicsModeRestriction, DuplexMode, NativeLayerImpl, PluginProxyImpl, PrintPreviewPluralStringProxyImpl} from 'chrome://print/print_preview.js';
// <if expr="chromeos or lacros">
import {ColorModeRestriction, DuplexModeRestriction, PinModeRestriction} from 'chrome://print/print_preview.js';
// </if>
import {assert} from 'chrome://resources/js/assert.m.js'; import {assert} from 'chrome://resources/js/assert.m.js';
import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
import {NativeLayerStub} from 'chrome://test/print_preview/native_layer_stub.js'; import {NativeLayerStub} from 'chrome://test/print_preview/native_layer_stub.js';
import {getCddTemplate, getDefaultInitialSettings} from 'chrome://test/print_preview/print_preview_test_utils.js'; import {getDefaultInitialSettings} from 'chrome://test/print_preview/print_preview_test_utils.js';
import {TestPluginProxy} from 'chrome://test/print_preview/test_plugin_proxy.js'; import {TestPluginProxy} from 'chrome://test/print_preview/test_plugin_proxy.js';
import {TestPluralStringProxy} from 'chrome://test/test_plural_string_proxy.js'; import {TestPluralStringProxy} from 'chrome://test/test_plural_string_proxy.js';
@@ -22,6 +25,9 @@ policy_tests.TestNames = {
CssBackgroundPolicy: 'css background policy', CssBackgroundPolicy: 'css background policy',
MediaSizePolicy: 'media size policy', MediaSizePolicy: 'media size policy',
SheetsPolicy: 'sheets policy', SheetsPolicy: 'sheets policy',
ColorPolicy: 'color policy',
DuplexPolicy: 'duplex policy',
PinPolicy: 'pin policy',
}; };
class PolicyTestPluralStringProxy extends TestPluralStringProxy { class PolicyTestPluralStringProxy extends TestPluralStringProxy {
@@ -137,7 +143,7 @@ suite(policy_tests.suiteName, function() {
.$$(`#${settingName}`); .$$(`#${settingName}`);
} }
/** Tests different scenarios of applying header/footer policy. */ // Tests different scenarios of applying header/footer policy.
test(assert(policy_tests.TestNames.HeaderFooterPolicy), async () => { test(assert(policy_tests.TestNames.HeaderFooterPolicy), async () => {
const tests = [ const tests = [
{ {
@@ -187,7 +193,7 @@ suite(policy_tests.suiteName, function() {
} }
}); });
/** Tests different scenarios of applying background graphics policy. */ // Tests different scenarios of applying background graphics policy.
test(assert(policy_tests.TestNames.CssBackgroundPolicy), async () => { test(assert(policy_tests.TestNames.CssBackgroundPolicy), async () => {
const tests = [ const tests = [
{ {
@@ -239,7 +245,7 @@ suite(policy_tests.suiteName, function() {
} }
}); });
/** Tests different scenarios of applying default paper policy. */ // Tests different scenarios of applying default paper policy.
test(assert(policy_tests.TestNames.MediaSizePolicy), async () => { test(assert(policy_tests.TestNames.MediaSizePolicy), async () => {
const tests = [ const tests = [
{ {
@@ -341,4 +347,320 @@ suite(policy_tests.suiteName, function() {
!errorMessage.hidden && !!errorMessage.innerText); !errorMessage.hidden && !!errorMessage.innerText);
} }
}); });
// <if expr="chromeos or lacros">
// Tests different scenarios of color printing policy.
test(assert(policy_tests.TestNames.ColorPolicy), async () => {
const tests = [
{
// No policies.
allowedMode: undefined,
defaultMode: undefined,
expectedDisabled: false,
expectedValue: 'color',
},
{
// Print in color by default.
allowedMode: undefined,
defaultMode: ColorModeRestriction.COLOR,
expectedDisabled: false,
expectedValue: 'color',
},
{
// Print in black and white by default.
allowedMode: undefined,
defaultMode: ColorModeRestriction.MONOCHROME,
expectedDisabled: false,
expectedValue: 'bw',
},
{
// Allowed and default policies unset.
allowedMode: ColorModeRestriction.UNSET,
defaultMode: ColorModeRestriction.UNSET,
expectedDisabled: false,
expectedValue: 'bw',
},
{
// Allowed unset, default set to color printing.
allowedMode: ColorModeRestriction.UNSET,
defaultMode: ColorModeRestriction.COLOR,
expectedDisabled: false,
expectedValue: 'color',
},
{
// Enforce color printing.
allowedMode: ColorModeRestriction.COLOR,
defaultMode: ColorModeRestriction.UNSET,
expectedDisabled: true,
expectedValue: 'color',
},
{
// Enforce black and white printing.
allowedMode: ColorModeRestriction.MONOCHROME,
defaultMode: undefined,
expectedDisabled: true,
expectedValue: 'bw',
},
{
// Enforce color printing, default is ignored.
allowedMode: ColorModeRestriction.COLOR,
defaultMode: ColorModeRestriction.MONOCHROME,
expectedDisabled: true,
expectedValue: 'color',
},
];
for (const subtestParams of tests) {
await doAllowedDefaultModePolicySetup(
'color', 'isColorEnabled', subtestParams.allowedMode,
subtestParams.defaultMode);
const colorSettingsSelect = page.$$('print-preview-sidebar')
.$$('print-preview-color-settings')
.$$('select');
assertEquals(
subtestParams.expectedDisabled, colorSettingsSelect.disabled);
assertEquals(subtestParams.expectedValue, colorSettingsSelect.value);
}
});
// Tests different scenarios of duplex printing policy.
test(assert(policy_tests.TestNames.DuplexPolicy), async () => {
const tests = [
{
// No policies.
allowedMode: undefined,
defaultMode: undefined,
expectedChecked: false,
expectedOpened: false,
expectedDisabled: false,
expectedValue: DuplexMode.LONG_EDGE,
},
{
// No restriction, default set to SIMPLEX.
allowedMode: undefined,
defaultMode: DuplexModeRestriction.SIMPLEX,
expectedChecked: false,
expectedOpened: false,
expectedDisabled: false,
expectedValue: DuplexMode.LONG_EDGE,
},
{
// No restriction, default set to UNSET.
allowedMode: undefined,
defaultMode: DuplexModeRestriction.UNSET,
expectedChecked: true,
expectedOpened: true,
expectedDisabled: false,
expectedValue: DuplexMode.LONG_EDGE,
},
{
// Allowed mode set to UNSET.
allowedMode: DuplexModeRestriction.UNSET,
defaultMode: undefined,
expectedChecked: false,
expectedOpened: false,
expectedDisabled: false,
expectedValue: DuplexMode.LONG_EDGE,
},
{
// No restriction, default set to LONG_EDGE.
allowedMode: undefined,
defaultMode: DuplexModeRestriction.LONG_EDGE,
expectedChecked: true,
expectedOpened: true,
expectedDisabled: false,
expectedValue: DuplexMode.LONG_EDGE,
},
{
// No restriction, default set to SHORT_EDGE.
allowedMode: undefined,
defaultMode: DuplexModeRestriction.SHORT_EDGE,
expectedChecked: true,
expectedOpened: true,
expectedDisabled: false,
expectedValue: DuplexMode.SHORT_EDGE,
},
{
// No restriction, default set to DUPLEX.
allowedMode: undefined,
defaultMode: DuplexModeRestriction.DUPLEX,
expectedChecked: true,
expectedOpened: true,
expectedDisabled: false,
expectedValue: DuplexMode.LONG_EDGE,
},
{
// No restriction, default set to SHORT_EDGE.
allowedMode: DuplexModeRestriction.SIMPLEX,
defaultMode: undefined,
expectedChecked: false,
expectedOpened: false,
expectedDisabled: false,
expectedValue: DuplexMode.LONG_EDGE,
},
{
// Restricted to LONG_EDGE.
allowedMode: DuplexModeRestriction.LONG_EDGE,
defaultMode: undefined,
expectedChecked: true,
expectedOpened: true,
expectedDisabled: true,
expectedValue: DuplexMode.LONG_EDGE,
},
{
// Restricted to SHORT_EDGE.
allowedMode: DuplexModeRestriction.SHORT_EDGE,
defaultMode: undefined,
expectedChecked: true,
expectedOpened: true,
expectedDisabled: true,
expectedValue: DuplexMode.SHORT_EDGE,
},
{
// Restricted to DUPLEX.
allowedMode: DuplexModeRestriction.DUPLEX,
defaultMode: undefined,
expectedChecked: true,
expectedOpened: true,
expectedDisabled: false,
expectedValue: DuplexMode.LONG_EDGE,
},
{
// Restricted to SHORT_EDGE, default is ignored.
allowedMode: DuplexModeRestriction.SHORT_EDGE,
defaultMode: DuplexModeRestriction.LONG_EDGE,
expectedChecked: true,
expectedOpened: true,
expectedDisabled: true,
expectedValue: DuplexMode.SHORT_EDGE,
},
];
for (const subtestParams of tests) {
await doAllowedDefaultModePolicySetup(
'duplex', 'isDuplexEnabled', subtestParams.allowedMode,
subtestParams.defaultMode);
toggleMoreSettings();
const duplexSettingsSection =
page.$$('print-preview-sidebar').$$('print-preview-duplex-settings');
const checkbox = duplexSettingsSection.$$('cr-checkbox');
const collapse = duplexSettingsSection.$$('iron-collapse');
const select = duplexSettingsSection.$$('select');
const expectedValue = subtestParams.expectedValue.toString();
assertEquals(subtestParams.expectedChecked, checkbox.checked);
assertEquals(subtestParams.expectedOpened, collapse.opened);
assertEquals(subtestParams.expectedDisabled, select.disabled);
assertEquals(expectedValue, select.value);
}
});
// Tests different scenarios of pin printing policy.
test(assert(policy_tests.TestNames.PinPolicy), async () => {
const tests = [
{
// No policies.
allowedMode: undefined,
defaultMode: undefined,
expectedCheckboxDisabled: false,
expectedChecked: false,
expectedOpened: false,
expectedInputDisabled: true,
},
{
// No restriction, default set to UNSET.
allowedMode: undefined,
defaultMode: PinModeRestriction.UNSET,
expectedCheckboxDisabled: false,
expectedChecked: false,
expectedOpened: false,
expectedInputDisabled: true,
},
{
// No restriction, default set to PIN.
allowedMode: undefined,
defaultMode: PinModeRestriction.PIN,
expectedCheckboxDisabled: false,
expectedChecked: true,
expectedOpened: true,
expectedInputDisabled: false,
},
{
// No restriction, default set to NO_PIN.
allowedMode: undefined,
defaultMode: PinModeRestriction.NO_PIN,
expectedCheckboxDisabled: false,
expectedChecked: false,
expectedOpened: false,
expectedInputDisabled: true,
},
{
// Restriction se to UNSET.
allowedMode: PinModeRestriction.UNSET,
defaultMode: undefined,
expectedCheckboxDisabled: false,
expectedChecked: false,
expectedOpened: false,
expectedInputDisabled: true,
},
{
// Restriction set to PIN.
allowedMode: PinModeRestriction.PIN,
defaultMode: undefined,
expectedCheckboxDisabled: true,
expectedChecked: true,
expectedOpened: true,
expectedInputDisabled: false,
},
{
// Restriction set to NO_PIN.
allowedMode: PinModeRestriction.NO_PIN,
defaultMode: undefined,
expectedCheckboxDisabled: true,
expectedChecked: false,
expectedOpened: false,
expectedInputDisabled: true,
},
{
// Restriction set to PIN, default is ignored.
allowedMode: PinModeRestriction.NO_PIN,
defaultMode: PinModeRestriction.PIN,
expectedCheckboxDisabled: true,
expectedChecked: false,
expectedOpened: false,
expectedInputDisabled: true,
},
];
for (const subtestParams of tests) {
const initialSettings = getDefaultInitialSettings();
if (subtestParams.allowedMode !== undefined ||
subtestParams.defaultMode !== undefined) {
const policy = {};
if (subtestParams.allowedMode !== undefined) {
policy.allowedMode = subtestParams.allowedMode;
}
if (subtestParams.defaultMode !== undefined) {
policy.defaultMode = subtestParams.defaultMode;
}
initialSettings.policies = {"pin": policy};
}
const appState = {version: 2, "pinValue": "0000"};
if (subtestParams.defaultMode !== undefined) {
appState.isPinEnabled = !subtestParams.defaultMode;
}
initialSettings.serializedAppStateStr = JSON.stringify(appState);
await loadInitialSettings(initialSettings);
const pinSettingsSection =
page.$$('print-preview-sidebar').$$('print-preview-pin-settings');
const checkbox = pinSettingsSection.$$('cr-checkbox');
const collapse = pinSettingsSection.$$('iron-collapse');
const input = pinSettingsSection.$$('cr-input');
assertEquals(subtestParams.expectedCheckboxDisabled, checkbox.disabled);
assertEquals(subtestParams.expectedChecked, checkbox.checked);
assertEquals(subtestParams.expectedOpened, collapse.opened);
assertEquals(subtestParams.expectedInputDisabled, input.disabled);
}
});
// </if>
}); });

@@ -235,6 +235,18 @@ GEN('#if defined(OS_CHROMEOS)');
TEST_F('PrintPreviewPolicyTest', 'SheetsPolicy', function() { TEST_F('PrintPreviewPolicyTest', 'SheetsPolicy', function() {
this.runMochaTest(policy_tests.TestNames.SheetsPolicy); this.runMochaTest(policy_tests.TestNames.SheetsPolicy);
}); });
TEST_F('PrintPreviewPolicyTest', 'ColorPolicy', function() {
this.runMochaTest(policy_tests.TestNames.ColorPolicy);
});
TEST_F('PrintPreviewPolicyTest', 'DuplexPolicy', function() {
this.runMochaTest(policy_tests.TestNames.DuplexPolicy);
});
TEST_F('PrintPreviewPolicyTest', 'PinPolicy', function() {
this.runMochaTest(policy_tests.TestNames.PinPolicy);
});
GEN('#endif'); GEN('#endif');
// eslint-disable-next-line no-var // eslint-disable-next-line no-var
@@ -986,13 +998,6 @@ TEST_F(
destination_search_test_chromeos.TestNames.ResolutionFails); destination_search_test_chromeos.TestNames.ResolutionFails);
}); });
TEST_F(
'PrintPreviewDestinationSearchTestChromeOS',
'ReceiveSuccessfultSetupWithPolicies', function() {
this.runMochaTest(
destination_search_test_chromeos.TestNames.ResolutionFails);
});
TEST_F( TEST_F(
'PrintPreviewDestinationSearchTestChromeOS', 'CloudKioskPrinter', 'PrintPreviewDestinationSearchTestChromeOS', 'CloudKioskPrinter',
function() { function() {

@@ -173,17 +173,17 @@ struct CapabilitiesResponse {
// Printer capabilities and defaults corresponding to the // Printer capabilities and defaults corresponding to the
// PrinterSemanticCapsAndDefaults class in printing/backend/print_backend.h. // PrinterSemanticCapsAndDefaults class in printing/backend/print_backend.h.
printing.mojom.PrinterSemanticCapsAndDefaults? capabilities@2; printing.mojom.PrinterSemanticCapsAndDefaults? capabilities@2;
// The fields below are no longer used.
// Bitmask of allowed color modes corresponding to the ColorModeRestriction // Bitmask of allowed color modes corresponding to the ColorModeRestriction
// enum in printing/backend/printing_restrictions.h. // enum in printing/backend/printing_restrictions.h.
uint32 allowed_color_modes@3; uint32 allowed_color_modes_deprecated@3;
// Bitmask of allowed duplex modes. // Bitmask of allowed duplex modes.
uint32 allowed_duplex_modes@4; uint32 allowed_duplex_modes_deprecated@4;
[MinVersion=1] printing.mojom.PinModeRestriction allowed_pin_modes@9; uint32 allowed_pin_modes_deprecated_version_0@5;
printing.mojom.ColorModeRestriction default_color_mode@6; [MinVersion=1] printing.mojom.PinModeRestriction allowed_pin_modes_deprecated_version_1@9;
printing.mojom.DuplexModeRestriction default_duplex_mode@7; printing.mojom.ColorModeRestriction default_color_mode_deprecated@6;
printing.mojom.PinModeRestriction default_pin_mode@8; printing.mojom.DuplexModeRestriction default_duplex_mode_deprecated@7;
// No longer used. printing.mojom.PinModeRestriction default_pin_mode_deprecated@8;
uint32 allowed_pin_modes_deprecated@5;
}; };
// Global print policies that are not printer specific. // Global print policies that are not printer specific.
@@ -202,6 +202,15 @@ struct Policies {
// Indicates how many sheets is allowed to use for a single print job. // Indicates how many sheets is allowed to use for a single print job.
uint32 max_sheets_allowed@5; uint32 max_sheets_allowed@5;
bool max_sheets_allowed_has_value@6; bool max_sheets_allowed_has_value@6;
// Bitmask of allowed color modes corresponding to the ColorModeRestriction
// enum in printing/backend/printing_restrictions.h.
[MinVersion=1] uint32 allowed_color_modes@7;
// Bitmask of allowed duplex modes.
[MinVersion=1] uint32 allowed_duplex_modes@8;
[MinVersion=1] printing.mojom.PinModeRestriction allowed_pin_modes@9;
[MinVersion=1] printing.mojom.ColorModeRestriction default_color_mode@10;
[MinVersion=1] printing.mojom.DuplexModeRestriction default_duplex_mode@11;
[MinVersion=1] printing.mojom.PinModeRestriction default_pin_mode@12;
// Allowed background graphics modes. // Allowed background graphics modes.
// This is used in pref file and should never change. // This is used in pref file and should never change.
// Corresponds to enum class BackgroundGraphicsModeRestriction in // Corresponds to enum class BackgroundGraphicsModeRestriction in

@@ -16,11 +16,11 @@ namespace printing {
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
// Allowed printing modes as a bitmask. // Allowed printing modes as a bitmask.
// This is used in pref file and should never change. // This is used in pref file and crosapi. It should never change.
using ColorModeRestriction = mojom::ColorModeRestriction; using ColorModeRestriction = mojom::ColorModeRestriction;
// Allowed duplex modes as a bitmask. // Allowed duplex modes as a bitmask.
// This is used in pref file and should never change. // This is used in pref file and crosapi. It should never change.
using DuplexModeRestriction = mojom::DuplexModeRestriction; using DuplexModeRestriction = mojom::DuplexModeRestriction;
// Allowed PIN printing modes. // Allowed PIN printing modes.