Use stack bounds to apply STACK_CLIP_BEFORE_ANIM
Clips the stack before the animation. Added back the
getAnimationBounds helper for testing.
Bug: 130651371
Test: atest AppWindowTokenTests#testTransitionAnimationBounds
Change-Id: Ibd0882ab790031585598efb2be64423da233228a
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index a53f85d..d4a4170 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -21,8 +21,6 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.content.pm.ActivityInfo.COLOR_MODE_DEFAULT;
-import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
-import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
@@ -81,6 +79,7 @@
import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
import static com.android.server.wm.WindowManagerService.logWithStack;
import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_AFTER_ANIM;
+import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_BEFORE_ANIM;
import android.annotation.CallSuper;
import android.annotation.Size;
@@ -2475,6 +2474,17 @@
return getBounds();
}
+ @VisibleForTesting
+ Rect getAnimationBounds(int appStackClipMode) {
+ if (appStackClipMode == STACK_CLIP_BEFORE_ANIM && getStack() != null) {
+ // Using the stack bounds here effectively applies the clipping before animation.
+ return getStack().getBounds();
+ }
+ // Use task-bounds if available so that activity-level letterbox (maxAspectRatio) is
+ // included in the animation.
+ return getTask() != null ? getTask().getBounds() : getBounds();
+ }
+
boolean applyAnimationLocked(WindowManager.LayoutParams lp, int transit, boolean enter,
boolean isVoiceInteraction) {
@@ -2495,9 +2505,11 @@
final AnimationAdapter adapter;
AnimationAdapter thumbnailAdapter = null;
- // Separate position and size for use in animators. Use task-bounds for now so
- // that activity-level letterbox (maxAspectRatio) is included in the animation.
- mTmpRect.set(getTask() != null ? getTask().getBounds() : getBounds());
+ final int appStackClipMode =
+ getDisplayContent().mAppTransition.getAppStackClipMode();
+
+ // Separate position and size for use in animators.
+ mTmpRect.set(getAnimationBounds(appStackClipMode));
mTmpPoint.set(mTmpRect.left, mTmpRect.top);
mTmpRect.offsetTo(0, 0);
@@ -2531,8 +2543,6 @@
mTransit = transit;
mTransitFlags = getDisplayContent().mAppTransition.getTransitFlags();
} else {
- final int appStackClipMode =
- getDisplayContent().mAppTransition.getAppStackClipMode();
mNeedsAnimationBoundsLayer = (appStackClipMode == STACK_CLIP_AFTER_ANIM);
final Animation a = loadAnimation(lp, transit, enter, isVoiceInteraction);
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
index ca3f684..064b553 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
@@ -16,6 +16,9 @@
package com.android.server.wm;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
@@ -34,6 +37,9 @@
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
+import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_AFTER_ANIM;
+import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_BEFORE_ANIM;
+import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_NONE;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -475,6 +481,27 @@
assertHasStartingWindow(tokenBottom);
}
+ @Test
+ public void testTransitionAnimationBounds() {
+ final Rect stackBounds = new Rect(0, 0, 1000, 600);
+ final Rect taskBounds = new Rect(100, 400, 600, 800);
+ mStack.setBounds(stackBounds);
+ mTask.setBounds(taskBounds);
+
+ // Check that anim bounds for freeform window match task bounds
+ mTask.setWindowingMode(WINDOWING_MODE_FREEFORM);
+ assertEquals(taskBounds, mToken.getAnimationBounds(STACK_CLIP_NONE));
+
+ // STACK_CLIP_AFTER_ANIM should use task bounds since they will be clipped by
+ // bounds animation layer.
+ mTask.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+ assertEquals(taskBounds, mToken.getAnimationBounds(STACK_CLIP_AFTER_ANIM));
+
+ // STACK_CLIP_BEFORE_ANIM should use stack bounds since it won't be clipped later.
+ mTask.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
+ assertEquals(stackBounds, mToken.getAnimationBounds(STACK_CLIP_BEFORE_ANIM));
+ }
+
private void assertHasStartingWindow(AppWindowToken atoken) {
assertNotNull(atoken.startingSurface);
assertNotNull(atoken.startingData);