Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipDisplayTransferHandler.java +39 −5 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static com.android.wm.shell.pip2.phone.PipTransition.PIP_DESTINATION_BOUN import android.annotation.Nullable; import android.app.TaskInfo; import android.content.Context; import android.graphics.Point; import android.graphics.Rect; import android.graphics.RectF; import android.os.Bundle; Loading Loading @@ -97,6 +98,10 @@ public class PipDisplayTransferHandler implements Rect boundsOnRelease) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "%s scheduleMovePipToDisplay from=%d to=%d", TAG, originDisplayId, targetDisplayId); mPipDisplayLayoutState.setDisplayId(targetDisplayId); mPipDisplayLayoutState.setDisplayLayout( mDisplayController.getDisplayLayout(targetDisplayId)); mPipBoundsState.updateMinMaxSize(mPipBoundsState.getAspectRatio()); // Set bounds to the bounds on drag release so that we can use this as the origin bounds // during animation to snap to the display's edge. Loading @@ -107,6 +112,7 @@ public class PipDisplayTransferHandler implements // is released and the display ID and layout are updated. mPipBoundsAlgorithm.snapToMovementBoundsEdge(boundsOnRelease, mDisplayController.getDisplayLayout(targetDisplayId)); snapBoundsWithinMinMaxSize(boundsOnRelease); Bundle extra = new Bundle(); extra.putInt(ORIGIN_DISPLAY_ID_KEY, originDisplayId); Loading @@ -116,6 +122,38 @@ public class PipDisplayTransferHandler implements mPipTransitionState.setState(PipTransitionState.SCHEDULED_BOUNDS_CHANGE, extra); } /** * Restricts {@param bounds} to the allowed min/max size constraints and snaps bounds to the * correct edge based on the snap fraction. */ private void snapBoundsWithinMinMaxSize(Rect bounds) { final float snapFraction = mPipBoundsAlgorithm.getSnapAlgorithm().getSnapFraction( bounds, mPipBoundsAlgorithm.getMovementBounds(bounds), mPipBoundsState.getStashedState()); final Point minSize = mPipBoundsState.getMinSize(); final Point maxSize = mPipBoundsState.getMaxSize(); int newWidth = bounds.width(); int newHeight = bounds.height(); if (bounds.width() < minSize.x || bounds.height() < minSize.y) { newWidth = minSize.x; newHeight = minSize.y; } else if (bounds.width() > maxSize.x || bounds.height() > maxSize.y) { newWidth = maxSize.x; newHeight = maxSize.y; } bounds.set(0, 0, newWidth, newHeight); mPipBoundsAlgorithm.getSnapAlgorithm().applySnapFraction(bounds, mPipBoundsAlgorithm.getMovementBounds(bounds), snapFraction, mPipBoundsState.getStashedState(), mPipBoundsState.getStashOffset(), mPipDisplayLayoutState.getDisplayBounds(), mPipDisplayLayoutState.getDisplayLayout().stableInsets()); } @Override public void onPipTransitionStateChanged(@PipTransitionState.TransitionState int oldState, @PipTransitionState.TransitionState int newState, @Nullable Bundle extra) { Loading Loading @@ -158,10 +196,6 @@ public class PipDisplayTransferHandler implements Trace.instant(Trace.TRACE_TAG_WINDOW_MANAGER, "PipDisplayTransferHandler#changingPipBounds"); mPipDisplayLayoutState.setDisplayId(mTargetDisplayId); mPipDisplayLayoutState.setDisplayLayout( mDisplayController.getDisplayLayout(mTargetDisplayId)); mPipSurfaceTransactionHelper.round(startTx, pipLeash, true).shadow(startTx, pipLeash, true /* applyShadowRadius */); // Set state to exiting and exited PiP to unregister input consumer on the current Loading @@ -177,7 +211,7 @@ public class PipDisplayTransferHandler implements final PipResizeAnimator animator = mPipResizeAnimatorSupplier.get(mContext, mPipSurfaceTransactionHelper, pipLeash, startTx, finishTx, mPipBoundsState.getBounds(), mPipBoundsState.getBounds(), pipBounds, pipBounds, mPipBoundsState.getBounds(), pipBounds, duration, 0); animator.setAnimationEndCallback(() -> { Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipDisplayTransferHandlerTest.kt +18 −1 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ import org.mockito.kotlin.whenever import org.mockito.kotlin.verify import android.content.res.Configuration import android.content.res.Resources import android.graphics.Point import android.graphics.PointF import android.graphics.Rect import android.os.Bundle Loading @@ -63,6 +64,7 @@ import com.android.wm.shell.common.DisplayLayout import com.android.wm.shell.common.MultiDisplayDragMoveBoundsCalculator import com.android.wm.shell.common.MultiDisplayTestUtil.TestDisplay import com.android.wm.shell.common.pip.PipBoundsAlgorithm import com.android.wm.shell.common.pip.PipSnapAlgorithm import com.android.wm.shell.pip2.animation.PipResizeAnimator import com.android.wm.shell.pip2.phone.PipTransitionState.EXITED_PIP import com.android.wm.shell.pip2.phone.PipTransitionState.EXITING_PIP Loading @@ -86,6 +88,7 @@ class PipDisplayTransferHandlerTest : ShellTestCase() { private val mockRootTaskDisplayAreaOrganizer = mock<RootTaskDisplayAreaOrganizer>() private val mockPipBoundsState = mock<PipBoundsState>() private val mockPipBoundsAlgorithm = mock<PipBoundsAlgorithm>() private val mockPipSnapAlgorithm = mock<PipSnapAlgorithm>() private val mockTaskInfo = mock<ActivityManager.RunningTaskInfo>() private val mockDisplayController = mock<DisplayController>() private val mockTransaction = mock<SurfaceControl.Transaction>() Loading Loading @@ -133,6 +136,10 @@ class PipDisplayTransferHandlerTest : ShellTestCase() { whenever(mockTransaction.show(any())).thenReturn(mockTransaction) whenever(mockFactory.transaction).thenReturn(mockTransaction) whenever(mockPipBoundsState.bounds).thenReturn(mockBounds) whenever(mockPipBoundsAlgorithm.snapAlgorithm).thenReturn(mockPipSnapAlgorithm) whenever(mockPipSnapAlgorithm.getSnapFraction(any(), any(), any())).thenReturn(0.5f) whenever(mockPipBoundsState.minSize).thenReturn(MIN_SIZE) whenever(mockPipBoundsState.maxSize).thenReturn(MAX_SIZE) whenever( mockSurfaceTransactionHelper.setPipTransformations( any(), Loading Loading @@ -165,6 +172,11 @@ class PipDisplayTransferHandlerTest : ShellTestCase() { whenever(mockDisplayController.getDisplayLayout(id)).thenReturn(displayLayout) whenever(mockDisplayController.isDisplayInTopology(id)).thenReturn(true) } whenever(mockPipDisplayLayoutState.displayLayout).thenReturn( displayLayouts.get( ORIGIN_DISPLAY_ID ) ) pipDisplayTransferHandler = PipDisplayTransferHandler( Loading @@ -181,13 +193,16 @@ class PipDisplayTransferHandlerTest : ShellTestCase() { } @Test fun scheduleMovePipToDisplay_setsTransitionState() { fun scheduleMovePipToDisplay_setsDisplayAndTransitionStates() { pipDisplayTransferHandler.scheduleMovePipToDisplay( ORIGIN_DISPLAY_ID, TARGET_DISPLAY_ID, DESTINATION_BOUNDS ) verify(mockPipDisplayLayoutState).displayId = eq(TARGET_DISPLAY_ID) verify(mockPipDisplayLayoutState).displayLayout = eq(displayLayouts.get(TARGET_DISPLAY_ID))!! verify(mockPipBoundsAlgorithm).snapToMovementBoundsEdge( eq(DESTINATION_BOUNDS), eq(displayLayouts.get(TARGET_DISPLAY_ID)) Loading Loading @@ -480,5 +495,7 @@ class PipDisplayTransferHandlerTest : ShellTestCase() { val START_DRAG_COORDINATES = PointF(100f, 100f) val PIP_BOUNDS = Rect(0, 0, 700, 700) val DESTINATION_BOUNDS = Rect(100, 100, 800, 800) val MIN_SIZE = Point(100, 200) val MAX_SIZE = Point(300, 400) } } No newline at end of file Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipDisplayTransferHandler.java +39 −5 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static com.android.wm.shell.pip2.phone.PipTransition.PIP_DESTINATION_BOUN import android.annotation.Nullable; import android.app.TaskInfo; import android.content.Context; import android.graphics.Point; import android.graphics.Rect; import android.graphics.RectF; import android.os.Bundle; Loading Loading @@ -97,6 +98,10 @@ public class PipDisplayTransferHandler implements Rect boundsOnRelease) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "%s scheduleMovePipToDisplay from=%d to=%d", TAG, originDisplayId, targetDisplayId); mPipDisplayLayoutState.setDisplayId(targetDisplayId); mPipDisplayLayoutState.setDisplayLayout( mDisplayController.getDisplayLayout(targetDisplayId)); mPipBoundsState.updateMinMaxSize(mPipBoundsState.getAspectRatio()); // Set bounds to the bounds on drag release so that we can use this as the origin bounds // during animation to snap to the display's edge. Loading @@ -107,6 +112,7 @@ public class PipDisplayTransferHandler implements // is released and the display ID and layout are updated. mPipBoundsAlgorithm.snapToMovementBoundsEdge(boundsOnRelease, mDisplayController.getDisplayLayout(targetDisplayId)); snapBoundsWithinMinMaxSize(boundsOnRelease); Bundle extra = new Bundle(); extra.putInt(ORIGIN_DISPLAY_ID_KEY, originDisplayId); Loading @@ -116,6 +122,38 @@ public class PipDisplayTransferHandler implements mPipTransitionState.setState(PipTransitionState.SCHEDULED_BOUNDS_CHANGE, extra); } /** * Restricts {@param bounds} to the allowed min/max size constraints and snaps bounds to the * correct edge based on the snap fraction. */ private void snapBoundsWithinMinMaxSize(Rect bounds) { final float snapFraction = mPipBoundsAlgorithm.getSnapAlgorithm().getSnapFraction( bounds, mPipBoundsAlgorithm.getMovementBounds(bounds), mPipBoundsState.getStashedState()); final Point minSize = mPipBoundsState.getMinSize(); final Point maxSize = mPipBoundsState.getMaxSize(); int newWidth = bounds.width(); int newHeight = bounds.height(); if (bounds.width() < minSize.x || bounds.height() < minSize.y) { newWidth = minSize.x; newHeight = minSize.y; } else if (bounds.width() > maxSize.x || bounds.height() > maxSize.y) { newWidth = maxSize.x; newHeight = maxSize.y; } bounds.set(0, 0, newWidth, newHeight); mPipBoundsAlgorithm.getSnapAlgorithm().applySnapFraction(bounds, mPipBoundsAlgorithm.getMovementBounds(bounds), snapFraction, mPipBoundsState.getStashedState(), mPipBoundsState.getStashOffset(), mPipDisplayLayoutState.getDisplayBounds(), mPipDisplayLayoutState.getDisplayLayout().stableInsets()); } @Override public void onPipTransitionStateChanged(@PipTransitionState.TransitionState int oldState, @PipTransitionState.TransitionState int newState, @Nullable Bundle extra) { Loading Loading @@ -158,10 +196,6 @@ public class PipDisplayTransferHandler implements Trace.instant(Trace.TRACE_TAG_WINDOW_MANAGER, "PipDisplayTransferHandler#changingPipBounds"); mPipDisplayLayoutState.setDisplayId(mTargetDisplayId); mPipDisplayLayoutState.setDisplayLayout( mDisplayController.getDisplayLayout(mTargetDisplayId)); mPipSurfaceTransactionHelper.round(startTx, pipLeash, true).shadow(startTx, pipLeash, true /* applyShadowRadius */); // Set state to exiting and exited PiP to unregister input consumer on the current Loading @@ -177,7 +211,7 @@ public class PipDisplayTransferHandler implements final PipResizeAnimator animator = mPipResizeAnimatorSupplier.get(mContext, mPipSurfaceTransactionHelper, pipLeash, startTx, finishTx, mPipBoundsState.getBounds(), mPipBoundsState.getBounds(), pipBounds, pipBounds, mPipBoundsState.getBounds(), pipBounds, duration, 0); animator.setAnimationEndCallback(() -> { Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipDisplayTransferHandlerTest.kt +18 −1 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ import org.mockito.kotlin.whenever import org.mockito.kotlin.verify import android.content.res.Configuration import android.content.res.Resources import android.graphics.Point import android.graphics.PointF import android.graphics.Rect import android.os.Bundle Loading @@ -63,6 +64,7 @@ import com.android.wm.shell.common.DisplayLayout import com.android.wm.shell.common.MultiDisplayDragMoveBoundsCalculator import com.android.wm.shell.common.MultiDisplayTestUtil.TestDisplay import com.android.wm.shell.common.pip.PipBoundsAlgorithm import com.android.wm.shell.common.pip.PipSnapAlgorithm import com.android.wm.shell.pip2.animation.PipResizeAnimator import com.android.wm.shell.pip2.phone.PipTransitionState.EXITED_PIP import com.android.wm.shell.pip2.phone.PipTransitionState.EXITING_PIP Loading @@ -86,6 +88,7 @@ class PipDisplayTransferHandlerTest : ShellTestCase() { private val mockRootTaskDisplayAreaOrganizer = mock<RootTaskDisplayAreaOrganizer>() private val mockPipBoundsState = mock<PipBoundsState>() private val mockPipBoundsAlgorithm = mock<PipBoundsAlgorithm>() private val mockPipSnapAlgorithm = mock<PipSnapAlgorithm>() private val mockTaskInfo = mock<ActivityManager.RunningTaskInfo>() private val mockDisplayController = mock<DisplayController>() private val mockTransaction = mock<SurfaceControl.Transaction>() Loading Loading @@ -133,6 +136,10 @@ class PipDisplayTransferHandlerTest : ShellTestCase() { whenever(mockTransaction.show(any())).thenReturn(mockTransaction) whenever(mockFactory.transaction).thenReturn(mockTransaction) whenever(mockPipBoundsState.bounds).thenReturn(mockBounds) whenever(mockPipBoundsAlgorithm.snapAlgorithm).thenReturn(mockPipSnapAlgorithm) whenever(mockPipSnapAlgorithm.getSnapFraction(any(), any(), any())).thenReturn(0.5f) whenever(mockPipBoundsState.minSize).thenReturn(MIN_SIZE) whenever(mockPipBoundsState.maxSize).thenReturn(MAX_SIZE) whenever( mockSurfaceTransactionHelper.setPipTransformations( any(), Loading Loading @@ -165,6 +172,11 @@ class PipDisplayTransferHandlerTest : ShellTestCase() { whenever(mockDisplayController.getDisplayLayout(id)).thenReturn(displayLayout) whenever(mockDisplayController.isDisplayInTopology(id)).thenReturn(true) } whenever(mockPipDisplayLayoutState.displayLayout).thenReturn( displayLayouts.get( ORIGIN_DISPLAY_ID ) ) pipDisplayTransferHandler = PipDisplayTransferHandler( Loading @@ -181,13 +193,16 @@ class PipDisplayTransferHandlerTest : ShellTestCase() { } @Test fun scheduleMovePipToDisplay_setsTransitionState() { fun scheduleMovePipToDisplay_setsDisplayAndTransitionStates() { pipDisplayTransferHandler.scheduleMovePipToDisplay( ORIGIN_DISPLAY_ID, TARGET_DISPLAY_ID, DESTINATION_BOUNDS ) verify(mockPipDisplayLayoutState).displayId = eq(TARGET_DISPLAY_ID) verify(mockPipDisplayLayoutState).displayLayout = eq(displayLayouts.get(TARGET_DISPLAY_ID))!! verify(mockPipBoundsAlgorithm).snapToMovementBoundsEdge( eq(DESTINATION_BOUNDS), eq(displayLayouts.get(TARGET_DISPLAY_ID)) Loading Loading @@ -480,5 +495,7 @@ class PipDisplayTransferHandlerTest : ShellTestCase() { val START_DRAG_COORDINATES = PointF(100f, 100f) val PIP_BOUNDS = Rect(0, 0, 700, 700) val DESTINATION_BOUNDS = Rect(100, 100, 800, 800) val MIN_SIZE = Point(100, 200) val MAX_SIZE = Point(300, 400) } } No newline at end of file