Merge "Move profile registration from bindApplication to LoadedApk" into nyc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
f016d3aef7
@@ -4970,70 +4970,6 @@ public final class ActivityThread {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 static void setupJitProfileSupport(LoadedApk loadedApk, File cacheDir) {
|
|
||||||
if (!SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final ApplicationInfo appInfo = loadedApk.getApplicationInfo();
|
|
||||||
final List<String> codePaths = new ArrayList<>();
|
|
||||||
if ((appInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0) {
|
|
||||||
codePaths.add(appInfo.sourceDir);
|
|
||||||
}
|
|
||||||
if (appInfo.splitSourceDirs != null) {
|
|
||||||
Collections.addAll(codePaths, appInfo.splitSourceDirs);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (codePaths.isEmpty()) {
|
|
||||||
// If there are no code paths there's no need to setup a profile file and register with
|
|
||||||
// the runtime,
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final File profileFile = getPrimaryProfileFile(loadedApk.mPackageName);
|
|
||||||
if (!profileFile.exists()) {
|
|
||||||
FileDescriptor fd = null;
|
|
||||||
try {
|
|
||||||
final int permissions = 0600; // read-write for user.
|
|
||||||
fd = Os.open(profileFile.getAbsolutePath(), OsConstants.O_CREAT, permissions);
|
|
||||||
Os.fchmod(fd, permissions);
|
|
||||||
Os.fchown(fd, appInfo.uid, appInfo.uid);
|
|
||||||
} catch (ErrnoException e) {
|
|
||||||
Log.v(TAG, "Unable to create jit profile file "
|
|
||||||
+ profileFile + ": " + e.getMessage());
|
|
||||||
try {
|
|
||||||
Os.unlink(profileFile.getAbsolutePath());
|
|
||||||
} catch (ErrnoException unlinkErr) {
|
|
||||||
if (unlinkErr.errno != OsConstants.ENOENT) {
|
|
||||||
Log.v(TAG, "Unable to unlink jit profile file "
|
|
||||||
+ profileFile + ": " + unlinkErr.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
} finally {
|
|
||||||
IoUtils.closeQuietly(fd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final File foreignDexProfilesFile =
|
|
||||||
Environment.getDataProfilesDeForeignDexDirectory(UserHandle.myUserId());
|
|
||||||
String foreignDexProfilesPath = null;
|
|
||||||
if (!foreignDexProfilesFile.exists()) {
|
|
||||||
Log.v(TAG, "ForeignDexProfilesPath does not exists:" +
|
|
||||||
foreignDexProfilesFile.getPath());
|
|
||||||
} else {
|
|
||||||
foreignDexProfilesPath = foreignDexProfilesFile.getAbsolutePath();
|
|
||||||
}
|
|
||||||
VMRuntime.registerAppInfo(profileFile.getAbsolutePath(), appInfo.dataDir,
|
|
||||||
codePaths.toArray(new String[codePaths.size()]), foreignDexProfilesPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateDefaultDensity() {
|
private void updateDefaultDensity() {
|
||||||
final int densityDpi = mCurDefaultDisplayDpi;
|
final int densityDpi = mCurDefaultDisplayDpi;
|
||||||
if (!mDensityCompatMode
|
if (!mDensityCompatMode
|
||||||
@@ -5259,18 +5195,13 @@ public final class ActivityThread {
|
|||||||
+ "due to missing cache directory");
|
+ "due to missing cache directory");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup a location to store generated/compiled graphics code and
|
// Setup a location to store generated/compiled graphics code.
|
||||||
// JIT profiling data. Note that this data is stored in a
|
|
||||||
// device-protected storage area, so these caches must never contain
|
|
||||||
// user sensitive user data.
|
|
||||||
final Context deviceContext = appContext.createDeviceProtectedStorageContext();
|
final Context deviceContext = appContext.createDeviceProtectedStorageContext();
|
||||||
final File codeCacheDir = deviceContext.getCodeCacheDir();
|
final File codeCacheDir = deviceContext.getCodeCacheDir();
|
||||||
if (codeCacheDir != null) {
|
if (codeCacheDir != null) {
|
||||||
setupGraphicsSupport(data.info, codeCacheDir);
|
setupGraphicsSupport(data.info, codeCacheDir);
|
||||||
setupJitProfileSupport(data.info, codeCacheDir);
|
|
||||||
} else {
|
} else {
|
||||||
Log.e(TAG, "Unable to setupGraphicsSupport and setupJitProfileSupport " +
|
Log.e(TAG, "Unable to setupGraphicsSupport due to missing code-cache directory");
|
||||||
"due to missing code-cache directory");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the lib dir path to hardware renderer so that vulkan layers
|
// Add the lib dir path to hardware renderer so that vulkan layers
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import android.content.res.AssetManager;
|
|||||||
import android.content.res.CompatibilityInfo;
|
import android.content.res.CompatibilityInfo;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Environment;
|
||||||
import android.os.FileUtils;
|
import android.os.FileUtils;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
@@ -38,6 +39,9 @@ import android.os.StrictMode;
|
|||||||
import android.os.SystemProperties;
|
import android.os.SystemProperties;
|
||||||
import android.os.Trace;
|
import android.os.Trace;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
|
import android.system.Os;
|
||||||
|
import android.system.OsConstants;
|
||||||
|
import android.system.ErrnoException;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.AndroidRuntimeException;
|
import android.util.AndroidRuntimeException;
|
||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
@@ -50,6 +54,7 @@ import android.view.DisplayAdjustments;
|
|||||||
import dalvik.system.VMRuntime;
|
import dalvik.system.VMRuntime;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileDescriptor;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
@@ -62,6 +67,8 @@ import java.util.Enumeration;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import libcore.io.IoUtils;
|
||||||
|
|
||||||
final class IntentReceiverLeaked extends AndroidRuntimeException {
|
final class IntentReceiverLeaked extends AndroidRuntimeException {
|
||||||
public IntentReceiverLeaked(String msg) {
|
public IntentReceiverLeaked(String msg) {
|
||||||
super(msg);
|
super(msg);
|
||||||
@@ -488,6 +495,13 @@ public final class LoadedApk {
|
|||||||
final String add = TextUtils.join(File.pathSeparator, addedPaths);
|
final String add = TextUtils.join(File.pathSeparator, addedPaths);
|
||||||
ApplicationLoaders.getDefault().addPath(mClassLoader, add);
|
ApplicationLoaders.getDefault().addPath(mClassLoader, add);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Setup jit profile support.
|
||||||
|
// It is ok to call this multiple times if the application gets updated with new splits.
|
||||||
|
// The runtime only keeps track of unique code paths and can handle re-registration of
|
||||||
|
// the same code path. There's no need to pass `addedPaths` since any new code paths
|
||||||
|
// are already in `mApplicationInfo`.
|
||||||
|
setupJitProfileSupport();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClassLoader getClassLoader() {
|
public ClassLoader getClassLoader() {
|
||||||
@@ -499,6 +513,83 @@ 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;
|
||||||
|
}
|
||||||
|
final List<String> codePaths = new ArrayList<>();
|
||||||
|
if ((mApplicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0) {
|
||||||
|
codePaths.add(mApplicationInfo.sourceDir);
|
||||||
|
}
|
||||||
|
if (mApplicationInfo.splitSourceDirs != null) {
|
||||||
|
Collections.addAll(codePaths, mApplicationInfo.splitSourceDirs);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (codePaths.isEmpty()) {
|
||||||
|
// If there are no code paths there's no need to setup a profile file and register with
|
||||||
|
// the runtime,
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final File profileFile = getPrimaryProfileFile(mPackageName);
|
||||||
|
if (profileFile.exists()) {
|
||||||
|
if (!profileFile.canRead() || !profileFile.canWrite()) {
|
||||||
|
// The apk might be loaded in a context where we don't have permissions
|
||||||
|
// to track the profile (e.g. when loaded by another app via
|
||||||
|
// createApplicationContext)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Profile does not exist. Create it.
|
||||||
|
FileDescriptor fd = null;
|
||||||
|
try {
|
||||||
|
final int permissions = 0600; // read-write for user.
|
||||||
|
fd = Os.open(profileFile.getAbsolutePath(), OsConstants.O_CREAT, permissions);
|
||||||
|
Os.fchmod(fd, permissions);
|
||||||
|
Os.fchown(fd, mApplicationInfo.uid, mApplicationInfo.uid);
|
||||||
|
} catch (ErrnoException e) {
|
||||||
|
if (e.errno == OsConstants.EACCES) {
|
||||||
|
// It can happen that the profile file does not exist but the apk is loaded in a
|
||||||
|
// context where we don't have permissions (e.g. when loaded by another app via
|
||||||
|
// createApplicationContext)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Log.v(TAG, "Unable to create jit profile file "
|
||||||
|
+ profileFile + ": " + e.getMessage());
|
||||||
|
try {
|
||||||
|
Os.unlink(profileFile.getAbsolutePath());
|
||||||
|
} catch (ErrnoException unlinkErr) {
|
||||||
|
if (unlinkErr.errno != OsConstants.ENOENT) {
|
||||||
|
Log.v(TAG, "Unable to unlink jit profile file "
|
||||||
|
+ profileFile + ": " + unlinkErr.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} finally {
|
||||||
|
IoUtils.closeQuietly(fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final File foreignDexProfilesFile =
|
||||||
|
Environment.getDataProfilesDeForeignDexDirectory(UserHandle.myUserId());
|
||||||
|
String foreignDexProfilesPath = null;
|
||||||
|
if (!foreignDexProfilesFile.exists()) {
|
||||||
|
Log.v(TAG, "ForeignDexProfilesPath does not exists:" +
|
||||||
|
foreignDexProfilesFile.getPath());
|
||||||
|
} else {
|
||||||
|
foreignDexProfilesPath = foreignDexProfilesFile.getAbsolutePath();
|
||||||
|
}
|
||||||
|
VMRuntime.registerAppInfo(profileFile.getAbsolutePath(), mApplicationInfo.dataDir,
|
||||||
|
codePaths.toArray(new String[codePaths.size()]), foreignDexProfilesPath);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setup value for Thread.getContextClassLoader(). If the
|
* Setup value for Thread.getContextClassLoader(). If the
|
||||||
* package will not run in in a VM with other packages, we set
|
* package will not run in in a VM with other packages, we set
|
||||||
|
|||||||
Reference in New Issue
Block a user