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

Commit bdd30d86 authored by Andreas Gampe's avatar Andreas Gampe
Browse files

Frameworks/base: Refactor package manager

Introduce a mapping between dexopt reasons and compiler filters. Use
reasons in package manager and other classes, where possible.

Change PackageDexOptimizer to accept a compilation filter. Adapt for
the split-out profile merging. Pass compilation filter to installd.

Bug: 27689078
Change-Id: I8c0ea6f10fbfdbd096adecc52abfd2466d048fdc
parent fbc98e1c
Loading
Loading
Loading
Loading
+15 −2
Original line number Diff line number Diff line
@@ -454,8 +454,21 @@ interface IPackageManager {
     */
    boolean performDexOptIfNeeded(String packageName, String instructionSet);

    boolean performDexOpt(String packageName, String instructionSet, boolean useProfiles,
            boolean extractOnly, boolean force);
    /**
     * Ask the package manager to perform a dex-opt for the given reason. The package
     * manager will map the reason to a compiler filter according to the current system
     * configuration.
     */
    boolean performDexOpt(String packageName, String instructionSet, boolean checkProfiles,
            int compileReason, boolean force);
    /**
     * Ask the package manager to perform a dex-opt with the given compiler filter.
     *
     * Note: exposed only for the shell command to allow moving packages explicitly to a
     *       definite state.
     */
    boolean performDexOptMode(String packageName, String instructionSet, boolean checkProfiles,
            String targetCompilerFilter, boolean force);

    void forceDexOpt(String packageName);

+25 −7
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@ import android.net.LocalSocketAddress;
import android.os.SystemClock;
import android.text.TextUtils;
import android.util.Slog;
import android.text.TextUtils;

import com.android.internal.util.Preconditions;

@@ -140,14 +139,14 @@ public class InstallerConnection {
    }

    public void dexopt(String apkPath, int uid, String instructionSet, int dexoptNeeded,
            int dexFlags, String volumeUuid, boolean useProfiles) throws InstallerException {
            int dexFlags, String compilerFilter, String volumeUuid) throws InstallerException {
        dexopt(apkPath, uid, "*", instructionSet, dexoptNeeded,
                null /*outputPath*/, dexFlags, volumeUuid, useProfiles);
                null /*outputPath*/, dexFlags, compilerFilter, volumeUuid);
    }

    public void dexopt(String apkPath, int uid, String pkgName, String instructionSet,
            int dexoptNeeded, String outputPath, int dexFlags, String volumeUuid,
            boolean useProfiles) throws InstallerException {
            int dexoptNeeded, String outputPath, int dexFlags, String compilerFilter,
            String volumeUuid) throws InstallerException {
        execute("dexopt",
                apkPath,
                uid,
@@ -156,8 +155,27 @@ public class InstallerConnection {
                dexoptNeeded,
                outputPath,
                dexFlags,
                volumeUuid,
                useProfiles ? '1' : '0');
                compilerFilter,
                volumeUuid);
    }

    public boolean mergeProfiles(int uid, String pkgName) throws InstallerException {
        String rawReply = executeForResult("merge_profiles", uid, pkgName);
        if (rawReply == null) {
            throw new IllegalStateException("Unexpected null reply");
        }
        final String res[] = rawReply.split(" ");

        if ((res == null) || (res.length != 2)) {
            throw new InstallerException("Invalid size result: " + rawReply);
        }

        // Just as a sanity check. Anything != "true" will be interpreted as false by parseBoolean.
        if (!res[1].equals("true") && !res[1].equals("false")) {
            throw new InstallerException("Invalid boolean result: " + rawReply);
        }

        return Boolean.parseBoolean(res[1]);
    }

    private boolean connect() {
+5 −3
Original line number Diff line number Diff line
@@ -501,12 +501,14 @@ public class ZygoteInit {
            for (String classPathElement : classPathElements) {
                // System server is fully AOTed and never profiled
                // for profile guided compilation.
                // TODO: Make this configurable between INTERPRET_ONLY, SPEED, SPACE and EVERYTHING?
                final int dexoptNeeded = DexFile.getDexOptNeeded(
                        classPathElement, instructionSet, DexFile.COMPILATION_TYPE_FULL);
                        classPathElement, instructionSet, "speed",
                        false /* newProfile */);
                if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
                    installer.dexopt(classPathElement, Process.SYSTEM_UID, instructionSet,
                            dexoptNeeded, 0 /*dexFlags*/, null /*volumeUuid*/,
                            false /*useProfiles*/);
                            dexoptNeeded, 0 /*dexFlags*/, "speed",
                            null /*volumeUuid*/);
                }
            }
        } catch (IOException | InstallerException e) {
+4 −4
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.server.pm;

import static com.android.server.pm.PackageManagerServiceCompilerMapping.REASON_BACKGROUND_DEXOPT;

import android.app.AlarmManager;
import android.app.job.JobInfo;
import android.app.job.JobParameters;
@@ -51,8 +53,6 @@ public class BackgroundDexOptService extends JobService {

    final AtomicBoolean mIdleTime = new AtomicBoolean(false);

    private boolean useJitProfiles = SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false);

    public static void schedule(Context context) {
        JobScheduler js = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
        JobInfo job = new JobInfo.Builder(BACKGROUND_DEXOPT_JOB, sDexoptServiceName)
@@ -93,8 +93,8 @@ public class BackgroundDexOptService extends JobService {
                        // skip previously failing package
                        continue;
                    }
                    if (!pm.performDexOpt(pkg, /* instruction set */ null, useJitProfiles,
                            /* extractOnly */ false, /* force */ false)) {
                    if (!pm.performDexOpt(pkg, /* instruction set */ null, /* checkProfiles */ true,
                            REASON_BACKGROUND_DEXOPT, /* force */ false)) {
                        // there was a problem running dexopt,
                        // remember this so we do not keep retrying.
                        sFailedPackageNames.add(pkg);
+15 −12
Original line number Diff line number Diff line
@@ -20,7 +20,6 @@ import android.annotation.Nullable;
import android.content.Context;
import android.content.pm.PackageStats;
import android.os.Build;
import android.os.storage.StorageManager;
import android.util.Slog;

import com.android.internal.os.InstallerConnection;
@@ -44,8 +43,8 @@ public final class Installer extends SystemService {
    public static final int DEXOPT_DEBUGGABLE     = 1 << 3;
    /** The system boot has finished */
    public static final int DEXOPT_BOOTCOMPLETE   = 1 << 4;
    /** Do not compile, only extract bytecode into an OAT file */
    public static final int DEXOPT_EXTRACTONLY  = 1 << 5;
    /** Hint that the dexopt type is profile-guided. */
    public static final int DEXOPT_PROFILE_GUIDED = 1 << 5;
    /** This is an OTA update dexopt */
    public static final int DEXOPT_OTA            = 1 << 6;

@@ -137,19 +136,23 @@ public final class Installer extends SystemService {
    }

    public void dexopt(String apkPath, int uid, String instructionSet, int dexoptNeeded,
            int dexFlags, String volumeUuid, boolean useProfiles) throws InstallerException {
            int dexFlags, String compilerFilter, String volumeUuid) throws InstallerException {
        assertValidInstructionSet(instructionSet);
        mInstaller.dexopt(apkPath, uid, instructionSet, dexoptNeeded, dexFlags,
                volumeUuid, useProfiles);
                compilerFilter, volumeUuid);
    }

    public void dexopt(String apkPath, int uid, String pkgName, String instructionSet,
            int dexoptNeeded, @Nullable String outputPath, int dexFlags,
            String volumeUuid, boolean useProfiles)
            String compilerFilter, String volumeUuid)
                    throws InstallerException {
        assertValidInstructionSet(instructionSet);
        mInstaller.dexopt(apkPath, uid, pkgName, instructionSet, dexoptNeeded,
                outputPath, dexFlags, volumeUuid, useProfiles);
                outputPath, dexFlags, compilerFilter, volumeUuid);
    }

    public boolean mergeProfiles(int uid, String pkgName) throws InstallerException {
        return mInstaller.mergeProfiles(uid, pkgName);
    }

    public void idmap(String targetApkPath, String overlayApkPath, int uid)
Loading