summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Jorim Jaggi <jjaggi@google.com> 2018-01-05 18:28:36 +0100
committer Jorim Jaggi <jjaggi@google.com> 2018-01-08 15:44:40 +0100
commitd6d971695647e742e24986be396524e8528d2f29 (patch)
treeeccf4704f524437068205819ad4613d0cc6ed4c7
parent8fb00b2c28eba84c88aa14d803c1a4687ec00fa6 (diff)
Make sure app transition are started simultaneously
Test: go/wm-smoke Test: Lock device in split screen, make sure everything is absolutely synchronized when unlocking Bug: 64674361 Change-Id: I25352d7a6b8beb9729310dd525710dca20a78166
-rw-r--r--services/core/java/com/android/server/wm/SurfaceAnimationRunner.java35
-rw-r--r--services/core/java/com/android/server/wm/WindowSurfacePlacer.java37
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java14
3 files changed, 69 insertions, 17 deletions
diff --git a/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java b/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java
index 3a41eb0e2afc..dc62cc89c14d 100644
--- a/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java
+++ b/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java
@@ -67,6 +67,9 @@ class SurfaceAnimationRunner {
@VisibleForTesting
final ArrayMap<SurfaceControl, RunningAnimation> mRunningAnimations = new ArrayMap<>();
+ @GuardedBy("mLock")
+ private boolean mAnimationStartDeferred;
+
SurfaceAnimationRunner() {
this(null /* callbackProvider */, null /* animatorFactory */, new Transaction());
}
@@ -86,13 +89,41 @@ class SurfaceAnimationRunner {
: SfValueAnimator::new;
}
+ /**
+ * Defers starting of animations until {@link #continueStartingAnimations} is called. This
+ * method is NOT nestable.
+ *
+ * @see #continueStartingAnimations
+ */
+ void deferStartingAnimations() {
+ synchronized (mLock) {
+ mAnimationStartDeferred = true;
+ }
+ }
+
+ /**
+ * Continues starting of animations.
+ *
+ * @see #deferStartingAnimations
+ */
+ void continueStartingAnimations() {
+ synchronized (mLock) {
+ mAnimationStartDeferred = false;
+ if (!mPendingAnimations.isEmpty()) {
+ mChoreographer.postFrameCallback(this::startAnimations);
+ }
+ }
+ }
+
void startAnimation(AnimationSpec a, SurfaceControl animationLeash, Transaction t,
Runnable finishCallback) {
synchronized (mLock) {
final RunningAnimation runningAnim = new RunningAnimation(a, animationLeash,
finishCallback);
mPendingAnimations.put(animationLeash, runningAnim);
- mChoreographer.postFrameCallback(this::stepAnimation);
+ if (!mAnimationStartDeferred) {
+ mChoreographer.postFrameCallback(this::startAnimations);
+ }
// Some animations (e.g. move animations) require the initial transform to be applied
// immediately.
@@ -185,7 +216,7 @@ class SurfaceAnimationRunner {
a.mAnimSpec.apply(t, a.mLeash, currentPlayTime);
}
- private void stepAnimation(long frameTimeNanos) {
+ private void startAnimations(long frameTimeNanos) {
synchronized (mLock) {
startPendingAnimationsLocked();
}
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index bdab9c765d36..08f49f689323 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -349,21 +349,28 @@ class WindowSurfacePlacer {
animLp = null;
}
- processApplicationsAnimatingInPlace(transit);
-
- mTmpLayerAndToken.token = null;
- handleClosingApps(transit, animLp, voiceInteraction, mTmpLayerAndToken);
- final AppWindowToken topClosingApp = mTmpLayerAndToken.token;
- final AppWindowToken topOpeningApp = handleOpeningApps(transit, animLp, voiceInteraction);
-
- mService.mAppTransition.setLastAppTransition(transit, topOpeningApp, topClosingApp);
-
- final int flags = mService.mAppTransition.getTransitFlags();
- int layoutRedo = mService.mAppTransition.goodToGo(transit, topOpeningApp,
- topClosingApp, mService.mOpeningApps, mService.mClosingApps);
- handleNonAppWindowsInTransition(transit, flags);
- mService.mAppTransition.postAnimationCallback();
- mService.mAppTransition.clear();
+ final int layoutRedo;
+ mService.mSurfaceAnimationRunner.deferStartingAnimations();
+ try {
+ processApplicationsAnimatingInPlace(transit);
+
+ mTmpLayerAndToken.token = null;
+ handleClosingApps(transit, animLp, voiceInteraction, mTmpLayerAndToken);
+ final AppWindowToken topClosingApp = mTmpLayerAndToken.token;
+ final AppWindowToken topOpeningApp = handleOpeningApps(transit, animLp,
+ voiceInteraction);
+
+ mService.mAppTransition.setLastAppTransition(transit, topOpeningApp, topClosingApp);
+
+ final int flags = mService.mAppTransition.getTransitFlags();
+ layoutRedo = mService.mAppTransition.goodToGo(transit, topOpeningApp,
+ topClosingApp, mService.mOpeningApps, mService.mClosingApps);
+ handleNonAppWindowsInTransition(transit, flags);
+ mService.mAppTransition.postAnimationCallback();
+ mService.mAppTransition.clear();
+ } finally {
+ mService.mSurfaceAnimationRunner.continueStartingAnimations();
+ }
mService.mTaskSnapshotController.onTransitionStarting();
diff --git a/services/tests/servicestests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java b/services/tests/servicestests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java
index 17fe6427f756..4831fcd67314 100644
--- a/services/tests/servicestests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java
@@ -162,6 +162,20 @@ public class SurfaceAnimationRunnerTest extends WindowTestsBase {
verify(mMockAnimationSpec, atLeastOnce()).apply(any(), any(), eq(0L));
}
+ @Test
+ public void testDeferStartingAnimations() throws Exception {
+ mSurfaceAnimationRunner.deferStartingAnimations();
+ mSurfaceAnimationRunner.startAnimation(createTranslateAnimation(), mMockSurface,
+ mMockTransaction, this::finishedCallback);
+ waitUntilNextFrame();
+ assertTrue(mSurfaceAnimationRunner.mRunningAnimations.isEmpty());
+ mSurfaceAnimationRunner.continueStartingAnimations();
+ waitUntilNextFrame();
+ assertFalse(mSurfaceAnimationRunner.mRunningAnimations.isEmpty());
+ mFinishCallbackLatch.await(1, SECONDS);
+ assertFinishCallbackCalled();
+ }
+
private void waitUntilNextFrame() throws Exception {
final CountDownLatch latch = new CountDownLatch(1);
mSurfaceAnimationRunner.mChoreographer.postCallback(Choreographer.CALLBACK_COMMIT,