Start processes asynchronously in AMS.

Currently, process start is initiated in ActivityManagerService
holding the main lock and this takes ~40ms to complete. As seen
in some of the issues in previous releases, this is one of the
contributors of the lock contention in system_server. This change
tries to address this issue by moving the process start outside
the locked section.

When a process start is required, instead of doing it synchronously,
this request will be posted on a handler thread. On the handler thread,
this process start request will be completed without holding a lock.
If for some reason, we decide the process is not needed anymore before
it is actually started or being started, then AMS does everything as
usual removing the references to the process from internal state except
actually killing the process which will be handled on the handler
thread.

Bug: 68775202
Test: Ran app startup perf tests using forrest, will update the bug with results.
Test: https://docs.google.com/spreadsheets/d/1cW81guRALZXKsN-WZsKyQiCSY-RgkJ2m_M9IfqIquz8
Test: cts-tradefed run singleCommand cts-dev -m CtsActivityManagerDeviceTestCases
Test: cts-tradefed run singleCommand cts-dev -m CtsWindowManagerDeviceTestCases
Test: cts-tradefed run singleCommand cts-dev -m CtsAppTestCases
Test: cts-tradefed run singleCommand cts-dev -m CtsMultiUserHostTestCases
Test: adb shell am instrument -e package com.android.server.am -w \
      com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
Test: adb shell am instrument -e class com.android.server.pm.UserManagerTest -w \
      com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
Test: adb shell am instrument -e package android.content -w \
      com.android.frameworks.coretests/android.support.test.runner.AndroidJUnitRunner
Test: cts-tradefed run singleCommand cts-dev -m CtsProviderTestCases
Test: cts-tradefed run singleCommand cts-dev -m CtsContentTestCases -t \
      android.content.cts.ContentResolverTest
Test: cts-tradefed run singleCommand cts-dev -m CtsContentTestCases -t \
      android.content.cts.ContentProviderTest
Test: cts-tradefed run singleCommand cts-dev -m CtsWebkitTestCases
Test: cts-tradefed run singleCommand cts-dev -m CtsHostsideWebViewTests
Test: cts-tradefed run singleCommand cts-dev -m CtsAssistTestCases
Test: make WebViewLoadingTests && make tradefed-all && tradefed.sh \
      run template/local_min --template:map test=WebViewLoadingTests
Test: adb shell setprop wrap.com.google.android.apps.maps \
      '"LIBC_DEBUG_MALLOC_OPTIONS=backtrace logwrapper"'
      && adb shell dumpsys meminfo --unreachable <PID_OF_APP>
      && check ppid of <APP> is logwrapper's pid.
Test: cts-tradefed run singleCommand cts-dev -m CtsWrapWrapNoDebugTestCases
Test: cts-tradefed run singleCommand cts-dev -m CtsWrapWrapDebugTestCases
Test: cts-tradefed run singleCommand cts-dev -m CtsWrapNoWrapTestCases
Test: cts-tradefed run singleCommand cts-dev -m CtsWrapWrapDebugMallocDebugTestCases
Test: manual

Change-Id: I1fe7ce48cd5a4aadccaf6b3d6fdb5cad3304f1d3
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index 71d6604..a1e5947 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -196,6 +196,9 @@
 
     String shortStringName;     // caching of toShortString() result.
     String stringName;          // caching of toString() result.
+    boolean pendingStart;       // Process start is pending.
+    long startSeq;              // Seq no. indicating the latest process start associated with
+                                // this process record.
 
     // These reports are generated & stored when an app gets into an error condition.
     // They will be "null" when all is OK.
@@ -211,6 +214,23 @@
     // App is allowed to manage whitelists such as temporary Power Save mode whitelist.
     boolean whitelistManager;
 
+    // Params used in starting this process.
+    String hostingType;
+    String hostingNameStr;
+    String seInfo;
+    long startTime;
+    // This will be same as {@link #uid} usually except for some apps used during factory testing.
+    int startUid;
+
+    void setStartParams(int startUid, String hostingType, String hostingNameStr, String seInfo,
+            long startTime) {
+        this.startUid = startUid;
+        this.hostingType = hostingType;
+        this.hostingNameStr = hostingNameStr;
+        this.seInfo = seInfo;
+        this.startTime = startTime;
+    }
+
     void dump(PrintWriter pw, String prefix) {
         final long nowUptime = SystemClock.uptimeMillis();
 
@@ -348,6 +368,10 @@
         if (hasStartedServices) {
             pw.print(prefix); pw.print("hasStartedServices="); pw.println(hasStartedServices);
         }
+        if (pendingStart) {
+            pw.print(prefix); pw.print("pendingStart="); pw.println(pendingStart);
+        }
+        pw.print(prefix); pw.print("startSeq="); pw.println(startSeq);
         if (setProcState > ActivityManager.PROCESS_STATE_SERVICE) {
             pw.print(prefix); pw.print("lastCpuTime="); pw.print(lastCpuTime);
                     if (lastCpuTime > 0) {
@@ -627,9 +651,13 @@
             if (noisy) {
                 Slog.i(TAG, "Killing " + toShortString() + " (adj " + setAdj + "): " + reason);
             }
-            EventLog.writeEvent(EventLogTags.AM_KILL, userId, pid, processName, setAdj, reason);
-            Process.killProcessQuiet(pid);
-            ActivityManagerService.killProcessGroup(uid, pid);
+            if (pid > 0) {
+                EventLog.writeEvent(EventLogTags.AM_KILL, userId, pid, processName, setAdj, reason);
+                Process.killProcessQuiet(pid);
+                ActivityManagerService.killProcessGroup(uid, pid);
+            } else {
+                pendingStart = false;
+            }
             if (!persistent) {
                 killed = true;
                 killedByAm = true;