diff options
| author | 2024-10-18 11:46:59 +0000 | |
|---|---|---|
| committer | 2024-10-18 11:46:59 +0000 | |
| commit | db71101981f355590064764ffece5b286d765f52 (patch) | |
| tree | 3b3231d90daa9d6b19d293d6c8317152ed97a550 | |
| parent | 21e3262466e3ae120d6be05103182e382926730e (diff) | |
| parent | 201e538f9641db8419eaf8b009cdfddf184b569e (diff) | |
Merge "Finish unfold transition after timeout" into main
3 files changed, 54 insertions, 1 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java index 97397cea4a38..03a851bb9507 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java @@ -597,9 +597,10 @@ public abstract class WMShellModule { TransactionPool transactionPool, Transitions transitions, @ShellMainThread ShellExecutor executor, + @ShellMainThread Handler handler, ShellInit shellInit) { return new UnfoldTransitionHandler(shellInit, progressProvider.get(), animator, - unfoldAnimator, transactionPool, executor, transitions); + unfoldAnimator, transactionPool, executor, handler, transitions); } @WMSingleton diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java index 5a2abe1e7e25..3e0e15afc53a 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java @@ -24,7 +24,9 @@ import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_TRANSITI import android.animation.ValueAnimator; import android.app.ActivityManager; +import android.os.Handler; import android.os.IBinder; +import android.util.Slog; import android.view.SurfaceControl; import android.window.TransitionInfo; import android.window.TransitionRequestInfo; @@ -33,6 +35,7 @@ import android.window.WindowContainerTransaction; import androidx.annotation.IntDef; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.annotation.VisibleForTesting; import com.android.internal.protolog.ProtoLog; import com.android.wm.shell.shared.TransactionPool; @@ -59,6 +62,10 @@ import java.util.concurrent.Executor; */ public class UnfoldTransitionHandler implements TransitionHandler, UnfoldListener { + private static final String TAG = "UnfoldTransitionHandler"; + @VisibleForTesting + static final int FINISH_ANIMATION_TIMEOUT_MILLIS = 5_000; + @Retention(RetentionPolicy.SOURCE) @IntDef({ DefaultDisplayChange.DEFAULT_DISPLAY_NO_CHANGE, @@ -75,6 +82,7 @@ public class UnfoldTransitionHandler implements TransitionHandler, UnfoldListene private final Transitions mTransitions; private final Executor mExecutor; private final TransactionPool mTransactionPool; + private final Handler mHandler; @Nullable private TransitionFinishCallback mFinishCallback; @@ -87,17 +95,25 @@ public class UnfoldTransitionHandler implements TransitionHandler, UnfoldListene private float mLastAnimationProgress = 0.0f; private final List<UnfoldTaskAnimator> mAnimators = new ArrayList<>(); + private final Runnable mAnimationPlayingTimeoutRunnable = () -> { + Slog.wtf(TAG, "Timeout occurred when playing the unfold animation, " + + "force finishing the transition"); + finishTransitionIfNeeded(); + }; + public UnfoldTransitionHandler(ShellInit shellInit, ShellUnfoldProgressProvider unfoldProgressProvider, FullscreenUnfoldTaskAnimator fullscreenUnfoldAnimator, SplitTaskUnfoldAnimator splitUnfoldTaskAnimator, TransactionPool transactionPool, Executor executor, + Handler handler, Transitions transitions) { mUnfoldProgressProvider = unfoldProgressProvider; mTransitions = transitions; mTransactionPool = transactionPool; mExecutor = executor; + mHandler = handler; mAnimators.add(splitUnfoldTaskAnimator); mAnimators.add(fullscreenUnfoldAnimator); @@ -159,6 +175,11 @@ public class UnfoldTransitionHandler implements TransitionHandler, UnfoldListene // finish shell transition immediately if (mAnimationFinished) { finishTransitionIfNeeded(); + } else { + // TODO: b/318803244 - remove timeout handling when we could guarantee that + // the animation will be always finished after receiving startAnimation + mHandler.removeCallbacks(mAnimationPlayingTimeoutRunnable); + mHandler.postDelayed(mAnimationPlayingTimeoutRunnable, FINISH_ANIMATION_TIMEOUT_MILLIS); } return true; @@ -333,6 +354,7 @@ public class UnfoldTransitionHandler implements TransitionHandler, UnfoldListene animator.stop(); } + mHandler.removeCallbacks(mAnimationPlayingTimeoutRunnable); mFinishCallback.onTransitionFinished(null); mFinishCallback = null; mTransition = null; diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/unfold/UnfoldTransitionHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/unfold/UnfoldTransitionHandlerTest.java index 22da66dd5e67..c36b88e34835 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/unfold/UnfoldTransitionHandlerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/unfold/UnfoldTransitionHandlerTest.java @@ -20,6 +20,8 @@ import static android.view.WindowManager.TRANSIT_CHANGE; import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY; import static android.view.WindowManager.TRANSIT_NONE; +import static com.android.wm.shell.unfold.UnfoldTransitionHandler.FINISH_ANIMATION_TIMEOUT_MILLIS; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; @@ -32,7 +34,9 @@ import static org.mockito.Mockito.verify; import android.app.ActivityManager; import android.graphics.Rect; import android.os.Binder; +import android.os.Handler; import android.os.IBinder; +import android.os.test.TestLooper; import android.view.Display; import android.view.SurfaceControl; import android.window.TransitionInfo; @@ -67,6 +71,8 @@ public class UnfoldTransitionHandlerTest { private FullscreenUnfoldTaskAnimator mFullscreenUnfoldTaskAnimator; private SplitTaskUnfoldAnimator mSplitTaskUnfoldAnimator; private Transitions mTransitions; + private TestLooper mTestLooper; + private Handler mHandler; private final IBinder mTransition = new Binder(); @@ -75,6 +81,9 @@ public class UnfoldTransitionHandlerTest { final ShellExecutor executor = new TestSyncExecutor(); final ShellInit shellInit = new ShellInit(executor); + mTestLooper = new TestLooper(); + mHandler = new Handler(mTestLooper.getLooper()); + mFullscreenUnfoldTaskAnimator = mock(FullscreenUnfoldTaskAnimator.class); mSplitTaskUnfoldAnimator = mock(SplitTaskUnfoldAnimator.class); mTransitions = mock(Transitions.class); @@ -86,6 +95,7 @@ public class UnfoldTransitionHandlerTest { mSplitTaskUnfoldAnimator, mTransactionPool, executor, + mHandler, mTransitions ); @@ -159,6 +169,7 @@ public class UnfoldTransitionHandlerTest { TransitionFinishCallback mergeFinishCallback = mock(TransitionFinishCallback.class); mUnfoldTransitionHandler.mergeAnimation(new Binder(), createFoldTransitionInfo(), mock(SurfaceControl.Transaction.class), mTransition, mergeFinishCallback); + mTestLooper.dispatchAll(); // Verify that fold transition is merged into unfold and that unfold is finished final InOrder inOrder = inOrder(mergeFinishCallback, finishCallback); @@ -201,6 +212,25 @@ public class UnfoldTransitionHandlerTest { } @Test + public void startAnimation_animationHasNotFinishedAfterTimeout_finishesTheTransition() { + TransitionRequestInfo requestInfo = createUnfoldTransitionRequestInfo(); + mUnfoldTransitionHandler.handleRequest(mTransition, requestInfo); + TransitionFinishCallback finishCallback = mock(TransitionFinishCallback.class); + mUnfoldTransitionHandler.startAnimation( + mTransition, + mock(TransitionInfo.class), + mock(SurfaceControl.Transaction.class), + mock(SurfaceControl.Transaction.class), + finishCallback + ); + + mTestLooper.moveTimeForward(FINISH_ANIMATION_TIMEOUT_MILLIS + 1); + mTestLooper.dispatchAll(); + + verify(finishCallback).onTransitionFinished(any()); + } + + @Test public void startAnimation_differentTransitionFromRequestWithResize_doesNotStartAnimation() { mUnfoldTransitionHandler.handleRequest(new Binder(), createNoneTransitionInfo()); TransitionFinishCallback finishCallback = mock(TransitionFinishCallback.class); |