summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Charles Chen <charlesccchen@google.com> 2024-10-30 20:30:04 +0800
committer Charles Chen <charlesccchen@google.com> 2024-11-11 03:25:00 +0000
commita37eec775e7347f079366efc9708cf5eb8ad7bc5 (patch)
tree5e6e73447eacd1e8bc49007cccb59eae3e1fc128
parent1fed1764a95d0c4ec8580a4daca836b169f3a90e (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
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java6
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java66
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());
+ }
}