Merge "Sync resize veil hide to app draw." into udc-dev am: 2202444446

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/23089457

Change-Id: I9ed1a53c2360d48f49072a5a7f4208408ef0441e
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Matt Sziklay
2023-05-13 00:46:58 +00:00
committed by Automerger Merge Worker
6 changed files with 87 additions and 27 deletions

View File

@@ -201,6 +201,7 @@ public abstract class WMShellModule {
ShellTaskOrganizer taskOrganizer, ShellTaskOrganizer taskOrganizer,
DisplayController displayController, DisplayController displayController,
SyncTransactionQueue syncQueue, SyncTransactionQueue syncQueue,
Transitions transitions,
Optional<DesktopModeController> desktopModeController, Optional<DesktopModeController> desktopModeController,
Optional<DesktopTasksController> desktopTasksController, Optional<DesktopTasksController> desktopTasksController,
Optional<SplitScreenController> splitScreenController) { Optional<SplitScreenController> splitScreenController) {
@@ -212,6 +213,7 @@ public abstract class WMShellModule {
taskOrganizer, taskOrganizer,
displayController, displayController,
syncQueue, syncQueue,
transitions,
desktopModeController, desktopModeController,
desktopTasksController, desktopTasksController,
splitScreenController); splitScreenController);

View File

@@ -104,6 +104,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
private final InputMonitorFactory mInputMonitorFactory; private final InputMonitorFactory mInputMonitorFactory;
private TaskOperations mTaskOperations; private TaskOperations mTaskOperations;
private final Supplier<SurfaceControl.Transaction> mTransactionFactory; private final Supplier<SurfaceControl.Transaction> mTransactionFactory;
private final Transitions mTransitions;
private Optional<SplitScreenController> mSplitScreenController; private Optional<SplitScreenController> mSplitScreenController;
@@ -118,6 +119,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
ShellTaskOrganizer taskOrganizer, ShellTaskOrganizer taskOrganizer,
DisplayController displayController, DisplayController displayController,
SyncTransactionQueue syncQueue, SyncTransactionQueue syncQueue,
Transitions transitions,
Optional<DesktopModeController> desktopModeController, Optional<DesktopModeController> desktopModeController,
Optional<DesktopTasksController> desktopTasksController, Optional<DesktopTasksController> desktopTasksController,
Optional<SplitScreenController> splitScreenController) { Optional<SplitScreenController> splitScreenController) {
@@ -128,6 +130,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
taskOrganizer, taskOrganizer,
displayController, displayController,
syncQueue, syncQueue,
transitions,
desktopModeController, desktopModeController,
desktopTasksController, desktopTasksController,
splitScreenController, splitScreenController,
@@ -144,6 +147,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
ShellTaskOrganizer taskOrganizer, ShellTaskOrganizer taskOrganizer,
DisplayController displayController, DisplayController displayController,
SyncTransactionQueue syncQueue, SyncTransactionQueue syncQueue,
Transitions transitions,
Optional<DesktopModeController> desktopModeController, Optional<DesktopModeController> desktopModeController,
Optional<DesktopTasksController> desktopTasksController, Optional<DesktopTasksController> desktopTasksController,
Optional<SplitScreenController> splitScreenController, Optional<SplitScreenController> splitScreenController,
@@ -158,6 +162,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
mDisplayController = displayController; mDisplayController = displayController;
mSplitScreenController = splitScreenController; mSplitScreenController = splitScreenController;
mSyncQueue = syncQueue; mSyncQueue = syncQueue;
mTransitions = transitions;
mDesktopModeController = desktopModeController; mDesktopModeController = desktopModeController;
mDesktopTasksController = desktopTasksController; mDesktopTasksController = desktopTasksController;
@@ -818,7 +823,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
} else { } else {
windowDecoration.createResizeVeil(); windowDecoration.createResizeVeil();
return new VeiledResizeTaskPositioner(mTaskOrganizer, windowDecoration, return new VeiledResizeTaskPositioner(mTaskOrganizer, windowDecoration,
mDisplayController, disallowedAreaForEndBounds, mDragStartListener); mDisplayController, disallowedAreaForEndBounds, mDragStartListener,
mTransitions);
} }
} }

View File

@@ -44,7 +44,7 @@ import java.util.function.Supplier;
* Creates and updates a veil that covers task contents on resize. * Creates and updates a veil that covers task contents on resize.
*/ */
public class ResizeVeil { public class ResizeVeil {
private static final int RESIZE_ALPHA_DURATION = 200; private static final int RESIZE_ALPHA_DURATION = 100;
private final Context mContext; private final Context mContext;
private final Supplier<SurfaceControl.Builder> mSurfaceControlBuilderSupplier; private final Supplier<SurfaceControl.Builder> mSurfaceControlBuilderSupplier;
private final Supplier<SurfaceControl.Transaction> mSurfaceControlTransactionSupplier; private final Supplier<SurfaceControl.Transaction> mSurfaceControlTransactionSupplier;
@@ -155,7 +155,6 @@ public class ResizeVeil {
* Animate veil's alpha to 0, fading it out. * Animate veil's alpha to 0, fading it out.
*/ */
public void hideVeil() { public void hideVeil() {
final View resizeVeilView = mViewHost.getView();
final ValueAnimator animator = new ValueAnimator(); final ValueAnimator animator = new ValueAnimator();
animator.setFloatValues(1, 0); animator.setFloatValues(1, 0);
animator.setDuration(RESIZE_ALPHA_DURATION); animator.setDuration(RESIZE_ALPHA_DURATION);

View File

@@ -16,13 +16,22 @@
package com.android.wm.shell.windowdecor; package com.android.wm.shell.windowdecor;
import static android.view.WindowManager.TRANSIT_CHANGE;
import android.graphics.PointF; import android.graphics.PointF;
import android.graphics.Rect; import android.graphics.Rect;
import android.os.IBinder;
import android.view.SurfaceControl; import android.view.SurfaceControl;
import android.window.TransitionInfo;
import android.window.TransitionRequestInfo;
import android.window.WindowContainerTransaction; import android.window.WindowContainerTransaction;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.transition.Transitions;
import java.util.function.Supplier; import java.util.function.Supplier;
@@ -32,12 +41,14 @@ import java.util.function.Supplier;
* If the drag is resizing the task, we resize the veil instead. * If the drag is resizing the task, we resize the veil instead.
* If the drag is repositioning, we update in the typical manner. * If the drag is repositioning, we update in the typical manner.
*/ */
public class VeiledResizeTaskPositioner implements DragPositioningCallback { public class VeiledResizeTaskPositioner implements DragPositioningCallback,
Transitions.TransitionHandler {
private DesktopModeWindowDecoration mDesktopWindowDecoration; private DesktopModeWindowDecoration mDesktopWindowDecoration;
private ShellTaskOrganizer mTaskOrganizer; private ShellTaskOrganizer mTaskOrganizer;
private DisplayController mDisplayController; private DisplayController mDisplayController;
private DragPositioningCallbackUtility.DragStartListener mDragStartListener; private DragPositioningCallbackUtility.DragStartListener mDragStartListener;
private final Transitions mTransitions;
private final Rect mStableBounds = new Rect(); private final Rect mStableBounds = new Rect();
private final Rect mTaskBoundsAtDragStart = new Rect(); private final Rect mTaskBoundsAtDragStart = new Rect();
private final PointF mRepositionStartPoint = new PointF(); private final PointF mRepositionStartPoint = new PointF();
@@ -46,28 +57,29 @@ public class VeiledResizeTaskPositioner implements DragPositioningCallback {
// finalize the bounds there using WCT#setBounds // finalize the bounds there using WCT#setBounds
private final Rect mDisallowedAreaForEndBounds = new Rect(); private final Rect mDisallowedAreaForEndBounds = new Rect();
private final Supplier<SurfaceControl.Transaction> mTransactionSupplier; private final Supplier<SurfaceControl.Transaction> mTransactionSupplier;
private boolean mHasDragResized;
private int mCtrlType; private int mCtrlType;
public VeiledResizeTaskPositioner(ShellTaskOrganizer taskOrganizer, public VeiledResizeTaskPositioner(ShellTaskOrganizer taskOrganizer,
DesktopModeWindowDecoration windowDecoration, DisplayController displayController, DesktopModeWindowDecoration windowDecoration, DisplayController displayController,
Rect disallowedAreaForEndBounds, Rect disallowedAreaForEndBounds,
DragPositioningCallbackUtility.DragStartListener dragStartListener) { DragPositioningCallbackUtility.DragStartListener dragStartListener,
Transitions transitions) {
this(taskOrganizer, windowDecoration, displayController, disallowedAreaForEndBounds, this(taskOrganizer, windowDecoration, displayController, disallowedAreaForEndBounds,
dragStartListener, SurfaceControl.Transaction::new); dragStartListener, SurfaceControl.Transaction::new, transitions);
} }
public VeiledResizeTaskPositioner(ShellTaskOrganizer taskOrganizer, public VeiledResizeTaskPositioner(ShellTaskOrganizer taskOrganizer,
DesktopModeWindowDecoration windowDecoration, DisplayController displayController, DesktopModeWindowDecoration windowDecoration, DisplayController displayController,
Rect disallowedAreaForEndBounds, Rect disallowedAreaForEndBounds,
DragPositioningCallbackUtility.DragStartListener dragStartListener, DragPositioningCallbackUtility.DragStartListener dragStartListener,
Supplier<SurfaceControl.Transaction> supplier) { Supplier<SurfaceControl.Transaction> supplier, Transitions transitions) {
mTaskOrganizer = taskOrganizer; mTaskOrganizer = taskOrganizer;
mDesktopWindowDecoration = windowDecoration; mDesktopWindowDecoration = windowDecoration;
mDisplayController = displayController; mDisplayController = displayController;
mDragStartListener = dragStartListener; mDragStartListener = dragStartListener;
mDisallowedAreaForEndBounds.set(disallowedAreaForEndBounds); mDisallowedAreaForEndBounds.set(disallowedAreaForEndBounds);
mTransactionSupplier = supplier; mTransactionSupplier = supplier;
mTransitions = transitions;
} }
@Override @Override
@@ -84,7 +96,6 @@ public class VeiledResizeTaskPositioner implements DragPositioningCallback {
mTaskOrganizer.applyTransaction(wct); mTaskOrganizer.applyTransaction(wct);
} }
} }
mHasDragResized = false;
mDragStartListener.onDragStart(mDesktopWindowDecoration.mTaskInfo.taskId); mDragStartListener.onDragStart(mDesktopWindowDecoration.mTaskInfo.taskId);
mRepositionTaskBounds.set(mTaskBoundsAtDragStart); mRepositionTaskBounds.set(mTaskBoundsAtDragStart);
} }
@@ -96,7 +107,6 @@ public class VeiledResizeTaskPositioner implements DragPositioningCallback {
mRepositionTaskBounds, mTaskBoundsAtDragStart, mStableBounds, delta, mRepositionTaskBounds, mTaskBoundsAtDragStart, mStableBounds, delta,
mDisplayController, mDesktopWindowDecoration)) { mDisplayController, mDesktopWindowDecoration)) {
mDesktopWindowDecoration.updateResizeVeil(mRepositionTaskBounds); mDesktopWindowDecoration.updateResizeVeil(mRepositionTaskBounds);
mHasDragResized = true;
} else if (mCtrlType == CTRL_TYPE_UNDEFINED) { } else if (mCtrlType == CTRL_TYPE_UNDEFINED) {
final SurfaceControl.Transaction t = mTransactionSupplier.get(); final SurfaceControl.Transaction t = mTransactionSupplier.get();
DragPositioningCallbackUtility.setPositionOnDrag(mDesktopWindowDecoration, DragPositioningCallbackUtility.setPositionOnDrag(mDesktopWindowDecoration,
@@ -111,18 +121,23 @@ public class VeiledResizeTaskPositioner implements DragPositioningCallback {
PointF delta = DragPositioningCallbackUtility.calculateDelta(x, y, PointF delta = DragPositioningCallbackUtility.calculateDelta(x, y,
mRepositionStartPoint); mRepositionStartPoint);
if (isResizing()) { if (isResizing()) {
if (mHasDragResized) { if (!mTaskBoundsAtDragStart.equals(mRepositionTaskBounds)) {
DragPositioningCallbackUtility.changeBounds( DragPositioningCallbackUtility.changeBounds(
mCtrlType, mRepositionTaskBounds, mTaskBoundsAtDragStart, mStableBounds, mCtrlType, mRepositionTaskBounds, mTaskBoundsAtDragStart, mStableBounds,
delta, mDisplayController, mDesktopWindowDecoration); delta, mDisplayController, mDesktopWindowDecoration);
DragPositioningCallbackUtility.applyTaskBoundsChange(
new WindowContainerTransaction(), mDesktopWindowDecoration,
mRepositionTaskBounds, mTaskOrganizer);
}
// TODO: (b/279062291) Synchronize the start of hide to the end of the draw triggered
// above.
mDesktopWindowDecoration.updateResizeVeil(mRepositionTaskBounds); mDesktopWindowDecoration.updateResizeVeil(mRepositionTaskBounds);
final WindowContainerTransaction wct = new WindowContainerTransaction();
wct.setBounds(mDesktopWindowDecoration.mTaskInfo.token, mRepositionTaskBounds);
if (Transitions.ENABLE_SHELL_TRANSITIONS) {
mTransitions.startTransition(TRANSIT_CHANGE, wct, this);
} else {
mTaskOrganizer.applyTransaction(wct);
}
} else {
// If bounds haven't changed, perform necessary veil reset here as startAnimation
// won't be called.
mDesktopWindowDecoration.hideResizeVeil(); mDesktopWindowDecoration.hideResizeVeil();
}
} else if (!mDisallowedAreaForEndBounds.contains((int) x, (int) y)) { } else if (!mDisallowedAreaForEndBounds.contains((int) x, (int) y)) {
DragPositioningCallbackUtility.updateTaskBounds(mRepositionTaskBounds, DragPositioningCallbackUtility.updateTaskBounds(mRepositionTaskBounds,
mTaskBoundsAtDragStart, mRepositionStartPoint, x, y); mTaskBoundsAtDragStart, mRepositionStartPoint, x, y);
@@ -133,7 +148,6 @@ public class VeiledResizeTaskPositioner implements DragPositioningCallback {
mCtrlType = CTRL_TYPE_UNDEFINED; mCtrlType = CTRL_TYPE_UNDEFINED;
mTaskBoundsAtDragStart.setEmpty(); mTaskBoundsAtDragStart.setEmpty();
mRepositionStartPoint.set(0, 0); mRepositionStartPoint.set(0, 0);
mHasDragResized = false;
} }
private boolean isResizing() { private boolean isResizing() {
@@ -141,4 +155,26 @@ public class VeiledResizeTaskPositioner implements DragPositioningCallback {
|| (mCtrlType & CTRL_TYPE_LEFT) != 0 || (mCtrlType & CTRL_TYPE_RIGHT) != 0; || (mCtrlType & CTRL_TYPE_LEFT) != 0 || (mCtrlType & CTRL_TYPE_RIGHT) != 0;
} }
@Override
public boolean startAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
@NonNull SurfaceControl.Transaction startTransaction,
@NonNull SurfaceControl.Transaction finishTransaction,
@NonNull Transitions.TransitionFinishCallback finishCallback) {
startTransaction.apply();
mDesktopWindowDecoration.hideResizeVeil();
mCtrlType = CTRL_TYPE_UNDEFINED;
finishCallback.onTransitionFinished(null, null);
return true;
}
/**
* We should never reach this as this handler's transitions are only started from shell
* explicitly.
*/
@Nullable
@Override
public WindowContainerTransaction handleRequest(@NonNull IBinder transition,
@NonNull TransitionRequestInfo request) {
return null;
}
} }

View File

@@ -54,6 +54,7 @@ import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.desktopmode.DesktopModeController; import com.android.wm.shell.desktopmode.DesktopModeController;
import com.android.wm.shell.desktopmode.DesktopTasksController; import com.android.wm.shell.desktopmode.DesktopTasksController;
import com.android.wm.shell.splitscreen.SplitScreenController; import com.android.wm.shell.splitscreen.SplitScreenController;
import com.android.wm.shell.transition.Transitions;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@@ -87,6 +88,7 @@ public class DesktopModeWindowDecorViewModelTests extends ShellTestCase {
@Mock private DesktopTasksController mDesktopTasksController; @Mock private DesktopTasksController mDesktopTasksController;
@Mock private InputMonitor mInputMonitor; @Mock private InputMonitor mInputMonitor;
@Mock private InputManager mInputManager; @Mock private InputManager mInputManager;
@Mock private Transitions mTransitions;
@Mock private DesktopModeWindowDecorViewModel.InputMonitorFactory mMockInputMonitorFactory; @Mock private DesktopModeWindowDecorViewModel.InputMonitorFactory mMockInputMonitorFactory;
@Mock private Supplier<SurfaceControl.Transaction> mTransactionFactory; @Mock private Supplier<SurfaceControl.Transaction> mTransactionFactory;
@Mock private SurfaceControl.Transaction mTransaction; @Mock private SurfaceControl.Transaction mTransaction;
@@ -106,6 +108,7 @@ public class DesktopModeWindowDecorViewModelTests extends ShellTestCase {
mTaskOrganizer, mTaskOrganizer,
mDisplayController, mDisplayController,
mSyncQueue, mSyncQueue,
mTransitions,
Optional.of(mDesktopModeController), Optional.of(mDesktopModeController),
Optional.of(mDesktopTasksController), Optional.of(mDesktopTasksController),
Optional.of(mSplitScreenController), Optional.of(mSplitScreenController),

View File

@@ -22,12 +22,14 @@ import android.os.IBinder
import android.testing.AndroidTestingRunner import android.testing.AndroidTestingRunner
import android.view.Display import android.view.Display
import android.view.SurfaceControl import android.view.SurfaceControl
import android.view.WindowManager.TRANSIT_CHANGE
import android.window.WindowContainerToken import android.window.WindowContainerToken
import androidx.test.filters.SmallTest import androidx.test.filters.SmallTest
import com.android.wm.shell.ShellTaskOrganizer import com.android.wm.shell.ShellTaskOrganizer
import com.android.wm.shell.ShellTestCase import com.android.wm.shell.ShellTestCase
import com.android.wm.shell.common.DisplayController import com.android.wm.shell.common.DisplayController
import com.android.wm.shell.common.DisplayLayout import com.android.wm.shell.common.DisplayLayout
import com.android.wm.shell.transition.Transitions
import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_RIGHT import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_RIGHT
import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_TOP import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_TOP
import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_UNDEFINED import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_UNDEFINED
@@ -78,6 +80,8 @@ class VeiledResizeTaskPositionerTest : ShellTestCase() {
private lateinit var mockTransactionFactory: Supplier<SurfaceControl.Transaction> private lateinit var mockTransactionFactory: Supplier<SurfaceControl.Transaction>
@Mock @Mock
private lateinit var mockTransaction: SurfaceControl.Transaction private lateinit var mockTransaction: SurfaceControl.Transaction
@Mock
private lateinit var mockTransitions: Transitions
private lateinit var taskPositioner: VeiledResizeTaskPositioner private lateinit var taskPositioner: VeiledResizeTaskPositioner
@@ -92,7 +96,8 @@ class VeiledResizeTaskPositionerTest : ShellTestCase() {
mockDisplayController, mockDisplayController,
DISALLOWED_AREA_FOR_END_BOUNDS, DISALLOWED_AREA_FOR_END_BOUNDS,
mockDragStartListener, mockDragStartListener,
mockTransactionFactory mockTransactionFactory,
mockTransitions
) )
whenever(taskToken.asBinder()).thenReturn(taskBinder) whenever(taskToken.asBinder()).thenReturn(taskBinder)
@@ -129,6 +134,12 @@ class VeiledResizeTaskPositionerTest : ShellTestCase() {
STARTING_BOUNDS.left.toFloat(), STARTING_BOUNDS.left.toFloat(),
STARTING_BOUNDS.top.toFloat() STARTING_BOUNDS.top.toFloat()
) )
verify(mockTransitions, never()).startTransition(eq(TRANSIT_CHANGE), argThat { wct ->
return@argThat wct.changes.any { (token, change) ->
token == taskBinder &&
(change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0 &&
change.configuration.windowConfiguration.bounds == STARTING_BOUNDS}},
eq(taskPositioner))
verify(mockDesktopWindowDecoration).hideResizeVeil() verify(mockDesktopWindowDecoration).hideResizeVeil()
} }
@@ -206,15 +217,12 @@ class VeiledResizeTaskPositionerTest : ShellTestCase() {
rectAfterEnd.right += 10 rectAfterEnd.right += 10
rectAfterEnd.top += 10 rectAfterEnd.top += 10
verify(mockDesktopWindowDecoration, times(2)).updateResizeVeil(any()) verify(mockDesktopWindowDecoration, times(2)).updateResizeVeil(any())
verify(mockDesktopWindowDecoration).hideResizeVeil() verify(mockTransitions).startTransition(eq(TRANSIT_CHANGE), argThat { wct ->
verify(mockShellTaskOrganizer).applyTransaction(argThat { wct ->
return@argThat wct.changes.any { (token, change) -> return@argThat wct.changes.any { (token, change) ->
token == taskBinder && token == taskBinder &&
(change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0 && (change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0 &&
change.configuration.windowConfiguration.bounds == rectAfterEnd change.configuration.windowConfiguration.bounds == rectAfterEnd}},
} eq(taskPositioner))
})
} }
@Test @Test
@@ -235,7 +243,13 @@ class VeiledResizeTaskPositionerTest : ShellTestCase() {
STARTING_BOUNDS.left.toFloat() + 10, STARTING_BOUNDS.left.toFloat() + 10,
STARTING_BOUNDS.top.toFloat() + 10 STARTING_BOUNDS.top.toFloat() + 10
) )
verify(mockDesktopWindowDecoration).hideResizeVeil()
verify(mockTransitions, never()).startTransition(eq(TRANSIT_CHANGE), argThat { wct ->
return@argThat wct.changes.any { (token, change) ->
token == taskBinder &&
(change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0 &&
change.configuration.windowConfiguration.bounds == STARTING_BOUNDS}},
eq(taskPositioner))
verify(mockShellTaskOrganizer, never()).applyTransaction(argThat { wct -> verify(mockShellTaskOrganizer, never()).applyTransaction(argThat { wct ->
return@argThat wct.changes.any { (token, change) -> return@argThat wct.changes.any { (token, change) ->