diff options
5 files changed, 189 insertions, 174 deletions
diff --git a/core/java/com/android/internal/accessibility/util/ShortcutUtils.java b/core/java/com/android/internal/accessibility/util/ShortcutUtils.java index 8718fb15eb60..5b09a8be8c65 100644 --- a/core/java/com/android/internal/accessibility/util/ShortcutUtils.java +++ b/core/java/com/android/internal/accessibility/util/ShortcutUtils.java @@ -181,26 +181,6 @@ public final class ShortcutUtils { } /** - * Converts {@link Settings.Secure} key to {@link UserShortcutType}. - * - * @param key The shortcut key. - * @return Mapping type in Settings. - */ - public static int convertToType(String key) { - return switch (key) { - case Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS -> UserShortcutType.SOFTWARE; - case Settings.Secure.ACCESSIBILITY_QS_TARGETS -> UserShortcutType.QUICK_SETTINGS; - case Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE -> UserShortcutType.HARDWARE; - case Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED -> - UserShortcutType.TRIPLETAP; - case Settings.Secure.ACCESSIBILITY_MAGNIFICATION_TWO_FINGER_TRIPLE_TAP_ENABLED -> - UserShortcutType.TWOFINGER_DOUBLETAP; - default -> throw new IllegalArgumentException( - "Unsupported user shortcut key: " + key); - }; - } - - /** * Updates an accessibility state if the accessibility service is a Always-On a11y service, * a.k.a. AccessibilityServices that has FLAG_REQUEST_ACCESSIBILITY_BUTTON * <p> diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java index 02a7b0fee989..4f9db8bece63 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -47,11 +47,6 @@ import static com.android.internal.accessibility.AccessibilityShortcutController import static com.android.internal.accessibility.common.ShortcutConstants.CHOOSER_PACKAGE_NAME; import static com.android.internal.accessibility.common.ShortcutConstants.USER_SHORTCUT_TYPES; import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType; -import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.HARDWARE; -import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.QUICK_SETTINGS; -import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE; -import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.TRIPLETAP; -import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.TWOFINGER_DOUBLETAP; import static com.android.internal.accessibility.util.AccessibilityStatsLogUtils.logAccessibilityShortcutActivated; import static com.android.internal.util.FunctionalUtils.ignoreRemoteException; import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage; @@ -928,11 +923,25 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub newValue, restoredFromSdk); } } - case Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, - Settings.Secure.ACCESSIBILITY_QS_TARGETS, - Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE -> - restoreAccessibilityShortcutTargets(previousValue, newValue, - ShortcutUtils.convertToType(which)); + case Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS -> { + synchronized (mLock) { + restoreAccessibilityButtonTargetsLocked( + previousValue, newValue); + } + } + case Settings.Secure.ACCESSIBILITY_QS_TARGETS -> { + if (!android.view.accessibility.Flags.a11yQsShortcut()) { + return; + } + restoreAccessibilityQsTargets(newValue); + } + case Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE -> { + if (!android.view.accessibility.Flags + .restoreA11yShortcutTargetService()) { + return; + } + restoreAccessibilityShortcutTargetService(previousValue, newValue); + } } } } @@ -1031,7 +1040,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub } persistColonDelimitedSetToSettingLocked(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, userState.mUserId, targetsFromSetting, str -> str); - readAccessibilityShortcutTargetsLocked(userState, SOFTWARE); + readAccessibilityButtonTargetsLocked(userState); onUserStateChangedLocked(userState); } @@ -1711,12 +1720,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub } // Turn on/off a11y qs shortcut for the a11y features based on the change in QS Panel if (!a11yFeaturesToEnable.isEmpty()) { - enableShortcutForTargets(/* enable= */ true, QUICK_SETTINGS, + enableShortcutForTargets(/* enable= */ true, UserShortcutType.QUICK_SETTINGS, a11yFeaturesToEnable, userId); } if (!a11yFeaturesToRemove.isEmpty()) { - enableShortcutForTargets(/* enable= */ false, QUICK_SETTINGS, + enableShortcutForTargets(/* enable= */ false, UserShortcutType.QUICK_SETTINGS, a11yFeaturesToRemove, userId); } } @@ -2048,70 +2057,99 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub } /** + * User could enable accessibility services and configure accessibility button during the SUW. + * Merges current value of accessibility button settings into the restored one to make sure + * user's preferences of accessibility button updated in SUW are not lost. + * + * Called only during settings restore; currently supports only the owner user + * TODO: http://b/22388012 + */ + void restoreAccessibilityButtonTargetsLocked(String oldSetting, String newSetting) { + final Set<String> targetsFromSetting = new ArraySet<>(); + readColonDelimitedStringToSet(oldSetting, str -> str, targetsFromSetting, + /* doMerge = */false); + readColonDelimitedStringToSet(newSetting, str -> str, targetsFromSetting, + /* doMerge = */true); + + final AccessibilityUserState userState = getUserStateLocked(UserHandle.USER_SYSTEM); + userState.mAccessibilityButtonTargets.clear(); + userState.mAccessibilityButtonTargets.addAll(targetsFromSetting); + persistColonDelimitedSetToSettingLocked(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, + UserHandle.USER_SYSTEM, userState.mAccessibilityButtonTargets, str -> str); + + scheduleNotifyClientsOfServicesStateChangeLocked(userState); + onUserStateChangedLocked(userState); + } + + /** * User could configure accessibility shortcut during the SUW before restoring user data. * Merges the current value and the new value to make sure we don't lost the setting the user's - * preferences of accessibility shortcut updated in SUW are not lost. - * Called only during settings restore; currently supports only the owner user. - * <P> - * Throws an exception if used with {@code TRIPLETAP} or {@code TWOFINGER_DOUBLETAP}. - * </P> + * preferences of accessibility qs shortcut updated in SUW are not lost. + * + * Called only during settings restore; currently supports only the owner user * TODO: http://b/22388012 */ - private void restoreAccessibilityShortcutTargets(String oldValue, String newValue, - @UserShortcutType int shortcutType) { - assertNoTapShortcut(shortcutType); - if (shortcutType == QUICK_SETTINGS && !android.view.accessibility.Flags.a11yQsShortcut()) { - return; - } - if (shortcutType == HARDWARE && !android.view.accessibility.Flags - .restoreA11yShortcutTargetService()) { - return; - } - + private void restoreAccessibilityQsTargets(String newValue) { synchronized (mLock) { final AccessibilityUserState userState = getUserStateLocked(UserHandle.USER_SYSTEM); - final Set<String> mergedTargets = userState.getShortcutTargetsLocked(shortcutType); - readColonDelimitedStringToSet(oldValue, str -> str, mergedTargets, + final Set<String> mergedTargets = userState.getA11yQsTargets(); + readColonDelimitedStringToSet(newValue, str -> str, mergedTargets, /* doMerge = */ true); - // If dealing with the hardware shortcut, - // remove the default service if it wasn't present before restore. - // Otherwise, merge the old and new targets normally. - if (Flags.clearDefaultFromA11yShortcutTargetServiceRestore() - && shortcutType == HARDWARE) { - final String defaultService = - mContext.getString(R.string.config_defaultAccessibilityService); - final ComponentName defaultServiceComponent = TextUtils.isEmpty(defaultService) - ? null : ComponentName.unflattenFromString(defaultService); - boolean shouldClearDefaultService = defaultServiceComponent != null - && !stringSetContainsComponentName(mergedTargets, defaultServiceComponent); - readColonDelimitedStringToSet(newValue, str -> str, mergedTargets, - /* doMerge = */ true); - - if (shouldClearDefaultService && stringSetContainsComponentName( - mergedTargets, defaultServiceComponent)) { - Slog.i(LOG_TAG, "Removing default service " + defaultService - + " from restore of " - + Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE); - mergedTargets.removeIf(str -> - defaultServiceComponent.equals(ComponentName.unflattenFromString(str))); - } - if (mergedTargets.isEmpty()) { - return; - } - } else { - readColonDelimitedStringToSet(newValue, str -> str, mergedTargets, - /* doMerge = */ true); - } - - userState.updateShortcutTargetsLocked(mergedTargets, shortcutType); - persistColonDelimitedSetToSettingLocked(ShortcutUtils.convertToKey(shortcutType), + userState.updateA11yQsTargetLocked(mergedTargets); + persistColonDelimitedSetToSettingLocked(Settings.Secure.ACCESSIBILITY_QS_TARGETS, UserHandle.USER_SYSTEM, mergedTargets, str -> str); scheduleNotifyClientsOfServicesStateChangeLocked(userState); onUserStateChangedLocked(userState); } } + /** + * Merges the old and restored value of + * {@link Settings.Secure#ACCESSIBILITY_SHORTCUT_TARGET_SERVICE}. + * + * <p>Also clears out {@link R.string#config_defaultAccessibilityService} from + * the merged set if it was not present before restoring. + */ + private void restoreAccessibilityShortcutTargetService( + String oldValue, String restoredValue) { + final Set<String> targetsFromSetting = new ArraySet<>(); + readColonDelimitedStringToSet(oldValue, str -> str, + targetsFromSetting, /*doMerge=*/false); + final String defaultService = + mContext.getString(R.string.config_defaultAccessibilityService); + final ComponentName defaultServiceComponent = TextUtils.isEmpty(defaultService) + ? null : ComponentName.unflattenFromString(defaultService); + boolean shouldClearDefaultService = defaultServiceComponent != null + && !stringSetContainsComponentName(targetsFromSetting, defaultServiceComponent); + readColonDelimitedStringToSet(restoredValue, str -> str, + targetsFromSetting, /*doMerge=*/true); + if (Flags.clearDefaultFromA11yShortcutTargetServiceRestore()) { + if (shouldClearDefaultService && stringSetContainsComponentName( + targetsFromSetting, defaultServiceComponent)) { + Slog.i(LOG_TAG, "Removing default service " + defaultService + + " from restore of " + + Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE); + targetsFromSetting.removeIf(str -> + defaultServiceComponent.equals(ComponentName.unflattenFromString(str))); + } + if (targetsFromSetting.isEmpty()) { + return; + } + } + synchronized (mLock) { + final AccessibilityUserState userState = getUserStateLocked(UserHandle.USER_SYSTEM); + final Set<String> shortcutTargets = + userState.getShortcutTargetsLocked(UserShortcutType.HARDWARE); + shortcutTargets.clear(); + shortcutTargets.addAll(targetsFromSetting); + persistColonDelimitedSetToSettingLocked( + Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, + UserHandle.USER_SYSTEM, targetsFromSetting, str -> str); + scheduleNotifyClientsOfServicesStateChangeLocked(userState); + onUserStateChangedLocked(userState); + } + } /** * Returns {@code true} if the set contains the provided non-null {@link ComponentName}. @@ -2225,7 +2263,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub private void showAccessibilityTargetsSelection(int displayId, @UserShortcutType int shortcutType) { final Intent intent = new Intent(AccessibilityManager.ACTION_CHOOSE_ACCESSIBILITY_BUTTON); - final String chooserClassName = (shortcutType == HARDWARE) + final String chooserClassName = (shortcutType == UserShortcutType.HARDWARE) ? AccessibilityShortcutChooserActivity.class.getName() : AccessibilityButtonChooserActivity.class.getName(); intent.setClassName(CHOOSER_PACKAGE_NAME, chooserClassName); @@ -3198,9 +3236,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub somethingChanged |= readAudioDescriptionEnabledSettingLocked(userState); somethingChanged |= readMagnificationEnabledSettingsLocked(userState); somethingChanged |= readAutoclickEnabledSettingLocked(userState); - somethingChanged |= readAccessibilityShortcutTargetsLocked(userState, HARDWARE); - somethingChanged |= readAccessibilityShortcutTargetsLocked(userState, QUICK_SETTINGS); - somethingChanged |= readAccessibilityShortcutTargetsLocked(userState, SOFTWARE); + somethingChanged |= readAccessibilityShortcutKeySettingLocked(userState); + somethingChanged |= readAccessibilityQsTargetsLocked(userState); + somethingChanged |= readAccessibilityButtonTargetsLocked(userState); somethingChanged |= readAccessibilityButtonTargetComponentLocked(userState); somethingChanged |= readUserRecommendedUiTimeoutSettingsLocked(userState); somethingChanged |= readMagnificationModeForDefaultDisplayLocked(userState); @@ -3348,31 +3386,60 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub userState.setSendMotionEventsEnabled(sendMotionEvents); } - /** - * Throws an exception for {@code TRIPLETAP} or {@code TWOFINGER_DOUBLETAP} types. - */ - private boolean readAccessibilityShortcutTargetsLocked(AccessibilityUserState userState, - @UserShortcutType int shortcutType) { - assertNoTapShortcut(shortcutType); + private boolean readAccessibilityShortcutKeySettingLocked(AccessibilityUserState userState) { final String settingValue = Settings.Secure.getStringForUser(mContext.getContentResolver(), - ShortcutUtils.convertToKey(shortcutType), userState.mUserId); + Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, userState.mUserId); final Set<String> targetsFromSetting = new ArraySet<>(); - // If dealing with an empty hardware shortcut, fall back to the default value. - if (shortcutType == HARDWARE && settingValue == null) { + readColonDelimitedStringToSet(settingValue, str -> str, targetsFromSetting, false); + // Fall back to device's default a11y service, only when setting is never updated. + if (settingValue == null) { final String defaultService = mContext.getString( R.string.config_defaultAccessibilityService); if (!TextUtils.isEmpty(defaultService)) { targetsFromSetting.add(defaultService); } - } else { - readColonDelimitedStringToSet(settingValue, str -> str, targetsFromSetting, false); } - if (userState.updateShortcutTargetsLocked(targetsFromSetting, shortcutType)) { - scheduleNotifyClientsOfServicesStateChangeLocked(userState); - return true; + final Set<String> currentTargets = + userState.getShortcutTargetsLocked(UserShortcutType.HARDWARE); + if (targetsFromSetting.equals(currentTargets)) { + return false; } - return false; + currentTargets.clear(); + currentTargets.addAll(targetsFromSetting); + scheduleNotifyClientsOfServicesStateChangeLocked(userState); + return true; + } + + private boolean readAccessibilityQsTargetsLocked(AccessibilityUserState userState) { + final Set<String> targetsFromSetting = new ArraySet<>(); + readColonDelimitedSettingToSet(Settings.Secure.ACCESSIBILITY_QS_TARGETS, + userState.mUserId, str -> str, targetsFromSetting); + + final Set<String> currentTargets = + userState.getShortcutTargetsLocked(UserShortcutType.QUICK_SETTINGS); + if (targetsFromSetting.equals(currentTargets)) { + return false; + } + userState.updateA11yQsTargetLocked(targetsFromSetting); + scheduleNotifyClientsOfServicesStateChangeLocked(userState); + return true; + } + + private boolean readAccessibilityButtonTargetsLocked(AccessibilityUserState userState) { + final Set<String> targetsFromSetting = new ArraySet<>(); + readColonDelimitedSettingToSet(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, + userState.mUserId, str -> str, targetsFromSetting); + + final Set<String> currentTargets = + userState.getShortcutTargetsLocked(UserShortcutType.SOFTWARE); + if (targetsFromSetting.equals(currentTargets)) { + return false; + } + currentTargets.clear(); + currentTargets.addAll(targetsFromSetting); + scheduleNotifyClientsOfServicesStateChangeLocked(userState); + return true; } private boolean readAccessibilityButtonTargetComponentLocked(AccessibilityUserState userState) { @@ -3420,7 +3487,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub */ private void updateAccessibilityShortcutKeyTargetsLocked(AccessibilityUserState userState) { final Set<String> currentTargets = - userState.getShortcutTargetsLocked(HARDWARE); + userState.getShortcutTargetsLocked(UserShortcutType.HARDWARE); final int lastSize = currentTargets.size(); if (lastSize == 0) { return; @@ -3689,9 +3756,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub lastSize = buttonTargets.size(); final Set<String> shortcutKeyTargets = - userState.getShortcutTargetsLocked(HARDWARE); + userState.getShortcutTargetsLocked(UserShortcutType.HARDWARE); final Set<String> qsShortcutTargets = - userState.getShortcutTargetsLocked(QUICK_SETTINGS); + userState.getShortcutTargetsLocked(UserShortcutType.QUICK_SETTINGS); userState.mEnabledServices.forEach(componentName -> { if (packageName != null && componentName != null && !packageName.equals(componentName.getPackageName())) { @@ -3748,7 +3815,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub } final Set<String> targets = - userState.getShortcutTargetsLocked(QUICK_SETTINGS); + userState.getShortcutTargetsLocked(UserShortcutType.QUICK_SETTINGS); // Removes the targets that are no longer installed on the device. boolean somethingChanged = targets.removeIf( @@ -3769,7 +3836,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub if (!somethingChanged) { return; } - userState.updateShortcutTargetsLocked(targets, QUICK_SETTINGS); + userState.updateA11yQsTargetLocked(targets); // Update setting key with new value. persistColonDelimitedSetToSettingLocked( @@ -3795,14 +3862,14 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub final List<Pair<Integer, String>> shortcutTypeAndShortcutSetting = new ArrayList<>(3); shortcutTypeAndShortcutSetting.add( - new Pair<>(HARDWARE, + new Pair<>(UserShortcutType.HARDWARE, Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE)); shortcutTypeAndShortcutSetting.add( new Pair<>(UserShortcutType.SOFTWARE, Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS)); if (android.view.accessibility.Flags.a11yQsShortcut()) { shortcutTypeAndShortcutSetting.add( - new Pair<>(QUICK_SETTINGS, + new Pair<>(UserShortcutType.QUICK_SETTINGS, Settings.Secure.ACCESSIBILITY_QS_TARGETS)); } @@ -3816,7 +3883,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub shortcutSettingName, userState.mUserId, currentTargets, str -> str); - if (shortcutType != QUICK_SETTINGS) { + if (shortcutType != UserShortcutType.QUICK_SETTINGS) { continue; } @@ -3901,7 +3968,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub mMainHandler.sendMessage(obtainMessage( AccessibilityManagerService::performAccessibilityShortcutInternal, this, - Display.DEFAULT_DISPLAY, HARDWARE, targetName)); + Display.DEFAULT_DISPLAY, UserShortcutType.HARDWARE, targetName)); } /** @@ -4048,7 +4115,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub final boolean requestA11yButton = (installedServiceInfo.flags & FLAG_REQUEST_ACCESSIBILITY_BUTTON) != 0; // Turns on / off the accessibility service - if ((targetSdk <= Build.VERSION_CODES.Q && shortcutType == HARDWARE) + if ((targetSdk <= Build.VERSION_CODES.Q && shortcutType == UserShortcutType.HARDWARE) || (targetSdk > Build.VERSION_CODES.Q && !requestA11yButton)) { if (serviceConnection == null) { logAccessibilityShortcutActivated(mContext, assignedTarget, shortcutType, @@ -4062,7 +4129,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub } return true; } - if (shortcutType == HARDWARE && targetSdk > Build.VERSION_CODES.Q + if (shortcutType == UserShortcutType.HARDWARE && targetSdk > Build.VERSION_CODES.Q && requestA11yButton) { if (!userState.getEnabledServicesLocked().contains(assignedTarget)) { enableAccessibilityServiceLocked(assignedTarget, mCurrentUserId); @@ -4155,7 +4222,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub validNewTargets = newTargets; // filter out targets that doesn't have qs shortcut - if (shortcutType == QUICK_SETTINGS) { + if (shortcutType == UserShortcutType.QUICK_SETTINGS) { validNewTargets = newTargets.stream().filter(target -> { ComponentName targetComponent = ComponentName.unflattenFromString(target); return featureToTileMap.containsKey(targetComponent); @@ -4173,10 +4240,10 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub /* defaultEmptyString= */ "" ); - if (shortcutType == QUICK_SETTINGS) { + if (shortcutType == UserShortcutType.QUICK_SETTINGS) { int numOfFeatureChanged = Math.abs(currentTargets.size() - validNewTargets.size()); logMetricForQsShortcutConfiguration(enable, numOfFeatureChanged); - userState.updateShortcutTargetsLocked(validNewTargets, QUICK_SETTINGS); + userState.updateA11yQsTargetLocked(validNewTargets); scheduleNotifyClientsOfServicesStateChangeLocked(userState); onUserStateChangedLocked(userState); } @@ -4190,7 +4257,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub } // Add or Remove tile in QS Panel - if (shortcutType == QUICK_SETTINGS) { + if (shortcutType == UserShortcutType.QUICK_SETTINGS) { mMainHandler.sendMessage(obtainMessage( AccessibilityManagerService::updateA11yTileServicesInQuickSettingsPanel, this, validNewTargets, currentTargets, userId)); @@ -4199,7 +4266,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub if (!enable) { return; } - if (shortcutType == HARDWARE) { + if (shortcutType == UserShortcutType.HARDWARE) { skipVolumeShortcutDialogTimeoutRestriction(userId); if (com.android.server.accessibility.Flags.enableHardwareShortcutDisablesWarning()) { persistIntToSetting( @@ -5605,7 +5672,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub || mShowImeWithHardKeyboardUri.equals(uri)) { userState.reconcileSoftKeyboardModeWithSettingsLocked(); } else if (mAccessibilityShortcutServiceIdUri.equals(uri)) { - if (readAccessibilityShortcutTargetsLocked(userState, HARDWARE)) { + if (readAccessibilityShortcutKeySettingLocked(userState)) { onUserStateChangedLocked(userState); } } else if (mAccessibilityButtonComponentIdUri.equals(uri)) { @@ -5613,7 +5680,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub onUserStateChangedLocked(userState); } } else if (mAccessibilityButtonTargetsUri.equals(uri)) { - if (readAccessibilityShortcutTargetsLocked(userState, SOFTWARE)) { + if (readAccessibilityButtonTargetsLocked(userState)) { onUserStateChangedLocked(userState); } } else if (mUserNonInteractiveUiTimeoutUri.equals(uri) @@ -6438,10 +6505,4 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub String metricId = enable ? METRIC_ID_QS_SHORTCUT_ADD : METRIC_ID_QS_SHORTCUT_REMOVE; Counter.logIncrementWithUid(metricId, Binder.getCallingUid(), numOfFeatures); } - - private void assertNoTapShortcut(@UserShortcutType int shortcutType) { - if ((shortcutType & (TRIPLETAP | TWOFINGER_DOUBLETAP)) != 0) { - throw new IllegalArgumentException("Tap shortcuts are not supported."); - } - } } diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java index 365d1d43d726..a37a1841fcc0 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java @@ -777,20 +777,12 @@ class AccessibilityUserState { * @return The array set of the strings */ public ArraySet<String> getShortcutTargetsLocked(@UserShortcutType int shortcutType) { - ArraySet<String> set = getShortcutTargetsInternalLocked(shortcutType); - // if it's Quick Settings, make a defensive copy. Otherwise, return the raw set. - if (shortcutType == UserShortcutType.QUICK_SETTINGS) { - set = new ArraySet<>(set); - } - return set; - } - private ArraySet<String> getShortcutTargetsInternalLocked(@UserShortcutType int shortcutType) { if (shortcutType == UserShortcutType.HARDWARE) { return mAccessibilityShortcutKeyTargets; } else if (shortcutType == UserShortcutType.SOFTWARE) { return mAccessibilityButtonTargets; } else if (shortcutType == UserShortcutType.QUICK_SETTINGS) { - return mAccessibilityQsTargets; + return getA11yQsTargets(); } else if ((shortcutType == UserShortcutType.TRIPLETAP && isMagnificationSingleFingerTripleTapEnabledLocked()) || ( shortcutType == UserShortcutType.TWOFINGER_DOUBLETAP @@ -803,32 +795,6 @@ class AccessibilityUserState { } /** - * Updates the corresponding shortcut targets with the provided set. - * Tap shortcuts don't operate using sets of targets, - * so trying to update {@code TRIPLETAP} or {@code TWOFINGER_DOUBLETAP} - * will instead throw an {@code IllegalArgumentException} - * @param newTargets set of targets to replace the existing set. - * @param shortcutType type to be replaced. - * @return {@code true} if the set was changed, or {@code false} if the elements are the same. - * @throws IllegalArgumentException if {@code TRIPLETAP} or {@code TWOFINGER_DOUBLETAP} is used. - */ - boolean updateShortcutTargetsLocked( - Set<String> newTargets, @UserShortcutType int shortcutType) { - final int mask = UserShortcutType.TRIPLETAP | UserShortcutType.TWOFINGER_DOUBLETAP; - if ((shortcutType & mask) != 0) { - throw new IllegalArgumentException("Tap shortcuts cannot be updated with target sets."); - } - - final Set<String> currentTargets = getShortcutTargetsInternalLocked(shortcutType); - if (newTargets.equals(currentTargets)) { - return false; - } - currentTargets.clear(); - currentTargets.addAll(newTargets); - return true; - } - - /** * Whether or not the given shortcut target is installed in device. * * @param name The shortcut target name @@ -878,8 +844,8 @@ class AccessibilityUserState { ); } - Set<String> targets = getShortcutTargetsInternalLocked(shortcutType); - return targets.removeIf(name -> { + Set<String> targets = getShortcutTargetsLocked(shortcutType); + boolean result = targets.removeIf(name -> { ComponentName componentName; if (name == null || (componentName = ComponentName.unflattenFromString(name)) == null) { @@ -887,6 +853,11 @@ class AccessibilityUserState { } return componentName.equals(target); }); + if (shortcutType == UserShortcutType.QUICK_SETTINGS) { + updateA11yQsTargetLocked(targets); + } + + return result; } /** @@ -1143,6 +1114,11 @@ class AccessibilityUserState { ); } + public void updateA11yQsTargetLocked(Set<String> targets) { + mAccessibilityQsTargets.clear(); + mAccessibilityQsTargets.addAll(targets); + } + /** * Returns a copy of the targets which has qs shortcut turned on */ diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java index 47258d684bd3..4e8c75559f3b 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java @@ -25,7 +25,6 @@ import static android.view.accessibility.Flags.FLAG_SKIP_ACCESSIBILITY_WARNING_D import static com.android.internal.accessibility.AccessibilityShortcutController.ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME; import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME; -import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.QUICK_SETTINGS; import static com.android.server.accessibility.AccessibilityManagerService.ACTION_LAUNCH_HEARING_DEVICES_DIALOG; import static com.android.window.flags.Flags.FLAG_ALWAYS_DRAW_MAGNIFICATION_FULLSCREEN_BORDER; @@ -1391,14 +1390,14 @@ public class AccessibilityManagerServiceTest { mA11yms.enableShortcutsForTargets( /* enable= */ true, - QUICK_SETTINGS, + UserShortcutType.QUICK_SETTINGS, List.of(TARGET_ALWAYS_ON_A11Y_SERVICE.flattenToString()), mA11yms.getCurrentUserIdLocked()); mTestableLooper.processAllMessages(); assertThat( ShortcutUtils.isComponentIdExistingInSettings( - mTestableContext, QUICK_SETTINGS, + mTestableContext, UserShortcutType.QUICK_SETTINGS, TARGET_ALWAYS_ON_A11Y_SERVICE.flattenToString()) ).isTrue(); verify(mStatusBarManagerInternal) @@ -1418,14 +1417,14 @@ public class AccessibilityManagerServiceTest { mA11yms.enableShortcutsForTargets( /* enable= */ false, - QUICK_SETTINGS, + UserShortcutType.QUICK_SETTINGS, List.of(TARGET_ALWAYS_ON_A11Y_SERVICE.flattenToString()), mA11yms.getCurrentUserIdLocked()); mTestableLooper.processAllMessages(); assertThat( ShortcutUtils.isComponentIdExistingInSettings( - mTestableContext, QUICK_SETTINGS, + mTestableContext, UserShortcutType.QUICK_SETTINGS, TARGET_ALWAYS_ON_A11Y_SERVICE.flattenToString()) ).isFalse(); verify(mStatusBarManagerInternal) @@ -1622,7 +1621,7 @@ public class AccessibilityManagerServiceTest { AccessibilityShortcutController.COLOR_INVERSION_COMPONENT_NAME.flattenToString(); final AccessibilityUserState userState = new AccessibilityUserState( UserHandle.USER_SYSTEM, mTestableContext, mA11yms); - userState.updateShortcutTargetsLocked(Set.of(daltonizerTile), QUICK_SETTINGS); + userState.updateA11yQsTargetLocked(Set.of(daltonizerTile)); mA11yms.mUserStates.put(UserHandle.USER_SYSTEM, userState); broadcastSettingRestored( @@ -1643,7 +1642,7 @@ public class AccessibilityManagerServiceTest { AccessibilityShortcutController.COLOR_INVERSION_COMPONENT_NAME.flattenToString(); final AccessibilityUserState userState = new AccessibilityUserState( UserHandle.USER_SYSTEM, mTestableContext, mA11yms); - userState.updateShortcutTargetsLocked(Set.of(daltonizerTile), QUICK_SETTINGS); + userState.updateA11yQsTargetLocked(Set.of(daltonizerTile)); mA11yms.mUserStates.put(UserHandle.USER_SYSTEM, userState); broadcastSettingRestored( diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityUserStateTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityUserStateTest.java index 9fad14d889fd..b269beb90c75 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityUserStateTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityUserStateTest.java @@ -28,7 +28,6 @@ import static android.view.accessibility.AccessibilityManager.STATE_FLAG_ACCESSI import static android.view.accessibility.AccessibilityManager.STATE_FLAG_HIGH_TEXT_CONTRAST_ENABLED; import static android.view.accessibility.AccessibilityManager.STATE_FLAG_TOUCH_EXPLORATION_ENABLED; -import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.QUICK_SETTINGS; import static com.android.server.accessibility.AccessibilityUserState.doesShortcutTargetsStringContain; import static com.google.common.truth.Truth.assertThat; @@ -430,20 +429,20 @@ public class AccessibilityUserStateTest { } @Test - public void updateShortcutTargetsLocked_quickSettings_valueUpdated() { + public void updateA11yQsTargetLocked_valueUpdated() { Set<String> newTargets = Set.of( AccessibilityShortcutController.DALTONIZER_COMPONENT_NAME.flattenToString(), AccessibilityShortcutController.COLOR_INVERSION_COMPONENT_NAME.flattenToString() ); - mUserState.updateShortcutTargetsLocked(newTargets, QUICK_SETTINGS); + mUserState.updateA11yQsTargetLocked(newTargets); assertThat(mUserState.getA11yQsTargets()).isEqualTo(newTargets); } @Test public void getA11yQsTargets_returnsCopiedData() { - updateShortcutTargetsLocked_quickSettings_valueUpdated(); + updateA11yQsTargetLocked_valueUpdated(); Set<String> targets = mUserState.getA11yQsTargets(); targets.clear(); |