Loading services/core/java/com/android/server/wm/ActivityRecord.java +3 −1 Original line number Diff line number Diff line Loading @@ -195,6 +195,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; Loading Loading @@ -5885,7 +5886,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) { Loading services/core/java/com/android/server/wm/SurfaceAnimator.java +16 −5 Original line number Diff line number Diff line Loading @@ -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. */ Loading Loading @@ -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. Loading services/core/java/com/android/server/wm/WindowContainer.java +36 −9 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -68,7 +69,6 @@ import android.util.Pools; import android.util.Slog; import android.util.proto.ProtoOutputStream; import android.view.DisplayInfo; import android.window.IWindowContainer; import android.view.MagnificationSpec; import android.view.RemoteAnimationDefinition; import android.view.RemoteAnimationTarget; Loading @@ -77,6 +77,7 @@ import android.view.SurfaceControl.Builder; import android.view.SurfaceSession; import android.view.WindowManager; import android.view.animation.Animation; import android.window.IWindowContainer; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ToBooleanFunction; Loading Loading @@ -782,7 +783,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. Loading @@ -792,12 +793,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()) { Loading @@ -805,14 +812,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; } } Loading @@ -820,6 +827,26 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< return false; } /** * 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. Loading services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java +3 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java +19 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,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; Loading Loading @@ -422,6 +423,23 @@ public class WindowContainerTests extends WindowTestsBase { assertFalse(child21.isAnimating(TRANSITION | CHILDREN)); } @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)); } @Test public void testIsVisible() { final TestWindowContainerBuilder builder = new TestWindowContainerBuilder(mWm); Loading Loading @@ -895,6 +913,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() { Loading Loading
services/core/java/com/android/server/wm/ActivityRecord.java +3 −1 Original line number Diff line number Diff line Loading @@ -195,6 +195,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; Loading Loading @@ -5885,7 +5886,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) { Loading
services/core/java/com/android/server/wm/SurfaceAnimator.java +16 −5 Original line number Diff line number Diff line Loading @@ -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. */ Loading Loading @@ -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. Loading
services/core/java/com/android/server/wm/WindowContainer.java +36 −9 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -68,7 +69,6 @@ import android.util.Pools; import android.util.Slog; import android.util.proto.ProtoOutputStream; import android.view.DisplayInfo; import android.window.IWindowContainer; import android.view.MagnificationSpec; import android.view.RemoteAnimationDefinition; import android.view.RemoteAnimationTarget; Loading @@ -77,6 +77,7 @@ import android.view.SurfaceControl.Builder; import android.view.SurfaceSession; import android.view.WindowManager; import android.view.animation.Animation; import android.window.IWindowContainer; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ToBooleanFunction; Loading Loading @@ -782,7 +783,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. Loading @@ -792,12 +793,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()) { Loading @@ -805,14 +812,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; } } Loading @@ -820,6 +827,26 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< return false; } /** * 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. Loading
services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java +3 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading
services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java +19 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,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; Loading Loading @@ -422,6 +423,23 @@ public class WindowContainerTests extends WindowTestsBase { assertFalse(child21.isAnimating(TRANSITION | CHILDREN)); } @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)); } @Test public void testIsVisible() { final TestWindowContainerBuilder builder = new TestWindowContainerBuilder(mWm); Loading Loading @@ -895,6 +913,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() { Loading