Loading libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java +2 −2 Original line number Diff line number Diff line Loading @@ -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) { Loading @@ -169,8 +171,6 @@ public class FreeformTaskTransitionObserver implements Transitions.TransitionObs } else { mTransitionToTaskInfo.put(playing, infoOfMerged); } mWindowDecorViewModel.onTransitionMerged(merged, playing); } @Override Loading libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java +23 −23 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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); } } Loading @@ -225,13 +223,8 @@ 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); } } @Override public void onTaskChanging( Loading Loading @@ -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)); } Loading Loading @@ -631,6 +623,15 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { return endBounds; } /** * 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 Loading Loading @@ -658,9 +659,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { animator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mDesktopTasksController.ifPresent( c -> c.onDragPositioningEndThroughStatusBar( relevantDecor.mTaskInfo, mDesktopTasksController.ifPresent(c -> c.onDragPositioningEndThroughStatusBar(relevantDecor.mTaskInfo, calculateFreeformBounds(FINAL_FREEFORM_SCALE))); } }); Loading libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java +48 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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}. Loading Loading @@ -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, Loading Loading @@ -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 Loading Loading @@ -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( Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java +2 −2 Original line number Diff line number Diff line Loading @@ -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) { Loading @@ -169,8 +171,6 @@ public class FreeformTaskTransitionObserver implements Transitions.TransitionObs } else { mTransitionToTaskInfo.put(playing, infoOfMerged); } mWindowDecorViewModel.onTransitionMerged(merged, playing); } @Override Loading
libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java +23 −23 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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); } } Loading @@ -225,13 +223,8 @@ 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); } } @Override public void onTaskChanging( Loading Loading @@ -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)); } Loading Loading @@ -631,6 +623,15 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { return endBounds; } /** * 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 Loading Loading @@ -658,9 +659,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { animator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mDesktopTasksController.ifPresent( c -> c.onDragPositioningEndThroughStatusBar( relevantDecor.mTaskInfo, mDesktopTasksController.ifPresent(c -> c.onDragPositioningEndThroughStatusBar(relevantDecor.mTaskInfo, calculateFreeformBounds(FINAL_FREEFORM_SCALE))); } }); Loading
libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java +48 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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}. Loading Loading @@ -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, Loading Loading @@ -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 Loading Loading @@ -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( Loading