diff options
6 files changed, 91 insertions, 17 deletions
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index a66741c90b1c..5ce63de87ee9 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -196,6 +196,7 @@ import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS_LIGHT; import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION; import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_STARTING_WINDOW; import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION; +import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_SCREEN_ROTATION; import static com.android.server.wm.TaskPersister.DEBUG; import static com.android.server.wm.TaskPersister.IMAGE_EXTENSION; import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN; @@ -5918,7 +5919,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A @Override void prepareSurfaces() { - final boolean show = isVisible() || isAnimating(PARENTS); + final boolean show = isVisible() || isAnimatingExcluding(PARENTS, + ANIMATION_TYPE_SCREEN_ROTATION); if (mSurfaceControl != null) { if (show && !mLastSurfaceShowing) { diff --git a/services/core/java/com/android/server/wm/SurfaceAnimator.java b/services/core/java/com/android/server/wm/SurfaceAnimator.java index 6358e4719fde..18e32c0683d6 100644 --- a/services/core/java/com/android/server/wm/SurfaceAnimator.java +++ b/services/core/java/com/android/server/wm/SurfaceAnimator.java @@ -202,6 +202,11 @@ class SurfaceAnimator { return mAnimation != null; } + @AnimationType + int getAnimationType() { + return mAnimationType; + } + /** * @return The current animation spec if we are running an animation, or {@code null} otherwise. */ @@ -453,32 +458,38 @@ class SurfaceAnimator { * Animation for screen rotation. * @hide */ - static final int ANIMATION_TYPE_SCREEN_ROTATION = 2; + static final int ANIMATION_TYPE_SCREEN_ROTATION = 1 << 1; /** * Animation for dimming. * @hide */ - static final int ANIMATION_TYPE_DIMMER = 3; + static final int ANIMATION_TYPE_DIMMER = 1 << 2; /** * Animation for recent apps. * @hide */ - static final int ANIMATION_TYPE_RECENTS = 4; + static final int ANIMATION_TYPE_RECENTS = 1 << 3; /** * Animation for a {@link WindowState} without animating the activity. * @hide */ - static final int ANIMATION_TYPE_WINDOW_ANIMATION = 5; + static final int ANIMATION_TYPE_WINDOW_ANIMATION = 1 << 4; /** * Animation to control insets. This is actually not an animation, but is used to give the * client a leash over the system window causing insets. * @hide */ - static final int ANIMATION_TYPE_INSETS_CONTROL = 6; + static final int ANIMATION_TYPE_INSETS_CONTROL = 1 << 5; + + /** + * Bitmask to include all animation types. This is NOT an {@link AnimationType} + * @hide + */ + static final int ANIMATION_TYPE_ALL = -1; /** * The type of the animation. diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index 037b9c830a50..37a0417fcf75 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -36,6 +36,7 @@ import static com.android.server.wm.IdentifierProto.USER_ID; import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS; import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS_ANIM; import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION; +import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_ALL; import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION; import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN; import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS; @@ -790,7 +791,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< * By default this predicate only checks if this container itself is actually running an * animation, but you can extend the check target over its relatives, or relax the condition * so that this can return {@code true} if an animation starts soon by giving a combination - * of {@link #AnimationFlags}. + * of {@link AnimationFlags}. * * Note that you can give a combination of bitmask flags to specify targets and condition for * checking animating status. @@ -800,12 +801,18 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< * * Note that TRANSITION propagates to parents and children as well. * - * {@see AnimationFlags#TRANSITION} - * {@see AnimationFlags#PARENTS} - * {@see AnimationFlags#CHILDREN} + * @param flags The combination of bitmask flags to specify targets and condition for + * checking animating status. + * @param typesToCheck The combination of bitmask {@link AnimationType} to compare when + * determining if animating. + * + * @see AnimationFlags#TRANSITION + * @see AnimationFlags#PARENTS + * @see AnimationFlags#CHILDREN */ - boolean isAnimating(int flags) { - if (mSurfaceAnimator.isAnimating()) { + boolean isAnimating(int flags, int typesToCheck) { + int animationType = mSurfaceAnimator.getAnimationType(); + if (mSurfaceAnimator.isAnimating() && (animationType & typesToCheck) > 0) { return true; } if ((flags & TRANSITION) != 0 && isWaitingForTransitionStart()) { @@ -813,14 +820,14 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< } if ((flags & PARENTS) != 0) { final WindowContainer parent = getParent(); - if (parent != null && parent.isAnimating(flags & ~CHILDREN)) { + if (parent != null && parent.isAnimating(flags & ~CHILDREN, typesToCheck)) { return true; } } if ((flags & CHILDREN) != 0) { for (int i = 0; i < mChildren.size(); ++i) { final WindowContainer wc = mChildren.get(i); - if (wc.isAnimating(flags & ~PARENTS)) { + if (wc.isAnimating(flags & ~PARENTS, typesToCheck)) { return true; } } @@ -829,6 +836,26 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< } /** + * Similar to {@link #isAnimating(int, int)} except provide a bitmask of + * {@link AnimationType} to exclude, rather than include + * @param flags The combination of bitmask flags to specify targets and condition for + * checking animating status. + * @param typesToExclude The combination of bitmask {@link AnimationType} to exclude when + * checking if animating. + */ + boolean isAnimatingExcluding(int flags, int typesToExclude) { + return isAnimating(flags, ANIMATION_TYPE_ALL & ~typesToExclude); + } + + /** + * @see #isAnimating(int, int) + * TODO (b/152333373): Migrate calls to use isAnimating with specified animation type + */ + boolean isAnimating(int flags) { + return isAnimating(flags, ANIMATION_TYPE_ALL); + } + + /** * @return {@code true} when the container is waiting the app transition start, {@code false} * otherwise. */ diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 9baa12602c7b..3ebc0f410fd7 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -4984,7 +4984,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } @Override - boolean isAnimating(int flags) { + boolean isAnimating(int flags, int typesToCheck) { // If we are an inset provider, all our animations are driven by the inset client, so we // aren't really animating. @@ -4992,7 +4992,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP if (mControllableInsetProvider != null) { return false; } - return super.isAnimating(flags); + return super.isAnimating(flags, typesToCheck); } void startAnimation(Animation anim) { diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java index d48e82723295..413ae134fe18 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java @@ -33,6 +33,8 @@ import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.clearInvocations; import android.app.WindowConfiguration; @@ -144,7 +146,7 @@ public class TaskStackTests extends WindowTestsBase { // Stack removal is deferred if one of its child is animating. doReturn(true).when(stack).hasWindowsAlive(); - doReturn(true).when(task).isAnimating(TRANSITION | CHILDREN); + doReturn(true).when(task).isAnimating(eq(TRANSITION | CHILDREN), anyInt()); stack.removeIfPossible(); // For the case of deferred removal the task controller will still be connected to the its diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java index 118c2e4db208..353c781c15ef 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java @@ -21,6 +21,7 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; +import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; import static android.view.WindowManager.TRANSIT_TASK_OPEN; import static com.android.dx.mockito.inline.extended.ExtendedMockito.any; @@ -35,6 +36,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.times; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION; +import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_SCREEN_ROTATION; import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN; import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS; import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION; @@ -423,6 +425,35 @@ public class WindowContainerTests extends WindowTestsBase { } @Test + public void testIsAnimating_typesToCheck() { + final TestWindowContainerBuilder builder = new TestWindowContainerBuilder(mWm); + final TestWindowContainer window = builder.setIsAnimating(true).setLayer(0).build(); + + assertTrue(window.isAnimating()); + assertFalse(window.isAnimating(0, ANIMATION_TYPE_SCREEN_ROTATION)); + assertTrue(window.isAnimating(0, ANIMATION_TYPE_APP_TRANSITION)); + assertFalse(window.isAnimatingExcluding(0, ANIMATION_TYPE_APP_TRANSITION)); + + final TestWindowContainer child = window.addChildWindow(); + assertFalse(child.isAnimating()); + assertTrue(child.isAnimating(PARENTS)); + assertTrue(child.isAnimating(PARENTS, ANIMATION_TYPE_APP_TRANSITION)); + assertFalse(child.isAnimating(PARENTS, ANIMATION_TYPE_SCREEN_ROTATION)); + + final WindowState windowState = createWindow(null /* parent */, TYPE_BASE_APPLICATION, + mDisplayContent, "TestWindowState"); + WindowContainer parent = windowState.getParent(); + spyOn(windowState.mSurfaceAnimator); + doReturn(true).when(windowState.mSurfaceAnimator).isAnimating(); + doReturn(ANIMATION_TYPE_APP_TRANSITION).when( + windowState.mSurfaceAnimator).getAnimationType(); + assertTrue(parent.isAnimating(CHILDREN)); + + windowState.setControllableInsetProvider(mock(InsetsSourceProvider.class)); + assertFalse(parent.isAnimating(CHILDREN)); + } + + @Test public void testIsVisible() { final TestWindowContainerBuilder builder = new TestWindowContainerBuilder(mWm); final TestWindowContainer root = builder.setLayer(0).build(); @@ -895,6 +926,7 @@ public class WindowContainerTests extends WindowTestsBase { mWaitForTransitStart = waitTransitStart; spyOn(mSurfaceAnimator); doReturn(mIsAnimating).when(mSurfaceAnimator).isAnimating(); + doReturn(ANIMATION_TYPE_APP_TRANSITION).when(mSurfaceAnimator).getAnimationType(); } TestWindowContainer getParentWindow() { |