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

Commit f4ff4954 authored by Sally Yuen's avatar Sally Yuen Committed by Automerger Merge Worker
Browse files

Merge "Add unit tests for ProxyManager" into udc-dev am: 9abe4e54

parents 1242ea3d 9abe4e54
Loading
Loading
Loading
Loading
+4 −7
Original line number Original line Diff line number Diff line
@@ -1012,8 +1012,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
                                + Binder.getCallingPid() + " for device id " + deviceId
                                + Binder.getCallingPid() + " for device id " + deviceId
                                + " with package names " + Arrays.toString(client.mPackageNames));
                                + " with package names " + Arrays.toString(client.mPackageNames));
                    }
                    }
                    return IntPair.of(mProxyManager.getStateLocked(deviceId,
                    return IntPair.of(mProxyManager.getStateLocked(deviceId),
                                    mUiAutomationManager.isUiAutomationRunningLocked()),
                            client.mLastSentRelevantEventTypes);
                            client.mLastSentRelevantEventTypes);
                }
                }
                mGlobalClients.register(callback, client);
                mGlobalClients.register(callback, client);
@@ -1028,8 +1027,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
                                + Binder.getCallingPid() + " for device id " + deviceId
                                + Binder.getCallingPid() + " for device id " + deviceId
                                + " with package names " + Arrays.toString(client.mPackageNames));
                                + " with package names " + Arrays.toString(client.mPackageNames));
                    }
                    }
                    return IntPair.of(mProxyManager.getStateLocked(deviceId,
                    return IntPair.of(mProxyManager.getStateLocked(deviceId),
                                    mUiAutomationManager.isUiAutomationRunningLocked()),
                            client.mLastSentRelevantEventTypes);
                            client.mLastSentRelevantEventTypes);
                }
                }
                userState.mUserClients.register(callback, client);
                userState.mUserClients.register(callback, client);
@@ -4024,9 +4022,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub


        final long identity = Binder.clearCallingIdentity();
        final long identity = Binder.clearCallingIdentity();
        try {
        try {
            mProxyManager.registerProxy(client, displayId, mContext,
            mProxyManager.registerProxy(client, displayId, sIdCounter++, mSecurityPolicy,
                    sIdCounter++, mMainHandler, mSecurityPolicy, this, getTraceManager(),
                    this, getTraceManager(), mWindowManagerService);
                    mWindowManagerService);


            synchronized (mLock) {
            synchronized (mLock) {
                notifyClearAccessibilityCacheLocked();
                notifyClearAccessibilityCacheLocked();
+23 −23
Original line number Original line Diff line number Diff line
@@ -61,7 +61,6 @@ import java.util.function.Consumer;
 * proxy connection will belong to a separate user state.
 * proxy connection will belong to a separate user state.
 *
 *
 * TODO(241117292): Remove or cut down during simultaneous user refactoring.
 * TODO(241117292): Remove or cut down during simultaneous user refactoring.
 * TODO(262244375): Add unit tests.
 */
 */
public class ProxyManager {
public class ProxyManager {
    private static final boolean DEBUG = false;
    private static final boolean DEBUG = false;
@@ -128,7 +127,7 @@ public class ProxyManager {
        RemoteCallbackList<IAccessibilityManagerClient> getCurrentUserClientsLocked();
        RemoteCallbackList<IAccessibilityManagerClient> getCurrentUserClientsLocked();
    }
    }


    ProxyManager(Object lock, AccessibilityWindowManager awm,
    public ProxyManager(Object lock, AccessibilityWindowManager awm,
            Context context, Handler mainHandler, UiAutomationManager uiAutomationManager,
            Context context, Handler mainHandler, UiAutomationManager uiAutomationManager,
            SystemSupport systemSupport) {
            SystemSupport systemSupport) {
        mLock = lock;
        mLock = lock;
@@ -144,9 +143,7 @@ public class ProxyManager {
     * Creates the service connection.
     * Creates the service connection.
     */
     */
    public void registerProxy(IAccessibilityServiceClient client, int displayId,
    public void registerProxy(IAccessibilityServiceClient client, int displayId,
            Context context,
            int id, AccessibilitySecurityPolicy securityPolicy,
            int id, Handler mainHandler,
            AccessibilitySecurityPolicy securityPolicy,
            AbstractAccessibilityServiceConnection.SystemSupport systemSupport,
            AbstractAccessibilityServiceConnection.SystemSupport systemSupport,
            AccessibilityTrace trace,
            AccessibilityTrace trace,
            WindowManagerInternal windowManagerInternal) throws RemoteException {
            WindowManagerInternal windowManagerInternal) throws RemoteException {
@@ -169,8 +166,8 @@ public class ProxyManager {
        info.setComponentName(new ComponentName(PROXY_COMPONENT_PACKAGE_NAME,
        info.setComponentName(new ComponentName(PROXY_COMPONENT_PACKAGE_NAME,
                componentClassDisplayName));
                componentClassDisplayName));
        ProxyAccessibilityServiceConnection connection =
        ProxyAccessibilityServiceConnection connection =
                new ProxyAccessibilityServiceConnection(context, info.getComponentName(), info,
                new ProxyAccessibilityServiceConnection(mContext, info.getComponentName(), info,
                        id, mainHandler, mLock, securityPolicy, systemSupport, trace,
                        id, mMainHandler, mLock, securityPolicy, systemSupport, trace,
                        windowManagerInternal,
                        windowManagerInternal,
                        mA11yWindowManager, displayId, deviceId);
                        mA11yWindowManager, displayId, deviceId);


@@ -263,7 +260,7 @@ public class ProxyManager {
     * When the connection is removed from tracking in ProxyManager, propagate changes to other a11y
     * When the connection is removed from tracking in ProxyManager, propagate changes to other a11y
     * system components like the input filter and IAccessibilityManagerClients.
     * system components like the input filter and IAccessibilityManagerClients.
     */
     */
    public void updateStateForRemovedDisplay(int displayId, int deviceId) {
    private void updateStateForRemovedDisplay(int displayId, int deviceId) {
        mA11yWindowManager.stopTrackingDisplayProxy(displayId);
        mA11yWindowManager.stopTrackingDisplayProxy(displayId);
        // A11yInputFilter isn't thread-safe, so post on the system thread.
        // A11yInputFilter isn't thread-safe, so post on the system thread.
        mMainHandler.post(
        mMainHandler.post(
@@ -360,8 +357,9 @@ public class ProxyManager {
    /**
    /**
     * If there is at least one proxy, accessibility is enabled.
     * If there is at least one proxy, accessibility is enabled.
     */
     */
    public int getStateLocked(int deviceId, boolean automationRunning) {
    public int getStateLocked(int deviceId) {
        int clientState = 0;
        int clientState = 0;
        final boolean automationRunning = mUiAutomationManager.isUiAutomationRunningLocked();
        if (automationRunning) {
        if (automationRunning) {
            clientState |= AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED;
            clientState |= AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED;
        }
        }
@@ -387,7 +385,7 @@ public class ProxyManager {
    /**
    /**
     * If there is at least one proxy, accessibility is enabled.
     * If there is at least one proxy, accessibility is enabled.
     */
     */
    public int getStateForDisplayIdLocked(ProxyAccessibilityServiceConnection proxy) {
    private int getStateForDisplayIdLocked(ProxyAccessibilityServiceConnection proxy) {
        int clientState = 0;
        int clientState = 0;
        if (proxy != null) {
        if (proxy != null) {
            clientState |= AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED;
            clientState |= AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED;
@@ -409,14 +407,14 @@ public class ProxyManager {
    /**
    /**
     * Gets the last state for a device.
     * Gets the last state for a device.
     */
     */
    public int getLastSentStateLocked(int deviceId) {
    private int getLastSentStateLocked(int deviceId) {
        return mLastStates.get(deviceId, 0);
        return mLastStates.get(deviceId, 0);
    }
    }


    /**
    /**
     * Sets the last state for a device.
     * Sets the last state for a device.
     */
     */
    public void setLastStateLocked(int deviceId, int proxyState) {
    private void setLastStateLocked(int deviceId, int proxyState) {
        mLastStates.put(deviceId, proxyState);
        mLastStates.put(deviceId, proxyState);
    }
    }


@@ -429,7 +427,7 @@ public class ProxyManager {
     * Virtual Device, the app clients will get the aggregated event types for all proxy-ed displays
     * Virtual Device, the app clients will get the aggregated event types for all proxy-ed displays
     * belonging to a VirtualDevice.
     * belonging to a VirtualDevice.
     */
     */
    public void updateRelevantEventTypesLocked(int deviceId) {
    private void updateRelevantEventTypesLocked(int deviceId) {
        if (!isProxyedDeviceId(deviceId)) {
        if (!isProxyedDeviceId(deviceId)) {
            return;
            return;
        }
        }
@@ -452,7 +450,7 @@ public class ProxyManager {
    /**
    /**
     * Returns the relevant event types for a Client.
     * Returns the relevant event types for a Client.
     */
     */
    int computeRelevantEventTypesLocked(AccessibilityManagerService.Client client) {
    public int computeRelevantEventTypesLocked(AccessibilityManagerService.Client client) {
        int relevantEventTypes = 0;
        int relevantEventTypes = 0;
        for (int i = 0; i < mProxyA11yServiceConnections.size(); i++) {
        for (int i = 0; i < mProxyA11yServiceConnections.size(); i++) {
            final ProxyAccessibilityServiceConnection proxy =
            final ProxyAccessibilityServiceConnection proxy =
@@ -578,9 +576,8 @@ public class ProxyManager {
    /**
    /**
     * Updates the states of the app AccessibilityManagers.
     * Updates the states of the app AccessibilityManagers.
     */
     */
    public void scheduleUpdateProxyClientsIfNeededLocked(int deviceId) {
    private void scheduleUpdateProxyClientsIfNeededLocked(int deviceId) {
        final int proxyState = getStateLocked(deviceId,
        final int proxyState = getStateLocked(deviceId);
                mUiAutomationManager.isUiAutomationRunningLocked());
        if (DEBUG) {
        if (DEBUG) {
            Slog.v(LOG_TAG, "State for device id " + deviceId + " is " + proxyState);
            Slog.v(LOG_TAG, "State for device id " + deviceId + " is " + proxyState);
            Slog.v(LOG_TAG, "Last state for device id " + deviceId + " is "
            Slog.v(LOG_TAG, "Last state for device id " + deviceId + " is "
@@ -606,7 +603,7 @@ public class ProxyManager {
     *
     *
     * @see AccessibilityManager.AccessibilityServicesStateChangeListener
     * @see AccessibilityManager.AccessibilityServicesStateChangeListener
     */
     */
    public void scheduleNotifyProxyClientsOfServicesStateChangeLocked(int deviceId) {
    private void scheduleNotifyProxyClientsOfServicesStateChangeLocked(int deviceId) {
        if (DEBUG) {
        if (DEBUG) {
            Slog.v(LOG_TAG, "Notify services state change at device id " + deviceId);
            Slog.v(LOG_TAG, "Notify services state change at device id " + deviceId);
        }
        }
@@ -625,7 +622,7 @@ public class ProxyManager {
    /**
    /**
     * Updates the focus appearance of AccessibilityManagerClients.
     * Updates the focus appearance of AccessibilityManagerClients.
     */
     */
    public void updateFocusAppearanceLocked(int deviceId) {
    private void updateFocusAppearanceLocked(int deviceId) {
        if (DEBUG) {
        if (DEBUG) {
            Slog.v(LOG_TAG, "Update proxy focus appearance at device id " + deviceId);
            Slog.v(LOG_TAG, "Update proxy focus appearance at device id " + deviceId);
        }
        }
@@ -764,7 +761,7 @@ public class ProxyManager {
    /**
    /**
     * Sets a Client device id if the app uid belongs to the virtual device.
     * Sets a Client device id if the app uid belongs to the virtual device.
     */
     */
    public void updateDeviceIdsIfNeededLocked(int deviceId) {
    private void updateDeviceIdsIfNeededLocked(int deviceId) {
        final RemoteCallbackList<IAccessibilityManagerClient> userClients =
        final RemoteCallbackList<IAccessibilityManagerClient> userClients =
                mSystemSupport.getCurrentUserClientsLocked();
                mSystemSupport.getCurrentUserClientsLocked();
        final RemoteCallbackList<IAccessibilityManagerClient> globalClients =
        final RemoteCallbackList<IAccessibilityManagerClient> globalClients =
@@ -777,7 +774,7 @@ public class ProxyManager {
    /**
    /**
     * Updates the device ids of IAccessibilityManagerClients if needed.
     * Updates the device ids of IAccessibilityManagerClients if needed.
     */
     */
    public void updateDeviceIdsIfNeededLocked(int deviceId,
    private void updateDeviceIdsIfNeededLocked(int deviceId,
            @NonNull RemoteCallbackList<IAccessibilityManagerClient> clients) {
            @NonNull RemoteCallbackList<IAccessibilityManagerClient> clients) {
        final VirtualDeviceManagerInternal localVdm = getLocalVdm();
        final VirtualDeviceManagerInternal localVdm = getLocalVdm();
        if (localVdm == null) {
        if (localVdm == null) {
@@ -809,14 +806,17 @@ public class ProxyManager {
        }
        }
    }
    }


    void setAccessibilityInputFilter(AccessibilityInputFilter filter) {
    /**
     * Sets the input filter for enabling and disabling features for proxy displays.
     */
    public void setAccessibilityInputFilter(AccessibilityInputFilter filter) {
        if (DEBUG) {
        if (DEBUG) {
            Slog.v(LOG_TAG, "Set proxy input filter to " + filter);
            Slog.v(LOG_TAG, "Set proxy input filter to " + filter);
        }
        }
        mA11yInputFilter = filter;
        mA11yInputFilter = filter;
    }
    }


    VirtualDeviceManagerInternal getLocalVdm() {
    private VirtualDeviceManagerInternal getLocalVdm() {
        if (mLocalVdm == null) {
        if (mLocalVdm == null) {
            mLocalVdm =  LocalServices.getService(VirtualDeviceManagerInternal.class);
            mLocalVdm =  LocalServices.getService(VirtualDeviceManagerInternal.class);
        }
        }
+6 −6
Original line number Original line Diff line number Diff line
@@ -281,8 +281,8 @@ public class AccessibilityManagerServiceTest {
    @Test
    @Test
    public void testRegisterProxy() throws Exception {
    public void testRegisterProxy() throws Exception {
        mA11yms.registerProxyForDisplay(mMockServiceClient, TEST_DISPLAY);
        mA11yms.registerProxyForDisplay(mMockServiceClient, TEST_DISPLAY);
        verify(mProxyManager).registerProxy(eq(mMockServiceClient), eq(TEST_DISPLAY),
        verify(mProxyManager).registerProxy(eq(mMockServiceClient), eq(TEST_DISPLAY), anyInt(),
                eq(mTestableContext), anyInt(), any(), eq(mMockSecurityPolicy),
                eq(mMockSecurityPolicy),
                eq(mA11yms), eq(mA11yms.getTraceManager()),
                eq(mA11yms), eq(mA11yms.getTraceManager()),
                eq(mMockWindowManagerService));
                eq(mMockWindowManagerService));
    }
    }
@@ -295,7 +295,7 @@ public class AccessibilityManagerServiceTest {


        assertThrows(SecurityException.class,
        assertThrows(SecurityException.class,
                () -> mA11yms.registerProxyForDisplay(mMockServiceClient, TEST_DISPLAY));
                () -> mA11yms.registerProxyForDisplay(mMockServiceClient, TEST_DISPLAY));
        verify(mProxyManager, never()).registerProxy(any(), anyInt(), any(), anyInt(), any(), any(),
        verify(mProxyManager, never()).registerProxy(any(), anyInt(), anyInt(), any(),
                any(), any(), any());
                any(), any(), any());
    }
    }


@@ -307,7 +307,7 @@ public class AccessibilityManagerServiceTest {


        assertThrows(SecurityException.class,
        assertThrows(SecurityException.class,
                () -> mA11yms.registerProxyForDisplay(mMockServiceClient, TEST_DISPLAY));
                () -> mA11yms.registerProxyForDisplay(mMockServiceClient, TEST_DISPLAY));
        verify(mProxyManager, never()).registerProxy(any(), anyInt(), any(), anyInt(), any(), any(),
        verify(mProxyManager, never()).registerProxy(any(), anyInt(), anyInt(), any(),
                any(), any(), any());
                any(), any(), any());
    }
    }


@@ -316,7 +316,7 @@ public class AccessibilityManagerServiceTest {
    public void testRegisterProxyForDefaultDisplay() throws Exception {
    public void testRegisterProxyForDefaultDisplay() throws Exception {
        assertThrows(IllegalArgumentException.class,
        assertThrows(IllegalArgumentException.class,
                () -> mA11yms.registerProxyForDisplay(mMockServiceClient, Display.DEFAULT_DISPLAY));
                () -> mA11yms.registerProxyForDisplay(mMockServiceClient, Display.DEFAULT_DISPLAY));
        verify(mProxyManager, never()).registerProxy(any(), anyInt(), any(), anyInt(), any(), any(),
        verify(mProxyManager, never()).registerProxy(any(), anyInt(), anyInt(), any(),
                any(), any(), any());
                any(), any(), any());
    }
    }


@@ -325,7 +325,7 @@ public class AccessibilityManagerServiceTest {
    public void testRegisterProxyForInvalidDisplay() throws Exception {
    public void testRegisterProxyForInvalidDisplay() throws Exception {
        assertThrows(IllegalArgumentException.class,
        assertThrows(IllegalArgumentException.class,
                () -> mA11yms.registerProxyForDisplay(mMockServiceClient, Display.INVALID_DISPLAY));
                () -> mA11yms.registerProxyForDisplay(mMockServiceClient, Display.INVALID_DISPLAY));
        verify(mProxyManager, never()).registerProxy(any(), anyInt(), any(), anyInt(), any(), any(),
        verify(mProxyManager, never()).registerProxy(any(), anyInt(), anyInt(), any(),
                any(), any(), any());
                any(), any(), any());
    }
    }


+21 −2
Original line number Original line Diff line number Diff line
@@ -29,12 +29,14 @@ import android.accessibilityservice.AccessibilityTrace;
import android.content.ComponentName;
import android.content.ComponentName;
import android.content.Context;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.Resources;
import android.graphics.Color;
import android.os.Handler;
import android.os.Handler;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityEvent;


import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertThat;


import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.when;


@@ -79,12 +81,15 @@ public class ProxyAccessibilityServiceConnectionTest {
    WindowManagerInternal mMockWindowManagerInternal;
    WindowManagerInternal mMockWindowManagerInternal;
    ProxyAccessibilityServiceConnection mProxyConnection;
    ProxyAccessibilityServiceConnection mProxyConnection;
    AccessibilityServiceInfo mAccessibilityServiceInfo;
    AccessibilityServiceInfo mAccessibilityServiceInfo;
    private int mFocusStrokeWidthDefaultValue;
    private int mFocusColorDefaultValue;


    @Before
    @Before
    public void setup() {
    public void setup() {
        final Resources resources = getInstrumentation().getContext().getResources();
        final Resources resources = getInstrumentation().getContext().getResources();
        MockitoAnnotations.initMocks(this);
        MockitoAnnotations.initMocks(this);
        when(mMockContext.getResources()).thenReturn(resources);
        when(mMockContext.getResources()).thenReturn(resources);
        when(mMockSecurityPolicy.checkAccessibilityAccess(any())).thenReturn(true);


        mAccessibilityServiceInfo = new AccessibilityServiceInfo();
        mAccessibilityServiceInfo = new AccessibilityServiceInfo();
        mProxyConnection = new ProxyAccessibilityServiceConnection(mMockContext, COMPONENT_NAME,
        mProxyConnection = new ProxyAccessibilityServiceConnection(mMockContext, COMPONENT_NAME,
@@ -92,10 +97,13 @@ public class ProxyAccessibilityServiceConnectionTest {
                        getInstrumentation().getContext().getMainLooper()),
                        getInstrumentation().getContext().getMainLooper()),
                mMockLock, mMockSecurityPolicy, mMockSystemSupport, mMockA11yTrace,
                mMockLock, mMockSecurityPolicy, mMockSystemSupport, mMockA11yTrace,
                mMockWindowManagerInternal, mMockA11yWindowManager, DISPLAY_ID, DEVICE_ID);
                mMockWindowManagerInternal, mMockA11yWindowManager, DISPLAY_ID, DEVICE_ID);

        mFocusStrokeWidthDefaultValue = mProxyConnection.getFocusStrokeWidthLocked();
        mFocusColorDefaultValue = mProxyConnection.getFocusColorLocked();
    }
    }


    @Test
    @Test
    public void testSetInstalledAndEnabledServices_clientChanged() {
    public void testSetInstalledAndEnabledServices_updateInfos_notifiesSystemOfProxyChange() {
        final List<AccessibilityServiceInfo> infos = new ArrayList<>();
        final List<AccessibilityServiceInfo> infos = new ArrayList<>();
        final AccessibilityServiceInfo info1 = new AccessibilityServiceInfo();
        final AccessibilityServiceInfo info1 = new AccessibilityServiceInfo();
        infos.add(info1);
        infos.add(info1);
@@ -105,6 +113,17 @@ public class ProxyAccessibilityServiceConnectionTest {
        verify(mMockSystemSupport).onProxyChanged(DEVICE_ID);
        verify(mMockSystemSupport).onProxyChanged(DEVICE_ID);
    }
    }


    @Test
    public void testSetFocusAppearance_updateAppearance_notifiesSystemOfProxyChange() {
        final int updatedWidth = mFocusStrokeWidthDefaultValue + 10;
        final int updatedColor = mFocusColorDefaultValue
                == Color.BLUE ? Color.RED : Color.BLUE;

        mProxyConnection.setFocusAppearance(updatedWidth, updatedColor);

        verify(mMockSystemSupport).onProxyChanged(DEVICE_ID);
    }

    @Test
    @Test
    public void testSetInstalledAndEnabledServices_returnList() {
    public void testSetInstalledAndEnabledServices_returnList() {
        final List<AccessibilityServiceInfo> infos = new ArrayList<>();
        final List<AccessibilityServiceInfo> infos = new ArrayList<>();
@@ -196,7 +215,7 @@ public class ProxyAccessibilityServiceConnectionTest {
    }
    }


    @Test
    @Test
    public void testSetServiceInfo_setIllegalOperationExceptionThrown_() {
    public void testSetServiceInfo_setIllegalOperationExceptionThrown() {
        UnsupportedOperationException thrown =
        UnsupportedOperationException thrown =
                assertThrows(
                assertThrows(
                        UnsupportedOperationException.class,
                        UnsupportedOperationException.class,
+527 −0

File added.

Preview size limit exceeded, changes collapsed.