Loading services/core/java/android/content/pm/PackageManagerInternal.java +27 −0 Original line number Diff line number Diff line Loading @@ -236,6 +236,33 @@ public abstract class PackageManagerInternal { */ public abstract boolean isPackageSuspended(String packageName, int userId); /** * Removes all package suspensions imposed by any non-system packages. */ public abstract void removeAllNonSystemPackageSuspensions(int userId); /** * Removes all suspensions imposed on the given package by non-system packages. */ public abstract void removeNonSystemPackageSuspensions(String packageName, int userId); /** * Removes all {@link PackageManager.DistractionRestriction restrictions} set on the given * package */ public abstract void removeDistractingPackageRestrictions(String packageName, int userId); /** * Removes all {@link PackageManager.DistractionRestriction restrictions} set on all the * packages. */ public abstract void removeAllDistractingPackageRestrictions(int userId); /** * Flushes package restrictions for the given user immediately to disk. */ public abstract void flushPackageRestrictions(int userId); /** * Get the name of the package that suspended the given package. Packages can be suspended by * device administrators or apps holding {@link android.Manifest.permission#MANAGE_USERS} or Loading services/core/java/com/android/server/pm/PackageManagerService.java +154 −14 Original line number Diff line number Diff line Loading @@ -12760,7 +12760,11 @@ public class PackageManagerService extends IPackageManager.Stub throw new SecurityException("Calling uid " + callingUid + " cannot call for user " + userId); } Preconditions.checkNotNull(packageNames, "packageNames cannot be null"); Objects.requireNonNull(packageNames, "packageNames cannot be null"); if (restrictionFlags != 0 && !isSuspendAllowedForUser(userId)) { Slog.w(TAG, "Cannot restrict packages due to restrictions on user " + userId); return packageNames; } final List<String> changedPackagesList = new ArrayList<>(packageNames.length); final IntArray changedUids = new IntArray(packageNames.length); Loading Loading @@ -12847,6 +12851,10 @@ public class PackageManagerService extends IPackageManager.Stub if (ArrayUtils.isEmpty(packageNames)) { return packageNames; } if (suspended && !isSuspendAllowedForUser(userId)) { Slog.w(TAG, "Cannot suspend due to restrictions on user " + userId); return packageNames; } final List<String> changedPackagesList = new ArrayList<>(packageNames.length); final IntArray changedUids = new IntArray(packageNames.length); Loading Loading @@ -12985,30 +12993,41 @@ public class PackageManagerService extends IPackageManager.Stub } } void unsuspendForSuspendingPackage(String suspendingPackage, int userId) { final String[] allPackages; synchronized (mLock) { allPackages = mPackages.keySet().toArray(new String[mPackages.size()]); } removeSuspensionsBySuspendingPackage(allPackages, suspendingPackage::equals, userId); } /** * Immediately unsuspends any packages suspended by the given package. To be called * when such a package's data is cleared or it is removed from the device. * Removes any suspensions on given packages that were added by packages that pass the given * predicate. * * <p><b>Should not be used on a frequent code path</b> as it flushes state to disk * synchronously * <p> Caller must flush package restrictions if it cares about immediate data consistency. * * @param suspendingPackage The suspending package * @param packagesToChange The packages on which the suspension are to be removed. * @param suspendingPackagePredicate A predicate identifying the suspending packages whose * suspensions will be removed. * @param userId The user for which the changes are taking place. */ private void unsuspendForSuspendingPackage(String suspendingPackage, int userId) { void removeSuspensionsBySuspendingPackage(String[] packagesToChange, Predicate<String> suspendingPackagePredicate, int userId) { final List<String> unsuspendedPackages = new ArrayList<>(); final IntArray unsuspendedUids = new IntArray(); synchronized (mLock) { for (PackageSetting ps : mSettings.mPackages.values()) { final PackageUserState pus = ps.readUserState(userId); if (pus.suspended) { ps.removeSuspension(suspendingPackage, userId); for (String packageName : packagesToChange) { final PackageSetting ps = mSettings.mPackages.get(packageName); if (ps.getSuspended(userId)) { ps.removeSuspension(suspendingPackagePredicate, userId); if (!ps.getSuspended(userId)) { unsuspendedPackages.add(ps.name); unsuspendedUids.add(UserHandle.getUid(userId, ps.getAppId())); } } } scheduleWritePackageRestrictionsLocked(userId); } if (!unsuspendedPackages.isEmpty()) { final String[] packageArray = unsuspendedPackages.toArray( Loading @@ -13016,13 +13035,67 @@ public class PackageManagerService extends IPackageManager.Stub sendMyPackageSuspendedOrUnsuspended(packageArray, false, userId); sendPackagesSuspendedForUser(packageArray, unsuspendedUids.toArray(), userId, false); } // Write package restrictions immediately to avoid an inconsistent state. mSettings.writePackageRestrictionsLPr(userId); } void removeAllDistractingPackageRestrictions(int userId) { final String[] allPackages; synchronized (mLock) { allPackages = mPackages.keySet().toArray(new String[mPackages.size()]); } PackageManagerService.this.removeDistractingPackageRestrictions(allPackages, userId); } /** * Removes any {@link android.content.pm.PackageManager.DistractionRestriction restrictions} * set on given packages. * * <p> Caller must flush package restrictions if it cares about immediate data consistency. * * @param packagesToChange The packages on which restrictions are to be removed. * @param userId the user for which changes are taking place. */ void removeDistractingPackageRestrictions(String[] packagesToChange, int userId) { final List<String> changedPackages = new ArrayList<>(); final IntArray changedUids = new IntArray(); synchronized (mLock) { for (String packageName : packagesToChange) { final PackageSetting ps = mSettings.mPackages.get(packageName); if (ps.getDistractionFlags(userId) != 0) { ps.setDistractionFlags(0, userId); changedPackages.add(ps.name); changedUids.add(UserHandle.getUid(userId, ps.getAppId())); } } if (!changedPackages.isEmpty()) { final String[] packageArray = changedPackages.toArray( new String[changedPackages.size()]); sendDistractingPackagesChanged(packageArray, changedUids.toArray(), userId, 0); scheduleWritePackageRestrictionsLocked(userId); } } } private boolean isCallerDeviceOrProfileOwner(int userId) { final int callingUid = Binder.getCallingUid(); if (callingUid == Process.SYSTEM_UID) { return true; } final String ownerPackage = mProtectedPackages.getDeviceOwnerOrProfileOwnerPackage(userId); if (ownerPackage != null) { return callingUid == getPackageUidInternal(ownerPackage, 0, userId, callingUid); } return false; } private boolean isSuspendAllowedForUser(int userId) { return isCallerDeviceOrProfileOwner(userId) || (!mUserManager.hasUserRestriction(UserManager.DISALLOW_APPS_CONTROL, userId) && !mUserManager.hasUserRestriction(UserManager.DISALLOW_UNINSTALL_APPS, userId)); } @Override public String[] getUnsuspendablePackagesForUser(String[] packageNames, int userId) { Preconditions.checkNotNull(packageNames, "packageNames cannot be null"); Objects.requireNonNull(packageNames, "packageNames cannot be null"); mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS, "getUnsuspendablePackagesForUser"); final int callingUid = Binder.getCallingUid(); Loading @@ -13030,11 +13103,23 @@ public class PackageManagerService extends IPackageManager.Stub throw new SecurityException("Calling uid " + callingUid + " cannot query getUnsuspendablePackagesForUser for user " + userId); } if (!isSuspendAllowedForUser(userId)) { Slog.w(TAG, "Cannot suspend due to restrictions on user " + userId); return packageNames; } final ArraySet<String> unactionablePackages = new ArraySet<>(); final boolean[] canSuspend = canSuspendPackageForUserInternal(packageNames, userId); for (int i = 0; i < packageNames.length; i++) { if (!canSuspend[i]) { unactionablePackages.add(packageNames[i]); continue; } synchronized (mLock) { final PackageSetting ps = mSettings.mPackages.get(packageNames[i]); if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) { Slog.w(TAG, "Could not find package setting for package: " + packageNames[i]); unactionablePackages.add(packageNames[i]); } } } return unactionablePackages.toArray(new String[unactionablePackages.size()]); Loading @@ -13051,6 +13136,7 @@ public class PackageManagerService extends IPackageManager.Stub @NonNull private boolean[] canSuspendPackageForUserInternal(@NonNull String[] packageNames, int userId) { final boolean[] canSuspend = new boolean[packageNames.length]; final boolean isCallerOwner = isCallerDeviceOrProfileOwner(userId); final long callingId = Binder.clearCallingIdentity(); try { final String activeLauncherPackageName = getActiveLauncherPackageName(userId); Loading Loading @@ -13100,6 +13186,11 @@ public class PackageManagerService extends IPackageManager.Stub + "\": protected package"); continue; } if (!isCallerOwner && mSettings.getBlockUninstallLPr(userId, packageName)) { Slog.w(TAG, "Cannot suspend package \"" + packageName + "\": blocked by admin"); continue; } // Cannot suspend static shared libs as they are considered // a part of the using app (emulating static linking). Also Loading Loading @@ -18449,6 +18540,8 @@ public class PackageManagerService extends IPackageManager.Stub if (checkPermission(Manifest.permission.SUSPEND_APPS, packageName, userId) == PERMISSION_GRANTED) { unsuspendForSuspendingPackage(packageName, userId); removeAllDistractingPackageRestrictions(userId); flushPackageRestrictionsAsUserInternalLocked(userId); } } } else { Loading Loading @@ -19972,6 +20065,16 @@ public class PackageManagerService extends IPackageManager.Stub } synchronized (mLock) { pkgSetting.setEnabled(newState, userId, callingPackage); if (newState == COMPONENT_ENABLED_STATE_DISABLED_USER || newState == COMPONENT_ENABLED_STATE_DISABLED && pkgSetting.getPermissionsState().hasPermission( Manifest.permission.SUSPEND_APPS, userId)) { // This app should not generally be allowed to get disabled by the UI, but if it // ever does, we don't want to end up with some of the user's apps permanently // blocked unsuspendForSuspendingPackage(packageName, userId); removeAllDistractingPackageRestrictions(userId); } } } else { synchronized (mLock) { Loading Loading @@ -23212,6 +23315,43 @@ public class PackageManagerService extends IPackageManager.Stub } } @Override public void removeAllNonSystemPackageSuspensions(int userId) { final String[] allPackages; synchronized (mLock) { allPackages = mPackages.keySet().toArray(new String[mPackages.size()]); } PackageManagerService.this.removeSuspensionsBySuspendingPackage(allPackages, (suspendingPackage) -> !PLATFORM_PACKAGE_NAME.equals(suspendingPackage), userId); } @Override public void removeNonSystemPackageSuspensions(String packageName, int userId) { PackageManagerService.this.removeSuspensionsBySuspendingPackage( new String[]{packageName}, (suspendingPackage) -> !PLATFORM_PACKAGE_NAME.equals(suspendingPackage), userId); } @Override public void flushPackageRestrictions(int userId) { synchronized (mLock) { PackageManagerService.this.flushPackageRestrictionsAsUserInternalLocked(userId); } } @Override public void removeDistractingPackageRestrictions(String packageName, int userId) { PackageManagerService.this.removeDistractingPackageRestrictions( new String[]{packageName}, userId); } @Override public void removeAllDistractingPackageRestrictions(int userId) { PackageManagerService.this.removeAllDistractingPackageRestrictions(userId); } @Override public String getSuspendingPackage(String suspendedPackage, int userId) { synchronized (mLock) { services/core/java/com/android/server/pm/PackageSettingBase.java +17 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.function.Predicate; /** * Settings base class for pending and resolved classes. Loading Loading @@ -433,6 +434,22 @@ public abstract class PackageSettingBase extends SettingBase { existingUserState.suspended = (existingUserState.suspendParams != null); } void removeSuspension(Predicate<String> suspendingPackagePredicate, int userId) { final PackageUserState existingUserState = modifyUserState(userId); if (existingUserState.suspendParams != null) { for (int i = existingUserState.suspendParams.size() - 1; i >= 0; i--) { final String suspendingPackage = existingUserState.suspendParams.keyAt(i); if (suspendingPackagePredicate.test(suspendingPackage)) { existingUserState.suspendParams.removeAt(i); } } if (existingUserState.suspendParams.size() == 0) { existingUserState.suspendParams = null; } } existingUserState.suspended = (existingUserState.suspendParams != null); } public boolean getInstantApp(int userId) { return readUserState(userId).instantApp; } Loading services/core/java/com/android/server/pm/UserRestrictionsUtils.java +11 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.IPackageManager; import android.content.pm.PackageManager; import android.content.pm.PackageManagerInternal; import android.os.Binder; import android.os.Bundle; import android.os.Process; Loading @@ -42,6 +43,7 @@ import android.util.Slog; import android.util.SparseArray; import com.android.internal.util.Preconditions; import com.android.server.LocalServices; import com.google.android.collect.Sets; Loading Loading @@ -679,6 +681,15 @@ public class UserRestrictionsUtils { Global.LOCATION_GLOBAL_KILL_SWITCH, "0"); } break; case UserManager.DISALLOW_APPS_CONTROL: // Intentional fall-through case UserManager.DISALLOW_UNINSTALL_APPS: final PackageManagerInternal pmi = LocalServices.getService( PackageManagerInternal.class); pmi.removeAllNonSystemPackageSuspensions(userId); pmi.removeAllDistractingPackageRestrictions(userId); pmi.flushPackageRestrictions(userId); break; } } finally { Binder.restoreCallingIdentity(id); Loading services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +6 −0 Original line number Diff line number Diff line Loading @@ -11176,6 +11176,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { mInjector.binderRestoreCallingIdentity(id); } } if (uninstallBlocked) { final PackageManagerInternal pmi = mInjector.getPackageManagerInternal(); pmi.removeNonSystemPackageSuspensions(packageName, userId); pmi.removeDistractingPackageRestrictions(packageName, userId); pmi.flushPackageRestrictions(userId); } final boolean isDelegate = (who == null); DevicePolicyEventLogger .createEvent(DevicePolicyEnums.SET_UNINSTALL_BLOCKED) Loading Loading
services/core/java/android/content/pm/PackageManagerInternal.java +27 −0 Original line number Diff line number Diff line Loading @@ -236,6 +236,33 @@ public abstract class PackageManagerInternal { */ public abstract boolean isPackageSuspended(String packageName, int userId); /** * Removes all package suspensions imposed by any non-system packages. */ public abstract void removeAllNonSystemPackageSuspensions(int userId); /** * Removes all suspensions imposed on the given package by non-system packages. */ public abstract void removeNonSystemPackageSuspensions(String packageName, int userId); /** * Removes all {@link PackageManager.DistractionRestriction restrictions} set on the given * package */ public abstract void removeDistractingPackageRestrictions(String packageName, int userId); /** * Removes all {@link PackageManager.DistractionRestriction restrictions} set on all the * packages. */ public abstract void removeAllDistractingPackageRestrictions(int userId); /** * Flushes package restrictions for the given user immediately to disk. */ public abstract void flushPackageRestrictions(int userId); /** * Get the name of the package that suspended the given package. Packages can be suspended by * device administrators or apps holding {@link android.Manifest.permission#MANAGE_USERS} or Loading
services/core/java/com/android/server/pm/PackageManagerService.java +154 −14 Original line number Diff line number Diff line Loading @@ -12760,7 +12760,11 @@ public class PackageManagerService extends IPackageManager.Stub throw new SecurityException("Calling uid " + callingUid + " cannot call for user " + userId); } Preconditions.checkNotNull(packageNames, "packageNames cannot be null"); Objects.requireNonNull(packageNames, "packageNames cannot be null"); if (restrictionFlags != 0 && !isSuspendAllowedForUser(userId)) { Slog.w(TAG, "Cannot restrict packages due to restrictions on user " + userId); return packageNames; } final List<String> changedPackagesList = new ArrayList<>(packageNames.length); final IntArray changedUids = new IntArray(packageNames.length); Loading Loading @@ -12847,6 +12851,10 @@ public class PackageManagerService extends IPackageManager.Stub if (ArrayUtils.isEmpty(packageNames)) { return packageNames; } if (suspended && !isSuspendAllowedForUser(userId)) { Slog.w(TAG, "Cannot suspend due to restrictions on user " + userId); return packageNames; } final List<String> changedPackagesList = new ArrayList<>(packageNames.length); final IntArray changedUids = new IntArray(packageNames.length); Loading Loading @@ -12985,30 +12993,41 @@ public class PackageManagerService extends IPackageManager.Stub } } void unsuspendForSuspendingPackage(String suspendingPackage, int userId) { final String[] allPackages; synchronized (mLock) { allPackages = mPackages.keySet().toArray(new String[mPackages.size()]); } removeSuspensionsBySuspendingPackage(allPackages, suspendingPackage::equals, userId); } /** * Immediately unsuspends any packages suspended by the given package. To be called * when such a package's data is cleared or it is removed from the device. * Removes any suspensions on given packages that were added by packages that pass the given * predicate. * * <p><b>Should not be used on a frequent code path</b> as it flushes state to disk * synchronously * <p> Caller must flush package restrictions if it cares about immediate data consistency. * * @param suspendingPackage The suspending package * @param packagesToChange The packages on which the suspension are to be removed. * @param suspendingPackagePredicate A predicate identifying the suspending packages whose * suspensions will be removed. * @param userId The user for which the changes are taking place. */ private void unsuspendForSuspendingPackage(String suspendingPackage, int userId) { void removeSuspensionsBySuspendingPackage(String[] packagesToChange, Predicate<String> suspendingPackagePredicate, int userId) { final List<String> unsuspendedPackages = new ArrayList<>(); final IntArray unsuspendedUids = new IntArray(); synchronized (mLock) { for (PackageSetting ps : mSettings.mPackages.values()) { final PackageUserState pus = ps.readUserState(userId); if (pus.suspended) { ps.removeSuspension(suspendingPackage, userId); for (String packageName : packagesToChange) { final PackageSetting ps = mSettings.mPackages.get(packageName); if (ps.getSuspended(userId)) { ps.removeSuspension(suspendingPackagePredicate, userId); if (!ps.getSuspended(userId)) { unsuspendedPackages.add(ps.name); unsuspendedUids.add(UserHandle.getUid(userId, ps.getAppId())); } } } scheduleWritePackageRestrictionsLocked(userId); } if (!unsuspendedPackages.isEmpty()) { final String[] packageArray = unsuspendedPackages.toArray( Loading @@ -13016,13 +13035,67 @@ public class PackageManagerService extends IPackageManager.Stub sendMyPackageSuspendedOrUnsuspended(packageArray, false, userId); sendPackagesSuspendedForUser(packageArray, unsuspendedUids.toArray(), userId, false); } // Write package restrictions immediately to avoid an inconsistent state. mSettings.writePackageRestrictionsLPr(userId); } void removeAllDistractingPackageRestrictions(int userId) { final String[] allPackages; synchronized (mLock) { allPackages = mPackages.keySet().toArray(new String[mPackages.size()]); } PackageManagerService.this.removeDistractingPackageRestrictions(allPackages, userId); } /** * Removes any {@link android.content.pm.PackageManager.DistractionRestriction restrictions} * set on given packages. * * <p> Caller must flush package restrictions if it cares about immediate data consistency. * * @param packagesToChange The packages on which restrictions are to be removed. * @param userId the user for which changes are taking place. */ void removeDistractingPackageRestrictions(String[] packagesToChange, int userId) { final List<String> changedPackages = new ArrayList<>(); final IntArray changedUids = new IntArray(); synchronized (mLock) { for (String packageName : packagesToChange) { final PackageSetting ps = mSettings.mPackages.get(packageName); if (ps.getDistractionFlags(userId) != 0) { ps.setDistractionFlags(0, userId); changedPackages.add(ps.name); changedUids.add(UserHandle.getUid(userId, ps.getAppId())); } } if (!changedPackages.isEmpty()) { final String[] packageArray = changedPackages.toArray( new String[changedPackages.size()]); sendDistractingPackagesChanged(packageArray, changedUids.toArray(), userId, 0); scheduleWritePackageRestrictionsLocked(userId); } } } private boolean isCallerDeviceOrProfileOwner(int userId) { final int callingUid = Binder.getCallingUid(); if (callingUid == Process.SYSTEM_UID) { return true; } final String ownerPackage = mProtectedPackages.getDeviceOwnerOrProfileOwnerPackage(userId); if (ownerPackage != null) { return callingUid == getPackageUidInternal(ownerPackage, 0, userId, callingUid); } return false; } private boolean isSuspendAllowedForUser(int userId) { return isCallerDeviceOrProfileOwner(userId) || (!mUserManager.hasUserRestriction(UserManager.DISALLOW_APPS_CONTROL, userId) && !mUserManager.hasUserRestriction(UserManager.DISALLOW_UNINSTALL_APPS, userId)); } @Override public String[] getUnsuspendablePackagesForUser(String[] packageNames, int userId) { Preconditions.checkNotNull(packageNames, "packageNames cannot be null"); Objects.requireNonNull(packageNames, "packageNames cannot be null"); mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS, "getUnsuspendablePackagesForUser"); final int callingUid = Binder.getCallingUid(); Loading @@ -13030,11 +13103,23 @@ public class PackageManagerService extends IPackageManager.Stub throw new SecurityException("Calling uid " + callingUid + " cannot query getUnsuspendablePackagesForUser for user " + userId); } if (!isSuspendAllowedForUser(userId)) { Slog.w(TAG, "Cannot suspend due to restrictions on user " + userId); return packageNames; } final ArraySet<String> unactionablePackages = new ArraySet<>(); final boolean[] canSuspend = canSuspendPackageForUserInternal(packageNames, userId); for (int i = 0; i < packageNames.length; i++) { if (!canSuspend[i]) { unactionablePackages.add(packageNames[i]); continue; } synchronized (mLock) { final PackageSetting ps = mSettings.mPackages.get(packageNames[i]); if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) { Slog.w(TAG, "Could not find package setting for package: " + packageNames[i]); unactionablePackages.add(packageNames[i]); } } } return unactionablePackages.toArray(new String[unactionablePackages.size()]); Loading @@ -13051,6 +13136,7 @@ public class PackageManagerService extends IPackageManager.Stub @NonNull private boolean[] canSuspendPackageForUserInternal(@NonNull String[] packageNames, int userId) { final boolean[] canSuspend = new boolean[packageNames.length]; final boolean isCallerOwner = isCallerDeviceOrProfileOwner(userId); final long callingId = Binder.clearCallingIdentity(); try { final String activeLauncherPackageName = getActiveLauncherPackageName(userId); Loading Loading @@ -13100,6 +13186,11 @@ public class PackageManagerService extends IPackageManager.Stub + "\": protected package"); continue; } if (!isCallerOwner && mSettings.getBlockUninstallLPr(userId, packageName)) { Slog.w(TAG, "Cannot suspend package \"" + packageName + "\": blocked by admin"); continue; } // Cannot suspend static shared libs as they are considered // a part of the using app (emulating static linking). Also Loading Loading @@ -18449,6 +18540,8 @@ public class PackageManagerService extends IPackageManager.Stub if (checkPermission(Manifest.permission.SUSPEND_APPS, packageName, userId) == PERMISSION_GRANTED) { unsuspendForSuspendingPackage(packageName, userId); removeAllDistractingPackageRestrictions(userId); flushPackageRestrictionsAsUserInternalLocked(userId); } } } else { Loading Loading @@ -19972,6 +20065,16 @@ public class PackageManagerService extends IPackageManager.Stub } synchronized (mLock) { pkgSetting.setEnabled(newState, userId, callingPackage); if (newState == COMPONENT_ENABLED_STATE_DISABLED_USER || newState == COMPONENT_ENABLED_STATE_DISABLED && pkgSetting.getPermissionsState().hasPermission( Manifest.permission.SUSPEND_APPS, userId)) { // This app should not generally be allowed to get disabled by the UI, but if it // ever does, we don't want to end up with some of the user's apps permanently // blocked unsuspendForSuspendingPackage(packageName, userId); removeAllDistractingPackageRestrictions(userId); } } } else { synchronized (mLock) { Loading Loading @@ -23212,6 +23315,43 @@ public class PackageManagerService extends IPackageManager.Stub } } @Override public void removeAllNonSystemPackageSuspensions(int userId) { final String[] allPackages; synchronized (mLock) { allPackages = mPackages.keySet().toArray(new String[mPackages.size()]); } PackageManagerService.this.removeSuspensionsBySuspendingPackage(allPackages, (suspendingPackage) -> !PLATFORM_PACKAGE_NAME.equals(suspendingPackage), userId); } @Override public void removeNonSystemPackageSuspensions(String packageName, int userId) { PackageManagerService.this.removeSuspensionsBySuspendingPackage( new String[]{packageName}, (suspendingPackage) -> !PLATFORM_PACKAGE_NAME.equals(suspendingPackage), userId); } @Override public void flushPackageRestrictions(int userId) { synchronized (mLock) { PackageManagerService.this.flushPackageRestrictionsAsUserInternalLocked(userId); } } @Override public void removeDistractingPackageRestrictions(String packageName, int userId) { PackageManagerService.this.removeDistractingPackageRestrictions( new String[]{packageName}, userId); } @Override public void removeAllDistractingPackageRestrictions(int userId) { PackageManagerService.this.removeAllDistractingPackageRestrictions(userId); } @Override public String getSuspendingPackage(String suspendedPackage, int userId) { synchronized (mLock) {
services/core/java/com/android/server/pm/PackageSettingBase.java +17 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.function.Predicate; /** * Settings base class for pending and resolved classes. Loading Loading @@ -433,6 +434,22 @@ public abstract class PackageSettingBase extends SettingBase { existingUserState.suspended = (existingUserState.suspendParams != null); } void removeSuspension(Predicate<String> suspendingPackagePredicate, int userId) { final PackageUserState existingUserState = modifyUserState(userId); if (existingUserState.suspendParams != null) { for (int i = existingUserState.suspendParams.size() - 1; i >= 0; i--) { final String suspendingPackage = existingUserState.suspendParams.keyAt(i); if (suspendingPackagePredicate.test(suspendingPackage)) { existingUserState.suspendParams.removeAt(i); } } if (existingUserState.suspendParams.size() == 0) { existingUserState.suspendParams = null; } } existingUserState.suspended = (existingUserState.suspendParams != null); } public boolean getInstantApp(int userId) { return readUserState(userId).instantApp; } Loading
services/core/java/com/android/server/pm/UserRestrictionsUtils.java +11 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.IPackageManager; import android.content.pm.PackageManager; import android.content.pm.PackageManagerInternal; import android.os.Binder; import android.os.Bundle; import android.os.Process; Loading @@ -42,6 +43,7 @@ import android.util.Slog; import android.util.SparseArray; import com.android.internal.util.Preconditions; import com.android.server.LocalServices; import com.google.android.collect.Sets; Loading Loading @@ -679,6 +681,15 @@ public class UserRestrictionsUtils { Global.LOCATION_GLOBAL_KILL_SWITCH, "0"); } break; case UserManager.DISALLOW_APPS_CONTROL: // Intentional fall-through case UserManager.DISALLOW_UNINSTALL_APPS: final PackageManagerInternal pmi = LocalServices.getService( PackageManagerInternal.class); pmi.removeAllNonSystemPackageSuspensions(userId); pmi.removeAllDistractingPackageRestrictions(userId); pmi.flushPackageRestrictions(userId); break; } } finally { Binder.restoreCallingIdentity(id); Loading
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +6 −0 Original line number Diff line number Diff line Loading @@ -11176,6 +11176,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { mInjector.binderRestoreCallingIdentity(id); } } if (uninstallBlocked) { final PackageManagerInternal pmi = mInjector.getPackageManagerInternal(); pmi.removeNonSystemPackageSuspensions(packageName, userId); pmi.removeDistractingPackageRestrictions(packageName, userId); pmi.flushPackageRestrictions(userId); } final boolean isDelegate = (who == null); DevicePolicyEventLogger .createEvent(DevicePolicyEnums.SET_UNINSTALL_BLOCKED) Loading