Add component types which a process is hosting into the proc memstats

When taking the snapshot of the memory usage of each process, log
what type of component this process is hosting, i.e., activities,
broadcast receivers, etc.

Bug: 233822891
Test: dumpsys activity -a
Test: statsd_testdrive 18
Change-Id: I04bfc53f87b67bbb6a765f13c8a010bb0d640135
This commit is contained in:
Jing Ji
2022-05-26 00:53:25 -07:00
parent e196a94cba
commit adfd04c375
7 changed files with 229 additions and 7 deletions

View File

@@ -128,6 +128,10 @@ import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.am.MemoryStatUtil.hasMemcg;
import static com.android.server.am.ProcessList.ProcStartHandler;
import static com.android.server.am.ProcessProfileRecord.HOSTING_COMPONENT_TYPE_BACKUP;
import static com.android.server.am.ProcessProfileRecord.HOSTING_COMPONENT_TYPE_INSTRUMENTATION;
import static com.android.server.am.ProcessProfileRecord.HOSTING_COMPONENT_TYPE_PERSISTENT;
import static com.android.server.am.ProcessProfileRecord.HOSTING_COMPONENT_TYPE_SYSTEM;
import static com.android.server.net.NetworkPolicyManagerInternal.updateBlockedReasonsWithProcState;
import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CLEANUP;
@@ -1877,6 +1881,7 @@ public class ActivityManagerService extends IActivityManager.Stub
app.setPid(MY_PID);
app.mState.setMaxAdj(ProcessList.SYSTEM_ADJ);
app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
app.mProfile.addHostingComponentType(HOSTING_COMPONENT_TYPE_SYSTEM);
addPidLocked(app);
updateLruProcessLocked(app, false, null);
updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_NONE);
@@ -4179,7 +4184,9 @@ public class ActivityManagerService extends IActivityManager.Stub
mi.getTotalRss(),
ProcessStats.ADD_PSS_EXTERNAL_SLOW,
duration,
holder.appVersion);
holder.appVersion,
profile.getCurrentHostingComponentTypes(),
profile.getHistoricalHostingComponentTypes());
});
}
}
@@ -4237,7 +4244,9 @@ public class ActivityManagerService extends IActivityManager.Stub
tmpUss[2],
ProcessStats.ADD_PSS_EXTERNAL,
duration,
holder.appVersion);
holder.appVersion,
profile.getCurrentHostingComponentTypes(),
profile.getHistoricalHostingComponentTypes());
});
}
}
@@ -6428,8 +6437,13 @@ public class ActivityManagerService extends IActivityManager.Stub
.getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
for (ApplicationInfo app : apps) {
if (!"android".equals(app.packageName)) {
addAppLocked(app, null, false, null /* ABI override */,
final ProcessRecord proc = addAppLocked(
app, null, false, null /* ABI override */,
ZYGOTE_POLICY_FLAG_BATCH_LAUNCH);
if (proc != null) {
proc.mProfile.addHostingComponentType(
HOSTING_COMPONENT_TYPE_PERSISTENT);
}
}
}
} catch (RemoteException ex) {
@@ -11308,7 +11322,9 @@ public class ActivityManagerService extends IActivityManager.Stub
holder.state.getPackage(),
myTotalPss, myTotalUss, myTotalRss, reportType,
endTime-startTime,
holder.appVersion);
holder.appVersion,
r.mProfile.getCurrentHostingComponentTypes(),
r.mProfile.getHistoricalHostingComponentTypes());
});
}
}
@@ -11951,7 +11967,9 @@ public class ActivityManagerService extends IActivityManager.Stub
holder.state.getName(),
holder.state.getPackage(),
myTotalPss, myTotalUss, myTotalRss, reportType, endTime-startTime,
holder.appVersion);
holder.appVersion,
r.mProfile.getCurrentHostingComponentTypes(),
r.mProfile.getHistoricalHostingComponentTypes());
});
}
}
@@ -12786,6 +12804,8 @@ public class ActivityManagerService extends IActivityManager.Stub
newBackupUid = proc.isInFullBackup() ? r.appInfo.uid : -1;
mBackupTargets.put(targetUserId, r);
proc.mProfile.addHostingComponentType(HOSTING_COMPONENT_TYPE_BACKUP);
// Try not to kill the process during backup
updateOomAdjLocked(proc, OomAdjuster.OOM_ADJ_REASON_NONE);
@@ -12828,7 +12848,15 @@ public class ActivityManagerService extends IActivityManager.Stub
}
synchronized (this) {
mBackupTargets.delete(userId);
final int indexOfKey = mBackupTargets.indexOfKey(userId);
if (indexOfKey >= 0) {
final BackupRecord backupTarget = mBackupTargets.valueAt(indexOfKey);
if (backupTarget != null && backupTarget.app != null) {
backupTarget.app.mProfile.clearHostingComponentType(
HOSTING_COMPONENT_TYPE_BACKUP);
}
mBackupTargets.removeAt(indexOfKey);
}
}
JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
@@ -12906,6 +12934,7 @@ public class ActivityManagerService extends IActivityManager.Stub
final ProcessRecord proc = backupTarget.app;
updateOomAdjLocked(proc, OomAdjuster.OOM_ADJ_REASON_NONE);
proc.setInFullBackup(false);
proc.mProfile.clearHostingComponentType(HOSTING_COMPONENT_TYPE_BACKUP);
oldBackupUid = backupTarget != null ? backupTarget.appInfo.uid : -1;
@@ -14634,6 +14663,7 @@ public class ActivityManagerService extends IActivityManager.Stub
}
app = addAppLocked(ai, defProcess, false, disableHiddenApiChecks,
disableTestApiChecks, abiOverride, ZYGOTE_POLICY_FLAG_EMPTY);
app.mProfile.addHostingComponentType(HOSTING_COMPONENT_TYPE_INSTRUMENTATION);
}
app.setActiveInstrumentation(activeInstr);
@@ -14758,6 +14788,7 @@ public class ActivityManagerService extends IActivityManager.Stub
if (!mActiveInstrumentation.contains(activeInstr)) {
mActiveInstrumentation.add(activeInstr);
}
app.mProfile.addHostingComponentType(HOSTING_COMPONENT_TYPE_INSTRUMENTATION);
}
} finally {
Binder.restoreCallingIdentity(token);
@@ -14887,6 +14918,7 @@ public class ActivityManagerService extends IActivityManager.Stub
instr.removeProcess(app);
app.setActiveInstrumentation(null);
}
app.mProfile.clearHostingComponentType(HOSTING_COMPONENT_TYPE_INSTRUMENTATION);
if (app.isSdkSandbox) {
// For sharedUid apps this will kill all sdk sandbox processes, which is not ideal.
@@ -15767,6 +15799,7 @@ public class ActivityManagerService extends IActivityManager.Stub
if (app.isPersistent()) {
addAppLocked(app.info, null, false, null /* ABI override */,
ZYGOTE_POLICY_FLAG_BATCH_LAUNCH);
app.mProfile.addHostingComponentType(HOSTING_COMPONENT_TYPE_PERSISTENT);
}
}
}

View File

@@ -573,7 +573,9 @@ public class AppProfiler {
holder.state.getPackage(),
pss, uss, rss,
statType, pssDuration,
holder.appVersion);
holder.appVersion,
profile.getCurrentHostingComponentTypes(),
profile.getHistoricalHostingComponentTypes());
});
if (DEBUG_PSS) {
Slog.d(TAG_PSS,

View File

@@ -24,6 +24,7 @@ import static android.os.Process.SYSTEM_UID;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
import static com.android.server.am.ActivityManagerService.TAG_MU;
import static com.android.server.am.ProcessProfileRecord.HOSTING_COMPONENT_TYPE_PROVIDER;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
@@ -701,6 +702,9 @@ public class ContentProviderHelper {
dst.onProviderPublishStatusLocked(true);
}
dst.mRestartCount = 0;
if (hasProviderConnectionLocked(r)) {
r.mProfile.addHostingComponentType(HOSTING_COMPONENT_TYPE_PROVIDER);
}
}
// update the app's oom adj value and each provider's usage stats
@@ -1375,6 +1379,9 @@ public class ContentProviderHelper {
conn.startAssociationIfNeeded();
conn.initializeCount(stable);
cpr.connections.add(conn);
if (cpr.proc != null) {
cpr.proc.mProfile.addHostingComponentType(HOSTING_COMPONENT_TYPE_PROVIDER);
}
pr.addProviderConnection(conn);
mService.startAssociationLocked(r.uid, r.processName, r.mState.getCurProcState(),
cpr.uid, cpr.appInfo.longVersionCode, cpr.name, cpr.info.processName);
@@ -1418,6 +1425,16 @@ public class ContentProviderHelper {
return true;
}
@GuardedBy("mService")
private boolean hasProviderConnectionLocked(ProcessRecord proc) {
for (int i = proc.mProviders.numberOfProviders() - 1; i >= 0; i--) {
if (!proc.mProviders.getProviderAt(i).connections.isEmpty()) {
return true;
}
}
return false;
}
private void handleProviderRemoval(ContentProviderConnection conn, boolean stable,
boolean updateOomAdj) {
synchronized (mService) {
@@ -1429,6 +1446,9 @@ public class ContentProviderHelper {
final ContentProviderRecord cpr = conn.provider;
conn.stopAssociation();
cpr.connections.remove(conn);
if (cpr.proc != null && !hasProviderConnectionLocked(cpr.proc)) {
cpr.proc.mProfile.clearHostingComponentType(HOSTING_COMPONENT_TYPE_PROVIDER);
}
conn.client.mProviders.removeProviderConnection(conn);
if (conn.client.mState.getSetProcState()
< ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
@@ -1737,6 +1757,9 @@ public class ContentProviderHelper {
// In the protocol here, we don't expect the client to correctly
// clean up this connection, we'll just remove it.
cpr.connections.remove(i);
if (cpr.proc != null && !hasProviderConnectionLocked(cpr.proc)) {
cpr.proc.mProfile.clearHostingComponentType(HOSTING_COMPONENT_TYPE_PROVIDER);
}
if (conn.client.mProviders.removeProviderConnection(conn)) {
mService.stopAssociationLocked(capp.uid, capp.processName,
cpr.uid, cpr.appInfo.longVersionCode, cpr.name, cpr.info.processName);

View File

@@ -19,6 +19,7 @@ package com.android.server.am;
import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
import static android.app.ActivityManager.processStateAmToProto;
import android.annotation.IntDef;
import android.app.IApplicationThread;
import android.content.pm.ApplicationInfo;
import android.os.Debug;
@@ -35,12 +36,95 @@ import com.android.internal.util.FrameworkStatsLog;
import com.android.server.am.ProcessList.ProcStateMemTracker;
import java.io.PrintWriter;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
/**
* Profiling info of the process, such as PSS, cpu, etc.
*/
final class ProcessProfileRecord {
// Keep below types in sync with the HostingComponentType in the atoms.proto.
/**
* The type of the component this process is hosting;
* this means not hosting any components (cached).
*/
static final int HOSTING_COMPONENT_TYPE_EMPTY = 0x0;
/**
* The type of the component this process is hosting;
* this means it's a system process.
*/
static final int HOSTING_COMPONENT_TYPE_SYSTEM = 0x00000001;
/**
* The type of the component this process is hosting;
* this means it's a persistent process.
*/
static final int HOSTING_COMPONENT_TYPE_PERSISTENT = 0x00000002;
/**
* The type of the component this process is hosting;
* this means it's hosting a backup/restore agent.
*/
static final int HOSTING_COMPONENT_TYPE_BACKUP = 0x00000004;
/**
* The type of the component this process is hosting;
* this means it's hosting an instrumentation.
*/
static final int HOSTING_COMPONENT_TYPE_INSTRUMENTATION = 0x00000008;
/**
* The type of the component this process is hosting;
* this means it's hosting an activity.
*/
static final int HOSTING_COMPONENT_TYPE_ACTIVITY = 0x00000010;
/**
* The type of the component this process is hosting;
* this means it's hosting a broadcast receiver.
*/
static final int HOSTING_COMPONENT_TYPE_BROADCAST_RECEIVER = 0x00000020;
/**
* The type of the component this process is hosting;
* this means it's hosting a content provider.
*/
static final int HOSTING_COMPONENT_TYPE_PROVIDER = 0x00000040;
/**
* The type of the component this process is hosting;
* this means it's hosting a started service.
*/
static final int HOSTING_COMPONENT_TYPE_STARTED_SERVICE = 0x00000080;
/**
* The type of the component this process is hosting;
* this means it's hosting a foreground service.
*/
static final int HOSTING_COMPONENT_TYPE_FOREGROUND_SERVICE = 0x00000100;
/**
* The type of the component this process is hosting;
* this means it's being bound via a service binding.
*/
static final int HOSTING_COMPONENT_TYPE_BOUND_SERVICE = 0x00000200;
@IntDef(flag = true, prefix = { "HOSTING_COMPONENT_TYPE_" }, value = {
HOSTING_COMPONENT_TYPE_EMPTY,
HOSTING_COMPONENT_TYPE_SYSTEM,
HOSTING_COMPONENT_TYPE_PERSISTENT,
HOSTING_COMPONENT_TYPE_BACKUP,
HOSTING_COMPONENT_TYPE_INSTRUMENTATION,
HOSTING_COMPONENT_TYPE_ACTIVITY,
HOSTING_COMPONENT_TYPE_BROADCAST_RECEIVER,
HOSTING_COMPONENT_TYPE_PROVIDER,
HOSTING_COMPONENT_TYPE_STARTED_SERVICE,
HOSTING_COMPONENT_TYPE_FOREGROUND_SERVICE,
HOSTING_COMPONENT_TYPE_BOUND_SERVICE,
})
@interface HostingComponentType {}
final ProcessRecord mApp;
private final ActivityManagerService mService;
@@ -194,6 +278,12 @@ final class ProcessProfileRecord {
@GuardedBy("mProfilerLock")
private long mLastStateTime;
private AtomicInteger mCurrentHostingComponentTypes =
new AtomicInteger(HOSTING_COMPONENT_TYPE_EMPTY);
private AtomicInteger mHistoricalHostingComponentTypes =
new AtomicInteger(HOSTING_COMPONENT_TYPE_EMPTY);
private final ActivityManagerGlobalLock mProcLock;
ProcessProfileRecord(final ProcessRecord app) {
@@ -292,6 +382,8 @@ final class ProcessProfileRecord {
mThread = null;
}
}
mCurrentHostingComponentTypes.set(HOSTING_COMPONENT_TYPE_EMPTY);
mHistoricalHostingComponentTypes.set(HOSTING_COMPONENT_TYPE_EMPTY);
}
@GuardedBy("mProfilerLock")
@@ -605,6 +697,23 @@ final class ProcessProfileRecord {
mLastStateTime = state.getLastStateTime();
}
void addHostingComponentType(@HostingComponentType int type) {
mCurrentHostingComponentTypes.set(mCurrentHostingComponentTypes.get() | type);
mHistoricalHostingComponentTypes.set(mHistoricalHostingComponentTypes.get() | type);
}
void clearHostingComponentType(@HostingComponentType int type) {
mCurrentHostingComponentTypes.set(mCurrentHostingComponentTypes.get() & ~type);
}
@HostingComponentType int getCurrentHostingComponentTypes() {
return mCurrentHostingComponentTypes.get();
}
@HostingComponentType int getHistoricalHostingComponentTypes() {
return mHistoricalHostingComponentTypes.get();
}
@GuardedBy("mService")
void dumpPss(PrintWriter pw, String prefix, long nowUptime) {
synchronized (mProfilerLock) {
@@ -643,6 +752,11 @@ final class ProcessProfileRecord {
pw.print(" reportLowMemory=");
pw.println(mReportLowMemory);
}
pw.print(prefix);
pw.print("currentHostingComponentTypes=0x");
pw.print(Integer.toHexString(getCurrentHostingComponentTypes()));
pw.print(" historicalHostingComponentTypes=0x");
pw.println(Integer.toHexString(getHistoricalHostingComponentTypes()));
}
void dumpCputime(PrintWriter pw, String prefix) {

View File

@@ -16,6 +16,9 @@
package com.android.server.am;
import static com.android.server.am.ProcessProfileRecord.HOSTING_COMPONENT_TYPE_BOUND_SERVICE;
import static com.android.server.am.ProcessProfileRecord.HOSTING_COMPONENT_TYPE_FOREGROUND_SERVICE;
import android.app.ActivityManager;
import android.content.Context;
import android.os.IBinder;
@@ -141,6 +144,11 @@ final class ProcessServiceRecord {
mHasForegroundServices = hasForegroundServices;
mFgServiceTypes = fgServiceTypes;
mApp.getWindowProcessController().setHasForegroundServices(hasForegroundServices);
if (hasForegroundServices) {
mApp.mProfile.addHostingComponentType(HOSTING_COMPONENT_TYPE_FOREGROUND_SERVICE);
} else {
mApp.mProfile.clearHostingComponentType(HOSTING_COMPONENT_TYPE_FOREGROUND_SERVICE);
}
}
boolean hasForegroundServices() {
@@ -295,6 +303,7 @@ final class ProcessServiceRecord {
boolean added = mServices.add(record);
if (added && record.serviceInfo != null) {
mApp.getWindowProcessController().onServiceStarted(record.serviceInfo);
updateHostingComonentTypeForBindingsLocked();
}
if (record.lastTopAlmostPerceptibleBindRequestUptimeMs > 0) {
mLastTopStartedAlmostPerceptibleBindRequestUptimeMs = Math.max(
@@ -318,6 +327,9 @@ final class ProcessServiceRecord {
if (record.lastTopAlmostPerceptibleBindRequestUptimeMs > 0) {
updateHasTopStartedAlmostPerceptibleServices();
}
if (removed) {
updateHostingComonentTypeForBindingsLocked();
}
return removed;
}
@@ -436,6 +448,23 @@ final class ProcessServiceRecord {
mApp.getWindowProcessController().setBoundClientUids(mBoundClientUids);
}
@GuardedBy("mService")
void updateHostingComonentTypeForBindingsLocked() {
boolean hasBoundClient = false;
for (int i = numberOfRunningServices() - 1; i >= 0; i--) {
final ServiceRecord sr = getRunningServiceAt(i);
if (sr != null && !sr.getConnections().isEmpty()) {
hasBoundClient = true;
break;
}
}
if (hasBoundClient) {
mApp.mProfile.addHostingComponentType(HOSTING_COMPONENT_TYPE_BOUND_SERVICE);
} else {
mApp.mProfile.clearHostingComponentType(HOSTING_COMPONENT_TYPE_BOUND_SERVICE);
}
}
@GuardedBy("mService")
boolean incServiceCrashCountLocked(long now) {
final boolean procIsBoundForeground = mApp.mState.getCurProcState()

View File

@@ -21,6 +21,9 @@ import static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
import static com.android.server.am.ProcessProfileRecord.HOSTING_COMPONENT_TYPE_ACTIVITY;
import static com.android.server.am.ProcessProfileRecord.HOSTING_COMPONENT_TYPE_BROADCAST_RECEIVER;
import static com.android.server.am.ProcessProfileRecord.HOSTING_COMPONENT_TYPE_STARTED_SERVICE;
import static com.android.server.am.ProcessRecord.TAG;
import android.annotation.ElapsedRealtimeLong;
@@ -694,6 +697,11 @@ final class ProcessStateRecord {
@GuardedBy("mProcLock")
void setHasStartedServices(boolean hasStartedServices) {
mHasStartedServices = hasStartedServices;
if (hasStartedServices) {
mApp.mProfile.addHostingComponentType(HOSTING_COMPONENT_TYPE_STARTED_SERVICE);
} else {
mApp.mProfile.clearHostingComponentType(HOSTING_COMPONENT_TYPE_STARTED_SERVICE);
}
}
@GuardedBy("mProcLock")
@@ -999,6 +1007,11 @@ final class ProcessStateRecord {
if (mCachedHasActivities == VALUE_INVALID) {
mCachedHasActivities = mApp.getWindowProcessController().hasActivities() ? VALUE_TRUE
: VALUE_FALSE;
if (mCachedHasActivities == VALUE_TRUE) {
mApp.mProfile.addHostingComponentType(HOSTING_COMPONENT_TYPE_ACTIVITY);
} else {
mApp.mProfile.clearHostingComponentType(HOSTING_COMPONENT_TYPE_ACTIVITY);
}
}
return mCachedHasActivities == VALUE_TRUE;
}
@@ -1065,6 +1078,9 @@ final class ProcessStateRecord {
if (mCachedIsReceivingBroadcast == VALUE_TRUE) {
mCachedSchedGroup = tmpQueue.contains(mService.mFgBroadcastQueue)
? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
mApp.mProfile.addHostingComponentType(HOSTING_COMPONENT_TYPE_BROADCAST_RECEIVER);
} else {
mApp.mProfile.clearHostingComponentType(HOSTING_COMPONENT_TYPE_BROADCAST_RECEIVER);
}
}
return mCachedIsReceivingBroadcast == VALUE_TRUE;

View File

@@ -23,6 +23,7 @@ import static android.os.PowerExemptionManager.REASON_DENIED;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOREGROUND_SERVICE;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.am.ProcessProfileRecord.HOSTING_COMPONENT_TYPE_BOUND_SERVICE;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -693,6 +694,7 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
app.removeAllowBackgroundActivityStartsToken(this);
}
app.mServices.updateBoundClientUids();
app.mServices.updateHostingComonentTypeForBindingsLocked();
}
app = proc;
if (pendingConnectionGroup > 0 && proc != null) {
@@ -717,6 +719,7 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
}
if (proc != null) {
proc.mServices.updateBoundClientUids();
proc.mServices.updateHostingComonentTypeForBindingsLocked();
}
}
@@ -736,6 +739,7 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
// if we have a process attached, add bound client uid of this connection to it
if (app != null) {
app.mServices.addBoundClientUid(c.clientUid);
app.mProfile.addHostingComponentType(HOSTING_COMPONENT_TYPE_BOUND_SERVICE);
}
}
@@ -744,6 +748,7 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
// if we have a process attached, tell it to update the state of bound clients
if (app != null) {
app.mServices.updateBoundClientUids();
app.mServices.updateHostingComonentTypeForBindingsLocked();
}
}