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

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

Merge "Introduce a new APK attribute: updatableSystem, default true." into main

parents 1fba603b ab59af61
Loading
Loading
Loading
Loading
+18 −3
Original line number Diff line number Diff line
@@ -139,6 +139,11 @@ public class ApkLite {
     */
    private final boolean mIsSdkLibrary;

    /**
     * Indicates if this system app can be updated.
     */
    private final boolean mUpdatableSystem;

    /**
     * Archival install info.
     */
@@ -154,7 +159,7 @@ public class ApkLite {
            String requiredSystemPropertyName, String requiredSystemPropertyValue,
            int minSdkVersion, int targetSdkVersion, int rollbackDataPolicy,
            Set<String> requiredSplitTypes, Set<String> splitTypes,
            boolean hasDeviceAdminReceiver, boolean isSdkLibrary) {
            boolean hasDeviceAdminReceiver, boolean isSdkLibrary, boolean updatableSystem) {
        mPath = path;
        mPackageName = packageName;
        mSplitName = splitName;
@@ -188,6 +193,7 @@ public class ApkLite {
        mRollbackDataPolicy = rollbackDataPolicy;
        mHasDeviceAdminReceiver = hasDeviceAdminReceiver;
        mIsSdkLibrary = isSdkLibrary;
        mUpdatableSystem = updatableSystem;
        mArchivedPackage = null;
    }

@@ -225,6 +231,7 @@ public class ApkLite {
        mRollbackDataPolicy = 0;
        mHasDeviceAdminReceiver = false;
        mIsSdkLibrary = false;
        mUpdatableSystem = true;
        mArchivedPackage = archivedPackage;
    }

@@ -534,6 +541,14 @@ public class ApkLite {
        return mIsSdkLibrary;
    }

    /**
     * Indicates if this system app can be updated.
     */
    @DataClass.Generated.Member
    public boolean isUpdatableSystem() {
        return mUpdatableSystem;
    }

    /**
     * Archival install info.
     */
@@ -543,10 +558,10 @@ public class ApkLite {
    }

    @DataClass.Generated(
            time = 1694792109463L,
            time = 1699587291575L,
            codegenVersion = "1.0.23",
            sourceFile = "frameworks/base/core/java/android/content/pm/parsing/ApkLite.java",
            inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.Nullable java.lang.String mSplitName\nprivate final @android.annotation.Nullable java.lang.String mUsesSplitName\nprivate final @android.annotation.Nullable java.lang.String mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mSplitTypes\nprivate final  int mVersionCodeMajor\nprivate final  int mVersionCode\nprivate final  int mRevisionCode\nprivate final  int mInstallLocation\nprivate final  int mMinSdkVersion\nprivate final  int mTargetSdkVersion\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.NonNull android.content.pm.SigningDetails mSigningDetails\nprivate final  boolean mFeatureSplit\nprivate final  boolean mIsolatedSplits\nprivate final  boolean mSplitRequired\nprivate final  boolean mCoreApp\nprivate final  boolean mDebuggable\nprivate final  boolean mProfileableByShell\nprivate final  boolean mMultiArch\nprivate final  boolean mUse32bitAbi\nprivate final  boolean mExtractNativeLibs\nprivate final  boolean mUseEmbeddedDex\nprivate final @android.annotation.Nullable java.lang.String mTargetPackageName\nprivate final  boolean mOverlayIsStatic\nprivate final  int mOverlayPriority\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyName\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyValue\nprivate final  int mRollbackDataPolicy\nprivate final  boolean mHasDeviceAdminReceiver\nprivate final  boolean mIsSdkLibrary\nprivate final @android.annotation.Nullable android.content.pm.ArchivedPackageParcel mArchivedPackage\npublic  long getLongVersionCode()\nprivate  boolean hasAnyRequiredSplitTypes()\nclass ApkLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)")
            inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.Nullable java.lang.String mSplitName\nprivate final @android.annotation.Nullable java.lang.String mUsesSplitName\nprivate final @android.annotation.Nullable java.lang.String mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mSplitTypes\nprivate final  int mVersionCodeMajor\nprivate final  int mVersionCode\nprivate final  int mRevisionCode\nprivate final  int mInstallLocation\nprivate final  int mMinSdkVersion\nprivate final  int mTargetSdkVersion\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.NonNull android.content.pm.SigningDetails mSigningDetails\nprivate final  boolean mFeatureSplit\nprivate final  boolean mIsolatedSplits\nprivate final  boolean mSplitRequired\nprivate final  boolean mCoreApp\nprivate final  boolean mDebuggable\nprivate final  boolean mProfileableByShell\nprivate final  boolean mMultiArch\nprivate final  boolean mUse32bitAbi\nprivate final  boolean mExtractNativeLibs\nprivate final  boolean mUseEmbeddedDex\nprivate final @android.annotation.Nullable java.lang.String mTargetPackageName\nprivate final  boolean mOverlayIsStatic\nprivate final  int mOverlayPriority\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyName\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyValue\nprivate final  int mRollbackDataPolicy\nprivate final  boolean mHasDeviceAdminReceiver\nprivate final  boolean mIsSdkLibrary\nprivate final  boolean mUpdatableSystem\nprivate final @android.annotation.Nullable android.content.pm.ArchivedPackageParcel mArchivedPackage\npublic  long getLongVersionCode()\nprivate  boolean hasAnyRequiredSplitTypes()\nclass ApkLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)")
    @Deprecated
    private void __metadata() {}

+14 −9
Original line number Diff line number Diff line
@@ -424,6 +424,7 @@ public class ApkLiteParseUtils {
                0);
        int revisionCode = parser.getAttributeIntValue(ANDROID_RES_NAMESPACE, "revisionCode", 0);
        boolean coreApp = parser.getAttributeBooleanValue(null, "coreApp", false);
        boolean updatableSystem = parser.getAttributeBooleanValue(null, "updatableSystem", true);
        boolean isolatedSplits = parser.getAttributeBooleanValue(ANDROID_RES_NAMESPACE,
                "isolatedSplits", false);
        boolean isFeatureSplit = parser.getAttributeBooleanValue(ANDROID_RES_NAMESPACE,
@@ -505,14 +506,18 @@ public class ApkLiteParseUtils {
                        continue;
                    }

                    if (TAG_PROFILEABLE.equals(parser.getName())) {
                        profilableByShell = parser.getAttributeBooleanValue(ANDROID_RES_NAMESPACE,
                                "shell", profilableByShell);
                    } else if (TAG_RECEIVER.equals(parser.getName())) {
                        hasDeviceAdminReceiver |= isDeviceAdminReceiver(
                                parser, hasBindDeviceAdminPermission);
                    } else if (TAG_SDK_LIBRARY.equals(parser.getName())) {
                    switch (parser.getName()) {
                        case TAG_PROFILEABLE:
                            profilableByShell = parser.getAttributeBooleanValue(
                                    ANDROID_RES_NAMESPACE, "shell", profilableByShell);
                            break;
                        case TAG_RECEIVER:
                            hasDeviceAdminReceiver |= isDeviceAdminReceiver(parser,
                                    hasBindDeviceAdminPermission);
                            break;
                        case TAG_SDK_LIBRARY:
                            isSdkLibrary = true;
                            break;
                    }
                }
            } else if (TAG_OVERLAY.equals(parser.getName())) {
@@ -614,7 +619,7 @@ public class ApkLiteParseUtils {
                        overlayIsStatic, overlayPriority, requiredSystemPropertyName,
                        requiredSystemPropertyValue, minSdkVersion, targetSdkVersion,
                        rollbackDataPolicy, requiredSplitTypes.first, requiredSplitTypes.second,
                        hasDeviceAdminReceiver, isSdkLibrary));
                        hasDeviceAdminReceiver, isSdkLibrary, updatableSystem));
    }

    private static boolean isDeviceAdminReceiver(
+6 −0
Original line number Diff line number Diff line
@@ -1592,6 +1592,12 @@
    <!-- Whether attributions provided are meant to be user-visible. -->
    <attr name="attributionsAreUserVisible" format="boolean" />

    <!-- If a preloaded APK is marked updatableSystem = false, any request for an update will be rejected.
         If an APK marked updatableSystem = false is being installed, regardless of the updatableSystem state
         of the version it's replacing, the install will be rejected.
         This is a private attribute, used without android: namespace. -->
    <attr name="updatableSystem" format="boolean" />

    <!-- Specify the type of foreground service. Multiple types can be specified by ORing the flags
         together. -->
    <attr name="foregroundServiceType">
+1 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.android.shell"
        coreApp="true"
        updatableSystem="false"
        android:sharedUserId="android.uid.shell"
        >

+41 −14
Original line number Diff line number Diff line
@@ -2248,31 +2248,39 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
                == PackageManager.PERMISSION_GRANTED;
    }

    private boolean isInstallationAllowed(PackageStateInternal psi) {
        if (psi == null || psi.getPkg() == null) {
            return true;
        }
        if (psi.getPkg().isUpdatableSystem()) {
            return true;
        }
        if (mOriginalInstallerUid == Process.ROOT_UID) {
            Slog.w(TAG, "Overriding updatableSystem because the installer is root: "
                    + psi.getPackageName());
            return true;
        }
        return false;
    }

    /**
     * Check if this package can be installed archived.
     */
    private static boolean isArchivedInstallationAllowed(String packageName) {
        final PackageManagerInternal pmi = LocalServices.getService(PackageManagerInternal.class);
        final PackageStateInternal existingPkgSetting = pmi.getPackageStateInternal(packageName);
        if (existingPkgSetting == null) {
    private static boolean isArchivedInstallationAllowed(PackageStateInternal psi) {
        if (psi == null) {
            return true;
        }

        return false;
    }

    /**
     * Checks if the package can be installed on IncFs.
     */
    private static boolean isIncrementalInstallationAllowed(String packageName) {
        final PackageManagerInternal pmi = LocalServices.getService(PackageManagerInternal.class);
        final PackageStateInternal existingPkgSetting = pmi.getPackageStateInternal(packageName);
        if (existingPkgSetting == null || existingPkgSetting.getPkg() == null) {
    private static boolean isIncrementalInstallationAllowed(PackageStateInternal psi) {
        if (psi == null || psi.getPkg() == null) {
            return true;
        }

        return !existingPkgSetting.isSystem()
                && !existingPkgSetting.isUpdatedSystemApp();
        return !psi.isSystem() && !psi.isUpdatedSystemApp();
    }

    /**
@@ -3371,6 +3379,16 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
                        "Split " + apk.getSplitName() + " was defined multiple times");
            }

            if (!apk.isUpdatableSystem()) {
                if (mOriginalInstallerUid == Process.ROOT_UID) {
                    Slog.w(TAG, "Overriding updatableSystem because the installer is root for: "
                            + apk.getPackageName());
                } else {
                    throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
                            "Non updatable system package can't be installed or updated");
                }
            }

            // Use first package to define unknown values
            if (mPackageName == null) {
                mPackageName = apk.getPackageName();
@@ -3445,8 +3463,17 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
            }
        }

        final PackageManagerInternal pmi = LocalServices.getService(PackageManagerInternal.class);
        final PackageStateInternal existingPkgSetting = pmi.getPackageStateInternal(mPackageName);

        if (!isInstallationAllowed(existingPkgSetting)) {
            throw new PackageManagerException(
                    PackageManager.INSTALL_FAILED_SESSION_INVALID,
                    "Installation of this package is not allowed.");
        }

        if (isArchivedInstallation()) {
            if (!isArchivedInstallationAllowed(mPackageName)) {
            if (!isArchivedInstallationAllowed(existingPkgSetting)) {
                throw new PackageManagerException(
                        PackageManager.INSTALL_FAILED_SESSION_INVALID,
                        "Archived installation of this package is not allowed.");
@@ -3462,7 +3489,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
        }

        if (isIncrementalInstallation()) {
            if (!isIncrementalInstallationAllowed(mPackageName)) {
            if (!isIncrementalInstallationAllowed(existingPkgSetting)) {
                throw new PackageManagerException(
                        PackageManager.INSTALL_FAILED_SESSION_INVALID,
                        "Incremental installation of this package is not allowed.");
Loading