summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java15
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt1
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/VisualIndicatorViewContainer.kt93
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java41
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModel.kt42
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt42
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/SnapEventHandler.kt12
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicatorTest.kt3
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/VisualIndicatorViewContainerTest.kt57
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModelTest.kt29
10 files changed, 281 insertions, 54 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java
index 99f052832a51..56de48daf810 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java
@@ -49,6 +49,7 @@ import com.android.wm.shell.shared.annotations.ShellMainThread;
import com.android.wm.shell.shared.bubbles.BubbleAnythingFlagHelper;
import com.android.wm.shell.shared.bubbles.BubbleDropTargetBoundsProvider;
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
+import com.android.wm.shell.windowdecor.tiling.SnapEventHandler;
/**
* Animated visual indicator for Desktop Mode windowing transitions.
@@ -98,7 +99,9 @@ public class DesktopModeVisualIndicator {
return FROM_SPLIT;
} else if (taskInfo.isFreeform()) {
return FROM_FREEFORM;
- } else return null;
+ } else {
+ return null;
+ }
}
}
@@ -110,6 +113,7 @@ public class DesktopModeVisualIndicator {
private IndicatorType mCurrentType;
private final DragStartState mDragStartState;
+ private final SnapEventHandler mSnapEventHandler;
public DesktopModeVisualIndicator(@ShellDesktopThread ShellExecutor desktopExecutor,
@ShellMainThread ShellExecutor mainExecutor,
@@ -118,18 +122,20 @@ public class DesktopModeVisualIndicator {
Context context, SurfaceControl taskSurface,
RootTaskDisplayAreaOrganizer taskDisplayAreaOrganizer,
DragStartState dragStartState,
- @Nullable BubbleDropTargetBoundsProvider bubbleBoundsProvider) {
+ @Nullable BubbleDropTargetBoundsProvider bubbleBoundsProvider,
+ SnapEventHandler snapEventHandler) {
SurfaceControl.Builder builder = new SurfaceControl.Builder();
taskDisplayAreaOrganizer.attachToDisplayArea(taskInfo.displayId, builder);
mVisualIndicatorViewContainer = new VisualIndicatorViewContainer(
DesktopModeFlags.ENABLE_DESKTOP_INDICATOR_IN_SEPARATE_THREAD_BUGFIX.isTrue()
? desktopExecutor : mainExecutor,
- mainExecutor, builder, syncQueue, bubbleBoundsProvider);
+ mainExecutor, builder, syncQueue, bubbleBoundsProvider, snapEventHandler);
mTaskInfo = taskInfo;
mDisplayController = displayController;
mContext = context;
mCurrentType = NO_INDICATOR;
mDragStartState = dragStartState;
+ mSnapEventHandler = snapEventHandler;
mVisualIndicatorViewContainer.createView(
mContext,
mDisplayController.getDisplay(mTaskInfo.displayId),
@@ -143,7 +149,8 @@ public class DesktopModeVisualIndicator {
public void fadeOutIndicator(
@NonNull Runnable callback) {
mVisualIndicatorViewContainer.fadeOutIndicator(
- mDisplayController.getDisplayLayout(mTaskInfo.displayId), mCurrentType, callback
+ mDisplayController.getDisplayLayout(mTaskInfo.displayId), mCurrentType, callback,
+ mTaskInfo.displayId, mSnapEventHandler
);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
index 1c880569fe7f..2d9aea014fbe 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
@@ -3051,6 +3051,7 @@ class DesktopTasksController(
rootTaskDisplayAreaOrganizer,
dragStartState,
bubbleController.getOrNull()?.bubbleDropTargetBoundsProvider,
+ snapEventHandler,
)
if (visualIndicator == null) visualIndicator = indicator
return indicator.updateIndicatorType(PointF(inputX, taskTop))
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/VisualIndicatorViewContainer.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/VisualIndicatorViewContainer.kt
index 2317274dbbf0..919e8164b58e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/VisualIndicatorViewContainer.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/VisualIndicatorViewContainer.kt
@@ -44,6 +44,7 @@ import com.android.wm.shell.shared.annotations.ShellDesktopThread
import com.android.wm.shell.shared.annotations.ShellMainThread
import com.android.wm.shell.shared.bubbles.BubbleDropTargetBoundsProvider
import com.android.wm.shell.windowdecor.WindowDecoration.SurfaceControlViewHostFactory
+import com.android.wm.shell.windowdecor.tiling.SnapEventHandler
/**
* Container for the view / viewhost of the indicator, ensuring it is created / animated off the
@@ -60,6 +61,7 @@ constructor(
private val surfaceControlViewHostFactory: SurfaceControlViewHostFactory =
object : SurfaceControlViewHostFactory {},
private val bubbleBoundsProvider: BubbleDropTargetBoundsProvider?,
+ private val snapEventHandler: SnapEventHandler,
) {
@VisibleForTesting var indicatorView: View? = null
private var indicatorViewHost: SurfaceControlViewHost? = null
@@ -164,9 +166,15 @@ constructor(
displayController.getDisplayLayout(taskInfo.displayId)
?: error("Expected to find DisplayLayout for taskId${taskInfo.taskId}.")
if (currentType == IndicatorType.NO_INDICATOR) {
- fadeInIndicator(layout, newType)
+ fadeInIndicator(layout, newType, taskInfo.displayId, snapEventHandler)
} else if (newType == IndicatorType.NO_INDICATOR) {
- fadeOutIndicator(layout, currentType, /* finishCallback= */ null)
+ fadeOutIndicator(
+ layout,
+ currentType,
+ /* finishCallback= */ null,
+ taskInfo.displayId,
+ snapEventHandler,
+ )
} else {
val animStartType = IndicatorType.valueOf(currentType.name)
val animator =
@@ -177,6 +185,8 @@ constructor(
animStartType,
newType,
bubbleBoundsProvider,
+ taskInfo.displayId,
+ snapEventHandler,
)
} ?: return@execute
animator.start()
@@ -188,12 +198,24 @@ constructor(
* Fade indicator in as provided type. Animator fades it in while expanding the bounds outwards.
*/
@VisibleForTesting
- fun fadeInIndicator(layout: DisplayLayout, type: IndicatorType) {
+ fun fadeInIndicator(
+ layout: DisplayLayout,
+ type: IndicatorType,
+ displayId: Int,
+ snapEventHandler: SnapEventHandler,
+ ) {
desktopExecutor.assertCurrentThread()
indicatorView?.let {
it.setBackgroundResource(R.drawable.desktop_windowing_transition_background)
val animator =
- VisualIndicatorAnimator.fadeBoundsIn(it, type, layout, bubbleBoundsProvider)
+ VisualIndicatorAnimator.fadeBoundsIn(
+ it,
+ type,
+ layout,
+ bubbleBoundsProvider,
+ displayId,
+ snapEventHandler,
+ )
animator.start()
}
}
@@ -207,6 +229,8 @@ constructor(
layout: DisplayLayout,
currentType: IndicatorType,
finishCallback: Runnable?,
+ displayId: Int,
+ snapEventHandler: SnapEventHandler,
) {
if (currentType == IndicatorType.NO_INDICATOR) {
// In rare cases, fade out can be requested before the indicator has determined its
@@ -223,6 +247,8 @@ constructor(
animStartType,
layout,
bubbleBoundsProvider,
+ displayId,
+ snapEventHandler,
)
animator.addListener(
object : AnimatorListenerAdapter() {
@@ -328,8 +354,17 @@ constructor(
type: IndicatorType,
displayLayout: DisplayLayout,
bubbleBoundsProvider: BubbleDropTargetBoundsProvider?,
+ displayId: Int,
+ snapEventHandler: SnapEventHandler,
): VisualIndicatorAnimator {
- val endBounds = getIndicatorBounds(displayLayout, type, bubbleBoundsProvider)
+ val endBounds =
+ getIndicatorBounds(
+ displayLayout,
+ type,
+ bubbleBoundsProvider,
+ displayId,
+ snapEventHandler,
+ )
val startBounds = getMinBounds(endBounds)
view.background.bounds = startBounds
@@ -345,11 +380,19 @@ constructor(
type: IndicatorType,
displayLayout: DisplayLayout,
bubbleBoundsProvider: BubbleDropTargetBoundsProvider?,
+ displayId: Int,
+ snapEventHandler: SnapEventHandler,
): VisualIndicatorAnimator {
- val startBounds = getIndicatorBounds(displayLayout, type, bubbleBoundsProvider)
+ val startBounds =
+ getIndicatorBounds(
+ displayLayout,
+ type,
+ bubbleBoundsProvider,
+ displayId,
+ snapEventHandler,
+ )
val endBounds = getMinBounds(startBounds)
view.background.bounds = startBounds
-
val animator = VisualIndicatorAnimator(view, startBounds, endBounds)
animator.interpolator = DecelerateInterpolator()
setupIndicatorAnimation(animator, AlphaAnimType.ALPHA_FADE_OUT_ANIM)
@@ -375,9 +418,25 @@ constructor(
origType: IndicatorType,
newType: IndicatorType,
bubbleBoundsProvider: BubbleDropTargetBoundsProvider?,
+ displayId: Int,
+ snapEventHandler: SnapEventHandler,
): VisualIndicatorAnimator {
- val startBounds = getIndicatorBounds(displayLayout, origType, bubbleBoundsProvider)
- val endBounds = getIndicatorBounds(displayLayout, newType, bubbleBoundsProvider)
+ val startBounds =
+ getIndicatorBounds(
+ displayLayout,
+ origType,
+ bubbleBoundsProvider,
+ displayId,
+ snapEventHandler,
+ )
+ val endBounds =
+ getIndicatorBounds(
+ displayLayout,
+ newType,
+ bubbleBoundsProvider,
+ displayId,
+ snapEventHandler,
+ )
val animator = VisualIndicatorAnimator(view, startBounds, endBounds)
animator.interpolator = DecelerateInterpolator()
setupIndicatorAnimation(animator, AlphaAnimType.ALPHA_NO_CHANGE_ANIM)
@@ -389,6 +448,8 @@ constructor(
layout: DisplayLayout,
type: IndicatorType,
bubbleBoundsProvider: BubbleDropTargetBoundsProvider?,
+ displayId: Int,
+ snapEventHandler: SnapEventHandler,
): Rect {
val desktopStableBounds = Rect()
layout.getStableBounds(desktopStableBounds)
@@ -417,21 +478,25 @@ constructor(
)
}
- IndicatorType.TO_SPLIT_LEFT_INDICATOR ->
+ IndicatorType.TO_SPLIT_LEFT_INDICATOR -> {
+ val currentLeftBounds = snapEventHandler.getLeftSnapBoundsIfTiled(displayId)
return Rect(
padding,
padding,
- desktopStableBounds.width() / 2 - padding,
+ currentLeftBounds.right - padding,
desktopStableBounds.height(),
)
-
- IndicatorType.TO_SPLIT_RIGHT_INDICATOR ->
+ }
+ IndicatorType.TO_SPLIT_RIGHT_INDICATOR -> {
+ val currentRightBounds =
+ snapEventHandler.getRightSnapBoundsIfTiled(displayId)
return Rect(
- desktopStableBounds.width() / 2 + padding,
+ currentRightBounds.left + padding,
padding,
desktopStableBounds.width() - padding,
desktopStableBounds.height(),
)
+ }
IndicatorType.TO_BUBBLE_LEFT_INDICATOR ->
return bubbleBoundsProvider?.getBubbleBarExpandedViewDropTargetBounds(
/* onLeft= */ true
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 d9afd1503db5..0d773ecf88e4 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
@@ -159,6 +159,8 @@ import kotlin.Pair;
import kotlin.Unit;
import kotlin.jvm.functions.Function1;
+import org.jetbrains.annotations.NotNull;
+
import kotlinx.coroutines.CoroutineScope;
import kotlinx.coroutines.ExperimentalCoroutinesApi;
import kotlinx.coroutines.MainCoroutineDispatcher;
@@ -935,6 +937,18 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
return mDesktopTilingDecorViewModel.moveTaskToFrontIfTiled(taskInfo);
}
+ @Override
+ @NotNull
+ public Rect getLeftSnapBoundsIfTiled(int displayId) {
+ return mDesktopTilingDecorViewModel.getLeftSnapBoundsIfTiled(displayId);
+ }
+
+ @Override
+ @NotNull
+ public Rect getRightSnapBoundsIfTiled(int displayId) {
+ return mDesktopTilingDecorViewModel.getRightSnapBoundsIfTiled(displayId);
+ }
+
private class DesktopModeTouchEventListener extends GestureDetector.SimpleOnGestureListener
implements View.OnClickListener, View.OnTouchListener, View.OnLongClickListener,
View.OnGenericMotionListener, DragDetector.MotionEventHandler {
@@ -974,7 +988,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
final int touchSlop = ViewConfiguration.get(mContext).getScaledTouchSlop();
final long appHandleHoldToDragDuration =
DesktopModeFlags.ENABLE_HOLD_TO_DRAG_APP_HANDLE.isTrue()
- ? APP_HANDLE_HOLD_TO_DRAG_DURATION_MS : 0;
+ ? APP_HANDLE_HOLD_TO_DRAG_DURATION_MS : 0;
mHandleDragDetector = new DragDetector(this, appHandleHoldToDragDuration,
touchSlop);
mHeaderDragDetector = new DragDetector(this, APP_HEADER_HOLD_TO_DRAG_DURATION_MS,
@@ -1027,7 +1041,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
decoration.mTaskInfo.userId);
if (DesktopModeFlags.ENABLE_FULLY_IMMERSIVE_IN_DESKTOP.isTrue()
&& desktopRepository.isTaskInFullImmersiveState(
- decoration.mTaskInfo.taskId)) {
+ decoration.mTaskInfo.taskId)) {
// Task is in immersive and should exit.
onEnterOrExitImmersive(decoration.mTaskInfo);
} else {
@@ -1321,6 +1335,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
/**
* Perform a task size toggle on release of the double-tap, assuming no drag event
* was handled during the double-tap.
+ *
* @param e The motion event that occurred during the double-tap gesture.
* @return true if the event should be consumed, false if not
*/
@@ -1346,6 +1361,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
class EventReceiver extends InputEventReceiver {
private InputMonitor mInputMonitor;
private int mTasksOnDisplay;
+
EventReceiver(InputMonitor inputMonitor, InputChannel channel, Looper looper) {
super(channel, looper);
mInputMonitor = inputMonitor;
@@ -1397,6 +1413,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
/**
* Check if an EventReceiver exists on a particular display.
* If it does, increment its task count. Otherwise, create one for that display.
+ *
* @param displayId the display to check against
*/
private void incrementEventReceiverTasks(int displayId) {
@@ -1902,7 +1919,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
@Override
public void onAnimationStart(int taskId, Transaction t, Rect bounds) {
final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(taskId);
- if (decoration == null) {
+ if (decoration == null) {
t.apply();
return;
}
@@ -1986,15 +2003,15 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
return activityTaskManager.getRecentTasks(Integer.MAX_VALUE,
ActivityManager.RECENT_WITH_EXCLUDED,
info.userId).getList().stream().filter(
- recentTaskInfo -> {
- if (recentTaskInfo.taskId == info.taskId) {
- return false;
- }
- final String recentTaskPackageName =
- ComponentUtils.getPackageName(recentTaskInfo);
- return packageName != null
- && packageName.equals(recentTaskPackageName);
- }
+ recentTaskInfo -> {
+ if (recentTaskInfo.taskId == info.taskId) {
+ return false;
+ }
+ final String recentTaskPackageName =
+ ComponentUtils.getPackageName(recentTaskInfo);
+ return packageName != null
+ && packageName.equals(recentTaskPackageName);
+ }
).toList().size();
} catch (RemoteException e) {
throw new RuntimeException(e);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModel.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModel.kt
index 8747f63e789f..ee5d0e80d90c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModel.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModel.kt
@@ -25,6 +25,7 @@ import android.window.DisplayAreaInfo
import android.window.WindowContainerTransaction
import androidx.core.util.valueIterator
import com.android.internal.annotations.VisibleForTesting
+import com.android.wm.shell.R
import com.android.wm.shell.RootTaskDisplayAreaOrganizer
import com.android.wm.shell.ShellTaskOrganizer
import com.android.wm.shell.common.DisplayChangeController
@@ -148,4 +149,45 @@ class DesktopTilingDecorViewModel(
if ((fromRotation % 2 == toRotation % 2)) return
tilingTransitionHandlerByDisplayId.get(displayId)?.resetTilingSession()
}
+
+ fun getRightSnapBoundsIfTiled(displayId: Int): Rect {
+ val tilingBounds =
+ tilingTransitionHandlerByDisplayId.get(displayId)?.getRightSnapBoundsIfTiled()
+ if (tilingBounds != null) {
+ return tilingBounds
+ }
+ val displayLayout = displayController.getDisplayLayout(displayId)
+ val stableBounds = Rect()
+ displayLayout?.getStableBounds(stableBounds)
+ val snapBounds =
+ Rect(
+ stableBounds.left +
+ stableBounds.width() / 2 +
+ context.resources.getDimensionPixelSize(R.dimen.split_divider_bar_width) / 2,
+ stableBounds.top,
+ stableBounds.right,
+ stableBounds.bottom,
+ )
+ return snapBounds
+ }
+
+ fun getLeftSnapBoundsIfTiled(displayId: Int): Rect {
+ val tilingBounds =
+ tilingTransitionHandlerByDisplayId.get(displayId)?.getLeftSnapBoundsIfTiled()
+ if (tilingBounds != null) {
+ return tilingBounds
+ }
+ val displayLayout = displayController.getDisplayLayout(displayId)
+ val stableBounds = Rect()
+ displayLayout?.getStableBounds(stableBounds)
+ val snapBounds =
+ Rect(
+ stableBounds.left,
+ stableBounds.top,
+ stableBounds.left + stableBounds.width() / 2 -
+ context.resources.getDimensionPixelSize(R.dimen.split_divider_bar_width) / 2,
+ stableBounds.bottom,
+ )
+ return snapBounds
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt
index 666d4bd046dc..983332565bd9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt
@@ -36,7 +36,6 @@ import android.window.WindowContainerTransaction
import com.android.internal.annotations.VisibleForTesting
import com.android.launcher3.icons.BaseIconFactory
import com.android.window.flags.Flags
-import com.android.wm.shell.shared.FocusTransitionListener
import com.android.wm.shell.R
import com.android.wm.shell.RootTaskDisplayAreaOrganizer
import com.android.wm.shell.ShellTaskOrganizer
@@ -50,6 +49,7 @@ import com.android.wm.shell.desktopmode.DesktopTasksController.SnapPosition
import com.android.wm.shell.desktopmode.DesktopUserRepositories
import com.android.wm.shell.desktopmode.ReturnToDragStartAnimator
import com.android.wm.shell.desktopmode.ToggleResizeDesktopTaskTransitionHandler
+import com.android.wm.shell.shared.FocusTransitionListener
import com.android.wm.shell.shared.annotations.ShellBackgroundThread
import com.android.wm.shell.shared.annotations.ShellMainThread
import com.android.wm.shell.transition.FocusTransitionObserver
@@ -112,7 +112,7 @@ class DesktopTilingWindowDecoration(
position: SnapPosition,
currentBounds: Rect,
): Boolean {
- val destinationBounds = getSnapBounds(taskInfo, position)
+ val destinationBounds = getSnapBounds(position)
val resizeMetadata =
AppResizingHelper(
taskInfo,
@@ -502,9 +502,11 @@ class DesktopTilingWindowDecoration(
}
// Overriding FocusTransitionListener
- override fun onFocusedTaskChanged(taskId: Int,
- isFocusedOnDisplay: Boolean,
- isFocusedGlobally: Boolean) {
+ override fun onFocusedTaskChanged(
+ taskId: Int,
+ isFocusedOnDisplay: Boolean,
+ isFocusedGlobally: Boolean,
+ ) {
if (!Flags.enableDisplayFocusInShellTransitions()) return
moveTiledPairToFront(taskId, isFocusedOnDisplay)
}
@@ -512,7 +514,7 @@ class DesktopTilingWindowDecoration(
// Only called if [taskInfo] relates to a focused task
private fun isTilingRefocused(taskId: Int): Boolean {
return taskId == leftTaskResizingHelper?.taskInfo?.taskId ||
- taskId == rightTaskResizingHelper?.taskInfo?.taskId
+ taskId == rightTaskResizingHelper?.taskInfo?.taskId
}
private fun buildTiledTasksMoveToFront(leftOnTop: Boolean): WindowContainerTransaction {
@@ -623,26 +625,24 @@ class DesktopTilingWindowDecoration(
val t = transactionSupplier.get()
if (!Flags.enableDisplayFocusInShellTransitions()) isTilingFocused = true
if (taskId == leftTaskResizingHelper?.taskInfo?.taskId) {
- desktopTilingDividerWindowManager?.onRelativeLeashChanged(
- leftTiledTask.getLeash(),
- t,
- )
+ desktopTilingDividerWindowManager?.onRelativeLeashChanged(leftTiledTask.getLeash(), t)
}
if (taskId == rightTaskResizingHelper?.taskInfo?.taskId) {
- desktopTilingDividerWindowManager?.onRelativeLeashChanged(
- rightTiledTask.getLeash(),
- t,
- )
+ desktopTilingDividerWindowManager?.onRelativeLeashChanged(rightTiledTask.getLeash(), t)
}
- transitions.startTransition(
- TRANSIT_TO_FRONT,
- buildTiledTasksMoveToFront(isLeftOnTop),
- null,
- )
+ transitions.startTransition(TRANSIT_TO_FRONT, buildTiledTasksMoveToFront(isLeftOnTop), null)
t.apply()
return true
}
+ fun getRightSnapBoundsIfTiled(): Rect {
+ return getSnapBounds(SnapPosition.RIGHT)
+ }
+
+ fun getLeftSnapBoundsIfTiled(): Rect {
+ return getSnapBounds(SnapPosition.LEFT)
+ }
+
private fun allTiledTasksVisible(): Boolean {
val leftTiledTask = leftTaskResizingHelper ?: return false
val rightTiledTask = rightTaskResizingHelper ?: return false
@@ -674,8 +674,8 @@ class DesktopTilingWindowDecoration(
)
}
- private fun getSnapBounds(taskInfo: RunningTaskInfo, position: SnapPosition): Rect {
- val displayLayout = displayController.getDisplayLayout(taskInfo.displayId) ?: return Rect()
+ private fun getSnapBounds(position: SnapPosition): Rect {
+ val displayLayout = displayController.getDisplayLayout(displayId) ?: return Rect()
val stableBounds = Rect()
displayLayout.getStableBounds(stableBounds)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/SnapEventHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/SnapEventHandler.kt
index 52e24d6fe0d0..b9d674110eb2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/SnapEventHandler.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/SnapEventHandler.kt
@@ -40,4 +40,16 @@ interface SnapEventHandler {
/** If a task is tiled, delegate moving to front to tiling infrastructure. */
fun moveTaskToFrontIfTiled(taskInfo: RunningTaskInfo): Boolean
+
+ /**
+ * Returns the bounds of a task tiled on the left on the specified display, defaults to default
+ * snapping bounds if no task is tiled.
+ */
+ fun getLeftSnapBoundsIfTiled(displayId: Int): Rect
+
+ /**
+ * Returns the bounds of a task tiled on the right on the specified display, defaults to default
+ * snapping bounds if no task is tiled.
+ */
+ fun getRightSnapBoundsIfTiled(displayId: Int): Rect
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicatorTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicatorTest.kt
index 20d50aa32f7f..dcc9e2415039 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicatorTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicatorTest.kt
@@ -36,6 +36,7 @@ import com.android.wm.shell.common.DisplayController
import com.android.wm.shell.common.DisplayLayout
import com.android.wm.shell.common.SyncTransactionQueue
import com.android.wm.shell.shared.bubbles.BubbleDropTargetBoundsProvider
+import com.android.wm.shell.windowdecor.tiling.SnapEventHandler
import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Rule
@@ -67,6 +68,7 @@ class DesktopModeVisualIndicatorTest : ShellTestCase() {
@Mock private lateinit var taskDisplayAreaOrganizer: RootTaskDisplayAreaOrganizer
@Mock private lateinit var displayLayout: DisplayLayout
@Mock private lateinit var bubbleBoundsProvider: BubbleDropTargetBoundsProvider
+ @Mock private lateinit var snapEventHandler: SnapEventHandler
private lateinit var visualIndicator: DesktopModeVisualIndicator
private val desktopExecutor = TestShellExecutor()
@@ -356,6 +358,7 @@ class DesktopModeVisualIndicatorTest : ShellTestCase() {
taskDisplayAreaOrganizer,
dragStartState,
bubbleBoundsProvider,
+ snapEventHandler,
)
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/VisualIndicatorViewContainerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/VisualIndicatorViewContainerTest.kt
index 79b0f1c7eadd..4c8cb3823f7e 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/VisualIndicatorViewContainerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/VisualIndicatorViewContainerTest.kt
@@ -38,6 +38,7 @@ import com.android.wm.shell.common.DisplayLayout
import com.android.wm.shell.common.SyncTransactionQueue
import com.android.wm.shell.shared.bubbles.BubbleDropTargetBoundsProvider
import com.android.wm.shell.windowdecor.WindowDecoration.SurfaceControlViewHostFactory
+import com.android.wm.shell.windowdecor.tiling.SnapEventHandler
import com.google.common.truth.Truth.assertThat
import kotlin.test.Test
import org.junit.Before
@@ -71,6 +72,7 @@ class VisualIndicatorViewContainerTest : ShellTestCase() {
@Mock private lateinit var mockSurfaceControlViewHostFactory: SurfaceControlViewHostFactory
@Mock private lateinit var mockBackground: LayerDrawable
@Mock private lateinit var bubbleDropTargetBoundsProvider: BubbleDropTargetBoundsProvider
+ @Mock private lateinit var snapEventHandler: SnapEventHandler
private val taskInfo: RunningTaskInfo = createTaskInfo()
private val mainExecutor = TestShellExecutor()
private val desktopExecutor = TestShellExecutor()
@@ -81,6 +83,8 @@ class VisualIndicatorViewContainerTest : ShellTestCase() {
whenever(displayLayout.getStableBounds(any())).thenAnswer { i ->
(i.arguments.first() as Rect).set(DISPLAY_BOUNDS)
}
+ whenever(snapEventHandler.getRightSnapBoundsIfTiled(any())).thenReturn(Rect(1, 2, 3, 4))
+ whenever(snapEventHandler.getLeftSnapBoundsIfTiled(any())).thenReturn(Rect(5, 6, 7, 8))
whenever(mockSurfaceControlViewHostFactory.create(any(), any(), any()))
.thenReturn(mock(SurfaceControlViewHost::class.java))
}
@@ -117,7 +121,7 @@ class VisualIndicatorViewContainerTest : ShellTestCase() {
DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR,
)
desktopExecutor.flushAll()
- verify(spyViewContainer).fadeInIndicator(any(), any())
+ verify(spyViewContainer).fadeInIndicator(any(), any(), any(), any())
}
@Test
@@ -135,6 +139,8 @@ class VisualIndicatorViewContainerTest : ShellTestCase() {
any(),
eq(DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR),
anyOrNull(),
+ eq(taskInfo.displayId),
+ eq(snapEventHandler),
)
}
@@ -167,6 +173,8 @@ class VisualIndicatorViewContainerTest : ShellTestCase() {
DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR,
displayLayout,
bubbleDropTargetBoundsProvider,
+ taskInfo.displayId,
+ snapEventHandler,
)
}
assertThat(animator?.indicatorStartBounds).isEqualTo(Rect(15, 15, 985, 985))
@@ -174,6 +182,46 @@ class VisualIndicatorViewContainerTest : ShellTestCase() {
}
@Test
+ fun testFadeInBoundsCalculationForLeftSnap() {
+ val spyIndicator = setupSpyViewContainer()
+ val animator =
+ spyIndicator.indicatorView?.let {
+ VisualIndicatorViewContainer.VisualIndicatorAnimator.fadeBoundsIn(
+ it,
+ DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_LEFT_INDICATOR,
+ displayLayout,
+ bubbleDropTargetBoundsProvider,
+ taskInfo.displayId,
+ snapEventHandler,
+ )
+ }
+
+ // Right bound is the same as whatever right bound snapEventHandler returned minus padding,
+ // in this case, the right bound for the left app is 7.
+ assertThat(animator?.indicatorEndBounds).isEqualTo(Rect(0, 0, 7, 1000))
+ }
+
+ @Test
+ fun testFadeInBoundsCalculationForRightSnap() {
+ val spyIndicator = setupSpyViewContainer()
+ val animator =
+ spyIndicator.indicatorView?.let {
+ VisualIndicatorViewContainer.VisualIndicatorAnimator.fadeBoundsIn(
+ it,
+ DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_RIGHT_INDICATOR,
+ displayLayout,
+ bubbleDropTargetBoundsProvider,
+ taskInfo.displayId,
+ snapEventHandler,
+ )
+ }
+
+ // Left bound is the same as whatever left bound snapEventHandler returned plus padding
+ // in this case, the left bound of the right app is 1.
+ assertThat(animator?.indicatorEndBounds).isEqualTo(Rect(1, 0, 1000, 1000))
+ }
+
+ @Test
fun testFadeOutBoundsCalculation() {
val spyIndicator = setupSpyViewContainer()
val animator =
@@ -183,6 +231,8 @@ class VisualIndicatorViewContainerTest : ShellTestCase() {
DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR,
displayLayout,
bubbleDropTargetBoundsProvider,
+ taskInfo.displayId,
+ snapEventHandler,
)
}
assertThat(animator?.indicatorStartBounds).isEqualTo(Rect(0, 0, 1000, 1000))
@@ -199,6 +249,8 @@ class VisualIndicatorViewContainerTest : ShellTestCase() {
DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR,
DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_LEFT_INDICATOR,
bubbleDropTargetBoundsProvider,
+ taskInfo.displayId,
+ snapEventHandler,
)
// Test desktop to split-right bounds.
animator =
@@ -208,6 +260,8 @@ class VisualIndicatorViewContainerTest : ShellTestCase() {
DesktopModeVisualIndicator.IndicatorType.TO_DESKTOP_INDICATOR,
DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_RIGHT_INDICATOR,
bubbleDropTargetBoundsProvider,
+ taskInfo.displayId,
+ snapEventHandler,
)
}
@@ -220,6 +274,7 @@ class VisualIndicatorViewContainerTest : ShellTestCase() {
syncQueue,
mockSurfaceControlViewHostFactory,
bubbleDropTargetBoundsProvider,
+ snapEventHandler,
)
viewContainer.createView(
context,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModelTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModelTest.kt
index 2cabb9a33b86..646ec21cab9b 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModelTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModelTest.kt
@@ -16,6 +16,7 @@
package com.android.wm.shell.windowdecor.tiling
import android.content.Context
+import android.content.res.Resources
import android.graphics.Rect
import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
@@ -23,12 +24,13 @@ import com.android.wm.shell.RootTaskDisplayAreaOrganizer
import com.android.wm.shell.ShellTaskOrganizer
import com.android.wm.shell.ShellTestCase
import com.android.wm.shell.common.DisplayController
+import com.android.wm.shell.common.DisplayLayout
import com.android.wm.shell.common.ShellExecutor
import com.android.wm.shell.common.SyncTransactionQueue
import com.android.wm.shell.desktopmode.DesktopModeEventLogger
-import com.android.wm.shell.desktopmode.DesktopUserRepositories
import com.android.wm.shell.desktopmode.DesktopTasksController
import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFreeformTask
+import com.android.wm.shell.desktopmode.DesktopUserRepositories
import com.android.wm.shell.desktopmode.ReturnToDragStartAnimator
import com.android.wm.shell.desktopmode.ToggleResizeDesktopTaskTransitionHandler
import com.android.wm.shell.transition.FocusTransitionObserver
@@ -52,6 +54,7 @@ import org.mockito.kotlin.whenever
@RunWith(AndroidTestingRunner::class)
class DesktopTilingDecorViewModelTest : ShellTestCase() {
private val contextMock: Context = mock()
+ private val resourcesMock: Resources = mock()
private val mainDispatcher: MainCoroutineDispatcher = mock()
private val bgScope: CoroutineScope = mock()
private val displayControllerMock: DisplayController = mock()
@@ -70,6 +73,7 @@ class DesktopTilingDecorViewModelTest : ShellTestCase() {
private val desktopTilingDecoration: DesktopTilingWindowDecoration = mock()
private val taskResourceLoader: WindowDecorTaskResourceLoader = mock()
private val focusTransitionObserver: FocusTransitionObserver = mock()
+ private val displayLayout: DisplayLayout = mock()
private val mainExecutor: ShellExecutor = mock()
private lateinit var desktopTilingDecorViewModel: DesktopTilingDecorViewModel
@@ -91,9 +95,16 @@ class DesktopTilingDecorViewModelTest : ShellTestCase() {
desktopModeEventLogger,
taskResourceLoader,
focusTransitionObserver,
- mainExecutor
+ mainExecutor,
)
whenever(contextMock.createContextAsUser(any(), any())).thenReturn(contextMock)
+ whenever(displayControllerMock.getDisplayLayout(any())).thenReturn(displayLayout)
+ whenever(displayLayout.getStableBounds(any())).thenAnswer { i ->
+ (i.arguments.first() as Rect).set(STABLE_BOUNDS)
+ }
+ whenever(contextMock.createContextAsUser(any(), any())).thenReturn(context)
+ whenever(contextMock.resources).thenReturn(resourcesMock)
+ whenever(resourcesMock.getDimensionPixelSize(any())).thenReturn(10)
}
@Test
@@ -202,7 +213,21 @@ class DesktopTilingDecorViewModelTest : ShellTestCase() {
verify(desktopTilingDecoration, times(1)).resetTilingSession()
}
+ @Test
+ fun getTiledAppBounds_NoTilingTransitionHandlerObject() {
+ // Right bound of the left app here represents default 8 / 2 - 2 ( {Right bound} / 2 -
+ // {divider pixel size})
+ assertThat(desktopTilingDecorViewModel.getLeftSnapBoundsIfTiled(1))
+ .isEqualTo(Rect(6, 7, 2, 9))
+
+ // Left bound of the right app here represents default 8 / 2 + 6 + 2 ( {Left bound} +
+ // {width}/ 2 + {divider pixel size})
+ assertThat(desktopTilingDecorViewModel.getRightSnapBoundsIfTiled(1))
+ .isEqualTo(Rect(12, 7, 8, 9))
+ }
+
companion object {
private val BOUNDS = Rect(1, 2, 3, 4)
+ private val STABLE_BOUNDS = Rect(6, 7, 8, 9)
}
}