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

Commit f49f75b9 authored by Songchun Fan's avatar Songchun Fan Committed by Song Chun Fan
Browse files

[pm] keep record of old code paths for DONT_KILL

Remember the old code paths till they are deleted or next reboot.

BUG: 291212866
Test: manual with dumpsys. Steps:
Test: adb shell device_config set_sync_disabled_for_tests persistent
Test: adb shell device_config put package_manager_service android.content.pm.improve_install_dont_kill true
Test: adb reboot
Test: adb install out/target/product/oriole/testcases/CtsPackageManagerTestCases/arm64/CtsPackageManagerTestCases.apk
Test: adb install -p android.content.cts --dont-kill out/target/product/oriole/testcases/CtsPackageManagerTestCases/arm64/CtsPackageManagerTestCases_hdpi-v4.apk
Test: adb install -p android.content.cts --dont-kill out/target/product/oriole/testcases/CtsPackageManagerTestCases/arm64/CtsPackageManagerTestCases_mdpi-v4.apk
Test: adb shell dumpsys package android.content.cts
...
Packages:
  Package [android.content.cts] (96dcd08):
    appId=10284
    pkg=Package{3e3bd99 android.content.cts}
    codePath=/data/app/~~18rBVZSv1eM-N57FoDiipg==/android.content.cts-ml8Eu3ATfq-vE-6jPBuwrw==
      oldCodePath=/data/app/~~7Nm84FuSQyQbowmQlFpzIQ==/android.content.cts-n6lXiSDvOOvROWtDhwQbKQ==
      oldCodePath=/data/app/~~1zIiiOR5rCIozXtw7mAyEQ==/android.content.cts-3LyIwg5UcWRCuyMjQ4Jvlw==
    resourcePath=/data/app/~~18rBVZSv1eM-N57FoDiipg==/android.content.cts-ml8Eu3ATfq-vE-6jPBuwrw==
    ...

Test: atest com.android.server.pm.PackageManagerSettingsTests

Change-Id: I99c57d5fd553bc98a350cb7cc1640c556dbb500f
parent e4d0a065
Loading
Loading
Loading
Loading
+62 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.pm;

import android.annotation.NonNull;

import java.io.File;

final class CleanUpArgs {
    @NonNull
    private final String mPackageName;
    @NonNull
    private final File mCodeFile;
    @NonNull
    private final String[] mInstructionSets;

    /**
     * Create args that describe an existing installed package. Typically used
     * when cleaning up old installs.
     */
    CleanUpArgs(@NonNull String packageName, @NonNull String codePath,
                @NonNull String[] instructionSets) {
        mPackageName = packageName;
        mCodeFile = new File(codePath);
        mInstructionSets = instructionSets;
    }

    @NonNull
    String getPackageName() {
        return mPackageName;
    }

    @NonNull
    File getCodeFile() {
        return mCodeFile;
    }

    @NonNull
    /** @see PackageSetting#getPath() */
    String getCodePath() {
        return mCodeFile.getAbsolutePath();
    }

    @NonNull
    String[] getInstructionSets() {
        return mInstructionSets;
    }
}
+3 −3
Original line number Diff line number Diff line
@@ -282,8 +282,8 @@ final class DeletePackageHelper {
        // other processes clean up before deleting resources.
        synchronized (mPm.mInstallLock) {
            if (info.mArgs != null) {
                mRemovePackageHelper.cleanUpResources(info.mArgs.mCodeFile,
                        info.mArgs.mInstructionSets);
                mRemovePackageHelper.cleanUpResources(info.mArgs.getPackageName(),
                        info.mArgs.getCodeFile(), info.mArgs.getInstructionSets());
            }

            boolean reEnableStub = false;
@@ -571,7 +571,7 @@ final class DeletePackageHelper {

        // Delete application code and resources only for parent packages
        if (deleteCodeAndResources) {
            outInfo.mArgs = new InstallArgs(
            outInfo.mArgs = new CleanUpArgs(ps.getName(),
                    ps.getPathString(), getAppDexInstructionSets(
                            ps.getPrimaryCpuAbiLegacy(), ps.getSecondaryCpuAbiLegacy()));
            if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.mArgs);
+0 −23
Original line number Diff line number Diff line
@@ -16,14 +16,9 @@

package com.android.server.pm;

import static android.app.AppOpsManager.MODE_DEFAULT;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.pm.DataLoaderType;
import android.content.pm.IPackageInstallObserver2;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
import android.content.pm.SigningDetails;
import android.os.UserHandle;
import android.util.ArrayMap;
@@ -102,22 +97,4 @@ final class InstallArgs {
        mPackageSource = packageSource;
        mApplicationEnabledSettingPersistent = applicationEnabledSettingPersistent;
    }

    /**
     * Create args that describe an existing installed package. Typically used
     * when cleaning up old installs, or used as a move source.
     */
    InstallArgs(String codePath, String[] instructionSets) {
        this(OriginInfo.fromNothing(), null, null, 0, 0, InstallSource.EMPTY, null, null,
                instructionSets, null, new ArrayMap<>(), null, MODE_DEFAULT, null, 0,
                SigningDetails.UNKNOWN, PackageManager.INSTALL_REASON_UNKNOWN,
                PackageManager.INSTALL_SCENARIO_DEFAULT, false, DataLoaderType.NONE,
                PackageInstaller.PACKAGE_SOURCE_UNSPECIFIED, false);
        mCodeFile = (codePath != null) ? new File(codePath) : null;
    }

    /** @see PackageSettingBase#getPath() */
    String getCodePath() {
        return (mCodeFile != null) ? mCodeFile.getAbsolutePath() : null;
    }
}
+9 −6
Original line number Diff line number Diff line
@@ -2111,7 +2111,8 @@ final class InstallPackageHelper {
                        // We didn't need to disable the .apk as a current system package,
                        // which means we are replacing another update that is already
                        // installed.  We need to make sure to delete the older one's .apk.
                        installRequest.getRemovedInfo().mArgs = new InstallArgs(
                        installRequest.getRemovedInfo().mArgs = new CleanUpArgs(
                                packageName,
                                oldPackage.getPath(),
                                getAppDexInstructionSets(
                                        deletedPkgSetting.getPrimaryCpuAbi(),
@@ -2820,7 +2821,7 @@ final class InstallPackageHelper {
            request.setReturnMessage("Package was removed before install could complete.");

            // Remove the update failed package's older resources safely now
            mRemovePackageHelper.cleanUpResources(request.getOldCodeFile(),
            mRemovePackageHelper.cleanUpResources(packageName, request.getOldCodeFile(),
                    request.getOldInstructionSet());
            mPm.notifyInstallObserver(request);
            return;
@@ -2872,7 +2873,7 @@ final class InstallPackageHelper {
                    getUnknownSourcesSettings());

            // Remove the replaced package's older resources safely now
            InstallArgs args = request.getRemovedInfo() != null
            CleanUpArgs args = request.getRemovedInfo() != null
                    ? request.getRemovedInfo().mArgs : null;
            if (args != null) {
                if (!killApp) {
@@ -2883,7 +2884,8 @@ final class InstallPackageHelper {
                    // propagated to all application threads.
                    mPm.scheduleDeferredNoKillPostDelete(args);
                } else {
                    mRemovePackageHelper.cleanUpResources(args.mCodeFile, args.mInstructionSets);
                    mRemovePackageHelper.cleanUpResources(packageName, args.getCodeFile(),
                            args.getInstructionSets());
                }
            } else {
                // Force a gc to clear up things. Ask for a background one, it's fine to go on
@@ -4040,7 +4042,7 @@ final class InstallPackageHelper {
                            + "; " + pkgSetting.getPathString()
                            + " --> " + parsedPackage.getPath());

            mRemovePackageHelper.cleanUpResources(
            mRemovePackageHelper.cleanUpResources(pkgSetting.getPackageName(),
                    new File(pkgSetting.getPathString()),
                    getAppDexInstructionSets(pkgSetting.getPrimaryCpuAbiLegacy(),
                            pkgSetting.getSecondaryCpuAbiLegacy()));
@@ -4146,7 +4148,8 @@ final class InstallPackageHelper {
                                + parsedPackage.getLongVersionCode()
                                + "; " + pkgSetting.getPathString() + " --> "
                                + parsedPackage.getPath());
                mRemovePackageHelper.cleanUpResources(new File(pkgSetting.getPathString()),
                mRemovePackageHelper.cleanUpResources(pkgSetting.getPackageName(),
                        new File(pkgSetting.getPathString()),
                        getAppDexInstructionSets(
                                pkgSetting.getPrimaryCpuAbiLegacy(), pkgSetting.getSecondaryCpuAbiLegacy()));
            } else {
+2 −2
Original line number Diff line number Diff line
@@ -294,13 +294,13 @@ final class InstallRequest {
    @Nullable
    public File getOldCodeFile() {
        return (mRemovedInfo != null && mRemovedInfo.mArgs != null)
                ? mRemovedInfo.mArgs.mCodeFile : null;
                ? mRemovedInfo.mArgs.getCodeFile() : null;
    }

    @Nullable
    public String[] getOldInstructionSet() {
        return (mRemovedInfo != null && mRemovedInfo.mArgs != null)
                ? mRemovedInfo.mArgs.mInstructionSets : null;
                ? mRemovedInfo.mArgs.getInstructionSets() : null;
    }

    public UserHandle getUser() {
Loading