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

Commit 25de1d2d authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Move abstraction of activity priority calculation

This converts ComputeOomAdjCallback interface to exported flags.
So it is easier to separate the dependency, add new conditions,
and handle state consistently in the future.

Bug: 302575389
Bug: 200769420
Flag: EXEMPT refactor
Test: WindowProcessControllerTests#testComputeOomAdjFromActivities
      MockingOomAdjusterTests
Change-Id: I1f43ec2c6701ef1240ce483f8a2d14972bc2a01c
parent 733b315a
Loading
Loading
Loading
Loading
+5 −10
Original line number Diff line number Diff line
@@ -1653,8 +1653,7 @@ public class OomAdjuster {
            new ComputeOomAdjWindowCallback();

    /** These methods are called inline during computeOomAdjLSP(), on the same thread */
    final class ComputeOomAdjWindowCallback
            implements WindowProcessController.ComputeOomAdjCallback {
    final class ComputeOomAdjWindowCallback {

        ProcessRecord app;
        int adj;
@@ -1684,8 +1683,7 @@ public class OomAdjuster {
            this.mState = app.mState;
        }

        @Override
        public void onVisibleActivity() {
        void onVisibleActivity() {
            // App has a visible activity; only upgrade adjustment.
            if (adj > VISIBLE_APP_ADJ) {
                adj = VISIBLE_APP_ADJ;
@@ -1709,8 +1707,7 @@ public class OomAdjuster {
            mHasVisibleActivities = true;
        }

        @Override
        public void onPausedActivity() {
        void onPausedActivity() {
            if (adj > PERCEPTIBLE_APP_ADJ) {
                adj = PERCEPTIBLE_APP_ADJ;
                mAdjType = "pause-activity";
@@ -1733,8 +1730,7 @@ public class OomAdjuster {
            mHasVisibleActivities = false;
        }

        @Override
        public void onStoppingActivity(boolean finishing) {
        void onStoppingActivity(boolean finishing) {
            if (adj > PERCEPTIBLE_APP_ADJ) {
                adj = PERCEPTIBLE_APP_ADJ;
                mAdjType = "stop-activity";
@@ -1764,8 +1760,7 @@ public class OomAdjuster {
            mHasVisibleActivities = false;
        }

        @Override
        public void onOtherActivity() {
        void onOtherActivity() {
            if (procState > PROCESS_STATE_CACHED_ACTIVITY) {
                procState = PROCESS_STATE_CACHED_ACTIVITY;
                mAdjType = "cch-act";
+18 −2
Original line number Diff line number Diff line
@@ -27,6 +27,11 @@ import static android.app.ProcessMemoryState.HOSTING_COMPONENT_TYPE_STARTED_SERV
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
import static com.android.server.am.ProcessList.CACHED_APP_MIN_ADJ;
import static com.android.server.am.ProcessRecord.TAG;
import static com.android.server.wm.WindowProcessController.ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED;
import static com.android.server.wm.WindowProcessController.ACTIVITY_STATE_FLAG_IS_STOPPING;
import static com.android.server.wm.WindowProcessController.ACTIVITY_STATE_FLAG_IS_STOPPING_FINISHING;
import static com.android.server.wm.WindowProcessController.ACTIVITY_STATE_FLAG_IS_VISIBLE;
import static com.android.server.wm.WindowProcessController.ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER;

import android.annotation.ElapsedRealtimeLong;
import android.app.ActivityManager;
@@ -1117,8 +1122,17 @@ final class ProcessStateRecord {
        }
        callback.initialize(mApp, adj, foregroundActivities, hasVisibleActivities, procState,
                schedGroup, appUid, logUid, processCurTop);
        final int minLayer = Math.min(ProcessList.VISIBLE_APP_LAYER_MAX,
                mApp.getWindowProcessController().computeOomAdjFromActivities(callback));
        final int flags = mApp.getWindowProcessController().getActivityStateFlags();

        if ((flags & ACTIVITY_STATE_FLAG_IS_VISIBLE) != 0) {
            callback.onVisibleActivity();
        } else if ((flags & ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED) != 0) {
            callback.onPausedActivity();
        } else if ((flags & ACTIVITY_STATE_FLAG_IS_STOPPING) != 0) {
            callback.onStoppingActivity((flags & ACTIVITY_STATE_FLAG_IS_STOPPING_FINISHING) != 0);
        } else {
            callback.onOtherActivity();
        }

        mCachedAdj = callback.adj;
        mCachedForegroundActivities = callback.foregroundActivities;
@@ -1128,6 +1142,8 @@ final class ProcessStateRecord {
        mCachedAdjType = callback.mAdjType;

        if (mCachedAdj == ProcessList.VISIBLE_APP_ADJ) {
            final int taskLayer = flags & ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER;
            final int minLayer = Math.min(ProcessList.VISIBLE_APP_LAYER_MAX, taskLayer);
            mCachedAdj += minLayer;
        }
    }
+12 −30
Original line number Diff line number Diff line
@@ -309,14 +309,14 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
    private volatile boolean mWasStoppedLogged;

    // The bits used for mActivityStateFlags.
    private static final int ACTIVITY_STATE_FLAG_IS_VISIBLE = 1 << 16;
    private static final int ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED = 1 << 17;
    private static final int ACTIVITY_STATE_FLAG_IS_STOPPING = 1 << 18;
    private static final int ACTIVITY_STATE_FLAG_IS_STOPPING_FINISHING = 1 << 19;
    private static final int ACTIVITY_STATE_FLAG_IS_WINDOW_VISIBLE = 1 << 20;
    private static final int ACTIVITY_STATE_FLAG_HAS_RESUMED = 1 << 21;
    private static final int ACTIVITY_STATE_FLAG_HAS_ACTIVITY_IN_VISIBLE_TASK = 1 << 22;
    private static final int ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER = 0x0000ffff;
    public static final int ACTIVITY_STATE_FLAG_IS_VISIBLE = 1 << 16;
    public static final int ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED = 1 << 17;
    public static final int ACTIVITY_STATE_FLAG_IS_STOPPING = 1 << 18;
    public static final int ACTIVITY_STATE_FLAG_IS_STOPPING_FINISHING = 1 << 19;
    public static final int ACTIVITY_STATE_FLAG_IS_WINDOW_VISIBLE = 1 << 20;
    public static final int ACTIVITY_STATE_FLAG_HAS_RESUMED = 1 << 21;
    public static final int ACTIVITY_STATE_FLAG_HAS_ACTIVITY_IN_VISIBLE_TASK = 1 << 22;
    public static final int ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER = 0x0000ffff;

    /**
     * The state for oom-adjustment calculation. The higher 16 bits are the activity states, and the
@@ -1211,31 +1211,13 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
        }
    }

    public interface ComputeOomAdjCallback {
        void onVisibleActivity();
        void onPausedActivity();
        void onStoppingActivity(boolean finishing);
        void onOtherActivity();
    }

    /**
     * Returns the minimum task layer rank. It should only be called if {@link #hasActivities}
     * returns {@code true}.
     * Returns the current ACTIVITY_STATE_FLAG_* of this process. It should only be called if
     * {@link #hasActivities} returns {@code true}.
     */
    @HotPath(caller = HotPath.OOM_ADJUSTMENT)
    public int computeOomAdjFromActivities(ComputeOomAdjCallback callback) {
        final int flags = mActivityStateFlags;
        if ((flags & ACTIVITY_STATE_FLAG_IS_VISIBLE) != 0) {
            callback.onVisibleActivity();
        } else if ((flags & ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED) != 0) {
            callback.onPausedActivity();
        } else if ((flags & ACTIVITY_STATE_FLAG_IS_STOPPING) != 0) {
            callback.onStoppingActivity(
                    (flags & ACTIVITY_STATE_FLAG_IS_STOPPING_FINISHING) != 0);
        } else {
            callback.onOtherActivity();
        }
        return flags & ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER;
    public int getActivityStateFlags() {
        return mActivityStateFlags;
    }

    void computeProcessActivityState() {
+3 −17
Original line number Diff line number Diff line
@@ -72,14 +72,12 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.AdditionalAnswers.answer;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doCallRealMethod;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
@@ -486,24 +484,12 @@ public class MockingOomAdjusterTests {
                MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true));
        WindowProcessController wpc = app.getWindowProcessController();
        doReturn(true).when(wpc).hasActivities();
        doAnswer(answer(callback -> {
            Field field = callback.getClass().getDeclaredField("adj");
            field.set(callback, VISIBLE_APP_ADJ);
            field = callback.getClass().getDeclaredField("foregroundActivities");
            field.set(callback, true);
            field = callback.getClass().getDeclaredField("procState");
            field.set(callback, PROCESS_STATE_TOP);
            field = callback.getClass().getDeclaredField("schedGroup");
            field.set(callback, SCHED_GROUP_TOP_APP);
            field = callback.getClass().getDeclaredField("mAdjType");
            field.set(callback, "vis-activity");
            return 0;
        })).when(wpc).computeOomAdjFromActivities(
                any(WindowProcessController.ComputeOomAdjCallback.class));
        doReturn(WindowProcessController.ACTIVITY_STATE_FLAG_IS_VISIBLE)
                .when(wpc).getActivityStateFlags();
        mService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
        updateOomAdj(app);

        assertProcStates(app, PROCESS_STATE_TOP, VISIBLE_APP_ADJ, SCHED_GROUP_TOP_APP);
        assertProcStates(app, PROCESS_STATE_TOP, VISIBLE_APP_ADJ, SCHED_GROUP_DEFAULT);
        assertFalse(app.mState.isCached());
        assertFalse(app.mState.isEmpty());
        assertEquals("vis-activity", app.mState.getAdjType());
+17 −38
Original line number Diff line number Diff line
@@ -340,54 +340,33 @@ public class WindowProcessControllerTests extends WindowTestsBase {
    public void testComputeOomAdjFromActivities() {
        final ActivityRecord activity = createActivityRecord(mWpc);
        activity.setVisibleRequested(true);
        final int[] callbackResult = { 0 };
        final int visible = 1;
        final int paused = 2;
        final int stopping = 4;
        final int other = 8;
        final WindowProcessController.ComputeOomAdjCallback callback =
                new WindowProcessController.ComputeOomAdjCallback() {
            @Override
            public void onVisibleActivity() {
                callbackResult[0] |= visible;
            }

            @Override
            public void onPausedActivity() {
                callbackResult[0] |= paused;
            }

            @Override
            public void onStoppingActivity(boolean finishing) {
                callbackResult[0] |= stopping;
            }

            @Override
            public void onOtherActivity() {
                callbackResult[0] |= other;
            }
        };

        // onStartActivity should refresh the state immediately.
        mWpc.onStartActivity(0 /* topProcessState */, activity.info);
        assertEquals(1 /* minTaskLayer */, mWpc.computeOomAdjFromActivities(callback));
        assertEquals(visible, callbackResult[0]);
        int flags = mWpc.getActivityStateFlags();
        assertEquals(1 /* minTaskLayer */,
                flags & WindowProcessController.ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER);
        final int visibleFlags = WindowProcessController.ACTIVITY_STATE_FLAG_IS_VISIBLE
                | WindowProcessController.ACTIVITY_STATE_FLAG_IS_WINDOW_VISIBLE
                | WindowProcessController.ACTIVITY_STATE_FLAG_HAS_ACTIVITY_IN_VISIBLE_TASK;
        assertEquals(visibleFlags,
                flags & ~WindowProcessController.ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER);

        callbackResult[0] = 0;
        activity.setVisibleRequested(false);
        activity.setState(PAUSED, "test");
        mWpc.computeOomAdjFromActivities(callback);
        assertEquals(paused, callbackResult[0]);
        final int exclusiveFlags = WindowProcessController.ACTIVITY_STATE_FLAG_IS_VISIBLE
                | WindowProcessController.ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED
                | WindowProcessController.ACTIVITY_STATE_FLAG_IS_STOPPING;
        flags = mWpc.getActivityStateFlags() & exclusiveFlags;
        assertEquals(WindowProcessController.ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED, flags);

        callbackResult[0] = 0;
        activity.setState(STOPPING, "test");
        mWpc.computeOomAdjFromActivities(callback);
        assertEquals(stopping, callbackResult[0]);
        flags = mWpc.getActivityStateFlags() & exclusiveFlags;
        assertEquals(WindowProcessController.ACTIVITY_STATE_FLAG_IS_STOPPING, flags);

        callbackResult[0] = 0;
        activity.setState(STOPPED, "test");
        mWpc.computeOomAdjFromActivities(callback);
        assertEquals(other, callbackResult[0]);
        flags = mWpc.getActivityStateFlags() & exclusiveFlags;
        assertEquals(0, flags);
    }

    @Test