blob: 1a4ff38921efd79cef85cb2ad58870ffdd457a87 [file] [log] [blame]
package org.robolectric.shadows;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.content.Context;
import android.os.Bundle;
import android.os.Process;
import android.os.UserManager;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.Shadows;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
/** Shadow for {@link DevicePolicyManager} */
@Implements(DevicePolicyManager.class)
public class ShadowDevicePolicyManager {
private ComponentName deviceOwner;
private ComponentName profileOwner;
private List<ComponentName> deviceAdmins = new ArrayList<>();
private Map<String, Bundle> applicationRestrictionsMap = new HashMap<>();
private final Set<String> hiddenPackages = new HashSet<>();
private final Set<String> wasHiddenPackages = new HashSet<>();
private final Set<String> accountTypesWithManagementDisabled = new HashSet<>();
private final Set<String> systemAppsEnabled = new HashSet<>();
private final Set<String> uninstallBlockedPackages = new HashSet<>();
@Implementation
public boolean isDeviceOwnerApp(String packageName) {
return deviceOwner != null && deviceOwner.getPackageName().equals(packageName);
}
@Implementation
public boolean isProfileOwnerApp(String packageName) {
return profileOwner != null && profileOwner.getPackageName().equals(packageName);
}
@Implementation
public List<ComponentName> getActiveAdmins() {
return deviceAdmins;
}
@Implementation
public void addUserRestriction(ComponentName admin, String key) {
enforceActiveAdmin(admin);
getShadowUserManager().setUserRestriction(Process.myUserHandle(), key, true);
}
@Implementation
public void clearUserRestriction(ComponentName admin, String key) {
enforceActiveAdmin(admin);
getShadowUserManager().setUserRestriction(Process.myUserHandle(), key, false);
}
@Implementation
public void setApplicationHidden(ComponentName admin, String packageName, boolean hidden) {
enforceActiveAdmin(admin);
if (hidden) {
hiddenPackages.add(packageName);
wasHiddenPackages.add(packageName);
} else {
hiddenPackages.remove(packageName);
}
}
@Implementation
public boolean isApplicationHidden(ComponentName admin, String packageName) {
enforceActiveAdmin(admin);
return hiddenPackages.contains(packageName);
}
/** Returns {@code true} if the given {@code packageName} was ever hidden. */
public boolean wasPackageEverHidden(String packageName) {
return wasHiddenPackages.contains(packageName);
}
@Implementation
public int enableSystemApp(ComponentName admin, String packageName) {
enforceActiveAdmin(admin);
systemAppsEnabled.add(packageName);
return 1;
}
/** Returns {@code true} if the given {@code packageName} was a system app and was enabled. */
public boolean wasSystemAppEnabled(String packageName) {
return systemAppsEnabled.contains(packageName);
}
@Implementation
public void setUninstallBlocked(
ComponentName admin, String packageName, boolean uninstallBlocked) {
enforceActiveAdmin(admin);
if (uninstallBlocked) {
uninstallBlockedPackages.add(packageName);
} else {
uninstallBlockedPackages.remove(packageName);
}
}
@Implementation
public boolean isUninstallBlocked(ComponentName admin, String packageName) {
enforceActiveAdmin(admin);
return uninstallBlockedPackages.contains(packageName);
}
private ShadowUserManager getShadowUserManager() {
return Shadows.shadowOf(
(UserManager) RuntimeEnvironment.application.getSystemService(Context.USER_SERVICE));
}
/** Sets the admin as active admin and device owner. */
public void setDeviceOwner(ComponentName admin) {
setActiveAdmin(admin);
deviceOwner = admin;
}
/** Sets the admin as active admin and profile owner. */
public void setProfileOwner(ComponentName admin) {
setActiveAdmin(admin);
profileOwner = admin;
}
/** Sets the given {@code componentName} as one of the active admins. */
public void setActiveAdmin(ComponentName componentName) {
deviceAdmins.add(componentName);
}
@Implementation
public Bundle getApplicationRestrictions(ComponentName admin, String packageName) {
enforceDeviceOwnerOrProfileOwner(admin);
return getApplicationRestrictions(packageName);
}
/** Returns all application restrictions of the {@code packageName} in a {@link Bundle}. */
public Bundle getApplicationRestrictions(String packageName) {
Bundle bundle = applicationRestrictionsMap.get(packageName);
// If no restrictions were saved, DPM method should return an empty Bundle as per JavaDoc.
return bundle != null ? bundle : Bundle.EMPTY;
}
@Implementation
public void setApplicationRestrictions(
ComponentName admin, String packageName, Bundle applicationRestrictions) {
enforceDeviceOwnerOrProfileOwner(admin);
setApplicationRestrictions(packageName, applicationRestrictions);
}
/**
* Sets the application restrictions of the {@code packageName}.
*
* <p>The new {@code applicationRestrictions} always completely overwrites any existing ones.
*/
public void setApplicationRestrictions(String packageName, Bundle applicationRestrictions) {
applicationRestrictionsMap.put(packageName, applicationRestrictions);
}
private void enforceDeviceOwnerOrProfileOwner(ComponentName admin) {
if (!admin.equals(deviceOwner) && !admin.equals(profileOwner)) {
throw new SecurityException("[" + admin + "] is neither a device owner nor a profile owner.");
}
}
private void enforceActiveAdmin(ComponentName admin) {
if (!deviceAdmins.contains(admin)) {
throw new SecurityException("[" + admin + "] is not an active device admin");
}
}
@Implementation
public void setAccountManagementDisabled(
ComponentName admin, String accountType, boolean disabled) {
enforceDeviceOwnerOrProfileOwner(admin);
if (disabled) {
accountTypesWithManagementDisabled.add(accountType);
} else {
accountTypesWithManagementDisabled.remove(accountType);
}
}
@Implementation
public String[] getAccountTypesWithManagementDisabled() {
return accountTypesWithManagementDisabled.toArray(new String[0]);
}
}