Loading services/core/java/com/android/server/pm/InstallPackageHelper.java +51 −85 Original line number Diff line number Diff line Loading @@ -56,7 +56,6 @@ import static com.android.server.pm.PackageManagerService.DEBUG_PACKAGE_SCANNING import static com.android.server.pm.PackageManagerService.DEBUG_REMOVE; import static com.android.server.pm.PackageManagerService.DEBUG_UPGRADE; import static com.android.server.pm.PackageManagerService.DEBUG_VERIFY; import static com.android.server.pm.PackageManagerService.EMPTY_INT_ARRAY; import static com.android.server.pm.PackageManagerService.MIN_INSTALLABLE_TARGET_SDK; import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME; import static com.android.server.pm.PackageManagerService.POST_INSTALL; Loading Loading @@ -180,7 +179,6 @@ import com.android.server.pm.parsing.pkg.ParsedPackage; import com.android.server.pm.permission.Permission; import com.android.server.pm.permission.PermissionManagerServiceInternal; import com.android.server.pm.pkg.AndroidPackage; import com.android.server.pm.pkg.PackageState; import com.android.server.pm.pkg.PackageStateInternal; import com.android.server.pm.pkg.SharedLibraryWrapper; import com.android.server.pm.pkg.component.ComponentMutateUtils; Loading Loading @@ -1245,6 +1243,7 @@ final class InstallPackageHelper { boolean systemApp = false; boolean replace = false; synchronized (mPm.mLock) { final PackageSetting ps = mPm.mSettings.getPackageLPr(pkgName); // Check if installing already existing package if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { String oldName = mPm.mSettings.getRenamedPackageLPr(pkgName); Loading @@ -1261,16 +1260,15 @@ final class InstallPackageHelper { Slog.d(TAG, "Replacing existing renamed package: oldName=" + oldName + " pkgName=" + pkgName); } } else if (mPm.mPackages.containsKey(pkgName)) { } else if (ps != null) { // This package, under its official name, already exists // on the device; we should replace it. replace = true; if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing package: " + pkgName); } if (replace) { final AndroidPackage oldPackage = mPm.mPackages.get(pkgName); if (replace && oldPackage != null) { // Prevent apps opting out from runtime permissions AndroidPackage oldPackage = mPm.mPackages.get(pkgName); final int oldTargetSdk = oldPackage.getTargetSdkVersion(); final int newTargetSdk = parsedPackage.getTargetSdkVersion(); if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1 Loading @@ -1292,7 +1290,6 @@ final class InstallPackageHelper { } } PackageSetting ps = mPm.mSettings.getPackageLPr(pkgName); PackageSetting signatureCheckPs = ps; // SDK libs can have other major versions with different package names. Loading Loading @@ -1368,8 +1365,8 @@ final class InstallPackageHelper { if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps); systemApp = ps.isSystem(); request.setOriginUsers( ps.queryInstalledUsers(mPm.mUserManager.getUserIds(), true)); request.setOriginUsers(ps.queryUsersInstalledOrHasData( mPm.mUserManager.getUserIds())); } final int numGroups = ArrayUtils.size(parsedPackage.getPermissionGroups()); Loading Loading @@ -1595,7 +1592,7 @@ final class InstallPackageHelper { boolean shouldCloseFreezerBeforeReturn = true; try { final PackageState oldPackageState; final PackageSetting oldPackageState; final AndroidPackage oldPackage; String renamedPackage; boolean sysPkg = false; Loading Loading @@ -1648,7 +1645,7 @@ final class InstallPackageHelper { } } else { SigningDetails parsedPkgSigningDetails = parsedPackage.getSigningDetails(); SigningDetails oldPkgSigningDetails = oldPackage.getSigningDetails(); SigningDetails oldPkgSigningDetails = oldPackageState.getSigningDetails(); // default to original signature matching if (!parsedPkgSigningDetails.checkCapability(oldPkgSigningDetails, SigningDetails.CertCapabilities.INSTALLED_DATA) Loading @@ -1668,7 +1665,8 @@ final class InstallPackageHelper { } // don't allow a system upgrade unless the upgrade hash matches if (oldPackage.getRestrictUpdateHash() != null && oldPackageState.isSystem()) { if (oldPackage != null && oldPackage.getRestrictUpdateHash() != null && oldPackageState.isSystem()) { final byte[] digestBytes; try { final MessageDigest digest = MessageDigest.getInstance("SHA-512"); Loading @@ -1691,6 +1689,7 @@ final class InstallPackageHelper { parsedPackage.setRestrictUpdateHash(oldPackage.getRestrictUpdateHash()); } if (oldPackage != null) { // APK should not change its sharedUserId declarations final var oldSharedUid = oldPackage.getSharedUserId() != null ? oldPackage.getSharedUserId() : "<nothing>"; Loading @@ -1704,11 +1703,13 @@ final class InstallPackageHelper { } // APK should not re-join shared UID if (oldPackage.isLeavingSharedUser() && !parsedPackage.isLeavingSharedUser()) { if (oldPackage.isLeavingSharedUser() && !parsedPackage.isLeavingSharedUser()) { throw new PrepareFailure(INSTALL_FAILED_UID_CHANGED, "Package " + parsedPackage.getPackageName() + " attempting to rejoin " + newSharedUid); } } // In case of rollback, remember per-user/profile install state allUsers = mPm.mUserManager.getUserIds(); Loading Loading @@ -1740,8 +1741,8 @@ final class InstallPackageHelper { // Update what is removed PackageRemovedInfo removedInfo = new PackageRemovedInfo(mPm); removedInfo.mUid = oldPackage.getUid(); removedInfo.mRemovedPackage = oldPackage.getPackageName(); removedInfo.mUid = ps.getAppId(); removedInfo.mRemovedPackage = ps.getPackageName(); removedInfo.mInstallerPackageName = ps.getInstallSource().mInstallerPackageName; removedInfo.mIsStaticSharedLib = Loading @@ -1760,8 +1761,8 @@ final class InstallPackageHelper { removedInfo.mUninstallReasons.put(userId, ps.getUninstallReason(userId)); } removedInfo.mIsExternal = oldPackage.isExternalStorage(); removedInfo.mRemovedPackageVersionCode = oldPackage.getLongVersionCode(); removedInfo.mIsExternal = oldPackageState.isExternalStorage(); removedInfo.mRemovedPackageVersionCode = oldPackageState.getVersionCode(); request.setRemovedInfo(removedInfo); sysPkg = oldPackageState.isSystem(); Loading Loading @@ -1801,7 +1802,7 @@ final class InstallPackageHelper { } else { // new package install ps = null; disabledPs = null; oldPackage = null; oldPackageState = null; // Remember this for later, in case we need to rollback this install String pkgName1 = parsedPackage.getPackageName(); Loading Loading @@ -1832,8 +1833,8 @@ final class InstallPackageHelper { shouldCloseFreezerBeforeReturn = false; request.setPrepareResult(replace, targetScanFlags, targetParseFlags, oldPackage, parsedPackage, replace /* clearCodeCache */, sysPkg, ps, disabledPs); oldPackageState, parsedPackage, replace /* clearCodeCache */, sysPkg, ps, disabledPs); } finally { request.setFreezer(freezer); if (shouldCloseFreezerBeforeReturn) { Loading Loading @@ -2077,7 +2078,7 @@ final class InstallPackageHelper { // Set the update and install times PackageStateInternal deletedPkgSetting = mPm.snapshotComputer() .getPackageStateInternal(oldPackage.getPackageName()); .getPackageStateInternal(packageName); // TODO(b/225756739): For rebootless APEX, consider using lastUpdateMillis provided // by apexd to be more accurate. installRequest.setScannedPackageSettingFirstInstallTimeFromReplaced( Loading Loading @@ -2126,8 +2127,10 @@ final class InstallPackageHelper { if (oldCodePaths == null) { oldCodePaths = new ArraySet<>(); } if (oldPackage != null) { Collections.addAll(oldCodePaths, oldPackage.getBaseApkPath()); Collections.addAll(oldCodePaths, oldPackage.getSplitCodePaths()); } ps1.setOldCodePaths(oldCodePaths); } else { ps1.setOldCodePaths(null); Loading Loading @@ -2852,46 +2855,11 @@ final class InstallPackageHelper { mPm.notifyInstantAppPackageInstalled(request.getPkg().getPackageName(), request.getNewUsers()); // Determine the set of users who are adding this package for // the first time vs. those who are seeing an update. int[] firstUserIds = EMPTY_INT_ARRAY; int[] firstInstantUserIds = EMPTY_INT_ARRAY; int[] updateUserIds = EMPTY_INT_ARRAY; int[] instantUserIds = EMPTY_INT_ARRAY; final boolean allNewUsers = request.getOriginUsers() == null || request.getOriginUsers().length == 0; for (int newUser : request.getNewUsers()) { final boolean isInstantApp = pkgSetting.getUserStateOrDefault(newUser) .isInstantApp(); if (allNewUsers) { if (isInstantApp) { firstInstantUserIds = ArrayUtils.appendInt(firstInstantUserIds, newUser); } else { firstUserIds = ArrayUtils.appendInt(firstUserIds, newUser); } continue; } boolean isNew = true; for (int origUser : request.getOriginUsers()) { if (origUser == newUser) { isNew = false; break; } } if (isNew) { if (isInstantApp) { firstInstantUserIds = ArrayUtils.appendInt(firstInstantUserIds, newUser); } else { firstUserIds = ArrayUtils.appendInt(firstUserIds, newUser); } } else { if (isInstantApp) { instantUserIds = ArrayUtils.appendInt(instantUserIds, newUser); } else { updateUserIds = ArrayUtils.appendInt(updateUserIds, newUser); } } } request.populateBroadcastUsers(); final int[] firstUserIds = request.getFirstTimeBroadcastUserIds(); final int[] firstInstantUserIds = request.getFirstTimeBroadcastInstantUserIds(); final int[] updateUserIds = request.getUpdateBroadcastUserIds(); final int[] instantUserIds = request.getUpdateBroadcastInstantUserIds(); Bundle extras = new Bundle(); extras.putInt(Intent.EXTRA_UID, request.getAppId()); Loading Loading @@ -2969,12 +2937,10 @@ final class InstallPackageHelper { } // If package installer is defined, notify package installer about new // app installed if (mPm.mRequiredInstallerPackage != null) { mPm.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND /*flags*/, mPm.mRequiredInstallerPackage, null /*finishedReceiver*/, firstUserIds, instantUserIds, null /* broadcastAllowList */, null); } // Send replaced for users that don't see the package for the first time if (update) { Loading Loading @@ -3070,7 +3036,7 @@ final class InstallPackageHelper { } } if (allNewUsers && !update) { if (request.isAllNewUsers() && !update) { mPm.notifyPackageAdded(packageName, request.getAppId()); } else { mPm.notifyPackageChanged(packageName, request.getAppId()); Loading services/core/java/com/android/server/pm/InstallRequest.java +89 −13 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static android.content.pm.PackageManager.INSTALL_REASON_UNKNOWN; import static android.content.pm.PackageManager.INSTALL_SCENARIO_DEFAULT; import static android.content.pm.PackageManager.INSTALL_SUCCEEDED; import static android.os.Process.INVALID_UID; import static com.android.server.pm.PackageManagerService.EMPTY_INT_ARRAY; import static com.android.server.pm.PackageManagerService.SCAN_AS_INSTANT_APP; import static com.android.server.pm.PackageManagerService.TAG; Loading @@ -43,6 +44,7 @@ import android.util.ArrayMap; import android.util.ExceptionUtils; import android.util.Slog; import com.android.internal.util.ArrayUtils; import com.android.server.art.model.DexoptResult; import com.android.server.pm.parsing.pkg.ParsedPackage; import com.android.server.pm.pkg.AndroidPackage; Loading @@ -52,6 +54,7 @@ import com.android.server.pm.pkg.parsing.ParsingPackageUtils; import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.List; final class InstallRequest { Loading @@ -69,8 +72,8 @@ final class InstallRequest { private int mParseFlags; private boolean mReplace; @Nullable /* The original Package if it is being replaced, otherwise {@code null} */ private AndroidPackage mExistingPackage; @Nullable /* The original package's name if it is being replaced, otherwise {@code null} */ private String mExistingPackageName; /** parsed package to be scanned */ @Nullable private ParsedPackage mParsedPackage; Loading Loading @@ -132,6 +135,15 @@ final class InstallRequest { private int mDexoptStatus; @NonNull private int[] mFirstTimeBroadcastUserIds = EMPTY_INT_ARRAY; @NonNull private int[] mFirstTimeBroadcastInstantUserIds = EMPTY_INT_ARRAY; @NonNull private int[] mUpdateBroadcastUserIds = EMPTY_INT_ARRAY; @NonNull private int[] mUpdateBroadcastInstantUserIds = EMPTY_INT_ARRAY; // New install InstallRequest(InstallingSession params) { mUserId = params.getUser().getIdentifier(); Loading Loading @@ -412,11 +424,6 @@ final class InstallRequest { return mLibraryConsumers; } @Nullable public AndroidPackage getExistingPackage() { return mExistingPackage; } @Nullable public List<String> getAllowlistedRestrictedPermissions() { return mInstallArgs == null ? null : mInstallArgs.mAllowlistedRestrictedPermissions; Loading Loading @@ -453,10 +460,7 @@ final class InstallRequest { @Nullable public String getExistingPackageName() { if (mExistingPackage != null) { return mExistingPackage.getPackageName(); } return null; return mExistingPackageName; } @Nullable Loading Loading @@ -627,6 +631,25 @@ final class InstallRequest { return mDexoptStatus; } public boolean isAllNewUsers() { return mOrigUsers == null || mOrigUsers.length == 0; } public int[] getFirstTimeBroadcastUserIds() { return mFirstTimeBroadcastUserIds; } public int[] getFirstTimeBroadcastInstantUserIds() { return mFirstTimeBroadcastInstantUserIds; } public int[] getUpdateBroadcastUserIds() { return mUpdateBroadcastUserIds; } public int[] getUpdateBroadcastInstantUserIds() { return mUpdateBroadcastInstantUserIds; } public void setScanFlags(int scanFlags) { mScanFlags = scanFlags; } Loading Loading @@ -729,13 +752,14 @@ final class InstallRequest { } public void setPrepareResult(boolean replace, int scanFlags, int parseFlags, AndroidPackage existingPackage, int parseFlags, PackageState existingPackageState, ParsedPackage packageToScan, boolean clearCodeCache, boolean system, PackageSetting originalPs, PackageSetting disabledPs) { mReplace = replace; mScanFlags = scanFlags; mParseFlags = parseFlags; mExistingPackage = existingPackage; mExistingPackageName = existingPackageState != null ? existingPackageState.getPackageName() : null; mParsedPackage = packageToScan; mClearCodeCache = clearCodeCache; mSystem = system; Loading Loading @@ -769,6 +793,58 @@ final class InstallRequest { } } /** * Determine the set of users who are adding this package for the first time vs. those who are * seeing an update. */ public void populateBroadcastUsers() { assertScanResultExists(); mFirstTimeBroadcastUserIds = EMPTY_INT_ARRAY; mFirstTimeBroadcastInstantUserIds = EMPTY_INT_ARRAY; mUpdateBroadcastUserIds = EMPTY_INT_ARRAY; mUpdateBroadcastInstantUserIds = EMPTY_INT_ARRAY; final boolean allNewUsers = isAllNewUsers(); if (allNewUsers) { // App was not currently installed on any user for (int newUser : mNewUsers) { final boolean isInstantApp = mScanResult.mPkgSetting.getUserStateOrDefault(newUser).isInstantApp(); if (isInstantApp) { mFirstTimeBroadcastInstantUserIds = ArrayUtils.appendInt(mFirstTimeBroadcastInstantUserIds, newUser); } else { mFirstTimeBroadcastUserIds = ArrayUtils.appendInt(mFirstTimeBroadcastUserIds, newUser); } } return; } // App was already installed on some users, but is new to some other users for (int newUser : mNewUsers) { boolean isFirstTimeUser = !ArrayUtils.contains(mOrigUsers, newUser); final boolean isInstantApp = mScanResult.mPkgSetting.getUserStateOrDefault(newUser).isInstantApp(); if (isFirstTimeUser) { if (isInstantApp) { mFirstTimeBroadcastInstantUserIds = ArrayUtils.appendInt(mFirstTimeBroadcastInstantUserIds, newUser); } else { mFirstTimeBroadcastUserIds = ArrayUtils.appendInt(mFirstTimeBroadcastUserIds, newUser); } } else { if (isInstantApp) { mUpdateBroadcastInstantUserIds = ArrayUtils.appendInt(mUpdateBroadcastInstantUserIds, newUser); } else { mUpdateBroadcastUserIds = ArrayUtils.appendInt(mUpdateBroadcastUserIds, newUser); } } } } public void onPrepareStarted() { if (mPackageMetrics != null) { mPackageMetrics.onStepStarted(PackageMetrics.STEP_PREPARE); Loading services/core/java/com/android/server/pm/PackageSetting.java +18 −0 Original line number Diff line number Diff line Loading @@ -844,6 +844,24 @@ public class PackageSetting extends SettingBase implements PackageStateInternal return res; } int[] queryUsersInstalledOrHasData(int[] users) { int num = 0; for (int user : users) { if (getInstalled(user) || readUserState(user).dataExists()) { num++; } } int[] res = new int[num]; num = 0; for (int user : users) { if (getInstalled(user) || readUserState(user).dataExists()) { res[num] = user; num++; } } return res; } long getCeDataInode(int userId) { return readUserState(userId).getCeDataInode(); } Loading Loading
services/core/java/com/android/server/pm/InstallPackageHelper.java +51 −85 Original line number Diff line number Diff line Loading @@ -56,7 +56,6 @@ import static com.android.server.pm.PackageManagerService.DEBUG_PACKAGE_SCANNING import static com.android.server.pm.PackageManagerService.DEBUG_REMOVE; import static com.android.server.pm.PackageManagerService.DEBUG_UPGRADE; import static com.android.server.pm.PackageManagerService.DEBUG_VERIFY; import static com.android.server.pm.PackageManagerService.EMPTY_INT_ARRAY; import static com.android.server.pm.PackageManagerService.MIN_INSTALLABLE_TARGET_SDK; import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME; import static com.android.server.pm.PackageManagerService.POST_INSTALL; Loading Loading @@ -180,7 +179,6 @@ import com.android.server.pm.parsing.pkg.ParsedPackage; import com.android.server.pm.permission.Permission; import com.android.server.pm.permission.PermissionManagerServiceInternal; import com.android.server.pm.pkg.AndroidPackage; import com.android.server.pm.pkg.PackageState; import com.android.server.pm.pkg.PackageStateInternal; import com.android.server.pm.pkg.SharedLibraryWrapper; import com.android.server.pm.pkg.component.ComponentMutateUtils; Loading Loading @@ -1245,6 +1243,7 @@ final class InstallPackageHelper { boolean systemApp = false; boolean replace = false; synchronized (mPm.mLock) { final PackageSetting ps = mPm.mSettings.getPackageLPr(pkgName); // Check if installing already existing package if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { String oldName = mPm.mSettings.getRenamedPackageLPr(pkgName); Loading @@ -1261,16 +1260,15 @@ final class InstallPackageHelper { Slog.d(TAG, "Replacing existing renamed package: oldName=" + oldName + " pkgName=" + pkgName); } } else if (mPm.mPackages.containsKey(pkgName)) { } else if (ps != null) { // This package, under its official name, already exists // on the device; we should replace it. replace = true; if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing package: " + pkgName); } if (replace) { final AndroidPackage oldPackage = mPm.mPackages.get(pkgName); if (replace && oldPackage != null) { // Prevent apps opting out from runtime permissions AndroidPackage oldPackage = mPm.mPackages.get(pkgName); final int oldTargetSdk = oldPackage.getTargetSdkVersion(); final int newTargetSdk = parsedPackage.getTargetSdkVersion(); if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1 Loading @@ -1292,7 +1290,6 @@ final class InstallPackageHelper { } } PackageSetting ps = mPm.mSettings.getPackageLPr(pkgName); PackageSetting signatureCheckPs = ps; // SDK libs can have other major versions with different package names. Loading Loading @@ -1368,8 +1365,8 @@ final class InstallPackageHelper { if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps); systemApp = ps.isSystem(); request.setOriginUsers( ps.queryInstalledUsers(mPm.mUserManager.getUserIds(), true)); request.setOriginUsers(ps.queryUsersInstalledOrHasData( mPm.mUserManager.getUserIds())); } final int numGroups = ArrayUtils.size(parsedPackage.getPermissionGroups()); Loading Loading @@ -1595,7 +1592,7 @@ final class InstallPackageHelper { boolean shouldCloseFreezerBeforeReturn = true; try { final PackageState oldPackageState; final PackageSetting oldPackageState; final AndroidPackage oldPackage; String renamedPackage; boolean sysPkg = false; Loading Loading @@ -1648,7 +1645,7 @@ final class InstallPackageHelper { } } else { SigningDetails parsedPkgSigningDetails = parsedPackage.getSigningDetails(); SigningDetails oldPkgSigningDetails = oldPackage.getSigningDetails(); SigningDetails oldPkgSigningDetails = oldPackageState.getSigningDetails(); // default to original signature matching if (!parsedPkgSigningDetails.checkCapability(oldPkgSigningDetails, SigningDetails.CertCapabilities.INSTALLED_DATA) Loading @@ -1668,7 +1665,8 @@ final class InstallPackageHelper { } // don't allow a system upgrade unless the upgrade hash matches if (oldPackage.getRestrictUpdateHash() != null && oldPackageState.isSystem()) { if (oldPackage != null && oldPackage.getRestrictUpdateHash() != null && oldPackageState.isSystem()) { final byte[] digestBytes; try { final MessageDigest digest = MessageDigest.getInstance("SHA-512"); Loading @@ -1691,6 +1689,7 @@ final class InstallPackageHelper { parsedPackage.setRestrictUpdateHash(oldPackage.getRestrictUpdateHash()); } if (oldPackage != null) { // APK should not change its sharedUserId declarations final var oldSharedUid = oldPackage.getSharedUserId() != null ? oldPackage.getSharedUserId() : "<nothing>"; Loading @@ -1704,11 +1703,13 @@ final class InstallPackageHelper { } // APK should not re-join shared UID if (oldPackage.isLeavingSharedUser() && !parsedPackage.isLeavingSharedUser()) { if (oldPackage.isLeavingSharedUser() && !parsedPackage.isLeavingSharedUser()) { throw new PrepareFailure(INSTALL_FAILED_UID_CHANGED, "Package " + parsedPackage.getPackageName() + " attempting to rejoin " + newSharedUid); } } // In case of rollback, remember per-user/profile install state allUsers = mPm.mUserManager.getUserIds(); Loading Loading @@ -1740,8 +1741,8 @@ final class InstallPackageHelper { // Update what is removed PackageRemovedInfo removedInfo = new PackageRemovedInfo(mPm); removedInfo.mUid = oldPackage.getUid(); removedInfo.mRemovedPackage = oldPackage.getPackageName(); removedInfo.mUid = ps.getAppId(); removedInfo.mRemovedPackage = ps.getPackageName(); removedInfo.mInstallerPackageName = ps.getInstallSource().mInstallerPackageName; removedInfo.mIsStaticSharedLib = Loading @@ -1760,8 +1761,8 @@ final class InstallPackageHelper { removedInfo.mUninstallReasons.put(userId, ps.getUninstallReason(userId)); } removedInfo.mIsExternal = oldPackage.isExternalStorage(); removedInfo.mRemovedPackageVersionCode = oldPackage.getLongVersionCode(); removedInfo.mIsExternal = oldPackageState.isExternalStorage(); removedInfo.mRemovedPackageVersionCode = oldPackageState.getVersionCode(); request.setRemovedInfo(removedInfo); sysPkg = oldPackageState.isSystem(); Loading Loading @@ -1801,7 +1802,7 @@ final class InstallPackageHelper { } else { // new package install ps = null; disabledPs = null; oldPackage = null; oldPackageState = null; // Remember this for later, in case we need to rollback this install String pkgName1 = parsedPackage.getPackageName(); Loading Loading @@ -1832,8 +1833,8 @@ final class InstallPackageHelper { shouldCloseFreezerBeforeReturn = false; request.setPrepareResult(replace, targetScanFlags, targetParseFlags, oldPackage, parsedPackage, replace /* clearCodeCache */, sysPkg, ps, disabledPs); oldPackageState, parsedPackage, replace /* clearCodeCache */, sysPkg, ps, disabledPs); } finally { request.setFreezer(freezer); if (shouldCloseFreezerBeforeReturn) { Loading Loading @@ -2077,7 +2078,7 @@ final class InstallPackageHelper { // Set the update and install times PackageStateInternal deletedPkgSetting = mPm.snapshotComputer() .getPackageStateInternal(oldPackage.getPackageName()); .getPackageStateInternal(packageName); // TODO(b/225756739): For rebootless APEX, consider using lastUpdateMillis provided // by apexd to be more accurate. installRequest.setScannedPackageSettingFirstInstallTimeFromReplaced( Loading Loading @@ -2126,8 +2127,10 @@ final class InstallPackageHelper { if (oldCodePaths == null) { oldCodePaths = new ArraySet<>(); } if (oldPackage != null) { Collections.addAll(oldCodePaths, oldPackage.getBaseApkPath()); Collections.addAll(oldCodePaths, oldPackage.getSplitCodePaths()); } ps1.setOldCodePaths(oldCodePaths); } else { ps1.setOldCodePaths(null); Loading Loading @@ -2852,46 +2855,11 @@ final class InstallPackageHelper { mPm.notifyInstantAppPackageInstalled(request.getPkg().getPackageName(), request.getNewUsers()); // Determine the set of users who are adding this package for // the first time vs. those who are seeing an update. int[] firstUserIds = EMPTY_INT_ARRAY; int[] firstInstantUserIds = EMPTY_INT_ARRAY; int[] updateUserIds = EMPTY_INT_ARRAY; int[] instantUserIds = EMPTY_INT_ARRAY; final boolean allNewUsers = request.getOriginUsers() == null || request.getOriginUsers().length == 0; for (int newUser : request.getNewUsers()) { final boolean isInstantApp = pkgSetting.getUserStateOrDefault(newUser) .isInstantApp(); if (allNewUsers) { if (isInstantApp) { firstInstantUserIds = ArrayUtils.appendInt(firstInstantUserIds, newUser); } else { firstUserIds = ArrayUtils.appendInt(firstUserIds, newUser); } continue; } boolean isNew = true; for (int origUser : request.getOriginUsers()) { if (origUser == newUser) { isNew = false; break; } } if (isNew) { if (isInstantApp) { firstInstantUserIds = ArrayUtils.appendInt(firstInstantUserIds, newUser); } else { firstUserIds = ArrayUtils.appendInt(firstUserIds, newUser); } } else { if (isInstantApp) { instantUserIds = ArrayUtils.appendInt(instantUserIds, newUser); } else { updateUserIds = ArrayUtils.appendInt(updateUserIds, newUser); } } } request.populateBroadcastUsers(); final int[] firstUserIds = request.getFirstTimeBroadcastUserIds(); final int[] firstInstantUserIds = request.getFirstTimeBroadcastInstantUserIds(); final int[] updateUserIds = request.getUpdateBroadcastUserIds(); final int[] instantUserIds = request.getUpdateBroadcastInstantUserIds(); Bundle extras = new Bundle(); extras.putInt(Intent.EXTRA_UID, request.getAppId()); Loading Loading @@ -2969,12 +2937,10 @@ final class InstallPackageHelper { } // If package installer is defined, notify package installer about new // app installed if (mPm.mRequiredInstallerPackage != null) { mPm.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND /*flags*/, mPm.mRequiredInstallerPackage, null /*finishedReceiver*/, firstUserIds, instantUserIds, null /* broadcastAllowList */, null); } // Send replaced for users that don't see the package for the first time if (update) { Loading Loading @@ -3070,7 +3036,7 @@ final class InstallPackageHelper { } } if (allNewUsers && !update) { if (request.isAllNewUsers() && !update) { mPm.notifyPackageAdded(packageName, request.getAppId()); } else { mPm.notifyPackageChanged(packageName, request.getAppId()); Loading
services/core/java/com/android/server/pm/InstallRequest.java +89 −13 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static android.content.pm.PackageManager.INSTALL_REASON_UNKNOWN; import static android.content.pm.PackageManager.INSTALL_SCENARIO_DEFAULT; import static android.content.pm.PackageManager.INSTALL_SUCCEEDED; import static android.os.Process.INVALID_UID; import static com.android.server.pm.PackageManagerService.EMPTY_INT_ARRAY; import static com.android.server.pm.PackageManagerService.SCAN_AS_INSTANT_APP; import static com.android.server.pm.PackageManagerService.TAG; Loading @@ -43,6 +44,7 @@ import android.util.ArrayMap; import android.util.ExceptionUtils; import android.util.Slog; import com.android.internal.util.ArrayUtils; import com.android.server.art.model.DexoptResult; import com.android.server.pm.parsing.pkg.ParsedPackage; import com.android.server.pm.pkg.AndroidPackage; Loading @@ -52,6 +54,7 @@ import com.android.server.pm.pkg.parsing.ParsingPackageUtils; import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.List; final class InstallRequest { Loading @@ -69,8 +72,8 @@ final class InstallRequest { private int mParseFlags; private boolean mReplace; @Nullable /* The original Package if it is being replaced, otherwise {@code null} */ private AndroidPackage mExistingPackage; @Nullable /* The original package's name if it is being replaced, otherwise {@code null} */ private String mExistingPackageName; /** parsed package to be scanned */ @Nullable private ParsedPackage mParsedPackage; Loading Loading @@ -132,6 +135,15 @@ final class InstallRequest { private int mDexoptStatus; @NonNull private int[] mFirstTimeBroadcastUserIds = EMPTY_INT_ARRAY; @NonNull private int[] mFirstTimeBroadcastInstantUserIds = EMPTY_INT_ARRAY; @NonNull private int[] mUpdateBroadcastUserIds = EMPTY_INT_ARRAY; @NonNull private int[] mUpdateBroadcastInstantUserIds = EMPTY_INT_ARRAY; // New install InstallRequest(InstallingSession params) { mUserId = params.getUser().getIdentifier(); Loading Loading @@ -412,11 +424,6 @@ final class InstallRequest { return mLibraryConsumers; } @Nullable public AndroidPackage getExistingPackage() { return mExistingPackage; } @Nullable public List<String> getAllowlistedRestrictedPermissions() { return mInstallArgs == null ? null : mInstallArgs.mAllowlistedRestrictedPermissions; Loading Loading @@ -453,10 +460,7 @@ final class InstallRequest { @Nullable public String getExistingPackageName() { if (mExistingPackage != null) { return mExistingPackage.getPackageName(); } return null; return mExistingPackageName; } @Nullable Loading Loading @@ -627,6 +631,25 @@ final class InstallRequest { return mDexoptStatus; } public boolean isAllNewUsers() { return mOrigUsers == null || mOrigUsers.length == 0; } public int[] getFirstTimeBroadcastUserIds() { return mFirstTimeBroadcastUserIds; } public int[] getFirstTimeBroadcastInstantUserIds() { return mFirstTimeBroadcastInstantUserIds; } public int[] getUpdateBroadcastUserIds() { return mUpdateBroadcastUserIds; } public int[] getUpdateBroadcastInstantUserIds() { return mUpdateBroadcastInstantUserIds; } public void setScanFlags(int scanFlags) { mScanFlags = scanFlags; } Loading Loading @@ -729,13 +752,14 @@ final class InstallRequest { } public void setPrepareResult(boolean replace, int scanFlags, int parseFlags, AndroidPackage existingPackage, int parseFlags, PackageState existingPackageState, ParsedPackage packageToScan, boolean clearCodeCache, boolean system, PackageSetting originalPs, PackageSetting disabledPs) { mReplace = replace; mScanFlags = scanFlags; mParseFlags = parseFlags; mExistingPackage = existingPackage; mExistingPackageName = existingPackageState != null ? existingPackageState.getPackageName() : null; mParsedPackage = packageToScan; mClearCodeCache = clearCodeCache; mSystem = system; Loading Loading @@ -769,6 +793,58 @@ final class InstallRequest { } } /** * Determine the set of users who are adding this package for the first time vs. those who are * seeing an update. */ public void populateBroadcastUsers() { assertScanResultExists(); mFirstTimeBroadcastUserIds = EMPTY_INT_ARRAY; mFirstTimeBroadcastInstantUserIds = EMPTY_INT_ARRAY; mUpdateBroadcastUserIds = EMPTY_INT_ARRAY; mUpdateBroadcastInstantUserIds = EMPTY_INT_ARRAY; final boolean allNewUsers = isAllNewUsers(); if (allNewUsers) { // App was not currently installed on any user for (int newUser : mNewUsers) { final boolean isInstantApp = mScanResult.mPkgSetting.getUserStateOrDefault(newUser).isInstantApp(); if (isInstantApp) { mFirstTimeBroadcastInstantUserIds = ArrayUtils.appendInt(mFirstTimeBroadcastInstantUserIds, newUser); } else { mFirstTimeBroadcastUserIds = ArrayUtils.appendInt(mFirstTimeBroadcastUserIds, newUser); } } return; } // App was already installed on some users, but is new to some other users for (int newUser : mNewUsers) { boolean isFirstTimeUser = !ArrayUtils.contains(mOrigUsers, newUser); final boolean isInstantApp = mScanResult.mPkgSetting.getUserStateOrDefault(newUser).isInstantApp(); if (isFirstTimeUser) { if (isInstantApp) { mFirstTimeBroadcastInstantUserIds = ArrayUtils.appendInt(mFirstTimeBroadcastInstantUserIds, newUser); } else { mFirstTimeBroadcastUserIds = ArrayUtils.appendInt(mFirstTimeBroadcastUserIds, newUser); } } else { if (isInstantApp) { mUpdateBroadcastInstantUserIds = ArrayUtils.appendInt(mUpdateBroadcastInstantUserIds, newUser); } else { mUpdateBroadcastUserIds = ArrayUtils.appendInt(mUpdateBroadcastUserIds, newUser); } } } } public void onPrepareStarted() { if (mPackageMetrics != null) { mPackageMetrics.onStepStarted(PackageMetrics.STEP_PREPARE); Loading
services/core/java/com/android/server/pm/PackageSetting.java +18 −0 Original line number Diff line number Diff line Loading @@ -844,6 +844,24 @@ public class PackageSetting extends SettingBase implements PackageStateInternal return res; } int[] queryUsersInstalledOrHasData(int[] users) { int num = 0; for (int user : users) { if (getInstalled(user) || readUserState(user).dataExists()) { num++; } } int[] res = new int[num]; num = 0; for (int user : users) { if (getInstalled(user) || readUserState(user).dataExists()) { res[num] = user; num++; } } return res; } long getCeDataInode(int userId) { return readUserState(userId).getCeDataInode(); } Loading