/*
 * Copyright (C) 2017 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.dex;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.AppOpsManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.dex.ArtManager;
import android.content.pm.dex.ArtManager.ProfileType;
import android.content.pm.dex.ArtManagerInternal;
import android.content.pm.dex.DexMetadataHelper;
import android.content.pm.dex.ISnapshotRuntimeProfileCallback;
import android.content.pm.dex.PackageOptimizationInfo;
import android.content.pm.parsing.PackageInfoWithoutStateUtils;
import android.os.Binder;
import android.os.Build;
import android.os.Handler;
import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.RemoteException;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.system.Os;
import android.util.ArrayMap;
import android.util.Log;
import android.util.Slog;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.os.BackgroundThread;
import com.android.internal.os.RoSystemProperties;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.Preconditions;
import com.android.server.LocalServices;
import com.android.server.pm.Installer;
import com.android.server.pm.Installer.InstallerException;
import com.android.server.pm.PackageManagerServiceCompilerMapping;
import com.android.server.pm.parsing.pkg.AndroidPackage;

import dalvik.system.DexFile;
import dalvik.system.VMRuntime;

import libcore.io.IoUtils;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Objects;

/**
 * A system service that provides access to runtime and compiler artifacts.
 *
 * This service is not accessed by users directly, instead one uses an instance of
 * {@link ArtManager}, which can be accessed via {@link PackageManager} as follows:
 * <p/>
 * {@code context().getPackageManager().getArtManager();}
 * <p class="note">
 * Note: Accessing runtime artifacts may require extra permissions. For example querying the
 * runtime profiles of apps requires {@link android.Manifest.permission#READ_RUNTIME_PROFILES}
 * which is a system-level permission that will not be granted to normal apps.
 */
public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub {
    private static final String TAG = "ArtManagerService";
    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);

    // Package name used to create the profile directory layout when
    // taking a snapshot of the boot image profile.
    private static final String BOOT_IMAGE_ANDROID_PACKAGE = "android";
    // Profile name used for the boot image profile.
    private static final String BOOT_IMAGE_PROFILE_NAME = "android.prof";

    private final Context mContext;
    private final IPackageManager mPackageManager;
    private final Object mInstallLock;
    @GuardedBy("mInstallLock")
    private final Installer mInstaller;

    private final Handler mHandler;

    static {
        verifyTronLoggingConstants();
    }

    public ArtManagerService(Context context, IPackageManager pm, Installer installer,
            Object installLock) {
        mContext = context;
        mPackageManager = pm;
        mInstaller = installer;
        mInstallLock = installLock;
        mHandler = new Handler(BackgroundThread.getHandler().getLooper());

        LocalServices.addService(ArtManagerInternal.class, new ArtManagerInternalImpl());
    }

    private boolean checkAndroidPermissions(int callingUid, String callingPackage) {
        // Callers always need this permission
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.READ_RUNTIME_PROFILES, TAG);

        // Callers also need the ability to read usage statistics
        switch (mContext.getSystemService(AppOpsManager.class)
                .noteOp(AppOpsManager.OP_GET_USAGE_STATS, callingUid, callingPackage)) {
            case AppOpsManager.MODE_ALLOWED:
                return true;
            case AppOpsManager.MODE_DEFAULT:
                mContext.enforceCallingOrSelfPermission(
                        android.Manifest.permission.PACKAGE_USAGE_STATS, TAG);
                return true;
            default:
                return false;
        }
    }

    /**
     * Checks if the calling user is the shell user and if it is, it checks if it can
     * to take a profile snapshot of the give package:
     *   - on debuggable builds the shell user can take profile snapshots of any app.
     *   - on non-debuggable builds the shell user can only take snapshots of debuggable apps.
     *
     * Returns true iff the callingUid is the shell uid and the shell is allowed snapshot profiles.
     *
     * Note that the root users will go through the regular {@link #checkAndroidPermissions) checks.
     */
    private boolean checkShellPermissions(@ProfileType int profileType, String packageName,
            int callingUid) {
        if (callingUid != Process.SHELL_UID) {
            return false;
        }
        if (RoSystemProperties.DEBUGGABLE) {
            return true;
        }
        if (profileType == ArtManager.PROFILE_BOOT_IMAGE) {
            // The shell cannot profile the boot image on non-debuggable builds.
            return false;
        }
        PackageInfo info = null;
        try {
            info = mPackageManager.getPackageInfo(packageName, /*flags*/ 0, /*userId*/ 0);
        } catch (RemoteException ignored) {
            // Should not happen.
        }
        if (info == null) {
            return false;
        }

        // On user builds the shell can only profile debuggable apps.
        return (info.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE)
                == ApplicationInfo.FLAG_DEBUGGABLE;
    }


    @Override
    public void snapshotRuntimeProfile(@ProfileType int profileType, @Nullable String packageName,
            @Nullable String codePath, @NonNull ISnapshotRuntimeProfileCallback callback,
            String callingPackage) {
        int callingUid = Binder.getCallingUid();
        if (!checkShellPermissions(profileType, packageName, callingUid) &&
                !checkAndroidPermissions(callingUid, callingPackage)) {
            try {
                callback.onError(ArtManager.SNAPSHOT_FAILED_INTERNAL_ERROR);
            } catch (RemoteException ignored) {
            }
            return;
        }

        // Sanity checks on the arguments.
        Objects.requireNonNull(callback);

        boolean bootImageProfile = profileType == ArtManager.PROFILE_BOOT_IMAGE;
        if (!bootImageProfile) {
            Preconditions.checkStringNotEmpty(codePath);
            Preconditions.checkStringNotEmpty(packageName);
        }

        // Verify that runtime profiling is enabled.
        if (!isRuntimeProfilingEnabled(profileType, callingPackage)) {
            throw new IllegalStateException("Runtime profiling is not enabled for " + profileType);
        }

        if (DEBUG) {
            Slog.d(TAG, "Requested snapshot for " + packageName + ":" + codePath);
        }

        if (bootImageProfile) {
            snapshotBootImageProfile(callback);
        } else {
            snapshotAppProfile(packageName, codePath, callback);
        }
    }

    private void snapshotAppProfile(String packageName, String codePath,
            ISnapshotRuntimeProfileCallback callback) {
        PackageInfo info = null;
        try {
            // Note that we use the default user 0 to retrieve the package info.
            // This doesn't really matter because for user 0 we always get a package back (even if
            // it's not installed for the user 0). It is ok because we only care about the code
            // paths and not if the package is enabled or not for the user.

            // TODO(calin): consider adding an API to PMS which can retrieve the
            // PackageParser.Package.
            info = mPackageManager.getPackageInfo(packageName, /*flags*/ 0, /*userId*/ 0);
        } catch (RemoteException ignored) {
            // Should not happen.
        }
        if (info == null) {
            postError(callback, packageName, ArtManager.SNAPSHOT_FAILED_PACKAGE_NOT_FOUND);
            return;
        }

        boolean pathFound = info.applicationInfo.getBaseCodePath().equals(codePath);
        String splitName = null;
        String[] splitCodePaths = info.applicationInfo.getSplitCodePaths();
        if (!pathFound && (splitCodePaths != null)) {
            for (int i = splitCodePaths.length - 1; i >= 0; i--) {
                if (splitCodePaths[i].equals(codePath)) {
                    pathFound = true;
                    splitName = info.applicationInfo.splitNames[i];
                    break;
                }
            }
        }
        if (!pathFound) {
            postError(callback, packageName, ArtManager.SNAPSHOT_FAILED_CODE_PATH_NOT_FOUND);
            return;
        }

        // All good, create the profile snapshot.
        int appId = UserHandle.getAppId(info.applicationInfo.uid);
        if (appId < 0) {
            postError(callback, packageName, ArtManager.SNAPSHOT_FAILED_INTERNAL_ERROR);
            Slog.wtf(TAG, "AppId is -1 for package: " + packageName);
            return;
        }

        createProfileSnapshot(packageName, ArtManager.getProfileName(splitName), codePath,
                appId, callback);
        // Destroy the snapshot, we no longer need it.
        destroyProfileSnapshot(packageName, ArtManager.getProfileName(splitName));
    }

    private void createProfileSnapshot(String packageName, String profileName, String classpath,
            int appId, ISnapshotRuntimeProfileCallback callback) {
        // Ask the installer to snapshot the profile.
        synchronized (mInstallLock) {
            try {
                if (!mInstaller.createProfileSnapshot(appId, packageName, profileName, classpath)) {
                    postError(callback, packageName, ArtManager.SNAPSHOT_FAILED_INTERNAL_ERROR);
                    return;
                }
            } catch (InstallerException e) {
                postError(callback, packageName, ArtManager.SNAPSHOT_FAILED_INTERNAL_ERROR);
                return;
            }
        }

        // Open the snapshot and invoke the callback.
        File snapshotProfile = ArtManager.getProfileSnapshotFileForName(packageName, profileName);

        ParcelFileDescriptor fd = null;
        try {
            fd = ParcelFileDescriptor.open(snapshotProfile, ParcelFileDescriptor.MODE_READ_ONLY);
            if (fd == null || !fd.getFileDescriptor().valid()) {
                postError(callback, packageName, ArtManager.SNAPSHOT_FAILED_INTERNAL_ERROR);
            } else {
                postSuccess(packageName, fd, callback);
            }
        } catch (FileNotFoundException e) {
            Slog.w(TAG, "Could not open snapshot profile for " + packageName + ":"
                    + snapshotProfile, e);
            postError(callback, packageName, ArtManager.SNAPSHOT_FAILED_INTERNAL_ERROR);
        }
    }

    private void destroyProfileSnapshot(String packageName, String profileName) {
        if (DEBUG) {
            Slog.d(TAG, "Destroying profile snapshot for" + packageName + ":" + profileName);
        }

        synchronized (mInstallLock) {
            try {
                mInstaller.destroyProfileSnapshot(packageName, profileName);
            } catch (InstallerException e) {
                Slog.e(TAG, "Failed to destroy profile snapshot for " +
                    packageName + ":" + profileName, e);
            }
        }
    }

    @Override
    public boolean isRuntimeProfilingEnabled(@ProfileType int profileType, String callingPackage) {
        int callingUid = Binder.getCallingUid();
        if (callingUid != Process.SHELL_UID && !checkAndroidPermissions(callingUid, callingPackage)) {
            return false;
        }

        switch (profileType) {
            case ArtManager.PROFILE_APPS :
                return SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false);
            case ArtManager.PROFILE_BOOT_IMAGE:
                // The device config property overrides the system property version.
                boolean profileBootClassPath = SystemProperties.getBoolean(
                        "persist.device_config.runtime_native_boot.profilebootclasspath",
                        SystemProperties.getBoolean("dalvik.vm.profilebootclasspath", false));
                return (Build.IS_USERDEBUG || Build.IS_ENG) &&
                        SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false) &&
                        profileBootClassPath;
            default:
                throw new IllegalArgumentException("Invalid profile type:" + profileType);
        }
    }

    private void snapshotBootImageProfile(ISnapshotRuntimeProfileCallback callback) {
        // Combine the profiles for boot classpath and system server classpath.
        // This avoids having yet another type of profiles and simplifies the processing.
        String classpath = String.join(":", Os.getenv("BOOTCLASSPATH"),
                Os.getenv("SYSTEMSERVERCLASSPATH"));

        // Create the snapshot.
        createProfileSnapshot(BOOT_IMAGE_ANDROID_PACKAGE, BOOT_IMAGE_PROFILE_NAME, classpath,
                /*appId*/ -1, callback);
        // Destroy the snapshot, we no longer need it.
        destroyProfileSnapshot(BOOT_IMAGE_ANDROID_PACKAGE, BOOT_IMAGE_PROFILE_NAME);
    }

    /**
     * Post {@link ISnapshotRuntimeProfileCallback#onError(int)} with the given error message
     * on the internal {@code mHandler}.
     */
    private void postError(ISnapshotRuntimeProfileCallback callback, String packageName,
            int errCode) {
        if (DEBUG) {
            Slog.d(TAG, "Failed to snapshot profile for " + packageName + " with error: " +
                    errCode);
        }
        mHandler.post(() -> {
            try {
                callback.onError(errCode);
            } catch (Exception e) {
                Slog.w(TAG, "Failed to callback after profile snapshot for " + packageName, e);
            }
        });
    }

    private void postSuccess(String packageName, ParcelFileDescriptor fd,
            ISnapshotRuntimeProfileCallback callback) {
        if (DEBUG) {
            Slog.d(TAG, "Successfully snapshot profile for " + packageName);
        }
        mHandler.post(() -> {
            try {
                // Double check that the descriptor is still valid.
                // We've seen production issues (b/76028139) where this can turn invalid (there are
                // suspicions around the finalizer behaviour).
                if (fd.getFileDescriptor().valid()) {
                    callback.onSuccess(fd);
                } else {
                    Slog.wtf(TAG, "The snapshot FD became invalid before posting the result for "
                            + packageName);
                    callback.onError(ArtManager.SNAPSHOT_FAILED_INTERNAL_ERROR);
                }
            } catch (Exception e) {
                Slog.w(TAG,
                        "Failed to call onSuccess after profile snapshot for " + packageName, e);
            } finally {
                IoUtils.closeQuietly(fd);
            }
        });
    }

    /**
     * Prepare the application profiles.
     * For all code paths:
     *   - create the current primary profile to save time at app startup time.
     *   - copy the profiles from the associated dex metadata file to the reference profile.
     */
    public void prepareAppProfiles(
            AndroidPackage pkg, @UserIdInt int user,
            boolean updateReferenceProfileContent) {
        final int appId = UserHandle.getAppId(pkg.getUid());
        if (user < 0) {
            Slog.wtf(TAG, "Invalid user id: " + user);
            return;
        }
        if (appId < 0) {
            Slog.wtf(TAG, "Invalid app id: " + appId);
            return;
        }
        try {
            ArrayMap<String, String> codePathsProfileNames = getPackageProfileNames(pkg);
            for (int i = codePathsProfileNames.size() - 1; i >= 0; i--) {
                String codePath = codePathsProfileNames.keyAt(i);
                String profileName = codePathsProfileNames.valueAt(i);
                String dexMetadataPath = null;
                // Passing the dex metadata file to the prepare method will update the reference
                // profile content. As such, we look for the dex metadata file only if we need to
                // perform an update.
                if (updateReferenceProfileContent) {
                    File dexMetadata = DexMetadataHelper.findDexMetadataForFile(new File(codePath));
                    dexMetadataPath = dexMetadata == null ? null : dexMetadata.getAbsolutePath();
                }
                synchronized (mInstaller) {
                    boolean result = mInstaller.prepareAppProfile(pkg.getPackageName(), user, appId,
                            profileName, codePath, dexMetadataPath);
                    if (!result) {
                        Slog.e(TAG, "Failed to prepare profile for " +
                                pkg.getPackageName() + ":" + codePath);
                    }
                }
            }
        } catch (InstallerException e) {
            Slog.e(TAG, "Failed to prepare profile for " + pkg.getPackageName(), e);
        }
    }

    /**
     * Prepares the app profiles for a set of users. {@see ArtManagerService#prepareAppProfiles}.
     */
    public void prepareAppProfiles(
            AndroidPackage pkg, int[] user,
            boolean updateReferenceProfileContent) {
        for (int i = 0; i < user.length; i++) {
            prepareAppProfiles(pkg, user[i], updateReferenceProfileContent);
        }
    }

    /**
     * Clear the profiles for the given package.
     */
    public void clearAppProfiles(AndroidPackage pkg) {
        try {
            ArrayMap<String, String> packageProfileNames = getPackageProfileNames(pkg);
            for (int i = packageProfileNames.size() - 1; i >= 0; i--) {
                String profileName = packageProfileNames.valueAt(i);
                mInstaller.clearAppProfiles(pkg.getPackageName(), profileName);
            }
        } catch (InstallerException e) {
            Slog.w(TAG, String.valueOf(e));
        }
    }

    /**
     * Dumps the profiles for the given package.
     */
    public void dumpProfiles(AndroidPackage pkg) {
        final int sharedGid = UserHandle.getSharedAppGid(pkg.getUid());
        try {
            ArrayMap<String, String> packageProfileNames = getPackageProfileNames(pkg);
            for (int i = packageProfileNames.size() - 1; i >= 0; i--) {
                String codePath = packageProfileNames.keyAt(i);
                String profileName = packageProfileNames.valueAt(i);
                synchronized (mInstallLock) {
                    mInstaller.dumpProfiles(sharedGid, pkg.getPackageName(), profileName, codePath);
                }
            }
        } catch (InstallerException e) {
            Slog.w(TAG, "Failed to dump profiles", e);
        }
    }

    /**
     * Compile layout resources in a given package.
     */
    public boolean compileLayouts(AndroidPackage pkg) {
        try {
            final String packageName = pkg.getPackageName();
            final String apkPath = pkg.getBaseCodePath();
            // TODO(b/143971007): Use a cross-user directory
            File dataDir = PackageInfoWithoutStateUtils.getDataDir(pkg, UserHandle.myUserId());
            final String outDexFile = dataDir.getAbsolutePath() + "/code_cache/compiled_view.dex";
            if (pkg.isPrivileged() || pkg.isUseEmbeddedDex()
                    || pkg.isDefaultToDeviceProtectedStorage()) {
                // Privileged apps prefer to load trusted code so they don't use compiled views.
                // If the app is not privileged but prefers code integrity, also avoid compiling
                // views.
                // Also disable the view compiler for protected storage apps since there are
                // selinux permissions required for writing to user_de.
                return false;
            }
            Log.i("PackageManager", "Compiling layouts in " + packageName + " (" + apkPath +
                    ") to " + outDexFile);
            long callingId = Binder.clearCallingIdentity();
            try {
                synchronized (mInstallLock) {
                    return mInstaller.compileLayouts(apkPath, packageName, outDexFile,
                            pkg.getUid());
                }
            } finally {
                Binder.restoreCallingIdentity(callingId);
            }
        }
        catch (Throwable e) {
            Log.e("PackageManager", "Failed to compile layouts", e);
            return false;
        }
    }

    /**
     * Build the profiles names for all the package code paths (excluding resource only paths).
     * Return the map [code path -> profile name].
     */
    private ArrayMap<String, String> getPackageProfileNames(AndroidPackage pkg) {
        ArrayMap<String, String> result = new ArrayMap<>();
        if (pkg.isHasCode()) {
            result.put(pkg.getBaseCodePath(), ArtManager.getProfileName(null));
        }

        String[] splitCodePaths = pkg.getSplitCodePaths();
        int[] splitFlags = pkg.getSplitFlags();
        String[] splitNames = pkg.getSplitNames();
        if (!ArrayUtils.isEmpty(splitCodePaths)) {
            for (int i = 0; i < splitCodePaths.length; i++) {
                if ((splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0) {
                    result.put(splitCodePaths[i], ArtManager.getProfileName(splitNames[i]));
                }
            }
        }
        return result;
    }

    // Constants used for logging compilation filter to TRON.
    // DO NOT CHANGE existing values.
    //
    // NOTE: '-1' value is reserved for the case where we cannot produce a valid
    // PackageOptimizationInfo because the ArtManagerInternal is not ready to be used by the
    // ActivityMetricsLoggers.
    private static final int TRON_COMPILATION_FILTER_ERROR = 0;
    private static final int TRON_COMPILATION_FILTER_UNKNOWN = 1;
    private static final int TRON_COMPILATION_FILTER_ASSUMED_VERIFIED = 2;
    private static final int TRON_COMPILATION_FILTER_EXTRACT = 3;
    private static final int TRON_COMPILATION_FILTER_VERIFY = 4;
    private static final int TRON_COMPILATION_FILTER_QUICKEN = 5;
    private static final int TRON_COMPILATION_FILTER_SPACE_PROFILE = 6;
    private static final int TRON_COMPILATION_FILTER_SPACE = 7;
    private static final int TRON_COMPILATION_FILTER_SPEED_PROFILE = 8;
    private static final int TRON_COMPILATION_FILTER_SPEED = 9;
    private static final int TRON_COMPILATION_FILTER_EVERYTHING_PROFILE = 10;
    private static final int TRON_COMPILATION_FILTER_EVERYTHING = 11;
    private static final int TRON_COMPILATION_FILTER_FAKE_RUN_FROM_APK = 12;
    private static final int TRON_COMPILATION_FILTER_FAKE_RUN_FROM_APK_FALLBACK = 13;
    private static final int TRON_COMPILATION_FILTER_FAKE_RUN_FROM_VDEX_FALLBACK = 14;

    // Constants used for logging compilation reason to TRON.
    // DO NOT CHANGE existing values.
    //
    // NOTE: '-1' value is reserved for the case where we cannot produce a valid
    // PackageOptimizationInfo because the ArtManagerInternal is not ready to be used by the
    // ActivityMetricsLoggers.
    private static final int TRON_COMPILATION_REASON_ERROR = 0;
    private static final int TRON_COMPILATION_REASON_UNKNOWN = 1;
    private static final int TRON_COMPILATION_REASON_FIRST_BOOT = 2;
    private static final int TRON_COMPILATION_REASON_BOOT = 3;
    private static final int TRON_COMPILATION_REASON_INSTALL = 4;
    private static final int TRON_COMPILATION_REASON_BG_DEXOPT = 5;
    private static final int TRON_COMPILATION_REASON_AB_OTA = 6;
    private static final int TRON_COMPILATION_REASON_INACTIVE = 7;
    private static final int TRON_COMPILATION_REASON_SHARED = 8;
    private static final int TRON_COMPILATION_REASON_INSTALL_WITH_DEX_METADATA = 9;

    // The annotation to add as a suffix to the compilation reason when dexopt was
    // performed with dex metadata.
    public static final String DEXOPT_REASON_WITH_DEX_METADATA_ANNOTATION = "-dm";

    /**
     * Convert the compilation reason to an int suitable to be logged to TRON.
     */
    private static int getCompilationReasonTronValue(String compilationReason) {
        switch (compilationReason) {
            case "unknown" : return TRON_COMPILATION_REASON_UNKNOWN;
            case "error" : return TRON_COMPILATION_REASON_ERROR;
            case "first-boot" : return TRON_COMPILATION_REASON_FIRST_BOOT;
            case "boot" : return TRON_COMPILATION_REASON_BOOT;
            case "install" : return TRON_COMPILATION_REASON_INSTALL;
            case "bg-dexopt" : return TRON_COMPILATION_REASON_BG_DEXOPT;
            case "ab-ota" : return TRON_COMPILATION_REASON_AB_OTA;
            case "inactive" : return TRON_COMPILATION_REASON_INACTIVE;
            case "shared" : return TRON_COMPILATION_REASON_SHARED;
            // This is a special marker for dex metadata installation that does not
            // have an equivalent as a system property.
            case "install" + DEXOPT_REASON_WITH_DEX_METADATA_ANNOTATION :
                return TRON_COMPILATION_REASON_INSTALL_WITH_DEX_METADATA;
            default: return TRON_COMPILATION_REASON_UNKNOWN;
        }
    }

    /**
     * Convert the compilation filter to an int suitable to be logged to TRON.
     */
    private static int getCompilationFilterTronValue(String compilationFilter) {
        switch (compilationFilter) {
            case "error" : return TRON_COMPILATION_FILTER_ERROR;
            case "unknown" : return TRON_COMPILATION_FILTER_UNKNOWN;
            case "assume-verified" : return TRON_COMPILATION_FILTER_ASSUMED_VERIFIED;
            case "extract" : return TRON_COMPILATION_FILTER_EXTRACT;
            case "verify" : return TRON_COMPILATION_FILTER_VERIFY;
            case "quicken" : return TRON_COMPILATION_FILTER_QUICKEN;
            case "space-profile" : return TRON_COMPILATION_FILTER_SPACE_PROFILE;
            case "space" : return TRON_COMPILATION_FILTER_SPACE;
            case "speed-profile" : return TRON_COMPILATION_FILTER_SPEED_PROFILE;
            case "speed" : return TRON_COMPILATION_FILTER_SPEED;
            case "everything-profile" : return TRON_COMPILATION_FILTER_EVERYTHING_PROFILE;
            case "everything" : return TRON_COMPILATION_FILTER_EVERYTHING;
            case "run-from-apk" : return TRON_COMPILATION_FILTER_FAKE_RUN_FROM_APK;
            case "run-from-apk-fallback" :
                return TRON_COMPILATION_FILTER_FAKE_RUN_FROM_APK_FALLBACK;
            case "run-from-vdex-fallback" :
                return TRON_COMPILATION_FILTER_FAKE_RUN_FROM_VDEX_FALLBACK;
            default: return TRON_COMPILATION_FILTER_UNKNOWN;
        }
    }

    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 {
        @Override
        public PackageOptimizationInfo getPackageOptimizationInfo(
                ApplicationInfo info, String abi) {
            String compilationReason;
            String compilationFilter;
            try {
                String isa = VMRuntime.getInstructionSet(abi);
                DexFile.OptimizationInfo optInfo =
                        DexFile.getDexFileOptimizationInfo(info.getBaseCodePath(), isa);
                compilationFilter = optInfo.getStatus();
                compilationReason = optInfo.getReason();
            } catch (FileNotFoundException e) {
                Slog.e(TAG, "Could not get optimizations status for " + info.getBaseCodePath(), e);
                compilationFilter = "error";
                compilationReason = "error";
            } catch (IllegalArgumentException e) {
                Slog.wtf(TAG, "Requested optimization status for " + info.getBaseCodePath()
                        + " due to an invalid abi " + abi, e);
                compilationFilter = "error";
                compilationReason = "error";
            }

            int compilationFilterTronValue = getCompilationFilterTronValue(compilationFilter);
            int compilationReasonTronValue = getCompilationReasonTronValue(compilationReason);

            return new PackageOptimizationInfo(
                    compilationFilterTronValue, compilationReasonTronValue);
        }
    }
}
