resolve merge conflicts of 435ad029a3 to master.
Change-Id: I87202d69a772c593b691de8ce2faeaac9b7d1f58
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 177fabe..4531a74 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -101,6 +101,9 @@
import android.view.WindowManagerGlobal;
import android.renderscript.RenderScriptCacheDir;
import android.security.keystore.AndroidKeyStoreProvider;
+import android.system.Os;
+import android.system.OsConstants;
+import android.system.ErrnoException;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.app.IVoiceInteractor;
@@ -820,48 +823,6 @@
setCoreSettings(coreSettings);
- /*
- * Two possible indications that this package could be
- * sharing its runtime with other packages:
- *
- * 1.) the sharedUserId attribute is set in the manifest,
- * indicating a request to share a VM with other
- * packages with the same sharedUserId.
- *
- * 2.) the application element of the manifest has an
- * attribute specifying a non-default process name,
- * indicating the desire to run in another packages VM.
- *
- * If sharing is enabled we do not have a unique application
- * in a process and therefore cannot rely on the package
- * name inside the runtime.
- */
- IPackageManager pm = getPackageManager();
- android.content.pm.PackageInfo pi = null;
- try {
- pi = pm.getPackageInfo(appInfo.packageName, 0, UserHandle.myUserId());
- } catch (RemoteException e) {
- }
- if (pi != null) {
- boolean sharedUserIdSet = (pi.sharedUserId != null);
- boolean processNameNotDefault =
- (pi.applicationInfo != null &&
- !appInfo.packageName.equals(pi.applicationInfo.processName));
- boolean sharable = (sharedUserIdSet || processNameNotDefault);
-
- // Tell the VMRuntime about the application, unless it is shared
- // inside a process.
- if (!sharable) {
- final List<String> codePaths = new ArrayList<>();
- codePaths.add(appInfo.sourceDir);
- if (appInfo.splitSourceDirs != null) {
- Collections.addAll(codePaths, appInfo.splitSourceDirs);
- }
- VMRuntime.registerAppInfo(appInfo.packageName, appInfo.dataDir,
- codePaths.toArray(new String[codePaths.size()]));
- }
- }
-
AppBindData data = new AppBindData();
data.processName = processName;
data.appInfo = appInfo;
@@ -4697,6 +4658,87 @@
}
}
+ private static void setupJitProfileSupport(LoadedApk loadedApk, File cacheDir) {
+ final ApplicationInfo appInfo = loadedApk.getApplicationInfo();
+ if (isSharingRuntime(appInfo)) {
+ // If sharing is enabled we do not have a unique application
+ // in a process and therefore cannot rely on the package
+ // name inside the runtime.
+ return;
+ }
+ 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;
+ }
+
+ // Add an extension to the file name to better reveal its intended use.
+ // Keep in sync with BackgroundDexOptService.
+ final String profileExtension = ".prof";
+ final File profileFile = new File(cacheDir, loadedApk.mPackageName + profileExtension);
+ 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.w(TAG, "Unable to create jit profile file " + profileFile, e);
+ try {
+ Os.unlink(profileFile.getAbsolutePath());
+ } catch (ErrnoException unlinkErr) {
+ Log.v(TAG, "Unable to unlink jit profile file " + profileFile, unlinkErr);
+ }
+ return;
+ } finally {
+ IoUtils.closeQuietly(fd);
+ }
+ }
+
+ VMRuntime.registerAppInfo(profileFile.getAbsolutePath(), appInfo.dataDir,
+ codePaths.toArray(new String[codePaths.size()]));
+ }
+
+ /*
+ * Two possible indications that this package could be
+ * sharing its runtime with other packages:
+ *
+ * 1) the sharedUserId attribute is set in the manifest,
+ * indicating a request to share a VM with other
+ * packages with the same sharedUserId.
+ *
+ * 2) the application element of the manifest has an
+ * attribute specifying a non-default process name,
+ * indicating the desire to run in another packages VM.
+ */
+ private static boolean isSharingRuntime(ApplicationInfo appInfo) {
+ IPackageManager pm = getPackageManager();
+ android.content.pm.PackageInfo pi = null;
+ try {
+ pi = pm.getPackageInfo(appInfo.packageName, 0, UserHandle.myUserId());
+ } catch (RemoteException e) {
+ }
+ if (pi != null) {
+ boolean sharedUserIdSet = (pi.sharedUserId != null);
+ boolean processNameNotDefault = (pi.applicationInfo != null) &&
+ !appInfo.packageName.equals(pi.applicationInfo.processName);
+ boolean sharable = sharedUserIdSet || processNameNotDefault;
+ return sharable;
+ }
+ // We couldn't get information for the package. Be pessimistic and assume
+ // it's sharing the runtime.
+ return true;
+ }
+
private void updateDefaultDensity() {
if (mCurDefaultDisplayDpi != Configuration.DENSITY_DPI_UNDEFINED
&& mCurDefaultDisplayDpi != DisplayMetrics.DENSITY_DEVICE
@@ -4900,12 +4942,14 @@
+ "due to missing cache directory");
}
- // Use codeCacheDir to store generated/compiled graphics code
+ // Use codeCacheDir to store generated/compiled graphics code and jit profiling data.
final File codeCacheDir = appContext.getCodeCacheDir();
if (codeCacheDir != null) {
setupGraphicsSupport(data.info, codeCacheDir);
+ setupJitProfileSupport(data.info, codeCacheDir);
} else {
- Log.e(TAG, "Unable to setupGraphicsSupport due to missing code-cache directory");
+ Log.e(TAG, "Unable to setupGraphicsSupport and setupJitProfileSupport " +
+ "due to missing code-cache directory");
}
}