blob: 369017c61b8eded1f48beefb00f6c88b8e4ed9b3 [file] [log] [blame]
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.cts.managedprofile;
import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.UserManager;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.BySelector;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject2;
import android.support.test.uiautomator.UiWatcher;
import android.support.test.uiautomator.Until;
import android.util.Log;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
/**
* Test Runtime Permissions APIs in DevicePolicyManager.
*/
public class PermissionsTest extends BaseManagedProfileTest {
private static final String TAG = "PermissionsTest";
private static final String PERMISSION_APP_PACKAGE_NAME
= "com.android.cts.permission.permissionapp";
private static final String SIMPLE_PRE_M_APP_PACKAGE_NAME =
"com.android.cts.launcherapps.simplepremapp";
private static final String PERMISSION_NAME = "android.permission.READ_CONTACTS";
private static final String PERMISSIONS_ACTIVITY_NAME
= PERMISSION_APP_PACKAGE_NAME + ".PermissionActivity";
private static final String ACTION_CHECK_HAS_PERMISSION
= "com.android.cts.permission.action.CHECK_HAS_PERMISSION";
private static final String ACTION_REQUEST_PERMISSION
= "com.android.cts.permission.action.REQUEST_PERMISSION";
private static final String ACTION_PERMISSION_RESULT
= "com.android.cts.permission.action.PERMISSION_RESULT";
private static final String EXTRA_PERMISSION
= "com.android.cts.permission.extra.PERMISSION";
private static final String EXTRA_GRANT_STATE
= "com.android.cts.permission.extra.GRANT_STATE";
private static final int PERMISSION_ERROR = -2;
private static final BySelector CRASH_POPUP_BUTTON_SELECTOR = By
.clazz(android.widget.Button.class.getName())
.text("OK")
.pkg("android");
private static final BySelector CRASH_POPUP_TEXT_SELECTOR = By
.clazz(android.widget.TextView.class.getName())
.pkg("android");
private static final String CRASH_WATCHER_ID = "CRASH";
private PermissionBroadcastReceiver mReceiver;
private PackageManager mPackageManager;
private UiDevice mDevice;
@Override
protected void setUp() throws Exception {
super.setUp();
// Make sure we are running in a managed profile, otherwise risk wiping the primary user's
// data.
assertTrue(mDevicePolicyManager.isAdminActive(ADMIN_RECEIVER_COMPONENT));
assertTrue(mDevicePolicyManager.isProfileOwnerApp(
ADMIN_RECEIVER_COMPONENT.getPackageName()));
mReceiver = new PermissionBroadcastReceiver();
mContext.registerReceiver(mReceiver, new IntentFilter(ACTION_PERMISSION_RESULT));
mPackageManager = mContext.getPackageManager();
mDevice = UiDevice.getInstance(getInstrumentation());
}
@Override
protected void tearDown() throws Exception {
mContext.unregisterReceiver(mReceiver);
mDevice.removeWatcher(CRASH_WATCHER_ID);
super.tearDown();
}
public void testPermissionGrantState() throws Exception {
assertSetPermissionGrantState(DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED);
assertPermissionGrantState(PackageManager.PERMISSION_DENIED);
assertPermissionRequest(PackageManager.PERMISSION_DENIED);
assertSetPermissionGrantState(DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT);
// Should stay denied
assertPermissionGrantState(PackageManager.PERMISSION_DENIED);
assertSetPermissionGrantState(DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED);
assertPermissionGrantState(PackageManager.PERMISSION_GRANTED);
assertPermissionRequest(PackageManager.PERMISSION_GRANTED);
assertSetPermissionGrantState(DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT);
// Should stay granted
assertPermissionGrantState(PackageManager.PERMISSION_GRANTED);
}
public void testPermissionPolicy() throws Exception {
// reset permission to denied and unlocked
assertSetPermissionGrantState(DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED);
assertSetPermissionGrantState(DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT);
assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_AUTO_DENY);
assertPermissionRequest(PackageManager.PERMISSION_DENIED);
// permission should be locked, so changing the policy should not change the grant state
assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_PROMPT);
assertPermissionRequest(PackageManager.PERMISSION_DENIED);
assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_AUTO_GRANT);
assertPermissionRequest(PackageManager.PERMISSION_DENIED);
// reset permission to denied and unlocked
assertSetPermissionGrantState(DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT);
assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_AUTO_GRANT);
assertPermissionRequest(PackageManager.PERMISSION_GRANTED);
// permission should be locked, so changing the policy should not change the grant state
assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_PROMPT);
assertPermissionRequest(PackageManager.PERMISSION_GRANTED);
assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_AUTO_DENY);
assertPermissionRequest(PackageManager.PERMISSION_GRANTED);
assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_PROMPT);
}
public void testPermissionMixedPolicies() throws Exception {
assertSetPermissionGrantState(DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED);
assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_AUTO_GRANT);
assertPermissionRequest(PackageManager.PERMISSION_DENIED);
assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_AUTO_DENY);
assertPermissionRequest(PackageManager.PERMISSION_DENIED);
assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_PROMPT);
assertPermissionRequest(PackageManager.PERMISSION_DENIED);
assertSetPermissionGrantState(DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED);
assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_AUTO_GRANT);
assertPermissionRequest(PackageManager.PERMISSION_GRANTED);
assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_AUTO_DENY);
assertPermissionRequest(PackageManager.PERMISSION_GRANTED);
assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_PROMPT);
assertPermissionRequest(PackageManager.PERMISSION_GRANTED);
}
public void testPermissionPrompts() throws Exception {
// register a crash watcher
mDevice.registerWatcher(CRASH_WATCHER_ID, new UiWatcher() {
@Override
public boolean checkForCondition() {
UiObject2 button = mDevice.findObject(CRASH_POPUP_BUTTON_SELECTOR);
if (button != null) {
UiObject2 text = mDevice.findObject(CRASH_POPUP_TEXT_SELECTOR);
Log.d(TAG, "Removing an error dialog: " + text != null ? text.getText() : null);
button.click();
return true;
}
return false;
}
});
mDevice.runWatchers();
assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_PROMPT);
assertPermissionRequest(PackageManager.PERMISSION_DENIED, "permission_deny_button");
assertPermissionRequest(PackageManager.PERMISSION_GRANTED, "permission_allow_button");
}
public void testPermissionUpdate_setDeniedState() throws Exception {
assertEquals(mDevicePolicyManager.getPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
PERMISSION_APP_PACKAGE_NAME, PERMISSION_NAME),
DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT);
assertSetPermissionGrantState(DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED);
}
public void testPermissionUpdate_setAutoDeniedPolicy() throws Exception {
assertEquals(mDevicePolicyManager.getPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
PERMISSION_APP_PACKAGE_NAME, PERMISSION_NAME),
DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT);
assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_AUTO_DENY);
assertPermissionRequest(PackageManager.PERMISSION_DENIED);
}
public void testPermissionUpdate_checkDenied() throws Exception {
assertPermissionRequest(PackageManager.PERMISSION_DENIED);
assertPermissionGrantState(PackageManager.PERMISSION_DENIED);
}
public void testPermissionUpdate_setGrantedState() throws Exception {
assertEquals(mDevicePolicyManager.getPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
PERMISSION_APP_PACKAGE_NAME, PERMISSION_NAME),
DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT);
assertSetPermissionGrantState(DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED);
}
public void testPermissionUpdate_setAutoGrantedPolicy() throws Exception {
assertEquals(mDevicePolicyManager.getPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
PERMISSION_APP_PACKAGE_NAME, PERMISSION_NAME),
DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT);
assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_AUTO_GRANT);
assertPermissionRequest(PackageManager.PERMISSION_GRANTED);
}
public void testPermissionUpdate_checkGranted() throws Exception {
assertPermissionRequest(PackageManager.PERMISSION_GRANTED);
assertPermissionGrantState(PackageManager.PERMISSION_GRANTED);
}
public void testPermissionGrantStatePreMApp() throws Exception {
// These tests are to make sure that pre-M apps are not granted runtime permissions
// by a profile owner
assertSetPermissionGrantStatePreMApp(DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED);
assertSetPermissionGrantStatePreMApp(DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED);
}
private void assertPermissionRequest(int expected) throws Exception {
assertPermissionRequest(expected, null);
}
private void assertPermissionRequest(int expected, String buttonResource) throws Exception {
Intent launchIntent = new Intent();
launchIntent.setComponent(new ComponentName(PERMISSION_APP_PACKAGE_NAME,
PERMISSIONS_ACTIVITY_NAME));
launchIntent.putExtra(EXTRA_PERMISSION, PERMISSION_NAME);
launchIntent.setAction(ACTION_REQUEST_PERMISSION);
launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(launchIntent);
pressPermissionPromptButton(buttonResource);
assertEquals(expected, mReceiver.waitForBroadcast());
assertEquals(expected, mPackageManager.checkPermission(PERMISSION_NAME,
PERMISSION_APP_PACKAGE_NAME));
}
private void assertPermissionGrantState(int expected) throws Exception {
assertEquals(expected, mPackageManager.checkPermission(PERMISSION_NAME,
PERMISSION_APP_PACKAGE_NAME));
Intent launchIntent = new Intent();
launchIntent.setComponent(new ComponentName(PERMISSION_APP_PACKAGE_NAME,
PERMISSIONS_ACTIVITY_NAME));
launchIntent.putExtra(EXTRA_PERMISSION, PERMISSION_NAME);
launchIntent.setAction(ACTION_CHECK_HAS_PERMISSION);
launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(launchIntent);
assertEquals(expected, mReceiver.waitForBroadcast());
}
private void assertSetPermissionPolicy(int value) throws Exception {
mDevicePolicyManager.setPermissionPolicy(ADMIN_RECEIVER_COMPONENT,
value);
assertEquals(mDevicePolicyManager.getPermissionPolicy(ADMIN_RECEIVER_COMPONENT),
value);
}
private void assertSetPermissionGrantState(int value) throws Exception {
mDevicePolicyManager.setPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
PERMISSION_APP_PACKAGE_NAME, PERMISSION_NAME,
value);
assertEquals(mDevicePolicyManager.getPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
PERMISSION_APP_PACKAGE_NAME, PERMISSION_NAME),
value);
}
private void assertSetPermissionGrantStatePreMApp(int value) throws Exception {
assertFalse(mDevicePolicyManager.setPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
SIMPLE_PRE_M_APP_PACKAGE_NAME, PERMISSION_NAME,
value));
assertEquals(mDevicePolicyManager.getPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
SIMPLE_PRE_M_APP_PACKAGE_NAME, PERMISSION_NAME),
DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT);
// Install time permissions should always be granted
assertEquals(mPackageManager.checkPermission(PERMISSION_NAME,
SIMPLE_PRE_M_APP_PACKAGE_NAME),
PackageManager.PERMISSION_GRANTED);
}
private void pressPermissionPromptButton(String resName) throws Exception {
if (resName == null) {
return;
}
BySelector selector = By
.clazz(android.widget.Button.class.getName())
.res("com.android.packageinstaller", resName);
mDevice.wait(Until.hasObject(selector), 5000);
UiObject2 button = mDevice.findObject(selector);
assertNotNull("Couldn't find button with resource id: " + resName, button);
button.click();
}
private class PermissionBroadcastReceiver extends BroadcastReceiver {
private BlockingQueue<Integer> mQueue = new ArrayBlockingQueue<Integer> (1);
@Override
public void onReceive(Context context, Intent intent) {
Integer result = new Integer(intent.getIntExtra(EXTRA_GRANT_STATE, PERMISSION_ERROR));
Log.d(TAG, "Grant state received " + result);
assertTrue(mQueue.add(result));
}
public int waitForBroadcast() throws Exception {
Integer result = mQueue.poll(30, TimeUnit.SECONDS);
mQueue.clear();
assertNotNull(result);
Log.d(TAG, "Grant state retrieved " + result.intValue());
return result.intValue();
}
}
}