Loading services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +17 −14 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ import static android.content.Context.DEVICE_ID_DEFAULT; import static android.provider.Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED; import static android.view.accessibility.AccessibilityManager.FlashNotificationReason; import static com.android.hardware.input.Flags.keyboardA11yMouseKeys; import static com.android.internal.accessibility.AccessibilityShortcutController.ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME; import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_COMPONENT_NAME; import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME; Loading @@ -57,7 +58,6 @@ import static com.android.internal.accessibility.util.AccessibilityStatsLogUtils import static com.android.internal.util.FunctionalUtils.ignoreRemoteException; import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage; import static com.android.server.accessibility.AccessibilityUserState.doesShortcutTargetsStringContain; import static com.android.hardware.input.Flags.keyboardA11yMouseKeys; import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; import android.accessibilityservice.AccessibilityGestureEvent; Loading Loading @@ -825,25 +825,27 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub @VisibleForTesting boolean onPackagesForceStoppedLocked( String[] packages, AccessibilityUserState userState) { final List<String> continuousServicePackages = final Set<String> packageSet = new HashSet<>(List.of(packages)); final ArrayList<ComponentName> continuousServices = new ArrayList<>( userState.mInstalledServices.stream().filter(service -> (service.flags & FLAG_REQUEST_ACCESSIBILITY_BUTTON) == FLAG_REQUEST_ACCESSIBILITY_BUTTON ).map(service -> service.getComponentName().flattenToString()).toList(); ).map(AccessibilityServiceInfo::getComponentName).toList()); // Filter out continuous packages that are not from the array of stopped packages. continuousServices.removeIf( continuousName -> !packageSet.contains(continuousName.getPackageName())); boolean enabledServicesChanged = false; final Iterator<ComponentName> it = userState.mEnabledServices.iterator(); while (it.hasNext()) { final ComponentName comp = it.next(); final String compPkg = comp.getPackageName(); for (String pkg : packages) { if (compPkg.equals(pkg)) { if (packageSet.contains(compPkg)) { it.remove(); userState.getBindingServicesLocked().remove(comp); userState.getCrashedServicesLocked().remove(comp); enabledServicesChanged = true; break; } } } if (enabledServicesChanged) { Loading @@ -855,8 +857,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub // Remove any button targets that match any stopped continuous services Set<String> buttonTargets = userState.getShortcutTargetsLocked(SOFTWARE); boolean buttonTargetsChanged = buttonTargets.removeIf( target -> continuousServicePackages.stream().anyMatch( pkg -> Objects.equals(target, pkg))); target -> continuousServices.stream().anyMatch( continuousName -> continuousName.flattenToString().equals(target))); if (buttonTargetsChanged) { userState.updateShortcutTargetsLocked(buttonTargets, SOFTWARE); persistColonDelimitedSetToSettingLocked( Loading Loading @@ -2641,7 +2643,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub } } private <T> void persistColonDelimitedSetToSettingLocked(String settingName, int userId, @VisibleForTesting <T> void persistColonDelimitedSetToSettingLocked(String settingName, int userId, Set<T> set, Function<T, String> toString) { persistColonDelimitedSetToSettingLocked(settingName, userId, set, toString, /* defaultEmptyString= */ null); Loading services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java +59 −7 Original line number Diff line number Diff line Loading @@ -840,6 +840,10 @@ public class AccessibilityManagerServiceTest { info_a.setComponentName(COMPONENT_NAME); final AccessibilityServiceInfo info_b = new AccessibilityServiceInfo(); info_b.setComponentName(new ComponentName("package", "class")); writeStringsToSetting(Set.of( info_a.getComponentName().flattenToString(), info_b.getComponentName().flattenToString()), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES); AccessibilityUserState userState = mA11yms.getCurrentUserState(); userState.mInstalledServices.clear(); Loading @@ -858,10 +862,9 @@ public class AccessibilityManagerServiceTest { userState = mA11yms.getCurrentUserState(); assertThat(userState.mEnabledServices).containsExactly(info_b.getComponentName()); //Assert setting change final Set<ComponentName> componentsFromSetting = new ArraySet<>(); mA11yms.readComponentNamesFromSettingLocked(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, userState.mUserId, componentsFromSetting); assertThat(componentsFromSetting).containsExactly(info_b.getComponentName()); final Set<String> enabledServices = readStringsFromSetting(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES); assertThat(enabledServices).containsExactly(info_b.getComponentName().flattenToString()); } @Test Loading @@ -880,6 +883,10 @@ public class AccessibilityManagerServiceTest { info_a.getComponentName().flattenToString(), info_b.getComponentName().flattenToString()), SOFTWARE); writeStringsToSetting(Set.of( info_a.getComponentName().flattenToString(), info_b.getComponentName().flattenToString()), ShortcutUtils.convertToKey(SOFTWARE)); // despite force stopping both packages, only the first service has the relevant flag, // so only the first should be removed. Loading @@ -896,12 +903,52 @@ public class AccessibilityManagerServiceTest { assertThat(userState.getShortcutTargetsLocked(SOFTWARE)).containsExactly( info_b.getComponentName().flattenToString()); //Assert setting change final Set<String> targetsFromSetting = new ArraySet<>(); mA11yms.readColonDelimitedSettingToSet(ShortcutUtils.convertToKey(SOFTWARE), userState.mUserId, str -> str, targetsFromSetting); final Set<String> targetsFromSetting = readStringsFromSetting( ShortcutUtils.convertToKey(SOFTWARE)); assertThat(targetsFromSetting).containsExactly(info_b.getComponentName().flattenToString()); } @Test public void testPackagesForceStopped_otherServiceStopped_doesNotRemoveContinuousTarget() { final AccessibilityServiceInfo info_a = new AccessibilityServiceInfo(); info_a.setComponentName(COMPONENT_NAME); info_a.flags = FLAG_REQUEST_ACCESSIBILITY_BUTTON; final AccessibilityServiceInfo info_b = new AccessibilityServiceInfo(); info_b.setComponentName(new ComponentName("package", "class")); writeStringsToSetting(Set.of( info_a.getComponentName().flattenToString(), info_b.getComponentName().flattenToString()), ShortcutUtils.convertToKey(SOFTWARE)); AccessibilityUserState userState = mA11yms.getCurrentUserState(); userState.mInstalledServices.clear(); userState.mInstalledServices.add(info_a); userState.mInstalledServices.add(info_b); userState.updateShortcutTargetsLocked(Set.of( info_a.getComponentName().flattenToString(), info_b.getComponentName().flattenToString()), SOFTWARE); // Force stopping a service should not disable unrelated continuous services. synchronized (mA11yms.getLock()) { mA11yms.onPackagesForceStoppedLocked( new String[]{info_b.getComponentName().getPackageName()}, userState); } //Assert user state change userState = mA11yms.getCurrentUserState(); assertThat(userState.getShortcutTargetsLocked(SOFTWARE)).containsExactly( info_a.getComponentName().flattenToString(), info_b.getComponentName().flattenToString()); //Assert setting unchanged final Set<String> targetsFromSetting = readStringsFromSetting( ShortcutUtils.convertToKey(SOFTWARE)); assertThat(targetsFromSetting).containsExactly( info_a.getComponentName().flattenToString(), info_b.getComponentName().flattenToString()); } @Test public void testPackageMonitorScanPackages_scansWithoutHoldingLock() { setupAccessibilityServiceConnection(0); Loading Loading @@ -1844,6 +1891,11 @@ public class AccessibilityManagerServiceTest { return result; } private void writeStringsToSetting(Set<String> strings, String setting) { mA11yms.persistColonDelimitedSetToSettingLocked( setting, UserHandle.USER_SYSTEM, strings, str -> str); } private void broadcastSettingRestored(String setting, String newValue) { Intent intent = new Intent(Intent.ACTION_SETTING_RESTORED) .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY) Loading Loading
services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +17 −14 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ import static android.content.Context.DEVICE_ID_DEFAULT; import static android.provider.Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED; import static android.view.accessibility.AccessibilityManager.FlashNotificationReason; import static com.android.hardware.input.Flags.keyboardA11yMouseKeys; import static com.android.internal.accessibility.AccessibilityShortcutController.ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME; import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_COMPONENT_NAME; import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME; Loading @@ -57,7 +58,6 @@ import static com.android.internal.accessibility.util.AccessibilityStatsLogUtils import static com.android.internal.util.FunctionalUtils.ignoreRemoteException; import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage; import static com.android.server.accessibility.AccessibilityUserState.doesShortcutTargetsStringContain; import static com.android.hardware.input.Flags.keyboardA11yMouseKeys; import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; import android.accessibilityservice.AccessibilityGestureEvent; Loading Loading @@ -825,25 +825,27 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub @VisibleForTesting boolean onPackagesForceStoppedLocked( String[] packages, AccessibilityUserState userState) { final List<String> continuousServicePackages = final Set<String> packageSet = new HashSet<>(List.of(packages)); final ArrayList<ComponentName> continuousServices = new ArrayList<>( userState.mInstalledServices.stream().filter(service -> (service.flags & FLAG_REQUEST_ACCESSIBILITY_BUTTON) == FLAG_REQUEST_ACCESSIBILITY_BUTTON ).map(service -> service.getComponentName().flattenToString()).toList(); ).map(AccessibilityServiceInfo::getComponentName).toList()); // Filter out continuous packages that are not from the array of stopped packages. continuousServices.removeIf( continuousName -> !packageSet.contains(continuousName.getPackageName())); boolean enabledServicesChanged = false; final Iterator<ComponentName> it = userState.mEnabledServices.iterator(); while (it.hasNext()) { final ComponentName comp = it.next(); final String compPkg = comp.getPackageName(); for (String pkg : packages) { if (compPkg.equals(pkg)) { if (packageSet.contains(compPkg)) { it.remove(); userState.getBindingServicesLocked().remove(comp); userState.getCrashedServicesLocked().remove(comp); enabledServicesChanged = true; break; } } } if (enabledServicesChanged) { Loading @@ -855,8 +857,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub // Remove any button targets that match any stopped continuous services Set<String> buttonTargets = userState.getShortcutTargetsLocked(SOFTWARE); boolean buttonTargetsChanged = buttonTargets.removeIf( target -> continuousServicePackages.stream().anyMatch( pkg -> Objects.equals(target, pkg))); target -> continuousServices.stream().anyMatch( continuousName -> continuousName.flattenToString().equals(target))); if (buttonTargetsChanged) { userState.updateShortcutTargetsLocked(buttonTargets, SOFTWARE); persistColonDelimitedSetToSettingLocked( Loading Loading @@ -2641,7 +2643,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub } } private <T> void persistColonDelimitedSetToSettingLocked(String settingName, int userId, @VisibleForTesting <T> void persistColonDelimitedSetToSettingLocked(String settingName, int userId, Set<T> set, Function<T, String> toString) { persistColonDelimitedSetToSettingLocked(settingName, userId, set, toString, /* defaultEmptyString= */ null); Loading
services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java +59 −7 Original line number Diff line number Diff line Loading @@ -840,6 +840,10 @@ public class AccessibilityManagerServiceTest { info_a.setComponentName(COMPONENT_NAME); final AccessibilityServiceInfo info_b = new AccessibilityServiceInfo(); info_b.setComponentName(new ComponentName("package", "class")); writeStringsToSetting(Set.of( info_a.getComponentName().flattenToString(), info_b.getComponentName().flattenToString()), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES); AccessibilityUserState userState = mA11yms.getCurrentUserState(); userState.mInstalledServices.clear(); Loading @@ -858,10 +862,9 @@ public class AccessibilityManagerServiceTest { userState = mA11yms.getCurrentUserState(); assertThat(userState.mEnabledServices).containsExactly(info_b.getComponentName()); //Assert setting change final Set<ComponentName> componentsFromSetting = new ArraySet<>(); mA11yms.readComponentNamesFromSettingLocked(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, userState.mUserId, componentsFromSetting); assertThat(componentsFromSetting).containsExactly(info_b.getComponentName()); final Set<String> enabledServices = readStringsFromSetting(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES); assertThat(enabledServices).containsExactly(info_b.getComponentName().flattenToString()); } @Test Loading @@ -880,6 +883,10 @@ public class AccessibilityManagerServiceTest { info_a.getComponentName().flattenToString(), info_b.getComponentName().flattenToString()), SOFTWARE); writeStringsToSetting(Set.of( info_a.getComponentName().flattenToString(), info_b.getComponentName().flattenToString()), ShortcutUtils.convertToKey(SOFTWARE)); // despite force stopping both packages, only the first service has the relevant flag, // so only the first should be removed. Loading @@ -896,12 +903,52 @@ public class AccessibilityManagerServiceTest { assertThat(userState.getShortcutTargetsLocked(SOFTWARE)).containsExactly( info_b.getComponentName().flattenToString()); //Assert setting change final Set<String> targetsFromSetting = new ArraySet<>(); mA11yms.readColonDelimitedSettingToSet(ShortcutUtils.convertToKey(SOFTWARE), userState.mUserId, str -> str, targetsFromSetting); final Set<String> targetsFromSetting = readStringsFromSetting( ShortcutUtils.convertToKey(SOFTWARE)); assertThat(targetsFromSetting).containsExactly(info_b.getComponentName().flattenToString()); } @Test public void testPackagesForceStopped_otherServiceStopped_doesNotRemoveContinuousTarget() { final AccessibilityServiceInfo info_a = new AccessibilityServiceInfo(); info_a.setComponentName(COMPONENT_NAME); info_a.flags = FLAG_REQUEST_ACCESSIBILITY_BUTTON; final AccessibilityServiceInfo info_b = new AccessibilityServiceInfo(); info_b.setComponentName(new ComponentName("package", "class")); writeStringsToSetting(Set.of( info_a.getComponentName().flattenToString(), info_b.getComponentName().flattenToString()), ShortcutUtils.convertToKey(SOFTWARE)); AccessibilityUserState userState = mA11yms.getCurrentUserState(); userState.mInstalledServices.clear(); userState.mInstalledServices.add(info_a); userState.mInstalledServices.add(info_b); userState.updateShortcutTargetsLocked(Set.of( info_a.getComponentName().flattenToString(), info_b.getComponentName().flattenToString()), SOFTWARE); // Force stopping a service should not disable unrelated continuous services. synchronized (mA11yms.getLock()) { mA11yms.onPackagesForceStoppedLocked( new String[]{info_b.getComponentName().getPackageName()}, userState); } //Assert user state change userState = mA11yms.getCurrentUserState(); assertThat(userState.getShortcutTargetsLocked(SOFTWARE)).containsExactly( info_a.getComponentName().flattenToString(), info_b.getComponentName().flattenToString()); //Assert setting unchanged final Set<String> targetsFromSetting = readStringsFromSetting( ShortcutUtils.convertToKey(SOFTWARE)); assertThat(targetsFromSetting).containsExactly( info_a.getComponentName().flattenToString(), info_b.getComponentName().flattenToString()); } @Test public void testPackageMonitorScanPackages_scansWithoutHoldingLock() { setupAccessibilityServiceConnection(0); Loading Loading @@ -1844,6 +1891,11 @@ public class AccessibilityManagerServiceTest { return result; } private void writeStringsToSetting(Set<String> strings, String setting) { mA11yms.persistColonDelimitedSetToSettingLocked( setting, UserHandle.USER_SYSTEM, strings, str -> str); } private void broadcastSettingRestored(String setting, String newValue) { Intent intent = new Intent(Intent.ACTION_SETTING_RESTORED) .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY) Loading