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