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

Commit 190bee0e authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "[PM] Add downgrade check for split apps when data exists" into main

parents 8d673ddf 39952bb8
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -2261,6 +2261,12 @@ final class InstallPackageHelper {
                        installRequest.getNewUsers());
                mPm.updateSequenceNumberLP(ps, installRequest.getNewUsers());
                mPm.updateInstantAppInstallerLocked(packageName);

                // The installation is success, remove the split info copy stored in package
                // setting for the downgrade version check of DELETE_KEEP_DATA and archived app
                // cases.
                ps.setSplitNames(null);
                ps.setSplitRevisionCodes(null);
            }
            installRequest.onCommitFinished();
        }
+17 −13
Original line number Diff line number Diff line
@@ -1423,11 +1423,8 @@ public class PackageManagerServiceUtils {
     */
    public static void checkDowngrade(@NonNull PackageSetting before,
            @NonNull PackageInfoLite after) throws PackageManagerException {
        if (after.getLongVersionCode() < before.getVersionCode()) {
            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
                    "Update version code " + after.versionCode + " is older than current "
                            + before.getVersionCode());
        }
        checkDowngrade(before.getVersionCode(), before.getBaseRevisionCode(),
                before.getSplitNames(), before.getSplitRevisionCodes(), after);
    }

    /**
@@ -1436,28 +1433,35 @@ public class PackageManagerServiceUtils {
     */
    public static void checkDowngrade(@NonNull AndroidPackage before,
            @NonNull PackageInfoLite after) throws PackageManagerException {
        if (after.getLongVersionCode() < before.getLongVersionCode()) {
        checkDowngrade(before.getLongVersionCode(), before.getBaseRevisionCode(),
                before.getSplitNames(), before.getSplitRevisionCodes(), after);
    }

    private static void checkDowngrade(long beforeVersionCode, int beforeBaseRevisionCode,
            @NonNull String[] beforeSplitNames, @NonNull int[] beforeSplitRevisionCodes,
            @NonNull PackageInfoLite after) throws PackageManagerException {
        if (after.getLongVersionCode() < beforeVersionCode) {
            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
                    "Update version code " + after.versionCode + " is older than current "
                            + before.getLongVersionCode());
        } else if (after.getLongVersionCode() == before.getLongVersionCode()) {
            if (after.baseRevisionCode < before.getBaseRevisionCode()) {
                            + beforeVersionCode);
        } else if (after.getLongVersionCode() == beforeVersionCode) {
            if (after.baseRevisionCode < beforeBaseRevisionCode) {
                throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
                        "Update base revision code " + after.baseRevisionCode
                                + " is older than current " + before.getBaseRevisionCode());
                                + " is older than current " + beforeBaseRevisionCode);
            }

            if (!ArrayUtils.isEmpty(after.splitNames)) {
                for (int i = 0; i < after.splitNames.length; i++) {
                    final String splitName = after.splitNames[i];
                    final int j = ArrayUtils.indexOf(before.getSplitNames(), splitName);
                    final int j = ArrayUtils.indexOf(beforeSplitNames, splitName);
                    if (j != -1) {
                        if (after.splitRevisionCodes[i] < before.getSplitRevisionCodes()[j]) {
                        if (after.splitRevisionCodes[i] < beforeSplitRevisionCodes[j]) {
                            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
                                    "Update split " + splitName + " revision code "
                                            + after.splitRevisionCodes[i]
                                            + " is older than current "
                                            + before.getSplitRevisionCodes()[j]);
                                            + beforeSplitRevisionCodes[j]);
                        }
                    }
                }
+77 −0
Original line number Diff line number Diff line
@@ -234,6 +234,22 @@ public class PackageSetting extends SettingBase implements PackageStateInternal
    @Nullable
    private byte[] mRestrictUpdateHash;

    // This is the copy of the same data stored in AndroidPackage. It is not null if the
    // AndroidPackage is deleted in cases of DELETE_KEEP_DATA. When AndroidPackage is not null,
    // the field will be null, and the getter method will return the data from AndroidPackage
    // instead.
    @Nullable
    private String[] mSplitNames;

    // This is the copy of the same data stored in AndroidPackage. It is not null if the
    // AndroidPackage is deleted in cases of DELETE_KEEP_DATA. When AndroidPackage is not null,
    // the field will be null, and the getter method will return the data from AndroidPackage
    // instead.
    @Nullable
    private int[] mSplitRevisionCodes;

    private int mBaseRevisionCode;

    /**
     * Snapshot support.
     */
@@ -578,6 +594,62 @@ public class PackageSetting extends SettingBase implements PackageStateInternal
        return getBoolean(Booleans.DEBUGGABLE);
    }

    /**
     * @see AndroidPackage#getBaseRevisionCode
     */
    public PackageSetting setBaseRevisionCode(int value) {
        mBaseRevisionCode = value;
        onChanged();
        return this;
    }

    /**
     * @see AndroidPackage#getBaseRevisionCode
     */
    public int getBaseRevisionCode() {
        return mBaseRevisionCode;
    }

    /**
     * @see AndroidPackage#getSplitNames
     */
    public PackageSetting setSplitNames(String[] value) {
        mSplitNames = value;
        onChanged();
        return this;
    }

    /**
     * @see AndroidPackage#getSplitNames
     */
    @NonNull
    public String[] getSplitNames() {
        if (pkg != null) {
            return pkg.getSplitNames();
        }
        return mSplitNames == null ? EmptyArray.STRING : mSplitNames;
    }

    /**
     * @see AndroidPackage#getSplitRevisionCodes
     */
    public PackageSetting setSplitRevisionCodes(int[] value) {
        mSplitRevisionCodes = value;
        onChanged();
        return this;
    }

    /**
     * @see AndroidPackage#getSplitRevisionCodes
     */
    @NonNull
    public int[] getSplitRevisionCodes() {
        if (pkg != null) {
            return pkg.getSplitRevisionCodes();
        }
        return mSplitRevisionCodes == null ? EmptyArray.INT : mSplitRevisionCodes;
    }

    @Override
    public String toString() {
        return "PackageSetting{"
@@ -739,6 +811,11 @@ public class PackageSetting extends SettingBase implements PackageStateInternal
        mTargetSdkVersion = other.mTargetSdkVersion;
        mRestrictUpdateHash = other.mRestrictUpdateHash == null
                ? null : other.mRestrictUpdateHash.clone();
        mBaseRevisionCode = other.mBaseRevisionCode;
        mSplitNames = other.mSplitNames != null
                ? Arrays.copyOf(other.mSplitNames, other.mSplitNames.length) : null;
        mSplitRevisionCodes = other.mSplitRevisionCodes != null
                ? Arrays.copyOf(other.mSplitRevisionCodes, other.mSplitRevisionCodes.length) : null;

        usesSdkLibraries = other.usesSdkLibraries != null
                ? Arrays.copyOf(other.usesSdkLibraries,
+7 −0
Original line number Diff line number Diff line
@@ -432,6 +432,13 @@ final class RemovePackageHelper {
                }
                deletedPs.setInstalled(/* installed= */ false, userId);
            }

            // Preserve split apk information for downgrade check with DELETE_KEEP_DATA and archived
            // app cases
            if (deletedPkg.getSplitNames() != null) {
                deletedPs.setSplitNames(deletedPkg.getSplitNames());
                deletedPs.setSplitRevisionCodes(deletedPkg.getSplitRevisionCodes());
            }
        }

        // make sure to preserve per-user installed state if this removal was just
+2 −1
Original line number Diff line number Diff line
@@ -437,8 +437,9 @@ final class ScanPackageUtils {
            pkgSetting.setIsOrphaned(true);
        }

        // update debuggable to packageSetting
        // update debuggable and BaseRevisionCode to packageSetting
        pkgSetting.setDebuggable(parsedPackage.isDebuggable());
        pkgSetting.setBaseRevisionCode(parsedPackage.getBaseRevisionCode());

        // Take care of first install / last update times.
        final long scanFileTime = getLastModifiedTime(parsedPackage);
Loading