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

Commit a4f4ae77 authored by Jing Ji's avatar Jing Ji
Browse files

Scan the downstream apps while updating oomadj for pending records

Bug: 188060432
Test: atest ActivityManagerFgsBgStartTest
Test: atest FrameworksServicesTests:ActivityManagerTest
Test: atest MockingOomAdjusterTests
Test: atest CtsAppTestCases:ActivityManagerProcessStateTest
Change-Id: I8f2574d7cc6a59c76452f7cce57dab1b633fa7f5
parent c562b93a
Loading
Loading
Loading
Loading
+53 −34
Original line number Diff line number Diff line
@@ -511,6 +511,7 @@ public class OomAdjuster {
        final ProcessRecord topApp = mService.getTopApp();
        final ProcessStateRecord state = app.mState;
        final boolean wasCached = state.isCached();
        final int oldCap = state.getSetCapability();

        mAdjSeq++;

@@ -526,6 +527,7 @@ public class OomAdjuster {
                SystemClock.uptimeMillis());
        if (oomAdjAll
                && (wasCached != state.isCached()
                    || oldCap != state.getSetCapability()
                    || state.getCurRawAdj() == ProcessList.UNKNOWN_ADJ)) {
            // Changed to/from cached state, so apps after it in the LRU
            // list may also be changed.
@@ -663,6 +665,7 @@ public class OomAdjuster {
                ? oldAdj : ProcessList.UNKNOWN_ADJ;
        final boolean wasBackground = ActivityManager.isProcStateBackground(
                state.getSetProcState());
        final int oldCap = state.getSetCapability();
        state.setContainsCycle(false);
        state.setProcStateChanged(false);
        state.resetCachedInfo();
@@ -671,6 +674,7 @@ public class OomAdjuster {
        boolean success = performUpdateOomAdjLSP(app, cachedAdj, topApp, false,
                SystemClock.uptimeMillis());
        if (!success || (wasCached == state.isCached() && oldAdj != ProcessList.INVALID_ADJ
                && oldCap == state.getCurCapability()
                && wasBackground == ActivityManager.isProcStateBackground(
                        state.getSetProcState()))) {
            // Okay, it's unchanged, it won't impact any service it binds to, we're done here.
@@ -685,20 +689,60 @@ public class OomAdjuster {
        // Next to find out all its reachable processes
        ArrayList<ProcessRecord> processes = mTmpProcessList;
        ActiveUids uids = mTmpUidRecords;
        ArrayDeque<ProcessRecord> queue = mTmpQueue;
        mPendingProcessSet.add(app);

        boolean containsCycle = collectReachableProcessesLocked(mPendingProcessSet,
                processes, uids);

        // Reset the flag
        state.setReachable(false);
        // Remove this app from the return list because we've done the computation on it.
        processes.remove(app);

        int size = processes.size();
        if (size > 0) {
            mAdjSeq--;
            // Update these reachable processes
            updateOomAdjInnerLSP(oomAdjReason, topApp, processes, uids, containsCycle, false);
        } else if (state.getCurRawAdj() == ProcessList.UNKNOWN_ADJ) {
            // In case the app goes from non-cached to cached but it doesn't have other reachable
            // processes, its adj could be still unknown as of now, assign one.
            processes.add(app);
            assignCachedAdjIfNecessary(processes);
            applyOomAdjLSP(app, false, SystemClock.uptimeMillis(),
                    SystemClock.elapsedRealtime());
        }
        mTmpProcessList.clear();
        mService.mOomAdjProfiler.oomAdjEnded();
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        return true;
    }

    @GuardedBy("mService")
    private boolean collectReachableProcessesLocked(ArraySet<ProcessRecord> apps,
            ArrayList<ProcessRecord> processes, ActiveUids uids) {
        final ArrayDeque<ProcessRecord> queue = mTmpQueue;
        queue.clear();
        for (int i = 0, size = apps.size(); i < size; i++) {
            final ProcessRecord app = apps.valueAt(i);
            app.mState.setReachable(true);
            queue.offer(app);
        }

        return collectReachableProcessesLocked(queue, processes, uids);
    }

    @GuardedBy("mService")
    private boolean collectReachableProcessesLocked(ArrayDeque<ProcessRecord> queue,
            ArrayList<ProcessRecord> processes, ActiveUids uids) {
        processes.clear();
        uids.clear();
        queue.clear();

        // Track if any of them reachables could include a cycle
        boolean containsCycle = false;
        // Scan downstreams of the process record
        state.setReachable(true);
        for (ProcessRecord pr = app; pr != null; pr = queue.poll()) {
            if (pr != app) {
        for (ProcessRecord pr = queue.poll(); pr != null; pr = queue.poll()) {
            processes.add(pr);
            }
            final UidRecord uidRec = pr.getUidRecord();
            if (uidRec != null) {
                uids.put(uidRec.getUid(), uidRec);
@@ -749,8 +793,6 @@ public class OomAdjuster {
            }
        }

        // Reset the flag
        state.setReachable(false);
        int size = processes.size();
        if (size > 0) {
            // Reverse the process list, since the updateOomAdjInnerLSP scans from the end of it.
@@ -759,21 +801,8 @@ public class OomAdjuster {
                processes.set(l, processes.get(r));
                processes.set(r, t);
            }
            mAdjSeq--;
            // Update these reachable processes
            updateOomAdjInnerLSP(oomAdjReason, topApp, processes, uids, containsCycle, false);
        } else if (state.getCurRawAdj() == ProcessList.UNKNOWN_ADJ) {
            // In case the app goes from non-cached to cached but it doesn't have other reachable
            // processes, its adj could be still unknown as of now, assign one.
            processes.add(app);
            assignCachedAdjIfNecessary(processes);
            applyOomAdjLSP(app, false, SystemClock.uptimeMillis(),
                    SystemClock.elapsedRealtime());
        }
        mTmpProcessList.clear();
        mService.mOomAdjProfiler.oomAdjEnded();
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        return true;
        return containsCycle;
    }

    /**
@@ -857,18 +886,8 @@ public class OomAdjuster {

        final ArrayList<ProcessRecord> processes = mTmpProcessList;
        final ActiveUids uids = mTmpUidRecords;
        collectReachableProcessesLocked(mPendingProcessSet, processes, uids);
        synchronized (mProcLock) {
            uids.clear();
            processes.clear();
            for (int i = mPendingProcessSet.size() - 1; i >= 0; i--) {
                final ProcessRecord app = mPendingProcessSet.valueAt(i);
                final UidRecord uidRec = app.getUidRecord();
                if (uidRec != null) {
                    uids.put(uidRec.getUid(), uidRec);
                }
                processes.add(app);
            }

            updateOomAdjInnerLSP(oomAdjReason, topApp, processes, uids, true, false);
        }
        processes.clear();