OSDN Git Service

Refactor hostingType/hostingName/hostingNameStr.
authorMartijn Coenen <maco@google.com>
Thu, 28 Mar 2019 13:09:38 +0000 (14:09 +0100)
committerMartijn Coenen <maco@google.com>
Fri, 12 Apr 2019 12:05:01 +0000 (14:05 +0200)
These are parameters to various startProcess calls, and have been
overloaded to mean different things. In most cases, the hostingType
describes why we asked to start the process, or what type of component
we were starting it for; examples: "content provider", "service". But,
it is also used to indicate that a process should use either the Webview
or Application zygote, eg "webview_zygote". In some cases (eg for the
system process), it can be null.

The hostingName parameter is a ComponentName, which is the component we
are intending to host in the process. There are also instances where we
take a String instead of a ComponentName. This parameter is actually
only used for logging purposes, and doesn't really have any functional
effects.

To that end, introduce a new HostingRecord class to be used in the
startProcess() calls, which replaces the previous
hostingType/hostingName/hostingNameStr paramaters.

It removes the "zygote" overload and makes that explicit, and directly
converts the ComponentName to a String (since that is the only
representation of it that is used anyway).

The main reason to do this refactor now is that we need to have some
more information when starting a process for a BIND_EXTERNAL service
that use the application zygote; adding yet another parameter to
startProcess() didn't seem like the right way to go.

In the future, more information can be moved into this class, in order
to clean up the startProcess(...) calls, which have become rather
complicated.

Bug: 127820394
Test: Device boots
Change-Id: I6569bb4533ea829071e8715b7f22df918009dd08

services/core/java/com/android/server/am/ActiveServices.java
services/core/java/com/android/server/am/ActivityManagerService.java
services/core/java/com/android/server/am/BroadcastQueue.java
services/core/java/com/android/server/am/HostingRecord.java [new file with mode: 0644]
services/core/java/com/android/server/am/ProcessList.java
services/core/java/com/android/server/am/ProcessRecord.java

index f0982d3..460de73 100644 (file)
@@ -2557,7 +2557,7 @@ public final class ActiveServices {
 
         final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
         final String procName = r.processName;
-        String hostingType = "service";
+        HostingRecord hostingRecord = new HostingRecord("service", r.instanceName);
         ProcessRecord app;
 
         if (!isolated) {
@@ -2588,10 +2588,10 @@ public final class ActiveServices {
             app = r.isolatedProc;
             if (WebViewZygote.isMultiprocessEnabled()
                     && r.serviceInfo.packageName.equals(WebViewZygote.getPackageName())) {
-                hostingType = "webview_service";
+                hostingRecord = HostingRecord.byWebviewZygote(r.instanceName);
             }
             if ((r.serviceInfo.flags & ServiceInfo.FLAG_USE_APP_ZYGOTE) != 0) {
-                hostingType = "app_zygote";
+                hostingRecord = HostingRecord.byAppZygote(r.instanceName);
             }
         }
 
@@ -2599,7 +2599,7 @@ public final class ActiveServices {
         // to be executed when the app comes up.
         if (app == null && !permissionsReviewRequired) {
             if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
-                    hostingType, r.instanceName, false, isolated, false)) == null) {
+                    hostingRecord, false, isolated, false)) == null) {
                 String msg = "Unable to launch app "
                         + r.appInfo.packageName + "/"
                         + r.appInfo.uid + " for service "
index 0b9e3bb..ac96a1b 100644 (file)
@@ -1498,6 +1498,7 @@ public class ActivityManagerService extends IActivityManager.Stub
 
     private ParcelFileDescriptor[] mLifeMonitorFds;
 
+    static final HostingRecord sNullHostingRecord = new HostingRecord(null);
     /**
      * Used to notify activity lifecycle events.
      */
@@ -2894,8 +2895,9 @@ public class ActivityManagerService extends IActivityManager.Stub
             info.seInfoUser = SELinuxUtil.COMPLETE_STR;
             info.targetSdkVersion = Build.VERSION.SDK_INT;
             ProcessRecord proc = mProcessList.startProcessLocked(processName, info /* info */,
-                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
-                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
+                    false /* knownToBeDead */, 0 /* intentFlags */,
+                    sNullHostingRecord  /* hostingRecord */,
+                    true /* allowWhileBooting */, true /* isolated */,
                     uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
                     crashHandler);
             return proc != null;
@@ -2905,11 +2907,10 @@ public class ActivityManagerService extends IActivityManager.Stub
     @GuardedBy("this")
     final ProcessRecord startProcessLocked(String processName,
             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
-            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
+            HostingRecord hostingRecord, boolean allowWhileBooting,
             boolean isolated, boolean keepIfLarge) {
         return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
-                hostingType,
-                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
+                hostingRecord, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
                 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
                 null /* crashHandler */);
     }
@@ -4692,7 +4693,8 @@ public class ActivityManagerService extends IActivityManager.Stub
             app.deathRecipient = adr;
         } catch (RemoteException e) {
             app.resetPackageList(mProcessStats);
-            mProcessList.startProcessLocked(app, "link fail", processName);
+            mProcessList.startProcessLocked(app,
+                    new HostingRecord("link fail", processName));
             return false;
         }
 
@@ -4931,7 +4933,7 @@ public class ActivityManagerService extends IActivityManager.Stub
 
             app.resetPackageList(mProcessStats);
             app.unlinkDeathRecipient();
-            mProcessList.startProcessLocked(app, "bind fail", processName);
+            mProcessList.startProcessLocked(app, new HostingRecord("bind-fail", processName));
             return false;
         }
 
@@ -5013,8 +5015,8 @@ public class ActivityManagerService extends IActivityManager.Stub
                 app.startTime,
                 (int) (bindApplicationTimeMillis - app.startTime),
                 (int) (SystemClock.elapsedRealtime() - app.startTime),
-                app.hostingType,
-                (app.hostingNameStr != null ? app.hostingNameStr : ""));
+                app.hostingRecord.getType(),
+                (app.hostingRecord.getName() != null ? app.hostingRecord.getName() : ""));
         return true;
     }
 
@@ -5123,7 +5125,7 @@ public class ActivityManagerService extends IActivityManager.Stub
                 for (int ip=0; ip<NP; ip++) {
                     if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
                             + procs.get(ip));
-                    mProcessList.startProcessLocked(procs.get(ip), "on-hold", null);
+                    mProcessList.startProcessLocked(procs.get(ip), new HostingRecord("on-hold"));
                 }
             }
             if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
@@ -6915,9 +6917,10 @@ public class ActivityManagerService extends IActivityManager.Stub
                         } else {
                             checkTime(startTime, "getContentProviderImpl: before start process");
                             proc = startProcessLocked(cpi.processName,
-                                    cpr.appInfo, false, 0, "content provider",
+                                    cpr.appInfo, false, 0,
+                                    new HostingRecord("content provider",
                                     new ComponentName(cpi.applicationInfo.packageName,
-                                            cpi.name), false, false, false);
+                                            cpi.name)), false, false, false);
                             checkTime(startTime, "getContentProviderImpl: after start process");
                             if (proc == null) {
                                 Slog.w(TAG, "Unable to launch app "
@@ -7659,9 +7662,9 @@ public class ActivityManagerService extends IActivityManager.Stub
         }
         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
             mPersistentStartingProcesses.add(app);
-            mProcessList.startProcessLocked(app, "added application",
-                    customProcess != null ? customProcess : app.processName, disableHiddenApiChecks,
-                    mountExtStorageFull, abiOverride);
+            mProcessList.startProcessLocked(app, new HostingRecord("added application",
+                    customProcess != null ? customProcess : app.processName),
+                    disableHiddenApiChecks, mountExtStorageFull, abiOverride);
         }
 
         return app;
@@ -13611,7 +13614,8 @@ public class ActivityManagerService extends IActivityManager.Stub
             }
             mProcessList.addProcessNameLocked(app);
             app.pendingStart = false;
-            mProcessList.startProcessLocked(app, "restart", app.processName);
+            mProcessList.startProcessLocked(app,
+                    new HostingRecord("restart", app.processName));
             return true;
         } else if (app.pid > 0 && app.pid != MY_PID) {
             // Goodbye!
@@ -13952,9 +13956,12 @@ public class ActivityManagerService extends IActivityManager.Stub
                     (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
                             ? new ComponentName(app.packageName, app.backupAgentName)
                             : new ComponentName("android", "FullBackupAgent");
+
             // startProcessLocked() returns existing proc's record if it's already running
             ProcessRecord proc = startProcessLocked(app.processName, app,
-                    false, 0, "backup", hostingName, false, false, false);
+                    false, 0,
+                    new HostingRecord("backup", hostingName),
+                    false, false, false);
             if (proc == null) {
                 Slog.e(TAG, "Unable to start backup agent process " + r);
                 return false;
@@ -18163,8 +18170,9 @@ public class ActivityManagerService extends IActivityManager.Stub
                 }
                 synchronized (ActivityManagerService.this) {
                     startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
-                            hostingType, hostingName, false /* allowWhileBooting */,
-                            false /* isolated */, true /* keepIfLarge */);
+                            new HostingRecord(hostingType, hostingName),
+                            false /* allowWhileBooting */, false /* isolated */,
+                            true /* keepIfLarge */);
                 }
             } finally {
                 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
index 4bfbb78..3c57c3b 100644 (file)
@@ -1623,7 +1623,7 @@ public final class BroadcastQueue {
         if ((r.curApp=mService.startProcessLocked(targetProcess,
                 info.activityInfo.applicationInfo, true,
                 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
-                "broadcast", r.curComponent,
+                new HostingRecord("broadcast", r.curComponent),
                 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0, false, false))
                         == null) {
             // Ah, this recipient is unavailable.  Finish it if necessary,
diff --git a/services/core/java/com/android/server/am/HostingRecord.java b/services/core/java/com/android/server/am/HostingRecord.java
new file mode 100644 (file)
index 0000000..3295657
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.am;
+
+import android.content.ComponentName;
+
+/**
+ * This class describes various information required to start a process.
+ *
+ * The {@link #mHostingType} parameter describes the reason why we started a process, and
+ * is only used for logging and stats.
+ *
+ * The {@link #mHostingName} parameter describes the Component for which we are starting the
+ * process, and is only used for logging and stats.
+ *
+ * The {@link #mHostingZygote} describes from which Zygote the new process should be spawned.
+ *
+ */
+
+public final class HostingRecord {
+    private static final int REGULAR_ZYGOTE = 0;
+    private static final int WEBVIEW_ZYGOTE = 1;
+    private static final int APP_ZYGOTE = 2;
+
+    private final String mHostingType;
+    private final String mHostingName;
+    private final int mHostingZygote;
+
+    public HostingRecord(String hostingType) {
+        this(hostingType, null, REGULAR_ZYGOTE);
+    }
+
+    public HostingRecord(String hostingType, ComponentName hostingName) {
+        this(hostingType, hostingName.toShortString(), REGULAR_ZYGOTE);
+    }
+
+    public HostingRecord(String hostingType, String hostingName) {
+        this(hostingType, hostingName, REGULAR_ZYGOTE);
+    }
+
+    private HostingRecord(String hostingType, String hostingName, int hostingZygote) {
+        mHostingType = hostingType;
+        mHostingName = hostingName;
+        mHostingZygote = hostingZygote;
+    }
+
+    public String getType() {
+        return mHostingType;
+    }
+
+    public String getName() {
+        return mHostingName;
+    }
+
+    /**
+     * Creates a HostingRecord for a process that must spawn from the webview zygote
+     * @param hostingName name of the component to be hosted in this process
+     * @return The constructed HostingRecord
+     */
+    public static HostingRecord byWebviewZygote(ComponentName hostingName) {
+        return new HostingRecord("", hostingName.toShortString(), WEBVIEW_ZYGOTE);
+    }
+
+    /**
+     * Creates a HostingRecord for a process that must spawn from the application zygote
+     * @param hostingName name of the component to be hosted in this process
+     * @return The constructed HostingRecord
+     */
+    public static HostingRecord byAppZygote(ComponentName hostingName) {
+        return new HostingRecord("", hostingName.toShortString(), APP_ZYGOTE);
+    }
+
+    /**
+     * @return whether the process should spawn from the application zygote
+     */
+    public boolean usesAppZygote() {
+        return mHostingZygote == APP_ZYGOTE;
+    }
+
+    /**
+     * @return whether the process should spawn from the webview zygote
+     */
+    public boolean usesWebviewZygote() {
+        return mHostingZygote == WEBVIEW_ZYGOTE;
+    }
+}
index 9780a7f..e8f4f1e 100644 (file)
@@ -1427,14 +1427,13 @@ public final class ProcessList {
     /**
      * @return {@code true} if process start is successful, false otherwise.
      * @param app
-     * @param hostingType
-     * @param hostingNameStr
+     * @param hostingRecord
      * @param disableHiddenApiChecks
      * @param abiOverride
      */
     @GuardedBy("mService")
-    boolean startProcessLocked(ProcessRecord app, String hostingType,
-            String hostingNameStr, boolean disableHiddenApiChecks, boolean mountExtStorageFull,
+    boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
+            boolean disableHiddenApiChecks, boolean mountExtStorageFull,
             String abiOverride) {
         if (app.pendingStart) {
             return true;
@@ -1625,7 +1624,7 @@ public final class ProcessList {
             // the PID of the new process, or else throw a RuntimeException.
             final String entryPoint = "android.app.ActivityThread";
 
-            return startProcessLocked(hostingType, hostingNameStr, entryPoint, app, uid, gids,
+            return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,
                     runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
                     startTime);
         } catch (RuntimeException e) {
@@ -1644,7 +1643,7 @@ public final class ProcessList {
     }
 
     @GuardedBy("mService")
-    boolean startProcessLocked(String hostingType, String hostingNameStr,
+    boolean startProcessLocked(HostingRecord hostingRecord,
             String entryPoint,
             ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
             String seInfo, String requiredAbi, String instructionSet, String invokeWith,
@@ -1654,7 +1653,7 @@ public final class ProcessList {
         app.removed = false;
         app.killed = false;
         final long startSeq = app.startSeq = ++mProcStartSeqCounter;
-        app.setStartParams(uid, hostingType, hostingNameStr, seInfo, startTime);
+        app.setStartParams(uid, hostingRecord, seInfo, startTime);
         if (mService.mConstants.FLAG_PROCESS_START_ASYNC) {
             if (DEBUG_PROCESSES) Slog.i(TAG_PROCESSES,
                     "Posting procStart msg for " + app.toShortString());
@@ -1672,7 +1671,7 @@ public final class ProcessList {
                                 || SystemProperties.get("wrap." + app.processName) != null);
                         mPendingStarts.put(startSeq, app);
                     }
-                    final Process.ProcessStartResult startResult = startProcess(app.hostingType,
+                    final Process.ProcessStartResult startResult = startProcess(app.hostingRecord,
                             entryPoint, app, app.startUid, gids, runtimeFlags, mountExternal,
                             app.seInfo, requiredAbi, instructionSet, invokeWith, app.startTime);
                     synchronized (mService) {
@@ -1693,7 +1692,7 @@ public final class ProcessList {
             return true;
         } else {
             try {
-                final Process.ProcessStartResult startResult = startProcess(hostingType,
+                final Process.ProcessStartResult startResult = startProcess(hostingRecord,
                         entryPoint, app,
                         uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet,
                         invokeWith, startTime);
@@ -1781,7 +1780,7 @@ public final class ProcessList {
         }
     }
 
-    private Process.ProcessStartResult startProcess(String hostingType, String entryPoint,
+    private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
             ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
             String seInfo, String requiredAbi, String instructionSet, String invokeWith,
             long startTime) {
@@ -1797,7 +1796,7 @@ public final class ProcessList {
                     app.processName);
             checkSlow(startTime, "startProcess: asking zygote to start proc");
             final Process.ProcessStartResult startResult;
-            if (hostingType.equals("webview_service")) {
+            if (hostingRecord.usesWebviewZygote()) {
                 startResult = startWebView(entryPoint,
                         app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
@@ -1805,7 +1804,7 @@ public final class ProcessList {
                         packageNames, sandboxId,
                         new String[] {PROC_START_SEQ_IDENT + app.startSeq},
                         useSystemGraphicsDriver);
-            } else if (hostingType.equals("app_zygote")) {
+            } else if (hostingRecord.usesAppZygote()) {
                 final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);
 
                 startResult = appZygote.getProcess().start(entryPoint,
@@ -1832,21 +1831,20 @@ public final class ProcessList {
     }
 
     @GuardedBy("mService")
-    final void startProcessLocked(ProcessRecord app,
-            String hostingType, String hostingNameStr) {
-        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */);
+    final void startProcessLocked(ProcessRecord app, HostingRecord hostingRecord) {
+        startProcessLocked(app, hostingRecord, null /* abiOverride */);
     }
 
     @GuardedBy("mService")
-    final boolean startProcessLocked(ProcessRecord app,
-            String hostingType, String hostingNameStr, String abiOverride) {
-        return startProcessLocked(app, hostingType, hostingNameStr,
+    final boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
+            String abiOverride) {
+        return startProcessLocked(app, hostingRecord,
                 false /* disableHiddenApiChecks */, false /* mountExtStorageFull */, abiOverride);
     }
 
     @GuardedBy("mService")
     final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
-            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
+            boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,
             boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
             String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
         long startTime = SystemClock.elapsedRealtime();
@@ -1916,11 +1914,8 @@ public final class ProcessList {
             checkSlow(startTime, "startProcess: done killing old proc");
         }
 
-        String hostingNameStr = hostingName != null
-                ? hostingName.flattenToShortString() : null;
-
         if (app == null) {
-            final boolean fromAppZygote = "app_zygote".equals(hostingType);
+            final boolean fromAppZygote = hostingRecord.usesAppZygote();
             checkSlow(startTime, "startProcess: creating new process record");
             app = newProcessRecordLocked(info, processName, isolated, isolatedUid, fromAppZygote);
             if (app == null) {
@@ -1953,8 +1948,7 @@ public final class ProcessList {
         }
 
         checkSlow(startTime, "startProcess: stepping in to startProcess");
-        final boolean success = startProcessLocked(app, hostingType, hostingNameStr,
-                abiOverride);
+        final boolean success = startProcessLocked(app, hostingRecord, abiOverride);
         checkSlow(startTime, "startProcess: done starting proc!");
         return success ? app : null;
     }
@@ -2015,8 +2009,8 @@ public final class ProcessList {
 
         EventLog.writeEvent(EventLogTags.AM_PROC_START,
                 UserHandle.getUserId(app.startUid), pid, app.startUid,
-                app.processName, app.hostingType,
-                app.hostingNameStr != null ? app.hostingNameStr : "");
+                app.processName, app.hostingRecord.getType(),
+                app.hostingRecord.getName() != null ? app.hostingRecord.getName() : "");
 
         try {
             AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
@@ -2044,10 +2038,10 @@ public final class ProcessList {
             buf.append("]");
         }
         buf.append(" for ");
-        buf.append(app.hostingType);
-        if (app.hostingNameStr != null) {
+        buf.append(app.hostingRecord.getType());
+        if (app.hostingRecord.getName() != null) {
             buf.append(" ");
-            buf.append(app.hostingNameStr);
+            buf.append(app.hostingRecord.getName());
         }
         mService.reportUidInfoMessageLocked(TAG, buf.toString(), app.startUid);
         app.setPid(pid);
index ce13cd8..2886265 100644 (file)
@@ -301,18 +301,16 @@ class ProcessRecord implements WindowProcessListener {
     boolean whitelistManager;
 
     // Params used in starting this process.
-    String hostingType;
-    String hostingNameStr;
+    HostingRecord hostingRecord;
     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,
+    void setStartParams(int startUid, HostingRecord hostingRecord, String seInfo,
             long startTime) {
         this.startUid = startUid;
-        this.hostingType = hostingType;
-        this.hostingNameStr = hostingNameStr;
+        this.hostingRecord = hostingRecord;
         this.seInfo = seInfo;
         this.startTime = startTime;
     }