Clears the default service from A11Y_SHORTCUT B&R.

If the restored value contains the default service then it is removed,
unless the previous value (pre-restore) also contains the default
service.

Bug: 341374402
Flag: com.android.server.accessibility.clear_default_from_a11y_shortcut_target_service_restore
Test: atest AccessibilityManagerServiceTest
Test: Create a backup with the default service in the Setting.
      - Restore backup when the Setting is empty.
        Observe Setting is unchanged.
      - Restore backup when the Setting has another service.
	Observe Setting is unchanged.
      - Restore backup when the Setting already has the default service.
        Observe Setting keeps the default service.
Change-Id: Id7f9e6de96f032abf1f073cbef801fd2dbcee9a1
diff --git a/services/accessibility/accessibility.aconfig b/services/accessibility/accessibility.aconfig
index a50fb9a..1c57dd3 100644
--- a/services/accessibility/accessibility.aconfig
+++ b/services/accessibility/accessibility.aconfig
@@ -25,6 +25,16 @@
 }
 
 flag {
+    name: "clear_default_from_a11y_shortcut_target_service_restore"
+    namespace: "accessibility"
+    description: "Clears the config_defaultAccessibilityService from B&R for ACCESSIBILITY_SHORTCUT_TARGET_SERVICE."
+    bug: "341374402"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
+
+flag {
     name: "compute_window_changes_on_a11y_v2"
     namespace: "accessibility"
     description: "Computes accessibility window changes in accessibility instead of wm package."
@@ -209,4 +219,4 @@
     namespace: "accessibility"
     description: "Feature allows users to change color correction saturation for daltonizer."
     bug: "322829049"
-}
\ No newline at end of file
+}
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index c55e9ea..f3dd635 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -2098,14 +2098,36 @@
     /**
      * 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 =
@@ -2120,6 +2142,18 @@
         }
     }
 
+    /**
+     * Returns {@code true} if the set contains the provided non-null {@link ComponentName}.
+     *
+     * <p>This ignores values in the set that are not valid {@link ComponentName}s.
+     */
+    private boolean stringSetContainsComponentName(Set<String> set,
+            @NonNull ComponentName componentName) {
+        return componentName != null && set.stream()
+                .map(ComponentName::unflattenFromString)
+                .anyMatch(componentName::equals);
+    }
+
     private int getClientStateLocked(AccessibilityUserState userState) {
         return userState.getClientStateLocked(
             mUiAutomationManager.canIntrospect(),
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 78cd2c1..fe5144e 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
@@ -1707,6 +1707,64 @@
                 .containsExactlyElementsIn(expected);
     }
 
+    @Test
+    @EnableFlags({
+            android.view.accessibility.Flags.FLAG_RESTORE_A11Y_SHORTCUT_TARGET_SERVICE,
+            Flags.FLAG_CLEAR_DEFAULT_FROM_A11Y_SHORTCUT_TARGET_SERVICE_RESTORE})
+    public void restoreA11yShortcutTargetService_alreadyHadDefaultService_doesNotClear() {
+        final String serviceDefault = TARGET_STANDARD_A11Y_SERVICE.flattenToString();
+        mTestableContext.getOrCreateTestableResources().addOverride(
+                R.string.config_defaultAccessibilityService, serviceDefault);
+        final AccessibilityUserState userState = new AccessibilityUserState(
+                UserHandle.USER_SYSTEM, mTestableContext, mA11yms);
+        mA11yms.mUserStates.put(UserHandle.USER_SYSTEM, userState);
+        setupShortcutTargetServices(userState);
+
+        broadcastSettingRestored(
+                Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE,
+                /*previousValue=*/serviceDefault,
+                /*newValue=*/serviceDefault);
+
+        final Set<String> expected = Set.of(serviceDefault);
+        assertThat(readStringsFromSetting(
+                Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE))
+                .containsExactlyElementsIn(expected);
+        assertThat(mA11yms.mUserStates.get(UserHandle.USER_SYSTEM)
+                .getShortcutTargetsLocked(UserShortcutType.HARDWARE))
+                .containsExactlyElementsIn(expected);
+    }
+
+    @Test
+    @EnableFlags({
+            android.view.accessibility.Flags.FLAG_RESTORE_A11Y_SHORTCUT_TARGET_SERVICE,
+            Flags.FLAG_CLEAR_DEFAULT_FROM_A11Y_SHORTCUT_TARGET_SERVICE_RESTORE})
+    public void restoreA11yShortcutTargetService_didNotHaveDefaultService_clearsDefaultService() {
+        final String serviceDefault = TARGET_STANDARD_A11Y_SERVICE.flattenToString();
+        final String serviceRestored = TARGET_ALWAYS_ON_A11Y_SERVICE.flattenToString();
+        // Restored value from the broadcast contains both default and non-default service.
+        final String combinedRestored = String.join(":", serviceDefault, serviceRestored);
+        mTestableContext.getOrCreateTestableResources().addOverride(
+                R.string.config_defaultAccessibilityService, serviceDefault);
+        final AccessibilityUserState userState = new AccessibilityUserState(
+                UserHandle.USER_SYSTEM, mTestableContext, mA11yms);
+        mA11yms.mUserStates.put(UserHandle.USER_SYSTEM, userState);
+        setupShortcutTargetServices(userState);
+
+        broadcastSettingRestored(
+                Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE,
+                /*previousValue=*/null,
+                /*newValue=*/combinedRestored);
+
+        // The default service is cleared from the final restored value.
+        final Set<String> expected = Set.of(serviceRestored);
+        assertThat(readStringsFromSetting(
+                Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE))
+                .containsExactlyElementsIn(expected);
+        assertThat(mA11yms.mUserStates.get(UserHandle.USER_SYSTEM)
+                .getShortcutTargetsLocked(UserShortcutType.HARDWARE))
+                .containsExactlyElementsIn(expected);
+    }
+
     private Set<String> readStringsFromSetting(String setting) {
         final Set<String> result = new ArraySet<>();
         mA11yms.readColonDelimitedSettingToSet(