Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 33670edb authored by TYM Tsai's avatar TYM Tsai Committed by Android (Google) Code Review
Browse files

Merge "Move dexopt out of the package freezer." into main

parents 81d2a1ec be0d6093
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -80,6 +80,7 @@ import com.android.server.pinner.PinnerService;
import com.android.server.pm.PackageDexOptimizer.DexOptResult;
import com.android.server.pm.dex.DexManager;
import com.android.server.pm.dex.DexoptOptions;
import com.android.server.pm.local.PackageManagerLocalImpl;
import com.android.server.pm.pkg.AndroidPackage;
import com.android.server.pm.pkg.PackageState;
import com.android.server.pm.pkg.PackageStateInternal;
@@ -819,10 +820,16 @@ public final class DexOptHelper {
        final PackageSetting ps = installRequest.getScannedPackageSetting();
        final String packageName = ps.getPackageName();

        PackageSetting uncommittedPs = null;
        if (Flags.improveInstallFreeze()) {
            uncommittedPs = ps;
        }

        PackageManagerLocal packageManagerLocal =
                LocalManagerRegistry.getManager(PackageManagerLocal.class);
        try (PackageManagerLocal.FilteredSnapshot snapshot =
                     packageManagerLocal.withFilteredSnapshot()) {
                     PackageManagerLocalImpl.withFilteredSnapshot(packageManagerLocal,
                uncommittedPs)) {
            boolean ignoreDexoptProfile =
                    (installRequest.getInstallFlags()
                            & PackageManager.INSTALL_IGNORE_DEXOPT_PROFILE)
+88 −12
Original line number Diff line number Diff line
@@ -148,6 +148,7 @@ import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.EventLog;
import android.util.ExceptionUtils;
import android.util.IntArray;
import android.util.Log;
import android.util.Pair;
import android.util.Slog;
@@ -1014,13 +1015,17 @@ final class InstallPackageHelper {
        final Map<String, Settings.VersionInfo> versionInfos = new ArrayMap<>(requests.size());
        try {
            CriticalEventLog.getInstance().logInstallPackagesStarted();

            if (prepareInstallPackages(requests)
                    && scanInstallPackages(requests, createdAppId, versionInfos)) {
                List<ReconciledPackage> reconciledPackages =
                        reconcileInstallPackages(requests, versionInfos);
                if (reconciledPackages != null
                        && renameAndUpdatePaths(requests)
                if (reconciledPackages == null) {
                    return;
                }
                if (Flags.improveInstallFreeze()) {
                    prepPerformDexoptIfNeeded(reconciledPackages);
                }
                if (renameAndUpdatePaths(requests)
                        && commitInstallPackages(reconciledPackages)) {
                    success = true;
                }
@@ -1031,6 +1036,75 @@ final class InstallPackageHelper {
        }
    }

    private int[] getNewUsers(InstallRequest installRequest, int[] allUsers)
            throws PackageManagerException {
        final int userId = installRequest.getUserId();
        if (userId != UserHandle.USER_ALL && userId != UserHandle.USER_CURRENT
                && !mPm.mUserManager.exists(userId)) {
            throw new PackageManagerException(PackageManagerException.INTERNAL_ERROR_MISSING_USER,
                    "User " + userId + " doesn't exist or has been removed");
        }

        final IntArray newUserIds = new IntArray();
        if (userId != UserHandle.USER_ALL) {
            newUserIds.add(userId);
        } else if (allUsers != null) {
            final int[] installedForUsers = installRequest.getOriginUsers();
            for (int currentUserId : allUsers) {
                final boolean installedForCurrentUser = ArrayUtils.contains(
                        installedForUsers, currentUserId);
                final boolean restrictedByPolicy =
                        mPm.isUserRestricted(currentUserId,
                                UserManager.DISALLOW_INSTALL_APPS)
                                || mPm.isUserRestricted(currentUserId,
                                UserManager.DISALLOW_DEBUGGING_FEATURES);
                if (installedForCurrentUser || !restrictedByPolicy) {
                    newUserIds.add(currentUserId);
                }
            }
        }

        if (newUserIds.size() == 0) {
            throw new PackageManagerException(PackageManagerException.INTERNAL_ERROR_MISSING_USER,
                    "User " + userId + " doesn't exist or has been removed");
        } else {
            return newUserIds.toArray();
        }
    }

    private void prepPerformDexoptIfNeeded(List<ReconciledPackage> reconciledPackages) {
        for (ReconciledPackage reconciledPkg : reconciledPackages) {
            final InstallRequest request = reconciledPkg.mInstallRequest;
            // prepare profiles
            final PackageSetting ps = request.getScannedPackageSetting();
            final PackageSetting oldPkgSetting = request.getScanRequestOldPackageSetting();
            final int[] allUsers = mPm.mUserManager.getUserIds();
            if (reconciledPkg.mCollectedSharedLibraryInfos != null
                    || (oldPkgSetting != null
                    && !oldPkgSetting.getSharedLibraryDependencies().isEmpty())) {
                // Reconcile if the new package or the old package uses shared libraries.
                // It is possible that the old package uses shared libraries but the new
                // one doesn't.
                mSharedLibraries.executeSharedLibrariesUpdate(request.getParsedPackage(), ps,
                        null, null, reconciledPkg.mCollectedSharedLibraryInfos, allUsers);
            }
            try (PackageManagerTracedLock installLock = mPm.mInstallLock.acquireLock()) {
                final int[] newUsers = getNewUsers(request, allUsers);
                // Hardcode previousAppId to 0 to disable any data migration (http://b/221088088)
                mAppDataHelper.prepareAppDataPostCommitLIF(ps, 0, newUsers);
                if (request.isClearCodeCache()) {
                    mAppDataHelper.clearAppDataLIF(ps.getPkg(), UserHandle.USER_ALL,
                            FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL
                                    | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
                }
            } catch (PackageManagerException e) {
                request.setError(e.error, e.getMessage());
                return;
            }
            DexOptHelper.performDexoptIfNeeded(request, mDexManager, mContext, null);
        }
    }

    private boolean renameAndUpdatePaths(List<InstallRequest> requests) {
        try (PackageManagerTracedLock installLock = mPm.mInstallLock.acquireLock()) {
            for (InstallRequest request : requests) {
@@ -2655,6 +2729,11 @@ final class InstallPackageHelper {
                incrementalStorages.add(storage);
            }

            if (installRequest.isInstallReplace() && pkg != null) {
                mDexManager.notifyPackageUpdated(packageName,
                        pkg.getBaseApkPath(), pkg.getSplitCodePaths());
            }
            if (!Flags.improveInstallFreeze()) {
                // Hardcode previousAppId to 0 to disable any data migration (http://b/221088088)
                mAppDataHelper.prepareAppDataPostCommitLIF(ps, 0, installRequest.getNewUsers());
                if (installRequest.isClearCodeCache()) {
@@ -2662,14 +2741,11 @@ final class InstallPackageHelper {
                            FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL
                                    | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
                }
            if (installRequest.isInstallReplace() && pkg != null) {
                mDexManager.notifyPackageUpdated(packageName,
                        pkg.getBaseApkPath(), pkg.getSplitCodePaths());
            }

                DexOptHelper.performDexoptIfNeeded(installRequest, mDexManager, mContext,
                        mPm.mInstallLock.getRawLock());
            }
        }
        PackageManagerServiceUtils.waitForNativeBinariesExtractionForIncremental(
                incrementalStorages);
    }
+37 −3
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import com.android.server.pm.Computer;
import com.android.server.pm.PackageManagerLocal;
import com.android.server.pm.PackageManagerService;
import com.android.server.pm.pkg.PackageState;
import com.android.server.pm.pkg.PackageStateInternal;
import com.android.server.pm.pkg.SharedUserApi;
import com.android.server.pm.snapshot.PackageDataSnapshot;

@@ -71,8 +72,26 @@ public class PackageManagerLocalImpl implements PackageManagerLocal {
    @NonNull
    @Override
    public FilteredSnapshotImpl withFilteredSnapshot(int callingUid, @NonNull UserHandle user) {
        return withFilteredSnapshot(callingUid, user, /* uncommittedPs= */ null);
    }

    /**
     * Creates a {@link FilteredSnapshot} with a uncommitted {@link PackageState} that is used for
     * dexopt in the art service to get the correct package state before the package is committed.
     */
    @NonNull
    public static FilteredSnapshotImpl withFilteredSnapshot(PackageManagerLocal pm,
            @NonNull PackageState uncommittedPs) {
        return ((PackageManagerLocalImpl) pm).withFilteredSnapshot(Binder.getCallingUid(),
                Binder.getCallingUserHandle(), uncommittedPs);
    }

    @NonNull
    private FilteredSnapshotImpl withFilteredSnapshot(int callingUid, @NonNull UserHandle user,
            @Nullable PackageState uncommittedPs) {
        return new FilteredSnapshotImpl(callingUid, user,
                mService.snapshotComputer(false /*allowLiveComputer*/), null);
                mService.snapshotComputer(/* allowLiveComputer= */ false),
                /* parentSnapshot= */ null, uncommittedPs);
    }

    @Override
@@ -145,7 +164,8 @@ public class PackageManagerLocalImpl implements PackageManagerLocal {

        @Override
        public FilteredSnapshot filtered(int callingUid, @NonNull UserHandle user) {
            return new FilteredSnapshotImpl(callingUid, user, mSnapshot, this);
            return new FilteredSnapshotImpl(callingUid, user, mSnapshot, this,
                    /* uncommittedPs= */ null);
        }

        @SuppressWarnings("RedundantSuppression")
@@ -209,13 +229,18 @@ public class PackageManagerLocalImpl implements PackageManagerLocal {
        @Nullable
        private final UnfilteredSnapshotImpl mParentSnapshot;

        @Nullable
        private final PackageState mUncommitPackageState;

        private FilteredSnapshotImpl(int callingUid, @NonNull UserHandle user,
                @NonNull PackageDataSnapshot snapshot,
                @Nullable UnfilteredSnapshotImpl parentSnapshot) {
                @Nullable UnfilteredSnapshotImpl parentSnapshot,
                @Nullable PackageState uncommittedPs) {
            super(snapshot);
            mCallingUid = callingUid;
            mUserId = user.getIdentifier();
            mParentSnapshot = parentSnapshot;
            mUncommitPackageState = uncommittedPs;
        }

        @Override
@@ -237,6 +262,10 @@ public class PackageManagerLocalImpl implements PackageManagerLocal {
        @Override
        public PackageState getPackageState(@NonNull String packageName) {
            checkClosed();
            if (mUncommitPackageState != null
                    && packageName.equals(mUncommitPackageState.getPackageName())) {
                return mUncommitPackageState;
            }
            return mSnapshot.getPackageStateFiltered(packageName, mCallingUid, mUserId);
        }

@@ -250,6 +279,11 @@ public class PackageManagerLocalImpl implements PackageManagerLocal {
                var filteredPackageStates = new ArrayMap<String, PackageState>();
                for (int index = 0, size = packageStates.size(); index < size; index++) {
                    var packageState = packageStates.valueAt(index);
                    if (mUncommitPackageState != null
                            && packageState.getPackageName().equals(
                            mUncommitPackageState.getPackageName())) {
                        packageState = (PackageStateInternal) mUncommitPackageState;
                    }
                    if (!mSnapshot.shouldFilterApplication(packageState, mCallingUid, mUserId)) {
                        filteredPackageStates.put(packageStates.keyAt(index), packageState);
                    }