Merge "Add test method to remove admins." into nyc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
3c5ceae1d3
@@ -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);
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user