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_ACTIVE_ADMIN = "set-active-admin";
|
||||||
private static final String COMMAND_SET_DEVICE_OWNER = "set-device-owner";
|
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_SET_PROFILE_OWNER = "set-profile-owner";
|
||||||
|
private static final String COMMAND_REMOVE_ACTIVE_ADMIN = "remove-active-admin";
|
||||||
|
|
||||||
private IDevicePolicyManager mDevicePolicyManager;
|
private IDevicePolicyManager mDevicePolicyManager;
|
||||||
private int mUserId = UserHandle.USER_SYSTEM;
|
private int mUserId = UserHandle.USER_SYSTEM;
|
||||||
@@ -60,6 +61,8 @@ public final class Dpm extends BaseCommand {
|
|||||||
"[ --name <NAME> ] <COMPONENT>\n" +
|
"[ --name <NAME> ] <COMPONENT>\n" +
|
||||||
"usage: dpm set-profile-owner [ --user <USER_ID> | current ] [ --name <NAME> ] " +
|
"usage: dpm set-profile-owner [ --user <USER_ID> | current ] [ --name <NAME> ] " +
|
||||||
"<COMPONENT>\n" +
|
"<COMPONENT>\n" +
|
||||||
|
"usage: dpm remove-active-admin [ --user <USER_ID> | current ] [ --name <NAME> ] " +
|
||||||
|
"<COMPONENT>\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"dpm set-active-admin: Sets the given component as active admin" +
|
"dpm set-active-admin: Sets the given component as active admin" +
|
||||||
" for an existing user.\n" +
|
" for an existing user.\n" +
|
||||||
@@ -68,7 +71,11 @@ public final class Dpm extends BaseCommand {
|
|||||||
" package as device owner.\n" +
|
" package as device owner.\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"dpm set-profile-owner: Sets the given component as active admin and profile" +
|
"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
|
@Override
|
||||||
@@ -91,6 +98,9 @@ public final class Dpm extends BaseCommand {
|
|||||||
case COMMAND_SET_PROFILE_OWNER:
|
case COMMAND_SET_PROFILE_OWNER:
|
||||||
runSetProfileOwner();
|
runSetProfileOwner();
|
||||||
break;
|
break;
|
||||||
|
case COMMAND_REMOVE_ACTIVE_ADMIN:
|
||||||
|
runRemoveActiveAdmin();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException ("unknown command '" + command + "'");
|
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());
|
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 {
|
private void runSetProfileOwner() throws RemoteException {
|
||||||
parseArgs(/*canHaveName=*/ true);
|
parseArgs(/*canHaveName=*/ true);
|
||||||
mDevicePolicyManager.setActiveAdmin(mComponent, true /*refreshing*/, mUserId);
|
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) {
|
private void throwIfParentInstance(String functionName) {
|
||||||
if (mParentInstance) {
|
if (mParentInstance) {
|
||||||
throw new SecurityException(functionName + " cannot be called on the parent instance");
|
throw new SecurityException(functionName + " cannot be called on the parent instance");
|
||||||
|
|||||||
@@ -111,6 +111,7 @@ interface IDevicePolicyManager {
|
|||||||
boolean packageHasActiveAdmins(String packageName, int userHandle);
|
boolean packageHasActiveAdmins(String packageName, int userHandle);
|
||||||
void getRemoveWarning(in ComponentName policyReceiver, in RemoteCallback result, int userHandle);
|
void getRemoveWarning(in ComponentName policyReceiver, in RemoteCallback result, int userHandle);
|
||||||
void removeActiveAdmin(in ComponentName policyReceiver, 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);
|
boolean hasGrantedPolicy(in ComponentName policyReceiver, int usesPolicy, int userHandle);
|
||||||
|
|
||||||
void setActivePasswordState(int quality, int length, int letters, int uppercase, int lowercase,
|
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
|
@Override
|
||||||
public void removeActiveAdmin(ComponentName adminReceiver, int userHandle) {
|
public void removeActiveAdmin(ComponentName adminReceiver, int userHandle) {
|
||||||
if (!mHasFeature) {
|
if (!mHasFeature) {
|
||||||
@@ -5732,32 +5780,37 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
|||||||
enforceUserUnlocked(deviceOwnerUserId);
|
enforceUserUnlocked(deviceOwnerUserId);
|
||||||
|
|
||||||
final ActiveAdmin admin = getDeviceOwnerAdminLocked();
|
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();
|
long ident = mInjector.binderClearCallingIdentity();
|
||||||
try {
|
try {
|
||||||
mInjector.getIBackupManager().setBackupServiceActive(UserHandle.USER_SYSTEM, true);
|
clearDeviceOwnerLocked(admin, deviceOwnerUserId);
|
||||||
|
|
||||||
removeActiveAdminLocked(deviceOwnerComponent, deviceOwnerUserId);
|
removeActiveAdminLocked(deviceOwnerComponent, deviceOwnerUserId);
|
||||||
} catch (RemoteException e) {
|
|
||||||
throw new IllegalStateException("Failed reactivating backup service.", e);
|
|
||||||
} finally {
|
} finally {
|
||||||
mInjector.binderRestoreCallingIdentity(ident);
|
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
|
@Override
|
||||||
public boolean setProfileOwner(ComponentName who, String ownerName, int userHandle) {
|
public boolean setProfileOwner(ComponentName who, String ownerName, int userHandle) {
|
||||||
if (!mHasFeature) {
|
if (!mHasFeature) {
|
||||||
@@ -5794,14 +5847,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
|||||||
final ActiveAdmin admin =
|
final ActiveAdmin admin =
|
||||||
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
|
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
admin.disableCamera = false;
|
|
||||||
admin.userRestrictions = null;
|
|
||||||
clearUserPoliciesLocked(userId);
|
|
||||||
mOwners.removeProfileOwner(userId);
|
|
||||||
mOwners.writeProfileOwner(userId);
|
|
||||||
|
|
||||||
final long ident = mInjector.binderClearCallingIdentity();
|
final long ident = mInjector.binderClearCallingIdentity();
|
||||||
try {
|
try {
|
||||||
|
clearProfileOwnerLocked(admin, userId);
|
||||||
removeActiveAdminLocked(who, userId);
|
removeActiveAdminLocked(who, userId);
|
||||||
} finally {
|
} finally {
|
||||||
mInjector.binderRestoreCallingIdentity(ident);
|
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
|
@Override
|
||||||
public void setDeviceOwnerLockScreenInfo(ComponentName who, CharSequence info) {
|
public void setDeviceOwnerLockScreenInfo(ComponentName who, CharSequence info) {
|
||||||
Preconditions.checkNotNull(who, "ComponentName is null");
|
Preconditions.checkNotNull(who, "ComponentName is null");
|
||||||
@@ -5842,15 +5900,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
|||||||
policy.mUserProvisioningState = DevicePolicyManager.STATE_USER_UNMANAGED;
|
policy.mUserProvisioningState = DevicePolicyManager.STATE_USER_UNMANAGED;
|
||||||
saveSettingsLocked(userId);
|
saveSettingsLocked(userId);
|
||||||
|
|
||||||
final long ident = mInjector.binderClearCallingIdentity();
|
|
||||||
try {
|
try {
|
||||||
mIPackageManager.updatePermissionFlagsForAllApps(
|
mIPackageManager.updatePermissionFlagsForAllApps(
|
||||||
PackageManager.FLAG_PERMISSION_POLICY_FIXED,
|
PackageManager.FLAG_PERMISSION_POLICY_FIXED,
|
||||||
0 /* flagValues */, userId);
|
0 /* flagValues */, userId);
|
||||||
pushUserRestrictions(userId);
|
pushUserRestrictions(userId);
|
||||||
} catch (RemoteException re) {
|
} catch (RemoteException re) {
|
||||||
} finally {
|
// Shouldn't happen.
|
||||||
mInjector.binderRestoreCallingIdentity(ident);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user