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

Commit 9dca8001 authored by Misha Wagner's avatar Misha Wagner Committed by Automerger Merge Worker
Browse files

Merge changes from topic "CacheOomRanker-new-features-sc-qpr1-dev" into...

Merge changes from topic "CacheOomRanker-new-features-sc-qpr1-dev" into sc-qpr1-dev am: 78c1e444 am: aaf5f8b9

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15771575

Change-Id: I71fb6e62e01a18962a7c82b9bf2b120676de657d
parents 4ced6561 aaf5f8b9
Loading
Loading
Loading
Loading
+102 −2
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.server.am;

import android.os.Process;
import android.os.SystemClock;
import android.provider.DeviceConfig;
import android.util.Slog;

@@ -46,6 +48,14 @@ public class CacheOomRanker {
    @VisibleForTesting
    static final int DEFAULT_PRESERVE_TOP_N_APPS = 3;
    @VisibleForTesting
    static final String KEY_OOM_RE_RANKING_USE_FREQUENT_RSS = "oom_re_ranking_rss_use_frequent_rss";
    @VisibleForTesting
    static final boolean DEFAULT_USE_FREQUENT_RSS = true;
    @VisibleForTesting
    static final String KEY_OOM_RE_RANKING_RSS_UPDATE_RATE_MS = "oom_re_ranking_rss_update_rate_ms";
    @VisibleForTesting
    static final long DEFAULT_RSS_UPDATE_RATE_MS = 10_000; // 10 seconds
    @VisibleForTesting
    static final String KEY_OOM_RE_RANKING_LRU_WEIGHT = "oom_re_ranking_lru_weight";
    @VisibleForTesting
    static final float DEFAULT_OOM_RE_RANKING_LRU_WEIGHT = 0.35f;
@@ -62,6 +72,8 @@ public class CacheOomRanker {
            new ScoreComparator();
    private static final Comparator<RankedProcessRecord> CACHE_USE_COMPARATOR =
            new CacheUseComparator();
    private static final Comparator<RankedProcessRecord> RSS_COMPARATOR =
            new RssComparator();
    private static final Comparator<RankedProcessRecord> LAST_RSS_COMPARATOR =
            new LastRssComparator();
    private static final Comparator<RankedProcessRecord> LAST_ACTIVITY_TIME_COMPARATOR =
@@ -70,6 +82,7 @@ public class CacheOomRanker {
    private final Object mPhenotypeFlagLock = new Object();

    private final ActivityManagerService mService;
    private final ProcessDependencies mProcessDependencies;
    private final ActivityManagerGlobalLock mProcLock;
    private final Object mProfilerLock;

@@ -78,6 +91,12 @@ public class CacheOomRanker {
    @GuardedBy("mPhenotypeFlagLock")
    @VisibleForTesting
    int mPreserveTopNApps = DEFAULT_PRESERVE_TOP_N_APPS;
    @GuardedBy("mPhenotypeFlagLock")
    @VisibleForTesting
    boolean mUseFrequentRss = DEFAULT_USE_FREQUENT_RSS;
    @GuardedBy("mPhenotypeFlagLock")
    @VisibleForTesting
    long mRssUpdateRateMs = DEFAULT_RSS_UPDATE_RATE_MS;
    // Weight to apply to the LRU ordering.
    @GuardedBy("mPhenotypeFlagLock")
    @VisibleForTesting
@@ -110,6 +129,10 @@ public class CacheOomRanker {
                                updateNumberToReRank();
                            } else if (KEY_OOM_RE_RANKING_PRESERVE_TOP_N_APPS.equals(name)) {
                                updatePreserveTopNApps();
                            } else if (KEY_OOM_RE_RANKING_USE_FREQUENT_RSS.equals(name)) {
                                updateUseFrequentRss();
                            } else if (KEY_OOM_RE_RANKING_RSS_UPDATE_RATE_MS.equals(name)) {
                                updateRssUpdateRateMs();
                            } else if (KEY_OOM_RE_RANKING_LRU_WEIGHT.equals(name)) {
                                updateLruWeight();
                            } else if (KEY_OOM_RE_RANKING_USES_WEIGHT.equals(name)) {
@@ -123,9 +146,15 @@ public class CacheOomRanker {
            };

    CacheOomRanker(final ActivityManagerService service) {
        this(service, new ProcessDependenciesImpl());
    }

    @VisibleForTesting
    CacheOomRanker(final ActivityManagerService service, ProcessDependencies processDependencies) {
        mService = service;
        mProcLock = service.mProcLock;
        mProfilerLock = service.mAppProfiler.mProfilerLock;
        mProcessDependencies = processDependencies;
    }

    /** Load settings from device config and register a listener for changes. */
@@ -189,6 +218,18 @@ public class CacheOomRanker {
        mPreserveTopNApps = preserveTopNApps;
    }

    @GuardedBy("mPhenotypeFlagLock")
    private void updateRssUpdateRateMs() {
        mRssUpdateRateMs = DeviceConfig.getLong(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
                KEY_OOM_RE_RANKING_RSS_UPDATE_RATE_MS, DEFAULT_RSS_UPDATE_RATE_MS);
    }

    @GuardedBy("mPhenotypeFlagLock")
    private void updateUseFrequentRss() {
        mUseFrequentRss = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
                KEY_OOM_RE_RANKING_USE_FREQUENT_RSS, DEFAULT_USE_FREQUENT_RSS);
    }

    @GuardedBy("mPhenotypeFlagLock")
    private void updateLruWeight() {
        mLruWeight = DeviceConfig.getFloat(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
@@ -244,6 +285,8 @@ public class CacheOomRanker {
        float usesWeight;
        float rssWeight;
        int preserveTopNApps;
        boolean useFrequentRss;
        long rssUpdateRateMs;
        int[] lruPositions;
        RankedProcessRecord[] scoredProcessRecords;

@@ -252,6 +295,8 @@ public class CacheOomRanker {
            usesWeight = mUsesWeight;
            rssWeight = mRssWeight;
            preserveTopNApps = mPreserveTopNApps;
            useFrequentRss = mUseFrequentRss;
            rssUpdateRateMs = mRssUpdateRateMs;
            lruPositions = mLruPositions;
            scoredProcessRecords = mScoredProcessRecords;
        }
@@ -296,6 +341,33 @@ public class CacheOomRanker {
            }
        }

        if (useFrequentRss) {
            // Update RSS values for re-ranked apps.
            long nowMs = SystemClock.elapsedRealtime();
            for (int i = 0; i < numProcessesReRanked; ++i) {
                RankedProcessRecord scoredProcessRecord = scoredProcessRecords[i];
                long sinceUpdateMs =
                        nowMs - scoredProcessRecord.proc.mState.getCacheOomRankerRssTimeMs();
                if (scoredProcessRecord.proc.mState.getCacheOomRankerRss() != 0
                        && sinceUpdateMs < rssUpdateRateMs) {
                    continue;
                }

                long[] rss = mProcessDependencies.getRss(scoredProcessRecord.proc.getPid());
                if (rss == null || rss.length == 0) {
                    Slog.e(
                            OomAdjuster.TAG,
                            "Process.getRss returned bad value, not re-ranking: "
                                    + Arrays.toString(rss));
                    return;
                }
                // First element is total RSS:
                // frameworks/base/core/jni/android_util_Process.cpp:1192
                scoredProcessRecord.proc.mState.setCacheOomRankerRss(rss[0], nowMs);
                scoredProcessRecord.proc.mProfile.setLastRss(rss[0]);
            }
        }

        // Add scores for each of the weighted features we want to rank based on.
        if (lruWeight > 0.0f) {
            // This doesn't use the LRU list ordering as after the first re-ranking
@@ -305,9 +377,13 @@ public class CacheOomRanker {
            addToScore(scoredProcessRecords, lruWeight);
        }
        if (rssWeight > 0.0f) {
            if (useFrequentRss) {
                Arrays.sort(scoredProcessRecords, 0, numProcessesReRanked, RSS_COMPARATOR);
            } else {
                synchronized (mService.mAppProfiler.mProfilerLock) {
                    Arrays.sort(scoredProcessRecords, 0, numProcessesReRanked, LAST_RSS_COMPARATOR);
                }
            }
            addToScore(scoredProcessRecords, rssWeight);
        }
        if (usesWeight > 0.0f) {
@@ -385,6 +461,16 @@ public class CacheOomRanker {
        }
    }

    private static class RssComparator implements Comparator<RankedProcessRecord> {
        @Override
        public int compare(RankedProcessRecord o1, RankedProcessRecord o2) {
            // High RSS first to match least recently used.
            return Long.compare(
                    o2.proc.mState.getCacheOomRankerRss(),
                    o1.proc.mState.getCacheOomRankerRss());
        }
    }

    private static class LastRssComparator implements Comparator<RankedProcessRecord> {
        @Override
        public int compare(RankedProcessRecord o1, RankedProcessRecord o2) {
@@ -397,4 +483,18 @@ public class CacheOomRanker {
        public ProcessRecord proc;
        public float score;
    }

    /**
     * Interface for mocking {@link Process} static methods.
     */
    interface ProcessDependencies {
        long[] getRss(int pid);
    }

    private static class ProcessDependenciesImpl implements ProcessDependencies {
        @Override
        public long[] getRss(int pid) {
            return Process.getRss(pid);
        }
    }
}
+29 −0
Original line number Diff line number Diff line
@@ -342,6 +342,20 @@ final class ProcessStateRecord {
    @GuardedBy("mService")
    private int mCacheOomRankerUseCount;

    /**
     * Process memory usage (RSS).
     *
     * Periodically populated by {@code CacheOomRanker}, stored in this object to cache the values.
     */
    @GuardedBy("mService")
    private long mCacheOomRankerRss;

    /**
     * The last time, in milliseconds since boot, since {@link #mCacheOomRankerRss} was updated.
     */
    @GuardedBy("mService")
    private long mCacheOomRankerRssTimeMs;

    /**
     * Whether or not this process is reachable from given process.
     */
@@ -1150,6 +1164,21 @@ final class ProcessStateRecord {
        return mLastInvisibleTime;
    }

    public void setCacheOomRankerRss(long rss, long rssTimeMs) {
        mCacheOomRankerRss = rss;
        mCacheOomRankerRssTimeMs = rssTimeMs;
    }

    @GuardedBy("mService")
    public long getCacheOomRankerRss() {
        return mCacheOomRankerRss;
    }

    @GuardedBy("mService")
    public long getCacheOomRankerRssTimeMs() {
        return mCacheOomRankerRssTimeMs;
    }

    @GuardedBy({"mService", "mProcLock"})
    void dump(PrintWriter pw, String prefix, long nowUptime) {
        if (mReportedInteraction || mFgInteractionTime != 0) {
+162 −4
Original line number Diff line number Diff line
@@ -57,6 +57,9 @@ import java.time.LocalDate;
import java.time.ZoneOffset;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
@@ -67,6 +70,7 @@ import java.util.concurrent.TimeUnit;
 * Build/Install/Run:
 * atest FrameworksMockingServicesTests:CacheOomRankerTest
 */
@SuppressWarnings("GuardedBy") // No tests are concurrent, so no need to test locking.
@RunWith(MockitoJUnitRunner.class)
public class CacheOomRankerTest {
    private static final Instant NOW = LocalDate.of(2021, 1, 1).atStartOfDay(
@@ -91,6 +95,7 @@ public class CacheOomRankerTest {
    private int mNextUid = 30000;
    private int mNextPackageUid = 40000;
    private int mNextPackageName = 1;
    private Map<Integer, Long> mPidToRss;

    private TestExecutor mExecutor = new TestExecutor();
    private CacheOomRanker mCacheOomRanker;
@@ -116,7 +121,15 @@ public class CacheOomRankerTest {
        LocalServices.removeServiceForTest(PackageManagerInternal.class);
        LocalServices.addService(PackageManagerInternal.class, mPackageManagerInt);

        mCacheOomRanker = new CacheOomRanker(mAms);
        mPidToRss = new HashMap<>();
        mCacheOomRanker = new CacheOomRanker(
                mAms,
                pid -> {
                    Long rss = mPidToRss.get(pid);
                    assertThat(rss).isNotNull();
                    return new long[]{rss};
                }
        );
        mCacheOomRanker.init(mExecutor);
    }

@@ -184,6 +197,8 @@ public class CacheOomRankerTest {
    public void reRankLruCachedApps_lruImpactsOrdering() throws InterruptedException {
        setConfig(/* numberToReRank= */ 5,
                /* preserveTopNApps= */ 0,
                /* useFrequentRss= */ true,
                /* rssUpdateRateMs= */ 0,
                /* usesWeight= */ 0.0f,
                /* pssWeight= */ 0.0f,
                /* lruWeight= */1.0f);
@@ -223,6 +238,52 @@ public class CacheOomRankerTest {
    public void reRankLruCachedApps_rssImpactsOrdering() throws InterruptedException {
        setConfig(/* numberToReRank= */ 6,
                /* preserveTopNApps= */ 0,
                /* useFrequentRss= */ true,
                /* rssUpdateRateMs= */ 0,
                /* usesWeight= */ 0.0f,
                /* pssWeight= */ 1.0f,
                /* lruWeight= */ 0.0f);

        ProcessList list = new ProcessList();
        ArrayList<ProcessRecord> processList = list.getLruProcessesLSP();
        ProcessRecord rss10k = nextProcessRecord(ProcessList.UNKNOWN_ADJ,
                NOW.minus(40, ChronoUnit.MINUTES).toEpochMilli(), 10 * 1024L, 1000);
        processList.add(rss10k);
        ProcessRecord rss20k = nextProcessRecord(ProcessList.UNKNOWN_ADJ,
                NOW.minus(42, ChronoUnit.MINUTES).toEpochMilli(), 20 * 1024L, 2000);
        processList.add(rss20k);
        ProcessRecord rss1k = nextProcessRecord(ProcessList.UNKNOWN_ADJ,
                NOW.minus(60, ChronoUnit.MINUTES).toEpochMilli(), 1024L, 10000);
        processList.add(rss1k);
        ProcessRecord rss100k = nextProcessRecord(ProcessList.UNKNOWN_ADJ,
                NOW.minus(15, ChronoUnit.MINUTES).toEpochMilli(), 100 * 1024L, 10);
        processList.add(rss100k);
        ProcessRecord rss2k = nextProcessRecord(ProcessList.UNKNOWN_ADJ,
                NOW.minus(17, ChronoUnit.MINUTES).toEpochMilli(), 2 * 1024L, 20);
        processList.add(rss2k);
        ProcessRecord rss15k = nextProcessRecord(ProcessList.UNKNOWN_ADJ,
                NOW.minus(30, ChronoUnit.MINUTES).toEpochMilli(), 15 * 1024L, 20);
        processList.add(rss15k);
        // Only re-ranking 6 entries so this should stay in most recent position.
        ProcessRecord rss16k = nextProcessRecord(ProcessList.UNKNOWN_ADJ,
                NOW.minus(30, ChronoUnit.MINUTES).toEpochMilli(), 16 * 1024L, 20);
        processList.add(rss16k);
        list.setLruProcessServiceStartLSP(processList.size());

        mCacheOomRanker.reRankLruCachedAppsLSP(processList, list.getLruProcessServiceStartLOSP());

        // First 6 ordered by largest pss, then last processes position unchanged.
        assertThat(processList).containsExactly(rss100k, rss20k, rss15k, rss10k, rss2k, rss1k,
                rss16k).inOrder();
    }

    @Test
    public void reRankLruCachedApps_rssImpactsOrdering_cachedRssValues()
            throws InterruptedException {
        setConfig(/* numberToReRank= */ 6,
                /* preserveTopNApps= */ 0,
                /* useFrequentRss= */ true,
                /* rssUpdateRateMs= */ 10000000,
                /* usesWeight= */ 0.0f,
                /* pssWeight= */ 1.0f,
                /* lruWeight= */ 0.0f);
@@ -254,16 +315,91 @@ public class CacheOomRankerTest {
        list.setLruProcessServiceStartLSP(processList.size());

        mCacheOomRanker.reRankLruCachedAppsLSP(processList, list.getLruProcessServiceStartLOSP());
        // First 6 ordered by largest pss, then last processes position unchanged.
        assertThat(processList).containsExactly(rss100k, rss20k, rss15k, rss10k, rss2k, rss1k,
                rss16k).inOrder();

        // Clear mPidToRss so that Process.getRss calls fail.
        mPidToRss.clear();
        // Mix up the process list to ensure that CacheOomRanker actually re-ranks.
        Collections.swap(processList, 0, 1);

        mCacheOomRanker.reRankLruCachedAppsLSP(processList, list.getLruProcessServiceStartLOSP());
        // Re ranking is the same.
        assertThat(processList).containsExactly(rss100k, rss20k, rss15k, rss10k, rss2k, rss1k,
                rss16k).inOrder();
    }

    @Test
    public void reRankLruCachedApps_rssImpactsOrdering_profileRss()
            throws InterruptedException {
        setConfig(/* numberToReRank= */ 6,
                /* preserveTopNApps= */ 0,
                /* useFrequentRss= */ false,
                /* rssUpdateRateMs= */ 10000000,
                /* usesWeight= */ 0.0f,
                /* pssWeight= */ 1.0f,
                /* lruWeight= */ 0.0f);

        ProcessList list = new ProcessList();
        ArrayList<ProcessRecord> processList = list.getLruProcessesLSP();
        ProcessRecord rss10k = nextProcessRecord(ProcessList.UNKNOWN_ADJ,
                NOW.minus(40, ChronoUnit.MINUTES).toEpochMilli(), 0L, 1000);
        rss10k.mProfile.setLastRss(10 * 1024L);
        processList.add(rss10k);
        ProcessRecord rss20k = nextProcessRecord(ProcessList.UNKNOWN_ADJ,
                NOW.minus(42, ChronoUnit.MINUTES).toEpochMilli(), 0L, 2000);
        rss20k.mProfile.setLastRss(20 * 1024L);
        processList.add(rss20k);
        ProcessRecord rss1k = nextProcessRecord(ProcessList.UNKNOWN_ADJ,
                NOW.minus(60, ChronoUnit.MINUTES).toEpochMilli(), 0L, 10000);
        rss1k.mProfile.setLastRss(1024L);
        processList.add(rss1k);
        ProcessRecord rss100k = nextProcessRecord(ProcessList.UNKNOWN_ADJ,
                NOW.minus(15, ChronoUnit.MINUTES).toEpochMilli(), 0L, 10);
        rss100k.mProfile.setLastRss(100 * 1024L);
        processList.add(rss100k);
        ProcessRecord rss2k = nextProcessRecord(ProcessList.UNKNOWN_ADJ,
                NOW.minus(17, ChronoUnit.MINUTES).toEpochMilli(), 0L, 20);
        rss2k.mProfile.setLastRss(2 * 1024L);
        processList.add(rss2k);
        ProcessRecord rss15k = nextProcessRecord(ProcessList.UNKNOWN_ADJ,
                NOW.minus(30, ChronoUnit.MINUTES).toEpochMilli(), 15 * 1024L, 20);
        rss15k.mProfile.setLastRss(15 * 1024L);
        processList.add(rss15k);
        // Only re-ranking 6 entries so this should stay in most recent position.
        ProcessRecord rss16k = nextProcessRecord(ProcessList.UNKNOWN_ADJ,
                NOW.minus(30, ChronoUnit.MINUTES).toEpochMilli(), 16 * 1024L, 20);
        rss16k.mProfile.setLastRss(16 * 1024L);
        processList.add(rss16k);
        list.setLruProcessServiceStartLSP(processList.size());

        // This should not be used, as RSS values are taken from mProfile.
        mPidToRss.clear();

        mCacheOomRanker.reRankLruCachedAppsLSP(processList, list.getLruProcessServiceStartLOSP());
        // First 6 ordered by largest pss, then last processes position unchanged.
        assertThat(processList).containsExactly(rss100k, rss20k, rss15k, rss10k, rss2k, rss1k,
                rss16k).inOrder();

        // Clear mPidToRss so that Process.getRss calls fail.
        mPidToRss.clear();
        // Mix up the process list to ensure that CacheOomRanker actually re-ranks.
        Collections.swap(processList, 0, 1);

        mCacheOomRanker.reRankLruCachedAppsLSP(processList, list.getLruProcessServiceStartLOSP());
        // Re ranking is the same.
        assertThat(processList).containsExactly(rss100k, rss20k, rss15k, rss10k, rss2k, rss1k,
                rss16k).inOrder();
    }


    @Test
    public void reRankLruCachedApps_usesImpactsOrdering() throws InterruptedException {
        setConfig(/* numberToReRank= */ 4,
                /* preserveTopNApps= */ 0,
                /* useFrequentRss= */ true,
                /* rssUpdateRateMs= */ 0,
                /* usesWeight= */ 1.0f,
                /* pssWeight= */ 0.0f,
                /* lruWeight= */ 0.0f);
@@ -302,6 +438,8 @@ public class CacheOomRankerTest {
    public void reRankLruCachedApps_fewProcesses() throws InterruptedException {
        setConfig(/* numberToReRank= */ 4,
                /* preserveTopNApps= */ 0,
                /* useFrequentRss= */ true,
                /* rssUpdateRateMs= */ 0,
                /* usesWeight= */ 1.0f,
                /* pssWeight= */ 0.0f,
                /* lruWeight= */ 0.0f);
@@ -339,6 +477,8 @@ public class CacheOomRankerTest {
    public void reRankLruCachedApps_fewNonServiceProcesses() throws InterruptedException {
        setConfig(/* numberToReRank= */ 4,
                /* preserveTopNApps= */ 0,
                /* useFrequentRss= */ true,
                /* rssUpdateRateMs= */ 0,
                /* usesWeight= */ 1.0f,
                /* pssWeight= */ 0.0f,
                /* lruWeight= */ 0.0f);
@@ -376,6 +516,8 @@ public class CacheOomRankerTest {
    public void reRankLruCachedApps_manyProcessesThenFew() throws InterruptedException {
        setConfig(/* numberToReRank= */ 6,
                /* preserveTopNApps= */ 0,
                /* useFrequentRss= */ true,
                /* rssUpdateRateMs= */ 0,
                /* usesWeight= */ 1.0f,
                /* pssWeight= */ 0.0f,
                /* lruWeight= */ 0.0f);
@@ -439,6 +581,8 @@ public class CacheOomRankerTest {
    public void reRankLruCachedApps_preservesTopNApps() throws InterruptedException {
        setConfig(/* numberToReRank= */ 6,
                /* preserveTopNApps= */ 3,
                /* useFrequentRss= */ true,
                /* rssUpdateRateMs= */ 0,
                /* usesWeight= */ 1.0f,
                /* pssWeight= */ 0.0f,
                /* lruWeight= */ 0.0f);
@@ -478,6 +622,8 @@ public class CacheOomRankerTest {
            throws InterruptedException {
        setConfig(/* numberToReRank= */ 6,
                /* preserveTopNApps= */ 100,
                /* useFrequentRss= */ true,
                /* rssUpdateRateMs= */ 0,
                /* usesWeight= */ 1.0f,
                /* pssWeight= */ 0.0f,
                /* lruWeight= */ 0.0f);
@@ -516,6 +662,8 @@ public class CacheOomRankerTest {
            throws InterruptedException {
        setConfig(/* numberToReRank= */ 6,
                /* preserveTopNApps= */ -100,
                /* useFrequentRss= */ true,
                /* rssUpdateRateMs= */ 0,
                /* usesWeight= */ 1.0f,
                /* pssWeight= */ 0.0f,
                /* lruWeight= */ 0.0f);
@@ -550,8 +698,8 @@ public class CacheOomRankerTest {
                used200).inOrder();
    }

    private void setConfig(int numberToReRank, int preserveTopNApps, float usesWeight,
            float pssWeight, float lruWeight)
    private void setConfig(int numberToReRank, int preserveTopNApps, boolean useFrequentRss,
            long rssUpdateRateMs, float usesWeight, float pssWeight, float lruWeight)
            throws InterruptedException {
        mExecutor.init(4);
        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
@@ -562,6 +710,14 @@ public class CacheOomRankerTest {
                CacheOomRanker.KEY_OOM_RE_RANKING_PRESERVE_TOP_N_APPS,
                Integer.toString(preserveTopNApps),
                false);
        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
                CacheOomRanker.KEY_OOM_RE_RANKING_USE_FREQUENT_RSS,
                Boolean.toString(useFrequentRss),
                false);
        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
                CacheOomRanker.KEY_OOM_RE_RANKING_RSS_UPDATE_RATE_MS,
                Long.toString(rssUpdateRateMs),
                false);
        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
                CacheOomRanker.KEY_OOM_RE_RANKING_LRU_WEIGHT,
                Float.toString(lruWeight),
@@ -576,6 +732,8 @@ public class CacheOomRankerTest {
                false);
        mExecutor.waitForLatch();
        assertThat(mCacheOomRanker.getNumberToReRank()).isEqualTo(numberToReRank);
        assertThat(mCacheOomRanker.mUseFrequentRss).isEqualTo(useFrequentRss);
        assertThat(mCacheOomRanker.mRssUpdateRateMs).isEqualTo(rssUpdateRateMs);
        assertThat(mCacheOomRanker.mRssWeight).isEqualTo(pssWeight);
        assertThat(mCacheOomRanker.mUsesWeight).isEqualTo(usesWeight);
        assertThat(mCacheOomRanker.mLruWeight).isEqualTo(lruWeight);
@@ -592,7 +750,7 @@ public class CacheOomRankerTest {
        app.mState.setSetProcState(PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
        app.mState.setCurAdj(setAdj);
        app.setLastActivityTime(lastActivityTime);
        app.mProfile.setLastRss(lastRss);
        mPidToRss.put(app.getPid(), lastRss);
        app.mState.setCached(false);
        for (int i = 0; i < wentToForegroundCount; ++i) {
            app.mState.setSetProcState(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);