| /* |
| * Copyright (C) 2010 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.server; |
| |
| import static org.easymock.EasyMock.createStrictMock; |
| import static org.easymock.EasyMock.expect; |
| import static org.easymock.EasyMock.replay; |
| import static org.easymock.EasyMock.reportMatcher; |
| import static org.easymock.EasyMock.reset; |
| import static org.easymock.EasyMock.verify; |
| |
| import org.easymock.IArgumentMatcher; |
| |
| import android.content.pm.ServiceInfo; |
| import android.test.AndroidTestCase; |
| import android.test.suitebuilder.annotation.LargeTest; |
| import android.test.suitebuilder.annotation.MediumTest; |
| import android.view.accessibility.AccessibilityEvent; |
| import android.view.accessibility.AccessibilityManager; |
| import android.view.accessibility.IAccessibilityManager; |
| import android.view.accessibility.IAccessibilityManagerClient; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| /** |
| * Tests for the AccessibilityManager which mocking the backing service. |
| */ |
| public class AccessibilityManagerTest extends AndroidTestCase { |
| |
| /** |
| * Timeout required for pending Binder calls or event processing to |
| * complete. |
| */ |
| public static final long TIMEOUT_BINDER_CALL = 50; |
| |
| /** |
| * The reusable mock {@link IAccessibilityManager}. |
| */ |
| private final IAccessibilityManager mMockServiceInterface = |
| createStrictMock(IAccessibilityManager.class); |
| |
| @Override |
| public void setUp() throws Exception { |
| reset(mMockServiceInterface); |
| } |
| |
| @MediumTest |
| public void testGetAccessibilityServiceList() throws Exception { |
| // create a list of installed accessibility services the mock service returns |
| List<ServiceInfo> expectedServices = new ArrayList<ServiceInfo>(); |
| ServiceInfo serviceInfo = new ServiceInfo(); |
| serviceInfo.name = "TestServiceInfoName"; |
| expectedServices.add(serviceInfo); |
| |
| // configure the mock service behavior |
| IAccessibilityManager mockServiceInterface = mMockServiceInterface; |
| expect(mockServiceInterface.addClient(anyIAccessibilityManagerClient())).andReturn(true); |
| expect(mockServiceInterface.getAccessibilityServiceList()).andReturn(expectedServices); |
| replay(mockServiceInterface); |
| |
| // invoke the method under test |
| AccessibilityManager manager = new AccessibilityManager(mContext, mockServiceInterface); |
| List<ServiceInfo> receivedServices = manager.getAccessibilityServiceList(); |
| |
| // check expected result (list equals() compares it contents as well) |
| assertEquals("All expected services must be returned", receivedServices, expectedServices); |
| |
| // verify the mock service was properly called |
| verify(mockServiceInterface); |
| } |
| |
| @MediumTest |
| public void testInterrupt() throws Exception { |
| // configure the mock service behavior |
| IAccessibilityManager mockServiceInterface = mMockServiceInterface; |
| expect(mockServiceInterface.addClient(anyIAccessibilityManagerClient())).andReturn(true); |
| mockServiceInterface.interrupt(); |
| replay(mockServiceInterface); |
| |
| // invoke the method under test |
| AccessibilityManager manager = new AccessibilityManager(mContext, mockServiceInterface); |
| manager.interrupt(); |
| |
| // verify the mock service was properly called |
| verify(mockServiceInterface); |
| } |
| |
| @LargeTest |
| public void testIsEnabled() throws Exception { |
| // configure the mock service behavior |
| IAccessibilityManager mockServiceInterface = mMockServiceInterface; |
| expect(mockServiceInterface.addClient(anyIAccessibilityManagerClient())).andReturn(true); |
| replay(mockServiceInterface); |
| |
| // invoke the method under test |
| AccessibilityManager manager = new AccessibilityManager(mContext, mockServiceInterface); |
| boolean isEnabledServiceEnabled = manager.isEnabled(); |
| |
| // check expected result |
| assertTrue("Must be enabled since the mock service is enabled", isEnabledServiceEnabled); |
| |
| // disable accessibility |
| manager.getClient().setEnabled(false); |
| |
| // wait for the asynchronous IBinder call to complete |
| Thread.sleep(TIMEOUT_BINDER_CALL); |
| |
| // invoke the method under test |
| boolean isEnabledServcieDisabled = manager.isEnabled(); |
| |
| // check expected result |
| assertFalse("Must be disabled since the mock service is disabled", |
| isEnabledServcieDisabled); |
| |
| // verify the mock service was properly called |
| verify(mockServiceInterface); |
| } |
| |
| @MediumTest |
| public void testSendAccessibilityEvent_AccessibilityEnabled() throws Exception { |
| // create an event to be dispatched |
| AccessibilityEvent sentEvent = AccessibilityEvent.obtain(); |
| |
| // configure the mock service behavior |
| IAccessibilityManager mockServiceInterface = mMockServiceInterface; |
| expect(mockServiceInterface.addClient(anyIAccessibilityManagerClient())).andReturn(true); |
| expect(mockServiceInterface.sendAccessibilityEvent(eqAccessibilityEvent(sentEvent))) |
| .andReturn(true); |
| expect(mockServiceInterface.sendAccessibilityEvent(eqAccessibilityEvent(sentEvent))) |
| .andReturn(false); |
| replay(mockServiceInterface); |
| |
| // invoke the method under test (manager and service in different processes) |
| AccessibilityManager manager = new AccessibilityManager(mContext, mockServiceInterface); |
| manager.sendAccessibilityEvent(sentEvent); |
| |
| // check expected result |
| AccessibilityEvent nextEventDifferentProcesses = AccessibilityEvent.obtain(); |
| assertSame("The manager and the service are in different processes, so the event must be " + |
| "recycled", sentEvent, nextEventDifferentProcesses); |
| |
| // invoke the method under test (manager and service in the same process) |
| manager.sendAccessibilityEvent(sentEvent); |
| |
| // check expected result |
| AccessibilityEvent nextEventSameProcess = AccessibilityEvent.obtain(); |
| assertNotSame("The manager and the service are in the same process, so the event must not" + |
| "be recycled", sentEvent, nextEventSameProcess); |
| |
| // verify the mock service was properly called |
| verify(mockServiceInterface); |
| } |
| |
| @MediumTest |
| public void testSendAccessibilityEvent_AccessibilityDisabled() throws Exception { |
| // create an event to be dispatched |
| AccessibilityEvent sentEvent = AccessibilityEvent.obtain(); |
| |
| // configure the mock service behavior |
| IAccessibilityManager mockServiceInterface = mMockServiceInterface; |
| expect(mockServiceInterface.addClient(anyIAccessibilityManagerClient())).andReturn(false); |
| replay(mockServiceInterface); |
| |
| // invoke the method under test (accessibility disabled) |
| AccessibilityManager manager = new AccessibilityManager(mContext, mockServiceInterface); |
| try { |
| manager.sendAccessibilityEvent(sentEvent); |
| fail("No accessibility events are sent if accessibility is disabled"); |
| } catch (IllegalStateException ise) { |
| // check expected result |
| assertEquals("Accessibility off. Did you forget to check that?", ise.getMessage()); |
| } |
| |
| // verify the mock service was properly called |
| verify(mockServiceInterface); |
| } |
| |
| /** |
| * Determines if an {@link AccessibilityEvent} passed as a method argument |
| * matches expectations. |
| * |
| * @param matched The event to check. |
| * @return True if expectations are matched. |
| */ |
| private static AccessibilityEvent eqAccessibilityEvent(AccessibilityEvent matched) { |
| reportMatcher(new AccessibilityEventMather(matched)); |
| return null; |
| } |
| |
| /** |
| * Determines if an {@link IAccessibilityManagerClient} passed as a method argument |
| * matches expectations which in this case are that any instance is accepted. |
| * |
| * @return <code>null</code>. |
| */ |
| private static IAccessibilityManagerClient anyIAccessibilityManagerClient() { |
| reportMatcher(new AnyIAccessibilityManagerClientMather()); |
| return null; |
| } |
| |
| /** |
| * Matcher for {@link AccessibilityEvent}s. |
| */ |
| private static class AccessibilityEventMather implements IArgumentMatcher { |
| private AccessibilityEvent mExpectedEvent; |
| |
| public AccessibilityEventMather(AccessibilityEvent expectedEvent) { |
| mExpectedEvent = expectedEvent; |
| } |
| |
| public boolean matches(Object matched) { |
| if (!(matched instanceof AccessibilityEvent)) { |
| return false; |
| } |
| AccessibilityEvent receivedEvent = (AccessibilityEvent) matched; |
| return mExpectedEvent.getEventType() == receivedEvent.getEventType(); |
| } |
| |
| public void appendTo(StringBuffer buffer) { |
| buffer.append("sendAccessibilityEvent()"); |
| buffer.append(" with event type \""); |
| buffer.append(mExpectedEvent.getEventType()); |
| buffer.append("\""); |
| } |
| } |
| |
| /** |
| * Matcher for {@link IAccessibilityManagerClient}s. |
| */ |
| private static class AnyIAccessibilityManagerClientMather implements IArgumentMatcher { |
| public boolean matches(Object matched) { |
| if (!(matched instanceof IAccessibilityManagerClient)) { |
| return false; |
| } |
| return true; |
| } |
| |
| public void appendTo(StringBuffer buffer) { |
| buffer.append("addClient() with any IAccessibilityManagerClient"); |
| } |
| } |
| } |