Add a global setting for forcing PSS collection
The flag for replacing PSS collection in AppProfiler with RSS will make
numbers in the "Memory use" UI in developer settings incorrect, as the
numbers presented there are gathered from AppProfiler. This change adds
a global setting that can be toggled from that page to resume collecting
PSS information.
Test: Build+flash, verify using test logs that PSS is collected in
AppProfiler instead of RSS when the new toggle in Settings is
enabled while the flag is enabled.
Bug: 296454553
Change-Id: Ic821a6fc9dbb6bd2c1a5d2c66805d8e9be70fae7
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 8b5995a..93f04b9 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -14965,6 +14965,16 @@
"foreground_service_starts_logging_enabled";
/**
+ * Describes whether AM's AppProfiler should collect PSS even if RSS is the default. This
+ * can be set by a user in developer settings.
+ * Default: 0
+ * @hide
+ */
+ @Readable
+ public static final String FORCE_ENABLE_PSS_PROFILING =
+ "force_enable_pss_profiling";
+
+ /**
* @hide
* @see com.android.server.appbinding.AppBindingConstants
*/
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java
index e5dbe5f..e9b9656 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java
@@ -112,5 +112,6 @@
Settings.Global.Wearable.SCREENSHOT_ENABLED,
Settings.Global.Wearable.SCREEN_UNLOCK_SOUND_ENABLED,
Settings.Global.Wearable.CHARGING_SOUNDS_ENABLED,
+ Settings.Global.FORCE_ENABLE_PSS_PROFILING,
};
}
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
index d9fe733..54baead 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
@@ -446,5 +446,6 @@
VALIDATORS.put(Global.Wearable.WEAR_LAUNCHER_UI_MODE, ANY_INTEGER_VALIDATOR);
VALIDATORS.put(Global.Wearable.WEAR_POWER_ANOMALY_SERVICE_ENABLED, BOOLEAN_VALIDATOR);
VALIDATORS.put(Global.Wearable.CONNECTIVITY_KEEP_DATA_ON, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Global.FORCE_ENABLE_PSS_PROFILING, BOOLEAN_VALIDATOR);
}
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java
index 3ce91c8..2ec2172 100644
--- a/services/core/java/com/android/server/am/ActivityManagerConstants.java
+++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java
@@ -629,6 +629,10 @@
// foreground service background start restriction.
volatile boolean mFgsStartRestrictionNotificationEnabled = false;
+ // Indicates whether PSS profiling in AppProfiler is force-enabled, even if RSS is used by
+ // default. Controlled by Settings.Global.FORCE_ENABLE_PSS_PROFILING
+ volatile boolean mForceEnablePssProfiling = false;
+
/**
* Indicates whether the foreground service background start restriction is enabled for
* caller app that is targeting S+.
@@ -958,6 +962,9 @@
private static final Uri ENABLE_AUTOMATIC_SYSTEM_SERVER_HEAP_DUMPS_URI =
Settings.Global.getUriFor(Settings.Global.ENABLE_AUTOMATIC_SYSTEM_SERVER_HEAP_DUMPS);
+ private static final Uri FORCE_ENABLE_PSS_PROFILING_URI =
+ Settings.Global.getUriFor(Settings.Global.FORCE_ENABLE_PSS_PROFILING);
+
/**
* The threshold to decide if a given association should be dumped into metrics.
*/
@@ -1368,6 +1375,7 @@
mResolver.registerContentObserver(ENABLE_AUTOMATIC_SYSTEM_SERVER_HEAP_DUMPS_URI,
false, this);
}
+ mResolver.registerContentObserver(FORCE_ENABLE_PSS_PROFILING_URI, false, this);
updateConstants();
if (mSystemServerAutomaticHeapDumpEnabled) {
updateEnableAutomaticSystemServerHeapDumps();
@@ -1383,6 +1391,7 @@
// The following read from Settings.
updateActivityStartsLoggingEnabled();
updateForegroundServiceStartsLoggingEnabled();
+ updateForceEnablePssProfiling();
// Read DropboxRateLimiter params from flags.
mService.initDropboxRateLimiter();
}
@@ -1424,6 +1433,8 @@
updateForegroundServiceStartsLoggingEnabled();
} else if (ENABLE_AUTOMATIC_SYSTEM_SERVER_HEAP_DUMPS_URI.equals(uri)) {
updateEnableAutomaticSystemServerHeapDumps();
+ } else if (FORCE_ENABLE_PSS_PROFILING_URI.equals(uri)) {
+ updateForceEnablePssProfiling();
}
}
@@ -1536,6 +1547,11 @@
Settings.Global.ACTIVITY_STARTS_LOGGING_ENABLED, 1) == 1;
}
+ private void updateForceEnablePssProfiling() {
+ mForceEnablePssProfiling = Settings.Global.getInt(mResolver,
+ Settings.Global.FORCE_ENABLE_PSS_PROFILING, 0) == 1;
+ }
+
private void updateBackgroundActivityStarts() {
mFlagBackgroundActivityStartsEnabled = DeviceConfig.getBoolean(
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 3e533a6..7d52eb5 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -326,7 +326,6 @@
import android.os.DropBoxManager;
import android.os.FactoryTest;
import android.os.FileUtils;
-import android.os.Flags;
import android.os.Handler;
import android.os.IBinder;
import android.os.IDeviceIdentifiersPolicyService;
@@ -8563,7 +8562,7 @@
final long initialIdlePssOrRss, lastPssOrRss, lastSwapPss;
synchronized (mAppProfiler.mProfilerLock) {
initialIdlePssOrRss = pr.getInitialIdlePssOrRss();
- lastPssOrRss = !Flags.removeAppProfilerPssCollection()
+ lastPssOrRss = mAppProfiler.isProfilingPss()
? pr.getLastPss() : pr.getLastRss();
lastSwapPss = pr.getLastSwapPss();
}
@@ -8573,14 +8572,14 @@
final StringBuilder sb2 = new StringBuilder(128);
sb2.append("Kill");
sb2.append(proc.processName);
- if (!Flags.removeAppProfilerPssCollection()) {
+ if (mAppProfiler.isProfilingPss()) {
sb2.append(" in idle maint: pss=");
} else {
sb2.append(" in idle maint: rss=");
}
sb2.append(lastPssOrRss);
- if (!Flags.removeAppProfilerPssCollection()) {
+ if (mAppProfiler.isProfilingPss()) {
sb2.append(", swapPss=");
sb2.append(lastSwapPss);
sb2.append(", initialPss=");
@@ -8595,7 +8594,7 @@
Slog.wtfQuiet(TAG, sb2.toString());
mHandler.post(() -> {
synchronized (ActivityManagerService.this) {
- proc.killLocked(!Flags.removeAppProfilerPssCollection()
+ proc.killLocked(mAppProfiler.isProfilingPss()
? "idle maint (pss " : "idle maint (rss " + lastPssOrRss
+ " from " + initialIdlePssOrRss + ")",
ApplicationExitInfo.REASON_OTHER,
diff --git a/services/core/java/com/android/server/am/AppProfiler.java b/services/core/java/com/android/server/am/AppProfiler.java
index 2e0aec9..e4956b3 100644
--- a/services/core/java/com/android/server/am/AppProfiler.java
+++ b/services/core/java/com/android/server/am/AppProfiler.java
@@ -602,7 +602,7 @@
public void handleMessage(Message msg) {
switch (msg.what) {
case COLLECT_PSS_BG_MSG:
- if (!Flags.removeAppProfilerPssCollection()) {
+ if (isProfilingPss()) {
collectPssInBackground();
} else {
collectRssInBackground();
@@ -748,6 +748,11 @@
} while (true);
}
+ boolean isProfilingPss() {
+ return !Flags.removeAppProfilerPssCollection()
+ || mService.mConstants.mForceEnablePssProfiling;
+ }
+
// This method is analogous to collectPssInBackground() and is intended to be used as a
// replacement if Flags.removeAppProfilerPssCollection() is enabled. References to PSS in
// methods outside of AppProfiler have generally been kept where a new RSS equivalent is not
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index b00dcd6..3f7a144 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -144,7 +144,6 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.ServiceInfo;
import android.net.NetworkPolicyManager;
-import android.os.Flags;
import android.os.Handler;
import android.os.IBinder;
import android.os.PowerManagerInternal;
@@ -2419,7 +2418,7 @@
// normally be a B service, but if we are low on RAM and it
// is large we want to force it down since we would prefer to
// keep launcher over it.
- long lastPssOrRss = !Flags.removeAppProfilerPssCollection()
+ long lastPssOrRss = mService.mAppProfiler.isProfilingPss()
? app.mProfile.getLastPss() : app.mProfile.getLastRss();
// RSS is larger than PSS, but the RSS/PSS ratio varies per-process based on how
@@ -2428,9 +2427,8 @@
//
// TODO(b/296454553): Tune the second value so that the relative number of
// service B is similar before/after this flag is enabled.
- double thresholdModifier = !Flags.removeAppProfilerPssCollection()
- ? 1
- : mConstants.PSS_TO_RSS_THRESHOLD_MODIFIER;
+ double thresholdModifier = mService.mAppProfiler.isProfilingPss()
+ ? 1 : mConstants.PSS_TO_RSS_THRESHOLD_MODIFIER;
double cachedRestoreThreshold =
mProcessList.getCachedRestoreThresholdKb() * thresholdModifier;
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 4ff34b1..1c3f475 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -94,7 +94,6 @@
import android.os.Build;
import android.os.Bundle;
import android.os.DropBoxManager;
-import android.os.Flags;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
@@ -4726,7 +4725,7 @@
pw.print("state: cur="); pw.print(makeProcStateString(state.getCurProcState()));
pw.print(" set="); pw.print(makeProcStateString(state.getSetProcState()));
// These values won't be collected if the flag is enabled.
- if (!Flags.removeAppProfilerPssCollection()) {
+ if (service.mAppProfiler.isProfilingPss()) {
pw.print(" lastPss=");
DebugUtils.printSizeValue(pw, r.mProfile.getLastPss() * 1024);
pw.print(" lastSwapPss=");
diff --git a/services/core/java/com/android/server/am/ProcessProfileRecord.java b/services/core/java/com/android/server/am/ProcessProfileRecord.java
index 8ca64f8..d8f797c 100644
--- a/services/core/java/com/android/server/am/ProcessProfileRecord.java
+++ b/services/core/java/com/android/server/am/ProcessProfileRecord.java
@@ -23,7 +23,6 @@
import android.app.ProcessMemoryState.HostingComponentType;
import android.content.pm.ApplicationInfo;
import android.os.Debug;
-import android.os.Flags;
import android.os.Process;
import android.os.SystemClock;
import android.util.DebugUtils;
@@ -677,7 +676,7 @@
void dumpPss(PrintWriter pw, String prefix, long nowUptime) {
synchronized (mProfilerLock) {
// TODO(b/297542292): Remove this case once PSS profiling is replaced
- if (!Flags.removeAppProfilerPssCollection()) {
+ if (mService.mAppProfiler.isProfilingPss()) {
pw.print(prefix);
pw.print("lastPssTime=");
TimeUtils.formatDuration(mLastPssTime, nowUptime, pw);
diff --git a/services/core/java/com/android/server/am/ProcessStateRecord.java b/services/core/java/com/android/server/am/ProcessStateRecord.java
index 5ad921f..3391ec7 100644
--- a/services/core/java/com/android/server/am/ProcessStateRecord.java
+++ b/services/core/java/com/android/server/am/ProcessStateRecord.java
@@ -29,7 +29,6 @@
import android.annotation.ElapsedRealtimeLong;
import android.app.ActivityManager;
import android.content.ComponentName;
-import android.os.Flags;
import android.os.SystemClock;
import android.os.Trace;
import android.util.Slog;
@@ -1351,7 +1350,7 @@
}
if (mNotCachedSinceIdle) {
pw.print(prefix); pw.print("notCachedSinceIdle="); pw.print(mNotCachedSinceIdle);
- if (!Flags.removeAppProfilerPssCollection()) {
+ if (mService.mAppProfiler.isProfilingPss()) {
pw.print(" initialIdlePss=");
} else {
pw.print(" initialIdleRss=");