summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java4
-rw-r--r--services/core/java/com/android/server/wm/SurfaceAnimator.java21
-rw-r--r--services/core/java/com/android/server/wm/WindowContainer.java43
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java4
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java4
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java32
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() {