diff options
6 files changed, 159 insertions, 59 deletions
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index f0982d3aa142..460de731565a 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -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 " diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 0b9e3bb1b99e..ac96a1bf60e9 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -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); diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java index 4bfbb78e4187..3c57c3bcb7d6 100644 --- a/services/core/java/com/android/server/am/BroadcastQueue.java +++ b/services/core/java/com/android/server/am/BroadcastQueue.java @@ -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 index 000000000000..3295657b77ad --- /dev/null +++ b/services/core/java/com/android/server/am/HostingRecord.java @@ -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; + } +} diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index 9780a7f71970..e8f4f1e57a2e 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -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); diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java index ce13cd88a192..28862653d90a 100644 --- a/services/core/java/com/android/server/am/ProcessRecord.java +++ b/services/core/java/com/android/server/am/ProcessRecord.java @@ -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; } |