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

Commit a1485f61 authored by Eric Holk's avatar Eric Holk
Browse files

[view compilation] Add --compile-layouts flag to `pm compile`

This allows us to generate precompiled layouts for installed applications.

If the system property view.precompiled_layout_enabled is set, then
PackageMannager will also automatically generate precompiled layouts for apps at
install or upgrade time.

Bug: 111895153
Test: manual
Change-Id: If6455e1b9b0542a36882af9f3e29d0185a53393c
parent d906d809
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -539,6 +539,11 @@ interface IPackageManager {
    boolean performDexOptSecondary(String packageName,
            String targetCompilerFilter, boolean force);

    /**
    * Ask the package manager to compile layouts in the given package.
    */
    boolean compileLayouts(String packageName);

    /**
     * Ask the package manager to dump profiles associated with a package.
     */
+5 −0
Original line number Diff line number Diff line
@@ -822,4 +822,9 @@ public abstract class PackageManagerInternal {
     *            PACKAGE_ROLLBACK_AGENT permission.
     */
    public abstract void setEnableRollbackCode(int token, int enableRollbackCode);

    /**
     * Ask the package manager to compile layouts in the given package.
     */
    public abstract boolean compileLayouts(String packageName);
}
+8 −0
Original line number Diff line number Diff line
@@ -621,6 +621,14 @@ public class Installer extends SystemService {
        throw new InstallerException("Invalid instruction set: " + instructionSet);
    }

    public boolean compileLayouts(String apkPath, String packageName, String outDexFile, int uid) {
        try {
            return mInstalld.compileLayouts(apkPath, packageName, outDexFile, uid);
        } catch (RemoteException e) {
            return false;
        }
    }

    public static class InstallerException extends Exception {
        public InstallerException(String detailMessage) {
            super(detailMessage);
+49 −0
Original line number Diff line number Diff line
@@ -311,6 +311,7 @@ import com.android.server.pm.dex.ArtManagerService;
import com.android.server.pm.dex.DexManager;
import com.android.server.pm.dex.DexoptOptions;
import com.android.server.pm.dex.PackageDexUsage;
import com.android.server.pm.dex.ViewCompiler;
import com.android.server.pm.permission.BasePermission;
import com.android.server.pm.permission.DefaultPermissionGrantPolicy;
import com.android.server.pm.permission.DefaultPermissionGrantPolicy.DefaultPermissionGrantedCallback;
@@ -446,6 +447,9 @@ public class PackageManagerService extends IPackageManager.Stub
    private static final long BACKUP_TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(60);
    private static final boolean PRECOMPILED_LAYOUT_ENABLED =
            SystemProperties.getBoolean("view.precompiled_layout_enabled", false);
    private static final int RADIO_UID = Process.PHONE_UID;
    private static final int LOG_UID = Process.LOG_UID;
    private static final int NFC_UID = Process.NFC_UID;
@@ -888,6 +892,8 @@ public class PackageManagerService extends IPackageManager.Stub
    // is used by other apps).
    private final DexManager mDexManager;
    private final ViewCompiler mViewCompiler;
    private AtomicInteger mNextMoveId = new AtomicInteger();
    private final MoveCallbacks mMoveCallbacks;
@@ -2262,6 +2268,8 @@ public class PackageManagerService extends IPackageManager.Stub
        mArtManagerService = new ArtManagerService(mContext, this, installer, mInstallLock);
        mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
        mViewCompiler = new ViewCompiler(mInstallLock, mInstaller);
        mOnPermissionChangeListeners = new OnPermissionChangeListeners(
                FgThread.get().getLooper());
@@ -9104,6 +9112,10 @@ public class PackageManagerService extends IPackageManager.Stub
                pkgCompilationReason = PackageManagerService.REASON_BACKGROUND_DEXOPT;
            }
            if (PRECOMPILED_LAYOUT_ENABLED) {
                mArtManagerService.compileLayouts(pkg);
            }
            // checkProfiles is false to avoid merging profiles during boot which
            // might interfere with background compilation (b/28612421).
            // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
@@ -9248,6 +9260,21 @@ public class PackageManagerService extends IPackageManager.Stub
        return performDexOpt(new DexoptOptions(packageName, compilerFilter, flags));
    }
    /**
    * Ask the package manager to compile layouts in the given package.
    */
    @Override
    public boolean compileLayouts(String packageName) {
        PackageParser.Package pkg;
        synchronized (mPackages) {
            pkg = mPackages.get(packageName);
            if (pkg == null) {
                return false;
            }
        }
        return mViewCompiler.compileLayouts(pkg);
    }
    /*package*/ boolean performDexOpt(DexoptOptions options) {
        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
            return false;
@@ -16143,6 +16170,13 @@ public class PackageManagerService extends IPackageManager.Stub
                    && ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0);
            if (performDexopt) {
                // Compile the layout resources.
                if (PRECOMPILED_LAYOUT_ENABLED) {
                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "compileLayouts");
                    mViewCompiler.compileLayouts(pkg);
                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
                }
                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
                // Do not run PackageDexOptimizer through the local performDexOpt
                // method because `pkg` may not be in `mPackages` yet.
@@ -23737,6 +23771,21 @@ public class PackageManagerService extends IPackageManager.Stub
        public void setEnableRollbackCode(int token, int enableRollbackCode) {
            PackageManagerService.this.setEnableRollbackCode(token, enableRollbackCode);
        }
        /**
         * Ask the package manager to compile layouts in the given package.
         */
        @Override
        public boolean compileLayouts(String packageName) {
            PackageParser.Package pkg;
            synchronized (mPackages) {
                pkg = mPackages.get(packageName);
                if (pkg == null) {
                    return false;
                }
            }
            return mArtManagerService.compileLayouts(pkg);
        }
    }
    @GuardedBy("mPackages")
+28 −12
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ import android.content.pm.InstrumentationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageInstaller.SessionParams;
import android.content.pm.PackageManagerInternal;
import android.content.pm.PackageItemInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
@@ -1170,6 +1171,7 @@ class PackageManagerShellCommand extends ShellCommand {
        String checkProfilesRaw = null;
        boolean secondaryDex = false;
        String split = null;
        boolean compileLayouts = false;

        String opt;
        while ((opt = getNextOption()) != null) {
@@ -1189,6 +1191,9 @@ class PackageManagerShellCommand extends ShellCommand {
                case "-r":
                    compilationReason = getNextArgRequired();
                    break;
                case "--compile-layouts":
                    compileLayouts = true;
                    break;
                case "--check-prof":
                    checkProfilesRaw = getNextArgRequired();
                    break;
@@ -1220,14 +1225,16 @@ class PackageManagerShellCommand extends ShellCommand {
            }
        }

        if (compilerFilter != null && compilationReason != null) {
            pw.println("Cannot use compilation filter (\"-m\") and compilation reason (\"-r\") " +
                    "at the same time");
            return 1;
        }
        if (compilerFilter == null && compilationReason == null) {
            pw.println("Cannot run without any of compilation filter (\"-m\") and compilation " +
                    "reason (\"-r\") at the same time");
        final boolean compilerFilterGiven = compilerFilter != null;
        final boolean compilationReasonGiven = compilationReason != null;
        // Make sure exactly one of -m, -r, or --compile-layouts is given.
        if ((!compilerFilterGiven && !compilationReasonGiven && !compileLayouts)
            || (!compilerFilterGiven && compilationReasonGiven && compileLayouts)
            || (compilerFilterGiven && !compilationReasonGiven && compileLayouts)
            || (compilerFilterGiven && compilationReasonGiven && !compileLayouts)
            || (compilerFilterGiven && compilationReasonGiven && compileLayouts)) {
            pw.println("Must specify exactly one of compilation filter (\"-m\"), compilation " +
                    "reason (\"-r\"), or compile layouts (\"--compile-layouts\")");
            return 1;
        }

@@ -1241,15 +1248,16 @@ class PackageManagerShellCommand extends ShellCommand {
            return 1;
        }

        String targetCompilerFilter;
        if (compilerFilter != null) {
        String targetCompilerFilter = null;
        if (compilerFilterGiven) {
            if (!DexFile.isValidCompilerFilter(compilerFilter)) {
                pw.println("Error: \"" + compilerFilter +
                        "\" is not a valid compilation filter.");
                return 1;
            }
            targetCompilerFilter = compilerFilter;
        } else {
        }
        if (compilationReasonGiven) {
            int reason = -1;
            for (int i = 0; i < PackageManagerServiceCompilerMapping.REASON_STRINGS.length; i++) {
                if (PackageManagerServiceCompilerMapping.REASON_STRINGS[i].equals(
@@ -1291,12 +1299,19 @@ class PackageManagerShellCommand extends ShellCommand {
                pw.flush();
            }

            boolean result = secondaryDex
            boolean result = true;
            if (compileLayouts) {
                PackageManagerInternal internal = LocalServices.getService(
                        PackageManagerInternal.class);
                result = internal.compileLayouts(packageName);
            } else {
                result = secondaryDex
                    ? mInterface.performDexOptSecondary(packageName,
                            targetCompilerFilter, forceCompilation)
                    : mInterface.performDexOptMode(packageName,
                            checkProfiles, targetCompilerFilter, forceCompilation,
                            true /* bootComplete */, split);
            }
            if (!result) {
                failedPackages.add(packageName);
            }
@@ -3004,6 +3019,7 @@ class PackageManagerShellCommand extends ShellCommand {
        pw.println("      --check-prof (true | false): look at profiles when doing dexopt?");
        pw.println("      --secondary-dex: compile app secondary dex files");
        pw.println("      --split SPLIT: compile only the given split name");
        pw.println("      --compile-layouts: compile layout resources for faster inflation");
        pw.println("");
        pw.println("  force-dex-opt PACKAGE");
        pw.println("    Force immediate execution of dex opt for the given PACKAGE.");
Loading