diff options
4 files changed, 75 insertions, 72 deletions
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java index c6fe4971b9e5..974cba2450f4 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -52,6 +52,7 @@ 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.ALL; import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.GESTURE; import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.HARDWARE; import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.QUICK_SETTINGS; @@ -3897,6 +3898,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub userState.getShortcutTargetsLocked(HARDWARE); final Set<String> qsShortcutTargets = userState.getShortcutTargetsLocked(QUICK_SETTINGS); + final Set<String> shortcutTargets = userState.getShortcutTargetsLocked(ALL); userState.mEnabledServices.forEach(componentName -> { if (packageName != null && componentName != null && !packageName.equals(componentName.getPackageName())) { @@ -3917,7 +3919,11 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub if (TextUtils.isEmpty(serviceName)) { return; } - if (doesShortcutTargetsStringContain(buttonTargets, serviceName) + if (android.provider.Flags.a11yStandaloneGestureEnabled()) { + if (doesShortcutTargetsStringContain(shortcutTargets, serviceName)) { + return; + } + } else if (doesShortcutTargetsStringContain(buttonTargets, serviceName) || doesShortcutTargetsStringContain(shortcutKeyTargets, serviceName) || doesShortcutTargetsStringContain(qsShortcutTargets, serviceName)) { return; diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java index 0bf7ec001d4d..67b40632dde8 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java @@ -106,21 +106,17 @@ class AccessibilityUserState { final Set<ComponentName> mTouchExplorationGrantedServices = new HashSet<>(); - private final ArraySet<String> mAccessibilityShortcutKeyTargets = new ArraySet<>(); - - private final ArraySet<String> mAccessibilityButtonTargets = new ArraySet<>(); - private final ArraySet<String> mAccessibilityGestureTargets = new ArraySet<>(); - private final ArraySet<String> mAccessibilityQsTargets = new ArraySet<>(); + private final HashMap<Integer, ArraySet<String>> mShortcutTargets = new HashMap<>(); /** - * The QuickSettings tiles in the QS Panel. This can be different from - * {@link #mAccessibilityQsTargets} in that {@link #mA11yTilesInQsPanel} stores the + * The QuickSettings tiles in the QS Panel. This can be different from the QS targets in + * {@link #mShortcutTargets} in that {@link #mA11yTilesInQsPanel} stores the * TileService's or the a11y framework tile component names (e.g. * {@link AccessibilityShortcutController#COLOR_INVERSION_TILE_COMPONENT_NAME}) instead of the * A11y Feature's component names. * <p/> * In addition, {@link #mA11yTilesInQsPanel} stores what's on the QS Panel, whereas - * {@link #mAccessibilityQsTargets} stores the targets that configured qs as their shortcut and + * {@link #mShortcutTargets} stores the targets that configured qs as their shortcut and * also grant full device control permission. */ private final ArraySet<ComponentName> mA11yTilesInQsPanel = new ArraySet<>(); @@ -208,6 +204,11 @@ class AccessibilityUserState { mSupportWindowMagnification = mContext.getResources().getBoolean( R.bool.config_magnification_area) && mContext.getPackageManager().hasSystemFeature( PackageManager.FEATURE_WINDOW_MAGNIFICATION); + + mShortcutTargets.put(HARDWARE, new ArraySet<>()); + mShortcutTargets.put(SOFTWARE, new ArraySet<>()); + mShortcutTargets.put(GESTURE, new ArraySet<>()); + mShortcutTargets.put(QUICK_SETTINGS, new ArraySet<>()); } boolean isHandlingAccessibilityEventsLocked() { @@ -233,10 +234,7 @@ class AccessibilityUserState { // Clear state persisted in settings. mEnabledServices.clear(); mTouchExplorationGrantedServices.clear(); - mAccessibilityShortcutKeyTargets.clear(); - mAccessibilityButtonTargets.clear(); - mAccessibilityGestureTargets.clear(); - mAccessibilityQsTargets.clear(); + mShortcutTargets.forEach((type, targets) -> targets.clear()); mA11yTilesInQsPanel.clear(); mTargetAssignedToAccessibilityButton = null; mIsTouchExplorationEnabled = false; @@ -541,7 +539,7 @@ class AccessibilityUserState { private void dumpShortcutTargets( PrintWriter pw, @UserShortcutType int shortcutType, String name) { pw.append(" ").append(name).append(":{"); - ArraySet<String> targets = getShortcutTargetsInternalLocked(shortcutType); + ArraySet<String> targets = getShortcutTargetsLocked(shortcutType); int size = targets.size(); for (int i = 0; i < size; i++) { if (i > 0) { @@ -712,7 +710,7 @@ class AccessibilityUserState { */ public boolean isShortcutMagnificationEnabledLocked() { for (int shortcutType : ShortcutConstants.USER_SHORTCUT_TYPES) { - if (getShortcutTargetsInternalLocked(shortcutType) + if (getShortcutTargetsLocked(shortcutType) .contains(MAGNIFICATION_CONTROLLER_NAME)) { return true; } @@ -788,43 +786,29 @@ class AccessibilityUserState { } /** - * Disable both shortcuts' magnification function. - */ - public void disableShortcutMagnificationLocked() { - mAccessibilityShortcutKeyTargets.remove(MAGNIFICATION_CONTROLLER_NAME); - mAccessibilityButtonTargets.remove(MAGNIFICATION_CONTROLLER_NAME); - } - - /** * Returns a set which contains the flattened component names and the system class names - * assigned to the given shortcut. The set is a defensive copy. To apply any changes to the set, - * use {@link #updateShortcutTargetsLocked(Set, int)} + * assigned to the given shortcut. <strong>The set is a defensive copy.</strong> + * To apply any changes to the set, use {@link #updateShortcutTargetsLocked(Set, int)} * - * @param shortcutType The shortcut type. + * @param shortcutTypes The shortcut type or types (in bitmask format). * @return The array set of the strings */ - public ArraySet<String> getShortcutTargetsLocked(@UserShortcutType int shortcutType) { - return new ArraySet<>(getShortcutTargetsInternalLocked(shortcutType)); - } - - private ArraySet<String> getShortcutTargetsInternalLocked(@UserShortcutType int shortcutType) { - if (shortcutType == HARDWARE) { - return mAccessibilityShortcutKeyTargets; - } else if (shortcutType == SOFTWARE) { - return mAccessibilityButtonTargets; - } else if (shortcutType == GESTURE) { - return mAccessibilityGestureTargets; - } else if (shortcutType == QUICK_SETTINGS) { - return mAccessibilityQsTargets; - } else if ((shortcutType == TRIPLETAP - && isMagnificationSingleFingerTripleTapEnabledLocked()) || ( - shortcutType == TWOFINGER_DOUBLETAP - && isMagnificationTwoFingerTripleTapEnabledLocked())) { - ArraySet<String> targets = new ArraySet<>(); - targets.add(MAGNIFICATION_CONTROLLER_NAME); - return targets; + public ArraySet<String> getShortcutTargetsLocked(int shortcutTypes) { + ArraySet<String> targets = new ArraySet<>(); + for (int shortcutType : ShortcutConstants.USER_SHORTCUT_TYPES) { + if ((shortcutTypes & shortcutType) != shortcutType) { + continue; + } + if ((shortcutType == TRIPLETAP + && isMagnificationSingleFingerTripleTapEnabledLocked()) || ( + shortcutType == TWOFINGER_DOUBLETAP + && isMagnificationTwoFingerTripleTapEnabledLocked())) { + targets.add(MAGNIFICATION_CONTROLLER_NAME); + } else if (mShortcutTargets.containsKey(shortcutType)) { + targets.addAll(mShortcutTargets.get(shortcutType)); + } } - return new ArraySet<>(); + return targets; } /** @@ -843,8 +827,10 @@ class AccessibilityUserState { if ((shortcutType & mask) != 0) { throw new IllegalArgumentException("Tap shortcuts cannot be updated with target sets."); } - - final Set<String> currentTargets = getShortcutTargetsInternalLocked(shortcutType); + if (!mShortcutTargets.containsKey(shortcutType)) { + mShortcutTargets.put(shortcutType, new ArraySet<>()); + } + ArraySet<String> currentTargets = mShortcutTargets.get(shortcutType); if (newTargets.equals(currentTargets)) { return false; } @@ -904,7 +890,7 @@ class AccessibilityUserState { } // getting internal set lets us directly modify targets, as it's not a copy. - Set<String> targets = getShortcutTargetsInternalLocked(shortcutType); + Set<String> targets = mShortcutTargets.get(shortcutType); return targets.removeIf(name -> { ComponentName componentName; if (name == null @@ -1169,13 +1155,6 @@ class AccessibilityUserState { ); } - /** - * Returns a copy of the targets which has qs shortcut turned on - */ - public ArraySet<String> getA11yQsTargets() { - return new ArraySet<>(mAccessibilityQsTargets); - } - public void updateA11yTilesInQsPanelLocked(Set<ComponentName> componentNames) { mA11yTilesInQsPanel.clear(); mA11yTilesInQsPanel.addAll(componentNames); 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 7481fc8ec46d..2edde9b74d0a 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java @@ -1615,7 +1615,8 @@ public class AccessibilityManagerServiceTest { List.of(tile) ); - assertThat(mA11yms.getCurrentUserState().getA11yQsTargets()).doesNotContain(tile); + assertThat(mA11yms.getCurrentUserState() + .getShortcutTargetsLocked(QUICK_SETTINGS)).doesNotContain(tile.flattenToString()); } @Test @@ -1636,7 +1637,7 @@ public class AccessibilityManagerServiceTest { List.of(tile) ); - assertThat(mA11yms.getCurrentUserState().getA11yQsTargets()) + assertThat(mA11yms.getCurrentUserState().getShortcutTargetsLocked(QUICK_SETTINGS)) .contains(TARGET_ALWAYS_ON_A11Y_SERVICE.flattenToString()); } @@ -1656,7 +1657,7 @@ public class AccessibilityManagerServiceTest { ); assertThat( - mA11yms.getCurrentUserState().getA11yQsTargets() + mA11yms.getCurrentUserState().getShortcutTargetsLocked(QUICK_SETTINGS) ).containsExactlyElementsIn(List.of( AccessibilityShortcutController.DALTONIZER_COMPONENT_NAME.flattenToString(), AccessibilityShortcutController.COLOR_INVERSION_COMPONENT_NAME.flattenToString()) @@ -1676,7 +1677,7 @@ public class AccessibilityManagerServiceTest { ); assertThat( - mA11yms.getCurrentUserState().getA11yQsTargets() + mA11yms.getCurrentUserState().getShortcutTargetsLocked(QUICK_SETTINGS) ).doesNotContain( AccessibilityShortcutController.DALTONIZER_COMPONENT_NAME.flattenToString()); } 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 627b5e39a20a..8c35925debff 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityUserStateTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityUserStateTest.java @@ -29,6 +29,7 @@ import static android.view.accessibility.AccessibilityManager.STATE_FLAG_HIGH_TE import static android.view.accessibility.AccessibilityManager.STATE_FLAG_TOUCH_EXPLORATION_ENABLED; import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME; +import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.ALL; import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.GESTURE; import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.HARDWARE; import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.QUICK_SETTINGS; @@ -72,6 +73,7 @@ import com.android.internal.R; import com.android.internal.accessibility.AccessibilityShortcutController; import com.android.internal.accessibility.common.ShortcutConstants; import com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType; +import com.android.internal.accessibility.util.ShortcutUtils; import com.android.internal.util.test.FakeSettingsProvider; import org.junit.After; @@ -454,17 +456,7 @@ public class AccessibilityUserStateTest { mUserState.updateShortcutTargetsLocked(newTargets, QUICK_SETTINGS); - assertThat(mUserState.getA11yQsTargets()).isEqualTo(newTargets); - } - - @Test - public void getA11yQsTargets_returnsCopiedData() { - updateShortcutTargetsLocked_quickSettings_valueUpdated(); - - Set<String> targets = mUserState.getA11yQsTargets(); - targets.clear(); - - assertThat(mUserState.getA11yQsTargets()).isNotEmpty(); + assertThat(mUserState.getShortcutTargetsLocked(QUICK_SETTINGS)).isEqualTo(newTargets); } @Test @@ -539,6 +531,31 @@ public class AccessibilityUserStateTest { assertThat(mUserState.isShortcutMagnificationEnabledLocked()).isFalse(); } + @Test + public void getShortcutTargetsLocked_returnsCorrectTargets() { + for (int shortcutType : ShortcutConstants.USER_SHORTCUT_TYPES) { + if (((TRIPLETAP | TWOFINGER_DOUBLETAP) & shortcutType) == shortcutType) { + continue; + } + Set<String> expectedSet = Set.of(ShortcutUtils.convertToKey(shortcutType)); + mUserState.updateShortcutTargetsLocked(expectedSet, shortcutType); + + assertThat(mUserState.getShortcutTargetsLocked(shortcutType)) + .containsExactlyElementsIn(expectedSet); + } + } + + @Test + public void getShortcutTargetsLocked_returnsCopiedData() { + Set<String> set = Set.of("FOO", "BAR"); + mUserState.updateShortcutTargetsLocked(set, SOFTWARE); + + Set<String> targets = mUserState.getShortcutTargetsLocked(ALL); + targets.clear(); + + assertThat(mUserState.getShortcutTargetsLocked(ALL)).isNotEmpty(); + } + private int getSecureIntForUser(String key, int userId) { return Settings.Secure.getIntForUser(mMockResolver, key, -1, userId); } |