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