blob: cb0425a7cf43a7c55d70dc2d0d82278bc03f98ec [file] [log] [blame]
/*
* Copyright (C) 2013 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 android.admin.cts;
import android.app.Activity;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.deviceadmin.cts.CtsDeviceAdminBrokenReceiver;
import android.deviceadmin.cts.CtsDeviceAdminBrokenReceiver2;
import android.deviceadmin.cts.CtsDeviceAdminBrokenReceiver3;
import android.deviceadmin.cts.CtsDeviceAdminBrokenReceiver4;
import android.deviceadmin.cts.CtsDeviceAdminBrokenReceiver5;
import android.deviceadmin.cts.CtsDeviceAdminDeactivatedReceiver;
import android.deviceadmin.cts.CtsDeviceAdminActivationTestActivity;
import android.deviceadmin.cts.CtsDeviceAdminActivationTestActivity.OnActivityResultListener;
import android.os.SystemClock;
import android.test.ActivityInstrumentationTestCase2;
/**
* Tests for the standard way of activating a Device Admin: by starting system UI via an
* {@link Intent} with {@link DevicePolicyManager#ACTION_ADD_DEVICE_ADMIN}. The test requires that
* the {@code CtsDeviceAdmin.apk} be installed.
*/
public class DeviceAdminActivationTest
extends ActivityInstrumentationTestCase2<CtsDeviceAdminActivationTestActivity> {
// IMPLEMENTATION NOTE: Because Device Admin activation requires the use of
// Activity.startActivityForResult, this test creates an empty Activity which then invokes
// startActivityForResult.
private static final int REQUEST_CODE_ACTIVATE_ADMIN = 1;
/**
* Maximum duration of time (milliseconds) after which the effects of programmatic actions in
* this test should have affected the UI.
*/
private static final int UI_EFFECT_TIMEOUT_MILLIS = 5000;
/**
* Monitor guarding access to {@link #mLastOnActivityResultResultCode} and which is notified
* every time {@code onActivityResult} of the {@code CtsDeviceAdminActivationTestActivity} is
* invoked.
*/
private final Object mOnActivityResultListenerLock = new Object();
/**
* Result code of the most recent invocation of
* {@code CtsDeviceAdminActivationTestActivity.onActivityResult} or {@code null} if no
* invocations have occured yet.
*
* @GuardedBy {@link #mOnActivityResultListenerLock}
*/
private Integer mLastOnActivityResultResultCode;
public DeviceAdminActivationTest() {
super(CtsDeviceAdminActivationTestActivity.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
getActivity().setOnActivityResultListener(new OnActivityResultListener() {
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode != REQUEST_CODE_ACTIVATE_ADMIN) {
return;
}
synchronized (mOnActivityResultListenerLock) {
mLastOnActivityResultResultCode = resultCode;
mOnActivityResultListenerLock.notifyAll();
}
}
});
}
@Override
protected void tearDown() throws Exception {
try {
finishActivateDeviceAdminActivity();
} finally {
super.tearDown();
}
}
public void testActivateGoodReceiverDisplaysActivationUi() throws Exception {
assertDeviceAdminDeactivated(CtsDeviceAdminDeactivatedReceiver.class);
startAddDeviceAdminActivityForResult(CtsDeviceAdminDeactivatedReceiver.class);
assertWithTimeoutOnActivityResultNotInvoked();
// The UI is up and running. Assert that dismissing the UI returns the corresponding result
// to the test activity.
finishActivateDeviceAdminActivity();
assertWithTimeoutOnActivityResultInvokedWithResultCode(Activity.RESULT_CANCELED);
assertDeviceAdminDeactivated(CtsDeviceAdminDeactivatedReceiver.class);
}
public void testActivateBrokenReceiverFails() throws Exception {
assertDeviceAdminDeactivated(CtsDeviceAdminBrokenReceiver.class);
startAddDeviceAdminActivityForResult(CtsDeviceAdminBrokenReceiver.class);
assertWithTimeoutOnActivityResultInvokedWithResultCode(Activity.RESULT_CANCELED);
assertDeviceAdminDeactivated(CtsDeviceAdminBrokenReceiver.class);
}
public void testActivateBrokenReceiver2Fails() throws Exception {
assertDeviceAdminDeactivated(CtsDeviceAdminBrokenReceiver2.class);
startAddDeviceAdminActivityForResult(CtsDeviceAdminBrokenReceiver2.class);
assertWithTimeoutOnActivityResultInvokedWithResultCode(Activity.RESULT_CANCELED);
assertDeviceAdminDeactivated(CtsDeviceAdminBrokenReceiver2.class);
}
public void testActivateBrokenReceiver3Fails() throws Exception {
assertDeviceAdminDeactivated(CtsDeviceAdminBrokenReceiver3.class);
startAddDeviceAdminActivityForResult(CtsDeviceAdminBrokenReceiver3.class);
assertWithTimeoutOnActivityResultInvokedWithResultCode(Activity.RESULT_CANCELED);
assertDeviceAdminDeactivated(CtsDeviceAdminBrokenReceiver3.class);
}
public void testActivateBrokenReceiver4Fails() throws Exception {
assertDeviceAdminDeactivated(CtsDeviceAdminBrokenReceiver4.class);
startAddDeviceAdminActivityForResult(CtsDeviceAdminBrokenReceiver4.class);
assertWithTimeoutOnActivityResultInvokedWithResultCode(Activity.RESULT_CANCELED);
assertDeviceAdminDeactivated(CtsDeviceAdminBrokenReceiver4.class);
}
public void testActivateBrokenReceiver5Fails() throws Exception {
assertDeviceAdminDeactivated(CtsDeviceAdminBrokenReceiver5.class);
startAddDeviceAdminActivityForResult(CtsDeviceAdminBrokenReceiver5.class);
assertWithTimeoutOnActivityResultInvokedWithResultCode(Activity.RESULT_CANCELED);
assertDeviceAdminDeactivated(CtsDeviceAdminBrokenReceiver5.class);
}
private void startAddDeviceAdminActivityForResult(Class<?> receiverClass) {
getActivity().startActivityForResult(
getAddDeviceAdminIntent(receiverClass),
REQUEST_CODE_ACTIVATE_ADMIN);
}
private Intent getAddDeviceAdminIntent(Class<?> receiverClass) {
return new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN)
.putExtra(
DevicePolicyManager.EXTRA_DEVICE_ADMIN,
new ComponentName(
getInstrumentation().getTargetContext(),
receiverClass));
}
private void assertWithTimeoutOnActivityResultNotInvoked() {
SystemClock.sleep(UI_EFFECT_TIMEOUT_MILLIS);
synchronized (mOnActivityResultListenerLock) {
assertNull(mLastOnActivityResultResultCode);
}
}
private void assertWithTimeoutOnActivityResultInvokedWithResultCode(int expectedResultCode)
throws Exception {
long deadlineMillis = SystemClock.elapsedRealtime() + UI_EFFECT_TIMEOUT_MILLIS;
synchronized (mOnActivityResultListenerLock) {
while (true) {
if (mLastOnActivityResultResultCode != null) {
// onActivityResult has been invoked -- check the arguments
assertEquals(expectedResultCode, (int) mLastOnActivityResultResultCode);
break;
}
// onActivityResult has not yet been invoked -- wait until it is
long millisTillDeadline = deadlineMillis - SystemClock.elapsedRealtime();
if (millisTillDeadline <= 0) {
fail("onActivityResult not invoked within " + UI_EFFECT_TIMEOUT_MILLIS + " ms");
break;
}
mOnActivityResultListenerLock.wait(millisTillDeadline);
}
}
}
private void finishActivateDeviceAdminActivity() {
getActivity().finishActivity(REQUEST_CODE_ACTIVATE_ADMIN);
}
private void assertDeviceAdminDeactivated(Class<?> receiverClass) {
DevicePolicyManager devicePolicyManager =
(DevicePolicyManager) getActivity().getSystemService(
Context.DEVICE_POLICY_SERVICE);
assertFalse(devicePolicyManager.isAdminActive(
new ComponentName(getInstrumentation().getTargetContext(), receiverClass)));
}
}