Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3bb73ab4 authored by Varun Shah's avatar Varun Shah Committed by Android (Google) Code Review
Browse files

Merge "Rate limit calls to AM.getMyMemoryState()." into main

parents 486822e9 509d4ce7
Loading
Loading
Loading
Loading
+40 −1
Original line number Diff line number Diff line
@@ -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.
@@ -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) {
@@ -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) {
+11 −0
Original line number Diff line number Diff line
@@ -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
     }
}
+10 −17
Original line number Diff line number Diff line
@@ -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,
@@ -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"})