Merge "Cleanup some more DPM tests to use runAsCaller."

This commit is contained in:
Pavel Grafov
2017-05-23 10:12:42 +00:00
committed by Android (Google) Code Review
7 changed files with 976 additions and 944 deletions

View File

@@ -47,14 +47,14 @@ public class DevicePolicyManagerServiceMigrationTest extends DpmTestBase {
mContext = getContext();
when(mContext.packageManager.hasSystemFeature(eq(PackageManager.FEATURE_DEVICE_ADMIN)))
when(getServices().packageManager.hasSystemFeature(eq(PackageManager.FEATURE_DEVICE_ADMIN)))
.thenReturn(true);
}
public void testMigration() throws Exception {
final File user10dir = mMockContext.addUser(10, 0);
final File user11dir = mMockContext.addUser(11, UserInfo.FLAG_MANAGED_PROFILE);
mMockContext.addUser(12, 0);
final File user10dir = getServices().addUser(10, 0);
final File user11dir = getServices().addUser(11, UserInfo.FLAG_MANAGED_PROFILE);
getServices().addUser(12, 0);
setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
setUpPackageManagerForAdmin(admin2, UserHandle.getUid(10, 123));
@@ -62,12 +62,12 @@ public class DevicePolicyManagerServiceMigrationTest extends DpmTestBase {
// Create the legacy owners & policies file.
DpmTestUtils.writeToFile(
(new File(mContext.dataDir, OwnersTestable.LEGACY_FILE)).getAbsoluteFile(),
(new File(getServices().dataDir, OwnersTestable.LEGACY_FILE)).getAbsoluteFile(),
DpmTestUtils.readAsset(mRealTestContext,
"DevicePolicyManagerServiceMigrationTest/legacy_device_owner.xml"));
DpmTestUtils.writeToFile(
(new File(mContext.systemUserDataDir, "device_policies.xml")).getAbsoluteFile(),
(new File(getServices().systemUserDataDir, "device_policies.xml")).getAbsoluteFile(),
DpmTestUtils.readAsset(mRealTestContext,
"DevicePolicyManagerServiceMigrationTest/legacy_device_policies.xml"));
@@ -81,12 +81,12 @@ public class DevicePolicyManagerServiceMigrationTest extends DpmTestBase {
"DevicePolicyManagerServiceMigrationTest/legacy_device_policies_11.xml"));
// Set up UserManager
when(mMockContext.userManagerInternal.getBaseUserRestrictions(
when(getServices().userManagerInternal.getBaseUserRestrictions(
eq(UserHandle.USER_SYSTEM))).thenReturn(DpmTestUtils.newRestrictions(
UserManager.DISALLOW_ADD_USER,
UserManager.DISALLOW_RECORD_AUDIO));
when(mMockContext.userManagerInternal.getBaseUserRestrictions(
when(getServices().userManagerInternal.getBaseUserRestrictions(
eq(10))).thenReturn(DpmTestUtils.newRestrictions(
UserManager.DISALLOW_REMOVE_USER,
UserManager.DISALLOW_ADD_USER,
@@ -95,7 +95,7 @@ public class DevicePolicyManagerServiceMigrationTest extends DpmTestBase {
UserManager.DISALLOW_WALLPAPER,
UserManager.DISALLOW_RECORD_AUDIO));
when(mMockContext.userManagerInternal.getBaseUserRestrictions(
when(getServices().userManagerInternal.getBaseUserRestrictions(
eq(11))).thenReturn(DpmTestUtils.newRestrictions(
UserManager.DISALLOW_REMOVE_USER,
UserManager.DISALLOW_ADD_USER,
@@ -113,7 +113,7 @@ public class DevicePolicyManagerServiceMigrationTest extends DpmTestBase {
newBaseRestrictions.put(userId, bundle);
return null;
}).when(mContext.userManagerInternal).setBaseUserRestrictionsByDpmsForMigration(
}).when(getServices().userManagerInternal).setBaseUserRestrictionsByDpmsForMigration(
anyInt(), any(Bundle.class));
// Initialize DPM/DPMS and let it migrate the persisted information.
@@ -125,7 +125,7 @@ public class DevicePolicyManagerServiceMigrationTest extends DpmTestBase {
try {
LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
dpms = new DevicePolicyManagerServiceTestable(mContext, dataDir);
dpms = new DevicePolicyManagerServiceTestable(getServices(), mContext);
dpms.systemReady(SystemService.PHASE_LOCK_SETTINGS_READY);
dpms.systemReady(SystemService.PHASE_BOOT_COMPLETED);
@@ -200,17 +200,17 @@ public class DevicePolicyManagerServiceMigrationTest extends DpmTestBase {
// Create the legacy owners & policies file.
DpmTestUtils.writeToFile(
(new File(mContext.dataDir, OwnersTestable.LEGACY_FILE)).getAbsoluteFile(),
(new File(getServices().dataDir, OwnersTestable.LEGACY_FILE)).getAbsoluteFile(),
DpmTestUtils.readAsset(mRealTestContext,
"DevicePolicyManagerServiceMigrationTest2/legacy_device_owner.xml"));
DpmTestUtils.writeToFile(
(new File(mContext.systemUserDataDir, "device_policies.xml")).getAbsoluteFile(),
(new File(getServices().systemUserDataDir, "device_policies.xml")).getAbsoluteFile(),
DpmTestUtils.readAsset(mRealTestContext,
"DevicePolicyManagerServiceMigrationTest2/legacy_device_policies.xml"));
// Set up UserManager
when(mMockContext.userManagerInternal.getBaseUserRestrictions(
when(getServices().userManagerInternal.getBaseUserRestrictions(
eq(UserHandle.USER_SYSTEM))).thenReturn(DpmTestUtils.newRestrictions(
UserManager.DISALLOW_ADD_USER,
UserManager.DISALLOW_RECORD_AUDIO,
@@ -226,7 +226,7 @@ public class DevicePolicyManagerServiceMigrationTest extends DpmTestBase {
newBaseRestrictions.put(userId, bundle);
return null;
}).when(mContext.userManagerInternal).setBaseUserRestrictionsByDpmsForMigration(
}).when(getServices().userManagerInternal).setBaseUserRestrictionsByDpmsForMigration(
anyInt(), any(Bundle.class));
// Initialize DPM/DPMS and let it migrate the persisted information.
@@ -238,7 +238,7 @@ public class DevicePolicyManagerServiceMigrationTest extends DpmTestBase {
try {
LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
dpms = new DevicePolicyManagerServiceTestable(mContext, dataDir);
dpms = new DevicePolicyManagerServiceTestable(getServices(), mContext);
dpms.systemReady(SystemService.PHASE_LOCK_SETTINGS_READY);
dpms.systemReady(SystemService.PHASE_BOOT_COMPLETED);
@@ -273,18 +273,18 @@ public class DevicePolicyManagerServiceMigrationTest extends DpmTestBase {
// Test setting default restrictions for managed profile.
public void testMigration3_managedProfileOwner() throws Exception {
// Create a managed profile user.
final File user10dir = mMockContext.addUser(10, UserInfo.FLAG_MANAGED_PROFILE);
final File user10dir = getServices().addUser(10, UserInfo.FLAG_MANAGED_PROFILE);
// Profile owner package for managed profile user.
setUpPackageManagerForAdmin(admin1, UserHandle.getUid(10, 123));
// Set up fake UserManager to make it look like a managed profile.
when(mMockContext.userManager.isManagedProfile(eq(10))).thenReturn(true);
when(getServices().userManager.isManagedProfile(eq(10))).thenReturn(true);
// Set up fake Settings to make it look like INSTALL_NON_MARKET_APPS was reversed.
when(mMockContext.settings.settingsSecureGetIntForUser(
when(getServices().settings.settingsSecureGetIntForUser(
eq(Settings.Secure.UNKNOWN_SOURCES_DEFAULT_REVERSED),
eq(0), eq(10))).thenReturn(1);
// Write policy and owners files.
DpmTestUtils.writeToFile(
(new File(mContext.systemUserDataDir, "device_policies.xml")).getAbsoluteFile(),
(new File(getServices().systemUserDataDir, "device_policies.xml")).getAbsoluteFile(),
DpmTestUtils.readAsset(mRealTestContext,
"DevicePolicyManagerServiceMigrationTest3/system_device_policies.xml"));
DpmTestUtils.writeToFile(
@@ -304,7 +304,7 @@ public class DevicePolicyManagerServiceMigrationTest extends DpmTestBase {
try {
LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
dpms = new DevicePolicyManagerServiceTestable(mContext, dataDir);
dpms = new DevicePolicyManagerServiceTestable(getServices(), mContext);
dpms.systemReady(SystemService.PHASE_LOCK_SETTINGS_READY);
dpms.systemReady(SystemService.PHASE_BOOT_COMPLETED);

View File

@@ -61,11 +61,12 @@ public class DevicePolicyManagerServiceTestable extends DevicePolicyManagerServi
private final File mDeviceOwnerFile;
private final File mUsersDataDir;
public OwnersTestable(DpmMockContext context) {
super(context.userManager, context.userManagerInternal, context.packageManagerInternal);
mLegacyFile = new File(context.dataDir, LEGACY_FILE);
mDeviceOwnerFile = new File(context.dataDir, DEVICE_OWNER_FILE);
mUsersDataDir = new File(context.dataDir, "users");
public OwnersTestable(MockSystemServices services) {
super(services.userManager, services.userManagerInternal,
services.packageManagerInternal);
mLegacyFile = new File(services.dataDir, LEGACY_FILE);
mDeviceOwnerFile = new File(services.dataDir, DEVICE_OWNER_FILE);
mUsersDataDir = new File(services.dataDir, "users");
}
@Override
@@ -88,8 +89,8 @@ public class DevicePolicyManagerServiceTestable extends DevicePolicyManagerServi
public final DpmMockContext context;
private final MockInjector mMockInjector;
public DevicePolicyManagerServiceTestable(DpmMockContext context, File dataDir) {
this(new MockInjector(context, dataDir));
public DevicePolicyManagerServiceTestable(MockSystemServices services, DpmMockContext context) {
this(new MockInjector(services, context));
}
private DevicePolicyManagerServiceTestable(MockInjector injector) {
@@ -100,15 +101,13 @@ public class DevicePolicyManagerServiceTestable extends DevicePolicyManagerServi
public void notifyChangeToContentObserver(Uri uri, int userHandle) {
ContentObserver co = mMockInjector.mContentObservers
.get(new Pair<Uri, Integer>(uri, userHandle));
ContentObserver co = mMockInjector.mContentObservers.get(new Pair<>(uri, userHandle));
if (co != null) {
co.onChange(false, uri, userHandle); // notify synchronously
}
// Notify USER_ALL observer too.
co = mMockInjector.mContentObservers
.get(new Pair<Uri, Integer>(uri, UserHandle.USER_ALL));
co = mMockInjector.mContentObservers.get(new Pair<>(uri, UserHandle.USER_ALL));
if (co != null) {
co.onChange(false, uri, userHandle); // notify synchronously
}
@@ -118,76 +117,75 @@ public class DevicePolicyManagerServiceTestable extends DevicePolicyManagerServi
private static class MockInjector extends Injector {
public final DpmMockContext context;
public final File dataDir;
private final MockSystemServices services;
// Key is a pair of uri and userId
private final Map<Pair<Uri, Integer>, ContentObserver> mContentObservers = new ArrayMap<>();
private MockInjector(DpmMockContext context, File dataDir) {
private MockInjector(MockSystemServices services, DpmMockContext context) {
super(context);
this.services = services;
this.context = context;
this.dataDir = dataDir;
}
@Override
Owners newOwners() {
return new OwnersTestable(context);
return new OwnersTestable(services);
}
@Override
UserManager getUserManager() {
return context.userManager;
return services.userManager;
}
@Override
UserManagerInternal getUserManagerInternal() {
return context.userManagerInternal;
return services.userManagerInternal;
}
@Override
PackageManagerInternal getPackageManagerInternal() {
return context.packageManagerInternal;
return services.packageManagerInternal;
}
@Override
PowerManagerInternal getPowerManagerInternal() {
return context.powerManagerInternal;
return services.powerManagerInternal;
}
@Override
NotificationManager getNotificationManager() {
return context.notificationManager;
return services.notificationManager;
}
@Override
IIpConnectivityMetrics getIIpConnectivityMetrics() {
return context.iipConnectivityMetrics;
return services.iipConnectivityMetrics;
}
@Override
IWindowManager getIWindowManager() {
return context.iwindowManager;
return services.iwindowManager;
}
@Override
IActivityManager getIActivityManager() {
return context.iactivityManager;
return services.iactivityManager;
}
@Override
IPackageManager getIPackageManager() {
return context.ipackageManager;
return services.ipackageManager;
}
@Override
IBackupManager getIBackupManager() {
return context.ibackupManager;
return services.ibackupManager;
}
@Override
IAudioService getIAudioService() {
return context.iaudioService;
return services.iaudioService;
}
@Override
@@ -197,32 +195,32 @@ public class DevicePolicyManagerServiceTestable extends DevicePolicyManagerServi
@Override
LockPatternUtils newLockPatternUtils() {
return context.lockPatternUtils;
return services.lockPatternUtils;
}
@Override
boolean storageManagerIsFileBasedEncryptionEnabled() {
return context.storageManager.isFileBasedEncryptionEnabled();
return services.storageManager.isFileBasedEncryptionEnabled();
}
@Override
boolean storageManagerIsNonDefaultBlockEncrypted() {
return context.storageManager.isNonDefaultBlockEncrypted();
return services.storageManager.isNonDefaultBlockEncrypted();
}
@Override
boolean storageManagerIsEncrypted() {
return context.storageManager.isEncrypted();
return services.storageManager.isEncrypted();
}
@Override
boolean storageManagerIsEncryptable() {
return context.storageManager.isEncryptable();
return services.storageManager.isEncryptable();
}
@Override
String getDevicePolicyFilePathForSystemUser() {
return context.systemUserDataDir.getAbsolutePath() + "/";
return services.systemUserDataDir.getAbsolutePath() + "/";
}
@Override
@@ -257,53 +255,53 @@ public class DevicePolicyManagerServiceTestable extends DevicePolicyManagerServi
@Override
File environmentGetUserSystemDirectory(int userId) {
return context.environment.getUserSystemDirectory(userId);
return services.environment.getUserSystemDirectory(userId);
}
@Override
void powerManagerGoToSleep(long time, int reason, int flags) {
context.powerManager.goToSleep(time, reason, flags);
services.powerManager.goToSleep(time, reason, flags);
}
@Override
void powerManagerReboot(String reason) {
context.powerManager.reboot(reason);
services.powerManager.reboot(reason);
}
@Override
void recoverySystemRebootWipeUserData(boolean shutdown, String reason, boolean force)
throws IOException {
context.recoverySystem.rebootWipeUserData(shutdown, reason, force);
services.recoverySystem.rebootWipeUserData(shutdown, reason, force);
}
@Override
boolean systemPropertiesGetBoolean(String key, boolean def) {
return context.systemProperties.getBoolean(key, def);
return services.systemProperties.getBoolean(key, def);
}
@Override
long systemPropertiesGetLong(String key, long def) {
return context.systemProperties.getLong(key, def);
return services.systemProperties.getLong(key, def);
}
@Override
String systemPropertiesGet(String key, String def) {
return context.systemProperties.get(key, def);
return services.systemProperties.get(key, def);
}
@Override
String systemPropertiesGet(String key) {
return context.systemProperties.get(key);
return services.systemProperties.get(key);
}
@Override
void systemPropertiesSet(String key, String value) {
context.systemProperties.set(key, value);
services.systemProperties.set(key, value);
}
@Override
boolean userManagerIsSplitSystemUser() {
return context.userManagerForMock.isSplitSystemUser();
return services.userManagerForMock.isSplitSystemUser();
}
@Override
@@ -320,87 +318,87 @@ public class DevicePolicyManagerServiceTestable extends DevicePolicyManagerServi
@Override
int settingsSecureGetIntForUser(String name, int def, int userHandle) {
return context.settings.settingsSecureGetIntForUser(name, def, userHandle);
return services.settings.settingsSecureGetIntForUser(name, def, userHandle);
}
@Override
String settingsSecureGetStringForUser(String name, int userHandle) {
return context.settings.settingsSecureGetStringForUser(name, userHandle);
return services.settings.settingsSecureGetStringForUser(name, userHandle);
}
@Override
void settingsSecurePutIntForUser(String name, int value, int userHandle) {
context.settings.settingsSecurePutIntForUser(name, value, userHandle);
services.settings.settingsSecurePutIntForUser(name, value, userHandle);
}
@Override
void settingsSecurePutStringForUser(String name, String value, int userHandle) {
context.settings.settingsSecurePutStringForUser(name, value, userHandle);
services.settings.settingsSecurePutStringForUser(name, value, userHandle);
}
@Override
void settingsGlobalPutStringForUser(String name, String value, int userHandle) {
context.settings.settingsGlobalPutStringForUser(name, value, userHandle);
services.settings.settingsGlobalPutStringForUser(name, value, userHandle);
}
@Override
void settingsSecurePutInt(String name, int value) {
context.settings.settingsSecurePutInt(name, value);
services.settings.settingsSecurePutInt(name, value);
}
@Override
void settingsGlobalPutInt(String name, int value) {
context.settings.settingsGlobalPutInt(name, value);
services.settings.settingsGlobalPutInt(name, value);
}
@Override
void settingsSecurePutString(String name, String value) {
context.settings.settingsSecurePutString(name, value);
services.settings.settingsSecurePutString(name, value);
}
@Override
void settingsGlobalPutString(String name, String value) {
context.settings.settingsGlobalPutString(name, value);
services.settings.settingsGlobalPutString(name, value);
}
@Override
int settingsGlobalGetInt(String name, int def) {
return context.settings.settingsGlobalGetInt(name, def);
return services.settings.settingsGlobalGetInt(name, def);
}
@Override
String settingsGlobalGetString(String name) {
return context.settings.settingsGlobalGetString(name);
return services.settings.settingsGlobalGetString(name);
}
@Override
void securityLogSetLoggingEnabledProperty(boolean enabled) {
context.settings.securityLogSetLoggingEnabledProperty(enabled);
services.settings.securityLogSetLoggingEnabledProperty(enabled);
}
@Override
boolean securityLogGetLoggingEnabledProperty() {
return context.settings.securityLogGetLoggingEnabledProperty();
return services.settings.securityLogGetLoggingEnabledProperty();
}
@Override
boolean securityLogIsLoggingEnabled() {
return context.settings.securityLogIsLoggingEnabled();
return services.settings.securityLogIsLoggingEnabled();
}
@Override
TelephonyManager getTelephonyManager() {
return context.telephonyManager;
return services.telephonyManager;
}
@Override
boolean isBuildDebuggable() {
return context.buildMock.isDebuggable;
return services.buildMock.isDebuggable;
}
@Override
KeyChain.KeyChainConnection keyChainBindAsUser(UserHandle user) {
return context.keyChainConnection;
return services.keyChainConnection;
}
}
}

View File

@@ -16,61 +16,27 @@
package com.android.server.devicepolicy;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.AlarmManager;
import android.app.IActivityManager;
import android.app.NotificationManager;
import android.app.backup.IBackupManager;
import static org.mockito.Mockito.mock;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.media.IAudioService;
import android.net.IIpConnectivityMetrics;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.PowerManager.WakeLock;
import android.os.PowerManagerInternal;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.UserManagerInternal;
import android.security.KeyChain;
import android.telephony.TelephonyManager;
import android.test.mock.MockContentResolver;
import android.test.mock.MockContext;
import android.util.ArrayMap;
import android.util.Pair;
import android.view.IWindowManager;
import com.android.internal.widget.LockPatternUtils;
import org.junit.Assert;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
/**
* Context used throughout DPMS tests.
@@ -107,9 +73,10 @@ public class DpmMockContext extends MockContext {
public static final int SYSTEM_PID = 11111;
public static final String ANOTHER_PACKAGE_NAME = "com.another.package.name";
public static final int ANOTHER_UID = UserHandle.getUid(UserHandle.USER_SYSTEM, 18434);
private final MockSystemServices mMockSystemServices;
public static class MockBinder {
public int callingUid = CALLER_UID;
public int callingPid = CALLER_PID;
@@ -144,130 +111,7 @@ public class DpmMockContext extends MockContext {
}
}
public static class EnvironmentForMock {
public File getUserSystemDirectory(int userId) {
return null;
}
}
public static class BuildMock {
public boolean isDebuggable = true;
}
public static class PowerManagerForMock {
public WakeLock newWakeLock(int levelAndFlags, String tag) {
return null;
}
public void goToSleep(long time, int reason, int flags) {
}
public void reboot(String reason) {
}
}
public static class RecoverySystemForMock {
public void rebootWipeUserData(
boolean shutdown, String reason, boolean force) throws IOException {
}
}
public static class SystemPropertiesForMock {
public boolean getBoolean(String key, boolean def) {
return false;
}
public long getLong(String key, long def) {
return 0;
}
public String get(String key, String def) {
return null;
}
public String get(String key) {
return null;
}
public void set(String key, String value) {
}
}
public static class UserManagerForMock {
public boolean isSplitSystemUser() {
return false;
}
}
public static class SettingsForMock {
public int settingsSecureGetIntForUser(String name, int def, int userHandle) {
return 0;
}
public String settingsSecureGetStringForUser(String name, int userHandle) {
return null;
}
public void settingsSecurePutIntForUser(String name, int value, int userHandle) {
}
public void settingsSecurePutStringForUser(String name, String value, int userHandle) {
}
public void settingsGlobalPutStringForUser(String name, String value, int userHandle) {
}
public void settingsSecurePutInt(String name, int value) {
}
public void settingsGlobalPutInt(String name, int value) {
}
public void settingsSecurePutString(String name, String value) {
}
public void settingsGlobalPutString(String name, String value) {
}
public int settingsGlobalGetInt(String name, int value) {
return 0;
}
public String settingsGlobalGetString(String name) {
return "";
}
public void securityLogSetLoggingEnabledProperty(boolean enabled) {
}
public boolean securityLogGetLoggingEnabledProperty() {
return false;
}
public boolean securityLogIsLoggingEnabled() {
return false;
}
}
public static class StorageManagerForMock {
public boolean isFileBasedEncryptionEnabled() {
return false;
}
public boolean isNonDefaultBlockEncrypted() {
return false;
}
public boolean isEncrypted() {
return false;
}
public boolean isEncryptable() {
return false;
}
}
public final Context realTestContext;
private final Context realTestContext;
/**
* Use this instance to verify unimplemented methods such as {@link #sendBroadcast}.
@@ -276,39 +120,8 @@ public class DpmMockContext extends MockContext {
*/
public final Context spiedContext;
public final File dataDir;
public final File systemUserDataDir;
public final MockBinder binder;
public final EnvironmentForMock environment;
public final Resources resources;
public final SystemPropertiesForMock systemProperties;
public final UserManager userManager;
public final UserManagerInternal userManagerInternal;
public final PackageManagerInternal packageManagerInternal;
public final UserManagerForMock userManagerForMock;
public final PowerManagerForMock powerManager;
public final PowerManagerInternal powerManagerInternal;
public final RecoverySystemForMock recoverySystem;
public final NotificationManager notificationManager;
public final IIpConnectivityMetrics iipConnectivityMetrics;
public final IWindowManager iwindowManager;
public final IActivityManager iactivityManager;
public final IPackageManager ipackageManager;
public final IBackupManager ibackupManager;
public final IAudioService iaudioService;
public final LockPatternUtils lockPatternUtils;
public final StorageManagerForMock storageManager;
public final WifiManager wifiManager;
public final SettingsForMock settings;
public final MockContentResolver contentResolver;
public final TelephonyManager telephonyManager;
public final AccountManager accountManager;
public final AlarmManager alarmManager;
public final KeyChain.KeyChainConnection keyChainConnection;
/** Note this is a partial mock, not a real mock. */
public final PackageManager packageManager;
/** TODO: Migrate everything to use {@link #permissions} to avoid confusion. */
@Deprecated
@@ -317,246 +130,17 @@ public class DpmMockContext extends MockContext {
/** Less confusing alias for {@link #callerPermissions}. */
public final List<String> permissions = callerPermissions;
private final ArrayList<UserInfo> mUserInfos = new ArrayList<>();
public final BuildMock buildMock = new BuildMock();
/** Optional mapping of other user contexts for {@link #createPackageContextAsUser} to return */
public final Map<Pair<UserHandle, String>, Context> userPackageContexts = new ArrayMap<>();
public String packageName = null;
public ApplicationInfo applicationInfo = null;
// We have to keep track of broadcast receivers registered for a given intent ourselves as the
// DPM unit tests mock out the package manager and PackageManager.queryBroadcastReceivers() does
// not work.
private class BroadcastReceiverRegistration {
public final BroadcastReceiver receiver;
public final IntentFilter filter;
public final Handler scheduler;
// Exceptions thrown in a background thread kill the whole test. Save them instead.
public final AtomicReference<Exception> backgroundException = new AtomicReference<>();
public BroadcastReceiverRegistration(BroadcastReceiver receiver, IntentFilter filter,
Handler scheduler) {
this.receiver = receiver;
this.filter = filter;
this.scheduler = scheduler;
}
public void sendBroadcastIfApplicable(int userId, Intent intent) {
final BroadcastReceiver.PendingResult result = new BroadcastReceiver.PendingResult(
0 /* resultCode */, null /* resultData */, null /* resultExtras */,
0 /* type */, false /* ordered */, false /* sticky */, null /* token */, userId,
0 /* flags */);
if (filter.match(null, intent, false, "DpmMockContext") > 0) {
final Runnable send = () -> {
receiver.setPendingResult(result);
receiver.onReceive(DpmMockContext.this, intent);
};
if (scheduler != null) {
scheduler.post(() -> {
try {
send.run();
} catch (Exception e) {
backgroundException.compareAndSet(null, e);
}
});
} else {
send.run();
}
}
}
}
private List<BroadcastReceiverRegistration> mBroadcastReceivers = new ArrayList<>();
public DpmMockContext(Context realTestContext, String name) {
this(realTestContext, new File(realTestContext.getCacheDir(), name));
}
public DpmMockContext(Context context, File dataDir) {
public DpmMockContext(MockSystemServices mockSystemServices, Context context) {
mMockSystemServices = mockSystemServices;
realTestContext = context;
this.dataDir = dataDir;
DpmTestUtils.clearDir(dataDir);
binder = new MockBinder();
environment = mock(EnvironmentForMock.class);
resources = mock(Resources.class);
systemProperties = mock(SystemPropertiesForMock.class);
userManager = mock(UserManager.class);
userManagerInternal = mock(UserManagerInternal.class);
userManagerForMock = mock(UserManagerForMock.class);
packageManagerInternal = mock(PackageManagerInternal.class);
powerManager = mock(PowerManagerForMock.class);
powerManagerInternal = mock(PowerManagerInternal.class);
recoverySystem = mock(RecoverySystemForMock.class);
notificationManager = mock(NotificationManager.class);
iipConnectivityMetrics = mock(IIpConnectivityMetrics.class);
iwindowManager = mock(IWindowManager.class);
iactivityManager = mock(IActivityManager.class);
ipackageManager = mock(IPackageManager.class);
ibackupManager = mock(IBackupManager.class);
iaudioService = mock(IAudioService.class);
lockPatternUtils = mock(LockPatternUtils.class);
storageManager = mock(StorageManagerForMock.class);
wifiManager = mock(WifiManager.class);
settings = mock(SettingsForMock.class);
telephonyManager = mock(TelephonyManager.class);
accountManager = mock(AccountManager.class);
alarmManager = mock(AlarmManager.class);
keyChainConnection = mock(KeyChain.KeyChainConnection.class, RETURNS_DEEP_STUBS);
// Package manager is huge, so we use a partial mock instead.
packageManager = spy(context.getPackageManager());
spiedContext = mock(Context.class);
contentResolver = new MockContentResolver();
// Add the system user with a fake profile group already set up (this can happen in the real
// world if a managed profile is added and then removed).
systemUserDataDir =
addUser(UserHandle.USER_SYSTEM, UserInfo.FLAG_PRIMARY, UserHandle.USER_SYSTEM);
// System user is always running.
setUserRunning(UserHandle.USER_SYSTEM, true);
}
public File addUser(int userId, int flags) {
return addUser(userId, flags, UserInfo.NO_PROFILE_GROUP_ID);
}
public File addUser(int userId, int flags, int profileGroupId) {
// Set up (default) UserInfo for CALLER_USER_HANDLE.
final UserInfo uh = new UserInfo(userId, "user" + userId, flags);
uh.profileGroupId = profileGroupId;
when(userManager.getUserInfo(eq(userId))).thenReturn(uh);
mUserInfos.add(uh);
when(userManager.getUsers()).thenReturn(mUserInfos);
when(userManager.getUsers(anyBoolean())).thenReturn(mUserInfos);
when(userManager.isUserRunning(eq(new UserHandle(userId)))).thenReturn(true);
when(userManager.getUserInfo(anyInt())).thenAnswer(
new Answer<UserInfo>() {
@Override
public UserInfo answer(InvocationOnMock invocation) throws Throwable {
final int userId = (int) invocation.getArguments()[0];
return getUserInfo(userId);
}
}
);
when(userManager.getProfiles(anyInt())).thenAnswer(
new Answer<List<UserInfo>>() {
@Override
public List<UserInfo> answer(InvocationOnMock invocation) throws Throwable {
final int userId = (int) invocation.getArguments()[0];
return getProfiles(userId);
}
}
);
when(userManager.getProfileIdsWithDisabled(anyInt())).thenAnswer(
new Answer<int[]>() {
@Override
public int[] answer(InvocationOnMock invocation) throws Throwable {
final int userId = (int) invocation.getArguments()[0];
List<UserInfo> profiles = getProfiles(userId);
return profiles.stream()
.mapToInt(profile -> profile.id)
.toArray();
}
}
);
when(accountManager.getAccountsAsUser(anyInt())).thenReturn(new Account[0]);
// Create a data directory.
final File dir = new File(dataDir, "users/" + userId);
DpmTestUtils.clearDir(dir);
when(environment.getUserSystemDirectory(eq(userId))).thenReturn(dir);
return dir;
}
public void removeUser(int userId) {
for (int i = 0; i < mUserInfos.size(); i++) {
if (mUserInfos.get(i).id == userId) {
mUserInfos.remove(i);
break;
}
}
when(userManager.getUserInfo(eq(userId))).thenReturn(null);
when(userManager.isUserRunning(eq(new UserHandle(userId)))).thenReturn(false);
}
private UserInfo getUserInfo(int userId) {
for (UserInfo ui : mUserInfos) {
if (ui.id == userId) {
return ui;
}
}
return null;
}
private List<UserInfo> getProfiles(int userId) {
final ArrayList<UserInfo> ret = new ArrayList<UserInfo>();
UserInfo parent = null;
for (UserInfo ui : mUserInfos) {
if (ui.id == userId) {
parent = ui;
break;
}
}
if (parent == null) {
return ret;
}
for (UserInfo ui : mUserInfos) {
if (ui == parent
|| ui.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID
&& ui.profileGroupId == parent.profileGroupId) {
ret.add(ui);
}
}
return ret;
}
/**
* Add multiple users at once. They'll all have flag 0.
*/
public void addUsers(int... userIds) {
for (int userId : userIds) {
addUser(userId, 0);
}
}
public void setUserRunning(int userId, boolean isRunning) {
when(userManager.isUserRunning(MockUtils.checkUserHandle(userId)))
.thenReturn(isRunning);
}
public void injectBroadcast(final Intent intent) {
final int userId = UserHandle.getUserId(binder.getCallingUid());
for (final BroadcastReceiverRegistration receiver : mBroadcastReceivers) {
receiver.sendBroadcastIfApplicable(userId, intent);
}
}
public void rethrowBackgroundBroadcastExceptions() throws Exception {
for (final BroadcastReceiverRegistration receiver : mBroadcastReceivers) {
final Exception e = receiver.backgroundException.getAndSet(null);
if (e != null) {
throw e;
}
}
}
public void addPackageContext(UserHandle user, Context context) {
if (context.getPackageName() == null) {
throw new NullPointerException("getPackageName() == null");
}
userPackageContexts.put(new Pair<>(user, context.getPackageName()), context);
}
@Override
@@ -589,15 +173,15 @@ public class DpmMockContext extends MockContext {
public Object getSystemService(String name) {
switch (name) {
case Context.ALARM_SERVICE:
return alarmManager;
return mMockSystemServices.alarmManager;
case Context.USER_SERVICE:
return userManager;
return mMockSystemServices.userManager;
case Context.POWER_SERVICE:
return powerManager;
return mMockSystemServices.powerManager;
case Context.WIFI_SERVICE:
return wifiManager;
return mMockSystemServices.wifiManager;
case Context.ACCOUNT_SERVICE:
return accountManager;
return mMockSystemServices.accountManager;
}
throw new UnsupportedOperationException();
}
@@ -609,22 +193,21 @@ public class DpmMockContext extends MockContext {
@Override
public PackageManager getPackageManager() {
return packageManager;
return mMockSystemServices.packageManager;
}
@Override
public void enforceCallingOrSelfPermission(String permission, String message) {
if (binder.getCallingUid() == SYSTEM_UID) {
if (UserHandle.isSameApp(binder.getCallingUid(), SYSTEM_UID)) {
return; // Assume system has all permissions.
}
List<String> permissions = binder.callingPermissions.get(binder.getCallingUid());
if (permissions == null) {
// TODO: delete the following line. to do this without breaking any tests, first it's
// necessary to remove all tests that set it directly.
permissions = callerPermissions;
// throw new UnsupportedOperationException(
// "Caller UID " + binder.getCallingUid() + " doesn't exist");
// throw new UnsupportedOperationException(
// "Caller UID " + binder.getCallingUid() + " doesn't exist");
}
if (!permissions.contains(permission)) {
throw new SecurityException("Caller doesn't have " + permission + " : " + message);
@@ -773,44 +356,40 @@ public class DpmMockContext extends MockContext {
@Override
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
mBroadcastReceivers.add(new BroadcastReceiverRegistration(receiver, filter, null));
mMockSystemServices.registerReceiver(receiver, filter, null);
return spiedContext.registerReceiver(receiver, filter);
}
@Override
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
String broadcastPermission, Handler scheduler) {
mBroadcastReceivers.add(new BroadcastReceiverRegistration(receiver, filter, scheduler));
mMockSystemServices.registerReceiver(receiver, filter, scheduler);
return spiedContext.registerReceiver(receiver, filter, broadcastPermission, scheduler);
}
@Override
public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
IntentFilter filter, String broadcastPermission, Handler scheduler) {
mBroadcastReceivers.add(new BroadcastReceiverRegistration(receiver, filter, scheduler));
mMockSystemServices.registerReceiver(receiver, filter, scheduler);
return spiedContext.registerReceiverAsUser(receiver, user, filter, broadcastPermission,
scheduler);
}
@Override
public void unregisterReceiver(BroadcastReceiver receiver) {
mBroadcastReceivers.removeIf(r -> r.receiver == receiver);
mMockSystemServices.unregisterReceiver(receiver);
spiedContext.unregisterReceiver(receiver);
}
@Override
public Context createPackageContextAsUser(String packageName, int flags, UserHandle user)
throws PackageManager.NameNotFoundException {
final Pair<UserHandle, String> key = new Pair<>(user, packageName);
if (userPackageContexts.containsKey(key)) {
return userPackageContexts.get(key);
}
throw new UnsupportedOperationException("No package " + packageName + " for user " + user);
return mMockSystemServices.createPackageContextAsUser(packageName, flags, user);
}
@Override
public ContentResolver getContentResolver() {
return contentResolver;
return mMockSystemServices.contentResolver;
}
@Override

View File

@@ -16,6 +16,10 @@
package com.android.server.devicepolicy;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doReturn;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.content.Context;
@@ -28,20 +32,14 @@ import android.content.pm.ResolveInfo;
import android.os.UserHandle;
import android.test.AndroidTestCase;
import java.io.File;
import java.util.List;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doReturn;
public abstract class DpmTestBase extends AndroidTestCase {
public static final String TAG = "DpmTest";
protected Context mRealTestContext;
protected DpmMockContext mMockContext;
public File dataDir;
private MockSystemServices mServices;
public ComponentName admin1;
public ComponentName admin2;
@@ -55,8 +53,8 @@ public abstract class DpmTestBase extends AndroidTestCase {
mRealTestContext = super.getContext();
mMockContext = new DpmMockContext(
mRealTestContext, new File(mRealTestContext.getCacheDir(), "test-data"));
mServices = new MockSystemServices(mRealTestContext, "test-data");
mMockContext = new DpmMockContext(mServices, mRealTestContext);
admin1 = new ComponentName(mRealTestContext, DummyDeviceAdmins.Admin1.class);
admin2 = new ComponentName(mRealTestContext, DummyDeviceAdmins.Admin2.class);
@@ -71,12 +69,16 @@ public abstract class DpmTestBase extends AndroidTestCase {
return mMockContext;
}
public MockSystemServices getServices() {
return mServices;
}
protected interface DpmRunnable {
public void run(DevicePolicyManager dpm) throws Exception;
void run(DevicePolicyManager dpm) throws Exception;
}
/**
* Simulate an RPC from {@param caller} to the service context ({@link #mContext}).
* Simulate an RPC from {@param caller} to the service context ({@link #mMockContext}).
*
* The caller sees its own context. The server also sees its own separate context, with the
* appropriate calling UID and calling permissions fields already set up.
@@ -85,12 +87,15 @@ public abstract class DpmTestBase extends AndroidTestCase {
DpmRunnable action) {
final DpmMockContext serviceContext = mMockContext;
// Save calling UID and PID before clearing identity so we don't run into aliasing issues.
final int callingUid = caller.binder.callingUid;
final int callingPid = caller.binder.callingPid;
final long origId = serviceContext.binder.clearCallingIdentity();
try {
serviceContext.binder.callingUid = caller.binder.callingUid;
serviceContext.binder.callingPid = caller.binder.callingPid;
serviceContext.binder.callingPermissions.put(caller.binder.callingUid,
caller.permissions);
serviceContext.binder.callingUid = callingUid;
serviceContext.binder.callingPid = callingPid;
serviceContext.binder.callingPermissions.put(callingUid, caller.permissions);
action.run(new DevicePolicyManagerTestable(caller, dpms));
} catch (Exception e) {
throw new AssertionError(e);
@@ -99,7 +104,7 @@ public abstract class DpmTestBase extends AndroidTestCase {
}
}
protected void markPackageAsInstalled(String packageName, ApplicationInfo ai, int userId)
private void markPackageAsInstalled(String packageName, ApplicationInfo ai, int userId)
throws Exception {
final PackageInfo pi = DpmTestUtils.cloneParcelable(
mRealTestContext.getPackageManager().getPackageInfo(
@@ -110,12 +115,12 @@ public abstract class DpmTestBase extends AndroidTestCase {
pi.applicationInfo = ai;
}
doReturn(pi).when(mMockContext.ipackageManager).getPackageInfo(
doReturn(pi).when(mServices.ipackageManager).getPackageInfo(
eq(packageName),
eq(0),
eq(userId));
doReturn(ai.uid).when(mMockContext.packageManager).getPackageUidAsUser(
doReturn(ai.uid).when(mServices.packageManager).getPackageUidAsUser(
eq(packageName),
eq(userId));
}
@@ -151,7 +156,7 @@ public abstract class DpmTestBase extends AndroidTestCase {
* @param copyFromAdmin package information for {@code admin} will be built based on this
* component's information.
*/
protected void setUpPackageManagerForFakeAdmin(ComponentName admin, int packageUid,
private void setUpPackageManagerForFakeAdmin(ComponentName admin, int packageUid,
Integer enabledSetting, Integer appTargetSdk, ComponentName copyFromAdmin)
throws Exception {
@@ -171,7 +176,7 @@ public abstract class DpmTestBase extends AndroidTestCase {
ai.packageName = admin.getPackageName();
ai.name = admin.getClassName();
doReturn(ai).when(mMockContext.ipackageManager).getApplicationInfo(
doReturn(ai).when(mServices.ipackageManager).getApplicationInfo(
eq(admin.getPackageName()),
anyInt(),
eq(UserHandle.getUserId(packageUid)));
@@ -198,12 +203,12 @@ public abstract class DpmTestBase extends AndroidTestCase {
// Note we don't set up queryBroadcastReceivers. We don't use it in DPMS.
doReturn(aci).when(mMockContext.ipackageManager).getReceiverInfo(
doReturn(aci).when(mServices.ipackageManager).getReceiverInfo(
eq(admin),
anyInt(),
eq(UserHandle.getUserId(packageUid)));
doReturn(new String[] {admin.getPackageName()}).when(mMockContext.ipackageManager)
doReturn(new String[] {admin.getPackageName()}).when(mServices.ipackageManager)
.getPackagesForUid(eq(packageUid));
// Set up getPackageInfo().
markPackageAsInstalled(admin.getPackageName(), ai, UserHandle.getUserId(packageUid));

View File

@@ -0,0 +1,459 @@
/*
* Copyright (C) 2017 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.server.devicepolicy;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.AlarmManager;
import android.app.IActivityManager;
import android.app.NotificationManager;
import android.app.backup.IBackupManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.UserInfo;
import android.media.IAudioService;
import android.net.IIpConnectivityMetrics;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.os.PowerManager;
import android.os.PowerManagerInternal;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.UserManagerInternal;
import android.security.KeyChain;
import android.telephony.TelephonyManager;
import android.test.mock.MockContentResolver;
import android.util.ArrayMap;
import android.util.Pair;
import android.view.IWindowManager;
import com.android.internal.widget.LockPatternUtils;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
/**
* System services mocks and some other data that are shared by all contexts during the test.
*/
public class MockSystemServices {
public final File systemUserDataDir;
public final EnvironmentForMock environment;
public final SystemPropertiesForMock systemProperties;
public final UserManager userManager;
public final UserManagerInternal userManagerInternal;
public final PackageManagerInternal packageManagerInternal;
public final UserManagerForMock userManagerForMock;
public final PowerManagerForMock powerManager;
public final PowerManagerInternal powerManagerInternal;
public final RecoverySystemForMock recoverySystem;
public final NotificationManager notificationManager;
public final IIpConnectivityMetrics iipConnectivityMetrics;
public final IWindowManager iwindowManager;
public final IActivityManager iactivityManager;
public final IPackageManager ipackageManager;
public final IBackupManager ibackupManager;
public final IAudioService iaudioService;
public final LockPatternUtils lockPatternUtils;
public final StorageManagerForMock storageManager;
public final WifiManager wifiManager;
public final SettingsForMock settings;
public final MockContentResolver contentResolver;
public final TelephonyManager telephonyManager;
public final AccountManager accountManager;
public final AlarmManager alarmManager;
public final KeyChain.KeyChainConnection keyChainConnection;
/** Note this is a partial mock, not a real mock. */
public final PackageManager packageManager;
public final BuildMock buildMock = new BuildMock();
public final File dataDir;
public MockSystemServices(Context realContext, String name) {
dataDir = new File(realContext.getCacheDir(), name);
DpmTestUtils.clearDir(dataDir);
environment = mock(EnvironmentForMock.class);
systemProperties = mock(SystemPropertiesForMock.class);
userManager = mock(UserManager.class);
userManagerInternal = mock(UserManagerInternal.class);
userManagerForMock = mock(UserManagerForMock.class);
packageManagerInternal = mock(PackageManagerInternal.class);
powerManager = mock(PowerManagerForMock.class);
powerManagerInternal = mock(PowerManagerInternal.class);
recoverySystem = mock(RecoverySystemForMock.class);
notificationManager = mock(NotificationManager.class);
iipConnectivityMetrics = mock(IIpConnectivityMetrics.class);
iwindowManager = mock(IWindowManager.class);
iactivityManager = mock(IActivityManager.class);
ipackageManager = mock(IPackageManager.class);
ibackupManager = mock(IBackupManager.class);
iaudioService = mock(IAudioService.class);
lockPatternUtils = mock(LockPatternUtils.class);
storageManager = mock(StorageManagerForMock.class);
wifiManager = mock(WifiManager.class);
settings = mock(SettingsForMock.class);
telephonyManager = mock(TelephonyManager.class);
accountManager = mock(AccountManager.class);
alarmManager = mock(AlarmManager.class);
keyChainConnection = mock(KeyChain.KeyChainConnection.class, RETURNS_DEEP_STUBS);
// Package manager is huge, so we use a partial mock instead.
packageManager = spy(realContext.getPackageManager());
contentResolver = new MockContentResolver();
// Add the system user with a fake profile group already set up (this can happen in the real
// world if a managed profile is added and then removed).
systemUserDataDir =
addUser(UserHandle.USER_SYSTEM, UserInfo.FLAG_PRIMARY, UserHandle.USER_SYSTEM);
// System user is always running.
setUserRunning(UserHandle.USER_SYSTEM, true);
}
/** Optional mapping of other user contexts for {@link #createPackageContextAsUser} to return */
private final Map<Pair<UserHandle, String>, Context> userPackageContexts = new ArrayMap<>();
private final ArrayList<UserInfo> mUserInfos = new ArrayList<>();
private final List<BroadcastReceiverRegistration> mBroadcastReceivers = new ArrayList<>();
public void registerReceiver(
BroadcastReceiver receiver, IntentFilter filter, Handler scheduler) {
mBroadcastReceivers.add(new BroadcastReceiverRegistration(receiver, filter, scheduler));
}
public void unregisterReceiver(BroadcastReceiver receiver) {
mBroadcastReceivers.removeIf(r -> r.receiver == receiver);
}
public File addUser(int userId, int flags) {
return addUser(userId, flags, UserInfo.NO_PROFILE_GROUP_ID);
}
public File addUser(int userId, int flags, int profileGroupId) {
// Set up (default) UserInfo for CALLER_USER_HANDLE.
final UserInfo uh = new UserInfo(userId, "user" + userId, flags);
uh.profileGroupId = profileGroupId;
when(userManager.getUserInfo(eq(userId))).thenReturn(uh);
mUserInfos.add(uh);
when(userManager.getUsers()).thenReturn(mUserInfos);
when(userManager.getUsers(anyBoolean())).thenReturn(mUserInfos);
when(userManager.isUserRunning(eq(new UserHandle(userId)))).thenReturn(true);
when(userManager.getUserInfo(anyInt())).thenAnswer(
invocation -> {
final int userId1 = (int) invocation.getArguments()[0];
return getUserInfo(userId1);
}
);
when(userManager.getProfiles(anyInt())).thenAnswer(
invocation -> {
final int userId12 = (int) invocation.getArguments()[0];
return getProfiles(userId12);
}
);
when(userManager.getProfileIdsWithDisabled(anyInt())).thenAnswer(
invocation -> {
final int userId13 = (int) invocation.getArguments()[0];
List<UserInfo> profiles = getProfiles(userId13);
return profiles.stream()
.mapToInt(profile -> profile.id)
.toArray();
}
);
when(accountManager.getAccountsAsUser(anyInt())).thenReturn(new Account[0]);
// Create a data directory.
final File dir = new File(dataDir, "users/" + userId);
DpmTestUtils.clearDir(dir);
when(environment.getUserSystemDirectory(eq(userId))).thenReturn(dir);
return dir;
}
public void removeUser(int userId) {
for (int i = 0; i < mUserInfos.size(); i++) {
if (mUserInfos.get(i).id == userId) {
mUserInfos.remove(i);
break;
}
}
when(userManager.getUserInfo(eq(userId))).thenReturn(null);
when(userManager.isUserRunning(eq(new UserHandle(userId)))).thenReturn(false);
}
private UserInfo getUserInfo(int userId) {
for (final UserInfo ui : mUserInfos) {
if (ui.id == userId) {
return ui;
}
}
return null;
}
private List<UserInfo> getProfiles(int userId) {
final ArrayList<UserInfo> ret = new ArrayList<>();
UserInfo parent = null;
for (final UserInfo ui : mUserInfos) {
if (ui.id == userId) {
parent = ui;
break;
}
}
if (parent == null) {
return ret;
}
for (final UserInfo ui : mUserInfos) {
if (ui == parent
|| ui.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID
&& ui.profileGroupId == parent.profileGroupId) {
ret.add(ui);
}
}
return ret;
}
/**
* Add multiple users at once. They'll all have flag 0.
*/
public void addUsers(int... userIds) {
for (final int userId : userIds) {
addUser(userId, 0);
}
}
public void setUserRunning(int userId, boolean isRunning) {
when(userManager.isUserRunning(MockUtils.checkUserHandle(userId)))
.thenReturn(isRunning);
}
public void injectBroadcast(Context context, final Intent intent, int userId) {
//final int userId = UserHandle.getUserId(binder.getCallingUid());
for (final BroadcastReceiverRegistration receiver : mBroadcastReceivers) {
receiver.sendBroadcastIfApplicable(context, userId, intent);
}
}
public void rethrowBackgroundBroadcastExceptions() throws Exception {
for (final BroadcastReceiverRegistration receiver : mBroadcastReceivers) {
final Exception e = receiver.backgroundException.getAndSet(null);
if (e != null) {
throw e;
}
}
}
public void addPackageContext(UserHandle user, Context context) {
if (context.getPackageName() == null) {
throw new NullPointerException("getPackageName() == null");
}
userPackageContexts.put(new Pair<>(user, context.getPackageName()), context);
}
public Context createPackageContextAsUser(String packageName, int flags, UserHandle user)
throws PackageManager.NameNotFoundException {
final Pair<UserHandle, String> key = new Pair<>(user, packageName);
if (userPackageContexts.containsKey(key)) {
return userPackageContexts.get(key);
}
throw new UnsupportedOperationException("No package " + packageName + " for user " + user);
}
public static class EnvironmentForMock {
public File getUserSystemDirectory(int userId) {
return null;
}
}
public static class BuildMock {
public boolean isDebuggable = true;
}
public static class PowerManagerForMock {
public PowerManager.WakeLock newWakeLock(int levelAndFlags, String tag) {
return null;
}
public void goToSleep(long time, int reason, int flags) {
}
public void reboot(String reason) {
}
}
public static class RecoverySystemForMock {
public void rebootWipeUserData(
boolean shutdown, String reason, boolean force) throws IOException {
}
}
public static class SystemPropertiesForMock {
public boolean getBoolean(String key, boolean def) {
return false;
}
public long getLong(String key, long def) {
return 0;
}
public String get(String key, String def) {
return null;
}
public String get(String key) {
return null;
}
public void set(String key, String value) {
}
}
public static class UserManagerForMock {
public boolean isSplitSystemUser() {
return false;
}
}
public static class SettingsForMock {
public int settingsSecureGetIntForUser(String name, int def, int userHandle) {
return 0;
}
public String settingsSecureGetStringForUser(String name, int userHandle) {
return null;
}
public void settingsSecurePutIntForUser(String name, int value, int userHandle) {
}
public void settingsSecurePutStringForUser(String name, String value, int userHandle) {
}
public void settingsGlobalPutStringForUser(String name, String value, int userHandle) {
}
public void settingsSecurePutInt(String name, int value) {
}
public void settingsGlobalPutInt(String name, int value) {
}
public void settingsSecurePutString(String name, String value) {
}
public void settingsGlobalPutString(String name, String value) {
}
public int settingsGlobalGetInt(String name, int value) {
return 0;
}
public String settingsGlobalGetString(String name) {
return "";
}
public void securityLogSetLoggingEnabledProperty(boolean enabled) {
}
public boolean securityLogGetLoggingEnabledProperty() {
return false;
}
public boolean securityLogIsLoggingEnabled() {
return false;
}
}
public static class StorageManagerForMock {
public boolean isFileBasedEncryptionEnabled() {
return false;
}
public boolean isNonDefaultBlockEncrypted() {
return false;
}
public boolean isEncrypted() {
return false;
}
public boolean isEncryptable() {
return false;
}
}
// We have to keep track of broadcast receivers registered for a given intent ourselves as the
// DPM unit tests mock out the package manager and PackageManager.queryBroadcastReceivers() does
// not work.
private static class BroadcastReceiverRegistration {
public final BroadcastReceiver receiver;
public final IntentFilter filter;
public final Handler scheduler;
// Exceptions thrown in a background thread kill the whole test. Save them instead.
public final AtomicReference<Exception> backgroundException = new AtomicReference<>();
public BroadcastReceiverRegistration(BroadcastReceiver receiver, IntentFilter filter,
Handler scheduler) {
this.receiver = receiver;
this.filter = filter;
this.scheduler = scheduler;
}
public void sendBroadcastIfApplicable(Context context, int userId, Intent intent) {
final BroadcastReceiver.PendingResult result = new BroadcastReceiver.PendingResult(
0 /* resultCode */, null /* resultData */, null /* resultExtras */,
0 /* type */, false /* ordered */, false /* sticky */, null /* token */, userId,
0 /* flags */);
if (filter.match(null, intent, false, "DpmMockContext") > 0) {
final Runnable send = () -> {
receiver.setPendingResult(result);
receiver.onReceive(context, intent);
};
if (scheduler != null) {
scheduler.post(() -> {
try {
send.run();
} catch (Exception e) {
backgroundException.compareAndSet(null, e);
}
});
} else {
send.run();
}
}
}
}
}

View File

@@ -34,11 +34,11 @@ import android.os.UserHandle;
*/
public class OwnersTest extends DpmTestBase {
public void testUpgrade01() throws Exception {
getContext().addUsers(10, 11, 20, 21);
getServices().addUsers(10, 11, 20, 21);
// First, migrate.
{
final OwnersTestable owners = new OwnersTestable(getContext());
final OwnersTestable owners = new OwnersTestable(getServices());
DpmTestUtils.writeToFile(owners.getLegacyConfigFileWithTestOverride(),
DpmTestUtils.readAsset(mRealTestContext, "OwnersTest/test01/input.xml"));
@@ -70,7 +70,7 @@ public class OwnersTest extends DpmTestBase {
// Then re-read and check.
{
final OwnersTestable owners = new OwnersTestable(getContext());
final OwnersTestable owners = new OwnersTestable(getServices());
owners.load();
assertFalse(owners.hasDeviceOwner());
@@ -87,11 +87,11 @@ public class OwnersTest extends DpmTestBase {
}
public void testUpgrade02() throws Exception {
getContext().addUsers(10, 11, 20, 21);
getServices().addUsers(10, 11, 20, 21);
// First, migrate.
{
final OwnersTestable owners = new OwnersTestable(getContext());
final OwnersTestable owners = new OwnersTestable(getServices());
DpmTestUtils.writeToFile(owners.getLegacyConfigFileWithTestOverride(),
DpmTestUtils.readAsset(mRealTestContext, "OwnersTest/test02/input.xml"));
@@ -125,7 +125,7 @@ public class OwnersTest extends DpmTestBase {
// Then re-read and check.
{
final OwnersTestable owners = new OwnersTestable(getContext());
final OwnersTestable owners = new OwnersTestable(getServices());
owners.load();
assertTrue(owners.hasDeviceOwner());
@@ -145,11 +145,11 @@ public class OwnersTest extends DpmTestBase {
}
public void testUpgrade03() throws Exception {
getContext().addUsers(10, 11, 20, 21);
getServices().addUsers(10, 11, 20, 21);
// First, migrate.
{
final OwnersTestable owners = new OwnersTestable(getContext());
final OwnersTestable owners = new OwnersTestable(getServices());
DpmTestUtils.writeToFile(owners.getLegacyConfigFileWithTestOverride(),
DpmTestUtils.readAsset(mRealTestContext, "OwnersTest/test03/input.xml"));
@@ -191,7 +191,7 @@ public class OwnersTest extends DpmTestBase {
// Then re-read and check.
{
final OwnersTestable owners = new OwnersTestable(getContext());
final OwnersTestable owners = new OwnersTestable(getServices());
owners.load();
assertFalse(owners.hasDeviceOwner());
@@ -223,11 +223,11 @@ public class OwnersTest extends DpmTestBase {
* and {@link Owners#setProfileOwnerUserRestrictionsMigrated(int)}.
*/
public void testUpgrade04() throws Exception {
getContext().addUsers(10, 11, 20, 21);
getServices().addUsers(10, 11, 20, 21);
// First, migrate.
{
final OwnersTestable owners = new OwnersTestable(getContext());
final OwnersTestable owners = new OwnersTestable(getServices());
DpmTestUtils.writeToFile(owners.getLegacyConfigFileWithTestOverride(),
DpmTestUtils.readAsset(mRealTestContext, "OwnersTest/test04/input.xml"));
@@ -273,7 +273,7 @@ public class OwnersTest extends DpmTestBase {
// Then re-read and check.
{
final OwnersTestable owners = new OwnersTestable(getContext());
final OwnersTestable owners = new OwnersTestable(getServices());
owners.load();
assertTrue(owners.hasDeviceOwner());
@@ -306,7 +306,7 @@ public class OwnersTest extends DpmTestBase {
}
{
final OwnersTestable owners = new OwnersTestable(getContext());
final OwnersTestable owners = new OwnersTestable(getServices());
owners.load();
assertFalse(owners.getDeviceOwnerUserRestrictionsNeedsMigration());
@@ -319,7 +319,7 @@ public class OwnersTest extends DpmTestBase {
}
{
final OwnersTestable owners = new OwnersTestable(getContext());
final OwnersTestable owners = new OwnersTestable(getServices());
owners.load();
assertFalse(owners.getDeviceOwnerUserRestrictionsNeedsMigration());
@@ -333,11 +333,11 @@ public class OwnersTest extends DpmTestBase {
}
public void testUpgrade05() throws Exception {
getContext().addUsers(10, 11, 20, 21);
getServices().addUsers(10, 11, 20, 21);
// First, migrate.
{
final OwnersTestable owners = new OwnersTestable(getContext());
final OwnersTestable owners = new OwnersTestable(getServices());
DpmTestUtils.writeToFile(owners.getLegacyConfigFileWithTestOverride(),
DpmTestUtils.readAsset(mRealTestContext, "OwnersTest/test05/input.xml"));
@@ -370,7 +370,7 @@ public class OwnersTest extends DpmTestBase {
// Then re-read and check.
{
final OwnersTestable owners = new OwnersTestable(getContext());
final OwnersTestable owners = new OwnersTestable(getServices());
owners.load();
assertFalse(owners.hasDeviceOwner());
@@ -389,11 +389,11 @@ public class OwnersTest extends DpmTestBase {
}
public void testUpgrade06() throws Exception {
getContext().addUsers(10, 11, 20, 21);
getServices().addUsers(10, 11, 20, 21);
// First, migrate.
{
final OwnersTestable owners = new OwnersTestable(getContext());
final OwnersTestable owners = new OwnersTestable(getServices());
DpmTestUtils.writeToFile(owners.getLegacyConfigFileWithTestOverride(),
DpmTestUtils.readAsset(mRealTestContext, "OwnersTest/test06/input.xml"));
@@ -425,7 +425,7 @@ public class OwnersTest extends DpmTestBase {
// Then re-read and check.
{
final OwnersTestable owners = new OwnersTestable(getContext());
final OwnersTestable owners = new OwnersTestable(getServices());
owners.load();
assertFalse(owners.hasDeviceOwner());
@@ -444,9 +444,9 @@ public class OwnersTest extends DpmTestBase {
}
public void testRemoveExistingFiles() throws Exception {
getContext().addUsers(10, 11, 20, 21);
getServices().addUsers(10, 11, 20, 21);
final OwnersTestable owners = new OwnersTestable(getContext());
final OwnersTestable owners = new OwnersTestable(getServices());
// First, migrate to create new-style config files.
DpmTestUtils.writeToFile(owners.getLegacyConfigFileWithTestOverride(),