AccessibilitySettings.java revision 24ef59737b962258a143ed7be3159dd64e8f8c85
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
17package com.android.settings.accessibility;
18
19import android.accessibilityservice.AccessibilityServiceInfo;
20import android.app.ActivityManagerNative;
21import android.app.AlertDialog;
22import android.app.Dialog;
23import android.content.ActivityNotFoundException;
24import android.content.ComponentName;
25import android.content.Context;
26import android.content.DialogInterface;
27import android.content.Intent;
28import android.content.SharedPreferences;
29import android.content.pm.ResolveInfo;
30import android.content.pm.ServiceInfo;
31import android.content.res.Configuration;
32import android.net.Uri;
33import android.os.Bundle;
34import android.os.Handler;
35import android.os.RemoteException;
36import android.os.SystemProperties;
37import android.preference.CheckBoxPreference;
38import android.preference.ListPreference;
39import android.preference.Preference;
40import android.preference.PreferenceCategory;
41import android.preference.PreferenceScreen;
42import android.provider.Settings;
43import android.text.TextUtils;
44import android.text.TextUtils.SimpleStringSplitter;
45import android.util.Log;
46import android.view.KeyCharacterMap;
47import android.view.KeyEvent;
48import android.view.View;
49import android.view.accessibility.AccessibilityManager;
50import android.widget.TextView;
51
52import com.android.internal.content.PackageMonitor;
53import com.android.internal.view.RotationPolicy;
54import com.android.internal.view.RotationPolicy.RotationPolicyListener;
55import com.android.settings.DialogCreatable;
56import com.android.settings.R;
57import com.android.settings.SettingsPreferenceFragment;
58import com.android.settings.Utils;
59
60import java.util.HashMap;
61import java.util.HashSet;
62import java.util.List;
63import java.util.Map;
64import java.util.Set;
65
66/**
67 * Activity with the accessibility settings.
68 */
69public class AccessibilitySettings extends SettingsPreferenceFragment implements DialogCreatable,
70        Preference.OnPreferenceChangeListener {
71    private static final String LOG_TAG = "AccessibilitySettings";
72
73    private static final String DEFAULT_SCREENREADER_MARKET_LINK =
74            "market://search?q=pname:com.google.android.marvin.talkback";
75
76    private static final float LARGE_FONT_SCALE = 1.3f;
77
78    private static final String SYSTEM_PROPERTY_MARKET_URL = "ro.screenreader.market";
79
80    static final char ENABLED_ACCESSIBILITY_SERVICES_SEPARATOR = ':';
81
82    private static final String KEY_INSTALL_ACCESSIBILITY_SERVICE_OFFERED_ONCE =
83            "key_install_accessibility_service_offered_once";
84
85    // Preference categories
86    private static final String SERVICES_CATEGORY = "services_category";
87    private static final String SYSTEM_CATEGORY = "system_category";
88
89    // Preferences
90    private static final String TOGGLE_LARGE_TEXT_PREFERENCE =
91            "toggle_large_text_preference";
92    private static final String TOGGLE_POWER_BUTTON_ENDS_CALL_PREFERENCE =
93            "toggle_power_button_ends_call_preference";
94    private static final String TOGGLE_LOCK_SCREEN_ROTATION_PREFERENCE =
95            "toggle_lock_screen_rotation_preference";
96    private static final String TOGGLE_SPEAK_PASSWORD_PREFERENCE =
97            "toggle_speak_password_preference";
98    private static final String SELECT_LONG_PRESS_TIMEOUT_PREFERENCE =
99            "select_long_press_timeout_preference";
100    private static final String ENABLE_ACCESSIBILITY_GESTURE_PREFERENCE_SCREEN =
101            "enable_global_gesture_preference_screen";
102    private static final String CAPTIONING_PREFERENCE_SCREEN =
103            "captioning_preference_screen";
104    private static final String DISPLAY_MAGNIFICATION_PREFERENCE_SCREEN =
105            "screen_magnification_preference_screen";
106    private static final String DISPLAY_CONTRAST_PREFERENCE_SCREEN =
107            "contrast_preference_screen";
108    private static final String DISPLAY_INVERSION_PREFERENCE_SCREEN =
109            "inversion_preference_screen";
110    private static final String DISPLAY_DALTONIZER_PREFERENCE_SCREEN =
111            "daltonizer_preference_screen";
112
113    // Extras passed to sub-fragments.
114    static final String EXTRA_PREFERENCE_KEY = "preference_key";
115    static final String EXTRA_CHECKED = "checked";
116    static final String EXTRA_TITLE = "title";
117    static final String EXTRA_SUMMARY = "summary";
118    static final String EXTRA_SETTINGS_TITLE = "settings_title";
119    static final String EXTRA_COMPONENT_NAME = "component_name";
120    static final String EXTRA_SETTINGS_COMPONENT_NAME = "settings_component_name";
121
122    // Timeout before we update the services if packages are added/removed
123    // since the AccessibilityManagerService has to do that processing first
124    // to generate the AccessibilityServiceInfo we need for proper
125    // presentation.
126    private static final long DELAY_UPDATE_SERVICES_MILLIS = 1000;
127
128    // Dialog IDs.
129    private static final int DIALOG_ID_NO_ACCESSIBILITY_SERVICES = 1;
130
131    // Auxiliary members.
132    final static SimpleStringSplitter sStringColonSplitter =
133            new SimpleStringSplitter(ENABLED_ACCESSIBILITY_SERVICES_SEPARATOR);
134
135    static final Set<ComponentName> sInstalledServices = new HashSet<ComponentName>();
136
137    private final Map<String, String> mLongPressTimeoutValuetoTitleMap =
138            new HashMap<String, String>();
139
140    private final Configuration mCurConfig = new Configuration();
141
142    private final Handler mHandler = new Handler();
143
144    private final Runnable mUpdateRunnable = new Runnable() {
145        @Override
146        public void run() {
147            loadInstalledServices();
148            updateServicesPreferences();
149        }
150    };
151
152    private final PackageMonitor mSettingsPackageMonitor = new PackageMonitor() {
153        @Override
154        public void onPackageAdded(String packageName, int uid) {
155            sendUpdate();
156        }
157
158        @Override
159        public void onPackageAppeared(String packageName, int reason) {
160            sendUpdate();
161        }
162
163        @Override
164        public void onPackageDisappeared(String packageName, int reason) {
165            sendUpdate();
166        }
167
168        @Override
169        public void onPackageRemoved(String packageName, int uid) {
170            sendUpdate();
171        }
172
173        private void sendUpdate() {
174            mHandler.postDelayed(mUpdateRunnable, DELAY_UPDATE_SERVICES_MILLIS);
175        }
176    };
177
178    private final SettingsContentObserver mSettingsContentObserver =
179            new SettingsContentObserver(mHandler) {
180                @Override
181                public void onChange(boolean selfChange, Uri uri) {
182                    loadInstalledServices();
183                    updateServicesPreferences();
184                }
185            };
186
187    private final RotationPolicyListener mRotationPolicyListener = new RotationPolicyListener() {
188        @Override
189        public void onChange() {
190            updateLockScreenRotationCheckbox();
191        }
192    };
193
194    // Preference controls.
195    private PreferenceCategory mServicesCategory;
196    private PreferenceCategory mSystemsCategory;
197
198    private CheckBoxPreference mToggleLargeTextPreference;
199    private CheckBoxPreference mTogglePowerButtonEndsCallPreference;
200    private CheckBoxPreference mToggleLockScreenRotationPreference;
201    private CheckBoxPreference mToggleSpeakPasswordPreference;
202    private ListPreference mSelectLongPressTimeoutPreference;
203    private Preference mNoServicesMessagePreference;
204    private PreferenceScreen mCaptioningPreferenceScreen;
205    private PreferenceScreen mDisplayMagnificationPreferenceScreen;
206    private PreferenceScreen mGlobalGesturePreferenceScreen;
207    private PreferenceScreen mDisplayInversionPreferenceScreen;
208    private PreferenceScreen mDisplayContrastPreferenceScreen;
209    private PreferenceScreen mDisplayDaltonizerPreferenceScreen;
210
211    private int mLongPressTimeoutDefault;
212
213    @Override
214    public void onCreate(Bundle icicle) {
215        super.onCreate(icicle);
216        addPreferencesFromResource(R.xml.accessibility_settings);
217        initializeAllPreferences();
218    }
219
220    @Override
221    public void onResume() {
222        super.onResume();
223        loadInstalledServices();
224        updateAllPreferences();
225
226        mSettingsPackageMonitor.register(getActivity(), getActivity().getMainLooper(), false);
227        mSettingsContentObserver.register(getContentResolver());
228        if (RotationPolicy.isRotationSupported(getActivity())) {
229            RotationPolicy.registerRotationPolicyListener(getActivity(),
230                    mRotationPolicyListener);
231        }
232    }
233
234    @Override
235    public void onPause() {
236        mSettingsPackageMonitor.unregister();
237        mSettingsContentObserver.unregister(getContentResolver());
238        if (RotationPolicy.isRotationSupported(getActivity())) {
239            RotationPolicy.unregisterRotationPolicyListener(getActivity(),
240                    mRotationPolicyListener);
241        }
242        super.onPause();
243    }
244
245    @Override
246    public boolean onPreferenceChange(Preference preference, Object newValue) {
247        if (preference == mSelectLongPressTimeoutPreference) {
248            String stringValue = (String) newValue;
249            Settings.Secure.putInt(getContentResolver(),
250                    Settings.Secure.LONG_PRESS_TIMEOUT, Integer.parseInt(stringValue));
251            mSelectLongPressTimeoutPreference.setSummary(
252                    mLongPressTimeoutValuetoTitleMap.get(stringValue));
253            return true;
254        }
255        return false;
256    }
257
258    @Override
259    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
260        if (mToggleLargeTextPreference == preference) {
261            handleToggleLargeTextPreferenceClick();
262            return true;
263        } else if (mTogglePowerButtonEndsCallPreference == preference) {
264            handleTogglePowerButtonEndsCallPreferenceClick();
265            return true;
266        } else if (mToggleLockScreenRotationPreference == preference) {
267            handleLockScreenRotationPreferenceClick();
268            return true;
269        } else if (mToggleSpeakPasswordPreference == preference) {
270            handleToggleSpeakPasswordPreferenceClick();
271            return true;
272        } else if (mGlobalGesturePreferenceScreen == preference) {
273            handleTogglEnableAccessibilityGesturePreferenceClick();
274            return true;
275        } else if (mDisplayMagnificationPreferenceScreen == preference) {
276            handleDisplayMagnificationPreferenceScreenClick();
277            return true;
278        }
279        return super.onPreferenceTreeClick(preferenceScreen, preference);
280    }
281
282    private void handleToggleLargeTextPreferenceClick() {
283        try {
284            mCurConfig.fontScale = mToggleLargeTextPreference.isChecked() ? LARGE_FONT_SCALE : 1;
285            ActivityManagerNative.getDefault().updatePersistentConfiguration(mCurConfig);
286        } catch (RemoteException re) {
287            /* ignore */
288        }
289    }
290
291    private void handleTogglePowerButtonEndsCallPreferenceClick() {
292        Settings.Secure.putInt(getContentResolver(),
293                Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR,
294                (mTogglePowerButtonEndsCallPreference.isChecked()
295                        ? Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP
296                        : Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_SCREEN_OFF));
297    }
298
299    private void handleLockScreenRotationPreferenceClick() {
300        RotationPolicy.setRotationLockForAccessibility(getActivity(),
301                !mToggleLockScreenRotationPreference.isChecked());
302    }
303
304    private void handleToggleSpeakPasswordPreferenceClick() {
305        Settings.Secure.putInt(getContentResolver(),
306                Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD,
307                mToggleSpeakPasswordPreference.isChecked() ? 1 : 0);
308    }
309
310    private void handleTogglEnableAccessibilityGesturePreferenceClick() {
311        Bundle extras = mGlobalGesturePreferenceScreen.getExtras();
312        extras.putString(EXTRA_TITLE, getString(
313                R.string.accessibility_global_gesture_preference_title));
314        extras.putString(EXTRA_SUMMARY, getString(
315                R.string.accessibility_global_gesture_preference_description));
316        extras.putBoolean(EXTRA_CHECKED, Settings.Global.getInt(getContentResolver(),
317                Settings.Global.ENABLE_ACCESSIBILITY_GLOBAL_GESTURE_ENABLED, 0) == 1);
318        super.onPreferenceTreeClick(mGlobalGesturePreferenceScreen,
319                mGlobalGesturePreferenceScreen);
320    }
321
322    private void handleDisplayMagnificationPreferenceScreenClick() {
323        Bundle extras = mDisplayMagnificationPreferenceScreen.getExtras();
324        extras.putString(EXTRA_TITLE, getString(
325                R.string.accessibility_screen_magnification_title));
326        extras.putCharSequence(EXTRA_SUMMARY, getActivity().getResources().getText(
327                R.string.accessibility_screen_magnification_summary));
328        extras.putBoolean(EXTRA_CHECKED, Settings.Secure.getInt(getContentResolver(),
329                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, 0) == 1);
330        super.onPreferenceTreeClick(mDisplayMagnificationPreferenceScreen,
331                mDisplayMagnificationPreferenceScreen);
332    }
333
334    private void initializeAllPreferences() {
335        mServicesCategory = (PreferenceCategory) findPreference(SERVICES_CATEGORY);
336        mSystemsCategory = (PreferenceCategory) findPreference(SYSTEM_CATEGORY);
337
338        // Large text.
339        mToggleLargeTextPreference =
340                (CheckBoxPreference) findPreference(TOGGLE_LARGE_TEXT_PREFERENCE);
341
342        // Power button ends calls.
343        mTogglePowerButtonEndsCallPreference =
344                (CheckBoxPreference) findPreference(TOGGLE_POWER_BUTTON_ENDS_CALL_PREFERENCE);
345        if (!KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_POWER)
346                || !Utils.isVoiceCapable(getActivity())) {
347            mSystemsCategory.removePreference(mTogglePowerButtonEndsCallPreference);
348        }
349
350        // Lock screen rotation.
351        mToggleLockScreenRotationPreference =
352                (CheckBoxPreference) findPreference(TOGGLE_LOCK_SCREEN_ROTATION_PREFERENCE);
353        if (!RotationPolicy.isRotationSupported(getActivity())) {
354            mSystemsCategory.removePreference(mToggleLockScreenRotationPreference);
355        }
356
357        // Speak passwords.
358        mToggleSpeakPasswordPreference =
359                (CheckBoxPreference) findPreference(TOGGLE_SPEAK_PASSWORD_PREFERENCE);
360
361        // Long press timeout.
362        mSelectLongPressTimeoutPreference =
363                (ListPreference) findPreference(SELECT_LONG_PRESS_TIMEOUT_PREFERENCE);
364        mSelectLongPressTimeoutPreference.setOnPreferenceChangeListener(this);
365        if (mLongPressTimeoutValuetoTitleMap.size() == 0) {
366            String[] timeoutValues = getResources().getStringArray(
367                    R.array.long_press_timeout_selector_values);
368            mLongPressTimeoutDefault = Integer.parseInt(timeoutValues[0]);
369            String[] timeoutTitles = getResources().getStringArray(
370                    R.array.long_press_timeout_selector_titles);
371            final int timeoutValueCount = timeoutValues.length;
372            for (int i = 0; i < timeoutValueCount; i++) {
373                mLongPressTimeoutValuetoTitleMap.put(timeoutValues[i], timeoutTitles[i]);
374            }
375        }
376
377        // Captioning.
378        mCaptioningPreferenceScreen = (PreferenceScreen) findPreference(
379                CAPTIONING_PREFERENCE_SCREEN);
380
381        // Display magnification.
382        mDisplayMagnificationPreferenceScreen = (PreferenceScreen) findPreference(
383                DISPLAY_MAGNIFICATION_PREFERENCE_SCREEN);
384
385        // Display color adjustments.
386        mDisplayContrastPreferenceScreen = (PreferenceScreen) findPreference(
387                DISPLAY_CONTRAST_PREFERENCE_SCREEN);
388        mDisplayInversionPreferenceScreen = (PreferenceScreen) findPreference(
389                DISPLAY_INVERSION_PREFERENCE_SCREEN);
390        mDisplayDaltonizerPreferenceScreen = (PreferenceScreen) findPreference(
391                DISPLAY_DALTONIZER_PREFERENCE_SCREEN);
392
393        // Global gesture.
394        mGlobalGesturePreferenceScreen =
395                (PreferenceScreen) findPreference(ENABLE_ACCESSIBILITY_GESTURE_PREFERENCE_SCREEN);
396        final int longPressOnPowerBehavior = getActivity().getResources().getInteger(
397                com.android.internal.R.integer.config_longPressOnPowerBehavior);
398        final int LONG_PRESS_POWER_GLOBAL_ACTIONS = 1;
399        if (!KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_POWER)
400                || longPressOnPowerBehavior != LONG_PRESS_POWER_GLOBAL_ACTIONS) {
401            // Remove accessibility shortcut if power key is not present
402            // nor long press power does not show global actions menu.
403            mSystemsCategory.removePreference(mGlobalGesturePreferenceScreen);
404        }
405    }
406
407    private void updateAllPreferences() {
408        updateServicesPreferences();
409        updateSystemPreferences();
410    }
411
412    private void updateServicesPreferences() {
413        // Since services category is auto generated we have to do a pass
414        // to generate it since services can come and go and then based on
415        // the global accessibility state to decided whether it is enabled.
416
417        // Generate.
418        mServicesCategory.removeAll();
419
420        AccessibilityManager accessibilityManager = AccessibilityManager.getInstance(getActivity());
421
422        List<AccessibilityServiceInfo> installedServices =
423                accessibilityManager.getInstalledAccessibilityServiceList();
424        Set<ComponentName> enabledServices = AccessibilityUtils.getEnabledServicesFromSettings(
425                getActivity());
426
427        final boolean accessibilityEnabled = Settings.Secure.getInt(getContentResolver(),
428                Settings.Secure.ACCESSIBILITY_ENABLED, 0) == 1;
429
430        for (int i = 0, count = installedServices.size(); i < count; ++i) {
431            AccessibilityServiceInfo info = installedServices.get(i);
432
433            PreferenceScreen preference = getPreferenceManager().createPreferenceScreen(
434                    getActivity());
435            String title = info.getResolveInfo().loadLabel(getPackageManager()).toString();
436
437            ServiceInfo serviceInfo = info.getResolveInfo().serviceInfo;
438            ComponentName componentName = new ComponentName(serviceInfo.packageName,
439                    serviceInfo.name);
440
441            preference.setKey(componentName.flattenToString());
442
443            preference.setTitle(title);
444            final boolean serviceEnabled = accessibilityEnabled
445                    && enabledServices.contains(componentName);
446            if (serviceEnabled) {
447                preference.setSummary(getString(R.string.accessibility_feature_state_on));
448            } else {
449                preference.setSummary(getString(R.string.accessibility_feature_state_off));
450            }
451
452            preference.setOrder(i);
453            preference.setFragment(ToggleAccessibilityServicePreferenceFragment.class.getName());
454            preference.setPersistent(true);
455
456            Bundle extras = preference.getExtras();
457            extras.putString(EXTRA_PREFERENCE_KEY, preference.getKey());
458            extras.putBoolean(EXTRA_CHECKED, serviceEnabled);
459            extras.putString(EXTRA_TITLE, title);
460
461            String description = info.loadDescription(getPackageManager());
462            if (TextUtils.isEmpty(description)) {
463                description = getString(R.string.accessibility_service_default_description);
464            }
465            extras.putString(EXTRA_SUMMARY, description);
466
467            String settingsClassName = info.getSettingsActivityName();
468            if (!TextUtils.isEmpty(settingsClassName)) {
469                extras.putString(EXTRA_SETTINGS_TITLE,
470                        getString(R.string.accessibility_menu_item_settings));
471                extras.putString(EXTRA_SETTINGS_COMPONENT_NAME,
472                        new ComponentName(info.getResolveInfo().serviceInfo.packageName,
473                                settingsClassName).flattenToString());
474            }
475
476            extras.putParcelable(EXTRA_COMPONENT_NAME, componentName);
477
478            mServicesCategory.addPreference(preference);
479        }
480
481        if (mServicesCategory.getPreferenceCount() == 0) {
482            if (mNoServicesMessagePreference == null) {
483                mNoServicesMessagePreference = new Preference(getActivity()) {
484                        @Override
485                    protected void onBindView(View view) {
486                        super.onBindView(view);
487                        TextView summaryView = (TextView) view.findViewById(R.id.summary);
488                        String title = getString(R.string.accessibility_no_services_installed);
489                        summaryView.setText(title);
490                    }
491                };
492                mNoServicesMessagePreference.setPersistent(false);
493                mNoServicesMessagePreference.setLayoutResource(
494                        R.layout.text_description_preference);
495                mNoServicesMessagePreference.setSelectable(false);
496            }
497            mServicesCategory.addPreference(mNoServicesMessagePreference);
498        }
499    }
500
501    private void updateSystemPreferences() {
502        // Large text.
503        try {
504            mCurConfig.updateFrom(ActivityManagerNative.getDefault().getConfiguration());
505        } catch (RemoteException re) {
506            /* ignore */
507        }
508        mToggleLargeTextPreference.setChecked(mCurConfig.fontScale == LARGE_FONT_SCALE);
509
510        // Power button ends calls.
511        if (KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_POWER)
512                && Utils.isVoiceCapable(getActivity())) {
513            final int incallPowerBehavior = Settings.Secure.getInt(getContentResolver(),
514                    Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR,
515                    Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_DEFAULT);
516            final boolean powerButtonEndsCall =
517                    (incallPowerBehavior == Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP);
518            mTogglePowerButtonEndsCallPreference.setChecked(powerButtonEndsCall);
519        }
520
521        // Auto-rotate screen
522        updateLockScreenRotationCheckbox();
523
524        // Speak passwords.
525        final boolean speakPasswordEnabled = Settings.Secure.getInt(getContentResolver(),
526                Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD, 0) != 0;
527        mToggleSpeakPasswordPreference.setChecked(speakPasswordEnabled);
528
529        // Long press timeout.
530        final int longPressTimeout = Settings.Secure.getInt(getContentResolver(),
531                Settings.Secure.LONG_PRESS_TIMEOUT, mLongPressTimeoutDefault);
532        String value = String.valueOf(longPressTimeout);
533        mSelectLongPressTimeoutPreference.setValue(value);
534        mSelectLongPressTimeoutPreference.setSummary(mLongPressTimeoutValuetoTitleMap.get(value));
535
536        updateFeatureSummary(Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED,
537                mCaptioningPreferenceScreen);
538        updateFeatureSummary(Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED,
539                mDisplayMagnificationPreferenceScreen);
540        updateFeatureSummary(Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED,
541                mDisplayInversionPreferenceScreen);
542        updateFeatureSummary(Settings.Secure.ACCESSIBILITY_DISPLAY_CONTRAST_ENABLED,
543                mDisplayContrastPreferenceScreen);
544        updateFeatureSummary(Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED,
545                mDisplayDaltonizerPreferenceScreen);
546
547        // Global gesture
548        final boolean globalGestureEnabled = Settings.Global.getInt(getContentResolver(),
549                Settings.Global.ENABLE_ACCESSIBILITY_GLOBAL_GESTURE_ENABLED, 0) == 1;
550        if (globalGestureEnabled) {
551            mGlobalGesturePreferenceScreen.setSummary(
552                    R.string.accessibility_global_gesture_preference_summary_on);
553        } else {
554            mGlobalGesturePreferenceScreen.setSummary(
555                    R.string.accessibility_global_gesture_preference_summary_off);
556        }
557    }
558
559    private void updateFeatureSummary(String prefKey, Preference pref) {
560        final boolean enabled = Settings.Secure.getInt(getContentResolver(), prefKey, 0) == 1;
561        pref.setSummary(enabled ? R.string.accessibility_feature_state_on
562                : R.string.accessibility_feature_state_off);
563    }
564
565    private void updateLockScreenRotationCheckbox() {
566        Context context = getActivity();
567        if (context != null) {
568            mToggleLockScreenRotationPreference.setChecked(
569                    !RotationPolicy.isRotationLocked(context));
570        }
571    }
572
573    private void loadInstalledServices() {
574        Set<ComponentName> installedServices = sInstalledServices;
575        installedServices.clear();
576
577        List<AccessibilityServiceInfo> installedServiceInfos =
578                AccessibilityManager.getInstance(getActivity())
579                        .getInstalledAccessibilityServiceList();
580        if (installedServiceInfos == null) {
581            return;
582        }
583
584        final int installedServiceInfoCount = installedServiceInfos.size();
585        for (int i = 0; i < installedServiceInfoCount; i++) {
586            ResolveInfo resolveInfo = installedServiceInfos.get(i).getResolveInfo();
587            ComponentName installedService = new ComponentName(
588                    resolveInfo.serviceInfo.packageName,
589                    resolveInfo.serviceInfo.name);
590            installedServices.add(installedService);
591        }
592    }
593}
594