• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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 junit.framework.Assert.assertFalse;
20 import static junit.framework.TestCase.assertNull;
21 import static junit.framework.TestCase.assertTrue;
22 
23 import static org.hamcrest.Matchers.containsInAnyOrder;
24 import static org.hamcrest.Matchers.emptyArray;
25 import static org.hamcrest.Matchers.hasSize;
26 import static org.junit.Assert.assertEquals;
27 import static org.junit.Assert.assertThat;
28 import static org.mockito.AdditionalAnswers.returnsFirstArg;
29 import static org.mockito.ArgumentMatchers.any;
30 import static org.mockito.ArgumentMatchers.anyInt;
31 import static org.mockito.ArgumentMatchers.eq;
32 import static org.mockito.Mockito.doReturn;
33 import static org.mockito.Mockito.verify;
34 import static org.mockito.Mockito.when;
35 
36 import android.Manifest;
37 import android.accessibilityservice.AccessibilityServiceInfo;
38 import android.app.AppOpsManager;
39 import android.appwidget.AppWidgetManagerInternal;
40 import android.content.ComponentName;
41 import android.content.Context;
42 import android.content.pm.ApplicationInfo;
43 import android.content.pm.PackageManager;
44 import android.content.pm.ResolveInfo;
45 import android.content.pm.ServiceInfo;
46 import android.os.Process;
47 import android.os.UserHandle;
48 import android.os.UserManager;
49 import android.testing.DexmakerShareClassLoaderRule;
50 import android.util.ArraySet;
51 import android.view.accessibility.AccessibilityEvent;
52 import android.view.accessibility.AccessibilityWindowInfo;
53 
54 import com.android.server.LocalServices;
55 import com.android.server.wm.ActivityTaskManagerInternal;
56 
57 import org.junit.Before;
58 import org.junit.Rule;
59 import org.junit.Test;
60 import org.mockito.Mock;
61 import org.mockito.Mockito;
62 import org.mockito.MockitoAnnotations;
63 
64 import java.util.Arrays;
65 import java.util.List;
66 
67 /**
68  * Tests for the AccessibilitySecurityPolicy
69  */
70 public class AccessibilitySecurityPolicyTest {
71     private static final String PACKAGE_NAME = "com.android.server.accessibility";
72     private static final String PACKAGE_NAME2 = "com.android.server.accessibility2";
73     private static final int WINDOWID = 0x000a;
74     private static final int WINDOWID2 = 0x000b;
75     private static final int APP_UID = 10400;
76     private static final int APP_PID = 2000;
77     private static final int SYSTEM_PID = 558;
78 
79     private static final String PERMISSION = "test-permission";
80     private static final String FUNCTION = "test-function-name";
81 
82     private static final int[] ALWAYS_DISPATCH_EVENTS = {
83             AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED,
84             AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED,
85             AccessibilityEvent.TYPE_ANNOUNCEMENT,
86             AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_START,
87             AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_END,
88             AccessibilityEvent.TYPE_GESTURE_DETECTION_START,
89             AccessibilityEvent.TYPE_GESTURE_DETECTION_END,
90             AccessibilityEvent.TYPE_TOUCH_INTERACTION_START,
91             AccessibilityEvent.TYPE_TOUCH_INTERACTION_END,
92             AccessibilityEvent.TYPE_VIEW_HOVER_ENTER,
93             AccessibilityEvent.TYPE_VIEW_HOVER_EXIT,
94             AccessibilityEvent.TYPE_ASSIST_READING_CONTEXT,
95             AccessibilityEvent.TYPE_WINDOWS_CHANGED,
96     };
97     private static final int[] OTHER_EVENTS = {
98             AccessibilityEvent.TYPE_VIEW_CLICKED,
99             AccessibilityEvent.TYPE_VIEW_LONG_CLICKED,
100             AccessibilityEvent.TYPE_VIEW_SELECTED,
101             AccessibilityEvent.TYPE_VIEW_FOCUSED,
102             AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED,
103             AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED,
104             AccessibilityEvent.TYPE_VIEW_SCROLLED,
105             AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED,
106             AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED,
107             AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED,
108             AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY,
109             AccessibilityEvent.TYPE_VIEW_CONTEXT_CLICKED,
110     };
111 
112     private AccessibilitySecurityPolicy mA11ySecurityPolicy;
113 
114     // To mock package-private class
115     @Rule public final DexmakerShareClassLoaderRule mDexmakerShareClassLoaderRule =
116             new DexmakerShareClassLoaderRule();
117 
118     @Mock private Context mMockContext;
119     @Mock private PackageManager mMockPackageManager;
120     @Mock private UserManager mMockUserManager;
121     @Mock private AppOpsManager mMockAppOpsManager;
122     @Mock private AccessibilityServiceConnection mMockA11yServiceConnection;
123     @Mock private AccessibilityWindowManager mMockA11yWindowManager;
124     @Mock private AppWidgetManagerInternal mMockAppWidgetManager;
125     @Mock private AccessibilitySecurityPolicy.AccessibilityUserManager mMockA11yUserManager;
126     @Mock private ActivityTaskManagerInternal mMockActivityTaskManagerInternal;
127 
128     @Before
setUp()129     public void setUp() {
130         MockitoAnnotations.initMocks(this);
131         when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
132         when(mMockContext.getSystemService(Context.USER_SERVICE)).thenReturn(mMockUserManager);
133         when(mMockContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mMockAppOpsManager);
134 
135         LocalServices.removeServiceForTest(ActivityTaskManagerInternal.class);
136         LocalServices.addService(
137                 ActivityTaskManagerInternal.class, mMockActivityTaskManagerInternal);
138 
139         mA11ySecurityPolicy = new AccessibilitySecurityPolicy(mMockContext, mMockA11yUserManager);
140         mA11ySecurityPolicy.setAccessibilityWindowManager(mMockA11yWindowManager);
141         mA11ySecurityPolicy.setAppWidgetManager(mMockAppWidgetManager);
142 
143         when(mMockA11yWindowManager.resolveParentWindowIdLocked(anyInt())).then(returnsFirstArg());
144     }
145 
146     @Test
canDispatchAccessibilityEvent_alwaysDispatchEvents_returnTrue()147     public void canDispatchAccessibilityEvent_alwaysDispatchEvents_returnTrue() {
148         for (int i = 0; i < ALWAYS_DISPATCH_EVENTS.length; i++) {
149             final AccessibilityEvent event = AccessibilityEvent.obtain(ALWAYS_DISPATCH_EVENTS[i]);
150             assertTrue("Should dispatch [" + event + "]",
151                     mA11ySecurityPolicy.canDispatchAccessibilityEventLocked(
152                             UserHandle.USER_SYSTEM,
153                             event));
154         }
155     }
156 
157     @Test
canDispatchAccessibilityEvent_otherEvents_invalidWindowId_returnFalse()158     public void canDispatchAccessibilityEvent_otherEvents_invalidWindowId_returnFalse() {
159         final int invalidWindowId = WINDOWID;
160         for (int i = 0; i < OTHER_EVENTS.length; i++) {
161             final AccessibilityEvent event = AccessibilityEvent.obtain(OTHER_EVENTS[i]);
162             event.setWindowId(invalidWindowId);
163             assertFalse("Shouldn't dispatch [" + event + "]",
164                     mA11ySecurityPolicy.canDispatchAccessibilityEventLocked(
165                             UserHandle.USER_SYSTEM,
166                             event));
167         }
168     }
169 
170     @Test
canDispatchAccessibilityEvent_otherEvents_windowIdIsActive_returnTrue()171     public void canDispatchAccessibilityEvent_otherEvents_windowIdIsActive_returnTrue() {
172         when(mMockA11yWindowManager.getActiveWindowId(UserHandle.USER_SYSTEM))
173                 .thenReturn(WINDOWID);
174         for (int i = 0; i < OTHER_EVENTS.length; i++) {
175             final AccessibilityEvent event = AccessibilityEvent.obtain(OTHER_EVENTS[i]);
176             event.setWindowId(WINDOWID);
177             assertTrue("Should dispatch [" + event + "]",
178                     mA11ySecurityPolicy.canDispatchAccessibilityEventLocked(
179                             UserHandle.USER_SYSTEM,
180                             event));
181         }
182     }
183 
184     @Test
canDispatchAccessibilityEvent_otherEvents_windowIdExist_returnTrue()185     public void canDispatchAccessibilityEvent_otherEvents_windowIdExist_returnTrue() {
186         when(mMockA11yWindowManager.getActiveWindowId(UserHandle.USER_SYSTEM))
187                 .thenReturn(WINDOWID2);
188         when(mMockA11yWindowManager.findA11yWindowInfoByIdLocked(WINDOWID))
189                 .thenReturn(AccessibilityWindowInfo.obtain());
190         for (int i = 0; i < OTHER_EVENTS.length; i++) {
191             final AccessibilityEvent event = AccessibilityEvent.obtain(OTHER_EVENTS[i]);
192             event.setWindowId(WINDOWID);
193             assertTrue("Should dispatch [" + event + "]",
194                     mA11ySecurityPolicy.canDispatchAccessibilityEventLocked(
195                             UserHandle.USER_SYSTEM,
196                             event));
197         }
198     }
199 
200     @Test
resolveValidReportedPackage_nullPkgName_returnNull()201     public void resolveValidReportedPackage_nullPkgName_returnNull() {
202         assertNull(mA11ySecurityPolicy.resolveValidReportedPackageLocked(
203                 null, Process.SYSTEM_UID, UserHandle.USER_SYSTEM, SYSTEM_PID));
204     }
205 
206     @Test
resolveValidReportedPackage_uidIsSystem_returnPkgName()207     public void resolveValidReportedPackage_uidIsSystem_returnPkgName() {
208         assertEquals(mA11ySecurityPolicy.resolveValidReportedPackageLocked(
209                 PACKAGE_NAME, Process.SYSTEM_UID, UserHandle.USER_SYSTEM, SYSTEM_PID),
210                 PACKAGE_NAME);
211     }
212 
213     @Test
resolveValidReportedPackage_uidAndPkgNameMatched_returnPkgName()214     public void resolveValidReportedPackage_uidAndPkgNameMatched_returnPkgName()
215             throws PackageManager.NameNotFoundException {
216         when(mMockPackageManager.getPackageUidAsUser(PACKAGE_NAME, UserHandle.USER_SYSTEM))
217                 .thenReturn(APP_UID);
218 
219         assertEquals(mA11ySecurityPolicy.resolveValidReportedPackageLocked(
220                 PACKAGE_NAME, APP_UID, UserHandle.USER_SYSTEM, APP_PID),
221                 PACKAGE_NAME);
222     }
223 
224     @Test
resolveValidReportedPackage_uidIsWidgetHost_pkgNameIsAppWidget_returnPkgName()225     public void resolveValidReportedPackage_uidIsWidgetHost_pkgNameIsAppWidget_returnPkgName()
226             throws PackageManager.NameNotFoundException {
227         final int widgetHostUid = APP_UID;
228         final int widgetHostPid = APP_PID;
229         final String hostPackageName = PACKAGE_NAME;
230         final String widgetPackageName = PACKAGE_NAME2;
231         final ArraySet<String> widgetPackages = new ArraySet<>();
232         widgetPackages.add(widgetPackageName);
233 
234         when(mMockAppWidgetManager.getHostedWidgetPackages(widgetHostUid))
235                 .thenReturn(widgetPackages);
236         when(mMockPackageManager.getPackageUidAsUser(hostPackageName, UserHandle.USER_SYSTEM))
237                 .thenReturn(widgetHostUid);
238 
239         assertEquals(mA11ySecurityPolicy.resolveValidReportedPackageLocked(
240                 widgetPackageName, widgetHostUid, UserHandle.USER_SYSTEM, widgetHostPid),
241                 widgetPackageName);
242     }
243 
244     @Test
resolveValidReportedPackage_pkgNameIsInvalid_returnFirstCorrectPkgName()245     public void resolveValidReportedPackage_pkgNameIsInvalid_returnFirstCorrectPkgName()
246             throws PackageManager.NameNotFoundException {
247         final String invalidPackageName = "x";
248         final String[] uidPackages = {PACKAGE_NAME, PACKAGE_NAME2};
249         when(mMockPackageManager.getPackagesForUid(APP_UID))
250                 .thenReturn(uidPackages);
251         when(mMockPackageManager.getPackageUidAsUser(invalidPackageName, UserHandle.USER_SYSTEM))
252                 .thenThrow(PackageManager.NameNotFoundException.class);
253         when(mMockAppWidgetManager.getHostedWidgetPackages(APP_UID))
254                 .thenReturn(new ArraySet<>());
255         when(mMockContext.checkPermission(
256                 eq(Manifest.permission.ACT_AS_PACKAGE_FOR_ACCESSIBILITY), anyInt(), eq(APP_UID)))
257                 .thenReturn(PackageManager.PERMISSION_DENIED);
258 
259         assertEquals(PACKAGE_NAME, mA11ySecurityPolicy.resolveValidReportedPackageLocked(
260                 invalidPackageName, APP_UID, UserHandle.USER_SYSTEM, APP_PID));
261     }
262 
263     @Test
resolveValidReportedPackage_anotherPkgNameWithActAsPkgPermission_returnPkg()264     public void resolveValidReportedPackage_anotherPkgNameWithActAsPkgPermission_returnPkg()
265             throws PackageManager.NameNotFoundException {
266         final String wantedPackageName = PACKAGE_NAME2;
267         final int wantedUid = APP_UID + 1;
268         final String[] uidPackages = {PACKAGE_NAME};
269         when(mMockPackageManager.getPackagesForUid(APP_UID))
270                 .thenReturn(uidPackages);
271         when(mMockPackageManager.getPackageUidAsUser(wantedPackageName, UserHandle.USER_SYSTEM))
272                 .thenReturn(wantedUid);
273         when(mMockAppWidgetManager.getHostedWidgetPackages(APP_UID))
274                 .thenReturn(new ArraySet<>());
275         when(mMockContext.checkPermission(
276                 eq(Manifest.permission.ACT_AS_PACKAGE_FOR_ACCESSIBILITY), anyInt(), eq(APP_UID)))
277                 .thenReturn(PackageManager.PERMISSION_GRANTED);
278 
279         assertEquals(wantedPackageName, mA11ySecurityPolicy.resolveValidReportedPackageLocked(
280                 wantedPackageName, APP_UID, UserHandle.USER_SYSTEM, APP_PID));
281     }
282 
283     @Test
resolveValidReportedPackage_anotherPkgNameWithoutActAsPkgPermission_returnUidPkg()284     public void resolveValidReportedPackage_anotherPkgNameWithoutActAsPkgPermission_returnUidPkg()
285             throws PackageManager.NameNotFoundException {
286         final String wantedPackageName = PACKAGE_NAME2;
287         final int wantedUid = APP_UID + 1;
288         final String[] uidPackages = {PACKAGE_NAME};
289         when(mMockPackageManager.getPackagesForUid(APP_UID))
290                 .thenReturn(uidPackages);
291         when(mMockPackageManager.getPackageUidAsUser(wantedPackageName, UserHandle.USER_SYSTEM))
292                 .thenReturn(wantedUid);
293         when(mMockAppWidgetManager.getHostedWidgetPackages(APP_UID))
294                 .thenReturn(new ArraySet<>());
295         when(mMockContext.checkPermission(
296                 eq(Manifest.permission.ACT_AS_PACKAGE_FOR_ACCESSIBILITY), anyInt(), eq(APP_UID)))
297                 .thenReturn(PackageManager.PERMISSION_DENIED);
298 
299         assertEquals(PACKAGE_NAME, mA11ySecurityPolicy.resolveValidReportedPackageLocked(
300                 wantedPackageName, APP_UID, UserHandle.USER_SYSTEM, APP_PID));
301     }
302 
303     @Test
computeValidReportedPackages_uidIsSystem_returnEmptyArray()304     public void computeValidReportedPackages_uidIsSystem_returnEmptyArray() {
305         assertThat(mA11ySecurityPolicy.computeValidReportedPackages(
306                 PACKAGE_NAME, Process.SYSTEM_UID), emptyArray());
307     }
308 
309     @Test
computeValidReportedPackages_uidIsAppWidgetHost_returnTargetAndWidgetName()310     public void computeValidReportedPackages_uidIsAppWidgetHost_returnTargetAndWidgetName() {
311         final int widgetHostUid = APP_UID;
312         final String targetPackageName =  PACKAGE_NAME;
313         final String widgetPackageName = PACKAGE_NAME2;
314         final ArraySet<String> widgetPackages = new ArraySet<>();
315         widgetPackages.add(widgetPackageName);
316         when(mMockAppWidgetManager.getHostedWidgetPackages(widgetHostUid))
317                 .thenReturn(widgetPackages);
318 
319         List<String> packages = Arrays.asList(mA11ySecurityPolicy.computeValidReportedPackages(
320                 targetPackageName, widgetHostUid));
321         assertThat(packages, hasSize(2));
322         assertThat(packages, containsInAnyOrder(targetPackageName, widgetPackageName));
323     }
324 
325     @Test
canGetAccessibilityNodeInfo_windowIdNotExist_returnFalse()326     public void canGetAccessibilityNodeInfo_windowIdNotExist_returnFalse() {
327         final int invalidWindowId = WINDOWID;
328         when(mMockA11yServiceConnection.getCapabilities())
329                 .thenReturn(AccessibilityServiceInfo.CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT);
330 
331         assertFalse(mA11ySecurityPolicy.canGetAccessibilityNodeInfoLocked(UserHandle.USER_SYSTEM,
332                 mMockA11yServiceConnection, invalidWindowId));
333     }
334 
335     @Test
canGetAccessibilityNodeInfo_hasCapAndWindowIsActive_returnTrue()336     public void canGetAccessibilityNodeInfo_hasCapAndWindowIsActive_returnTrue() {
337         when(mMockA11yServiceConnection.getCapabilities())
338                 .thenReturn(AccessibilityServiceInfo.CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT);
339         when(mMockA11yWindowManager.getActiveWindowId(UserHandle.USER_SYSTEM))
340                 .thenReturn(WINDOWID);
341 
342         assertTrue(mA11ySecurityPolicy.canGetAccessibilityNodeInfoLocked(UserHandle.USER_SYSTEM,
343                 mMockA11yServiceConnection, WINDOWID));
344     }
345 
346     @Test
canGetAccessibilityNodeInfo_hasCapAndWindowExist_returnTrue()347     public void canGetAccessibilityNodeInfo_hasCapAndWindowExist_returnTrue() {
348         when(mMockA11yServiceConnection.getCapabilities())
349                 .thenReturn(AccessibilityServiceInfo.CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT);
350         when(mMockA11yWindowManager.getActiveWindowId(UserHandle.USER_SYSTEM))
351                 .thenReturn(WINDOWID2);
352         when(mMockA11yWindowManager.findA11yWindowInfoByIdLocked(WINDOWID))
353                 .thenReturn(AccessibilityWindowInfo.obtain());
354 
355         assertTrue(mA11ySecurityPolicy.canGetAccessibilityNodeInfoLocked(UserHandle.USER_SYSTEM,
356                 mMockA11yServiceConnection, WINDOWID));
357     }
358 
359     @Test
canRetrieveWindows_retrieveWindowsFlagIsFalse_returnFalse()360     public void canRetrieveWindows_retrieveWindowsFlagIsFalse_returnFalse() {
361         when(mMockA11yServiceConnection.getCapabilities())
362                 .thenReturn(AccessibilityServiceInfo.CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT);
363 
364         assertFalse(mA11ySecurityPolicy.canRetrieveWindowsLocked(mMockA11yServiceConnection));
365     }
366 
367     @Test
canRetrieveWindows_hasCapabilityAndRetrieveWindowsFlag_returnTrue()368     public void canRetrieveWindows_hasCapabilityAndRetrieveWindowsFlag_returnTrue() {
369         when(mMockA11yServiceConnection.getCapabilities())
370                 .thenReturn(AccessibilityServiceInfo.CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT);
371         mMockA11yServiceConnection.mRetrieveInteractiveWindows = true;
372 
373         assertTrue(mA11ySecurityPolicy.canRetrieveWindowsLocked(mMockA11yServiceConnection));
374     }
375 
376     @Test
canRetrieveWindowContent_hasCapability_returnTrue()377     public void canRetrieveWindowContent_hasCapability_returnTrue() {
378         when(mMockA11yServiceConnection.getCapabilities())
379                 .thenReturn(AccessibilityServiceInfo.CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT);
380 
381         assertTrue(mA11ySecurityPolicy.canRetrieveWindowContentLocked(mMockA11yServiceConnection));
382     }
383 
384     @Test
canControlMagnification_hasCapability_returnTrue()385     public void canControlMagnification_hasCapability_returnTrue() {
386         when(mMockA11yServiceConnection.getCapabilities())
387                 .thenReturn(AccessibilityServiceInfo.CAPABILITY_CAN_CONTROL_MAGNIFICATION);
388 
389         assertTrue(mA11ySecurityPolicy.canControlMagnification(mMockA11yServiceConnection));
390     }
391 
392     @Test
canPerformGestures_hasCapability_returnTrue()393     public void canPerformGestures_hasCapability_returnTrue() {
394         assertFalse(mA11ySecurityPolicy.canPerformGestures(mMockA11yServiceConnection));
395         when(mMockA11yServiceConnection.getCapabilities())
396                 .thenReturn(AccessibilityServiceInfo.CAPABILITY_CAN_PERFORM_GESTURES);
397 
398         assertTrue(mA11ySecurityPolicy.canPerformGestures(mMockA11yServiceConnection));
399     }
400 
401     @Test
canCaptureFingerprintGestures_hasCapability_returnTrue()402     public void canCaptureFingerprintGestures_hasCapability_returnTrue() {
403         assertFalse(mA11ySecurityPolicy.canCaptureFingerprintGestures(mMockA11yServiceConnection));
404         when(mMockA11yServiceConnection.getCapabilities())
405                 .thenReturn(AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_FINGERPRINT_GESTURES);
406 
407         assertTrue(mA11ySecurityPolicy.canCaptureFingerprintGestures(mMockA11yServiceConnection));
408     }
409 
410     @Test
canTakeScreenshot_hasCapability_returnTrue()411     public void canTakeScreenshot_hasCapability_returnTrue() {
412         when(mMockA11yServiceConnection.getCapabilities())
413                 .thenReturn(AccessibilityServiceInfo.CAPABILITY_CAN_TAKE_SCREENSHOT);
414 
415         assertTrue(mA11ySecurityPolicy.canTakeScreenshotLocked(mMockA11yServiceConnection));
416     }
417 
418     @Test
resolveProfileParent_userIdIsCurrentUser_returnCurrentUser()419     public void resolveProfileParent_userIdIsCurrentUser_returnCurrentUser() {
420         final int currentUserId = 10;
421         final int userId = currentUserId;
422         when(mMockA11yUserManager.getCurrentUserIdLocked())
423                 .thenReturn(currentUserId);
424 
425         assertEquals(mA11ySecurityPolicy.resolveProfileParentLocked(userId),
426                 currentUserId);
427     }
428 
429     @Test
resolveProfileParent_userIdNotCurrentUser_shouldGetProfileParent()430     public void resolveProfileParent_userIdNotCurrentUser_shouldGetProfileParent() {
431         final int userId = 15;
432         final int currentUserId = 20;
433         when(mMockA11yUserManager.getCurrentUserIdLocked()).thenReturn(currentUserId);
434 
435         mA11ySecurityPolicy.resolveProfileParentLocked(userId);
436         verify(mMockUserManager).getProfileParent(userId);
437     }
438 
439     @Test
resolveCallingUserId_userIdIsCallingUser_shouldResolveProfileParent()440     public void resolveCallingUserId_userIdIsCallingUser_shouldResolveProfileParent() {
441         final AccessibilitySecurityPolicy spySecurityPolicy = Mockito.spy(mA11ySecurityPolicy);
442         final int callingUserId = UserHandle.getUserId(Process.myUid());
443         final int userId = callingUserId;
444 
445         spySecurityPolicy.resolveCallingUserIdEnforcingPermissionsLocked(userId);
446         verify(spySecurityPolicy).resolveProfileParentLocked(userId);
447     }
448 
449     @Test
resolveCallingUserId_callingParentIsCurrentUser_returnCurrentUser()450     public void resolveCallingUserId_callingParentIsCurrentUser_returnCurrentUser() {
451         final AccessibilitySecurityPolicy spySecurityPolicy = Mockito.spy(mA11ySecurityPolicy);
452         final int callingUserId = UserHandle.getUserId(Process.myUid());
453         final int callingParentId = 20;
454         final int currentUserId = callingParentId;
455         when(mMockA11yUserManager.getCurrentUserIdLocked())
456                 .thenReturn(currentUserId);
457         doReturn(callingParentId).when(spySecurityPolicy).resolveProfileParentLocked(
458                 callingUserId);
459 
460         assertEquals(spySecurityPolicy.resolveCallingUserIdEnforcingPermissionsLocked(
461                 UserHandle.USER_CURRENT_OR_SELF), currentUserId);
462 
463     }
464 
465     @Test(expected = SecurityException.class)
resolveCallingUserId_callingParentNotCurrentUserAndNoPerm_shouldException()466     public void resolveCallingUserId_callingParentNotCurrentUserAndNoPerm_shouldException() {
467         final AccessibilitySecurityPolicy spySecurityPolicy = Mockito.spy(mA11ySecurityPolicy);
468         final int callingUserId = UserHandle.getUserId(Process.myUid());
469         final int callingParentId = 20;
470         final int currentUserId = 30;
471         when(mMockA11yUserManager.getCurrentUserIdLocked())
472                 .thenReturn(currentUserId);
473         doReturn(callingParentId).when(spySecurityPolicy).resolveProfileParentLocked(
474                 callingUserId);
475         when(mMockContext.checkCallingPermission(any()))
476                 .thenReturn(PackageManager.PERMISSION_DENIED);
477 
478         spySecurityPolicy.resolveCallingUserIdEnforcingPermissionsLocked(
479                 UserHandle.USER_CURRENT_OR_SELF);
480     }
481 
482     @Test
resolveCallingUserId_anotherUserIdWithCrossUserPermission_returnUserId()483     public void resolveCallingUserId_anotherUserIdWithCrossUserPermission_returnUserId() {
484         final AccessibilitySecurityPolicy spySecurityPolicy = Mockito.spy(mA11ySecurityPolicy);
485         final int callingUserId = UserHandle.getUserId(Process.myUid());
486         final int callingParentId = 20;
487         final int currentUserId = 30;
488         final int wantedUserId = 40;
489         when(mMockA11yUserManager.getCurrentUserIdLocked())
490                 .thenReturn(currentUserId);
491         doReturn(callingParentId).when(spySecurityPolicy).resolveProfileParentLocked(
492                 callingUserId);
493         when(mMockContext.checkCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS))
494                 .thenReturn(PackageManager.PERMISSION_GRANTED);
495 
496         assertEquals(wantedUserId,
497                 spySecurityPolicy.resolveCallingUserIdEnforcingPermissionsLocked(wantedUserId));
498     }
499 
500     @Test
resolveCallingUserId_anotherUserIdWithCrossUserFullPermission_returnUserId()501     public void resolveCallingUserId_anotherUserIdWithCrossUserFullPermission_returnUserId() {
502         final AccessibilitySecurityPolicy spySecurityPolicy = Mockito.spy(mA11ySecurityPolicy);
503         final int callingUserId = UserHandle.getUserId(Process.myUid());
504         final int callingParentId = 20;
505         final int currentUserId = 30;
506         final int wantedUserId = 40;
507         when(mMockA11yUserManager.getCurrentUserIdLocked())
508                 .thenReturn(currentUserId);
509         doReturn(callingParentId).when(spySecurityPolicy).resolveProfileParentLocked(
510                 callingUserId);
511         when(mMockContext.checkCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL))
512                 .thenReturn(PackageManager.PERMISSION_GRANTED);
513 
514         assertEquals(wantedUserId,
515                 spySecurityPolicy.resolveCallingUserIdEnforcingPermissionsLocked(wantedUserId));
516     }
517 
518     @Test(expected = SecurityException.class)
resolveCallingUserId_anotherUserIdWithoutCrossUserPermission_shouldException()519     public void resolveCallingUserId_anotherUserIdWithoutCrossUserPermission_shouldException() {
520         final AccessibilitySecurityPolicy spySecurityPolicy = Mockito.spy(mA11ySecurityPolicy);
521         final int callingUserId = UserHandle.getUserId(Process.myUid());
522         final int callingParentId = 20;
523         final int currentUserId = 30;
524         final int wantedUserId = 40;
525         when(mMockA11yUserManager.getCurrentUserIdLocked())
526                 .thenReturn(currentUserId);
527         doReturn(callingParentId).when(spySecurityPolicy).resolveProfileParentLocked(
528                 callingUserId);
529         when(mMockContext.checkCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS))
530                 .thenReturn(PackageManager.PERMISSION_DENIED);
531         when(mMockContext.checkCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL))
532                 .thenReturn(PackageManager.PERMISSION_DENIED);
533 
534         spySecurityPolicy.resolveCallingUserIdEnforcingPermissionsLocked(wantedUserId);
535     }
536 
537     @Test
canRegisterService_shouldCheckAppOps()538     public void canRegisterService_shouldCheckAppOps() {
539         final ServiceInfo serviceInfo = new ServiceInfo();
540         serviceInfo.applicationInfo = new ApplicationInfo();
541         serviceInfo.packageName = PACKAGE_NAME;
542         serviceInfo.name = AccessibilitySecurityPolicyTest.class.getSimpleName();
543 
544         assertFalse(mA11ySecurityPolicy.canRegisterService(serviceInfo));
545         serviceInfo.permission = android.Manifest.permission.BIND_ACCESSIBILITY_SERVICE;
546         mA11ySecurityPolicy.canRegisterService(serviceInfo);
547         verify(mMockAppOpsManager).noteOpNoThrow(AppOpsManager.OPSTR_BIND_ACCESSIBILITY_SERVICE,
548                 serviceInfo.applicationInfo.uid, serviceInfo.packageName);
549     }
550 
551     @Test
checkAccessibilityAccess_shouldCheckAppOps()552     public void checkAccessibilityAccess_shouldCheckAppOps() {
553         final AccessibilityServiceInfo mockServiceInfo = Mockito.mock(
554                 AccessibilityServiceInfo.class);
555         final ResolveInfo mockResolveInfo = Mockito.mock(
556                 ResolveInfo.class);
557         final ServiceInfo serviceInfo = new ServiceInfo();
558         serviceInfo.applicationInfo = new ApplicationInfo();
559         serviceInfo.applicationInfo.uid = APP_UID;
560         mockResolveInfo.serviceInfo = serviceInfo;
561 
562         when(mMockA11yServiceConnection.getServiceInfo()).thenReturn(mockServiceInfo);
563         when(mockServiceInfo.getResolveInfo()).thenReturn(mockResolveInfo);
564         when(mMockA11yServiceConnection.getComponentName())
565                 .thenReturn(new ComponentName(
566                         PACKAGE_NAME, AccessibilitySecurityPolicyTest.class.getSimpleName()));
567 
568         mA11ySecurityPolicy.checkAccessibilityAccess(mMockA11yServiceConnection);
569         verify(mMockAppOpsManager).noteOpNoThrow(AppOpsManager.OPSTR_ACCESS_ACCESSIBILITY,
570                 APP_UID, PACKAGE_NAME);
571     }
572 
573     @Test
testEnforceCallerIsRecentsOrHasPermission()574     public void testEnforceCallerIsRecentsOrHasPermission() {
575         mA11ySecurityPolicy.enforceCallerIsRecentsOrHasPermission(PERMISSION, FUNCTION);
576         verify(mMockActivityTaskManagerInternal).enforceCallerIsRecentsOrHasPermission(
577                 PERMISSION, FUNCTION);
578     }
579 }
580