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

Commit 480cc312 authored by Misha Wagner's avatar Misha Wagner
Browse files

Change CacheOomRanker's "uses" feature.

The previous implementation was incorrect, as an app goes in and out of
the cache several times during oom_adj calculation. If all apps started
at the same time, then this would be OK - as they all get incremented
the same amount, plus get incremented when they actually go in and out
of the cache. This would result in the relative counts being correct.

However, as all apps aren't started at the same time, the old
implementation is instead a measure of how long the app has been
started.

So instead we use mSetProcState, which isn't changed on each oom_adj
calculation. This measure should accurately reflect the number of times
the process is used - whether that's by a user app open, or a content
receiver call, or an intent being broadcast.

See go/sim-v-impl for more details.

Test: atest CacheOomRankerTest
Bug: 196031723
Change-Id: I49d02362b8277f8472355e78412f79256c2289a1
parent a0326c86
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -771,6 +771,11 @@ public class ActivityManager {
        return procState >= PROCESS_STATE_TRANSIENT_BACKGROUND;
    }

    /** @hide Should this process state be considered in the cache? */
    public static final boolean isProcStateCached(int procState) {
        return procState >= PROCESS_STATE_CACHED_ACTIVITY;
    }

    /** @hide Is this a foreground service type? */
    public static boolean isForegroundService(int procState) {
        return procState == PROCESS_STATE_FOREGROUND_SERVICE;
+5 −6
Original line number Diff line number Diff line
@@ -611,6 +611,10 @@ final class ProcessStateRecord {

    @GuardedBy({"mService", "mProcLock"})
    void setSetProcState(int setProcState) {
        if (ActivityManager.isProcStateCached(mSetProcState)
                && !ActivityManager.isProcStateCached(setProcState)) {
            mCacheOomRankerUseCount++;
        }
        mSetProcState = setProcState;
    }

@@ -874,12 +878,7 @@ final class ProcessStateRecord {

    @GuardedBy("mService")
    void setCached(boolean cached) {
        if (mCached != cached) {
        mCached = cached;
            if (cached) {
                ++mCacheOomRankerUseCount;
            }
        }
    }

    @GuardedBy("mService")
+5 −4
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;

import android.app.ActivityManager;
import android.app.IApplicationThread;
import android.content.ComponentName;
import android.content.Context;
@@ -581,7 +582,7 @@ public class CacheOomRankerTest {
    }

    private ProcessRecord nextProcessRecord(int setAdj, long lastActivityTime, long lastRss,
            int returnedToCacheCount) {
            int wentToForegroundCount) {
        ApplicationInfo ai = new ApplicationInfo();
        ai.packageName = "a.package.name" + mNextPackageName++;
        ProcessRecord app = new ProcessRecord(mAms, ai, ai.packageName + ":process", mNextUid++);
@@ -593,9 +594,9 @@ public class CacheOomRankerTest {
        app.setLastActivityTime(lastActivityTime);
        app.mProfile.setLastRss(lastRss);
        app.mState.setCached(false);
        for (int i = 0; i < returnedToCacheCount; ++i) {
            app.mState.setCached(false);
            app.mState.setCached(true);
        for (int i = 0; i < wentToForegroundCount; ++i) {
            app.mState.setSetProcState(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
            app.mState.setSetProcState(ActivityManager.PROCESS_STATE_CACHED_RECENT);
        }
        // Sets the thread returned by ProcessRecord#getThread, which we use to check whether the
        // app is currently launching.