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) {
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);
}
}
// 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 "
private ParcelFileDescriptor[] mLifeMonitorFds;
+ static final HostingRecord sNullHostingRecord = new HostingRecord(null);
/**
* Used to notify activity lifecycle events.
*/
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;
@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 */);
}
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;
}
app.resetPackageList(mProcessStats);
app.unlinkDeathRecipient();
- mProcessList.startProcessLocked(app, "bind fail", processName);
+ mProcessList.startProcessLocked(app, new HostingRecord("bind-fail", processName));
return false;
}
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;
}
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) {
} 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 "
}
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;
}
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!
(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;
}
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);
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,
--- /dev/null
+/*
+ * 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;
+ }
+}
/**
* @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;
// 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) {
}
@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,
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());
|| 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) {
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);
}
}
- 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) {
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,
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,
}
@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();
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) {
}
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;
}
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,
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);
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;
}