Loading core/java/android/app/admin/DevicePolicyManager.java +9 −6 Original line number Diff line number Diff line Loading @@ -14569,12 +14569,13 @@ public class DevicePolicyManager { } /** * Called by Device owner to disable user control over apps. User will not be able to clear * app data or force-stop packages. * Called by a device owner or a profile owner to disable user control over apps. User will not * be able to clear app data or force-stop packages. When called by a device owner, applies to * all users on the device. * * @param admin which {@link DeviceAdminReceiver} this request is associated with * @param packages The package names for the apps. * @throws SecurityException if {@code admin} is not a device owner. * @throws SecurityException if {@code admin} is not a device owner or a profile owner. */ public void setUserControlDisabledPackages(@NonNull ComponentName admin, @NonNull List<String> packages) { Loading @@ -14589,12 +14590,14 @@ public class DevicePolicyManager { } /** * Returns the list of packages over which user control is disabled by the device owner. * Returns the list of packages over which user control is disabled by a device or profile * owner. * * @param admin which {@link DeviceAdminReceiver} this request is associated with * @throws SecurityException if {@code admin} is not a device owner. * @throws SecurityException if {@code admin} is not a device or profile owner. */ public @NonNull List<String> getUserControlDisabledPackages(@NonNull ComponentName admin) { @NonNull public List<String> getUserControlDisabledPackages(@NonNull ComponentName admin) { throwIfParentInstance("getUserControlDisabledPackages"); if (mService != null) { try { services/core/java/android/content/pm/PackageManagerInternal.java +3 −3 Original line number Diff line number Diff line Loading @@ -371,10 +371,10 @@ public abstract class PackageManagerInternal { int deviceOwnerUserId, String deviceOwner, SparseArray<String> profileOwners); /** * Called by Owners to set the package names protected by the device owner. * Marks packages as protected for a given user or all users in case of USER_ALL. */ public abstract void setDeviceOwnerProtectedPackages( String deviceOwnerPackageName, List<String> packageNames); public abstract void setOwnerProtectedPackages( @UserIdInt int userId, @NonNull List<String> packageNames); /** * Returns {@code true} if a given package can't be wiped. Otherwise, returns {@code false}. Loading services/core/java/com/android/server/pm/PackageManagerInternalBase.java +3 −4 Original line number Diff line number Diff line Loading @@ -352,10 +352,9 @@ abstract class PackageManagerInternalBase extends PackageManagerInternal { @Override @Deprecated public final void setDeviceOwnerProtectedPackages( String deviceOwnerPackageName, List<String> packageNames) { getProtectedPackages().setDeviceOwnerProtectedPackages( deviceOwnerPackageName, packageNames); public final void setOwnerProtectedPackages( @UserIdInt int userId, @NonNull List<String> packageNames) { getProtectedPackages().setOwnerProtectedPackages(userId, packageNames); } @Override Loading services/core/java/com/android/server/pm/ProtectedPackages.java +24 −19 Original line number Diff line number Diff line Loading @@ -16,11 +16,11 @@ package com.android.server.pm; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.content.Context; import android.os.UserHandle; import android.util.ArrayMap; import android.util.ArraySet; import android.util.SparseArray; Loading Loading @@ -56,7 +56,7 @@ public class ProtectedPackages { @Nullable @GuardedBy("this") private final ArrayMap<String, Set<String>> mDeviceOwnerProtectedPackages = new ArrayMap<>(); private final SparseArray<Set<String>> mOwnerProtectedPackages = new SparseArray<>(); private final Context mContext; Loading @@ -79,13 +79,13 @@ public class ProtectedPackages { : profileOwnerPackages.clone(); } /** Sets the protected packages for the device owner. */ public synchronized void setDeviceOwnerProtectedPackages( String deviceOwnerPackageName, List<String> packageNames) { /** Sets packages protected by a device or profile owner. */ public synchronized void setOwnerProtectedPackages( @UserIdInt int userId, @NonNull List<String> packageNames) { if (packageNames.isEmpty()) { mDeviceOwnerProtectedPackages.remove(deviceOwnerPackageName); mOwnerProtectedPackages.remove(userId); } else { mDeviceOwnerProtectedPackages.put(deviceOwnerPackageName, new ArraySet<>(packageNames)); mOwnerProtectedPackages.put(userId, new ArraySet<>(packageNames)); } } Loading Loading @@ -123,19 +123,24 @@ public class ProtectedPackages { * <p>A protected package means that, apart from the package owner, no system or privileged apps * can modify its data or package state. */ private synchronized boolean isProtectedPackage(String packageName) { private synchronized boolean isProtectedPackage(@UserIdInt int userId, String packageName) { return packageName != null && (packageName.equals(mDeviceProvisioningPackage) || isDeviceOwnerProtectedPackage(packageName)); || isOwnerProtectedPackage(userId, packageName)); } /** Returns {@code true} if the given package is a protected package set by any device owner. */ private synchronized boolean isDeviceOwnerProtectedPackage(String packageName) { for (Set<String> protectedPackages : mDeviceOwnerProtectedPackages.values()) { if (protectedPackages.contains(packageName)) { return true; } /** * Returns {@code true} if the given package is a protected package set by any device or * profile owner. */ private synchronized boolean isOwnerProtectedPackage( @UserIdInt int userId, String packageName) { return isPackageProtectedForUser(UserHandle.USER_ALL, packageName) || isPackageProtectedForUser(userId, packageName); } return false; private synchronized boolean isPackageProtectedForUser(int userId, String packageName) { int userIdx = mOwnerProtectedPackages.indexOfKey(userId); return userIdx >= 0 && mOwnerProtectedPackages.valueAt(userIdx).contains(packageName); } /** Loading @@ -146,7 +151,7 @@ public class ProtectedPackages { */ public boolean isPackageStateProtected(@UserIdInt int userId, String packageName) { return hasDeviceOwnerOrProfileOwner(userId, packageName) || isProtectedPackage(packageName); || isProtectedPackage(userId, packageName); } /** Loading @@ -155,6 +160,6 @@ public class ProtectedPackages { */ public boolean isPackageDataProtected(@UserIdInt int userId, String packageName) { return hasDeviceOwnerOrProfileOwner(userId, packageName) || isProtectedPackage(packageName); || isProtectedPackage(userId, packageName); } } services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +24 −22 Original line number Diff line number Diff line Loading @@ -3116,6 +3116,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { deleteTransferOwnershipBundleLocked(metadata.userId); } updateSystemUpdateFreezePeriodsRecord(/* saveIfChanged */ true); pushUserControlDisabledPackagesLocked(metadata.userId); } private void maybeLogStart() { Loading Loading @@ -3178,18 +3179,22 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { startOwnerService(userId, "start-user"); } // TODO(b/218639412): Once PM stores these on a per-user basis, push even empty lists to handle // DO/PO removal correctly. void pushUserControlDisabledPackagesLocked(int userId) { if (userId != mOwners.getDeviceOwnerUserId()) { return; } ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked(); if (deviceOwner == null || deviceOwner.protectedPackages == null) { return; final int targetUserId; final ActiveAdmin owner; if (getDeviceOwnerUserIdUncheckedLocked() == userId) { owner = getDeviceOwnerAdminLocked(); targetUserId = UserHandle.USER_ALL; } else { owner = getProfileOwnerAdminLocked(userId); targetUserId = userId; } mInjector.getPackageManagerInternal().setDeviceOwnerProtectedPackages( deviceOwner.info.getPackageName(), deviceOwner.protectedPackages); List<String> protectedPackages = (owner == null || owner.protectedPackages == null) ? Collections.emptyList() : owner.protectedPackages; mInjector.binderWithCleanCallingIdentity(() -> mInjector.getPackageManagerInternal().setOwnerProtectedPackages( targetUserId, protectedPackages)); } @Override Loading Loading @@ -16967,23 +16972,20 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { Objects.requireNonNull(who, "ComponentName is null"); Objects.requireNonNull(packages, "packages is null"); final CallerIdentity caller = getCallerIdentity(who); Preconditions.checkCallAuthorization( isDefaultDeviceOwner(caller) || isFinancedDeviceOwner(caller)); Preconditions.checkCallAuthorization(isDefaultDeviceOwner(caller) || isProfileOwner(caller) || isFinancedDeviceOwner(caller)); checkCanExecuteOrThrowUnsafe( DevicePolicyManager.OPERATION_SET_USER_CONTROL_DISABLED_PACKAGES); synchronized (getLockObject()) { ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked(); if (!Objects.equals(deviceOwner.protectedPackages, packages)) { deviceOwner.protectedPackages = packages.isEmpty() ? null : packages; ActiveAdmin owner = getDeviceOrProfileOwnerAdminLocked(caller.getUserId()); if (!Objects.equals(owner.protectedPackages, packages)) { owner.protectedPackages = packages.isEmpty() ? null : packages; saveSettingsLocked(caller.getUserId()); pushUserControlDisabledPackagesLocked(caller.getUserId()); } } mInjector.binderWithCleanCallingIdentity( () -> mInjector.getPackageManagerInternal().setDeviceOwnerProtectedPackages( who.getPackageName(), packages)); DevicePolicyEventLogger .createEvent(DevicePolicyEnums.SET_USER_CONTROL_DISABLED_PACKAGES) .setAdmin(who) Loading @@ -16996,11 +16998,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { Objects.requireNonNull(who, "ComponentName is null"); final CallerIdentity caller = getCallerIdentity(who); Preconditions.checkCallAuthorization( isDefaultDeviceOwner(caller) || isFinancedDeviceOwner(caller)); Preconditions.checkCallAuthorization(isDefaultDeviceOwner(caller) || isProfileOwner(caller) || isFinancedDeviceOwner(caller)); synchronized (getLockObject()) { ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked(); ActiveAdmin deviceOwner = getDeviceOrProfileOwnerAdminLocked(caller.getUserId()); return deviceOwner.protectedPackages != null ? deviceOwner.protectedPackages : Collections.emptyList(); } Loading
core/java/android/app/admin/DevicePolicyManager.java +9 −6 Original line number Diff line number Diff line Loading @@ -14569,12 +14569,13 @@ public class DevicePolicyManager { } /** * Called by Device owner to disable user control over apps. User will not be able to clear * app data or force-stop packages. * Called by a device owner or a profile owner to disable user control over apps. User will not * be able to clear app data or force-stop packages. When called by a device owner, applies to * all users on the device. * * @param admin which {@link DeviceAdminReceiver} this request is associated with * @param packages The package names for the apps. * @throws SecurityException if {@code admin} is not a device owner. * @throws SecurityException if {@code admin} is not a device owner or a profile owner. */ public void setUserControlDisabledPackages(@NonNull ComponentName admin, @NonNull List<String> packages) { Loading @@ -14589,12 +14590,14 @@ public class DevicePolicyManager { } /** * Returns the list of packages over which user control is disabled by the device owner. * Returns the list of packages over which user control is disabled by a device or profile * owner. * * @param admin which {@link DeviceAdminReceiver} this request is associated with * @throws SecurityException if {@code admin} is not a device owner. * @throws SecurityException if {@code admin} is not a device or profile owner. */ public @NonNull List<String> getUserControlDisabledPackages(@NonNull ComponentName admin) { @NonNull public List<String> getUserControlDisabledPackages(@NonNull ComponentName admin) { throwIfParentInstance("getUserControlDisabledPackages"); if (mService != null) { try {
services/core/java/android/content/pm/PackageManagerInternal.java +3 −3 Original line number Diff line number Diff line Loading @@ -371,10 +371,10 @@ public abstract class PackageManagerInternal { int deviceOwnerUserId, String deviceOwner, SparseArray<String> profileOwners); /** * Called by Owners to set the package names protected by the device owner. * Marks packages as protected for a given user or all users in case of USER_ALL. */ public abstract void setDeviceOwnerProtectedPackages( String deviceOwnerPackageName, List<String> packageNames); public abstract void setOwnerProtectedPackages( @UserIdInt int userId, @NonNull List<String> packageNames); /** * Returns {@code true} if a given package can't be wiped. Otherwise, returns {@code false}. Loading
services/core/java/com/android/server/pm/PackageManagerInternalBase.java +3 −4 Original line number Diff line number Diff line Loading @@ -352,10 +352,9 @@ abstract class PackageManagerInternalBase extends PackageManagerInternal { @Override @Deprecated public final void setDeviceOwnerProtectedPackages( String deviceOwnerPackageName, List<String> packageNames) { getProtectedPackages().setDeviceOwnerProtectedPackages( deviceOwnerPackageName, packageNames); public final void setOwnerProtectedPackages( @UserIdInt int userId, @NonNull List<String> packageNames) { getProtectedPackages().setOwnerProtectedPackages(userId, packageNames); } @Override Loading
services/core/java/com/android/server/pm/ProtectedPackages.java +24 −19 Original line number Diff line number Diff line Loading @@ -16,11 +16,11 @@ package com.android.server.pm; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.content.Context; import android.os.UserHandle; import android.util.ArrayMap; import android.util.ArraySet; import android.util.SparseArray; Loading Loading @@ -56,7 +56,7 @@ public class ProtectedPackages { @Nullable @GuardedBy("this") private final ArrayMap<String, Set<String>> mDeviceOwnerProtectedPackages = new ArrayMap<>(); private final SparseArray<Set<String>> mOwnerProtectedPackages = new SparseArray<>(); private final Context mContext; Loading @@ -79,13 +79,13 @@ public class ProtectedPackages { : profileOwnerPackages.clone(); } /** Sets the protected packages for the device owner. */ public synchronized void setDeviceOwnerProtectedPackages( String deviceOwnerPackageName, List<String> packageNames) { /** Sets packages protected by a device or profile owner. */ public synchronized void setOwnerProtectedPackages( @UserIdInt int userId, @NonNull List<String> packageNames) { if (packageNames.isEmpty()) { mDeviceOwnerProtectedPackages.remove(deviceOwnerPackageName); mOwnerProtectedPackages.remove(userId); } else { mDeviceOwnerProtectedPackages.put(deviceOwnerPackageName, new ArraySet<>(packageNames)); mOwnerProtectedPackages.put(userId, new ArraySet<>(packageNames)); } } Loading Loading @@ -123,19 +123,24 @@ public class ProtectedPackages { * <p>A protected package means that, apart from the package owner, no system or privileged apps * can modify its data or package state. */ private synchronized boolean isProtectedPackage(String packageName) { private synchronized boolean isProtectedPackage(@UserIdInt int userId, String packageName) { return packageName != null && (packageName.equals(mDeviceProvisioningPackage) || isDeviceOwnerProtectedPackage(packageName)); || isOwnerProtectedPackage(userId, packageName)); } /** Returns {@code true} if the given package is a protected package set by any device owner. */ private synchronized boolean isDeviceOwnerProtectedPackage(String packageName) { for (Set<String> protectedPackages : mDeviceOwnerProtectedPackages.values()) { if (protectedPackages.contains(packageName)) { return true; } /** * Returns {@code true} if the given package is a protected package set by any device or * profile owner. */ private synchronized boolean isOwnerProtectedPackage( @UserIdInt int userId, String packageName) { return isPackageProtectedForUser(UserHandle.USER_ALL, packageName) || isPackageProtectedForUser(userId, packageName); } return false; private synchronized boolean isPackageProtectedForUser(int userId, String packageName) { int userIdx = mOwnerProtectedPackages.indexOfKey(userId); return userIdx >= 0 && mOwnerProtectedPackages.valueAt(userIdx).contains(packageName); } /** Loading @@ -146,7 +151,7 @@ public class ProtectedPackages { */ public boolean isPackageStateProtected(@UserIdInt int userId, String packageName) { return hasDeviceOwnerOrProfileOwner(userId, packageName) || isProtectedPackage(packageName); || isProtectedPackage(userId, packageName); } /** Loading @@ -155,6 +160,6 @@ public class ProtectedPackages { */ public boolean isPackageDataProtected(@UserIdInt int userId, String packageName) { return hasDeviceOwnerOrProfileOwner(userId, packageName) || isProtectedPackage(packageName); || isProtectedPackage(userId, packageName); } }
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +24 −22 Original line number Diff line number Diff line Loading @@ -3116,6 +3116,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { deleteTransferOwnershipBundleLocked(metadata.userId); } updateSystemUpdateFreezePeriodsRecord(/* saveIfChanged */ true); pushUserControlDisabledPackagesLocked(metadata.userId); } private void maybeLogStart() { Loading Loading @@ -3178,18 +3179,22 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { startOwnerService(userId, "start-user"); } // TODO(b/218639412): Once PM stores these on a per-user basis, push even empty lists to handle // DO/PO removal correctly. void pushUserControlDisabledPackagesLocked(int userId) { if (userId != mOwners.getDeviceOwnerUserId()) { return; } ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked(); if (deviceOwner == null || deviceOwner.protectedPackages == null) { return; final int targetUserId; final ActiveAdmin owner; if (getDeviceOwnerUserIdUncheckedLocked() == userId) { owner = getDeviceOwnerAdminLocked(); targetUserId = UserHandle.USER_ALL; } else { owner = getProfileOwnerAdminLocked(userId); targetUserId = userId; } mInjector.getPackageManagerInternal().setDeviceOwnerProtectedPackages( deviceOwner.info.getPackageName(), deviceOwner.protectedPackages); List<String> protectedPackages = (owner == null || owner.protectedPackages == null) ? Collections.emptyList() : owner.protectedPackages; mInjector.binderWithCleanCallingIdentity(() -> mInjector.getPackageManagerInternal().setOwnerProtectedPackages( targetUserId, protectedPackages)); } @Override Loading Loading @@ -16967,23 +16972,20 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { Objects.requireNonNull(who, "ComponentName is null"); Objects.requireNonNull(packages, "packages is null"); final CallerIdentity caller = getCallerIdentity(who); Preconditions.checkCallAuthorization( isDefaultDeviceOwner(caller) || isFinancedDeviceOwner(caller)); Preconditions.checkCallAuthorization(isDefaultDeviceOwner(caller) || isProfileOwner(caller) || isFinancedDeviceOwner(caller)); checkCanExecuteOrThrowUnsafe( DevicePolicyManager.OPERATION_SET_USER_CONTROL_DISABLED_PACKAGES); synchronized (getLockObject()) { ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked(); if (!Objects.equals(deviceOwner.protectedPackages, packages)) { deviceOwner.protectedPackages = packages.isEmpty() ? null : packages; ActiveAdmin owner = getDeviceOrProfileOwnerAdminLocked(caller.getUserId()); if (!Objects.equals(owner.protectedPackages, packages)) { owner.protectedPackages = packages.isEmpty() ? null : packages; saveSettingsLocked(caller.getUserId()); pushUserControlDisabledPackagesLocked(caller.getUserId()); } } mInjector.binderWithCleanCallingIdentity( () -> mInjector.getPackageManagerInternal().setDeviceOwnerProtectedPackages( who.getPackageName(), packages)); DevicePolicyEventLogger .createEvent(DevicePolicyEnums.SET_USER_CONTROL_DISABLED_PACKAGES) .setAdmin(who) Loading @@ -16996,11 +16998,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { Objects.requireNonNull(who, "ComponentName is null"); final CallerIdentity caller = getCallerIdentity(who); Preconditions.checkCallAuthorization( isDefaultDeviceOwner(caller) || isFinancedDeviceOwner(caller)); Preconditions.checkCallAuthorization(isDefaultDeviceOwner(caller) || isProfileOwner(caller) || isFinancedDeviceOwner(caller)); synchronized (getLockObject()) { ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked(); ActiveAdmin deviceOwner = getDeviceOrProfileOwnerAdminLocked(caller.getUserId()); return deviceOwner.protectedPackages != null ? deviceOwner.protectedPackages : Collections.emptyList(); }