OSDN Git Service

Aligned buttons on the Wi-Fi Assistant Card.
[android-x86/packages-apps-Settings.git] / src / com / android / settings / accessibility / AccessibilitySettings.java
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 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;
48
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;
59
60 import java.util.ArrayList;
61 import java.util.HashMap;
62 import java.util.HashSet;
63 import java.util.List;
64 import java.util.Map;
65 import java.util.Set;
66
67 /**
68  * Activity with the accessibility settings.
69  */
70 public class AccessibilitySettings extends SettingsPreferenceFragment implements DialogCreatable,
71         Preference.OnPreferenceChangeListener, Indexable {
72
73     private static final float LARGE_FONT_SCALE = 1.3f;
74
75     static final char ENABLED_ACCESSIBILITY_SERVICES_SEPARATOR = ':';
76
77     // Preference categories
78     private static final String SERVICES_CATEGORY = "services_category";
79     private static final String SYSTEM_CATEGORY = "system_category";
80
81     // Preferences
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";
104
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";
113
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
117     // presentation.
118     private static final long DELAY_UPDATE_SERVICES_MILLIS = 1000;
119
120     // Auxiliary members.
121     final static SimpleStringSplitter sStringColonSplitter =
122             new SimpleStringSplitter(ENABLED_ACCESSIBILITY_SERVICES_SEPARATOR);
123
124     static final Set<ComponentName> sInstalledServices = new HashSet<ComponentName>();
125
126     private final Map<String, String> mLongPressTimeoutValuetoTitleMap =
127             new HashMap<String, String>();
128
129     private final Configuration mCurConfig = new Configuration();
130
131     private final Handler mHandler = new Handler();
132
133     private final Runnable mUpdateRunnable = new Runnable() {
134         @Override
135         public void run() {
136             loadInstalledServices();
137             updateServicesPreferences();
138         }
139     };
140
141     private final PackageMonitor mSettingsPackageMonitor = new PackageMonitor() {
142         @Override
143         public void onPackageAdded(String packageName, int uid) {
144             sendUpdate();
145         }
146
147         @Override
148         public void onPackageAppeared(String packageName, int reason) {
149             sendUpdate();
150         }
151
152         @Override
153         public void onPackageDisappeared(String packageName, int reason) {
154             sendUpdate();
155         }
156
157         @Override
158         public void onPackageRemoved(String packageName, int uid) {
159             sendUpdate();
160         }
161
162         private void sendUpdate() {
163             mHandler.postDelayed(mUpdateRunnable, DELAY_UPDATE_SERVICES_MILLIS);
164         }
165     };
166
167     private final SettingsContentObserver mSettingsContentObserver =
168             new SettingsContentObserver(mHandler) {
169                 @Override
170                 public void onChange(boolean selfChange, Uri uri) {
171                     loadInstalledServices();
172                     updateServicesPreferences();
173                 }
174             };
175
176     private final RotationPolicyListener mRotationPolicyListener = new RotationPolicyListener() {
177         @Override
178         public void onChange() {
179             updateLockScreenRotationCheckbox();
180         }
181     };
182
183     // Preference controls.
184     private PreferenceCategory mServicesCategory;
185     private PreferenceCategory mSystemsCategory;
186
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;
199
200     private int mLongPressTimeoutDefault;
201
202     private DevicePolicyManager mDpm;
203
204     @Override
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));
211     }
212
213     @Override
214     public void onResume() {
215         super.onResume();
216         loadInstalledServices();
217         updateAllPreferences();
218
219         mSettingsPackageMonitor.register(getActivity(), getActivity().getMainLooper(), false);
220         mSettingsContentObserver.register(getContentResolver());
221         if (RotationPolicy.isRotationSupported(getActivity())) {
222             RotationPolicy.registerRotationPolicyListener(getActivity(),
223                     mRotationPolicyListener);
224         }
225     }
226
227     @Override
228     public void onPause() {
229         mSettingsPackageMonitor.unregister();
230         mSettingsContentObserver.unregister(getContentResolver());
231         if (RotationPolicy.isRotationSupported(getActivity())) {
232             RotationPolicy.unregisterRotationPolicyListener(getActivity(),
233                     mRotationPolicyListener);
234         }
235         super.onPause();
236     }
237
238     @Override
239     public boolean onPreferenceChange(Preference preference, Object newValue) {
240         if (mSelectLongPressTimeoutPreference == preference) {
241             handleLongPressTimeoutPreferenceChange((String) newValue);
242             return true;
243         } else if (mToggleInversionPreference == preference) {
244             handleToggleInversionPreferenceChange((Boolean) newValue);
245             return true;
246         }
247         return false;
248     }
249
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));
255     }
256
257     private void handleToggleInversionPreferenceChange(boolean checked) {
258         Settings.Secure.putInt(getContentResolver(),
259                 Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, (checked ? 1 : 0));
260     }
261
262     @Override
263     public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
264         if (mToggleLargeTextPreference == preference) {
265             handleToggleLargeTextPreferenceClick();
266             return true;
267         } else if (mToggleHighTextContrastPreference == preference) {
268             handleToggleTextContrastPreferenceClick();
269             return true;
270         } else if (mTogglePowerButtonEndsCallPreference == preference) {
271             handleTogglePowerButtonEndsCallPreferenceClick();
272             return true;
273         } else if (mToggleLockScreenRotationPreference == preference) {
274             handleLockScreenRotationPreferenceClick();
275             return true;
276         } else if (mToggleSpeakPasswordPreference == preference) {
277             handleToggleSpeakPasswordPreferenceClick();
278             return true;
279         } else if (mGlobalGesturePreferenceScreen == preference) {
280             handleToggleEnableAccessibilityGesturePreferenceClick();
281             return true;
282         } else if (mDisplayMagnificationPreferenceScreen == preference) {
283             handleDisplayMagnificationPreferenceScreenClick();
284             return true;
285         }
286         return super.onPreferenceTreeClick(preferenceScreen, preference);
287     }
288
289     private void handleToggleLargeTextPreferenceClick() {
290         try {
291             mCurConfig.fontScale = mToggleLargeTextPreference.isChecked() ? LARGE_FONT_SCALE : 1;
292             ActivityManagerNative.getDefault().updatePersistentConfiguration(mCurConfig);
293         } catch (RemoteException re) {
294             /* ignore */
295         }
296     }
297
298     private void handleToggleTextContrastPreferenceClick() {
299         Settings.Secure.putInt(getContentResolver(),
300                 Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED,
301                 (mToggleHighTextContrastPreference.isChecked() ? 1 : 0));
302     }
303
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));
310     }
311
312     private void handleLockScreenRotationPreferenceClick() {
313         RotationPolicy.setRotationLockForAccessibility(getActivity(),
314                 !mToggleLockScreenRotationPreference.isChecked());
315     }
316
317     private void handleToggleSpeakPasswordPreferenceClick() {
318         Settings.Secure.putInt(getContentResolver(),
319                 Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD,
320                 mToggleSpeakPasswordPreference.isChecked() ? 1 : 0);
321     }
322
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);
333     }
334
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);
345     }
346
347     private void initializeAllPreferences() {
348         mServicesCategory = (PreferenceCategory) findPreference(SERVICES_CATEGORY);
349         mSystemsCategory = (PreferenceCategory) findPreference(SYSTEM_CATEGORY);
350
351         // Large text.
352         mToggleLargeTextPreference =
353                 (CheckBoxPreference) findPreference(TOGGLE_LARGE_TEXT_PREFERENCE);
354
355         // Text contrast.
356         mToggleHighTextContrastPreference =
357                 (CheckBoxPreference) findPreference(TOGGLE_HIGH_TEXT_CONTRAST_PREFERENCE);
358
359         // Display inversion.
360         mToggleInversionPreference = (SwitchPreference) findPreference(TOGGLE_INVERSION_PREFERENCE);
361         mToggleInversionPreference.setOnPreferenceChangeListener(this);
362
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);
369         }
370
371         // Lock screen rotation.
372         mToggleLockScreenRotationPreference =
373                 (CheckBoxPreference) findPreference(TOGGLE_LOCK_SCREEN_ROTATION_PREFERENCE);
374         if (!RotationPolicy.isRotationSupported(getActivity())) {
375             mSystemsCategory.removePreference(mToggleLockScreenRotationPreference);
376         }
377
378         // Speak passwords.
379         mToggleSpeakPasswordPreference =
380                 (CheckBoxPreference) findPreference(TOGGLE_SPEAK_PASSWORD_PREFERENCE);
381
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]);
395             }
396         }
397
398         // Captioning.
399         mCaptioningPreferenceScreen = (PreferenceScreen) findPreference(
400                 CAPTIONING_PREFERENCE_SCREEN);
401
402         // Display magnification.
403         mDisplayMagnificationPreferenceScreen = (PreferenceScreen) findPreference(
404                 DISPLAY_MAGNIFICATION_PREFERENCE_SCREEN);
405
406         // Display color adjustments.
407         mDisplayDaltonizerPreferenceScreen = (PreferenceScreen) findPreference(
408                 DISPLAY_DALTONIZER_PREFERENCE_SCREEN);
409
410         // Global gesture.
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);
421         }
422     }
423
424     private void updateAllPreferences() {
425         updateServicesPreferences();
426         updateSystemPreferences();
427     }
428
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.
433
434         // Generate.
435         mServicesCategory.removeAll();
436
437         AccessibilityManager accessibilityManager = AccessibilityManager.getInstance(getActivity());
438
439         List<AccessibilityServiceInfo> installedServices =
440                 accessibilityManager.getInstalledAccessibilityServiceList();
441         Set<ComponentName> enabledServices = AccessibilityUtils.getEnabledServicesFromSettings(
442                 getActivity());
443         List<String> permittedServices = mDpm.getPermittedAccessibilityServices(
444                 UserHandle.myUserId());
445         final boolean accessibilityEnabled = Settings.Secure.getInt(getContentResolver(),
446                 Settings.Secure.ACCESSIBILITY_ENABLED, 0) == 1;
447
448         for (int i = 0, count = installedServices.size(); i < count; ++i) {
449             AccessibilityServiceInfo info = installedServices.get(i);
450
451             PreferenceScreen preference = getPreferenceManager().createPreferenceScreen(
452                     getActivity());
453             String title = info.getResolveInfo().loadLabel(getPackageManager()).toString();
454
455             ServiceInfo serviceInfo = info.getResolveInfo().serviceInfo;
456             ComponentName componentName = new ComponentName(serviceInfo.packageName,
457                     serviceInfo.name);
458
459             preference.setKey(componentName.flattenToString());
460
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);
467             } else {
468                 serviceEnabledString = getString(R.string.accessibility_feature_state_off);
469             }
470
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);
476
477             String summaryString;
478             if (serviceAllowed) {
479                 summaryString = serviceEnabledString;
480             } else  {
481                 summaryString = getString(R.string.accessibility_feature_or_input_method_not_allowed);
482             }
483             preference.setSummary(summaryString);
484
485             preference.setOrder(i);
486             preference.setFragment(ToggleAccessibilityServicePreferenceFragment.class.getName());
487             preference.setPersistent(true);
488
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);
493
494             String description = info.loadDescription(getPackageManager());
495             if (TextUtils.isEmpty(description)) {
496                 description = getString(R.string.accessibility_service_default_description);
497             }
498             extras.putString(EXTRA_SUMMARY, description);
499
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());
507             }
508
509             extras.putParcelable(EXTRA_COMPONENT_NAME, componentName);
510
511             mServicesCategory.addPreference(preference);
512         }
513
514         if (mServicesCategory.getPreferenceCount() == 0) {
515             if (mNoServicesMessagePreference == null) {
516                 mNoServicesMessagePreference = new Preference(getActivity()) {
517                         @Override
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);
523                     }
524                 };
525                 mNoServicesMessagePreference.setPersistent(false);
526                 mNoServicesMessagePreference.setLayoutResource(
527                         R.layout.text_description_preference);
528                 mNoServicesMessagePreference.setSelectable(false);
529             }
530             mServicesCategory.addPreference(mNoServicesMessagePreference);
531         }
532     }
533
534     private void updateSystemPreferences() {
535         // Large text.
536         try {
537             mCurConfig.updateFrom(ActivityManagerNative.getDefault().getConfiguration());
538         } catch (RemoteException re) {
539             /* ignore */
540         }
541         mToggleLargeTextPreference.setChecked(mCurConfig.fontScale == LARGE_FONT_SCALE);
542
543         mToggleHighTextContrastPreference.setChecked(
544                 Settings.Secure.getInt(getContentResolver(),
545                         Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED, 0) == 1);
546
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);
550
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);
560         }
561
562         // Auto-rotate screen
563         updateLockScreenRotationCheckbox();
564
565         // Speak passwords.
566         final boolean speakPasswordEnabled = Settings.Secure.getInt(getContentResolver(),
567                 Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD, 0) != 0;
568         mToggleSpeakPasswordPreference.setChecked(speakPasswordEnabled);
569
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));
576
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);
583
584         // Global gesture
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);
590         } else {
591             mGlobalGesturePreferenceScreen.setSummary(
592                     R.string.accessibility_global_gesture_preference_summary_off);
593         }
594     }
595
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);
600     }
601
602     private void updateLockScreenRotationCheckbox() {
603         Context context = getActivity();
604         if (context != null) {
605             mToggleLockScreenRotationPreference.setChecked(
606                     !RotationPolicy.isRotationLocked(context));
607         }
608     }
609
610     private void loadInstalledServices() {
611         Set<ComponentName> installedServices = sInstalledServices;
612         installedServices.clear();
613
614         List<AccessibilityServiceInfo> installedServiceInfos =
615                 AccessibilityManager.getInstance(getActivity())
616                         .getInstalledAccessibilityServiceList();
617         if (installedServiceInfos == null) {
618             return;
619         }
620
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);
628         }
629     }
630
631     public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
632             new BaseSearchIndexProvider() {
633         @Override
634         public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) {
635             List<SearchIndexableRaw> indexables = new ArrayList<SearchIndexableRaw>();
636
637             PackageManager packageManager = context.getPackageManager();
638             AccessibilityManager accessibilityManager = (AccessibilityManager)
639                     context.getSystemService(Context.ACCESSIBILITY_SERVICE);
640
641             String screenTitle = context.getResources().getString(
642                     R.string.accessibility_services_title);
643
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) {
651                     continue;
652                 }
653
654                 ServiceInfo serviceInfo = service.getResolveInfo().serviceInfo;
655                 ComponentName componentName = new ComponentName(serviceInfo.packageName,
656                         serviceInfo.name);
657
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);
665             }
666
667             return indexables;
668         }
669
670         @Override
671         public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
672                boolean enabled) {
673             List<SearchIndexableResource> indexables = new ArrayList<SearchIndexableResource>();
674             SearchIndexableResource indexable = new SearchIndexableResource(context);
675             indexable.xmlResId = R.xml.accessibility_settings;
676             indexables.add(indexable);
677             return indexables;
678         }
679     };
680 }