Loading services/core/java/com/android/server/wm/AppWindowToken.java +17 −5 Original line number Diff line number Diff line Loading @@ -79,6 +79,7 @@ import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL; 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; Loading Loading @@ -2473,6 +2474,17 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree 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) { Loading @@ -2493,9 +2505,11 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree 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); Loading Loading @@ -2529,8 +2543,6 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree 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); Loading services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java +27 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -34,6 +37,9 @@ import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentat 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; Loading Loading @@ -475,6 +481,27 @@ public class AppWindowTokenTests extends WindowTestsBase { 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); Loading Loading
services/core/java/com/android/server/wm/AppWindowToken.java +17 −5 Original line number Diff line number Diff line Loading @@ -79,6 +79,7 @@ import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL; 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; Loading Loading @@ -2473,6 +2474,17 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree 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) { Loading @@ -2493,9 +2505,11 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree 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); Loading Loading @@ -2529,8 +2543,6 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree 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); Loading
services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java +27 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -34,6 +37,9 @@ import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentat 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; Loading Loading @@ -475,6 +481,27 @@ public class AppWindowTokenTests extends WindowTestsBase { 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); Loading