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.content.pm.ServiceInfo;
     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())).andReturn(
     74                 AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED);
     75         expect(mockServiceInterface.getInstalledAccessibilityServiceList()).andReturn(
     76                 expectedServices);
     77         replay(mockServiceInterface);
     78 
     79         // invoke the method under test
     80         AccessibilityManager manager = new AccessibilityManager(mContext, mockServiceInterface);
     81         List<AccessibilityServiceInfo> receivedServices =
     82             manager.getInstalledAccessibilityServiceList();
     83 
     84         // check expected result (list equals() compares it contents as well)
     85         assertEquals("All expected services must be returned", receivedServices, expectedServices);
     86 
     87         // verify the mock service was properly called
     88         verify(mockServiceInterface);
     89     }
     90 
     91     @MediumTest
     92     public void testInterrupt() throws Exception {
     93         // configure the mock service behavior
     94         IAccessibilityManager mockServiceInterface = mMockServiceInterface;
     95         expect(mockServiceInterface.addClient(anyIAccessibilityManagerClient())).andReturn(
     96                 AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED);
     97         mockServiceInterface.interrupt();
     98         replay(mockServiceInterface);
     99 
    100         // invoke the method under test
    101         AccessibilityManager manager = new AccessibilityManager(mContext, mockServiceInterface);
    102         manager.interrupt();
    103 
    104         // verify the mock service was properly called
    105         verify(mockServiceInterface);
    106     }
    107 
    108     @LargeTest
    109     public void testIsEnabled() throws Exception {
    110         // configure the mock service behavior
    111         IAccessibilityManager mockServiceInterface = mMockServiceInterface;
    112         expect(mockServiceInterface.addClient(anyIAccessibilityManagerClient())).andReturn(
    113                 AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED);
    114         replay(mockServiceInterface);
    115 
    116         // invoke the method under test
    117         AccessibilityManager manager = new AccessibilityManager(mContext, mockServiceInterface);
    118         boolean isEnabledServiceEnabled = manager.isEnabled();
    119 
    120         // check expected result
    121         assertTrue("Must be enabled since the mock service is enabled", isEnabledServiceEnabled);
    122 
    123         // disable accessibility
    124         manager.getClient().setState(0);
    125 
    126         // wait for the asynchronous IBinder call to complete
    127         Thread.sleep(TIMEOUT_BINDER_CALL);
    128 
    129         // invoke the method under test
    130         boolean isEnabledServcieDisabled = manager.isEnabled();
    131 
    132         // check expected result
    133         assertFalse("Must be disabled since the mock service is disabled",
    134                 isEnabledServcieDisabled);
    135 
    136         // verify the mock service was properly called
    137         verify(mockServiceInterface);
    138     }
    139 
    140     @MediumTest
    141     public void testSendAccessibilityEvent_AccessibilityEnabled() throws Exception {
    142         // create an event to be dispatched
    143         AccessibilityEvent sentEvent = AccessibilityEvent.obtain();
    144 
    145         // configure the mock service behavior
    146         IAccessibilityManager mockServiceInterface = mMockServiceInterface;
    147         expect(mockServiceInterface.addClient(anyIAccessibilityManagerClient())).andReturn(
    148                 AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED);
    149         expect(mockServiceInterface.sendAccessibilityEvent(eqAccessibilityEvent(sentEvent)))
    150                 .andReturn(true);
    151         expect(mockServiceInterface.sendAccessibilityEvent(eqAccessibilityEvent(sentEvent)))
    152                 .andReturn(false);
    153         replay(mockServiceInterface);
    154 
    155         // invoke the method under test (manager and service in different processes)
    156         AccessibilityManager manager = new AccessibilityManager(mContext, mockServiceInterface);
    157         manager.sendAccessibilityEvent(sentEvent);
    158 
    159         // check expected result
    160         AccessibilityEvent nextEventDifferentProcesses = AccessibilityEvent.obtain();
    161         assertSame("The manager and the service are in different processes, so the event must be " +
    162                 "recycled", sentEvent, nextEventDifferentProcesses);
    163 
    164         // invoke the method under test (manager and service in the same process)
    165         manager.sendAccessibilityEvent(sentEvent);
    166 
    167         // check expected result
    168         AccessibilityEvent nextEventSameProcess = AccessibilityEvent.obtain();
    169         assertNotSame("The manager and the service are in the same process, so the event must not" +
    170                 "be recycled", sentEvent, nextEventSameProcess);
    171 
    172         // verify the mock service was properly called
    173         verify(mockServiceInterface);
    174     }
    175 
    176     @MediumTest
    177     public void testSendAccessibilityEvent_AccessibilityDisabled() throws Exception {
    178         // create an event to be dispatched
    179         AccessibilityEvent sentEvent = AccessibilityEvent.obtain();
    180 
    181         // configure the mock service behavior
    182         IAccessibilityManager mockServiceInterface = mMockServiceInterface;
    183         expect(mockServiceInterface.addClient(anyIAccessibilityManagerClient())).andReturn(0);
    184         replay(mockServiceInterface);
    185 
    186         // invoke the method under test (accessibility disabled)
    187         AccessibilityManager manager = new AccessibilityManager(mContext, mockServiceInterface);
    188         try {
    189             manager.sendAccessibilityEvent(sentEvent);
    190             fail("No accessibility events are sent if accessibility is disabled");
    191         } catch (IllegalStateException ise) {
    192             // check expected result
    193             assertEquals("Accessibility off. Did you forget to check that?", ise.getMessage());
    194         }
    195 
    196         // verify the mock service was properly called
    197         verify(mockServiceInterface);
    198     }
    199 
    200     /**
    201      * Determines if an {@link AccessibilityEvent} passed as a method argument
    202      * matches expectations.
    203      *
    204      * @param matched The event to check.
    205      * @return True if expectations are matched.
    206      */
    207     private static AccessibilityEvent eqAccessibilityEvent(AccessibilityEvent matched) {
    208         reportMatcher(new AccessibilityEventMather(matched));
    209         return null;
    210     }
    211 
    212     /**
    213      * Determines if an {@link IAccessibilityManagerClient} passed as a method argument
    214      * matches expectations which in this case are that any instance is accepted.
    215      *
    216      * @return <code>null</code>.
    217      */
    218     private static IAccessibilityManagerClient anyIAccessibilityManagerClient() {
    219         reportMatcher(new AnyIAccessibilityManagerClientMather());
    220         return null;
    221     }
    222 
    223     /**
    224      * Matcher for {@link AccessibilityEvent}s.
    225      */
    226     private static class AccessibilityEventMather implements IArgumentMatcher {
    227         private AccessibilityEvent mExpectedEvent;
    228 
    229         public AccessibilityEventMather(AccessibilityEvent expectedEvent) {
    230             mExpectedEvent = expectedEvent;
    231         }
    232 
    233         public boolean matches(Object matched) {
    234             if (!(matched instanceof AccessibilityEvent)) {
    235                 return false;
    236             }
    237             AccessibilityEvent receivedEvent = (AccessibilityEvent) matched;
    238             return mExpectedEvent.getEventType() == receivedEvent.getEventType();
    239         }
    240 
    241         public void appendTo(StringBuffer buffer) {
    242             buffer.append("sendAccessibilityEvent()");
    243             buffer.append(" with event type \"");
    244             buffer.append(mExpectedEvent.getEventType());
    245             buffer.append("\"");
    246         }
    247     }
    248 
    249     /**
    250      * Matcher for {@link IAccessibilityManagerClient}s.
    251      */
    252     private static class AnyIAccessibilityManagerClientMather implements IArgumentMatcher {
    253         public boolean matches(Object matched) {
    254             if (!(matched instanceof IAccessibilityManagerClient)) {
    255                 return false;
    256             }
    257             return true;
    258         }
    259 
    260         public void appendTo(StringBuffer buffer) {
    261             buffer.append("addClient() with any IAccessibilityManagerClient");
    262         }
    263     }
    264 }
    265