From 756089a218696542cadcf96a1a7ed00025c1f255 Mon Sep 17 00:00:00 2001 From: dmazzoni Date: Tue, 15 Mar 2016 16:55:16 -0700 Subject: Add 5 experimental accessibility features on Chrome OS. This just adds the boilerplate for five new accessibility features and hides them behind a flag. All five have been prototyped and are ready for implementation. The first three are related, they just provide visual highlighting to help low-vision users keep track of things on the screen: * Caret highlight * Cursor highlight * Focus highlight Hold down a key and click or drag to speak any visible text on screen * Select to speak Control the whole computer with a single switch (for motor impaired users) * Switch access For now, there's no need to put these in the tray. They can graduate to the tray when they launch. BUG=314889,593887,593885 Review URL: https://codereview.chromium.org/1785833002 Cr-Commit-Position: refs/heads/master@{#381353} --- ash/accessibility_delegate.h | 30 ++++ ash/default_accessibility_delegate.cc | 51 ++++-- ash/default_accessibility_delegate.h | 31 +++- chrome/app/chromeos_strings.grdp | 21 +++ chrome/browser/about_flags.cc | 7 + .../accessibility/accessibility_manager.cc | 187 +++++++++++++++++++++ .../chromeos/accessibility/accessibility_manager.h | 45 +++++ .../chromeos/extensions/info_private_api.cc | 45 +++-- chrome/browser/chromeos/preferences.cc | 18 +- .../browser/resources/options/browser_options.html | 69 +++++++- .../browser/resources/options/browser_options.js | 2 + .../ui/ash/chrome_shell_delegate_chromeos.cc | 50 ++++++ .../browser/ui/ash/chrome_shell_delegate_views.cc | 20 +++ .../ui/webui/options/browser_options_handler.cc | 14 ++ .../extensions/api/accessibility_features.json | 30 ++++ .../extensions/api/chromeos_info_private.json | 5 + .../templates/intros/accessibilityFeatures.html | 1 + chrome/common/pref_names.cc | 15 ++ chrome/common/pref_names.h | 9 + chromeos/chromeos_switches.cc | 5 + chromeos/chromeos_switches.h | 1 + tools/metrics/actions/actions.xml | 52 ++++++ tools/metrics/histograms/histograms.xml | 41 +++++ 23 files changed, 717 insertions(+), 32 deletions(-) create mode 100644 chrome/common/extensions/docs/templates/intros/accessibilityFeatures.html diff --git a/ash/accessibility_delegate.h b/ash/accessibility_delegate.h index cb821c8..f702c2a 100644 --- a/ash/accessibility_delegate.h +++ b/ash/accessibility_delegate.h @@ -59,6 +59,36 @@ class ASH_EXPORT AccessibilityDelegate { // Returns if the a11y virtual keyboard is enabled. virtual bool IsVirtualKeyboardEnabled() const = 0; + // Invoked to enable or disable caret highlighting. + virtual void SetCaretHighlightEnabled(bool enabled) = 0; + + // Returns if caret highlighting is enabled. + virtual bool IsCaretHighlightEnabled() const = 0; + + // Invoked to enable or disable cursor highlighting. + virtual void SetCursorHighlightEnabled(bool enabled) = 0; + + // Returns if cursor highlighting is enabled. + virtual bool IsCursorHighlightEnabled() const = 0; + + // Invoked to enable or disable focus highlighting. + virtual void SetFocusHighlightEnabled(bool enabled) = 0; + + // Returns if focus highlighting is enabled. + virtual bool IsFocusHighlightEnabled() const = 0; + + // Invoked to enable or disable select-to-speak. + virtual void SetSelectToSpeakEnabled(bool enabled) = 0; + + // Returns if select-to-speak is enabled. + virtual bool IsSelectToSpeakEnabled() const = 0; + + // Invoked to enable or disable switch access. + virtual void SetSwitchAccessEnabled(bool enabled) = 0; + + // Returns if switch access is enabled. + virtual bool IsSwitchAccessEnabled() const = 0; + // Returns true when the accessibility menu should be shown. virtual bool ShouldShowAccessibilityMenu() const = 0; diff --git a/ash/default_accessibility_delegate.cc b/ash/default_accessibility_delegate.cc index f337a2e..402e5b5 100644 --- a/ash/default_accessibility_delegate.cc +++ b/ash/default_accessibility_delegate.cc @@ -8,16 +8,7 @@ namespace ash { -DefaultAccessibilityDelegate::DefaultAccessibilityDelegate() - : spoken_feedback_enabled_(false), - high_contrast_enabled_(false), - screen_magnifier_enabled_(false), - screen_magnifier_type_(ui::kDefaultMagnifierType), - large_cursor_enabled_(false), - autoclick_enabled_(false), - virtual_keyboard_enabled_(false), - accessibility_alert_(ui::A11Y_ALERT_NONE) { -} +DefaultAccessibilityDelegate::DefaultAccessibilityDelegate() {} DefaultAccessibilityDelegate::~DefaultAccessibilityDelegate() {} @@ -73,6 +64,46 @@ bool DefaultAccessibilityDelegate::IsVirtualKeyboardEnabled() const { return virtual_keyboard_enabled_; } +void DefaultAccessibilityDelegate::SetCaretHighlightEnabled(bool enabled) { + caret_highlight_enabled_ = enabled; +} + +bool DefaultAccessibilityDelegate::IsCaretHighlightEnabled() const { + return caret_highlight_enabled_; +} + +void DefaultAccessibilityDelegate::SetCursorHighlightEnabled(bool enabled) { + cursor_highlight_enabled_ = enabled; +} + +bool DefaultAccessibilityDelegate::IsCursorHighlightEnabled() const { + return cursor_highlight_enabled_; +} + +void DefaultAccessibilityDelegate::SetFocusHighlightEnabled(bool enabled) { + focus_highligh_enabled_ = enabled; +} + +bool DefaultAccessibilityDelegate::IsFocusHighlightEnabled() const { + return focus_highligh_enabled_; +} + +void DefaultAccessibilityDelegate::SetSelectToSpeakEnabled(bool enabled) { + select_to_speak_enabled_ = enabled; +} + +bool DefaultAccessibilityDelegate::IsSelectToSpeakEnabled() const { + return select_to_speak_enabled_; +} + +void DefaultAccessibilityDelegate::SetSwitchAccessEnabled(bool enabled) { + switch_access_enabled_ = enabled; +} + +bool DefaultAccessibilityDelegate::IsSwitchAccessEnabled() const { + return switch_access_enabled_; +} + bool DefaultAccessibilityDelegate::ShouldShowAccessibilityMenu() const { return spoken_feedback_enabled_ || high_contrast_enabled_ || diff --git a/ash/default_accessibility_delegate.h b/ash/default_accessibility_delegate.h index e973f56..986b13bb 100644 --- a/ash/default_accessibility_delegate.h +++ b/ash/default_accessibility_delegate.h @@ -30,6 +30,16 @@ class ASH_EXPORT DefaultAccessibilityDelegate : public AccessibilityDelegate { bool IsAutoclickEnabled() const override; void SetVirtualKeyboardEnabled(bool enabled) override; bool IsVirtualKeyboardEnabled() const override; + void SetCaretHighlightEnabled(bool enabled) override; + bool IsCaretHighlightEnabled() const override; + void SetCursorHighlightEnabled(bool enabled) override; + bool IsCursorHighlightEnabled() const override; + void SetFocusHighlightEnabled(bool enabled) override; + bool IsFocusHighlightEnabled() const override; + void SetSelectToSpeakEnabled(bool enabled) override; + bool IsSelectToSpeakEnabled() const override; + void SetSwitchAccessEnabled(bool enabled) override; + bool IsSwitchAccessEnabled() const override; bool ShouldShowAccessibilityMenu() const override; bool IsBrailleDisplayConnected() const override; void SilenceSpokenFeedback() const override; @@ -43,14 +53,19 @@ class ASH_EXPORT DefaultAccessibilityDelegate : public AccessibilityDelegate { base::TimeDelta PlayShutdownSound() const override; private: - bool spoken_feedback_enabled_; - bool high_contrast_enabled_; - bool screen_magnifier_enabled_; - ui::MagnifierType screen_magnifier_type_; - bool large_cursor_enabled_; - bool autoclick_enabled_; - bool virtual_keyboard_enabled_; - ui::AccessibilityAlert accessibility_alert_; + bool spoken_feedback_enabled_ = false; + bool high_contrast_enabled_ = false; + bool screen_magnifier_enabled_ = false; + ui::MagnifierType screen_magnifier_type_ = ui::kDefaultMagnifierType; + bool large_cursor_enabled_ = false; + bool autoclick_enabled_ = false; + bool virtual_keyboard_enabled_ = false; + bool caret_highlight_enabled_ = false; + bool cursor_highlight_enabled_ = false; + bool focus_highligh_enabled_ = false; + bool select_to_speak_enabled_ = false; + bool switch_access_enabled_ = false; + ui::AccessibilityAlert accessibility_alert_ = ui::A11Y_ALERT_NONE; DISALLOW_COPY_AND_ASSIGN(DefaultAccessibilityDelegate); }; diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index 52b5c4a..ca45478 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp @@ -2306,6 +2306,27 @@ Press any key to continue exploring. very long + + Highlight the caret (when editing text) + + + Highlight the mouse cursor + + + Highlight the object with keyboard focus + + + Select-to-speak: Hold down Search and click or drag to speak anything + + + Switch access (control the computer with just one or two switches) + + + Experimental acecssibility features + + + Enable additional accessibility features in the Settings page. + Display settings diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index bfabb90..9b496f8 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc @@ -1800,6 +1800,13 @@ const FeatureEntry kFeatureEntries[] = { IDS_FLAGS_PROTECT_SYNC_CREDENTIAL_ON_REAUTH_DESCRIPTION, kOsAll, FEATURE_VALUE_TYPE( password_manager::features::kProtectSyncCredentialOnReauth)}, +#if defined(OS_CHROMEOS) + {"enable-experimental-accessibility-features", + IDS_FLAGS_EXPERIMENTAL_ACCESSIBILITY_FEATURES_NAME, + IDS_FLAGS_EXPERIMENTAL_ACCESSIBILITY_FEATURES_DESCRIPTION, kOsCrOS, + SINGLE_VALUE_TYPE( + chromeos::switches::kEnableExperimentalAccessibilityFeatures)}, +#endif // NOTE: Adding new command-line switches requires adding corresponding // entries to enum "LoginCustomFlags" in histograms.xml. See note in // histograms.xml and don't forget to run AboutFlagsHistogramTest unit test. diff --git a/chrome/browser/chromeos/accessibility/accessibility_manager.cc b/chrome/browser/chromeos/accessibility/accessibility_manager.cc index add91d4..1ea9351 100644 --- a/chrome/browser/chromeos/accessibility/accessibility_manager.cc +++ b/chrome/browser/chromeos/accessibility/accessibility_manager.cc @@ -399,6 +399,12 @@ AccessibilityManager::AccessibilityManager() autoclick_delay_pref_handler_(prefs::kAccessibilityAutoclickDelayMs), virtual_keyboard_pref_handler_( prefs::kAccessibilityVirtualKeyboardEnabled), + caret_highlight_pref_handler_(prefs::kAccessibilityCaretHighlightEnabled), + cursor_highlight_pref_handler_( + prefs::kAccessibilityCursorHighlightEnabled), + focus_highlight_pref_handler_(prefs::kAccessibilityFocusHighlightEnabled), + select_to_speak_pref_handler_(prefs::kAccessibilitySelectToSpeakEnabled), + switch_access_pref_handler_(prefs::kAccessibilitySwitchAccessEnabled), large_cursor_enabled_(false), sticky_keys_enabled_(false), spoken_feedback_enabled_(false), @@ -406,6 +412,11 @@ AccessibilityManager::AccessibilityManager() autoclick_enabled_(false), autoclick_delay_ms_(ash::AutoclickController::kDefaultAutoclickDelayMs), virtual_keyboard_enabled_(false), + caret_highlight_enabled_(false), + cursor_highlight_enabled_(false), + focus_highlight_enabled_(false), + select_to_speak_enabled_(false), + switch_access_enabled_(false), spoken_feedback_notification_(ui::A11Y_NOTIFICATION_NONE), should_speak_chrome_vox_announcements_on_user_screen_(true), system_sounds_enabled_(false), @@ -866,6 +877,142 @@ void AccessibilityManager::UpdateVirtualKeyboardFromPref() { NotifyAccessibilityStatusChanged(details); } +void AccessibilityManager::SetCaretHighlightEnabled(bool enabled) { + if (!profile_) + return; + + PrefService* pref_service = profile_->GetPrefs(); + pref_service->SetBoolean(prefs::kAccessibilityCaretHighlightEnabled, enabled); + pref_service->CommitPendingWrite(); +} + +bool AccessibilityManager::IsCaretHighlightEnabled() const { + return caret_highlight_enabled_; +} + +void AccessibilityManager::UpdateCaretHighlightFromPref() { + if (!profile_) + return; + + const bool enabled = profile_->GetPrefs()->GetBoolean( + prefs::kAccessibilityCaretHighlightEnabled); + + if (caret_highlight_enabled_ == enabled) + return; + caret_highlight_enabled_ = enabled; + + // TODO(dmazzoni): implement feature here. +} + +void AccessibilityManager::SetCursorHighlightEnabled(bool enabled) { + if (!profile_) + return; + + PrefService* pref_service = profile_->GetPrefs(); + pref_service->SetBoolean(prefs::kAccessibilityCursorHighlightEnabled, + enabled); + pref_service->CommitPendingWrite(); +} + +bool AccessibilityManager::IsCursorHighlightEnabled() const { + return cursor_highlight_enabled_; +} + +void AccessibilityManager::UpdateCursorHighlightFromPref() { + if (!profile_) + return; + + const bool enabled = profile_->GetPrefs()->GetBoolean( + prefs::kAccessibilityCursorHighlightEnabled); + + if (cursor_highlight_enabled_ == enabled) + return; + cursor_highlight_enabled_ = enabled; + + // TODO(dmazzoni): implement feature here. +} + +void AccessibilityManager::SetFocusHighlightEnabled(bool enabled) { + if (!profile_) + return; + + PrefService* pref_service = profile_->GetPrefs(); + pref_service->SetBoolean(prefs::kAccessibilityFocusHighlightEnabled, enabled); + pref_service->CommitPendingWrite(); +} + +bool AccessibilityManager::IsFocusHighlightEnabled() const { + return focus_highlight_enabled_; +} + +void AccessibilityManager::UpdateFocusHighlightFromPref() { + if (!profile_) + return; + + const bool enabled = profile_->GetPrefs()->GetBoolean( + prefs::kAccessibilityFocusHighlightEnabled); + + if (focus_highlight_enabled_ == enabled) + return; + focus_highlight_enabled_ = enabled; + + // TODO(dmazzoni): implement feature here. +} + +void AccessibilityManager::SetSelectToSpeakEnabled(bool enabled) { + if (!profile_) + return; + + PrefService* pref_service = profile_->GetPrefs(); + pref_service->SetBoolean(prefs::kAccessibilitySelectToSpeakEnabled, enabled); + pref_service->CommitPendingWrite(); +} + +bool AccessibilityManager::IsSelectToSpeakEnabled() const { + return select_to_speak_enabled_; +} + +void AccessibilityManager::UpdateSelectToSpeakFromPref() { + if (!profile_) + return; + + const bool enabled = profile_->GetPrefs()->GetBoolean( + prefs::kAccessibilitySelectToSpeakEnabled); + + if (select_to_speak_enabled_ == enabled) + return; + select_to_speak_enabled_ = enabled; + + // TODO(dmazzoni): implement feature here. +} + +void AccessibilityManager::SetSwitchAccessEnabled(bool enabled) { + if (!profile_) + return; + + PrefService* pref_service = profile_->GetPrefs(); + pref_service->SetBoolean(prefs::kAccessibilitySwitchAccessEnabled, enabled); + pref_service->CommitPendingWrite(); +} + +bool AccessibilityManager::IsSwitchAccessEnabled() const { + return switch_access_enabled_; +} + +void AccessibilityManager::UpdateSwitchAccessFromPref() { + if (!profile_) + return; + + const bool enabled = profile_->GetPrefs()->GetBoolean( + prefs::kAccessibilitySwitchAccessEnabled); + + if (switch_access_enabled_ == enabled) + return; + switch_access_enabled_ = enabled; + + // TODO(dmazzoni): implement feature here. +} + bool AccessibilityManager::IsBrailleDisplayConnected() const { return braille_display_connected_; } @@ -965,6 +1112,26 @@ void AccessibilityManager::SetProfile(Profile* profile) { prefs::kAccessibilityVirtualKeyboardEnabled, base::Bind(&AccessibilityManager::UpdateVirtualKeyboardFromPref, base::Unretained(this))); + pref_change_registrar_->Add( + prefs::kAccessibilityCaretHighlightEnabled, + base::Bind(&AccessibilityManager::UpdateCaretHighlightFromPref, + base::Unretained(this))); + pref_change_registrar_->Add( + prefs::kAccessibilityCursorHighlightEnabled, + base::Bind(&AccessibilityManager::UpdateCursorHighlightFromPref, + base::Unretained(this))); + pref_change_registrar_->Add( + prefs::kAccessibilityFocusHighlightEnabled, + base::Bind(&AccessibilityManager::UpdateFocusHighlightFromPref, + base::Unretained(this))); + pref_change_registrar_->Add( + prefs::kAccessibilitySelectToSpeakEnabled, + base::Bind(&AccessibilityManager::UpdateSelectToSpeakFromPref, + base::Unretained(this))); + pref_change_registrar_->Add( + prefs::kAccessibilitySwitchAccessEnabled, + base::Bind(&AccessibilityManager::UpdateSwitchAccessFromPref, + base::Unretained(this))); local_state_pref_change_registrar_.reset(new PrefChangeRegistrar); local_state_pref_change_registrar_->Init(g_browser_process->local_state()); @@ -985,6 +1152,11 @@ void AccessibilityManager::SetProfile(Profile* profile) { autoclick_pref_handler_.HandleProfileChanged(profile_, profile); autoclick_delay_pref_handler_.HandleProfileChanged(profile_, profile); virtual_keyboard_pref_handler_.HandleProfileChanged(profile_, profile); + caret_highlight_pref_handler_.HandleProfileChanged(profile_, profile); + cursor_highlight_pref_handler_.HandleProfileChanged(profile_, profile); + focus_highlight_pref_handler_.HandleProfileChanged(profile_, profile); + select_to_speak_pref_handler_.HandleProfileChanged(profile_, profile); + switch_access_pref_handler_.HandleProfileChanged(profile_, profile); bool had_profile = (profile_ != NULL); profile_ = profile; @@ -1000,6 +1172,11 @@ void AccessibilityManager::SetProfile(Profile* profile) { UpdateAutoclickFromPref(); UpdateAutoclickDelayFromPref(); UpdateVirtualKeyboardFromPref(); + UpdateCaretHighlightFromPref(); + UpdateCursorHighlightFromPref(); + UpdateFocusHighlightFromPref(); + UpdateSelectToSpeakFromPref(); + UpdateSwitchAccessFromPref(); } void AccessibilityManager::ActiveUserChanged(const AccountId& account_id) { @@ -1088,6 +1265,16 @@ void AccessibilityManager::UpdateChromeOSAccessibilityHistograms() { 50); } } + UMA_HISTOGRAM_BOOLEAN("Accessibility.CrosCaretHighlight", + IsCaretHighlightEnabled()); + UMA_HISTOGRAM_BOOLEAN("Accessibility.CrosCursorHighlight", + IsCursorHighlightEnabled()); + UMA_HISTOGRAM_BOOLEAN("Accessibility.CrosFocusHighlight", + IsFocusHighlightEnabled()); + UMA_HISTOGRAM_BOOLEAN("Accessibility.CrosSelectToSpeak", + IsSelectToSpeakEnabled()); + UMA_HISTOGRAM_BOOLEAN("Accessibility.CrosSwitchAccess", + IsSwitchAccessEnabled()); } void AccessibilityManager::Observe( diff --git a/chrome/browser/chromeos/accessibility/accessibility_manager.h b/chrome/browser/chromeos/accessibility/accessibility_manager.h index 50121fb..3fbc377 100644 --- a/chrome/browser/chromeos/accessibility/accessibility_manager.h +++ b/chrome/browser/chromeos/accessibility/accessibility_manager.h @@ -165,6 +165,36 @@ class AccessibilityManager // Returns true if the virtual keyboard is enabled, otherwise false. bool IsVirtualKeyboardEnabled(); + // Invoked to enable or disable caret highlighting. + void SetCaretHighlightEnabled(bool enabled); + + // Returns if caret highlighting is enabled. + bool IsCaretHighlightEnabled() const; + + // Invoked to enable or disable cursor highlighting. + void SetCursorHighlightEnabled(bool enabled); + + // Returns if cursor highlighting is enabled. + bool IsCursorHighlightEnabled() const; + + // Invoked to enable or disable focus highlighting. + void SetFocusHighlightEnabled(bool enabled); + + // Returns if focus highlighting is enabled. + bool IsFocusHighlightEnabled() const; + + // Invoked to enable or disable select-to-speak. + void SetSelectToSpeakEnabled(bool enabled); + + // Returns if select-to-speak is enabled. + bool IsSelectToSpeakEnabled() const; + + // Invoked to enable or disable switch access. + void SetSwitchAccessEnabled(bool enabled); + + // Returns if switch access is enabled. + bool IsSwitchAccessEnabled() const; + // Returns true if a braille display is connected to the system, otherwise // false. bool IsBrailleDisplayConnected() const; @@ -246,6 +276,11 @@ class AccessibilityManager void UpdateAutoclickFromPref(); void UpdateAutoclickDelayFromPref(); void UpdateVirtualKeyboardFromPref(); + void UpdateCaretHighlightFromPref(); + void UpdateCursorHighlightFromPref(); + void UpdateFocusHighlightFromPref(); + void UpdateSelectToSpeakFromPref(); + void UpdateSwitchAccessFromPref(); void CheckBrailleState(); void ReceiveBrailleDisplayState( @@ -300,6 +335,11 @@ class AccessibilityManager PrefHandler autoclick_pref_handler_; PrefHandler autoclick_delay_pref_handler_; PrefHandler virtual_keyboard_pref_handler_; + PrefHandler caret_highlight_pref_handler_; + PrefHandler cursor_highlight_pref_handler_; + PrefHandler focus_highlight_pref_handler_; + PrefHandler select_to_speak_pref_handler_; + PrefHandler switch_access_pref_handler_; bool large_cursor_enabled_; bool sticky_keys_enabled_; @@ -308,6 +348,11 @@ class AccessibilityManager bool autoclick_enabled_; int autoclick_delay_ms_; bool virtual_keyboard_enabled_; + bool caret_highlight_enabled_; + bool cursor_highlight_enabled_; + bool focus_highlight_enabled_; + bool select_to_speak_enabled_; + bool switch_access_enabled_; ui::AccessibilityNotificationVisibility spoken_feedback_notification_; diff --git a/chrome/browser/chromeos/extensions/info_private_api.cc b/chrome/browser/chromeos/extensions/info_private_api.cc index e827294..16640f8 100644 --- a/chrome/browser/chromeos/extensions/info_private_api.cc +++ b/chrome/browser/chromeos/extensions/info_private_api.cc @@ -81,6 +81,21 @@ const char kPropertyAutoclickEnabled[] = "a11yAutoClickEnabled"; // Key which corresponds to the auto click A11Y property in JS. const char kPropertyVirtualKeyboardEnabled[] = "a11yVirtualKeyboardEnabled"; +// Key which corresponds to the caret highlight A11Y property in JS. +const char kPropertyCaretHighlightEnabled[] = "a11yCaretHighlightEnabled"; + +// Key which corresponds to the cursor highlight A11Y property in JS. +const char kPropertyCursorHighlightEnabled[] = "a11yCursorHighlightEnabled"; + +// Key which corresponds to the focus highlight A11Y property in JS. +const char kPropertyFocusHighlightEnabled[] = "a11yFocusHighlightEnabled"; + +// Key which corresponds to the select-to-speak A11Y property in JS. +const char kPropertySelectToSpeakEnabled[] = "a11ySelectToSpeakEnabled"; + +// Key which corresponds to the switch access A11Y property in JS. +const char kPropertySwitchAccessEnabled[] = "a11ySwitchAccessEnabled"; + // Key which corresponds to the send-function-keys property in JS. const char kPropertySendFunctionsKeys[] = "sendFunctionKeys"; @@ -91,17 +106,25 @@ const struct { const char* api_name; const char* preference_name; } kPreferencesMap[] = { - {kPropertyLargeCursorEnabled, prefs::kAccessibilityLargeCursorEnabled}, - {kPropertyStickyKeysEnabled, prefs::kAccessibilityStickyKeysEnabled}, - {kPropertySpokenFeedbackEnabled, - prefs::kAccessibilitySpokenFeedbackEnabled}, - {kPropertyHighContrastEnabled, prefs::kAccessibilityHighContrastEnabled}, - {kPropertyScreenMagnifierEnabled, - prefs::kAccessibilityScreenMagnifierEnabled}, - {kPropertyAutoclickEnabled, prefs::kAccessibilityAutoclickEnabled}, - {kPropertyVirtualKeyboardEnabled, - prefs::kAccessibilityVirtualKeyboardEnabled}, - {kPropertySendFunctionsKeys, prefs::kLanguageSendFunctionKeys}}; + {kPropertyLargeCursorEnabled, prefs::kAccessibilityLargeCursorEnabled}, + {kPropertyStickyKeysEnabled, prefs::kAccessibilityStickyKeysEnabled}, + {kPropertySpokenFeedbackEnabled, + prefs::kAccessibilitySpokenFeedbackEnabled}, + {kPropertyHighContrastEnabled, prefs::kAccessibilityHighContrastEnabled}, + {kPropertyScreenMagnifierEnabled, + prefs::kAccessibilityScreenMagnifierEnabled}, + {kPropertyAutoclickEnabled, prefs::kAccessibilityAutoclickEnabled}, + {kPropertyVirtualKeyboardEnabled, + prefs::kAccessibilityVirtualKeyboardEnabled}, + {kPropertyCaretHighlightEnabled, + prefs::kAccessibilityCaretHighlightEnabled}, + {kPropertyCursorHighlightEnabled, + prefs::kAccessibilityCursorHighlightEnabled}, + {kPropertyFocusHighlightEnabled, + prefs::kAccessibilityFocusHighlightEnabled}, + {kPropertySelectToSpeakEnabled, prefs::kAccessibilitySelectToSpeakEnabled}, + {kPropertySwitchAccessEnabled, prefs::kAccessibilitySwitchAccessEnabled}, + {kPropertySendFunctionsKeys, prefs::kLanguageSendFunctionKeys}}; const char* GetBoolPrefNameForApiProperty(const char* api_name) { for (size_t i = 0; diff --git a/chrome/browser/chromeos/preferences.cc b/chrome/browser/chromeos/preferences.cc index 5fb9161..16a742d 100644 --- a/chrome/browser/chromeos/preferences.cc +++ b/chrome/browser/chromeos/preferences.cc @@ -177,8 +177,22 @@ void Preferences::RegisterProfilePrefs( false, user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); registry->RegisterBooleanPref( - prefs::kShouldAlwaysShowAccessibilityMenu, - false, + prefs::kAccessibilityCaretHighlightEnabled, false, + user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); + registry->RegisterBooleanPref( + prefs::kAccessibilityCursorHighlightEnabled, false, + user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); + registry->RegisterBooleanPref( + prefs::kAccessibilityFocusHighlightEnabled, false, + user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); + registry->RegisterBooleanPref( + prefs::kAccessibilitySelectToSpeakEnabled, false, + user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); + registry->RegisterBooleanPref( + prefs::kAccessibilitySwitchAccessEnabled, false, + user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); + registry->RegisterBooleanPref( + prefs::kShouldAlwaysShowAccessibilityMenu, false, user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); registry->RegisterIntegerPref( prefs::kMouseSensitivity, diff --git a/chrome/browser/resources/options/browser_options.html b/chrome/browser/resources/options/browser_options.html index 0a48159..77ee6a1 100644 --- a/chrome/browser/resources/options/browser_options.html +++ b/chrome/browser/resources/options/browser_options.html @@ -953,7 +953,7 @@ pref="settings.a11y.autoclick_delay_ms"> -
+
+
diff --git a/chrome/browser/resources/options/browser_options.js b/chrome/browser/resources/options/browser_options.js index 49d7c9b..2b63e80 100644 --- a/chrome/browser/resources/options/browser_options.js +++ b/chrome/browser/resources/options/browser_options.js @@ -728,6 +728,8 @@ cr.define('options', function() { Preferences.getInstance().addEventListener( $('accessibility-autoclick-check').getAttribute('pref'), updateDelayDropdown); + $('experimental-accessibility-features').hidden = + !loadTimeData.getBoolean('enableExperimentalAccessibilityFeatures'); } // Display management section (CrOS only). diff --git a/chrome/browser/ui/ash/chrome_shell_delegate_chromeos.cc b/chrome/browser/ui/ash/chrome_shell_delegate_chromeos.cc index 8140a59..eb0401e 100644 --- a/chrome/browser/ui/ash/chrome_shell_delegate_chromeos.cc +++ b/chrome/browser/ui/ash/chrome_shell_delegate_chromeos.cc @@ -147,6 +147,56 @@ class AccessibilityDelegateImpl : public ash::AccessibilityDelegate { return chromeos::AccessibilityManager::Get()->IsVirtualKeyboardEnabled(); } + void SetCaretHighlightEnabled(bool enabled) override { + DCHECK(chromeos::AccessibilityManager::Get()); + chromeos::AccessibilityManager::Get()->SetCaretHighlightEnabled(enabled); + } + + bool IsCaretHighlightEnabled() const override { + DCHECK(chromeos::AccessibilityManager::Get()); + return chromeos::AccessibilityManager::Get()->IsCaretHighlightEnabled(); + } + + void SetCursorHighlightEnabled(bool enabled) override { + DCHECK(chromeos::AccessibilityManager::Get()); + chromeos::AccessibilityManager::Get()->SetCursorHighlightEnabled(enabled); + } + + bool IsCursorHighlightEnabled() const override { + DCHECK(chromeos::AccessibilityManager::Get()); + return chromeos::AccessibilityManager::Get()->IsCursorHighlightEnabled(); + } + + void SetFocusHighlightEnabled(bool enabled) override { + DCHECK(chromeos::AccessibilityManager::Get()); + chromeos::AccessibilityManager::Get()->SetFocusHighlightEnabled(enabled); + } + + bool IsFocusHighlightEnabled() const override { + DCHECK(chromeos::AccessibilityManager::Get()); + return chromeos::AccessibilityManager::Get()->IsFocusHighlightEnabled(); + } + + void SetSelectToSpeakEnabled(bool enabled) override { + DCHECK(chromeos::AccessibilityManager::Get()); + chromeos::AccessibilityManager::Get()->SetSelectToSpeakEnabled(enabled); + } + + bool IsSelectToSpeakEnabled() const override { + DCHECK(chromeos::AccessibilityManager::Get()); + return chromeos::AccessibilityManager::Get()->IsSelectToSpeakEnabled(); + } + + void SetSwitchAccessEnabled(bool enabled) override { + DCHECK(chromeos::AccessibilityManager::Get()); + chromeos::AccessibilityManager::Get()->SetSwitchAccessEnabled(enabled); + } + + bool IsSwitchAccessEnabled() const override { + DCHECK(chromeos::AccessibilityManager::Get()); + return chromeos::AccessibilityManager::Get()->IsSwitchAccessEnabled(); + } + bool ShouldShowAccessibilityMenu() const override { DCHECK(chromeos::AccessibilityManager::Get()); return chromeos::AccessibilityManager::Get()-> diff --git a/chrome/browser/ui/ash/chrome_shell_delegate_views.cc b/chrome/browser/ui/ash/chrome_shell_delegate_views.cc index 198a9ab..39cb4d1 100644 --- a/chrome/browser/ui/ash/chrome_shell_delegate_views.cc +++ b/chrome/browser/ui/ash/chrome_shell_delegate_views.cc @@ -95,6 +95,26 @@ class EmptyAccessibilityDelegate : public ash::AccessibilityDelegate { bool IsAutoclickEnabled() const override { return false; } + void SetCaretHighlightEnabled(bool enabled) override {} + + bool IsCaretHighlightEnabled() const override { return false; } + + void SetCursorHighlightEnabled(bool enabled) override {} + + bool IsCursorHighlightEnabled() const override { return false; } + + void SetFocusHighlightEnabled(bool enabled) override {} + + bool IsFocusHighlightEnabled() const override { return false; } + + void SetSelectToSpeakEnabled(bool enabled) override {} + + bool IsSelectToSpeakEnabled() const override { return false; } + + void SetSwitchAccessEnabled(bool enabled) override {} + + bool IsSwitchAccessEnabled() const override { return false; } + ui::MagnifierType GetMagnifierType() const override { return ui::kDefaultMagnifierType; } diff --git a/chrome/browser/ui/webui/options/browser_options_handler.cc b/chrome/browser/ui/webui/options/browser_options_handler.cc index 6bd2743..673efdc 100644 --- a/chrome/browser/ui/webui/options/browser_options_handler.cc +++ b/chrome/browser/ui/webui/options/browser_options_handler.cc @@ -399,8 +399,14 @@ void BrowserOptionsHandler::GetLocalizedValues(base::DictionaryValue* values) { IDS_OPTIONS_SETTINGS_ACCESSIBILITY_AUTOCLICK_DESCRIPTION }, { "accessibilityAutoclickDropdown", IDS_OPTIONS_SETTINGS_ACCESSIBILITY_AUTOCLICK_DROPDOWN_DESCRIPTION }, + { "accessibilityCaretHighlight", + IDS_OPTIONS_SETTINGS_ACCESSIBILITY_CARET_HIGHLIGHT_DESCRIPTION }, + { "accessibilityCursorHighlight", + IDS_OPTIONS_SETTINGS_ACCESSIBILITY_CURSOR_HIGHLIGHT_DESCRIPTION }, { "accessibilityExplanation", IDS_OPTIONS_SETTINGS_ACCESSIBILITY_EXPLANATION }, + { "accessibilityFocusHighlight", + IDS_OPTIONS_SETTINGS_ACCESSIBILITY_FOCUS_HIGHLIGHT_DESCRIPTION }, { "accessibilityHighContrast", IDS_OPTIONS_SETTINGS_ACCESSIBILITY_HIGH_CONTRAST_DESCRIPTION }, { "accessibilityLargeCursor", @@ -415,12 +421,16 @@ void BrowserOptionsHandler::GetLocalizedValues(base::DictionaryValue* values) { IDS_OPTIONS_SETTINGS_ACCESSIBILITY_SCREEN_MAGNIFIER_OFF }, { "accessibilityScreenMagnifierPartial", IDS_OPTIONS_SETTINGS_ACCESSIBILITY_SCREEN_MAGNIFIER_PARTIAL }, + { "accessibilitySelectToSpeak", + IDS_OPTIONS_SETTINGS_ACCESSIBILITY_SELECT_TO_SPEAK_DESCRIPTION }, { "accessibilitySettings", IDS_OPTIONS_SETTINGS_ACCESSIBILITY_SETTINGS }, { "accessibilitySpokenFeedback", IDS_OPTIONS_SETTINGS_ACCESSIBILITY_SPOKEN_FEEDBACK_DESCRIPTION }, { "accessibilityStickyKeys", IDS_OPTIONS_SETTINGS_ACCESSIBILITY_STICKY_KEYS_DESCRIPTION }, + { "accessibilitySwitchAccess", + IDS_OPTIONS_SETTINGS_ACCESSIBILITY_SWITCH_ACCESS_DESCRIPTION }, { "accessibilityTapDragging", IDS_OPTIONS_SETTINGS_ACCESSIBILITY_TOUCHPAD_TAP_DRAGGING_DESCRIPTION }, { "accessibilityVirtualKeyboard", @@ -709,6 +719,10 @@ void BrowserOptionsHandler::GetLocalizedValues(base::DictionaryValue* values) { prefs::kResolveTimezoneByGeolocation)); values->SetBoolean("enableLanguageOptionsImeMenu", chromeos::switches::IsImeMenuEnabled()); + values->SetBoolean( + "enableExperimentalAccessibilityFeatures", + base::CommandLine::ForCurrentProcess()->HasSwitch( + chromeos::switches::kEnableExperimentalAccessibilityFeatures)); #endif } diff --git a/chrome/common/extensions/api/accessibility_features.json b/chrome/common/extensions/api/accessibility_features.json index 105a9bd..4311c07 100644 --- a/chrome/common/extensions/api/accessibility_features.json +++ b/chrome/common/extensions/api/accessibility_features.json @@ -49,6 +49,36 @@ "value": ["virtualKeyboard", {"type": "boolean"}], "platforms": ["chromeos"] }, + "caretHighlight": { + "$ref": "types.ChromeSetting", + "description": "

ChromeOS only.

Caret highlighting. The value indicates whether the feature is enabled or not. get() requires accessibilityFeatures.read permission. set() and clear() require accessibilityFeatures.modify permission.

", + "value": ["caretHighlight", {"type": "boolean"}], + "platforms": ["chromeos"] + }, + "cursorHighlight": { + "$ref": "types.ChromeSetting", + "description": "

ChromeOS only.

Cursor highlighting. The value indicates whether the feature is enabled or not. get() requires accessibilityFeatures.read permission. set() and clear() require accessibilityFeatures.modify permission.

", + "value": ["cursorHighlight", {"type": "boolean"}], + "platforms": ["chromeos"] + }, + "focusHighlight": { + "$ref": "types.ChromeSetting", + "description": "

ChromeOS only.

Focus highlighting. The value indicates whether the feature is enabled or not. get() requires accessibilityFeatures.read permission. set() and clear() require accessibilityFeatures.modify permission.

", + "value": ["focusHighlight", {"type": "boolean"}], + "platforms": ["chromeos"] + }, + "selectToSpeak": { + "$ref": "types.ChromeSetting", + "description": "

ChromeOS only.

Select-to-speak. The value indicates whether the feature is enabled or not. get() requires accessibilityFeatures.read permission. set() and clear() require accessibilityFeatures.modify permission.

", + "value": ["selectToSpeak", {"type": "boolean"}], + "platforms": ["chromeos"] + }, + "switchAccess": { + "$ref": "types.ChromeSetting", + "description": "

ChromeOS only.

Switch access. The value indicates whether the feature is enabled or not. get() requires accessibilityFeatures.read permission. set() and clear() require accessibilityFeatures.modify permission.

", + "value": ["switchAccess", {"type": "boolean"}], + "platforms": ["chromeos"] + }, "animationPolicy": { "$ref": "types.ChromeSetting", "description": "get() requires accessibilityFeatures.read permission. set() and clear() require accessibilityFeatures.modify permission.", diff --git a/chrome/common/extensions/api/chromeos_info_private.json b/chrome/common/extensions/api/chromeos_info_private.json index d792908..b87c606 100644 --- a/chrome/common/extensions/api/chromeos_info_private.json +++ b/chrome/common/extensions/api/chromeos_info_private.json @@ -21,6 +21,11 @@ "a11yScreenMagnifierEnabled", "a11yAutoClickEnabled", "a11yVirtualKeyboardEnabled", + "a11yCaretHighlightEnabled", + "a11yCursorHighlightEnabled", + "a11yFocusHighlightEnabled", + "a11ySelectToSpeakEnabled", + "a11ySwitchAccessEnabled", "sendFunctionKeys"], "description": "Chrome OS system property name" } diff --git a/chrome/common/extensions/docs/templates/intros/accessibilityFeatures.html b/chrome/common/extensions/docs/templates/intros/accessibilityFeatures.html new file mode 100644 index 0000000..cce70d0 --- /dev/null +++ b/chrome/common/extensions/docs/templates/intros/accessibilityFeatures.html @@ -0,0 +1 @@ + diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index 503c0f9..c48a381 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc @@ -598,6 +598,21 @@ const char kAccessibilityAutoclickEnabled[] = "settings.a11y.autoclick"; // stops and when an autoclick is triggered. const char kAccessibilityAutoclickDelayMs[] = "settings.a11y.autoclick_delay_ms"; +// A boolean pref which determines whether caret highlighting is enabled. +const char kAccessibilityCaretHighlightEnabled[] = + "settings.a11y.caret_highlight"; +// A boolean pref which determines whether cursor highlighting is enabled. +const char kAccessibilityCursorHighlightEnabled[] = + "settings.a11y.cursor_highlight"; +// A boolean pref which determines whether focus highlighting is enabled. +const char kAccessibilityFocusHighlightEnabled[] = + "settings.a11y.focus_highlight"; +// A boolean pref which determines whether select-to-speak is enabled. +const char kAccessibilitySelectToSpeakEnabled[] = + "settings.a11y.select_to_speak"; +// A boolean pref which determines whether switch access is enabled. +const char kAccessibilitySwitchAccessEnabled[] = + "settings.a11y.switch_access"; // A boolean pref which determines whether the accessibility menu shows // regardless of the state of a11y features. const char kShouldAlwaysShowAccessibilityMenu[] = "settings.a11y.enable_menu"; diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index 1e3bd63..a1fffed 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h @@ -205,6 +205,9 @@ extern const char kLanguageSendFunctionKeys[]; extern const char kLanguageXkbAutoRepeatEnabled[]; extern const char kLanguageXkbAutoRepeatDelay[]; extern const char kLanguageXkbAutoRepeatInterval[]; + +// TODO(dmazzoni): move accessibility prefs out of chrome/. +// http://crbug.com/594887 extern const char kAccessibilityLargeCursorEnabled[]; extern const char kAccessibilityStickyKeysEnabled[]; extern const char kAccessibilitySpokenFeedbackEnabled[]; @@ -216,7 +219,13 @@ extern const char kAccessibilityScreenMagnifierScale[]; extern const char kAccessibilityVirtualKeyboardEnabled[]; extern const char kAccessibilityAutoclickEnabled[]; extern const char kAccessibilityAutoclickDelayMs[]; +extern const char kAccessibilityCaretHighlightEnabled[]; +extern const char kAccessibilityCursorHighlightEnabled[]; +extern const char kAccessibilityFocusHighlightEnabled[]; +extern const char kAccessibilitySelectToSpeakEnabled[]; +extern const char kAccessibilitySwitchAccessEnabled[]; extern const char kShouldAlwaysShowAccessibilityMenu[]; + extern const char kLabsAdvancedFilesystemEnabled[]; extern const char kLabsMediaplayerEnabled[]; extern const char kEnableAutoScreenLock[]; diff --git a/chromeos/chromeos_switches.cc b/chromeos/chromeos_switches.cc index 1fbad80..15b3167 100644 --- a/chromeos/chromeos_switches.cc +++ b/chromeos/chromeos_switches.cc @@ -145,6 +145,11 @@ const char kEnablePhysicalKeyboardAutocorrect[] = const char kDisablePhysicalKeyboardAutocorrect[] = "disable-physical-keyboard-autocorrect"; +// Shows additional checkboxes in Settings to enable Chrome OS accessibility +// features that haven't launched yet. +const char kEnableExperimentalAccessibilityFeatures[] = + "enable-experimental-accessibility-features"; + // Enabled sharing assets for installed default apps. const char kEnableExtensionAssetsSharing[] = "enable-extension-assets-sharing"; diff --git a/chromeos/chromeos_switches.h b/chromeos/chromeos_switches.h index 0124dd4..47b7637 100644 --- a/chromeos/chromeos_switches.h +++ b/chromeos/chromeos_switches.h @@ -60,6 +60,7 @@ CHROMEOS_EXPORT extern const char kEafeUrl[]; CHROMEOS_EXPORT extern const char kEafePath[]; CHROMEOS_EXPORT extern const char kEnableArc[]; CHROMEOS_EXPORT extern const char kEnableConsumerManagement[]; +CHROMEOS_EXPORT extern const char kEnableExperimentalAccessibilityFeatures[]; CHROMEOS_EXPORT extern const char kEnableExtensionAssetsSharing[]; CHROMEOS_EXPORT extern const char kEnableFilesDetailsPanel[]; CHROMEOS_EXPORT extern const char kEnableFirstRunUITransitions[]; diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml index 640b23d..541d0ba 100644 --- a/tools/metrics/actions/actions.xml +++ b/tools/metrics/actions/actions.xml @@ -9344,6 +9344,38 @@ should be able to be added at any place in this file. Settings: About Chrome + + dmazzoni@chromium.org + Settings: Accessibility: Disable caret highlighting + + + + dmazzoni@chromium.org + Settings: Accessibility: Enable caret highlighting + + + + dmazzoni@chromium.org + + Settings: Accessibility: Disable cursor highlighting + + + + + dmazzoni@chromium.org + Settings: Accessibility: Enable cursor highlighting + + + + dmazzoni@chromium.org + Settings: Accessibility: Disable focus highlighting + + + + dmazzoni@chromium.org + Settings: Accessibility: Enable focus highlighting + + stevenjb@chromium.org Settings: Accessibility: Toggle high contrast mode @@ -9410,6 +9442,16 @@ should be able to be added at any place in this file. Settings: Accessibility: Enable screen magnifier + + dmazzoni@chromium.org + Settings: Accessibility: Disable select-to-speak + + + + dmazzoni@chromium.org + Settings: Accessibility: Enable select-to-speak + + stevenjb@chromium.org Settings: Accessibility: Disable ChromeVox @@ -9430,6 +9472,16 @@ should be able to be added at any place in this file. Settings: Accessibility: Enable sticky keys + + dmazzoni@chromium.org + Settings: Accessibility: Disable switch access + + + + dmazzoni@chromium.org + Settings: Accessibility: Enable switch access + + stevenjb@chromium.org diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index ba8aa2e7d9..a5fa035 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml @@ -101,6 +101,30 @@ http://cs/file:chrome/histograms.xml - but prefer this file for new entries. + + dmazzoni@chromium.org + + Whether the Chrome OS caret highlighting is on (checked once 45 secs after + startup). + + + + + dmazzoni@chromium.org + + Whether the Chrome OS cursor highlighting is on (checked once 45 secs after + startup). + + + + + dmazzoni@chromium.org + + Whether the Chrome OS focus highlighting is on (checked once 45 secs after + startup). + + + dmazzoni@chromium.org kenjibaheux@google.com @@ -128,6 +152,14 @@ http://cs/file:chrome/histograms.xml - but prefer this file for new entries. + + dmazzoni@chromium.org + + Whether the Chrome OS select-to-speak is on (checked once 45 secs after + startup). + + + dmazzoni@chromium.org kenjibaheux@google.com @@ -147,6 +179,14 @@ http://cs/file:chrome/histograms.xml - but prefer this file for new entries. + + dmazzoni@chromium.org + + Whether the Chrome OS switch access is on (checked once 45 secs after + startup). + + + dmazzoni@chromium.org kenjibaheux@google.com @@ -72889,6 +72929,7 @@ To add a new entry, add it with any value and run test to compute valid value. + -- cgit v1.1