Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 411775fd authored by Riley Jones's avatar Riley Jones Committed by Android (Google) Code Review
Browse files

Merge "Fix for dynamic properties persisting between service restarts" into main

parents 5998ec2b 275ad1df
Loading
Loading
Loading
Loading
+65 −2
Original line number Diff line number Diff line
@@ -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);
    }

    /**
@@ -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.
@@ -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)) {
@@ -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) {
+7 −0
Original line number Diff line number Diff line
@@ -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"
+3 −0
Original line number Diff line number Diff line
@@ -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
+1 −1
Original line number Diff line number Diff line
@@ -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;
+25 −3
Original line number Diff line number Diff line
@@ -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.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;
@@ -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;
@@ -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);

@@ -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);
@@ -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);
    }
}