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

Commit 31743d8c authored by Svetoslav Ganov's avatar Svetoslav Ganov Committed by Android (Google) Code Review
Browse files

Merge "Accessibility test automation API not working."

parents 3b88d87e b6eca6e6
Loading
Loading
Loading
Loading
+77 −150
Original line number Diff line number Diff line
@@ -19,14 +19,10 @@ import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLEAR_SELE
import static android.view.accessibility.AccessibilityNodeInfo.ACTION_FOCUS;
import static android.view.accessibility.AccessibilityNodeInfo.ACTION_SELECT;

import com.android.frameworks.coretests.R;

import android.content.Context;
import android.graphics.Rect;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.provider.Settings;
import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.LargeTest;
import android.util.Log;
@@ -36,8 +32,8 @@ import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.IAccessibilityManager;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import com.android.frameworks.coretests.R;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
@@ -58,11 +54,6 @@ public class InterrogationActivityTest
    // Timeout before give up wait for the system to process an accessibility setting change.       
    private static final int TIMEOUT_PROPAGATE_ACCESSIBLITY_SETTING = 2000;

    // Helpers to figure out the first and last test methods
    // This is a workaround for the lack of such support in JUnit3
    private static int sTestMethodCount;
    private static int sExecutedTestMethodCount;

    // Handle to a connection to the AccessibilityManagerService
    private static IAccessibilityServiceConnection sConnection;

@@ -71,19 +62,20 @@ public class InterrogationActivityTest

    public InterrogationActivityTest() {
        super(InterrogationActivity.class);
        sTestMethodCount = getTestMethodCount();
    }

    @LargeTest
    public void testFindAccessibilityNodeInfoByViewId() throws Exception {
        beforeClassIfNeeded();
        final long startTimeMillis = SystemClock.uptimeMillis();
        try {
            // hook into the system first
            IAccessibilityServiceConnection connection = getConnection();

            // bring up the activity
            getActivity();

            AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance()
                .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5);
                .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5);
            assertNotNull(button);
            assertEquals(0, button.getChildCount());

@@ -116,7 +108,6 @@ public class InterrogationActivityTest
            assertEquals(ACTION_FOCUS | ACTION_SELECT | ACTION_CLEAR_SELECTION,
                button.getActions());
        } finally {
            afterClassIfNeeded();
            if (DEBUG) {
                final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
                Log.i(LOG_TAG, "testFindAccessibilityNodeInfoByViewId: "
@@ -127,18 +118,19 @@ public class InterrogationActivityTest

    @LargeTest
    public void testFindAccessibilityNodeInfoByViewText() throws Exception {
        beforeClassIfNeeded();
        final long startTimeMillis = SystemClock.uptimeMillis();
        try {
            // hook into the system first
            IAccessibilityServiceConnection connection = getConnection();

            // bring up the activity
            getActivity();

            // find a view by text
            List<AccessibilityNodeInfo> buttons =  AccessibilityInteractionClient.getInstance()
                .findAccessibilityNodeInfosByViewTextInActiveWindow(getConnection(), "butto");
                .findAccessibilityNodeInfosByViewTextInActiveWindow(connection, "butto");
            assertEquals(9, buttons.size());
        } finally {
            afterClassIfNeeded();
            if (DEBUG) {
                final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
                Log.i(LOG_TAG, "testFindAccessibilityNodeInfoByViewText: "
@@ -149,19 +141,20 @@ public class InterrogationActivityTest

    @LargeTest
    public void testFindAccessibilityNodeInfoByViewTextContentDescription() throws Exception {
        beforeClassIfNeeded();
        final long startTimeMillis = SystemClock.uptimeMillis();
        try {
            // hook into the system first
            IAccessibilityServiceConnection connection = getConnection();

            // bring up the activity
            getActivity();

            // find a view by text
            List<AccessibilityNodeInfo> buttons =  AccessibilityInteractionClient.getInstance()
                .findAccessibilityNodeInfosByViewTextInActiveWindow(getConnection(),
                .findAccessibilityNodeInfosByViewTextInActiveWindow(connection,
                        "contentDescription");
            assertEquals(1, buttons.size());
        } finally {
            afterClassIfNeeded();
            if (DEBUG) {
                final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
                Log.i(LOG_TAG, "testFindAccessibilityNodeInfoByViewTextContentDescription: "
@@ -172,9 +165,11 @@ public class InterrogationActivityTest

    @LargeTest
    public void testTraverseAllViews() throws Exception {
        beforeClassIfNeeded();
        final long startTimeMillis = SystemClock.uptimeMillis();
        try {
            // hook into the system first
            IAccessibilityServiceConnection connection = getConnection();

            // bring up the activity
            getActivity();

@@ -195,7 +190,7 @@ public class InterrogationActivityTest
            classNameAndTextList.add("android.widget.ButtonButton9");

            AccessibilityNodeInfo root = AccessibilityInteractionClient.getInstance()
                .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.root);
                .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.root);
            assertNotNull("We must find the existing root.", root);

            Queue<AccessibilityNodeInfo> fringe = new LinkedList<AccessibilityNodeInfo>();
@@ -221,7 +216,6 @@ public class InterrogationActivityTest
                }
            }
        } finally {
            afterClassIfNeeded();
            if (DEBUG) {
                final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
                Log.i(LOG_TAG, "testTraverseAllViews: " + elapsedTimeMillis + "ms");
@@ -231,15 +225,17 @@ public class InterrogationActivityTest

    @LargeTest
    public void testPerformAccessibilityActionFocus() throws Exception {
        beforeClassIfNeeded();
        final long startTimeMillis = SystemClock.uptimeMillis();
        try {
            // hook into the system first
            IAccessibilityServiceConnection connection = getConnection();

            // bring up the activity
            getActivity();

            // find a view and make sure it is not focused
            AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance()
                .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5);
                .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5);
            assertFalse(button.isFocused());

            // focus the view
@@ -247,10 +243,9 @@ public class InterrogationActivityTest

            // find the view again and make sure it is focused
            button =  AccessibilityInteractionClient.getInstance()
                .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5);
                .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5);
            assertTrue(button.isFocused());
        } finally {
            afterClassIfNeeded();
            if (DEBUG) {
                final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
                Log.i(LOG_TAG, "testPerformAccessibilityActionFocus: " + elapsedTimeMillis + "ms");
@@ -260,15 +255,17 @@ public class InterrogationActivityTest

    @LargeTest
    public void testPerformAccessibilityActionClearFocus() throws Exception {
        beforeClassIfNeeded();
        final long startTimeMillis = SystemClock.uptimeMillis();
        try {
            // hook into the system first
            IAccessibilityServiceConnection connection = getConnection();

            // bring up the activity
            getActivity();

            // find a view and make sure it is not focused
            AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance()
                .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5);
                .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5);
            assertFalse(button.isFocused());

            // focus the view
@@ -276,7 +273,7 @@ public class InterrogationActivityTest

            // find the view again and make sure it is focused
            button = AccessibilityInteractionClient.getInstance()
                .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5);
                .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5);
            assertTrue(button.isFocused());

            // unfocus the view
@@ -284,10 +281,9 @@ public class InterrogationActivityTest

            // find the view again and make sure it is not focused
            button = AccessibilityInteractionClient.getInstance()
                .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5);
                .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5);
            assertFalse(button.isFocused());
        } finally {
            afterClassIfNeeded();
            if (DEBUG) {
                final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
                Log.i(LOG_TAG, "testPerformAccessibilityActionClearFocus: "
@@ -298,15 +294,17 @@ public class InterrogationActivityTest

    @LargeTest
    public void testPerformAccessibilityActionSelect() throws Exception {
        beforeClassIfNeeded();
        final long startTimeMillis = SystemClock.uptimeMillis();
        try {
            // hook into the system first
            IAccessibilityServiceConnection connection = getConnection();

            // bring up the activity
            getActivity();

            // find a view and make sure it is not selected
            AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance()
                .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5);
                .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5);
            assertFalse(button.isSelected());

            // select the view
@@ -314,10 +312,9 @@ public class InterrogationActivityTest

            // find the view again and make sure it is selected
            button = AccessibilityInteractionClient.getInstance()
                .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5);
                .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5);
            assertTrue(button.isSelected());
        } finally {
            afterClassIfNeeded();
            if (DEBUG) {
                final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
                Log.i(LOG_TAG, "testPerformAccessibilityActionSelect: " + elapsedTimeMillis + "ms");
@@ -327,15 +324,17 @@ public class InterrogationActivityTest

    @LargeTest
    public void testPerformAccessibilityActionClearSelection() throws Exception {
        beforeClassIfNeeded();
        final long startTimeMillis = SystemClock.uptimeMillis();
        try {
            // hook into the system first
            IAccessibilityServiceConnection connection = getConnection();

            // bring up the activity
            getActivity();

            // find a view and make sure it is not selected
            AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance()
                .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5);
                .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5);
            assertFalse(button.isSelected());

            // select the view
@@ -343,7 +342,7 @@ public class InterrogationActivityTest

            // find the view again and make sure it is selected
            button = AccessibilityInteractionClient.getInstance()
                .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5);
                .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5);
            assertTrue(button.isSelected());

            // unselect the view
@@ -351,10 +350,9 @@ public class InterrogationActivityTest

            // find the view again and make sure it is not selected
            button =  AccessibilityInteractionClient.getInstance()
                .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5);
                .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5);
            assertFalse(button.isSelected());
        } finally {
            afterClassIfNeeded();
            if (DEBUG) {
                final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
                Log.i(LOG_TAG, "testPerformAccessibilityActionClearSelection: "
@@ -365,15 +363,17 @@ public class InterrogationActivityTest

    @LargeTest
    public void testAccessibilityEventGetSource() throws Exception {
        beforeClassIfNeeded();
        final long startTimeMillis = SystemClock.uptimeMillis();
        try {
            // hook into the system first
            IAccessibilityServiceConnection connection = getConnection();

            // bring up the activity
            getActivity();  

            // find a view and make sure it is not focused
            AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance()
                .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5);
                .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5);
            assertFalse(button.isSelected());

            // focus the view
@@ -419,7 +419,6 @@ public class InterrogationActivityTest
            assertSame(button.isCheckable(), source.isCheckable());
            assertSame(button.isChecked(), source.isChecked());
        } finally {
            afterClassIfNeeded();
            if (DEBUG) {
                final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
                Log.i(LOG_TAG, "testAccessibilityEventGetSource: " + elapsedTimeMillis + "ms");
@@ -429,15 +428,17 @@ public class InterrogationActivityTest

    @LargeTest
    public void testObjectContract() throws Exception {
        beforeClassIfNeeded();
        final long startTimeMillis = SystemClock.uptimeMillis();
        try {
            // hook into the system first
            IAccessibilityServiceConnection connection = getConnection();

            // bring up the activity
            getActivity();

            // find a view and make sure it is not focused
            AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance()
                .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5);
                .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5);
            AccessibilityNodeInfo parent = button.getParent();
            final int childCount = parent.getChildCount();
            for (int i = 0; i < childCount; i++) {
@@ -451,7 +452,6 @@ public class InterrogationActivityTest
            }
            fail("Parent's children do not have the info whose parent is the parent.");
        } finally {
            afterClassIfNeeded();
            if (DEBUG) {
                final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
                Log.i(LOG_TAG, "testObjectContract: " + elapsedTimeMillis + "ms");
@@ -464,90 +464,10 @@ public class InterrogationActivityTest
        /* intentionally do not scrub */
    }

    /**
     * Sets accessibility in a given state by writing the state to the
     * settings and waiting until the accessibility manager service picks
     * it up for max {@link #TIMEOUT_PROPAGATE_ACCESSIBLITY_SETTING}.
     *
     * @param state The accessibility state.
     * @throws Exception If any error occurs.
     */
    private void ensureAccessibilityState(boolean state) throws Exception {
        Context context = getInstrumentation().getContext();
        // If the local manager ready => nothing to do.
        AccessibilityManager accessibilityManager = AccessibilityManager.getInstance(context);
        if (accessibilityManager.isEnabled() == state) {
            return;
        }
        synchronized (this) {
            // Check if the system already knows about the desired state. 
            final boolean currentState = Settings.Secure.getInt(context.getContentResolver(),
                    Settings.Secure.ACCESSIBILITY_ENABLED) == 1;
            if (currentState != state) {
                // Make sure we wake ourselves as the desired state is propagated.
                accessibilityManager.addAccessibilityStateChangeListener(
                        new AccessibilityManager.AccessibilityStateChangeListener() {
                            public void onAccessibilityStateChanged(boolean enabled) {
                                synchronized (this) {
                                    notifyAll();
                                }
                            }
                        });
                Settings.Secure.putInt(context.getContentResolver(),
                        Settings.Secure.ACCESSIBILITY_ENABLED, state ? 1 : 0);
            }
            // No while one attempt and that is it.
            try {
                wait(TIMEOUT_PROPAGATE_ACCESSIBLITY_SETTING);
            } catch (InterruptedException ie) {
                /* ignore */
            }
        }
        if (accessibilityManager.isEnabled() != state) {
            throw new IllegalStateException("Could not set accessibility state to: " + state);
        }
    }

    /**
     * Execute some set up code before any test method.
     *
     * NOTE: I miss Junit4's @BeforeClass
     *
     * @throws Exception If an error occurs.
     */
    private void beforeClassIfNeeded() throws Exception {
        sExecutedTestMethodCount++;
        if (sExecutedTestMethodCount == 1) {
            ensureAccessibilityState(true);
        }
    }

    /**
     * Execute some clean up code after all test methods.
     *
     * NOTE: I miss Junit4's @AfterClass
     *
     * @throws Exception If an error occurs.
     */
    public void afterClassIfNeeded() throws Exception {
        if (sExecutedTestMethodCount == sTestMethodCount) {
            sExecutedTestMethodCount = 0;
            ensureAccessibilityState(false);
        }
    }

    private static IAccessibilityServiceConnection getConnection() throws Exception {
    private IAccessibilityServiceConnection getConnection() throws Exception {
        if (sConnection == null) {
            IEventListener listener = new IEventListener.Stub() {
                public void setConnection(IAccessibilityServiceConnection connection)
                        throws RemoteException {
                    AccessibilityServiceInfo info = new AccessibilityServiceInfo();
                    info.eventTypes = AccessibilityEvent.TYPES_ALL_MASK;
                    info.feedbackType = AccessibilityServiceInfo.FEEDBACK_SPOKEN;
                    info.notificationTimeout = 0;
                    info.flags = AccessibilityServiceInfo.DEFAULT;
                    connection.setServiceInfo(info);
                }
                public void setConnection(IAccessibilityServiceConnection connection) {}

                public void onInterrupt() {}

@@ -560,26 +480,33 @@ public class InterrogationActivityTest
                    }
                }
            };

            AccessibilityManager accessibilityManager =
                AccessibilityManager.getInstance(getInstrumentation().getContext());

            synchronized (this) {
                if (!accessibilityManager.isEnabled()) {
                    // Make sure we wake ourselves as the desired state is propagated.
                    accessibilityManager.addAccessibilityStateChangeListener(
                            new AccessibilityManager.AccessibilityStateChangeListener() {
                                public void onAccessibilityStateChanged(boolean enabled) {
                                    synchronized (this) {
                                        notifyAll();
                                    }
                                }
                            });
                    IAccessibilityManager manager = IAccessibilityManager.Stub.asInterface(
                        ServiceManager.getService(Context.ACCESSIBILITY_SERVICE));
                    sConnection = manager.registerEventListener(listener);
        }
        return sConnection;
    }

    /**
     * @return The number of test methods.
     */
    private int getTestMethodCount() {
        int testMethodCount = 0;
        for (Method method : getClass().getMethods()) {
            final int modifiers = method.getModifiers();
            if (method.getName().startsWith("test")
                    && (modifiers & Modifier.PUBLIC) != 0
                    && (modifiers & Modifier.STATIC) == 0) {
                testMethodCount++;
                    wait(TIMEOUT_PROPAGATE_ACCESSIBLITY_SETTING);
                } else {
                    IAccessibilityManager manager = IAccessibilityManager.Stub.asInterface(
                          ServiceManager.getService(Context.ACCESSIBILITY_SERVICE));
                    sConnection = manager.registerEventListener(listener);
                }
            }
        return testMethodCount;
        }
        return sConnection;
    }
}
+59 −25

File changed.

Preview size limit exceeded, changes collapsed.