diff options
| author | 2023-04-28 18:53:18 +0000 | |
|---|---|---|
| committer | 2023-04-28 18:53:18 +0000 | |
| commit | 3be325fb6424b1b70d95da7f835fd1ccf603e020 (patch) | |
| tree | 14bf9b64b4dbad2e9e7713657ff2c10c26c68248 | |
| parent | fa17e75b202d1b753b2d2a6adcbac3a195d760e8 (diff) | |
| parent | 1ed33484360df9c772ede2566a56513537c29063 (diff) | |
Merge "Block relayout during transition to desktop" into udc-dev
3 files changed, 73 insertions, 25 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java index e1a56a1a5a7a..6b6a7bc42046 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java @@ -153,6 +153,8 @@ public class FreeformTaskTransitionObserver implements Transitions.TransitionObs @Override public void onTransitionMerged(@NonNull IBinder merged, @NonNull IBinder playing) { + mWindowDecorViewModel.onTransitionMerged(merged, playing); + final List<ActivityManager.RunningTaskInfo> infoOfMerged = mTransitionToTaskInfo.get(merged); if (infoOfMerged == null) { @@ -169,8 +171,6 @@ public class FreeformTaskTransitionObserver implements Transitions.TransitionObs } else { mTransitionToTaskInfo.put(playing, infoOfMerged); } - - mWindowDecorViewModel.onTransitionMerged(merged, playing); } @Override diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java index 4ef3350d06a4..4cda5715ac1f 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java @@ -113,11 +113,6 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { private boolean mDragToDesktopAnimationStarted; private float mCaptionDragStartX; - // These values keep track of any transitions to freeform to stop relayout from running on - // changing task so that shellTransitions has a chance to animate the transition - private int mPauseRelayoutForTask = -1; - private IBinder mTransitionPausingRelayout; - public DesktopModeWindowDecorViewModel( Context context, Handler mainHandler, @@ -195,22 +190,25 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { @NonNull TransitionInfo info, @NonNull TransitionInfo.Change change) { if (change.getMode() == WindowManager.TRANSIT_CHANGE - && info.getType() == Transitions.TRANSIT_ENTER_DESKTOP_MODE) { - mTransitionPausingRelayout = transition; + && (info.getType() == Transitions.TRANSIT_ENTER_DESKTOP_MODE)) { + mWindowDecorByTaskId.get(change.getTaskInfo().taskId) + .addTransitionPausingRelayout(transition); } } @Override public void onTransitionMerged(@NonNull IBinder merged, @NonNull IBinder playing) { - if (merged.equals(mTransitionPausingRelayout)) { - mTransitionPausingRelayout = playing; + for (int i = 0; i < mWindowDecorByTaskId.size(); i++) { + final DesktopModeWindowDecoration decor = mWindowDecorByTaskId.valueAt(i); + decor.mergeTransitionPausingRelayout(merged, playing); } } @Override public void onTransitionFinished(@NonNull IBinder transition) { - if (transition.equals(mTransitionPausingRelayout)) { - mPauseRelayoutForTask = -1; + for (int i = 0; i < mWindowDecorByTaskId.size(); i++) { + final DesktopModeWindowDecoration decor = mWindowDecorByTaskId.valueAt(i); + decor.removeTransitionPausingRelayout(transition); } } @@ -225,12 +223,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { incrementEventReceiverTasks(taskInfo.displayId); } - // TaskListener callbacks and shell transitions aren't synchronized, so starting a shell - // transition can trigger an onTaskInfoChanged call that updates the task's SurfaceControl - // and interferes with the transition animation that is playing at the same time. - if (taskInfo.taskId != mPauseRelayoutForTask) { - decoration.relayout(taskInfo); - } + decoration.relayout(taskInfo); } @Override @@ -555,8 +548,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { relevantDecor.mTaskInfo.displayId); if (ev.getY() > 2 * statusBarHeight) { if (DesktopModeStatus.isProto2Enabled()) { - mPauseRelayoutForTask = relevantDecor.mTaskInfo.taskId; - centerAndMoveToDesktopWithAnimation(relevantDecor, ev); + animateToDesktop(relevantDecor, ev); } else if (DesktopModeStatus.isProto1Enabled()) { mDesktopModeController.ifPresent(c -> c.setDesktopModeActive(true)); } @@ -632,6 +624,15 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { } /** + * Blocks relayout until transition is finished and transitions to Desktop + */ + private void animateToDesktop(DesktopModeWindowDecoration relevantDecor, + MotionEvent ev) { + relevantDecor.incrementRelayoutBlock(); + centerAndMoveToDesktopWithAnimation(relevantDecor, ev); + } + + /** * Animates a window to the center, grows to freeform size, and transitions to Desktop Mode. * @param relevantDecor the window decor of the task to be animated * @param ev the motion event that triggers the animation @@ -658,10 +659,9 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { animator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { - mDesktopTasksController.ifPresent( - c -> c.onDragPositioningEndThroughStatusBar( - relevantDecor.mTaskInfo, - calculateFreeformBounds(FINAL_FREEFORM_SCALE))); + mDesktopTasksController.ifPresent(c -> + c.onDragPositioningEndThroughStatusBar(relevantDecor.mTaskInfo, + calculateFreeformBounds(FINAL_FREEFORM_SCALE))); } }); animator.start(); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java index b1c3791ad15a..95ed42a222b8 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java @@ -30,6 +30,7 @@ import android.graphics.Rect; import android.graphics.Region; import android.graphics.drawable.Drawable; import android.os.Handler; +import android.os.IBinder; import android.util.Log; import android.view.Choreographer; import android.view.MotionEvent; @@ -49,6 +50,9 @@ import com.android.wm.shell.windowdecor.viewholder.DesktopModeAppControlsWindowD import com.android.wm.shell.windowdecor.viewholder.DesktopModeFocusedWindowDecorationViewHolder; import com.android.wm.shell.windowdecor.viewholder.DesktopModeWindowDecorationViewHolder; +import java.util.HashSet; +import java.util.Set; + /** * Defines visuals and behaviors of a window decoration of a caption bar and shadows. It works with * {@link DesktopModeWindowDecorViewModel}. @@ -83,6 +87,9 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin private TaskCornersListener mCornersListener; + private final Set<IBinder> mTransitionsPausingRelayout = new HashSet<>(); + private int mRelayoutBlock; + DesktopModeWindowDecoration( Context context, DisplayController displayController, @@ -134,6 +141,13 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin @Override void relayout(ActivityManager.RunningTaskInfo taskInfo) { + // TaskListener callbacks and shell transitions aren't synchronized, so starting a shell + // transition can trigger an onTaskInfoChanged call that updates the task's SurfaceControl + // and interferes with the transition animation that is playing at the same time. + if (mRelayoutBlock > 0) { + return; + } + final SurfaceControl.Transaction t = new SurfaceControl.Transaction(); // Use |applyStartTransactionOnDraw| so that the transaction (that applies task crop) is // synced with the buffer transaction (that draws the View). Both will be shown on screen @@ -455,6 +469,40 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin return cornersRegion; } + /** + * If transition exists in mTransitionsPausingRelayout, remove the transition and decrement + * mRelayoutBlock + */ + void removeTransitionPausingRelayout(IBinder transition) { + if (mTransitionsPausingRelayout.remove(transition)) { + mRelayoutBlock--; + } + } + + /** + * Add transition to mTransitionsPausingRelayout + */ + void addTransitionPausingRelayout(IBinder transition) { + mTransitionsPausingRelayout.add(transition); + } + + /** + * If two transitions merge and the merged transition is in mTransitionsPausingRelayout, + * remove the merged transition from the set and add the transition it was merged into. + */ + public void mergeTransitionPausingRelayout(IBinder merged, IBinder playing) { + if (mTransitionsPausingRelayout.remove(merged)) { + mTransitionsPausingRelayout.add(playing); + } + } + + /** + * Increase mRelayoutBlock, stopping relayout if mRelayoutBlock is now greater than 0. + */ + public void incrementRelayoutBlock() { + mRelayoutBlock++; + } + static class Factory { DesktopModeWindowDecoration create( |