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

Commit ea6c0ffb authored by Calin Juravle's avatar Calin Juravle Committed by Andreas Gampe
Browse files

[framework] Extend profile operations to take the profile name

Extend the installd profile interface to take the profile name as
argument. This shifts the responsibility for choosing the names of
profiles for primary apks completely to PackageManager. Each of the
application code paths will get an unique profile name based on their
split name.

All the profile operations will now work on a specific profile name rather
than assuming a default global name.

Also, move dumpProfiles and clearProfiles functionality to the
ArtManagerService so that we can re-use profileName computations easier.

(cherry picked from commit 6ae39fc2)

Test: manual (dexopt apps, merge profiles, clear profiles)
      gts GtsAndroidRuntimeManagerHostTestCases
Bug: 30934496

Merged-In: Ie65d45eed7de0844edf4b7af918d7eaa74ec1f2c
Change-Id: Ie65d45eed7de0844edf4b7af918d7eaa74ec1f2c
parent 362b591a
Loading
Loading
Loading
Loading
+10 −13
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.dex.ArtManager;
import android.content.pm.split.SplitDependencyLoader;
import android.content.res.AssetManager;
import android.content.res.CompatibilityInfo;
@@ -35,7 +36,6 @@ import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.FileUtils;
import android.os.Handler;
import android.os.IBinder;
@@ -49,13 +49,15 @@ import android.text.TextUtils;
import android.util.AndroidRuntimeException;
import android.util.ArrayMap;
import android.util.Log;
import android.util.LogPrinter;
import android.util.Slog;
import android.util.SparseArray;
import android.view.Display;
import android.view.DisplayAdjustments;

import com.android.internal.util.ArrayUtils;

import dalvik.system.VMRuntime;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
@@ -729,13 +731,6 @@ public final class LoadedApk {
        }
    }

    // Keep in sync with installd (frameworks/native/cmds/installd/commands.cpp).
    private static File getPrimaryProfileFile(String packageName) {
        File profileDir = Environment.getDataProfilesDePackageDirectory(
                UserHandle.myUserId(), packageName);
        return new File(profileDir, "primary.prof");
    }

    private void setupJitProfileSupport() {
        if (!SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false)) {
            return;
@@ -763,10 +758,12 @@ public final class LoadedApk {
            return;
        }

        final File profileFile = getPrimaryProfileFile(mPackageName);

        VMRuntime.registerAppInfo(profileFile.getPath(),
                codePaths.toArray(new String[codePaths.size()]));
        for (int i = codePaths.size() - 1; i >= 0; i--) {
            String splitName = i == 0 ? null : mApplicationInfo.splitNames[i - 1];
            String profileFile = ArtManager.getCurrentProfilePath(
                    mPackageName, UserHandle.myUserId(), splitName);
            VMRuntime.registerAppInfo(profileFile, new String[] {codePaths.get(i)});
        }

        // Register the app data directory with the reporter. It will
        // help deciding whether or not a dex file is the primary apk or a
+28 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package android.content.pm.dex;
import android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
@@ -26,6 +27,8 @@ import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.util.Slog;

import java.io.File;

/**
 * Class for retrieving various kinds of information related to the runtime artifacts of
 * packages that are currently installed on the device.
@@ -163,4 +166,29 @@ public class ArtManager {
    public static String getProfileName(String splitName) {
        return splitName == null ? "primary.prof" : splitName + ".split.prof";
    }

    /**
     * Return the path to the current profile corresponding to given package and split.
     *
     * @hide
     */
    public static String getCurrentProfilePath(String packageName, int userId, String splitName) {
        File profileDir = Environment.getDataProfilesDePackageDirectory(userId, packageName);
        return new File(profileDir, getProfileName(splitName)).getAbsolutePath();
    }

    /**
     * Return the snapshot profile file for the given package and split.
     *
     * KEEP in sync with installd dexopt.cpp.
     * TODO(calin): inject the snapshot profile name from PM to avoid the dependency.
     *
     * @hide
     */
    public static File getProfileSnapshotFile(String packageName, String splitName) {
        File profileDir = Environment.getDataRefProfilesDePackageDirectory(packageName);
        String snapshotFile = getProfileName(splitName) + ".snapshot";
        return new File(profileDir, snapshotFile);

    }
}
+2 −3
Original line number Diff line number Diff line
@@ -291,9 +291,8 @@ public class Environment {
    }

    /** {@hide} */
    public static File getProfileSnapshotPath(String packageName, String codePath) {
        return buildPath(buildPath(getDataDirectory(), "misc", "profiles", "ref", packageName,
                "primary.prof.snapshot"));
    public static File getDataRefProfilesDePackageDirectory(String packageName) {
        return buildPath(getDataDirectory(), "misc", "profiles", "ref", packageName);
    }

    /** {@hide} */
+1 −1
Original line number Diff line number Diff line
@@ -576,7 +576,7 @@ public class ZygoteInit {
                    installd.dexopt(classPathElement, Process.SYSTEM_UID, packageName,
                            instructionSet, dexoptNeeded, outputPath, dexFlags, compilerFilter,
                            uuid, classLoaderContext, seInfo, false /* downgrade */,
                            targetSdkVersion);
                            targetSdkVersion, /*profileName*/ null);
                } catch (RemoteException | ServiceSpecificException e) {
                    // Ignore (but log), we need this on the classpath for fallback mode.
                    Log.w(TAG, "Failed compiling classpath element for system server: "
+17 −16
Original line number Diff line number Diff line
@@ -285,43 +285,44 @@ public class Installer extends SystemService {
    public void dexopt(String apkPath, int uid, @Nullable String pkgName, String instructionSet,
            int dexoptNeeded, @Nullable String outputPath, int dexFlags,
            String compilerFilter, @Nullable String volumeUuid, @Nullable String sharedLibraries,
            @Nullable String seInfo, boolean downgrade, int targetSdkVersion)
            throws InstallerException {
            @Nullable String seInfo, boolean downgrade, int targetSdkVersion,
            @Nullable String profileName) throws InstallerException {
        assertValidInstructionSet(instructionSet);
        if (!checkBeforeRemote()) return;
        try {
            mInstalld.dexopt(apkPath, uid, pkgName, instructionSet, dexoptNeeded, outputPath,
                    dexFlags, compilerFilter, volumeUuid, sharedLibraries, seInfo, downgrade,
                    targetSdkVersion);
                    targetSdkVersion, profileName);
        } catch (Exception e) {
            throw InstallerException.from(e);
        }
    }

    public boolean mergeProfiles(int uid, String packageName) throws InstallerException {
    public boolean mergeProfiles(int uid, String packageName, String profileName)
            throws InstallerException {
        if (!checkBeforeRemote()) return false;
        try {
            return mInstalld.mergeProfiles(uid, packageName);
            return mInstalld.mergeProfiles(uid, packageName, profileName);
        } catch (Exception e) {
            throw InstallerException.from(e);
        }
    }

    public boolean dumpProfiles(int uid, String packageName, String codePaths)
    public boolean dumpProfiles(int uid, String packageName, String profileName, String codePath)
            throws InstallerException {
        if (!checkBeforeRemote()) return false;
        try {
            return mInstalld.dumpProfiles(uid, packageName, codePaths);
            return mInstalld.dumpProfiles(uid, packageName, profileName, codePath);
        } catch (Exception e) {
            throw InstallerException.from(e);
        }
    }

    public boolean copySystemProfile(String systemProfile, int uid, String packageName)
            throws InstallerException {
    public boolean copySystemProfile(String systemProfile, int uid, String packageName,
                String profileName) throws InstallerException {
        if (!checkBeforeRemote()) return false;
        try {
            return mInstalld.copySystemProfile(systemProfile, uid, packageName);
            return mInstalld.copySystemProfile(systemProfile, uid, packageName, profileName);
        } catch (Exception e) {
            throw InstallerException.from(e);
        }
@@ -365,10 +366,10 @@ public class Installer extends SystemService {
        }
    }

    public void clearAppProfiles(String packageName) throws InstallerException {
    public void clearAppProfiles(String packageName, String profileName) throws InstallerException {
        if (!checkBeforeRemote()) return;
        try {
            mInstalld.clearAppProfiles(packageName);
            mInstalld.clearAppProfiles(packageName, profileName);
        } catch (Exception e) {
            throw InstallerException.from(e);
        }
@@ -501,21 +502,21 @@ public class Installer extends SystemService {
        }
    }

    public boolean createProfileSnapshot(int appId, String packageName, String codePath)
    public boolean createProfileSnapshot(int appId, String packageName, String profileName)
            throws InstallerException {
        if (!checkBeforeRemote()) return false;
        try {
            return mInstalld.createProfileSnapshot(appId, packageName, codePath);
            return mInstalld.createProfileSnapshot(appId, packageName, profileName);
        } catch (Exception e) {
            throw InstallerException.from(e);
        }
    }

    public void destroyProfileSnapshot(String packageName, String codePath)
    public void destroyProfileSnapshot(String packageName, String profileName)
            throws InstallerException {
        if (!checkBeforeRemote()) return;
        try {
            mInstalld.destroyProfileSnapshot(packageName, codePath);
            mInstalld.destroyProfileSnapshot(packageName, profileName);
        } catch (Exception e) {
            throw InstallerException.from(e);
        }
Loading