Commit a1fa390c authored by Jimmy Gong's avatar Jimmy Gong Committed by Commit Bot

Display EULA URL in Chrome OS print preview

- An End License User Agreement (EULA) link will be displayed to users
  in print preview if the printer they have selected requires a EULA.
- Adds a browser test to reflect this change.
- This CL will have a follow up to actually get the EULA URL from the
  Printer object.

Bug: 1023589
Test: Browser Tests + end to end manual
Change-Id: Iadffddf148eb13bc95687532ed66b9e2215ff3c5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1929089
Commit-Queue: jimmy gong <jimmyxgong@chromium.org>
Reviewed-by: default avatarRebekah Potter <rbpotter@chromium.org>
Reviewed-by: default avatarLei Zhang <thestig@chromium.org>
Reviewed-by: default avatarBailey Berro <baileyberro@chromium.org>
Cr-Commit-Position: refs/heads/master@{#721289}
parent 0354358c
...@@ -325,6 +325,9 @@ ...@@ -325,6 +325,9 @@
<message name="IDS_PRINT_CONFIGURING_FAILED_TEXT" desc="Message shown to user when their printer is failed to set up in Chrome OS."> <message name="IDS_PRINT_CONFIGURING_FAILED_TEXT" desc="Message shown to user when their printer is failed to set up in Chrome OS.">
Error setting up printer Error setting up printer
</message> </message>
<message name="IDS_PRINT_PREVIEW_EULA_URL" desc="Message shown to user when their printer has a EULA associated with its PPD. This message is hyperlinked to the EULA.">
End User License Agreement
</message>
</if> </if>
<if expr="not chromeos"> <if expr="not chromeos">
<message name="IDS_PRINT_PREVIEW_SYSTEM_DIALOG_OPTION" desc="Option allowing the user to access advanced printer settings using the native print system dialog instead of printing through the print preview mechanism. Shortcut key is not translated"> <message name="IDS_PRINT_PREVIEW_SYSTEM_DIALOG_OPTION" desc="Option allowing the user to access advanced printer settings using the native print system dialog instead of printing through the print preview mechanism. Shortcut key is not translated">
......
...@@ -277,6 +277,7 @@ export class Destination { ...@@ -277,6 +277,7 @@ export class Destination {
* certificateStatus: * certificateStatus:
* (DestinationCertificateStatus|undefined), * (DestinationCertificateStatus|undefined),
* policies: (DestinationPolicies|undefined), * policies: (DestinationPolicies|undefined),
* eulaUrl: (string|undefined),
* }=} opt_params Optional * }=} opt_params Optional
* parameters for the destination. * parameters for the destination.
*/ */
...@@ -406,6 +407,14 @@ export class Destination { ...@@ -406,6 +407,14 @@ export class Destination {
this.certificateStatus_ = opt_params && opt_params.certificateStatus || this.certificateStatus_ = opt_params && opt_params.certificateStatus ||
DestinationCertificateStatus.NONE; DestinationCertificateStatus.NONE;
// <if expr="chromeos">
/**
* EULA url for printer's PPD. Empty string indicates no provided EULA.
* @private {string}
*/
this.eulaUrl_ = (opt_params && opt_params.eulaUrl) || '';
// </if>
assert( assert(
this.provisionalType_ != this.provisionalType_ !=
DestinationProvisionalType.NEEDS_USB_PERMISSION || DestinationProvisionalType.NEEDS_USB_PERMISSION ||
...@@ -579,6 +588,11 @@ export class Destination { ...@@ -579,6 +588,11 @@ export class Destination {
set policies(policies) { set policies(policies) {
this.policies_ = policies; this.policies_ = policies;
} }
/** @return {string} The EULA URL for a the destination */
get eulaUrl() {
return this.eulaUrl_;
}
// </if> // </if>
/** /**
......
...@@ -47,7 +47,7 @@ function parseLocalDestination(destinationInfo) { ...@@ -47,7 +47,7 @@ function parseLocalDestination(destinationInfo) {
const options = { const options = {
description: destinationInfo.printerDescription, description: destinationInfo.printerDescription,
isEnterprisePrinter: destinationInfo.cupsEnterprisePrinter, isEnterprisePrinter: destinationInfo.cupsEnterprisePrinter,
policies: destinationInfo.policies policies: destinationInfo.policies,
}; };
if (destinationInfo.printerOptions) { if (destinationInfo.printerOptions) {
// Convert options into cloud print tags format. // Convert options into cloud print tags format.
...@@ -55,6 +55,9 @@ function parseLocalDestination(destinationInfo) { ...@@ -55,6 +55,9 @@ function parseLocalDestination(destinationInfo) {
Object.keys(destinationInfo.printerOptions).map(function(key) { Object.keys(destinationInfo.printerOptions).map(function(key) {
return '__cp__' + key + '=' + this[key]; return '__cp__' + key + '=' + this[key];
}, destinationInfo.printerOptions); }, destinationInfo.printerOptions);
// <if expr="chromeos">
options.eulaUrl = destinationInfo.printerOptions['printerEulaUrl'];
// </if>
} }
return new Destination( return new Destination(
destinationInfo.deviceName, DestinationType.LOCAL, destinationInfo.deviceName, DestinationType.LOCAL,
......
...@@ -183,7 +183,8 @@ ...@@ -183,7 +183,8 @@
type="chrome_html" /> type="chrome_html" />
<structure name="IDR_PRINT_PREVIEW_DATA_LOCAL_PARSERS_JS" <structure name="IDR_PRINT_PREVIEW_DATA_LOCAL_PARSERS_JS"
file="data/local_parsers.js" file="data/local_parsers.js"
type="chrome_html" /> type="chrome_html"
preprocess="true" />
<structure name="IDR_PRINT_PREVIEW_DATA_INVITATION_JS" <structure name="IDR_PRINT_PREVIEW_DATA_INVITATION_JS"
file="data/invitation.js" file="data/invitation.js"
type="chrome_html" /> type="chrome_html" />
......
...@@ -11,6 +11,12 @@ ...@@ -11,6 +11,12 @@
overflow: hidden; overflow: hidden;
} }
.destination-additional-info,
.destination-additional-info div {
height: 100%;
min-height: 0;
}
.destination-status { .destination-status {
color: var(--cr-secondary-text-color); color: var(--cr-secondary-text-color);
font-size: calc(12/13 * 1em); font-size: calc(12/13 * 1em);
...@@ -25,12 +31,6 @@ ...@@ -25,12 +31,6 @@
be aligned with others after adding margin for the border. */ be aligned with others after adding margin for the border. */
margin: 0 calc(var(--print-preview-sidebar-margin) - 2px); margin: 0 calc(var(--print-preview-sidebar-margin) - 2px);
} }
#destination-status-wrapper,
#destination-status-wrapper div {
height: 100%;
min-height: 0;
}
</style> </style>
<print-preview-user-manager id="userManager" active-user="{{activeUser_}}" <print-preview-user-manager id="userManager" active-user="{{activeUser_}}"
cloud-print-disabled="{{cloudPrintDisabled_}}" cloud-print-disabled="{{cloudPrintDisabled_}}"
...@@ -58,13 +58,26 @@ ...@@ -58,13 +58,26 @@
</print-preview-destination-select> </print-preview-destination-select>
</div> </div>
</print-preview-settings-section> </print-preview-settings-section>
<print-preview-settings-section id="destination-status-wrapper" <print-preview-settings-section class="destination-additional-info"
hidden$="[[!statusText_]]"> hidden$="[[!statusText_]]">
<div slot="title"></div> <div slot="title"></div>
<div slot="controls"> <div slot="controls">
<div class="destination-status">[[statusText_]]</div> <div class="destination-status">[[statusText_]]</div>
</div> </div>
</print-preview-settings-section> </print-preview-settings-section>
<if expr="chromeos">
<print-preview-settings-section class="destination-additional-info"
id="destinationEulaWrapper"
hidden$="[[!destination.eulaUrl]]">
<div slot="title"></div>
<div slot="controls">
<a class="destination-status" href="[[destination.eulaUrl]]"
target="_blank">
$i18n{printerEulaURL}
</a>
</div>
</print-preview-settings-section>
</if>
<cr-lazy-render id="destinationDialog"> <cr-lazy-render id="destinationDialog">
<template> <template>
<print-preview-destination-dialog <print-preview-destination-dialog
......
...@@ -51,6 +51,8 @@ PrinterBasicInfo ToBasicInfo(const chromeos::Printer& printer) { ...@@ -51,6 +51,8 @@ PrinterBasicInfo ToBasicInfo(const chromeos::Printer& printer) {
basic_info.options[kCUPSEnterprisePrinter] = basic_info.options[kCUPSEnterprisePrinter] =
(printer.source() == chromeos::Printer::SRC_POLICY) ? kValueTrue (printer.source() == chromeos::Printer::SRC_POLICY) ? kValueTrue
: kValueFalse; : kValueFalse;
// TODO(1023589): Get the printer's EULA url from the printer object.
basic_info.options[kPrinterEulaURL] = "";
basic_info.printer_name = printer.id(); basic_info.printer_name = printer.id();
basic_info.display_name = printer.display_name(); basic_info.display_name = printer.display_name();
basic_info.printer_description = printer.description(); basic_info.printer_description = printer.description();
......
...@@ -120,6 +120,9 @@ TEST_F(LocalPrinterHandlerChromeosTest, GetPrinters) { ...@@ -120,6 +120,9 @@ TEST_F(LocalPrinterHandlerChromeosTest, GetPrinters) {
std::unique_ptr<base::ListValue> printers; std::unique_ptr<base::ListValue> printers;
bool is_done = false; bool is_done = false;
// TODO(1023589): Add the eulaUrl field to the test printers and test that
// the field is properly set. This is done after the Printer object has
// the EULA field.
Printer saved_printer = Printer saved_printer =
CreateTestPrinter("printer1", "saved", "description1"); CreateTestPrinter("printer1", "saved", "description1");
Printer enterprise_printer = Printer enterprise_printer =
...@@ -147,7 +150,8 @@ TEST_F(LocalPrinterHandlerChromeosTest, GetPrinters) { ...@@ -147,7 +150,8 @@ TEST_F(LocalPrinterHandlerChromeosTest, GetPrinters) {
"printerDescription": "description1", "printerDescription": "description1",
"printerName": "saved", "printerName": "saved",
"printerOptions": { "printerOptions": {
"cupsEnterprisePrinter": "false" "cupsEnterprisePrinter": "false",
"printerEulaUrl": ""
} }
}, },
{ {
...@@ -156,7 +160,8 @@ TEST_F(LocalPrinterHandlerChromeosTest, GetPrinters) { ...@@ -156,7 +160,8 @@ TEST_F(LocalPrinterHandlerChromeosTest, GetPrinters) {
"printerDescription": "description2", "printerDescription": "description2",
"printerName": "enterprise", "printerName": "enterprise",
"printerOptions": { "printerOptions": {
"cupsEnterprisePrinter": "true" "cupsEnterprisePrinter": "true",
"printerEulaUrl": ""
} }
}, },
{ {
...@@ -165,7 +170,8 @@ TEST_F(LocalPrinterHandlerChromeosTest, GetPrinters) { ...@@ -165,7 +170,8 @@ TEST_F(LocalPrinterHandlerChromeosTest, GetPrinters) {
"printerDescription": "description3", "printerDescription": "description3",
"printerName": "automatic", "printerName": "automatic",
"printerOptions": { "printerOptions": {
"cupsEnterprisePrinter": "false" "cupsEnterprisePrinter": "false",
"printerEulaUrl": ""
} }
} }
] ]
......
...@@ -292,6 +292,7 @@ void AddPrintPreviewStrings(content::WebUIDataSource* source) { ...@@ -292,6 +292,7 @@ void AddPrintPreviewStrings(content::WebUIDataSource* source) {
{"optionPin", IDS_PRINT_PREVIEW_OPTION_PIN}, {"optionPin", IDS_PRINT_PREVIEW_OPTION_PIN},
{"pinErrorMessage", IDS_PRINT_PREVIEW_PIN_ERROR_MESSAGE}, {"pinErrorMessage", IDS_PRINT_PREVIEW_PIN_ERROR_MESSAGE},
{"pinPlaceholder", IDS_PRINT_PREVIEW_PIN_PLACEHOLDER}, {"pinPlaceholder", IDS_PRINT_PREVIEW_PIN_PLACEHOLDER},
{"printerEulaURL", IDS_PRINT_PREVIEW_EULA_URL},
#endif #endif
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
{"openPdfInPreviewOption", IDS_PRINT_PREVIEW_OPEN_PDF_IN_PREVIEW_APP}, {"openPdfInPreviewOption", IDS_PRINT_PREVIEW_OPEN_PDF_IN_PREVIEW_APP},
......
...@@ -56,11 +56,17 @@ void PrintersToValues(const PrinterList& printer_list, ...@@ -56,11 +56,17 @@ void PrintersToValues(const PrinterList& printer_list,
for (const auto opt_it : printer.options) for (const auto opt_it : printer.options)
options->SetString(opt_it.first, opt_it.second); options->SetString(opt_it.first, opt_it.second);
#if defined(OS_CHROMEOS)
printer_info->SetBoolean( printer_info->SetBoolean(
kCUPSEnterprisePrinter, kCUPSEnterprisePrinter,
base::Contains(printer.options, kCUPSEnterprisePrinter) && base::Contains(printer.options, kCUPSEnterprisePrinter) &&
printer.options.at(kCUPSEnterprisePrinter) == kValueTrue); printer.options.at(kCUPSEnterprisePrinter) == kValueTrue);
auto it = printer.options.find(kPrinterEulaURL);
options->SetString(kPrinterEulaURL,
it != printer.options.end() ? it->second : "");
#endif // defined(OS_CHROMEOS)
printer_info->Set(kSettingPrinterOptions, std::move(options)); printer_info->Set(kSettingPrinterOptions, std::move(options));
printers->Append(std::move(printer_info)); printers->Append(std::move(printer_info));
......
...@@ -28,7 +28,8 @@ destination_settings_test.TestNames = { ...@@ -28,7 +28,8 @@ destination_settings_test.TestNames = {
UpdateRecentDestinations: 'update recent destinations', UpdateRecentDestinations: 'update recent destinations',
ResetDestinationOnSignOut: 'reset destination on sign out', ResetDestinationOnSignOut: 'reset destination on sign out',
DisabledSaveAsPdf: 'disabled save as pdf', DisabledSaveAsPdf: 'disabled save as pdf',
NoDestinations: 'no destinations' NoDestinations: 'no destinations',
EulaIsDisplayed: 'eula is displayed'
}; };
suite(destination_settings_test.suiteName, function() { suite(destination_settings_test.suiteName, function() {
...@@ -44,6 +45,9 @@ suite(destination_settings_test.suiteName, function() { ...@@ -44,6 +45,9 @@ suite(destination_settings_test.suiteName, function() {
/** @type {!Array<!RecentDestination>} */ /** @type {!Array<!RecentDestination>} */
let recentDestinations = []; let recentDestinations = [];
/** @type {!Array<!LocalDestinationInfo>} */
let localDestinations = [];
/** @type {!Array<!Destination>} */ /** @type {!Array<!Destination>} */
let destinations = []; let destinations = [];
...@@ -68,7 +72,7 @@ suite(destination_settings_test.suiteName, function() { ...@@ -68,7 +72,7 @@ suite(destination_settings_test.suiteName, function() {
// Stub out native layer and cloud print interface. // Stub out native layer and cloud print interface.
nativeLayer = new NativeLayerStub(); nativeLayer = new NativeLayerStub();
NativeLayer.setInstance(nativeLayer); NativeLayer.setInstance(nativeLayer);
const localDestinations = []; localDestinations = [];
destinations = getDestinations(nativeLayer, localDestinations); destinations = getDestinations(nativeLayer, localDestinations);
nativeLayer.setLocalDestinations(localDestinations); nativeLayer.setLocalDestinations(localDestinations);
cloudPrintInterface = new CloudPrintInterfaceStub(); cloudPrintInterface = new CloudPrintInterfaceStub();
...@@ -734,4 +738,89 @@ suite(destination_settings_test.suiteName, function() { ...@@ -734,4 +738,89 @@ suite(destination_settings_test.suiteName, function() {
assertDropdownItems(['noDestinations']); assertDropdownItems(['noDestinations']);
}); });
}); });
/**
* @param {!Array<!LocalDestinationInfo>} localDestinations The array that
* |info| will be added to.
* @param {!Array<!Destinations>} destinations The array that will add a new
* Destination based off of |info|.
* @param {!LocalDestinationInfo} info The LocalDestinationInfo to be added.
*/
function addNewDestination(localDestinations, destinations, info) {
const eulaDest = new Destination(
info.deviceName, DestinationType.LOCAL, DestinationOrigin.CROS,
info.printerName, DestinationConnectionStatus.ONLINE,
{eulaUrl: info.eulaUrl ? info.eulaUrl : ''});
localDestinations.push(info);
destinations.push(eulaDest);
nativeLayer.setLocalDestinations(localDestinations);
}
/**
* Tests that destinations with a EULA will display the EULA URL.
*/
test(assert(destination_settings_test.TestNames.EulaIsDisplayed), function() {
// Recent destinations start out empty.
assertRecentDestinations([]);
const expectedUrl = 'http://google.com';
const eulaDestInfo = {
deviceName: 'ID5',
printerName: 'Five',
eulaUrl: expectedUrl,
};
addNewDestination(localDestinations, destinations, eulaDestInfo);
assertEquals(0, nativeLayer.getCallCount('getPrinterCapabilities'));
initialize();
return nativeLayer.whenCalled('getPrinterCapabilities')
.then(() => {
assertRecentDestinations(['Save as PDF']);
assertEquals(1, nativeLayer.getCallCount('getPrinterCapabilities'));
// Assert that the EULA URL is hidden.
assertTrue(destinationSettings.$.destinationEulaWrapper.hidden);
nativeLayer.resetResolver('getPrinterCapabilities');
// Select a destination that has a EULA URL.
selectDestination(destinations[5]);
return nativeLayer.whenCalled('getPrinterCapabilities');
})
.then(() => {
assertRecentDestinations(['ID5', 'Save as PDF']);
assertEquals(1, nativeLayer.getCallCount('getPrinterCapabilities'));
// Assert that the EULA URL is displayed.
assertFalse(destinationSettings.$.destinationEulaWrapper.hidden);
assertEquals(expectedUrl, destinationSettings.destination.eulaUrl);
nativeLayer.resetResolver('getPrinterCapabilities');
// Select a destination without a EULA URL.
selectDestination(destinations[4]);
return nativeLayer.whenCalled('getPrinterCapabilities');
})
.then(() => {
assertRecentDestinations(['FooDevice', 'ID5', 'Save as PDF']);
assertEquals(1, nativeLayer.getCallCount('getPrinterCapabilities'));
// Assert that switching to a destination without a EULA does
// not display the EULA URL.
assertTrue(destinationSettings.$.destinationEulaWrapper.hidden);
nativeLayer.resetResolver('getPrinterCapabilities');
// Reselect a destination with a EULA URL.
selectDestination(destinations[5]);
return nativeLayer.whenCalled('getPrinterCapabilities');
})
.then(() => {
assertRecentDestinations(['ID5', 'FooDevice', 'Save as PDF']);
assertEquals(1, nativeLayer.getCallCount('getPrinterCapabilities'));
// Assert that switching back to a destination with a EULA displays
// the EULA URL.
assertFalse(destinationSettings.$.destinationEulaWrapper.hidden);
assertEquals(expectedUrl, destinationSettings.destination.eulaUrl);
});
});
}); });
...@@ -1105,6 +1105,12 @@ TEST_F('PrintPreviewDestinationSettingsTest', 'NoDestinations', function() { ...@@ -1105,6 +1105,12 @@ TEST_F('PrintPreviewDestinationSettingsTest', 'NoDestinations', function() {
this.runMochaTest(destination_settings_test.TestNames.NoDestinations); this.runMochaTest(destination_settings_test.TestNames.NoDestinations);
}); });
GEN('#if defined(OS_CHROMEOS)');
TEST_F('PrintPreviewDestinationSettingsTest', 'EulaIsDisplayed', function() {
this.runMochaTest(destination_settings_test.TestNames.EulaIsDisplayed);
});
GEN('#endif');
// eslint-disable-next-line no-var // eslint-disable-next-line no-var
var PrintPreviewScalingSettingsTest = class extends PrintPreviewTest { var PrintPreviewScalingSettingsTest = class extends PrintPreviewTest {
/** @override */ /** @override */
......
...@@ -165,10 +165,21 @@ base::Value GetSettingsOnBlockingTaskRunner( ...@@ -165,10 +165,21 @@ base::Value GetSettingsOnBlockingTaskRunner(
base::Value(basic_info.display_name)); base::Value(basic_info.display_name));
printer_info.SetKey(kSettingPrinterDescription, printer_info.SetKey(kSettingPrinterDescription,
base::Value(basic_info.printer_description)); base::Value(basic_info.printer_description));
base::Value options(base::Value::Type::DICTIONARY);
#if defined(OS_CHROMEOS)
auto it = basic_info.options.find(kPrinterEulaURL);
options.SetKey(kPrinterEulaURL, it != basic_info.options.end()
? base::Value(it->second)
: base::Value());
printer_info.SetKey( printer_info.SetKey(
kCUPSEnterprisePrinter, kCUPSEnterprisePrinter,
base::Value(base::Contains(basic_info.options, kCUPSEnterprisePrinter) && base::Value(base::Contains(basic_info.options, kCUPSEnterprisePrinter) &&
basic_info.options.at(kCUPSEnterprisePrinter) == kValueTrue)); basic_info.options.at(kCUPSEnterprisePrinter) == kValueTrue));
#endif // defined(OS_CHROMEOS)
printer_info.SetKey(kSettingPrinterOptions, std::move(options));
base::Value printer_info_capabilities(base::Value::Type::DICTIONARY); base::Value printer_info_capabilities(base::Value::Type::DICTIONARY);
printer_info_capabilities.SetKey(kPrinter, std::move(printer_info)); printer_info_capabilities.SetKey(kPrinter, std::move(printer_info));
......
...@@ -13,5 +13,6 @@ const char kCUPSPrintServerURL[] = "print_server_url"; ...@@ -13,5 +13,6 @@ const char kCUPSPrintServerURL[] = "print_server_url";
const char kDriverInfoTagName[] = "system_driverinfo"; const char kDriverInfoTagName[] = "system_driverinfo";
const char kDriverNameTagName[] = "printer-make-and-model"; // Match CUPS. const char kDriverNameTagName[] = "printer-make-and-model"; // Match CUPS.
const char kLocationTagName[] = "printer-location"; // Match CUPS. const char kLocationTagName[] = "printer-location"; // Match CUPS.
const char kPrinterEulaURL[] = "printerEulaUrl";
const char kValueFalse[] = "false"; const char kValueFalse[] = "false";
const char kValueTrue[] = "true"; const char kValueTrue[] = "true";
...@@ -14,6 +14,7 @@ PRINTING_EXPORT extern const char kCUPSPrintServerURL[]; ...@@ -14,6 +14,7 @@ PRINTING_EXPORT extern const char kCUPSPrintServerURL[];
PRINTING_EXPORT extern const char kDriverInfoTagName[]; PRINTING_EXPORT extern const char kDriverInfoTagName[];
PRINTING_EXPORT extern const char kDriverNameTagName[]; PRINTING_EXPORT extern const char kDriverNameTagName[];
PRINTING_EXPORT extern const char kLocationTagName[]; PRINTING_EXPORT extern const char kLocationTagName[];
PRINTING_EXPORT extern const char kPrinterEulaURL[];
PRINTING_EXPORT extern const char kValueFalse[]; PRINTING_EXPORT extern const char kValueFalse[];
PRINTING_EXPORT extern const char kValueTrue[]; PRINTING_EXPORT extern const char kValueTrue[];
......
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