Loading core/java/android/content/pm/IPackageManager.aidl +0 −11 Original line number Diff line number Diff line Loading @@ -497,20 +497,9 @@ interface IPackageManager { void enterSafeMode(); @UnsupportedAppUsage boolean isSafeMode(); void systemReady(); @UnsupportedAppUsage boolean hasSystemUidErrors(); /** * Ask the package manager to fstrim the disk if needed. */ void performFstrimIfNeeded(); /** * Ask the package manager to update packages if needed. */ void updatePackagesIfNeeded(); /** * Notify the package manager that a package is going to be used and why. * Loading services/core/java/android/content/pm/PackageManagerInternal.java +11 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import android.util.SparseArray; import com.android.internal.util.function.pooled.PooledLambda; import com.android.server.pm.PackageList; import com.android.server.pm.PackageSetting; import com.android.server.pm.dex.DynamicCodeLogger; import com.android.server.pm.parsing.pkg.AndroidPackage; import com.android.server.pm.pkg.AndroidPackageApi; import com.android.server.pm.pkg.PackageState; Loading @@ -68,6 +69,7 @@ import java.util.function.Consumer; * @hide Only for use within the system server. */ public abstract class PackageManagerInternal { @IntDef(prefix = "PACKAGE_", value = { PACKAGE_SYSTEM, PACKAGE_SETUP_WIZARD, Loading Loading @@ -902,6 +904,11 @@ public abstract class PackageManagerInternal { public abstract void freeStorage(String volumeUuid, long bytes, @StorageManager.AllocateFlags int flags) throws IOException; /** * Blocking call to clear all cached app data above quota. */ public abstract void freeAllAppCacheAboveQuota(@NonNull String volumeUuid) throws IOException; /** Returns {@code true} if the specified component is enabled and matches the given flags. */ public abstract boolean isEnabledAndMatches(@NonNull ParsedMainComponent component, @PackageManager.ComponentInfoFlagsBits long flags, int userId); Loading Loading @@ -1362,4 +1369,8 @@ public abstract class PackageManagerInternal { */ @NonNull public abstract PackageDataSnapshot snapshot(); public abstract void shutdown(); public abstract DynamicCodeLogger getDynamicCodeLogger(); } services/core/java/com/android/server/pm/BackgroundDexOptService.java +1 −1 Original line number Diff line number Diff line Loading @@ -557,7 +557,7 @@ public final class BackgroundDexOptService { /** Gets the size of a package. */ private long getPackageSize(PackageManagerService pm, String pkg) { PackageInfo info = pm.getPackageInfo(pkg, 0, UserHandle.USER_SYSTEM); PackageInfo info = pm.snapshotComputer().getPackageInfo(pkg, 0, UserHandle.USER_SYSTEM); long size = 0; if (info != null && info.applicationInfo != null) { File path = Paths.get(info.applicationInfo.sourceDir).toFile(); Loading services/core/java/com/android/server/pm/Computer.java +15 −0 Original line number Diff line number Diff line Loading @@ -284,6 +284,21 @@ public interface Computer extends PackageDataSnapshot { @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED) long updateFlagsForResolve(long flags, int userId, int callingUid, boolean wantInstantApps, boolean onlyExposedExplicitly, boolean isImplicitImageCaptureIntentAndNotSetByDpc); /** * Checks if the request is from the system or an app that has the appropriate cross-user * permissions defined as follows: * <ul> * <li>INTERACT_ACROSS_USERS_FULL if {@code requireFullPermission} is true.</li> * <li>INTERACT_ACROSS_USERS if the given {@code userId} is in a different profile group * to the caller.</li> * <li>Otherwise, INTERACT_ACROSS_PROFILES if the given {@code userId} is in the same profile * group as the caller.</li> * </ul> * * @param checkShell whether to prevent shell from access if there's a debugging restriction * @param message the message to log on security exception */ @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED) void enforceCrossUserOrProfilePermission(int callingUid, @UserIdInt int userId, boolean requireFullPermission, boolean checkShell, String message); Loading services/core/java/com/android/server/pm/DeletePackageHelper.java +20 −15 Original line number Diff line number Diff line Loading @@ -685,7 +685,8 @@ final class DeletePackageHelper { return; } if (!deleteAllUsers && mPm.getBlockUninstallForUser(internalPackageName, userId)) { if (!deleteAllUsers && mPm.mIPackageManager .getBlockUninstallForUser(internalPackageName, userId)) { mPm.mHandler.post(() -> { try { observer.onPackageDeleted(packageName, Loading @@ -705,11 +706,14 @@ final class DeletePackageHelper { // Queue up an async operation since the package deletion may take a little while. mPm.mHandler.post(() -> { int returnCode; final PackageSetting ps = mPm.mSettings.getPackageLPr(internalPackageName); final Computer innerSnapshot = mPm.snapshotComputer(); final PackageStateInternal packageState = innerSnapshot.getPackageStateInternal(internalPackageName); boolean doDeletePackage = true; if (ps != null) { if (packageState != null) { final boolean targetIsInstantApp = ps.getInstantApp(UserHandle.getUserId(callingUid)); packageState.getUserStateOrDefault(UserHandle.getUserId(callingUid)) .isInstantApp(); doDeletePackage = !targetIsInstantApp || canViewInstantApps; } Loading @@ -718,7 +722,7 @@ final class DeletePackageHelper { returnCode = deletePackageX(internalPackageName, versionCode, userId, deleteFlags, false /*removedBySystem*/); } else { int[] blockUninstallUserIds = getBlockUninstallForUsers( int[] blockUninstallUserIds = getBlockUninstallForUsers(innerSnapshot, internalPackageName, users); // If nobody is blocking uninstall, proceed with delete for all users if (ArrayUtils.isEmpty(blockUninstallUserIds)) { Loading Loading @@ -769,39 +773,40 @@ final class DeletePackageHelper { } final int callingUserId = UserHandle.getUserId(callingUid); // If the caller installed the pkgName, then allow it to silently uninstall. if (callingUid == mPm.getPackageUid( mPm.getInstallerPackageName(pkgName), 0, callingUserId)) { if (callingUid == mPm.mIPackageManager.getPackageUid( mPm.mIPackageManager.getInstallerPackageName(pkgName), 0, callingUserId)) { return true; } // Allow package verifier to silently uninstall. if (mPm.mRequiredVerifierPackage != null && callingUid == mPm.getPackageUid( mPm.mRequiredVerifierPackage, 0, callingUserId)) { if (mPm.mRequiredVerifierPackage != null && callingUid == mPm.mIPackageManager .getPackageUid(mPm.mRequiredVerifierPackage, 0, callingUserId)) { return true; } // Allow package uninstaller to silently uninstall. if (mPm.mRequiredUninstallerPackage != null && callingUid == mPm.getPackageUid( mPm.mRequiredUninstallerPackage, 0, callingUserId)) { if (mPm.mRequiredUninstallerPackage != null && callingUid == mPm.mIPackageManager .getPackageUid(mPm.mRequiredUninstallerPackage, 0, callingUserId)) { return true; } // Allow storage manager to silently uninstall. if (mPm.mStorageManagerPackage != null && callingUid == mPm.getPackageUid( if (mPm.mStorageManagerPackage != null && callingUid == mPm.mIPackageManager.getPackageUid( mPm.mStorageManagerPackage, 0, callingUserId)) { return true; } // Allow caller having MANAGE_PROFILE_AND_DEVICE_OWNERS permission to silently // uninstall for device owner provisioning. return mPm.checkUidPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS, callingUid) return mPm.mIPackageManager.checkUidPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS, callingUid) == PERMISSION_GRANTED; } private int[] getBlockUninstallForUsers(String packageName, int[] userIds) { private int[] getBlockUninstallForUsers(@NonNull Computer snapshot, String packageName, int[] userIds) { int[] result = EMPTY_INT_ARRAY; for (int userId : userIds) { if (mPm.getBlockUninstallForUser(packageName, userId)) { if (snapshot.getBlockUninstallForUser(packageName, userId)) { result = ArrayUtils.appendInt(result, userId); } } Loading Loading
core/java/android/content/pm/IPackageManager.aidl +0 −11 Original line number Diff line number Diff line Loading @@ -497,20 +497,9 @@ interface IPackageManager { void enterSafeMode(); @UnsupportedAppUsage boolean isSafeMode(); void systemReady(); @UnsupportedAppUsage boolean hasSystemUidErrors(); /** * Ask the package manager to fstrim the disk if needed. */ void performFstrimIfNeeded(); /** * Ask the package manager to update packages if needed. */ void updatePackagesIfNeeded(); /** * Notify the package manager that a package is going to be used and why. * Loading
services/core/java/android/content/pm/PackageManagerInternal.java +11 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import android.util.SparseArray; import com.android.internal.util.function.pooled.PooledLambda; import com.android.server.pm.PackageList; import com.android.server.pm.PackageSetting; import com.android.server.pm.dex.DynamicCodeLogger; import com.android.server.pm.parsing.pkg.AndroidPackage; import com.android.server.pm.pkg.AndroidPackageApi; import com.android.server.pm.pkg.PackageState; Loading @@ -68,6 +69,7 @@ import java.util.function.Consumer; * @hide Only for use within the system server. */ public abstract class PackageManagerInternal { @IntDef(prefix = "PACKAGE_", value = { PACKAGE_SYSTEM, PACKAGE_SETUP_WIZARD, Loading Loading @@ -902,6 +904,11 @@ public abstract class PackageManagerInternal { public abstract void freeStorage(String volumeUuid, long bytes, @StorageManager.AllocateFlags int flags) throws IOException; /** * Blocking call to clear all cached app data above quota. */ public abstract void freeAllAppCacheAboveQuota(@NonNull String volumeUuid) throws IOException; /** Returns {@code true} if the specified component is enabled and matches the given flags. */ public abstract boolean isEnabledAndMatches(@NonNull ParsedMainComponent component, @PackageManager.ComponentInfoFlagsBits long flags, int userId); Loading Loading @@ -1362,4 +1369,8 @@ public abstract class PackageManagerInternal { */ @NonNull public abstract PackageDataSnapshot snapshot(); public abstract void shutdown(); public abstract DynamicCodeLogger getDynamicCodeLogger(); }
services/core/java/com/android/server/pm/BackgroundDexOptService.java +1 −1 Original line number Diff line number Diff line Loading @@ -557,7 +557,7 @@ public final class BackgroundDexOptService { /** Gets the size of a package. */ private long getPackageSize(PackageManagerService pm, String pkg) { PackageInfo info = pm.getPackageInfo(pkg, 0, UserHandle.USER_SYSTEM); PackageInfo info = pm.snapshotComputer().getPackageInfo(pkg, 0, UserHandle.USER_SYSTEM); long size = 0; if (info != null && info.applicationInfo != null) { File path = Paths.get(info.applicationInfo.sourceDir).toFile(); Loading
services/core/java/com/android/server/pm/Computer.java +15 −0 Original line number Diff line number Diff line Loading @@ -284,6 +284,21 @@ public interface Computer extends PackageDataSnapshot { @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED) long updateFlagsForResolve(long flags, int userId, int callingUid, boolean wantInstantApps, boolean onlyExposedExplicitly, boolean isImplicitImageCaptureIntentAndNotSetByDpc); /** * Checks if the request is from the system or an app that has the appropriate cross-user * permissions defined as follows: * <ul> * <li>INTERACT_ACROSS_USERS_FULL if {@code requireFullPermission} is true.</li> * <li>INTERACT_ACROSS_USERS if the given {@code userId} is in a different profile group * to the caller.</li> * <li>Otherwise, INTERACT_ACROSS_PROFILES if the given {@code userId} is in the same profile * group as the caller.</li> * </ul> * * @param checkShell whether to prevent shell from access if there's a debugging restriction * @param message the message to log on security exception */ @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED) void enforceCrossUserOrProfilePermission(int callingUid, @UserIdInt int userId, boolean requireFullPermission, boolean checkShell, String message); Loading
services/core/java/com/android/server/pm/DeletePackageHelper.java +20 −15 Original line number Diff line number Diff line Loading @@ -685,7 +685,8 @@ final class DeletePackageHelper { return; } if (!deleteAllUsers && mPm.getBlockUninstallForUser(internalPackageName, userId)) { if (!deleteAllUsers && mPm.mIPackageManager .getBlockUninstallForUser(internalPackageName, userId)) { mPm.mHandler.post(() -> { try { observer.onPackageDeleted(packageName, Loading @@ -705,11 +706,14 @@ final class DeletePackageHelper { // Queue up an async operation since the package deletion may take a little while. mPm.mHandler.post(() -> { int returnCode; final PackageSetting ps = mPm.mSettings.getPackageLPr(internalPackageName); final Computer innerSnapshot = mPm.snapshotComputer(); final PackageStateInternal packageState = innerSnapshot.getPackageStateInternal(internalPackageName); boolean doDeletePackage = true; if (ps != null) { if (packageState != null) { final boolean targetIsInstantApp = ps.getInstantApp(UserHandle.getUserId(callingUid)); packageState.getUserStateOrDefault(UserHandle.getUserId(callingUid)) .isInstantApp(); doDeletePackage = !targetIsInstantApp || canViewInstantApps; } Loading @@ -718,7 +722,7 @@ final class DeletePackageHelper { returnCode = deletePackageX(internalPackageName, versionCode, userId, deleteFlags, false /*removedBySystem*/); } else { int[] blockUninstallUserIds = getBlockUninstallForUsers( int[] blockUninstallUserIds = getBlockUninstallForUsers(innerSnapshot, internalPackageName, users); // If nobody is blocking uninstall, proceed with delete for all users if (ArrayUtils.isEmpty(blockUninstallUserIds)) { Loading Loading @@ -769,39 +773,40 @@ final class DeletePackageHelper { } final int callingUserId = UserHandle.getUserId(callingUid); // If the caller installed the pkgName, then allow it to silently uninstall. if (callingUid == mPm.getPackageUid( mPm.getInstallerPackageName(pkgName), 0, callingUserId)) { if (callingUid == mPm.mIPackageManager.getPackageUid( mPm.mIPackageManager.getInstallerPackageName(pkgName), 0, callingUserId)) { return true; } // Allow package verifier to silently uninstall. if (mPm.mRequiredVerifierPackage != null && callingUid == mPm.getPackageUid( mPm.mRequiredVerifierPackage, 0, callingUserId)) { if (mPm.mRequiredVerifierPackage != null && callingUid == mPm.mIPackageManager .getPackageUid(mPm.mRequiredVerifierPackage, 0, callingUserId)) { return true; } // Allow package uninstaller to silently uninstall. if (mPm.mRequiredUninstallerPackage != null && callingUid == mPm.getPackageUid( mPm.mRequiredUninstallerPackage, 0, callingUserId)) { if (mPm.mRequiredUninstallerPackage != null && callingUid == mPm.mIPackageManager .getPackageUid(mPm.mRequiredUninstallerPackage, 0, callingUserId)) { return true; } // Allow storage manager to silently uninstall. if (mPm.mStorageManagerPackage != null && callingUid == mPm.getPackageUid( if (mPm.mStorageManagerPackage != null && callingUid == mPm.mIPackageManager.getPackageUid( mPm.mStorageManagerPackage, 0, callingUserId)) { return true; } // Allow caller having MANAGE_PROFILE_AND_DEVICE_OWNERS permission to silently // uninstall for device owner provisioning. return mPm.checkUidPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS, callingUid) return mPm.mIPackageManager.checkUidPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS, callingUid) == PERMISSION_GRANTED; } private int[] getBlockUninstallForUsers(String packageName, int[] userIds) { private int[] getBlockUninstallForUsers(@NonNull Computer snapshot, String packageName, int[] userIds) { int[] result = EMPTY_INT_ARRAY; for (int userId : userIds) { if (mPm.getBlockUninstallForUser(packageName, userId)) { if (snapshot.getBlockUninstallForUser(packageName, userId)) { result = ArrayUtils.appendInt(result, userId); } } Loading