blob: 0159b12818dce87c7a8feb35b9531088b7878ab1 [file] [log] [blame]
/*
* Copyright (C) 2016 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.deviceowner;
import android.app.ActivityManager;
import android.app.admin.DeviceAdminReceiver;
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.Bundle;
import android.os.PersistableBundle;
import android.os.Process;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import java.lang.reflect.Field;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
/**
* Test {@link DevicePolicyManager#createAndManageUser}.
*/
public class CreateAndManageUserTest extends BaseDeviceOwnerTest {
private static final String TAG = "CreateAndManageUserTest";
private static final String BROADCAST_EXTRA = "broadcastExtra";
private static final String ACTION_EXTRA = "actionExtra";
private static final String SERIAL_EXTRA = "serialExtra";
private static final String PROFILE_OWNER_EXTRA = "profileOwnerExtra";
private static final String SETUP_COMPLETE_EXTRA = "setupCompleteExtra";
private static final int BROADCAST_TIMEOUT = 15_000;
private static final int USER_SWITCH_DELAY = 10_000;
private PackageManager mPackageManager;
private ActivityManager mActivityManager;
private volatile boolean mReceived;
private volatile boolean mTestProfileOwnerWasUsed;
private volatile boolean mSetupComplete;
private UserHandle mUserHandle;
@Override
protected void setUp() throws Exception {
super.setUp();
mPackageManager = mContext.getPackageManager();
mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
}
@Override
protected void tearDown() throws Exception {
mDevicePolicyManager.clearUserRestriction(getWho(), UserManager.DISALLOW_ADD_USER);
mDevicePolicyManager.clearUserRestriction(getWho(), UserManager.DISALLOW_REMOVE_USER);
// Remove user in case of failed test.
if (mUserHandle != null) {
mDevicePolicyManager.removeUser(getWho(), mUserHandle);
mUserHandle = null;
}
super.tearDown();
}
// This class is used by createAndManageUserTest as profile owner for the new user. When
// enabled, it sends a broadcast to signal success.
public static class TestProfileOwner extends DeviceAdminReceiver {
@Override
public void onEnabled(Context context, Intent intent) {
if (intent.getBooleanExtra(BROADCAST_EXTRA, false)) {
Intent i = new Intent(intent.getStringExtra(ACTION_EXTRA));
UserManager userManager = (UserManager)
context.getSystemService(Context.USER_SERVICE);
long serial = intent.getLongExtra(SERIAL_EXTRA, 0);
UserHandle handle = userManager.getUserForSerialNumber(serial);
i.putExtra(PROFILE_OWNER_EXTRA, true);
// find value of user_setup_complete on new user, and send the result back
try {
boolean setupComplete = (Settings.Secure.getInt(context.getContentResolver(),
"user_setup_complete") == 1);
i.putExtra(SETUP_COMPLETE_EXTRA, setupComplete);
} catch (Settings.SettingNotFoundException e) {
fail("Did not find settings user_setup_complete");
}
context.sendBroadcastAsUser(i, handle);
}
}
public static ComponentName getComponentName() {
return new ComponentName(CreateAndManageUserTest.class.getPackage().getName(),
TestProfileOwner.class.getName());
}
}
private void waitForBroadcastLocked() {
// Wait for broadcast. Time is measured in a while loop because of spurious wakeups.
final long initTime = System.currentTimeMillis();
while (!mReceived) {
try {
wait(BROADCAST_TIMEOUT - (System.currentTimeMillis() - initTime));
} catch (InterruptedException e) {
fail("InterruptedException: " + e.getMessage());
}
if (!mReceived && System.currentTimeMillis() - initTime > BROADCAST_TIMEOUT) {
fail("Timeout while waiting for broadcast after createAndManageUser.");
}
}
}
// Disabled due to b/29072728
// // This test will create a user that will get passed a bundle that we specify. The bundle will
// // contain an action and a serial (for user handle) to broadcast to notify the test that the
// // configuration was triggered.
// private void createAndManageUserTest(final int flags) {
// // This test sets a profile owner on the user, which requires the managed_users feature.
// if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS)) {
// return;
// }
//
// final boolean expectedSetupComplete = (flags & DevicePolicyManager.SKIP_SETUP_WIZARD) != 0;
// UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
//
// UserHandle firstUser = Process.myUserHandle();
// final String testUserName = "TestUser_" + System.currentTimeMillis();
// String action = "com.android.cts.TEST_USER_ACTION";
// PersistableBundle bundle = new PersistableBundle();
// bundle.putBoolean(BROADCAST_EXTRA, true);
// bundle.putLong(SERIAL_EXTRA, userManager.getSerialNumberForUser(firstUser));
// bundle.putString(ACTION_EXTRA, action);
//
// mReceived = false;
// mTestProfileOwnerWasUsed = false;
// mSetupComplete = !expectedSetupComplete;
// BroadcastReceiver receiver = new BroadcastReceiver() {
// @Override
// public void onReceive(Context context, Intent intent) {
// mReceived = true;
// if (intent.getBooleanExtra(PROFILE_OWNER_EXTRA, false)) {
// mTestProfileOwnerWasUsed = true;
// }
// mSetupComplete = intent.getBooleanExtra(SETUP_COMPLETE_EXTRA,
// !expectedSetupComplete);
// synchronized (CreateAndManageUserTest.this) {
// CreateAndManageUserTest.this.notify();
// }
// }
// };
//
// IntentFilter filter = new IntentFilter();
// filter.addAction(action);
// mContext.registerReceiver(receiver, filter);
//
// synchronized (this) {
// mUserHandle = mDevicePolicyManager.createAndManageUser(getWho(), testUserName,
// TestProfileOwner.getComponentName(), bundle, flags);
// assertNotNull(mUserHandle);
//
// mDevicePolicyManager.switchUser(getWho(), mUserHandle);
// try {
// wait(USER_SWITCH_DELAY);
// } catch (InterruptedException e) {
// fail("InterruptedException: " + e.getMessage());
// }
// mDevicePolicyManager.switchUser(getWho(), firstUser);
//
// waitForBroadcastLocked();
//
// assertTrue(mReceived);
// assertTrue(mTestProfileOwnerWasUsed);
// assertEquals(expectedSetupComplete, mSetupComplete);
//
// assertTrue(mDevicePolicyManager.removeUser(getWho(), mUserHandle));
//
// mUserHandle = null;
// }
//
// mContext.unregisterReceiver(receiver);
// }
/**
* Test creating an ephemeral user using the {@link DevicePolicyManager#createAndManageUser}
* method.
*
* <p>The test creates a user by calling to {@link DevicePolicyManager#createAndManageUser}. It
* doesn't remove the user afterwards, so its properties can be queried and tested by host-side
* tests.
* <p>The user's flags will be checked from the corresponding host-side test.
*/
public void testCreateAndManageEphemeralUser() throws Exception {
String testUserName = "TestUser_" + System.currentTimeMillis();
// Use reflection to get the value of the hidden flag to make the new user ephemeral.
Field field = DevicePolicyManager.class.getField("MAKE_USER_EPHEMERAL");
int makeEphemeralFlag = field.getInt(null);
// Do not assign return value to mUserHandle, so it is not removed in tearDown.
mDevicePolicyManager.createAndManageUser(
getWho(),
testUserName,
getWho(),
null,
makeEphemeralFlag);
}
/**
* Test creating an ephemeral user using the {@link DevicePolicyManager#createAndManageUser}
* method fails on systems without the split system user.
*
* <p>To be used by host-side test on systems without the split system user.
*/
public void testCreateAndManageEphemeralUserFails() throws Exception {
String testUserName = "TestUser_" + System.currentTimeMillis();
// Use reflection to get the value of the hidden flag to make the new user ephemeral.
Field field = DevicePolicyManager.class.getField("MAKE_USER_EPHEMERAL");
int makeEphemeralFlag = field.getInt(null);
try {
mDevicePolicyManager.createAndManageUser(
getWho(),
testUserName,
getWho(),
null,
makeEphemeralFlag);
} catch (IllegalArgumentException e) {
// Success, the expected exception was thrown.
return;
}
fail("createAndManageUser should have thrown IllegalArgumentException");
}
// Disabled due to b/29072728
// public void testCreateAndManageUser_SkipSetupWizard() {
// createAndManageUserTest(DevicePolicyManager.SKIP_SETUP_WIZARD);
// }
//
// public void testCreateAndManageUser_DontSkipSetupWizard() {
// if (!mActivityManager.isRunningInTestHarness()) {
// // In test harness, the setup wizard will be disabled by default, so this test is always
// // failing.
// createAndManageUserTest(0);
// }
// }
// createAndManageUser should circumvent the DISALLOW_ADD_USER restriction
public void testCreateAndManageUser_AddRestrictionSet() {
mDevicePolicyManager.addUserRestriction(getWho(), UserManager.DISALLOW_ADD_USER);
mUserHandle = mDevicePolicyManager.createAndManageUser(getWho(), "Test User", getWho(),
null, 0);
assertNotNull(mUserHandle);
}
public void testCreateAndManageUser_RemoveRestrictionSet() {
mDevicePolicyManager.addUserRestriction(getWho(), UserManager.DISALLOW_REMOVE_USER);
mUserHandle = mDevicePolicyManager.createAndManageUser(getWho(), "Test User", getWho(),
null, 0);
assertNotNull(mUserHandle);
boolean removed = mDevicePolicyManager.removeUser(getWho(), mUserHandle);
// When the device owner itself has set the user restriction, it should still be allowed
// to remove a user.
assertTrue(removed);
}
public void testUserAddedOrRemovedBroadcasts() throws InterruptedException {
LocalBroadcastReceiver receiver = new LocalBroadcastReceiver();
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(
getContext());
localBroadcastManager.registerReceiver(receiver, new IntentFilter(ACTION_USER_ADDED));
try {
mUserHandle = mDevicePolicyManager.createAndManageUser(getWho(), "Test User", getWho(),
null, 0);
assertNotNull(mUserHandle);
assertEquals(mUserHandle, receiver.waitForBroadcastReceived());
} finally {
localBroadcastManager.unregisterReceiver(receiver);
}
localBroadcastManager.registerReceiver(receiver, new IntentFilter(ACTION_USER_REMOVED));
try {
assertTrue(mDevicePolicyManager.removeUser(getWho(), mUserHandle));
assertEquals(mUserHandle, receiver.waitForBroadcastReceived());
mUserHandle = null;
} finally {
localBroadcastManager.unregisterReceiver(receiver);
}
}
static class LocalBroadcastReceiver extends BroadcastReceiver {
private LinkedBlockingQueue<UserHandle> mQueue = new LinkedBlockingQueue<UserHandle>(1);
@Override
public void onReceive(Context context, Intent intent) {
UserHandle userHandle = intent.getParcelableExtra(EXTRA_USER_HANDLE);
Log.d(TAG, "broadcast receiver received " + intent + " with userHandle "
+ userHandle);
mQueue.offer(userHandle);
}
public UserHandle waitForBroadcastReceived() throws InterruptedException {
return mQueue.poll(BROADCAST_TIMEOUT, TimeUnit.MILLISECONDS);
}
}
}