1 /* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.settings.accessibility; 18 19 import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME; 20 import static com.android.settings.accessibility.AccessibilityDialogUtils.DialogEnums; 21 import static com.android.settings.accessibility.AccessibilityUtil.State.OFF; 22 import static com.android.settings.accessibility.AccessibilityUtil.State.ON; 23 24 import android.app.Dialog; 25 import android.app.settings.SettingsEnums; 26 import android.content.ContentResolver; 27 import android.content.Context; 28 import android.content.DialogInterface; 29 import android.icu.text.CaseMap; 30 import android.net.Uri; 31 import android.os.Bundle; 32 import android.provider.Settings; 33 import android.text.TextUtils; 34 import android.view.LayoutInflater; 35 import android.view.View; 36 import android.view.ViewGroup; 37 import android.view.accessibility.AccessibilityManager; 38 import android.view.accessibility.AccessibilityManager.TouchExplorationStateChangeListener; 39 import android.widget.CheckBox; 40 41 import androidx.preference.Preference; 42 import androidx.preference.PreferenceCategory; 43 44 import com.android.internal.annotations.VisibleForTesting; 45 import com.android.settings.DialogCreatable; 46 import com.android.settings.R; 47 import com.android.settings.accessibility.AccessibilityDialogUtils.DialogType; 48 import com.android.settings.accessibility.AccessibilityUtil.UserShortcutType; 49 import com.android.settings.utils.LocaleUtils; 50 51 import com.google.android.setupcompat.util.WizardManagerHelper; 52 53 import java.util.ArrayList; 54 import java.util.List; 55 import java.util.Locale; 56 import java.util.StringJoiner; 57 58 /** 59 * Fragment that shows the actual UI for providing basic magnification accessibility service setup 60 * and does not have toggle bar to turn on service to use. 61 */ 62 public class ToggleScreenMagnificationPreferenceFragment extends 63 ToggleFeaturePreferenceFragment implements 64 MagnificationModePreferenceController.DialogHelper { 65 // TODO(b/147021230): Move duplicated functions with android/internal/accessibility into util. 66 private TouchExplorationStateChangeListener mTouchExplorationStateChangeListener; 67 68 private CheckBox mSoftwareTypeCheckBox; 69 private CheckBox mHardwareTypeCheckBox; 70 private CheckBox mTripleTapTypeCheckBox; 71 72 private static final char COMPONENT_NAME_SEPARATOR = ':'; 73 private static final TextUtils.SimpleStringSplitter sStringColonSplitter = 74 new TextUtils.SimpleStringSplitter(COMPONENT_NAME_SEPARATOR); 75 76 private MagnificationModePreferenceController mModePreferenceController; 77 private DialogCreatable mDialogDelegate; 78 79 @Override onCreate(Bundle savedInstanceState)80 public void onCreate(Bundle savedInstanceState) { 81 super.onCreate(savedInstanceState); 82 getActivity().setTitle(R.string.accessibility_screen_magnification_title); 83 } 84 85 @Override onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)86 public View onCreateView(LayoutInflater inflater, ViewGroup container, 87 Bundle savedInstanceState) { 88 mPackageName = getString(R.string.accessibility_screen_magnification_title); 89 mImageUri = new Uri.Builder().scheme(ContentResolver.SCHEME_ANDROID_RESOURCE) 90 .authority(getPrefContext().getPackageName()) 91 .appendPath(String.valueOf(R.raw.accessibility_magnification_banner)) 92 .build(); 93 mTouchExplorationStateChangeListener = isTouchExplorationEnabled -> { 94 removeDialog(DialogEnums.EDIT_SHORTCUT); 95 mShortcutPreference.setSummary(getShortcutTypeSummary(getPrefContext())); 96 }; 97 98 final View view = super.onCreateView(inflater, container, savedInstanceState); 99 updateFooterPreference(); 100 return view; 101 } 102 updateFooterPreference()103 private void updateFooterPreference() { 104 final String title = getPrefContext().getString( 105 R.string.accessibility_screen_magnification_about_title); 106 final String learnMoreContentDescription = getPrefContext().getString( 107 R.string.accessibility_screen_magnification_footer_learn_more_content_description); 108 mFooterPreferenceController.setIntroductionTitle(title); 109 mFooterPreferenceController.setupHelpLink(getHelpResource(), learnMoreContentDescription); 110 mFooterPreferenceController.displayPreference(getPreferenceScreen()); 111 } 112 113 @Override onResume()114 public void onResume() { 115 super.onResume(); 116 117 final AccessibilityManager am = getPrefContext().getSystemService( 118 AccessibilityManager.class); 119 am.addTouchExplorationStateChangeListener(mTouchExplorationStateChangeListener); 120 } 121 122 @Override onPause()123 public void onPause() { 124 final AccessibilityManager am = getPrefContext().getSystemService( 125 AccessibilityManager.class); 126 am.removeTouchExplorationStateChangeListener(mTouchExplorationStateChangeListener); 127 128 super.onPause(); 129 } 130 131 @Override onCreateDialog(int dialogId)132 public Dialog onCreateDialog(int dialogId) { 133 if (mDialogDelegate != null) { 134 mDialog = mDialogDelegate.onCreateDialog(dialogId); 135 if (mDialog != null) { 136 return mDialog; 137 } 138 } 139 switch (dialogId) { 140 case DialogEnums.GESTURE_NAVIGATION_TUTORIAL: 141 return AccessibilityGestureNavigationTutorial 142 .showAccessibilityGestureTutorialDialog(getPrefContext()); 143 case DialogEnums.MAGNIFICATION_EDIT_SHORTCUT: 144 final CharSequence dialogTitle = getPrefContext().getString( 145 R.string.accessibility_shortcut_title, mPackageName); 146 final int dialogType = WizardManagerHelper.isAnySetupWizard(getIntent()) 147 ? DialogType.EDIT_SHORTCUT_MAGNIFICATION_SUW 148 : DialogType.EDIT_SHORTCUT_MAGNIFICATION; 149 mDialog = AccessibilityDialogUtils.showEditShortcutDialog(getPrefContext(), 150 dialogType, dialogTitle, this::callOnAlertDialogCheckboxClicked); 151 setupMagnificationEditShortcutDialog(mDialog); 152 return mDialog; 153 default: 154 return super.onCreateDialog(dialogId); 155 } 156 } 157 158 @Override initSettingsPreference()159 protected void initSettingsPreference() { 160 // If the device doesn't support magnification area, it should hide the settings preference. 161 if (!getContext().getResources().getBoolean( 162 com.android.internal.R.bool.config_magnification_area)) { 163 return; 164 } 165 mSettingsPreference = new Preference(getPrefContext()); 166 mSettingsPreference.setTitle(R.string.accessibility_magnification_mode_title); 167 mSettingsPreference.setKey(MagnificationModePreferenceController.PREF_KEY); 168 mSettingsPreference.setPersistent(false); 169 170 final PreferenceCategory generalCategory = findPreference(KEY_GENERAL_CATEGORY); 171 generalCategory.addPreference(mSettingsPreference); 172 173 mModePreferenceController = new MagnificationModePreferenceController(getContext(), 174 MagnificationModePreferenceController.PREF_KEY); 175 mModePreferenceController.setDialogHelper(this); 176 getSettingsLifecycle().addObserver(mModePreferenceController); 177 mModePreferenceController.displayPreference(getPreferenceScreen()); 178 } 179 180 @Override showDialog(int dialogId)181 public void showDialog(int dialogId) { 182 super.showDialog(dialogId); 183 } 184 185 @Override setDialogDelegate(DialogCreatable delegate)186 public void setDialogDelegate(DialogCreatable delegate) { 187 mDialogDelegate = delegate; 188 } 189 190 @Override getShortcutTypeCheckBoxValue()191 protected int getShortcutTypeCheckBoxValue() { 192 if (mSoftwareTypeCheckBox == null || mHardwareTypeCheckBox == null) { 193 return NOT_SET; 194 } 195 196 int value = UserShortcutType.EMPTY; 197 if (mSoftwareTypeCheckBox.isChecked()) { 198 value |= UserShortcutType.SOFTWARE; 199 } 200 if (mHardwareTypeCheckBox.isChecked()) { 201 value |= UserShortcutType.HARDWARE; 202 } 203 if (mTripleTapTypeCheckBox.isChecked()) { 204 value |= UserShortcutType.TRIPLETAP; 205 } 206 return value; 207 } 208 209 @VisibleForTesting setupMagnificationEditShortcutDialog(Dialog dialog)210 void setupMagnificationEditShortcutDialog(Dialog dialog) { 211 final View dialogSoftwareView = dialog.findViewById(R.id.software_shortcut); 212 mSoftwareTypeCheckBox = dialogSoftwareView.findViewById(R.id.checkbox); 213 setDialogTextAreaClickListener(dialogSoftwareView, mSoftwareTypeCheckBox); 214 215 final View dialogHardwareView = dialog.findViewById(R.id.hardware_shortcut); 216 mHardwareTypeCheckBox = dialogHardwareView.findViewById(R.id.checkbox); 217 setDialogTextAreaClickListener(dialogHardwareView, mHardwareTypeCheckBox); 218 219 final View dialogTripleTapView = dialog.findViewById(R.id.triple_tap_shortcut); 220 mTripleTapTypeCheckBox = dialogTripleTapView.findViewById(R.id.checkbox); 221 setDialogTextAreaClickListener(dialogTripleTapView, mTripleTapTypeCheckBox); 222 223 final View advancedView = dialog.findViewById(R.id.advanced_shortcut); 224 if (mTripleTapTypeCheckBox.isChecked()) { 225 advancedView.setVisibility(View.GONE); 226 dialogTripleTapView.setVisibility(View.VISIBLE); 227 } 228 229 updateMagnificationEditShortcutDialogCheckBox(); 230 } 231 setDialogTextAreaClickListener(View dialogView, CheckBox checkBox)232 private void setDialogTextAreaClickListener(View dialogView, CheckBox checkBox) { 233 final View dialogTextArea = dialogView.findViewById(R.id.container); 234 dialogTextArea.setOnClickListener(v -> checkBox.toggle()); 235 } 236 updateMagnificationEditShortcutDialogCheckBox()237 private void updateMagnificationEditShortcutDialogCheckBox() { 238 // If it is during onConfigChanged process then restore the value, or get the saved value 239 // when shortcutPreference is checked. 240 int value = restoreOnConfigChangedValue(); 241 if (value == NOT_SET) { 242 final int lastNonEmptyUserShortcutType = PreferredShortcuts.retrieveUserShortcutType( 243 getPrefContext(), MAGNIFICATION_CONTROLLER_NAME, UserShortcutType.SOFTWARE); 244 value = mShortcutPreference.isChecked() ? lastNonEmptyUserShortcutType 245 : UserShortcutType.EMPTY; 246 } 247 248 mSoftwareTypeCheckBox.setChecked( 249 hasShortcutType(value, UserShortcutType.SOFTWARE)); 250 mHardwareTypeCheckBox.setChecked( 251 hasShortcutType(value, UserShortcutType.HARDWARE)); 252 mTripleTapTypeCheckBox.setChecked( 253 hasShortcutType(value, UserShortcutType.TRIPLETAP)); 254 } 255 restoreOnConfigChangedValue()256 private int restoreOnConfigChangedValue() { 257 final int savedValue = mSavedCheckBoxValue; 258 mSavedCheckBoxValue = NOT_SET; 259 return savedValue; 260 } 261 hasShortcutType(int value, @UserShortcutType int type)262 private boolean hasShortcutType(int value, @UserShortcutType int type) { 263 return (value & type) == type; 264 } 265 getSoftwareShortcutTypeSummary(Context context)266 private static CharSequence getSoftwareShortcutTypeSummary(Context context) { 267 int resId; 268 if (AccessibilityUtil.isFloatingMenuEnabled(context)) { 269 resId = R.string.accessibility_shortcut_edit_summary_software; 270 } else if (AccessibilityUtil.isGestureNavigateEnabled(context)) { 271 resId = R.string.accessibility_shortcut_edit_summary_software_gesture; 272 } else { 273 resId = R.string.accessibility_shortcut_edit_summary_software; 274 } 275 return context.getText(resId); 276 } 277 278 @Override getFeatureSettingsKeys()279 protected List<String> getFeatureSettingsKeys() { 280 final List<String> shortcutKeys = super.getFeatureSettingsKeys(); 281 shortcutKeys.add(Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED); 282 return shortcutKeys; 283 } 284 285 @Override getShortcutTypeSummary(Context context)286 protected CharSequence getShortcutTypeSummary(Context context) { 287 if (!mShortcutPreference.isChecked()) { 288 return context.getText(R.string.switch_off_text); 289 } 290 291 final int shortcutTypes = PreferredShortcuts.retrieveUserShortcutType(context, 292 MAGNIFICATION_CONTROLLER_NAME, UserShortcutType.SOFTWARE); 293 294 final List<CharSequence> list = new ArrayList<>(); 295 if (hasShortcutType(shortcutTypes, UserShortcutType.SOFTWARE)) { 296 list.add(getSoftwareShortcutTypeSummary(context)); 297 } 298 if (hasShortcutType(shortcutTypes, UserShortcutType.HARDWARE)) { 299 final CharSequence hardwareTitle = context.getText( 300 R.string.accessibility_shortcut_hardware_keyword); 301 list.add(hardwareTitle); 302 } 303 if (hasShortcutType(shortcutTypes, UserShortcutType.TRIPLETAP)) { 304 final CharSequence tripleTapTitle = context.getText( 305 R.string.accessibility_shortcut_triple_tap_keyword); 306 list.add(tripleTapTitle); 307 } 308 309 // Show software shortcut if first time to use. 310 if (list.isEmpty()) { 311 list.add(getSoftwareShortcutTypeSummary(context)); 312 } 313 314 return CaseMap.toTitle().wholeString().noLowercase().apply(Locale.getDefault(), /* iter= */ 315 null, LocaleUtils.getConcatenatedString(list)); 316 } 317 318 @Override callOnAlertDialogCheckboxClicked(DialogInterface dialog, int which)319 protected void callOnAlertDialogCheckboxClicked(DialogInterface dialog, int which) { 320 final int value = getShortcutTypeCheckBoxValue(); 321 322 saveNonEmptyUserShortcutType(value); 323 optInAllMagnificationValuesToSettings(getPrefContext(), value); 324 optOutAllMagnificationValuesFromSettings(getPrefContext(), ~value); 325 mShortcutPreference.setChecked(value != UserShortcutType.EMPTY); 326 mShortcutPreference.setSummary( 327 getShortcutTypeSummary(getPrefContext())); 328 } 329 330 @Override getHelpResource()331 public int getHelpResource() { 332 return R.string.help_url_magnification; 333 } 334 335 @Override getMetricsCategory()336 public int getMetricsCategory() { 337 // TODO: Distinguish between magnification modes 338 return SettingsEnums.ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFICATION; 339 } 340 341 @Override getDialogMetricsCategory(int dialogId)342 public int getDialogMetricsCategory(int dialogId) { 343 if (mDialogDelegate != null) { 344 final int category = mDialogDelegate.getDialogMetricsCategory(dialogId); 345 if (category != 0) { 346 return category; 347 } 348 } 349 350 switch (dialogId) { 351 case DialogEnums.GESTURE_NAVIGATION_TUTORIAL: 352 return SettingsEnums.DIALOG_TOGGLE_SCREEN_MAGNIFICATION_GESTURE_NAVIGATION; 353 case DialogEnums.ACCESSIBILITY_BUTTON_TUTORIAL: 354 return SettingsEnums.DIALOG_TOGGLE_SCREEN_MAGNIFICATION_ACCESSIBILITY_BUTTON; 355 case DialogEnums.MAGNIFICATION_EDIT_SHORTCUT: 356 return SettingsEnums.DIALOG_MAGNIFICATION_EDIT_SHORTCUT; 357 default: 358 return super.getDialogMetricsCategory(dialogId); 359 } 360 } 361 362 @Override getUserShortcutTypes()363 int getUserShortcutTypes() { 364 return getUserShortcutTypeFromSettings(getPrefContext()); 365 } 366 367 @Override onPreferenceToggled(String preferenceKey, boolean enabled)368 protected void onPreferenceToggled(String preferenceKey, boolean enabled) { 369 if (enabled && TextUtils.equals( 370 Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED, 371 preferenceKey)) { 372 showDialog(DialogEnums.LAUNCH_ACCESSIBILITY_TUTORIAL); 373 } 374 MagnificationPreferenceFragment.setChecked(getContentResolver(), preferenceKey, enabled); 375 } 376 377 @Override onInstallSwitchPreferenceToggleSwitch()378 protected void onInstallSwitchPreferenceToggleSwitch() { 379 mToggleServiceSwitchPreference.setVisible(false); 380 } 381 382 @Override onToggleClicked(ShortcutPreference preference)383 public void onToggleClicked(ShortcutPreference preference) { 384 final int shortcutTypes = PreferredShortcuts.retrieveUserShortcutType(getPrefContext(), 385 MAGNIFICATION_CONTROLLER_NAME, UserShortcutType.SOFTWARE); 386 if (preference.isChecked()) { 387 optInAllMagnificationValuesToSettings(getPrefContext(), shortcutTypes); 388 showDialog(DialogEnums.LAUNCH_ACCESSIBILITY_TUTORIAL); 389 } else { 390 optOutAllMagnificationValuesFromSettings(getPrefContext(), shortcutTypes); 391 } 392 mShortcutPreference.setSummary(getShortcutTypeSummary(getPrefContext())); 393 } 394 395 @Override onSettingsClicked(ShortcutPreference preference)396 public void onSettingsClicked(ShortcutPreference preference) { 397 showDialog(DialogEnums.MAGNIFICATION_EDIT_SHORTCUT); 398 } 399 400 @Override updateShortcutPreferenceData()401 protected void updateShortcutPreferenceData() { 402 final int shortcutTypes = getUserShortcutTypeFromSettings(getPrefContext()); 403 if (shortcutTypes != UserShortcutType.EMPTY) { 404 final PreferredShortcut shortcut = new PreferredShortcut( 405 MAGNIFICATION_CONTROLLER_NAME, shortcutTypes); 406 PreferredShortcuts.saveUserShortcutType(getPrefContext(), shortcut); 407 } 408 } 409 410 @Override initShortcutPreference()411 protected void initShortcutPreference() { 412 mShortcutPreference = new ShortcutPreference(getPrefContext(), null); 413 mShortcutPreference.setPersistent(false); 414 mShortcutPreference.setKey(getShortcutPreferenceKey()); 415 mShortcutPreference.setSummary(getShortcutTypeSummary(getPrefContext())); 416 mShortcutPreference.setOnClickCallback(this); 417 418 final CharSequence title = getString(R.string.accessibility_shortcut_title, mPackageName); 419 mShortcutPreference.setTitle(title); 420 421 final PreferenceCategory generalCategory = findPreference(KEY_GENERAL_CATEGORY); 422 generalCategory.addPreference(mShortcutPreference); 423 } 424 425 @Override updateShortcutTitle(ShortcutPreference shortcutPreference)426 protected void updateShortcutTitle(ShortcutPreference shortcutPreference) { 427 shortcutPreference.setTitle(R.string.accessibility_screen_magnification_shortcut_title); 428 } 429 430 @Override updateShortcutPreference()431 protected void updateShortcutPreference() { 432 final int shortcutTypes = PreferredShortcuts.retrieveUserShortcutType(getPrefContext(), 433 MAGNIFICATION_CONTROLLER_NAME, UserShortcutType.SOFTWARE); 434 mShortcutPreference.setChecked( 435 hasMagnificationValuesInSettings(getPrefContext(), shortcutTypes)); 436 mShortcutPreference.setSummary(getShortcutTypeSummary(getPrefContext())); 437 } 438 439 @VisibleForTesting saveNonEmptyUserShortcutType(int type)440 void saveNonEmptyUserShortcutType(int type) { 441 if (type == UserShortcutType.EMPTY) { 442 return; 443 } 444 445 final PreferredShortcut shortcut = new PreferredShortcut( 446 MAGNIFICATION_CONTROLLER_NAME, type); 447 PreferredShortcuts.saveUserShortcutType(getPrefContext(), shortcut); 448 } 449 450 @VisibleForTesting optInAllMagnificationValuesToSettings(Context context, int shortcutTypes)451 static void optInAllMagnificationValuesToSettings(Context context, int shortcutTypes) { 452 if ((shortcutTypes & UserShortcutType.SOFTWARE) == UserShortcutType.SOFTWARE) { 453 optInMagnificationValueToSettings(context, UserShortcutType.SOFTWARE); 454 } 455 if (((shortcutTypes & UserShortcutType.HARDWARE) == UserShortcutType.HARDWARE)) { 456 optInMagnificationValueToSettings(context, UserShortcutType.HARDWARE); 457 } 458 if (((shortcutTypes & UserShortcutType.TRIPLETAP) == UserShortcutType.TRIPLETAP)) { 459 optInMagnificationValueToSettings(context, UserShortcutType.TRIPLETAP); 460 } 461 } 462 optInMagnificationValueToSettings(Context context, @UserShortcutType int shortcutType)463 private static void optInMagnificationValueToSettings(Context context, 464 @UserShortcutType int shortcutType) { 465 if (shortcutType == UserShortcutType.TRIPLETAP) { 466 Settings.Secure.putInt(context.getContentResolver(), 467 Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, ON); 468 return; 469 } 470 471 if (hasMagnificationValueInSettings(context, shortcutType)) { 472 return; 473 } 474 475 final String targetKey = AccessibilityUtil.convertKeyFromSettings(shortcutType); 476 final String targetString = Settings.Secure.getString(context.getContentResolver(), 477 targetKey); 478 final StringJoiner joiner = new StringJoiner(String.valueOf(COMPONENT_NAME_SEPARATOR)); 479 480 if (!TextUtils.isEmpty(targetString)) { 481 joiner.add(targetString); 482 } 483 joiner.add(MAGNIFICATION_CONTROLLER_NAME); 484 485 Settings.Secure.putString(context.getContentResolver(), targetKey, joiner.toString()); 486 } 487 488 @VisibleForTesting optOutAllMagnificationValuesFromSettings(Context context, int shortcutTypes)489 static void optOutAllMagnificationValuesFromSettings(Context context, 490 int shortcutTypes) { 491 if ((shortcutTypes & UserShortcutType.SOFTWARE) == UserShortcutType.SOFTWARE) { 492 optOutMagnificationValueFromSettings(context, UserShortcutType.SOFTWARE); 493 } 494 if (((shortcutTypes & UserShortcutType.HARDWARE) == UserShortcutType.HARDWARE)) { 495 optOutMagnificationValueFromSettings(context, UserShortcutType.HARDWARE); 496 } 497 if (((shortcutTypes & UserShortcutType.TRIPLETAP) == UserShortcutType.TRIPLETAP)) { 498 optOutMagnificationValueFromSettings(context, UserShortcutType.TRIPLETAP); 499 } 500 } 501 optOutMagnificationValueFromSettings(Context context, @UserShortcutType int shortcutType)502 private static void optOutMagnificationValueFromSettings(Context context, 503 @UserShortcutType int shortcutType) { 504 if (shortcutType == UserShortcutType.TRIPLETAP) { 505 Settings.Secure.putInt(context.getContentResolver(), 506 Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, OFF); 507 return; 508 } 509 510 final String targetKey = AccessibilityUtil.convertKeyFromSettings(shortcutType); 511 final String targetString = Settings.Secure.getString(context.getContentResolver(), 512 targetKey); 513 514 if (TextUtils.isEmpty(targetString)) { 515 return; 516 } 517 518 final StringJoiner joiner = new StringJoiner(String.valueOf(COMPONENT_NAME_SEPARATOR)); 519 520 sStringColonSplitter.setString(targetString); 521 while (sStringColonSplitter.hasNext()) { 522 final String name = sStringColonSplitter.next(); 523 if (TextUtils.isEmpty(name) || MAGNIFICATION_CONTROLLER_NAME.equals(name)) { 524 continue; 525 } 526 joiner.add(name); 527 } 528 529 Settings.Secure.putString(context.getContentResolver(), targetKey, joiner.toString()); 530 } 531 532 @VisibleForTesting hasMagnificationValuesInSettings(Context context, int shortcutTypes)533 static boolean hasMagnificationValuesInSettings(Context context, int shortcutTypes) { 534 boolean exist = false; 535 536 if ((shortcutTypes & UserShortcutType.SOFTWARE) == UserShortcutType.SOFTWARE) { 537 exist = hasMagnificationValueInSettings(context, UserShortcutType.SOFTWARE); 538 } 539 if (((shortcutTypes & UserShortcutType.HARDWARE) == UserShortcutType.HARDWARE)) { 540 exist |= hasMagnificationValueInSettings(context, UserShortcutType.HARDWARE); 541 } 542 if (((shortcutTypes & UserShortcutType.TRIPLETAP) == UserShortcutType.TRIPLETAP)) { 543 exist |= hasMagnificationValueInSettings(context, UserShortcutType.TRIPLETAP); 544 } 545 return exist; 546 } 547 hasMagnificationValueInSettings(Context context, @UserShortcutType int shortcutType)548 private static boolean hasMagnificationValueInSettings(Context context, 549 @UserShortcutType int shortcutType) { 550 if (shortcutType == UserShortcutType.TRIPLETAP) { 551 return Settings.Secure.getInt(context.getContentResolver(), 552 Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, OFF) == ON; 553 } 554 555 final String targetKey = AccessibilityUtil.convertKeyFromSettings(shortcutType); 556 final String targetString = Settings.Secure.getString(context.getContentResolver(), 557 targetKey); 558 559 if (TextUtils.isEmpty(targetString)) { 560 return false; 561 } 562 563 sStringColonSplitter.setString(targetString); 564 while (sStringColonSplitter.hasNext()) { 565 final String name = sStringColonSplitter.next(); 566 if (MAGNIFICATION_CONTROLLER_NAME.equals(name)) { 567 return true; 568 } 569 } 570 return false; 571 } 572 isWindowMagnification(Context context)573 private boolean isWindowMagnification(Context context) { 574 final int mode = Settings.Secure.getIntForUser( 575 context.getContentResolver(), 576 Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE, 577 Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN, 578 context.getContentResolver().getUserId()); 579 return mode == Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW; 580 } 581 getUserShortcutTypeFromSettings(Context context)582 private static int getUserShortcutTypeFromSettings(Context context) { 583 int shortcutTypes = UserShortcutType.EMPTY; 584 if (hasMagnificationValuesInSettings(context, UserShortcutType.SOFTWARE)) { 585 shortcutTypes |= UserShortcutType.SOFTWARE; 586 } 587 if (hasMagnificationValuesInSettings(context, UserShortcutType.HARDWARE)) { 588 shortcutTypes |= UserShortcutType.HARDWARE; 589 } 590 if (hasMagnificationValuesInSettings(context, UserShortcutType.TRIPLETAP)) { 591 shortcutTypes |= UserShortcutType.TRIPLETAP; 592 } 593 return shortcutTypes; 594 } 595 596 /** 597 * Gets the service summary of magnification. 598 * 599 * @param context The current context. 600 */ getServiceSummary(Context context)601 public static CharSequence getServiceSummary(Context context) { 602 // Get the user shortcut type from settings provider. 603 final int uerShortcutType = getUserShortcutTypeFromSettings(context); 604 return (uerShortcutType != AccessibilityUtil.UserShortcutType.EMPTY) 605 ? context.getText(R.string.accessibility_summary_shortcut_enabled) 606 : context.getText(R.string.accessibility_summary_shortcut_disabled); 607 } 608 } 609