Commit 835a73ab authored by Joon Ahn's avatar Joon Ahn Committed by Commit Bot

Scanning: Launch from settings page.

http://screen/3VkMjJQmSZKjniG

Add an entry in settings under printing section for launching the scanning ui. Gated by an expflag.

Bug: 1059779
Change-Id: Ib3e6b2566ababe109afa4fdafbd88f740d42c895
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2522498
Commit-Queue: Joon Ahn <joonbug@chromium.org>
Reviewed-by: default avatarDominick Ng <dominickn@chromium.org>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Reviewed-by: default avatarKyle Horimoto <khorimoto@chromium.org>
Reviewed-by: default avatarZentaro Kavanagh <zentaro@chromium.org>
Cr-Commit-Position: refs/heads/master@{#827169}
parent 6a3c1f96
...@@ -959,6 +959,9 @@ ...@@ -959,6 +959,9 @@
<message name="IDS_OS_SETTINGS_TAG_PRINT_MANAGEMENT_ALT2" desc="text for search result item which, when clicked, naviagets the user to the printing section to open the print jobs app. alternate phrase for: 'Print Management', 'Print Jobs'"> <message name="IDS_OS_SETTINGS_TAG_PRINT_MANAGEMENT_ALT2" desc="text for search result item which, when clicked, naviagets the user to the printing section to open the print jobs app. alternate phrase for: 'Print Management', 'Print Jobs'">
Print history Print history
</message> </message>
<message name="IDS_OS_SETTINGS_TAG_SCANNING_APP" desc="text for search result item which, when clicked, navigates the user to the printing section to open the scanning app.">
Scan
</message>
<!-- Accessibility section. --> <!-- Accessibility section. -->
<message name="IDS_OS_SETTINGS_TAG_A11Y" desc="Text for search result item which, when clicked, navigates the user to accessibility (a.k.a. a11y) settings. Alternate phrase for: 'A11y'"> <message name="IDS_OS_SETTINGS_TAG_A11Y" desc="Text for search result item which, when clicked, navigates the user to accessibility (a.k.a. a11y) settings. Alternate phrase for: 'A11y'">
......
d02aa88397dc46f41f17b601f4acf588be3edc77
\ No newline at end of file
...@@ -1963,6 +1963,12 @@ ...@@ -1963,6 +1963,12 @@
<message name="IDS_SETTINGS_PRINTING_PRINT_JOBS_LAUNCH_APP_SUBLABEL" desc="Sub-label that describes that the print management app lets users view and manage their print jobs."> <message name="IDS_SETTINGS_PRINTING_PRINT_JOBS_LAUNCH_APP_SUBLABEL" desc="Sub-label that describes that the print management app lets users view and manage their print jobs.">
View and manage print jobs View and manage print jobs
</message> </message>
<message name="IDS_SETTINGS_PRINTING_SCANNING_LAUNCH_APP_TITLE_LABEL" desc="Label for launching the scanning app from the os settings page.">
Scan
</message>
<message name="IDS_SETTINGS_PRINTING_SCANNING_LAUNCH_APP_SUBLABEL" desc="Sub-label that describes the scanning app which lets users scan documents.">
Scan documents and images
</message>
<!-- Internet page (OS settings) --> <!-- Internet page (OS settings) -->
<message name="IDS_SETTINGS_INTERNET_ADD_CELLULAR" desc="The accessibility label for the add cellular icon at Settings > Internet > Add Cellular label. This text will not be visible, but will be announced when ChromeVox is on and the user navigates to the icon. Clicking this icon will show a dialog that allows the user to activate a physical SIM or set up eSIM."> <message name="IDS_SETTINGS_INTERNET_ADD_CELLULAR" desc="The accessibility label for the add cellular icon at Settings > Internet > Add Cellular label. This text will not be visible, but will be announced when ChromeVox is on and the user navigates to the icon. Clicking this icon will show a dialog that allows the user to activate a physical SIM or set up eSIM.">
......
a866b21f10850b5bb8720367bdbff4b17e8d4d93
\ No newline at end of file
7cf42766fdc0fcd8cd6cf6f745ffda9e2a3d07f8
\ No newline at end of file
...@@ -168,6 +168,7 @@ js_library("cups_saved_printers") { ...@@ -168,6 +168,7 @@ js_library("cups_saved_printers") {
js_library("os_printing_page") { js_library("os_printing_page") {
deps = [ deps = [
"..:deep_linking_behavior", "..:deep_linking_behavior",
"..:metrics_recorder",
"..:os_route", "..:os_route",
"../..:router", "../..:router",
"../../settings_page:settings_animated_pages", "../../settings_page:settings_animated_pages",
...@@ -350,6 +351,7 @@ js_library("os_printing_page.m") { ...@@ -350,6 +351,7 @@ js_library("os_printing_page.m") {
deps = [ deps = [
":cups_printers_browser_proxy.m", ":cups_printers_browser_proxy.m",
"..:deep_linking_behavior.m", "..:deep_linking_behavior.m",
"..:metrics_recorder.m",
"..:os_route.m", "..:os_route.m",
"../..:router.m", "../..:router.m",
"//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
......
...@@ -221,6 +221,11 @@ cr.define('settings', function() { ...@@ -221,6 +221,11 @@ cr.define('settings', function() {
* Opens the print management app in its own window. * Opens the print management app in its own window.
*/ */
openPrintManagementApp() {} openPrintManagementApp() {}
/**
* Opens the Scanning app in its own window.
*/
openScanningApp() {}
} }
/** /**
...@@ -311,6 +316,11 @@ cr.define('settings', function() { ...@@ -311,6 +316,11 @@ cr.define('settings', function() {
openPrintManagementApp() { openPrintManagementApp() {
chrome.send('openPrintManagementApp'); chrome.send('openPrintManagementApp');
} }
/** @override */
openScanningApp() {
chrome.send('openScanningApp');
}
} }
cr.addSingletonGetter(CupsPrintersBrowserProxyImpl); cr.addSingletonGetter(CupsPrintersBrowserProxyImpl);
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
<link rel="import" href="chrome://resources/html/assert.html"> <link rel="import" href="chrome://resources/html/assert.html">
<link rel="import" href="chrome://resources/html/load_time_data.html"> <link rel="import" href="chrome://resources/html/load_time_data.html">
<link rel="import" href="../deep_linking_behavior.html"> <link rel="import" href="../deep_linking_behavior.html">
<link rel="import" href="../metrics_recorder.html">
<link rel="import" href="../os_route.html"> <link rel="import" href="../os_route.html">
<link rel="import" href="../../router.html"> <link rel="import" href="../../router.html">
<link rel="import" href="../../settings_page/settings_animated_pages.html"> <link rel="import" href="../../settings_page/settings_animated_pages.html">
...@@ -29,6 +30,14 @@ ...@@ -29,6 +30,14 @@
external deep-link-focus-id$="[[Setting.kPrintJobs]]"> external deep-link-focus-id$="[[Setting.kPrintJobs]]">
</cr-link-row> </cr-link-row>
</template> </template>
<template is="dom-if" if="[[isScanningAppEnabled_]]">
<cr-link-row class="hr" id="scanningApp"
on-click="onOpenScanningApp_"
label="$i18n{scanAppTitle}"
sub-label="$i18n{scanAppSublabel}"
external deep-link-focus-id$="[[Setting.kScanningApp]]">
</cr-link-row>
</template>
</div> </div>
<template is="dom-if" route-path="/cupsPrinters"> <template is="dom-if" route-path="/cupsPrinters">
<settings-subpage <settings-subpage
......
...@@ -34,6 +34,7 @@ Polymer({ ...@@ -34,6 +34,7 @@ Polymer({
}, },
}, },
/** @private */
isPrintManagementEnabled_: { isPrintManagementEnabled_: {
type: Boolean, type: Boolean,
value: function() { value: function() {
...@@ -41,13 +42,24 @@ Polymer({ ...@@ -41,13 +42,24 @@ Polymer({
} }
}, },
/** @private */
isScanningAppEnabled_: {
type: Boolean,
value: function() {
return loadTimeData.getBoolean('scanningAppEnabled');
}
},
/** /**
* Used by DeepLinkingBehavior to focus this page's deep links. * Used by DeepLinkingBehavior to focus this page's deep links.
* @type {!Set<!chromeos.settings.mojom.Setting>} * @type {!Set<!chromeos.settings.mojom.Setting>}
*/ */
supportedSettingIds: { supportedSettingIds: {
type: Object, type: Object,
value: () => new Set([chromeos.settings.mojom.Setting.kPrintJobs]), value: () => new Set([
chromeos.settings.mojom.Setting.kPrintJobs,
chromeos.settings.mojom.Setting.kScanningApp
]),
}, },
}, },
...@@ -74,5 +86,12 @@ Polymer({ ...@@ -74,5 +86,12 @@ Polymer({
assert(this.isPrintManagementEnabled_); assert(this.isPrintManagementEnabled_);
settings.CupsPrintersBrowserProxyImpl.getInstance() settings.CupsPrintersBrowserProxyImpl.getInstance()
.openPrintManagementApp(); .openPrintManagementApp();
},
/** @private */
onOpenScanningApp_() {
assert(this.isScanningAppEnabled_);
settings.CupsPrintersBrowserProxyImpl.getInstance().openScanningApp();
settings.recordSettingChange(chromeos.settings.mojom.Setting.kScanningApp);
} }
}); });
...@@ -463,6 +463,14 @@ void ShowConnectivityDiagnosticsApp(Profile* profile) { ...@@ -463,6 +463,14 @@ void ShowConnectivityDiagnosticsApp(Profile* profile) {
GURL(chromeos::kChromeUIConnectivityDiagnosticsUrl)); GURL(chromeos::kChromeUIConnectivityDiagnosticsUrl));
} }
void ShowScanningApp(Profile* profile) {
DCHECK(base::FeatureList::IsEnabled(chromeos::features::kScanningUI));
// TODO(joonbug): Add uma metric to track entry point for the app.
LaunchSystemWebApp(profile, web_app::SystemAppType::SCANNING,
GURL(chrome::kChromeUIScanningAppURL));
}
GURL GetOSSettingsUrl(const std::string& sub_page) { GURL GetOSSettingsUrl(const std::string& sub_page) {
DCHECK(sub_page.empty() || chromeos::settings::IsOSSettingsSubPage(sub_page)) DCHECK(sub_page.empty() || chromeos::settings::IsOSSettingsSubPage(sub_page))
<< sub_page; << sub_page;
......
...@@ -155,6 +155,8 @@ void ShowPrintManagementApp(Profile* profile, ...@@ -155,6 +155,8 @@ void ShowPrintManagementApp(Profile* profile,
PrintManagementAppEntryPoint entry_point); PrintManagementAppEntryPoint entry_point);
void ShowConnectivityDiagnosticsApp(Profile* profile); void ShowConnectivityDiagnosticsApp(Profile* profile);
void ShowScanningApp(Profile* profile);
#endif #endif
#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) #if !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
......
...@@ -185,6 +185,7 @@ enum Setting { ...@@ -185,6 +185,7 @@ enum Setting {
kAddPrinter = 1400, kAddPrinter = 1400,
kSavedPrinters = 1401, kSavedPrinters = 1401,
kPrintJobs = 1402, kPrintJobs = 1402,
kScanningApp = 1403,
// Accessibility section. // Accessibility section.
kA11yQuickSettings = 1500, kA11yQuickSettings = 1500,
......
...@@ -357,6 +357,12 @@ void CupsPrintersHandler::RegisterMessages() { ...@@ -357,6 +357,12 @@ void CupsPrintersHandler::RegisterMessages() {
base::BindRepeating(&CupsPrintersHandler::HandleOpenPrintManagementApp, base::BindRepeating(&CupsPrintersHandler::HandleOpenPrintManagementApp,
base::Unretained(this))); base::Unretained(this)));
} }
if (base::FeatureList::IsEnabled(chromeos::features::kScanningUI)) {
web_ui()->RegisterMessageCallback(
"openScanningApp",
base::BindRepeating(&CupsPrintersHandler::HandleOpenScanningApp,
base::Unretained(this)));
}
} }
void CupsPrintersHandler::OnJavascriptAllowed() { void CupsPrintersHandler::OnJavascriptAllowed() {
...@@ -1308,5 +1314,11 @@ void CupsPrintersHandler::HandleOpenPrintManagementApp( ...@@ -1308,5 +1314,11 @@ void CupsPrintersHandler::HandleOpenPrintManagementApp(
PrintManagementAppEntryPoint::kSettings); PrintManagementAppEntryPoint::kSettings);
} }
void CupsPrintersHandler::HandleOpenScanningApp(const base::ListValue* args) {
DCHECK(args->empty());
DCHECK(base::FeatureList::IsEnabled(chromeos::features::kScanningUI));
chrome::ShowScanningApp(profile_);
}
} // namespace settings } // namespace settings
} // namespace chromeos } // namespace chromeos
...@@ -235,6 +235,8 @@ class CupsPrintersHandler : public ::settings::SettingsPageUIHandler, ...@@ -235,6 +235,8 @@ class CupsPrintersHandler : public ::settings::SettingsPageUIHandler,
void HandleOpenPrintManagementApp(const base::ListValue* args); void HandleOpenPrintManagementApp(const base::ListValue* args);
void HandleOpenScanningApp(const base::ListValue* args);
Profile* profile_; Profile* profile_;
// Discovery support. discovery_active_ tracks whether or not the UI // Discovery support. discovery_active_ tracks whether or not the UI
......
...@@ -68,11 +68,27 @@ const std::vector<SearchConcept>& GetPrintingManagementSearchConcepts() { ...@@ -68,11 +68,27 @@ const std::vector<SearchConcept>& GetPrintingManagementSearchConcepts() {
return *tags; return *tags;
} }
const std::vector<SearchConcept>& GetScanningAppSearchConcepts() {
static const base::NoDestructor<std::vector<SearchConcept>> tags({
{IDS_OS_SETTINGS_TAG_SCANNING_APP,
mojom::kPrintingSectionPath,
mojom::SearchResultIcon::kPrinter,
mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSetting,
{.setting = mojom::Setting::kScanningApp}},
});
return *tags;
}
bool IsPrintManagementEnabled() { bool IsPrintManagementEnabled() {
return base::FeatureList::IsEnabled( return base::FeatureList::IsEnabled(
chromeos::features::kPrintJobManagementApp); chromeos::features::kPrintJobManagementApp);
} }
bool IsScanningAppEnabled() {
return base::FeatureList::IsEnabled(chromeos::features::kScanningUI);
}
} // namespace } // namespace
PrintingSection::PrintingSection(Profile* profile, PrintingSection::PrintingSection(Profile* profile,
...@@ -85,6 +101,9 @@ PrintingSection::PrintingSection(Profile* profile, ...@@ -85,6 +101,9 @@ PrintingSection::PrintingSection(Profile* profile,
if (IsPrintManagementEnabled()) if (IsPrintManagementEnabled())
updater.AddSearchTags(GetPrintingManagementSearchConcepts()); updater.AddSearchTags(GetPrintingManagementSearchConcepts());
if (IsScanningAppEnabled())
updater.AddSearchTags(GetScanningAppSearchConcepts());
// Saved Printers search tags are added/removed dynamically. // Saved Printers search tags are added/removed dynamically.
if (printers_manager_) { if (printers_manager_) {
printers_manager_->AddObserver(this); printers_manager_->AddObserver(this);
...@@ -118,6 +137,8 @@ void PrintingSection::AddLoadTimeData(content::WebUIDataSource* html_source) { ...@@ -118,6 +137,8 @@ void PrintingSection::AddLoadTimeData(content::WebUIDataSource* html_source) {
IDS_SETTINGS_PRINTING_PRINT_JOBS_LAUNCH_APP_TITLE_LABEL}, IDS_SETTINGS_PRINTING_PRINT_JOBS_LAUNCH_APP_TITLE_LABEL},
{"printJobsSublabel", {"printJobsSublabel",
IDS_SETTINGS_PRINTING_PRINT_JOBS_LAUNCH_APP_SUBLABEL}, IDS_SETTINGS_PRINTING_PRINT_JOBS_LAUNCH_APP_SUBLABEL},
{"scanAppTitle", IDS_SETTINGS_PRINTING_SCANNING_LAUNCH_APP_TITLE_LABEL},
{"scanAppSublabel", IDS_SETTINGS_PRINTING_SCANNING_LAUNCH_APP_SUBLABEL},
{"printerDetailsTitle", IDS_SETTINGS_PRINTING_CUPS_PRINTER_DETAILS_TITLE}, {"printerDetailsTitle", IDS_SETTINGS_PRINTING_CUPS_PRINTER_DETAILS_TITLE},
{"printerName", IDS_SETTINGS_PRINTING_CUPS_PRINTER_DETAILS_NAME}, {"printerName", IDS_SETTINGS_PRINTING_CUPS_PRINTER_DETAILS_NAME},
{"printerModel", IDS_SETTINGS_PRINTING_CUPS_PRINTER_DETAILS_MODEL}, {"printerModel", IDS_SETTINGS_PRINTING_CUPS_PRINTER_DETAILS_MODEL},
...@@ -251,6 +272,7 @@ void PrintingSection::AddLoadTimeData(content::WebUIDataSource* html_source) { ...@@ -251,6 +272,7 @@ void PrintingSection::AddLoadTimeData(content::WebUIDataSource* html_source) {
"printingCUPSPrintPpdLearnMoreUrl", "printingCUPSPrintPpdLearnMoreUrl",
GetHelpUrlWithBoard(chrome::kCupsPrintPPDLearnMoreURL)); GetHelpUrlWithBoard(chrome::kCupsPrintPPDLearnMoreURL));
html_source->AddBoolean("printManagementEnabled", IsPrintManagementEnabled()); html_source->AddBoolean("printManagementEnabled", IsPrintManagementEnabled());
html_source->AddBoolean("scanningAppEnabled", IsScanningAppEnabled());
} }
void PrintingSection::AddHandlers(content::WebUI* web_ui) { void PrintingSection::AddHandlers(content::WebUI* web_ui) {
...@@ -282,6 +304,7 @@ bool PrintingSection::LogMetric(mojom::Setting setting, ...@@ -282,6 +304,7 @@ bool PrintingSection::LogMetric(mojom::Setting setting,
void PrintingSection::RegisterHierarchy(HierarchyGenerator* generator) const { void PrintingSection::RegisterHierarchy(HierarchyGenerator* generator) const {
generator->RegisterTopLevelSetting(mojom::Setting::kPrintJobs); generator->RegisterTopLevelSetting(mojom::Setting::kPrintJobs);
generator->RegisterTopLevelSetting(mojom::Setting::kScanningApp);
// Printing details. // Printing details.
generator->RegisterTopLevelSubpage(IDS_SETTINGS_PRINTING_CUPS_PRINTERS, generator->RegisterTopLevelSubpage(IDS_SETTINGS_PRINTING_CUPS_PRINTERS,
......
...@@ -276,6 +276,7 @@ const char kChromeUIPasswordChangeHost[] = "password-change"; ...@@ -276,6 +276,7 @@ const char kChromeUIPasswordChangeHost[] = "password-change";
const char kChromeUIPasswordChangeUrl[] = "chrome://password-change"; const char kChromeUIPasswordChangeUrl[] = "chrome://password-change";
const char kChromeUIPrintManagementUrl[] = "chrome://print-management"; const char kChromeUIPrintManagementUrl[] = "chrome://print-management";
const char kChromeUIPowerHost[] = "power"; const char kChromeUIPowerHost[] = "power";
const char kChromeUIScanningAppURL[] = "chrome://scanning";
const char kChromeUIScreenlockIconHost[] = "screenlock-icon"; const char kChromeUIScreenlockIconHost[] = "screenlock-icon";
const char kChromeUIScreenlockIconURL[] = "chrome://screenlock-icon/"; const char kChromeUIScreenlockIconURL[] = "chrome://screenlock-icon/";
const char kChromeUISetTimeHost[] = "set-time"; const char kChromeUISetTimeHost[] = "set-time";
......
...@@ -266,6 +266,7 @@ extern const char kChromeUIPasswordChangeHost[]; ...@@ -266,6 +266,7 @@ extern const char kChromeUIPasswordChangeHost[];
extern const char kChromeUIPasswordChangeUrl[]; extern const char kChromeUIPasswordChangeUrl[];
extern const char kChromeUIPrintManagementUrl[]; extern const char kChromeUIPrintManagementUrl[];
extern const char kChromeUIPowerHost[]; extern const char kChromeUIPowerHost[];
extern const char kChromeUIScanningAppURL[];
extern const char kChromeUIScreenlockIconHost[]; extern const char kChromeUIScreenlockIconHost[];
extern const char kChromeUIScreenlockIconURL[]; extern const char kChromeUIScreenlockIconURL[];
extern const char kChromeUISetTimeHost[]; extern const char kChromeUISetTimeHost[];
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
// #import {assertEquals, assertFalse, assertTrue} from '../../chai_assert.js'; // #import {assertEquals, assertFalse, assertTrue} from '../../chai_assert.js';
// #import {getDeepActiveElement} from 'chrome://resources/js/util.m.js'; // #import {getDeepActiveElement} from 'chrome://resources/js/util.m.js';
// #import {Router, routes} from 'chrome://os-settings/chromeos/os_settings.js'; // #import {Router, routes} from 'chrome://os-settings/chromeos/os_settings.js';
// #import {waitAfterNextRender} from 'chrome://test/test_util.m.js'; // #import {flushTasks, waitAfterNextRender} from 'chrome://test/test_util.m.js';
// clang-format on // clang-format on
suite('PrintingPageTests', function() { suite('PrintingPageTests', function() {
...@@ -19,9 +19,6 @@ suite('PrintingPageTests', function() { ...@@ -19,9 +19,6 @@ suite('PrintingPageTests', function() {
setup(function() { setup(function() {
PolymerTest.clearBody(); PolymerTest.clearBody();
printingPage = document.createElement('os-settings-printing-page');
document.body.appendChild(printingPage);
Polymer.dom.flush();
}); });
teardown(function() { teardown(function() {
...@@ -29,8 +26,22 @@ suite('PrintingPageTests', function() { ...@@ -29,8 +26,22 @@ suite('PrintingPageTests', function() {
settings.Router.getInstance().resetRouteForTesting(); settings.Router.getInstance().resetRouteForTesting();
}); });
/**
* Set up printing page with loadTimeData overrides
* @param {Object} overrides Dictionary of objects to override.
* @return {!Promise}
*/
function initializePrintingPage(overrides) {
loadTimeData.overrideValues(overrides);
printingPage = /** @type {!SettingsPrintingPageElement} */ (
document.createElement('os-settings-printing-page'));
assertTrue(!!printingPage);
document.body.appendChild(printingPage);
return test_util.flushTasks();
}
test('Deep link to print jobs', async () => { test('Deep link to print jobs', async () => {
loadTimeData.overrideValues({ await initializePrintingPage({
isDeepLinkingEnabled: true, isDeepLinkingEnabled: true,
}); });
...@@ -48,4 +59,25 @@ suite('PrintingPageTests', function() { ...@@ -48,4 +59,25 @@ suite('PrintingPageTests', function() {
deepLinkElement, getDeepActiveElement(), deepLinkElement, getDeepActiveElement(),
'Print jobs button should be focused for settingId=1402.'); 'Print jobs button should be focused for settingId=1402.');
}); });
test('Deep link to scanning app', async () => {
await initializePrintingPage({
isDeepLinkingEnabled: true,
scanningAppEnabled: true,
});
const params = new URLSearchParams;
params.append('settingId', '1403');
settings.Router.getInstance().navigateTo(
settings.routes.OS_PRINTING, params);
Polymer.dom.flush();
const deepLinkElement =
printingPage.$$('#scanningApp').$$('cr-icon-button');
await test_util.waitAfterNextRender(deepLinkElement);
assertEquals(
deepLinkElement, getDeepActiveElement(),
'Scanning app button should be focused for settingId=1403.');
});
}); });
\ No newline at end of file
...@@ -55041,6 +55041,7 @@ Called by update_net_trust_anchors.py.--> ...@@ -55041,6 +55041,7 @@ Called by update_net_trust_anchors.py.-->
<int value="1400" label="Add Printer"/> <int value="1400" label="Add Printer"/>
<int value="1401" label="Saved Printers"/> <int value="1401" label="Saved Printers"/>
<int value="1402" label="Print Jobs"/> <int value="1402" label="Print Jobs"/>
<int value="1403" label="Scanning App"/>
<int value="1500" label="A11y Quick Settings"/> <int value="1500" label="A11y Quick Settings"/>
<int value="1501" label="Chrome Vox"/> <int value="1501" label="Chrome Vox"/>
<int value="1502" label="Select To Speak"/> <int value="1502" label="Select To Speak"/>
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