Loading libs/WindowManager/Shell/src/com/android/wm/shell/common/MultiDisplayDragMoveBoundsCalculator.kt +2 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ object MultiDisplayDragMoveBoundsCalculator { * @param y The current y-coordinate of the drag pointer (in pixels). * @return A RectF object representing the calculated global DP bounds of the window. */ @JvmStatic fun calculateGlobalDpBoundsForDrag( startDisplayLayout: DisplayLayout, repositionStartPoint: PointF, Loading Loading @@ -73,6 +74,7 @@ object MultiDisplayDragMoveBoundsCalculator { * @param displayLayout The DisplayLayout representing the display to convert the bounds to. * @return A Rect object representing the local pixel bounds on the specified display. */ @JvmStatic fun convertGlobalDpToLocalPxForRect(rectDp: RectF, displayLayout: DisplayLayout): Rect { val leftTopPxDisplay = displayLayout.globalDpToLocalPx(rectDp.left, rectDp.top) val rightBottomPxDisplay = displayLayout.globalDpToLocalPx(rectDp.right, rectDp.bottom) Loading libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipDesktopState.kt +10 −0 Original line number Diff line number Diff line Loading @@ -54,6 +54,16 @@ class PipDesktopState( isDesktopWindowingPipEnabled() && DesktopExperienceFlags.ENABLE_CONNECTED_DISPLAYS_PIP.isTrue && Flags.enablePip2() /** * Returns whether dragging PiP in Connected Displays is enabled by checking the following: * - Dragging PiP in Connected Displays flag is enabled * - PiP in Connected Displays flag is enabled * - PiP2 flag is enabled */ fun isDraggingPipAcrossDisplaysEnabled(): Boolean = DesktopExperienceFlags.ENABLE_DRAGGING_PIP_ACROSS_DISPLAYS.isTrue && isConnectedDisplaysPipEnabled() /** Returns whether the display with the PiP task is in freeform windowing mode. */ private fun isDisplayInFreeform(): Boolean { val tdaInfo = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo( Loading libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java +15 −2 Original line number Diff line number Diff line Loading @@ -50,6 +50,7 @@ import com.android.wm.shell.desktopmode.DragToDesktopTransitionHandler; import com.android.wm.shell.pip2.PipSurfaceTransactionHelper; import com.android.wm.shell.pip2.phone.PhonePipMenuController; import com.android.wm.shell.pip2.phone.PipController; import com.android.wm.shell.pip2.phone.PipDisplayTransferHandler; import com.android.wm.shell.pip2.phone.PipInteractionHandler; import com.android.wm.shell.pip2.phone.PipMotionHelper; import com.android.wm.shell.pip2.phone.PipScheduler; Loading Loading @@ -198,12 +199,24 @@ public abstract class Pip2Module { FloatingContentCoordinator floatingContentCoordinator, PipUiEventLogger pipUiEventLogger, @ShellMainThread ShellExecutor mainExecutor, Optional<PipPerfHintController> pipPerfHintControllerOptional) { Optional<PipPerfHintController> pipPerfHintControllerOptional, PipDisplayTransferHandler pipDisplayTransferHandler) { return new PipTouchHandler(context, shellInit, shellCommandHandler, menuPhoneController, pipBoundsAlgorithm, pipBoundsState, pipTransitionState, pipScheduler, sizeSpecSource, pipDisplayLayoutState, pipDesktopState, displayController, pipMotionHelper, floatingContentCoordinator, pipUiEventLogger, mainExecutor, pipPerfHintControllerOptional); pipPerfHintControllerOptional, pipDisplayTransferHandler); } @WMSingleton @Provides static PipDisplayTransferHandler providePipDisplayTransferHandler(Context context, PipTransitionState pipTransitionState, PipScheduler pipScheduler, RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer, PipBoundsState pipBoundsState, DisplayController displayController ) { return new PipDisplayTransferHandler(context, pipTransitionState, pipScheduler, rootTaskDisplayAreaOrganizer, pipBoundsState, displayController); } @WMSingleton Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipDisplayTransferHandler.java +124 −10 Original line number Diff line number Diff line Loading @@ -15,14 +15,29 @@ */ package com.android.wm.shell.pip2.phone; import android.annotation.NonNull; 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; import android.util.ArrayMap; import android.view.SurfaceControl; 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; import com.android.wm.shell.common.MultiDisplayDragMoveBoundsCalculator; import com.android.wm.shell.common.pip.PipBoundsState; import com.android.wm.shell.pip2.PipSurfaceTransactionHelper; /** * Handler for moving PiP window to another display when the device is connected to external * display(s) in extended mode. Loading @@ -34,15 +49,31 @@ public class PipDisplayTransferHandler implements static final String ORIGIN_DISPLAY_ID_KEY = "origin_display_id"; static final String TARGET_DISPLAY_ID_KEY = "target_display_id"; @NonNull private final PipTransitionState mPipTransitionState; @NonNull private final PipScheduler mPipScheduler; private final PipBoundsState mPipBoundsState; private PipSurfaceTransactionHelper.SurfaceControlTransactionFactory mSurfaceControlTransactionFactory; private final RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer; private final PipSurfaceTransactionHelper mPipSurfaceTransactionHelper; private final DisplayController mDisplayController; private final PipTransitionState mPipTransitionState; private final PipScheduler mPipScheduler; @VisibleForTesting boolean mWaitingForDisplayTransfer; @VisibleForTesting ArrayMap<Integer, SurfaceControl> mOnDragMirrorPerDisplayId = new ArrayMap<>(); public PipDisplayTransferHandler(PipTransitionState pipTransitionState, PipScheduler pipScheduler) { public PipDisplayTransferHandler(Context context, PipTransitionState pipTransitionState, PipScheduler pipScheduler, RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer, PipBoundsState pipBoundsState, DisplayController displayController) { mPipTransitionState = pipTransitionState; mPipTransitionState.addPipTransitionStateChangedListener(this::onPipTransitionStateChanged); mPipTransitionState.addPipTransitionStateChangedListener(this); mPipScheduler = pipScheduler; mSurfaceControlTransactionFactory = new PipSurfaceTransactionHelper.VsyncSurfaceControlTransactionFactory(); mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer; mPipSurfaceTransactionHelper = new PipSurfaceTransactionHelper(context); mPipBoundsState = pipBoundsState; mDisplayController = displayController; } void scheduleMovePipToDisplay(int originDisplayId, int targetDisplayId) { Loading Loading @@ -72,8 +103,8 @@ public class PipDisplayTransferHandler implements break; } final SurfaceControl.Transaction startTx = extra.getParcelable( PipTransition.PIP_START_TX, SurfaceControl.Transaction.class); final Transaction startTx = extra.getParcelable( PipTransition.PIP_START_TX, Transaction.class); final Rect destinationBounds = extra.getParcelable( PipTransition.PIP_DESTINATION_BOUNDS, Rect.class); Loading @@ -81,11 +112,94 @@ public class PipDisplayTransferHandler implements } } private void startMoveToDisplayAnimation(SurfaceControl.Transaction startTx, Rect destinationBounds) { private void startMoveToDisplayAnimation(Transaction startTx, Rect destinationBounds) { if (startTx == null) return; startTx.apply(); mPipScheduler.scheduleFinishPipBoundsChange(destinationBounds); } /** * Show a drag indicator mirror on each connected display according to the current pointer * 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 */ 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 ); final Transaction transaction = mSurfaceControlTransactionFactory.getTransaction(); // Iterate through each connected display ID to ensure partial PiP bounds are shown on // all corresponding displays while dragging for (int displayId : mRootTaskDisplayAreaOrganizer.getDisplayIds()) { if (displayId == originDisplayId) continue; DisplayLayout displayLayout = mDisplayController.getDisplayLayout(displayId); if (displayLayout == null) continue; // If PiP does not cross the boundaries of a given display bounds, skip boolean shouldShowOnDisplay = RectF.intersects(globalDpPipBounds, displayLayout.globalBoundsDp()); if (!shouldShowOnDisplay) continue; // Create a mirror for the current display if it hasn't been created yet SurfaceControl mirror; if (!mOnDragMirrorPerDisplayId.containsKey(displayId)) { mirror = SurfaceControl.mirrorSurface(mPipTransitionState.getPinnedTaskLeash()); mOnDragMirrorPerDisplayId.put(displayId, mirror); } else { mirror = mOnDragMirrorPerDisplayId.get(displayId); } // Convert the PiP bounds in dp to px based on the current display layout final Rect boundsOnCurrentDisplay = MultiDisplayDragMoveBoundsCalculator.convertGlobalDpToLocalPxForRect( globalDpPipBounds, displayLayout); mPipScheduler.setPipTransformations(mirror, transaction, boundsOnCurrentDisplay, /* degrees= */ 0); mRootTaskDisplayAreaOrganizer.reparentToDisplayArea(displayId, mirror, transaction); transaction.show(mirror); } transaction.apply(); } /** * Remove all drag indicator mirrors from each connected display. */ // TODO(b/408981327): Remove mirrors on screen lock // TODO(b/408982524): Remove mirrors on opening app while dragging public void removeMirrors() { final Transaction transaction = mSurfaceControlTransactionFactory.getTransaction(); for (SurfaceControl mirror : mOnDragMirrorPerDisplayId.values()) { transaction.remove(mirror); } transaction.apply(); mOnDragMirrorPerDisplayId.clear(); } @VisibleForTesting void setSurfaceControlTransactionFactory( @NonNull PipSurfaceTransactionHelper.SurfaceControlTransactionFactory factory) { mSurfaceControlTransactionFactory = factory; } } libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java +17 −3 Original line number Diff line number Diff line Loading @@ -279,6 +279,20 @@ public class PipScheduler implements PipTransitionState.PipTransitionStateChange SurfaceControl leash = mPipTransitionState.getPinnedTaskLeash(); final SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction(); setPipTransformations(leash, tx, toBounds, degrees); tx.apply(); } /** * Sets PiP translational, scaling and rotational transformations on a given transaction. * * @param leash PiP leash to apply the transformations on * @param outTransaction transaction to set the matrix on * @param toBounds bounds to position the PiP to * @param degrees the angle to rotate the bounds to */ public void setPipTransformations(SurfaceControl leash, SurfaceControl.Transaction outTransaction, Rect toBounds, float degrees) { Matrix transformTensor = new Matrix(); final float[] mMatrixTmp = new float[9]; final float scale = (float) toBounds.width() / mPipBoundsState.getBounds().width(); Loading @@ -287,10 +301,10 @@ public class PipScheduler implements PipTransitionState.PipTransitionStateChange transformTensor.postTranslate(toBounds.left, toBounds.top); transformTensor.postRotate(degrees, toBounds.centerX(), toBounds.centerY()); mPipSurfaceTransactionHelper.round(tx, leash, mPipBoundsState.getBounds(), toBounds); mPipSurfaceTransactionHelper.round(outTransaction, leash, mPipBoundsState.getBounds(), toBounds); tx.setMatrix(leash, transformTensor, mMatrixTmp); tx.apply(); outTransaction.setMatrix(leash, transformTensor, mMatrixTmp); } void startOverlayFadeoutAnimation(@NonNull SurfaceControl overlayLeash, Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/common/MultiDisplayDragMoveBoundsCalculator.kt +2 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ object MultiDisplayDragMoveBoundsCalculator { * @param y The current y-coordinate of the drag pointer (in pixels). * @return A RectF object representing the calculated global DP bounds of the window. */ @JvmStatic fun calculateGlobalDpBoundsForDrag( startDisplayLayout: DisplayLayout, repositionStartPoint: PointF, Loading Loading @@ -73,6 +74,7 @@ object MultiDisplayDragMoveBoundsCalculator { * @param displayLayout The DisplayLayout representing the display to convert the bounds to. * @return A Rect object representing the local pixel bounds on the specified display. */ @JvmStatic fun convertGlobalDpToLocalPxForRect(rectDp: RectF, displayLayout: DisplayLayout): Rect { val leftTopPxDisplay = displayLayout.globalDpToLocalPx(rectDp.left, rectDp.top) val rightBottomPxDisplay = displayLayout.globalDpToLocalPx(rectDp.right, rectDp.bottom) Loading
libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipDesktopState.kt +10 −0 Original line number Diff line number Diff line Loading @@ -54,6 +54,16 @@ class PipDesktopState( isDesktopWindowingPipEnabled() && DesktopExperienceFlags.ENABLE_CONNECTED_DISPLAYS_PIP.isTrue && Flags.enablePip2() /** * Returns whether dragging PiP in Connected Displays is enabled by checking the following: * - Dragging PiP in Connected Displays flag is enabled * - PiP in Connected Displays flag is enabled * - PiP2 flag is enabled */ fun isDraggingPipAcrossDisplaysEnabled(): Boolean = DesktopExperienceFlags.ENABLE_DRAGGING_PIP_ACROSS_DISPLAYS.isTrue && isConnectedDisplaysPipEnabled() /** Returns whether the display with the PiP task is in freeform windowing mode. */ private fun isDisplayInFreeform(): Boolean { val tdaInfo = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo( Loading
libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java +15 −2 Original line number Diff line number Diff line Loading @@ -50,6 +50,7 @@ import com.android.wm.shell.desktopmode.DragToDesktopTransitionHandler; import com.android.wm.shell.pip2.PipSurfaceTransactionHelper; import com.android.wm.shell.pip2.phone.PhonePipMenuController; import com.android.wm.shell.pip2.phone.PipController; import com.android.wm.shell.pip2.phone.PipDisplayTransferHandler; import com.android.wm.shell.pip2.phone.PipInteractionHandler; import com.android.wm.shell.pip2.phone.PipMotionHelper; import com.android.wm.shell.pip2.phone.PipScheduler; Loading Loading @@ -198,12 +199,24 @@ public abstract class Pip2Module { FloatingContentCoordinator floatingContentCoordinator, PipUiEventLogger pipUiEventLogger, @ShellMainThread ShellExecutor mainExecutor, Optional<PipPerfHintController> pipPerfHintControllerOptional) { Optional<PipPerfHintController> pipPerfHintControllerOptional, PipDisplayTransferHandler pipDisplayTransferHandler) { return new PipTouchHandler(context, shellInit, shellCommandHandler, menuPhoneController, pipBoundsAlgorithm, pipBoundsState, pipTransitionState, pipScheduler, sizeSpecSource, pipDisplayLayoutState, pipDesktopState, displayController, pipMotionHelper, floatingContentCoordinator, pipUiEventLogger, mainExecutor, pipPerfHintControllerOptional); pipPerfHintControllerOptional, pipDisplayTransferHandler); } @WMSingleton @Provides static PipDisplayTransferHandler providePipDisplayTransferHandler(Context context, PipTransitionState pipTransitionState, PipScheduler pipScheduler, RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer, PipBoundsState pipBoundsState, DisplayController displayController ) { return new PipDisplayTransferHandler(context, pipTransitionState, pipScheduler, rootTaskDisplayAreaOrganizer, pipBoundsState, displayController); } @WMSingleton Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipDisplayTransferHandler.java +124 −10 Original line number Diff line number Diff line Loading @@ -15,14 +15,29 @@ */ package com.android.wm.shell.pip2.phone; import android.annotation.NonNull; 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; import android.util.ArrayMap; import android.view.SurfaceControl; 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; import com.android.wm.shell.common.MultiDisplayDragMoveBoundsCalculator; import com.android.wm.shell.common.pip.PipBoundsState; import com.android.wm.shell.pip2.PipSurfaceTransactionHelper; /** * Handler for moving PiP window to another display when the device is connected to external * display(s) in extended mode. Loading @@ -34,15 +49,31 @@ public class PipDisplayTransferHandler implements static final String ORIGIN_DISPLAY_ID_KEY = "origin_display_id"; static final String TARGET_DISPLAY_ID_KEY = "target_display_id"; @NonNull private final PipTransitionState mPipTransitionState; @NonNull private final PipScheduler mPipScheduler; private final PipBoundsState mPipBoundsState; private PipSurfaceTransactionHelper.SurfaceControlTransactionFactory mSurfaceControlTransactionFactory; private final RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer; private final PipSurfaceTransactionHelper mPipSurfaceTransactionHelper; private final DisplayController mDisplayController; private final PipTransitionState mPipTransitionState; private final PipScheduler mPipScheduler; @VisibleForTesting boolean mWaitingForDisplayTransfer; @VisibleForTesting ArrayMap<Integer, SurfaceControl> mOnDragMirrorPerDisplayId = new ArrayMap<>(); public PipDisplayTransferHandler(PipTransitionState pipTransitionState, PipScheduler pipScheduler) { public PipDisplayTransferHandler(Context context, PipTransitionState pipTransitionState, PipScheduler pipScheduler, RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer, PipBoundsState pipBoundsState, DisplayController displayController) { mPipTransitionState = pipTransitionState; mPipTransitionState.addPipTransitionStateChangedListener(this::onPipTransitionStateChanged); mPipTransitionState.addPipTransitionStateChangedListener(this); mPipScheduler = pipScheduler; mSurfaceControlTransactionFactory = new PipSurfaceTransactionHelper.VsyncSurfaceControlTransactionFactory(); mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer; mPipSurfaceTransactionHelper = new PipSurfaceTransactionHelper(context); mPipBoundsState = pipBoundsState; mDisplayController = displayController; } void scheduleMovePipToDisplay(int originDisplayId, int targetDisplayId) { Loading Loading @@ -72,8 +103,8 @@ public class PipDisplayTransferHandler implements break; } final SurfaceControl.Transaction startTx = extra.getParcelable( PipTransition.PIP_START_TX, SurfaceControl.Transaction.class); final Transaction startTx = extra.getParcelable( PipTransition.PIP_START_TX, Transaction.class); final Rect destinationBounds = extra.getParcelable( PipTransition.PIP_DESTINATION_BOUNDS, Rect.class); Loading @@ -81,11 +112,94 @@ public class PipDisplayTransferHandler implements } } private void startMoveToDisplayAnimation(SurfaceControl.Transaction startTx, Rect destinationBounds) { private void startMoveToDisplayAnimation(Transaction startTx, Rect destinationBounds) { if (startTx == null) return; startTx.apply(); mPipScheduler.scheduleFinishPipBoundsChange(destinationBounds); } /** * Show a drag indicator mirror on each connected display according to the current pointer * 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 */ 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 ); final Transaction transaction = mSurfaceControlTransactionFactory.getTransaction(); // Iterate through each connected display ID to ensure partial PiP bounds are shown on // all corresponding displays while dragging for (int displayId : mRootTaskDisplayAreaOrganizer.getDisplayIds()) { if (displayId == originDisplayId) continue; DisplayLayout displayLayout = mDisplayController.getDisplayLayout(displayId); if (displayLayout == null) continue; // If PiP does not cross the boundaries of a given display bounds, skip boolean shouldShowOnDisplay = RectF.intersects(globalDpPipBounds, displayLayout.globalBoundsDp()); if (!shouldShowOnDisplay) continue; // Create a mirror for the current display if it hasn't been created yet SurfaceControl mirror; if (!mOnDragMirrorPerDisplayId.containsKey(displayId)) { mirror = SurfaceControl.mirrorSurface(mPipTransitionState.getPinnedTaskLeash()); mOnDragMirrorPerDisplayId.put(displayId, mirror); } else { mirror = mOnDragMirrorPerDisplayId.get(displayId); } // Convert the PiP bounds in dp to px based on the current display layout final Rect boundsOnCurrentDisplay = MultiDisplayDragMoveBoundsCalculator.convertGlobalDpToLocalPxForRect( globalDpPipBounds, displayLayout); mPipScheduler.setPipTransformations(mirror, transaction, boundsOnCurrentDisplay, /* degrees= */ 0); mRootTaskDisplayAreaOrganizer.reparentToDisplayArea(displayId, mirror, transaction); transaction.show(mirror); } transaction.apply(); } /** * Remove all drag indicator mirrors from each connected display. */ // TODO(b/408981327): Remove mirrors on screen lock // TODO(b/408982524): Remove mirrors on opening app while dragging public void removeMirrors() { final Transaction transaction = mSurfaceControlTransactionFactory.getTransaction(); for (SurfaceControl mirror : mOnDragMirrorPerDisplayId.values()) { transaction.remove(mirror); } transaction.apply(); mOnDragMirrorPerDisplayId.clear(); } @VisibleForTesting void setSurfaceControlTransactionFactory( @NonNull PipSurfaceTransactionHelper.SurfaceControlTransactionFactory factory) { mSurfaceControlTransactionFactory = factory; } }
libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java +17 −3 Original line number Diff line number Diff line Loading @@ -279,6 +279,20 @@ public class PipScheduler implements PipTransitionState.PipTransitionStateChange SurfaceControl leash = mPipTransitionState.getPinnedTaskLeash(); final SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction(); setPipTransformations(leash, tx, toBounds, degrees); tx.apply(); } /** * Sets PiP translational, scaling and rotational transformations on a given transaction. * * @param leash PiP leash to apply the transformations on * @param outTransaction transaction to set the matrix on * @param toBounds bounds to position the PiP to * @param degrees the angle to rotate the bounds to */ public void setPipTransformations(SurfaceControl leash, SurfaceControl.Transaction outTransaction, Rect toBounds, float degrees) { Matrix transformTensor = new Matrix(); final float[] mMatrixTmp = new float[9]; final float scale = (float) toBounds.width() / mPipBoundsState.getBounds().width(); Loading @@ -287,10 +301,10 @@ public class PipScheduler implements PipTransitionState.PipTransitionStateChange transformTensor.postTranslate(toBounds.left, toBounds.top); transformTensor.postRotate(degrees, toBounds.centerX(), toBounds.centerY()); mPipSurfaceTransactionHelper.round(tx, leash, mPipBoundsState.getBounds(), toBounds); mPipSurfaceTransactionHelper.round(outTransaction, leash, mPipBoundsState.getBounds(), toBounds); tx.setMatrix(leash, transformTensor, mMatrixTmp); tx.apply(); outTransaction.setMatrix(leash, transformTensor, mMatrixTmp); } void startOverlayFadeoutAnimation(@NonNull SurfaceControl overlayLeash, Loading