Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipDisplayTransferHandler.java +2 −26 Original line number Diff line number Diff line Loading @@ -15,11 +15,8 @@ */ package com.android.wm.shell.pip2.phone; import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE; import android.annotation.Nullable; import android.content.Context; import android.graphics.PointF; import android.graphics.Rect; import android.graphics.RectF; import android.os.Bundle; Loading @@ -30,7 +27,6 @@ import android.view.SurfaceControl.Transaction; import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; import com.android.internal.protolog.ProtoLog; import com.android.wm.shell.RootTaskDisplayAreaOrganizer; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayLayout; Loading Loading @@ -124,29 +120,9 @@ public class PipDisplayTransferHandler implements * position. * * @param originDisplayId the display ID where the drag originated from * @param currentDisplayId the current display ID the pointer is on * @param originPointerCoordinates the position of the pointer when it started dragging * @param currentPointerCoordinates the position of the pointer it's currently on * @param originBounds the PiP bounds when dragging starts * @param globalDpPipBounds the PiP bounds in display topology-aware global DP */ public void showDragMirrorOnConnectedDisplays(int originDisplayId, int currentDisplayId, PointF originPointerCoordinates, PointF currentPointerCoordinates, Rect originBounds) { DisplayLayout originDisplayLayout = mDisplayController.getDisplayLayout(originDisplayId); DisplayLayout currentDisplayLayout = mDisplayController.getDisplayLayout(currentDisplayId); if (originDisplayLayout == null || currentDisplayLayout == null) { ProtoLog.w(WM_SHELL_PICTURE_IN_PICTURE, "%s: Failed to show drag mirror on connected displays because displayLayout " + "is null", TAG); return; } RectF globalDpPipBounds = MultiDisplayDragMoveBoundsCalculator.calculateGlobalDpBoundsForDrag( originDisplayLayout, originPointerCoordinates, originBounds, currentDisplayLayout, currentPointerCoordinates.x, currentPointerCoordinates.y ); public void showDragMirrorOnConnectedDisplays(int originDisplayId, RectF globalDpPipBounds) { final Transaction transaction = mSurfaceControlTransactionFactory.getTransaction(); // Iterate through each connected display ID to ensure partial PiP bounds are shown on // all corresponding displays while dragging Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java +44 −19 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import android.content.Context; import android.content.res.Resources; import android.graphics.PointF; import android.graphics.Rect; import android.graphics.RectF; import android.os.Bundle; import android.os.SystemProperties; import android.provider.DeviceConfig; Loading @@ -53,7 +54,9 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.protolog.ProtoLog; import com.android.wm.shell.R; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.FloatingContentCoordinator; import com.android.wm.shell.common.MultiDisplayDragMoveBoundsCalculator; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.pip.PipBoundsAlgorithm; import com.android.wm.shell.common.pip.PipBoundsState; Loading Loading @@ -102,6 +105,7 @@ public class PipTouchHandler implements PipTransitionState.PipTransitionStateCha private final PipDisplayTransferHandler mPipDisplayTransferHandler; private final PhonePipMenuController mMenuController; private final AccessibilityManager mAccessibilityManager; private final DisplayController mDisplayController; /** * Whether PIP stash is enabled or not. When enabled, if the user flings toward the edge of the Loading Loading @@ -205,6 +209,7 @@ public class PipTouchHandler implements PipTransitionState.PipTransitionStateCha mPipBoundsAlgorithm = pipBoundsAlgorithm; mPipBoundsState = pipBoundsState; mPipDesktopState = pipDesktopState; mDisplayController = displayController; mPipTransitionState = pipTransitionState; mPipTransitionState.addPipTransitionStateChangedListener(this::onPipTransitionStateChanged); Loading @@ -220,7 +225,7 @@ public class PipTouchHandler implements PipTransitionState.PipTransitionStateCha mPipDisplayTransferHandler = pipDisplayTransferHandler; mPipScheduler.setUpdateMovementBoundsRunnable(this::updateMovementBounds); mPipDismissTargetHandler = new PipDismissTargetHandler(context, pipUiEventLogger, mMotionHelper, mPipDisplayLayoutState, displayController, mainExecutor); mMotionHelper, mPipDisplayLayoutState, mDisplayController, mainExecutor); mTouchState = new PipTouchState(ViewConfiguration.get(context), () -> { mMenuController.showMenuWithPossibleDelay(MENU_STATE_FULL, Loading Loading @@ -868,7 +873,34 @@ public class PipTouchHandler implements PipTransitionState.PipTransitionStateCha if (touchState.isDragging()) { mPipBoundsState.setHasUserMovedPip(true); final PointF curPos = touchState.getLastTouchPosition(); if (mPipDesktopState.isDraggingPipAcrossDisplaysEnabled()) { DisplayLayout currentDisplayLayout = mDisplayController.getDisplayLayout( touchState.getLastTouchDisplayId()); DisplayLayout displayLayoutOnDown = mDisplayController.getDisplayLayout( mDisplayIdOnDown); if (displayLayoutOnDown == null || currentDisplayLayout == null) { ProtoLog.w(WM_SHELL_PICTURE_IN_PICTURE, "%s: Failed to show drag mirror on connected displays because " + "displayLayout is null", TAG); return false; } RectF globalDpPipBounds = MultiDisplayDragMoveBoundsCalculator.calculateGlobalDpBoundsForDrag( displayLayoutOnDown, mPointerPositionOnDown, mStartBounds, currentDisplayLayout, curPos.x, curPos.y); // Create mirrors on connected displays to simulate dragging PiP across displays mPipDisplayTransferHandler.showDragMirrorOnConnectedDisplays(mDisplayIdOnDown, globalDpPipBounds); // Set PiP bounds on the origin display in display topology-aware local px mTmpBounds.set( MultiDisplayDragMoveBoundsCalculator.convertGlobalDpToLocalPxForRect( globalDpPipBounds, displayLayoutOnDown)); } else { // Move the pinned stack freely final PointF lastDelta = touchState.getLastTouchDelta(); float lastX = mStartBounds.left + mDelta.x; Loading @@ -882,17 +914,10 @@ public class PipTouchHandler implements PipTransitionState.PipTransitionStateCha mTmpBounds.set(getPossiblyMotionBounds()); mTmpBounds.offsetTo((int) left, (int) top); mMotionHelper.movePip(mTmpBounds, true /* isDragging */); final PointF curPos = touchState.getLastTouchPosition(); if (mPipDesktopState.isDraggingPipAcrossDisplaysEnabled()) { // Create mirrors on connected displays to simulate dragging PiP across displays mPipDisplayTransferHandler.showDragMirrorOnConnectedDisplays(mDisplayIdOnDown, touchState.getLastTouchDisplayId(), mPointerPositionOnDown, curPos, mStartBounds); } mMotionHelper.movePip(mTmpBounds, true /* isDragging */); if (mMovementWithinDismiss) { // Track if movement remains near the bottom edge to identify swipe to dismiss mMovementWithinDismiss = curPos.y >= mPipBoundsState.getMovementBounds().bottom; Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipDisplayTransferHandlerTest.kt +18 −12 Original line number Diff line number Diff line Loading @@ -43,7 +43,6 @@ import android.content.res.Configuration import android.content.res.Resources import android.graphics.PointF import android.graphics.Rect import android.graphics.RectF import android.os.Bundle import android.testing.TestableResources import android.util.ArrayMap Loading @@ -60,6 +59,8 @@ import org.mockito.kotlin.eq import org.mockito.kotlin.times import com.google.common.truth.Truth.assertThat import com.android.wm.shell.R import com.android.wm.shell.common.DisplayLayout import com.android.wm.shell.common.MultiDisplayDragMoveBoundsCalculator import com.android.wm.shell.common.MultiDisplayTestUtil.TestDisplay import org.junit.Rule import org.mockito.kotlin.never Loading Loading @@ -92,6 +93,7 @@ class PipDisplayTransferHandlerTest : ShellTestCase() { private lateinit var pipDisplayTransferHandler: PipDisplayTransferHandler private val displayIds = intArrayOf(ORIGIN_DISPLAY_ID, TARGET_DISPLAY_ID, SECONDARY_DISPLAY_ID) private val displayLayouts = ArrayMap<Int, DisplayLayout>() private val mockBounds = Rect() @JvmField Loading Loading @@ -137,6 +139,7 @@ class PipDisplayTransferHandlerTest : ShellTestCase() { whenever(mockDisplayController.getDisplay(id)).thenReturn(display) val displayLayout = TestDisplay.entries.find { it.id == id }?.getSpyDisplayLayout(resources) displayLayouts.put(id, displayLayout) whenever(mockDisplayController.getDisplayLayout(id)).thenReturn(displayLayout) } Loading Loading @@ -189,10 +192,11 @@ class PipDisplayTransferHandlerTest : ShellTestCase() { @Test fun showDragMirrorOnConnectedDisplays_hasNotLeftOriginDisplay_shouldNotCreateMirrors() { val globalDpBounds = MultiDisplayDragMoveBoundsCalculator.calculateGlobalDpBoundsForDrag( displayLayouts.get(ORIGIN_DISPLAY_ID)!!, START_DRAG_COORDINATES, PIP_BOUNDS, displayLayouts.get(ORIGIN_DISPLAY_ID)!!, 150f, 150f) pipDisplayTransferHandler.showDragMirrorOnConnectedDisplays( ORIGIN_DISPLAY_ID, ORIGIN_DISPLAY_ID, START_DRAG_COORDINATES, PointF(150f, 150f), PIP_BOUNDS ORIGIN_DISPLAY_ID, globalDpBounds ) verify(mockRootTaskDisplayAreaOrganizer, never()).reparentToDisplayArea( Loading @@ -214,10 +218,12 @@ class PipDisplayTransferHandlerTest : ShellTestCase() { @Test fun showDragMirrorOnConnectedDisplays_movedToAnotherDisplay_createsOneMirror() { val globalDpBounds = MultiDisplayDragMoveBoundsCalculator.calculateGlobalDpBoundsForDrag( displayLayouts.get(ORIGIN_DISPLAY_ID)!!, START_DRAG_COORDINATES, PIP_BOUNDS, displayLayouts.get(TARGET_DISPLAY_ID)!!, TestDisplay.DISPLAY_1.bounds.centerX(), TestDisplay.DISPLAY_1.bounds.centerY()) pipDisplayTransferHandler.showDragMirrorOnConnectedDisplays( ORIGIN_DISPLAY_ID, TARGET_DISPLAY_ID, START_DRAG_COORDINATES, TestDisplay.DISPLAY_1.bounds.center(), PIP_BOUNDS ORIGIN_DISPLAY_ID, globalDpBounds ) verify(mockRootTaskDisplayAreaOrganizer).reparentToDisplayArea( Loading @@ -240,10 +246,12 @@ class PipDisplayTransferHandlerTest : ShellTestCase() { @Test fun showDragMirrorOnConnectedDisplays_inBetweenThreeDisplays_createsTwoMirrors() { val globalDpBounds = MultiDisplayDragMoveBoundsCalculator.calculateGlobalDpBoundsForDrag( displayLayouts.get(ORIGIN_DISPLAY_ID)!!, START_DRAG_COORDINATES, PIP_BOUNDS, displayLayouts.get(TARGET_DISPLAY_ID)!!, 1000f, -100f) pipDisplayTransferHandler.showDragMirrorOnConnectedDisplays( ORIGIN_DISPLAY_ID, TARGET_DISPLAY_ID, START_DRAG_COORDINATES, PointF(1000f, -100f), PIP_BOUNDS ORIGIN_DISPLAY_ID, globalDpBounds ) verify(mockRootTaskDisplayAreaOrganizer).reparentToDisplayArea( Loading Loading @@ -290,8 +298,6 @@ class PipDisplayTransferHandlerTest : ShellTestCase() { assertThat(pipDisplayTransferHandler.mOnDragMirrorPerDisplayId.isEmpty()).isTrue() } fun RectF.center(): PointF = PointF(this.centerX(), this.centerY()) companion object { const val ORIGIN_DISPLAY_ID = 0 const val TARGET_DISPLAY_ID = 1 Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipTouchHandlerTest.kt +43 −9 Original line number Diff line number Diff line Loading @@ -17,13 +17,18 @@ package com.android.wm.shell.pip2.phone import android.graphics.PointF import android.graphics.Rect import android.graphics.RectF import android.testing.AndroidTestingRunner import android.testing.TestableLooper.RunWithLooper import android.view.SurfaceControl import androidx.test.filters.SmallTest import com.android.dx.mockito.inline.extended.ExtendedMockito import com.android.modules.utils.testing.ExtendedMockitoRule 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.FloatingContentCoordinator import com.android.wm.shell.common.MultiDisplayDragMoveBoundsCalculator import com.android.wm.shell.common.ShellExecutor import com.android.wm.shell.common.pip.PipBoundsAlgorithm import com.android.wm.shell.common.pip.PipBoundsState Loading @@ -37,6 +42,7 @@ import com.android.wm.shell.sysui.ShellCommandHandler import com.android.wm.shell.sysui.ShellInit import java.util.Optional import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.anyInt Loading Loading @@ -76,13 +82,20 @@ class PipTouchHandlerTest : ShellTestCase() { private val pipTouchState = mock<PipTouchState>() private val mockMotionBoundsState = mock<PipBoundsState.MotionBoundsState>() private val mockLeash = mock<SurfaceControl>() private val mockBounds = Rect() private val mockDisplayLayout = mock<DisplayLayout>() private val mockTouchPosition = PointF() private val mockPipSurfaceTransactionHelper = mock<PipSurfaceTransactionHelper>() private lateinit var pipTouchHandler: PipTouchHandler private lateinit var pipTouchGesture: PipTouchGesture @JvmField @Rule val extendedMockitoRule = ExtendedMockitoRule.Builder(this) .mockStatic(MultiDisplayDragMoveBoundsCalculator::class.java) .build()!! @Before fun setUp() { pipTouchHandler = PipTouchHandler( Loading @@ -102,9 +115,19 @@ class PipTouchHandlerTest : ShellTestCase() { whenever(pipTouchState.lastTouchDisplayId).thenReturn(ORIGIN_DISPLAY_ID) whenever(pipTouchState.lastTouchDelta).thenReturn(mockTouchPosition) whenever(pipTransitionState.pinnedTaskLeash).thenReturn(mockLeash) whenever(mockPipBoundsState.movementBounds).thenReturn(mockBounds) whenever(mockPipBoundsState.movementBounds).thenReturn(PIP_BOUNDS) whenever(mockPipBoundsState.motionBoundsState).thenReturn(mockMotionBoundsState) whenever(pipTouchHandler.possiblyMotionBounds).thenReturn(mockBounds) whenever(pipTouchHandler.possiblyMotionBounds).thenReturn(PIP_BOUNDS) whenever(mockDisplayController.getDisplayLayout(anyInt())) .thenReturn(mockDisplayLayout) whenever( MultiDisplayDragMoveBoundsCalculator.convertGlobalDpToLocalPxForRect(any(), any()) ).thenReturn(PIP_BOUNDS) whenever( MultiDisplayDragMoveBoundsCalculator.calculateGlobalDpBoundsForDrag( any(), any(), any(), any(), any(), any() ) ).thenReturn(GLOBAL_BOUNDS) } @Test Loading @@ -112,17 +135,26 @@ class PipTouchHandlerTest : ShellTestCase() { whenever(mockPipDesktopState.isDraggingPipAcrossDisplaysEnabled()).thenReturn(true) whenever(pipTouchState.isUserInteracting).thenReturn(true) whenever(pipTouchState.isDragging).thenReturn(true) // Initialize variables that are set on down pipTouchGesture.onDown(pipTouchState) pipTouchGesture.onMove(pipTouchState) verify(mockPipDisplayTransferHandler).showDragMirrorOnConnectedDisplays( anyInt(), anyInt(), any(), any(), any() ExtendedMockito.verify { MultiDisplayDragMoveBoundsCalculator.calculateGlobalDpBoundsForDrag( any(), any(), any(), any(), any(), any() ) } ExtendedMockito.verify { MultiDisplayDragMoveBoundsCalculator.convertGlobalDpToLocalPxForRect( eq(GLOBAL_BOUNDS), eq(mockDisplayLayout) ) } verify(mockPipDisplayTransferHandler).showDragMirrorOnConnectedDisplays( eq(ORIGIN_DISPLAY_ID), eq(GLOBAL_BOUNDS)) verify(mockPipMotionHelper).movePip(eq(PIP_BOUNDS), eq(true)) } @Test fun pipTouchGesture_crossDisplayDragFlagEnabled_onUpOnADifferentDisplay_schedulesMovePip() { Loading Loading @@ -153,5 +185,7 @@ class PipTouchHandlerTest : ShellTestCase() { private companion object { const val ORIGIN_DISPLAY_ID = 0 const val TARGET_DISPLAY_ID = 1 val PIP_BOUNDS = Rect(0, 0, 700, 700) val GLOBAL_BOUNDS = RectF(0f, 0f, 400f, 400f) } } No newline at end of file Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipDisplayTransferHandler.java +2 −26 Original line number Diff line number Diff line Loading @@ -15,11 +15,8 @@ */ package com.android.wm.shell.pip2.phone; import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE; import android.annotation.Nullable; import android.content.Context; import android.graphics.PointF; import android.graphics.Rect; import android.graphics.RectF; import android.os.Bundle; Loading @@ -30,7 +27,6 @@ import android.view.SurfaceControl.Transaction; import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; import com.android.internal.protolog.ProtoLog; import com.android.wm.shell.RootTaskDisplayAreaOrganizer; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayLayout; Loading Loading @@ -124,29 +120,9 @@ public class PipDisplayTransferHandler implements * position. * * @param originDisplayId the display ID where the drag originated from * @param currentDisplayId the current display ID the pointer is on * @param originPointerCoordinates the position of the pointer when it started dragging * @param currentPointerCoordinates the position of the pointer it's currently on * @param originBounds the PiP bounds when dragging starts * @param globalDpPipBounds the PiP bounds in display topology-aware global DP */ public void showDragMirrorOnConnectedDisplays(int originDisplayId, int currentDisplayId, PointF originPointerCoordinates, PointF currentPointerCoordinates, Rect originBounds) { DisplayLayout originDisplayLayout = mDisplayController.getDisplayLayout(originDisplayId); DisplayLayout currentDisplayLayout = mDisplayController.getDisplayLayout(currentDisplayId); if (originDisplayLayout == null || currentDisplayLayout == null) { ProtoLog.w(WM_SHELL_PICTURE_IN_PICTURE, "%s: Failed to show drag mirror on connected displays because displayLayout " + "is null", TAG); return; } RectF globalDpPipBounds = MultiDisplayDragMoveBoundsCalculator.calculateGlobalDpBoundsForDrag( originDisplayLayout, originPointerCoordinates, originBounds, currentDisplayLayout, currentPointerCoordinates.x, currentPointerCoordinates.y ); public void showDragMirrorOnConnectedDisplays(int originDisplayId, RectF globalDpPipBounds) { final Transaction transaction = mSurfaceControlTransactionFactory.getTransaction(); // Iterate through each connected display ID to ensure partial PiP bounds are shown on // all corresponding displays while dragging Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java +44 −19 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import android.content.Context; import android.content.res.Resources; import android.graphics.PointF; import android.graphics.Rect; import android.graphics.RectF; import android.os.Bundle; import android.os.SystemProperties; import android.provider.DeviceConfig; Loading @@ -53,7 +54,9 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.protolog.ProtoLog; import com.android.wm.shell.R; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.FloatingContentCoordinator; import com.android.wm.shell.common.MultiDisplayDragMoveBoundsCalculator; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.pip.PipBoundsAlgorithm; import com.android.wm.shell.common.pip.PipBoundsState; Loading Loading @@ -102,6 +105,7 @@ public class PipTouchHandler implements PipTransitionState.PipTransitionStateCha private final PipDisplayTransferHandler mPipDisplayTransferHandler; private final PhonePipMenuController mMenuController; private final AccessibilityManager mAccessibilityManager; private final DisplayController mDisplayController; /** * Whether PIP stash is enabled or not. When enabled, if the user flings toward the edge of the Loading Loading @@ -205,6 +209,7 @@ public class PipTouchHandler implements PipTransitionState.PipTransitionStateCha mPipBoundsAlgorithm = pipBoundsAlgorithm; mPipBoundsState = pipBoundsState; mPipDesktopState = pipDesktopState; mDisplayController = displayController; mPipTransitionState = pipTransitionState; mPipTransitionState.addPipTransitionStateChangedListener(this::onPipTransitionStateChanged); Loading @@ -220,7 +225,7 @@ public class PipTouchHandler implements PipTransitionState.PipTransitionStateCha mPipDisplayTransferHandler = pipDisplayTransferHandler; mPipScheduler.setUpdateMovementBoundsRunnable(this::updateMovementBounds); mPipDismissTargetHandler = new PipDismissTargetHandler(context, pipUiEventLogger, mMotionHelper, mPipDisplayLayoutState, displayController, mainExecutor); mMotionHelper, mPipDisplayLayoutState, mDisplayController, mainExecutor); mTouchState = new PipTouchState(ViewConfiguration.get(context), () -> { mMenuController.showMenuWithPossibleDelay(MENU_STATE_FULL, Loading Loading @@ -868,7 +873,34 @@ public class PipTouchHandler implements PipTransitionState.PipTransitionStateCha if (touchState.isDragging()) { mPipBoundsState.setHasUserMovedPip(true); final PointF curPos = touchState.getLastTouchPosition(); if (mPipDesktopState.isDraggingPipAcrossDisplaysEnabled()) { DisplayLayout currentDisplayLayout = mDisplayController.getDisplayLayout( touchState.getLastTouchDisplayId()); DisplayLayout displayLayoutOnDown = mDisplayController.getDisplayLayout( mDisplayIdOnDown); if (displayLayoutOnDown == null || currentDisplayLayout == null) { ProtoLog.w(WM_SHELL_PICTURE_IN_PICTURE, "%s: Failed to show drag mirror on connected displays because " + "displayLayout is null", TAG); return false; } RectF globalDpPipBounds = MultiDisplayDragMoveBoundsCalculator.calculateGlobalDpBoundsForDrag( displayLayoutOnDown, mPointerPositionOnDown, mStartBounds, currentDisplayLayout, curPos.x, curPos.y); // Create mirrors on connected displays to simulate dragging PiP across displays mPipDisplayTransferHandler.showDragMirrorOnConnectedDisplays(mDisplayIdOnDown, globalDpPipBounds); // Set PiP bounds on the origin display in display topology-aware local px mTmpBounds.set( MultiDisplayDragMoveBoundsCalculator.convertGlobalDpToLocalPxForRect( globalDpPipBounds, displayLayoutOnDown)); } else { // Move the pinned stack freely final PointF lastDelta = touchState.getLastTouchDelta(); float lastX = mStartBounds.left + mDelta.x; Loading @@ -882,17 +914,10 @@ public class PipTouchHandler implements PipTransitionState.PipTransitionStateCha mTmpBounds.set(getPossiblyMotionBounds()); mTmpBounds.offsetTo((int) left, (int) top); mMotionHelper.movePip(mTmpBounds, true /* isDragging */); final PointF curPos = touchState.getLastTouchPosition(); if (mPipDesktopState.isDraggingPipAcrossDisplaysEnabled()) { // Create mirrors on connected displays to simulate dragging PiP across displays mPipDisplayTransferHandler.showDragMirrorOnConnectedDisplays(mDisplayIdOnDown, touchState.getLastTouchDisplayId(), mPointerPositionOnDown, curPos, mStartBounds); } mMotionHelper.movePip(mTmpBounds, true /* isDragging */); if (mMovementWithinDismiss) { // Track if movement remains near the bottom edge to identify swipe to dismiss mMovementWithinDismiss = curPos.y >= mPipBoundsState.getMovementBounds().bottom; Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipDisplayTransferHandlerTest.kt +18 −12 Original line number Diff line number Diff line Loading @@ -43,7 +43,6 @@ import android.content.res.Configuration import android.content.res.Resources import android.graphics.PointF import android.graphics.Rect import android.graphics.RectF import android.os.Bundle import android.testing.TestableResources import android.util.ArrayMap Loading @@ -60,6 +59,8 @@ import org.mockito.kotlin.eq import org.mockito.kotlin.times import com.google.common.truth.Truth.assertThat import com.android.wm.shell.R import com.android.wm.shell.common.DisplayLayout import com.android.wm.shell.common.MultiDisplayDragMoveBoundsCalculator import com.android.wm.shell.common.MultiDisplayTestUtil.TestDisplay import org.junit.Rule import org.mockito.kotlin.never Loading Loading @@ -92,6 +93,7 @@ class PipDisplayTransferHandlerTest : ShellTestCase() { private lateinit var pipDisplayTransferHandler: PipDisplayTransferHandler private val displayIds = intArrayOf(ORIGIN_DISPLAY_ID, TARGET_DISPLAY_ID, SECONDARY_DISPLAY_ID) private val displayLayouts = ArrayMap<Int, DisplayLayout>() private val mockBounds = Rect() @JvmField Loading Loading @@ -137,6 +139,7 @@ class PipDisplayTransferHandlerTest : ShellTestCase() { whenever(mockDisplayController.getDisplay(id)).thenReturn(display) val displayLayout = TestDisplay.entries.find { it.id == id }?.getSpyDisplayLayout(resources) displayLayouts.put(id, displayLayout) whenever(mockDisplayController.getDisplayLayout(id)).thenReturn(displayLayout) } Loading Loading @@ -189,10 +192,11 @@ class PipDisplayTransferHandlerTest : ShellTestCase() { @Test fun showDragMirrorOnConnectedDisplays_hasNotLeftOriginDisplay_shouldNotCreateMirrors() { val globalDpBounds = MultiDisplayDragMoveBoundsCalculator.calculateGlobalDpBoundsForDrag( displayLayouts.get(ORIGIN_DISPLAY_ID)!!, START_DRAG_COORDINATES, PIP_BOUNDS, displayLayouts.get(ORIGIN_DISPLAY_ID)!!, 150f, 150f) pipDisplayTransferHandler.showDragMirrorOnConnectedDisplays( ORIGIN_DISPLAY_ID, ORIGIN_DISPLAY_ID, START_DRAG_COORDINATES, PointF(150f, 150f), PIP_BOUNDS ORIGIN_DISPLAY_ID, globalDpBounds ) verify(mockRootTaskDisplayAreaOrganizer, never()).reparentToDisplayArea( Loading @@ -214,10 +218,12 @@ class PipDisplayTransferHandlerTest : ShellTestCase() { @Test fun showDragMirrorOnConnectedDisplays_movedToAnotherDisplay_createsOneMirror() { val globalDpBounds = MultiDisplayDragMoveBoundsCalculator.calculateGlobalDpBoundsForDrag( displayLayouts.get(ORIGIN_DISPLAY_ID)!!, START_DRAG_COORDINATES, PIP_BOUNDS, displayLayouts.get(TARGET_DISPLAY_ID)!!, TestDisplay.DISPLAY_1.bounds.centerX(), TestDisplay.DISPLAY_1.bounds.centerY()) pipDisplayTransferHandler.showDragMirrorOnConnectedDisplays( ORIGIN_DISPLAY_ID, TARGET_DISPLAY_ID, START_DRAG_COORDINATES, TestDisplay.DISPLAY_1.bounds.center(), PIP_BOUNDS ORIGIN_DISPLAY_ID, globalDpBounds ) verify(mockRootTaskDisplayAreaOrganizer).reparentToDisplayArea( Loading @@ -240,10 +246,12 @@ class PipDisplayTransferHandlerTest : ShellTestCase() { @Test fun showDragMirrorOnConnectedDisplays_inBetweenThreeDisplays_createsTwoMirrors() { val globalDpBounds = MultiDisplayDragMoveBoundsCalculator.calculateGlobalDpBoundsForDrag( displayLayouts.get(ORIGIN_DISPLAY_ID)!!, START_DRAG_COORDINATES, PIP_BOUNDS, displayLayouts.get(TARGET_DISPLAY_ID)!!, 1000f, -100f) pipDisplayTransferHandler.showDragMirrorOnConnectedDisplays( ORIGIN_DISPLAY_ID, TARGET_DISPLAY_ID, START_DRAG_COORDINATES, PointF(1000f, -100f), PIP_BOUNDS ORIGIN_DISPLAY_ID, globalDpBounds ) verify(mockRootTaskDisplayAreaOrganizer).reparentToDisplayArea( Loading Loading @@ -290,8 +298,6 @@ class PipDisplayTransferHandlerTest : ShellTestCase() { assertThat(pipDisplayTransferHandler.mOnDragMirrorPerDisplayId.isEmpty()).isTrue() } fun RectF.center(): PointF = PointF(this.centerX(), this.centerY()) companion object { const val ORIGIN_DISPLAY_ID = 0 const val TARGET_DISPLAY_ID = 1 Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipTouchHandlerTest.kt +43 −9 Original line number Diff line number Diff line Loading @@ -17,13 +17,18 @@ package com.android.wm.shell.pip2.phone import android.graphics.PointF import android.graphics.Rect import android.graphics.RectF import android.testing.AndroidTestingRunner import android.testing.TestableLooper.RunWithLooper import android.view.SurfaceControl import androidx.test.filters.SmallTest import com.android.dx.mockito.inline.extended.ExtendedMockito import com.android.modules.utils.testing.ExtendedMockitoRule 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.FloatingContentCoordinator import com.android.wm.shell.common.MultiDisplayDragMoveBoundsCalculator import com.android.wm.shell.common.ShellExecutor import com.android.wm.shell.common.pip.PipBoundsAlgorithm import com.android.wm.shell.common.pip.PipBoundsState Loading @@ -37,6 +42,7 @@ import com.android.wm.shell.sysui.ShellCommandHandler import com.android.wm.shell.sysui.ShellInit import java.util.Optional import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.anyInt Loading Loading @@ -76,13 +82,20 @@ class PipTouchHandlerTest : ShellTestCase() { private val pipTouchState = mock<PipTouchState>() private val mockMotionBoundsState = mock<PipBoundsState.MotionBoundsState>() private val mockLeash = mock<SurfaceControl>() private val mockBounds = Rect() private val mockDisplayLayout = mock<DisplayLayout>() private val mockTouchPosition = PointF() private val mockPipSurfaceTransactionHelper = mock<PipSurfaceTransactionHelper>() private lateinit var pipTouchHandler: PipTouchHandler private lateinit var pipTouchGesture: PipTouchGesture @JvmField @Rule val extendedMockitoRule = ExtendedMockitoRule.Builder(this) .mockStatic(MultiDisplayDragMoveBoundsCalculator::class.java) .build()!! @Before fun setUp() { pipTouchHandler = PipTouchHandler( Loading @@ -102,9 +115,19 @@ class PipTouchHandlerTest : ShellTestCase() { whenever(pipTouchState.lastTouchDisplayId).thenReturn(ORIGIN_DISPLAY_ID) whenever(pipTouchState.lastTouchDelta).thenReturn(mockTouchPosition) whenever(pipTransitionState.pinnedTaskLeash).thenReturn(mockLeash) whenever(mockPipBoundsState.movementBounds).thenReturn(mockBounds) whenever(mockPipBoundsState.movementBounds).thenReturn(PIP_BOUNDS) whenever(mockPipBoundsState.motionBoundsState).thenReturn(mockMotionBoundsState) whenever(pipTouchHandler.possiblyMotionBounds).thenReturn(mockBounds) whenever(pipTouchHandler.possiblyMotionBounds).thenReturn(PIP_BOUNDS) whenever(mockDisplayController.getDisplayLayout(anyInt())) .thenReturn(mockDisplayLayout) whenever( MultiDisplayDragMoveBoundsCalculator.convertGlobalDpToLocalPxForRect(any(), any()) ).thenReturn(PIP_BOUNDS) whenever( MultiDisplayDragMoveBoundsCalculator.calculateGlobalDpBoundsForDrag( any(), any(), any(), any(), any(), any() ) ).thenReturn(GLOBAL_BOUNDS) } @Test Loading @@ -112,17 +135,26 @@ class PipTouchHandlerTest : ShellTestCase() { whenever(mockPipDesktopState.isDraggingPipAcrossDisplaysEnabled()).thenReturn(true) whenever(pipTouchState.isUserInteracting).thenReturn(true) whenever(pipTouchState.isDragging).thenReturn(true) // Initialize variables that are set on down pipTouchGesture.onDown(pipTouchState) pipTouchGesture.onMove(pipTouchState) verify(mockPipDisplayTransferHandler).showDragMirrorOnConnectedDisplays( anyInt(), anyInt(), any(), any(), any() ExtendedMockito.verify { MultiDisplayDragMoveBoundsCalculator.calculateGlobalDpBoundsForDrag( any(), any(), any(), any(), any(), any() ) } ExtendedMockito.verify { MultiDisplayDragMoveBoundsCalculator.convertGlobalDpToLocalPxForRect( eq(GLOBAL_BOUNDS), eq(mockDisplayLayout) ) } verify(mockPipDisplayTransferHandler).showDragMirrorOnConnectedDisplays( eq(ORIGIN_DISPLAY_ID), eq(GLOBAL_BOUNDS)) verify(mockPipMotionHelper).movePip(eq(PIP_BOUNDS), eq(true)) } @Test fun pipTouchGesture_crossDisplayDragFlagEnabled_onUpOnADifferentDisplay_schedulesMovePip() { Loading Loading @@ -153,5 +185,7 @@ class PipTouchHandlerTest : ShellTestCase() { private companion object { const val ORIGIN_DISPLAY_ID = 0 const val TARGET_DISPLAY_ID = 1 val PIP_BOUNDS = Rect(0, 0, 700, 700) val GLOBAL_BOUNDS = RectF(0f, 0f, 400f, 400f) } } No newline at end of file