1 /*
2  ** Copyright 2017, 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.accessibility;
18 
19 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
20 
21 import static org.junit.Assert.assertEquals;
22 import static org.junit.Assert.assertFalse;
23 import static org.junit.Assert.assertTrue;
24 import static org.mockito.ArgumentMatchers.anyInt;
25 import static org.mockito.Mockito.mock;
26 import static org.mockito.Mockito.verify;
27 import static org.mockito.Mockito.when;
28 
29 import android.accessibilityservice.AccessibilityServiceInfo;
30 import android.accessibilityservice.AccessibilityTrace;
31 import android.accessibilityservice.IAccessibilityServiceClient;
32 import android.app.UiAutomation;
33 import android.content.Context;
34 import android.content.pm.ApplicationInfo;
35 import android.content.pm.ResolveInfo;
36 import android.content.pm.ServiceInfo;
37 import android.hardware.display.DisplayManager;
38 import android.os.IBinder;
39 import android.view.accessibility.AccessibilityEvent;
40 
41 import com.android.server.accessibility.test.MessageCapturingHandler;
42 import com.android.server.wm.WindowManagerInternal;
43 
44 import org.junit.After;
45 import org.junit.Before;
46 import org.junit.Test;
47 import org.mockito.ArgumentCaptor;
48 import org.mockito.Mock;
49 import org.mockito.MockitoAnnotations;
50 
51 /**
52  * Tests for UiAutomationManager
53  */
54 public class UiAutomationManagerTest {
55     static final int SERVICE_ID = 42;
56 
57     final UiAutomationManager mUiAutomationManager = new UiAutomationManager(new Object());
58 
59     MessageCapturingHandler mMessageCapturingHandler;
60 
61     @Mock Context mMockContext;
62     @Mock AccessibilityServiceInfo mMockServiceInfo;
63     @Mock ResolveInfo mMockResolveInfo;
64     @Mock AccessibilitySecurityPolicy mMockSecurityPolicy;
65     @Mock AccessibilityWindowManager mMockA11yWindowManager;
66     @Mock AbstractAccessibilityServiceConnection.SystemSupport mMockSystemSupport;
67     @Mock AccessibilityTrace mMockA11yTrace;
68     @Mock WindowManagerInternal mMockWindowManagerInternal;
69     @Mock SystemActionPerformer mMockSystemActionPerformer;
70     @Mock IBinder mMockOwner;
71     @Mock IAccessibilityServiceClient mMockAccessibilityServiceClient;
72     @Mock IBinder mMockServiceAsBinder;
73 
74     @Before
setup()75     public void setup() {
76         MockitoAnnotations.initMocks(this);
77 
78         when(mMockSystemSupport.getKeyEventDispatcher()).thenReturn(mock(KeyEventDispatcher.class));
79 
80         when(mMockServiceInfo.getResolveInfo()).thenReturn(mMockResolveInfo);
81         mMockResolveInfo.serviceInfo = mock(ServiceInfo.class);
82         mMockResolveInfo.serviceInfo.applicationInfo = mock(ApplicationInfo.class);
83 
84         when(mMockAccessibilityServiceClient.asBinder()).thenReturn(mMockServiceAsBinder);
85         when(mMockA11yTrace.isA11yTracingEnabled()).thenReturn(false);
86 
87         final Context context = getInstrumentation().getTargetContext();
88         when(mMockContext.getSystemService(Context.DISPLAY_SERVICE)).thenReturn(
89                 context.getSystemService(
90                         DisplayManager.class));
91 
92         mMessageCapturingHandler = new MessageCapturingHandler(null);
93     }
94 
95     @After
tearDown()96     public void tearDown() {
97         mMessageCapturingHandler.removeAllMessages();
98     }
99 
100 
101     @Test
isRunning_returnsTrueOnlyWhenRunning()102     public void isRunning_returnsTrueOnlyWhenRunning() {
103         assertFalse(mUiAutomationManager.isUiAutomationRunningLocked());
104         register(0);
105         assertTrue(mUiAutomationManager.isUiAutomationRunningLocked());
106         unregister();
107         assertFalse(mUiAutomationManager.isUiAutomationRunningLocked());
108     }
109 
110     @Test
suppressingAccessibilityServicesLocked_dependsOnFlags()111     public void suppressingAccessibilityServicesLocked_dependsOnFlags() {
112         assertFalse(mUiAutomationManager.suppressingAccessibilityServicesLocked());
113         register(0);
114         assertTrue(mUiAutomationManager.suppressingAccessibilityServicesLocked());
115         unregister();
116         assertFalse(mUiAutomationManager.suppressingAccessibilityServicesLocked());
117         register(UiAutomation.FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES);
118         assertFalse(mUiAutomationManager.suppressingAccessibilityServicesLocked());
119         unregister();
120         assertFalse(mUiAutomationManager.suppressingAccessibilityServicesLocked());
121     }
122 
123     @Test
isTouchExplorationEnabledLocked_dependsOnInfoFlags()124     public void isTouchExplorationEnabledLocked_dependsOnInfoFlags() {
125         assertFalse(mUiAutomationManager.isTouchExplorationEnabledLocked());
126         register(0);
127         assertFalse(mUiAutomationManager.isTouchExplorationEnabledLocked());
128         unregister();
129         mMockServiceInfo.flags = AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE;
130         register(0);
131         assertTrue(mUiAutomationManager.isTouchExplorationEnabledLocked());
132         unregister();
133         assertFalse(mUiAutomationManager.isTouchExplorationEnabledLocked());
134     }
135 
136     @Test
canRetrieveInteractiveWindowsLocked_dependsOnInfoFlags()137     public void canRetrieveInteractiveWindowsLocked_dependsOnInfoFlags() {
138         assertFalse(mUiAutomationManager.canRetrieveInteractiveWindowsLocked());
139         register(0);
140         assertFalse(mUiAutomationManager.canRetrieveInteractiveWindowsLocked());
141         unregister();
142         mMockServiceInfo.flags = AccessibilityServiceInfo.FLAG_RETRIEVE_INTERACTIVE_WINDOWS;
143         register(0);
144         assertTrue(mUiAutomationManager.canRetrieveInteractiveWindowsLocked());
145         unregister();
146         assertFalse(mUiAutomationManager.canRetrieveInteractiveWindowsLocked());
147     }
148 
149     @Test
getRequestedEventMaskLocked_dependsOnInfoEventTypes()150     public void getRequestedEventMaskLocked_dependsOnInfoEventTypes() {
151         assertEquals(0, mUiAutomationManager.getRequestedEventMaskLocked());
152         mMockServiceInfo.eventTypes = 0;
153         register(0);
154         assertEquals(mMockServiceInfo.eventTypes,
155                 mUiAutomationManager.getRequestedEventMaskLocked());
156         unregister();
157         mMockServiceInfo.eventTypes = AccessibilityEvent.TYPES_ALL_MASK;
158         register(0);
159         assertEquals(mMockServiceInfo.eventTypes,
160                 mUiAutomationManager.getRequestedEventMaskLocked());
161         unregister();
162         assertEquals(0, mUiAutomationManager.getRequestedEventMaskLocked());
163     }
164 
165     @Test
uiAutomationBinderDiesBeforeConnecting_notifiesSystem()166     public void uiAutomationBinderDiesBeforeConnecting_notifiesSystem() throws Exception {
167         register(0);
168         ArgumentCaptor<IBinder.DeathRecipient> captor = ArgumentCaptor.forClass(
169                 IBinder.DeathRecipient.class);
170         verify(mMockOwner).linkToDeath(captor.capture(), anyInt());
171         captor.getValue().binderDied();
172         mMessageCapturingHandler.sendAllMessages();
173         verify(mMockSystemSupport).onClientChangeLocked(false);
174     }
175 
176     @Test
uiAutomationWithDontUseAccessibilityFlagAfterUnregistering_notifiesSystem()177     public void uiAutomationWithDontUseAccessibilityFlagAfterUnregistering_notifiesSystem()
178             throws Exception {
179         register(UiAutomation.FLAG_DONT_USE_ACCESSIBILITY);
180         unregister();
181         verify(mMockSystemSupport).onClientChangeLocked(false);
182     }
183 
184     @Test
uiAutomationWithDontUseAccessibilityFlag_disableAccessibilityFunctions()185     public void uiAutomationWithDontUseAccessibilityFlag_disableAccessibilityFunctions()
186             throws Exception {
187         register(0);
188         assertTrue(mUiAutomationManager.isUiAutomationRunningLocked());
189         unregister();
190         assertFalse(mUiAutomationManager.isUiAutomationRunningLocked());
191         register(UiAutomation.FLAG_DONT_USE_ACCESSIBILITY);
192         assertTrue(mUiAutomationManager.isUiAutomationRunningLocked());
193         assertFalse(mUiAutomationManager.useAccessibility());
194         assertFalse(mUiAutomationManager.canRetrieveInteractiveWindowsLocked());
195         assertFalse(mUiAutomationManager.isTouchExplorationEnabledLocked());
196         assertEquals(0, mUiAutomationManager.getRelevantEventTypes());
197         assertEquals(0, mUiAutomationManager.getRequestedEventMaskLocked());
198     }
199 
register(int flags)200     private void register(int flags) {
201         mUiAutomationManager.registerUiTestAutomationServiceLocked(mMockOwner,
202                 mMockAccessibilityServiceClient, mMockContext, mMockServiceInfo, SERVICE_ID,
203                 mMessageCapturingHandler, mMockSecurityPolicy, mMockSystemSupport, mMockA11yTrace,
204                 mMockWindowManagerInternal, mMockSystemActionPerformer,
205                 mMockA11yWindowManager, flags);
206     }
207 
unregister()208     private void unregister() {
209         mUiAutomationManager.unregisterUiTestAutomationServiceLocked(
210                 mMockAccessibilityServiceClient);
211     }
212 }
213