blob: 56667e5ac4780f913936e0ea3830587a7495c7d1 [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.server.devicepolicy;
import com.android.internal.widget.LockPatternUtils;
import android.app.IActivityManager;
import android.app.NotificationManager;
import android.app.backup.IBackupManager;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
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.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.test.mock.MockContentResolver;
import android.test.mock.MockContext;
import android.view.IWindowManager;
import org.junit.Assert;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
/**
* Context used throughout DPMS tests.
*/
public class DpmMockContext extends MockContext {
/**
* User-id of a non-system user we use throughout unit tests.
*/
public static final int CALLER_USER_HANDLE = 20;
/**
* UID corresponding to {@link #CALLER_USER_HANDLE}.
*/
public static final int CALLER_UID = UserHandle.getUid(CALLER_USER_HANDLE, 20123);
/**
* UID used when a caller is on the system user.
*/
public static final int CALLER_SYSTEM_USER_UID = 20321;
/**
* PID of the caller.
*/
public static final int CALLER_PID = 22222;
/**
* UID of the system server.
*/
public static final int SYSTEM_UID = android.os.Process.SYSTEM_UID;
/**
* PID of the system server.
*/
public static final int SYSTEM_PID = 11111;
public static class MockBinder {
public int callingUid = CALLER_UID;
public int callingPid = CALLER_PID;
public long clearCallingIdentity() {
final long token = (((long) callingUid) << 32) | (callingPid);
callingUid = SYSTEM_UID;
callingPid = SYSTEM_PID;
return token;
}
public void restoreCallingIdentity(long token) {
callingUid = (int) (token >> 32);
callingPid = (int) token;
}
public int getCallingUid() {
return callingUid;
}
public int getCallingPid() {
return callingPid;
}
public UserHandle getCallingUserHandle() {
return new UserHandle(UserHandle.getUserId(getCallingUid()));
}
public boolean isCallerUidMyUid() {
return callingUid == SYSTEM_UID;
}
}
public static class EnvironmentForMock {
public File getUserSystemDirectory(int userId) {
return null;
}
}
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 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 {
int settingsSecureGetIntForUser(String name, int def, int userHandle) {
return 0;
}
void settingsSecurePutIntForUser(String name, int value, int userHandle) {
}
void settingsSecurePutStringForUser(String name, String value, int userHandle) {
}
void settingsGlobalPutStringForUser(String name, String value, int userHandle) {
}
void settingsSecurePutInt(String name, int value) {
}
void settingsGlobalPutInt(String name, int value) {
}
void settingsSecurePutString(String name, String value) {
}
void settingsGlobalPutString(String name, String value) {
}
}
public final Context realTestContext;
/**
* Use this instance to verify unimplemented methods such as {@link #sendBroadcast}.
* (Spying on {@code this} instance will confuse mockito somehow and I got weired "wrong number
* of arguments" exceptions.)
*/
public final Context spiedContext;
public final File dataDir;
public final File systemUserDataDir;
public final MockBinder binder;
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 NotificationManager notificationManager;
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 WifiManager wifiManager;
public final SettingsForMock settings;
public final MockContentResolver contentResolver;
/** Note this is a partial mock, not a real mock. */
public final PackageManager packageManager;
public final List<String> callerPermissions = new ArrayList<>();
private final ArrayList<UserInfo> mUserInfos = new ArrayList<>();
public DpmMockContext(Context context, File dataDir) {
realTestContext = context;
this.dataDir = dataDir;
DpmTestUtils.clearDir(dataDir);
binder = new MockBinder();
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);
notificationManager = mock(NotificationManager.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);
wifiManager = mock(WifiManager.class);
settings = mock(SettingsForMock.class);
// 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
systemUserDataDir = addUser(UserHandle.USER_SYSTEM, UserInfo.FLAG_PRIMARY);
// System user is always running.
setUserRunning(UserHandle.USER_SYSTEM, true);
}
public File addUser(int userId, int flags) {
// Set up (default) UserInfo for CALLER_USER_HANDLE.
final UserInfo uh = new UserInfo(userId, "user" + userId, flags);
when(userManager.getUserInfo(eq(userId))).thenReturn(uh);
mUserInfos.add(uh);
when(userManager.getUsers()).thenReturn(mUserInfos);
// Create a data directory.
final File dir = new File(dataDir, "user" + userId);
DpmTestUtils.clearDir(dir);
when(environment.getUserSystemDirectory(eq(userId))).thenReturn(dir);
return dir;
}
/**
* 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);
}
@Override
public Object getSystemService(String name) {
switch (name) {
case Context.USER_SERVICE:
return userManager;
case Context.POWER_SERVICE:
return powerManager;
case Context.WIFI_SERVICE:
return wifiManager;
}
throw new UnsupportedOperationException();
}
@Override
public String getSystemServiceName(Class<?> serviceClass) {
return realTestContext.getSystemServiceName(serviceClass);
}
@Override
public PackageManager getPackageManager() {
return packageManager;
}
@Override
public void enforceCallingOrSelfPermission(String permission, String message) {
if (binder.getCallingUid() == SYSTEM_UID) {
return; // Assume system has all permissions.
}
if (!callerPermissions.contains(permission)) {
throw new SecurityException("Caller doesn't have " + permission + " : " + message);
}
}
@Override
public void sendBroadcast(Intent intent) {
spiedContext.sendBroadcast(intent);
}
@Override
public void sendBroadcast(Intent intent, String receiverPermission) {
spiedContext.sendBroadcast(intent, receiverPermission);
}
@Override
public void sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions) {
spiedContext.sendBroadcastMultiplePermissions(intent, receiverPermissions);
}
@Override
public void sendBroadcast(Intent intent, String receiverPermission, Bundle options) {
spiedContext.sendBroadcast(intent, receiverPermission, options);
}
@Override
public void sendBroadcast(Intent intent, String receiverPermission, int appOp) {
spiedContext.sendBroadcast(intent, receiverPermission, appOp);
}
@Override
public void sendOrderedBroadcast(Intent intent, String receiverPermission) {
spiedContext.sendOrderedBroadcast(intent, receiverPermission);
}
@Override
public void sendOrderedBroadcast(Intent intent, String receiverPermission,
BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
String initialData, Bundle initialExtras) {
spiedContext.sendOrderedBroadcast(intent, receiverPermission, resultReceiver, scheduler,
initialCode, initialData, initialExtras);
}
@Override
public void sendOrderedBroadcast(Intent intent, String receiverPermission, Bundle options,
BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
String initialData, Bundle initialExtras) {
spiedContext.sendOrderedBroadcast(intent, receiverPermission, options, resultReceiver,
scheduler,
initialCode, initialData, initialExtras);
}
@Override
public void sendOrderedBroadcast(Intent intent, String receiverPermission, int appOp,
BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
String initialData, Bundle initialExtras) {
spiedContext.sendOrderedBroadcast(intent, receiverPermission, appOp, resultReceiver,
scheduler,
initialCode, initialData, initialExtras);
}
@Override
public void sendBroadcastAsUser(Intent intent, UserHandle user) {
if (binder.callingPid != SYSTEM_PID) {
// Unless called as the system process, can only call if the target user is the
// calling user.
// (The actual check is more complex; we may need to change it later.)
Assert.assertEquals(UserHandle.getUserId(binder.getCallingUid()), user.getIdentifier());
}
spiedContext.sendBroadcastAsUser(intent, user);
}
@Override
public void sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission) {
spiedContext.sendBroadcastAsUser(intent, user, receiverPermission);
}
@Override
public void sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission,
int appOp) {
spiedContext.sendBroadcastAsUser(intent, user, receiverPermission, appOp);
}
@Override
public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler,
int initialCode, String initialData, Bundle initialExtras) {
spiedContext.sendOrderedBroadcastAsUser(intent, user, receiverPermission, resultReceiver,
scheduler, initialCode, initialData, initialExtras);
}
@Override
public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
String receiverPermission, int appOp, BroadcastReceiver resultReceiver,
Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
spiedContext.sendOrderedBroadcastAsUser(intent, user, receiverPermission, appOp,
resultReceiver,
scheduler, initialCode, initialData, initialExtras);
}
@Override
public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
String receiverPermission, int appOp, Bundle options, BroadcastReceiver resultReceiver,
Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
spiedContext.sendOrderedBroadcastAsUser(intent, user, receiverPermission, appOp, options,
resultReceiver, scheduler, initialCode, initialData, initialExtras);
}
@Override
public void sendStickyBroadcast(Intent intent) {
spiedContext.sendStickyBroadcast(intent);
}
@Override
public void sendStickyOrderedBroadcast(Intent intent, BroadcastReceiver resultReceiver,
Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
spiedContext.sendStickyOrderedBroadcast(intent, resultReceiver, scheduler, initialCode,
initialData, initialExtras);
}
@Override
public void removeStickyBroadcast(Intent intent) {
spiedContext.removeStickyBroadcast(intent);
}
@Override
public void sendStickyBroadcastAsUser(Intent intent, UserHandle user) {
spiedContext.sendStickyBroadcastAsUser(intent, user);
}
@Override
public void sendStickyOrderedBroadcastAsUser(Intent intent, UserHandle user,
BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
String initialData, Bundle initialExtras) {
spiedContext.sendStickyOrderedBroadcastAsUser(intent, user, resultReceiver, scheduler, initialCode,
initialData, initialExtras);
}
@Override
public void removeStickyBroadcastAsUser(Intent intent, UserHandle user) {
spiedContext.removeStickyBroadcastAsUser(intent, user);
}
@Override
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
return spiedContext.registerReceiver(receiver, filter);
}
@Override
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
String broadcastPermission, Handler scheduler) {
return spiedContext.registerReceiver(receiver, filter, broadcastPermission, scheduler);
}
@Override
public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
IntentFilter filter, String broadcastPermission, Handler scheduler) {
return spiedContext.registerReceiverAsUser(receiver, user, filter, broadcastPermission,
scheduler);
}
@Override
public void unregisterReceiver(BroadcastReceiver receiver) {
spiedContext.unregisterReceiver(receiver);
}
@Override
public ContentResolver getContentResolver() {
return contentResolver;
}
}