Loading core/java/android/accessibilityservice/AccessibilityServiceInfo.java +65 −2 Original line number Diff line number Diff line Loading @@ -647,11 +647,44 @@ public class AccessibilityServiceInfo implements Parcelable { private int mObservedMotionEventSources = 0; // Default values for each dynamic property // LINT.IfChange(dynamic_property_defaults) private final DynamicPropertyDefaults mDynamicPropertyDefaults; private static class DynamicPropertyDefaults { private final int mEventTypesDefault; private final List<String> mPackageNamesDefault; private final int mFeedbackTypeDefault; private final long mNotificationTimeoutDefault; private final int mFlagsDefault; private final int mNonInteractiveUiTimeoutDefault; private final int mInteractiveUiTimeoutDefault; private final int mMotionEventSourcesDefault; private final int mObservedMotionEventSourcesDefault; DynamicPropertyDefaults(AccessibilityServiceInfo info) { mEventTypesDefault = info.eventTypes; if (info.packageNames != null) { mPackageNamesDefault = List.of(info.packageNames); } else { mPackageNamesDefault = null; } mFeedbackTypeDefault = info.feedbackType; mNotificationTimeoutDefault = info.notificationTimeout; mNonInteractiveUiTimeoutDefault = info.mNonInteractiveUiTimeout; mInteractiveUiTimeoutDefault = info.mInteractiveUiTimeout; mFlagsDefault = info.flags; mMotionEventSourcesDefault = info.mMotionEventSources; mObservedMotionEventSourcesDefault = info.mObservedMotionEventSources; } } // LINT.ThenChange(:dynamic_property_reset) /** * Creates a new instance. */ public AccessibilityServiceInfo() { /* do nothing */ mDynamicPropertyDefaults = new DynamicPropertyDefaults(this); } /** Loading Loading @@ -793,8 +826,36 @@ public class AccessibilityServiceInfo implements Parcelable { if (parser != null) { parser.close(); } mDynamicPropertyDefaults = new DynamicPropertyDefaults(this); } } /** * Resets all dynamically configurable properties to their default values. * * @hide */ // LINT.IfChange(dynamic_property_reset) public void resetDynamicallyConfigurableProperties() { eventTypes = mDynamicPropertyDefaults.mEventTypesDefault; if (mDynamicPropertyDefaults.mPackageNamesDefault == null) { packageNames = null; } else { packageNames = mDynamicPropertyDefaults.mPackageNamesDefault.toArray(new String[0]); } feedbackType = mDynamicPropertyDefaults.mFeedbackTypeDefault; notificationTimeout = mDynamicPropertyDefaults.mNotificationTimeoutDefault; mNonInteractiveUiTimeout = mDynamicPropertyDefaults.mNonInteractiveUiTimeoutDefault; mInteractiveUiTimeout = mDynamicPropertyDefaults.mInteractiveUiTimeoutDefault; flags = mDynamicPropertyDefaults.mFlagsDefault; mMotionEventSources = mDynamicPropertyDefaults.mMotionEventSourcesDefault; if (Flags.motionEventObserving()) { mObservedMotionEventSources = mDynamicPropertyDefaults .mObservedMotionEventSourcesDefault; } } // LINT.ThenChange(:dynamic_property_update) /** * Updates the properties that an AccessibilityService can change dynamically. Loading @@ -808,6 +869,7 @@ public class AccessibilityServiceInfo implements Parcelable { * * @hide */ // LINT.IfChange(dynamic_property_update) public void updateDynamicallyConfigurableProperties(IPlatformCompat platformCompat, AccessibilityServiceInfo other) { if (isRequestAccessibilityButtonChangeEnabled(platformCompat)) { Loading @@ -828,6 +890,7 @@ public class AccessibilityServiceInfo implements Parcelable { // NOTE: Ensure that only properties that are safe to be modified by the service itself // are included here (regardless of hidden setters, etc.). } // LINT.ThenChange(:dynamic_property_defaults) private boolean isRequestAccessibilityButtonChangeEnabled(IPlatformCompat platformCompat) { if (mResolveInfo == null) { Loading services/accessibility/accessibility.aconfig +7 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,13 @@ flag { bug: "297972548" } 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" Loading services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java +3 −0 Original line number Diff line number Diff line Loading @@ -1685,6 +1685,9 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ } public void resetLocked() { if (Flags.resettableDynamicProperties()) { mAccessibilityServiceInfo.resetDynamicallyConfigurableProperties(); } mSystemSupport.getKeyEventDispatcher().flush(this); try { // Clear the proxy in the other process so this Loading services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +1 −1 Original line number Diff line number Diff line Loading @@ -23,9 +23,9 @@ import static android.accessibilityservice.AccessibilityTrace.FLAGS_ACCESSIBILIT 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; Loading services/tests/servicestests/src/com/android/server/accessibility/AccessibilityServiceConnectionTest.java +25 −3 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -24,6 +26,7 @@ import static org.mockito.ArgumentMatchers.anyInt; 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; Loading Loading @@ -88,7 +91,7 @@ public class AccessibilityServiceConnectionTest { @Mock AccessibilityUserState mMockUserState; @Mock Context mMockContext; @Mock AccessibilityServiceInfo mMockServiceInfo; AccessibilityServiceInfo mServiceInfo; @Mock ResolveInfo mMockResolveInfo; @Mock AccessibilitySecurityPolicy mMockSecurityPolicy; @Mock AccessibilityWindowManager mMockA11yWindowManager; Loading @@ -115,7 +118,8 @@ public class AccessibilityServiceConnectionTest { 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); Loading @@ -125,7 +129,7 @@ public class AccessibilityServiceConnectionTest { .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); Loading Loading @@ -286,4 +290,22 @@ public class AccessibilityServiceConnectionTest { 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); } } Loading
core/java/android/accessibilityservice/AccessibilityServiceInfo.java +65 −2 Original line number Diff line number Diff line Loading @@ -647,11 +647,44 @@ public class AccessibilityServiceInfo implements Parcelable { private int mObservedMotionEventSources = 0; // Default values for each dynamic property // LINT.IfChange(dynamic_property_defaults) private final DynamicPropertyDefaults mDynamicPropertyDefaults; private static class DynamicPropertyDefaults { private final int mEventTypesDefault; private final List<String> mPackageNamesDefault; private final int mFeedbackTypeDefault; private final long mNotificationTimeoutDefault; private final int mFlagsDefault; private final int mNonInteractiveUiTimeoutDefault; private final int mInteractiveUiTimeoutDefault; private final int mMotionEventSourcesDefault; private final int mObservedMotionEventSourcesDefault; DynamicPropertyDefaults(AccessibilityServiceInfo info) { mEventTypesDefault = info.eventTypes; if (info.packageNames != null) { mPackageNamesDefault = List.of(info.packageNames); } else { mPackageNamesDefault = null; } mFeedbackTypeDefault = info.feedbackType; mNotificationTimeoutDefault = info.notificationTimeout; mNonInteractiveUiTimeoutDefault = info.mNonInteractiveUiTimeout; mInteractiveUiTimeoutDefault = info.mInteractiveUiTimeout; mFlagsDefault = info.flags; mMotionEventSourcesDefault = info.mMotionEventSources; mObservedMotionEventSourcesDefault = info.mObservedMotionEventSources; } } // LINT.ThenChange(:dynamic_property_reset) /** * Creates a new instance. */ public AccessibilityServiceInfo() { /* do nothing */ mDynamicPropertyDefaults = new DynamicPropertyDefaults(this); } /** Loading Loading @@ -793,8 +826,36 @@ public class AccessibilityServiceInfo implements Parcelable { if (parser != null) { parser.close(); } mDynamicPropertyDefaults = new DynamicPropertyDefaults(this); } } /** * Resets all dynamically configurable properties to their default values. * * @hide */ // LINT.IfChange(dynamic_property_reset) public void resetDynamicallyConfigurableProperties() { eventTypes = mDynamicPropertyDefaults.mEventTypesDefault; if (mDynamicPropertyDefaults.mPackageNamesDefault == null) { packageNames = null; } else { packageNames = mDynamicPropertyDefaults.mPackageNamesDefault.toArray(new String[0]); } feedbackType = mDynamicPropertyDefaults.mFeedbackTypeDefault; notificationTimeout = mDynamicPropertyDefaults.mNotificationTimeoutDefault; mNonInteractiveUiTimeout = mDynamicPropertyDefaults.mNonInteractiveUiTimeoutDefault; mInteractiveUiTimeout = mDynamicPropertyDefaults.mInteractiveUiTimeoutDefault; flags = mDynamicPropertyDefaults.mFlagsDefault; mMotionEventSources = mDynamicPropertyDefaults.mMotionEventSourcesDefault; if (Flags.motionEventObserving()) { mObservedMotionEventSources = mDynamicPropertyDefaults .mObservedMotionEventSourcesDefault; } } // LINT.ThenChange(:dynamic_property_update) /** * Updates the properties that an AccessibilityService can change dynamically. Loading @@ -808,6 +869,7 @@ public class AccessibilityServiceInfo implements Parcelable { * * @hide */ // LINT.IfChange(dynamic_property_update) public void updateDynamicallyConfigurableProperties(IPlatformCompat platformCompat, AccessibilityServiceInfo other) { if (isRequestAccessibilityButtonChangeEnabled(platformCompat)) { Loading @@ -828,6 +890,7 @@ public class AccessibilityServiceInfo implements Parcelable { // NOTE: Ensure that only properties that are safe to be modified by the service itself // are included here (regardless of hidden setters, etc.). } // LINT.ThenChange(:dynamic_property_defaults) private boolean isRequestAccessibilityButtonChangeEnabled(IPlatformCompat platformCompat) { if (mResolveInfo == null) { Loading
services/accessibility/accessibility.aconfig +7 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,13 @@ flag { bug: "297972548" } 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" Loading
services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java +3 −0 Original line number Diff line number Diff line Loading @@ -1685,6 +1685,9 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ } public void resetLocked() { if (Flags.resettableDynamicProperties()) { mAccessibilityServiceInfo.resetDynamicallyConfigurableProperties(); } mSystemSupport.getKeyEventDispatcher().flush(this); try { // Clear the proxy in the other process so this Loading
services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +1 −1 Original line number Diff line number Diff line Loading @@ -23,9 +23,9 @@ import static android.accessibilityservice.AccessibilityTrace.FLAGS_ACCESSIBILIT 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; Loading
services/tests/servicestests/src/com/android/server/accessibility/AccessibilityServiceConnectionTest.java +25 −3 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -24,6 +26,7 @@ import static org.mockito.ArgumentMatchers.anyInt; 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; Loading Loading @@ -88,7 +91,7 @@ public class AccessibilityServiceConnectionTest { @Mock AccessibilityUserState mMockUserState; @Mock Context mMockContext; @Mock AccessibilityServiceInfo mMockServiceInfo; AccessibilityServiceInfo mServiceInfo; @Mock ResolveInfo mMockResolveInfo; @Mock AccessibilitySecurityPolicy mMockSecurityPolicy; @Mock AccessibilityWindowManager mMockA11yWindowManager; Loading @@ -115,7 +118,8 @@ public class AccessibilityServiceConnectionTest { 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); Loading @@ -125,7 +129,7 @@ public class AccessibilityServiceConnectionTest { .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); Loading Loading @@ -286,4 +290,22 @@ public class AccessibilityServiceConnectionTest { 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); } }