Fix for dynamic properties persisting between service restarts

NO_IFTTT=change adds IFTTT
Bug: 312386990
Test: atest AccessibilityServiceInfoTest
Flag: aconfig com.android.server.accessibility.cache_a11y_service_infos_for_restarting

Change-Id: I6b7d669629fdf066a3e199fac025c155dffabdd3
diff --git a/services/accessibility/accessibility.aconfig b/services/accessibility/accessibility.aconfig
index f902439..015c35e 100644
--- a/services/accessibility/accessibility.aconfig
+++ b/services/accessibility/accessibility.aconfig
@@ -10,6 +10,13 @@
 }
 
 flag {
+    name: "resettable_dynamic_properties"
+    namespace: "accessibility"
+    description: "Maintains initial copies of a11yServiceInfo dynamic properties so they can reset on disconnect."
+    bug: "312386990"
+}
+
+flag {
     name: "cleanup_a11y_overlays"
     namespace: "accessibility"
     description: "Removes all attached accessibility overlays when a service is removed."
diff --git a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
index 1d73843..b64c74e 100644
--- a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
+++ b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
@@ -1685,6 +1685,9 @@
     }
 
     public void resetLocked() {
+        if (Flags.resettableDynamicProperties()) {
+            mAccessibilityServiceInfo.resetDynamicallyConfigurableProperties();
+        }
         mSystemSupport.getKeyEventDispatcher().flush(this);
         try {
             // Clear the proxy in the other process so this
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index c58cb72..87b57b0 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -23,9 +23,9 @@
 import static android.accessibilityservice.AccessibilityTrace.FLAGS_ACCESSIBILITY_SERVICE_CLIENT;
 import static android.accessibilityservice.AccessibilityTrace.FLAGS_FINGERPRINT;
 import static android.accessibilityservice.AccessibilityTrace.FLAGS_INPUT_FILTER;
+import static android.accessibilityservice.AccessibilityTrace.FLAGS_MAGNIFICATION_CONNECTION;
 import static android.accessibilityservice.AccessibilityTrace.FLAGS_PACKAGE_BROADCAST_RECEIVER;
 import static android.accessibilityservice.AccessibilityTrace.FLAGS_USER_BROADCAST_RECEIVER;
-import static android.accessibilityservice.AccessibilityTrace.FLAGS_MAGNIFICATION_CONNECTION;
 import static android.accessibilityservice.AccessibilityTrace.FLAGS_WINDOW_MANAGER_INTERNAL;
 import static android.companion.virtual.VirtualDeviceManager.ACTION_VIRTUAL_DEVICE_REMOVED;
 import static android.companion.virtual.VirtualDeviceManager.EXTRA_VIRTUAL_DEVICE_ID;
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityServiceConnectionTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityServiceConnectionTest.java
index 2f0257a..ef80b59 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityServiceConnectionTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityServiceConnectionTest.java
@@ -16,6 +16,8 @@
 
 package com.android.server.accessibility;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertTrue;
 
@@ -24,6 +26,7 @@
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -88,7 +91,7 @@
 
     @Mock AccessibilityUserState mMockUserState;
     @Mock Context mMockContext;
-    @Mock AccessibilityServiceInfo mMockServiceInfo;
+    AccessibilityServiceInfo mServiceInfo;
     @Mock ResolveInfo mMockResolveInfo;
     @Mock AccessibilitySecurityPolicy mMockSecurityPolicy;
     @Mock AccessibilityWindowManager mMockA11yWindowManager;
@@ -115,7 +118,8 @@
         when(mMockSystemSupport.getMotionEventInjectorForDisplayLocked(
                 Display.DEFAULT_DISPLAY)).thenReturn(mMockMotionEventInjector);
 
-        when(mMockServiceInfo.getResolveInfo()).thenReturn(mMockResolveInfo);
+        mServiceInfo = spy(new AccessibilityServiceInfo());
+        when(mServiceInfo.getResolveInfo()).thenReturn(mMockResolveInfo);
         mMockResolveInfo.serviceInfo = mock(ServiceInfo.class);
         mMockResolveInfo.serviceInfo.applicationInfo = mock(ApplicationInfo.class);
 
@@ -125,7 +129,7 @@
                 .thenReturn(new DisplayManager(mMockContext));
 
         mConnection = new AccessibilityServiceConnection(mMockUserState, mMockContext,
-                COMPONENT_NAME, mMockServiceInfo, SERVICE_ID, mHandler, new Object(),
+                COMPONENT_NAME, mServiceInfo, SERVICE_ID, mHandler, new Object(),
                 mMockSecurityPolicy, mMockSystemSupport, mMockA11yTrace,
                 mMockWindowManagerInternal, mMockSystemActionPerformer,
                 mMockA11yWindowManager, mMockActivityTaskManagerInternal);
@@ -286,4 +290,22 @@
         verify(mMockMagnificationProcessor).resetAllIfNeeded(anyInt());
     }
 
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_RESETTABLE_DYNAMIC_PROPERTIES)
+    public void binderDied_resetA11yServiceInfo() {
+        final int flag = AccessibilityServiceInfo.FLAG_REPORT_VIEW_IDS;
+        setServiceBinding(COMPONENT_NAME);
+        mConnection.bindLocked();
+        mConnection.onServiceConnected(COMPONENT_NAME, mMockIBinder);
+        AccessibilityServiceInfo info = mConnection.getServiceInfo();
+        assertThat(info.flags & flag).isEqualTo(0);
+
+        info = mConnection.getServiceInfo();
+        info.flags |= flag;
+        mConnection.setServiceInfo(info);
+        assertThat(mConnection.getServiceInfo().flags & flag).isEqualTo(flag);
+
+        mConnection.binderDied();
+        assertThat(mConnection.getServiceInfo().flags & flag).isEqualTo(0);
+    }
 }