ART profiler usage.

This is a change to add args to some of the profiler related
functions, including installd commands.

Also read properties and set command line options for the runtime
profiling parameters.

Changed calls to isDexOptNeeded() to isDexOptNeededInternal().  This
needs additional arguments passed for profiles.

Bug: 12877748
Change-Id: I1a426c9309d760bac0cf92daa298defee62287c1

Conflicts:
	core/jni/AndroidRuntime.cpp
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 9243095..b103e71 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -744,8 +744,42 @@
 
             setCoreSettings(coreSettings);
 
-            // Tell the VMRuntime about the application.
-            VMRuntime.registerAppInfo(appInfo.dataDir, appInfo.processName);
+            /*
+             * 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) {
+                    VMRuntime.registerAppInfo(appInfo.packageName, appInfo.dataDir,
+                                            appInfo.processName);
+                }
+            }
 
             AppBindData data = new AppBindData();
             data.processName = processName;
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 96f0d6c..e623d5d 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -780,6 +780,49 @@
         mOptions.add(opt);
     }
 
+    /*
+     * Set profiler options
+     */
+    {
+      char period[sizeof("-Xprofile-period:") + PROPERTY_VALUE_MAX];
+      char duration[sizeof("-Xprofile-duration:") + PROPERTY_VALUE_MAX];
+      char interval[sizeof("-Xprofile-interval:") + PROPERTY_VALUE_MAX];
+      char backoff[sizeof("-Xprofile-backoff:") + PROPERTY_VALUE_MAX];
+
+      // Number of seconds during profile runs.
+      strcpy(period, "-Xprofile-period:");
+      property_get("dalvik.vm.profile.period_secs", period+17, "10");
+      opt.optionString = period;
+      mOptions.add(opt);
+
+      // Length of each profile run (seconds).
+      strcpy(duration, "-Xprofile-duration:");
+      property_get("dalvik.vm.profile.duration_secs", duration+19, "30");
+      opt.optionString = duration;
+      mOptions.add(opt);
+
+
+      // Polling interval during profile run (microseconds).
+      strcpy(interval, "-Xprofile-interval:");
+      property_get("dalvik.vm.profile.interval_us", interval+19, "10000");
+      opt.optionString = interval;
+      mOptions.add(opt);
+
+      // Coefficient for period backoff.  The the period is multiplied
+      // by this value after each profile run.
+      strcpy(backoff, "-Xprofile-backoff:");
+      property_get("dalvik.vm.profile.backoff_coeff", backoff+18, "2.0");
+      opt.optionString = backoff;
+      mOptions.add(opt);
+    }
+
+    /*
+     * We don't have /tmp on the device, but we often have an SD card.  Apps
+     * shouldn't use this, but some test suites might want to exercise it.
+     */
+    opt.optionString = "-Djava.io.tmpdir=/sdcard";
+    mOptions.add(opt);
+
     initArgs.version = JNI_VERSION_1_4;
     initArgs.options = mOptions.editArray();
     initArgs.nOptions = mOptions.size();
diff --git a/services/java/com/android/server/pm/Installer.java b/services/java/com/android/server/pm/Installer.java
index 11a6498..54acda2 100644
--- a/services/java/com/android/server/pm/Installer.java
+++ b/services/java/com/android/server/pm/Installer.java
@@ -208,6 +208,19 @@
         builder.append(' ');
         builder.append(uid);
         builder.append(isPublic ? " 1" : " 0");
+        builder.append(" *");         // No pkgName arg present
+        return execute(builder.toString());
+    }
+
+    public int dexopt(String apkPath, int uid, boolean isPublic, String pkgName) {
+        StringBuilder builder = new StringBuilder("dexopt");
+        builder.append(' ');
+        builder.append(apkPath);
+        builder.append(' ');
+        builder.append(uid);
+        builder.append(isPublic ? " 1" : " 0");
+        builder.append(' ');
+        builder.append(pkgName);
         return execute(builder.toString());
     }
 
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index d8b4f1a1..1bac1db 100755
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -1209,7 +1209,7 @@
                         continue;
                     }
                     try {
-                        if (dalvik.system.DexFile.isDexOptNeeded(lib)) {
+                        if (dalvik.system.DexFile.isDexOptNeededInternal(lib, null, false)) {
                             alreadyDexOpted.add(lib);
                             mInstaller.dexopt(lib, Process.SYSTEM_UID, true);
                             didDexOpt = true;
@@ -1253,7 +1253,7 @@
                         continue;
                     }
                     try {
-                        if (dalvik.system.DexFile.isDexOptNeeded(path)) {
+                        if (dalvik.system.DexFile.isDexOptNeededInternal(path, null, false)) {
                             mInstaller.dexopt(path, Process.SYSTEM_UID, true);
                             didDexOpt = true;
                         }
@@ -3988,7 +3988,8 @@
             String path = pkg.mScanPath;
             int ret = 0;
             try {
-                if (forceDex || dalvik.system.DexFile.isDexOptNeeded(path)) {
+                if (forceDex || dalvik.system.DexFile.isDexOptNeededInternal(path, pkg.packageName,
+                                                                             defer)) {
                     if (!forceDex && defer) {
                         if (mDeferredDexOpt == null) {
                             mDeferredDexOpt = new HashSet<PackageParser.Package>();
@@ -3998,7 +3999,8 @@
                     } else {
                         Log.i(TAG, "Running dexopt on: " + pkg.applicationInfo.packageName);
                         final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
-                        ret = mInstaller.dexopt(path, sharedGid, !isForwardLocked(pkg));
+                        ret = mInstaller.dexopt(path, sharedGid, !isForwardLocked(pkg),
+                                                pkg.packageName);
                         pkg.mDidDexOpt = true;
                         performed = true;
                     }