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.admin.DevicePolicyManager; 21 import android.content.ComponentName; 22 import android.content.Context; 23 import android.content.pm.PackageManager; 24 import android.content.pm.ServiceInfo; 25 import android.content.res.Resources; 26 import android.net.Uri; 27 import android.os.Bundle; 28 import android.os.Handler; 29 import android.os.RemoteException; 30 import android.os.UserHandle; 31 import android.provider.SearchIndexableResource; 32 import android.provider.Settings; 33 import android.support.v14.preference.SwitchPreference; 34 import android.support.v7.preference.ListPreference; 35 import android.support.v7.preference.Preference; 36 import android.support.v7.preference.PreferenceCategory; 37 import android.support.v7.preference.PreferenceScreen; 38 import android.text.TextUtils; 39 import android.view.KeyCharacterMap; 40 import android.view.KeyEvent; 41 import android.view.accessibility.AccessibilityManager; 42 43 import com.android.internal.content.PackageMonitor; 44 import com.android.internal.logging.MetricsProto.MetricsEvent; 45 import com.android.internal.view.RotationPolicy; 46 import com.android.internal.view.RotationPolicy.RotationPolicyListener; 47 import com.android.settings.DialogCreatable; 48 import com.android.settings.R; 49 import com.android.settings.SettingsPreferenceFragment; 50 import com.android.settings.Utils; 51 import com.android.settings.search.BaseSearchIndexProvider; 52 import com.android.settings.search.Indexable; 53 import com.android.settings.search.SearchIndexableRaw; 54 import com.android.settingslib.RestrictedLockUtils; 55 import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; 56 import com.android.settingslib.RestrictedPreference; 57 import com.android.settingslib.accessibility.AccessibilityUtils; 58 59 import java.util.ArrayList; 60 import java.util.HashMap; 61 import java.util.HashSet; 62 import java.util.List; 63 import java.util.Map; 64 import java.util.Set; 65 66 /** 67 * Activity with the accessibility settings. 68 */ 69 public class AccessibilitySettings extends SettingsPreferenceFragment implements DialogCreatable, 70 Preference.OnPreferenceChangeListener, Indexable { 71 72 // Preference categories 73 private static final String SERVICES_CATEGORY = "services_category"; 74 private static final String SYSTEM_CATEGORY = "system_category"; 75 76 // Preferences 77 private static final String TOGGLE_HIGH_TEXT_CONTRAST_PREFERENCE = 78 "toggle_high_text_contrast_preference"; 79 private static final String TOGGLE_INVERSION_PREFERENCE = 80 "toggle_inversion_preference"; 81 private static final String TOGGLE_POWER_BUTTON_ENDS_CALL_PREFERENCE = 82 "toggle_power_button_ends_call_preference"; 83 private static final String TOGGLE_LOCK_SCREEN_ROTATION_PREFERENCE = 84 "toggle_lock_screen_rotation_preference"; 85 private static final String TOGGLE_SPEAK_PASSWORD_PREFERENCE = 86 "toggle_speak_password_preference"; 87 private static final String TOGGLE_LARGE_POINTER_ICON = 88 "toggle_large_pointer_icon"; 89 private static final String TOGGLE_MASTER_MONO = 90 "toggle_master_mono"; 91 private static final String SELECT_LONG_PRESS_TIMEOUT_PREFERENCE = 92 "select_long_press_timeout_preference"; 93 private static final String ENABLE_ACCESSIBILITY_GESTURE_PREFERENCE_SCREEN = 94 "enable_global_gesture_preference_screen"; 95 private static final String CAPTIONING_PREFERENCE_SCREEN = 96 "captioning_preference_screen"; 97 private static final String DISPLAY_MAGNIFICATION_PREFERENCE_SCREEN = 98 "screen_magnification_preference_screen"; 99 private static final String FONT_SIZE_PREFERENCE_SCREEN = 100 "font_size_preference_screen"; 101 private static final String AUTOCLICK_PREFERENCE_SCREEN = 102 "autoclick_preference_screen"; 103 private static final String DISPLAY_DALTONIZER_PREFERENCE_SCREEN = 104 "daltonizer_preference_screen"; 105 106 // Extras passed to sub-fragments. 107 static final String EXTRA_PREFERENCE_KEY = "preference_key"; 108 static final String EXTRA_CHECKED = "checked"; 109 static final String EXTRA_TITLE = "title"; 110 static final String EXTRA_SUMMARY = "summary"; 111 static final String EXTRA_SETTINGS_TITLE = "settings_title"; 112 static final String EXTRA_COMPONENT_NAME = "component_name"; 113 static final String EXTRA_SETTINGS_COMPONENT_NAME = "settings_component_name"; 114 115 // Timeout before we update the services if packages are added/removed 116 // since the AccessibilityManagerService has to do that processing first 117 // to generate the AccessibilityServiceInfo we need for proper 118 // presentation. 119 private static final long DELAY_UPDATE_SERVICES_MILLIS = 1000; 120 121 // Auxiliary members. 122 static final Set<ComponentName> sInstalledServices = new HashSet<>(); 123 124 private final Map<String, String> mLongPressTimeoutValuetoTitleMap = new HashMap<>(); 125 126 private final Handler mHandler = new Handler(); 127 128 private final Runnable mUpdateRunnable = new Runnable() { 129 @Override 130 public void run() { 131 if (getActivity() != null) { 132 updateServicesPreferences(); 133 } 134 } 135 }; 136 137 private final PackageMonitor mSettingsPackageMonitor = new PackageMonitor() { 138 @Override 139 public void onPackageAdded(String packageName, int uid) { 140 sendUpdate(); 141 } 142 143 @Override 144 public void onPackageAppeared(String packageName, int reason) { 145 sendUpdate(); 146 } 147 148 @Override 149 public void onPackageDisappeared(String packageName, int reason) { 150 sendUpdate(); 151 } 152 153 @Override 154 public void onPackageRemoved(String packageName, int uid) { 155 sendUpdate(); 156 } 157 158 private void sendUpdate() { 159 mHandler.postDelayed(mUpdateRunnable, DELAY_UPDATE_SERVICES_MILLIS); 160 } 161 }; 162 163 private final SettingsContentObserver mSettingsContentObserver = 164 new SettingsContentObserver(mHandler) { 165 @Override 166 public void onChange(boolean selfChange, Uri uri) { 167 updateServicesPreferences(); 168 } 169 }; 170 171 private final RotationPolicyListener mRotationPolicyListener = new RotationPolicyListener() { 172 @Override 173 public void onChange() { 174 updateLockScreenRotationCheckbox(); 175 } 176 }; 177 178 // Preference controls. 179 private PreferenceCategory mServicesCategory; 180 private PreferenceCategory mSystemsCategory; 181 182 private SwitchPreference mToggleHighTextContrastPreference; 183 private SwitchPreference mTogglePowerButtonEndsCallPreference; 184 private SwitchPreference mToggleLockScreenRotationPreference; 185 private SwitchPreference mToggleSpeakPasswordPreference; 186 private SwitchPreference mToggleLargePointerIconPreference; 187 private SwitchPreference mToggleMasterMonoPreference; 188 private ListPreference mSelectLongPressTimeoutPreference; 189 private Preference mNoServicesMessagePreference; 190 private PreferenceScreen mCaptioningPreferenceScreen; 191 private PreferenceScreen mDisplayMagnificationPreferenceScreen; 192 private PreferenceScreen mFontSizePreferenceScreen; 193 private PreferenceScreen mAutoclickPreferenceScreen; 194 private PreferenceScreen mGlobalGesturePreferenceScreen; 195 private PreferenceScreen mDisplayDaltonizerPreferenceScreen; 196 private SwitchPreference mToggleInversionPreference; 197 198 private int mLongPressTimeoutDefault; 199 200 private DevicePolicyManager mDpm; 201 202 @Override getMetricsCategory()203 protected int getMetricsCategory() { 204 return MetricsEvent.ACCESSIBILITY; 205 } 206 207 @Override getHelpResource()208 protected int getHelpResource() { 209 return R.string.help_uri_accessibility; 210 } 211 212 @Override onCreate(Bundle icicle)213 public void onCreate(Bundle icicle) { 214 super.onCreate(icicle); 215 addPreferencesFromResource(R.xml.accessibility_settings); 216 initializeAllPreferences(); 217 mDpm = (DevicePolicyManager) (getActivity() 218 .getSystemService(Context.DEVICE_POLICY_SERVICE)); 219 } 220 221 @Override onResume()222 public void onResume() { 223 super.onResume(); 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 onPause()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 onPreferenceChange(Preference preference, Object newValue)246 public boolean onPreferenceChange(Preference preference, Object newValue) { 247 if (mSelectLongPressTimeoutPreference == preference) { 248 handleLongPressTimeoutPreferenceChange((String) newValue); 249 return true; 250 } else if (mToggleInversionPreference == preference) { 251 handleToggleInversionPreferenceChange((Boolean) newValue); 252 return true; 253 } 254 return false; 255 } 256 handleLongPressTimeoutPreferenceChange(String stringValue)257 private void handleLongPressTimeoutPreferenceChange(String stringValue) { 258 Settings.Secure.putInt(getContentResolver(), 259 Settings.Secure.LONG_PRESS_TIMEOUT, Integer.parseInt(stringValue)); 260 mSelectLongPressTimeoutPreference.setSummary( 261 mLongPressTimeoutValuetoTitleMap.get(stringValue)); 262 } 263 handleToggleInversionPreferenceChange(boolean checked)264 private void handleToggleInversionPreferenceChange(boolean checked) { 265 Settings.Secure.putInt(getContentResolver(), 266 Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, (checked ? 1 : 0)); 267 } 268 269 @Override onPreferenceTreeClick(Preference preference)270 public boolean onPreferenceTreeClick(Preference preference) { 271 if (mToggleHighTextContrastPreference == preference) { 272 handleToggleTextContrastPreferenceClick(); 273 return true; 274 } else if (mTogglePowerButtonEndsCallPreference == preference) { 275 handleTogglePowerButtonEndsCallPreferenceClick(); 276 return true; 277 } else if (mToggleLockScreenRotationPreference == preference) { 278 handleLockScreenRotationPreferenceClick(); 279 return true; 280 } else if (mToggleSpeakPasswordPreference == preference) { 281 handleToggleSpeakPasswordPreferenceClick(); 282 return true; 283 } else if (mToggleLargePointerIconPreference == preference) { 284 handleToggleLargePointerIconPreferenceClick(); 285 return true; 286 } else if (mToggleMasterMonoPreference == preference) { 287 handleToggleMasterMonoPreferenceClick(); 288 return true; 289 } else if (mGlobalGesturePreferenceScreen == preference) { 290 handleToggleEnableAccessibilityGesturePreferenceClick(); 291 return true; 292 } else if (mDisplayMagnificationPreferenceScreen == preference) { 293 handleDisplayMagnificationPreferenceScreenClick(); 294 return true; 295 } 296 return super.onPreferenceTreeClick(preference); 297 } 298 handleToggleTextContrastPreferenceClick()299 private void handleToggleTextContrastPreferenceClick() { 300 Settings.Secure.putInt(getContentResolver(), 301 Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED, 302 (mToggleHighTextContrastPreference.isChecked() ? 1 : 0)); 303 } 304 handleTogglePowerButtonEndsCallPreferenceClick()305 private void handleTogglePowerButtonEndsCallPreferenceClick() { 306 Settings.Secure.putInt(getContentResolver(), 307 Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR, 308 (mTogglePowerButtonEndsCallPreference.isChecked() 309 ? Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP 310 : Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_SCREEN_OFF)); 311 } 312 handleLockScreenRotationPreferenceClick()313 private void handleLockScreenRotationPreferenceClick() { 314 RotationPolicy.setRotationLockForAccessibility(getActivity(), 315 !mToggleLockScreenRotationPreference.isChecked()); 316 } 317 handleToggleSpeakPasswordPreferenceClick()318 private void handleToggleSpeakPasswordPreferenceClick() { 319 Settings.Secure.putInt(getContentResolver(), 320 Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD, 321 mToggleSpeakPasswordPreference.isChecked() ? 1 : 0); 322 } 323 handleToggleLargePointerIconPreferenceClick()324 private void handleToggleLargePointerIconPreferenceClick() { 325 Settings.Secure.putInt(getContentResolver(), 326 Settings.Secure.ACCESSIBILITY_LARGE_POINTER_ICON, 327 mToggleLargePointerIconPreference.isChecked() ? 1 : 0); 328 } 329 handleToggleMasterMonoPreferenceClick()330 private void handleToggleMasterMonoPreferenceClick() { 331 Settings.System.putIntForUser(getContentResolver(), Settings.System.MASTER_MONO, 332 mToggleMasterMonoPreference.isChecked() ? 1 : 0, UserHandle.USER_CURRENT); 333 } 334 handleToggleEnableAccessibilityGesturePreferenceClick()335 private void handleToggleEnableAccessibilityGesturePreferenceClick() { 336 Bundle extras = mGlobalGesturePreferenceScreen.getExtras(); 337 extras.putString(EXTRA_TITLE, getString( 338 R.string.accessibility_global_gesture_preference_title)); 339 extras.putString(EXTRA_SUMMARY, getString( 340 R.string.accessibility_global_gesture_preference_description)); 341 extras.putBoolean(EXTRA_CHECKED, Settings.Global.getInt(getContentResolver(), 342 Settings.Global.ENABLE_ACCESSIBILITY_GLOBAL_GESTURE_ENABLED, 0) == 1); 343 super.onPreferenceTreeClick(mGlobalGesturePreferenceScreen); 344 } 345 handleDisplayMagnificationPreferenceScreenClick()346 private void handleDisplayMagnificationPreferenceScreenClick() { 347 Bundle extras = mDisplayMagnificationPreferenceScreen.getExtras(); 348 extras.putString(EXTRA_TITLE, getString( 349 R.string.accessibility_screen_magnification_title)); 350 extras.putCharSequence(EXTRA_SUMMARY, getActivity().getResources().getText( 351 R.string.accessibility_screen_magnification_summary)); 352 extras.putBoolean(EXTRA_CHECKED, Settings.Secure.getInt(getContentResolver(), 353 Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, 0) == 1); 354 super.onPreferenceTreeClick(mDisplayMagnificationPreferenceScreen); 355 } 356 initializeAllPreferences()357 private void initializeAllPreferences() { 358 mServicesCategory = (PreferenceCategory) findPreference(SERVICES_CATEGORY); 359 mSystemsCategory = (PreferenceCategory) findPreference(SYSTEM_CATEGORY); 360 361 // Text contrast. 362 mToggleHighTextContrastPreference = 363 (SwitchPreference) findPreference(TOGGLE_HIGH_TEXT_CONTRAST_PREFERENCE); 364 365 // Display inversion. 366 mToggleInversionPreference = (SwitchPreference) findPreference(TOGGLE_INVERSION_PREFERENCE); 367 mToggleInversionPreference.setOnPreferenceChangeListener(this); 368 369 // Power button ends calls. 370 mTogglePowerButtonEndsCallPreference = 371 (SwitchPreference) findPreference(TOGGLE_POWER_BUTTON_ENDS_CALL_PREFERENCE); 372 if (!KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_POWER) 373 || !Utils.isVoiceCapable(getActivity())) { 374 mSystemsCategory.removePreference(mTogglePowerButtonEndsCallPreference); 375 } 376 377 // Lock screen rotation. 378 mToggleLockScreenRotationPreference = 379 (SwitchPreference) findPreference(TOGGLE_LOCK_SCREEN_ROTATION_PREFERENCE); 380 if (!RotationPolicy.isRotationSupported(getActivity())) { 381 mSystemsCategory.removePreference(mToggleLockScreenRotationPreference); 382 } 383 384 // Speak passwords. 385 mToggleSpeakPasswordPreference = 386 (SwitchPreference) findPreference(TOGGLE_SPEAK_PASSWORD_PREFERENCE); 387 388 // Large pointer icon. 389 mToggleLargePointerIconPreference = 390 (SwitchPreference) findPreference(TOGGLE_LARGE_POINTER_ICON); 391 392 // Master Mono 393 mToggleMasterMonoPreference = 394 (SwitchPreference) findPreference(TOGGLE_MASTER_MONO); 395 396 // Long press timeout. 397 mSelectLongPressTimeoutPreference = 398 (ListPreference) findPreference(SELECT_LONG_PRESS_TIMEOUT_PREFERENCE); 399 mSelectLongPressTimeoutPreference.setOnPreferenceChangeListener(this); 400 if (mLongPressTimeoutValuetoTitleMap.size() == 0) { 401 String[] timeoutValues = getResources().getStringArray( 402 R.array.long_press_timeout_selector_values); 403 mLongPressTimeoutDefault = Integer.parseInt(timeoutValues[0]); 404 String[] timeoutTitles = getResources().getStringArray( 405 R.array.long_press_timeout_selector_titles); 406 final int timeoutValueCount = timeoutValues.length; 407 for (int i = 0; i < timeoutValueCount; i++) { 408 mLongPressTimeoutValuetoTitleMap.put(timeoutValues[i], timeoutTitles[i]); 409 } 410 } 411 412 // Captioning. 413 mCaptioningPreferenceScreen = (PreferenceScreen) findPreference( 414 CAPTIONING_PREFERENCE_SCREEN); 415 416 // Display magnification. 417 mDisplayMagnificationPreferenceScreen = (PreferenceScreen) findPreference( 418 DISPLAY_MAGNIFICATION_PREFERENCE_SCREEN); 419 420 // Font size. 421 mFontSizePreferenceScreen = (PreferenceScreen) findPreference( 422 FONT_SIZE_PREFERENCE_SCREEN); 423 424 // Autoclick after pointer stops. 425 mAutoclickPreferenceScreen = (PreferenceScreen) findPreference( 426 AUTOCLICK_PREFERENCE_SCREEN); 427 428 // Display color adjustments. 429 mDisplayDaltonizerPreferenceScreen = (PreferenceScreen) findPreference( 430 DISPLAY_DALTONIZER_PREFERENCE_SCREEN); 431 432 // Global gesture. 433 mGlobalGesturePreferenceScreen = 434 (PreferenceScreen) findPreference(ENABLE_ACCESSIBILITY_GESTURE_PREFERENCE_SCREEN); 435 final int longPressOnPowerBehavior = getActivity().getResources().getInteger( 436 com.android.internal.R.integer.config_longPressOnPowerBehavior); 437 final int LONG_PRESS_POWER_GLOBAL_ACTIONS = 1; 438 if (!KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_POWER) 439 || longPressOnPowerBehavior != LONG_PRESS_POWER_GLOBAL_ACTIONS) { 440 // Remove accessibility shortcut if power key is not present 441 // nor long press power does not show global actions menu. 442 mSystemsCategory.removePreference(mGlobalGesturePreferenceScreen); 443 } 444 } 445 updateAllPreferences()446 private void updateAllPreferences() { 447 updateServicesPreferences(); 448 updateSystemPreferences(); 449 } 450 updateServicesPreferences()451 private void updateServicesPreferences() { 452 // Since services category is auto generated we have to do a pass 453 // to generate it since services can come and go and then based on 454 // the global accessibility state to decided whether it is enabled. 455 456 // Generate. 457 mServicesCategory.removeAll(); 458 459 AccessibilityManager accessibilityManager = AccessibilityManager.getInstance(getActivity()); 460 461 List<AccessibilityServiceInfo> installedServices = 462 accessibilityManager.getInstalledAccessibilityServiceList(); 463 Set<ComponentName> enabledServices = AccessibilityUtils.getEnabledServicesFromSettings( 464 getActivity()); 465 List<String> permittedServices = mDpm.getPermittedAccessibilityServices( 466 UserHandle.myUserId()); 467 final boolean accessibilityEnabled = Settings.Secure.getInt(getContentResolver(), 468 Settings.Secure.ACCESSIBILITY_ENABLED, 0) == 1; 469 470 for (int i = 0, count = installedServices.size(); i < count; ++i) { 471 AccessibilityServiceInfo info = installedServices.get(i); 472 473 RestrictedPreference preference = new RestrictedPreference(getActivity()); 474 String title = info.getResolveInfo().loadLabel(getPackageManager()).toString(); 475 476 ServiceInfo serviceInfo = info.getResolveInfo().serviceInfo; 477 ComponentName componentName = new ComponentName(serviceInfo.packageName, 478 serviceInfo.name); 479 480 preference.setKey(componentName.flattenToString()); 481 482 preference.setTitle(title); 483 final boolean serviceEnabled = accessibilityEnabled 484 && enabledServices.contains(componentName); 485 String serviceEnabledString; 486 if (serviceEnabled) { 487 serviceEnabledString = getString(R.string.accessibility_feature_state_on); 488 } else { 489 serviceEnabledString = getString(R.string.accessibility_feature_state_off); 490 } 491 492 // Disable all accessibility services that are not permitted. 493 String packageName = serviceInfo.packageName; 494 boolean serviceAllowed = 495 permittedServices == null || permittedServices.contains(packageName); 496 if (!serviceAllowed && !serviceEnabled) { 497 EnforcedAdmin admin = RestrictedLockUtils.checkIfAccessibilityServiceDisallowed( 498 getActivity(), serviceInfo.packageName, UserHandle.myUserId()); 499 if (admin != null) { 500 preference.setDisabledByAdmin(admin); 501 } else { 502 preference.setEnabled(false); 503 } 504 } else { 505 preference.setEnabled(true); 506 } 507 508 preference.setSummary(serviceEnabledString); 509 510 preference.setOrder(i); 511 preference.setFragment(ToggleAccessibilityServicePreferenceFragment.class.getName()); 512 preference.setPersistent(true); 513 514 Bundle extras = preference.getExtras(); 515 extras.putString(EXTRA_PREFERENCE_KEY, preference.getKey()); 516 extras.putBoolean(EXTRA_CHECKED, serviceEnabled); 517 extras.putString(EXTRA_TITLE, title); 518 519 String description = info.loadDescription(getPackageManager()); 520 if (TextUtils.isEmpty(description)) { 521 description = getString(R.string.accessibility_service_default_description); 522 } 523 extras.putString(EXTRA_SUMMARY, description); 524 525 String settingsClassName = info.getSettingsActivityName(); 526 if (!TextUtils.isEmpty(settingsClassName)) { 527 extras.putString(EXTRA_SETTINGS_TITLE, 528 getString(R.string.accessibility_menu_item_settings)); 529 extras.putString(EXTRA_SETTINGS_COMPONENT_NAME, 530 new ComponentName(info.getResolveInfo().serviceInfo.packageName, 531 settingsClassName).flattenToString()); 532 } 533 534 extras.putParcelable(EXTRA_COMPONENT_NAME, componentName); 535 536 mServicesCategory.addPreference(preference); 537 } 538 539 if (mServicesCategory.getPreferenceCount() == 0) { 540 if (mNoServicesMessagePreference == null) { 541 mNoServicesMessagePreference = new Preference(getPrefContext()); 542 mNoServicesMessagePreference.setPersistent(false); 543 mNoServicesMessagePreference.setLayoutResource( 544 R.layout.text_description_preference); 545 mNoServicesMessagePreference.setSelectable(false); 546 mNoServicesMessagePreference.setSummary( 547 getString(R.string.accessibility_no_services_installed)); 548 } 549 mServicesCategory.addPreference(mNoServicesMessagePreference); 550 } 551 } 552 updateSystemPreferences()553 private void updateSystemPreferences() { 554 // Text contrast. 555 mToggleHighTextContrastPreference.setChecked( 556 Settings.Secure.getInt(getContentResolver(), 557 Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED, 0) == 1); 558 559 // If the quick setting is enabled, the preference MUST be enabled. 560 mToggleInversionPreference.setChecked(Settings.Secure.getInt(getContentResolver(), 561 Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, 0) == 1); 562 563 // Power button ends calls. 564 if (KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_POWER) 565 && Utils.isVoiceCapable(getActivity())) { 566 final int incallPowerBehavior = Settings.Secure.getInt(getContentResolver(), 567 Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR, 568 Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_DEFAULT); 569 final boolean powerButtonEndsCall = 570 (incallPowerBehavior == Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP); 571 mTogglePowerButtonEndsCallPreference.setChecked(powerButtonEndsCall); 572 } 573 574 // Auto-rotate screen 575 updateLockScreenRotationCheckbox(); 576 577 // Speak passwords. 578 final boolean speakPasswordEnabled = Settings.Secure.getInt(getContentResolver(), 579 Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD, 0) != 0; 580 mToggleSpeakPasswordPreference.setChecked(speakPasswordEnabled); 581 582 // Large pointer icon. 583 mToggleLargePointerIconPreference.setChecked(Settings.Secure.getInt(getContentResolver(), 584 Settings.Secure.ACCESSIBILITY_LARGE_POINTER_ICON, 0) != 0); 585 586 // Master mono 587 updateMasterMono(); 588 589 // Long press timeout. 590 final int longPressTimeout = Settings.Secure.getInt(getContentResolver(), 591 Settings.Secure.LONG_PRESS_TIMEOUT, mLongPressTimeoutDefault); 592 String value = String.valueOf(longPressTimeout); 593 mSelectLongPressTimeoutPreference.setValue(value); 594 mSelectLongPressTimeoutPreference.setSummary(mLongPressTimeoutValuetoTitleMap.get(value)); 595 596 updateFeatureSummary(Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED, 597 mCaptioningPreferenceScreen); 598 updateFeatureSummary(Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, 599 mDisplayMagnificationPreferenceScreen); 600 updateFeatureSummary(Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 601 mDisplayDaltonizerPreferenceScreen); 602 603 updateFontSizeSummary(mFontSizePreferenceScreen); 604 605 updateAutoclickSummary(mAutoclickPreferenceScreen); 606 607 // Global gesture 608 final boolean globalGestureEnabled = Settings.Global.getInt(getContentResolver(), 609 Settings.Global.ENABLE_ACCESSIBILITY_GLOBAL_GESTURE_ENABLED, 0) == 1; 610 if (globalGestureEnabled) { 611 mGlobalGesturePreferenceScreen.setSummary( 612 R.string.accessibility_global_gesture_preference_summary_on); 613 } else { 614 mGlobalGesturePreferenceScreen.setSummary( 615 R.string.accessibility_global_gesture_preference_summary_off); 616 } 617 } 618 updateFeatureSummary(String prefKey, Preference pref)619 private void updateFeatureSummary(String prefKey, Preference pref) { 620 final boolean enabled = Settings.Secure.getInt(getContentResolver(), prefKey, 0) == 1; 621 pref.setSummary(enabled ? R.string.accessibility_feature_state_on 622 : R.string.accessibility_feature_state_off); 623 } 624 updateAutoclickSummary(Preference pref)625 private void updateAutoclickSummary(Preference pref) { 626 final boolean enabled = Settings.Secure.getInt( 627 getContentResolver(), Settings.Secure.ACCESSIBILITY_AUTOCLICK_ENABLED, 0) == 1; 628 if (!enabled) { 629 pref.setSummary(R.string.accessibility_feature_state_off); 630 return; 631 } 632 int delay = Settings.Secure.getInt( 633 getContentResolver(), Settings.Secure.ACCESSIBILITY_AUTOCLICK_DELAY, 634 AccessibilityManager.AUTOCLICK_DELAY_DEFAULT); 635 pref.setSummary(ToggleAutoclickPreferenceFragment.getAutoclickPreferenceSummary( 636 getResources(), delay)); 637 } 638 updateFontSizeSummary(Preference pref)639 private void updateFontSizeSummary(Preference pref) { 640 final float currentScale = Settings.System.getFloat(getContext().getContentResolver(), 641 Settings.System.FONT_SCALE, 1.0f); 642 final Resources res = getContext().getResources(); 643 final String[] entries = res.getStringArray(R.array.entries_font_size); 644 final String[] strEntryValues = res.getStringArray(R.array.entryvalues_font_size); 645 final int index = ToggleFontSizePreferenceFragment.fontSizeValueToIndex(currentScale, 646 strEntryValues); 647 pref.setSummary(entries[index]); 648 } 649 updateLockScreenRotationCheckbox()650 private void updateLockScreenRotationCheckbox() { 651 Context context = getActivity(); 652 if (context != null) { 653 mToggleLockScreenRotationPreference.setChecked( 654 !RotationPolicy.isRotationLocked(context)); 655 } 656 } 657 updateMasterMono()658 private void updateMasterMono() { 659 final boolean masterMono = Settings.System.getIntForUser( 660 getContentResolver(), Settings.System.MASTER_MONO, 661 0 /* default */, UserHandle.USER_CURRENT) == 1; 662 mToggleMasterMonoPreference.setChecked(masterMono); 663 } 664 665 public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = 666 new BaseSearchIndexProvider() { 667 @Override 668 public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) { 669 List<SearchIndexableRaw> indexables = new ArrayList<SearchIndexableRaw>(); 670 671 PackageManager packageManager = context.getPackageManager(); 672 AccessibilityManager accessibilityManager = (AccessibilityManager) 673 context.getSystemService(Context.ACCESSIBILITY_SERVICE); 674 675 String screenTitle = context.getResources().getString( 676 R.string.accessibility_services_title); 677 678 // Indexing all services, regardless if enabled. 679 List<AccessibilityServiceInfo> services = accessibilityManager 680 .getInstalledAccessibilityServiceList(); 681 final int serviceCount = services.size(); 682 for (int i = 0; i < serviceCount; i++) { 683 AccessibilityServiceInfo service = services.get(i); 684 if (service == null || service.getResolveInfo() == null) { 685 continue; 686 } 687 688 ServiceInfo serviceInfo = service.getResolveInfo().serviceInfo; 689 ComponentName componentName = new ComponentName(serviceInfo.packageName, 690 serviceInfo.name); 691 692 SearchIndexableRaw indexable = new SearchIndexableRaw(context); 693 indexable.key = componentName.flattenToString(); 694 indexable.title = service.getResolveInfo().loadLabel(packageManager).toString(); 695 indexable.summaryOn = context.getString(R.string.accessibility_feature_state_on); 696 indexable.summaryOff = context.getString(R.string.accessibility_feature_state_off); 697 indexable.screenTitle = screenTitle; 698 indexables.add(indexable); 699 } 700 701 return indexables; 702 } 703 704 @Override 705 public List<SearchIndexableResource> getXmlResourcesToIndex(Context context, 706 boolean enabled) { 707 List<SearchIndexableResource> indexables = new ArrayList<SearchIndexableResource>(); 708 SearchIndexableResource indexable = new SearchIndexableResource(context); 709 indexable.xmlResId = R.xml.accessibility_settings; 710 indexables.add(indexable); 711 return indexables; 712 } 713 }; 714 } 715