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

Commit 1d0e83d2 authored by Calin Juravle's avatar Calin Juravle
Browse files

Refactor the arguments passed to dexopt invocations

Wrap the arguments passed to the various performDexopt calls into the
DexoptOptions object.

This will make adding extra arguments (like compile only a split) much
easier and avoid extending quite a few internal methods.

Bug: 38138251
Test: adb shell cmd package compile ....
      adb shell cmd package bg-dexopt-job ...
      install new apps and check that they compiled
      runtest -x
services/tests/servicestests/src/com/android/server/pm/dex/DexoptOptionsTests.java

Change-Id: Ia9930edd2dceb7535d6168eceb8e3199c82b6306
parent af11a49d
Loading
Loading
Loading
Loading
+0 −8
Original line number Diff line number Diff line
@@ -507,14 +507,6 @@ interface IPackageManager {
     oneway void registerDexModule(in String packageName, in String dexModulePath,
             in boolean isSharedModule, IDexModuleRegisterCallback callback);

    /**
     * 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, boolean checkProfiles,
            int compileReason, boolean force, boolean bootComplete, boolean downgrade);

    /**
     * Ask the package manager to perform a dex-opt with the given compiler filter.
     *
+14 −15
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ import android.util.Log;
import com.android.server.pm.dex.DexManager;
import com.android.server.LocalServices;
import com.android.server.PinnerService;
import com.android.server.pm.dex.DexoptOptions;

import java.io.File;
import java.util.Set;
@@ -221,12 +222,10 @@ public class BackgroundDexOptService extends JobService {
            // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
            // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a
            // trade-off worth doing to save boot time work.
            int result = pm.performDexOptWithStatus(pkg,
                    /* checkProfiles */ false,
            int result = pm.performDexOptWithStatus(new DexoptOptions(
                    pkg,
                    PackageManagerService.REASON_BOOT,
                    /* force */ false,
                    /* bootComplete */ true,
                    /* downgrade */ false);
                    DexoptOptions.DEXOPT_BOOT_COMPLETE));
            if (result == PackageDexOptimizer.DEX_OPT_PERFORMED)  {
                updatedPackages.add(pkg);
            }
@@ -338,22 +337,22 @@ public class BackgroundDexOptService extends JobService {
            // Optimize package if needed. Note that there can be no race between
            // concurrent jobs because PackageDexOptimizer.performDexOpt is synchronized.
            boolean success;
            int dexoptFlags =
                    DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES |
                    DexoptOptions.DEXOPT_BOOT_COMPLETE |
                    (downgrade ? DexoptOptions.DEXOPT_DOWNGRADE : 0);
            if (is_for_primary_dex) {
                int result = pm.performDexOptWithStatus(pkg,
                        /* checkProfiles */ true,
                        reason,
                        false /* forceCompile*/,
                        true /* bootComplete */,
                        downgrade);
                int result = pm.performDexOptWithStatus(new DexoptOptions(pkg,
                        PackageManagerService.REASON_BACKGROUND_DEXOPT,
                        dexoptFlags));
                success = result != PackageDexOptimizer.DEX_OPT_FAILED;
                if (result == PackageDexOptimizer.DEX_OPT_PERFORMED) {
                    updatedPackages.add(pkg);
                }
            } else {
                success = pm.performDexOptSecondary(pkg,
                        reason,
                        false /* force */,
                        downgrade);
                success = pm.performDexOpt(new DexoptOptions(pkg,
                        PackageManagerService.REASON_BACKGROUND_DEXOPT,
                        dexoptFlags | DexoptOptions.DEXOPT_ONLY_SECONDARY_DEX));
            }
            if (success) {
                // Dexopt succeeded, remove package from the list of failing ones.
+11 −11
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@ package com.android.server.pm;

import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason;

import android.annotation.Nullable;
import android.content.Context;
@@ -35,6 +34,7 @@ import android.util.Slog;

import com.android.internal.logging.MetricsLogger;
import com.android.server.pm.Installer.InstallerException;
import com.android.server.pm.dex.DexoptOptions;

import java.io.File;
import java.io.FileDescriptor;
@@ -314,19 +314,19 @@ public class OtaDexoptService extends IOtaDexopt.Stub {
            libraryDependencies = NO_LIBRARIES;
        }


        optimizer.performDexOpt(pkg, libraryDependencies,
                null /* ISAs */, false /* checkProfiles */,
                getCompilerFilterForReason(compilationReason),
                null /* ISAs */,
                null /* CompilerStats.PackageStats */,
                mPackageManagerService.getDexManager().isUsedByOtherApps(pkg.packageName),
                true /* bootComplete */,
                false /* downgrade */);

        mPackageManagerService.getDexManager().dexoptSecondaryDex(pkg.packageName,
                getCompilerFilterForReason(compilationReason),
                false /* force */,
                false /* compileOnlySharedDex */,
                false /* downgrade */);
                new DexoptOptions(pkg.packageName, compilationReason,
                        DexoptOptions.DEXOPT_BOOT_COMPLETE));

        mPackageManagerService.getDexManager().dexoptSecondaryDex(
                new DexoptOptions(pkg.packageName, compilationReason,
                        DexoptOptions.DEXOPT_ONLY_SECONDARY_DEX |
                        DexoptOptions.DEXOPT_BOOT_COMPLETE));

        return commands;
    }

+11 −15
Original line number Diff line number Diff line
@@ -19,9 +19,7 @@ package com.android.server.pm;
import android.annotation.Nullable;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageParser;
import android.os.Environment;
import android.os.FileUtils;
import android.os.PowerManager;
import android.os.SystemClock;
@@ -34,6 +32,7 @@ import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.pm.Installer.InstallerException;
import com.android.server.pm.dex.DexoptOptions;

import java.io.File;
import java.io.IOException;
@@ -112,18 +111,16 @@ public class PackageDexOptimizer {
     * synchronized on {@link #mInstallLock}.
     */
    int performDexOpt(PackageParser.Package pkg, String[] sharedLibraries,
            String[] instructionSets, boolean checkProfiles, String targetCompilationFilter,
            CompilerStats.PackageStats packageStats, boolean isUsedByOtherApps,
            boolean bootComplete, boolean downgrade) {
            String[] instructionSets, CompilerStats.PackageStats packageStats,
            boolean isUsedByOtherApps, DexoptOptions options) {
        if (!canOptimizePackage(pkg)) {
            return DEX_OPT_SKIPPED;
        }
        synchronized (mInstallLock) {
            final long acquireTime = acquireWakeLockLI(pkg.applicationInfo.uid);
            try {
                return performDexOptLI(pkg, sharedLibraries, instructionSets, checkProfiles,
                        targetCompilationFilter, packageStats, isUsedByOtherApps, bootComplete,
                        downgrade);
                return performDexOptLI(pkg, sharedLibraries, instructionSets,
                        packageStats, isUsedByOtherApps, options);
            } finally {
                releaseWakeLockLI(acquireTime);
            }
@@ -136,9 +133,8 @@ public class PackageDexOptimizer {
     */
    @GuardedBy("mInstallLock")
    private int performDexOptLI(PackageParser.Package pkg, String[] sharedLibraries,
            String[] targetInstructionSets, boolean checkForProfileUpdates,
            String targetCompilerFilter, CompilerStats.PackageStats packageStats,
            boolean isUsedByOtherApps, boolean bootComplete, boolean downgrade) {
            String[] targetInstructionSets, CompilerStats.PackageStats packageStats,
            boolean isUsedByOtherApps, DexoptOptions options) {
        final String[] instructionSets = targetInstructionSets != null ?
                targetInstructionSets : getAppDexInstructionSets(pkg.applicationInfo);
        final String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
@@ -146,13 +142,13 @@ public class PackageDexOptimizer {
        final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);

        final String compilerFilter = getRealCompilerFilter(pkg.applicationInfo,
                targetCompilerFilter, isUsedByOtherApps);
        final boolean profileUpdated = checkForProfileUpdates &&
                options.getCompilerFilter(), isUsedByOtherApps);
        final boolean profileUpdated = options.isCheckForProfileUpdates() &&
                isProfileUpdated(pkg, sharedGid, compilerFilter);

        final String sharedLibrariesPath = getSharedLibrariesPath(sharedLibraries);
        // Get the dexopt flags after getRealCompilerFilter to make sure we get the correct flags.
        final int dexoptFlags = getDexFlags(pkg, compilerFilter, bootComplete);
        final int dexoptFlags = getDexFlags(pkg, compilerFilter, options.isBootComplete());
        // Get the dependencies of each split in the package. For each code path in the package,
        // this array contains the relative paths of each split it depends on, separated by colons.
        String[] splitDependencies = getSplitDependencies(pkg);
@@ -176,7 +172,7 @@ public class PackageDexOptimizer {
            for (String dexCodeIsa : dexCodeInstructionSets) {
                int newResult = dexOptPath(pkg, path, dexCodeIsa, compilerFilter, profileUpdated,
                        sharedLibrariesPathWithSplits, dexoptFlags, sharedGid, packageStats,
                        downgrade);
                        options.isDowngrade());
                // The end result is:
                //  - FAILED if any path failed,
                //  - PERFORMED if at least one path needed compilation,
+75 −86
Original line number Diff line number Diff line
@@ -283,6 +283,7 @@ import com.android.server.pm.PermissionsState.PermissionState;
import com.android.server.pm.Settings.DatabaseVersion;
import com.android.server.pm.Settings.VersionInfo;
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.storage.DeviceStorageMonitorInternal;
@@ -9365,21 +9366,22 @@ public class PackageManagerService extends IPackageManager.Stub
            // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
            // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a
            // trade-off worth doing to save boot time work.
            int primaryDexOptStaus = performDexOptTraced(pkg.packageName,
                    false /* checkProfiles */,
            int dexoptFlags = bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0;
            int primaryDexOptStaus = performDexOptTraced(new DexoptOptions(
                    pkg.packageName,
                    compilerFilter,
                    false /* force */,
                    bootComplete,
                    false /* downgrade */);
                    dexoptFlags));
            if (pkg.isSystemApp()) {
                // Only dexopt shared secondary dex files belonging to system apps to not slow down
                // too much boot after an OTA.
                mDexManager.dexoptSecondaryDex(pkg.packageName,
                int secondaryDexoptFlags = dexoptFlags |
                        DexoptOptions.DEXOPT_ONLY_SECONDARY_DEX |
                        DexoptOptions.DEXOPT_ONLY_SHARED_DEX;
                mDexManager.dexoptSecondaryDex(new DexoptOptions(
                        pkg.packageName,
                        compilerFilter,
                        false /* force */,
                        true /* compileOnlySharedDex */,
                        false /* downgrade */);
                        secondaryDexoptFlags));
            }
            // TODO(shubhamajmera): Record secondary dexopt stats.
@@ -9462,20 +9464,53 @@ public class PackageManagerService extends IPackageManager.Stub
        }
    }
    /**
     * 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.
     */
    @Override
    public boolean performDexOptMode(String packageName,
            boolean checkProfiles, String targetCompilerFilter, boolean force,
            boolean bootComplete) {
        int flags = (checkProfiles ? DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES : 0) |
                (force ? DexoptOptions.DEXOPT_FORCE : 0) |
                (bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0);
        return performDexOpt(new DexoptOptions(packageName, targetCompilerFilter, flags));
    }
    /**
     * Ask the package manager to perform a dex-opt with the given compiler filter on the
     * secondary dex files belonging to the given package.
     *
     * Note: exposed only for the shell command to allow moving packages explicitly to a
     *       definite state.
     */
    @Override
    public boolean performDexOpt(String packageName,
            boolean checkProfiles, int compileReason, boolean force, boolean bootComplete,
            boolean downgrade) {
    public boolean performDexOptSecondary(String packageName, String compilerFilter,
            boolean force) {
        int flags = DexoptOptions.DEXOPT_ONLY_SECONDARY_DEX |
                DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES |
                DexoptOptions.DEXOPT_BOOT_COMPLETE |
                (force ? DexoptOptions.DEXOPT_FORCE : 0);
        return performDexOpt(new DexoptOptions(packageName, compilerFilter, flags));
    }
    /*package*/ boolean performDexOpt(DexoptOptions options) {
        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
            return false;
        } else if (isInstantApp(packageName, UserHandle.getCallingUserId())) {
        } else if (isInstantApp(options.getPackageName(), UserHandle.getCallingUserId())) {
            return false;
        }
        int dexoptStatus = performDexOptWithStatus(
              packageName, checkProfiles, compileReason, force, bootComplete,
              downgrade);
        if (options.isDexoptOnlySecondaryDex()) {
            return mDexManager.dexoptSecondaryDex(options);
        } else {
            int dexoptStatus = performDexOptWithStatus(options);
            return dexoptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
        }
    }
    /**
     * Perform dexopt on the given package and return one of following result:
@@ -9483,34 +9518,14 @@ public class PackageManagerService extends IPackageManager.Stub
     *  {@link PackageDexOptimizer#DEX_OPT_PERFORMED}
     *  {@link PackageDexOptimizer#DEX_OPT_FAILED}
     */
    /* package */ int performDexOptWithStatus(String packageName,
            boolean checkProfiles, int compileReason, boolean force, boolean bootComplete,
            boolean downgrade) {
        return performDexOptTraced(packageName, checkProfiles,
                getCompilerFilterForReason(compileReason), force, bootComplete, downgrade);
    /* package */ int performDexOptWithStatus(DexoptOptions options) {
        return performDexOptTraced(options);
    }
    @Override
    public boolean performDexOptMode(String packageName,
            boolean checkProfiles, String targetCompilerFilter, boolean force,
            boolean bootComplete) {
        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
            return false;
        } else if (isInstantApp(packageName, UserHandle.getCallingUserId())) {
            return false;
        }
        int dexOptStatus = performDexOptTraced(packageName, checkProfiles,
                targetCompilerFilter, force, bootComplete, false /* downgrade */);
        return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
    }
    private int performDexOptTraced(String packageName,
                boolean checkProfiles, String targetCompilerFilter, boolean force,
                boolean bootComplete, boolean downgrade) {
    private int performDexOptTraced(DexoptOptions options) {
        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
        try {
            return performDexOptInternal(packageName, checkProfiles,
                    targetCompilerFilter, force, bootComplete, downgrade);
            return performDexOptInternal(options);
        } finally {
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
        }
@@ -9518,12 +9533,10 @@ public class PackageManagerService extends IPackageManager.Stub
    // Run dexopt on a given package. Returns true if dexopt did not fail, i.e.
    // if the package can now be considered up to date for the given filter.
    private int performDexOptInternal(String packageName,
                boolean checkProfiles, String targetCompilerFilter, boolean force,
                boolean bootComplete, boolean downgrade) {
    private int performDexOptInternal(DexoptOptions options) {
        PackageParser.Package p;
        synchronized (mPackages) {
            p = mPackages.get(packageName);
            p = mPackages.get(options.getPackageName());
            if (p == null) {
                // Package could not be found. Report failure.
                return PackageDexOptimizer.DEX_OPT_FAILED;
@@ -9534,8 +9547,7 @@ public class PackageManagerService extends IPackageManager.Stub
        long callingId = Binder.clearCallingIdentity();
        try {
            synchronized (mInstallLock) {
                return performDexOptInternalWithDependenciesLI(p, checkProfiles,
                        targetCompilerFilter, force, bootComplete, downgrade);
                return performDexOptInternalWithDependenciesLI(p, options);
            }
        } finally {
            Binder.restoreCallingIdentity(callingId);
@@ -9555,12 +9567,11 @@ public class PackageManagerService extends IPackageManager.Stub
    }
    private int performDexOptInternalWithDependenciesLI(PackageParser.Package p,
            boolean checkProfiles, String targetCompilerFilter,
            boolean force, boolean bootComplete, boolean downgrade) {
            DexoptOptions options) {
        // Select the dex optimizer based on the force parameter.
        // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to
        //       allocate an object here.
        PackageDexOptimizer pdo = force
        PackageDexOptimizer pdo = options.isForce()
                ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer)
                : mPackageDexOptimizer;
@@ -9577,37 +9588,14 @@ public class PackageManagerService extends IPackageManager.Stub
            for (PackageParser.Package depPackage : deps) {
                // TODO: Analyze and investigate if we (should) profile libraries.
                pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets,
                        false /* checkProfiles */,
                        targetCompilerFilter,
                        getOrCreateCompilerPackageStats(depPackage),
                        true /* isUsedByOtherApps */,
                        bootComplete,
                        downgrade);
            }
                        options);
            }
        return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets, checkProfiles,
                targetCompilerFilter, getOrCreateCompilerPackageStats(p),
                mDexManager.isUsedByOtherApps(p.packageName), bootComplete, downgrade);
        }
    // Performs dexopt on the used secondary dex files belonging to the given package.
    // Returns true if all dex files were process successfully (which could mean either dexopt or
    // skip). Returns false if any of the files caused errors.
    @Override
    public boolean performDexOptSecondary(String packageName, String compilerFilter,
            boolean force) {
        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
            return false;
        } else if (isInstantApp(packageName, UserHandle.getCallingUserId())) {
            return false;
        }
        return mDexManager.dexoptSecondaryDex(packageName, compilerFilter, force,
                false /* compileOnlySharedDex */, false /* downgrade */);
    }
    public boolean performDexOptSecondary(String packageName, int compileReason,
            boolean force, boolean downgrade) {
        return mDexManager.dexoptSecondaryDex(packageName, compileReason, force, downgrade);
        return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets,
                getOrCreateCompilerPackageStats(p),
                mDexManager.isUsedByOtherApps(p.packageName), options);
    }
    /**
@@ -9783,11 +9771,11 @@ public class PackageManagerService extends IPackageManager.Stub
            // Whoever is calling forceDexOpt wants a compiled package.
            // Don't use profiles since that may cause compilation to be skipped.
            final int res = performDexOptInternalWithDependenciesLI(pkg,
                    false /* checkProfiles */, getDefaultCompilerFilter(),
                    true /* force */,
                    true /* bootComplete */,
                    false /* downgrade */);
            final int res = performDexOptInternalWithDependenciesLI(
                    pkg,
                    new DexoptOptions(packageName,
                            getDefaultCompilerFilter(),
                            DexoptOptions.DEXOPT_FORCE | DexoptOptions.DEXOPT_BOOT_COMPLETE));
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
            if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
@@ -18249,13 +18237,14 @@ public class PackageManagerService extends IPackageManager.Stub
                // method because `pkg` may not be in `mPackages` yet.
                //
                // Also, don't fail application installs if the dexopt step fails.
                DexoptOptions dexoptOptions = new DexoptOptions(pkg.packageName,
                        REASON_INSTALL,
                        DexoptOptions.DEXOPT_BOOT_COMPLETE);
                mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
                        null /* instructionSets */, false /* checkProfiles */,
                        getCompilerFilterForReason(REASON_INSTALL),
                        null /* instructionSets */,
                        getOrCreateCompilerPackageStats(pkg),
                        mDexManager.isUsedByOtherApps(pkg.packageName),
                        true /* bootComplete */,
                        false /* downgrade */);
                        dexoptOptions);
                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
            }
Loading