Merge "Add test method to remove admins." into nyc-dev

This commit is contained in:
Amith Yamasani
2016-04-19 21:46:40 +00:00
committed by Android (Google) Code Review
4 changed files with 118 additions and 27 deletions

View File

@@ -44,6 +44,7 @@ public final class Dpm extends BaseCommand {
private static final String COMMAND_SET_ACTIVE_ADMIN = "set-active-admin";
private static final String COMMAND_SET_DEVICE_OWNER = "set-device-owner";
private static final String COMMAND_SET_PROFILE_OWNER = "set-profile-owner";
private static final String COMMAND_REMOVE_ACTIVE_ADMIN = "remove-active-admin";
private IDevicePolicyManager mDevicePolicyManager;
private int mUserId = UserHandle.USER_SYSTEM;
@@ -60,6 +61,8 @@ public final class Dpm extends BaseCommand {
"[ --name <NAME> ] <COMPONENT>\n" +
"usage: dpm set-profile-owner [ --user <USER_ID> | current ] [ --name <NAME> ] " +
"<COMPONENT>\n" +
"usage: dpm remove-active-admin [ --user <USER_ID> | current ] [ --name <NAME> ] " +
"<COMPONENT>\n" +
"\n" +
"dpm set-active-admin: Sets the given component as active admin" +
" for an existing user.\n" +
@@ -68,7 +71,11 @@ public final class Dpm extends BaseCommand {
" package as device owner.\n" +
"\n" +
"dpm set-profile-owner: Sets the given component as active admin and profile" +
" owner for an existing user.\n");
" owner for an existing user.\n" +
"\n" +
"dpm remove-active-admin: Disables an active admin, the admin must have declared" +
" android:testOnly in the application in its manifest. This will also remove" +
" device and profile owners\n");
}
@Override
@@ -91,6 +98,9 @@ public final class Dpm extends BaseCommand {
case COMMAND_SET_PROFILE_OWNER:
runSetProfileOwner();
break;
case COMMAND_REMOVE_ACTIVE_ADMIN:
runRemoveActiveAdmin();
break;
default:
throw new IllegalArgumentException ("unknown command '" + command + "'");
}
@@ -152,6 +162,12 @@ public final class Dpm extends BaseCommand {
System.out.println("Active admin set to component " + mComponent.toShortString());
}
private void runRemoveActiveAdmin() throws RemoteException {
parseArgs(/*canHaveName=*/ false);
mDevicePolicyManager.forceRemoveActiveAdmin(mComponent, mUserId);
System.out.println("Success: Admin removed " + mComponent);
}
private void runSetProfileOwner() throws RemoteException {
parseArgs(/*canHaveName=*/ true);
mDevicePolicyManager.setActiveAdmin(mComponent, true /*refreshing*/, mUserId);

View File

@@ -6391,6 +6391,24 @@ public class DevicePolicyManager {
}
}
/**
* @hide
* Remove a test admin synchronously without sending it a broadcast about being removed.
* If the admin is a profile owner or device owner it will still be removed.
*
* @param userHandle user id to remove the admin for.
* @param admin The administration compononent to remove.
* @throws SecurityException if the caller is not shell / root or the admin package
* isn't a test application see {@link ApplicationInfo#FLAG_TEST_APP}.
*/
public void forceRemoveActiveAdmin(ComponentName adminReceiver, int userHandle) {
try {
mService.forceRemoveActiveAdmin(adminReceiver, userHandle);
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
}
private void throwIfParentInstance(String functionName) {
if (mParentInstance) {
throw new SecurityException(functionName + " cannot be called on the parent instance");

View File

@@ -111,6 +111,7 @@ interface IDevicePolicyManager {
boolean packageHasActiveAdmins(String packageName, int userHandle);
void getRemoveWarning(in ComponentName policyReceiver, in RemoteCallback result, int userHandle);
void removeActiveAdmin(in ComponentName policyReceiver, int userHandle);
void forceRemoveActiveAdmin(in ComponentName policyReceiver, int userHandle);
boolean hasGrantedPolicy(in ComponentName policyReceiver, int usesPolicy, int userHandle);
void setActivePasswordState(int quality, int length, int letters, int uppercase, int lowercase,

View File

@@ -2909,6 +2909,54 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
}
public void forceRemoveActiveAdmin(ComponentName adminReceiver, int userHandle) {
if (!mHasFeature) {
return;
}
Preconditions.checkNotNull(adminReceiver, "ComponentName is null");
enforceShell("forceRemoveActiveAdmin");
long ident = mInjector.binderClearCallingIdentity();
try {
final ApplicationInfo ai;
try {
ai = mIPackageManager.getApplicationInfo(adminReceiver.getPackageName(),
0, userHandle);
} catch (RemoteException e) {
throw new IllegalStateException(e);
}
if (ai == null) {
throw new IllegalStateException("Couldn't find package to remove admin "
+ adminReceiver.getPackageName() + " " + userHandle);
}
if ((ai.flags & ApplicationInfo.FLAG_TEST_ONLY) == 0) {
throw new SecurityException("Attempt to remove non-test admin " + adminReceiver
+ adminReceiver + " " + userHandle);
}
// If admin is a device or profile owner tidy that up first.
synchronized (this) {
if (isDeviceOwner(adminReceiver, userHandle)) {
clearDeviceOwnerLocked(getDeviceOwnerAdminLocked(), userHandle);
}
if (isProfileOwner(adminReceiver, userHandle)) {
final ActiveAdmin admin = getActiveAdminUncheckedLocked(adminReceiver,
userHandle, /* parent */ false);
clearProfileOwnerLocked(admin, userHandle);
}
}
// Remove the admin skipping sending the broadcast.
removeAdminArtifacts(adminReceiver, userHandle);
} finally {
mInjector.binderRestoreCallingIdentity(ident);
}
}
private void enforceShell(String method) {
final int callingUid = Binder.getCallingUid();
if (callingUid != Process.SHELL_UID && callingUid != Process.ROOT_UID) {
throw new SecurityException("Non-shell user attempted to call " + method);
}
}
@Override
public void removeActiveAdmin(ComponentName adminReceiver, int userHandle) {
if (!mHasFeature) {
@@ -5732,32 +5780,37 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
enforceUserUnlocked(deviceOwnerUserId);
final ActiveAdmin admin = getDeviceOwnerAdminLocked();
if (admin != null) {
admin.disableCamera = false;
admin.userRestrictions = null;
admin.forceEphemeralUsers = false;
mUserManagerInternal.setForceEphemeralUsers(admin.forceEphemeralUsers);
}
clearUserPoliciesLocked(deviceOwnerUserId);
mOwners.clearDeviceOwner();
mOwners.writeDeviceOwner();
updateDeviceOwnerLocked();
disableSecurityLoggingIfNotCompliant();
// Reactivate backup service.
long ident = mInjector.binderClearCallingIdentity();
try {
mInjector.getIBackupManager().setBackupServiceActive(UserHandle.USER_SYSTEM, true);
clearDeviceOwnerLocked(admin, deviceOwnerUserId);
removeActiveAdminLocked(deviceOwnerComponent, deviceOwnerUserId);
} catch (RemoteException e) {
throw new IllegalStateException("Failed reactivating backup service.", e);
} finally {
mInjector.binderRestoreCallingIdentity(ident);
}
}
}
private void clearDeviceOwnerLocked(ActiveAdmin admin, int userId) {
if (admin != null) {
admin.disableCamera = false;
admin.userRestrictions = null;
admin.forceEphemeralUsers = false;
mUserManagerInternal.setForceEphemeralUsers(admin.forceEphemeralUsers);
}
clearUserPoliciesLocked(userId);
mOwners.clearDeviceOwner();
mOwners.writeDeviceOwner();
updateDeviceOwnerLocked();
disableSecurityLoggingIfNotCompliant();
try {
// Reactivate backup service.
mInjector.getIBackupManager().setBackupServiceActive(UserHandle.USER_SYSTEM, true);
} catch (RemoteException e) {
throw new IllegalStateException("Failed reactivating backup service.", e);
}
}
@Override
public boolean setProfileOwner(ComponentName who, String ownerName, int userHandle) {
if (!mHasFeature) {
@@ -5794,14 +5847,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
final ActiveAdmin admin =
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
synchronized (this) {
admin.disableCamera = false;
admin.userRestrictions = null;
clearUserPoliciesLocked(userId);
mOwners.removeProfileOwner(userId);
mOwners.writeProfileOwner(userId);
final long ident = mInjector.binderClearCallingIdentity();
try {
clearProfileOwnerLocked(admin, userId);
removeActiveAdminLocked(who, userId);
} finally {
mInjector.binderRestoreCallingIdentity(ident);
@@ -5809,6 +5857,16 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
}
public void clearProfileOwnerLocked(ActiveAdmin admin, int userId) {
if (admin != null) {
admin.disableCamera = false;
admin.userRestrictions = null;
}
clearUserPoliciesLocked(userId);
mOwners.removeProfileOwner(userId);
mOwners.writeProfileOwner(userId);
}
@Override
public void setDeviceOwnerLockScreenInfo(ComponentName who, CharSequence info) {
Preconditions.checkNotNull(who, "ComponentName is null");
@@ -5842,15 +5900,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
policy.mUserProvisioningState = DevicePolicyManager.STATE_USER_UNMANAGED;
saveSettingsLocked(userId);
final long ident = mInjector.binderClearCallingIdentity();
try {
mIPackageManager.updatePermissionFlagsForAllApps(
PackageManager.FLAG_PERMISSION_POLICY_FIXED,
0 /* flagValues */, userId);
pushUserRestrictions(userId);
} catch (RemoteException re) {
} finally {
mInjector.binderRestoreCallingIdentity(ident);
// Shouldn't happen.
}
}