diff options
| author | 2023-03-19 20:59:55 -0700 | |
|---|---|---|
| committer | 2023-04-03 18:50:06 -0700 | |
| commit | 09dbf1fdbee6d155917a15f669b9fbda1fd750ab (patch) | |
| tree | 1899868856f5e94c662263a06d6e1d9f34fd5917 | |
| parent | 74da091e71c42fe02dd220e4b7fb612e38425799 (diff) | |
Add support for modern trim memory dispatch.
This CL adds flagged implementation of onTrimMemory dispatch to
improve consistency of dispatch and prevent unnecessary work from
unnecessary onTrimMemory calls. When the flag is enabled, trim level
dispatch is coupled to process state and completely decoupled from
memory state.
- When an app becomes eligible for freezing, TRIM_MEMORY_BACKGROUND
will be triggered.
- Due to the likelihood of causing additional memory pressure when the
device is already under memory pressure, no other TRIM_MEMORY
constants will be used.
This implementation is behind the ActivityManager "use_modern_trim"
flag, which is currently set to false.
Test: atest android.app.cts.ActivityManagerTest
Bug: 253914117
Change-Id: I2c5b7db4b322723c2cc608d5f67946b8ccf77efb
3 files changed, 61 insertions, 0 deletions
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java index 553706db34d8..41f1e85c27c3 100644 --- a/services/core/java/com/android/server/am/ActivityManagerConstants.java +++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java @@ -151,6 +151,7 @@ final class ActivityManagerConstants extends ContentObserver { static final String KEY_USE_TIERED_CACHED_ADJ = "use_tiered_cached_adj"; static final String KEY_TIERED_CACHED_ADJ_DECAY_TIME = "tiered_cached_adj_decay_time"; + static final String KEY_USE_MODERN_TRIM = "use_modern_trim"; private static final int DEFAULT_MAX_CACHED_PROCESSES = 1024; private static final boolean DEFAULT_PRIORITIZE_ALARM_BROADCASTS = true; @@ -212,6 +213,8 @@ final class ActivityManagerConstants extends ContentObserver { private static final boolean DEFAULT_USE_TIERED_CACHED_ADJ = false; private static final long DEFAULT_TIERED_CACHED_ADJ_DECAY_TIME = 60 * 1000; + private static final boolean DEFAULT_USE_MODERN_TRIM = false; + /** * Same as {@link TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED} */ @@ -1052,6 +1055,9 @@ final class ActivityManagerConstants extends ContentObserver { /** @see #KEY_TIERED_CACHED_ADJ_DECAY_TIME */ public long TIERED_CACHED_ADJ_DECAY_TIME = DEFAULT_TIERED_CACHED_ADJ_DECAY_TIME; + /** @see #KEY_USE_MODERN_TRIM */ + public boolean USE_MODERN_TRIM = DEFAULT_USE_MODERN_TRIM; + private final OnPropertiesChangedListener mOnDeviceConfigChangedListener = new OnPropertiesChangedListener() { @Override @@ -1227,6 +1233,9 @@ final class ActivityManagerConstants extends ContentObserver { case KEY_TIERED_CACHED_ADJ_DECAY_TIME: updateUseTieredCachedAdj(); break; + case KEY_USE_MODERN_TRIM: + updateUseModernTrim(); + break; default: updateFGSPermissionEnforcementFlagsIfNecessary(name); break; @@ -1991,6 +2000,13 @@ final class ActivityManagerConstants extends ContentObserver { DEFAULT_TIERED_CACHED_ADJ_DECAY_TIME); } + private void updateUseModernTrim() { + USE_MODERN_TRIM = DeviceConfig.getBoolean( + DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + KEY_USE_MODERN_TRIM, + DEFAULT_USE_MODERN_TRIM); + } + private void updateFGSPermissionEnforcementFlagsIfNecessary(@NonNull String name) { ForegroundServiceTypePolicy.getDefaultPolicy() .updatePermissionEnforcementFlagIfNecessary(name); diff --git a/services/core/java/com/android/server/am/AppProfiler.java b/services/core/java/com/android/server/am/AppProfiler.java index ccd739006713..25ac956d328d 100644 --- a/services/core/java/com/android/server/am/AppProfiler.java +++ b/services/core/java/com/android/server/am/AppProfiler.java @@ -1005,6 +1005,37 @@ public class AppProfiler { mBgHandler.obtainMessage(BgHandler.MEMORY_PRESSURE_CHANGED, mLastMemoryLevel, memFactor) .sendToTarget(); } + + if (mService.mConstants.USE_MODERN_TRIM) { + // Modern trim is not sent based on lowmem state + // Dispatch UI_HIDDEN to processes that need it + mService.mProcessList.forEachLruProcessesLOSP(true, app -> { + final ProcessProfileRecord profile = app.mProfile; + final IApplicationThread thread; + final ProcessStateRecord state = app.mState; + if (state.hasProcStateChanged()) { + state.setProcStateChanged(false); + } + int procState = app.mState.getCurProcState(); + if (((procState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND + && procState < ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) + || app.mState.isSystemNoUi()) && app.mProfile.hasPendingUiClean()) { + // If this application is now in the background and it + // had done UI, then give it the special trim level to + // have it free UI resources. + if ((thread = app.getThread()) != null) { + try { + thread.scheduleTrimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); + app.mProfile.setPendingUiClean(false); + } catch (RemoteException e) { + + } + } + } + }); + return false; + } + mLastMemoryLevel = memFactor; mLastNumProcesses = mService.mProcessList.getLruSizeLOSP(); boolean allChanged; diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java index 9c1546324e4b..78edbba2e569 100644 --- a/services/core/java/com/android/server/am/CachedAppOptimizer.java +++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java @@ -18,6 +18,7 @@ package com.android.server.am; import static android.app.ActivityManager.UidFrozenStateChangedCallback.UID_FROZEN_STATE_FROZEN; import static android.app.ActivityManager.UidFrozenStateChangedCallback.UID_FROZEN_STATE_UNFROZEN; +import static android.content.ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_COMPACTION; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FREEZER; @@ -27,12 +28,14 @@ import android.annotation.IntDef; import android.app.ActivityManager; import android.app.ActivityThread; import android.app.ApplicationExitInfo; +import android.app.IApplicationThread; import android.database.ContentObserver; import android.net.Uri; import android.os.Handler; import android.os.Message; import android.os.PowerManagerInternal; import android.os.Process; +import android.os.RemoteException; import android.os.SystemClock; import android.os.Trace; import android.provider.DeviceConfig; @@ -1231,6 +1234,17 @@ public final class CachedAppOptimizer { return; } + if (mAm.mConstants.USE_MODERN_TRIM + && app.mState.getSetAdj() >= ProcessList.CACHED_APP_MIN_ADJ) { + final IApplicationThread thread = app.getThread(); + if (thread != null) { + try { + thread.scheduleTrimMemory(TRIM_MEMORY_BACKGROUND); + } catch (RemoteException e) { + // do nothing + } + } + } mFreezeHandler.sendMessageDelayed( mFreezeHandler.obtainMessage( SET_FROZEN_PROCESS_MSG, DO_FREEZE, 0, app), |