Loading core/java/android/app/ActivityManager.java +40 −1 Original line number Diff line number Diff line Loading @@ -247,6 +247,14 @@ public class ActivityManager { @GuardedBy("mMemoryInfoCache") private static final MemoryInfo mRateLimitedMemInfo = new MemoryInfo(); /** Rate-Limiting cache that allows no more than 200 calls to the service per second. */ @GuardedBy("mMyMemoryStateCache") private static final RateLimitingCache<RunningAppProcessInfo> mMyMemoryStateCache = new RateLimitingCache<>(10, 2); /** Used to store cached results for rate-limited calls to getMyMemoryState(). */ @GuardedBy("mMyMemoryStateCache") private static final RunningAppProcessInfo mRateLimitedMemState = new RunningAppProcessInfo(); /** * Query handler for mGetCurrentUserIdCache - returns a cached value of the current foreground * user id if the backstage_power/android.app.cache_get_current_user_id flag is enabled. Loading Loading @@ -4223,6 +4231,23 @@ public class ActivityManager { lastActivityTime = source.readLong(); } /** * Note: only fields that are updated in ProcessList.fillInProcMemInfoLOSP() are copied. * @hide */ public void copyTo(RunningAppProcessInfo other) { other.pid = pid; other.uid = uid; other.flags = flags; other.lastTrimLevel = lastTrimLevel; other.importance = importance; other.lru = lru; other.importanceReasonCode = importanceReasonCode; other.processState = processState; other.isFocused = isFocused; other.lastActivityTime = lastActivityTime; } public static final @android.annotation.NonNull Creator<RunningAppProcessInfo> CREATOR = new Creator<RunningAppProcessInfo>() { public RunningAppProcessInfo createFromParcel(Parcel source) { Loading Loading @@ -4854,7 +4879,21 @@ public class ActivityManager { * {@link RunningAppProcessInfo#lru}, and * {@link RunningAppProcessInfo#importanceReasonCode}. */ static public void getMyMemoryState(RunningAppProcessInfo outState) { public static void getMyMemoryState(RunningAppProcessInfo outState) { if (Flags.rateLimitGetMyMemoryState()) { synchronized (mMyMemoryStateCache) { mMyMemoryStateCache.get(() -> { getMyMemoryStateInternal(mRateLimitedMemState); return mRateLimitedMemState; }); mRateLimitedMemState.copyTo(outState); } } else { getMyMemoryStateInternal(outState); } } private static void getMyMemoryStateInternal(RunningAppProcessInfo outState) { try { getService().getMyMemoryState(outState); } catch (RemoteException e) { Loading core/java/android/app/activity_manager.aconfig +11 −0 Original line number Diff line number Diff line Loading @@ -136,3 +136,14 @@ flag { purpose: PURPOSE_BUGFIX } } flag { namespace: "backstage_power" name: "rate_limit_get_my_memory_state" description: "Rate limit calls to getMyMemoryState using a cache" is_fixed_read_only: true bug: "365182205" metadata { purpose: PURPOSE_BUGFIX } } services/core/java/com/android/server/am/ProcessList.java +10 −17 Original line number Diff line number Diff line Loading @@ -4125,19 +4125,6 @@ public final class ProcessList { return false; } private static int procStateToImportance(int procState, int memAdj, ActivityManager.RunningAppProcessInfo currApp, int clientTargetSdk) { int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk( procState, clientTargetSdk); if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { currApp.lru = memAdj; } else { currApp.lru = 0; } return imp; } @GuardedBy(anyOf = {"mService", "mProcLock"}) void fillInProcMemInfoLOSP(ProcessRecord app, ActivityManager.RunningAppProcessInfo outInfo, Loading @@ -4155,14 +4142,20 @@ public final class ProcessList { } outInfo.lastTrimLevel = app.mProfile.getTrimMemoryLevel(); final ProcessStateRecord state = app.mState; int adj = state.getCurAdj(); int procState = state.getCurProcState(); outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk); final int procState = state.getCurProcState(); outInfo.importance = ActivityManager.RunningAppProcessInfo .procStateToImportanceForTargetSdk(procState, clientTargetSdk); if (outInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { outInfo.lru = state.getCurAdj(); } else { outInfo.lru = 0; } outInfo.importanceReasonCode = state.getAdjTypeCode(); outInfo.processState = procState; outInfo.isFocused = (app == mService.getTopApp()); outInfo.lastActivityTime = app.getLastActivityTime(); // Note: ActivityManager$RunningAppProcessInfo.copyTo() must be updated if what gets // "filled into" outInfo in this method changes. } @GuardedBy(anyOf = {"mService", "mProcLock"}) Loading Loading
core/java/android/app/ActivityManager.java +40 −1 Original line number Diff line number Diff line Loading @@ -247,6 +247,14 @@ public class ActivityManager { @GuardedBy("mMemoryInfoCache") private static final MemoryInfo mRateLimitedMemInfo = new MemoryInfo(); /** Rate-Limiting cache that allows no more than 200 calls to the service per second. */ @GuardedBy("mMyMemoryStateCache") private static final RateLimitingCache<RunningAppProcessInfo> mMyMemoryStateCache = new RateLimitingCache<>(10, 2); /** Used to store cached results for rate-limited calls to getMyMemoryState(). */ @GuardedBy("mMyMemoryStateCache") private static final RunningAppProcessInfo mRateLimitedMemState = new RunningAppProcessInfo(); /** * Query handler for mGetCurrentUserIdCache - returns a cached value of the current foreground * user id if the backstage_power/android.app.cache_get_current_user_id flag is enabled. Loading Loading @@ -4223,6 +4231,23 @@ public class ActivityManager { lastActivityTime = source.readLong(); } /** * Note: only fields that are updated in ProcessList.fillInProcMemInfoLOSP() are copied. * @hide */ public void copyTo(RunningAppProcessInfo other) { other.pid = pid; other.uid = uid; other.flags = flags; other.lastTrimLevel = lastTrimLevel; other.importance = importance; other.lru = lru; other.importanceReasonCode = importanceReasonCode; other.processState = processState; other.isFocused = isFocused; other.lastActivityTime = lastActivityTime; } public static final @android.annotation.NonNull Creator<RunningAppProcessInfo> CREATOR = new Creator<RunningAppProcessInfo>() { public RunningAppProcessInfo createFromParcel(Parcel source) { Loading Loading @@ -4854,7 +4879,21 @@ public class ActivityManager { * {@link RunningAppProcessInfo#lru}, and * {@link RunningAppProcessInfo#importanceReasonCode}. */ static public void getMyMemoryState(RunningAppProcessInfo outState) { public static void getMyMemoryState(RunningAppProcessInfo outState) { if (Flags.rateLimitGetMyMemoryState()) { synchronized (mMyMemoryStateCache) { mMyMemoryStateCache.get(() -> { getMyMemoryStateInternal(mRateLimitedMemState); return mRateLimitedMemState; }); mRateLimitedMemState.copyTo(outState); } } else { getMyMemoryStateInternal(outState); } } private static void getMyMemoryStateInternal(RunningAppProcessInfo outState) { try { getService().getMyMemoryState(outState); } catch (RemoteException e) { Loading
core/java/android/app/activity_manager.aconfig +11 −0 Original line number Diff line number Diff line Loading @@ -136,3 +136,14 @@ flag { purpose: PURPOSE_BUGFIX } } flag { namespace: "backstage_power" name: "rate_limit_get_my_memory_state" description: "Rate limit calls to getMyMemoryState using a cache" is_fixed_read_only: true bug: "365182205" metadata { purpose: PURPOSE_BUGFIX } }
services/core/java/com/android/server/am/ProcessList.java +10 −17 Original line number Diff line number Diff line Loading @@ -4125,19 +4125,6 @@ public final class ProcessList { return false; } private static int procStateToImportance(int procState, int memAdj, ActivityManager.RunningAppProcessInfo currApp, int clientTargetSdk) { int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk( procState, clientTargetSdk); if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { currApp.lru = memAdj; } else { currApp.lru = 0; } return imp; } @GuardedBy(anyOf = {"mService", "mProcLock"}) void fillInProcMemInfoLOSP(ProcessRecord app, ActivityManager.RunningAppProcessInfo outInfo, Loading @@ -4155,14 +4142,20 @@ public final class ProcessList { } outInfo.lastTrimLevel = app.mProfile.getTrimMemoryLevel(); final ProcessStateRecord state = app.mState; int adj = state.getCurAdj(); int procState = state.getCurProcState(); outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk); final int procState = state.getCurProcState(); outInfo.importance = ActivityManager.RunningAppProcessInfo .procStateToImportanceForTargetSdk(procState, clientTargetSdk); if (outInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { outInfo.lru = state.getCurAdj(); } else { outInfo.lru = 0; } outInfo.importanceReasonCode = state.getAdjTypeCode(); outInfo.processState = procState; outInfo.isFocused = (app == mService.getTopApp()); outInfo.lastActivityTime = app.getLastActivityTime(); // Note: ActivityManager$RunningAppProcessInfo.copyTo() must be updated if what gets // "filled into" outInfo in this method changes. } @GuardedBy(anyOf = {"mService", "mProcLock"}) Loading