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 android.app.admin.DevicePolicyManager; 19 import android.content.BroadcastReceiver; 20 import android.content.ComponentName; 21 import android.content.Context; 22 import android.content.Intent; 23 import android.content.IntentFilter; 24 import android.content.pm.PackageManager; 25 import android.os.UserManager; 26 import android.support.test.uiautomator.By; 27 import android.support.test.uiautomator.BySelector; 28 import android.support.test.uiautomator.UiDevice; 29 import android.support.test.uiautomator.UiObject2; 30 import android.support.test.uiautomator.UiWatcher; 31 import android.support.test.uiautomator.Until; 32 import android.util.Log; 33 34 import java.util.concurrent.ArrayBlockingQueue; 35 import java.util.concurrent.BlockingQueue; 36 import java.util.concurrent.TimeUnit; 37 38 /** 39 * Test Runtime Permissions APIs in DevicePolicyManager. 40 */ 41 public class PermissionsTest extends BaseDeviceAdminTest { 42 private static final String TAG = "PermissionsTest"; 43 44 private static final String PERMISSION_APP_PACKAGE_NAME 45 = "com.android.cts.permissionapp"; 46 private static final String SIMPLE_PRE_M_APP_PACKAGE_NAME = 47 "com.android.cts.launcherapps.simplepremapp"; 48 private static final String PERMISSION_NAME = "android.permission.READ_CONTACTS"; 49 50 private static final String PERMISSIONS_ACTIVITY_NAME 51 = PERMISSION_APP_PACKAGE_NAME + ".PermissionActivity"; 52 private static final String ACTION_CHECK_HAS_PERMISSION 53 = "com.android.cts.permission.action.CHECK_HAS_PERMISSION"; 54 private static final String ACTION_REQUEST_PERMISSION 55 = "com.android.cts.permission.action.REQUEST_PERMISSION"; 56 private static final String ACTION_PERMISSION_RESULT 57 = "com.android.cts.permission.action.PERMISSION_RESULT"; 58 private static final String EXTRA_PERMISSION 59 = "com.android.cts.permission.extra.PERMISSION"; 60 private static final String EXTRA_GRANT_STATE 61 = "com.android.cts.permission.extra.GRANT_STATE"; 62 private static final int PERMISSION_ERROR = -2; 63 private static final BySelector CRASH_POPUP_BUTTON_SELECTOR = By 64 .clazz(android.widget.Button.class.getName()) 65 .text("OK") 66 .pkg("android"); 67 private static final BySelector CRASH_POPUP_TEXT_SELECTOR = By 68 .clazz(android.widget.TextView.class.getName()) 69 .pkg("android"); 70 private static final String CRASH_WATCHER_ID = "CRASH"; 71 72 private PermissionBroadcastReceiver mReceiver; 73 private PackageManager mPackageManager; 74 private UiDevice mDevice; 75 76 @Override 77 protected void setUp() throws Exception { 78 super.setUp(); 79 mReceiver = new PermissionBroadcastReceiver(); 80 mContext.registerReceiver(mReceiver, new IntentFilter(ACTION_PERMISSION_RESULT)); 81 mPackageManager = mContext.getPackageManager(); 82 mDevice = UiDevice.getInstance(getInstrumentation()); 83 } 84 85 @Override 86 protected void tearDown() throws Exception { 87 mContext.unregisterReceiver(mReceiver); 88 mDevice.removeWatcher(CRASH_WATCHER_ID); 89 super.tearDown(); 90 } 91 92 public void testPermissionGrantState() throws Exception { 93 assertSetPermissionGrantState(DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED); 94 assertPermissionGrantState(PackageManager.PERMISSION_DENIED); 95 assertPermissionRequest(PackageManager.PERMISSION_DENIED); 96 97 assertSetPermissionGrantState(DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT); 98 // Should stay denied 99 assertPermissionGrantState(PackageManager.PERMISSION_DENIED); 100 101 assertSetPermissionGrantState(DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED); 102 assertPermissionGrantState(PackageManager.PERMISSION_GRANTED); 103 assertPermissionRequest(PackageManager.PERMISSION_GRANTED); 104 105 assertSetPermissionGrantState(DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT); 106 // Should stay granted 107 assertPermissionGrantState(PackageManager.PERMISSION_GRANTED); 108 } 109 110 public void testPermissionPolicy() throws Exception { 111 // reset permission to denied and unlocked 112 assertSetPermissionGrantState(DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED); 113 assertSetPermissionGrantState(DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT); 114 115 assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_AUTO_DENY); 116 assertPermissionRequest(PackageManager.PERMISSION_DENIED); 117 // permission should be locked, so changing the policy should not change the grant state 118 assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_PROMPT); 119 assertPermissionRequest(PackageManager.PERMISSION_DENIED); 120 assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_AUTO_GRANT); 121 assertPermissionRequest(PackageManager.PERMISSION_DENIED); 122 123 // reset permission to denied and unlocked 124 assertSetPermissionGrantState(DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT); 125 126 assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_AUTO_GRANT); 127 assertPermissionRequest(PackageManager.PERMISSION_GRANTED); 128 // permission should be locked, so changing the policy should not change the grant state 129 assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_PROMPT); 130 assertPermissionRequest(PackageManager.PERMISSION_GRANTED); 131 assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_AUTO_DENY); 132 assertPermissionRequest(PackageManager.PERMISSION_GRANTED); 133 134 assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_PROMPT); 135 } 136 137 public void testPermissionMixedPolicies() throws Exception { 138 assertSetPermissionGrantState(DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED); 139 assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_AUTO_GRANT); 140 assertPermissionRequest(PackageManager.PERMISSION_DENIED); 141 142 assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_AUTO_DENY); 143 assertPermissionRequest(PackageManager.PERMISSION_DENIED); 144 145 assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_PROMPT); 146 assertPermissionRequest(PackageManager.PERMISSION_DENIED); 147 148 assertSetPermissionGrantState(DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED); 149 assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_AUTO_GRANT); 150 assertPermissionRequest(PackageManager.PERMISSION_GRANTED); 151 152 assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_AUTO_DENY); 153 assertPermissionRequest(PackageManager.PERMISSION_GRANTED); 154 155 assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_PROMPT); 156 assertPermissionRequest(PackageManager.PERMISSION_GRANTED); 157 } 158 159 public void testPermissionPrompts() throws Exception { 160 // register a crash watcher 161 mDevice.registerWatcher(CRASH_WATCHER_ID, new UiWatcher() { 162 @Override 163 public boolean checkForCondition() { 164 UiObject2 button = mDevice.findObject(CRASH_POPUP_BUTTON_SELECTOR); 165 if (button != null) { 166 UiObject2 text = mDevice.findObject(CRASH_POPUP_TEXT_SELECTOR); 167 Log.d(TAG, "Removing an error dialog: " + text != null ? text.getText() : null); 168 button.click(); 169 return true; 170 } 171 return false; 172 } 173 }); 174 mDevice.runWatchers(); 175 176 assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_PROMPT); 177 assertPermissionRequest(PackageManager.PERMISSION_DENIED, "permission_deny_button"); 178 assertPermissionRequest(PackageManager.PERMISSION_GRANTED, "permission_allow_button"); 179 } 180 181 public void testPermissionUpdate_setDeniedState() throws Exception { 182 assertEquals(mDevicePolicyManager.getPermissionGrantState(ADMIN_RECEIVER_COMPONENT, 183 PERMISSION_APP_PACKAGE_NAME, PERMISSION_NAME), 184 DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT); 185 assertSetPermissionGrantState(DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED); 186 } 187 188 public void testPermissionUpdate_setAutoDeniedPolicy() throws Exception { 189 assertEquals(mDevicePolicyManager.getPermissionGrantState(ADMIN_RECEIVER_COMPONENT, 190 PERMISSION_APP_PACKAGE_NAME, PERMISSION_NAME), 191 DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT); 192 assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_AUTO_DENY); 193 assertPermissionRequest(PackageManager.PERMISSION_DENIED); 194 } 195 196 public void testPermissionUpdate_checkDenied() throws Exception { 197 assertPermissionRequest(PackageManager.PERMISSION_DENIED); 198 assertPermissionGrantState(PackageManager.PERMISSION_DENIED); 199 } 200 201 public void testPermissionUpdate_setGrantedState() throws Exception { 202 assertEquals(mDevicePolicyManager.getPermissionGrantState(ADMIN_RECEIVER_COMPONENT, 203 PERMISSION_APP_PACKAGE_NAME, PERMISSION_NAME), 204 DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT); 205 assertSetPermissionGrantState(DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED); 206 } 207 208 public void testPermissionUpdate_setAutoGrantedPolicy() throws Exception { 209 assertEquals(mDevicePolicyManager.getPermissionGrantState(ADMIN_RECEIVER_COMPONENT, 210 PERMISSION_APP_PACKAGE_NAME, PERMISSION_NAME), 211 DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT); 212 assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_AUTO_GRANT); 213 assertPermissionRequest(PackageManager.PERMISSION_GRANTED); 214 } 215 216 public void testPermissionUpdate_checkGranted() throws Exception { 217 assertPermissionRequest(PackageManager.PERMISSION_GRANTED); 218 assertPermissionGrantState(PackageManager.PERMISSION_GRANTED); 219 } 220 221 public void testPermissionGrantStatePreMApp() throws Exception { 222 // These tests are to make sure that pre-M apps are not granted runtime permissions 223 // by a profile owner 224 assertSetPermissionGrantStatePreMApp(DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED); 225 assertSetPermissionGrantStatePreMApp(DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED); 226 } 227 228 private void assertPermissionRequest(int expected) throws Exception { 229 assertPermissionRequest(expected, null); 230 } 231 232 private void assertPermissionRequest(int expected, String buttonResource) throws Exception { 233 Intent launchIntent = new Intent(); 234 launchIntent.setComponent(new ComponentName(PERMISSION_APP_PACKAGE_NAME, 235 PERMISSIONS_ACTIVITY_NAME)); 236 launchIntent.putExtra(EXTRA_PERMISSION, PERMISSION_NAME); 237 launchIntent.setAction(ACTION_REQUEST_PERMISSION); 238 launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK); 239 mContext.startActivity(launchIntent); 240 pressPermissionPromptButton(buttonResource); 241 assertEquals(expected, mReceiver.waitForBroadcast()); 242 assertEquals(expected, mPackageManager.checkPermission(PERMISSION_NAME, 243 PERMISSION_APP_PACKAGE_NAME)); 244 } 245 246 private void assertPermissionGrantState(int expected) throws Exception { 247 assertEquals(expected, mPackageManager.checkPermission(PERMISSION_NAME, 248 PERMISSION_APP_PACKAGE_NAME)); 249 Intent launchIntent = new Intent(); 250 launchIntent.setComponent(new ComponentName(PERMISSION_APP_PACKAGE_NAME, 251 PERMISSIONS_ACTIVITY_NAME)); 252 launchIntent.putExtra(EXTRA_PERMISSION, PERMISSION_NAME); 253 launchIntent.setAction(ACTION_CHECK_HAS_PERMISSION); 254 launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK); 255 mContext.startActivity(launchIntent); 256 assertEquals(expected, mReceiver.waitForBroadcast()); 257 } 258 259 private void assertSetPermissionPolicy(int value) throws Exception { 260 mDevicePolicyManager.setPermissionPolicy(ADMIN_RECEIVER_COMPONENT, 261 value); 262 assertEquals(mDevicePolicyManager.getPermissionPolicy(ADMIN_RECEIVER_COMPONENT), 263 value); 264 } 265 266 private void assertSetPermissionGrantState(int value) throws Exception { 267 mDevicePolicyManager.setPermissionGrantState(ADMIN_RECEIVER_COMPONENT, 268 PERMISSION_APP_PACKAGE_NAME, PERMISSION_NAME, 269 value); 270 assertEquals(mDevicePolicyManager.getPermissionGrantState(ADMIN_RECEIVER_COMPONENT, 271 PERMISSION_APP_PACKAGE_NAME, PERMISSION_NAME), 272 value); 273 } 274 275 private void assertSetPermissionGrantStatePreMApp(int value) throws Exception { 276 assertFalse(mDevicePolicyManager.setPermissionGrantState(ADMIN_RECEIVER_COMPONENT, 277 SIMPLE_PRE_M_APP_PACKAGE_NAME, PERMISSION_NAME, 278 value)); 279 assertEquals(mDevicePolicyManager.getPermissionGrantState(ADMIN_RECEIVER_COMPONENT, 280 SIMPLE_PRE_M_APP_PACKAGE_NAME, PERMISSION_NAME), 281 DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT); 282 // Install time permissions should always be granted 283 assertEquals(mPackageManager.checkPermission(PERMISSION_NAME, 284 SIMPLE_PRE_M_APP_PACKAGE_NAME), 285 PackageManager.PERMISSION_GRANTED); 286 } 287 288 private void pressPermissionPromptButton(String resName) throws Exception { 289 if (resName == null) { 290 return; 291 } 292 293 BySelector selector = By 294 .clazz(android.widget.Button.class.getName()) 295 .res("com.android.packageinstaller", resName); 296 mDevice.wait(Until.hasObject(selector), 5000); 297 UiObject2 button = mDevice.findObject(selector); 298 assertNotNull("Couldn't find button with resource id: " + resName, button); 299 button.click(); 300 } 301 302 private class PermissionBroadcastReceiver extends BroadcastReceiver { 303 private BlockingQueue<Integer> mQueue = new ArrayBlockingQueue<Integer> (1); 304 305 @Override 306 public void onReceive(Context context, Intent intent) { 307 Integer result = new Integer(intent.getIntExtra(EXTRA_GRANT_STATE, PERMISSION_ERROR)); 308 Log.d(TAG, "Grant state received " + result); 309 assertTrue(mQueue.add(result)); 310 } 311 312 public int waitForBroadcast() throws Exception { 313 Integer result = mQueue.poll(30, TimeUnit.SECONDS); 314 mQueue.clear(); 315 assertNotNull(result); 316 Log.d(TAG, "Grant state retrieved " + result.intValue()); 317 return result.intValue(); 318 } 319 } 320 } 321