From 09efbe453cb013ac5a8f754ef0843c118c9f9532 Mon Sep 17 00:00:00 2001 From: Chun-Ku Lin Date: Tue, 21 May 2024 23:33:55 +0000 Subject: [PATCH] Pass user preferred shortcut types when launching the AccessibilityShortcutsTutorial. **Root cause** When toggle the shortcut, it asks the AccessibilityManager to turn on the shortcut and update the Settings data. Internally, the AccessibilityManager delegate the work to AccessibilityManagerService via a oneway binder call. In the past, when launching the AccessibilityShortcutsTutorial, we assume the shortcut selection are saved in the Settings before launching the AccessibilityShortcutsTutorial. So we pass whatever are in the Settings as what the user has selected to the tutorial. This is not true anymore since we use the oneway AIDL call to do the updates. The data in Settings may not yet be updated before we use it to launch the tutorial. Since the user preferred shortcuts are always set before we attempt to launch the AccessibilityShortcutsTutorial, we can rely on it instead of the Settings value to launch the AccessibilityShortcutsTutorial for the selected shortcut options. **Changes in this cl** - Mechanical refactor to extract the lines to get the user preferred shortcut into a method. - Use the new method to grab the shortcut options to pass to the AccessibilityShortcutsTutorial to prevent the crash. Bug: 341176890 Test: manual - Modify the AccessibilityManagerService locally to delay processing the request to update the shortcut options in Settings data - Turn on the shortcut toggle, and verify the app won't crash Test: atest com.android.settings.accessibility Flag: EXEMPT bugfix (low risk + mechanical refactor) Change-Id: Id3cc4cc5f6667061545955881632544472aedd95 --- ...cessibilityShortcutPreferenceFragment.java | 28 +++++++++++-------- ...ccessibilityServicePreferenceFragment.java | 7 ++--- .../ToggleFeaturePreferenceFragment.java | 22 +++++++++------ ...ScreenMagnificationPreferenceFragment.java | 15 ++++++---- 4 files changed, 42 insertions(+), 30 deletions(-) diff --git a/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java b/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java index b111faa6ec3..92259acf3e4 100644 --- a/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java +++ b/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java @@ -42,6 +42,7 @@ import androidx.annotation.VisibleForTesting; import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceScreen; +import com.android.internal.accessibility.common.ShortcutConstants; import com.android.settings.R; import com.android.settings.accessibility.AccessibilityUtil.QuickSettingsTooltipType; import com.android.settings.accessibility.shortcuts.EditShortcutsPreferenceFragment; @@ -222,12 +223,12 @@ public abstract class AccessibilityShortcutPreferenceFragment extends Restricted if (WizardManagerHelper.isAnySetupWizard(getIntent())) { mDialog = AccessibilityShortcutsTutorial .createAccessibilityTutorialDialogForSetupWizard( - getPrefContext(), getUserShortcutTypes(), + getPrefContext(), getUserPreferredShortcutTypes(), this::callOnTutorialDialogButtonClicked, getLabelName()); } else { mDialog = AccessibilityShortcutsTutorial .createAccessibilityTutorialDialog( - getPrefContext(), getUserShortcutTypes(), + getPrefContext(), getUserPreferredShortcutTypes(), this::callOnTutorialDialogButtonClicked, getLabelName()); } mDialog.setCanceledOnTouchOutside(false); @@ -274,8 +275,7 @@ public abstract class AccessibilityShortcutPreferenceFragment extends Restricted return; } - final int shortcutTypes = PreferredShortcuts.retrieveUserShortcutType(getPrefContext(), - getComponentName().flattenToString()); + final int shortcutTypes = getUserPreferredShortcutTypes(); if (preference.isChecked()) { AccessibilityUtil.optInAllValuesToSettings(getPrefContext(), shortcutTypes, getComponentName()); @@ -451,8 +451,7 @@ public abstract class AccessibilityShortcutPreferenceFragment extends Restricted return context.getText(R.string.accessibility_shortcut_state_off); } - final int shortcutTypes = PreferredShortcuts.retrieveUserShortcutType(context, - getComponentName().flattenToString()); + final int shortcutTypes = getUserPreferredShortcutTypes(); // LINT.IfChange(shortcut_type_ui_order) final List list = new ArrayList<>(); @@ -487,9 +486,7 @@ public abstract class AccessibilityShortcutPreferenceFragment extends Restricted // when shortcutPreference is checked. int value = restoreOnConfigChangedValue(); if (value == NOT_SET) { - final int lastNonEmptyUserShortcutType = PreferredShortcuts.retrieveUserShortcutType( - getPrefContext(), getComponentName().flattenToString() - ); + final int lastNonEmptyUserShortcutType = getUserPreferredShortcutTypes(); value = mShortcutPreference.isChecked() ? lastNonEmptyUserShortcutType : AccessibilityUtil.UserShortcutType.EMPTY; } @@ -529,8 +526,7 @@ public abstract class AccessibilityShortcutPreferenceFragment extends Restricted return; } - final int shortcutTypes = PreferredShortcuts.retrieveUserShortcutType(getPrefContext(), - getComponentName().flattenToString()); + final int shortcutTypes = getUserPreferredShortcutTypes(); mShortcutPreference.setChecked( AccessibilityUtil.hasValuesInSettings(getPrefContext(), shortcutTypes, getComponentName())); @@ -581,4 +577,14 @@ public abstract class AccessibilityShortcutPreferenceFragment extends Restricted tileComponentName); mNeedsQSTooltipReshow = false; } + + /** + * Returns the user preferred shortcut types or the default shortcut types if not set + */ + @ShortcutConstants.UserShortcutType + protected int getUserPreferredShortcutTypes() { + return PreferredShortcuts.retrieveUserShortcutType( + getPrefContext(), + getComponentName().flattenToString()); + } } diff --git a/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java index cf9c78f1cc9..a79098b7f46 100644 --- a/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java +++ b/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java @@ -18,7 +18,6 @@ package com.android.settings.accessibility; import static com.android.settings.accessibility.AccessibilityDialogUtils.DialogEnums; import static com.android.settings.accessibility.AccessibilityStatsLogUtils.logAccessibilityServiceEnabled; -import static com.android.settings.accessibility.PreferredShortcuts.retrieveUserShortcutType; import android.accessibilityservice.AccessibilityServiceInfo; import android.app.AlertDialog; @@ -327,8 +326,7 @@ public class ToggleAccessibilityServicePreferenceFragment extends @Override public void onToggleClicked(ShortcutPreference preference) { - final int shortcutTypes = retrieveUserShortcutType(getPrefContext(), - mComponentName.flattenToString(), getDefaultShortcutTypes()); + final int shortcutTypes = getUserPreferredShortcutTypes(); if (preference.isChecked()) { final boolean isWarningRequired = getPrefContext().getSystemService(AccessibilityManager.class) @@ -507,8 +505,7 @@ public class ToggleAccessibilityServicePreferenceFragment extends void onAllowButtonFromShortcutToggleClicked() { mShortcutPreference.setChecked(true); - final int shortcutTypes = retrieveUserShortcutType(getPrefContext(), - mComponentName.flattenToString(), getDefaultShortcutTypes()); + final int shortcutTypes = getUserPreferredShortcutTypes(); AccessibilityUtil.optInAllValuesToSettings(getPrefContext(), shortcutTypes, mComponentName); mIsDialogShown.set(false); diff --git a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java index e62e473c7c2..a57b4591240 100644 --- a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java +++ b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java @@ -227,12 +227,12 @@ public abstract class ToggleFeaturePreferenceFragment extends DashboardFragment if (isAnySetupWizard()) { mDialog = AccessibilityShortcutsTutorial .createAccessibilityTutorialDialogForSetupWizard( - getPrefContext(), getUserShortcutTypes(), + getPrefContext(), getUserPreferredShortcutTypes(), this::callOnTutorialDialogButtonClicked, mPackageName); } else { mDialog = AccessibilityShortcutsTutorial .createAccessibilityTutorialDialog( - getPrefContext(), getUserShortcutTypes(), + getPrefContext(), getUserPreferredShortcutTypes(), this::callOnTutorialDialogButtonClicked, mPackageName); } mDialog.setCanceledOnTouchOutside(false); @@ -662,8 +662,7 @@ public abstract class ToggleFeaturePreferenceFragment extends DashboardFragment // when shortcutPreference is checked. int value = restoreOnConfigChangedValue(); if (value == NOT_SET) { - final int lastNonEmptyUserShortcutType = PreferredShortcuts.retrieveUserShortcutType( - getPrefContext(), mComponentName.flattenToString(), getDefaultShortcutTypes()); + final int lastNonEmptyUserShortcutType = getUserPreferredShortcutTypes(); value = mShortcutPreference.isChecked() ? lastNonEmptyUserShortcutType : UserShortcutType.EMPTY; } @@ -814,8 +813,7 @@ public abstract class ToggleFeaturePreferenceFragment extends DashboardFragment return; } - final int shortcutTypes = PreferredShortcuts.retrieveUserShortcutType(getPrefContext(), - mComponentName.flattenToString(), getDefaultShortcutTypes()); + final int shortcutTypes = getUserPreferredShortcutTypes(); mShortcutPreference.setChecked( AccessibilityUtil.hasValuesInSettings(getPrefContext(), shortcutTypes, mComponentName)); @@ -832,8 +830,7 @@ public abstract class ToggleFeaturePreferenceFragment extends DashboardFragment return; } - final int shortcutTypes = PreferredShortcuts.retrieveUserShortcutType(getPrefContext(), - mComponentName.flattenToString(), getDefaultShortcutTypes()); + final int shortcutTypes = getUserPreferredShortcutTypes(); if (preference.isChecked()) { AccessibilityUtil.optInAllValuesToSettings(getPrefContext(), shortcutTypes, mComponentName); @@ -988,4 +985,13 @@ public abstract class ToggleFeaturePreferenceFragment extends DashboardFragment protected int getDefaultShortcutTypes() { return ShortcutConstants.UserShortcutType.SOFTWARE; } + + /** + * Returns the user preferred shortcut types or the default shortcut types if not set + */ + @ShortcutConstants.UserShortcutType + protected int getUserPreferredShortcutTypes() { + return PreferredShortcuts.retrieveUserShortcutType( + getPrefContext(), mComponentName.flattenToString(), getDefaultShortcutTypes()); + } } diff --git a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java index 25c8768375f..211ccb13fcf 100644 --- a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java +++ b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java @@ -409,8 +409,7 @@ public class ToggleScreenMagnificationPreferenceFragment extends // when shortcutPreference is checked. int value = restoreOnConfigChangedValue(); if (value == NOT_SET) { - final int lastNonEmptyUserShortcutType = PreferredShortcuts.retrieveUserShortcutType( - getPrefContext(), MAGNIFICATION_CONTROLLER_NAME); + final int lastNonEmptyUserShortcutType = getUserPreferredShortcutTypes(); value = mShortcutPreference.isChecked() ? lastNonEmptyUserShortcutType : UserShortcutType.EMPTY; } @@ -606,8 +605,7 @@ public class ToggleScreenMagnificationPreferenceFragment extends @Override public void onToggleClicked(ShortcutPreference preference) { - final int shortcutTypes = PreferredShortcuts.retrieveUserShortcutType(getPrefContext(), - MAGNIFICATION_CONTROLLER_NAME); + final int shortcutTypes = getUserPreferredShortcutTypes(); if (preference.isChecked()) { optInAllMagnificationValuesToSettings(getPrefContext(), shortcutTypes); showDialog(DialogEnums.LAUNCH_ACCESSIBILITY_TUTORIAL); @@ -661,8 +659,7 @@ public class ToggleScreenMagnificationPreferenceFragment extends @Override protected void updateShortcutPreference() { - final int shortcutTypes = PreferredShortcuts.retrieveUserShortcutType(getPrefContext(), - MAGNIFICATION_CONTROLLER_NAME); + final int shortcutTypes = getUserPreferredShortcutTypes(); mShortcutPreference.setChecked( hasMagnificationValuesInSettings(getPrefContext(), shortcutTypes)); mShortcutPreference.setSummary(getShortcutTypeSummary(getPrefContext())); @@ -933,4 +930,10 @@ public class ToggleScreenMagnificationPreferenceFragment extends return context.getString(R.string.preference_summary_default_combination, featureState, featureSummary); } + + @Override + protected int getUserPreferredShortcutTypes() { + return PreferredShortcuts.retrieveUserShortcutType( + getPrefContext(), MAGNIFICATION_CONTROLLER_NAME); + } }