diff options
3 files changed, 95 insertions, 27 deletions
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index 8673b90c966d..6c848d18a007 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -3029,9 +3029,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 @@ -5657,9 +5659,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; @@ -5676,13 +5679,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; diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java index 83e864673fa8..e769a2763fc5 100644 --- a/services/core/java/com/android/server/wm/WindowProcessController.java +++ b/services/core/java/com/android/server/wm/WindowProcessController.java @@ -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; @@ -76,7 +77,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; @@ -88,6 +88,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; @@ -250,11 +252,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; @@ -1869,30 +1890,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. */ @@ -1946,6 +1982,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="); diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java index cf839812f6aa..ebe40b05162d 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java @@ -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(); } |