Home | History | Annotate | Download | only in server
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.server;
     18 
     19 import static org.easymock.EasyMock.createStrictMock;
     20 import static org.easymock.EasyMock.expect;
     21 import static org.easymock.EasyMock.replay;
     22 import static org.easymock.EasyMock.reportMatcher;
     23 import static org.easymock.EasyMock.reset;
     24 import static org.easymock.EasyMock.verify;
     25 
     26 import org.easymock.IArgumentMatcher;
     27 
     28 import android.accessibilityservice.AccessibilityServiceInfo;
     29 import android.os.UserHandle;
     30 import android.test.AndroidTestCase;
     31 import android.test.suitebuilder.annotation.LargeTest;
     32 import android.test.suitebuilder.annotation.MediumTest;
     33 import android.view.accessibility.AccessibilityEvent;
     34 import android.view.accessibility.AccessibilityManager;
     35 import android.view.accessibility.IAccessibilityManager;
     36 import android.view.accessibility.IAccessibilityManagerClient;
     37 
     38 import java.util.ArrayList;
     39 import java.util.List;
     40 
     41 /**
     42  * Tests for the AccessibilityManager which mocking the backing service.
     43  */
     44 public class AccessibilityManagerTest extends AndroidTestCase {
     45 
     46     /**
     47      * Timeout required for pending Binder calls or event processing to
     48      * complete.
     49      */
     50     public static final long TIMEOUT_BINDER_CALL = 50;
     51 
     52     /**
     53      * The reusable mock {@link IAccessibilityManager}.
     54      */
     55     private final IAccessibilityManager mMockServiceInterface =
     56         createStrictMock(IAccessibilityManager.class);
     57 
     58     @Override
     59     public void setUp() throws Exception {
     60         reset(mMockServiceInterface);
     61     }
     62 
     63     @MediumTest
     64     public void testGetAccessibilityServiceList() throws Exception {
     65         // create a list of installed accessibility services the mock service returns
     66         List<AccessibilityServiceInfo> expectedServices = new ArrayList<AccessibilityServiceInfo>();
     67         AccessibilityServiceInfo accessibilityServiceInfo = new AccessibilityServiceInfo();
     68         accessibilityServiceInfo.packageNames = new String[] { "foo.bar" };
     69         expectedServices.add(accessibilityServiceInfo);
     70 
     71         // configure the mock service behavior
     72         IAccessibilityManager mockServiceInterface = mMockServiceInterface;
     73         expect(mockServiceInterface.addClient(anyIAccessibilityManagerClient(),
     74                 UserHandle.USER_OWNER)).andReturn(
     75                 AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED);
     76         expect(mockServiceInterface.getInstalledAccessibilityServiceList(UserHandle.USER_OWNER))
     77                 .andReturn(expectedServices);
     78         replay(mockServiceInterface);
     79 
     80         // invoke the method under test
     81         AccessibilityManager manager = new AccessibilityManager(mContext, mockServiceInterface,
     82                 UserHandle.USER_OWNER);
     83         List<AccessibilityServiceInfo> receivedServices =
     84             manager.getInstalledAccessibilityServiceList();
     85 
     86         // check expected result (list equals() compares it contents as well)
     87         assertEquals("All expected services must be returned", receivedServices, expectedServices);
     88 
     89         // verify the mock service was properly called
     90         verify(mockServiceInterface);
     91     }
     92 
     93     @MediumTest
     94     public void testInterrupt() throws Exception {
     95         // configure the mock service behavior
     96         IAccessibilityManager mockServiceInterface = mMockServiceInterface;
     97         expect(mockServiceInterface.addClient(anyIAccessibilityManagerClient(),
     98                 UserHandle.USER_OWNER)).andReturn(
     99                         AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED);
    100         mockServiceInterface.interrupt(UserHandle.USER_OWNER);
    101         replay(mockServiceInterface);
    102 
    103         // invoke the method under test
    104         AccessibilityManager manager = new AccessibilityManager(mContext, mockServiceInterface,
    105                 UserHandle.USER_OWNER);
    106         manager.interrupt();
    107 
    108         // verify the mock service was properly called
    109         verify(mockServiceInterface);
    110     }
    111 
    112     @LargeTest
    113     public void testIsEnabled() throws Exception {
    114         // configure the mock service behavior
    115         IAccessibilityManager mockServiceInterface = mMockServiceInterface;
    116         expect(mockServiceInterface.addClient(anyIAccessibilityManagerClient(),
    117                 UserHandle.USER_OWNER)).andReturn(
    118                         AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED);
    119         replay(mockServiceInterface);
    120 
    121         // invoke the method under test
    122         AccessibilityManager manager = new AccessibilityManager(mContext, mockServiceInterface,
    123                 UserHandle.USER_OWNER);
    124         boolean isEnabledServiceEnabled = manager.isEnabled();
    125 
    126         // check expected result
    127         assertTrue("Must be enabled since the mock service is enabled", isEnabledServiceEnabled);
    128 
    129         // disable accessibility
    130         manager.getClient().setState(0);
    131 
    132         // wait for the asynchronous IBinder call to complete
    133         Thread.sleep(TIMEOUT_BINDER_CALL);
    134 
    135         // invoke the method under test
    136         boolean isEnabledServcieDisabled = manager.isEnabled();
    137 
    138         // check expected result
    139         assertFalse("Must be disabled since the mock service is disabled",
    140                 isEnabledServcieDisabled);
    141 
    142         // verify the mock service was properly called
    143         verify(mockServiceInterface);
    144     }
    145 
    146     @MediumTest
    147     public void testSendAccessibilityEvent_AccessibilityEnabled() throws Exception {
    148         // create an event to be dispatched
    149         AccessibilityEvent sentEvent = AccessibilityEvent.obtain();
    150 
    151         // configure the mock service behavior
    152         IAccessibilityManager mockServiceInterface = mMockServiceInterface;
    153         expect(mockServiceInterface.addClient(anyIAccessibilityManagerClient(),
    154                 UserHandle.USER_OWNER)).andReturn(
    155                         AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED);
    156         expect(mockServiceInterface.sendAccessibilityEvent(eqAccessibilityEvent(sentEvent),
    157                 UserHandle.USER_OWNER)).andReturn(true);
    158         expect(mockServiceInterface.sendAccessibilityEvent(eqAccessibilityEvent(sentEvent),
    159                 UserHandle.USER_OWNER)).andReturn(false);
    160         replay(mockServiceInterface);
    161 
    162         // invoke the method under test (manager and service in different processes)
    163         AccessibilityManager manager = new AccessibilityManager(mContext, mockServiceInterface,
    164                 UserHandle.USER_OWNER);
    165         manager.sendAccessibilityEvent(sentEvent);
    166 
    167         // check expected result
    168         AccessibilityEvent nextEventDifferentProcesses = AccessibilityEvent.obtain();
    169         assertSame("The manager and the service are in different processes, so the event must be " +
    170                 "recycled", sentEvent, nextEventDifferentProcesses);
    171 
    172         // invoke the method under test (manager and service in the same process)
    173         manager.sendAccessibilityEvent(sentEvent);
    174 
    175         // check expected result
    176         AccessibilityEvent nextEventSameProcess = AccessibilityEvent.obtain();
    177         assertNotSame("The manager and the service are in the same process, so the event must not" +
    178                 "be recycled", sentEvent, nextEventSameProcess);
    179 
    180         // verify the mock service was properly called
    181         verify(mockServiceInterface);
    182     }
    183 
    184     @MediumTest
    185     public void testSendAccessibilityEvent_AccessibilityDisabled() throws Exception {
    186         // create an event to be dispatched
    187         AccessibilityEvent sentEvent = AccessibilityEvent.obtain();
    188 
    189         // configure the mock service behavior
    190         IAccessibilityManager mockServiceInterface = mMockServiceInterface;
    191         expect(mockServiceInterface.addClient(anyIAccessibilityManagerClient(),
    192                 UserHandle.USER_OWNER)).andReturn(0);
    193         replay(mockServiceInterface);
    194 
    195         // invoke the method under test (accessibility disabled)
    196         AccessibilityManager manager = new AccessibilityManager(mContext, mockServiceInterface,
    197                 UserHandle.USER_OWNER);
    198         try {
    199             manager.sendAccessibilityEvent(sentEvent);
    200             fail("No accessibility events are sent if accessibility is disabled");
    201         } catch (IllegalStateException ise) {
    202             // check expected result
    203             assertEquals("Accessibility off. Did you forget to check that?", ise.getMessage());
    204         }
    205 
    206         // verify the mock service was properly called
    207         verify(mockServiceInterface);
    208     }
    209 
    210     /**
    211      * Determines if an {@link AccessibilityEvent} passed as a method argument
    212      * matches expectations.
    213      *
    214      * @param matched The event to check.
    215      * @return True if expectations are matched.
    216      */
    217     private static AccessibilityEvent eqAccessibilityEvent(AccessibilityEvent matched) {
    218         reportMatcher(new AccessibilityEventMather(matched));
    219         return null;
    220     }
    221 
    222     /**
    223      * Determines if an {@link IAccessibilityManagerClient} passed as a method argument
    224      * matches expectations which in this case are that any instance is accepted.
    225      *
    226      * @return <code>null</code>.
    227      */
    228     private static IAccessibilityManagerClient anyIAccessibilityManagerClient() {
    229         reportMatcher(new AnyIAccessibilityManagerClientMather());
    230         return null;
    231     }
    232 
    233     /**
    234      * Matcher for {@link AccessibilityEvent}s.
    235      */
    236     private static class AccessibilityEventMather implements IArgumentMatcher {
    237         private AccessibilityEvent mExpectedEvent;
    238 
    239         public AccessibilityEventMather(AccessibilityEvent expectedEvent) {
    240             mExpectedEvent = expectedEvent;
    241         }
    242 
    243         public boolean matches(Object matched) {
    244             if (!(matched instanceof AccessibilityEvent)) {
    245                 return false;
    246             }
    247             AccessibilityEvent receivedEvent = (AccessibilityEvent) matched;
    248             return mExpectedEvent.getEventType() == receivedEvent.getEventType();
    249         }
    250 
    251         public void appendTo(StringBuffer buffer) {
    252             buffer.append("sendAccessibilityEvent()");
    253             buffer.append(" with event type \"");
    254             buffer.append(mExpectedEvent.getEventType());
    255             buffer.append("\"");
    256         }
    257     }
    258 
    259     /**
    260      * Matcher for {@link IAccessibilityManagerClient}s.
    261      */
    262     private static class AnyIAccessibilityManagerClientMather implements IArgumentMatcher {
    263         public boolean matches(Object matched) {
    264             if (!(matched instanceof IAccessibilityManagerClient)) {
    265                 return false;
    266             }
    267             return true;
    268         }
    269 
    270         public void appendTo(StringBuffer buffer) {
    271             buffer.append("addClient() with any IAccessibilityManagerClient");
    272         }
    273     }
    274 }
    275