diff options
| author | 2024-10-30 20:30:04 +0800 | |
|---|---|---|
| committer | 2024-11-11 03:25:00 +0000 | |
| commit | a37eec775e7347f079366efc9708cf5eb8ad7bc5 (patch) | |
| tree | 5e6e73447eacd1e8bc49007cccb59eae3e1fc128 | |
| parent | 1fed1764a95d0c4ec8580a4daca836b169f3a90e (diff) | |
Workaround for the case when task is letterboxed
There's a regression to make the task leash letterboxed in PIP animation
when enable_letterbox_translucent_activity is enabled even if the
activity matches parent.
This CL wordarounds to avoid overridding animation bounds if the task
is in size compat or letterboxed.
See b/376200414#comment6 to know how the transitions look like.
Bug: 376200414
Test: manual - 1. make activity to PIP mode
2. rotate the device
3. restore the activity from PIP
Test: atest PipAnimationControllerTest -j
Flag: com.android.window.flags.better_support_non_match_parent_activity
Change-Id: I92f1bca121a574c07cdd4c1ebdf4b0e474a90c40
2 files changed, 71 insertions, 1 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java index 4d5dc6da6ee5..5276d9d6a4df 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java @@ -27,6 +27,7 @@ import android.animation.RectEvaluator; import android.animation.ValueAnimator; import android.annotation.IntDef; import android.annotation.NonNull; +import android.app.AppCompatTaskInfo; import android.app.TaskInfo; import android.content.Context; import android.content.pm.ActivityInfo; @@ -593,10 +594,13 @@ public class PipAnimationController { // insets to calculate the window crop final Rect initialSourceValue; final Rect mainWindowFrame = taskInfo.topActivityMainWindowFrame; + final AppCompatTaskInfo compatInfo = taskInfo.appCompatTaskInfo; + final boolean isSizeCompatOrLetterboxed = compatInfo.isTopActivityInSizeCompat() + || compatInfo.isTopActivityLetterboxed(); // For the animation to swipe PIP to home or restore a PIP task from home, we don't // override to the main window frame since we should animate the whole task. final boolean shouldUseMainWindowFrame = mainWindowFrame != null - && !alwaysAnimateTaskBounds; + && !alwaysAnimateTaskBounds && !isSizeCompatOrLetterboxed; final boolean changeOrientation = rotationDelta == ROTATION_90 || rotationDelta == ROTATION_270; final Rect baseBounds = new Rect(baseValue); diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java index 4dca595b97c5..6d37ed766aef 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java @@ -28,8 +28,11 @@ import static com.android.wm.shell.pip.PipAnimationController.TRANSITION_DIRECTI import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; +import android.app.AppCompatTaskInfo; import android.app.TaskInfo; import android.graphics.Rect; import android.testing.AndroidTestingRunner; @@ -75,6 +78,7 @@ public class PipAnimationControllerTest extends ShellTestCase { .setContainerLayer() .setName("FakeLeash") .build(); + mTaskInfo.appCompatTaskInfo = mock(AppCompatTaskInfo.class); } @Test @@ -305,4 +309,66 @@ public class PipAnimationControllerTest extends ShellTestCase { assertEquals("Expect end value is not overridden for leave-PIP transition", endValue, animator.getEndValue()); } + + @Test + public void pipTransitionAnimator_letterboxed_animateTaskBounds() { + final Rect baseValue = new Rect(0, 0, 100, 100); + final Rect startValue = new Rect(0, 0, 100, 100); + final Rect endValue = new Rect(100, 100, 200, 200); + mTaskInfo.topActivityMainWindowFrame = new Rect(0, 50, 100, 100); + doReturn(true).when(mTaskInfo.appCompatTaskInfo).isTopActivityLetterboxed(); + PipAnimationController.PipTransitionAnimator<?> animator = mPipAnimationController + .getAnimator(mTaskInfo, mLeash, baseValue, startValue, endValue, null, + TRANSITION_DIRECTION_TO_PIP, 0, ROTATION_0, + false /* alwaysAnimateTaskBounds */); + + assertEquals("Expect base value is not overridden for in-PIP transition", + baseValue, animator.getBaseValue()); + assertEquals("Expect start value is not overridden for in-PIP transition", + startValue, animator.getStartValue()); + assertEquals("Expect end value is not overridden for in-PIP transition", + endValue, animator.getEndValue()); + + animator = mPipAnimationController.getAnimator(mTaskInfo, mLeash, baseValue, startValue, + endValue, null, TRANSITION_DIRECTION_LEAVE_PIP, 0, ROTATION_0, + false /* alwaysAnimateTaskBounds */); + + assertEquals("Expect base value is not overridden for leave-PIP transition", + baseValue, animator.getBaseValue()); + assertEquals("Expect start value is not overridden for leave-PIP transition", + startValue, animator.getStartValue()); + assertEquals("Expect end value is not overridden for leave-PIP transition", + endValue, animator.getEndValue()); + } + + @Test + public void pipTransitionAnimator_sizeCompat_animateTaskBounds() { + final Rect baseValue = new Rect(0, 0, 100, 100); + final Rect startValue = new Rect(0, 0, 100, 100); + final Rect endValue = new Rect(100, 100, 200, 200); + mTaskInfo.topActivityMainWindowFrame = new Rect(0, 50, 100, 100); + doReturn(true).when(mTaskInfo.appCompatTaskInfo).isTopActivityInSizeCompat(); + PipAnimationController.PipTransitionAnimator<?> animator = mPipAnimationController + .getAnimator(mTaskInfo, mLeash, baseValue, startValue, endValue, null, + TRANSITION_DIRECTION_TO_PIP, 0, ROTATION_0, + false /* alwaysAnimateTaskBounds */); + + assertEquals("Expect base value is not overridden for in-PIP transition", + baseValue, animator.getBaseValue()); + assertEquals("Expect start value is not overridden for in-PIP transition", + startValue, animator.getStartValue()); + assertEquals("Expect end value is not overridden for in-PIP transition", + endValue, animator.getEndValue()); + + animator = mPipAnimationController.getAnimator(mTaskInfo, mLeash, baseValue, startValue, + endValue, null, TRANSITION_DIRECTION_LEAVE_PIP, 0, ROTATION_0, + false /* alwaysAnimateTaskBounds */); + + assertEquals("Expect base value is not overridden for leave-PIP transition", + baseValue, animator.getBaseValue()); + assertEquals("Expect start value is not overridden for leave-PIP transition", + startValue, animator.getStartValue()); + assertEquals("Expect end value is not overridden for leave-PIP transition", + endValue, animator.getEndValue()); + } } |