• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.settings.accessibility;
18 
19 import static android.os.Vibrator.VibrationIntensity;
20 
21 import static com.android.settingslib.TwoTargetPreference.ICON_SIZE_MEDIUM;
22 
23 import android.accessibilityservice.AccessibilityServiceInfo;
24 import android.app.admin.DevicePolicyManager;
25 import android.app.settings.SettingsEnums;
26 import android.content.ComponentName;
27 import android.content.ContentResolver;
28 import android.content.Context;
29 import android.content.pm.ResolveInfo;
30 import android.content.pm.ServiceInfo;
31 import android.content.res.Resources;
32 import android.graphics.drawable.Drawable;
33 import android.hardware.display.ColorDisplayManager;
34 import android.net.Uri;
35 import android.os.Bundle;
36 import android.os.Handler;
37 import android.os.UserHandle;
38 import android.os.Vibrator;
39 import android.provider.DeviceConfig;
40 import android.provider.SearchIndexableResource;
41 import android.provider.Settings;
42 import android.text.TextUtils;
43 import android.util.ArrayMap;
44 import android.view.KeyCharacterMap;
45 import android.view.KeyEvent;
46 import android.view.accessibility.AccessibilityManager;
47 
48 import androidx.annotation.VisibleForTesting;
49 import androidx.core.content.ContextCompat;
50 import androidx.preference.ListPreference;
51 import androidx.preference.Preference;
52 import androidx.preference.PreferenceCategory;
53 import androidx.preference.PreferenceScreen;
54 import androidx.preference.SwitchPreference;
55 
56 import com.android.internal.accessibility.AccessibilityShortcutController;
57 import com.android.internal.content.PackageMonitor;
58 import com.android.internal.view.RotationPolicy;
59 import com.android.internal.view.RotationPolicy.RotationPolicyListener;
60 import com.android.settings.R;
61 import com.android.settings.SettingsPreferenceFragment;
62 import com.android.settings.Utils;
63 import com.android.settings.display.DarkUIPreferenceController;
64 import com.android.settings.display.ToggleFontSizePreferenceFragment;
65 import com.android.settings.search.BaseSearchIndexProvider;
66 import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
67 import com.android.settingslib.RestrictedLockUtilsInternal;
68 import com.android.settingslib.RestrictedPreference;
69 import com.android.settingslib.accessibility.AccessibilityUtils;
70 import com.android.settingslib.search.SearchIndexable;
71 
72 import com.google.common.primitives.Ints;
73 
74 import java.util.ArrayList;
75 import java.util.Collection;
76 import java.util.HashMap;
77 import java.util.List;
78 import java.util.Map;
79 import java.util.Set;
80 
81 /**
82  * Activity with the accessibility settings.
83  */
84 @SearchIndexable
85 public class AccessibilitySettings extends SettingsPreferenceFragment implements
86         Preference.OnPreferenceChangeListener {
87 
88     // Index of the first preference in a preference category.
89     private static final int FIRST_PREFERENCE_IN_CATEGORY_INDEX = -1;
90 
91     // Preference categories
92     private static final String CATEGORY_SCREEN_READER = "screen_reader_category";
93     private static final String CATEGORY_AUDIO_AND_CAPTIONS = "audio_and_captions_category";
94     private static final String CATEGORY_DISPLAY = "display_category";
95     private static final String CATEGORY_INTERACTION_CONTROL = "interaction_control_category";
96     private static final String CATEGORY_EXPERIMENTAL = "experimental_category";
97     private static final String CATEGORY_DOWNLOADED_SERVICES = "user_installed_services_category";
98 
99     private static final String[] CATEGORIES = new String[] {
100             CATEGORY_SCREEN_READER, CATEGORY_AUDIO_AND_CAPTIONS, CATEGORY_DISPLAY,
101             CATEGORY_INTERACTION_CONTROL, CATEGORY_EXPERIMENTAL, CATEGORY_DOWNLOADED_SERVICES
102     };
103 
104     // Preferences
105     private static final String TOGGLE_HIGH_TEXT_CONTRAST_PREFERENCE =
106             "toggle_high_text_contrast_preference";
107     private static final String TOGGLE_INVERSION_PREFERENCE =
108             "toggle_inversion_preference";
109     private static final String TOGGLE_POWER_BUTTON_ENDS_CALL_PREFERENCE =
110             "toggle_power_button_ends_call_preference";
111     private static final String TOGGLE_LOCK_SCREEN_ROTATION_PREFERENCE =
112             "toggle_lock_screen_rotation_preference";
113     private static final String TOGGLE_LARGE_POINTER_ICON =
114             "toggle_large_pointer_icon";
115     private static final String TOGGLE_DISABLE_ANIMATIONS = "toggle_disable_animations";
116     private static final String TOGGLE_MASTER_MONO =
117             "toggle_master_mono";
118     private static final String SELECT_LONG_PRESS_TIMEOUT_PREFERENCE =
119             "select_long_press_timeout_preference";
120     private static final String ACCESSIBILITY_SHORTCUT_PREFERENCE =
121             "accessibility_shortcut_preference";
122     private static final String HEARING_AID_PREFERENCE =
123             "hearing_aid_preference";
124     private static final String CAPTIONING_PREFERENCE_SCREEN =
125             "captioning_preference_screen";
126     private static final String DISPLAY_MAGNIFICATION_PREFERENCE_SCREEN =
127             "magnification_preference_screen";
128     private static final String FONT_SIZE_PREFERENCE_SCREEN =
129             "font_size_preference_screen";
130     private static final String AUTOCLICK_PREFERENCE_SCREEN =
131             "autoclick_preference";
132     private static final String VIBRATION_PREFERENCE_SCREEN =
133             "vibration_preference_screen";
134     private static final String DISPLAY_DALTONIZER_PREFERENCE_SCREEN =
135             "daltonizer_preference";
136     private static final String ACCESSIBILITY_CONTROL_TIMEOUT_PREFERENCE =
137             "accessibility_control_timeout_preference_fragment";
138     private static final String DARK_UI_MODE_PREFERENCE =
139             "dark_ui_mode_accessibility";
140     private static final String LIVE_CAPTION_PREFERENCE_KEY =
141             "live_caption";
142 
143 
144     // Extras passed to sub-fragments.
145     static final String EXTRA_PREFERENCE_KEY = "preference_key";
146     static final String EXTRA_CHECKED = "checked";
147     static final String EXTRA_TITLE = "title";
148     static final String EXTRA_TITLE_RES = "title_res";
149     static final String EXTRA_RESOLVE_INFO = "resolve_info";
150     static final String EXTRA_SUMMARY = "summary";
151     static final String EXTRA_SUMMARY_RES = "summary_res";
152     static final String EXTRA_SETTINGS_TITLE = "settings_title";
153     static final String EXTRA_COMPONENT_NAME = "component_name";
154     static final String EXTRA_SETTINGS_COMPONENT_NAME = "settings_component_name";
155     static final String EXTRA_VIDEO_RAW_RESOURCE_ID = "video_resource";
156     static final String EXTRA_LAUNCHED_FROM_SUW = "from_suw";
157 
158     // Timeout before we update the services if packages are added/removed
159     // since the AccessibilityManagerService has to do that processing first
160     // to generate the AccessibilityServiceInfo we need for proper
161     // presentation.
162     private static final long DELAY_UPDATE_SERVICES_MILLIS = 1000;
163 
164     // Settings that should be changed when toggling animations
165     private static final String[] TOGGLE_ANIMATION_TARGETS = {
166             Settings.Global.WINDOW_ANIMATION_SCALE, Settings.Global.TRANSITION_ANIMATION_SCALE,
167             Settings.Global.ANIMATOR_DURATION_SCALE
168     };
169     private static final String ANIMATION_ON_VALUE = "1";
170     private static final String ANIMATION_OFF_VALUE = "0";
171 
172     static final String RAMPING_RINGER_ENABLED = "ramping_ringer_enabled";
173 
174     private final Map<String, String> mLongPressTimeoutValueToTitleMap = new HashMap<>();
175 
176     private final Handler mHandler = new Handler();
177 
178     private final Runnable mUpdateRunnable = new Runnable() {
179         @Override
180         public void run() {
181             if (getActivity() != null) {
182                 updateServicePreferences();
183             }
184         }
185     };
186 
187     private final PackageMonitor mSettingsPackageMonitor = new PackageMonitor() {
188         @Override
189         public void onPackageAdded(String packageName, int uid) {
190             sendUpdate();
191         }
192 
193         @Override
194         public void onPackageAppeared(String packageName, int reason) {
195             sendUpdate();
196         }
197 
198         @Override
199         public void onPackageDisappeared(String packageName, int reason) {
200             sendUpdate();
201         }
202 
203         @Override
204         public void onPackageRemoved(String packageName, int uid) {
205             sendUpdate();
206         }
207 
208         private void sendUpdate() {
209             mHandler.postDelayed(mUpdateRunnable, DELAY_UPDATE_SERVICES_MILLIS);
210         }
211     };
212 
213     private final SettingsContentObserver mSettingsContentObserver;
214 
215     private final RotationPolicyListener mRotationPolicyListener = new RotationPolicyListener() {
216         @Override
217         public void onChange() {
218             updateLockScreenRotationCheckbox();
219         }
220     };
221 
222     private final Map<String, PreferenceCategory> mCategoryToPrefCategoryMap =
223             new ArrayMap<>();
224     private final Map<Preference, PreferenceCategory> mServicePreferenceToPreferenceCategoryMap =
225             new ArrayMap<>();
226     private final Map<ComponentName, PreferenceCategory> mPreBundledServiceComponentToCategoryMap =
227             new ArrayMap<>();
228 
229     private SwitchPreference mToggleHighTextContrastPreference;
230     private SwitchPreference mTogglePowerButtonEndsCallPreference;
231     private SwitchPreference mToggleLockScreenRotationPreference;
232     private SwitchPreference mToggleLargePointerIconPreference;
233     private SwitchPreference mToggleDisableAnimationsPreference;
234     private SwitchPreference mToggleMasterMonoPreference;
235     private ListPreference mSelectLongPressTimeoutPreference;
236     private Preference mCaptioningPreferenceScreen;
237     private Preference mDisplayMagnificationPreferenceScreen;
238     private Preference mFontSizePreferenceScreen;
239     private Preference mAutoclickPreferenceScreen;
240     private Preference mAccessibilityShortcutPreferenceScreen;
241     private Preference mDisplayDaltonizerPreferenceScreen;
242     private Preference mHearingAidPreference;
243     private Preference mVibrationPreferenceScreen;
244     private Preference mLiveCaptionPreference;
245     private SwitchPreference mToggleInversionPreference;
246     private ColorInversionPreferenceController mInversionPreferenceController;
247     private AccessibilityHearingAidPreferenceController mHearingAidPreferenceController;
248     private SwitchPreference mDarkUIModePreference;
249     private DarkUIPreferenceController mDarkUIPreferenceController;
250     private LiveCaptionPreferenceController mLiveCaptionPreferenceController;
251 
252     private int mLongPressTimeoutDefault;
253 
254     private DevicePolicyManager mDpm;
255 
256     /**
257      * Check if the color transforms are color accelerated. Some transforms are experimental only
258      * on non-accelerated platforms due to the performance implications.
259      *
260      * @param context The current context
261      */
isColorTransformAccelerated(Context context)262     public static boolean isColorTransformAccelerated(Context context) {
263         return context.getResources()
264                 .getBoolean(com.android.internal.R.bool.config_setColorTransformAccelerated);
265     }
266 
AccessibilitySettings()267     public AccessibilitySettings() {
268         // Observe changes to anything that the shortcut can toggle, so we can reflect updates
269         final Collection<AccessibilityShortcutController.ToggleableFrameworkFeatureInfo> features =
270                 AccessibilityShortcutController.getFrameworkShortcutFeaturesMap().values();
271         final List<String> shortcutFeatureKeys = new ArrayList<>(features.size());
272         for (AccessibilityShortcutController.ToggleableFrameworkFeatureInfo feature : features) {
273             shortcutFeatureKeys.add(feature.getSettingKey());
274         }
275         mSettingsContentObserver = new SettingsContentObserver(mHandler, shortcutFeatureKeys) {
276             @Override
277             public void onChange(boolean selfChange, Uri uri) {
278                 updateAllPreferences();
279             }
280         };
281     }
282 
283     @Override
getMetricsCategory()284     public int getMetricsCategory() {
285         return SettingsEnums.ACCESSIBILITY;
286     }
287 
288     @Override
getHelpResource()289     public int getHelpResource() {
290         return R.string.help_uri_accessibility;
291     }
292 
293     @Override
onCreate(Bundle icicle)294     public void onCreate(Bundle icicle) {
295         super.onCreate(icicle);
296         addPreferencesFromResource(R.xml.accessibility_settings);
297         initializeAllPreferences();
298         mDpm = (DevicePolicyManager) (getActivity()
299                 .getSystemService(Context.DEVICE_POLICY_SERVICE));
300     }
301 
302     @Override
onAttach(Context context)303     public void onAttach(Context context) {
304         super.onAttach(context);
305         mHearingAidPreferenceController = new AccessibilityHearingAidPreferenceController
306                 (context, HEARING_AID_PREFERENCE);
307         mHearingAidPreferenceController.setFragmentManager(getFragmentManager());
308         getLifecycle().addObserver(mHearingAidPreferenceController);
309 
310         mLiveCaptionPreferenceController = new LiveCaptionPreferenceController(context,
311                 LIVE_CAPTION_PREFERENCE_KEY);
312     }
313 
314     @Override
onResume()315     public void onResume() {
316         super.onResume();
317         updateAllPreferences();
318 
319         mSettingsPackageMonitor.register(getActivity(), getActivity().getMainLooper(), false);
320         mSettingsContentObserver.register(getContentResolver());
321         if (RotationPolicy.isRotationSupported(getActivity())) {
322             RotationPolicy.registerRotationPolicyListener(getActivity(),
323                     mRotationPolicyListener);
324         }
325     }
326 
327     @Override
onPause()328     public void onPause() {
329         mSettingsPackageMonitor.unregister();
330         mSettingsContentObserver.unregister(getContentResolver());
331         if (RotationPolicy.isRotationSupported(getActivity())) {
332             RotationPolicy.unregisterRotationPolicyListener(getActivity(),
333                     mRotationPolicyListener);
334         }
335         super.onPause();
336     }
337 
338     @Override
onPreferenceChange(Preference preference, Object newValue)339     public boolean onPreferenceChange(Preference preference, Object newValue) {
340         if (mSelectLongPressTimeoutPreference == preference) {
341             handleLongPressTimeoutPreferenceChange((String) newValue);
342             return true;
343         }
344         return false;
345     }
346 
handleLongPressTimeoutPreferenceChange(String stringValue)347     private void handleLongPressTimeoutPreferenceChange(String stringValue) {
348         Settings.Secure.putInt(getContentResolver(),
349                 Settings.Secure.LONG_PRESS_TIMEOUT, Integer.parseInt(stringValue));
350         mSelectLongPressTimeoutPreference.setSummary(
351                 mLongPressTimeoutValueToTitleMap.get(stringValue));
352     }
353 
354     @Override
onPreferenceTreeClick(Preference preference)355     public boolean onPreferenceTreeClick(Preference preference) {
356         if (mToggleHighTextContrastPreference == preference) {
357             handleToggleTextContrastPreferenceClick();
358             return true;
359         } else if (mTogglePowerButtonEndsCallPreference == preference) {
360             handleTogglePowerButtonEndsCallPreferenceClick();
361             return true;
362         } else if (mToggleLockScreenRotationPreference == preference) {
363             handleLockScreenRotationPreferenceClick();
364             return true;
365         } else if (mToggleLargePointerIconPreference == preference) {
366             handleToggleLargePointerIconPreferenceClick();
367             return true;
368         } else if (mToggleDisableAnimationsPreference == preference) {
369             handleToggleDisableAnimations();
370             return true;
371         } else if (mToggleMasterMonoPreference == preference) {
372             handleToggleMasterMonoPreferenceClick();
373             return true;
374         } else if (mHearingAidPreferenceController.handlePreferenceTreeClick(preference)) {
375             return true;
376         }
377         return super.onPreferenceTreeClick(preference);
378     }
379 
getServiceSummary(Context context, AccessibilityServiceInfo info, boolean serviceEnabled)380     public static CharSequence getServiceSummary(Context context, AccessibilityServiceInfo info,
381             boolean serviceEnabled) {
382         final String serviceState = serviceEnabled
383                 ? context.getString(R.string.accessibility_summary_state_enabled)
384                 : context.getString(R.string.accessibility_summary_state_disabled);
385         final CharSequence serviceSummary = info.loadSummary(context.getPackageManager());
386         final String stateSummaryCombo = context.getString(
387                 R.string.preference_summary_default_combination,
388                 serviceState, serviceSummary);
389 
390         return (TextUtils.isEmpty(serviceSummary))
391                 ? serviceState
392                 : stateSummaryCombo;
393     }
394 
395     @VisibleForTesting
isRampingRingerEnabled(final Context context)396     static boolean isRampingRingerEnabled(final Context context) {
397         return (Settings.Global.getInt(
398                         context.getContentResolver(),
399                         Settings.Global.APPLY_RAMPING_RINGER, 0) == 1)
400                 && DeviceConfig.getBoolean(
401                         DeviceConfig.NAMESPACE_TELEPHONY, RAMPING_RINGER_ENABLED, false);
402     }
403 
handleToggleTextContrastPreferenceClick()404     private void handleToggleTextContrastPreferenceClick() {
405         Settings.Secure.putInt(getContentResolver(),
406                 Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED,
407                 (mToggleHighTextContrastPreference.isChecked() ? 1 : 0));
408     }
409 
handleTogglePowerButtonEndsCallPreferenceClick()410     private void handleTogglePowerButtonEndsCallPreferenceClick() {
411         Settings.Secure.putInt(getContentResolver(),
412                 Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR,
413                 (mTogglePowerButtonEndsCallPreference.isChecked()
414                         ? Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP
415                         : Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_SCREEN_OFF));
416     }
417 
handleLockScreenRotationPreferenceClick()418     private void handleLockScreenRotationPreferenceClick() {
419         RotationPolicy.setRotationLockForAccessibility(getActivity(),
420                 !mToggleLockScreenRotationPreference.isChecked());
421     }
422 
handleToggleLargePointerIconPreferenceClick()423     private void handleToggleLargePointerIconPreferenceClick() {
424         Settings.Secure.putInt(getContentResolver(),
425                 Settings.Secure.ACCESSIBILITY_LARGE_POINTER_ICON,
426                 mToggleLargePointerIconPreference.isChecked() ? 1 : 0);
427     }
428 
handleToggleDisableAnimations()429     private void handleToggleDisableAnimations() {
430         String newAnimationValue = mToggleDisableAnimationsPreference.isChecked()
431                 ? ANIMATION_OFF_VALUE : ANIMATION_ON_VALUE;
432         for (String animationPreference : TOGGLE_ANIMATION_TARGETS) {
433             Settings.Global.putString(getContentResolver(), animationPreference, newAnimationValue);
434         }
435     }
436 
handleToggleMasterMonoPreferenceClick()437     private void handleToggleMasterMonoPreferenceClick() {
438         Settings.System.putIntForUser(getContentResolver(), Settings.System.MASTER_MONO,
439                 mToggleMasterMonoPreference.isChecked() ? 1 : 0, UserHandle.USER_CURRENT);
440     }
441 
initializeAllPreferences()442     private void initializeAllPreferences() {
443         for (int i = 0; i < CATEGORIES.length; i++) {
444             PreferenceCategory prefCategory = (PreferenceCategory) findPreference(CATEGORIES[i]);
445             mCategoryToPrefCategoryMap.put(CATEGORIES[i], prefCategory);
446         }
447 
448         // Text contrast.
449         mToggleHighTextContrastPreference =
450                 (SwitchPreference) findPreference(TOGGLE_HIGH_TEXT_CONTRAST_PREFERENCE);
451 
452         // Display inversion.
453         mToggleInversionPreference = (SwitchPreference) findPreference(TOGGLE_INVERSION_PREFERENCE);
454         mInversionPreferenceController =
455                 new ColorInversionPreferenceController(getContext(), TOGGLE_INVERSION_PREFERENCE);
456         mInversionPreferenceController.displayPreference(getPreferenceScreen());
457 
458         // Power button ends calls.
459         mTogglePowerButtonEndsCallPreference =
460                 (SwitchPreference) findPreference(TOGGLE_POWER_BUTTON_ENDS_CALL_PREFERENCE);
461         if (!KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_POWER)
462                 || !Utils.isVoiceCapable(getActivity())) {
463             mCategoryToPrefCategoryMap.get(CATEGORY_INTERACTION_CONTROL)
464                     .removePreference(mTogglePowerButtonEndsCallPreference);
465         }
466 
467         // Lock screen rotation.
468         mToggleLockScreenRotationPreference =
469                 (SwitchPreference) findPreference(TOGGLE_LOCK_SCREEN_ROTATION_PREFERENCE);
470         if (!RotationPolicy.isRotationSupported(getActivity())) {
471             mCategoryToPrefCategoryMap.get(CATEGORY_INTERACTION_CONTROL)
472                     .removePreference(mToggleLockScreenRotationPreference);
473         }
474 
475         // Large pointer icon.
476         mToggleLargePointerIconPreference =
477                 (SwitchPreference) findPreference(TOGGLE_LARGE_POINTER_ICON);
478 
479         mToggleDisableAnimationsPreference =
480                 (SwitchPreference) findPreference(TOGGLE_DISABLE_ANIMATIONS);
481 
482         // Master Mono
483         mToggleMasterMonoPreference =
484                 (SwitchPreference) findPreference(TOGGLE_MASTER_MONO);
485 
486         // Long press timeout.
487         mSelectLongPressTimeoutPreference =
488                 (ListPreference) findPreference(SELECT_LONG_PRESS_TIMEOUT_PREFERENCE);
489         mSelectLongPressTimeoutPreference.setOnPreferenceChangeListener(this);
490         if (mLongPressTimeoutValueToTitleMap.size() == 0) {
491             String[] timeoutValues = getResources().getStringArray(
492                     R.array.long_press_timeout_selector_values);
493             mLongPressTimeoutDefault = Integer.parseInt(timeoutValues[0]);
494             String[] timeoutTitles = getResources().getStringArray(
495                     R.array.long_press_timeout_selector_titles);
496             final int timeoutValueCount = timeoutValues.length;
497             for (int i = 0; i < timeoutValueCount; i++) {
498                 mLongPressTimeoutValueToTitleMap.put(timeoutValues[i], timeoutTitles[i]);
499             }
500         }
501 
502         // Hearing Aid.
503         mHearingAidPreference = findPreference(HEARING_AID_PREFERENCE);
504         mHearingAidPreferenceController.displayPreference(getPreferenceScreen());
505 
506         // Captioning.
507         mCaptioningPreferenceScreen = findPreference(CAPTIONING_PREFERENCE_SCREEN);
508 
509         // Live caption
510         mLiveCaptionPreference = findPreference(LIVE_CAPTION_PREFERENCE_KEY);
511         mLiveCaptionPreferenceController.displayPreference(getPreferenceScreen());
512 
513         // Display magnification.
514         mDisplayMagnificationPreferenceScreen = findPreference(
515                 DISPLAY_MAGNIFICATION_PREFERENCE_SCREEN);
516         configureMagnificationPreferenceIfNeeded(mDisplayMagnificationPreferenceScreen);
517 
518         // Font size.
519         mFontSizePreferenceScreen = findPreference(FONT_SIZE_PREFERENCE_SCREEN);
520 
521         // Autoclick after pointer stops.
522         mAutoclickPreferenceScreen = findPreference(AUTOCLICK_PREFERENCE_SCREEN);
523 
524         // Display color adjustments.
525         mDisplayDaltonizerPreferenceScreen = findPreference(DISPLAY_DALTONIZER_PREFERENCE_SCREEN);
526 
527         // Accessibility shortcut.
528         mAccessibilityShortcutPreferenceScreen = findPreference(ACCESSIBILITY_SHORTCUT_PREFERENCE);
529 
530         // Vibrations.
531         mVibrationPreferenceScreen = findPreference(VIBRATION_PREFERENCE_SCREEN);
532 
533         // Dark Mode.
534         mDarkUIModePreference = findPreference(DARK_UI_MODE_PREFERENCE);
535         mDarkUIPreferenceController = new DarkUIPreferenceController(getContext(),
536                 DARK_UI_MODE_PREFERENCE);
537         mDarkUIPreferenceController.setParentFragment(this);
538         mDarkUIPreferenceController.displayPreference(getPreferenceScreen());
539     }
540 
updateAllPreferences()541     private void updateAllPreferences() {
542         updateSystemPreferences();
543         updateServicePreferences();
544     }
545 
updateServicePreferences()546     protected void updateServicePreferences() {
547         // Since services category is auto generated we have to do a pass
548         // to generate it since services can come and go and then based on
549         // the global accessibility state to decided whether it is enabled.
550 
551         // Generate.
552         ArrayList<Preference> servicePreferences =
553                 new ArrayList<>(mServicePreferenceToPreferenceCategoryMap.keySet());
554         for (int i = 0; i < servicePreferences.size(); i++) {
555             Preference service = servicePreferences.get(i);
556             PreferenceCategory category = mServicePreferenceToPreferenceCategoryMap.get(service);
557             category.removePreference(service);
558         }
559 
560         initializePreBundledServicesMapFromArray(CATEGORY_SCREEN_READER,
561                 R.array.config_preinstalled_screen_reader_services);
562         initializePreBundledServicesMapFromArray(CATEGORY_AUDIO_AND_CAPTIONS,
563                 R.array.config_preinstalled_audio_and_caption_services);
564         initializePreBundledServicesMapFromArray(CATEGORY_DISPLAY,
565                 R.array.config_preinstalled_display_services);
566         initializePreBundledServicesMapFromArray(CATEGORY_INTERACTION_CONTROL,
567                 R.array.config_preinstalled_interaction_control_services);
568 
569         AccessibilityManager accessibilityManager = AccessibilityManager.getInstance(getActivity());
570 
571         List<AccessibilityServiceInfo> installedServices =
572                 accessibilityManager.getInstalledAccessibilityServiceList();
573         List<AccessibilityServiceInfo> enabledServiceInfos = accessibilityManager
574                 .getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_ALL_MASK);
575         Set<ComponentName> enabledServices = AccessibilityUtils.getEnabledServicesFromSettings(
576                 getActivity());
577         List<String> permittedServices = mDpm.getPermittedAccessibilityServices(
578                 UserHandle.myUserId());
579 
580         PreferenceCategory downloadedServicesCategory =
581                 mCategoryToPrefCategoryMap.get(CATEGORY_DOWNLOADED_SERVICES);
582         // Temporarily add the downloaded services category back if it was previously removed.
583         if (findPreference(CATEGORY_DOWNLOADED_SERVICES) == null) {
584             getPreferenceScreen().addPreference(downloadedServicesCategory);
585         }
586 
587         for (int i = 0, count = installedServices.size(); i < count; ++i) {
588             final AccessibilityServiceInfo info = installedServices.get(i);
589             final ResolveInfo resolveInfo = info.getResolveInfo();
590 
591             final RestrictedPreference preference =
592                     new RestrictedPreference(downloadedServicesCategory.getContext());
593             final String title = resolveInfo.loadLabel(getPackageManager()).toString();
594 
595             Drawable icon;
596             if (resolveInfo.getIconResource() == 0) {
597                 icon = ContextCompat.getDrawable(getContext(), R.drawable.ic_accessibility_generic);
598             } else {
599                 icon = resolveInfo.loadIcon(getPackageManager());
600             }
601 
602             final ServiceInfo serviceInfo = resolveInfo.serviceInfo;
603             final String packageName = serviceInfo.packageName;
604             final ComponentName componentName = new ComponentName(packageName, serviceInfo.name);
605 
606             preference.setKey(componentName.flattenToString());
607 
608             preference.setTitle(title);
609             preference.setIconSize(ICON_SIZE_MEDIUM);
610             Utils.setSafeIcon(preference, icon);
611             final boolean serviceEnabled = enabledServices.contains(componentName);
612             String description = info.loadDescription(getPackageManager());
613             if (TextUtils.isEmpty(description)) {
614                 description = getString(R.string.accessibility_service_default_description);
615             }
616 
617             if (serviceEnabled && AccessibilityUtils.hasServiceCrashed(
618                     packageName, serviceInfo.name, enabledServiceInfos)) {
619                 // Update the summaries for services that have crashed.
620                 preference.setSummary(R.string.accessibility_summary_state_stopped);
621                 description = getString(R.string.accessibility_description_state_stopped);
622             } else {
623                 final CharSequence serviceSummary = getServiceSummary(getContext(), info,
624                         serviceEnabled);
625                 preference.setSummary(serviceSummary);
626             }
627 
628             // Disable all accessibility services that are not permitted.
629             final boolean serviceAllowed =
630                     permittedServices == null || permittedServices.contains(packageName);
631             if (!serviceAllowed && !serviceEnabled) {
632                 final EnforcedAdmin admin =
633                         RestrictedLockUtilsInternal.checkIfAccessibilityServiceDisallowed(
634                                 getActivity(), packageName, UserHandle.myUserId());
635                 if (admin != null) {
636                     preference.setDisabledByAdmin(admin);
637                 } else {
638                     preference.setEnabled(false);
639                 }
640             } else {
641                 preference.setEnabled(true);
642             }
643 
644             preference.setFragment(ToggleAccessibilityServicePreferenceFragment.class.getName());
645             preference.setPersistent(true);
646 
647             final Bundle extras = preference.getExtras();
648             extras.putString(EXTRA_PREFERENCE_KEY, preference.getKey());
649             extras.putBoolean(EXTRA_CHECKED, serviceEnabled);
650             extras.putString(EXTRA_TITLE, title);
651             extras.putParcelable(EXTRA_RESOLVE_INFO, resolveInfo);
652             extras.putString(EXTRA_SUMMARY, description);
653 
654             final String settingsClassName = info.getSettingsActivityName();
655             if (!TextUtils.isEmpty(settingsClassName)) {
656                 extras.putString(EXTRA_SETTINGS_TITLE,
657                         getString(R.string.accessibility_menu_item_settings));
658                 extras.putString(EXTRA_SETTINGS_COMPONENT_NAME,
659                         new ComponentName(packageName, settingsClassName).flattenToString());
660             }
661             extras.putParcelable(EXTRA_COMPONENT_NAME, componentName);
662 
663             PreferenceCategory prefCategory = downloadedServicesCategory;
664             // Set the appropriate category if the service comes pre-installed.
665             if (mPreBundledServiceComponentToCategoryMap.containsKey(componentName)) {
666                 prefCategory = mPreBundledServiceComponentToCategoryMap.get(componentName);
667             }
668             preference.setOrder(FIRST_PREFERENCE_IN_CATEGORY_INDEX);
669             prefCategory.addPreference(preference);
670             mServicePreferenceToPreferenceCategoryMap.put(preference, prefCategory);
671         }
672 
673         // Update the order of all the category according to the order defined in xml file.
674         updateCategoryOrderFromArray(CATEGORY_SCREEN_READER,
675             R.array.config_order_screen_reader_services);
676         updateCategoryOrderFromArray(CATEGORY_AUDIO_AND_CAPTIONS,
677             R.array.config_order_audio_and_caption_services);
678         updateCategoryOrderFromArray(CATEGORY_INTERACTION_CONTROL,
679             R.array.config_order_interaction_control_services);
680         updateCategoryOrderFromArray(CATEGORY_DISPLAY,
681             R.array.config_order_display_services);
682 
683         // If the user has not installed any additional services, hide the category.
684         if (downloadedServicesCategory.getPreferenceCount() == 0) {
685             final PreferenceScreen screen = getPreferenceScreen();
686             screen.removePreference(downloadedServicesCategory);
687         }
688     }
689 
initializePreBundledServicesMapFromArray(String categoryKey, int key)690     private void initializePreBundledServicesMapFromArray(String categoryKey, int key) {
691         String[] services = getResources().getStringArray(key);
692         PreferenceCategory category = mCategoryToPrefCategoryMap.get(categoryKey);
693         for (int i = 0; i < services.length; i++) {
694             ComponentName component = ComponentName.unflattenFromString(services[i]);
695             mPreBundledServiceComponentToCategoryMap.put(component, category);
696         }
697     }
698 
699     /**
700      * Update the order of perferences in the category by matching their preference
701      * key with the string array of preference order which is defined in the xml.
702      *
703      * @param categoryKey The key of the category need to update the order
704      * @param key The key of the string array which defines the order of category
705      */
updateCategoryOrderFromArray(String categoryKey, int key)706     private void updateCategoryOrderFromArray(String categoryKey, int key) {
707         String[] services = getResources().getStringArray(key);
708         PreferenceCategory category = mCategoryToPrefCategoryMap.get(categoryKey);
709         int preferenceCount = category.getPreferenceCount();
710         int serviceLength = services.length;
711         for (int preferenceIndex = 0; preferenceIndex < preferenceCount; preferenceIndex++) {
712             for (int serviceIndex = 0; serviceIndex < serviceLength; serviceIndex++) {
713                 if (category.getPreference(preferenceIndex).getKey()
714                         .equals(services[serviceIndex])) {
715                     category.getPreference(preferenceIndex).setOrder(serviceIndex);
716                     break;
717                 }
718             }
719         }
720     }
721 
updateSystemPreferences()722     protected void updateSystemPreferences() {
723         // Move color inversion and color correction preferences to Display category if device
724         // supports HWC hardware-accelerated color transform.
725         if (ColorDisplayManager.isColorTransformAccelerated(getContext())) {
726             PreferenceCategory experimentalCategory =
727                     mCategoryToPrefCategoryMap.get(CATEGORY_EXPERIMENTAL);
728             PreferenceCategory displayCategory =
729                     mCategoryToPrefCategoryMap.get(CATEGORY_DISPLAY);
730             experimentalCategory.removePreference(mToggleInversionPreference);
731             experimentalCategory.removePreference(mDisplayDaltonizerPreferenceScreen);
732             mDisplayDaltonizerPreferenceScreen.setOrder(
733                     mDisplayMagnificationPreferenceScreen.getOrder() + 1);
734             mToggleInversionPreference.setOrder(
735                     mDisplayDaltonizerPreferenceScreen.getOrder() + 1);
736             mToggleLargePointerIconPreference.setOrder(
737                     mToggleInversionPreference.getOrder() + 1);
738             mToggleDisableAnimationsPreference.setOrder(
739                     mToggleLargePointerIconPreference.getOrder() + 1);
740             mToggleInversionPreference.setSummary(R.string.summary_empty);
741             displayCategory.addPreference(mToggleInversionPreference);
742             displayCategory.addPreference(mDisplayDaltonizerPreferenceScreen);
743         }
744 
745         // Text contrast.
746         mToggleHighTextContrastPreference.setChecked(
747                 Settings.Secure.getInt(getContentResolver(),
748                         Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED, 0) == 1);
749 
750         // If the quick setting is enabled, the preference MUST be enabled.
751         mInversionPreferenceController.updateState(mToggleInversionPreference);
752 
753         // Dark Mode
754         mDarkUIPreferenceController.updateState(mDarkUIModePreference);
755 
756         // Power button ends calls.
757         if (KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_POWER)
758                 && Utils.isVoiceCapable(getActivity())) {
759             final int incallPowerBehavior = Settings.Secure.getInt(getContentResolver(),
760                     Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR,
761                     Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_DEFAULT);
762             final boolean powerButtonEndsCall =
763                     (incallPowerBehavior == Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP);
764             mTogglePowerButtonEndsCallPreference.setChecked(powerButtonEndsCall);
765         }
766 
767         // Auto-rotate screen
768         updateLockScreenRotationCheckbox();
769 
770         // Large pointer icon.
771         mToggleLargePointerIconPreference.setChecked(Settings.Secure.getInt(getContentResolver(),
772                 Settings.Secure.ACCESSIBILITY_LARGE_POINTER_ICON, 0) != 0);
773 
774         updateDisableAnimationsToggle();
775 
776         // Master mono
777         updateMasterMono();
778 
779         // Long press timeout.
780         final int longPressTimeout = Settings.Secure.getInt(getContentResolver(),
781                 Settings.Secure.LONG_PRESS_TIMEOUT, mLongPressTimeoutDefault);
782         String value = String.valueOf(longPressTimeout);
783         mSelectLongPressTimeoutPreference.setValue(value);
784         mSelectLongPressTimeoutPreference.setSummary(mLongPressTimeoutValueToTitleMap.get(value));
785 
786         updateVibrationSummary(mVibrationPreferenceScreen);
787 
788         mHearingAidPreferenceController.updateState(mHearingAidPreference);
789 
790         mLiveCaptionPreferenceController.updateState(mLiveCaptionPreference);
791 
792         updateFeatureSummary(Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED,
793                 mCaptioningPreferenceScreen);
794         updateFeatureSummary(Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED,
795                 mDisplayDaltonizerPreferenceScreen);
796 
797         updateMagnificationSummary(mDisplayMagnificationPreferenceScreen);
798 
799         updateFontSizeSummary(mFontSizePreferenceScreen);
800 
801         updateAutoclickSummary(mAutoclickPreferenceScreen);
802 
803         updateAccessibilityShortcut(mAccessibilityShortcutPreferenceScreen);
804 
805         updateAccessibilityTimeoutSummary(getContentResolver(),
806                 findPreference(ACCESSIBILITY_CONTROL_TIMEOUT_PREFERENCE));
807     }
808 
updateAccessibilityTimeoutSummary(ContentResolver resolver, Preference pref)809     void updateAccessibilityTimeoutSummary(ContentResolver resolver, Preference pref) {
810         String[] timeoutSummarys = getResources().getStringArray(
811                 R.array.accessibility_timeout_summaries);
812         int[] timeoutValues = getResources().getIntArray(
813                 R.array.accessibility_timeout_selector_values);
814 
815         int timeoutValue = AccessibilityTimeoutController.getSecureAccessibilityTimeoutValue(
816                     resolver, AccessibilityTimeoutController.CONTROL_TIMEOUT_SETTINGS_SECURE);
817 
818         int idx = Ints.indexOf(timeoutValues, timeoutValue);
819         pref.setSummary(timeoutSummarys[idx == -1 ? 0 : idx]);
820     }
821 
updateMagnificationSummary(Preference pref)822     private void updateMagnificationSummary(Preference pref) {
823         final boolean tripleTapEnabled = Settings.Secure.getInt(getContentResolver(),
824                 Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, 0) == 1;
825         final boolean buttonEnabled = Settings.Secure.getInt(getContentResolver(),
826                 Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED, 0) == 1;
827 
828         int summaryResId = 0;
829         if (!tripleTapEnabled && !buttonEnabled) {
830             summaryResId = R.string.accessibility_feature_state_off;
831         } else if (!tripleTapEnabled && buttonEnabled) {
832             summaryResId = R.string.accessibility_screen_magnification_navbar_title;
833         } else if (tripleTapEnabled && !buttonEnabled) {
834             summaryResId = R.string.accessibility_screen_magnification_gestures_title;
835         } else {
836             summaryResId = R.string.accessibility_screen_magnification_state_navbar_gesture;
837         }
838         pref.setSummary(summaryResId);
839     }
840 
updateFeatureSummary(String prefKey, Preference pref)841     private void updateFeatureSummary(String prefKey, Preference pref) {
842         final boolean enabled = Settings.Secure.getInt(getContentResolver(), prefKey, 0) == 1;
843         pref.setSummary(enabled ? R.string.accessibility_feature_state_on
844                 : R.string.accessibility_feature_state_off);
845     }
846 
updateAutoclickSummary(Preference pref)847     private void updateAutoclickSummary(Preference pref) {
848         final boolean enabled = Settings.Secure.getInt(
849                 getContentResolver(), Settings.Secure.ACCESSIBILITY_AUTOCLICK_ENABLED, 0) == 1;
850         if (!enabled) {
851             pref.setSummary(R.string.accessibility_feature_state_off);
852             return;
853         }
854         int delay = Settings.Secure.getInt(
855                 getContentResolver(), Settings.Secure.ACCESSIBILITY_AUTOCLICK_DELAY,
856                 AccessibilityManager.AUTOCLICK_DELAY_DEFAULT);
857         pref.setSummary(ToggleAutoclickPreferenceFragment.getAutoclickPreferenceSummary(
858                 getResources(), delay));
859     }
860 
updateFontSizeSummary(Preference pref)861     private void updateFontSizeSummary(Preference pref) {
862         final float currentScale = Settings.System.getFloat(getContext().getContentResolver(),
863                 Settings.System.FONT_SCALE, 1.0f);
864         final Resources res = getContext().getResources();
865         final String[] entries = res.getStringArray(R.array.entries_font_size);
866         final String[] strEntryValues = res.getStringArray(R.array.entryvalues_font_size);
867         final int index = ToggleFontSizePreferenceFragment.fontSizeValueToIndex(currentScale,
868                 strEntryValues);
869         pref.setSummary(entries[index]);
870     }
871 
872     @VisibleForTesting
updateVibrationSummary(Preference pref)873     void updateVibrationSummary(Preference pref) {
874         final Context context = getContext();
875         final Vibrator vibrator = context.getSystemService(Vibrator.class);
876 
877         int ringIntensity = Settings.System.getInt(context.getContentResolver(),
878                 Settings.System.RING_VIBRATION_INTENSITY,
879                 vibrator.getDefaultRingVibrationIntensity());
880         if (Settings.System.getInt(context.getContentResolver(),
881                 Settings.System.VIBRATE_WHEN_RINGING, 0) == 0 && !isRampingRingerEnabled(context)) {
882             ringIntensity = Vibrator.VIBRATION_INTENSITY_OFF;
883         }
884         CharSequence ringIntensityString =
885                 VibrationIntensityPreferenceController.getIntensityString(context, ringIntensity);
886 
887         int notificationIntensity = Settings.System.getInt(context.getContentResolver(),
888                 Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
889                 vibrator.getDefaultNotificationVibrationIntensity());
890         CharSequence notificationIntensityString =
891                 VibrationIntensityPreferenceController.getIntensityString(context,
892                         notificationIntensity);
893 
894         int touchIntensity = Settings.System.getInt(context.getContentResolver(),
895                 Settings.System.HAPTIC_FEEDBACK_INTENSITY,
896                 vibrator.getDefaultHapticFeedbackIntensity());
897         if (Settings.System.getInt(context.getContentResolver(),
898                 Settings.System.HAPTIC_FEEDBACK_ENABLED, 0) == 0) {
899             touchIntensity = Vibrator.VIBRATION_INTENSITY_OFF;
900         }
901         CharSequence touchIntensityString =
902                 VibrationIntensityPreferenceController.getIntensityString(context, touchIntensity);
903 
904         if (mVibrationPreferenceScreen == null) {
905             mVibrationPreferenceScreen = findPreference(VIBRATION_PREFERENCE_SCREEN);
906         }
907 
908         if (ringIntensity == touchIntensity && ringIntensity == notificationIntensity) {
909             mVibrationPreferenceScreen.setSummary(ringIntensityString);
910         } else {
911             mVibrationPreferenceScreen.setSummary(
912                     getString(R.string.accessibility_vibration_summary,
913                             ringIntensityString,
914                             notificationIntensityString,
915                             touchIntensityString));
916         }
917     }
918 
getVibrationSummary(Context context, @VibrationIntensity int intensity)919     private String getVibrationSummary(Context context, @VibrationIntensity int intensity) {
920         final boolean supportsMultipleIntensities = context.getResources().getBoolean(
921                 R.bool.config_vibration_supports_multiple_intensities);
922         if (supportsMultipleIntensities) {
923             switch (intensity) {
924                 case Vibrator.VIBRATION_INTENSITY_OFF:
925                     return context.getString(R.string.accessibility_vibration_summary_off);
926                 case Vibrator.VIBRATION_INTENSITY_LOW:
927                     return context.getString(R.string.accessibility_vibration_summary_low);
928                 case Vibrator.VIBRATION_INTENSITY_MEDIUM:
929                     return context.getString(R.string.accessibility_vibration_summary_medium);
930                 case Vibrator.VIBRATION_INTENSITY_HIGH:
931                     return context.getString(R.string.accessibility_vibration_summary_high);
932                 default:
933                     return "";
934             }
935         } else {
936             if (intensity == Vibrator.VIBRATION_INTENSITY_OFF) {
937                 return context.getString(R.string.switch_on_text);
938             } else {
939                 return context.getString(R.string.switch_off_text);
940             }
941         }
942     }
943 
updateLockScreenRotationCheckbox()944     private void updateLockScreenRotationCheckbox() {
945         Context context = getActivity();
946         if (context != null) {
947             mToggleLockScreenRotationPreference.setChecked(
948                     !RotationPolicy.isRotationLocked(context));
949         }
950     }
951 
updateDisableAnimationsToggle()952     private void updateDisableAnimationsToggle() {
953         boolean allAnimationsDisabled = true;
954         for (String animationSetting : TOGGLE_ANIMATION_TARGETS) {
955             if (!TextUtils.equals(
956                     Settings.Global.getString(getContentResolver(), animationSetting),
957                     ANIMATION_OFF_VALUE)) {
958                 allAnimationsDisabled = false;
959                 break;
960             }
961         }
962         mToggleDisableAnimationsPreference.setChecked(allAnimationsDisabled);
963     }
964 
updateMasterMono()965     private void updateMasterMono() {
966         final boolean masterMono = Settings.System.getIntForUser(
967                 getContentResolver(), Settings.System.MASTER_MONO,
968                 0 /* default */, UserHandle.USER_CURRENT) == 1;
969         mToggleMasterMonoPreference.setChecked(masterMono);
970     }
971 
updateAccessibilityShortcut(Preference preference)972     private void updateAccessibilityShortcut(Preference preference) {
973         if (AccessibilityManager.getInstance(getActivity())
974                 .getInstalledAccessibilityServiceList().isEmpty()) {
975             mAccessibilityShortcutPreferenceScreen
976                     .setSummary(getString(R.string.accessibility_no_services_installed));
977             mAccessibilityShortcutPreferenceScreen.setEnabled(false);
978         } else {
979             mAccessibilityShortcutPreferenceScreen.setEnabled(true);
980             boolean shortcutEnabled =
981                     AccessibilityUtils.isShortcutEnabled(getContext(), UserHandle.myUserId());
982             CharSequence summary = shortcutEnabled
983                     ? AccessibilityShortcutPreferenceFragment.getServiceName(getContext())
984                     : getString(R.string.accessibility_feature_state_off);
985             mAccessibilityShortcutPreferenceScreen.setSummary(summary);
986         }
987     }
988 
configureMagnificationPreferenceIfNeeded(Preference preference)989     private static void configureMagnificationPreferenceIfNeeded(Preference preference) {
990         // Some devices support only a single magnification mode. In these cases, we redirect to
991         // the magnification mode's UI directly, rather than showing a PreferenceScreen with a
992         // single list item.
993         final Context context = preference.getContext();
994         if (!MagnificationPreferenceFragment.isApplicable(context.getResources())) {
995             preference.setFragment(ToggleScreenMagnificationPreferenceFragment.class.getName());
996             final Bundle extras = preference.getExtras();
997             MagnificationGesturesPreferenceController
998                     .populateMagnificationGesturesPreferenceExtras(extras, context);
999         }
1000     }
1001 
1002     public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
1003             new BaseSearchIndexProvider() {
1004 
1005                 @Override
1006                 public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
1007                         boolean enabled) {
1008                     List<SearchIndexableResource> indexables = new ArrayList<>();
1009                     SearchIndexableResource indexable = new SearchIndexableResource(context);
1010                     indexable.xmlResId = R.xml.accessibility_settings;
1011                     indexables.add(indexable);
1012                     return indexables;
1013                 }
1014             };
1015 }
1016