summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java20
-rw-r--r--services/core/java/com/android/server/wm/ActivityStack.java12
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java2
-rw-r--r--services/core/java/com/android/server/wm/RemoteAnimationController.java5
-rw-r--r--services/core/java/com/android/server/wm/Task.java25
-rw-r--r--services/core/java/com/android/server/wm/WindowContainer.java12
-rw-r--r--services/core/java/com/android/server/wm/WindowStateAnimator.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java63
8 files changed, 121 insertions, 20 deletions
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index b156d1bd8886..b5a57a4adc86 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -555,7 +555,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
private RemoteAnimationDefinition mRemoteAnimationDefinition;
- private AnimatingActivityRegistry mAnimatingActivityRegistry;
+ AnimatingActivityRegistry mAnimatingActivityRegistry;
private Task mLastParent;
@@ -3089,7 +3089,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
ProtoLog.v(WM_DEBUG_APP_TRANSITIONS,
"Removing app %s delayed=%b animation=%s animating=%b", this, delayed,
- getAnimation(), isAnimating(TRANSITION));
+ getAnimation(), isAnimating(PARENTS | TRANSITION));
ProtoLog.v(WM_DEBUG_ADD_REMOVE, "removeAppToken: %s"
+ " delayed=%b Callers=%s", this, delayed, Debug.getCallers(4));
@@ -3101,7 +3101,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// If this window was animating, then we need to ensure that the app transition notifies
// that animations have completed in DisplayContent.handleAnimatingStoppedAndTransition(),
// so add to that list now
- if (isAnimating(TRANSITION)) {
+ if (isAnimating(PARENTS | TRANSITION)) {
getDisplayContent().mNoAnimationNotifyOnTransitionFinished.add(token);
}
@@ -3437,7 +3437,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
* color mode set to avoid jank in the middle of the transition.
*/
boolean canShowWindows() {
- return allDrawn && !(isAnimating() && hasNonDefaultColorWindow());
+ return allDrawn && !(isAnimating(PARENTS) && hasNonDefaultColorWindow());
}
/**
@@ -5345,13 +5345,13 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
if (!allDrawn && w.mightAffectAllDrawn()) {
if (DEBUG_VISIBILITY || WM_DEBUG_ORIENTATION.isLogToLogcat()) {
Slog.v(TAG, "Eval win " + w + ": isDrawn=" + w.isDrawnLw()
- + ", isAnimationSet=" + isAnimating(TRANSITION));
+ + ", isAnimationSet=" + isAnimating(PARENTS | TRANSITION));
if (!w.isDrawnLw()) {
Slog.v(TAG, "Not displayed: s=" + winAnimator.mSurfaceController
+ " pv=" + w.isVisibleByPolicy()
+ " mDrawState=" + winAnimator.drawStateToString()
+ " ph=" + w.isParentWindowHidden() + " th=" + mVisibleRequested
- + " a=" + isAnimating(TRANSITION));
+ + " a=" + isAnimating(PARENTS | TRANSITION));
}
}
@@ -5952,7 +5952,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
@Override
void prepareSurfaces() {
- final boolean show = isVisible() || isAnimating();
+ final boolean show = isVisible() || isAnimating(PARENTS);
if (mSurfaceControl != null) {
if (show && !mLastSurfaceShowing) {
@@ -5980,7 +5980,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
void attachThumbnailAnimation() {
- if (!isAnimating()) {
+ if (!isAnimating(PARENTS)) {
return;
}
final GraphicBuffer thumbnailHeader =
@@ -6000,7 +6000,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
* {@link android.app.ActivityOptions#ANIM_OPEN_CROSS_PROFILE_APPS} animation.
*/
void attachCrossProfileAppsThumbnailAnimation() {
- if (!isAnimating()) {
+ if (!isAnimating(PARENTS)) {
return;
}
clearThumbnail();
@@ -7512,7 +7512,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
super.dumpDebug(proto, WINDOW_TOKEN, logLevel);
proto.write(LAST_SURFACE_SHOWING, mLastSurfaceShowing);
proto.write(IS_WAITING_FOR_TRANSITION_START, isWaitingForTransitionStart());
- proto.write(IS_ANIMATING, isAnimating());
+ proto.write(IS_ANIMATING, isAnimating(PARENTS));
if (mThumbnail != null){
mThumbnail.dumpDebug(proto, THUMBNAIL);
}
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index ef34327597bc..b47c28455027 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -4889,6 +4889,18 @@ class ActivityStack extends WindowContainer<WindowContainer> implements BoundsAn
}
}
+ @Override
+ protected void onAnimationFinished() {
+ super.onAnimationFinished();
+ // TODO(b/142617871): we may need to add animation type parameter on onAnimationFinished to
+ // identify if the callback is for launch animation finish and then calling
+ // activity#onAnimationFinished.
+ final ActivityRecord activity = getTopMostActivity();
+ if (activity != null) {
+ activity.onAnimationFinished();
+ }
+ }
+
/**
* Sets the current picture-in-picture aspect ratio.
*/
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 67fe1491c48b..36f1de395ef6 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -3360,7 +3360,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
// to look at all windows below the current target that are in this app, finding the
// highest visible one in layering.
WindowState highestTarget = null;
- if (activity.isAnimating(TRANSITION)) {
+ if (activity.isAnimating(PARENTS | TRANSITION)) {
highestTarget = activity.getHighestAnimLayerWindow(curTarget);
}
diff --git a/services/core/java/com/android/server/wm/RemoteAnimationController.java b/services/core/java/com/android/server/wm/RemoteAnimationController.java
index 0b9be1acbf93..6f7eeabfc4cd 100644
--- a/services/core/java/com/android/server/wm/RemoteAnimationController.java
+++ b/services/core/java/com/android/server/wm/RemoteAnimationController.java
@@ -378,9 +378,10 @@ class RemoteAnimationController implements DeathRecipient {
int getMode() {
final DisplayContent dc = mWindowContainer.getDisplayContent();
- if (dc.mOpeningApps.contains(mWindowContainer)) {
+ final ActivityRecord topActivity = mWindowContainer.getTopMostActivity();
+ if (dc.mOpeningApps.contains(topActivity)) {
return RemoteAnimationTarget.MODE_OPENING;
- } else if (dc.mChangingApps.contains(mWindowContainer)) {
+ } else if (dc.mChangingApps.contains(topActivity)) {
return RemoteAnimationTarget.MODE_CHANGING;
} else {
return RemoteAnimationTarget.MODE_CLOSING;
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 914b95c1c04c..b4633184c969 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -94,6 +94,7 @@ import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN;
import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_BEFORE_ANIM;
import static java.lang.Integer.MAX_VALUE;
@@ -2555,6 +2556,16 @@ class Task extends WindowContainer<WindowContainer> {
return getAppAnimationLayer(ANIMATION_LAYER_HOME);
}
+ @Override
+ Rect getAnimationBounds(int appStackClipMode) {
+ // TODO(b/131661052): we should remove appStackClipMode with hierarchical animations.
+ if (appStackClipMode == STACK_CLIP_BEFORE_ANIM && getStack() != null) {
+ // Using the stack bounds here effectively applies the clipping before animation.
+ return getStack().getBounds();
+ }
+ return super.getAnimationBounds(appStackClipMode);
+ }
+
boolean shouldAnimate() {
// Don't animate while the task runs recents animation but only if we are in the mode
// where we cancel with deferred screenshot, which means that the controller has
@@ -2568,6 +2579,18 @@ class Task extends WindowContainer<WindowContainer> {
}
@Override
+ protected void onAnimationFinished() {
+ super.onAnimationFinished();
+ // TODO(b/142617871): we may need to add animation type parameter on onAnimationFinished to
+ // identify if the callback is for launch animation finish and then calling
+ // activity#onAnimationFinished.
+ final ActivityRecord activity = getTopMostActivity();
+ if (activity != null) {
+ activity.onAnimationFinished();
+ }
+ }
+
+ @Override
SurfaceControl.Builder makeSurface() {
return super.makeSurface().setMetadata(METADATA_TASK_ID, mTaskId);
}
@@ -2594,7 +2617,7 @@ class Task extends WindowContainer<WindowContainer> {
@Override
RemoteAnimationTarget createRemoteAnimationTarget(
RemoteAnimationController.RemoteAnimationRecord record) {
- final ActivityRecord activity = getTopVisibleActivity();
+ final ActivityRecord activity = getTopMostActivity();
return activity != null ? activity.createRemoteAnimationTarget(record) : null;
}
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 5daf56767fed..039cf5f8f352 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -777,7 +777,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
* otherwise.
*/
boolean isWaitingForTransitionStart() {
- return false;
+ return getActivity(app -> app.isWaitingForTransitionStart()) != null;
}
/**
@@ -785,7 +785,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
* {@code ActivityRecord#isAnimating(TRANSITION)}, {@code false} otherwise.
*/
boolean isAppTransitioning() {
- return getActivity(app -> app.isAnimating(TRANSITION)) != null;
+ return getActivity(app -> app.isAnimating(PARENTS | TRANSITION)) != null;
}
/**
@@ -1895,7 +1895,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
if (adapter != null) {
startAnimation(getPendingTransaction(), adapter, !isVisible());
if (adapter.getShowWallpaper()) {
- mDisplayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
+ getDisplayContent().pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
}
if (thumbnailAdapter != null) {
mThumbnail.startAnimation(
@@ -2040,7 +2040,8 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
}
boolean okToDisplay() {
- return mDisplayContent != null && mDisplayContent.okToDisplay();
+ final DisplayContent dc = getDisplayContent();
+ return dc != null && dc.okToDisplay();
}
boolean okToAnimate() {
@@ -2048,7 +2049,8 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
}
boolean okToAnimate(boolean ignoreFrozen) {
- return mDisplayContent != null && mDisplayContent.okToAnimate(ignoreFrozen);
+ final DisplayContent dc = getDisplayContent();
+ return dc != null && dc.okToAnimate(ignoreFrozen);
}
@Override
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 1a11766ac9a8..486616df6f11 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -1398,7 +1398,7 @@ class WindowStateAnimator {
mWin.getDisplayContent().adjustForImeIfNeeded();
}
- return mWin.isAnimating(TRANSITION | PARENTS);
+ return mWin.isAnimating(PARENTS);
}
void dumpDebug(ProtoOutputStream proto, long fieldId) {
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 248b06b26b6d..d3cd3cbb42ca 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.TRANSIT_TASK_OPEN;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyFloat;
@@ -49,7 +50,12 @@ import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.IBinder;
+import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
+import android.view.IRemoteAnimationFinishedCallback;
+import android.view.IRemoteAnimationRunner;
+import android.view.RemoteAnimationAdapter;
+import android.view.RemoteAnimationTarget;
import android.view.SurfaceControl;
import android.view.SurfaceSession;
@@ -782,6 +788,63 @@ public class WindowContainerTests extends WindowTestsBase {
assertEquals(newDc, activity.mDisplayContent);
}
+ @Test
+ public void testTaskCanApplyAnimation() {
+ final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent);
+ final Task task = createTaskInStack(stack, 0 /* userId */);
+ final ActivityRecord activity =
+ WindowTestUtils.createActivityRecordInTask(mDisplayContent, task);
+ verifyWindowContainerApplyAnimation(task, activity);
+ }
+
+ @Test
+ public void testStackCanApplyAnimation() {
+ final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent);
+ final ActivityRecord activity = WindowTestUtils.createActivityRecordInTask(mDisplayContent,
+ createTaskInStack(stack, 0 /* userId */));
+ verifyWindowContainerApplyAnimation(stack, activity);
+ }
+
+ private void verifyWindowContainerApplyAnimation(WindowContainer wc, ActivityRecord act) {
+ // Initial remote animation for app transition.
+ final RemoteAnimationAdapter adapter = new RemoteAnimationAdapter(
+ new IRemoteAnimationRunner.Stub() {
+ @Override
+ public void onAnimationStart(RemoteAnimationTarget[] apps,
+ RemoteAnimationTarget[] wallpapers,
+ IRemoteAnimationFinishedCallback finishedCallback) {
+ try {
+ finishedCallback.onAnimationFinished();
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void onAnimationCancelled() {
+ }
+ }, 0, 0, false);
+ adapter.setCallingPidUid(123, 456);
+ wc.getDisplayContent().prepareAppTransition(TRANSIT_TASK_OPEN, false);
+ wc.getDisplayContent().mAppTransition.overridePendingAppTransitionRemote(adapter);
+ spyOn(wc);
+ doReturn(true).when(wc).okToAnimate();
+
+ // Make sure animating state is as expected after applied animation.
+ assertTrue(wc.applyAnimation(null, TRANSIT_TASK_OPEN, true, false));
+ assertEquals(wc.getTopMostActivity(), act);
+ assertTrue(wc.isAnimating());
+ assertTrue(act.isAnimating(PARENTS));
+
+ // Make sure animation finish callback will be received and reset animating state after
+ // animation finish.
+ wc.getDisplayContent().mAppTransition.goodToGo(TRANSIT_TASK_OPEN, act,
+ mDisplayContent.mOpeningApps);
+ verify(wc).onAnimationFinished();
+ assertFalse(wc.isAnimating());
+ assertFalse(act.isAnimating(PARENTS));
+ }
+
/* Used so we can gain access to some protected members of the {@link WindowContainer} class */
private static class TestWindowContainer extends WindowContainer<TestWindowContainer> {
private final int mLayer;