1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452 |
- // Copyright 2017 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.
- #include "ash/accessibility/accessibility_controller_impl.h"
- #include <map>
- #include <memory>
- #include <set>
- #include <string>
- #include <utility>
- #include "ash/accelerators/accelerator_controller_impl.h"
- #include "ash/accessibility/accessibility_observer.h"
- #include "ash/accessibility/autoclick/autoclick_controller.h"
- #include "ash/accessibility/dictation_nudge_controller.h"
- #include "ash/accessibility/sticky_keys/sticky_keys_controller.h"
- #include "ash/accessibility/switch_access/point_scan_controller.h"
- #include "ash/accessibility/ui/accessibility_highlight_controller.h"
- #include "ash/accessibility/ui/accessibility_panel_layout_manager.h"
- #include "ash/constants/ash_constants.h"
- #include "ash/constants/ash_pref_names.h"
- #include "ash/constants/notifier_catalogs.h"
- #include "ash/events/accessibility_event_rewriter.h"
- #include "ash/events/select_to_speak_event_handler.h"
- #include "ash/high_contrast/high_contrast_controller.h"
- #include "ash/keyboard/keyboard_controller_impl.h"
- #include "ash/keyboard/ui/keyboard_util.h"
- #include "ash/login_status.h"
- #include "ash/policy/policy_recommendation_restorer.h"
- #include "ash/public/cpp/accessibility_controller_client.h"
- #include "ash/public/cpp/ash_constants.h"
- #include "ash/public/cpp/notification_utils.h"
- #include "ash/public/cpp/session/session_observer.h"
- #include "ash/public/cpp/shell_window_ids.h"
- #include "ash/resources/vector_icons/vector_icons.h"
- #include "ash/root_window_controller.h"
- #include "ash/session/session_controller_impl.h"
- #include "ash/shell.h"
- #include "ash/strings/grit/ash_strings.h"
- #include "ash/system/accessibility/accessibility_feature_disable_dialog.h"
- #include "ash/system/accessibility/dictation_bubble_controller.h"
- #include "ash/system/accessibility/dictation_button_tray.h"
- #include "ash/system/accessibility/floating_accessibility_controller.h"
- #include "ash/system/accessibility/select_to_speak/select_to_speak_menu_bubble_controller.h"
- #include "ash/system/accessibility/switch_access/switch_access_menu_bubble_controller.h"
- #include "ash/system/power/backlights_forced_off_setter.h"
- #include "ash/system/power/power_status.h"
- #include "ash/system/power/scoped_backlights_forced_off.h"
- #include "ash/wm/tablet_mode/tablet_mode_controller.h"
- #include "base/bind.h"
- #include "base/callback_helpers.h"
- #include "base/metrics/histogram_functions.h"
- #include "base/metrics/histogram_macros.h"
- #include "base/metrics/user_metrics.h"
- #include "base/strings/string_number_conversions.h"
- #include "chromeos/ash/components/audio/cras_audio_handler.h"
- #include "chromeos/ash/components/audio/sounds.h"
- #include "components/live_caption/caption_util.h"
- #include "components/live_caption/pref_names.h"
- #include "components/pref_registry/pref_registry_syncable.h"
- #include "components/prefs/pref_change_registrar.h"
- #include "components/prefs/pref_registry_simple.h"
- #include "components/prefs/pref_service.h"
- #include "components/vector_icons/vector_icons.h"
- #include "media/base/media_switches.h"
- #include "ui/accessibility/accessibility_features.h"
- #include "ui/accessibility/accessibility_switches.h"
- #include "ui/accessibility/aura/aura_window_properties.h"
- #include "ui/aura/window.h"
- #include "ui/base/cursor/cursor_size.h"
- #include "ui/base/l10n/l10n_util.h"
- #include "ui/message_center/message_center.h"
- #include "ui/message_center/public/cpp/notifier_id.h"
- #include "ui/wm/core/cursor_manager.h"
- using session_manager::SessionState;
- namespace ash {
- namespace {
- using FeatureType = AccessibilityControllerImpl::FeatureType;
- // These classes are used to store the static configuration for a11y features.
- struct FeatureData {
- FeatureType type;
- const char* pref;
- const gfx::VectorIcon* icon;
- FeatureType conflicting_feature = FeatureType::kNoConflictingFeature;
- };
- struct FeatureDialogData {
- AccessibilityControllerImpl::FeatureType type;
- const char* pref;
- int title;
- int body;
- bool mandatory;
- };
- // A static array describing each feature.
- const FeatureData kFeatures[] = {
- {FeatureType::kAutoclick, prefs::kAccessibilityAutoclickEnabled,
- &kSystemMenuAccessibilityAutoClickIcon},
- {FeatureType::kCaretHighlight, prefs::kAccessibilityCaretHighlightEnabled,
- nullptr},
- {FeatureType::kCursorHighlight, prefs::kAccessibilityCursorHighlightEnabled,
- nullptr},
- {FeatureType::kCursorColor, prefs::kAccessibilityCursorColorEnabled,
- nullptr},
- {FeatureType::kDictation, prefs::kAccessibilityDictationEnabled,
- &kDictationMenuIcon},
- {FeatureType::kFocusHighlight, prefs::kAccessibilityFocusHighlightEnabled,
- nullptr, /* conflicting_feature= */ FeatureType::kSpokenFeedback},
- {FeatureType::kFloatingMenu, prefs::kAccessibilityFloatingMenuEnabled,
- nullptr},
- {FeatureType::kFullscreenMagnifier,
- prefs::kAccessibilityScreenMagnifierEnabled,
- &kSystemMenuAccessibilityFullscreenMagnifierIcon},
- {FeatureType::kDockedMagnifier, prefs::kDockedMagnifierEnabled,
- &kSystemMenuAccessibilityDockedMagnifierIcon},
- {FeatureType::kHighContrast, prefs::kAccessibilityHighContrastEnabled,
- &kSystemMenuAccessibilityContrastIcon},
- {FeatureType::kLargeCursor, prefs::kAccessibilityLargeCursorEnabled,
- nullptr},
- {FeatureType::kLiveCaption, ::prefs::kLiveCaptionEnabled,
- &vector_icons::kLiveCaptionOnIcon},
- {FeatureType::kMonoAudio, prefs::kAccessibilityMonoAudioEnabled, nullptr},
- {FeatureType::kSpokenFeedback, prefs::kAccessibilitySpokenFeedbackEnabled,
- &kSystemMenuAccessibilityChromevoxIcon},
- {FeatureType::kSelectToSpeak, prefs::kAccessibilitySelectToSpeakEnabled,
- &kSystemMenuAccessibilitySelectToSpeakIcon},
- {FeatureType::kStickyKeys, prefs::kAccessibilityStickyKeysEnabled, nullptr},
- {FeatureType::kSwitchAccess, prefs::kAccessibilitySwitchAccessEnabled,
- &kSwitchAccessIcon},
- {FeatureType::kVirtualKeyboard, prefs::kAccessibilityVirtualKeyboardEnabled,
- &kSystemMenuKeyboardLegacyIcon}};
- // An array describing the confirmation dialogs for the features which have
- // them.
- const FeatureDialogData kFeatureDialogs[] = {
- {FeatureType::kFullscreenMagnifier,
- prefs::kScreenMagnifierAcceleratorDialogHasBeenAccepted,
- IDS_ASH_SCREEN_MAGNIFIER_TITLE, IDS_ASH_SCREEN_MAGNIFIER_BODY, false},
- {FeatureType::kDockedMagnifier,
- prefs::kDockedMagnifierAcceleratorDialogHasBeenAccepted,
- IDS_ASH_DOCKED_MAGNIFIER_TITLE, IDS_ASH_DOCKED_MAGNIFIER_BODY, false},
- {FeatureType::kHighContrast,
- prefs::kHighContrastAcceleratorDialogHasBeenAccepted,
- IDS_ASH_HIGH_CONTRAST_TITLE, IDS_ASH_HIGH_CONTRAST_BODY, false}};
- constexpr char kNotificationId[] = "chrome://settings/accessibility";
- constexpr char kNotifierAccessibility[] = "ash.accessibility";
- // TODO(warx): Signin screen has more controllable accessibility prefs. We may
- // want to expand this to a complete list. If so, merge this with
- // |kCopiedOnSigninAccessibilityPrefs|.
- constexpr const char* const kA11yPrefsForRecommendedValueOnSignin[]{
- prefs::kAccessibilityLargeCursorEnabled,
- prefs::kAccessibilityHighContrastEnabled,
- prefs::kAccessibilityScreenMagnifierEnabled,
- prefs::kAccessibilitySpokenFeedbackEnabled,
- prefs::kAccessibilityVirtualKeyboardEnabled,
- };
- // List of accessibility prefs that are to be copied (if changed by the user) on
- // signin screen profile to a newly created user profile or a guest session.
- constexpr const char* const kCopiedOnSigninAccessibilityPrefs[]{
- prefs::kAccessibilityAutoclickDelayMs,
- prefs::kAccessibilityAutoclickEnabled,
- prefs::kAccessibilityCaretHighlightEnabled,
- prefs::kAccessibilityCursorHighlightEnabled,
- prefs::kAccessibilityCursorColorEnabled,
- prefs::kAccessibilityCursorColor,
- prefs::kAccessibilityDictationEnabled,
- prefs::kAccessibilityDictationLocale,
- prefs::kAccessibilityDictationLocaleOfflineNudge,
- prefs::kAccessibilityFocusHighlightEnabled,
- prefs::kAccessibilityHighContrastEnabled,
- prefs::kAccessibilityLargeCursorEnabled,
- prefs::kAccessibilityMonoAudioEnabled,
- prefs::kAccessibilityScreenMagnifierEnabled,
- prefs::kAccessibilityScreenMagnifierFocusFollowingEnabled,
- prefs::kAccessibilityScreenMagnifierMouseFollowingMode,
- prefs::kAccessibilityScreenMagnifierScale,
- prefs::kAccessibilitySelectToSpeakEnabled,
- prefs::kAccessibilitySpokenFeedbackEnabled,
- prefs::kAccessibilityStickyKeysEnabled,
- prefs::kAccessibilityShortcutsEnabled,
- prefs::kAccessibilitySwitchAccessEnabled,
- prefs::kAccessibilityVirtualKeyboardEnabled,
- prefs::kDockedMagnifierEnabled,
- prefs::kDockedMagnifierScale,
- prefs::kDockedMagnifierScreenHeightDivisor,
- prefs::kHighContrastAcceleratorDialogHasBeenAccepted,
- prefs::kScreenMagnifierAcceleratorDialogHasBeenAccepted,
- prefs::kDockedMagnifierAcceleratorDialogHasBeenAccepted,
- prefs::kDictationAcceleratorDialogHasBeenAccepted,
- prefs::kDisplayRotationAcceleratorDialogHasBeenAccepted2,
- };
- // List of switch access accessibility prefs that are to be copied (if changed
- // by the user) from the current user to the signin screen profile. That way
- // if a switch access user signs out, their switch continues to function.
- constexpr const char* const kSwitchAccessPrefsCopiedToSignin[]{
- prefs::kAccessibilitySwitchAccessAutoScanEnabled,
- prefs::kAccessibilitySwitchAccessAutoScanKeyboardSpeedMs,
- prefs::kAccessibilitySwitchAccessAutoScanSpeedMs,
- prefs::kAccessibilitySwitchAccessPointScanSpeedDipsPerSecond,
- prefs::kAccessibilitySwitchAccessEnabled,
- prefs::kAccessibilitySwitchAccessNextDeviceKeyCodes,
- prefs::kAccessibilitySwitchAccessPreviousDeviceKeyCodes,
- prefs::kAccessibilitySwitchAccessSelectDeviceKeyCodes,
- };
- // Helper function that is used to verify the validity of kFeatures and
- // kFeatureDialogs.
- bool VerifyFeaturesData() {
- // All feature prefs must be unique.
- std::set<const char*> feature_prefs;
- for (auto feature_data : kFeatures) {
- if (feature_prefs.find(feature_data.pref) != feature_prefs.end())
- return false;
- feature_prefs.insert(feature_data.pref);
- }
- for (auto dialog_data : kFeatureDialogs) {
- if (feature_prefs.find(dialog_data.pref) != feature_prefs.end())
- return false;
- feature_prefs.insert(dialog_data.pref);
- }
- return true;
- }
- // Returns true if |pref_service| is the one used for the signin screen.
- bool IsSigninPrefService(PrefService* pref_service) {
- const PrefService* signin_pref_service =
- Shell::Get()->session_controller()->GetSigninScreenPrefService();
- DCHECK(signin_pref_service);
- return pref_service == signin_pref_service;
- }
- // Returns true if the current session is the guest session.
- bool IsCurrentSessionGuest() {
- const absl::optional<user_manager::UserType> user_type =
- Shell::Get()->session_controller()->GetUserType();
- return user_type && *user_type == user_manager::USER_TYPE_GUEST;
- }
- bool IsUserFirstLogin() {
- return Shell::Get()->session_controller()->IsUserFirstLogin();
- }
- // The copying of any modified accessibility prefs on the signin prefs happens
- // when the |previous_pref_service| is of the signin profile, and the
- // |current_pref_service| is of a newly created profile first logged in, or if
- // the current session is the guest session.
- bool ShouldCopySigninPrefs(PrefService* previous_pref_service,
- PrefService* current_pref_service) {
- DCHECK(previous_pref_service);
- if (IsUserFirstLogin() && IsSigninPrefService(previous_pref_service) &&
- !IsSigninPrefService(current_pref_service)) {
- // If the user set a pref value on the login screen and is now starting a
- // session with a new profile, copy the pref value to the profile.
- return true;
- }
- if (IsCurrentSessionGuest()) {
- // Guest sessions don't have their own prefs, so always copy.
- return true;
- }
- return false;
- }
- // On a user's first login into a device, any a11y features enabled/disabled
- // by the user on the login screen are enabled/disabled in the user's profile.
- // This function copies settings from the signin prefs into the user's prefs
- // when it detects a login with a newly created profile.
- void CopySigninPrefsIfNeeded(PrefService* previous_pref_service,
- PrefService* current_pref_service) {
- DCHECK(current_pref_service);
- if (!ShouldCopySigninPrefs(previous_pref_service, current_pref_service))
- return;
- PrefService* signin_prefs =
- Shell::Get()->session_controller()->GetSigninScreenPrefService();
- DCHECK(signin_prefs);
- for (const auto* pref_path : kCopiedOnSigninAccessibilityPrefs) {
- const PrefService::Preference* pref =
- signin_prefs->FindPreference(pref_path);
- // Ignore if the pref has not been set by the user.
- if (!pref || !pref->IsUserControlled())
- continue;
- // Copy the pref value from the signin profile.
- const base::Value* value_on_login = pref->GetValue();
- current_pref_service->Set(pref_path, *value_on_login);
- }
- }
- // Returns notification icon based on the A11yNotificationType.
- const gfx::VectorIcon& GetNotificationIcon(A11yNotificationType type) {
- switch (type) {
- case A11yNotificationType::kSpokenFeedbackBrailleEnabled:
- return kNotificationAccessibilityIcon;
- case A11yNotificationType::kBrailleDisplayConnected:
- return kNotificationAccessibilityBrailleIcon;
- case A11yNotificationType::kSwitchAccessEnabled:
- return kSwitchAccessIcon;
- case A11yNotificationType::kSpeechRecognitionFilesDownloaded:
- case A11yNotificationType::kSpeechRecognitionFilesFailed:
- return kDictationMenuIcon;
- default:
- return kNotificationChromevoxIcon;
- }
- }
- void ShowAccessibilityNotification(
- const AccessibilityControllerImpl::A11yNotificationWrapper& wrapper) {
- A11yNotificationType type = wrapper.type;
- const auto& replacements = wrapper.replacements;
- message_center::MessageCenter* message_center =
- message_center::MessageCenter::Get();
- message_center->RemoveNotification(kNotificationId, false /* by_user */);
- if (type == A11yNotificationType::kNone)
- return;
- std::u16string text;
- std::u16string title;
- std::u16string display_source;
- auto catalog_name = NotificationCatalogName::kNone;
- bool pinned = true;
- message_center::SystemNotificationWarningLevel warning =
- message_center::SystemNotificationWarningLevel::NORMAL;
- if (type == A11yNotificationType::kBrailleDisplayConnected) {
- text = l10n_util::GetStringUTF16(
- IDS_ASH_STATUS_TRAY_BRAILLE_DISPLAY_CONNECTED);
- catalog_name = NotificationCatalogName::kBrailleDisplayConnected;
- } else if (type == A11yNotificationType::kSwitchAccessEnabled) {
- title = l10n_util::GetStringUTF16(
- IDS_ASH_STATUS_TRAY_SWITCH_ACCESS_ENABLED_TITLE);
- text = l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_SWITCH_ACCESS_ENABLED);
- catalog_name = NotificationCatalogName::kSwitchAccessEnabled;
- } else if (type == A11yNotificationType::kSpeechRecognitionFilesDownloaded) {
- display_source =
- l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_ACCESSIBILITY_DICTATION);
- title = l10n_util::GetStringFUTF16(
- IDS_ASH_A11Y_DICTATION_NOTIFICATION_SODA_DOWNLOAD_SUCCEEDED_TITLE,
- replacements, nullptr);
- text = l10n_util::GetStringUTF16(
- IDS_ASH_A11Y_DICTATION_NOTIFICATION_SODA_DOWNLOAD_SUCCEEDED_DESC);
- pinned = false;
- catalog_name = NotificationCatalogName::kSpeechRecognitionFilesDownloaded;
- } else if (type == A11yNotificationType::kSpeechRecognitionFilesFailed) {
- display_source =
- l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_ACCESSIBILITY_DICTATION);
- title = l10n_util::GetStringFUTF16(
- IDS_ASH_A11Y_DICTATION_NOTIFICATION_SODA_DOWNLOAD_FAILED_TITLE,
- replacements, nullptr);
- text = l10n_util::GetStringUTF16(
- IDS_ASH_A11Y_DICTATION_NOTIFICATION_SODA_DOWNLOAD_FAILED_DESC);
- // Use CRITICAL_WARNING to force the notification color to red.
- warning = message_center::SystemNotificationWarningLevel::CRITICAL_WARNING;
- pinned = false;
- catalog_name = NotificationCatalogName::kSpeechRecognitionFilesFailed;
- } else {
- bool is_tablet = Shell::Get()->tablet_mode_controller()->InTabletMode();
- title = l10n_util::GetStringUTF16(
- type == A11yNotificationType::kSpokenFeedbackBrailleEnabled
- ? IDS_ASH_STATUS_TRAY_SPOKEN_FEEDBACK_BRAILLE_ENABLED_TITLE
- : IDS_ASH_STATUS_TRAY_SPOKEN_FEEDBACK_ENABLED_TITLE);
- text = l10n_util::GetStringUTF16(
- is_tablet ? IDS_ASH_STATUS_TRAY_SPOKEN_FEEDBACK_ENABLED_TABLET
- : IDS_ASH_STATUS_TRAY_SPOKEN_FEEDBACK_ENABLED);
- catalog_name = type == A11yNotificationType::kSpokenFeedbackBrailleEnabled
- ? NotificationCatalogName::kSpokenFeedbackBrailleEnabled
- : NotificationCatalogName::kSpokenFeedbackEnabled;
- }
- message_center::RichNotificationData options;
- options.should_make_spoken_feedback_for_popup_updates = false;
- std::unique_ptr<message_center::Notification> notification =
- ash::CreateSystemNotification(
- message_center::NOTIFICATION_TYPE_SIMPLE, kNotificationId, title,
- text, display_source, GURL(),
- message_center::NotifierId(
- message_center::NotifierType::SYSTEM_COMPONENT,
- kNotifierAccessibility, catalog_name),
- options, nullptr, GetNotificationIcon(type), warning);
- notification->set_pinned(pinned);
- message_center->AddNotification(std::move(notification));
- }
- void RemoveAccessibilityNotification() {
- ShowAccessibilityNotification(
- AccessibilityControllerImpl::A11yNotificationWrapper(
- A11yNotificationType::kNone, std::vector<std::u16string>()));
- }
- AccessibilityPanelLayoutManager* GetLayoutManager() {
- // The accessibility panel is only shown on the primary display.
- aura::Window* root = Shell::GetPrimaryRootWindow();
- aura::Window* container =
- Shell::GetContainer(root, kShellWindowId_AccessibilityPanelContainer);
- // TODO(jamescook): Avoid this cast by moving ash::AccessibilityObserver
- // ownership to this class and notifying it on accessibility panel fullscreen
- // updates.
- return static_cast<AccessibilityPanelLayoutManager*>(
- container->layout_manager());
- }
- std::string PrefKeyForSwitchAccessCommand(SwitchAccessCommand command) {
- switch (command) {
- case SwitchAccessCommand::kSelect:
- return prefs::kAccessibilitySwitchAccessSelectDeviceKeyCodes;
- case SwitchAccessCommand::kNext:
- return prefs::kAccessibilitySwitchAccessNextDeviceKeyCodes;
- case SwitchAccessCommand::kPrevious:
- return prefs::kAccessibilitySwitchAccessPreviousDeviceKeyCodes;
- case SwitchAccessCommand::kNone:
- NOTREACHED();
- return "";
- }
- }
- std::string UmaNameForSwitchAccessCommand(SwitchAccessCommand command) {
- switch (command) {
- case SwitchAccessCommand::kSelect:
- return "Accessibility.CrosSwitchAccess.SelectKeyCode";
- case SwitchAccessCommand::kNext:
- return "Accessibility.CrosSwitchAccess.NextKeyCode";
- case SwitchAccessCommand::kPrevious:
- return "Accessibility.CrosSwitchAccess.PreviousKeyCode";
- case SwitchAccessCommand::kNone:
- NOTREACHED();
- return "";
- }
- }
- // These values are persisted to logs. Entries should not be renumbered and
- // numeric values should never be reused.
- enum class SwitchAccessKeyCode {
- kUnknown = 0,
- kKeycode1 = 1,
- kKeycode2 = 2,
- kKeycode3 = 3,
- kKeycode4 = 4,
- kKeycode5 = 5,
- kKeycode6 = 6,
- kKeycode7 = 7,
- kBackspace = 8,
- kTab = 9,
- kKeycode10 = 10,
- kKeycode11 = 11,
- kClear = 12,
- kReturn = 13,
- kKeycode14 = 14,
- kKeycode15 = 15,
- kShift = 16,
- kControl = 17,
- kAlt = 18,
- kPause = 19,
- kCapital = 20,
- kKana = 21,
- kKeycode22 = 22,
- kJunja = 23,
- kFinal = 24,
- kHanja = 25,
- kKeycode26 = 26,
- kEscape = 27,
- kConvert = 28,
- kNonconvert = 29,
- kAccept = 30,
- kModechange = 31,
- kSpace = 32,
- kPrior = 33,
- kNext = 34,
- kEnd = 35,
- kHome = 36,
- kLeft = 37,
- kUp = 38,
- kRight = 39,
- kDown = 40,
- kSelect = 41,
- kPrint = 42,
- kExecute = 43,
- kSnapshot = 44,
- kInsert = 45,
- kKeyDelete = 46,
- kHelp = 47,
- kNum0 = 48,
- kNum1 = 49,
- kNum2 = 50,
- kNum3 = 51,
- kNum4 = 52,
- kNum5 = 53,
- kNum6 = 54,
- kNum7 = 55,
- kNum8 = 56,
- kNum9 = 57,
- kKeycode58 = 58,
- kKeycode59 = 59,
- kKeycode60 = 60,
- kKeycode61 = 61,
- kKeycode62 = 62,
- kKeycode63 = 63,
- kKeycode64 = 64,
- kA = 65,
- kB = 66,
- kC = 67,
- kD = 68,
- kE = 69,
- kF = 70,
- kG = 71,
- kH = 72,
- kI = 73,
- kJ = 74,
- kK = 75,
- kL = 76,
- kM = 77,
- kN = 78,
- kO = 79,
- kP = 80,
- kQ = 81,
- kR = 82,
- kS = 83,
- kT = 84,
- kU = 85,
- kV = 86,
- kW = 87,
- kX = 88,
- kY = 89,
- kZ = 90,
- kLwin = 91,
- kRwin = 92,
- kApps = 93,
- kKeycode94 = 94,
- kSleep = 95,
- kNumpad0 = 96,
- kNumpad1 = 97,
- kNumpad2 = 98,
- kNumpad3 = 99,
- kNumpad4 = 100,
- kNumpad5 = 101,
- kNumpad6 = 102,
- kNumpad7 = 103,
- kNumpad8 = 104,
- kNumpad9 = 105,
- kMultiply = 106,
- kAdd = 107,
- kSeparator = 108,
- kSubtract = 109,
- kDecimal = 110,
- kDivide = 111,
- kF1 = 112,
- kF2 = 113,
- kF3 = 114,
- kF4 = 115,
- kF5 = 116,
- kF6 = 117,
- kF7 = 118,
- kF8 = 119,
- kF9 = 120,
- kF10 = 121,
- kF11 = 122,
- kF12 = 123,
- kF13 = 124,
- kF14 = 125,
- kF15 = 126,
- kF16 = 127,
- kF17 = 128,
- kF18 = 129,
- kF19 = 130,
- kF20 = 131,
- kF21 = 132,
- kF22 = 133,
- kF23 = 134,
- kF24 = 135,
- kKeycode136 = 136,
- kKeycode137 = 137,
- kKeycode138 = 138,
- kKeycode139 = 139,
- kKeycode140 = 140,
- kKeycode141 = 141,
- kKeycode142 = 142,
- kKeycode143 = 143,
- kNumlock = 144,
- kScroll = 145,
- kKeycode146 = 146,
- kKeycode147 = 147,
- kKeycode148 = 148,
- kKeycode149 = 149,
- kKeycode150 = 150,
- kWlan = 151,
- kPower = 152,
- kAssistant = 153,
- kKeycode154 = 154,
- kKeycode155 = 155,
- kKeycode156 = 156,
- kKeycode157 = 157,
- kKeycode158 = 158,
- kKeycode159 = 159,
- kLshift = 160,
- kRshift = 161,
- kLcontrol = 162,
- kRcontrol = 163,
- kLmenu = 164,
- kRmenu = 165,
- kBrowserBack = 166,
- kBrowserForward = 167,
- kBrowserRefresh = 168,
- kBrowserStop = 169,
- kBrowserSearch = 170,
- kBrowserFavorites = 171,
- kBrowserHome = 172,
- kVolumeMute = 173,
- kVolumeDown = 174,
- kVolumeUp = 175,
- kMediaNextTrack = 176,
- kMediaPrevTrack = 177,
- kMediaStop = 178,
- kMediaPlayPause = 179,
- kMediaLaunchMail = 180,
- kMediaLaunchMediaSelect = 181,
- kMediaLaunchApp1 = 182,
- kMediaLaunchApp2 = 183,
- kKeycode184 = 184,
- kKeycode185 = 185,
- kOem1 = 186,
- kOemPlus = 187,
- kOemComma = 188,
- kOemMinus = 189,
- kOemPeriod = 190,
- kOem2 = 191,
- kOem3 = 192,
- kKeycode193 = 193,
- kKeycode194 = 194,
- kKeycode195 = 195,
- kKeycode196 = 196,
- kKeycode197 = 197,
- kKeycode198 = 198,
- kKeycode199 = 199,
- kKeycode200 = 200,
- kKeycode201 = 201,
- kKeycode202 = 202,
- kKeycode203 = 203,
- kKeycode204 = 204,
- kKeycode205 = 205,
- kKeycode206 = 206,
- kKeycode207 = 207,
- kKeycode208 = 208,
- kKeycode209 = 209,
- kKeycode210 = 210,
- kKeycode211 = 211,
- kKeycode212 = 212,
- kKeycode213 = 213,
- kKeycode214 = 214,
- kKeycode215 = 215,
- kBrightnessDown = 216,
- kBrightnessUp = 217,
- kKbdBrightnessDown = 218,
- kOem4 = 219,
- kOem5 = 220,
- kOem6 = 221,
- kOem7 = 222,
- kOem8 = 223,
- kKeycode224 = 224,
- kAltgr = 225,
- kOem102 = 226,
- kKeycode227 = 227,
- kKeycode228 = 228,
- kProcesskey = 229,
- kCompose = 230,
- kPacket = 231,
- kKbdBrightnessUp = 232,
- kKeycode233 = 233,
- kKeycode234 = 234,
- kKeycode235 = 235,
- kKeycode236 = 236,
- kKeycode237 = 237,
- kKeycode238 = 238,
- kKeycode239 = 239,
- kKeycode240 = 240,
- kKeycode241 = 241,
- kKeycode242 = 242,
- kDbeSbcschar = 243,
- kDbeDbcschar = 244,
- kKeycode245 = 245,
- kAttn = 246,
- kCrsel = 247,
- kExsel = 248,
- kEreof = 249,
- kPlay = 250,
- kZoom = 251,
- kNoname = 252,
- kPa1 = 253,
- kOemClear = 254,
- kKeycode255 = 255,
- kNone = 256,
- kMaxValue = kNone,
- };
- } // namespace
- AccessibilityControllerImpl::Feature::Feature(
- FeatureType type,
- const std::string& pref_name,
- const gfx::VectorIcon* icon,
- AccessibilityControllerImpl* controller)
- : type_(type), pref_name_(pref_name), icon_(icon), owner_(controller) {}
- AccessibilityControllerImpl::Feature::~Feature() = default;
- void AccessibilityControllerImpl::Feature::SetEnabled(bool enabled) {
- PrefService* prefs = owner_->active_user_prefs_;
- if (!prefs)
- return;
- prefs->SetBoolean(pref_name_, enabled);
- prefs->CommitPendingWrite();
- }
- bool AccessibilityControllerImpl::Feature::IsVisibleInTray() const {
- return (conflicting_feature_ == kNoConflictingFeature ||
- !owner_->GetFeature(conflicting_feature_).enabled()) &&
- owner_->IsAccessibilityFeatureVisibleInTrayMenu(pref_name_);
- }
- bool AccessibilityControllerImpl::Feature::IsEnterpriseIconVisible() const {
- return owner_->IsEnterpriseIconVisibleInTrayMenu(pref_name_);
- }
- const gfx::VectorIcon& AccessibilityControllerImpl::Feature::icon() const {
- DCHECK(icon_);
- if (icon_)
- return *icon_;
- return kPaletteTrayIconDefaultIcon;
- }
- void AccessibilityControllerImpl::Feature::UpdateFromPref() {
- PrefService* prefs = owner_->active_user_prefs_;
- DCHECK(prefs);
- bool enabled = prefs->GetBoolean(pref_name_);
- if (conflicting_feature_ != FeatureType::kNoConflictingFeature &&
- owner_->GetFeature(conflicting_feature_).enabled()) {
- enabled = false;
- }
- if (enabled == enabled_)
- return;
- enabled_ = enabled;
- owner_->UpdateFeatureFromPref(type_);
- }
- void AccessibilityControllerImpl::Feature::SetConflictingFeature(
- AccessibilityControllerImpl::FeatureType feature) {
- DCHECK_EQ(conflicting_feature_, FeatureType::kNoConflictingFeature);
- conflicting_feature_ = feature;
- }
- AccessibilityControllerImpl::FeatureWithDialog::FeatureWithDialog(
- FeatureType type,
- const std::string& pref_name,
- const gfx::VectorIcon* icon,
- const Dialog& dialog,
- AccessibilityControllerImpl* controller)
- : AccessibilityControllerImpl::Feature(type, pref_name, icon, controller),
- dialog_(dialog) {}
- AccessibilityControllerImpl::FeatureWithDialog::~FeatureWithDialog() = default;
- void AccessibilityControllerImpl::FeatureWithDialog::SetDialogAccepted() {
- PrefService* prefs = owner_->active_user_prefs_;
- if (!prefs)
- return;
- prefs->SetBoolean(dialog_.pref_name, true);
- prefs->CommitPendingWrite();
- }
- bool AccessibilityControllerImpl::FeatureWithDialog::WasDialogAccepted() const {
- PrefService* prefs = owner_->active_user_prefs_;
- DCHECK(prefs);
- return prefs->GetBoolean(dialog_.pref_name);
- }
- void AccessibilityControllerImpl::FeatureWithDialog::SetEnabledWithDialog(
- bool enabled,
- base::OnceClosure completion_callback) {
- PrefService* prefs = owner_->active_user_prefs_;
- if (!prefs)
- return;
- // We should not show the dialog when the feature is already enabled.
- if (enabled && !this->enabled() && !WasDialogAccepted()) {
- Shell::Get()->accelerator_controller()->MaybeShowConfirmationDialog(
- dialog_.title_resource_id, dialog_.body_resource_id,
- // Callback for if the user accepts the dialog
- base::BindOnce(
- [](base::WeakPtr<AccessibilityControllerImpl> owner,
- FeatureType type, base::OnceClosure completion_callback) {
- if (!owner)
- return;
- static_cast<FeatureWithDialog&>(owner->GetFeature(type))
- .SetDialogAccepted();
- // If they accept, try again to set value to true
- owner->GetFeature(type).SetEnabled(true);
- std::move(completion_callback).Run();
- },
- owner_->weak_ptr_factory_.GetWeakPtr(), type_,
- std::move(completion_callback)),
- base::DoNothing());
- return;
- }
- Feature::SetEnabled(enabled);
- std::move(completion_callback).Run();
- }
- void AccessibilityControllerImpl::FeatureWithDialog::SetEnabled(bool enabled) {
- if (dialog_.mandatory)
- SetEnabledWithDialog(enabled, base::DoNothing());
- else
- Feature::SetEnabled(enabled);
- }
- AccessibilityControllerImpl::AccessibilityControllerImpl()
- : autoclick_delay_(AutoclickController::GetDefaultAutoclickDelay()) {
- Shell::Get()->session_controller()->AddObserver(this);
- Shell::Get()->tablet_mode_controller()->AddObserver(this);
- CreateAccessibilityFeatures();
- }
- AccessibilityControllerImpl::~AccessibilityControllerImpl() {
- floating_menu_controller_.reset();
- }
- void AccessibilityControllerImpl::CreateAccessibilityFeatures() {
- DCHECK(VerifyFeaturesData());
- // First, build all features with dialog.
- std::map<FeatureType, Dialog> dialogs;
- for (auto dialog_data : kFeatureDialogs) {
- dialogs[dialog_data.type] = {dialog_data.pref, dialog_data.title,
- dialog_data.body, dialog_data.mandatory};
- }
- for (auto feature_data : kFeatures) {
- DCHECK(!features_[feature_data.type]);
- auto it = dialogs.find(feature_data.type);
- if (it == dialogs.end()) {
- features_[feature_data.type] = std::make_unique<Feature>(
- feature_data.type, feature_data.pref, feature_data.icon, this);
- } else {
- features_[feature_data.type] = std::make_unique<FeatureWithDialog>(
- feature_data.type, feature_data.pref, feature_data.icon, it->second,
- this);
- }
- }
- }
- // static
- void AccessibilityControllerImpl::RegisterProfilePrefs(
- PrefRegistrySimple* registry) {
- //
- // Non-syncable prefs.
- //
- // These prefs control whether an accessibility feature is enabled. They are
- // not synced due to the impact they have on device interaction.
- registry->RegisterBooleanPref(prefs::kAccessibilityAutoclickEnabled, false);
- registry->RegisterBooleanPref(prefs::kAccessibilityCursorColorEnabled, false);
- registry->RegisterBooleanPref(prefs::kAccessibilityCaretHighlightEnabled,
- false);
- registry->RegisterBooleanPref(prefs::kAccessibilityCursorHighlightEnabled,
- false);
- registry->RegisterBooleanPref(prefs::kAccessibilityDictationEnabled, false);
- registry->RegisterBooleanPref(prefs::kAccessibilityFloatingMenuEnabled,
- false);
- registry->RegisterBooleanPref(prefs::kAccessibilityFocusHighlightEnabled,
- false);
- registry->RegisterBooleanPref(prefs::kAccessibilityHighContrastEnabled,
- false);
- registry->RegisterBooleanPref(prefs::kAccessibilityLargeCursorEnabled, false);
- registry->RegisterBooleanPref(prefs::kAccessibilityMonoAudioEnabled, false);
- registry->RegisterBooleanPref(prefs::kAccessibilityScreenMagnifierEnabled,
- false);
- registry->RegisterBooleanPref(prefs::kAccessibilitySpokenFeedbackEnabled,
- false);
- registry->RegisterBooleanPref(prefs::kAccessibilitySelectToSpeakEnabled,
- false);
- registry->RegisterBooleanPref(prefs::kAccessibilityStickyKeysEnabled, false);
- registry->RegisterBooleanPref(prefs::kAccessibilityShortcutsEnabled, true);
- registry->RegisterBooleanPref(prefs::kAccessibilitySwitchAccessEnabled,
- false);
- registry->RegisterBooleanPref(prefs::kAccessibilityVirtualKeyboardEnabled,
- false);
- registry->RegisterBooleanPref(
- prefs::kAccessibilityTabletModeShelfNavigationButtonsEnabled, false);
- // Not syncable because it might change depending on application locale,
- // user settings, and because different languages can cause speech recognition
- // files to download.
- registry->RegisterStringPref(prefs::kAccessibilityDictationLocale,
- std::string());
- registry->RegisterDictionaryPref(
- prefs::kAccessibilityDictationLocaleOfflineNudge);
- // A pref in this list is associated with accepting for the first time,
- // enabling of some pref above. Non-syncable like all of the above prefs.
- registry->RegisterBooleanPref(
- prefs::kHighContrastAcceleratorDialogHasBeenAccepted, false);
- registry->RegisterBooleanPref(
- prefs::kScreenMagnifierAcceleratorDialogHasBeenAccepted, false);
- registry->RegisterBooleanPref(
- prefs::kDockedMagnifierAcceleratorDialogHasBeenAccepted, false);
- registry->RegisterBooleanPref(
- prefs::kDictationAcceleratorDialogHasBeenAccepted, false);
- registry->RegisterBooleanPref(
- prefs::kDisplayRotationAcceleratorDialogHasBeenAccepted2, false);
- registry->RegisterBooleanPref(prefs::kShouldAlwaysShowAccessibilityMenu,
- false);
- //
- // Syncable prefs.
- //
- // These prefs pertain to specific features. They are synced to preserve
- // behaviors tied to user accounts once that user enables a feature.
- registry->RegisterIntegerPref(
- prefs::kAccessibilityAutoclickDelayMs, kDefaultAutoclickDelayMs,
- user_prefs::PrefRegistrySyncable::SYNCABLE_OS_PREF);
- registry->RegisterIntegerPref(
- prefs::kAccessibilityAutoclickEventType,
- static_cast<int>(kDefaultAutoclickEventType),
- user_prefs::PrefRegistrySyncable::SYNCABLE_OS_PREF);
- registry->RegisterBooleanPref(
- prefs::kAccessibilityAutoclickRevertToLeftClick, true,
- user_prefs::PrefRegistrySyncable::SYNCABLE_OS_PREF);
- registry->RegisterBooleanPref(
- prefs::kAccessibilityAutoclickStabilizePosition, false,
- user_prefs::PrefRegistrySyncable::SYNCABLE_OS_PREF);
- registry->RegisterIntegerPref(
- prefs::kAccessibilityAutoclickMovementThreshold,
- kDefaultAutoclickMovementThreshold,
- user_prefs::PrefRegistrySyncable::SYNCABLE_OS_PREF);
- registry->RegisterIntegerPref(
- prefs::kAccessibilityAutoclickMenuPosition,
- static_cast<int>(kDefaultAutoclickMenuPosition),
- user_prefs::PrefRegistrySyncable::SYNCABLE_OS_PREF);
- registry->RegisterIntegerPref(
- prefs::kAccessibilityCursorColor, 0,
- user_prefs::PrefRegistrySyncable::SYNCABLE_OS_PREF);
- registry->RegisterIntegerPref(
- prefs::kAccessibilityFloatingMenuPosition,
- static_cast<int>(kDefaultFloatingMenuPosition),
- user_prefs::PrefRegistrySyncable::SYNCABLE_OS_PREF);
- registry->RegisterIntegerPref(prefs::kAccessibilityLargeCursorDipSize,
- kDefaultLargeCursorSize);
- registry->RegisterIntegerPref(
- prefs::kAccessibilityScreenMagnifierMouseFollowingMode,
- static_cast<int>(MagnifierMouseFollowingMode::kEdge),
- user_prefs::PrefRegistrySyncable::SYNCABLE_OS_PREF);
- registry->RegisterBooleanPref(
- prefs::kAccessibilityScreenMagnifierCenterFocus, true,
- user_prefs::PrefRegistrySyncable::SYNCABLE_OS_PREF);
- registry->RegisterBooleanPref(
- prefs::kAccessibilityScreenMagnifierFocusFollowingEnabled, true,
- user_prefs::PrefRegistrySyncable::SYNCABLE_OS_PREF);
- registry->RegisterDoublePref(prefs::kAccessibilityScreenMagnifierScale,
- std::numeric_limits<double>::min());
- registry->RegisterDictionaryPref(
- prefs::kAccessibilitySwitchAccessSelectDeviceKeyCodes,
- base::Value(base::Value::Type::DICTIONARY),
- user_prefs::PrefRegistrySyncable::SYNCABLE_OS_PREF);
- registry->RegisterDictionaryPref(
- prefs::kAccessibilitySwitchAccessNextDeviceKeyCodes,
- base::Value(base::Value::Type::DICTIONARY),
- user_prefs::PrefRegistrySyncable::SYNCABLE_OS_PREF);
- registry->RegisterDictionaryPref(
- prefs::kAccessibilitySwitchAccessPreviousDeviceKeyCodes,
- base::Value(base::Value::Type::DICTIONARY),
- user_prefs::PrefRegistrySyncable::SYNCABLE_OS_PREF);
- registry->RegisterBooleanPref(
- prefs::kAccessibilitySwitchAccessAutoScanEnabled, false,
- user_prefs::PrefRegistrySyncable::SYNCABLE_OS_PREF);
- registry->RegisterIntegerPref(
- prefs::kAccessibilitySwitchAccessAutoScanSpeedMs,
- kDefaultSwitchAccessAutoScanSpeed.InMilliseconds(),
- user_prefs::PrefRegistrySyncable::SYNCABLE_OS_PREF);
- registry->RegisterIntegerPref(
- prefs::kAccessibilitySwitchAccessAutoScanKeyboardSpeedMs,
- kDefaultSwitchAccessAutoScanSpeed.InMilliseconds(),
- user_prefs::PrefRegistrySyncable::SYNCABLE_OS_PREF);
- registry->RegisterIntegerPref(
- prefs::kAccessibilitySwitchAccessPointScanSpeedDipsPerSecond,
- kDefaultSwitchAccessPointScanSpeedDipsPerSecond,
- user_prefs::PrefRegistrySyncable::SYNCABLE_OS_PREF);
- registry->RegisterBooleanPref(
- prefs::kAccessibilityEnhancedNetworkVoicesInSelectToSpeakAllowed, true,
- user_prefs::PrefRegistrySyncable::SYNCABLE_OS_PREF);
- }
- void AccessibilityControllerImpl::Shutdown() {
- Shell::Get()->tablet_mode_controller()->RemoveObserver(this);
- Shell::Get()->session_controller()->RemoveObserver(this);
- // Clean up any child windows and widgets that might be animating out.
- dictation_nudge_controller_.reset();
- dictation_bubble_controller_.reset();
- for (auto& observer : observers_)
- observer.OnAccessibilityControllerShutdown();
- }
- bool AccessibilityControllerImpl::
- HasDisplayRotationAcceleratorDialogBeenAccepted() const {
- return active_user_prefs_ &&
- active_user_prefs_->GetBoolean(
- prefs::kDisplayRotationAcceleratorDialogHasBeenAccepted2);
- }
- void AccessibilityControllerImpl::
- SetDisplayRotationAcceleratorDialogBeenAccepted() {
- if (!active_user_prefs_)
- return;
- active_user_prefs_->SetBoolean(
- prefs::kDisplayRotationAcceleratorDialogHasBeenAccepted2, true);
- active_user_prefs_->CommitPendingWrite();
- }
- void AccessibilityControllerImpl::AddObserver(AccessibilityObserver* observer) {
- observers_.AddObserver(observer);
- }
- void AccessibilityControllerImpl::RemoveObserver(
- AccessibilityObserver* observer) {
- observers_.RemoveObserver(observer);
- }
- AccessibilityControllerImpl::Feature& AccessibilityControllerImpl::GetFeature(
- FeatureType type) const {
- DCHECK(features_[type].get());
- return *features_[type].get();
- }
- base::WeakPtr<AccessibilityControllerImpl>
- AccessibilityControllerImpl::GetWeakPtr() {
- return weak_ptr_factory_.GetWeakPtr();
- }
- AccessibilityControllerImpl::Feature& AccessibilityControllerImpl::autoclick()
- const {
- return GetFeature(FeatureType::kAutoclick);
- }
- AccessibilityControllerImpl::Feature&
- AccessibilityControllerImpl::caret_highlight() const {
- return GetFeature(FeatureType::kCaretHighlight);
- }
- AccessibilityControllerImpl::Feature&
- AccessibilityControllerImpl::cursor_highlight() const {
- return GetFeature(FeatureType::kCursorHighlight);
- }
- AccessibilityControllerImpl::Feature&
- AccessibilityControllerImpl::cursor_color() const {
- return GetFeature(FeatureType::kCursorColor);
- }
- AccessibilityControllerImpl::Feature& AccessibilityControllerImpl::dictation()
- const {
- return GetFeature(FeatureType::kDictation);
- }
- AccessibilityControllerImpl::Feature&
- AccessibilityControllerImpl::focus_highlight() const {
- return GetFeature(FeatureType::kFocusHighlight);
- }
- AccessibilityControllerImpl::Feature&
- AccessibilityControllerImpl::floating_menu() const {
- return GetFeature(FeatureType::kFloatingMenu);
- }
- AccessibilityControllerImpl::FeatureWithDialog&
- AccessibilityControllerImpl::fullscreen_magnifier() const {
- return static_cast<FeatureWithDialog&>(
- GetFeature(FeatureType::kFullscreenMagnifier));
- }
- AccessibilityControllerImpl::FeatureWithDialog&
- AccessibilityControllerImpl::docked_magnifier() const {
- return static_cast<FeatureWithDialog&>(
- GetFeature(FeatureType::kDockedMagnifier));
- }
- AccessibilityControllerImpl::FeatureWithDialog&
- AccessibilityControllerImpl::high_contrast() const {
- return static_cast<FeatureWithDialog&>(
- GetFeature(FeatureType::kHighContrast));
- }
- AccessibilityControllerImpl::Feature&
- AccessibilityControllerImpl::large_cursor() const {
- return GetFeature(FeatureType::kLargeCursor);
- }
- AccessibilityControllerImpl::Feature&
- AccessibilityControllerImpl::live_caption() const {
- return GetFeature(FeatureType::kLiveCaption);
- }
- AccessibilityControllerImpl::Feature& AccessibilityControllerImpl::mono_audio()
- const {
- return GetFeature(FeatureType::kMonoAudio);
- }
- AccessibilityControllerImpl::Feature&
- AccessibilityControllerImpl::spoken_feedback() const {
- return GetFeature(FeatureType::kSpokenFeedback);
- }
- AccessibilityControllerImpl::Feature&
- AccessibilityControllerImpl::select_to_speak() const {
- return GetFeature(FeatureType::kSelectToSpeak);
- }
- AccessibilityControllerImpl::Feature& AccessibilityControllerImpl::sticky_keys()
- const {
- return GetFeature(FeatureType::kStickyKeys);
- }
- AccessibilityControllerImpl::Feature&
- AccessibilityControllerImpl::switch_access() const {
- return GetFeature(FeatureType::kSwitchAccess);
- }
- AccessibilityControllerImpl::Feature&
- AccessibilityControllerImpl::virtual_keyboard() const {
- return GetFeature(FeatureType::kVirtualKeyboard);
- }
- bool AccessibilityControllerImpl::IsAutoclickSettingVisibleInTray() {
- return autoclick().IsVisibleInTray();
- }
- bool AccessibilityControllerImpl::IsEnterpriseIconVisibleForAutoclick() {
- return autoclick().IsEnterpriseIconVisible();
- }
- bool AccessibilityControllerImpl::IsPrimarySettingsViewVisibleInTray() {
- return (IsSpokenFeedbackSettingVisibleInTray() ||
- IsSelectToSpeakSettingVisibleInTray() ||
- IsDictationSettingVisibleInTray() ||
- IsHighContrastSettingVisibleInTray() ||
- IsFullScreenMagnifierSettingVisibleInTray() ||
- IsDockedMagnifierSettingVisibleInTray() ||
- IsAutoclickSettingVisibleInTray() ||
- IsVirtualKeyboardSettingVisibleInTray() ||
- IsSwitchAccessSettingVisibleInTray() ||
- IsLiveCaptionSettingVisibleInTray());
- }
- bool AccessibilityControllerImpl::IsAdditionalSettingsViewVisibleInTray() {
- return (IsLargeCursorSettingVisibleInTray() ||
- IsMonoAudioSettingVisibleInTray() ||
- IsCaretHighlightSettingVisibleInTray() ||
- IsCursorHighlightSettingVisibleInTray() ||
- IsFocusHighlightSettingVisibleInTray() ||
- IsStickyKeysSettingVisibleInTray());
- }
- bool AccessibilityControllerImpl::IsAdditionalSettingsSeparatorVisibleInTray() {
- return IsPrimarySettingsViewVisibleInTray() &&
- IsAdditionalSettingsViewVisibleInTray();
- }
- bool AccessibilityControllerImpl::IsCaretHighlightSettingVisibleInTray() {
- return caret_highlight().IsVisibleInTray();
- }
- bool AccessibilityControllerImpl::IsEnterpriseIconVisibleForCaretHighlight() {
- return caret_highlight().IsEnterpriseIconVisible();
- }
- bool AccessibilityControllerImpl::IsCursorHighlightSettingVisibleInTray() {
- return cursor_highlight().IsVisibleInTray();
- }
- bool AccessibilityControllerImpl::IsEnterpriseIconVisibleForCursorHighlight() {
- return cursor_highlight().IsEnterpriseIconVisible();
- }
- bool AccessibilityControllerImpl::IsDictationSettingVisibleInTray() {
- return dictation().IsVisibleInTray();
- }
- bool AccessibilityControllerImpl::IsEnterpriseIconVisibleForDictation() {
- return dictation().IsEnterpriseIconVisible();
- }
- bool AccessibilityControllerImpl::IsFocusHighlightSettingVisibleInTray() {
- return focus_highlight().IsVisibleInTray();
- }
- bool AccessibilityControllerImpl::IsEnterpriseIconVisibleForFocusHighlight() {
- return focus_highlight().IsEnterpriseIconVisible();
- }
- bool AccessibilityControllerImpl::IsFullScreenMagnifierSettingVisibleInTray() {
- return fullscreen_magnifier().IsVisibleInTray();
- }
- bool AccessibilityControllerImpl::
- IsEnterpriseIconVisibleForFullScreenMagnifier() {
- return fullscreen_magnifier().IsEnterpriseIconVisible();
- }
- bool AccessibilityControllerImpl::IsDockedMagnifierSettingVisibleInTray() {
- return docked_magnifier().IsVisibleInTray();
- }
- bool AccessibilityControllerImpl::IsEnterpriseIconVisibleForDockedMagnifier() {
- return docked_magnifier().IsEnterpriseIconVisible();
- }
- bool AccessibilityControllerImpl::IsHighContrastSettingVisibleInTray() {
- return high_contrast().IsVisibleInTray();
- }
- bool AccessibilityControllerImpl::IsEnterpriseIconVisibleForHighContrast() {
- return high_contrast().IsEnterpriseIconVisible();
- }
- bool AccessibilityControllerImpl::IsLargeCursorSettingVisibleInTray() {
- return large_cursor().IsVisibleInTray();
- }
- bool AccessibilityControllerImpl::IsEnterpriseIconVisibleForLargeCursor() {
- return large_cursor().IsEnterpriseIconVisible();
- }
- bool AccessibilityControllerImpl::IsLiveCaptionSettingVisibleInTray() {
- return captions::IsLiveCaptionFeatureSupported() &&
- base::FeatureList::IsEnabled(
- media::kLiveCaptionSystemWideOnChromeOS) &&
- live_caption().IsVisibleInTray();
- }
- bool AccessibilityControllerImpl::IsEnterpriseIconVisibleForLiveCaption() {
- return captions::IsLiveCaptionFeatureSupported() &&
- base::FeatureList::IsEnabled(
- media::kLiveCaptionSystemWideOnChromeOS) &&
- live_caption().IsEnterpriseIconVisible();
- }
- bool AccessibilityControllerImpl::IsMonoAudioSettingVisibleInTray() {
- return mono_audio().IsVisibleInTray();
- }
- bool AccessibilityControllerImpl::IsEnterpriseIconVisibleForMonoAudio() {
- return mono_audio().IsEnterpriseIconVisible();
- }
- void AccessibilityControllerImpl::SetSpokenFeedbackEnabled(
- bool enabled,
- AccessibilityNotificationVisibility notify) {
- spoken_feedback().SetEnabled(enabled);
- // Value could be left unchanged because of higher-priority pref source, eg.
- // policy. See crbug.com/953245.
- const bool actual_enabled = active_user_prefs_->GetBoolean(
- prefs::kAccessibilitySpokenFeedbackEnabled);
- A11yNotificationType type = A11yNotificationType::kNone;
- if (enabled && actual_enabled && notify == A11Y_NOTIFICATION_SHOW)
- type = A11yNotificationType::kSpokenFeedbackEnabled;
- ShowAccessibilityNotification(
- A11yNotificationWrapper(type, std::vector<std::u16string>()));
- }
- bool AccessibilityControllerImpl::IsSpokenFeedbackSettingVisibleInTray() {
- return spoken_feedback().IsVisibleInTray();
- }
- bool AccessibilityControllerImpl::IsEnterpriseIconVisibleForSpokenFeedback() {
- return spoken_feedback().IsEnterpriseIconVisible();
- }
- bool AccessibilityControllerImpl::IsSelectToSpeakSettingVisibleInTray() {
- return select_to_speak().IsVisibleInTray();
- }
- bool AccessibilityControllerImpl::IsEnterpriseIconVisibleForSelectToSpeak() {
- return select_to_speak().IsEnterpriseIconVisible();
- }
- void AccessibilityControllerImpl::RequestSelectToSpeakStateChange() {
- client_->RequestSelectToSpeakStateChange();
- }
- void AccessibilityControllerImpl::SetSelectToSpeakState(
- SelectToSpeakState state) {
- select_to_speak_state_ = state;
- // Forward the state change event to select_to_speak_event_handler_.
- // The extension may have requested that the handler enter SELECTING state.
- // Prepare to start capturing events from stylus, mouse or touch.
- if (select_to_speak_event_handler_) {
- select_to_speak_event_handler_->SetSelectToSpeakStateSelecting(
- state == SelectToSpeakState::kSelectToSpeakStateSelecting);
- }
- NotifyAccessibilityStatusChanged();
- }
- void AccessibilityControllerImpl::SetSelectToSpeakEventHandlerDelegate(
- SelectToSpeakEventHandlerDelegate* delegate) {
- select_to_speak_event_handler_delegate_ = delegate;
- MaybeCreateSelectToSpeakEventHandler();
- }
- SelectToSpeakState AccessibilityControllerImpl::GetSelectToSpeakState() const {
- return select_to_speak_state_;
- }
- void AccessibilityControllerImpl::ShowSelectToSpeakPanel(
- const gfx::Rect& anchor,
- bool is_paused,
- double speech_rate) {
- if (!select_to_speak_bubble_controller_) {
- select_to_speak_bubble_controller_ =
- std::make_unique<SelectToSpeakMenuBubbleController>();
- }
- select_to_speak_bubble_controller_->Show(anchor, is_paused, speech_rate);
- }
- void AccessibilityControllerImpl::HideSelectToSpeakPanel() {
- if (!select_to_speak_bubble_controller_) {
- return;
- }
- select_to_speak_bubble_controller_->Hide();
- }
- void AccessibilityControllerImpl::OnSelectToSpeakPanelAction(
- SelectToSpeakPanelAction action,
- double value) {
- if (!client_) {
- return;
- }
- client_->OnSelectToSpeakPanelAction(action, value);
- }
- bool AccessibilityControllerImpl::IsSwitchAccessRunning() const {
- return switch_access().enabled() || switch_access_disable_dialog_showing_;
- }
- bool AccessibilityControllerImpl::IsSwitchAccessSettingVisibleInTray() {
- // Switch Access cannot be enabled on the sign-in page because there is no way
- // to configure switches while the device is locked.
- if (!switch_access().enabled() &&
- Shell::Get()->session_controller()->login_status() ==
- ash::LoginStatus::NOT_LOGGED_IN) {
- return false;
- }
- return switch_access().IsVisibleInTray();
- }
- bool AccessibilityControllerImpl::IsEnterpriseIconVisibleForSwitchAccess() {
- return switch_access().IsEnterpriseIconVisible();
- }
- void AccessibilityControllerImpl::SetAccessibilityEventRewriter(
- AccessibilityEventRewriter* accessibility_event_rewriter) {
- accessibility_event_rewriter_ = accessibility_event_rewriter;
- }
- void AccessibilityControllerImpl::HideSwitchAccessBackButton() {
- if (IsSwitchAccessRunning())
- switch_access_bubble_controller_->HideBackButton();
- }
- void AccessibilityControllerImpl::HideSwitchAccessMenu() {
- if (IsSwitchAccessRunning())
- switch_access_bubble_controller_->HideMenuBubble();
- }
- void AccessibilityControllerImpl::ShowSwitchAccessBackButton(
- const gfx::Rect& anchor) {
- switch_access_bubble_controller_->ShowBackButton(anchor);
- }
- void AccessibilityControllerImpl::ShowSwitchAccessMenu(
- const gfx::Rect& anchor,
- std::vector<std::string> actions_to_show) {
- switch_access_bubble_controller_->ShowMenu(anchor, actions_to_show);
- }
- bool AccessibilityControllerImpl::IsPointScanEnabled() {
- return point_scan_controller_.get() &&
- point_scan_controller_->IsPointScanEnabled();
- }
- void AccessibilityControllerImpl::StartPointScan() {
- point_scan_controller_->Start();
- }
- void AccessibilityControllerImpl::SetA11yOverrideWindow(
- aura::Window* a11y_override_window) {
- if (client_)
- client_->SetA11yOverrideWindow(a11y_override_window);
- }
- void AccessibilityControllerImpl::StopPointScan() {
- if (point_scan_controller_)
- point_scan_controller_->HideAll();
- }
- void AccessibilityControllerImpl::SetPointScanSpeedDipsPerSecond(
- int point_scan_speed_dips_per_second) {
- if (point_scan_controller_) {
- point_scan_controller_->SetSpeedDipsPerSecond(
- point_scan_speed_dips_per_second);
- }
- }
- void AccessibilityControllerImpl::
- DisablePolicyRecommendationRestorerForTesting() {
- Shell::Get()->policy_recommendation_restorer()->DisableForTesting();
- }
- bool AccessibilityControllerImpl::IsStickyKeysSettingVisibleInTray() {
- return sticky_keys().IsVisibleInTray();
- }
- bool AccessibilityControllerImpl::IsEnterpriseIconVisibleForStickyKeys() {
- return sticky_keys().IsEnterpriseIconVisible();
- }
- bool AccessibilityControllerImpl::IsVirtualKeyboardSettingVisibleInTray() {
- return virtual_keyboard().IsVisibleInTray();
- }
- bool AccessibilityControllerImpl::IsEnterpriseIconVisibleForVirtualKeyboard() {
- return virtual_keyboard().IsEnterpriseIconVisible();
- }
- void AccessibilityControllerImpl::ShowFloatingMenuIfEnabled() {
- if (floating_menu().enabled() && !floating_menu_controller_) {
- floating_menu_controller_ =
- std::make_unique<FloatingAccessibilityController>(this);
- floating_menu_controller_->Show(GetFloatingMenuPosition());
- } else {
- always_show_floating_menu_when_enabled_ = true;
- }
- }
- FloatingAccessibilityController*
- AccessibilityControllerImpl::GetFloatingMenuController() {
- return floating_menu_controller_.get();
- }
- PointScanController* AccessibilityControllerImpl::GetPointScanController() {
- return point_scan_controller_.get();
- }
- void AccessibilityControllerImpl::SetTabletModeShelfNavigationButtonsEnabled(
- bool enabled) {
- if (!active_user_prefs_)
- return;
- active_user_prefs_->SetBoolean(
- prefs::kAccessibilityTabletModeShelfNavigationButtonsEnabled, enabled);
- active_user_prefs_->CommitPendingWrite();
- }
- void AccessibilityControllerImpl::TriggerAccessibilityAlert(
- AccessibilityAlert alert) {
- if (client_)
- client_->TriggerAccessibilityAlert(alert);
- }
- void AccessibilityControllerImpl::TriggerAccessibilityAlertWithMessage(
- const std::string& message) {
- if (client_)
- client_->TriggerAccessibilityAlertWithMessage(message);
- }
- void AccessibilityControllerImpl::PlayEarcon(Sound sound_key) {
- if (client_)
- client_->PlayEarcon(sound_key);
- }
- base::TimeDelta AccessibilityControllerImpl::PlayShutdownSound() {
- return client_ ? client_->PlayShutdownSound() : base::TimeDelta();
- }
- void AccessibilityControllerImpl::HandleAccessibilityGesture(
- ax::mojom::Gesture gesture,
- gfx::PointF location) {
- if (client_)
- client_->HandleAccessibilityGesture(gesture, location);
- }
- void AccessibilityControllerImpl::ToggleDictation() {
- // Do nothing if dictation is not enabled.
- if (!dictation().enabled())
- return;
- if (client_) {
- const bool is_active = client_->ToggleDictation();
- SetDictationActive(is_active);
- if (is_active)
- Shell::Get()->OnDictationStarted();
- else
- Shell::Get()->OnDictationEnded();
- }
- }
- void AccessibilityControllerImpl::SetDictationActive(bool is_active) {
- dictation_active_ = is_active;
- }
- void AccessibilityControllerImpl::ToggleDictationFromSource(
- DictationToggleSource source) {
- base::RecordAction(base::UserMetricsAction("Accel_Toggle_Dictation"));
- UMA_HISTOGRAM_ENUMERATION("Accessibility.CrosDictation.ToggleDictationMethod",
- source);
- dictation().SetEnabled(true);
- ToggleDictation();
- }
- void AccessibilityControllerImpl::ShowDictationLanguageUpgradedNudge(
- const std::string& dictation_locale,
- const std::string& application_locale) {
- dictation_nudge_controller_ = std::make_unique<DictationNudgeController>(
- dictation_locale, application_locale);
- dictation_nudge_controller_->ShowNudge();
- }
- void AccessibilityControllerImpl::SilenceSpokenFeedback() {
- if (client_)
- client_->SilenceSpokenFeedback();
- }
- void AccessibilityControllerImpl::OnTwoFingerTouchStart() {
- if (client_)
- client_->OnTwoFingerTouchStart();
- }
- void AccessibilityControllerImpl::OnTwoFingerTouchStop() {
- if (client_)
- client_->OnTwoFingerTouchStop();
- }
- bool AccessibilityControllerImpl::ShouldToggleSpokenFeedbackViaTouch() const {
- return client_ && client_->ShouldToggleSpokenFeedbackViaTouch();
- }
- void AccessibilityControllerImpl::PlaySpokenFeedbackToggleCountdown(
- int tick_count) {
- if (client_)
- client_->PlaySpokenFeedbackToggleCountdown(tick_count);
- }
- bool AccessibilityControllerImpl::IsEnterpriseIconVisibleInTrayMenu(
- const std::string& path) {
- return active_user_prefs_ &&
- active_user_prefs_->FindPreference(path)->IsManaged();
- }
- void AccessibilityControllerImpl::SetClient(
- AccessibilityControllerClient* client) {
- client_ = client;
- }
- void AccessibilityControllerImpl::SetDarkenScreen(bool darken) {
- if (darken && !scoped_backlights_forced_off_) {
- scoped_backlights_forced_off_ =
- Shell::Get()->backlights_forced_off_setter()->ForceBacklightsOff();
- } else if (!darken && scoped_backlights_forced_off_) {
- scoped_backlights_forced_off_.reset();
- }
- }
- void AccessibilityControllerImpl::BrailleDisplayStateChanged(bool connected) {
- A11yNotificationType type = A11yNotificationType::kNone;
- if (connected && spoken_feedback().enabled())
- type = A11yNotificationType::kBrailleDisplayConnected;
- else if (connected && !spoken_feedback().enabled())
- type = A11yNotificationType::kSpokenFeedbackBrailleEnabled;
- if (connected)
- SetSpokenFeedbackEnabled(true, A11Y_NOTIFICATION_NONE);
- NotifyAccessibilityStatusChanged();
- ShowAccessibilityNotification(
- A11yNotificationWrapper(type, std::vector<std::u16string>()));
- }
- void AccessibilityControllerImpl::SetFocusHighlightRect(
- const gfx::Rect& bounds_in_screen) {
- if (!accessibility_highlight_controller_)
- return;
- accessibility_highlight_controller_->SetFocusHighlightRect(bounds_in_screen);
- }
- void AccessibilityControllerImpl::SetCaretBounds(
- const gfx::Rect& bounds_in_screen) {
- if (!accessibility_highlight_controller_)
- return;
- accessibility_highlight_controller_->SetCaretBounds(bounds_in_screen);
- }
- void AccessibilityControllerImpl::SetAccessibilityPanelAlwaysVisible(
- bool always_visible) {
- GetLayoutManager()->SetAlwaysVisible(always_visible);
- }
- void AccessibilityControllerImpl::SetAccessibilityPanelBounds(
- const gfx::Rect& bounds,
- AccessibilityPanelState state) {
- GetLayoutManager()->SetPanelBounds(bounds, state);
- }
- void AccessibilityControllerImpl::OnSigninScreenPrefServiceInitialized(
- PrefService* prefs) {
- // Make |kA11yPrefsForRecommendedValueOnSignin| observing recommended values
- // on signin screen. See PolicyRecommendationRestorer.
- PolicyRecommendationRestorer* policy_recommendation_restorer =
- Shell::Get()->policy_recommendation_restorer();
- for (auto* const pref_name : kA11yPrefsForRecommendedValueOnSignin)
- policy_recommendation_restorer->ObservePref(pref_name);
- // Observe user settings. This must happen after PolicyRecommendationRestorer.
- ObservePrefs(prefs);
- }
- void AccessibilityControllerImpl::OnActiveUserPrefServiceChanged(
- PrefService* prefs) {
- // This is guaranteed to be received after
- // OnSigninScreenPrefServiceInitialized() so only copy the signin prefs if
- // needed here.
- CopySigninPrefsIfNeeded(active_user_prefs_, prefs);
- ObservePrefs(prefs);
- }
- void AccessibilityControllerImpl::OnSessionStateChanged(
- session_manager::SessionState state) {
- // Everything behind the lock screen is in
- // kShellWindowId_NonLockScreenContainersContainer. If the session state is
- // changed to block the user session due to the lock screen or similar,
- // everything in that window should be made invisible for accessibility.
- // This keeps a11y features from being able to access parts of the tree
- // that are visibly hidden behind the lock screen.
- aura::Window* container =
- Shell::GetContainer(Shell::GetPrimaryRootWindow(),
- kShellWindowId_NonLockScreenContainersContainer);
- container->SetProperty(
- ui::kAXConsiderInvisibleAndIgnoreChildren,
- Shell::Get()->session_controller()->IsUserSessionBlocked());
- }
- AccessibilityEventRewriter*
- AccessibilityControllerImpl::GetAccessibilityEventRewriterForTest() {
- return accessibility_event_rewriter_;
- }
- void AccessibilityControllerImpl::
- DisableSwitchAccessDisableConfirmationDialogTesting() {
- no_switch_access_disable_confirmation_dialog_for_testing_ = true;
- }
- void AccessibilityControllerImpl::OnTabletModeStarted() {
- if (spoken_feedback().enabled())
- ShowAccessibilityNotification(
- A11yNotificationWrapper(A11yNotificationType::kSpokenFeedbackEnabled,
- std::vector<std::u16string>()));
- }
- void AccessibilityControllerImpl::OnTabletModeEnded() {
- if (spoken_feedback().enabled())
- ShowAccessibilityNotification(
- A11yNotificationWrapper(A11yNotificationType::kSpokenFeedbackEnabled,
- std::vector<std::u16string>()));
- }
- void AccessibilityControllerImpl::ObservePrefs(PrefService* prefs) {
- DCHECK(prefs);
- active_user_prefs_ = prefs;
- // Watch for pref updates from webui settings and policy.
- pref_change_registrar_ = std::make_unique<PrefChangeRegistrar>();
- pref_change_registrar_->Init(prefs);
- // It is safe to use base::Unreatined since we own pref_change_registrar.
- for (int feature_id = 0; feature_id < FeatureType::kFeatureCount;
- feature_id++) {
- Feature* feature = features_[feature_id].get();
- DCHECK(feature);
- pref_change_registrar_->Add(
- feature->pref_name(),
- base::BindRepeating(
- &AccessibilityControllerImpl::Feature::UpdateFromPref,
- base::Unretained(feature)));
- feature->UpdateFromPref();
- }
- pref_change_registrar_->Add(
- prefs::kAccessibilityAutoclickDelayMs,
- base::BindRepeating(
- &AccessibilityControllerImpl::UpdateAutoclickDelayFromPref,
- base::Unretained(this)));
- pref_change_registrar_->Add(
- prefs::kAccessibilityAutoclickEventType,
- base::BindRepeating(
- &AccessibilityControllerImpl::UpdateAutoclickEventTypeFromPref,
- base::Unretained(this)));
- pref_change_registrar_->Add(
- prefs::kAccessibilityAutoclickRevertToLeftClick,
- base::BindRepeating(&AccessibilityControllerImpl::
- UpdateAutoclickRevertToLeftClickFromPref,
- base::Unretained(this)));
- pref_change_registrar_->Add(
- prefs::kAccessibilityAutoclickStabilizePosition,
- base::BindRepeating(&AccessibilityControllerImpl::
- UpdateAutoclickStabilizePositionFromPref,
- base::Unretained(this)));
- pref_change_registrar_->Add(
- prefs::kAccessibilityAutoclickMovementThreshold,
- base::BindRepeating(&AccessibilityControllerImpl::
- UpdateAutoclickMovementThresholdFromPref,
- base::Unretained(this)));
- pref_change_registrar_->Add(
- prefs::kAccessibilityAutoclickMenuPosition,
- base::BindRepeating(
- &AccessibilityControllerImpl::UpdateAutoclickMenuPositionFromPref,
- base::Unretained(this)));
- pref_change_registrar_->Add(
- prefs::kAccessibilityFloatingMenuPosition,
- base::BindRepeating(
- &AccessibilityControllerImpl::UpdateFloatingMenuPositionFromPref,
- base::Unretained(this)));
- pref_change_registrar_->Add(
- prefs::kAccessibilityLargeCursorDipSize,
- base::BindRepeating(
- &AccessibilityControllerImpl::UpdateLargeCursorFromPref,
- base::Unretained(this)));
- pref_change_registrar_->Add(
- prefs::kAccessibilityShortcutsEnabled,
- base::BindRepeating(
- &AccessibilityControllerImpl::UpdateShortcutsEnabledFromPref,
- base::Unretained(this)));
- pref_change_registrar_->Add(
- prefs::kAccessibilitySwitchAccessSelectDeviceKeyCodes,
- base::BindRepeating(
- &AccessibilityControllerImpl::UpdateSwitchAccessKeyCodesFromPref,
- base::Unretained(this), SwitchAccessCommand::kSelect));
- pref_change_registrar_->Add(
- prefs::kAccessibilitySwitchAccessNextDeviceKeyCodes,
- base::BindRepeating(
- &AccessibilityControllerImpl::UpdateSwitchAccessKeyCodesFromPref,
- base::Unretained(this), SwitchAccessCommand::kNext));
- pref_change_registrar_->Add(
- prefs::kAccessibilitySwitchAccessPreviousDeviceKeyCodes,
- base::BindRepeating(
- &AccessibilityControllerImpl::UpdateSwitchAccessKeyCodesFromPref,
- base::Unretained(this), SwitchAccessCommand::kPrevious));
- pref_change_registrar_->Add(
- prefs::kAccessibilitySwitchAccessAutoScanEnabled,
- base::BindRepeating(&AccessibilityControllerImpl::
- UpdateSwitchAccessAutoScanEnabledFromPref,
- base::Unretained(this)));
- pref_change_registrar_->Add(
- prefs::kAccessibilitySwitchAccessAutoScanSpeedMs,
- base::BindRepeating(
- &AccessibilityControllerImpl::UpdateSwitchAccessAutoScanSpeedFromPref,
- base::Unretained(this)));
- pref_change_registrar_->Add(
- prefs::kAccessibilitySwitchAccessAutoScanKeyboardSpeedMs,
- base::BindRepeating(&AccessibilityControllerImpl::
- UpdateSwitchAccessAutoScanKeyboardSpeedFromPref,
- base::Unretained(this)));
- pref_change_registrar_->Add(
- prefs::kAccessibilitySwitchAccessPointScanSpeedDipsPerSecond,
- base::BindRepeating(&AccessibilityControllerImpl::
- UpdateSwitchAccessPointScanSpeedFromPref,
- base::Unretained(this)));
- pref_change_registrar_->Add(
- prefs::kAccessibilityTabletModeShelfNavigationButtonsEnabled,
- base::BindRepeating(&AccessibilityControllerImpl::
- UpdateTabletModeShelfNavigationButtonsFromPref,
- base::Unretained(this)));
- pref_change_registrar_->Add(
- prefs::kAccessibilityCursorColor,
- base::BindRepeating(
- &AccessibilityControllerImpl::UpdateCursorColorFromPrefs,
- base::Unretained(this)));
- // Load current state.
- for (int feature_id = 0; feature_id < FeatureType::kFeatureCount;
- feature_id++) {
- features_[feature_id]->UpdateFromPref();
- }
- UpdateAutoclickDelayFromPref();
- UpdateAutoclickEventTypeFromPref();
- UpdateAutoclickRevertToLeftClickFromPref();
- UpdateAutoclickStabilizePositionFromPref();
- UpdateAutoclickMovementThresholdFromPref();
- UpdateAutoclickMenuPositionFromPref();
- UpdateFloatingMenuPositionFromPref();
- UpdateLargeCursorFromPref();
- UpdateCursorColorFromPrefs();
- UpdateShortcutsEnabledFromPref();
- UpdateTabletModeShelfNavigationButtonsFromPref();
- }
- void AccessibilityControllerImpl::UpdateAutoclickDelayFromPref() {
- DCHECK(active_user_prefs_);
- base::TimeDelta autoclick_delay = base::Milliseconds(int64_t{
- active_user_prefs_->GetInteger(prefs::kAccessibilityAutoclickDelayMs)});
- if (autoclick_delay_ == autoclick_delay)
- return;
- autoclick_delay_ = autoclick_delay;
- Shell::Get()->autoclick_controller()->SetAutoclickDelay(autoclick_delay_);
- }
- void AccessibilityControllerImpl::UpdateAutoclickEventTypeFromPref() {
- Shell::Get()->autoclick_controller()->SetAutoclickEventType(
- GetAutoclickEventType());
- }
- void AccessibilityControllerImpl::SetAutoclickEventType(
- AutoclickEventType event_type) {
- if (!active_user_prefs_)
- return;
- active_user_prefs_->SetInteger(prefs::kAccessibilityAutoclickEventType,
- static_cast<int>(event_type));
- active_user_prefs_->CommitPendingWrite();
- Shell::Get()->autoclick_controller()->SetAutoclickEventType(event_type);
- }
- AutoclickEventType AccessibilityControllerImpl::GetAutoclickEventType() {
- DCHECK(active_user_prefs_);
- return static_cast<AutoclickEventType>(
- active_user_prefs_->GetInteger(prefs::kAccessibilityAutoclickEventType));
- }
- void AccessibilityControllerImpl::UpdateAutoclickRevertToLeftClickFromPref() {
- DCHECK(active_user_prefs_);
- bool revert_to_left_click = active_user_prefs_->GetBoolean(
- prefs::kAccessibilityAutoclickRevertToLeftClick);
- Shell::Get()->autoclick_controller()->set_revert_to_left_click(
- revert_to_left_click);
- }
- void AccessibilityControllerImpl::UpdateAutoclickStabilizePositionFromPref() {
- DCHECK(active_user_prefs_);
- bool stabilize_position = active_user_prefs_->GetBoolean(
- prefs::kAccessibilityAutoclickStabilizePosition);
- Shell::Get()->autoclick_controller()->set_stabilize_click_position(
- stabilize_position);
- }
- void AccessibilityControllerImpl::UpdateAutoclickMovementThresholdFromPref() {
- DCHECK(active_user_prefs_);
- int movement_threshold = active_user_prefs_->GetInteger(
- prefs::kAccessibilityAutoclickMovementThreshold);
- Shell::Get()->autoclick_controller()->SetMovementThreshold(
- movement_threshold);
- }
- void AccessibilityControllerImpl::UpdateAutoclickMenuPositionFromPref() {
- Shell::Get()->autoclick_controller()->SetMenuPosition(
- GetAutoclickMenuPosition());
- }
- void AccessibilityControllerImpl::SetAutoclickMenuPosition(
- FloatingMenuPosition position) {
- if (!active_user_prefs_)
- return;
- active_user_prefs_->SetInteger(prefs::kAccessibilityAutoclickMenuPosition,
- static_cast<int>(position));
- active_user_prefs_->CommitPendingWrite();
- Shell::Get()->autoclick_controller()->SetMenuPosition(position);
- }
- FloatingMenuPosition AccessibilityControllerImpl::GetAutoclickMenuPosition() {
- DCHECK(active_user_prefs_);
- return static_cast<FloatingMenuPosition>(active_user_prefs_->GetInteger(
- prefs::kAccessibilityAutoclickMenuPosition));
- }
- void AccessibilityControllerImpl::RequestAutoclickScrollableBoundsForPoint(
- gfx::Point& point_in_screen) {
- if (client_)
- client_->RequestAutoclickScrollableBoundsForPoint(point_in_screen);
- }
- void AccessibilityControllerImpl::MagnifierBoundsChanged(
- const gfx::Rect& bounds_in_screen) {
- if (client_)
- client_->MagnifierBoundsChanged(bounds_in_screen);
- }
- void AccessibilityControllerImpl::UpdateFloatingPanelBoundsIfNeeded() {
- Shell* shell = Shell::Get();
- if (shell->accessibility_controller()->autoclick().enabled())
- shell->autoclick_controller()->UpdateAutoclickMenuBoundsIfNeeded();
- if (shell->accessibility_controller()->sticky_keys().enabled())
- shell->sticky_keys_controller()->UpdateStickyKeysOverlayBoundsIfNeeded();
- }
- void AccessibilityControllerImpl::UpdateAutoclickMenuBoundsIfNeeded() {
- Shell::Get()->autoclick_controller()->UpdateAutoclickMenuBoundsIfNeeded();
- }
- void AccessibilityControllerImpl::HandleAutoclickScrollableBoundsFound(
- gfx::Rect& bounds_in_screen) {
- Shell::Get()->autoclick_controller()->HandleAutoclickScrollableBoundsFound(
- bounds_in_screen);
- }
- void AccessibilityControllerImpl::SetFloatingMenuPosition(
- FloatingMenuPosition position) {
- if (!active_user_prefs_)
- return;
- active_user_prefs_->SetInteger(prefs::kAccessibilityFloatingMenuPosition,
- static_cast<int>(position));
- active_user_prefs_->CommitPendingWrite();
- }
- void AccessibilityControllerImpl::UpdateFloatingMenuPositionFromPref() {
- if (floating_menu_controller_)
- floating_menu_controller_->SetMenuPosition(GetFloatingMenuPosition());
- }
- FloatingMenuPosition AccessibilityControllerImpl::GetFloatingMenuPosition() {
- DCHECK(active_user_prefs_);
- return static_cast<FloatingMenuPosition>(active_user_prefs_->GetInteger(
- prefs::kAccessibilityFloatingMenuPosition));
- }
- void AccessibilityControllerImpl::UpdateLargeCursorFromPref() {
- DCHECK(active_user_prefs_);
- const bool enabled =
- active_user_prefs_->GetBoolean(prefs::kAccessibilityLargeCursorEnabled);
- // Reset large cursor size to the default size when large cursor is disabled.
- if (!enabled)
- active_user_prefs_->ClearPref(prefs::kAccessibilityLargeCursorDipSize);
- const int size =
- active_user_prefs_->GetInteger(prefs::kAccessibilityLargeCursorDipSize);
- if (large_cursor_size_in_dip_ == size)
- return;
- large_cursor_size_in_dip_ = size;
- NotifyAccessibilityStatusChanged();
- Shell* shell = Shell::Get();
- shell->cursor_manager()->SetCursorSize(large_cursor().enabled()
- ? ui::CursorSize::kLarge
- : ui::CursorSize::kNormal);
- shell->SetLargeCursorSizeInDip(large_cursor_size_in_dip_);
- shell->UpdateCursorCompositingEnabled();
- }
- void AccessibilityControllerImpl::UpdateCursorColorFromPrefs() {
- DCHECK(active_user_prefs_);
- const bool enabled =
- active_user_prefs_->GetBoolean(prefs::kAccessibilityCursorColorEnabled);
- Shell* shell = Shell::Get();
- shell->SetCursorColor(
- enabled ? active_user_prefs_->GetInteger(prefs::kAccessibilityCursorColor)
- : kDefaultCursorColor);
- NotifyAccessibilityStatusChanged();
- shell->UpdateCursorCompositingEnabled();
- }
- void AccessibilityControllerImpl::UpdateAccessibilityHighlightingFromPrefs() {
- if (!caret_highlight().enabled() && !cursor_highlight().enabled() &&
- !focus_highlight().enabled()) {
- accessibility_highlight_controller_.reset();
- return;
- }
- if (!accessibility_highlight_controller_) {
- accessibility_highlight_controller_ =
- std::make_unique<AccessibilityHighlightController>();
- }
- accessibility_highlight_controller_->HighlightCaret(
- caret_highlight().enabled());
- accessibility_highlight_controller_->HighlightCursor(
- cursor_highlight().enabled());
- accessibility_highlight_controller_->HighlightFocus(
- focus_highlight().enabled());
- }
- void AccessibilityControllerImpl::MaybeCreateSelectToSpeakEventHandler() {
- // Construct the handler as needed when Select-to-Speak is enabled and the
- // delegate is set. Otherwise, destroy the handler when Select-to-Speak is
- // disabled or the delegate has been destroyed.
- if (!select_to_speak().enabled() ||
- !select_to_speak_event_handler_delegate_) {
- select_to_speak_event_handler_.reset();
- return;
- }
- if (select_to_speak_event_handler_)
- return;
- select_to_speak_event_handler_ = std::make_unique<SelectToSpeakEventHandler>(
- select_to_speak_event_handler_delegate_);
- }
- void AccessibilityControllerImpl::UpdateSwitchAccessKeyCodesFromPref(
- SwitchAccessCommand command) {
- if (!active_user_prefs_)
- return;
- SyncSwitchAccessPrefsToSignInProfile();
- if (!accessibility_event_rewriter_)
- return;
- std::string pref_key = PrefKeyForSwitchAccessCommand(command);
- const base::Value::Dict& key_codes_pref =
- active_user_prefs_->GetValueDict(pref_key);
- std::map<int, std::set<std::string>> key_codes;
- for (const auto v : key_codes_pref) {
- int key_code;
- if (!base::StringToInt(v.first, &key_code)) {
- NOTREACHED();
- return;
- }
- key_codes[key_code] = std::set<std::string>();
- for (const base::Value& device_type : v.second.GetList())
- key_codes[key_code].insert(device_type.GetString());
- DCHECK(!key_codes[key_code].empty());
- }
- std::string uma_name = UmaNameForSwitchAccessCommand(command);
- if (key_codes.size() == 0) {
- base::UmaHistogramEnumeration(uma_name, SwitchAccessKeyCode::kNone);
- }
- for (const auto& key_code : key_codes) {
- base::UmaHistogramEnumeration(
- uma_name, static_cast<SwitchAccessKeyCode>(key_code.first));
- }
- accessibility_event_rewriter_->SetKeyCodesForSwitchAccessCommand(key_codes,
- command);
- }
- void AccessibilityControllerImpl::UpdateSwitchAccessAutoScanEnabledFromPref() {
- DCHECK(active_user_prefs_);
- const bool enabled = active_user_prefs_->GetBoolean(
- prefs::kAccessibilitySwitchAccessAutoScanEnabled);
- base::UmaHistogramBoolean("Accessibility.CrosSwitchAccess.AutoScan", enabled);
- SyncSwitchAccessPrefsToSignInProfile();
- }
- void AccessibilityControllerImpl::UpdateSwitchAccessAutoScanSpeedFromPref() {
- DCHECK(active_user_prefs_);
- const int speed_ms = active_user_prefs_->GetInteger(
- prefs::kAccessibilitySwitchAccessAutoScanSpeedMs);
- base::UmaHistogramCustomCounts(
- "Accessibility.CrosSwitchAccess.AutoScan.SpeedMs", speed_ms, 1 /* min */,
- 10000 /* max */, 100 /* buckets */);
- SyncSwitchAccessPrefsToSignInProfile();
- }
- void AccessibilityControllerImpl::
- UpdateSwitchAccessAutoScanKeyboardSpeedFromPref() {
- DCHECK(active_user_prefs_);
- const int speed_ms = active_user_prefs_->GetInteger(
- prefs::kAccessibilitySwitchAccessAutoScanKeyboardSpeedMs);
- base::UmaHistogramCustomCounts(
- "Accessibility.CrosSwitchAccess.AutoScan.KeyboardSpeedMs", speed_ms,
- 1 /* min */, 10000 /* max */, 100 /* buckets */);
- SyncSwitchAccessPrefsToSignInProfile();
- }
- void AccessibilityControllerImpl::UpdateSwitchAccessPointScanSpeedFromPref() {
- // TODO(accessibility): Log histogram for point scan speed
- DCHECK(active_user_prefs_);
- const int point_scan_speed_dips_per_second = active_user_prefs_->GetInteger(
- prefs::kAccessibilitySwitchAccessPointScanSpeedDipsPerSecond);
- SetPointScanSpeedDipsPerSecond(point_scan_speed_dips_per_second);
- SyncSwitchAccessPrefsToSignInProfile();
- }
- void AccessibilityControllerImpl::SwitchAccessDisableDialogClosed(
- bool disable_dialog_accepted) {
- switch_access_disable_dialog_showing_ = false;
- // Always deactivate switch access. Turning switch access off ensures it is
- // re-activated correctly.
- // The pref was already disabled, but we left switch access on so the user
- // could interact with the dialog.
- DeactivateSwitchAccess();
- if (disable_dialog_accepted) {
- RemoveAccessibilityNotification();
- NotifyAccessibilityStatusChanged();
- SyncSwitchAccessPrefsToSignInProfile();
- } else {
- // Reset the preference (which was already set to false). Doing so turns
- // switch access back on.
- skip_switch_access_notification_ = true;
- switch_access().SetEnabled(true);
- }
- }
- void AccessibilityControllerImpl::UpdateKeyCodesAfterSwitchAccessEnabled() {
- UpdateSwitchAccessKeyCodesFromPref(SwitchAccessCommand::kSelect);
- UpdateSwitchAccessKeyCodesFromPref(SwitchAccessCommand::kNext);
- UpdateSwitchAccessKeyCodesFromPref(SwitchAccessCommand::kPrevious);
- }
- void AccessibilityControllerImpl::ActivateSwitchAccess() {
- switch_access_bubble_controller_ =
- std::make_unique<SwitchAccessMenuBubbleController>();
- point_scan_controller_ = std::make_unique<PointScanController>();
- UpdateKeyCodesAfterSwitchAccessEnabled();
- UpdateSwitchAccessPointScanSpeedFromPref();
- if (skip_switch_access_notification_) {
- skip_switch_access_notification_ = false;
- return;
- }
- ShowAccessibilityNotification(
- A11yNotificationWrapper(A11yNotificationType::kSwitchAccessEnabled,
- std::vector<std::u16string>()));
- }
- void AccessibilityControllerImpl::DeactivateSwitchAccess() {
- if (client_)
- client_->OnSwitchAccessDisabled();
- point_scan_controller_.reset();
- switch_access_bubble_controller_.reset();
- }
- void AccessibilityControllerImpl::SyncSwitchAccessPrefsToSignInProfile() {
- if (!active_user_prefs_ || IsSigninPrefService(active_user_prefs_))
- return;
- PrefService* signin_prefs =
- Shell::Get()->session_controller()->GetSigninScreenPrefService();
- DCHECK(signin_prefs);
- for (const auto* pref_path : kSwitchAccessPrefsCopiedToSignin) {
- const PrefService::Preference* pref =
- active_user_prefs_->FindPreference(pref_path);
- // Ignore if the pref has not been set by the user.
- if (!pref || !pref->IsUserControlled())
- continue;
- // Copy the pref value to the signin profile.
- const base::Value* value = pref->GetValue();
- signin_prefs->Set(pref_path, *value);
- }
- }
- void AccessibilityControllerImpl::UpdateShortcutsEnabledFromPref() {
- DCHECK(active_user_prefs_);
- const bool enabled =
- active_user_prefs_->GetBoolean(prefs::kAccessibilityShortcutsEnabled);
- if (shortcuts_enabled_ == enabled)
- return;
- shortcuts_enabled_ = enabled;
- NotifyAccessibilityStatusChanged();
- }
- void AccessibilityControllerImpl::
- UpdateTabletModeShelfNavigationButtonsFromPref() {
- DCHECK(active_user_prefs_);
- const bool enabled = active_user_prefs_->GetBoolean(
- prefs::kAccessibilityTabletModeShelfNavigationButtonsEnabled);
- if (tablet_mode_shelf_navigation_buttons_enabled_ == enabled)
- return;
- tablet_mode_shelf_navigation_buttons_enabled_ = enabled;
- NotifyAccessibilityStatusChanged();
- }
- std::u16string AccessibilityControllerImpl::GetBatteryDescription() const {
- // Pass battery status as string to callback function.
- return PowerStatus::Get()->GetAccessibleNameString(
- /*full_description=*/true);
- }
- void AccessibilityControllerImpl::SetVirtualKeyboardVisible(bool is_visible) {
- if (is_visible)
- Shell::Get()->keyboard_controller()->ShowKeyboard();
- else
- Shell::Get()->keyboard_controller()->HideKeyboard(HideReason::kUser);
- }
- void AccessibilityControllerImpl::PerformAcceleratorAction(
- AcceleratorAction accelerator_action) {
- AcceleratorController::Get()->PerformActionIfEnabled(accelerator_action,
- /* accelerator = */ {});
- }
- void AccessibilityControllerImpl::NotifyAccessibilityStatusChanged() {
- for (auto& observer : observers_)
- observer.OnAccessibilityStatusChanged();
- }
- bool AccessibilityControllerImpl::IsAccessibilityFeatureVisibleInTrayMenu(
- const std::string& path) {
- if (!active_user_prefs_)
- return true;
- if (active_user_prefs_->FindPreference(path)->IsManaged() &&
- !active_user_prefs_->GetBoolean(path)) {
- return false;
- }
- return true;
- }
- void AccessibilityControllerImpl::SuspendSwitchAccessKeyHandling(bool suspend) {
- accessibility_event_rewriter_->set_suspend_switch_access_key_handling(
- suspend);
- }
- void AccessibilityControllerImpl::EnableChromeVoxVolumeSlideGesture() {
- enable_chromevox_volume_slide_gesture_ = true;
- }
- void AccessibilityControllerImpl::ShowConfirmationDialog(
- const std::u16string& title,
- const std::u16string& description,
- base::OnceClosure on_accept_callback,
- base::OnceClosure on_cancel_callback,
- base::OnceClosure on_close_callback) {
- if (confirmation_dialog_) {
- // If a dialog is already being shown we do not show a new one.
- // Instead, run the on_close_callback on the new dialog to indicate
- // it was closed without the user taking any action.
- // This is consistent with AcceleratorController.
- std::move(on_close_callback).Run();
- return;
- }
- auto* dialog = new AccessibilityConfirmationDialog(
- title, description, std::move(on_accept_callback),
- std::move(on_cancel_callback), std::move(on_close_callback));
- // Save the dialog so it doesn't go out of scope before it is
- // used and closed.
- confirmation_dialog_ = dialog->GetWeakPtr();
- }
- void AccessibilityControllerImpl::
- UpdateDictationButtonOnSpeechRecognitionDownloadChanged(
- int download_progress) {
- dictation_soda_download_progress_ = download_progress;
- Shell::Get()
- ->GetPrimaryRootWindowController()
- ->GetStatusAreaWidget()
- ->dictation_button_tray()
- ->UpdateOnSpeechRecognitionDownloadChanged(download_progress);
- }
- void AccessibilityControllerImpl::
- ShowSpeechRecognitionDownloadNotificationForDictation(
- bool succeeded,
- const std::u16string& display_language) {
- A11yNotificationType type =
- succeeded ? A11yNotificationType::kSpeechRecognitionFilesDownloaded
- : A11yNotificationType::kSpeechRecognitionFilesFailed;
- ShowAccessibilityNotification(A11yNotificationWrapper(
- type, std::vector<std::u16string>{display_language}));
- }
- AccessibilityControllerImpl::A11yNotificationWrapper::
- A11yNotificationWrapper() = default;
- AccessibilityControllerImpl::A11yNotificationWrapper::A11yNotificationWrapper(
- A11yNotificationType type_in,
- std::vector<std::u16string> replacements_in)
- : type(type_in), replacements(replacements_in) {}
- AccessibilityControllerImpl::A11yNotificationWrapper::
- ~A11yNotificationWrapper() = default;
- AccessibilityControllerImpl::A11yNotificationWrapper::A11yNotificationWrapper(
- const A11yNotificationWrapper&) = default;
- void AccessibilityControllerImpl::UpdateFeatureFromPref(FeatureType feature) {
- bool enabled = features_[feature]->enabled();
- bool is_managed =
- active_user_prefs_->IsManagedPreference(features_[feature]->pref_name());
- switch (feature) {
- case FeatureType::kAutoclick:
- Shell::Get()->autoclick_controller()->SetEnabled(
- enabled, !is_managed /* show confirmation dialog */);
- break;
- case FeatureType::kCaretHighlight:
- UpdateAccessibilityHighlightingFromPrefs();
- break;
- case FeatureType::kCursorHighlight:
- UpdateAccessibilityHighlightingFromPrefs();
- break;
- case FeatureType::kDictation:
- if (enabled) {
- if (!dictation_bubble_controller_) {
- dictation_bubble_controller_ =
- std::make_unique<DictationBubbleController>();
- }
- } else {
- dictation_nudge_controller_.reset();
- dictation_bubble_controller_.reset();
- }
- break;
- case FeatureType::kFloatingMenu:
- if (enabled && always_show_floating_menu_when_enabled_)
- ShowFloatingMenuIfEnabled();
- else
- floating_menu_controller_.reset();
- break;
- case FeatureType::kFocusHighlight:
- UpdateAccessibilityHighlightingFromPrefs();
- break;
- case FeatureType::kFullscreenMagnifier:
- break;
- case FeatureType::kDockedMagnifier:
- break;
- case FeatureType::kHighContrast:
- Shell::Get()->high_contrast_controller()->SetEnabled(enabled);
- Shell::Get()->UpdateCursorCompositingEnabled();
- break;
- case FeatureType::kLargeCursor:
- if (!enabled)
- active_user_prefs_->ClearPref(prefs::kAccessibilityLargeCursorDipSize);
- Shell::Get()->cursor_manager()->SetCursorSize(
- large_cursor().enabled() ? ui::CursorSize::kLarge
- : ui::CursorSize::kNormal);
- Shell::Get()->SetLargeCursorSizeInDip(large_cursor_size_in_dip_);
- Shell::Get()->UpdateCursorCompositingEnabled();
- break;
- case FeatureType::kLiveCaption:
- live_caption().SetEnabled(enabled);
- break;
- case FeatureType::kMonoAudio:
- CrasAudioHandler::Get()->SetOutputMonoEnabled(enabled);
- break;
- case FeatureType::kSpokenFeedback:
- message_center::MessageCenter::Get()->SetSpokenFeedbackEnabled(enabled);
- // TODO(warx): ChromeVox loading/unloading requires browser process
- // started, thus it is still handled on Chrome side.
- // ChromeVox focus highlighting overrides the other focus highlighting.
- focus_highlight().UpdateFromPref();
- break;
- case FeatureType::kSelectToSpeak:
- select_to_speak_state_ = SelectToSpeakState::kSelectToSpeakStateInactive;
- if (enabled) {
- MaybeCreateSelectToSpeakEventHandler();
- } else {
- select_to_speak_event_handler_.reset();
- HideSelectToSpeakPanel();
- select_to_speak_bubble_controller_.reset();
- }
- break;
- case FeatureType::kStickyKeys:
- Shell::Get()->sticky_keys_controller()->Enable(enabled);
- break;
- case FeatureType::kSwitchAccess:
- if (!enabled) {
- if (no_switch_access_disable_confirmation_dialog_for_testing_) {
- SwitchAccessDisableDialogClosed(true);
- } else {
- // Show a dialog before disabling Switch Access.
- new AccessibilityFeatureDisableDialog(
- IDS_ASH_SWITCH_ACCESS_DISABLE_CONFIRMATION_TEXT,
- base::BindOnce(
- &AccessibilityControllerImpl::SwitchAccessDisableDialogClosed,
- weak_ptr_factory_.GetWeakPtr(), true),
- base::BindOnce(
- &AccessibilityControllerImpl::SwitchAccessDisableDialogClosed,
- weak_ptr_factory_.GetWeakPtr(), false));
- switch_access_disable_dialog_showing_ = true;
- }
- // Return early. We will call NotifyAccessibilityStatusChanged() if the
- // user accepts the dialog.
- return;
- } else {
- ActivateSwitchAccess();
- }
- SyncSwitchAccessPrefsToSignInProfile();
- break;
- case FeatureType::kVirtualKeyboard:
- keyboard::SetAccessibilityKeyboardEnabled(enabled);
- break;
- case FeatureType::kCursorColor:
- UpdateCursorColorFromPrefs();
- break;
- case FeatureType::kFeatureCount:
- case FeatureType::kNoConflictingFeature:
- NOTREACHED();
- }
- NotifyAccessibilityStatusChanged();
- }
- void AccessibilityControllerImpl::UpdateDictationBubble(
- bool visible,
- DictationBubbleIconType icon,
- const absl::optional<std::u16string>& text,
- const absl::optional<std::vector<DictationBubbleHintType>>& hints) {
- DCHECK(dictation().enabled());
- DCHECK(dictation_bubble_controller_);
- dictation_bubble_controller_->UpdateBubble(visible, icon, text, hints);
- }
- DictationBubbleController*
- AccessibilityControllerImpl::GetDictationBubbleControllerForTest() {
- if (!dictation_bubble_controller_) {
- dictation_bubble_controller_ =
- std::make_unique<DictationBubbleController>();
- }
- return dictation_bubble_controller_.get();
- }
- } // namespace ash
|