10b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov/*
20b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov * Copyright (C) 2010 The Android Open Source Project
30b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov *
40b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov * Licensed under the Apache License, Version 2.0 (the "License");
50b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov * you may not use this file except in compliance with the License.
60b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov * You may obtain a copy of the License at
70b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov *
80b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov *      http://www.apache.org/licenses/LICENSE-2.0
90b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov *
100b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov * Unless required by applicable law or agreed to in writing, software
110b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov * distributed under the License is distributed on an "AS IS" BASIS,
120b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov * See the License for the specific language governing permissions and
140b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov * limitations under the License.
150b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov */
160b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
170b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganovpackage com.android.server;
180b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
190b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganovimport android.accessibilityservice.AccessibilityService;
200b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganovimport android.accessibilityservice.AccessibilityServiceInfo;
215637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganovimport android.content.Intent;
220b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganovimport android.os.Message;
230b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganovimport android.view.accessibility.AccessibilityEvent;
240b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
250b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganovimport java.util.Iterator;
260b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganovimport java.util.LinkedList;
270b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganovimport java.util.List;
280b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganovimport java.util.Queue;
290b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
300b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganovimport junit.framework.TestCase;
310b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
320b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov/**
330b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov * This is the base class for mock {@link AccessibilityService}s.
340b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov */
350b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganovpublic abstract class MockAccessibilityService extends AccessibilityService {
360b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
370b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    /**
380b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * The event this service expects to receive.
390b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     */
400b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    private final Queue<AccessibilityEvent> mExpectedEvents = new LinkedList<AccessibilityEvent>();
410b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
420b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    /**
430b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * Interruption call this service expects to receive.
440b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     */
450b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    private boolean mExpectedInterrupt;
460b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
470b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    /**
480b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * Flag if the mock is currently replaying.
490b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     */
500b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    private boolean mReplaying;
510b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
520b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    /**
535637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov     * Flag if the system is bound as a client to this service.
545637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov     */
555637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov    private boolean mIsSystemBoundAsClient;
565637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov
575637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov    /**
580b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * Creates an {@link AccessibilityServiceInfo} populated with default
590b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * values.
600b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     *
610b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * @return The default info.
620b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     */
630b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    public static AccessibilityServiceInfo createDefaultInfo() {
640b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        AccessibilityServiceInfo defaultInfo = new AccessibilityServiceInfo();
650b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        defaultInfo.eventTypes = AccessibilityEvent.TYPE_VIEW_CLICKED;
660b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        defaultInfo.feedbackType = AccessibilityServiceInfo.FEEDBACK_AUDIBLE;
670b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        defaultInfo.flags = 0;
680b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        defaultInfo.notificationTimeout = 0;
690b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        defaultInfo.packageNames = new String[] {
700b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov            "foo.bar.baz"
710b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        };
720b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
730b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        return defaultInfo;
740b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    }
750b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
760b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    /**
770b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * Starts replaying the mock.
780b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     */
790b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    public void replay() {
800b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        mReplaying = true;
810b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    }
820b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
830b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    /**
840b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * Verifies if all expected service methods have been called.
850b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     */
860b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    public void verify() {
870b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        if (!mReplaying) {
880b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov            throw new IllegalStateException("Did you forget to call replay()");
890b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        }
900b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
910b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        if (mExpectedInterrupt) {
920b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov            throw new IllegalStateException("Expected call to #interrupt() not received");
930b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        }
940b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        if (!mExpectedEvents.isEmpty()) {
950b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov            throw new IllegalStateException("Expected a call to onAccessibilityEvent() for "
960b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov                    + "events \"" + mExpectedEvents + "\" not received");
970b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        }
980b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    }
990b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
1000b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    /**
1010b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * Resets this instance so it can be reused.
1020b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     */
1030b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    public void reset() {
1040b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        mExpectedEvents.clear();
1050b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        mExpectedInterrupt = false;
1060b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        mReplaying = false;
1070b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    }
1080b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
1090b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    /**
1100b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * Sets an expected call to
1110b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * {@link #onAccessibilityEvent(AccessibilityEvent)} with given event as
1120b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * argument.
1130b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     *
1140b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * @param expectedEvent The expected event argument.
1150b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     */
1160b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    public void expectEvent(AccessibilityEvent expectedEvent) {
1170b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        mExpectedEvents.add(expectedEvent);
1180b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    }
1190b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
1200b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    /**
1210b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * Sets an expected call of {@link #onInterrupt()}.
1220b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     */
1230b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    public void expectInterrupt() {
1240b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        mExpectedInterrupt = true;
1250b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    }
1260b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
1270b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    @Override
1280b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    public void onAccessibilityEvent(AccessibilityEvent receivedEvent) {
1290b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        if (!mReplaying) {
1300b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov            return;
1310b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        }
1320b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
1330b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        if (mExpectedEvents.isEmpty()) {
1340b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov            throw new IllegalStateException("Unexpected event: " + receivedEvent);
1350b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        }
1360b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
1370b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        AccessibilityEvent expectedEvent = mExpectedEvents.poll();
1380b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        assertEqualsAccessiblityEvent(expectedEvent, receivedEvent);
1390b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    }
1400b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
1410b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    @Override
1420b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    public void onInterrupt() {
1430b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        if (!mReplaying) {
1440b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov            return;
1450b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        }
1460b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
1470b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        if (!mExpectedInterrupt) {
1480b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov            throw new IllegalStateException("Unexpected call to onInterrupt()");
1490b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        }
1500b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
1510b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        mExpectedInterrupt = false;
1520b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    }
1530b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
1545637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov    @Override
1555637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov    protected void onServiceConnected() {
1565637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov        mIsSystemBoundAsClient = true;
1575637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov    }
1585637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov
1595637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov    @Override
1605637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov    public boolean onUnbind(Intent intent) {
1615637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov        mIsSystemBoundAsClient = false;
1625637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov        return false;
1635637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov    }
1645637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov
1655637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov    /**
1665637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov     * Returns if the system is bound as client to this service.
1675637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov     *
1685637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov     * @return True if the system is bound, false otherwise.
1695637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov     */
1705637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov    public boolean isSystemBoundAsClient() {
1715637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov        return mIsSystemBoundAsClient;
1725637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov    }
1735637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov
1740b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    /**
1750b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * Compares all properties of the <code>expectedEvent</code> and the
1760b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * <code>receviedEvent</code> to verify that the received event is the one
1770b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * that is expected.
1780b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     */
1790b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    private void assertEqualsAccessiblityEvent(AccessibilityEvent expectedEvent,
1800b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov            AccessibilityEvent receivedEvent) {
1810b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        TestCase.assertEquals("addedCount has incorrect value", expectedEvent.getAddedCount(),
1820b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov                receivedEvent.getAddedCount());
1830b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        TestCase.assertEquals("beforeText has incorrect value", expectedEvent.getBeforeText(),
1840b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov                receivedEvent.getBeforeText());
1850b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        TestCase.assertEquals("checked has incorrect value", expectedEvent.isChecked(),
1860b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov                receivedEvent.isChecked());
1870b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        TestCase.assertEquals("className has incorrect value", expectedEvent.getClassName(),
1880b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov                receivedEvent.getClassName());
1890b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        TestCase.assertEquals("contentDescription has incorrect value", expectedEvent
1900b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov                .getContentDescription(), receivedEvent.getContentDescription());
1910b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        TestCase.assertEquals("currentItemIndex has incorrect value", expectedEvent
1920b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov                .getCurrentItemIndex(), receivedEvent.getCurrentItemIndex());
1930b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        TestCase.assertEquals("enabled has incorrect value", expectedEvent.isEnabled(),
1940b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov                receivedEvent.isEnabled());
1950b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        TestCase.assertEquals("eventType has incorrect value", expectedEvent.getEventType(),
1960b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov                receivedEvent.getEventType());
1970b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        TestCase.assertEquals("fromIndex has incorrect value", expectedEvent.getFromIndex(),
1980b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov                receivedEvent.getFromIndex());
1990b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        TestCase.assertEquals("fullScreen has incorrect value", expectedEvent.isFullScreen(),
2000b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov                receivedEvent.isFullScreen());
2010b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        TestCase.assertEquals("itemCount has incorrect value", expectedEvent.getItemCount(),
2020b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov                receivedEvent.getItemCount());
2030b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        assertEqualsNotificationAsParcelableData(expectedEvent, receivedEvent);
2040b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        TestCase.assertEquals("password has incorrect value", expectedEvent.isPassword(),
2050b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov                receivedEvent.isPassword());
2060b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        TestCase.assertEquals("removedCount has incorrect value", expectedEvent.getRemovedCount(),
2070b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov                receivedEvent.getRemovedCount());
2080b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        assertEqualsText(expectedEvent, receivedEvent);
2090b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    }
2100b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
2110b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    /**
2120b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * Compares the {@link android.os.Parcelable} data of the
2130b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * <code>expectedEvent</code> and <code>receivedEvent</code> to verify that
2140b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * the received event is the one that is expected.
2150b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     */
2160b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    private void assertEqualsNotificationAsParcelableData(AccessibilityEvent expectedEvent,
2170b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov            AccessibilityEvent receivedEvent) {
2180b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        String message = "parcelableData has incorrect value";
2190b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        Message expectedMessage = (Message) expectedEvent.getParcelableData();
2200b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        Message receivedMessage = (Message) receivedEvent.getParcelableData();
2210b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
2220b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        if (expectedMessage == null) {
2230b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov            if (receivedMessage == null) {
2240b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov                return;
2250b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov            }
2260b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        }
2270b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
2280b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        TestCase.assertNotNull(message, receivedMessage);
2290b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
2300b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // we do a very simple sanity check since we do not test Message
2310b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        TestCase.assertEquals(message, expectedMessage.what, receivedMessage.what);
2320b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    }
2330b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
2340b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    /**
2350b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * Compares the text of the <code>expectedEvent</code> and
2360b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * <code>receivedEvent</code> by comparing the string representation of the
2370b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * corresponding {@link CharSequence}s.
2380b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     */
2390b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    private void assertEqualsText(AccessibilityEvent expectedEvent,
2400b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov            AccessibilityEvent receivedEvent) {
2410b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        String message = "text has incorrect value";
2420b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        List<CharSequence> expectedText = expectedEvent.getText();
2430b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        List<CharSequence> receivedText = receivedEvent.getText();
2440b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
2450b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        TestCase.assertEquals(message, expectedText.size(), receivedText.size());
2460b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
2470b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        Iterator<CharSequence> expectedTextIterator = expectedText.iterator();
2480b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        Iterator<CharSequence> receivedTextIterator = receivedText.iterator();
2490b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
2500b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        for (int i = 0; i < expectedText.size(); i++) {
2510b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov            // compare the string representation
2520b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov            TestCase.assertEquals(message, expectedTextIterator.next().toString(),
2530b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov                    receivedTextIterator.next().toString());
2540b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        }
2550b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    }
2560b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov}
257