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

Commit 903e3bbc authored by Rhed Jao's avatar Rhed Jao Committed by Android (Google) Code Review
Browse files

Merge "Fix PackageManager did not recognize OTA when only upgrade product"

parents ffeaf39a d150569b
Loading
Loading
Loading
Loading
+56 −8
Original line number Diff line number Diff line
@@ -19,8 +19,11 @@ package android.content.pm;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Build;
import android.os.Build.Partition;
import android.os.Environment;
import android.os.FileUtils;
import android.os.SystemProperties;

import com.android.internal.annotations.VisibleForTesting;

@@ -64,19 +67,33 @@ public class PackagePartitions {
     */
    private static final ArrayList<SystemPartition> SYSTEM_PARTITIONS =
            new ArrayList<>(Arrays.asList(
                    new SystemPartition(Environment.getRootDirectory(), PARTITION_SYSTEM,
                    new SystemPartition(Environment.getRootDirectory(),
                            PARTITION_SYSTEM, Partition.PARTITION_NAME_SYSTEM,
                            true /* containsPrivApp */, false /* containsOverlay */),
                    new SystemPartition(Environment.getVendorDirectory(), PARTITION_VENDOR,
                    new SystemPartition(Environment.getVendorDirectory(),
                            PARTITION_VENDOR, Partition.PARTITION_NAME_VENDOR,
                            true /* containsPrivApp */, true /* containsOverlay */),
                    new SystemPartition(Environment.getOdmDirectory(), PARTITION_ODM,
                    new SystemPartition(Environment.getOdmDirectory(),
                            PARTITION_ODM, Partition.PARTITION_NAME_ODM,
                            true /* containsPrivApp */, true /* containsOverlay */),
                    new SystemPartition(Environment.getOemDirectory(), PARTITION_OEM,
                    new SystemPartition(Environment.getOemDirectory(),
                            PARTITION_OEM, Partition.PARTITION_NAME_OEM,
                            false /* containsPrivApp */, true /* containsOverlay */),
                    new SystemPartition(Environment.getProductDirectory(), PARTITION_PRODUCT,
                    new SystemPartition(Environment.getProductDirectory(),
                            PARTITION_PRODUCT, Partition.PARTITION_NAME_PRODUCT,
                            true /* containsPrivApp */, true /* containsOverlay */),
                    new SystemPartition(Environment.getSystemExtDirectory(), PARTITION_SYSTEM_EXT,
                    new SystemPartition(Environment.getSystemExtDirectory(),
                            PARTITION_SYSTEM_EXT, Partition.PARTITION_NAME_SYSTEM_EXT,
                            true /* containsPrivApp */, true /* containsOverlay */)));

    /**
     * A string to represent the fingerprint of this build and all package partitions. Using it to
     * determine whether the system update has occurred. Different from {@link Build#FINGERPRINT},
     * this string is digested from the fingerprints of the build and all package partitions to
     * help detect the partition update.
     */
    public static final String FINGERPRINT = getFingerprint();

    /**
     * Returns a list in which the elements are products of the specified function applied to the
     * list of {@link #SYSTEM_PARTITIONS} in increasing specificity order.
@@ -101,12 +118,32 @@ public class PackagePartitions {
        }
    }

    /**
     * Returns a fingerprint string for this build and all package partitions. The string is
     * digested from the fingerprints of the build and all package partitions.
     *
     * @return A string to represent the fingerprint of this build and all package partitions.
     */
    @NonNull
    private static String getFingerprint() {
        final String[] digestProperties = new String[SYSTEM_PARTITIONS.size() + 1];
        for (int i = 0; i < SYSTEM_PARTITIONS.size(); i++) {
            final String partitionName = SYSTEM_PARTITIONS.get(i).getName();
            digestProperties[i] = "ro." + partitionName + ".build.fingerprint";
        }
        digestProperties[SYSTEM_PARTITIONS.size()] = "ro.build.fingerprint"; // build fingerprint
        return SystemProperties.digestOf(digestProperties);
    }

    /** Represents a partition that contains application packages. */
    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
    public static class SystemPartition {
        @PartitionType
        public final int type;

        @NonNull
        private final String mName;

        @NonNull
        private final DeferredCanonicalFile mFolder;

@@ -122,9 +159,10 @@ public class PackagePartitions {
        @NonNull
        private final File mNonConicalFolder;

        private SystemPartition(@NonNull File folder, @PartitionType int type,
        private SystemPartition(@NonNull File folder, @PartitionType int type, String name,
                boolean containsPrivApp, boolean containsOverlay) {
            this.type = type;
            this.mName = name;
            this.mFolder = new DeferredCanonicalFile(folder);
            this.mAppFolder = new DeferredCanonicalFile(folder, "app");
            this.mPrivAppFolder = containsPrivApp ? new DeferredCanonicalFile(folder, "priv-app")
@@ -136,6 +174,7 @@ public class PackagePartitions {

        public SystemPartition(@NonNull SystemPartition original) {
            this.type = original.type;
            this.mName = original.mName;
            this.mFolder = new DeferredCanonicalFile(original.mFolder.getFile());
            this.mAppFolder = original.mAppFolder;
            this.mPrivAppFolder = original.mPrivAppFolder;
@@ -148,10 +187,19 @@ public class PackagePartitions {
         * different root folder.
         */
        public SystemPartition(@NonNull File rootFolder, @NonNull SystemPartition partition) {
            this(rootFolder, partition.type, partition.mPrivAppFolder != null,
            this(rootFolder, partition.type, partition.mName, partition.mPrivAppFolder != null,
                    partition.mOverlayFolder != null);
        }

        /**
         * Returns the name identifying the partition.
         * @see Partition
         */
        @NonNull
        public String getName() {
            return mName;
        }

        /** Returns the canonical folder of the partition. */
        @NonNull
        public File getFolder() {
+18 −2
Original line number Diff line number Diff line
@@ -1294,6 +1294,18 @@ public class Build {
    public static class Partition {
        /** The name identifying the system partition. */
        public static final String PARTITION_NAME_SYSTEM = "system";
        /** @hide */
        public static final String PARTITION_NAME_BOOTIMAGE = "bootimage";
        /** @hide */
        public static final String PARTITION_NAME_ODM = "odm";
        /** @hide */
        public static final String PARTITION_NAME_OEM = "oem";
        /** @hide */
        public static final String PARTITION_NAME_PRODUCT = "product";
        /** @hide */
        public static final String PARTITION_NAME_SYSTEM_EXT = "system_ext";
        /** @hide */
        public static final String PARTITION_NAME_VENDOR = "vendor";

        private final String mName;
        private final String mFingerprint;
@@ -1350,8 +1362,12 @@ public class Build {
        ArrayList<Partition> partitions = new ArrayList();

        String[] names = new String[] {
            "bootimage", "odm", "product", "system_ext", Partition.PARTITION_NAME_SYSTEM,
            "vendor"
                Partition.PARTITION_NAME_BOOTIMAGE,
                Partition.PARTITION_NAME_ODM,
                Partition.PARTITION_NAME_PRODUCT,
                Partition.PARTITION_NAME_SYSTEM_EXT,
                Partition.PARTITION_NAME_SYSTEM,
                Partition.PARTITION_NAME_VENDOR
        };
        for (String name : names) {
            String fingerprint = SystemProperties.get("ro." + name + ".build.fingerprint");
+49 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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 android.content.pm;

import static com.google.common.truth.Truth.assertThat;

import static java.util.function.Function.identity;

import android.content.pm.PackagePartitions.SystemPartition;
import android.os.SystemProperties;

import androidx.test.runner.AndroidJUnit4;

import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.ArrayList;

@RunWith(AndroidJUnit4.class)
public class PackagePartitionsTest {

    @Test
    public void testPackagePartitionsFingerprint() {
        final ArrayList<SystemPartition> partitions = PackagePartitions.getOrderedPartitions(
                identity());
        final String[] properties = new String[partitions.size() + 1];
        for (int i = 0; i < partitions.size(); i++) {
            final String name = partitions.get(i).getName();
            properties[i] = "ro." + name + ".build.fingerprint";
        }
        properties[partitions.size()] = "ro.build.fingerprint";

        assertThat(SystemProperties.digestOf(properties)).isEqualTo(PackagePartitions.FINGERPRINT);
    }
}
+2 −2
Original line number Diff line number Diff line
@@ -67,10 +67,10 @@ import android.content.Intent;
import android.content.PermissionChecker;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.content.pm.PackagePartitions;
import android.content.pm.UserInfo;
import android.os.BatteryStats;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.Debug;
import android.os.Handler;
@@ -719,7 +719,7 @@ class UserController implements Handler.Callback {
        // purposefully block sending BOOT_COMPLETED until after all
        // PRE_BOOT receivers are finished to avoid ANR'ing apps
        final UserInfo info = getUserInfo(userId);
        if (!Objects.equals(info.lastLoggedInFingerprint, Build.FINGERPRINT)
        if (!Objects.equals(info.lastLoggedInFingerprint, PackagePartitions.FINGERPRINT)
                || SystemProperties.getBoolean("persist.pm.mock-upgrade", false)) {
            // Suppress double notifications for managed profiles that
            // were unlocked automatically as part of their parent user
+7 −6
Original line number Diff line number Diff line
@@ -1493,8 +1493,8 @@ public class PackageManagerService extends IPackageManager.Stub
        }

        PackageManagerService m = new PackageManagerService(injector, onlyCore, factoryTest,
                Build.FINGERPRINT, Build.IS_ENG, Build.IS_USERDEBUG, Build.VERSION.SDK_INT,
                Build.VERSION.INCREMENTAL, SNAPSHOT_ENABLED);
                PackagePartitions.FINGERPRINT, Build.IS_ENG, Build.IS_USERDEBUG,
                Build.VERSION.SDK_INT, Build.VERSION.INCREMENTAL, SNAPSHOT_ENABLED);
        t.traceEnd(); // "create package manager"

        final CompatChange.ChangeListener selinuxChangeListener = packageName -> {
@@ -1907,8 +1907,8 @@ public class PackageManagerService extends IPackageManager.Stub
            mIsUpgrade =
                    !buildFingerprint.equals(ver.fingerprint);
            if (mIsUpgrade) {
                PackageManagerServiceUtils.logCriticalInfo(Log.INFO,
                        "Upgrading from " + ver.fingerprint + " to " + Build.FINGERPRINT);
                PackageManagerServiceUtils.logCriticalInfo(Log.INFO, "Upgrading from "
                        + ver.fingerprint + " to " + PackagePartitions.FINGERPRINT);
            }

            // when upgrading from pre-M, promote system app permissions from install to runtime
@@ -2006,7 +2006,8 @@ public class PackageManagerService extends IPackageManager.Stub
            // this situation.
            if (mIsUpgrade) {
                Slog.i(TAG, "Build fingerprint changed from " + ver.fingerprint + " to "
                        + Build.FINGERPRINT + "; regranting permissions for internal storage");
                        + PackagePartitions.FINGERPRINT
                        + "; regranting permissions for internal storage");
            }
            mPermissionManager.onStorageVolumeMounted(
                    StorageManager.UUID_PRIVATE_INTERNAL, mIsUpgrade);
@@ -2040,7 +2041,7 @@ public class PackageManagerService extends IPackageManager.Stub
                                        | Installer.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES);
                    }
                }
                ver.fingerprint = Build.FINGERPRINT;
                ver.fingerprint = PackagePartitions.FINGERPRINT;
            }

            // Legacy existing (installed before Q) non-system apps to hide
Loading