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

Commit bea0e67d authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Demote top app scheduling group when unlocking

SystemUI may be running the unlock animation. If both SystemUI
and the resuming top app have top-app scheduling group, there
may be CPU contention which causes animation jank.

An exceptional case is unlocking to home which may also animate,
then keep original behavior: both system ui and home will have
top-app scheduling group.

Bug: 240356132
Bug: 226367352
Test: Launch calculator.
      Keep executing command "adb shell dumpsys activity o | grep calc"
      Lock and unlock device.
      The dump will have the changes:
      b/A/TPSL ----  t: 0 20687:calc/u0a158 (top-sleeping)
      F/A/TOP  LCMN  t: 0 20687:calc/u0a158 (intermediate-top-activity)
      T/A/TOP  LCMN  t: 0 20687:calc/u0a158 (top-activity)
      (b=BG, F=FG, T=TOP)

Change-Id: Id0fd2491a11bac7b81bc654e646b3d01643ca8b4
Merged-In: Id0fd2491a11bac7b81bc654e646b3d01643ca8b4
(cherry picked from commit f3139a9e)
parent f3bbee23
Loading
Loading
Loading
Loading
+12 −4
Original line number Diff line number Diff line
@@ -1556,14 +1556,22 @@ public class OomAdjuster {

        boolean foregroundActivities = false;
        boolean hasVisibleActivities = false;
        if (PROCESS_STATE_CUR_TOP == PROCESS_STATE_TOP && app == topApp) {
        if (app == topApp && (PROCESS_STATE_CUR_TOP == PROCESS_STATE_TOP
                || PROCESS_STATE_CUR_TOP == PROCESS_STATE_IMPORTANT_FOREGROUND)) {
            // The last app on the list is the foreground app.
            adj = ProcessList.FOREGROUND_APP_ADJ;
            if (PROCESS_STATE_CUR_TOP == PROCESS_STATE_TOP) {
                schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
                state.setAdjType("top-activity");
            } else {
                // Demote the scheduling group to avoid CPU contention if there is another more
                // important process which also uses top-app, such as if SystemUI is animating.
                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
                state.setAdjType("intermediate-top-activity");
            }
            foregroundActivities = true;
            hasVisibleActivities = true;
            procState = PROCESS_STATE_CUR_TOP;
            procState = PROCESS_STATE_TOP;
            if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
                reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making top: " + app);
            }
+31 −3
Original line number Diff line number Diff line
@@ -64,8 +64,8 @@ import static android.provider.Settings.Global.HIDE_ERROR_DIALOGS;
import static android.provider.Settings.System.FONT_SCALE;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_LAUNCHER_CLEAR_SNAPSHOT;
import static android.view.WindowManager.TRANSIT_WAKE;
import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_TO_LAUNCHER_CLEAR_SNAPSHOT;

import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_FOCUS;
@@ -400,6 +400,13 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
    /** The time at which the previous process was last visible. */
    private long mPreviousProcessVisibleTime;

    /**
     * It can be true from keyguard-going-away to set-keyguard-shown. And getTopProcessState() will
     * return {@link ActivityManager#PROCESS_STATE_IMPORTANT_FOREGROUND} to avoid top app from
     * preempting CPU while keyguard is animating.
     */
    private volatile boolean mDemoteTopAppDuringUnlocking;

    /** List of intents that were used to start the most recent tasks. */
    private RecentTasks mRecentTasks;
    /** State of external calls telling us if the device is awake or asleep. */
@@ -2830,12 +2837,24 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
                        keyguardShowing);
                mH.sendMessage(msg);
            }
            // Always reset the state regardless of keyguard-showing change, because that means the
            // unlock is either completed or canceled.
            if (mDemoteTopAppDuringUnlocking) {
                mDemoteTopAppDuringUnlocking = false;
                // The scheduling group of top process was demoted by unlocking, so recompute
                // to restore its real top priority if possible.
                if (mTopApp != null) {
                    mTopApp.scheduleUpdateOomAdj();
                }
            }
            try {
                Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "setLockScreenShown");
                mRootWindowContainer.forAllDisplays(displayContent -> {
                    mKeyguardController.setKeyguardShown(displayContent.getDisplayId(),
                            keyguardShowing, aodShowing);
                });
            } finally {
                Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
                Binder.restoreCallingIdentity(ident);
            }
        }
@@ -2862,6 +2881,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
        // animation of system UI. Even if AOD is not enabled, it should be no harm.
        final WindowProcessController proc;
        synchronized (mGlobalLockWithoutBoost) {
            mDemoteTopAppDuringUnlocking = false;
            final WindowState notificationShade = mRootWindowContainer.getDefaultDisplay()
                    .getDisplayPolicy().getNotificationShade();
            proc = notificationShade != null
@@ -3399,8 +3419,11 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
        try {
            synchronized (mGlobalLock) {
                // Keyguard asked us to clear the home task snapshot before going away, so do that.
                if ((flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_LAUNCHER_CLEAR_SNAPSHOT) != 0) {
                if ((flags & KEYGUARD_GOING_AWAY_FLAG_TO_LAUNCHER_CLEAR_SNAPSHOT) != 0) {
                    mActivityClientController.invalidateHomeTaskSnapshot(null /* token */);
                } else if (mKeyguardShown) {
                    // Only set if it is not unlocking to launcher which may also animate.
                    mDemoteTopAppDuringUnlocking = true;
                }

                mRootWindowContainer.forAllDisplays(displayContent -> {
@@ -5595,12 +5618,17 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
        @HotPath(caller = HotPath.OOM_ADJUSTMENT)
        @Override
        public int getTopProcessState() {
            final int topState = mTopProcessState;
            if (mDemoteTopAppDuringUnlocking && topState == ActivityManager.PROCESS_STATE_TOP) {
                // The unlocking UI is more important, so defer the top state of app.
                return ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
            }
            if (mRetainPowerModeAndTopProcessState) {
                // There is a launching app while device may be sleeping, force the top state so
                // the launching process can have top-app scheduling group.
                return ActivityManager.PROCESS_STATE_TOP;
            }
            return mTopProcessState;
            return topState;
        }

        @HotPath(caller = HotPath.PROCESS_CHANGE)
+7 −0
Original line number Diff line number Diff line
@@ -1126,6 +1126,13 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
        mAtm.mH.sendMessage(m);
    }

    /** Refreshes oom adjustment and process state of this process. */
    void scheduleUpdateOomAdj() {
        mAtm.mH.sendMessage(PooledLambda.obtainMessage(WindowProcessListener::updateProcessInfo,
                mListener, false /* updateServiceConnectionActivities */,
                false /* activityChange */, true /* updateOomAdj */));
    }

    /** Makes the process have top state before oom-adj is computed from a posted message. */
    void addToPendingTop() {
        mAtm.mAmInternal.addPendingTopUid(mUid, mPid, mThread);