2 * Copyright (C) 2009 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.android.settings.accessibility;
19 import android.accessibilityservice.AccessibilityServiceInfo;
20 import android.app.ActivityManagerNative;
21 import android.app.admin.DevicePolicyManager;
22 import android.content.ComponentName;
23 import android.content.Context;
24 import android.content.pm.PackageManager;
25 import android.content.pm.ResolveInfo;
26 import android.content.pm.ServiceInfo;
27 import android.content.res.Configuration;
28 import android.net.Uri;
29 import android.os.Bundle;
30 import android.os.Handler;
31 import android.os.RemoteException;
32 import android.os.UserHandle;
33 import android.preference.CheckBoxPreference;
34 import android.preference.ListPreference;
35 import android.preference.Preference;
36 import android.preference.PreferenceCategory;
37 import android.preference.PreferenceScreen;
38 import android.preference.SwitchPreference;
39 import android.provider.SearchIndexableResource;
40 import android.provider.Settings;
41 import android.text.TextUtils;
42 import android.text.TextUtils.SimpleStringSplitter;
43 import android.view.KeyCharacterMap;
44 import android.view.KeyEvent;
45 import android.view.View;
46 import android.view.accessibility.AccessibilityManager;
47 import android.widget.TextView;
49 import com.android.internal.content.PackageMonitor;
50 import com.android.internal.view.RotationPolicy;
51 import com.android.internal.view.RotationPolicy.RotationPolicyListener;
52 import com.android.settings.DialogCreatable;
53 import com.android.settings.R;
54 import com.android.settings.SettingsPreferenceFragment;
55 import com.android.settings.Utils;
56 import com.android.settings.search.BaseSearchIndexProvider;
57 import com.android.settings.search.Indexable;
58 import com.android.settings.search.SearchIndexableRaw;
60 import java.util.ArrayList;
61 import java.util.HashMap;
62 import java.util.HashSet;
63 import java.util.List;
68 * Activity with the accessibility settings.
70 public class AccessibilitySettings extends SettingsPreferenceFragment implements DialogCreatable,
71 Preference.OnPreferenceChangeListener, Indexable {
73 private static final float LARGE_FONT_SCALE = 1.3f;
75 static final char ENABLED_ACCESSIBILITY_SERVICES_SEPARATOR = ':';
77 // Preference categories
78 private static final String SERVICES_CATEGORY = "services_category";
79 private static final String SYSTEM_CATEGORY = "system_category";
82 private static final String TOGGLE_LARGE_TEXT_PREFERENCE =
83 "toggle_large_text_preference";
84 private static final String TOGGLE_HIGH_TEXT_CONTRAST_PREFERENCE =
85 "toggle_high_text_contrast_preference";
86 private static final String TOGGLE_INVERSION_PREFERENCE =
87 "toggle_inversion_preference";
88 private static final String TOGGLE_POWER_BUTTON_ENDS_CALL_PREFERENCE =
89 "toggle_power_button_ends_call_preference";
90 private static final String TOGGLE_LOCK_SCREEN_ROTATION_PREFERENCE =
91 "toggle_lock_screen_rotation_preference";
92 private static final String TOGGLE_SPEAK_PASSWORD_PREFERENCE =
93 "toggle_speak_password_preference";
94 private static final String SELECT_LONG_PRESS_TIMEOUT_PREFERENCE =
95 "select_long_press_timeout_preference";
96 private static final String ENABLE_ACCESSIBILITY_GESTURE_PREFERENCE_SCREEN =
97 "enable_global_gesture_preference_screen";
98 private static final String CAPTIONING_PREFERENCE_SCREEN =
99 "captioning_preference_screen";
100 private static final String DISPLAY_MAGNIFICATION_PREFERENCE_SCREEN =
101 "screen_magnification_preference_screen";
102 private static final String DISPLAY_DALTONIZER_PREFERENCE_SCREEN =
103 "daltonizer_preference_screen";
105 // Extras passed to sub-fragments.
106 static final String EXTRA_PREFERENCE_KEY = "preference_key";
107 static final String EXTRA_CHECKED = "checked";
108 static final String EXTRA_TITLE = "title";
109 static final String EXTRA_SUMMARY = "summary";
110 static final String EXTRA_SETTINGS_TITLE = "settings_title";
111 static final String EXTRA_COMPONENT_NAME = "component_name";
112 static final String EXTRA_SETTINGS_COMPONENT_NAME = "settings_component_name";
114 // Timeout before we update the services if packages are added/removed
115 // since the AccessibilityManagerService has to do that processing first
116 // to generate the AccessibilityServiceInfo we need for proper
118 private static final long DELAY_UPDATE_SERVICES_MILLIS = 1000;
120 // Auxiliary members.
121 final static SimpleStringSplitter sStringColonSplitter =
122 new SimpleStringSplitter(ENABLED_ACCESSIBILITY_SERVICES_SEPARATOR);
124 static final Set<ComponentName> sInstalledServices = new HashSet<ComponentName>();
126 private final Map<String, String> mLongPressTimeoutValuetoTitleMap =
127 new HashMap<String, String>();
129 private final Configuration mCurConfig = new Configuration();
131 private final Handler mHandler = new Handler();
133 private final Runnable mUpdateRunnable = new Runnable() {
136 loadInstalledServices();
137 updateServicesPreferences();
141 private final PackageMonitor mSettingsPackageMonitor = new PackageMonitor() {
143 public void onPackageAdded(String packageName, int uid) {
148 public void onPackageAppeared(String packageName, int reason) {
153 public void onPackageDisappeared(String packageName, int reason) {
158 public void onPackageRemoved(String packageName, int uid) {
162 private void sendUpdate() {
163 mHandler.postDelayed(mUpdateRunnable, DELAY_UPDATE_SERVICES_MILLIS);
167 private final SettingsContentObserver mSettingsContentObserver =
168 new SettingsContentObserver(mHandler) {
170 public void onChange(boolean selfChange, Uri uri) {
171 loadInstalledServices();
172 updateServicesPreferences();
176 private final RotationPolicyListener mRotationPolicyListener = new RotationPolicyListener() {
178 public void onChange() {
179 updateLockScreenRotationCheckbox();
183 // Preference controls.
184 private PreferenceCategory mServicesCategory;
185 private PreferenceCategory mSystemsCategory;
187 private CheckBoxPreference mToggleLargeTextPreference;
188 private CheckBoxPreference mToggleHighTextContrastPreference;
189 private CheckBoxPreference mTogglePowerButtonEndsCallPreference;
190 private CheckBoxPreference mToggleLockScreenRotationPreference;
191 private CheckBoxPreference mToggleSpeakPasswordPreference;
192 private ListPreference mSelectLongPressTimeoutPreference;
193 private Preference mNoServicesMessagePreference;
194 private PreferenceScreen mCaptioningPreferenceScreen;
195 private PreferenceScreen mDisplayMagnificationPreferenceScreen;
196 private PreferenceScreen mGlobalGesturePreferenceScreen;
197 private PreferenceScreen mDisplayDaltonizerPreferenceScreen;
198 private SwitchPreference mToggleInversionPreference;
200 private int mLongPressTimeoutDefault;
202 private DevicePolicyManager mDpm;
205 public void onCreate(Bundle icicle) {
206 super.onCreate(icicle);
207 addPreferencesFromResource(R.xml.accessibility_settings);
208 initializeAllPreferences();
209 mDpm = (DevicePolicyManager) (getActivity()
210 .getSystemService(Context.DEVICE_POLICY_SERVICE));
214 public void onResume() {
216 loadInstalledServices();
217 updateAllPreferences();
219 mSettingsPackageMonitor.register(getActivity(), getActivity().getMainLooper(), false);
220 mSettingsContentObserver.register(getContentResolver());
221 if (RotationPolicy.isRotationSupported(getActivity())) {
222 RotationPolicy.registerRotationPolicyListener(getActivity(),
223 mRotationPolicyListener);
228 public void onPause() {
229 mSettingsPackageMonitor.unregister();
230 mSettingsContentObserver.unregister(getContentResolver());
231 if (RotationPolicy.isRotationSupported(getActivity())) {
232 RotationPolicy.unregisterRotationPolicyListener(getActivity(),
233 mRotationPolicyListener);
239 public boolean onPreferenceChange(Preference preference, Object newValue) {
240 if (mSelectLongPressTimeoutPreference == preference) {
241 handleLongPressTimeoutPreferenceChange((String) newValue);
243 } else if (mToggleInversionPreference == preference) {
244 handleToggleInversionPreferenceChange((Boolean) newValue);
250 private void handleLongPressTimeoutPreferenceChange(String stringValue) {
251 Settings.Secure.putInt(getContentResolver(),
252 Settings.Secure.LONG_PRESS_TIMEOUT, Integer.parseInt(stringValue));
253 mSelectLongPressTimeoutPreference.setSummary(
254 mLongPressTimeoutValuetoTitleMap.get(stringValue));
257 private void handleToggleInversionPreferenceChange(boolean checked) {
258 Settings.Secure.putInt(getContentResolver(),
259 Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, (checked ? 1 : 0));
263 public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
264 if (mToggleLargeTextPreference == preference) {
265 handleToggleLargeTextPreferenceClick();
267 } else if (mToggleHighTextContrastPreference == preference) {
268 handleToggleTextContrastPreferenceClick();
270 } else if (mTogglePowerButtonEndsCallPreference == preference) {
271 handleTogglePowerButtonEndsCallPreferenceClick();
273 } else if (mToggleLockScreenRotationPreference == preference) {
274 handleLockScreenRotationPreferenceClick();
276 } else if (mToggleSpeakPasswordPreference == preference) {
277 handleToggleSpeakPasswordPreferenceClick();
279 } else if (mGlobalGesturePreferenceScreen == preference) {
280 handleToggleEnableAccessibilityGesturePreferenceClick();
282 } else if (mDisplayMagnificationPreferenceScreen == preference) {
283 handleDisplayMagnificationPreferenceScreenClick();
286 return super.onPreferenceTreeClick(preferenceScreen, preference);
289 private void handleToggleLargeTextPreferenceClick() {
291 mCurConfig.fontScale = mToggleLargeTextPreference.isChecked() ? LARGE_FONT_SCALE : 1;
292 ActivityManagerNative.getDefault().updatePersistentConfiguration(mCurConfig);
293 } catch (RemoteException re) {
298 private void handleToggleTextContrastPreferenceClick() {
299 Settings.Secure.putInt(getContentResolver(),
300 Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED,
301 (mToggleHighTextContrastPreference.isChecked() ? 1 : 0));
304 private void handleTogglePowerButtonEndsCallPreferenceClick() {
305 Settings.Secure.putInt(getContentResolver(),
306 Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR,
307 (mTogglePowerButtonEndsCallPreference.isChecked()
308 ? Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP
309 : Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_SCREEN_OFF));
312 private void handleLockScreenRotationPreferenceClick() {
313 RotationPolicy.setRotationLockForAccessibility(getActivity(),
314 !mToggleLockScreenRotationPreference.isChecked());
317 private void handleToggleSpeakPasswordPreferenceClick() {
318 Settings.Secure.putInt(getContentResolver(),
319 Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD,
320 mToggleSpeakPasswordPreference.isChecked() ? 1 : 0);
323 private void handleToggleEnableAccessibilityGesturePreferenceClick() {
324 Bundle extras = mGlobalGesturePreferenceScreen.getExtras();
325 extras.putString(EXTRA_TITLE, getString(
326 R.string.accessibility_global_gesture_preference_title));
327 extras.putString(EXTRA_SUMMARY, getString(
328 R.string.accessibility_global_gesture_preference_description));
329 extras.putBoolean(EXTRA_CHECKED, Settings.Global.getInt(getContentResolver(),
330 Settings.Global.ENABLE_ACCESSIBILITY_GLOBAL_GESTURE_ENABLED, 0) == 1);
331 super.onPreferenceTreeClick(mGlobalGesturePreferenceScreen,
332 mGlobalGesturePreferenceScreen);
335 private void handleDisplayMagnificationPreferenceScreenClick() {
336 Bundle extras = mDisplayMagnificationPreferenceScreen.getExtras();
337 extras.putString(EXTRA_TITLE, getString(
338 R.string.accessibility_screen_magnification_title));
339 extras.putCharSequence(EXTRA_SUMMARY, getActivity().getResources().getText(
340 R.string.accessibility_screen_magnification_summary));
341 extras.putBoolean(EXTRA_CHECKED, Settings.Secure.getInt(getContentResolver(),
342 Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, 0) == 1);
343 super.onPreferenceTreeClick(mDisplayMagnificationPreferenceScreen,
344 mDisplayMagnificationPreferenceScreen);
347 private void initializeAllPreferences() {
348 mServicesCategory = (PreferenceCategory) findPreference(SERVICES_CATEGORY);
349 mSystemsCategory = (PreferenceCategory) findPreference(SYSTEM_CATEGORY);
352 mToggleLargeTextPreference =
353 (CheckBoxPreference) findPreference(TOGGLE_LARGE_TEXT_PREFERENCE);
356 mToggleHighTextContrastPreference =
357 (CheckBoxPreference) findPreference(TOGGLE_HIGH_TEXT_CONTRAST_PREFERENCE);
359 // Display inversion.
360 mToggleInversionPreference = (SwitchPreference) findPreference(TOGGLE_INVERSION_PREFERENCE);
361 mToggleInversionPreference.setOnPreferenceChangeListener(this);
363 // Power button ends calls.
364 mTogglePowerButtonEndsCallPreference =
365 (CheckBoxPreference) findPreference(TOGGLE_POWER_BUTTON_ENDS_CALL_PREFERENCE);
366 if (!KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_POWER)
367 || !Utils.isVoiceCapable(getActivity())) {
368 mSystemsCategory.removePreference(mTogglePowerButtonEndsCallPreference);
371 // Lock screen rotation.
372 mToggleLockScreenRotationPreference =
373 (CheckBoxPreference) findPreference(TOGGLE_LOCK_SCREEN_ROTATION_PREFERENCE);
374 if (!RotationPolicy.isRotationSupported(getActivity())) {
375 mSystemsCategory.removePreference(mToggleLockScreenRotationPreference);
379 mToggleSpeakPasswordPreference =
380 (CheckBoxPreference) findPreference(TOGGLE_SPEAK_PASSWORD_PREFERENCE);
382 // Long press timeout.
383 mSelectLongPressTimeoutPreference =
384 (ListPreference) findPreference(SELECT_LONG_PRESS_TIMEOUT_PREFERENCE);
385 mSelectLongPressTimeoutPreference.setOnPreferenceChangeListener(this);
386 if (mLongPressTimeoutValuetoTitleMap.size() == 0) {
387 String[] timeoutValues = getResources().getStringArray(
388 R.array.long_press_timeout_selector_values);
389 mLongPressTimeoutDefault = Integer.parseInt(timeoutValues[0]);
390 String[] timeoutTitles = getResources().getStringArray(
391 R.array.long_press_timeout_selector_titles);
392 final int timeoutValueCount = timeoutValues.length;
393 for (int i = 0; i < timeoutValueCount; i++) {
394 mLongPressTimeoutValuetoTitleMap.put(timeoutValues[i], timeoutTitles[i]);
399 mCaptioningPreferenceScreen = (PreferenceScreen) findPreference(
400 CAPTIONING_PREFERENCE_SCREEN);
402 // Display magnification.
403 mDisplayMagnificationPreferenceScreen = (PreferenceScreen) findPreference(
404 DISPLAY_MAGNIFICATION_PREFERENCE_SCREEN);
406 // Display color adjustments.
407 mDisplayDaltonizerPreferenceScreen = (PreferenceScreen) findPreference(
408 DISPLAY_DALTONIZER_PREFERENCE_SCREEN);
411 mGlobalGesturePreferenceScreen =
412 (PreferenceScreen) findPreference(ENABLE_ACCESSIBILITY_GESTURE_PREFERENCE_SCREEN);
413 final int longPressOnPowerBehavior = getActivity().getResources().getInteger(
414 com.android.internal.R.integer.config_longPressOnPowerBehavior);
415 final int LONG_PRESS_POWER_GLOBAL_ACTIONS = 1;
416 if (!KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_POWER)
417 || longPressOnPowerBehavior != LONG_PRESS_POWER_GLOBAL_ACTIONS) {
418 // Remove accessibility shortcut if power key is not present
419 // nor long press power does not show global actions menu.
420 mSystemsCategory.removePreference(mGlobalGesturePreferenceScreen);
424 private void updateAllPreferences() {
425 updateServicesPreferences();
426 updateSystemPreferences();
429 private void updateServicesPreferences() {
430 // Since services category is auto generated we have to do a pass
431 // to generate it since services can come and go and then based on
432 // the global accessibility state to decided whether it is enabled.
435 mServicesCategory.removeAll();
437 AccessibilityManager accessibilityManager = AccessibilityManager.getInstance(getActivity());
439 List<AccessibilityServiceInfo> installedServices =
440 accessibilityManager.getInstalledAccessibilityServiceList();
441 Set<ComponentName> enabledServices = AccessibilityUtils.getEnabledServicesFromSettings(
443 List<String> permittedServices = mDpm.getPermittedAccessibilityServices(
444 UserHandle.myUserId());
445 final boolean accessibilityEnabled = Settings.Secure.getInt(getContentResolver(),
446 Settings.Secure.ACCESSIBILITY_ENABLED, 0) == 1;
448 for (int i = 0, count = installedServices.size(); i < count; ++i) {
449 AccessibilityServiceInfo info = installedServices.get(i);
451 PreferenceScreen preference = getPreferenceManager().createPreferenceScreen(
453 String title = info.getResolveInfo().loadLabel(getPackageManager()).toString();
455 ServiceInfo serviceInfo = info.getResolveInfo().serviceInfo;
456 ComponentName componentName = new ComponentName(serviceInfo.packageName,
459 preference.setKey(componentName.flattenToString());
461 preference.setTitle(title);
462 final boolean serviceEnabled = accessibilityEnabled
463 && enabledServices.contains(componentName);
464 String serviceEnabledString;
465 if (serviceEnabled) {
466 serviceEnabledString = getString(R.string.accessibility_feature_state_on);
468 serviceEnabledString = getString(R.string.accessibility_feature_state_off);
471 // Disable all accessibility services that are not permitted.
472 String packageName = serviceInfo.packageName;
473 boolean serviceAllowed =
474 permittedServices == null || permittedServices.contains(packageName);
475 preference.setEnabled(serviceAllowed || serviceEnabled);
477 String summaryString;
478 if (serviceAllowed) {
479 summaryString = serviceEnabledString;
481 summaryString = getString(R.string.accessibility_feature_or_input_method_not_allowed);
483 preference.setSummary(summaryString);
485 preference.setOrder(i);
486 preference.setFragment(ToggleAccessibilityServicePreferenceFragment.class.getName());
487 preference.setPersistent(true);
489 Bundle extras = preference.getExtras();
490 extras.putString(EXTRA_PREFERENCE_KEY, preference.getKey());
491 extras.putBoolean(EXTRA_CHECKED, serviceEnabled);
492 extras.putString(EXTRA_TITLE, title);
494 String description = info.loadDescription(getPackageManager());
495 if (TextUtils.isEmpty(description)) {
496 description = getString(R.string.accessibility_service_default_description);
498 extras.putString(EXTRA_SUMMARY, description);
500 String settingsClassName = info.getSettingsActivityName();
501 if (!TextUtils.isEmpty(settingsClassName)) {
502 extras.putString(EXTRA_SETTINGS_TITLE,
503 getString(R.string.accessibility_menu_item_settings));
504 extras.putString(EXTRA_SETTINGS_COMPONENT_NAME,
505 new ComponentName(info.getResolveInfo().serviceInfo.packageName,
506 settingsClassName).flattenToString());
509 extras.putParcelable(EXTRA_COMPONENT_NAME, componentName);
511 mServicesCategory.addPreference(preference);
514 if (mServicesCategory.getPreferenceCount() == 0) {
515 if (mNoServicesMessagePreference == null) {
516 mNoServicesMessagePreference = new Preference(getActivity()) {
518 protected void onBindView(View view) {
519 super.onBindView(view);
520 TextView summaryView = (TextView) view.findViewById(R.id.summary);
521 String title = getString(R.string.accessibility_no_services_installed);
522 summaryView.setText(title);
525 mNoServicesMessagePreference.setPersistent(false);
526 mNoServicesMessagePreference.setLayoutResource(
527 R.layout.text_description_preference);
528 mNoServicesMessagePreference.setSelectable(false);
530 mServicesCategory.addPreference(mNoServicesMessagePreference);
534 private void updateSystemPreferences() {
537 mCurConfig.updateFrom(ActivityManagerNative.getDefault().getConfiguration());
538 } catch (RemoteException re) {
541 mToggleLargeTextPreference.setChecked(mCurConfig.fontScale == LARGE_FONT_SCALE);
543 mToggleHighTextContrastPreference.setChecked(
544 Settings.Secure.getInt(getContentResolver(),
545 Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED, 0) == 1);
547 // If the quick setting is enabled, the preference MUST be enabled.
548 mToggleInversionPreference.setChecked(Settings.Secure.getInt(getContentResolver(),
549 Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, 0) == 1);
551 // Power button ends calls.
552 if (KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_POWER)
553 && Utils.isVoiceCapable(getActivity())) {
554 final int incallPowerBehavior = Settings.Secure.getInt(getContentResolver(),
555 Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR,
556 Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_DEFAULT);
557 final boolean powerButtonEndsCall =
558 (incallPowerBehavior == Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP);
559 mTogglePowerButtonEndsCallPreference.setChecked(powerButtonEndsCall);
562 // Auto-rotate screen
563 updateLockScreenRotationCheckbox();
566 final boolean speakPasswordEnabled = Settings.Secure.getInt(getContentResolver(),
567 Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD, 0) != 0;
568 mToggleSpeakPasswordPreference.setChecked(speakPasswordEnabled);
570 // Long press timeout.
571 final int longPressTimeout = Settings.Secure.getInt(getContentResolver(),
572 Settings.Secure.LONG_PRESS_TIMEOUT, mLongPressTimeoutDefault);
573 String value = String.valueOf(longPressTimeout);
574 mSelectLongPressTimeoutPreference.setValue(value);
575 mSelectLongPressTimeoutPreference.setSummary(mLongPressTimeoutValuetoTitleMap.get(value));
577 updateFeatureSummary(Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED,
578 mCaptioningPreferenceScreen);
579 updateFeatureSummary(Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED,
580 mDisplayMagnificationPreferenceScreen);
581 updateFeatureSummary(Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED,
582 mDisplayDaltonizerPreferenceScreen);
585 final boolean globalGestureEnabled = Settings.Global.getInt(getContentResolver(),
586 Settings.Global.ENABLE_ACCESSIBILITY_GLOBAL_GESTURE_ENABLED, 0) == 1;
587 if (globalGestureEnabled) {
588 mGlobalGesturePreferenceScreen.setSummary(
589 R.string.accessibility_global_gesture_preference_summary_on);
591 mGlobalGesturePreferenceScreen.setSummary(
592 R.string.accessibility_global_gesture_preference_summary_off);
596 private void updateFeatureSummary(String prefKey, Preference pref) {
597 final boolean enabled = Settings.Secure.getInt(getContentResolver(), prefKey, 0) == 1;
598 pref.setSummary(enabled ? R.string.accessibility_feature_state_on
599 : R.string.accessibility_feature_state_off);
602 private void updateLockScreenRotationCheckbox() {
603 Context context = getActivity();
604 if (context != null) {
605 mToggleLockScreenRotationPreference.setChecked(
606 !RotationPolicy.isRotationLocked(context));
610 private void loadInstalledServices() {
611 Set<ComponentName> installedServices = sInstalledServices;
612 installedServices.clear();
614 List<AccessibilityServiceInfo> installedServiceInfos =
615 AccessibilityManager.getInstance(getActivity())
616 .getInstalledAccessibilityServiceList();
617 if (installedServiceInfos == null) {
621 final int installedServiceInfoCount = installedServiceInfos.size();
622 for (int i = 0; i < installedServiceInfoCount; i++) {
623 ResolveInfo resolveInfo = installedServiceInfos.get(i).getResolveInfo();
624 ComponentName installedService = new ComponentName(
625 resolveInfo.serviceInfo.packageName,
626 resolveInfo.serviceInfo.name);
627 installedServices.add(installedService);
631 public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
632 new BaseSearchIndexProvider() {
634 public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) {
635 List<SearchIndexableRaw> indexables = new ArrayList<SearchIndexableRaw>();
637 PackageManager packageManager = context.getPackageManager();
638 AccessibilityManager accessibilityManager = (AccessibilityManager)
639 context.getSystemService(Context.ACCESSIBILITY_SERVICE);
641 String screenTitle = context.getResources().getString(
642 R.string.accessibility_services_title);
644 // Indexing all services, regardless if enabled.
645 List<AccessibilityServiceInfo> services = accessibilityManager
646 .getInstalledAccessibilityServiceList();
647 final int serviceCount = services.size();
648 for (int i = 0; i < serviceCount; i++) {
649 AccessibilityServiceInfo service = services.get(i);
650 if (service == null || service.getResolveInfo() == null) {
654 ServiceInfo serviceInfo = service.getResolveInfo().serviceInfo;
655 ComponentName componentName = new ComponentName(serviceInfo.packageName,
658 SearchIndexableRaw indexable = new SearchIndexableRaw(context);
659 indexable.key = componentName.flattenToString();
660 indexable.title = service.getResolveInfo().loadLabel(packageManager).toString();
661 indexable.summaryOn = context.getString(R.string.accessibility_feature_state_on);
662 indexable.summaryOff = context.getString(R.string.accessibility_feature_state_off);
663 indexable.screenTitle = screenTitle;
664 indexables.add(indexable);
671 public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
673 List<SearchIndexableResource> indexables = new ArrayList<SearchIndexableResource>();
674 SearchIndexableResource indexable = new SearchIndexableResource(context);
675 indexable.xmlResId = R.xml.accessibility_settings;
676 indexables.add(indexable);