• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 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 package com.android.cts.deviceandprofileowner;
17 
18 import static android.Manifest.permission.READ_CONTACTS;
19 import static android.Manifest.permission.WRITE_CONTACTS;
20 import static android.app.admin.DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT;
21 import static android.app.admin.DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED;
22 import static android.app.admin.DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED;
23 import static android.app.admin.DevicePolicyManager.PERMISSION_POLICY_AUTO_DENY;
24 import static android.app.admin.DevicePolicyManager.PERMISSION_POLICY_AUTO_GRANT;
25 import static android.app.admin.DevicePolicyManager.PERMISSION_POLICY_PROMPT;
26 import static android.content.pm.PackageManager.PERMISSION_DENIED;
27 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
28 
29 import static com.android.cts.devicepolicy.PermissionUtils.permissionGrantStateToString;
30 import static com.android.cts.devicepolicy.PermissionUtils.permissionPolicyToString;
31 
32 import static com.google.common.truth.Truth.assertWithMessage;
33 
34 import android.Manifest.permission;
35 import android.app.UiAutomation;
36 import android.app.admin.DevicePolicyManager;
37 import android.content.Context;
38 import android.content.IntentFilter;
39 import android.os.Process;
40 import android.os.UserHandle;
41 import android.os.UserManager;
42 import android.util.Log;
43 
44 import androidx.test.uiautomator.By;
45 import androidx.test.uiautomator.BySelector;
46 import androidx.test.uiautomator.UiDevice;
47 import androidx.test.uiautomator.UiObject2;
48 
49 import com.android.compatibility.common.util.CddTest;
50 import com.android.compatibility.common.util.PollingCheck;
51 import com.android.cts.devicepolicy.PermissionBroadcastReceiver;
52 import com.android.cts.devicepolicy.PermissionUtils;
53 
54 import com.google.android.collect.Sets;
55 
56 import java.util.Set;
57 
58 /**
59  * Test Runtime Permissions APIs in DevicePolicyManager.
60  */
61 public class PermissionsTest extends BaseDeviceAdminTest {
62 
63     private static final String TAG = "PermissionsTest";
64 
65     private static final String PERMISSION_APP_PACKAGE_NAME = "com.android.cts.permissionapp";
66     private static final String PRE_M_APP_PACKAGE_NAME
67             = "com.android.cts.launcherapps.simplepremapp";
68     private static final String PERMISSIONS_ACTIVITY_NAME
69             = PERMISSION_APP_PACKAGE_NAME + ".PermissionActivity";
70     private static final String CUSTOM_PERM_A_NAME = "com.android.cts.permissionapp.permA";
71     private static final String CUSTOM_PERM_B_NAME = "com.android.cts.permissionapp.permB";
72 
73     private static final String ACTION_PERMISSION_RESULT
74             = "com.android.cts.permission.action.PERMISSION_RESULT";
75 
76     private static final BySelector CRASH_POPUP_BUTTON_SELECTOR = By
77             .clazz(android.widget.Button.class.getName())
78             .text("OK")
79             .pkg("android");
80     private static final BySelector CRASH_POPUP_TEXT_SELECTOR = By
81             .clazz(android.widget.TextView.class.getName())
82             .pkg("android");
83     private static final String CRASH_WATCHER_ID = "CRASH";
84 
85     private static final Set<String> LOCATION_PERMISSIONS = Sets.newHashSet(
86             permission.ACCESS_FINE_LOCATION,
87             permission.ACCESS_BACKGROUND_LOCATION,
88             permission.ACCESS_COARSE_LOCATION);
89 
90     private static final Set<String> SENSORS_PERMISSIONS = Sets.newHashSet(
91             permission.ACCESS_FINE_LOCATION,
92             permission.ACCESS_COARSE_LOCATION,
93             permission.CAMERA,
94             permission.ACTIVITY_RECOGNITION,
95             permission.BODY_SENSORS);
96 
97 
98     private PermissionBroadcastReceiver mReceiver;
99     private UiDevice mDevice;
100     private UiAutomation mUiAutomation;
101 
102     @Override
setUp()103     protected void setUp() throws Exception {
104         super.setUp();
105         mReceiver = new PermissionBroadcastReceiver();
106         mContext.registerReceiver(mReceiver, new IntentFilter(ACTION_PERMISSION_RESULT),
107                 Context.RECEIVER_EXPORTED);
108         mDevice = UiDevice.getInstance(getInstrumentation());
109         mUiAutomation = getInstrumentation().getUiAutomation();
110     }
111 
112     @Override
tearDown()113     protected void tearDown() throws Exception {
114         mContext.unregisterReceiver(mReceiver);
115         mDevice.removeWatcher(CRASH_WATCHER_ID);
116         super.tearDown();
117     }
118 
testPermissionGrantStateDenied()119     public void testPermissionGrantStateDenied() throws Exception {
120         setPermissionGrantState(READ_CONTACTS, PERMISSION_GRANT_STATE_DENIED);
121 
122         assertPermissionGrantState(READ_CONTACTS, PERMISSION_GRANT_STATE_DENIED);
123         assertCannotRequestPermissionFromActivity(READ_CONTACTS);
124     }
125 
testPermissionGrantStateDenied_otherPermissionIsGranted()126     public void testPermissionGrantStateDenied_otherPermissionIsGranted() throws Exception {
127         int grantStateA = mDevicePolicyManager.getPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
128                 PERMISSION_APP_PACKAGE_NAME, CUSTOM_PERM_A_NAME);
129         int grantStateB = mDevicePolicyManager.getPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
130                 PERMISSION_APP_PACKAGE_NAME, CUSTOM_PERM_B_NAME);
131         try {
132             setPermissionGrantState(CUSTOM_PERM_A_NAME, PERMISSION_GRANT_STATE_GRANTED);
133             setPermissionGrantState(CUSTOM_PERM_B_NAME, PERMISSION_GRANT_STATE_DENIED);
134 
135             assertPermissionGrantState(CUSTOM_PERM_A_NAME, PERMISSION_GRANT_STATE_GRANTED);
136             assertPermissionGrantState(CUSTOM_PERM_B_NAME, PERMISSION_GRANT_STATE_DENIED);
137 
138             /*
139              * CUSTOM_PERM_A_NAME and CUSTOM_PERM_B_NAME are in the same permission group and one is
140              * granted the other one is not.
141              *
142              * It should not be possible to get the permission that was denied via policy granted by
143              * requesting it.
144              */
145             assertCannotRequestPermissionFromActivity(CUSTOM_PERM_B_NAME);
146         } finally {
147             // Restore original state
148             setPermissionGrantState(CUSTOM_PERM_A_NAME, grantStateA);
149             setPermissionGrantState(CUSTOM_PERM_B_NAME, grantStateB);
150         }
151     }
152 
testPermissionGrantStateGranted()153     public void testPermissionGrantStateGranted() throws Exception {
154         setPermissionGrantState(READ_CONTACTS, PERMISSION_GRANT_STATE_GRANTED);
155 
156         assertPermissionGrantState(READ_CONTACTS, PERMISSION_GRANT_STATE_GRANTED);
157         assertCanRequestPermissionFromActivity(READ_CONTACTS);
158     }
159 
testPermissionGrantState_preMApp_preQDeviceAdmin()160     public void testPermissionGrantState_preMApp_preQDeviceAdmin() throws Exception {
161         // These tests are to make sure that pre-M apps are not granted/denied runtime permissions
162         // by a profile owner that targets pre-Q
163         assertCannotSetPermissionGrantStatePreMApp(READ_CONTACTS, PERMISSION_GRANT_STATE_DENIED);
164         assertCannotSetPermissionGrantStatePreMApp(READ_CONTACTS, PERMISSION_GRANT_STATE_GRANTED);
165     }
166 
assertCannotSetPermissionGrantStatePreMApp(String permission, int value)167     private void assertCannotSetPermissionGrantStatePreMApp(String permission, int value)
168             throws Exception {
169         assertFalse(mDevicePolicyManager.setPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
170                 PRE_M_APP_PACKAGE_NAME, permission, value));
171         assertEquals(mDevicePolicyManager.getPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
172                 PRE_M_APP_PACKAGE_NAME, permission), PERMISSION_GRANT_STATE_DEFAULT);
173 
174         // Install runtime permissions should always be granted
175         PermissionUtils.checkPermission(permission, PERMISSION_GRANTED, PRE_M_APP_PACKAGE_NAME);
176         PermissionUtils.checkPermissionAndAppOps(permission, PERMISSION_GRANTED,
177                 PRE_M_APP_PACKAGE_NAME);
178     }
179 
testPermissionGrantState_preMApp()180     public void testPermissionGrantState_preMApp() throws Exception {
181         // These tests are to make sure that pre-M apps can be granted/denied runtime permissions
182         // by a profile owner targets Q or later
183         assertCanSetPermissionGrantStatePreMApp(READ_CONTACTS, PERMISSION_GRANT_STATE_DENIED);
184         assertCanSetPermissionGrantStatePreMApp(READ_CONTACTS, PERMISSION_GRANT_STATE_GRANTED);
185     }
186 
assertCanSetPermissionGrantStatePreMApp(String permission, int value)187     private void assertCanSetPermissionGrantStatePreMApp(String permission, int value)
188             throws Exception {
189         Log.d(TAG, "Calling " + mDevicePolicyManager + ".setPermissionGrantState("
190                 + PRE_M_APP_PACKAGE_NAME + ", " + permission + ", "
191                 + permissionGrantStateToString(value) + ")");
192         boolean result = mDevicePolicyManager.setPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
193                 PRE_M_APP_PACKAGE_NAME, permission, value);
194         Log.d(TAG, "Result: " + result);
195 
196         assertWithMessage("%s.setPermissionGrantState(%s, %s, %s)", mDevicePolicyManager,
197                 ADMIN_RECEIVER_COMPONENT, PRE_M_APP_PACKAGE_NAME,
198                 permissionGrantStateToString(value)).that(result).isTrue();
199 
200         assertPermissionGrantState(mDevicePolicyManager, PRE_M_APP_PACKAGE_NAME, permission, value);
201 
202         Context context = mContext;
203 
204         // Install time permissions should always be granted
205         PermissionUtils.checkPermission(context, permission, PERMISSION_GRANTED,
206                 PRE_M_APP_PACKAGE_NAME);
207 
208         // For pre-M apps the access to the data might be prevented via app-ops. Hence check that
209         // they are correctly set
210         switch (value) {
211             case PERMISSION_GRANT_STATE_GRANTED:
212                 PermissionUtils.checkPermissionAndAppOps(context, permission, PERMISSION_GRANTED,
213                         PRE_M_APP_PACKAGE_NAME);
214                 break;
215             case PERMISSION_GRANT_STATE_DENIED:
216                 PermissionUtils.checkPermissionAndAppOps(context, permission, PERMISSION_DENIED,
217                         PRE_M_APP_PACKAGE_NAME);
218                 break;
219             default:
220                 fail("unsupported policy value (" + value + ")");
221         }
222     }
223 
testPermissionPolicyAutoDeny()224     public void testPermissionPolicyAutoDeny() throws Exception {
225         setPermissionPolicy(PERMISSION_POLICY_AUTO_DENY);
226 
227         assertPermissionPolicy(PERMISSION_POLICY_AUTO_DENY);
228         assertCannotRequestPermissionFromActivity(READ_CONTACTS);
229     }
230 
testPermissionPolicyAutoDeny_permissionLocked()231     public void testPermissionPolicyAutoDeny_permissionLocked() throws Exception {
232         int grantState = mDevicePolicyManager.getPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
233                 PERMISSION_APP_PACKAGE_NAME, READ_CONTACTS);
234         int permissionPolicy = mDevicePolicyManager.getPermissionPolicy(ADMIN_RECEIVER_COMPONENT);
235         try {
236             setPermissionGrantState(READ_CONTACTS, PERMISSION_GRANT_STATE_DENIED);
237             setPermissionGrantState(READ_CONTACTS, PERMISSION_GRANT_STATE_DEFAULT);
238 
239             // Wait for permission grant state to propagate.
240             PollingCheck.waitFor(() -> mDevicePolicyManager.getPermissionGrantState(
241                     ADMIN_RECEIVER_COMPONENT, PERMISSION_APP_PACKAGE_NAME, READ_CONTACTS)
242                     == PERMISSION_GRANT_STATE_DEFAULT);
243 
244             testPermissionPolicyAutoDeny();
245 
246             // Permission should be locked, so changing the policy should not change the grant state
247             setPermissionPolicy(PERMISSION_POLICY_PROMPT);
248 
249             assertPermissionPolicy(PERMISSION_POLICY_PROMPT);
250             assertCannotRequestPermissionFromActivity(READ_CONTACTS);
251 
252             setPermissionPolicy(PERMISSION_POLICY_AUTO_GRANT);
253 
254             assertPermissionPolicy(PERMISSION_POLICY_AUTO_GRANT);
255             assertCannotRequestPermissionFromActivity(READ_CONTACTS);
256         } finally {
257             // Restore original state
258             setPermissionGrantState(READ_CONTACTS, grantState);
259             setPermissionPolicy(permissionPolicy);
260         }
261     }
262 
testPermissionPolicyAutoGrant()263     public void testPermissionPolicyAutoGrant() throws Exception {
264         int permissionPolicy = mDevicePolicyManager.getPermissionPolicy(ADMIN_RECEIVER_COMPONENT);
265         try {
266             setPermissionPolicy(PERMISSION_POLICY_AUTO_GRANT);
267 
268             assertPermissionPolicy(PERMISSION_POLICY_AUTO_GRANT);
269             assertCanRequestPermissionFromActivity(READ_CONTACTS);
270        } finally {
271             // Restore original state
272             setPermissionPolicy(permissionPolicy);
273         }
274     }
275 
testPermissionPolicyAutoGrant_permissionLocked()276     public void testPermissionPolicyAutoGrant_permissionLocked() throws Exception {
277         int grantState = mDevicePolicyManager.getPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
278                 PERMISSION_APP_PACKAGE_NAME, READ_CONTACTS);
279         int permissionPolicy = mDevicePolicyManager.getPermissionPolicy(ADMIN_RECEIVER_COMPONENT);
280         try {
281             setPermissionGrantState(READ_CONTACTS, PERMISSION_GRANT_STATE_DEFAULT);
282             setPermissionPolicy(PERMISSION_POLICY_AUTO_GRANT);
283 
284             assertPermissionPolicy(PERMISSION_POLICY_AUTO_GRANT);
285             assertCanRequestPermissionFromActivity(READ_CONTACTS);
286 
287             // permission should be locked, so changing the policy should not change the grant state
288             setPermissionPolicy(PERMISSION_POLICY_PROMPT);
289 
290             assertPermissionPolicy(PERMISSION_POLICY_PROMPT);
291             assertCanRequestPermissionFromActivity(READ_CONTACTS);
292 
293             setPermissionPolicy(PERMISSION_POLICY_AUTO_DENY);
294 
295             assertPermissionPolicy(PERMISSION_POLICY_AUTO_DENY);
296             assertCanRequestPermissionFromActivity(READ_CONTACTS);
297         } finally {
298             // Restore original state
299             setPermissionGrantState(READ_CONTACTS, grantState);
300             setPermissionPolicy(permissionPolicy);
301         }
302     }
303 
testCannotRequestPermission()304     public void testCannotRequestPermission() throws Exception {
305         assertCannotRequestPermissionFromActivity(READ_CONTACTS);
306     }
307 
testCanRequestPermission()308     public void testCanRequestPermission() throws Exception {
309         assertCanRequestPermissionFromActivity(READ_CONTACTS);
310     }
311 
testPermissionPrompts()312     public void testPermissionPrompts() throws Exception {
313         // register a crash watcher
314         mDevice.registerWatcher(CRASH_WATCHER_ID, () -> {
315             UiObject2 button = mDevice.findObject(CRASH_POPUP_BUTTON_SELECTOR);
316             if (button != null) {
317                 UiObject2 text = mDevice.findObject(CRASH_POPUP_TEXT_SELECTOR);
318                 Log.d(TAG, "Removing an error dialog: " + text != null ? text.getText() : null);
319                 button.click();
320                 return true;
321             }
322             return false;
323         });
324         mDevice.runWatchers();
325         setPermissionPolicy(PERMISSION_POLICY_PROMPT);
326 
327         assertPermissionPolicy(PERMISSION_POLICY_PROMPT);
328         PermissionUtils.launchActivityAndRequestPermission(mReceiver, mDevice, READ_CONTACTS,
329                 PERMISSION_DENIED, PERMISSION_APP_PACKAGE_NAME, PERMISSIONS_ACTIVITY_NAME);
330         PermissionUtils.checkPermission(READ_CONTACTS, PERMISSION_DENIED,
331                 PERMISSION_APP_PACKAGE_NAME);
332         PermissionUtils.launchActivityAndRequestPermission(mReceiver, mDevice, READ_CONTACTS,
333                 PERMISSION_GRANTED, PERMISSION_APP_PACKAGE_NAME, PERMISSIONS_ACTIVITY_NAME);
334         PermissionUtils.checkPermission(READ_CONTACTS, PERMISSION_GRANTED,
335                 PERMISSION_APP_PACKAGE_NAME);
336     }
337 
revokePermission(String sensorPermission)338     private void revokePermission(String sensorPermission) {
339         if (LOCATION_PERMISSIONS.contains(sensorPermission)) {
340             mUiAutomation.revokeRuntimePermission(PERMISSION_APP_PACKAGE_NAME,
341                     permission.ACCESS_FINE_LOCATION);
342             mUiAutomation.revokeRuntimePermission(PERMISSION_APP_PACKAGE_NAME,
343                     permission.ACCESS_COARSE_LOCATION);
344         } else {
345             mUiAutomation.revokeRuntimePermission(PERMISSION_APP_PACKAGE_NAME, sensorPermission);
346         }
347     }
348 
setPermissionPolicy(int permissionPolicy)349     private void setPermissionPolicy(int permissionPolicy) {
350         Log.d(TAG, "Calling setPermissionPolicy(" + permissionPolicyToString(permissionPolicy)
351                 + ") using DPM " + mDevicePolicyManager + " on uid " + Process.myUid());
352         mDevicePolicyManager.setPermissionPolicy(ADMIN_RECEIVER_COMPONENT, permissionPolicy);
353     }
354 
setPermissionGrantState(String permission, int grantState)355     private boolean setPermissionGrantState(String permission, int grantState) {
356         return setPermissionGrantState(mDevicePolicyManager, permission, grantState);
357     }
358 
setPermissionGrantState(DevicePolicyManager dpm, String permission, int grantState)359     private boolean setPermissionGrantState(DevicePolicyManager dpm, String permission,
360             int grantState) {
361         boolean result = dpm.setPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
362                 PERMISSION_APP_PACKAGE_NAME, permission, grantState);
363         Log.d(TAG, "setPermissionGrantState(" + PERMISSION_APP_PACKAGE_NAME + ", " + permission
364                 + "): requested " + grantState + " (" + permissionGrantStateToString(grantState)
365                 + ") using DPM " + mDevicePolicyManager + " on uid " + Process.myUid()
366                 + ", got " + result);
367         return result;
368     }
369 
assertPermissionGrantState(String permission, int expectedState)370     private void assertPermissionGrantState(String permission, int expectedState) {
371         assertPermissionGrantState(mDevicePolicyManager, permission, expectedState);
372     }
373 
assertPermissionGrantState(DevicePolicyManager dpm, String permission, int expectedState)374     private void assertPermissionGrantState(DevicePolicyManager dpm, String permission,
375             int expectedState) {
376         assertPermissionGrantState(dpm, PERMISSION_APP_PACKAGE_NAME, permission, expectedState);
377     }
378 
assertPermissionGrantState(DevicePolicyManager dpm, String packageName, String permission, int expectedState)379     private void assertPermissionGrantState(DevicePolicyManager dpm, String packageName,
380             String permission, int expectedState) {
381         int actualState = dpm.getPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
382                 packageName, permission);
383 
384         assertWithMessage("%s.getPermissionGrantState(%s, %s, %s) (where %s=%s and %s=%s)",
385                 mDevicePolicyManager, ADMIN_RECEIVER_COMPONENT, packageName, permission,
386                 expectedState, permissionGrantStateToString(expectedState),
387                 actualState, permissionGrantStateToString(actualState))
388                         .that(actualState)
389                         .isEqualTo(expectedState);
390     }
391 
assertPermissionPolicy(int expectedPolicy)392     private void assertPermissionPolicy(int expectedPolicy) {
393         int actualPolicy = mDevicePolicyManager.getPermissionPolicy(ADMIN_RECEIVER_COMPONENT);
394         assertWithMessage("%s.getPermissionPolicy(%s) (where %s=%s and %s=%s)",
395                 mDevicePolicyManager, ADMIN_RECEIVER_COMPONENT,
396                 expectedPolicy, permissionPolicyToString(expectedPolicy),
397                 actualPolicy, permissionPolicyToString(actualPolicy))
398                         .that(actualPolicy)
399                         .isEqualTo(expectedPolicy);
400     }
401 
assertCanRequestPermissionFromActivity(String permission)402     private void assertCanRequestPermissionFromActivity(String permission) throws Exception {
403         PermissionUtils.launchActivityAndRequestPermission(
404                 mReceiver, permission, PERMISSION_GRANTED,
405                 PERMISSION_APP_PACKAGE_NAME, PERMISSIONS_ACTIVITY_NAME);
406     }
407 
assertCannotRequestPermissionFromActivity(String permission)408     private void assertCannotRequestPermissionFromActivity(String permission) throws Exception {
409         PermissionUtils.launchActivityAndRequestPermission(
410                 mReceiver, permission, PERMISSION_DENIED,
411                 PERMISSION_APP_PACKAGE_NAME, PERMISSIONS_ACTIVITY_NAME);
412     }
413 }
414