From b576702e30f7e5eb25467119fba6c5bd0ebd0837 Mon Sep 17 00:00:00 2001 From: Hongwei Wang Date: Wed, 14 Dec 2022 12:35:18 -0800 Subject: [PATCH] Do not reset surface when entering PiP When UnfoldAnimationController is present and entering PiP from a Task with multiple activities, the resetTask within UnfoldAnimationController could conflict with the PiP animation and cause flicker. Fixed this by ignoring restTask in UnfoldAnimationController if there is no state change going on. Bug: 261996076 Test: Enter PiP from Task with multi-Activity on foldables Change-Id: I7f13e86d030d427383e65a37efde13ec94dea2a8 --- .../unfold/UnfoldAnimationController.java | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldAnimationController.java index 6b59e313b01ba..d7cb490ed0cb8 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldAnimationController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldAnimationController.java @@ -16,8 +16,6 @@ package com.android.wm.shell.unfold; -import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; - import android.annotation.NonNull; import android.app.ActivityManager.RunningTaskInfo; import android.app.TaskInfo; @@ -56,6 +54,12 @@ public class UnfoldAnimationController implements UnfoldListener { private final SparseArray mTaskSurfaces = new SparseArray<>(); private final SparseArray mAnimatorsByTaskId = new SparseArray<>(); + /** + * Indicates whether we're in stage change process. This should be set to {@code true} in + * {@link #onStateChangeStarted()} and {@code false} in {@link #onStateChangeFinished()}. + */ + private boolean mIsInStageChange; + public UnfoldAnimationController( @NonNull ShellInit shellInit, @NonNull TransactionPool transactionPool, @@ -123,7 +127,7 @@ public class UnfoldAnimationController implements UnfoldListener { animator.onTaskChanged(taskInfo); } else { // Became inapplicable - resetTask(animator, taskInfo); + maybeResetTask(animator, taskInfo); animator.onTaskVanished(taskInfo); mAnimatorsByTaskId.remove(taskInfo.taskId); } @@ -154,7 +158,7 @@ public class UnfoldAnimationController implements UnfoldListener { final boolean isCurrentlyApplicable = animator != null; if (isCurrentlyApplicable) { - resetTask(animator, taskInfo); + maybeResetTask(animator, taskInfo); animator.onTaskVanished(taskInfo); mAnimatorsByTaskId.remove(taskInfo.taskId); } @@ -166,6 +170,7 @@ public class UnfoldAnimationController implements UnfoldListener { return; } + mIsInStageChange = true; SurfaceControl.Transaction transaction = null; for (int i = 0; i < mAnimators.size(); i++) { final UnfoldTaskAnimator animator = mAnimators.get(i); @@ -219,11 +224,12 @@ public class UnfoldAnimationController implements UnfoldListener { transaction.apply(); mTransactionPool.release(transaction); + mIsInStageChange = false; } - private void resetTask(UnfoldTaskAnimator animator, TaskInfo taskInfo) { - if (taskInfo.getWindowingMode() == WINDOWING_MODE_PINNED) { - // PiP task has its own cleanup path, ignore surface reset to avoid conflict. + private void maybeResetTask(UnfoldTaskAnimator animator, TaskInfo taskInfo) { + if (!mIsInStageChange) { + // No need to resetTask if there is no ongoing state change. return; } final SurfaceControl.Transaction transaction = mTransactionPool.acquire();