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

Commit 232d29e0 authored by Todd Kennedy's avatar Todd Kennedy
Browse files

Make sense out of scan & parse flags

Parse flags are often used confusingly to control policy during
APK parsing. Additionally, some flags [such as PARSE_IS_PRIVILEGED
or PARSE_IS_SYSTEM] aren't always determined based upon APK location
[they change based upon which apps are installed]. This means we
have to perform some gymnastics to set them correctly _before_
parsing a package.

Instead, these should be scan flags that can be determined at a
later point during package parsing. Then, based upon the scan flag
we apply policy on the package object to create the resulting
data structures.

Bug: 63539144
Bug: 69663125
Test: Manual; it builds, runs and applications can be installed / removed
Test: bit FrameworksServicesTests:com.android.server.pm.
Change-Id: I53fb18e58544e0a39f35eb6fb53c950e5c696aee
parent d7f98747
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -1322,6 +1322,7 @@ public abstract class PackageManager {
            DELETE_ALL_USERS,
            DELETE_SYSTEM_APP,
            DELETE_DONT_KILL_APP,
            DELETE_CHATTY,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface DeleteFlags {}
@@ -1362,6 +1363,14 @@ public abstract class PackageManager {
     */
    public static final int DELETE_DONT_KILL_APP = 0x00000008;

    /**
     * Flag parameter for {@link #deletePackage} to indicate that package deletion
     * should be chatty.
     *
     * @hide
     */
    public static final int DELETE_CHATTY = 0x80000000;

    /**
     * Return code for when package deletion succeeds. This is passed to the
     * {@link IPackageDeleteObserver} if the system succeeded in deleting the
+41 −53
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ import static android.os.Build.VERSION_CODES.O;
import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_UNSPECIFIED;

import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -107,6 +108,8 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Constructor;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
@@ -816,22 +819,33 @@ public class PackageParser {
        }
    }

    public static final int PARSE_IS_SYSTEM = 1 << 0;
    public static final int PARSE_CHATTY = 1 << 1;
    public static final int PARSE_MUST_BE_APK = 1 << 2;
    public static final int PARSE_IGNORE_PROCESSES = 1 << 3;
    public static final int PARSE_FORWARD_LOCK = 1 << 4;
    public static final int PARSE_EXTERNAL_STORAGE = 1 << 5;
    public static final int PARSE_IS_SYSTEM_DIR = 1 << 6;
    public static final int PARSE_IS_PRIVILEGED = 1 << 7;
    public static final int PARSE_COLLECT_CERTIFICATES = 1 << 8;
    public static final int PARSE_TRUSTED_OVERLAY = 1 << 9;
    public static final int PARSE_ENFORCE_CODE = 1 << 10;
    /** @deprecated remove when fixing b/34761192 */
    public static final int PARSE_MUST_BE_APK = 1 << 0;
    public static final int PARSE_IGNORE_PROCESSES = 1 << 1;
    public static final int PARSE_FORWARD_LOCK = 1 << 2;
    public static final int PARSE_EXTERNAL_STORAGE = 1 << 3;
    public static final int PARSE_IS_SYSTEM_DIR = 1 << 4;
    public static final int PARSE_COLLECT_CERTIFICATES = 1 << 5;
    public static final int PARSE_ENFORCE_CODE = 1 << 6;
    public static final int PARSE_FORCE_SDK = 1 << 7;
    /** @deprecated remove when fixing b/68860689 */
    @Deprecated
    public static final int PARSE_IS_EPHEMERAL = 1 << 11;
    public static final int PARSE_FORCE_SDK = 1 << 12;
    public static final int PARSE_IS_OEM = 1 << 13;
    public static final int PARSE_IS_EPHEMERAL = 1 << 8;
    public static final int PARSE_CHATTY = 1 << 31;

    @IntDef(flag = true, prefix = { "PARSE_" }, value = {
            PARSE_CHATTY,
            PARSE_COLLECT_CERTIFICATES,
            PARSE_ENFORCE_CODE,
            PARSE_EXTERNAL_STORAGE,
            PARSE_FORCE_SDK,
            PARSE_FORWARD_LOCK,
            PARSE_IGNORE_PROCESSES,
            PARSE_IS_EPHEMERAL,
            PARSE_IS_SYSTEM_DIR,
            PARSE_MUST_BE_APK,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface ParseFlags {}

    private static final Comparator<String> sSplitNameComparator = new SplitNameComparator();

@@ -1505,7 +1519,7 @@ public class PackageParser {
     * populating {@link Package#mSignatures}. Also asserts that all APK
     * contents are signed correctly and consistently.
     */
    public static void collectCertificates(Package pkg, int parseFlags)
    public static void collectCertificates(Package pkg, @ParseFlags int parseFlags)
            throws PackageParserException {
        collectCertificatesInternal(pkg, parseFlags);
        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
@@ -1517,7 +1531,7 @@ public class PackageParser {
        }
    }

    private static void collectCertificatesInternal(Package pkg, int parseFlags)
    private static void collectCertificatesInternal(Package pkg, @ParseFlags int parseFlags)
            throws PackageParserException {
        pkg.mCertificates = null;
        pkg.mSignatures = null;
@@ -1537,7 +1551,7 @@ public class PackageParser {
        }
    }

    private static void collectCertificates(Package pkg, File apkFile, int parseFlags)
    private static void collectCertificates(Package pkg, File apkFile, @ParseFlags int parseFlags)
            throws PackageParserException {
        final String apkPath = apkFile.getAbsolutePath();

@@ -2442,7 +2456,7 @@ public class PackageParser {

                sa.recycle();

                if (name != null && (flags&PARSE_IS_SYSTEM) != 0) {
                if (name != null) {
                    if (pkg.protectedBroadcasts == null) {
                        pkg.protectedBroadcasts = new ArrayList<String>();
                    }
@@ -3243,9 +3257,6 @@ public class PackageParser {
                com.android.internal.R.styleable.AndroidManifestPermissionGroup_permissionGroupFlags, 0);
        perm.info.priority = sa.getInt(
                com.android.internal.R.styleable.AndroidManifestPermissionGroup_priority, 0);
        if (perm.info.priority > 0 && (flags&PARSE_IS_SYSTEM) == 0) {
            perm.info.priority = 0;
        }

        sa.recycle();

@@ -3551,19 +3562,16 @@ public class PackageParser {
        ai.descriptionRes = sa.getResourceId(
                com.android.internal.R.styleable.AndroidManifestApplication_description, 0);

        if ((flags&PARSE_IS_SYSTEM) != 0) {
        if (sa.getBoolean(
                com.android.internal.R.styleable.AndroidManifestApplication_persistent,
                false)) {
            // Check if persistence is based on a feature being present
                final String requiredFeature = sa.getNonResourceString(
                    com.android.internal.R.styleable.
                    AndroidManifestApplication_persistentWhenFeatureAvailable);
            final String requiredFeature = sa.getNonResourceString(com.android.internal.R.styleable
                    .AndroidManifestApplication_persistentWhenFeatureAvailable);
            if (requiredFeature == null || mCallback.hasFeature(requiredFeature)) {
                ai.flags |= ApplicationInfo.FLAG_PERSISTENT;
            }
        }
        }

        if (sa.getBoolean(
                com.android.internal.R.styleable.AndroidManifestApplication_requiredForAllUsers,
@@ -4431,13 +4439,6 @@ public class PackageParser {

            if (sa.getBoolean(R.styleable.AndroidManifestActivity_singleUser, false)) {
                a.info.flags |= ActivityInfo.FLAG_SINGLE_USER;
                if (a.info.exported && (flags & PARSE_IS_PRIVILEGED) == 0) {
                    Slog.w(TAG, "Activity exported request ignored due to singleUser: "
                            + a.className + " at " + mArchiveSourcePath + " "
                            + parser.getPositionDescription());
                    a.info.exported = false;
                    setExported = true;
                }
            }

            a.info.encryptionAware = a.info.directBootAware = sa.getBoolean(
@@ -5026,12 +5027,6 @@ public class PackageParser {
                com.android.internal.R.styleable.AndroidManifestProvider_singleUser,
                false)) {
            p.info.flags |= ProviderInfo.FLAG_SINGLE_USER;
            if (p.info.exported && (flags & PARSE_IS_PRIVILEGED) == 0) {
                Slog.w(TAG, "Provider exported request ignored due to singleUser: "
                        + p.className + " at " + mArchiveSourcePath + " "
                        + parser.getPositionDescription());
                p.info.exported = false;
            }
        }

        p.info.encryptionAware = p.info.directBootAware = sa.getBoolean(
@@ -5353,13 +5348,6 @@ public class PackageParser {
                com.android.internal.R.styleable.AndroidManifestService_singleUser,
                false)) {
            s.info.flags |= ServiceInfo.FLAG_SINGLE_USER;
            if (s.info.exported && (flags & PARSE_IS_PRIVILEGED) == 0) {
                Slog.w(TAG, "Service exported request ignored due to singleUser: "
                        + s.className + " at " + mArchiveSourcePath + " "
                        + parser.getPositionDescription());
                s.info.exported = false;
                setExported = true;
            }
        }

        s.info.encryptionAware = s.info.directBootAware = sa.getBoolean(
+290 −195

File changed.

Preview size limit exceeded, changes collapsed.