diff options
| author | 2024-02-29 05:39:37 +0000 | |
|---|---|---|
| committer | 2024-03-01 03:26:03 +0000 | |
| commit | 615e4aaa7743b1fae64729bc4ddfee62499b3940 (patch) | |
| tree | b5f09261398c76b242bce7cc03c6d02b498c6f16 | |
| parent | a9a83eed92731255899741e5b8dd011704cc479c (diff) | |
Cancel running split decor animations before finishing the current resize transition
- One possible flow for this:
1) play a pending split resize animation with a transition that
includes a snapshot -> this creates a SplitDecorManager animation
which directly animates the snapshot leash
2) have another resize which triggers setup of a new pending resize
animation -> this cancels the current animation which cleans up/
releases the existing transition's surfaces, but nothing notifies
SplitDecorManager, so that animation continues to play
3) Next frame comes in, SplitDecorManager's animation tries to update
the surface that has already been released -> crash
- This change just cancels any existing animations (which will remove
the decor) before creating a new pending resize animation and
finishing the previous transition
Fixes: 325306101
Test: Presubmit (not reproducible)
Change-Id: Id77f02871bfd684e8dd814b3a38a94e06049e210
3 files changed, 22 insertions, 17 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java index 194eb47c9360..dae62ac74483 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java @@ -138,8 +138,10 @@ public class SplitDecorManager extends WindowlessWindowManager { mViewHost.setView(rootLayout, lp); } - /** Releases the surfaces for split decor. */ - public void release(SurfaceControl.Transaction t) { + /** + * Cancels any currently running animations. + */ + public void cancelRunningAnimations() { if (mFadeAnimator != null) { if (mFadeAnimator.isRunning()) { mFadeAnimator.cancel(); @@ -152,6 +154,11 @@ public class SplitDecorManager extends WindowlessWindowManager { } mScreenshotAnimator = null; } + } + + /** Releases the surfaces for split decor. */ + public void release(SurfaceControl.Transaction t) { + cancelRunningAnimations(); if (mViewHost != null) { mViewHost.release(); mViewHost = null; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java index 1d9fdeb92715..1a53a1d10dd2 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java @@ -403,25 +403,23 @@ class SplitScreenTransitions { IBinder startResizeTransition(WindowContainerTransaction wct, Transitions.TransitionHandler handler, @Nullable TransitionConsumedCallback consumedCallback, - @Nullable TransitionFinishedCallback finishCallback) { + @Nullable TransitionFinishedCallback finishCallback, + @NonNull SplitDecorManager mainDecor, @NonNull SplitDecorManager sideDecor) { + ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, + " splitTransition deduced Resize split screen."); + ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "setResizeTransition: hasPendingResize=%b", + mPendingResize != null); if (mPendingResize != null) { + mainDecor.cancelRunningAnimations(); + sideDecor.cancelRunningAnimations(); mPendingResize.cancel(null); mAnimations.clear(); onFinish(null /* wct */); } IBinder transition = mTransitions.startTransition(TRANSIT_CHANGE, wct, handler); - setResizeTransition(transition, consumedCallback, finishCallback); - return transition; - } - - void setResizeTransition(@NonNull IBinder transition, - @Nullable TransitionConsumedCallback consumedCallback, - @Nullable TransitionFinishedCallback finishCallback) { mPendingResize = new TransitSession(transition, consumedCallback, finishCallback); - ProtoLog.v(WM_SHELL_TRANSITIONS, " splitTransition " - + " deduced Resize split screen"); - ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "setResizeTransition"); + return transition; } void mergeAnimation(IBinder transition, TransitionInfo info, SurfaceControl.Transaction t, diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java index 7a1595fdbf01..8f964d053289 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java @@ -2308,10 +2308,10 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, if (ENABLE_SHELL_TRANSITIONS) { mSplitLayout.setDividerInteractive(false, false, "onSplitResizeStart"); mSplitTransitions.startResizeTransition(wct, this, (aborted) -> { - mSplitLayout.setDividerInteractive(true, false, "onSplitResizeConsumed"); - }, (finishWct, t) -> { - mSplitLayout.setDividerInteractive(true, false, "onSplitResizeFinish"); - }); + mSplitLayout.setDividerInteractive(true, false, "onSplitResizeConsumed"); + }, (finishWct, t) -> { + mSplitLayout.setDividerInteractive(true, false, "onSplitResizeFinish"); + }, mMainStage.getSplitDecorManager(), mSideStage.getSplitDecorManager()); } else { // Only need screenshot for legacy case because shell transition should screenshot // itself during transition. |