diff options
| -rw-r--r-- | services/core/java/com/android/server/pm/PackageManagerService.java | 31 |
1 files changed, 24 insertions, 7 deletions
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index cac96e544432..84f0057757dd 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -60,6 +60,7 @@ import android.app.ApplicationExitInfo; import android.app.ApplicationPackageManager; import android.app.BroadcastOptions; import android.app.IActivityManager; +import android.app.admin.DevicePolicyManagerInternal; import android.app.admin.IDevicePolicyManager; import android.app.admin.SecurityLog; import android.app.backup.IBackupManager; @@ -3371,8 +3372,10 @@ public class PackageManagerService implements PackageSender, TestUtilityService // TODO(b/261957226): centralise this logic in DPM boolean isPackageDeviceAdmin(String packageName, int userId) { final IDevicePolicyManager dpm = getDevicePolicyManager(); + final DevicePolicyManagerInternal dpmi = + mInjector.getLocalService(DevicePolicyManagerInternal.class); try { - if (dpm != null) { + if (dpm != null && dpmi != null) { final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent( /* callingUserOnly =*/ false); final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null @@ -3385,17 +3388,31 @@ public class PackageManagerService implements PackageSender, TestUtilityService return true; } // Does it contain a device admin for any user? - int[] users; + int[] allUsers = mUserManager.getUserIds(); + int[] targetUsers; if (userId == UserHandle.USER_ALL) { - users = mUserManager.getUserIds(); + targetUsers = allUsers; } else { - users = new int[]{userId}; + targetUsers = new int[]{userId}; } - for (int i = 0; i < users.length; ++i) { - if (dpm.packageHasActiveAdmins(packageName, users[i])) { + + for (int i = 0; i < targetUsers.length; ++i) { + if (dpm.packageHasActiveAdmins(packageName, targetUsers[i])) { return true; } - if (isDeviceManagementRoleHolder(packageName, users[i])) { + } + + // If a package is DMRH on a managed user, it should also be treated as an admin on + // that user. If that package is also a system package, it should also be protected + // on other users otherwise "uninstall updates" on an unmanaged user may break + // management on other users because apk version is shared between all users. + var packageState = snapshotComputer().getPackageStateInternal(packageName); + if (packageState == null) { + return false; + } + for (int user : packageState.isSystem() ? allUsers : targetUsers) { + if (isDeviceManagementRoleHolder(packageName, user) + && dpmi.isUserOrganizationManaged(user)) { return true; } } |