Loading core/java/android/os/Environment.java +3 −2 Original line number Diff line number Diff line Loading @@ -291,8 +291,9 @@ public class Environment { } /** {@hide} */ public static File getReferenceProfile(String packageName) { return buildPath(getDataDirectory(), "misc", "profiles", "ref", packageName); public static File getProfileSnapshotPath(String packageName, String codePath) { return buildPath(buildPath(getDataDirectory(), "misc", "profiles", "ref", packageName, "primary.prof.snapshot")); } /** {@hide} */ Loading services/core/java/com/android/server/pm/Installer.java +20 −0 Original line number Diff line number Diff line Loading @@ -496,6 +496,26 @@ public class Installer extends SystemService { } } public boolean createProfileSnapshot(int appId, String packageName, String codePath) throws InstallerException { if (!checkBeforeRemote()) return false; try { return mInstalld.snapshotProfile(appId, packageName, codePath); } catch (Exception e) { throw InstallerException.from(e); } } public void destroyProfileSnapshot(String packageName, String codePath) throws InstallerException { if (!checkBeforeRemote()) return; try { mInstalld.destroyProfileSnapshot(packageName, codePath); } catch (Exception e) { throw InstallerException.from(e); } } public void invalidateMounts() throws InstallerException { if (!checkBeforeRemote()) return; try { Loading services/core/java/com/android/server/pm/PackageManagerService.java +1 −1 Original line number Diff line number Diff line Loading @@ -3038,7 +3038,7 @@ public class PackageManagerService extends IPackageManager.Stub } mInstallerService = new PackageInstallerService(context, this); mArtManagerService = new ArtManagerService(this); mArtManagerService = new ArtManagerService(this, mInstaller, mInstallLock); final Pair<ComponentName, String> instantAppResolverComponent = getInstantAppResolverLPr(); if (instantAppResolverComponent != null) { services/core/java/com/android/server/pm/dex/ArtManagerService.java +81 −3 Original line number Diff line number Diff line Loading @@ -21,15 +21,23 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.dex.ArtManager; import android.os.Binder; import android.os.Environment; import android.os.Handler; import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.content.pm.IPackageManager; import android.content.pm.dex.ISnapshotRuntimeProfileCallback; import android.os.SystemProperties; import android.os.UserHandle; import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.internal.os.BackgroundThread; import com.android.internal.util.Preconditions; import com.android.server.pm.Installer; import com.android.server.pm.Installer.InstallerException; import java.io.File; import java.io.FileNotFoundException; /** * A system service that provides access to runtime and compiler artifacts. Loading @@ -50,10 +58,16 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub { private static boolean DEBUG_IGNORE_PERMISSIONS = false; private final IPackageManager mPackageManager; private final Object mInstallLock; @GuardedBy("mInstallLock") private final Installer mInstaller; private final Handler mHandler; public ArtManagerService(IPackageManager pm) { public ArtManagerService(IPackageManager pm, Installer installer, Object installLock) { mPackageManager = pm; mInstaller = installer; mInstallLock = installLock; mHandler = new Handler(BackgroundThread.getHandler().getLooper()); } Loading Loading @@ -105,8 +119,53 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub { return; } // All good, move forward and get the profile. // All good, create the profile snapshot. createProfileSnapshot(packageName, codePath, callback, info); // Destroy the snapshot, we no longer need it. destroyProfileSnapshot(packageName, codePath); } private void createProfileSnapshot(String packageName, String codePath, ISnapshotRuntimeProfileCallback callback, PackageInfo info) { // Ask the installer to snapshot the profile. synchronized (mInstallLock) { try { if (!mInstaller.createProfileSnapshot(UserHandle.getAppId(info.applicationInfo.uid), packageName, codePath)) { 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 = Environment.getProfileSnapshotPath(packageName, codePath); ParcelFileDescriptor fd; try { fd = ParcelFileDescriptor.open(snapshotProfile, ParcelFileDescriptor.MODE_READ_ONLY); postSuccess(packageName, fd, callback); } catch (FileNotFoundException e) { Slog.w(TAG, "Could not open snapshot profile for " + packageName + ":" + codePath, e); postError(callback, packageName, ArtManager.SNAPSHOT_FAILED_INTERNAL_ERROR); } } private void destroyProfileSnapshot(String packageName, String codePath) { if (DEBUG) { Slog.d(TAG, "Destroying profile snapshot for" + packageName + ":" + codePath); } synchronized (mInstallLock) { try { mInstaller.destroyProfileSnapshot(packageName, codePath); } catch (InstallerException e) { Slog.e(TAG, "Failed to destroy profile snapshot for " + packageName + ":" + codePath, e); } } } @Override Loading @@ -123,6 +182,10 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub { */ 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); Loading @@ -132,6 +195,21 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub { }); } private void postSuccess(String packageName, ParcelFileDescriptor fd, ISnapshotRuntimeProfileCallback callback) { if (DEBUG) { Slog.d(TAG, "Successfully snapshot profile for " + packageName); } mHandler.post(() -> { try { callback.onSuccess(fd); } catch (RemoteException e) { Slog.w(TAG, "Failed to call onSuccess after profile snapshot for " + packageName, e); } }); } /** * Verify that the binder calling uid has {@code android.permission.READ_RUNTIME_PROFILE}. * If not, it throws a {@link SecurityException}. Loading Loading
core/java/android/os/Environment.java +3 −2 Original line number Diff line number Diff line Loading @@ -291,8 +291,9 @@ public class Environment { } /** {@hide} */ public static File getReferenceProfile(String packageName) { return buildPath(getDataDirectory(), "misc", "profiles", "ref", packageName); public static File getProfileSnapshotPath(String packageName, String codePath) { return buildPath(buildPath(getDataDirectory(), "misc", "profiles", "ref", packageName, "primary.prof.snapshot")); } /** {@hide} */ Loading
services/core/java/com/android/server/pm/Installer.java +20 −0 Original line number Diff line number Diff line Loading @@ -496,6 +496,26 @@ public class Installer extends SystemService { } } public boolean createProfileSnapshot(int appId, String packageName, String codePath) throws InstallerException { if (!checkBeforeRemote()) return false; try { return mInstalld.snapshotProfile(appId, packageName, codePath); } catch (Exception e) { throw InstallerException.from(e); } } public void destroyProfileSnapshot(String packageName, String codePath) throws InstallerException { if (!checkBeforeRemote()) return; try { mInstalld.destroyProfileSnapshot(packageName, codePath); } catch (Exception e) { throw InstallerException.from(e); } } public void invalidateMounts() throws InstallerException { if (!checkBeforeRemote()) return; try { Loading
services/core/java/com/android/server/pm/PackageManagerService.java +1 −1 Original line number Diff line number Diff line Loading @@ -3038,7 +3038,7 @@ public class PackageManagerService extends IPackageManager.Stub } mInstallerService = new PackageInstallerService(context, this); mArtManagerService = new ArtManagerService(this); mArtManagerService = new ArtManagerService(this, mInstaller, mInstallLock); final Pair<ComponentName, String> instantAppResolverComponent = getInstantAppResolverLPr(); if (instantAppResolverComponent != null) {
services/core/java/com/android/server/pm/dex/ArtManagerService.java +81 −3 Original line number Diff line number Diff line Loading @@ -21,15 +21,23 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.dex.ArtManager; import android.os.Binder; import android.os.Environment; import android.os.Handler; import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.content.pm.IPackageManager; import android.content.pm.dex.ISnapshotRuntimeProfileCallback; import android.os.SystemProperties; import android.os.UserHandle; import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.internal.os.BackgroundThread; import com.android.internal.util.Preconditions; import com.android.server.pm.Installer; import com.android.server.pm.Installer.InstallerException; import java.io.File; import java.io.FileNotFoundException; /** * A system service that provides access to runtime and compiler artifacts. Loading @@ -50,10 +58,16 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub { private static boolean DEBUG_IGNORE_PERMISSIONS = false; private final IPackageManager mPackageManager; private final Object mInstallLock; @GuardedBy("mInstallLock") private final Installer mInstaller; private final Handler mHandler; public ArtManagerService(IPackageManager pm) { public ArtManagerService(IPackageManager pm, Installer installer, Object installLock) { mPackageManager = pm; mInstaller = installer; mInstallLock = installLock; mHandler = new Handler(BackgroundThread.getHandler().getLooper()); } Loading Loading @@ -105,8 +119,53 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub { return; } // All good, move forward and get the profile. // All good, create the profile snapshot. createProfileSnapshot(packageName, codePath, callback, info); // Destroy the snapshot, we no longer need it. destroyProfileSnapshot(packageName, codePath); } private void createProfileSnapshot(String packageName, String codePath, ISnapshotRuntimeProfileCallback callback, PackageInfo info) { // Ask the installer to snapshot the profile. synchronized (mInstallLock) { try { if (!mInstaller.createProfileSnapshot(UserHandle.getAppId(info.applicationInfo.uid), packageName, codePath)) { 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 = Environment.getProfileSnapshotPath(packageName, codePath); ParcelFileDescriptor fd; try { fd = ParcelFileDescriptor.open(snapshotProfile, ParcelFileDescriptor.MODE_READ_ONLY); postSuccess(packageName, fd, callback); } catch (FileNotFoundException e) { Slog.w(TAG, "Could not open snapshot profile for " + packageName + ":" + codePath, e); postError(callback, packageName, ArtManager.SNAPSHOT_FAILED_INTERNAL_ERROR); } } private void destroyProfileSnapshot(String packageName, String codePath) { if (DEBUG) { Slog.d(TAG, "Destroying profile snapshot for" + packageName + ":" + codePath); } synchronized (mInstallLock) { try { mInstaller.destroyProfileSnapshot(packageName, codePath); } catch (InstallerException e) { Slog.e(TAG, "Failed to destroy profile snapshot for " + packageName + ":" + codePath, e); } } } @Override Loading @@ -123,6 +182,10 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub { */ 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); Loading @@ -132,6 +195,21 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub { }); } private void postSuccess(String packageName, ParcelFileDescriptor fd, ISnapshotRuntimeProfileCallback callback) { if (DEBUG) { Slog.d(TAG, "Successfully snapshot profile for " + packageName); } mHandler.post(() -> { try { callback.onSuccess(fd); } catch (RemoteException e) { Slog.w(TAG, "Failed to call onSuccess after profile snapshot for " + packageName, e); } }); } /** * Verify that the binder calling uid has {@code android.permission.READ_RUNTIME_PROFILE}. * If not, it throws a {@link SecurityException}. Loading