diff options
| author | 2024-01-02 16:31:44 -0800 | |
|---|---|---|
| committer | 2024-01-08 16:54:59 -0800 | |
| commit | b8041b1b95d1663b6f7801f1b92ef7ec67ebada5 (patch) | |
| tree | 8e1dc888521b7d5a0debff7754e3f1b52bbc6bf0 | |
| parent | 1d00de07dd549e6ae6f7593afe491d64c1685385 (diff) | |
Use launcher app bounds to reset PiP icon overlay
Use PipTaskOrganizer#stopSwipePipToHome() to cache
the app bounds by launcher in Shell's PiP component.
These can later be used to properly calculate the overlay size
to reset its scale and offset properly in
PipTransition#onFinishResize().
This makes sure the icon overlay is properly set for cases such as
fixed rotation and swipe to PiP with pinned taskbar.
Also make sure the app bounds are correct
for button navigation enter pip flow by setting them in
PipTransition#startEnterAnimation().
Recording following repro steps with this fix applied:
http://recall/-/da2uuq57YtQRpR4N9NryZR
The bug report contains recording for before this fix.
Bug: 316993346
Test: manually enter PiP w/ fixed rotation at 90 and 270 deg
Test: manually enter PiP w/ pinned task bar on large screens
Change-Id: Iff392b6c8d6a3268e13e05d7cc0107218255e400
4 files changed, 41 insertions, 28 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPip.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPip.aidl index 3906599b7581..8b3de6298b2a 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPip.aidl +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPip.aidl @@ -52,9 +52,10 @@ interface IPip { * @param componentName ComponentName represents the Activity * @param destinationBounds the destination bounds the PiP window lands into * @param overlay an optional overlay to fade out after entering PiP + * @param appBounds the bounds used to set the buffer size of the optional content overlay */ oneway void stopSwipePipToHome(int taskId, in ComponentName componentName, - in Rect destinationBounds, in SurfaceControl overlay) = 2; + in Rect destinationBounds, in SurfaceControl overlay, in Rect appBounds) = 2; /** * Notifies the swiping Activity to PiP onto home transition is aborted diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java index 3635165d76ce..a9a3f788cb7e 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java @@ -334,6 +334,16 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, @Nullable SurfaceControl mPipOverlay; + /** + * The app bounds used for the buffer size of the + * {@link com.android.wm.shell.pip.PipContentOverlay.PipAppIconOverlay}. + * + * Note that this is empty if the overlay is removed or if it's some other type of overlay + * defined in {@link PipContentOverlay}. + */ + @NonNull + final Rect mAppBounds = new Rect(); + public PipTaskOrganizer(Context context, @NonNull SyncTransactionQueue syncTransactionQueue, @NonNull PipTransitionState pipTransitionState, @@ -464,15 +474,15 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, * Expect {@link #onTaskAppeared(ActivityManager.RunningTaskInfo, SurfaceControl)} afterwards. */ public void stopSwipePipToHome(int taskId, ComponentName componentName, Rect destinationBounds, - SurfaceControl overlay) { + SurfaceControl overlay, Rect appBounds) { ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "stopSwipePipToHome: %s, state=%s", componentName, mPipTransitionState); + "stopSwipePipToHome: %s, stat=%s", componentName, mPipTransitionState); // do nothing if there is no startSwipePipToHome being called before if (!mPipTransitionState.getInSwipePipToHomeTransition()) { return; } mPipBoundsState.setBounds(destinationBounds); - mPipOverlay = overlay; + setContentOverlay(overlay, appBounds); if (ENABLE_SHELL_TRANSITIONS && overlay != null) { // With Shell transition, the overlay was attached to the remote transition leash, which // will be removed when the current transition is finished, so we need to reparent it @@ -1888,7 +1898,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, "%s: trying to remove overlay (%s) which is not local reference (%s)", TAG, surface, mPipOverlay); } - mPipOverlay = null; + clearContentOverlay(); } if (mPipTransitionState.getTransitionState() == PipTransitionState.UNDEFINED) { // Avoid double removal, which is fatal. @@ -1905,6 +1915,20 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, if (callback != null) callback.run(); } + void clearContentOverlay() { + mPipOverlay = null; + mAppBounds.setEmpty(); + } + + void setContentOverlay(@Nullable SurfaceControl leash, @NonNull Rect appBounds) { + mPipOverlay = leash; + if (mPipOverlay != null) { + mAppBounds.set(appBounds); + } else { + mAppBounds.setEmpty(); + } + } + private void resetShadowRadius() { if (mPipTransitionState.getTransitionState() == PipTransitionState.UNDEFINED) { // mLeash is undefined when in PipTransitionState.UNDEFINED diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java index f5f15d81ea44..89dcc4c1d261 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java @@ -141,8 +141,6 @@ public class PipTransition extends PipTransitionController { /** Whether the PIP window has fade out for fixed rotation. */ private boolean mHasFadeOut; - private Rect mInitBounds = new Rect(); - /** Used for setting transform to a transaction from animator. */ private final PipAnimationController.PipTransactionHandler mTransactionConsumer = new PipAnimationController.PipTransactionHandler() { @@ -465,12 +463,13 @@ public class PipTransition extends PipTransitionController { mSurfaceTransactionHelper.crop(tx, leash, destinationBounds) .resetScale(tx, leash, destinationBounds) .round(tx, leash, true /* applyCornerRadius */); - if (mPipOrganizer.mPipOverlay != null && !mInitBounds.isEmpty()) { + final Rect appBounds = mPipOrganizer.mAppBounds; + if (mPipOrganizer.mPipOverlay != null && !appBounds.isEmpty()) { // Resetting the scale for pinned task while re-adjusting its crop, // also scales the overlay. So we need to update the overlay leash too. Rect overlayBounds = new Rect(destinationBounds); final int overlaySize = PipContentOverlay.PipAppIconOverlay - .getOverlaySize(mInitBounds, destinationBounds); + .getOverlaySize(appBounds, destinationBounds); overlayBounds.offsetTo( (destinationBounds.width() - overlaySize) / 2, @@ -479,7 +478,6 @@ public class PipTransition extends PipTransitionController { mPipOrganizer.mPipOverlay, overlayBounds); } } - mInitBounds.setEmpty(); wct.setBoundsChangeTransaction(taskInfo.token, tx); } final int displayRotation = taskInfo.getConfiguration().windowConfiguration @@ -617,7 +615,7 @@ public class PipTransition extends PipTransitionController { // if overlay is present remove it immediately, as exit transition came before it faded out if (mPipOrganizer.mPipOverlay != null) { startTransaction.remove(mPipOrganizer.mPipOverlay); - clearPipOverlay(); + mPipOrganizer.clearContentOverlay(); } if (pipChange == null) { ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, @@ -951,9 +949,6 @@ public class PipTransition extends PipTransitionController { final Rect destinationBounds = mPipBoundsAlgorithm.getEntryDestinationBounds(); final Rect currentBounds = pipChange.getStartAbsBounds(); - // Cache the start bounds for overlay manipulations as a part of finishCallback. - mInitBounds.set(currentBounds); - int rotationDelta = deltaRotation(startRotation, endRotation); Rect sourceHintRect = PipBoundsAlgorithm.getValidSourceHintRect( taskInfo.pictureInPictureParams, currentBounds, destinationBounds); @@ -1022,7 +1017,7 @@ public class PipTransition extends PipTransitionController { } else { throw new RuntimeException("Unrecognized animation type: " + enterAnimationType); } - mPipOrganizer.mPipOverlay = animator.getContentOverlayLeash(); + mPipOrganizer.setContentOverlay(animator.getContentOverlayLeash(), currentBounds); animator.setTransitionDirection(TRANSITION_DIRECTION_TO_PIP) .setPipAnimationCallback(mPipAnimationCallback) .setDuration(mEnterExitAnimationDuration); @@ -1073,10 +1068,6 @@ public class PipTransition extends PipTransitionController { ProtoLog.w(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "%s: SwipePipToHome should not use fixed rotation %d", TAG, mEndFixedRotation); } - Rect appBounds = pipTaskInfo.configuration.windowConfiguration.getAppBounds(); - if (mFixedRotationState == FIXED_ROTATION_CALLBACK && appBounds != null) { - mInitBounds.set(appBounds); - } final SurfaceControl swipePipToHomeOverlay = mPipOrganizer.mPipOverlay; if (swipePipToHomeOverlay != null) { // Launcher fade in the overlay on top of the fullscreen Task. It is possible we @@ -1106,7 +1097,7 @@ public class PipTransition extends PipTransitionController { sendOnPipTransitionFinished(TRANSITION_DIRECTION_TO_PIP); if (swipePipToHomeOverlay != null) { mPipOrganizer.fadeOutAndRemoveOverlay(swipePipToHomeOverlay, - this::clearPipOverlay /* callback */, false /* withStartDelay */); + null /* callback */, false /* withStartDelay */); } mPipTransitionState.setInSwipePipToHomeTransition(false); } @@ -1250,10 +1241,6 @@ public class PipTransition extends PipTransitionController { mPipMenuController.updateMenuBounds(destinationBounds); } - private void clearPipOverlay() { - mPipOrganizer.mPipOverlay = null; - } - @Override public void dump(PrintWriter pw, String prefix) { final String innerPrefix = prefix + " "; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java index 63f20fd8e997..238e6b5bf2af 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java @@ -982,8 +982,9 @@ public class PipController implements PipTransitionController.PipTransitionCallb } private void stopSwipePipToHome(int taskId, ComponentName componentName, Rect destinationBounds, - SurfaceControl overlay) { - mPipTaskOrganizer.stopSwipePipToHome(taskId, componentName, destinationBounds, overlay); + SurfaceControl overlay, Rect appBounds) { + mPipTaskOrganizer.stopSwipePipToHome(taskId, componentName, destinationBounds, overlay, + appBounds); } private void abortSwipePipToHome(int taskId, ComponentName componentName) { @@ -1280,13 +1281,13 @@ public class PipController implements PipTransitionController.PipTransitionCallb @Override public void stopSwipePipToHome(int taskId, ComponentName componentName, - Rect destinationBounds, SurfaceControl overlay) { + Rect destinationBounds, SurfaceControl overlay, Rect appBounds) { if (overlay != null) { overlay.setUnreleasedWarningCallSite("PipController.stopSwipePipToHome"); } executeRemoteCallWithTaskPermission(mController, "stopSwipePipToHome", (controller) -> controller.stopSwipePipToHome( - taskId, componentName, destinationBounds, overlay)); + taskId, componentName, destinationBounds, overlay, appBounds)); } @Override |