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

Commit 15620b01 authored by Jared Duke's avatar Jared Duke Committed by Oluwarotimi Adesina
Browse files

Support per-process useEmbeddedDex opt-in

Extend the useEmbeddedDex attribute to allow opt-in at the <process>
level. Note that if the parent application has opted in to
useEmbeddedDex, that will override any value set at the process level.

This configuration is useful for lighter weight processes that don't
rely heavily on the usual set of dex compilation optimizations critical
for the usual set of app CUJs (e.g., app startup).

Bug: 295870718
Test: atest android.appsecurity.cts.UseEmbeddedDexTest
Change-Id: Ic50ae2e1c568006cb3199013889a91fe38afc9d0
parent bdf038d5
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -68,6 +68,7 @@ aconfig_srcjars = [
    ":com.android.hardware.input-aconfig-java{.generated_srcjars}",
    ":com.android.input.flags-aconfig-java{.generated_srcjars}",
    ":com.android.internal.foldables.flags-aconfig-java{.generated_srcjars}",
    ":com.android.internal.pm.pkg.component.flags-aconfig-java{.generated_srcjars}",
    ":com.android.media.flags.bettertogether-aconfig-java{.generated_srcjars}",
    ":com.android.media.flags.editing-aconfig-java{.generated_srcjars}",
    ":com.android.net.thread.flags-aconfig-java{.generated_srcjars}",
@@ -1137,3 +1138,22 @@ java_aconfig_library {
    aconfig_declarations: "android.app.wearable.flags-aconfig",
    defaults: ["framework-minus-apex-aconfig-java-defaults"],
}

aconfig_declarations {
    name: "com.android.internal.pm.pkg.component.flags-aconfig",
    package: "com.android.internal.pm.pkg.component.flags",
    srcs: ["core/java/com/android/internal/pm/pkg/component/flags/flags.aconfig"],
}

java_aconfig_library {
    name: "com.android.internal.pm.pkg.component.flags-aconfig-java",
    aconfig_declarations: "com.android.internal.pm.pkg.component.flags-aconfig",
    defaults: ["framework-minus-apex-aconfig-java-defaults"],
}

java_aconfig_library {
    name: "com.android.internal.pm.pkg.component.flags-aconfig-java-host",
    aconfig_declarations: "com.android.internal.pm.pkg.component.flags-aconfig",
    host_supported: true,
    defaults: ["framework-minus-apex-aconfig-java-defaults"],
}
+20 −7
Original line number Diff line number Diff line
@@ -18,10 +18,8 @@ package android.content.pm;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.pm.ApplicationInfo;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import android.util.ArraySet;

import com.android.internal.util.DataClass;
@@ -64,6 +62,12 @@ public class ProcessInfo implements Parcelable {
     */
    public @ApplicationInfo.NativeHeapZeroInitialized int nativeHeapZeroInitialized;

    /**
     * Enable use of embedded dex in the APK, rather than extracted or locally compiled variants.
     * If false (default), the parent app's configuration determines behavior.
     */
    public boolean useEmbeddedDex;

    @Deprecated
    public ProcessInfo(@NonNull ProcessInfo orig) {
        this.name = orig.name;
@@ -71,11 +75,12 @@ public class ProcessInfo implements Parcelable {
        this.gwpAsanMode = orig.gwpAsanMode;
        this.memtagMode = orig.memtagMode;
        this.nativeHeapZeroInitialized = orig.nativeHeapZeroInitialized;
        this.useEmbeddedDex = orig.useEmbeddedDex;
    }



    // Code below generated by codegen v1.0.22.
    // Code below generated by codegen v1.0.23.
    //
    // DO NOT MODIFY!
    // CHECKSTYLE:OFF Generated code
@@ -102,6 +107,9 @@ public class ProcessInfo implements Parcelable {
     *   disabled, or left unspecified.
     * @param nativeHeapZeroInitialized
     *   Enable automatic zero-initialization of native heap memory allocations.
     * @param useEmbeddedDex
     *   Enable use of embedded dex in the APK, rather than extracted or locally compiled variants.
     *   If false (default), the parent app's configuration determines behavior.
     */
    @DataClass.Generated.Member
    public ProcessInfo(
@@ -109,7 +117,8 @@ public class ProcessInfo implements Parcelable {
            @Nullable ArraySet<String> deniedPermissions,
            @ApplicationInfo.GwpAsanMode int gwpAsanMode,
            @ApplicationInfo.MemtagMode int memtagMode,
            @ApplicationInfo.NativeHeapZeroInitialized int nativeHeapZeroInitialized) {
            @ApplicationInfo.NativeHeapZeroInitialized int nativeHeapZeroInitialized,
            boolean useEmbeddedDex) {
        this.name = name;
        com.android.internal.util.AnnotationValidations.validate(
                NonNull.class, null, name);
@@ -123,6 +132,7 @@ public class ProcessInfo implements Parcelable {
        this.nativeHeapZeroInitialized = nativeHeapZeroInitialized;
        com.android.internal.util.AnnotationValidations.validate(
                ApplicationInfo.NativeHeapZeroInitialized.class, null, nativeHeapZeroInitialized);
        this.useEmbeddedDex = useEmbeddedDex;

        // onConstructed(); // You can define this method to get a callback
    }
@@ -145,6 +155,7 @@ public class ProcessInfo implements Parcelable {
        // void parcelFieldName(Parcel dest, int flags) { ... }

        byte flg = 0;
        if (useEmbeddedDex) flg |= 0x20;
        if (deniedPermissions != null) flg |= 0x2;
        dest.writeByte(flg);
        dest.writeString(name);
@@ -166,6 +177,7 @@ public class ProcessInfo implements Parcelable {
        // static FieldType unparcelFieldName(Parcel in) { ... }

        byte flg = in.readByte();
        boolean _useEmbeddedDex = (flg & 0x20) != 0;
        String _name = in.readString();
        ArraySet<String> _deniedPermissions = sParcellingForDeniedPermissions.unparcel(in);
        int _gwpAsanMode = in.readInt();
@@ -185,6 +197,7 @@ public class ProcessInfo implements Parcelable {
        this.nativeHeapZeroInitialized = _nativeHeapZeroInitialized;
        com.android.internal.util.AnnotationValidations.validate(
                ApplicationInfo.NativeHeapZeroInitialized.class, null, nativeHeapZeroInitialized);
        this.useEmbeddedDex = _useEmbeddedDex;

        // onConstructed(); // You can define this method to get a callback
    }
@@ -204,10 +217,10 @@ public class ProcessInfo implements Parcelable {
    };

    @DataClass.Generated(
            time = 1615850184524L,
            codegenVersion = "1.0.22",
            time = 1706177470784L,
            codegenVersion = "1.0.23",
            sourceFile = "frameworks/base/core/java/android/content/pm/ProcessInfo.java",
            inputSignatures = "public @android.annotation.NonNull java.lang.String name\npublic @android.annotation.Nullable @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInternedStringArraySet.class) android.util.ArraySet<java.lang.String> deniedPermissions\npublic @android.content.pm.ApplicationInfo.GwpAsanMode int gwpAsanMode\npublic @android.content.pm.ApplicationInfo.MemtagMode int memtagMode\npublic @android.content.pm.ApplicationInfo.NativeHeapZeroInitialized int nativeHeapZeroInitialized\nclass ProcessInfo extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genGetters=true, genSetters=false, genParcelable=true, genAidl=false, genBuilder=false)")
            inputSignatures = "public @android.annotation.NonNull java.lang.String name\npublic @android.annotation.Nullable @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInternedStringArraySet.class) android.util.ArraySet<java.lang.String> deniedPermissions\npublic @android.content.pm.ApplicationInfo.GwpAsanMode int gwpAsanMode\npublic @android.content.pm.ApplicationInfo.MemtagMode int memtagMode\npublic @android.content.pm.ApplicationInfo.NativeHeapZeroInitialized int nativeHeapZeroInitialized\npublic  boolean useEmbeddedDex\nclass ProcessInfo extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genGetters=true, genSetters=false, genParcelable=true, genAidl=false, genBuilder=false)")
    @Deprecated
    private void __metadata() {}

+25 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import android.util.AttributeSet;
import android.util.Pair;
import android.util.Slog;

import com.android.internal.pm.pkg.component.flags.Flags;
import com.android.internal.util.ArrayUtils;

import libcore.io.IoUtils;
@@ -89,6 +90,8 @@ public class ApkLiteParseUtils {
    private static final String TAG_SDK_LIBRARY = "sdk-library";
    private static final int SDK_VERSION = Build.VERSION.SDK_INT;
    private static final String[] SDK_CODENAMES = Build.VERSION.ACTIVE_CODENAMES;
    private static final String TAG_PROCESSES = "processes";
    private static final String TAG_PROCESS = "process";

    /**
     * Parse only lightweight details about the package at the given location.
@@ -518,6 +521,28 @@ public class ApkLiteParseUtils {
                        case TAG_SDK_LIBRARY:
                            isSdkLibrary = true;
                            break;
                        case TAG_PROCESSES:
                            final int processesDepth = parser.getDepth();
                            int processesType;
                            while ((processesType = parser.next()) != XmlPullParser.END_DOCUMENT
                                    && (processesType != XmlPullParser.END_TAG
                                    || parser.getDepth() > processesDepth)) {
                                if (processesType == XmlPullParser.END_TAG
                                        || processesType == XmlPullParser.TEXT) {
                                    continue;
                                }

                                if (parser.getDepth() != processesDepth + 1) {
                                    // Search only under <processes>.
                                    continue;
                                }

                                if (parser.getName().equals(TAG_PROCESS)
                                        && Flags.enablePerProcessUseEmbeddedDexAttr()) {
                                    useEmbeddedDex |= parser.getAttributeBooleanValue(
                                            ANDROID_RES_NAMESPACE, "useEmbeddedDex", false);
                                }
                            }
                    }
                }
            } else if (TAG_OVERLAY.equals(parser.getName())) {
+2 −0
Original line number Diff line number Diff line
@@ -51,4 +51,6 @@ public interface ParsedProcess {

    @ApplicationInfo.NativeHeapZeroInitialized
    int getNativeHeapZeroInitialized();

    boolean isUseEmbeddedDex();
}
+26 −3
Original line number Diff line number Diff line
@@ -54,6 +54,8 @@ public class ParsedProcessImpl implements ParsedProcess, Parcelable {
    @ApplicationInfo.NativeHeapZeroInitialized
    private int nativeHeapZeroInitialized = ApplicationInfo.ZEROINIT_DEFAULT;

    private boolean useEmbeddedDex;

    public ParsedProcessImpl() {
    }

@@ -65,6 +67,7 @@ public class ParsedProcessImpl implements ParsedProcess, Parcelable {
        gwpAsanMode = other.getGwpAsanMode();
        memtagMode = other.getMemtagMode();
        nativeHeapZeroInitialized = other.getNativeHeapZeroInitialized();
        useEmbeddedDex = other.isUseEmbeddedDex();
    }

    public void addStateFrom(@NonNull ParsedProcess other) {
@@ -72,6 +75,7 @@ public class ParsedProcessImpl implements ParsedProcess, Parcelable {
        gwpAsanMode = other.getGwpAsanMode();
        memtagMode = other.getMemtagMode();
        nativeHeapZeroInitialized = other.getNativeHeapZeroInitialized();
        useEmbeddedDex = other.isUseEmbeddedDex();

        final ArrayMap<String, String> oacn = other.getAppClassNamesByPackage();
        for (int i = 0; i < oacn.size(); i++) {
@@ -115,7 +119,8 @@ public class ParsedProcessImpl implements ParsedProcess, Parcelable {
            @NonNull Set<String> deniedPermissions,
            @ApplicationInfo.GwpAsanMode int gwpAsanMode,
            @ApplicationInfo.MemtagMode int memtagMode,
            @ApplicationInfo.NativeHeapZeroInitialized int nativeHeapZeroInitialized) {
            @ApplicationInfo.NativeHeapZeroInitialized int nativeHeapZeroInitialized,
            boolean useEmbeddedDex) {
        this.name = name;
        com.android.internal.util.AnnotationValidations.validate(
                NonNull.class, null, name);
@@ -134,6 +139,7 @@ public class ParsedProcessImpl implements ParsedProcess, Parcelable {
        this.nativeHeapZeroInitialized = nativeHeapZeroInitialized;
        com.android.internal.util.AnnotationValidations.validate(
                ApplicationInfo.NativeHeapZeroInitialized.class, null, nativeHeapZeroInitialized);
        this.useEmbeddedDex = useEmbeddedDex;

        // onConstructed(); // You can define this method to get a callback
    }
@@ -171,6 +177,11 @@ public class ParsedProcessImpl implements ParsedProcess, Parcelable {
        return nativeHeapZeroInitialized;
    }

    @DataClass.Generated.Member
    public boolean isUseEmbeddedDex() {
        return useEmbeddedDex;
    }

    @DataClass.Generated.Member
    public @NonNull ParsedProcessImpl setName(@NonNull String value) {
        name = value;
@@ -222,6 +233,12 @@ public class ParsedProcessImpl implements ParsedProcess, Parcelable {
        return this;
    }

    @DataClass.Generated.Member
    public @NonNull ParsedProcessImpl setUseEmbeddedDex( boolean value) {
        useEmbeddedDex = value;
        return this;
    }

    @DataClass.Generated.Member
    static Parcelling<Set<String>> sParcellingForDeniedPermissions =
            Parcelling.Cache.get(
@@ -239,6 +256,9 @@ public class ParsedProcessImpl implements ParsedProcess, Parcelable {
        // You can override field parcelling by defining methods like:
        // void parcelFieldName(Parcel dest, int flags) { ... }

        byte flg = 0;
        if (useEmbeddedDex) flg |= 0x40;
        dest.writeByte(flg);
        dest.writeString(name);
        dest.writeMap(appClassNamesByPackage);
        sParcellingForDeniedPermissions.parcel(deniedPermissions, dest, flags);
@@ -258,6 +278,8 @@ public class ParsedProcessImpl implements ParsedProcess, Parcelable {
        // You can override field unparcelling by defining methods like:
        // static FieldType unparcelFieldName(Parcel in) { ... }

        byte flg = in.readByte();
        boolean _useEmbeddedDex = (flg & 0x40) != 0;
        String _name = in.readString();
        ArrayMap<String,String> _appClassNamesByPackage = new ArrayMap();
        in.readMap(_appClassNamesByPackage, String.class.getClassLoader());
@@ -284,6 +306,7 @@ public class ParsedProcessImpl implements ParsedProcess, Parcelable {
        this.nativeHeapZeroInitialized = _nativeHeapZeroInitialized;
        com.android.internal.util.AnnotationValidations.validate(
                ApplicationInfo.NativeHeapZeroInitialized.class, null, nativeHeapZeroInitialized);
        this.useEmbeddedDex = _useEmbeddedDex;

        // onConstructed(); // You can define this method to get a callback
    }
@@ -303,10 +326,10 @@ public class ParsedProcessImpl implements ParsedProcess, Parcelable {
    };

    @DataClass.Generated(
            time = 1701445656489L,
            time = 1706177189475L,
            codegenVersion = "1.0.23",
            sourceFile = "frameworks/base/core/java/com/android/internal/pm/pkg/component/ParsedProcessImpl.java",
            inputSignatures = "private @android.annotation.NonNull java.lang.String name\nprivate @android.annotation.NonNull android.util.ArrayMap<java.lang.String,java.lang.String> appClassNamesByPackage\nprivate @android.annotation.NonNull @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInternedStringSet.class) java.util.Set<java.lang.String> deniedPermissions\nprivate @android.content.pm.ApplicationInfo.GwpAsanMode int gwpAsanMode\nprivate @android.content.pm.ApplicationInfo.MemtagMode int memtagMode\nprivate @android.content.pm.ApplicationInfo.NativeHeapZeroInitialized int nativeHeapZeroInitialized\npublic  void addStateFrom(com.android.internal.pm.pkg.component.ParsedProcess)\npublic  void putAppClassNameForPackage(java.lang.String,java.lang.String)\nclass ParsedProcessImpl extends java.lang.Object implements [com.android.internal.pm.pkg.component.ParsedProcess, android.os.Parcelable]\n@com.android.internal.util.DataClass(genGetters=true, genSetters=true, genParcelable=true, genAidl=false, genBuilder=false)")
            inputSignatures = "private @android.annotation.NonNull java.lang.String name\nprivate @android.annotation.NonNull android.util.ArrayMap<java.lang.String,java.lang.String> appClassNamesByPackage\nprivate @android.annotation.NonNull @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInternedStringSet.class) java.util.Set<java.lang.String> deniedPermissions\nprivate @android.content.pm.ApplicationInfo.GwpAsanMode int gwpAsanMode\nprivate @android.content.pm.ApplicationInfo.MemtagMode int memtagMode\nprivate @android.content.pm.ApplicationInfo.NativeHeapZeroInitialized int nativeHeapZeroInitialized\nprivate  boolean useEmbeddedDex\npublic  void addStateFrom(com.android.internal.pm.pkg.component.ParsedProcess)\npublic  void putAppClassNameForPackage(java.lang.String,java.lang.String)\nclass ParsedProcessImpl extends java.lang.Object implements [com.android.internal.pm.pkg.component.ParsedProcess, android.os.Parcelable]\n@com.android.internal.util.DataClass(genGetters=true, genSetters=true, genParcelable=true, genAidl=false, genBuilder=false)")
    @Deprecated
    private void __metadata() {}

Loading