diff options
3 files changed, 98 insertions, 4 deletions
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 717e77b22bdc..06d737fa7ca8 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -313,6 +313,7 @@ import com.android.server.PersistentDataBlockManagerInternal; import com.android.server.SystemServerInitThreadPool; import com.android.server.SystemService; import com.android.server.devicepolicy.ActiveAdmin.TrustAgentInfo; +import com.android.server.devicepolicy.Owners.OwnerDto; import com.android.server.inputmethod.InputMethodManagerInternal; import com.android.server.net.NetworkPolicyManagerInternal; import com.android.server.pm.RestrictionsSet; @@ -1130,6 +1131,22 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { mSafetyChecker = new OneTimeSafetyChecker(this, operation, reason); } + // Used by DevicePolicyManagerServiceShellCommand + List<OwnerDto> listAllOwners() { + Preconditions.checkCallAuthorization( + hasCallingOrSelfPermission(permission.MANAGE_DEVICE_ADMINS)); + + List<OwnerDto> owners = mOwners.listAllOwners(); + synchronized (getLockObject()) { + for (int i = 0; i < owners.size(); i++) { + OwnerDto owner = owners.get(i); + owner.isAffiliated = isUserAffiliatedWithDeviceLocked(owner.userId); + } + } + + return owners; + } + /** * Unit test will subclass it to inject mocks. */ @@ -13466,15 +13483,15 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mOwners.hasDeviceOwner()) { return false; } - if (userId == mOwners.getDeviceOwnerUserId()) { - // The user that the DO is installed on is always affiliated with the device. - return true; - } if (userId == UserHandle.USER_SYSTEM) { // The system user is always affiliated in a DO device, // even if in headless system user mode. return true; } + if (userId == mOwners.getDeviceOwnerUserId()) { + // The user that the DO is installed on is always affiliated with the device. + return true; + } final ComponentName profileOwner = getProfileOwnerAsUser(userId); if (profileOwner == null) { diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerServiceShellCommand.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerServiceShellCommand.java index fc1d83158801..222c987d906f 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerServiceShellCommand.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerServiceShellCommand.java @@ -18,13 +18,17 @@ package com.android.server.devicepolicy; import android.app.admin.DevicePolicyManager; import android.os.ShellCommand; +import com.android.server.devicepolicy.Owners.OwnerDto; + import java.io.PrintWriter; +import java.util.List; import java.util.Objects; final class DevicePolicyManagerServiceShellCommand extends ShellCommand { private static final String CMD_IS_SAFE_OPERATION = "is-operation-safe"; private static final String CMD_SET_SAFE_OPERATION = "set-operation-safe"; + private static final String CMD_LIST_OWNERS = "list-owners"; private final DevicePolicyManagerService mService; @@ -51,6 +55,8 @@ final class DevicePolicyManagerServiceShellCommand extends ShellCommand { return runIsSafeOperation(pw); case CMD_SET_SAFE_OPERATION: return runSetSafeOperation(pw); + case CMD_LIST_OWNERS: + return runListOwners(pw); default: return onInvalidCommand(pw, cmd); } @@ -76,6 +82,8 @@ final class DevicePolicyManagerServiceShellCommand extends ShellCommand { pw.printf(" %s <OPERATION_ID> <REASON_ID>\n", CMD_SET_SAFE_OPERATION); pw.printf(" Emulates the result of the next call to check if the given operation is safe" + " \n\n"); + pw.printf(" %s\n", CMD_LIST_OWNERS); + pw.printf(" Lists the device / profile owners per user \n\n"); } private int runIsSafeOperation(PrintWriter pw) { @@ -97,4 +105,36 @@ final class DevicePolicyManagerServiceShellCommand extends ShellCommand { DevicePolicyManager.unsafeOperationReasonToString(reason)); return 0; } + + private int runListOwners(PrintWriter pw) { + List<OwnerDto> owners = mService.listAllOwners(); + if (owners.isEmpty()) { + pw.println("none"); + return 0; + } + int size = owners.size(); + if (size == 1) { + pw.println("1 owner:"); + } else { + pw.printf("%d owners:\n", size); + } + + for (int i = 0; i < size; i++) { + OwnerDto owner = owners.get(i); + pw.printf("User %2d: admin=%s", owner.userId, owner.admin.flattenToShortString()); + if (owner.isDeviceOwner) { + pw.print(",DeviceOwner"); + } + if (owner.isProfileOwner) { + pw.print(",ProfileOwner"); + } + if (owner.isAffiliated) { + pw.print(",Affiliated"); + } + pw.println(); + } + + return 0; + } + } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java index 809afe01da2d..1e70d59a5fd5 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java @@ -17,6 +17,7 @@ package com.android.server.devicepolicy; import android.annotation.Nullable; +import android.annotation.UserIdInt; import android.app.ActivityManagerInternal; import android.app.AppOpsManagerInternal; import android.app.admin.SystemUpdateInfo; @@ -57,6 +58,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.time.LocalDate; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Objects; @@ -433,6 +435,23 @@ class Owners { } } + List<OwnerDto> listAllOwners() { + List<OwnerDto> owners = new ArrayList<>(); + synchronized (mLock) { + if (mDeviceOwner != null) { + owners.add(new OwnerDto(mDeviceOwnerUserId, mDeviceOwner.admin, + /* isDeviceOwner= */ true)); + } + for (int i = 0; i < mProfileOwners.size(); i++) { + int userId = mProfileOwners.keyAt(i); + OwnerInfo info = mProfileOwners.valueAt(i); + owners.add(new OwnerDto(userId, info.admin, /* isDeviceOwner= */ false)); + } + } + return owners; + } + + SystemUpdatePolicy getSystemUpdatePolicy() { synchronized (mLock) { return mSystemUpdatePolicy; @@ -1076,6 +1095,24 @@ class Owners { } } + /** + * Data-transfer object used by {@link DevicePolicyManagerServiceShellCommand}. + */ + static final class OwnerDto { + public final @UserIdInt int userId; + public final ComponentName admin; + public final boolean isDeviceOwner; + public final boolean isProfileOwner; + public boolean isAffiliated; + + private OwnerDto(@UserIdInt int userId, ComponentName admin, boolean isDeviceOwner) { + this.userId = userId; + this.admin = Objects.requireNonNull(admin, "admin must not be null"); + this.isDeviceOwner = isDeviceOwner; + this.isProfileOwner = !isDeviceOwner; + } + } + public void dump(IndentingPrintWriter pw) { boolean needBlank = false; if (mDeviceOwner != null) { |