AccessibilityManagerServiceTest.java revision 0b29a587142b19ed25dd6489cfa037d06145afd1
1db0e15ae3e2b5e180541eec35e2bce54359ca7d8Zhongxing Xu/*
261f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek * Copyright (C) 2010 The Android Open Source Project
361f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek *
461f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek * Licensed under the Apache License, Version 2.0 (the "License");
561f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek * you may not use this file except in compliance with the License.
661f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek * You may obtain a copy of the License at
761f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek *
861f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek *      http://www.apache.org/licenses/LICENSE-2.0
961f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek *
1061f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek * Unless required by applicable law or agreed to in writing, software
114adc81e540b874bafa15715fd2c5cb662463debdTed Kremenek * distributed under the License is distributed on an "AS IS" BASIS,
1261f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1361f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek * See the License for the specific language governing permissions and
1461f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek * limitations under the License.
155a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis */
165a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis
1761f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenekpackage com.android.server;
18d2f642b56e87493edfc3b0dab359b5e32d5f8a5eTed Kremenek
199b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenekimport android.accessibilityservice.AccessibilityService;
201b431023814196f87515a540ebcb9e9f1a9176a1Ted Kremenekimport android.accessibilityservice.AccessibilityServiceInfo;
211b431023814196f87515a540ebcb9e9f1a9176a1Ted Kremenekimport android.content.ComponentName;
221b431023814196f87515a540ebcb9e9f1a9176a1Ted Kremenekimport android.content.Context;
23f377fc85488f4799ced714ac60e65a0e3f8f69cbTed Kremenekimport android.content.pm.ServiceInfo;
24e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenekimport android.os.IBinder;
25e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenekimport android.os.Message;
2661f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenekimport android.os.ServiceManager;
271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpimport android.os.SystemClock;
285a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidisimport android.provider.Settings;
295a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidisimport android.test.AndroidTestCase;
305a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidisimport android.test.suitebuilder.annotation.LargeTest;
315a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidisimport android.view.accessibility.AccessibilityEvent;
325a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidisimport android.view.accessibility.IAccessibilityManager;
339ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenekimport android.view.accessibility.IAccessibilityManagerClient;
345a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis
3561f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek/**
3661f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek * This test exercises the
3761f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek * {@link com.android.server.AccessibilityManagerService} by mocking the
385e2d2c2ee3cf410643e0f9a5701708e51409d973Benjamin Kramer * {@link android.view.accessibility.AccessibilityManager} which talks to to the
395e2d2c2ee3cf410643e0f9a5701708e51409d973Benjamin Kramer * service. The service itself is interacting with the platform. Note: Testing
4050a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek * the service in full isolation would require significant amount of work for
418966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek * mocking all system interactions. It would also require a lot of mocking code.
42d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis */
434adc81e540b874bafa15715fd2c5cb662463debdTed Kremenekpublic class AccessibilityManagerServiceTest extends AndroidTestCase {
44cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    /**
46cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek     * Timeout required for pending Binder calls or event processing to
47cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek     * complete.
48cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek     */
498966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek    private static final long TIMEOUT_BINDER_CALL = 100;
501b431023814196f87515a540ebcb9e9f1a9176a1Ted Kremenek
518966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek    /**
528966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek     * Timeout used for testing that a service is notified only upon a
53c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu     * notification timeout.
54c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu     */
55dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek    private static final long TIMEOUT_TEST_NOTIFICATION_TIMEOUT = 300;
561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
578966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek    /**
581b431023814196f87515a540ebcb9e9f1a9176a1Ted Kremenek     * The package name.
598966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek     */
601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    private static String sPackageName;
61cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
628966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek    /**
637a9bb52171f962d51ab13c1e012d2236feb9558dTed Kremenek     * The interface used to talk to the tested service.
64cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek     */
65d49967f8764135ae65658e354b6d38e3637c9de3Ted Kremenek    private IAccessibilityManager mManagerService;
66cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
67212f6d3b5fb3fa55ba1e40671cfc336430abc8ddTom Care    @Override
68640ccf071076e684713cc3c3276bb51982bff607Argyrios Kyrtzidis    public void setContext(Context context) {
691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        super.setContext(context);
70cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek        if (sPackageName == null) {
71cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek            sPackageName = context.getPackageName();
72cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek        }
73cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek    }
74cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
75404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis    /**
76cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek     * Creates a new instance.
771a0c8b9183fde84982aea9190a55fde1541c432dTed Kremenek     */
78072192bcbb05a0fee7ec3061750b27e8d2004952Ted Kremenek    public AccessibilityManagerServiceTest() {
791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        IBinder iBinder = ServiceManager.getService(Context.ACCESSIBILITY_SERVICE);
8050a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek        mManagerService = IAccessibilityManager.Stub.asInterface(iBinder);
81fe9e543a2a363df7fcaa899367d3b2580b63b27cTed Kremenek    }
82fe9e543a2a363df7fcaa899367d3b2580b63b27cTed Kremenek
83fe9e543a2a363df7fcaa899367d3b2580b63b27cTed Kremenek    @LargeTest
84c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu    public void testAddClient_AccessibilityDisabledThenEnabled() throws Exception {
85c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu        // make sure accessibility is disabled
86fe9e543a2a363df7fcaa899367d3b2580b63b27cTed Kremenek        ensureAccessibilityEnabled(mContext, false);
871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
88212f6d3b5fb3fa55ba1e40671cfc336430abc8ddTom Care        // create a client mock instance
89212f6d3b5fb3fa55ba1e40671cfc336430abc8ddTom Care        MyMockAccessibilityManagerClient mockClient = new MyMockAccessibilityManagerClient();
901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
91d02e232c43b979758810794de24d3f5cde40fe93Benjamin Kramer        // invoke the method under test
92212f6d3b5fb3fa55ba1e40671cfc336430abc8ddTom Care        boolean enabledAccessibilityDisabled = mManagerService.addClient(mockClient);
93212f6d3b5fb3fa55ba1e40671cfc336430abc8ddTom Care
94212f6d3b5fb3fa55ba1e40671cfc336430abc8ddTom Care        // check expected result
95d49967f8764135ae65658e354b6d38e3637c9de3Ted Kremenek        assertFalse("The client must be disabled since accessibility is disabled.",
9650a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek                enabledAccessibilityDisabled);
971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
988966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek        // enable accessibility
99cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek        ensureAccessibilityEnabled(mContext, true);
100cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
101cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek        // invoke the method under test
1021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        boolean enabledAccessibilityEnabled = mManagerService.addClient(mockClient);
103cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
104212f6d3b5fb3fa55ba1e40671cfc336430abc8ddTom Care        // check expected result
1051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        assertTrue("The client must be enabled since accessibility is enabled.",
106cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek                enabledAccessibilityEnabled);
107cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek    }
1088966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek
1098966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek    @LargeTest
11050d5bc4e3b53eb8bb4ebf198f1213348a3fa0f38Zhongxing Xu    public void testAddClient_AccessibilityEnabledThenDisabled() throws Exception {
1111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        // enable accessibility before registering the client
1128b9317186fd5243938128a0b0e0494498d78ab8cTed Kremenek        ensureAccessibilityEnabled(mContext, true);
113d49967f8764135ae65658e354b6d38e3637c9de3Ted Kremenek
1148b9317186fd5243938128a0b0e0494498d78ab8cTed Kremenek        // create a client mock instance
115d49967f8764135ae65658e354b6d38e3637c9de3Ted Kremenek        MyMockAccessibilityManagerClient mockClient = new MyMockAccessibilityManagerClient();
116d49967f8764135ae65658e354b6d38e3637c9de3Ted Kremenek
1171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        // invoke the method under test
118cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek        boolean enabledAccessibilityEnabled = mManagerService.addClient(mockClient);
119072192bcbb05a0fee7ec3061750b27e8d2004952Ted Kremenek
120cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek        // check expected result
121072192bcbb05a0fee7ec3061750b27e8d2004952Ted Kremenek        assertTrue("The client must be enabled since accessibility is enabled.",
1221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                enabledAccessibilityEnabled);
123cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
124dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek        // disable accessibility
125c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu        ensureAccessibilityEnabled(mContext, false);
1261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
127cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek        // invoke the method under test
128cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek        boolean enabledAccessibilityDisabled = mManagerService.addClient(mockClient);
129cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
130cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek        // check expected result
131cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek        assertFalse("The client must be disabled since accessibility is disabled.",
1321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                enabledAccessibilityDisabled);
133640ccf071076e684713cc3c3276bb51982bff607Argyrios Kyrtzidis    }
134640ccf071076e684713cc3c3276bb51982bff607Argyrios Kyrtzidis
135cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek    @LargeTest
136640ccf071076e684713cc3c3276bb51982bff607Argyrios Kyrtzidis    public void testGetAccessibilityServicesList() throws Exception {
137cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek        boolean firstMockServiceInstalled = false;
138c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu        boolean secondMockServiceInstalled = false;
139c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu
140dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek        String packageName = getContext().getPackageName();
1411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        String firstMockServiceClassName = MyFirstMockAccessibilityService.class.getName();
142dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek        String secondMockServiceClassName = MySecondMockAccessibilityService.class.getName();
143c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu
1446837faa083bebad39aa342f84c2b450fb6410eafTed Kremenek        // look for the two mock services
145cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek        for (ServiceInfo serviceInfo : mManagerService.getAccessibilityServiceList()) {
146cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek            if (packageName.equals(serviceInfo.packageName)) {
147cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek                if (firstMockServiceClassName.equals(serviceInfo.name)) {
148cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek                    firstMockServiceInstalled = true;
1491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                } else if (secondMockServiceClassName.equals(serviceInfo.name)) {
150cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek                    secondMockServiceInstalled = true;
151cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek                }
152cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek            }
1531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        }
154cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
155cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek        // check expected result
156cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek        assertTrue("First mock service must be installed", firstMockServiceInstalled);
157cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek        assertTrue("Second mock service must be installed", secondMockServiceInstalled);
158cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek    }
159cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
160cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek    @LargeTest
161cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek    public void testSendAccessibilityEvent_OneService_MatchingPackageAndEventType()
162cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek            throws Exception {
163cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek        // set the accessibility setting value
164cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek        ensureAccessibilityEnabled(mContext, true);
165cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
166cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek        // enable the mock accessibility service
167cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek        ensureOnlyMockServicesEnabled(mContext, MyFirstMockAccessibilityService.sComponentName);
168cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
169cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek        // configure the mock service
170cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek        MockAccessibilityService service = MyFirstMockAccessibilityService.sInstance;
171cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek        service.setServiceInfo(MockAccessibilityService.createDefaultInfo());
172cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
173cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek        // wait for the binder call to #setService to complete
174cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek        Thread.sleep(TIMEOUT_BINDER_CALL);
1751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1763aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek        // create and populate an event to be sent
1773aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek        AccessibilityEvent sentEvent = AccessibilityEvent.obtain();
1783aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek        fullyPopulateDefaultAccessibilityEvent(sentEvent);
1793aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek
1803aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek        // set expectations
1813aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek        service.expectEvent(sentEvent);
1823aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek        service.replay();
1833aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek
1843aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek        // send the event
1853aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek        mManagerService.sendAccessibilityEvent(sentEvent);
1861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
187cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek        // verify if all expected methods have been called
188cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek        assertMockServiceVerifiedWithinTimeout(service);
1891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    }
1903aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek
1913aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek    @LargeTest
192cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek    public void testSendAccessibilityEvent_OneService_NotMatchingPackage() throws Exception {
1931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        // set the accessibility setting value
1941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        ensureAccessibilityEnabled(mContext, true);
195cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
196cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek        // enable the mock accessibility service
197cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek        ensureOnlyMockServicesEnabled(mContext, MyFirstMockAccessibilityService.sComponentName);
1981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
199cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek        // configure the mock service
200d2f642b56e87493edfc3b0dab359b5e32d5f8a5eTed Kremenek        MockAccessibilityService service = MyFirstMockAccessibilityService.sInstance;
201640ccf071076e684713cc3c3276bb51982bff607Argyrios Kyrtzidis        service.setServiceInfo(MockAccessibilityService.createDefaultInfo());
2025e55cda64f4452fa65d83f66390c7126a8b248bbTed Kremenek
203212f6d3b5fb3fa55ba1e40671cfc336430abc8ddTom Care        // wait for the binder call to #setService to complete
204212f6d3b5fb3fa55ba1e40671cfc336430abc8ddTom Care        Thread.sleep(TIMEOUT_BINDER_CALL);
205212f6d3b5fb3fa55ba1e40671cfc336430abc8ddTom Care
2061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        // create and populate an event to be sent
207d02e232c43b979758810794de24d3f5cde40fe93Benjamin Kramer        AccessibilityEvent sentEvent = AccessibilityEvent.obtain();
208212f6d3b5fb3fa55ba1e40671cfc336430abc8ddTom Care        fullyPopulateDefaultAccessibilityEvent(sentEvent);
209212f6d3b5fb3fa55ba1e40671cfc336430abc8ddTom Care        sentEvent.setPackageName("no.service.registered.for.this.package");
2101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
211cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek        // set expectations
21222bda887aacd0e591978541a799aa43835652ec9Ted Kremenek        service.replay();
213cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
21494fd0b8c88db9b1cd99457d3cd8cd333341dd39cTed Kremenek        // send the event
215a5083e6ab51b031241152e81457240497ab9bff9Ted Kremenek        mManagerService.sendAccessibilityEvent(sentEvent);
216a5083e6ab51b031241152e81457240497ab9bff9Ted Kremenek
217a5083e6ab51b031241152e81457240497ab9bff9Ted Kremenek        // verify if all expected methods have been called
2181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        assertMockServiceVerifiedWithinTimeout(service);
219640ccf071076e684713cc3c3276bb51982bff607Argyrios Kyrtzidis    }
220640ccf071076e684713cc3c3276bb51982bff607Argyrios Kyrtzidis
2215e55cda64f4452fa65d83f66390c7126a8b248bbTed Kremenek    @LargeTest
2225e55cda64f4452fa65d83f66390c7126a8b248bbTed Kremenek    public void testSendAccessibilityEvent_OneService_NotMatchingEventType() throws Exception {
2231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        // set the accessibility setting value
224592362b46ad69db0db0988e7f9d8cbe647510bddTed Kremenek        ensureAccessibilityEnabled(mContext, true);
225592362b46ad69db0db0988e7f9d8cbe647510bddTed Kremenek
226592362b46ad69db0db0988e7f9d8cbe647510bddTed Kremenek        // enable the mock accessibility service
227592362b46ad69db0db0988e7f9d8cbe647510bddTed Kremenek        ensureOnlyMockServicesEnabled(mContext, MyFirstMockAccessibilityService.sComponentName);
2281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
229592362b46ad69db0db0988e7f9d8cbe647510bddTed Kremenek        // configure the mock service
230592362b46ad69db0db0988e7f9d8cbe647510bddTed Kremenek        MockAccessibilityService service = MyFirstMockAccessibilityService.sInstance;
231592362b46ad69db0db0988e7f9d8cbe647510bddTed Kremenek        service.setServiceInfo(MockAccessibilityService.createDefaultInfo());
2321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
233592362b46ad69db0db0988e7f9d8cbe647510bddTed Kremenek        // wait for the binder call to #setService to complete
234212f6d3b5fb3fa55ba1e40671cfc336430abc8ddTom Care        Thread.sleep(TIMEOUT_BINDER_CALL);
235212f6d3b5fb3fa55ba1e40671cfc336430abc8ddTom Care
236212f6d3b5fb3fa55ba1e40671cfc336430abc8ddTom Care        // create and populate an event to be sent
2371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        AccessibilityEvent sentEvent = AccessibilityEvent.obtain();
238d02e232c43b979758810794de24d3f5cde40fe93Benjamin Kramer        fullyPopulateDefaultAccessibilityEvent(sentEvent);
239212f6d3b5fb3fa55ba1e40671cfc336430abc8ddTom Care        sentEvent.setEventType(AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED);
240212f6d3b5fb3fa55ba1e40671cfc336430abc8ddTom Care
2411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        // set expectations
242592362b46ad69db0db0988e7f9d8cbe647510bddTed Kremenek        service.replay();
2431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        // send the event
245592362b46ad69db0db0988e7f9d8cbe647510bddTed Kremenek        mManagerService.sendAccessibilityEvent(sentEvent);
246592362b46ad69db0db0988e7f9d8cbe647510bddTed Kremenek
247592362b46ad69db0db0988e7f9d8cbe647510bddTed Kremenek        // verify if all expected methods have been called
2481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        assertMockServiceVerifiedWithinTimeout(service);
249592362b46ad69db0db0988e7f9d8cbe647510bddTed Kremenek    }
250592362b46ad69db0db0988e7f9d8cbe647510bddTed Kremenek
251592362b46ad69db0db0988e7f9d8cbe647510bddTed Kremenek    @LargeTest
252592362b46ad69db0db0988e7f9d8cbe647510bddTed Kremenek    public void testSendAccessibilityEvent_OneService_NotifivationAfterTimeout() throws Exception {
2531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        // set the accessibility setting value
254cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek        ensureAccessibilityEnabled(mContext, true);
255cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
256cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek        // enable the mock accessibility service
257cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek        ensureOnlyMockServicesEnabled(mContext, MyFirstMockAccessibilityService.sComponentName);
258c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek
259c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek        // configure the mock service
260c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek        MockAccessibilityService service = MyFirstMockAccessibilityService.sInstance;
2611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        AccessibilityServiceInfo info = MockAccessibilityService.createDefaultInfo();
2621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        info.notificationTimeout = TIMEOUT_TEST_NOTIFICATION_TIMEOUT;
2635032ffe4259e7d436f2eb19e5a29fdae559e7c12Zhongxing Xu        service.setServiceInfo(info);
264c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek
265c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek        // wait for the binder call to #setService to complete
2661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        Thread.sleep(TIMEOUT_BINDER_CALL);
26761f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek
268c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek        // create and populate the first event to be sent
269c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek        AccessibilityEvent firstEvent = AccessibilityEvent.obtain();
270c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek        fullyPopulateDefaultAccessibilityEvent(firstEvent);
271cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
272cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek        // create and populate the second event to be sent
273cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek        AccessibilityEvent secondEvent = AccessibilityEvent.obtain();
274cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek        fullyPopulateDefaultAccessibilityEvent(secondEvent);
275cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
2761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        // set expectations
277c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek        service.expectEvent(secondEvent);
2781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        service.replay();
279cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
280cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek        // send the events
281404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis        mManagerService.sendAccessibilityEvent(firstEvent);
282404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis        mManagerService.sendAccessibilityEvent(secondEvent);
283cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
2843baf672378f105602d2b12f03f00277ae1936fe9Ted Kremenek        // wait for #sendAccessibilityEvent to reach the backing service
285212f6d3b5fb3fa55ba1e40671cfc336430abc8ddTom Care        Thread.sleep(TIMEOUT_BINDER_CALL);
286cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
28761f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek        try {
2883baf672378f105602d2b12f03f00277ae1936fe9Ted Kremenek            service.verify();
289212f6d3b5fb3fa55ba1e40671cfc336430abc8ddTom Care            fail("No events must be dispatched before the expiration of the notification timeout.");
290c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek        } catch (IllegalStateException ise) {
2911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            /* expected */
292cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek        }
2931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
294c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek        // wait for the configured notification timeout to expire
2951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        Thread.sleep(TIMEOUT_TEST_NOTIFICATION_TIMEOUT);
296c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek
297c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek        // verify if all expected methods have been called
298c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek        assertMockServiceVerifiedWithinTimeout(service);
2991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    }
300c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek
301c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek    @LargeTest
302c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek    public void testSendAccessibilityEvent_TwoServices_MatchingPackageAndEventType_DiffFeedback()
3031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            throws Exception {
3043aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek        // set the accessibility setting value
3053aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek        ensureAccessibilityEnabled(mContext, true);
3063aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek
3071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        // enable the mock accessibility services
308404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis        ensureOnlyMockServicesEnabled(mContext, MyFirstMockAccessibilityService.sComponentName,
309404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis                MySecondMockAccessibilityService.sComponentName);
310404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis
311404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis        // configure the first mock service
3125032ffe4259e7d436f2eb19e5a29fdae559e7c12Zhongxing Xu        MockAccessibilityService firstService = MyFirstMockAccessibilityService.sInstance;
3131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        AccessibilityServiceInfo firstInfo = MockAccessibilityService.createDefaultInfo();
314cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek        firstInfo.feedbackType = AccessibilityServiceInfo.FEEDBACK_AUDIBLE;
3151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        firstService.setServiceInfo(firstInfo);
31640406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek
31740406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek        // configure the second mock service
31861f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek        MockAccessibilityService secondService = MySecondMockAccessibilityService.sInstance;
319cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek        AccessibilityServiceInfo secondInfo = MockAccessibilityService.createDefaultInfo();
3201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        secondInfo.feedbackType = AccessibilityServiceInfo.FEEDBACK_HAPTIC;
321cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek        secondService.setServiceInfo(secondInfo);
3221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
323f0171732efb4647772ad2a45c0f31978b0e34f71Benjamin Kramer        // wait for the binder calls to #setService to complete
3248f2698621f5090db1dea691059bd0ebd79fb7f14Ted Kremenek        Thread.sleep(TIMEOUT_BINDER_CALL);
3258f2698621f5090db1dea691059bd0ebd79fb7f14Ted Kremenek
3268f2698621f5090db1dea691059bd0ebd79fb7f14Ted Kremenek        // create and populate an event to be sent
327f0171732efb4647772ad2a45c0f31978b0e34f71Benjamin Kramer        AccessibilityEvent sentEvent = AccessibilityEvent.obtain();
328f0171732efb4647772ad2a45c0f31978b0e34f71Benjamin Kramer        fullyPopulateDefaultAccessibilityEvent(sentEvent);
3298c036c7f77d69f96df49219ed0bdbade200d52ebTed Kremenek
3301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        // set expectations for the first mock service
3311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        firstService.expectEvent(sentEvent);
332f0171732efb4647772ad2a45c0f31978b0e34f71Benjamin Kramer        firstService.replay();
3338f2698621f5090db1dea691059bd0ebd79fb7f14Ted Kremenek
3348f2698621f5090db1dea691059bd0ebd79fb7f14Ted Kremenek        // set expectations for the second mock service
3358f2698621f5090db1dea691059bd0ebd79fb7f14Ted Kremenek        secondService.expectEvent(sentEvent);
3361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        secondService.replay();
337f0171732efb4647772ad2a45c0f31978b0e34f71Benjamin Kramer
338f0171732efb4647772ad2a45c0f31978b0e34f71Benjamin Kramer        // send the event
33962059e809596a419e6fc3e751b2f0b57b7cc51e7Ted Kremenek        mManagerService.sendAccessibilityEvent(sentEvent);
34062059e809596a419e6fc3e751b2f0b57b7cc51e7Ted Kremenek
3411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        // verify if all expected methods have been called
342f0171732efb4647772ad2a45c0f31978b0e34f71Benjamin Kramer        assertMockServiceVerifiedWithinTimeout(firstService);
3438f2698621f5090db1dea691059bd0ebd79fb7f14Ted Kremenek        assertMockServiceVerifiedWithinTimeout(secondService);
3448f2698621f5090db1dea691059bd0ebd79fb7f14Ted Kremenek    }
3458f2698621f5090db1dea691059bd0ebd79fb7f14Ted Kremenek
3461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    @LargeTest
347f0171732efb4647772ad2a45c0f31978b0e34f71Benjamin Kramer    public void testSendAccessibilityEvent_TwoServices_MatchingPackageAndEventType()
348f0171732efb4647772ad2a45c0f31978b0e34f71Benjamin Kramer            throws Exception {
349f0171732efb4647772ad2a45c0f31978b0e34f71Benjamin Kramer        // set the accessibility setting value
3508c036c7f77d69f96df49219ed0bdbade200d52ebTed Kremenek        ensureAccessibilityEnabled(mContext, true);
3518c036c7f77d69f96df49219ed0bdbade200d52ebTed Kremenek
3521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        // enable the mock accessibility services
353c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek        ensureOnlyMockServicesEnabled(mContext, MyFirstMockAccessibilityService.sComponentName,
354404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis                MySecondMockAccessibilityService.sComponentName);
355404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis
356404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis        // configure the first mock service
357404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis        MockAccessibilityService firstService = MyFirstMockAccessibilityService.sInstance;
358404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis        firstService.setServiceInfo(MockAccessibilityService.createDefaultInfo());
359404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis
360404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis        // configure the second mock service
361c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek        MockAccessibilityService secondService = MySecondMockAccessibilityService.sInstance;
3628966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek        secondService.setServiceInfo(MockAccessibilityService.createDefaultInfo());
363cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
364c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek        // wait for the binder calls to #setService to complete
365d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis        Thread.sleep(TIMEOUT_BINDER_CALL);
3662dabd4372c50019fa00aae223ce634e0e754a3f2Ted Kremenek
3671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        // create and populate an event to be sent
368d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis        AccessibilityEvent sentEvent = AccessibilityEvent.obtain();
369c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek        fullyPopulateDefaultAccessibilityEvent(sentEvent);
3701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
371c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek        // set expectations for the first mock service
3721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        firstService.expectEvent(sentEvent);
373cfdf9b4edf1172728be97d1ae2d95171975f812bTed Kremenek        firstService.replay();
374cfdf9b4edf1172728be97d1ae2d95171975f812bTed Kremenek
375d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis        // set expectations for the second mock service
376c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek        secondService.replay();
377cfdf9b4edf1172728be97d1ae2d95171975f812bTed Kremenek
378cfdf9b4edf1172728be97d1ae2d95171975f812bTed Kremenek        // send the event
37938b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu        mManagerService.sendAccessibilityEvent(sentEvent);
3801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
381cfdf9b4edf1172728be97d1ae2d95171975f812bTed Kremenek        // verify if all expected methods have been called
382cfdf9b4edf1172728be97d1ae2d95171975f812bTed Kremenek        assertMockServiceVerifiedWithinTimeout(firstService);
38338b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu        assertMockServiceVerifiedWithinTimeout(secondService);
3841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    }
38540406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek
38640406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek    @LargeTest
387c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek    public void testSendAccessibilityEvent_TwoServices_MatchingPackageAndEventType_OneDefault()
3882dabd4372c50019fa00aae223ce634e0e754a3f2Ted Kremenek            throws Exception {
389c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek        // set the accessibility setting value
390c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek        ensureAccessibilityEnabled(mContext, true);
3911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3922dabd4372c50019fa00aae223ce634e0e754a3f2Ted Kremenek        // enable the mock accessibility services
393c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek        ensureOnlyMockServicesEnabled(mContext, MyFirstMockAccessibilityService.sComponentName,
394c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek                MySecondMockAccessibilityService.sComponentName);
3951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
396cfdf9b4edf1172728be97d1ae2d95171975f812bTed Kremenek        // configure the first mock service
397c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek        MockAccessibilityService firstService = MyFirstMockAccessibilityService.sInstance;
398c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek        AccessibilityServiceInfo firstInfo = MyFirstMockAccessibilityService.createDefaultInfo();
399c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek        firstInfo.flags = AccessibilityServiceInfo.DEFAULT;
40061f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek        firstService.setServiceInfo(firstInfo);
4011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4028966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek        // configure the second mock service
4038966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek        MockAccessibilityService secondService = MySecondMockAccessibilityService.sInstance;
4046493b8153a56cbff9f89c1a53f04b6af424b383aTed Kremenek        secondService.setServiceInfo(MySecondMockAccessibilityService.createDefaultInfo());
4056493b8153a56cbff9f89c1a53f04b6af424b383aTed Kremenek
4066493b8153a56cbff9f89c1a53f04b6af424b383aTed Kremenek        // wait for the binder calls to #setService to complete
4076493b8153a56cbff9f89c1a53f04b6af424b383aTed Kremenek        Thread.sleep(TIMEOUT_BINDER_CALL);
4081b431023814196f87515a540ebcb9e9f1a9176a1Ted Kremenek
4098966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek        // create and populate an event to be sent
4103baf672378f105602d2b12f03f00277ae1936fe9Ted Kremenek        AccessibilityEvent sentEvent = AccessibilityEvent.obtain();
4118966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek        fullyPopulateDefaultAccessibilityEvent(sentEvent);
4121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4131b431023814196f87515a540ebcb9e9f1a9176a1Ted Kremenek        // set expectations for the first mock service
4141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        firstService.replay();
4156493b8153a56cbff9f89c1a53f04b6af424b383aTed Kremenek
4168966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek        // set expectations for the second mock service
4171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        secondService.expectEvent(sentEvent);
4181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        secondService.replay();
4191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        // send the event
42138b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu        mManagerService.sendAccessibilityEvent(sentEvent);
4221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4238966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek        // verify if all expected methods have been called
4248966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek        assertMockServiceVerifiedWithinTimeout(firstService);
4258966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek        assertMockServiceVerifiedWithinTimeout(secondService);
4268966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek    }
4271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4288966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek    @LargeTest
4298966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek    public void testSendAccessibilityEvent_TwoServices_MatchingPackageAndEventType_TwoDefault()
4308966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek            throws Exception {
4318966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek        // set the accessibility setting value
4321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        ensureAccessibilityEnabled(mContext, true);
4338966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek
4348966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek        // enable the mock accessibility services
4358966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek        ensureOnlyMockServicesEnabled(mContext, MyFirstMockAccessibilityService.sComponentName,
4361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                MySecondMockAccessibilityService.sComponentName);
437c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek
438c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek        // configure the first mock service
439dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek        MockAccessibilityService firstService = MyFirstMockAccessibilityService.sInstance;
4401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        AccessibilityServiceInfo firstInfo = MyFirstMockAccessibilityService.createDefaultInfo();
4418966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek        firstInfo.flags = AccessibilityServiceInfo.DEFAULT;
4428966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek        firstService.setServiceInfo(firstInfo);
4438966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek
4441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        // configure the second mock service
4458966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek        MockAccessibilityService secondService = MySecondMockAccessibilityService.sInstance;
4468966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek        AccessibilityServiceInfo secondInfo = MyFirstMockAccessibilityService.createDefaultInfo();
4478966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek        secondInfo.flags = AccessibilityServiceInfo.DEFAULT;
4481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        secondService.setServiceInfo(firstInfo);
4491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4508966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek        // wait for the binder calls to #setService to complete
451e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek        Thread.sleep(TIMEOUT_BINDER_CALL);
452e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek
453e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek        // create and populate an event to be sent
454e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek        AccessibilityEvent sentEvent = AccessibilityEvent.obtain();
455e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek        fullyPopulateDefaultAccessibilityEvent(sentEvent);
456f0171732efb4647772ad2a45c0f31978b0e34f71Benjamin Kramer
457cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek        // set expectations for the first mock service
4581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        firstService.expectEvent(sentEvent);
459e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek        firstService.replay();
4601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
461cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek        // set expectations for the second mock service
462cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek        secondService.replay();
4631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4648b9317186fd5243938128a0b0e0494498d78ab8cTed Kremenek        // send the event
4651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        mManagerService.sendAccessibilityEvent(sentEvent);
466e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek
467e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek        // verify if all expected methods have been called
468e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek        assertMockServiceVerifiedWithinTimeout(firstService);
469e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek        assertMockServiceVerifiedWithinTimeout(secondService);
4701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    }
4715350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek
4725350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek    @LargeTest
4731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    public void testInterrupt() throws Exception {
4745350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek        // set the accessibility setting value
4751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        ensureAccessibilityEnabled(mContext, true);
476c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu
477c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu        // enable the mock accessibility services
478c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu        ensureOnlyMockServicesEnabled(mContext, MyFirstMockAccessibilityService.sComponentName,
479c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu                MySecondMockAccessibilityService.sComponentName);
4805350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek
481592362b46ad69db0db0988e7f9d8cbe647510bddTed Kremenek        // configure the first mock service
482c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu        MockAccessibilityService firstService = MyFirstMockAccessibilityService.sInstance;
4835350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek        firstService.setServiceInfo(MockAccessibilityService.createDefaultInfo());
48494fd0b8c88db9b1cd99457d3cd8cd333341dd39cTed Kremenek
48594fd0b8c88db9b1cd99457d3cd8cd333341dd39cTed Kremenek        // configure the second mock service
48694fd0b8c88db9b1cd99457d3cd8cd333341dd39cTed Kremenek        MockAccessibilityService secondService = MySecondMockAccessibilityService.sInstance;
487ff7f736211070be873df0a345295fd1453ee7c50Ted Kremenek        secondService.setServiceInfo(MockAccessibilityService.createDefaultInfo());
48894fd0b8c88db9b1cd99457d3cd8cd333341dd39cTed Kremenek
4892bbbe50dbaa0bf231c16333b335304655deeb26bTom Care        // wait for the binder calls to #setService to complete
4902bbbe50dbaa0bf231c16333b335304655deeb26bTom Care        Thread.sleep(TIMEOUT_BINDER_CALL);
4912bbbe50dbaa0bf231c16333b335304655deeb26bTom Care
4925350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek        // set expectations for the first mock service
4931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        firstService.expectInterrupt();
4945350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek        firstService.replay();
495e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek
4965a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis        // set expectations for the second mock service
4975a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis        secondService.expectInterrupt();
49861f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek        secondService.replay();
49961f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek
50061f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek        // call the method under test
501        mManagerService.interrupt();
502
503        // verify if all expected methods have been called
504        assertMockServiceVerifiedWithinTimeout(firstService);
505        assertMockServiceVerifiedWithinTimeout(secondService);
506    }
507
508    /**
509     * Fully populates the {@link AccessibilityEvent} to marshal.
510     *
511     * @param sentEvent The event to populate.
512     */
513    private void fullyPopulateDefaultAccessibilityEvent(AccessibilityEvent sentEvent) {
514        sentEvent.setAddedCount(1);
515        sentEvent.setBeforeText("BeforeText");
516        sentEvent.setChecked(true);
517        sentEvent.setClassName("foo.bar.baz.Class");
518        sentEvent.setContentDescription("ContentDescription");
519        sentEvent.setCurrentItemIndex(1);
520        sentEvent.setEnabled(true);
521        sentEvent.setEventType(AccessibilityEvent.TYPE_VIEW_CLICKED);
522        sentEvent.setEventTime(1000);
523        sentEvent.setFromIndex(1);
524        sentEvent.setFullScreen(true);
525        sentEvent.setItemCount(1);
526        sentEvent.setPackageName("foo.bar.baz");
527        sentEvent.setParcelableData(Message.obtain(null, 1, null));
528        sentEvent.setPassword(true);
529        sentEvent.setRemovedCount(1);
530    }
531
532    /**
533     * This class is a mock {@link IAccessibilityManagerClient}.
534     */
535    public class MyMockAccessibilityManagerClient extends IAccessibilityManagerClient.Stub {
536        boolean mIsEnabled;
537
538        public void setEnabled(boolean enabled) {
539            mIsEnabled = enabled;
540        }
541    }
542
543    /**
544     * Ensures accessibility is in a given state by writing the state to the
545     * settings and waiting until the accessibility manager service pick it up.
546     *
547     * @param context A context handle to access the settings.
548     * @param enabled The accessibility state to write to the settings.
549     * @throws Exception If any error occurs.
550     */
551    private void ensureAccessibilityEnabled(Context context, boolean enabled) throws Exception {
552        boolean isEnabled = (Settings.Secure.getInt(context.getContentResolver(),
553                Settings.Secure.ACCESSIBILITY_ENABLED, 0) == 1 ? true : false);
554
555        if (isEnabled == enabled) {
556            return;
557        }
558
559        Settings.Secure.putInt(context.getContentResolver(), Settings.Secure.ACCESSIBILITY_ENABLED,
560                enabled ? 1 : 0);
561
562        // wait the accessibility manager service to pick the change up
563        Thread.sleep(TIMEOUT_BINDER_CALL);
564    }
565
566    /**
567     * Ensures the only {@link MockAccessibilityService}s with given component
568     * names are enabled by writing to the system settings and waiting until the
569     * accessibility manager service picks that up.
570     *
571     * @param context A context handle to access the settings.
572     * @param componentNames The string representation of the
573     *            {@link ComponentName}s to enable.
574     * @throws Exception Exception If any error occurs.
575     */
576    private void ensureOnlyMockServicesEnabled(Context context, String... componentNames)
577            throws Exception {
578        String enabledServices = Settings.Secure.getString(context.getContentResolver(),
579                Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
580
581        StringBuilder servicesToEnable = new StringBuilder();
582        for (String componentName : componentNames) {
583            servicesToEnable.append(componentName).append(":");
584        }
585
586        if (servicesToEnable.equals(enabledServices)) {
587            return;
588        }
589
590        Settings.Secure.putString(context.getContentResolver(),
591                Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, servicesToEnable.toString());
592
593        // wait the system to perform asynchronous processing
594        Thread.sleep(TIMEOUT_BINDER_CALL);
595    }
596
597    /**
598     * Asserts the the mock accessibility service has been successfully verified
599     * (which is it has received the expected method calls with expected
600     * arguments) within the {@link #TIMEOUT_BINDER_CALL}. The verified state is
601     * checked by polling upon small intervals.
602     *
603     * @param service The service to verify.
604     * @throws Exception If the verification has failed with exception after the
605     *             {@link #TIMEOUT_BINDER_CALL}.
606     */
607    private void assertMockServiceVerifiedWithinTimeout(MockAccessibilityService service)
608            throws Exception {
609        Exception lastVerifyException = null;
610        long beginTime = SystemClock.uptimeMillis();
611        long pollTmeout = TIMEOUT_BINDER_CALL / 5;
612
613        // poll until the timeout has elapsed
614        while (SystemClock.uptimeMillis() - beginTime < TIMEOUT_BINDER_CALL) {
615            // sleep first since immediate call will always fail
616            try {
617                Thread.sleep(pollTmeout);
618            } catch (InterruptedException ie) {
619                /* ignore */
620            }
621            // poll for verification and if this fails save the exception and
622            // keep polling
623            try {
624                service.verify();
625                // reset so it does not accept more events
626                service.reset();
627                return;
628            } catch (Exception e) {
629                lastVerifyException = e;
630            }
631        }
632
633        // reset, we have already failed
634        service.reset();
635
636        // always not null
637        throw lastVerifyException;
638    }
639
640    /**
641     * This class is the first mock {@link AccessibilityService}.
642     */
643    public static class MyFirstMockAccessibilityService extends MockAccessibilityService {
644
645        /**
646         * The service {@link ComponentName} flattened as a string.
647         */
648        static final String sComponentName = new ComponentName(
649                sPackageName,
650                MyFirstMockAccessibilityService.class.getName()
651                ).flattenToShortString();
652
653        /**
654         * Handle to the service instance.
655         */
656        static MyFirstMockAccessibilityService sInstance;
657
658        /**
659         * Creates a new instance.
660         */
661        public MyFirstMockAccessibilityService() {
662            sInstance = this;
663        }
664    }
665
666    /**
667     * This class is the first mock {@link AccessibilityService}.
668     */
669    public static class MySecondMockAccessibilityService extends MockAccessibilityService {
670
671        /**
672         * The service {@link ComponentName} flattened as a string.
673         */
674        static final String sComponentName = new ComponentName(
675                sPackageName,
676                MySecondMockAccessibilityService.class.getName()
677                ).flattenToShortString();
678
679        /**
680         * Handle to the service instance.
681         */
682        static MySecondMockAccessibilityService sInstance;
683
684        /**
685         * Creates a new instance.
686         */
687        public MySecondMockAccessibilityService() {
688            sInstance = this;
689        }
690    }
691}
692