Commit c1c2c6de authored by Anastasia Helfinstein's avatar Anastasia Helfinstein Committed by Commit Bot

[Switch Access] Create settings page

This commit creates a settings page for Switch Access behind the
Switch Access experimental flag. The page is not accessible to users at
this point except by typing in the direct URL
(chrome://settings/manageAccessibility/switchAccess) with the flag
enabled. The preferences set here are not yet connected to the behavior
of Switch Access.

Bug: 958081
Change-Id: I86951e2877c18c047053a4ec3fcb3b2f18dd46b5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1600082
Commit-Queue: Anastasia Helfinstein <anastasi@google.com>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Reviewed-by: default avatarJames Cook <jamescook@chromium.org>
Reviewed-by: default avatarDan Beam <dbeam@chromium.org>
Reviewed-by: default avatarKatie Dektar <katie@chromium.org>
Cr-Commit-Position: refs/heads/master@{#665705}
parent c7e20461
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "ash/keyboard/ash_keyboard_controller.h" #include "ash/keyboard/ash_keyboard_controller.h"
#include "ash/keyboard/ui/keyboard_util.h" #include "ash/keyboard/ui/keyboard_util.h"
#include "ash/policy/policy_recommendation_restorer.h" #include "ash/policy/policy_recommendation_restorer.h"
#include "ash/public/cpp/ash_constants.h"
#include "ash/public/cpp/ash_pref_names.h" #include "ash/public/cpp/ash_pref_names.h"
#include "ash/public/cpp/notification_utils.h" #include "ash/public/cpp/notification_utils.h"
#include "ash/public/cpp/shell_window_ids.h" #include "ash/public/cpp/shell_window_ids.h"
...@@ -300,6 +301,26 @@ void AccessibilityController::RegisterProfilePrefs(PrefRegistrySimple* registry, ...@@ -300,6 +301,26 @@ void AccessibilityController::RegisterProfilePrefs(PrefRegistrySimple* registry,
false); false);
registry->RegisterBooleanPref(prefs::kAccessibilitySwitchAccessEnabled, registry->RegisterBooleanPref(prefs::kAccessibilitySwitchAccessEnabled,
false); false);
registry->RegisterListPref(prefs::kAccessibilitySwitchAccessSelectKeyCodes,
base::Value(std::vector<base::Value>()));
registry->RegisterIntegerPref(
prefs::kAccessibilitySwitchAccessSelectSetting,
kSwitchAccessAssignmentNone);
registry->RegisterListPref(prefs::kAccessibilitySwitchAccessNextKeyCodes,
base::Value(std::vector<base::Value>()));
registry->RegisterIntegerPref(prefs::kAccessibilitySwitchAccessNextSetting,
kSwitchAccessAssignmentNone);
registry->RegisterListPref(
prefs::kAccessibilitySwitchAccessPreviousKeyCodes,
base::Value(std::vector<base::Value>()));
registry->RegisterIntegerPref(
prefs::kAccessibilitySwitchAccessPreviousSetting,
kSwitchAccessAssignmentNone);
registry->RegisterBooleanPref(
prefs::kAccessibilitySwitchAccessAutoScanEnabled, false);
registry->RegisterIntegerPref(
prefs::kAccessibilitySwitchAccessAutoScanSpeedMs,
kDefaultSwitchAccessAutoScanSpeed.InMilliseconds());
registry->RegisterBooleanPref(prefs::kAccessibilityVirtualKeyboardEnabled, registry->RegisterBooleanPref(prefs::kAccessibilityVirtualKeyboardEnabled,
false); false);
registry->RegisterBooleanPref( registry->RegisterBooleanPref(
......
...@@ -37,6 +37,15 @@ constexpr int kFocusBorderThickness = 2; ...@@ -37,6 +37,15 @@ constexpr int kFocusBorderThickness = 2;
constexpr int kDefaultLargeCursorSize = 64; constexpr int kDefaultLargeCursorSize = 64;
// The option in the Switch Access settings for no switch assigned.
constexpr int kSwitchAccessAssignmentNone = 0;
// The default delay before Switch Access automatically moves to the next
// element on the page that is interesting, based on the Switch Access
// predicates.
constexpr base::TimeDelta kDefaultSwitchAccessAutoScanSpeed =
base::TimeDelta::FromMilliseconds(1200);
// The default wait time between last mouse movement and sending autoclick. // The default wait time between last mouse movement and sending autoclick.
constexpr int kDefaultAutoclickDelayMs = 1000; constexpr int kDefaultAutoclickDelayMs = 1000;
......
...@@ -81,7 +81,34 @@ const char kAccessibilityFocusHighlightEnabled[] = ...@@ -81,7 +81,34 @@ const char kAccessibilityFocusHighlightEnabled[] =
const char kAccessibilitySelectToSpeakEnabled[] = const char kAccessibilitySelectToSpeakEnabled[] =
"settings.a11y.select_to_speak"; "settings.a11y.select_to_speak";
// A boolean pref which determines whether switch access is enabled. // A boolean pref which determines whether switch access is enabled.
const char kAccessibilitySwitchAccessEnabled[] = "settings.a11y.switch_access"; const char kAccessibilitySwitchAccessEnabled[] =
"settings.a11y.switch_access.enabled";
// A pref that stores the key code for the "select" action.
const char kAccessibilitySwitchAccessSelectKeyCodes[] =
"settings.a11y.switch_access.select.key_codes";
// A pref that stores the setting value for the "select" action.
const char kAccessibilitySwitchAccessSelectSetting[] =
"settings.a11y.switch_access.select.setting";
// A pref that stores the key code for the "next" action.
const char kAccessibilitySwitchAccessNextKeyCodes[] =
"settings.a11y.switch_access.next.key_codes";
// A pref that stores the setting value for the "next" action.
const char kAccessibilitySwitchAccessNextSetting[] =
"settings.a11y.switch_access.next.setting";
// A pref that stores the key code for the "previous" action.
const char kAccessibilitySwitchAccessPreviousKeyCodes[] =
"settings.a11y.switch_access.previous.key_codes";
// A pref that stores the setting value for the "previous" action.
const char kAccessibilitySwitchAccessPreviousSetting[] =
"settings.a11y.switch_access.previous.setting";
// A boolean pref which determines whether auto-scanning is enabled within
// switch access.
const char kAccessibilitySwitchAccessAutoScanEnabled[] =
"settings.a11y.switch_access.auto_scan.enabled";
// An integer pref which determines time delay in ms before automatically
// scanning forward (when auto-scan is enabled).
const char kAccessibilitySwitchAccessAutoScanSpeedMs[] =
"settings.a11y.switch_access.auto_scan.speed_ms";
// A boolean pref which determines whether dictation is enabled. // A boolean pref which determines whether dictation is enabled.
const char kAccessibilityDictationEnabled[] = "settings.a11y.dictation"; const char kAccessibilityDictationEnabled[] = "settings.a11y.dictation";
// A boolean pref which determines whether the accessibility menu shows // A boolean pref which determines whether the accessibility menu shows
......
...@@ -33,6 +33,15 @@ ASH_PUBLIC_EXPORT extern const char kAccessibilityCursorHighlightEnabled[]; ...@@ -33,6 +33,15 @@ ASH_PUBLIC_EXPORT extern const char kAccessibilityCursorHighlightEnabled[];
ASH_PUBLIC_EXPORT extern const char kAccessibilityFocusHighlightEnabled[]; ASH_PUBLIC_EXPORT extern const char kAccessibilityFocusHighlightEnabled[];
ASH_PUBLIC_EXPORT extern const char kAccessibilitySelectToSpeakEnabled[]; ASH_PUBLIC_EXPORT extern const char kAccessibilitySelectToSpeakEnabled[];
ASH_PUBLIC_EXPORT extern const char kAccessibilitySwitchAccessEnabled[]; ASH_PUBLIC_EXPORT extern const char kAccessibilitySwitchAccessEnabled[];
ASH_PUBLIC_EXPORT extern const char kAccessibilitySwitchAccessSelectKeyCodes[];
ASH_PUBLIC_EXPORT extern const char kAccessibilitySwitchAccessSelectSetting[];
ASH_PUBLIC_EXPORT extern const char kAccessibilitySwitchAccessNextKeyCodes[];
ASH_PUBLIC_EXPORT extern const char kAccessibilitySwitchAccessNextSetting[];
ASH_PUBLIC_EXPORT extern const char
kAccessibilitySwitchAccessPreviousKeyCodes[];
ASH_PUBLIC_EXPORT extern const char kAccessibilitySwitchAccessPreviousSetting[];
ASH_PUBLIC_EXPORT extern const char kAccessibilitySwitchAccessAutoScanEnabled[];
ASH_PUBLIC_EXPORT extern const char kAccessibilitySwitchAccessAutoScanSpeedMs[];
ASH_PUBLIC_EXPORT extern const char kAccessibilityDictationEnabled[]; ASH_PUBLIC_EXPORT extern const char kAccessibilityDictationEnabled[];
ASH_PUBLIC_EXPORT extern const char kShouldAlwaysShowAccessibilityMenu[]; ASH_PUBLIC_EXPORT extern const char kShouldAlwaysShowAccessibilityMenu[];
......
...@@ -190,6 +190,42 @@ ...@@ -190,6 +190,42 @@
<message name="IDS_SETTINGS_TTS_LINK_DESCRIPTION" desc="Description of link to manage text-to-speech settings"> <message name="IDS_SETTINGS_TTS_LINK_DESCRIPTION" desc="Description of link to manage text-to-speech settings">
Select and customize text-to-speech voices Select and customize text-to-speech voices
</message> </message>
<message name="IDS_SETTINGS_MANAGE_SWITCH_ACCESS_SETTINGS" desc="Title of the page to manage Switch Access settings.">
Switch Access settings
</message>
<message name="IDS_SETTINGS_SWITCH_ASSIGNMENT_HEADING" desc="Heading for the settings section for Switch Access to assign switches to actions">
Switch action assignment
</message>
<message name="IDS_SETTINGS_SWITCH_ASSIGN_OPTION_SPACE" desc="Label for the option to assign the spacebar as a switch.">
Space
</message>
<message name="IDS_SETTINGS_SWITCH_ASSIGN_OPTION_ENTER" desc="Label for the option to assign the enter key as a switch.">
Enter
</message>
<message name="IDS_SETTINGS_SWITCH_ASSIGN_OPTION_NONE" desc="Label for the option to have no switch assigned to an action.">
None
</message>
<message name="IDS_SETTINGS_ASSIGN_SELECT_SWITCH_LABEL" desc="Label for the setting to assign a switch to the action 'Select', which selects the currently focused element and begins an interaction (which varies depending on the element/other settings).">
Select
</message>
<message name="IDS_SETTINGS_ASSIGN_NEXT_SWITCH_LABEL" desc="Label for the setting to assign a switch to the action 'Next', which moves focus to the next element.">
Next
</message>
<message name="IDS_SETTINGS_ASSIGN_PREVIOUS_SWITCH_LABEL" desc="Label for the setting to assign a switch to the action 'Previous', which moves focus to the previous element.">
Previous
</message>
<message name="IDS_SETTINGS_SWITCH_ACCESS_AUTO_SCAN_HEADING" desc="Heading for the settings section containing preferences around Switch Access automatically scanning between elements.">
Auto-scan
</message>
<message name="IDS_SETTINGS_SWITCH_ACCESS_AUTO_SCAN_LABEL" desc="Label for the toggle which enables automatic scanning between elements in Switch Access.">
Enable auto-scan
</message>
<message name="IDS_SETTINGS_SWITCH_ACCESS_AUTO_SCAN_SPEED_LABEL" desc="Label for slider which sets the time interval for automatically scanning to the next element. Will be immediately followed by the numeric value of the interval.">
Scanning speed: <ph name="SPEED_WITH_UNITS">$1<ex>1.5s</ex></ph>
</message>
<message name="IDS_SETTINGS_DURATION_IN_SECONDS" desc="A duration in seconds. Should be short.">
<ph name="DURATION">$1<ex>1.5</ex></ph>s
</message>
<message name="IDS_SETTINGS_LARGE_MOUSE_CURSOR_LABEL" desc="Label for checkbox which enables showing a larger mouse cursor than normal."> <message name="IDS_SETTINGS_LARGE_MOUSE_CURSOR_LABEL" desc="Label for checkbox which enables showing a larger mouse cursor than normal.">
Show large mouse cursor Show large mouse cursor
</message> </message>
......
...@@ -333,6 +333,37 @@ void Preferences::RegisterProfilePrefs( ...@@ -333,6 +333,37 @@ void Preferences::RegisterProfilePrefs(
registry->RegisterBooleanPref( registry->RegisterBooleanPref(
ash::prefs::kAccessibilitySwitchAccessEnabled, false, ash::prefs::kAccessibilitySwitchAccessEnabled, false,
user_prefs::PrefRegistrySyncable::SYNCABLE_PREF | PrefRegistry::PUBLIC); user_prefs::PrefRegistrySyncable::SYNCABLE_PREF | PrefRegistry::PUBLIC);
registry->RegisterListPref(
ash::prefs::kAccessibilitySwitchAccessSelectKeyCodes,
base::Value(std::vector<base::Value>()),
user_prefs::PrefRegistrySyncable::SYNCABLE_PREF | PrefRegistry::PUBLIC);
registry->RegisterIntegerPref(
ash::prefs::kAccessibilitySwitchAccessSelectSetting,
ash::kSwitchAccessAssignmentNone,
user_prefs::PrefRegistrySyncable::SYNCABLE_PREF | PrefRegistry::PUBLIC);
registry->RegisterListPref(
ash::prefs::kAccessibilitySwitchAccessNextKeyCodes,
base::Value(std::vector<base::Value>()),
user_prefs::PrefRegistrySyncable::SYNCABLE_PREF | PrefRegistry::PUBLIC);
registry->RegisterIntegerPref(
ash::prefs::kAccessibilitySwitchAccessNextSetting,
ash::kSwitchAccessAssignmentNone,
user_prefs::PrefRegistrySyncable::SYNCABLE_PREF | PrefRegistry::PUBLIC);
registry->RegisterListPref(
ash::prefs::kAccessibilitySwitchAccessPreviousKeyCodes,
base::Value(std::vector<base::Value>()),
user_prefs::PrefRegistrySyncable::SYNCABLE_PREF | PrefRegistry::PUBLIC);
registry->RegisterIntegerPref(
ash::prefs::kAccessibilitySwitchAccessPreviousSetting,
ash::kSwitchAccessAssignmentNone,
user_prefs::PrefRegistrySyncable::SYNCABLE_PREF | PrefRegistry::PUBLIC);
registry->RegisterBooleanPref(
ash::prefs::kAccessibilitySwitchAccessAutoScanEnabled, false,
user_prefs::PrefRegistrySyncable::SYNCABLE_PREF | PrefRegistry::PUBLIC);
registry->RegisterIntegerPref(
ash::prefs::kAccessibilitySwitchAccessAutoScanSpeedMs,
ash::kDefaultSwitchAccessAutoScanSpeed.InMilliseconds(),
user_prefs::PrefRegistrySyncable::SYNCABLE_PREF | PrefRegistry::PUBLIC);
registry->RegisterBooleanPref( registry->RegisterBooleanPref(
ash::prefs::kShouldAlwaysShowAccessibilityMenu, false, ash::prefs::kShouldAlwaysShowAccessibilityMenu, false,
user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
......
...@@ -355,6 +355,22 @@ const PrefsUtil::TypedPrefMap& PrefsUtil::GetWhitelistedKeys() { ...@@ -355,6 +355,22 @@ const PrefsUtil::TypedPrefMap& PrefsUtil::GetWhitelistedKeys() {
settings_api::PrefType::PREF_TYPE_BOOLEAN; settings_api::PrefType::PREF_TYPE_BOOLEAN;
(*s_whitelist)[ash::prefs::kAccessibilitySwitchAccessEnabled] = (*s_whitelist)[ash::prefs::kAccessibilitySwitchAccessEnabled] =
settings_api::PrefType::PREF_TYPE_BOOLEAN; settings_api::PrefType::PREF_TYPE_BOOLEAN;
(*s_whitelist)[ash::prefs::kAccessibilitySwitchAccessSelectKeyCodes] =
settings_api::PrefType::PREF_TYPE_LIST;
(*s_whitelist)[ash::prefs::kAccessibilitySwitchAccessSelectSetting] =
settings_api::PrefType::PREF_TYPE_NUMBER;
(*s_whitelist)[ash::prefs::kAccessibilitySwitchAccessNextKeyCodes] =
settings_api::PrefType::PREF_TYPE_LIST;
(*s_whitelist)[ash::prefs::kAccessibilitySwitchAccessNextSetting] =
settings_api::PrefType::PREF_TYPE_NUMBER;
(*s_whitelist)[ash::prefs::kAccessibilitySwitchAccessPreviousKeyCodes] =
settings_api::PrefType::PREF_TYPE_LIST;
(*s_whitelist)[ash::prefs::kAccessibilitySwitchAccessPreviousSetting] =
settings_api::PrefType::PREF_TYPE_NUMBER;
(*s_whitelist)[ash::prefs::kAccessibilitySwitchAccessAutoScanEnabled] =
settings_api::PrefType::PREF_TYPE_BOOLEAN;
(*s_whitelist)[ash::prefs::kAccessibilitySwitchAccessAutoScanSpeedMs] =
settings_api::PrefType::PREF_TYPE_NUMBER;
(*s_whitelist)[ash::prefs::kAccessibilityVirtualKeyboardEnabled] = (*s_whitelist)[ash::prefs::kAccessibilityVirtualKeyboardEnabled] =
settings_api::PrefType::PREF_TYPE_BOOLEAN; settings_api::PrefType::PREF_TYPE_BOOLEAN;
(*s_whitelist)[ash::prefs::kAccessibilityMonoAudioEnabled] = (*s_whitelist)[ash::prefs::kAccessibilityMonoAudioEnabled] =
......
...@@ -54,6 +54,14 @@ const char* const kPersistentPrefNames[] = { ...@@ -54,6 +54,14 @@ const char* const kPersistentPrefNames[] = {
ash::prefs::kAccessibilityFocusHighlightEnabled, ash::prefs::kAccessibilityFocusHighlightEnabled,
ash::prefs::kAccessibilitySelectToSpeakEnabled, ash::prefs::kAccessibilitySelectToSpeakEnabled,
ash::prefs::kAccessibilitySwitchAccessEnabled, ash::prefs::kAccessibilitySwitchAccessEnabled,
ash::prefs::kAccessibilitySwitchAccessSelectKeyCodes,
ash::prefs::kAccessibilitySwitchAccessSelectSetting,
ash::prefs::kAccessibilitySwitchAccessNextKeyCodes,
ash::prefs::kAccessibilitySwitchAccessNextSetting,
ash::prefs::kAccessibilitySwitchAccessPreviousKeyCodes,
ash::prefs::kAccessibilitySwitchAccessPreviousSetting,
ash::prefs::kAccessibilitySwitchAccessAutoScanEnabled,
ash::prefs::kAccessibilitySwitchAccessAutoScanSpeedMs,
ash::prefs::kAccessibilityDictationEnabled, ash::prefs::kAccessibilityDictationEnabled,
ash::prefs::kDockedMagnifierEnabled, ash::prefs::kDockedMagnifierEnabled,
ash::prefs::kDockedMagnifierScale, ash::prefs::kDockedMagnifierScale,
......
...@@ -13,6 +13,7 @@ js_type_check("closure_compile") { ...@@ -13,6 +13,7 @@ js_type_check("closure_compile") {
deps += [ deps += [
":externs", ":externs",
":manage_a11y_page", ":manage_a11y_page",
":switch_access_subpage",
":tts_subpage", ":tts_subpage",
] ]
} }
...@@ -36,6 +37,15 @@ js_library("manage_a11y_page") { ...@@ -36,6 +37,15 @@ js_library("manage_a11y_page") {
externs_list = [ "$externs_path/settings_private.js" ] externs_list = [ "$externs_path/settings_private.js" ]
} }
js_library("switch_access_subpage") {
deps = [
"..:route",
"//ui/webui/resources/js:i18n_behavior",
"//ui/webui/resources/js:load_time_data",
"//ui/webui/resources/js:web_ui_listener_behavior",
]
}
js_library("tts_subpage") { js_library("tts_subpage") {
deps = [ deps = [
":externs", ":externs",
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
<link rel="import" href="../controls/settings_toggle_button.html"> <link rel="import" href="../controls/settings_toggle_button.html">
<link rel="import" href="../settings_page/settings_animated_pages.html"> <link rel="import" href="../settings_page/settings_animated_pages.html">
<link rel="import" href="../settings_page/settings_subpage.html"> <link rel="import" href="../settings_page/settings_subpage.html">
<link rel="import" href="switch_access_subpage.html">
<link rel="import" href="tts_subpage.html"> <link rel="import" href="tts_subpage.html">
</if> </if>
...@@ -56,6 +57,15 @@ ...@@ -56,6 +57,15 @@
</settings-tts-subpage> </settings-tts-subpage>
</settings-subpage> </settings-subpage>
</template> </template>
<template is="dom-if" if="[[showExperimentalSwitchAccess_]]">
<template is="dom-if" route-path="/manageAccessibility/switchAccess">
<settings-subpage associated-control="[[$$('#subpage-trigger')]]"
page-title="$i18n{manageSwitchAccessSettings}">
<settings-switch-access-subpage prefs="{{prefs.settings.a11y}}">
</settings-switch-access-subpage>
</settings-subpage>
</template>
</template>
</settings-animated-pages> </settings-animated-pages>
</template> </template>
<cr-link-row class="hr" label="$i18n{moreFeaturesLink}" <cr-link-row class="hr" label="$i18n{moreFeaturesLink}"
......
...@@ -65,6 +65,18 @@ Polymer({ ...@@ -65,6 +65,18 @@ Polymer({
return loadTimeData.getBoolean('showExperimentalA11yFeatures'); return loadTimeData.getBoolean('showExperimentalA11yFeatures');
}, },
}, },
/**
* Whether to show Switch Access.
* @private {boolean}
*/
showExperimentalSwitchAccess_: {
type: Boolean,
value: function() {
return loadTimeData.getBoolean(
'showExperimentalAccessibilitySwitchAccess');
},
},
// </if> // </if>
}, },
......
...@@ -133,10 +133,11 @@ ...@@ -133,10 +133,11 @@
</settings-toggle-button> </settings-toggle-button>
<template is="dom-if" if="[[showExperimentalSwitchAccess_]]"> <template is="dom-if" if="[[showExperimentalSwitchAccess_]]">
<settings-toggle-button <settings-toggle-button
pref="{{prefs.settings.a11y.switch_access}}" pref="{{prefs.settings.a11y.switch_access.enabled}}"
label="$i18n{switchAccessLabel}"> label="$i18n{switchAccessLabel}">
</settings-toggle-button> </settings-toggle-button>
<iron-collapse opened="[[prefs.settings.a11y.switch_access.value]]"> <iron-collapse
opened="[[prefs.settings.a11y.switch_access.enabled.value]]">
<cr-link-row label="$i18n{switchAccessOptionsLabel}" <cr-link-row label="$i18n{switchAccessOptionsLabel}"
on-click="onSwitchAccessSettingsTap_" embedded external> on-click="onSwitchAccessSettingsTap_" embedded external>
</cr-link-row> </cr-link-row>
......
<link rel="import" href="chrome://resources/html/polymer.html">
<link rel="import" href="chrome://resources/html/i18n_behavior.html">
<link rel="import" href="chrome://resources/html/md_select_css.html">
<link rel="import" href="../controls/settings_dropdown_menu.html">
<link rel="import" href="../controls/settings_slider.html">
<link rel="import" href="../controls/settings_toggle_button.html">
<link rel="import" href="../i18n_setup.html">
<link rel="import" href="../settings_shared_css.html">
<dom-module id="settings-switch-access-subpage">
<template>
<style include="settings-shared md-select">
h2 {
padding-inline-start: var(--cr-section-padding);
}
</style>
<h2>$i18n{switchAssignmentHeading}</h2>
<div class="list-frame">
<div class="settings-box continuation list-item">
<div class="start sub-item">
$i18n{assignSelectSwitchLabel}
</div>
<settings-dropdown-menu label="$i18n{assignSelectSwitchLabel}"
pref="{{prefs.switch_access.select.dropdown}}"
menu-options="[[switchAssignOptions_]]"
on-settings-control-change="onSelectAssigned_">
</settings-dropdown-menu>
</div>
<div class="settings-box continuation list-item">
<div class="start sub-item">
$i18n{assignNextSwitchLabel}
</div>
<settings-dropdown-menu label="$i18n{assignNextSwitchLabel}"
pref="{{prefs.switch_access.next.dropdown}}"
menu-options="[[switchAssignOptions_]]"
on-settings-control-change="onNextAssigned_">
</settings-dropdown-menu>
</div>
<div class="settings-box continuation list-item">
<div class="start sub-item">
$i18n{assignPreviousSwitchLabel}
</div>
<settings-dropdown-menu label="$i18n{assignPreviousSwitchLabel}"
pref="{{prefs.switch_access.previous.dropdown}}"
menu-options="[[switchAssignOptions_]]"
on-settings-control-change="onPreviousAssigned_">
</settings-dropdown-menu>
</div>
</div>
<h2>$i18n{switchAccessAutoScanHeading}</h2>
<div class="list-frame">
<settings-toggle-button class="continuation list-item"
pref="{{prefs.switch_access.auto_scan.enabled}}"
label="$i18n{switchAccessAutoScanLabel}">
</settings-toggle-button>
<div class="settings-box continuation list-item"
hidden$="[[!prefs.switch_access.auto_scan.enabled.value]]">
<div class="start sub-item" id="scanSpeed">
[[getLabelForSpeedSlider_(prefs.switch_access.auto_scan.speed_ms.*)]]
</div>
<settings-slider id="scanSpeedSlider" aria-describedby="scanSpeed"
pref="{{prefs.switch_access.auto_scan.speed_ms}}"
ticks="[[autoScanSpeedValuesMs_]]"
min="[[minScanSpeedMs_]]"
max="[[maxScanSpeedMs_]]"
label-min="[[minScanSpeedLabelSec_]]"
label-max="[[maxScanSpeedLabelSec_]]">
</settings-dropdown-menu>
</div>
</div>
</template>
<script src="switch_access_subpage.js"></script>
</dom-module>
// 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.
/**
* Available switch assignment values.
* @enum {number}
* @const
*/
const SwitchAccessAssignmentValue = {
NONE: 0,
SPACE: 1,
ENTER: 2,
};
/**
* @fileoverview 'switch-access-subpage' is the collapsible section containing
* Switch Access settings.
*/
Polymer({
is: 'settings-switch-access-subpage',
behaviors: [I18nBehavior],
properties: {
/**
* Preferences state.
*/
prefs: {
type: Object,
notify: true,
},
/** @private {Array<number>} */
autoScanSpeedValuesMs_: {
readOnly: true,
type: Array,
value: [
500, 600, 700, 800, 900, 1000, 1100, 1200, 1300,
1400, 1500, 1600, 1700, 1800, 1900, 2000, 2100, 2200,
2300, 2400, 2500, 2600, 2700, 2800, 2900, 3000, 3100,
3200, 3300, 3400, 3500, 3600, 3700, 3800, 3900, 4000
]
},
/** @private {Object} */
formatter_: {
type: Object,
value: function() {
// navigator.language actually returns a locale, not just a language.
const locale = window.navigator.language;
const options = {minimumFractionDigits: 1, maximumFractionDigits: 1};
return new Intl.NumberFormat(locale, options);
},
},
/** @private {number} */
maxScanSpeedMs_: {readOnly: true, type: Number, value: 4000},
/** @private {string} */
maxScanSpeedLabelSec_: {
readOnly: true,
type: String,
value: function() {
return this.scanSpeedStringInSec_(this.maxScanSpeedMs_);
},
},
/** @private {number} */
minScanSpeedMs_: {readOnly: true, type: Number, value: 500},
/** @private {string} */
minScanSpeedLabelSec_: {
readOnly: true,
type: String,
value: function() {
return this.scanSpeedStringInSec_(this.minScanSpeedMs_);
},
},
/** @private {Array<Object>} */
switchAssignOptions_: {
readOnly: true,
type: Array,
value: function() {
return [
{
value: SwitchAccessAssignmentValue.NONE,
name: this.i18n('switchAssignOptionNone')
},
{
value: SwitchAccessAssignmentValue.SPACE,
name: this.i18n('switchAssignOptionSpace')
},
{
value: SwitchAccessAssignmentValue.ENTER,
name: this.i18n('switchAssignOptionEnter')
},
];
},
},
},
/**
* @return {string}
* @private
*/
currentSpeed_: function() {
const speed = this.get('prefs.switch_access.auto_scan.speed_ms.value');
if (typeof speed != 'number') {
return '';
}
return this.scanSpeedStringInSec_(speed);
},
/**
* @return {string} label for the speed slider.
* @private
*/
getLabelForSpeedSlider_: function() {
const speedString = this.currentSpeed_();
return this.i18n('switchAccessAutoScanSpeedLabel', speedString);
},
/**
* @param {string} command
*/
onSwitchAssigned_: function(command) {
const pref = 'prefs.switch_access.' + command;
const keyCodeSuffix = '.key_codes.value';
const settingSuffix = '.setting.value';
switch (this.get(pref + settingSuffix)) {
case SwitchAccessAssignmentValue.NONE:
this.set(pref + keyCodeSuffix, []);
break;
case SwitchAccessAssignmentValue.SPACE:
this.set(pref + keyCodeSuffix, [32]);
break;
case SwitchAccessAssignmentValue.ENTER:
this.set(pref + keyCodeSuffix, [13]);
break;
}
},
onNextAssigned_: function() {
this.onSwitchAssigned_('next');
},
onPreviousAssigned_: function() {
this.onSwitchAssigned_('previous');
},
onSelectAssigned_: function() {
this.onSwitchAssigned_('select');
},
/**
* @param {number} scanSpeedValueMs
* @return {string} a string representing the scan speed in seconds.
* @private
*/
scanSpeedStringInSec_: function(scanSpeedValueMs) {
const scanSpeedValueSec = scanSpeedValueMs / 1000;
return this.i18n(
'durationInSeconds', this.formatter_.format(scanSpeedValueSec));
},
});
...@@ -9,6 +9,7 @@ js_type_check("closure_compile") { ...@@ -9,6 +9,7 @@ js_type_check("closure_compile") {
":os_a11y_page", ":os_a11y_page",
"../../a11y_page:externs", "../../a11y_page:externs",
"../../a11y_page:manage_a11y_page", "../../a11y_page:manage_a11y_page",
"../../a11y_page:switch_access_subpage",
"../../a11y_page:tts_subpage", "../../a11y_page:tts_subpage",
] ]
} }
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
<link rel="import" href="../../controls/settings_toggle_button.html"> <link rel="import" href="../../controls/settings_toggle_button.html">
<link rel="import" href="../../settings_page/settings_animated_pages.html"> <link rel="import" href="../../settings_page/settings_animated_pages.html">
<link rel="import" href="../../settings_page/settings_subpage.html"> <link rel="import" href="../../settings_page/settings_subpage.html">
<link rel="import" href="../../a11y_page/switch_access_subpage.html">
<link rel="import" href="../../a11y_page/tts_subpage.html"> <link rel="import" href="../../a11y_page/tts_subpage.html">
<dom-module id="os-settings-a11y-page"> <dom-module id="os-settings-a11y-page">
...@@ -51,6 +52,15 @@ ...@@ -51,6 +52,15 @@
</settings-tts-subpage> </settings-tts-subpage>
</settings-subpage> </settings-subpage>
</template> </template>
<template is="dom-if" if="[[showExperimentalSwitchAccess_]]">
<template is="dom-if" route-path="/manageAccessibility/switchAccess">
<settings-subpage associated-control="[[$$('#subpage-trigger')]]"
page-title="$i18n{manageSwitchAccessSettings}">
<settings-switch-access-subpage prefs="{{prefs.settings.a11y}}">
</settings-switch-access-subpage>
</settings-subpage>
</template>
</template>
</settings-animated-pages> </settings-animated-pages>
</template> </template>
<script src="os_a11y_page.js"></script> <script src="os_a11y_page.js"></script>
......
...@@ -60,6 +60,18 @@ Polymer({ ...@@ -60,6 +60,18 @@ Polymer({
return loadTimeData.getBoolean('showExperimentalA11yFeatures'); return loadTimeData.getBoolean('showExperimentalA11yFeatures');
}, },
}, },
/**
* Whether to show Switch Access.
* @private {boolean}
*/
showExperimentalSwitchAccess_: {
type: Boolean,
value: function() {
return loadTimeData.getBoolean(
'showExperimentalAccessibilitySwitchAccess');
},
},
}, },
/** @override */ /** @override */
......
...@@ -27,6 +27,12 @@ ...@@ -27,6 +27,12 @@
<structure name="IDR_OS_SETTINGS_MANAGE_A11Y_PAGE_HTML" <structure name="IDR_OS_SETTINGS_MANAGE_A11Y_PAGE_HTML"
file="a11y_page/manage_a11y_page.html" file="a11y_page/manage_a11y_page.html"
type="chrome_html" /> type="chrome_html" />
<structure name="IDS_OS_SETTINGS_SWITCH_ACCESS_SUBPAGE_JS"
file="a11y_page/switch_access_subpage.js"
type="chrome_html" />
<structure name="IDR_OS_SETTINGS_SWITCH_ACCESS_SUBPAGE_HTML"
file="a11y_page/switch_access_subpage.html"
type="chrome_html" />
<structure name="IDR_OS_SETTINGS_TTS_SUBPAGE_JS" <structure name="IDR_OS_SETTINGS_TTS_SUBPAGE_JS"
file="a11y_page/tts_subpage.js" file="a11y_page/tts_subpage.js"
type="chrome_html" /> type="chrome_html" />
......
...@@ -56,6 +56,7 @@ ...@@ -56,6 +56,7 @@
* LOCK_SCREEN: (undefined|!settings.Route), * LOCK_SCREEN: (undefined|!settings.Route),
* MANAGE_ACCESSIBILITY: (undefined|!settings.Route), * MANAGE_ACCESSIBILITY: (undefined|!settings.Route),
* MANAGE_PROFILE: (undefined|!settings.Route), * MANAGE_PROFILE: (undefined|!settings.Route),
* MANAGE_SWITCH_ACCESS_SETTINGS: (undefined|!settings.Route),
* MANAGE_TTS_SETTINGS: (undefined|!settings.Route), * MANAGE_TTS_SETTINGS: (undefined|!settings.Route),
* MULTIDEVICE: (undefined|!settings.Route), * MULTIDEVICE: (undefined|!settings.Route),
* MULTIDEVICE_FEATURES: (undefined|!settings.Route), * MULTIDEVICE_FEATURES: (undefined|!settings.Route),
...@@ -456,6 +457,8 @@ cr.define('settings', function() { ...@@ -456,6 +457,8 @@ cr.define('settings', function() {
// <if expr="chromeos"> // <if expr="chromeos">
r.MANAGE_ACCESSIBILITY = r.MANAGE_ACCESSIBILITY =
r.ACCESSIBILITY.createChild('/manageAccessibility'); r.ACCESSIBILITY.createChild('/manageAccessibility');
r.MANAGE_SWITCH_ACCESS_SETTINGS = r.MANAGE_ACCESSIBILITY.createChild(
'/manageAccessibility/switchAccess');
r.MANAGE_TTS_SETTINGS = r.MANAGE_TTS_SETTINGS =
r.MANAGE_ACCESSIBILITY.createChild('/manageAccessibility/tts'); r.MANAGE_ACCESSIBILITY.createChild('/manageAccessibility/tts');
// </if> // </if>
......
...@@ -28,6 +28,12 @@ ...@@ -28,6 +28,12 @@
<structure name="IDR_SETTINGS_MANAGE_A11Y_PAGE_HTML" <structure name="IDR_SETTINGS_MANAGE_A11Y_PAGE_HTML"
file="a11y_page/manage_a11y_page.html" file="a11y_page/manage_a11y_page.html"
type="chrome_html" /> type="chrome_html" />
<structure name="IDR_SETTINGS_SWITCH_ACCESS_SUBPAGE_JS"
file="a11y_page/switch_access_subpage.js"
type="chrome_html" />
<structure name="IDR_SETTINGS_SWITCH_ACCESS_SUBPAGE_HTML"
file="a11y_page/switch_access_subpage.html"
type="chrome_html" />
<structure name="IDR_SETTINGS_TTS_SUBPAGE_JS" <structure name="IDR_SETTINGS_TTS_SUBPAGE_JS"
file="a11y_page/tts_subpage.js" file="a11y_page/tts_subpage.js"
type="chrome_html" /> type="chrome_html" />
......
...@@ -265,6 +265,20 @@ void AddA11yStrings(content::WebUIDataSource* html_source) { ...@@ -265,6 +265,20 @@ void AddA11yStrings(content::WebUIDataSource* html_source) {
{"switchAccessLabel", IDS_SETTINGS_ACCESSIBILITY_SWITCH_ACCESS_DESCRIPTION}, {"switchAccessLabel", IDS_SETTINGS_ACCESSIBILITY_SWITCH_ACCESS_DESCRIPTION},
{"switchAccessOptionsLabel", {"switchAccessOptionsLabel",
IDS_SETTINGS_ACCESSIBILITY_SWITCH_ACCESS_OPTIONS_LABEL}, IDS_SETTINGS_ACCESSIBILITY_SWITCH_ACCESS_OPTIONS_LABEL},
{"manageSwitchAccessSettings", IDS_SETTINGS_MANAGE_SWITCH_ACCESS_SETTINGS},
{"switchAssignmentHeading", IDS_SETTINGS_SWITCH_ASSIGNMENT_HEADING},
{"switchAssignOptionNone", IDS_SETTINGS_SWITCH_ASSIGN_OPTION_NONE},
{"switchAssignOptionSpace", IDS_SETTINGS_SWITCH_ASSIGN_OPTION_SPACE},
{"switchAssignOptionEnter", IDS_SETTINGS_SWITCH_ASSIGN_OPTION_ENTER},
{"assignSelectSwitchLabel", IDS_SETTINGS_ASSIGN_SELECT_SWITCH_LABEL},
{"assignNextSwitchLabel", IDS_SETTINGS_ASSIGN_NEXT_SWITCH_LABEL},
{"assignPreviousSwitchLabel", IDS_SETTINGS_ASSIGN_PREVIOUS_SWITCH_LABEL},
{"switchAccessAutoScanHeading",
IDS_SETTINGS_SWITCH_ACCESS_AUTO_SCAN_HEADING},
{"switchAccessAutoScanLabel", IDS_SETTINGS_SWITCH_ACCESS_AUTO_SCAN_LABEL},
{"switchAccessAutoScanSpeedLabel",
IDS_SETTINGS_SWITCH_ACCESS_AUTO_SCAN_SPEED_LABEL},
{"durationInSeconds", IDS_SETTINGS_DURATION_IN_SECONDS},
{"manageAccessibilityFeatures", {"manageAccessibilityFeatures",
IDS_SETTINGS_ACCESSIBILITY_MANAGE_ACCESSIBILITY_FEATURES}, IDS_SETTINGS_ACCESSIBILITY_MANAGE_ACCESSIBILITY_FEATURES},
{"textToSpeechHeading", IDS_SETTINGS_ACCESSIBILITY_TEXT_TO_SPEECH_HEADING}, {"textToSpeechHeading", IDS_SETTINGS_ACCESSIBILITY_TEXT_TO_SPEECH_HEADING},
......
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