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

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

Update process animating state with different reasons

Since shell transition is enabled, it is more often to invoke
setRunningRemoteAnimation for SystemUI. So there may a race
race that SystemUI has been boosted for entering AOD, but the
state is canceled by a finished transition.

So now with individual animating reasons, the transition will
only remove its corresponding reason. If other reasons still exist,
the process can keep the animating state for a higher priority.

Bug: 295116622
Test: atest WindowProcessControllerTests#testSetAnimatingReason
Change-Id: Id326518a0e2b2b9375015e55b5ce3983a9e801e7
(cherry picked from commit a2b2d739)
parent bf9f55f0
Loading
Loading
Loading
Loading
+18 −5
Original line number Diff line number Diff line
@@ -3024,9 +3024,11 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
        // Set to activity manager directly to make sure the state can be seen by the subsequent
        // update of scheduling group.
        proc.setRunningAnimationUnsafe();
        mH.removeMessages(H.UPDATE_PROCESS_ANIMATING_STATE, proc);
        mH.sendMessageDelayed(mH.obtainMessage(H.UPDATE_PROCESS_ANIMATING_STATE, proc),
        mH.sendMessage(mH.obtainMessage(H.ADD_WAKEFULNESS_ANIMATING_REASON, proc));
        mH.removeMessages(H.REMOVE_WAKEFULNESS_ANIMATING_REASON, proc);
        mH.sendMessageDelayed(mH.obtainMessage(H.REMOVE_WAKEFULNESS_ANIMATING_REASON, proc),
                DOZE_ANIMATING_STATE_RETAIN_TIME_MS);
        Trace.instant(TRACE_TAG_WINDOW_MANAGER, "requestWakefulnessAnimating");
    }

    @Override
@@ -5651,9 +5653,10 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {

    final class H extends Handler {
        static final int REPORT_TIME_TRACKER_MSG = 1;
        static final int UPDATE_PROCESS_ANIMATING_STATE = 2;
        static final int END_POWER_MODE_UNKNOWN_VISIBILITY_MSG = 3;
        static final int RESUME_FG_APP_SWITCH_MSG = 4;
        static final int ADD_WAKEFULNESS_ANIMATING_REASON = 5;
        static final int REMOVE_WAKEFULNESS_ANIMATING_REASON = 6;

        static final int FIRST_ACTIVITY_TASK_MSG = 100;
        static final int FIRST_SUPERVISOR_TASK_MSG = 200;
@@ -5670,13 +5673,23 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
                    tracker.deliverResult(mContext);
                }
                break;
                case UPDATE_PROCESS_ANIMATING_STATE: {
                case ADD_WAKEFULNESS_ANIMATING_REASON: {
                    final WindowProcessController proc = (WindowProcessController) msg.obj;
                    synchronized (mGlobalLock) {
                        proc.updateRunningRemoteOrRecentsAnimation();
                        proc.addAnimatingReason(
                                WindowProcessController.ANIMATING_REASON_WAKEFULNESS_CHANGE);
                    }
                }
                break;
                case REMOVE_WAKEFULNESS_ANIMATING_REASON: {
                    final WindowProcessController proc = (WindowProcessController) msg.obj;
                    synchronized (mGlobalLock) {
                        proc.removeAnimatingReason(
                                WindowProcessController.ANIMATING_REASON_WAKEFULNESS_CHANGE);
                    }
                    Trace.instant(TRACE_TAG_WINDOW_MANAGER, "finishWakefulnessAnimating");
                }
                break;
                case END_POWER_MODE_UNKNOWN_VISIBILITY_MSG: {
                    synchronized (mGlobalLock) {
                        mRetainPowerModeAndTopProcessState = false;
+69 −18
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ import static com.android.server.wm.WindowManagerService.MY_PID;
import static java.util.Objects.requireNonNull;

import android.Manifest;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
@@ -75,7 +76,6 @@ import android.util.ArrayMap;
import android.util.Log;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
import android.view.IRemoteAnimationRunner;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
@@ -87,6 +87,8 @@ import com.android.server.wm.ActivityTaskManagerService.HotPath;

import java.io.IOException;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;

@@ -249,11 +251,30 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
    @Nullable
    private ArrayMap<ActivityRecord, int[]> mRemoteActivities;

    /** Whether our process is currently running a {@link RecentsAnimation} */
    private boolean mRunningRecentsAnimation;
    /**
     * It can be set for a running transition player ({@link android.window.ITransitionPlayer}) or
     * remote animators (running {@link android.window.IRemoteTransition}).
     */
    static final int ANIMATING_REASON_REMOTE_ANIMATION = 1;
    /** It is set for wakefulness transition. */
    static final int ANIMATING_REASON_WAKEFULNESS_CHANGE = 1 << 1;
    /** Whether the legacy {@link RecentsAnimation} is running. */
    static final int ANIMATING_REASON_LEGACY_RECENT_ANIMATION = 1 << 2;

    @Retention(RetentionPolicy.SOURCE)
    @IntDef({
            ANIMATING_REASON_REMOTE_ANIMATION,
            ANIMATING_REASON_WAKEFULNESS_CHANGE,
            ANIMATING_REASON_LEGACY_RECENT_ANIMATION,
    })
    @interface AnimatingReason {}

    /** Whether our process is currently running a {@link IRemoteAnimationRunner} */
    private boolean mRunningRemoteAnimation;
    /**
     * Non-zero if this process is currently running an important animation. This should be never
     * set for system server.
     */
    @AnimatingReason
    private int mAnimatingReasons;

    // The bits used for mActivityStateFlags.
    private static final int ACTIVITY_STATE_FLAG_IS_VISIBLE = 1 << 16;
@@ -1847,30 +1868,45 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
    }

    void setRunningRecentsAnimation(boolean running) {
        if (mRunningRecentsAnimation == running) {
            return;
        if (running) {
            addAnimatingReason(ANIMATING_REASON_LEGACY_RECENT_ANIMATION);
        } else {
            removeAnimatingReason(ANIMATING_REASON_LEGACY_RECENT_ANIMATION);
        }
        mRunningRecentsAnimation = running;
        updateRunningRemoteOrRecentsAnimation();
    }

    void setRunningRemoteAnimation(boolean running) {
        if (mRunningRemoteAnimation == running) {
            return;
        if (running) {
            addAnimatingReason(ANIMATING_REASON_REMOTE_ANIMATION);
        } else {
            removeAnimatingReason(ANIMATING_REASON_REMOTE_ANIMATION);
        }
    }

    void addAnimatingReason(@AnimatingReason int reason) {
        final int prevReasons = mAnimatingReasons;
        mAnimatingReasons |= reason;
        if (prevReasons == 0) {
            setAnimating(true);
        }
        mRunningRemoteAnimation = running;
        updateRunningRemoteOrRecentsAnimation();
    }

    void updateRunningRemoteOrRecentsAnimation() {
    void removeAnimatingReason(@AnimatingReason int reason) {
        final int prevReasons = mAnimatingReasons;
        mAnimatingReasons &= ~reason;
        if (prevReasons != 0 && mAnimatingReasons == 0) {
            setAnimating(false);
        }
    }

    /** Applies the animating state to activity manager for updating process priority. */
    private void setAnimating(boolean animating) {
        // Posting on handler so WM lock isn't held when we call into AM.
        mAtm.mH.sendMessage(PooledLambda.obtainMessage(
                WindowProcessListener::setRunningRemoteAnimation, mListener,
                isRunningRemoteTransition()));
        mAtm.mH.post(() -> mListener.setRunningRemoteAnimation(animating));
    }

    boolean isRunningRemoteTransition() {
        return mRunningRecentsAnimation || mRunningRemoteAnimation;
        return (mAnimatingReasons & ANIMATING_REASON_REMOTE_ANIMATION) != 0;
    }

    /** Adjusts scheduling group for animation. This method MUST NOT be called inside WM lock. */
@@ -1924,6 +1960,21 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
        pw.println(prefix + " mLastReportedConfiguration=" + (mHasCachedConfiguration
                ? ("(cached) " + mLastReportedConfiguration) : mLastReportedConfiguration));

        final int animatingReasons = mAnimatingReasons;
        if (animatingReasons != 0) {
            pw.print(prefix + " mAnimatingReasons=");
            if ((animatingReasons & ANIMATING_REASON_REMOTE_ANIMATION) != 0) {
                pw.print("remote-animation|");
            }
            if ((animatingReasons & ANIMATING_REASON_WAKEFULNESS_CHANGE) != 0) {
                pw.print("wakefulness|");
            }
            if ((animatingReasons & ANIMATING_REASON_LEGACY_RECENT_ANIMATION) != 0) {
                pw.print("legacy-recents");
            }
            pw.println();
        }

        final int stateFlags = mActivityStateFlags;
        if (stateFlags != ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER) {
            pw.print(prefix + " mActivityStateFlags=");
+8 −4
Original line number Diff line number Diff line
@@ -170,9 +170,13 @@ public class WindowProcessControllerTests extends WindowTestsBase {
    }

    @Test
    public void testSetRunningRecentsAnimation() {
        mWpc.setRunningRecentsAnimation(true);
        mWpc.setRunningRecentsAnimation(false);
    public void testSetAnimatingReason() {
        mWpc.addAnimatingReason(WindowProcessController.ANIMATING_REASON_REMOTE_ANIMATION);
        assertTrue(mWpc.isRunningRemoteTransition());
        mWpc.addAnimatingReason(WindowProcessController.ANIMATING_REASON_WAKEFULNESS_CHANGE);
        mWpc.removeAnimatingReason(WindowProcessController.ANIMATING_REASON_REMOTE_ANIMATION);
        assertFalse(mWpc.isRunningRemoteTransition());
        mWpc.removeAnimatingReason(WindowProcessController.ANIMATING_REASON_WAKEFULNESS_CHANGE);
        waitHandlerIdle(mAtm.mH);

        InOrder orderVerifier = Mockito.inOrder(mMockListener);
@@ -201,7 +205,7 @@ public class WindowProcessControllerTests extends WindowTestsBase {
        waitHandlerIdle(mAtm.mH);

        InOrder orderVerifier = Mockito.inOrder(mMockListener);
        orderVerifier.verify(mMockListener, times(3)).setRunningRemoteAnimation(eq(true));
        orderVerifier.verify(mMockListener, times(1)).setRunningRemoteAnimation(eq(true));
        orderVerifier.verify(mMockListener, times(1)).setRunningRemoteAnimation(eq(false));
        orderVerifier.verifyNoMoreInteractions();
    }