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

Commit a7fa814e authored by Dieter Hsu's avatar Dieter Hsu
Browse files

Fix accessibility services tests to work with atest

- Remove @BeforeClass `Looper.prepare()` that do not work with atest
- Fix TouchExplorerTest: mock AccessibilityGestureDetector to not create
  internal handler.
- Fix broken tests in MagnificationControllerTest
- Remove @FlakyTest annotation from MagnificationControllerTest &
  FingerprintGestureControllerTest

When using atest, timeout is applied to command `am instrument`. Then
@BeforeClass & @Before are both running on instrument thread, but test
cases are running on a seperate thread. It dispatch messages immediately
if the looper is associated to the same thread. When runniung tests with
atest, dispatching the message is not always done in the same thread. So
verifying the expectation on test thread would be flaky.

The solution to use a looper associated with test thread would be ugly.
Because the looper related stuff should set up without @Before or
@BeforeClass including preparing a looper on demand in a utility
function for every test case needed.

Here changing the handler behavior to enqueue but to dispatch messages
explictly from test could serialize the execution. This would use main
looper (no need to prepare) to create handler, but dispatch and clear
messages ourself. Not good enough but less ugly to run `am instrument`
with or without timeout.

Bug: 74748946
Test: atest -d FrameworksServicesTests:com.android.server.accessibility
Test: adb shell am instrument -w -e package com.android.server.accessibility \
      com.android.frameworks.servicestests/androidx.test.runner.AndroidJUnitRunner

Change-Id: Ib67d8b7305511d218b23f4b5ab0b0a12bea9ae10
parent 7b39606e
Loading
Loading
Loading
Loading
+19 −1
Original line number Diff line number Diff line
@@ -170,6 +170,20 @@ class TouchExplorer extends BaseEventStreamTransformation
     *                action.
     */
    public TouchExplorer(Context context, AccessibilityManagerService service) {
        this(context, service, null);
    }

    /**
     * Creates a new instance.
     *
     * @param context A context handle for accessing resources.
     * @param service The service to notify touch interaction and gesture completed and to perform
     *                action.
     * @param detector The gesture detector to handle accessibility touch event. If null the default
     *                one created in place, or for testing purpose.
     */
    public TouchExplorer(Context context, AccessibilityManagerService service,
            AccessibilityGestureDetector detector) {
        mContext = context;
        mAms = service;
        mReceivedPointerTracker = new ReceivedPointerTracker();
@@ -186,7 +200,11 @@ class TouchExplorer extends BaseEventStreamTransformation
        mSendTouchInteractionEndDelayed = new SendAccessibilityEventDelayed(
                AccessibilityEvent.TYPE_TOUCH_INTERACTION_END,
                mDetermineUserIntentTimeout);
        if (detector == null) {
            mGestureDetector = new AccessibilityGestureDetector(context, this);
        } else {
            mGestureDetector = detector;
        }
        final float density = context.getResources().getDisplayMetrics().density;
        mScaledMinPointerDistanceToUseMiddleLocation =
            (int) (MIN_POINTER_DISTANCE_TO_USE_MIDDLE_LOCATION_DIP * density);
+3 −13
Original line number Diff line number Diff line
@@ -18,23 +18,22 @@ package com.android.server.accessibility;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.accessibilityservice.AccessibilityService;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Point;
import android.graphics.PointF;
import android.os.Looper;
import android.util.DisplayMetrics;
import android.view.GestureDetector;
import android.view.MotionEvent;
import java.util.ArrayList;

import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

import java.util.ArrayList;

/**
 * Tests for AccessibilityGestureDetector
@@ -50,14 +49,6 @@ public class AccessibilityGestureDetectorTest {
    private AccessibilityGestureDetector mDetector;
    private AccessibilityGestureDetector.Listener mResultListener;


    @BeforeClass
    public static void oneTimeInitialization() {
        if (Looper.myLooper() == null) {
            Looper.prepare();
        }
    }

    @Before
    public void setUp() {
        // Construct a mock Context.
@@ -67,7 +58,6 @@ public class AccessibilityGestureDetectorTest {
        Resources mockResources = mock(Resources.class);
        when(mockResources.getDisplayMetrics()).thenReturn(displayMetricsMock);
        Context contextMock = mock(Context.class);
        when(contextMock.getMainLooper()).thenReturn(Looper.myLooper());
        when(contextMock.getResources()).thenReturn(mockResources);

        // Construct a testable AccessibilityGestureDetector.
+7 −9
Original line number Diff line number Diff line
@@ -29,7 +29,6 @@ import static org.mockito.Mockito.when;

import android.accessibilityservice.AccessibilityServiceInfo;
import android.app.Instrumentation;
import android.os.Looper;
import android.os.UserHandle;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
@@ -41,8 +40,8 @@ import androidx.test.runner.AndroidJUnit4;

import com.android.internal.util.IntPair;

import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -63,13 +62,6 @@ public class AccessibilityManagerTest {
    private MessageCapturingHandler mHandler;
    private Instrumentation mInstrumentation;

    @BeforeClass
    public static void oneTimeInitialization() {
        if (Looper.myLooper() == null) {
            Looper.prepare();
        }
    }

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
@@ -77,6 +69,12 @@ public class AccessibilityManagerTest {
        mInstrumentation = InstrumentationRegistry.getInstrumentation();
    }

    @After
    public void tearDown() {
        mHandler.removeAllMessages();
    }


    private AccessibilityManager createManager(boolean enabled) throws Exception {
        long serviceReturnValue = IntPair.of(
                (enabled) ? AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED : 0,
+7 −10
Original line number Diff line number Diff line
@@ -33,16 +33,14 @@ import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;
import android.os.UserHandle;

import com.android.server.wm.WindowManagerInternal;

import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -74,13 +72,6 @@ public class AccessibilityServiceConnectionTest {

    MessageCapturingHandler mHandler = new MessageCapturingHandler(null);

    @BeforeClass
    public static void oneTimeInitialization() {
        if (Looper.myLooper() == null) {
            Looper.prepare();
        }
    }

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
@@ -98,6 +89,12 @@ public class AccessibilityServiceConnectionTest {
                mMockGlobalActionPerformer);
    }

    @After
    public void tearDown() {
        mHandler.removeAllMessages();
    }


    @Test
    public void bind_requestsContextToBindService() {
        mConnection.bindLocked();
+15 −22
Original line number Diff line number Diff line
@@ -16,19 +16,8 @@

package com.android.server.accessibility;

import android.accessibilityservice.FingerprintGestureController;
import android.accessibilityservice.FingerprintGestureController.FingerprintGestureCallback;
import android.accessibilityservice.IAccessibilityServiceConnection;
import android.os.Looper;
import android.support.test.filters.FlakyTest;

import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import static android.accessibilityservice.FingerprintGestureController.FINGERPRINT_GESTURE_SWIPE_DOWN;
import static android.accessibilityservice.FingerprintGestureController
        .FINGERPRINT_GESTURE_SWIPE_DOWN;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -38,6 +27,15 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;

import android.accessibilityservice.FingerprintGestureController;
import android.accessibilityservice.FingerprintGestureController.FingerprintGestureCallback;
import android.accessibilityservice.IAccessibilityServiceConnection;

import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

/**
 * Tests for FingerprintGestureController.
 * TODO: These tests aren't really for server code, so this isn't their ideal home.
@@ -47,13 +45,6 @@ public class FingerprintGestureControllerTest {
    @Mock FingerprintGestureCallback mMockFingerprintGestureCallback;
    FingerprintGestureController mFingerprintGestureController;

    @BeforeClass
    public static void oneTimeInitialization() {
        if (Looper.myLooper() == null) {
            Looper.prepare();
        }
    }

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
@@ -97,7 +88,6 @@ public class FingerprintGestureControllerTest {
    }

    @Test
    @FlakyTest
    public void testDetectionActiveCallback_withHandler_shouldPostRunnableToHandler() {
        MessageCapturingHandler messageCapturingHandler = new MessageCapturingHandler((message) -> {
            message.getCallback().run();
@@ -127,6 +117,8 @@ public class FingerprintGestureControllerTest {
        mFingerprintGestureController.onGestureDetectionActiveChanged(false);
        assertFalse(messageCapturingHandler.hasMessages());
        verifyZeroInteractions(mMockFingerprintGestureCallback);

        messageCapturingHandler.removeAllMessages();
    }

    @Test
@@ -145,7 +137,6 @@ public class FingerprintGestureControllerTest {
    }

    @Test
    @FlakyTest
    public void testGestureCallback_withHandler_shouldPostRunnableToHandler() {
        MessageCapturingHandler messageCapturingHandler = new MessageCapturingHandler((message) -> {
            message.getCallback().run();
@@ -167,5 +158,7 @@ public class FingerprintGestureControllerTest {
        mFingerprintGestureController.onGesture(FINGERPRINT_GESTURE_SWIPE_DOWN);
        assertFalse(messageCapturingHandler.hasMessages());
        verifyZeroInteractions(mMockFingerprintGestureCallback);

        messageCapturingHandler.removeAllMessages();
    }
}
Loading