From 50c7ad25be1ad3df8f19c22c21b4c7252a73d4ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martynas=20Petu=C5=A1ka?= Date: Tue, 7 Feb 2023 15:02:01 +0000 Subject: [PATCH] Fix DPMS NPE on admin ComponentDetails Test: Provision into PO and open BetterBug - there should be no Work Setup Crashed report. Bug: b/266725883 Change-Id: I6acf3a72714790c071bed5cde81c9b6d5d0d1711 --- .../DevicePolicyManagerService.java | 53 +++++++++++++------ 1 file changed, 38 insertions(+), 15 deletions(-) diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index c1e7bba5690be..5dafda4273d64 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -7119,11 +7119,20 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { * @param factoryReset null: legacy behaviour, false: attempt to remove user, true: attempt to * factory reset */ - private void wipeDataNoLock(ComponentName admin, int flags, String internalReason, - @NonNull String wipeReasonForUser, int userId, boolean calledOnParentInstance, + private void wipeDataNoLock(@Nullable ComponentName admin, int flags, String internalReason, + String wipeReasonForUser, int userId, boolean calledOnParentInstance, @Nullable Boolean factoryReset) { wtfIfInLock(); - + final String adminPackage; + if (admin != null) { + adminPackage = admin.getPackageName(); + } else { + int callerId = mInjector.binderGetCallingUid(); + String[] adminPackages = mInjector.getPackageManager().getPackagesForUid(callerId); + Preconditions.checkState(adminPackages.length > 0, + "Caller %s does not have any associated packages", callerId); + adminPackage = adminPackages[0]; + } mInjector.binderWithCleanCallingIdentity(() -> { // First check whether the admin is allowed to wipe the device/user/profile. final String restriction; @@ -7142,7 +7151,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { boolean isSystemUser = userId == UserHandle.USER_SYSTEM; boolean wipeDevice; if (factoryReset == null || !mInjector.isChangeEnabled(EXPLICIT_WIPE_BEHAVIOUR, - admin.getPackageName(), + adminPackage, userId)) { // Legacy mode wipeDevice = isSystemUser; @@ -8788,9 +8797,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public boolean hasDeviceOwner() { final CallerIdentity caller = getCallerIdentity(); - Preconditions.checkCallAuthorization(isDefaultDeviceOwner(caller) - || canManageUsers(caller) || isFinancedDeviceOwner(caller) - || hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS)); + Preconditions.checkCallAuthorization( + isDefaultDeviceOwner(caller) || canManageUsers(caller) || isFinancedDeviceOwner( + caller) || hasCallingOrSelfPermission( + permission.MANAGE_PROFILE_AND_DEVICE_OWNERS)); return mOwners.hasDeviceOwner(); } @@ -8798,10 +8808,16 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return isDeviceOwner(admin.info.getComponent(), admin.getUserHandle().getIdentifier()); } - public boolean isDeviceOwner(ComponentName who, int userId) { + /** + * Check if the user is a Device Owner + * + * @param who component to check against + * @param userId user to check + * @return if the user is a Device Owner + */ + public boolean isDeviceOwner(@Nullable ComponentName who, int userId) { synchronized (getLockObject()) { - return mOwners.hasDeviceOwner() - && mOwners.getDeviceOwnerUserId() == userId + return mOwners.hasDeviceOwner() && mOwners.getDeviceOwnerUserId() == userId && mOwners.getDeviceOwnerComponent().equals(who); } } @@ -8850,9 +8866,16 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } - public boolean isProfileOwner(ComponentName who, int userId) { - final ComponentName profileOwner = mInjector.binderWithCleanCallingIdentity(() -> - getProfileOwnerAsUser(userId)); + /** + * Check if {@link userId} is a Profile Owner + * + * @param who component to check against + * @param userId user to check + * @return if the user is a Profile Owner + */ + public boolean isProfileOwner(@Nullable ComponentName who, int userId) { + final ComponentName profileOwner = mInjector.binderWithCleanCallingIdentity( + () -> getProfileOwnerAsUser(userId)); return who != null && who.equals(profileOwner); } @@ -11416,8 +11439,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } private boolean isAdminAffectedByRestriction( - ComponentName admin, String userRestriction, int userId) { - switch(mUserManager.getUserRestrictionSource(userRestriction, UserHandle.of(userId))) { + @Nullable ComponentName admin, String userRestriction, int userId) { + switch (mUserManager.getUserRestrictionSource(userRestriction, UserHandle.of(userId))) { case UserManager.RESTRICTION_NOT_SET: return false; case UserManager.RESTRICTION_SOURCE_DEVICE_OWNER: