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

Commit 47485661 authored by Jiakai Zhang's avatar Jiakai Zhang
Browse files

Remove DexoptOptions.

DexoptOptions used to be a proxy to bridge the legacy dexopt options and
ART Service options (DexoptParams), for seamless migration. Now the
migration has been done, and we can use ART Service options
(DexoptParams) directly.

This CL includes the following behavior changes, which has no effect in
practice:

- When install reason is not backup or restore, the code no longer
  explicitly sets priority class to PRIORITY_INTERACTIVE. Instead, it
  relies on ART Service's defaults. In practice, this makes no
  difference because:
  - For "install", the default is PRIORITY_INTERACTIVE.
  - For "install-fast", the default is REASON_INSTALL_FAST, but the
    default compiler filter is "skip", so the priority class is not
    applicable.
  - For "install-bulk-*", the default is PRIORITY_BACKGROUND, but nobody
    currently uses them.
- When the install request doesn't explicitly specify a compiler filter
  (only specifiable through the `adb install` command), the code no
  longer sets the compiler filter based on "pm.dexopt.*" properties.
  Instead, it relies on ART Service's default. In practice, this makes
  no difference because ART Service's default is to apply the compiler
  filter based on "pm.dexopt.*" properties.
- The code no longer explicitly sets FLAG_FOR_PRIMARY_DEX. Instead, it
  relies on ART Service's default. In practice, this makes
  no difference because ART Service's default flag for "install-*"
  reasons is FLAG_FOR_PRIMARY_DEX.

Bug: 258223472
Bug: 6527146
Test: Presubmit
Flag: EXEMPT cleanup
Change-Id: I2e5eca824bdd0ef6c1498306d2946c76be6188c1
parent c4a90c54
Loading
Loading
Loading
Loading
+27 −75
Original line number Diff line number Diff line
@@ -18,30 +18,18 @@ package com.android.server.pm;

import static android.content.pm.PackageManager.INSTALL_REASON_DEVICE_RESTORE;
import static android.content.pm.PackageManager.INSTALL_REASON_DEVICE_SETUP;
import static android.os.Trace.TRACE_TAG_DALVIK;
import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
import static android.os.incremental.IncrementalManager.isIncrementalPath;

import static com.android.server.LocalManagerRegistry.ManagerNotFoundException;
import static com.android.server.pm.ApexManager.ActiveApexInfo;
import static com.android.server.pm.PackageManagerService.DEBUG_DEXOPT;
import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
import static com.android.server.pm.PackageManagerService.REASON_BOOT_AFTER_MAINLINE_UPDATE;
import static com.android.server.pm.PackageManagerService.REASON_BOOT_AFTER_OTA;
import static com.android.server.pm.PackageManagerService.REASON_CMDLINE;
import static com.android.server.pm.PackageManagerService.REASON_FIRST_BOOT;
import static com.android.server.pm.PackageManagerService.SCAN_AS_APEX;
import static com.android.server.pm.PackageManagerService.SCAN_AS_INSTANT_APP;
import static com.android.server.pm.PackageManagerService.TAG;
import static com.android.server.pm.PackageManagerServiceUtils.REMOVE_IF_APEX_PKG;
import static com.android.server.pm.PackageManagerServiceUtils.REMOVE_IF_NULL_PKG;
import static com.android.server.pm.PackageManagerServiceUtils.getPackageManagerLocal;

import static dalvik.system.DexFile.isProfileGuidedCompilerFilter;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.AppGlobals;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -50,14 +38,11 @@ import android.content.pm.ApexStagedEvent;
import android.content.pm.IPackageManagerNative;
import android.content.pm.IStagedApexObserver;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Binder;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.Trace;
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Log;
@@ -77,11 +62,8 @@ import com.android.server.art.model.DexoptParams;
import com.android.server.art.model.DexoptResult;
import com.android.server.pinner.PinnerService;
import com.android.server.pm.dex.InstallScenarioHelper;
import com.android.server.pm.dex.DexoptOptions;
import com.android.server.pm.local.PackageManagerLocalImpl;
import com.android.server.pm.pkg.AndroidPackage;
import com.android.server.pm.pkg.PackageState;
import com.android.server.pm.pkg.PackageStateInternal;

import java.io.File;
import java.io.IOException;
@@ -89,9 +71,6 @@ import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@@ -100,15 +79,10 @@ import java.util.concurrent.CompletableFuture;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.function.Predicate;
import java.util.zip.ZipEntry;

/**
 * Helper class for dex optimization operations in PackageManagerService.
 */
/** Helper class for dex optimization operations in PackageManagerService. */
public final class DexOptHelper {
    private static final long SEVEN_DAYS_IN_MILLISECONDS = 7 * 24 * 60 * 60 * 1000;

    @NonNull
    private static final ThreadPoolExecutor sDexoptExecutor =
            new ThreadPoolExecutor(1 /* corePoolSize */, 1 /* maximumPoolSize */,
@@ -141,26 +115,24 @@ public final class DexOptHelper {
        PackageManagerServiceUtils.enforceSystemOrRoot(
                "Only the system can request package update");

        int reason;
        String reason;
        if (mPm.isFirstBoot()) {
            reason = REASON_FIRST_BOOT; // First boot or factory reset.
            reason = ReasonMapping.REASON_FIRST_BOOT; // First boot or factory reset.
        } else if (mPm.isDeviceUpgrading()) {
            reason = REASON_BOOT_AFTER_OTA;
            reason = ReasonMapping.REASON_BOOT_AFTER_OTA;
        } else if (hasBcpApexesChanged()) {
            reason = REASON_BOOT_AFTER_MAINLINE_UPDATE;
            reason = ReasonMapping.REASON_BOOT_AFTER_MAINLINE_UPDATE;
        } else {
            return;
        }

        Log.i(TAG,
                "Starting boot dexopt for reason "
                        + DexoptOptions.convertToArtServiceDexoptReason(reason));
        Log.i(TAG, "Starting boot dexopt for reason " + reason);

        final long startTime = System.nanoTime();

        mBootDexoptStartTime = startTime;
        getArtManagerLocal().onBoot(DexoptOptions.convertToArtServiceDexoptReason(reason),
                null /* progressCallbackExecutor */, null /* progressCallback */);
        getArtManagerLocal()
                .onBoot(reason, null /* progressCallbackExecutor */, null /* progressCallback */);
    }

    private void reportBootDexopt(long startTime, int numDexopted, int numSkipped, int numFailed) {
@@ -401,29 +373,25 @@ public final class DexOptHelper {
        }
    }

    /** Returns DexoptOptions by the given InstallRequest. */
    private DexoptOptions getDexoptOptionsByInstallRequest(InstallRequest installRequest) {
        final PackageSetting ps = installRequest.getScannedPackageSetting();
        final String packageName = ps.getPackageName();
        final boolean isBackupOrRestore =
                installRequest.getInstallReason() == INSTALL_REASON_DEVICE_RESTORE
                        || installRequest.getInstallReason() == INSTALL_REASON_DEVICE_SETUP;
        final int dexoptFlags = DexoptOptions.DEXOPT_BOOT_COMPLETE
                | DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES
                | DexoptOptions.DEXOPT_INSTALL_WITH_DEX_METADATA_FILE
                | (isBackupOrRestore ? DexoptOptions.DEXOPT_FOR_RESTORE : 0);
        // Compute the compilation reason from the installation scenario.
        final int compilationReason =
    private DexoptParams getDexoptParamsByInstallRequest(InstallRequest installRequest) {
        String compilationReason =
                mInstallScenarioHelper.getCompilationReasonForInstallScenario(
                        installRequest.getInstallScenario());
        final AndroidPackage pkg = ps.getPkg();
        var options = new DexoptOptions(packageName, compilationReason, dexoptFlags);
        var builder = new DexoptParams.Builder(compilationReason);
        if (installRequest.getInstallReason() == INSTALL_REASON_DEVICE_RESTORE
                || installRequest.getInstallReason() == INSTALL_REASON_DEVICE_SETUP) {
            builder.setPriorityClass(ArtFlags.PRIORITY_INTERACTIVE_FAST);
        }
        if (installRequest.getDexoptCompilerFilter() != null) {
            options = options.overrideCompilerFilter(installRequest.getDexoptCompilerFilter());
            builder.setCompilerFilter(installRequest.getDexoptCompilerFilter());
        } else if (shouldSkipDexopt(installRequest)) {
            options = options.overrideCompilerFilter(DexoptParams.COMPILER_FILTER_NOOP);
            builder.setCompilerFilter(DexoptParams.COMPILER_FILTER_NOOP);
        }
        if ((installRequest.getInstallFlags() & PackageManager.INSTALL_IGNORE_DEXOPT_PROFILE)
                != 0) {
            builder.setFlags(ArtFlags.FLAG_IGNORE_PROFILE, ArtFlags.FLAG_IGNORE_PROFILE);
        }
        return options;
        return builder.build();
    }

    /** Perform dexopt asynchronously if needed for the installation. */
@@ -436,13 +404,10 @@ public final class DexOptHelper {
                        () -> {
                            try {
                                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
                                DexoptOptions dexoptOptions =
                                        getDexoptOptionsByInstallRequest(installRequest);
                                // Don't fail application installs if the dexopt step fails.
                                // TODO(b/393076925): Make this async in ART Service.
                                DexoptResult dexOptResult =
                                        DexOptHelper.dexoptPackageUsingArtService(
                                                installRequest, dexoptOptions);
                                        dexoptPackageUsingArtService(installRequest);
                                installRequest.onDexoptFinished(dexOptResult);
                            } finally {
                                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
@@ -458,29 +423,16 @@ public final class DexOptHelper {
                        });
    }

    /**
     * Use ArtService to perform dexopt by the given InstallRequest.
     */
    static DexoptResult dexoptPackageUsingArtService(InstallRequest installRequest,
            DexoptOptions dexoptOptions) {
    /** Use ArtService to perform dexopt by the given InstallRequest. */
    private DexoptResult dexoptPackageUsingArtService(InstallRequest installRequest) {
        final PackageSetting ps = installRequest.getScannedPackageSetting();
        final String packageName = ps.getPackageName();

        PackageManagerLocal packageManagerLocal =
                LocalManagerRegistry.getManager(PackageManagerLocal.class);
        try (PackageManagerLocal.FilteredSnapshot snapshot =
                     PackageManagerLocalImpl.withFilteredSnapshot(packageManagerLocal, ps)) {
            boolean ignoreDexoptProfile =
                    (installRequest.getInstallFlags()
                            & PackageManager.INSTALL_IGNORE_DEXOPT_PROFILE)
                            != 0;
            /*@DexoptFlags*/ int extraFlags =
                    ignoreDexoptProfile ? ArtFlags.FLAG_IGNORE_PROFILE : 0;
            DexoptParams params = dexoptOptions.convertToDexoptParams(extraFlags);
            DexoptResult dexOptResult = getArtManagerLocal().dexoptPackage(
                    snapshot, packageName, params);

            return dexOptResult;
            DexoptParams params = getDexoptParamsByInstallRequest(installRequest);
            return getArtManagerLocal().dexoptPackage(snapshot, ps.getPackageName(), params);
        }
    }

+0 −20
Original line number Diff line number Diff line
@@ -573,26 +573,6 @@ public class PackageManagerService implements PackageSender, TestUtilityService
    public static final int MIN_INSTALLABLE_TARGET_SDK =
            Flags.minTargetSdk24() ? Build.VERSION_CODES.N : Build.VERSION_CODES.M;

    // Compilation reasons.
    // TODO(b/260124949): Clean this up with the legacy dexopt code.
    public static final int REASON_FIRST_BOOT = 0;
    public static final int REASON_BOOT_AFTER_OTA = 1;
    public static final int REASON_POST_BOOT = 2;
    public static final int REASON_INSTALL = 3;
    public static final int REASON_INSTALL_FAST = 4;
    public static final int REASON_INSTALL_BULK = 5;
    public static final int REASON_INSTALL_BULK_SECONDARY = 6;
    public static final int REASON_INSTALL_BULK_DOWNGRADED = 7;
    public static final int REASON_INSTALL_BULK_SECONDARY_DOWNGRADED = 8;
    public static final int REASON_BACKGROUND_DEXOPT = 9;
    public static final int REASON_AB_OTA = 10;
    public static final int REASON_INACTIVE_PACKAGE_DOWNGRADE = 11;
    public static final int REASON_CMDLINE = 12;
    public static final int REASON_BOOT_AFTER_MAINLINE_UPDATE = 13;
    public static final int REASON_SHARED = 14;

    public static final int REASON_LAST = REASON_SHARED;

    static final String RANDOM_DIR_PREFIX = "~~";
    static final char RANDOM_CODEPATH_PREFIX = '-';

+0 −93
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.pm;

import android.os.SystemProperties;

import com.android.server.art.model.DexoptParams;

import dalvik.system.DexFile;

/**
 * Manage (retrieve) mappings from compilation reason to compilation filter.
 */
public class PackageManagerServiceCompilerMapping {
    // Names for compilation reasons.
    public static final String REASON_STRINGS[] = {
        "first-boot",
        "boot-after-ota",
        "post-boot",
        "install",
        "install-fast",
        "install-bulk",
        "install-bulk-secondary",
        "install-bulk-downgraded",
        "install-bulk-secondary-downgraded",
        "bg-dexopt",
        "ab-ota",
        "inactive",
        "cmdline",
        "boot-after-mainline-update",
        // "shared" must be the last entry
        "shared"
    };

    static final int REASON_SHARED_INDEX = REASON_STRINGS.length - 1;

    // Static block to ensure the strings array is of the right length.
    static {
        if (PackageManagerService.REASON_LAST + 1 != REASON_STRINGS.length) {
            throw new IllegalStateException("REASON_STRINGS not correct");
        }
        if (!"shared".equals(REASON_STRINGS[REASON_SHARED_INDEX])) {
            throw new IllegalStateException("REASON_STRINGS not correct because of shared index");
        }
    }

    private static String getSystemPropertyName(int reason) {
        if (reason < 0 || reason >= REASON_STRINGS.length) {
            throw new IllegalArgumentException("reason " + reason + " invalid");
        }

        return "pm.dexopt." + REASON_STRINGS[reason];
    }

    // Load the property for the given reason and check for validity. This will throw an
    // exception in case the reason or value are invalid.
    private static String getAndCheckValidity(int reason) {
        String sysPropValue = SystemProperties.get(getSystemPropertyName(reason));
        if (sysPropValue == null || sysPropValue.isEmpty()
                || !(sysPropValue.equals(DexoptParams.COMPILER_FILTER_NOOP)
                        || DexFile.isValidCompilerFilter(sysPropValue))) {
            throw new IllegalStateException("Value \"" + sysPropValue +"\" not valid "
                    + "(reason " + REASON_STRINGS[reason] + ")");
        } else if (!isFilterAllowedForReason(reason, sysPropValue)) {
            throw new IllegalStateException("Value \"" + sysPropValue +"\" not allowed "
                    + "(reason " + REASON_STRINGS[reason] + ")");
        }

        return sysPropValue;
    }

    private static boolean isFilterAllowedForReason(int reason, String filter) {
        return reason != REASON_SHARED_INDEX || !DexFile.isProfileGuidedCompilerFilter(filter);
    }

    public static String getCompilerFilterForReason(int reason) {
        return getAndCheckValidity(reason);
    }
}
+0 −17
Original line number Diff line number Diff line
@@ -49,7 +49,6 @@ import com.android.server.LocalServices;
import com.android.server.art.ArtManagerLocal;
import com.android.server.pm.DexOptHelper;
import com.android.server.pm.PackageManagerLocal;
import com.android.server.pm.PackageManagerServiceCompilerMapping;
import com.android.server.pm.PackageManagerServiceUtils;

import dalvik.system.DexFile;
@@ -81,10 +80,6 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub {

    private final Handler mHandler;

    static {
        verifyTronLoggingConstants();
    }

    public ArtManagerService(Context context) {
        mContext = context;
        mHandler = new Handler(BackgroundThread.getHandler().getLooper());
@@ -476,18 +471,6 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub {
        }
    }

    private static void verifyTronLoggingConstants() {
        for (int i = 0; i < PackageManagerServiceCompilerMapping.REASON_STRINGS.length; i++) {
            String reason = PackageManagerServiceCompilerMapping.REASON_STRINGS[i];
            int value = getCompilationReasonTronValue(reason);
            if (value == TRON_COMPILATION_REASON_ERROR
                    || value == TRON_COMPILATION_REASON_UNKNOWN) {
                throw new IllegalArgumentException("Compilation reason not configured for TRON "
                        + "logging: " + reason);
            }
        }
    }

    private class ArtManagerInternalImpl extends ArtManagerInternal {
        private static final String TAG = "ArtManagerInternalImpl";

+0 −318

File deleted.

Preview size limit exceeded, changes collapsed.

Loading