From 76e0ddc0480687000d2ff43961d0a11ea192463d Mon Sep 17 00:00:00 2001 From: Chris Li Date: Mon, 20 Dec 2021 20:42:26 +0800 Subject: [PATCH] Set PIP corner radius after rotation When there is screen rotation, we need to set the corner radius and window crop in both start and finish transaction to avoid janky animation. Fix: 210965679 Test: atest WMShellFlickerTests:PipRotationTest Change-Id: I03d1c3c4e39ea55dd4cc3f43b1170cfd6fe88cfa --- .../wm/shell/pip/PipTaskOrganizer.java | 5 ++++- .../android/wm/shell/pip/PipTransition.java | 20 +++++++++++++++++++ .../transition/DefaultTransitionHandler.java | 7 +++++++ .../wm/shell/flicker/pip/PipRotationTest.kt | 4 ---- 4 files changed, 31 insertions(+), 5 deletions(-) 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 f0b2716f05d86..667d16636e6c1 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 @@ -882,7 +882,10 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, if (animator == null || !animator.isRunning() || animator.getTransitionDirection() != TRANSITION_DIRECTION_TO_PIP) { final boolean rotatingPip = mPipTransitionState.isInPip() && fromRotation; - if (rotatingPip && mWaitForFixedRotation && mHasFadeOut) { + if (rotatingPip && Transitions.ENABLE_SHELL_TRANSITIONS) { + // The animation and surface update will be handled by the shell transition handler. + mPipBoundsState.setBounds(destinationBoundsOut); + } else if (rotatingPip && mWaitForFixedRotation && mHasFadeOut) { // The position will be used by fade-in animation when the fixed rotation is done. mPipBoundsState.setBounds(destinationBoundsOut); } else if (rotatingPip) { 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 0c443ce511166..0fcfced2dcfc6 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 @@ -19,6 +19,7 @@ package com.android.wm.shell.pip; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.util.RotationUtils.deltaRotation; +import static android.view.WindowManager.TRANSIT_CHANGE; import static android.view.WindowManager.TRANSIT_OPEN; import static android.view.WindowManager.TRANSIT_PIP; import static android.window.TransitionInfo.FLAG_IS_WALLPAPER; @@ -154,6 +155,25 @@ public class PipTransition extends PipTransitionController { // We only support TRANSIT_PIP type (from RootWindowContainer) or TRANSIT_OPEN (from apps // that enter PiP instantly on opening, mostly from CTS/Flicker tests) if (info.getType() != TRANSIT_PIP && info.getType() != TRANSIT_OPEN) { + // In case the PIP window is part of rotation transition, reset the bounds and rounded + // corner. + for (int i = info.getChanges().size() - 1; i >= 0; --i) { + final TransitionInfo.Change change = info.getChanges().get(i); + if (change.getMode() == TRANSIT_CHANGE && change.getTaskInfo() != null + && change.getTaskInfo().configuration.windowConfiguration.getWindowingMode() + == WINDOWING_MODE_PINNED) { + final SurfaceControl leash = change.getLeash(); + final Rect destBounds = mPipBoundsState.getBounds(); + final boolean isInPip = mPipTransitionState.isInPip(); + mSurfaceTransactionHelper + .crop(startTransaction, leash, destBounds) + .round(startTransaction, leash, isInPip); + mSurfaceTransactionHelper + .crop(finishTransaction, leash, destBounds) + .round(finishTransaction, leash, isInPip); + break; + } + } return false; } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java index 324b8b53e4334..01343251f499d 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java @@ -23,6 +23,7 @@ import static android.app.ActivityOptions.ANIM_OPEN_CROSS_PROFILE_APPS; import static android.app.ActivityOptions.ANIM_SCALE_UP; import static android.app.ActivityOptions.ANIM_THUMBNAIL_SCALE_DOWN; import static android.app.ActivityOptions.ANIM_THUMBNAIL_SCALE_UP; +import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_JUMPCUT; import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_ROTATE; import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS; @@ -356,6 +357,12 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { continue; } + // There is no default animation for Pip window in rotation transition, and the + // PipTransition will update the surface of its own window at start/finish. + if (isTask && change.getTaskInfo().configuration.windowConfiguration + .getWindowingMode() == WINDOWING_MODE_PINNED) { + continue; + } // No default animation for this, so just update bounds/position. startTransaction.setPosition(change.getLeash(), change.getEndAbsBounds().left - info.getRootOffset().x, diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt index 59bbdfee13664..af984b3cb1010 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt @@ -27,12 +27,10 @@ import com.android.server.wm.flicker.annotation.Group4 import com.android.server.wm.flicker.dsl.FlickerBuilder import com.android.server.wm.flicker.entireScreenCovered import com.android.server.wm.flicker.helpers.WindowUtils -import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled import com.android.server.wm.flicker.helpers.setRotation import com.android.server.wm.flicker.navBarLayerRotatesAndScales import com.android.server.wm.flicker.statusBarLayerRotatesScales import com.android.wm.shell.flicker.helpers.FixedAppHelper -import org.junit.Assume.assumeFalse import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith @@ -121,8 +119,6 @@ class PipRotationTest(testSpec: FlickerTestParameter) : PipTransition(testSpec) @Presubmit @Test fun appLayerRotates_EndingBounds() { - // This CUJ don't work in shell transitions because of b/204570898 b/204562589 b/206753786 - assumeFalse(isShellTransitionsEnabled) testSpec.assertLayersEnd { visibleRegion(fixedApp.component).coversExactly(screenBoundsEnd) }