AccessibilityManagerServiceTest.java revision 00aabf7d187bc05408199bd687a538b2e68bdc17
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;
210b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganovimport android.content.ComponentName;
220b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganovimport android.content.Context;
230b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganovimport android.content.pm.ServiceInfo;
240b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganovimport android.os.IBinder;
250b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganovimport android.os.Message;
260b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganovimport android.os.ServiceManager;
270b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganovimport android.os.SystemClock;
280b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganovimport android.provider.Settings;
290b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganovimport android.test.AndroidTestCase;
300b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganovimport android.test.suitebuilder.annotation.LargeTest;
310b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganovimport android.view.accessibility.AccessibilityEvent;
3200aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganovimport android.view.accessibility.AccessibilityManager;
330b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganovimport android.view.accessibility.IAccessibilityManager;
340b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganovimport android.view.accessibility.IAccessibilityManagerClient;
350b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
360b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov/**
370b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov * This test exercises the
3800aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov * {@link com.android.server.accessibility.AccessibilityManagerService} by mocking the
390b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov * {@link android.view.accessibility.AccessibilityManager} which talks to to the
400b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov * service. The service itself is interacting with the platform. Note: Testing
410b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov * the service in full isolation would require significant amount of work for
420b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov * mocking all system interactions. It would also require a lot of mocking code.
430b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov */
440b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganovpublic class AccessibilityManagerServiceTest extends AndroidTestCase {
450b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
460b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    /**
470b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * Timeout required for pending Binder calls or event processing to
480b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * complete.
490b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     */
500b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    private static final long TIMEOUT_BINDER_CALL = 100;
510b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
520b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    /**
535637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov     * Timeout in which we are waiting for the system to start the mock
545637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov     * accessibility services.
555637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov     */
565637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov    private static final long TIMEOUT_START_MOCK_ACCESSIBILITY_SERVICES = 300;
575637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov
585637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov    /**
590b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * Timeout used for testing that a service is notified only upon a
600b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * notification timeout.
610b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     */
620b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    private static final long TIMEOUT_TEST_NOTIFICATION_TIMEOUT = 300;
630b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
640b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    /**
650b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * The interface used to talk to the tested service.
660b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     */
670b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    private IAccessibilityManager mManagerService;
680b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
690b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    @Override
700b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    public void setContext(Context context) {
710b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        super.setContext(context);
72383742c16d3dcbfcf748a89f0cb88ac8d2b31bb5Svetoslav Ganov        if (MyFirstMockAccessibilityService.sComponentName == null) {
73383742c16d3dcbfcf748a89f0cb88ac8d2b31bb5Svetoslav Ganov            MyFirstMockAccessibilityService.sComponentName = new ComponentName(
74383742c16d3dcbfcf748a89f0cb88ac8d2b31bb5Svetoslav Ganov                    context.getPackageName(), MyFirstMockAccessibilityService.class.getName())
75383742c16d3dcbfcf748a89f0cb88ac8d2b31bb5Svetoslav Ganov                    .flattenToShortString();
76383742c16d3dcbfcf748a89f0cb88ac8d2b31bb5Svetoslav Ganov        }
77383742c16d3dcbfcf748a89f0cb88ac8d2b31bb5Svetoslav Ganov        if (MySecondMockAccessibilityService.sComponentName == null) {
78383742c16d3dcbfcf748a89f0cb88ac8d2b31bb5Svetoslav Ganov            MySecondMockAccessibilityService.sComponentName = new ComponentName(
79383742c16d3dcbfcf748a89f0cb88ac8d2b31bb5Svetoslav Ganov                    context.getPackageName(), MySecondMockAccessibilityService.class.getName())
80383742c16d3dcbfcf748a89f0cb88ac8d2b31bb5Svetoslav Ganov                    .flattenToShortString();
810b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        }
820b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    }
830b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
840b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    /**
850b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * Creates a new instance.
860b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     */
870b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    public AccessibilityManagerServiceTest() {
880b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        IBinder iBinder = ServiceManager.getService(Context.ACCESSIBILITY_SERVICE);
890b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        mManagerService = IAccessibilityManager.Stub.asInterface(iBinder);
900b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    }
910b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
920b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    @LargeTest
930b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    public void testAddClient_AccessibilityDisabledThenEnabled() throws Exception {
940b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // make sure accessibility is disabled
950b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        ensureAccessibilityEnabled(mContext, false);
960b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
970b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // create a client mock instance
980b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        MyMockAccessibilityManagerClient mockClient = new MyMockAccessibilityManagerClient();
990b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
1000b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // invoke the method under test
10100aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov        final int stateFlagsDisabled = mManagerService.addClient(mockClient);
10200aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov        boolean enabledAccessibilityDisabled =
10300aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov            (stateFlagsDisabled & AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED) != 0;
1040b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
1050b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // check expected result
1060b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        assertFalse("The client must be disabled since accessibility is disabled.",
1070b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov                enabledAccessibilityDisabled);
1080b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
1090b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // enable accessibility
1100b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        ensureAccessibilityEnabled(mContext, true);
1110b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
1120b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // invoke the method under test
11300aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov        final int stateFlagsEnabled = mManagerService.addClient(mockClient);
11400aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov        boolean enabledAccessibilityEnabled =
11500aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov            (stateFlagsEnabled & AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED) != 0;
11600aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov
1170b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
1180b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // check expected result
1190b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        assertTrue("The client must be enabled since accessibility is enabled.",
1200b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov                enabledAccessibilityEnabled);
1210b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    }
1220b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
1230b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    @LargeTest
1240b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    public void testAddClient_AccessibilityEnabledThenDisabled() throws Exception {
1250b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // enable accessibility before registering the client
1260b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        ensureAccessibilityEnabled(mContext, true);
1270b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
1280b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // create a client mock instance
1290b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        MyMockAccessibilityManagerClient mockClient = new MyMockAccessibilityManagerClient();
1300b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
1310b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // invoke the method under test
13200aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov        final int stateFlagsEnabled = mManagerService.addClient(mockClient);
13300aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov        boolean enabledAccessibilityEnabled =
13400aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov            (stateFlagsEnabled & AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED) != 0;
1350b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
1360b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // check expected result
1370b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        assertTrue("The client must be enabled since accessibility is enabled.",
1380b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov                enabledAccessibilityEnabled);
1390b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
1400b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // disable accessibility
1410b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        ensureAccessibilityEnabled(mContext, false);
1420b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
1430b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // invoke the method under test
14400aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov        final int stateFlagsDisabled = mManagerService.addClient(mockClient);
14500aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov        boolean enabledAccessibilityDisabled =
14600aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov            (stateFlagsDisabled & AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED) != 0;
1470b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
1480b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // check expected result
1490b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        assertFalse("The client must be disabled since accessibility is disabled.",
1500b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov                enabledAccessibilityDisabled);
1510b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    }
1520b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
1530b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    @LargeTest
1540b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    public void testGetAccessibilityServicesList() throws Exception {
1550b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        boolean firstMockServiceInstalled = false;
1560b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        boolean secondMockServiceInstalled = false;
1570b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
1580b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        String packageName = getContext().getPackageName();
1590b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        String firstMockServiceClassName = MyFirstMockAccessibilityService.class.getName();
1600b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        String secondMockServiceClassName = MySecondMockAccessibilityService.class.getName();
1610b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
1620b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // look for the two mock services
163cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov        for (AccessibilityServiceInfo info : mManagerService.getInstalledAccessibilityServiceList()) {
164cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov            ServiceInfo serviceInfo = info.getResolveInfo().serviceInfo;
1650b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov            if (packageName.equals(serviceInfo.packageName)) {
1660b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov                if (firstMockServiceClassName.equals(serviceInfo.name)) {
1670b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov                    firstMockServiceInstalled = true;
1680b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov                } else if (secondMockServiceClassName.equals(serviceInfo.name)) {
1690b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov                    secondMockServiceInstalled = true;
1700b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov                }
1710b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov            }
1720b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        }
1730b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
1740b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // check expected result
1750b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        assertTrue("First mock service must be installed", firstMockServiceInstalled);
1760b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        assertTrue("Second mock service must be installed", secondMockServiceInstalled);
1770b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    }
1780b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
1790b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    @LargeTest
1800b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    public void testSendAccessibilityEvent_OneService_MatchingPackageAndEventType()
1810b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov            throws Exception {
1820b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // set the accessibility setting value
1830b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        ensureAccessibilityEnabled(mContext, true);
1840b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
1850b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // enable the mock accessibility service
1865637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov        ensureOnlyMockServicesEnabled(mContext, true, false);
1870b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
1880b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // configure the mock service
1890b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        MockAccessibilityService service = MyFirstMockAccessibilityService.sInstance;
1900b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        service.setServiceInfo(MockAccessibilityService.createDefaultInfo());
1910b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
1920b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // wait for the binder call to #setService to complete
1930b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        Thread.sleep(TIMEOUT_BINDER_CALL);
1940b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
1950b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // create and populate an event to be sent
1960b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        AccessibilityEvent sentEvent = AccessibilityEvent.obtain();
1970b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        fullyPopulateDefaultAccessibilityEvent(sentEvent);
1980b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
1990b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // set expectations
2000b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        service.expectEvent(sentEvent);
2010b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        service.replay();
2020b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
2030b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // send the event
2040b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        mManagerService.sendAccessibilityEvent(sentEvent);
2050b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
2060b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // verify if all expected methods have been called
2070b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        assertMockServiceVerifiedWithinTimeout(service);
2080b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    }
2090b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
2100b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    @LargeTest
2110b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    public void testSendAccessibilityEvent_OneService_NotMatchingPackage() throws Exception {
2120b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // set the accessibility setting value
2130b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        ensureAccessibilityEnabled(mContext, true);
2140b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
2150b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // enable the mock accessibility service
2165637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov        ensureOnlyMockServicesEnabled(mContext, true, false);
2170b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
2180b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // configure the mock service
2190b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        MockAccessibilityService service = MyFirstMockAccessibilityService.sInstance;
2200b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        service.setServiceInfo(MockAccessibilityService.createDefaultInfo());
2210b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
2220b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // wait for the binder call to #setService to complete
2230b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        Thread.sleep(TIMEOUT_BINDER_CALL);
2240b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
2250b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // create and populate an event to be sent
2260b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        AccessibilityEvent sentEvent = AccessibilityEvent.obtain();
2270b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        fullyPopulateDefaultAccessibilityEvent(sentEvent);
2280b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        sentEvent.setPackageName("no.service.registered.for.this.package");
2290b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
2300b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // set expectations
2310b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        service.replay();
2320b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
2330b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // send the event
2340b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        mManagerService.sendAccessibilityEvent(sentEvent);
2350b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
2360b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // verify if all expected methods have been called
2370b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        assertMockServiceVerifiedWithinTimeout(service);
2380b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    }
2390b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
2400b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    @LargeTest
2410b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    public void testSendAccessibilityEvent_OneService_NotMatchingEventType() throws Exception {
2420b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // set the accessibility setting value
2430b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        ensureAccessibilityEnabled(mContext, true);
2440b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
2450b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // enable the mock accessibility service
2465637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov        ensureOnlyMockServicesEnabled(mContext, true, false);
2470b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
2480b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // configure the mock service
2490b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        MockAccessibilityService service = MyFirstMockAccessibilityService.sInstance;
2500b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        service.setServiceInfo(MockAccessibilityService.createDefaultInfo());
2510b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
2520b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // wait for the binder call to #setService to complete
2530b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        Thread.sleep(TIMEOUT_BINDER_CALL);
2540b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
2550b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // create and populate an event to be sent
2560b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        AccessibilityEvent sentEvent = AccessibilityEvent.obtain();
2570b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        fullyPopulateDefaultAccessibilityEvent(sentEvent);
2580b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        sentEvent.setEventType(AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED);
2590b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
2600b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // set expectations
2610b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        service.replay();
2620b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
2630b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // send the event
2640b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        mManagerService.sendAccessibilityEvent(sentEvent);
2650b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
2660b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // verify if all expected methods have been called
2670b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        assertMockServiceVerifiedWithinTimeout(service);
2680b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    }
2690b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
2700b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    @LargeTest
2710b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    public void testSendAccessibilityEvent_OneService_NotifivationAfterTimeout() throws Exception {
2720b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // set the accessibility setting value
2730b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        ensureAccessibilityEnabled(mContext, true);
2740b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
2750b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // enable the mock accessibility service
2765637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov        ensureOnlyMockServicesEnabled(mContext, true, false);
2770b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
2780b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // configure the mock service
2790b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        MockAccessibilityService service = MyFirstMockAccessibilityService.sInstance;
2800b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        AccessibilityServiceInfo info = MockAccessibilityService.createDefaultInfo();
2810b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        info.notificationTimeout = TIMEOUT_TEST_NOTIFICATION_TIMEOUT;
2820b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        service.setServiceInfo(info);
2830b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
2840b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // wait for the binder call to #setService to complete
2850b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        Thread.sleep(TIMEOUT_BINDER_CALL);
2860b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
2870b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // create and populate the first event to be sent
2880b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        AccessibilityEvent firstEvent = AccessibilityEvent.obtain();
2890b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        fullyPopulateDefaultAccessibilityEvent(firstEvent);
2900b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
2910b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // create and populate the second event to be sent
2920b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        AccessibilityEvent secondEvent = AccessibilityEvent.obtain();
2930b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        fullyPopulateDefaultAccessibilityEvent(secondEvent);
2940b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
2950b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // set expectations
2960b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        service.expectEvent(secondEvent);
2970b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        service.replay();
2980b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
2990b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // send the events
3000b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        mManagerService.sendAccessibilityEvent(firstEvent);
3010b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        mManagerService.sendAccessibilityEvent(secondEvent);
3020b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
3030b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // wait for #sendAccessibilityEvent to reach the backing service
3040b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        Thread.sleep(TIMEOUT_BINDER_CALL);
3050b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
3060b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        try {
3070b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov            service.verify();
3080b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov            fail("No events must be dispatched before the expiration of the notification timeout.");
3090b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        } catch (IllegalStateException ise) {
3100b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov            /* expected */
3110b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        }
3120b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
3130b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // wait for the configured notification timeout to expire
3140b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        Thread.sleep(TIMEOUT_TEST_NOTIFICATION_TIMEOUT);
3150b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
3160b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // verify if all expected methods have been called
3170b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        assertMockServiceVerifiedWithinTimeout(service);
3180b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    }
3190b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
3200b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    @LargeTest
3210b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    public void testSendAccessibilityEvent_TwoServices_MatchingPackageAndEventType_DiffFeedback()
3220b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov            throws Exception {
3230b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // set the accessibility setting value
3240b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        ensureAccessibilityEnabled(mContext, true);
3250b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
3260b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // enable the mock accessibility services
3275637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov        ensureOnlyMockServicesEnabled(mContext, true, true);
3280b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
3290b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // configure the first mock service
3300b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        MockAccessibilityService firstService = MyFirstMockAccessibilityService.sInstance;
3310b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        AccessibilityServiceInfo firstInfo = MockAccessibilityService.createDefaultInfo();
3320b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        firstInfo.feedbackType = AccessibilityServiceInfo.FEEDBACK_AUDIBLE;
3330b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        firstService.setServiceInfo(firstInfo);
3340b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
3350b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // configure the second mock service
3360b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        MockAccessibilityService secondService = MySecondMockAccessibilityService.sInstance;
3370b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        AccessibilityServiceInfo secondInfo = MockAccessibilityService.createDefaultInfo();
3380b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        secondInfo.feedbackType = AccessibilityServiceInfo.FEEDBACK_HAPTIC;
3390b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        secondService.setServiceInfo(secondInfo);
3400b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
3410b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // wait for the binder calls to #setService to complete
3420b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        Thread.sleep(TIMEOUT_BINDER_CALL);
3430b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
3440b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // create and populate an event to be sent
3450b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        AccessibilityEvent sentEvent = AccessibilityEvent.obtain();
3460b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        fullyPopulateDefaultAccessibilityEvent(sentEvent);
3470b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
3480b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // set expectations for the first mock service
3490b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        firstService.expectEvent(sentEvent);
3500b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        firstService.replay();
3510b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
3520b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // set expectations for the second mock service
3530b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        secondService.expectEvent(sentEvent);
3540b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        secondService.replay();
3550b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
3560b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // send the event
3570b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        mManagerService.sendAccessibilityEvent(sentEvent);
3580b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
3590b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // verify if all expected methods have been called
3600b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        assertMockServiceVerifiedWithinTimeout(firstService);
3610b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        assertMockServiceVerifiedWithinTimeout(secondService);
3620b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    }
3630b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
3640b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    @LargeTest
3650b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    public void testSendAccessibilityEvent_TwoServices_MatchingPackageAndEventType()
3660b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov            throws Exception {
3670b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // set the accessibility setting value
3680b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        ensureAccessibilityEnabled(mContext, true);
3690b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
3700b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // enable the mock accessibility services
3715637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov        ensureOnlyMockServicesEnabled(mContext, true, true);
3720b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
3730b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // configure the first mock service
3740b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        MockAccessibilityService firstService = MyFirstMockAccessibilityService.sInstance;
3750b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        firstService.setServiceInfo(MockAccessibilityService.createDefaultInfo());
3760b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
3770b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // configure the second mock service
3780b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        MockAccessibilityService secondService = MySecondMockAccessibilityService.sInstance;
3790b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        secondService.setServiceInfo(MockAccessibilityService.createDefaultInfo());
3800b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
3810b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // wait for the binder calls to #setService to complete
3820b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        Thread.sleep(TIMEOUT_BINDER_CALL);
3830b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
3840b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // create and populate an event to be sent
3850b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        AccessibilityEvent sentEvent = AccessibilityEvent.obtain();
3860b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        fullyPopulateDefaultAccessibilityEvent(sentEvent);
3870b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
3880b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // set expectations for the first mock service
3890b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        firstService.expectEvent(sentEvent);
3900b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        firstService.replay();
3910b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
3920b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // set expectations for the second mock service
3930b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        secondService.replay();
3940b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
3950b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // send the event
3960b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        mManagerService.sendAccessibilityEvent(sentEvent);
3970b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
3980b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // verify if all expected methods have been called
3990b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        assertMockServiceVerifiedWithinTimeout(firstService);
4000b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        assertMockServiceVerifiedWithinTimeout(secondService);
4010b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    }
4020b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
4030b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    @LargeTest
4040b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    public void testSendAccessibilityEvent_TwoServices_MatchingPackageAndEventType_OneDefault()
4050b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov            throws Exception {
4060b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // set the accessibility setting value
4070b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        ensureAccessibilityEnabled(mContext, true);
4080b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
4090b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // enable the mock accessibility services
4105637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov        ensureOnlyMockServicesEnabled(mContext, true, true);
4110b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
4120b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // configure the first mock service
4130b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        MockAccessibilityService firstService = MyFirstMockAccessibilityService.sInstance;
4140b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        AccessibilityServiceInfo firstInfo = MyFirstMockAccessibilityService.createDefaultInfo();
4150b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        firstInfo.flags = AccessibilityServiceInfo.DEFAULT;
4160b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        firstService.setServiceInfo(firstInfo);
4170b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
4180b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // configure the second mock service
4190b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        MockAccessibilityService secondService = MySecondMockAccessibilityService.sInstance;
4200b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        secondService.setServiceInfo(MySecondMockAccessibilityService.createDefaultInfo());
4210b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
4220b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // wait for the binder calls to #setService to complete
4230b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        Thread.sleep(TIMEOUT_BINDER_CALL);
4240b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
4250b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // create and populate an event to be sent
4260b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        AccessibilityEvent sentEvent = AccessibilityEvent.obtain();
4270b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        fullyPopulateDefaultAccessibilityEvent(sentEvent);
4280b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
4290b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // set expectations for the first mock service
4300b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        firstService.replay();
4310b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
4320b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // set expectations for the second mock service
4330b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        secondService.expectEvent(sentEvent);
4340b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        secondService.replay();
4350b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
4360b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // send the event
4370b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        mManagerService.sendAccessibilityEvent(sentEvent);
4380b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
4390b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // verify if all expected methods have been called
4400b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        assertMockServiceVerifiedWithinTimeout(firstService);
4410b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        assertMockServiceVerifiedWithinTimeout(secondService);
4420b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    }
4430b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
4440b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    @LargeTest
4450b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    public void testSendAccessibilityEvent_TwoServices_MatchingPackageAndEventType_TwoDefault()
4460b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov            throws Exception {
4470b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // set the accessibility setting value
4480b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        ensureAccessibilityEnabled(mContext, true);
4490b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
4500b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // enable the mock accessibility services
4515637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov        ensureOnlyMockServicesEnabled(mContext, true, true);
4520b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
4530b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // configure the first mock service
4540b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        MockAccessibilityService firstService = MyFirstMockAccessibilityService.sInstance;
4550b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        AccessibilityServiceInfo firstInfo = MyFirstMockAccessibilityService.createDefaultInfo();
4560b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        firstInfo.flags = AccessibilityServiceInfo.DEFAULT;
4570b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        firstService.setServiceInfo(firstInfo);
4580b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
4590b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // configure the second mock service
4600b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        MockAccessibilityService secondService = MySecondMockAccessibilityService.sInstance;
4610b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        AccessibilityServiceInfo secondInfo = MyFirstMockAccessibilityService.createDefaultInfo();
4620b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        secondInfo.flags = AccessibilityServiceInfo.DEFAULT;
4630b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        secondService.setServiceInfo(firstInfo);
4640b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
4650b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // wait for the binder calls to #setService to complete
4660b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        Thread.sleep(TIMEOUT_BINDER_CALL);
4670b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
4680b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // create and populate an event to be sent
4690b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        AccessibilityEvent sentEvent = AccessibilityEvent.obtain();
4700b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        fullyPopulateDefaultAccessibilityEvent(sentEvent);
4710b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
4720b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // set expectations for the first mock service
4730b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        firstService.expectEvent(sentEvent);
4740b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        firstService.replay();
4750b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
4760b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // set expectations for the second mock service
4770b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        secondService.replay();
4780b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
4790b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // send the event
4800b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        mManagerService.sendAccessibilityEvent(sentEvent);
4810b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
4820b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // verify if all expected methods have been called
4830b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        assertMockServiceVerifiedWithinTimeout(firstService);
4840b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        assertMockServiceVerifiedWithinTimeout(secondService);
4850b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    }
4860b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
4870b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    @LargeTest
4880b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    public void testInterrupt() throws Exception {
4890b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // set the accessibility setting value
4900b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        ensureAccessibilityEnabled(mContext, true);
4910b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
4920b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // enable the mock accessibility services
4935637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov        ensureOnlyMockServicesEnabled(mContext, true, true);
4940b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
4950b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // configure the first mock service
4960b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        MockAccessibilityService firstService = MyFirstMockAccessibilityService.sInstance;
4970b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        firstService.setServiceInfo(MockAccessibilityService.createDefaultInfo());
4980b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
4990b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // configure the second mock service
5000b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        MockAccessibilityService secondService = MySecondMockAccessibilityService.sInstance;
5010b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        secondService.setServiceInfo(MockAccessibilityService.createDefaultInfo());
5020b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
5030b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // wait for the binder calls to #setService to complete
5040b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        Thread.sleep(TIMEOUT_BINDER_CALL);
5050b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
5060b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // set expectations for the first mock service
5070b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        firstService.expectInterrupt();
5080b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        firstService.replay();
5090b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
5100b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // set expectations for the second mock service
5110b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        secondService.expectInterrupt();
5120b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        secondService.replay();
5130b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
5140b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // call the method under test
5150b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        mManagerService.interrupt();
5160b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
5170b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // verify if all expected methods have been called
5180b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        assertMockServiceVerifiedWithinTimeout(firstService);
5190b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        assertMockServiceVerifiedWithinTimeout(secondService);
5200b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    }
5210b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
5220b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    /**
5230b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * Fully populates the {@link AccessibilityEvent} to marshal.
5240b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     *
5250b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * @param sentEvent The event to populate.
5260b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     */
5270b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    private void fullyPopulateDefaultAccessibilityEvent(AccessibilityEvent sentEvent) {
5280b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        sentEvent.setAddedCount(1);
5290b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        sentEvent.setBeforeText("BeforeText");
5300b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        sentEvent.setChecked(true);
5310b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        sentEvent.setClassName("foo.bar.baz.Class");
5320b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        sentEvent.setContentDescription("ContentDescription");
5330b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        sentEvent.setCurrentItemIndex(1);
5340b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        sentEvent.setEnabled(true);
5350b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        sentEvent.setEventType(AccessibilityEvent.TYPE_VIEW_CLICKED);
5360b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        sentEvent.setEventTime(1000);
5370b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        sentEvent.setFromIndex(1);
5380b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        sentEvent.setFullScreen(true);
5390b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        sentEvent.setItemCount(1);
5400b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        sentEvent.setPackageName("foo.bar.baz");
5410b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        sentEvent.setParcelableData(Message.obtain(null, 1, null));
5420b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        sentEvent.setPassword(true);
5430b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        sentEvent.setRemovedCount(1);
5440b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    }
5450b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
5460b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    /**
5470b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * This class is a mock {@link IAccessibilityManagerClient}.
5480b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     */
5490b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    public class MyMockAccessibilityManagerClient extends IAccessibilityManagerClient.Stub {
55000aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov        int mState;
5510b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
55200aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov        public void setState(int state) {
55300aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov            mState = state;
5540b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        }
55535bfedeaba724aeadc6f6c890269cb6bf7ef42f5Svetoslav Ganov
55635bfedeaba724aeadc6f6c890269cb6bf7ef42f5Svetoslav Ganov        public void setTouchExplorationEnabled(boolean enabled) {
55735bfedeaba724aeadc6f6c890269cb6bf7ef42f5Svetoslav Ganov        }
5580b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    }
5590b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
5600b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    /**
5610b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * Ensures accessibility is in a given state by writing the state to the
5620b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * settings and waiting until the accessibility manager service pick it up.
5630b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     *
5640b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * @param context A context handle to access the settings.
5650b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * @param enabled The accessibility state to write to the settings.
5660b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * @throws Exception If any error occurs.
5670b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     */
5680b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    private void ensureAccessibilityEnabled(Context context, boolean enabled) throws Exception {
5690b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        boolean isEnabled = (Settings.Secure.getInt(context.getContentResolver(),
5700b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov                Settings.Secure.ACCESSIBILITY_ENABLED, 0) == 1 ? true : false);
5710b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
5720b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        if (isEnabled == enabled) {
5730b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov            return;
5740b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        }
5750b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
5760b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        Settings.Secure.putInt(context.getContentResolver(), Settings.Secure.ACCESSIBILITY_ENABLED,
5770b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov                enabled ? 1 : 0);
5780b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
5790b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // wait the accessibility manager service to pick the change up
5800b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        Thread.sleep(TIMEOUT_BINDER_CALL);
5810b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    }
5820b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
5830b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    /**
5840b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * Ensures the only {@link MockAccessibilityService}s with given component
5850b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * names are enabled by writing to the system settings and waiting until the
5865637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov     * accessibility manager service picks that up or the
5875637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov     * {@link #TIMEOUT_START_MOCK_ACCESSIBILITY_SERVICES} is exceeded.
5880b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     *
5890b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * @param context A context handle to access the settings.
5905637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov     * @param firstMockServiceEnabled If the first mock accessibility service is enabled.
5915637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov     * @param secondMockServiceEnabled If the second mock accessibility service is enabled.
5925637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov     * @throws IllegalStateException If some of the requested for enabling mock services
5935637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov     *         is not properly started.
5940b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * @throws Exception Exception If any error occurs.
5950b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     */
5965637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov    private void ensureOnlyMockServicesEnabled(Context context, boolean firstMockServiceEnabled,
5975637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov            boolean secondMockServiceEnabled) throws Exception {
5980b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        String enabledServices = Settings.Secure.getString(context.getContentResolver(),
5990b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov                Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
6000b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
6010b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        StringBuilder servicesToEnable = new StringBuilder();
6025637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov        if (firstMockServiceEnabled) {
6035637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov            servicesToEnable.append(MyFirstMockAccessibilityService.sComponentName).append(":");
6045637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov        }
6055637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov        if (secondMockServiceEnabled) {
6065637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov            servicesToEnable.append(MySecondMockAccessibilityService.sComponentName).append(":");
6070b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        }
6080b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
6090b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        if (servicesToEnable.equals(enabledServices)) {
6100b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov            return;
6110b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        }
6120b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
6130b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        Settings.Secure.putString(context.getContentResolver(),
6140b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov                Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, servicesToEnable.toString());
6150b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
6165637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov        // we have enabled the services of interest and need to wait until they
6175637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov        // are instantiated and started (if needed) and the system binds to them
6185637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov        boolean firstMockServiceOK = false;
6195637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov        boolean secondMockServiceOK = false;
6205637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov        long start = SystemClock.uptimeMillis();
6215637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov        long pollingInterval = TIMEOUT_START_MOCK_ACCESSIBILITY_SERVICES / 6;
6225637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov
6235637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov        while (SystemClock.uptimeMillis() - start < TIMEOUT_START_MOCK_ACCESSIBILITY_SERVICES)  {
6245637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov            firstMockServiceOK = !firstMockServiceEnabled
6255637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov                    || (MyFirstMockAccessibilityService.sInstance != null
6265637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov                    && MyFirstMockAccessibilityService.sInstance.isSystemBoundAsClient());
6275637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov
6285637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov            secondMockServiceOK = !secondMockServiceEnabled
6295637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov                    || (MySecondMockAccessibilityService.sInstance != null
6305637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov                    && MySecondMockAccessibilityService.sInstance.isSystemBoundAsClient());
6315637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov
6325637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov            if (firstMockServiceOK && secondMockServiceOK) {
6335637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov                return;
6345637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov            }
6355637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov
6365637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov            Thread.sleep(pollingInterval);
6375637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov        }
6385637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov
6395637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov        StringBuilder message = new StringBuilder();
6405637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov        message.append("Mock accessibility services not started or system not bound as a client: ");
6415637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov        if (!firstMockServiceOK) {
6425637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov            message.append(MyFirstMockAccessibilityService.sComponentName);
6435637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov            message.append(" ");
6445637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov        }
6455637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov        if (!secondMockServiceOK) {
6465637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov            message.append(MySecondMockAccessibilityService.sComponentName);
6475637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov        }
6485637745e59e1c0c22ec2e0adb1f48f8f4edcb7beSvetoslav Ganov        throw new IllegalStateException(message.toString());
6490b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    }
6500b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
6510b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    /**
6520b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * Asserts the the mock accessibility service has been successfully verified
6530b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * (which is it has received the expected method calls with expected
6540b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * arguments) within the {@link #TIMEOUT_BINDER_CALL}. The verified state is
6550b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * checked by polling upon small intervals.
6560b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     *
6570b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * @param service The service to verify.
6580b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * @throws Exception If the verification has failed with exception after the
6590b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     *             {@link #TIMEOUT_BINDER_CALL}.
6600b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     */
6610b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    private void assertMockServiceVerifiedWithinTimeout(MockAccessibilityService service)
6620b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov            throws Exception {
6630b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        Exception lastVerifyException = null;
6640b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        long beginTime = SystemClock.uptimeMillis();
6650b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        long pollTmeout = TIMEOUT_BINDER_CALL / 5;
6660b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
6670b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // poll until the timeout has elapsed
6680b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        while (SystemClock.uptimeMillis() - beginTime < TIMEOUT_BINDER_CALL) {
6690b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov            // sleep first since immediate call will always fail
6700b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov            try {
6710b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov                Thread.sleep(pollTmeout);
6720b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov            } catch (InterruptedException ie) {
6730b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov                /* ignore */
6740b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov            }
6750b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov            // poll for verification and if this fails save the exception and
6760b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov            // keep polling
6770b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov            try {
6780b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov                service.verify();
6790b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov                // reset so it does not accept more events
6800b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov                service.reset();
6810b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov                return;
6820b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov            } catch (Exception e) {
6830b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov                lastVerifyException = e;
6840b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov            }
6850b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        }
6860b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
6870b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // reset, we have already failed
6880b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        service.reset();
6890b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
6900b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        // always not null
6910b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        throw lastVerifyException;
6920b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    }
6930b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
6940b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    /**
6950b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * This class is the first mock {@link AccessibilityService}.
6960b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     */
6970b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    public static class MyFirstMockAccessibilityService extends MockAccessibilityService {
6980b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
6990b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        /**
7000b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov         * The service {@link ComponentName} flattened as a string.
7010b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov         */
702383742c16d3dcbfcf748a89f0cb88ac8d2b31bb5Svetoslav Ganov        static String sComponentName;
7030b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
7040b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        /**
7050b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov         * Handle to the service instance.
7060b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov         */
7070b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        static MyFirstMockAccessibilityService sInstance;
7080b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
7090b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        /**
7100b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov         * Creates a new instance.
7110b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov         */
7120b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        public MyFirstMockAccessibilityService() {
7130b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov            sInstance = this;
7140b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        }
7150b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    }
7160b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
7170b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    /**
7180b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     * This class is the first mock {@link AccessibilityService}.
7190b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov     */
7200b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    public static class MySecondMockAccessibilityService extends MockAccessibilityService {
7210b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
7220b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        /**
7230b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov         * The service {@link ComponentName} flattened as a string.
7240b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov         */
725383742c16d3dcbfcf748a89f0cb88ac8d2b31bb5Svetoslav Ganov        static String sComponentName;
7260b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
7270b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        /**
7280b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov         * Handle to the service instance.
7290b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov         */
7300b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        static MySecondMockAccessibilityService sInstance;
7310b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov
7320b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        /**
7330b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov         * Creates a new instance.
7340b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov         */
7350b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        public MySecondMockAccessibilityService() {
7360b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov            sInstance = this;
7370b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov        }
7380b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov    }
7390b29a587142b19ed25dd6489cfa037d06145afd1Svetoslav Ganov}
740