// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ASH_ACCESSIBILITY_ACCESSIBILITY_CONTROLLER_H_
#define ASH_ACCESSIBILITY_ACCESSIBILITY_CONTROLLER_H_
#include <memory>
#include <optional>
#include <string>
#include "ash/accessibility/a11y_feature_type.h"
#include "ash/accessibility/accessibility_notification_controller.h"
#include "ash/ash_export.h"
#include "ash/constants/ash_constants.h"
#include "ash/public/cpp/accelerator_actions.h"
#include "ash/public/cpp/session/session_observer.h"
#include "base/functional/callback_forward.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/time/time.h"
#include "ui/display/display_observer.h"
#include "ui/events/keycodes/keyboard_codes.h"
#include "ui/gfx/geometry/rect.h"
class PrefChangeRegistrar;
class PrefRegistrySimple;
class PrefService;
namespace aura {
class Window;
} // namespace aura
namespace ax {
namespace mojom {
enum class Gesture;
} // namespace mojom
} // namespace ax
namespace display {
enum class TabletState;
} // namespace display
namespace gfx {
class Point;
class PointF;
struct VectorIcon;
} // namespace gfx
namespace ash {
class AccessibilityConfirmationDialog;
class AccessibilityControllerClient;
class AccessibilityEventRewriter;
class AccessibilityHighlightController;
class AccessibilityObserver;
enum class AccessibilityPanelState;
enum class DictationToggleSource;
class DictationBubbleController;
enum class DictationBubbleHintType;
enum class DictationBubbleIconType;
enum class DictationNotificationType;
class DisableTrackpadEventRewriter;
class FilterKeysEventRewriter;
class FlashScreenController;
class FloatingAccessibilityController;
class PointScanController;
class ScopedBacklightsForcedOff;
class SelectToSpeakEventHandler;
class SelectToSpeakEventHandlerDelegate;
class SelectToSpeakMenuBubbleController;
enum class SelectToSpeakState;
enum class Sound;
class SwitchAccessMenuBubbleController;
enum AccessibilityNotificationVisibility {
A11Y_NOTIFICATION_NONE,
A11Y_NOTIFICATION_SHOW,
};
// Used to indicate which accessibility notification should be shown.
enum class A11yNotificationType {
// No accessibility notification.
kNone,
// Shown when spoken feedback is set enabled with A11Y_NOTIFICATION_SHOW.
kSpokenFeedbackEnabled,
// Shown when braille display is connected while spoken feedback is enabled.
kBrailleDisplayConnected,
// Shown when all Dictation-related DLCs have downloaded successfully.
kDictationAllDlcsDownloaded,
// Shown when all Dictation-related DLCs failed to download.
kDictationNoDlcsDownloaded,
// Shown when the Pumpkin DLC (but no other DLCs) have downloaded.
kDicationOnlyPumpkinDownloaded,
// Shown when the SODA DLC (but no other DLCs) have downloaded.
kDictationOnlySodaDownloaded,
// Shown when the facegaze-assets DLC has successfully downloaded.
kFaceGazeAssetsDownloaded,
// Shown when the facegaze-assets DLC failed to download.
kFaceGazeAssetsFailed,
// Shown when braille display is connected while spoken feedback is not
// enabled yet. Note: in this case braille display connected would enable
// spoken feedback.
kSpokenFeedbackBrailleEnabled,
// Shown when Switch Access is enabled.
kSwitchAccessEnabled,
};
// The controller for accessibility features in ash. Features can be enabled
// in chrome's webui settings or the system tray menu (see TrayAccessibility).
// Uses preferences to communicate with chrome to support mash.
class ASH_EXPORT AccessibilityController : public SessionObserver,
public display::DisplayObserver {
public:
// Common interface for all features.
class Feature {
public:
Feature(A11yFeatureType type,
const std::string& pref_name,
const gfx::VectorIcon* icon,
const int name_resource_id,
const bool toggleable_in_quicksettings,
AccessibilityController* controller);
Feature(const Feature&) = delete;
Feature& operator=(Feature const&) = delete;
virtual ~Feature();
A11yFeatureType type() const { return type_; }
// Tries to set the feature to |enabled| by setting the user pref.
// Setting feature to be enabled can fail in following conditions:
// - there is a higher priority pref(managed), which overrides this value.
// - there is an other feature, which conflicts with the current one.
virtual void SetEnabled(bool enabled);
bool enabled() const { return enabled_; }
bool IsVisibleInTray() const;
bool IsEnterpriseIconVisible() const;
const std::string& pref_name() const { return pref_name_; }
const gfx::VectorIcon& icon() const;
int name_resource_id() const { return name_resource_id_; }
bool toggleable_in_quicksettings() const {
return toggleable_in_quicksettings_;
}
A11yFeatureType conflicting_feature() const { return conflicting_feature_; }
void UpdateFromPref();
void SetConflictingFeature(A11yFeatureType feature);
// Start observing changes to the conflicting feature's pref, in order to
// update own enabled state.
void ObserveConflictingFeature();
// Logs the amount of time this feature has been on, if it was turned on
// during the logged in state. Clears the `enabled_time_`.
void LogDurationMetric();
protected:
const A11yFeatureType type_;
// Some features cannot be enabled while others are on. When a conflicting
// feature is enabled, we cannot enable current feature.
A11yFeatureType conflicting_feature_ =
A11yFeatureType::kNoConflictingFeature;
// Used to watch for changes in conflicting feature to ensure this updates
// enabled state appropriately.
std::unique_ptr<PrefChangeRegistrar> pref_change_registrar_;
bool enabled_ = false;
const std::string pref_name_;
raw_ptr<const gfx::VectorIcon> icon_;
// The resource id used to fetch the string with this feature's name. Used
// in quicksettings.
const int name_resource_id_;
// Specifies if this feature can be toggled from the accessibility options
// available in the quicksettings menu.
const bool toggleable_in_quicksettings_;
// The time at which this feature was last enabled. Used for metrics.
base::Time enabled_time_;
const raw_ptr<AccessibilityController> owner_;
};
// Some features have confirmation dialog associated with them.
// Dialog can be applied for all SetEnabled() actions, or only to ones
// associated with accelerators.
class FeatureWithDialog : public Feature {
public:
FeatureWithDialog(A11yFeatureType type,
const std::string& pref_name,
const gfx::VectorIcon* icon,
const int name_resource_id,
const bool toggleable_in_quicksettings,
const std::string& dialog_pref_name,
AccessibilityController* controller);
~FeatureWithDialog() override;
void SetDialogAccepted();
bool WasDialogAccepted() const;
private:
const std::string dialog_pref_;
};
// Contains data used to give an accessibility-related notification.
struct A11yNotificationWrapper {
A11yNotificationWrapper();
A11yNotificationWrapper(A11yNotificationType type_in,
std::vector<std::u16string> replacements_in);
~A11yNotificationWrapper();
A11yNotificationWrapper(const A11yNotificationWrapper&);
A11yNotificationType type = A11yNotificationType::kNone;
std::vector<std::u16string> replacements;
};
static AccessibilityController* Get();
AccessibilityController();
AccessibilityController(const AccessibilityController&) = delete;
AccessibilityController& operator=(const AccessibilityController&) = delete;
~AccessibilityController() override;
// See Shell::RegisterProfilePrefs().
static void RegisterProfilePrefs(PrefRegistrySimple* registry);
void Shutdown();
void AddObserver(AccessibilityObserver* observer);
void RemoveObserver(AccessibilityObserver* observer);
Feature& GetFeature(A11yFeatureType feature) const;
// Returns all `Feature`s that are toggleable in quicksettings and currently
// enabled.
std::vector<Feature*> GetEnabledFeaturesInQuickSettings() const;
base::WeakPtr<AccessibilityController> GetWeakPtr();
// Getters for the corresponding features.
Feature& autoclick() const;
Feature& caret_highlight() const;
Feature& color_correction() const;
Feature& cursor_color() const;
Feature& cursor_highlight() const;
Feature& dictation() const;
Feature& disable_trackpad() const;
Feature& face_gaze() const;
Feature& flash_notifications() const;
Feature& floating_menu() const;
Feature& focus_highlight() const;
Feature& large_cursor() const;
Feature& live_caption() const;
Feature& mono_audio() const;
Feature& mouse_keys() const;
Feature& reduced_animations() const;
Feature& spoken_feedback() const;
Feature& select_to_speak() const;
Feature& sticky_keys() const;
Feature& switch_access() const;
Feature& virtual_keyboard() const;
FeatureWithDialog& docked_magnifier() const;
FeatureWithDialog& fullscreen_magnifier() const;
FeatureWithDialog& high_contrast() const;
void SetDisplayRotationAcceleratorDialogBeenAccepted();
bool HasDisplayRotationAcceleratorDialogBeenAccepted() const;
bool IsAutoclickSettingVisibleInTray();
bool IsEnterpriseIconVisibleForAutoclick();
void SetAutoclickEventType(AutoclickEventType event_type);
AutoclickEventType GetAutoclickEventType();
void SetAutoclickMenuPosition(FloatingMenuPosition position);
FloatingMenuPosition GetAutoclickMenuPosition();
void RequestAutoclickScrollableBoundsForPoint(
const gfx::Point& point_in_screen);
void MagnifierBoundsChanged(const gfx::Rect& bounds_in_screen);
void SetFloatingMenuPosition(FloatingMenuPosition position);
FloatingMenuPosition GetFloatingMenuPosition();
FloatingAccessibilityController* GetFloatingMenuController();
PointScanController* GetPointScanController();
// Update the autoclick menu bounds and sticky keys overlay bounds if
// necessary. This may need to happen when the display work area changes, or
// if system UI regions change (like the virtual keyboard position).
void UpdateFloatingPanelBoundsIfNeeded();
// Update the autoclick menu bounds if necessary. This may need to happen when
// the display work area changes, or if system UI regions change (like the
// virtual keyboard position).
void UpdateAutoclickMenuBoundsIfNeeded();
bool IsCaretHighlightSettingVisibleInTray();
bool IsEnterpriseIconVisibleForCaretHighlight();
bool IsCursorHighlightSettingVisibleInTray();
bool IsEnterpriseIconVisibleForCursorHighlight();
bool IsDictationSettingVisibleInTray();
bool IsEnterpriseIconVisibleForDictation();
bool IsFaceGazeSettingVisibleInTray();
bool IsEnterpriseIconVisibleForFaceGaze();
bool IsFocusHighlightSettingVisibleInTray();
bool IsEnterpriseIconVisibleForFocusHighlight();
bool IsFullScreenMagnifierSettingVisibleInTray();
bool IsEnterpriseIconVisibleForFullScreenMagnifier();
bool IsDockedMagnifierSettingVisibleInTray();
bool IsEnterpriseIconVisibleForDockedMagnifier();
bool IsHighContrastSettingVisibleInTray();
bool IsEnterpriseIconVisibleForHighContrast();
bool IsColorCorrectionSettingVisibleInTray();
bool IsEnterpriseIconVisibleForColorCorrection();
bool IsLargeCursorSettingVisibleInTray();
bool IsEnterpriseIconVisibleForLargeCursor();
bool IsLiveCaptionSettingVisibleInTray();
bool IsEnterpriseIconVisibleForLiveCaption();
bool IsMonoAudioSettingVisibleInTray();
bool IsEnterpriseIconVisibleForMonoAudio();
void SetSpokenFeedbackEnabled(bool enabled,
AccessibilityNotificationVisibility notify);
bool IsSpokenFeedbackSettingVisibleInTray();
bool IsEnterpriseIconVisibleForSpokenFeedback();
bool IsSelectToSpeakSettingVisibleInTray();
bool IsEnterpriseIconVisibleForSelectToSpeak();
void RequestSelectToSpeakStateChange();
SelectToSpeakState GetSelectToSpeakState() const;
bool IsStickyKeysSettingVisibleInTray();
bool IsEnterpriseIconVisibleForStickyKeys();
bool IsReducedAnimationsSettingVisibleInTray();
bool IsEnterpriseIconVisibleForReducedAnimations();
// Switch access may be disabled in prefs but still running when the disable
// dialog is displaying.
bool IsSwitchAccessRunning() const;
bool IsSwitchAccessSettingVisibleInTray();
bool IsEnterpriseIconVisibleForSwitchAccess();
void SetAccessibilityEventRewriter(
AccessibilityEventRewriter* accessibility_event_rewriter);
void SetDisableTrackpadEventRewriter(DisableTrackpadEventRewriter* rewriter);
void SetFilterKeysEventRewriter(FilterKeysEventRewriter* rewriter);
bool IsPointScanEnabled();
bool IsVirtualKeyboardSettingVisibleInTray();
bool IsEnterpriseIconVisibleForVirtualKeyboard();
void SetTabletModeShelfNavigationButtonsEnabled(bool enabled);
bool tablet_mode_shelf_navigation_buttons_enabled() const {
return tablet_mode_shelf_navigation_buttons_enabled_;
}
// Shows floating accessibility menu if it was enabled by policy.
void ShowFloatingMenuIfEnabled();
bool dictation_active() const { return dictation_active_; }
// Returns true if accessibility shortcuts have been disabled.
bool accessibility_shortcuts_enabled() const { return shortcuts_enabled_; }
// Triggers an accessibility alert to give the user feedback.
void TriggerAccessibilityAlert(AccessibilityAlert alert);
// Triggers an accessibility alert with the given |message|.
void TriggerAccessibilityAlertWithMessage(const std::string& message);
// Plays an earcon. Earcons are brief and distinctive sounds that indicate
// that their mapped event has occurred. The |sound_key| enums can be found in
// chromeos/ash/components/audio/sounds.h.
void PlayEarcon(Sound sound_key);
// Initiates play of shutdown sound. Returns the TimeDelta duration.
base::TimeDelta PlayShutdownSound();
// Forwards an accessibility gesture from the touch exploration controller to
// ChromeVox.
void HandleAccessibilityGesture(ax::mojom::Gesture gesture,
gfx::PointF location);
// Toggle dictation.
void ToggleDictation();
// Whether or not to enable toggling spoken feedback via holding down two
// fingers on the screen.
bool ShouldToggleSpokenFeedbackViaTouch() const;
// Plays tick sound indicating spoken feedback will be toggled after
// countdown.
void PlaySpokenFeedbackToggleCountdown(int tick_count);
// Returns true if that accessibility feature pref |path| is being controlled
// by a policy and false otherwise.
bool IsEnterpriseIconVisibleInTrayMenu(const std::string& path);
// Returns true if at least one of the primary settings of the accessibility
// features is going to be visible in the accessibility tray menu.
bool IsPrimarySettingsViewVisibleInTray();
// Starts point scanning, to select a point onscreen without using a mouse
// (as used by Switch Access).
void StartPointScanning();
// Sets a window to take a11y focus. This is for windows that need to work
// with accessibility clients that consume accessibility APIs, but cannot take
// real focus themselves. This is meant for temporary UIs, such as capture
// mode and should be set back to null when exiting those UIs, so a11y can
// focus windows with real focus. Destroying |a11y_override_window| will also
// set the a11y override window back to null.
void SetA11yOverrideWindow(aura::Window* a11y_override_window);
// Sets the client interface.
void SetClient(AccessibilityControllerClient* client);
// Starts or stops darkening the screen (e.g. to allow chrome a11y extensions
// to darken the screen).
void SetDarkenScreen(bool darken);
// Called when braille display state is changed.
void BrailleDisplayStateChanged(bool connected);
// Sets the focus highlight rect using |bounds_in_screen|. Called when focus
// changed in page and a11y focus highlight feature is enabled.
void SetFocusHighlightRect(const gfx::Rect& bounds_in_screen);
// Sets the text input caret bounds used to draw the caret highlight effect.
// For effciency, only sent when the caret highlight feature is enabled.
// Setting off-screen or empty bounds suppresses the highlight.
void SetCaretBounds(const gfx::Rect& bounds_in_screen);
// Sets whether the accessibility panel should always be visible, regardless
// of whether the window is fullscreen.
void SetAccessibilityPanelAlwaysVisible(bool always_visible);
// Sets the bounds for the accessibility panel. Overrides current
// configuration (i.e. fullscreen, full-width).
void SetAccessibilityPanelBounds(const gfx::Rect& bounds,
AccessibilityPanelState state);
// Sets the current Select-to-Speak state. This should be used by the Select-
// to-Speak extension to inform ash of its updated state.
void SetSelectToSpeakState(SelectToSpeakState state);
// Set the delegate used by the Select-to-Speak event handler.
void SetSelectToSpeakEventHandlerDelegate(
SelectToSpeakEventHandlerDelegate* delegate);
// Displays the Select-to-Speak panel.
void ShowSelectToSpeakPanel(const gfx::Rect& anchor,
bool is_paused,
double speech_rate);
// Hides the Select-to-Speak panel.
void HideSelectToSpeakPanel();
// Dispatches event to notify Select-to-speak that a panel action occurred,
// with an optional value.
void OnSelectToSpeakPanelAction(SelectToSpeakPanelAction action,
double value);
// Hides the Switch Access back button.
void HideSwitchAccessBackButton();
// Hides the Switch Access menu.
void HideSwitchAccessMenu();
// Show the Switch Access back button next to the specified rectangle.
void ShowSwitchAccessBackButton(const gfx::Rect& anchor);
// Show the Switch Access menu with the specified actions.
void ShowSwitchAccessMenu(const gfx::Rect& anchor,
std::vector<std::string> actions_to_show);
// Starts point scanning in Switch Access.
void StartPointScan();
// Stops point scanning in Switch Access.
void StopPointScan();
// Sets point scanning speed in Switch Access.
void SetPointScanSpeedDipsPerSecond(int point_scan_speed_dips_per_second);
// Set whether dictation is active.
void SetDictationActive(bool is_active);
// Starts or stops dictation. Records metrics for toggling via SwitchAccess.
void ToggleDictationFromSource(DictationToggleSource source);
// Enables Select to Speak if the feature is currently disabled. If Select to
// Speak has not been enabled on the current profile before, then this method
// shows a dialog giving background about the feature. Once the dialog is
// accepted, it is never shown again for that profile. This method does
// nothing if the Select to Speak is currently enabled.
void EnableSelectToSpeakWithDialog();
// Enables Dictation if the feature is currently disabled. Toggles (starts or
// stops) Dictation if the feature is currently enabled.
void EnableOrToggleDictationFromSource(DictationToggleSource source);
// Shows a nudge explaining that a user's dictation language was upgraded to
// work offline.
void ShowDictationLanguageUpgradedNudge(
const std::string& dictation_locale,
const std::string& application_locale);
// Called when the Automatic Clicks extension finds scrollable bounds.
void HandleAutoclickScrollableBoundsFound(const gfx::Rect& bounds_in_screen);
// Retrieves a string description of the current battery status.
std::u16string GetBatteryDescription() const;
// Shows or hides the virtual keyboard.
void SetVirtualKeyboardVisible(bool is_visible);
// Toggle Mouse Keys.
void ToggleMouseKeys();
// Perform the action assigned to the accessibility key.
void PerformAccessibilityAction();
// Performs the given accelerator action.
void PerformAcceleratorAction(AcceleratorAction accelerator_action);
// Notify observers that the accessibility status has changed. This is part of
// the public interface because a11y features like screen magnifier are
// managed outside of this accessibility controller.
void NotifyAccessibilityStatusChanged();
// Returns true if the |path| pref is being controlled by a policy which
// enforces turning it on or its not being controlled by any type of policy
// and false otherwise.
bool IsAccessibilityFeatureVisibleInTrayMenu(const std::string& path);
// Disables restoring of recommended policy values.
void DisablePolicyRecommendationRestorerForTesting();
// Suspends (or resumes) key handling for Switch Access.
void SuspendSwitchAccessKeyHandling(bool suspend);
// Enables ChromeVox's volume slide gesture.
void EnableChromeVoxVolumeSlideGesture();
// Updates the enabled state, tooltip, and progress ring of the dictation
// button in the status tray when speech recognition file download state
// changes. `download_progress` indicates SODA download progress and is
// guaranteed to be between 0 and 100 (inclusive).
void UpdateDictationButtonOnSpeechRecognitionDownloadChanged(
int download_progress);
// Shows a notification card in the message center informing the user that
// speech recognition files have either downloaded successfully or failed.
// Specific to the Dictation feature.
void ShowNotificationForDictation(DictationNotificationType type,
const std::u16string& display_language);
// Updates the Dictation UI bubble. `text` is optional to allow clients to
// clear the bubble's text.
void UpdateDictationBubble(
bool visible,
DictationBubbleIconType icon,
const std::optional<std::u16string>& text,
const std::optional<std::vector<DictationBubbleHintType>>& hints);
// Shows a notification notifying the user about the FaceGaze DLC download.
void ShowNotificationForFaceGaze(FaceGazeNotificationType type);
// Cancels all of spoken feedback's current and queued speech immediately.
void SilenceSpokenFeedback();
// Determines the action key that corresponds to F7 for the caret browsing
// dialog.
std::optional<ui::KeyboardCode> GetCaretBrowsingActionKey();
// Shows an accessibility-related toast.
void ShowToast(AccessibilityToastType type);
// Shows a confirmation dialog with the given text, description,
// and cancel button name, and calls the relevant callback when the
// dialog is confirmed, canceled or closed.
// A confirmation dialog will be shown the first time an accessibility feature
// is enabled using the specified accelerator key sequence. Only one dialog
// will be shown at a time, and will not be shown again if the user has
// selected "accept" on a given dialog. The dialog was added to ensure that
// users would be aware of the shortcut they have just enabled, and to prevent
// users from accidentally triggering the feature. The dialog is currently
// shown when enabling the following features: high contrast, full screen
// magnifier, docked magnifier and screen rotation and when requested by the
// AccessibilityPrivate extension API. The shown dialog is stored as a weak
// pointer in the variable |confirmation_dialog_| below.
// This is also used to show the dialog for Select to Speak's enhanced network
// voices.
void ShowConfirmationDialog(const std::u16string& title,
const std::u16string& description,
const std::u16string& confirm_name,
const std::u16string& cancel_name,
base::OnceClosure on_accept_callback,
base::OnceClosure on_cancel_callback,
base::OnceClosure on_close_callback);
gfx::Rect GetConfirmationDialogBoundsInScreen();
void PreviewFlashNotification() const;
// SessionObserver:
void OnSigninScreenPrefServiceInitialized(PrefService* prefs) override;
void OnActiveUserPrefServiceChanged(PrefService* prefs) override;
void OnSessionStateChanged(session_manager::SessionState state) override;
// Test helpers:
AccessibilityEventRewriter* GetAccessibilityEventRewriterForTest();
DisableTrackpadEventRewriter* GetDisableTrackpadEventRewriterForTest();
FilterKeysEventRewriter* GetFilterKeysEventRewriterForTest();
SwitchAccessMenuBubbleController* GetSwitchAccessBubbleControllerForTest() {
return switch_access_bubble_controller_.get();
}
// Disables the dialog shown when Auto Click is turned on.
// Used in tests.
void DisableAutoClickConfirmationDialogForTest();
// Disables the dialog shown when Switch Access is turned off.
// Used in tests.
void DisableSwitchAccessDisableConfirmationDialogTesting();
// Disables the dialog shown when Switch Access is turned off.
// Used in tests.
void DisableSwitchAccessEnableNotificationTesting();
SelectToSpeakMenuBubbleController*
GetSelectToSpeakMenuBubbleControllerForTest() {
return select_to_speak_bubble_controller_.get();
}
AccessibilityConfirmationDialog* GetConfirmationDialogForTest() {
return confirmation_dialog_.get();
}
bool enable_chromevox_volume_slide_gesture() {
return enable_chromevox_volume_slide_gesture_;
}
int dictation_soda_download_progress() {
return dictation_soda_download_progress_;
}
DictationBubbleController* GetDictationBubbleControllerForTest();
bool IsDictationKeyboardDialogShowingForTesting() {
return dictation_keyboard_dialog_showing_for_testing_;
}
void AcceptDictationKeyboardDialogForTesting() {
OnDictationKeyboardDialogAccepted();
}
void DismissDictationKeyboardDialogForTesting() {
OnDictationKeyboardDialogDismissed();
}
void AddShowToastCallbackForTesting(
base::RepeatingCallback<void(AccessibilityToastType)> callback);
void AddShowConfirmationDialogCallbackForTesting(
base::RepeatingCallback<void()> callback);
bool VerifyFeaturesDataForTesting();
SelectToSpeakEventHandler* GetSelectToSpeakEventHandlerForTesting() const {
return select_to_speak_event_handler_.get();
}
FlashScreenController* GetFlashScreenControllerForTesting() const {
return flash_screen_controller_.get();
}
void SetVirtualKeyboardVisibleCallbackForTesting(
base::RepeatingCallback<void()> callback);
// Scrolls at the target location in the specified direction.
void ScrollAtPoint(const gfx::Point& target,
AccessibilityScrollDirection direction);
private:
// Populate |features_| with the feature of the correct type.
void CreateAccessibilityFeatures();
// Propagates the state of |feature| according to |feature->enabled()|.
void OnFeatureChanged(A11yFeatureType feature);
// display::DisplayObserver:
void OnDisplayTabletStateChanged(display::TabletState state) override;
// Observes either the signin screen prefs or active user prefs and loads
// initial settings.
void ObservePrefs(PrefService* prefs);
// Updates the actual feature status based on the prefs value.
void UpdateFeatureFromPref(A11yFeatureType feature);
void UpdateAutoclickDelayFromPref();
void UpdateAutoclickEventTypeFromPref();
void UpdateAutoclickRevertToLeftClickFromPref();
void UpdateAutoclickStabilizePositionFromPref();
void UpdateAutoclickMovementThresholdFromPref();
void UpdateAutoclickMenuPositionFromPref();
void UpdateMouseKeysDisableInTextFieldsFromPref();
void UpdateMouseKeysAccelerationFromPref();
void UpdateMouseKeysMaxSpeedFromPref();
void UpdateMouseKeysUsePrimaryKeysFromPref();
void UpdateMouseKeysDominantHandFromPref();
void UpdateFloatingMenuPositionFromPref();
void UpdateLargeCursorFromPref();
void UpdateLiveCaptionFromPref();
void UpdateCursorColorFromPrefs(bool notify);
void UpdateFaceGazeFromPrefs();
void UpdateFlashNotificationsFromPrefs();
void UpdateDisableTrackpadFromPrefs();
void UpdateColorCorrectionFromPrefs();
void UpdateCaretBlinkIntervalFromPrefs() const;
void UpdateSwitchAccessKeyCodesFromPref(SwitchAccessCommand command);
void UpdateSwitchAccessAutoScanEnabledFromPref();
void UpdateSwitchAccessAutoScanSpeedFromPref();
void UpdateSwitchAccessAutoScanKeyboardSpeedFromPref();
void UpdateSwitchAccessPointScanSpeedFromPref();
void UpdateAccessibilityHighlightingFromPrefs();
void UpdateShortcutsEnabledFromPref();
void UpdateTabletModeShelfNavigationButtonsFromPref();
void SwitchAccessDisableDialogClosed(bool disable_dialog_accepted);
void MaybeCreateSelectToSpeakEventHandler();
void ActivateSwitchAccess();
void DeactivateSwitchAccess();
void SyncSwitchAccessPrefsToSignInProfile();
void UpdateKeyCodesAfterSwitchAccessEnabled();
void ShowDictationKeyboardDialog();
void OnDictationKeyboardDialogAccepted();
void OnDictationKeyboardDialogDismissed();
void ShowSelectToSpeakKeyboardDialog();
void OnSelectToSpeakKeyboardDialogAccepted();
void OnSelectToSpeakKeyboardDialogDismissed();
void RecordSelectToSpeakSpeechDuration(SelectToSpeakState old_state,
SelectToSpeakState new_state);
// Dictation's SODA download progress. Values are between 0 and 100. Tracked
// for testing purposes only.
int dictation_soda_download_progress_ = 0;
bool dictation_keyboard_dialog_showing_for_testing_ = false;
// Client interface in chrome browser.
raw_ptr<AccessibilityControllerClient> client_ = nullptr;
// Features are indexed by A11yFeatureType cast to int.
std::unique_ptr<Feature> features_[kA11yFeatureTypeCount];
base::TimeDelta autoclick_delay_;
int large_cursor_size_in_dip_ = kDefaultLargeCursorSize;
bool dictation_active_ = false;
bool shortcuts_enabled_ = true;
bool tablet_mode_shelf_navigation_buttons_enabled_ = false;
SelectToSpeakState select_to_speak_state_ =
SelectToSpeakState::kSelectToSpeakStateInactive;
std::unique_ptr<SelectToSpeakEventHandler> select_to_speak_event_handler_;
raw_ptr<SelectToSpeakEventHandlerDelegate>
select_to_speak_event_handler_delegate_ = nullptr;
std::unique_ptr<SelectToSpeakMenuBubbleController>
select_to_speak_bubble_controller_;
// List of key codes that Switch Access should capture.
std::vector<int> switch_access_keys_to_capture_;
std::unique_ptr<SwitchAccessMenuBubbleController>
switch_access_bubble_controller_;
raw_ptr<AccessibilityEventRewriter> accessibility_event_rewriter_ = nullptr;
raw_ptr<DisableTrackpadEventRewriter> disable_trackpad_event_rewriter_ =
nullptr;
raw_ptr<FilterKeysEventRewriter> filter_keys_event_rewriter_ = nullptr;
// Used in tests to disable the dialog shown when Auto Click is turned on.
bool no_auto_click_confirmation_dialog_for_testing_ = false;
bool no_switch_access_disable_confirmation_dialog_for_testing_ = false;
bool switch_access_disable_dialog_showing_ = false;
bool skip_switch_access_notification_ = false;
base::RepeatingCallback<void()> set_virtual_keyboard_visible_callback_;
// Used to control the highlights of caret, cursor and focus.
std::unique_ptr<AccessibilityHighlightController>
accessibility_highlight_controller_;
// Used to display accessibility floating menu.
std::unique_ptr<FloatingAccessibilityController> floating_menu_controller_;
// By default, floating accessibility menu is not shown unless
// ShowFloatingMenuIfEnabled() is called. This is used in kiosk mode to
// postpone the showing of the menu till the splash screen closes. This value
// makes floating menu visible as soon as it is enabled.
bool always_show_floating_menu_when_enabled_ = false;
// Used to control point scanning, or selecting a point onscreen without using
// a mouse (as done by Switch Access).
std::unique_ptr<PointScanController> point_scan_controller_;
// Used to force the backlights off to darken the screen.
std::unique_ptr<ScopedBacklightsForcedOff> scoped_backlights_forced_off_;
// Used to control the Dictation bubble UI.
std::unique_ptr<DictationBubbleController> dictation_bubble_controller_;
// Used to control accessibility-related notifications.
std::unique_ptr<AccessibilityNotificationController>
accessibility_notification_controller_;
std::unique_ptr<FlashScreenController> flash_screen_controller_;
// True if ChromeVox should enable its volume slide gesture.
bool enable_chromevox_volume_slide_gesture_ = false;
base::ObserverList<AccessibilityObserver> observers_;
// The pref service of the currently active user or the signin profile before
// user logs in. Can be null in ash_unittests.
raw_ptr<PrefService> active_user_prefs_ = nullptr;
// This has to be the first one to be destroyed so we don't get updates about
// any prefs during destruction.
std::unique_ptr<PrefChangeRegistrar> pref_change_registrar_;
// The current AccessibilityConfirmationDialog, if one exists.
base::WeakPtr<AccessibilityConfirmationDialog> confirmation_dialog_;
base::RepeatingCallback<void()>
show_confirmation_dialog_callback_for_testing_;
base::Time select_to_speak_speech_start_time_;
base::WeakPtrFactory<AccessibilityController> weak_ptr_factory_{this};
};
} // namespace ash
#endif // ASH_ACCESSIBILITY_ACCESSIBILITY_CONTROLLER_H_