Improve ActivityManagerInternal.startIsolatedProcess.

The processes created by ActivityManagerInternal.startIsolatedProcess
were not being tracked by ActivityManager after creation (other than to
handle crashes), but they still had ProcessRecords created for them.
This meant that if a second process was started with the same name, a
WTF would be triggered due to the old ProcessRecord still existing.

To resolve this, we change the way that these special isolated processes
start up: instead of directly executing the main() of the requested
class after forking, the process first runs ActivityThread as with
ordinary processes. When the process attaches to ActivityManagerService,
it is given the name and parameters of the entry point class to execute
instead of being given an ApplicationInfo to bind. We also reinstate the
previously-disabled process start timeout, since the process is now
expected to attach as normal.

This means that ActivityManagerService can observe the process's death
via Binder as usual and clean up the ProcessRecord, as well as making
this process less of a special case. To ensure the process is still
treated as important, we set a minimum OOM adjustment of
PERSISTENT_SERVICE_ADJ (which is accurate as the system server is
depending on the process even though it does not directly bind to it as
a service), and exclude processes of this type from being killed due to
being empty isolated processes. The process will exit voluntarily after
the entry point function returns instead.

Bug: 19061358
Test: Upgrade the current WebView implementation APK and check for WTFs
Change-Id: Ide4f89d308851bb591194a8d59e6d581e9d59b50
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index 411e973..0e318d9 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -47,6 +47,7 @@
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Arrays;
 
 /**
  * Full information about a particular process that
@@ -174,6 +175,9 @@
     // All ContentProviderRecord process is using
     final ArrayList<ContentProviderConnection> conProviders = new ArrayList<>();
 
+    String isolatedEntryPoint;  // Class to run on start if this is a special isolated process.
+    String[] isolatedEntryPointArgs; // Arguments to pass to isolatedEntryPoint's main().
+
     boolean execServicesFg;     // do we need to be executing services in the foreground?
     boolean persistent;         // always keep this application running?
     boolean crashing;           // are we in the process of crashing?
@@ -379,6 +383,11 @@
         if (whitelistManager) {
             pw.print(prefix); pw.print("whitelistManager="); pw.println(whitelistManager);
         }
+        if (isolatedEntryPoint != null || isolatedEntryPointArgs != null) {
+            pw.print(prefix); pw.print("isolatedEntryPoint="); pw.println(isolatedEntryPoint);
+            pw.print(prefix); pw.print("isolatedEntryPointArgs=");
+            pw.println(Arrays.toString(isolatedEntryPointArgs));
+        }
         if (activities.size() > 0) {
             pw.print(prefix); pw.println("Activities:");
             for (int i=0; i<activities.size(); i++) {