Loading services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +21 −4 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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. */ Loading Loading @@ -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) { services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerServiceShellCommand.java +40 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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); } Loading @@ -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) { Loading @@ -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; } } services/devicepolicy/java/com/android/server/devicepolicy/Owners.java +37 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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) { Loading Loading
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +21 −4 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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. */ Loading Loading @@ -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) {
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerServiceShellCommand.java +40 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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); } Loading @@ -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) { Loading @@ -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; } }
services/devicepolicy/java/com/android/server/devicepolicy/Owners.java +37 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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) { Loading