From f8a96ddcb8e37b3da4ce5027689db20e626220fd Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Mon, 16 Jul 2018 12:42:37 -0700 Subject: [PATCH] Fix race condition in BoundsAnimationController - The SfVsyncFrameCallbackProvider needs to be initialized with the associated handler thread's Choreographer instance. Bug: 111465953 Test: Take a systrace and ensure the animation is running on the right thread Change-Id: Ia70b09d391fd2d154e00d081cfcf0d2354e51db2 (cherry picked from commit 3749a052c9890b114a7286ce4961f3894d776c54) --- .../com/android/server/wm/BoundsAnimationController.java | 9 +++++++++ .../java/com/android/server/wm/WindowManagerService.java | 1 - 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/wm/BoundsAnimationController.java b/services/core/java/com/android/server/wm/BoundsAnimationController.java index b2a12bef52838..86f328d248db5 100644 --- a/services/core/java/com/android/server/wm/BoundsAnimationController.java +++ b/services/core/java/com/android/server/wm/BoundsAnimationController.java @@ -31,11 +31,13 @@ import android.os.IBinder; import android.os.Debug; import android.util.ArrayMap; import android.util.Slog; +import android.view.Choreographer; import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.graphics.SfVsyncFrameCallbackProvider; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -112,6 +114,7 @@ public class BoundsAnimationController { private final Interpolator mFastOutSlowInInterpolator; private boolean mFinishAnimationAfterTransition = false; private final AnimationHandler mAnimationHandler; + private Choreographer mChoreographer; private static final int WAIT_FOR_DRAW_TIMEOUT_MS = 3000; @@ -123,6 +126,12 @@ public class BoundsAnimationController { mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(context, com.android.internal.R.interpolator.fast_out_slow_in); mAnimationHandler = animationHandler; + if (animationHandler != null) { + // If an animation handler is provided, then ensure that it runs on the sf vsync tick + handler.runWithScissors(() -> mChoreographer = Choreographer.getSfInstance(), + 0 /* timeout */); + animationHandler.setProvider(new SfVsyncFrameCallbackProvider(mChoreographer)); + } } @VisibleForTesting diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 8bc224636c1ef..a4303bf19b6c3 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -1005,7 +1005,6 @@ public class WindowManagerService extends IWindowManager.Stub mAppTransition.registerListenerLocked(mActivityManagerAppTransitionNotifier); final AnimationHandler animationHandler = new AnimationHandler(); - animationHandler.setProvider(new SfVsyncFrameCallbackProvider()); mBoundsAnimationController = new BoundsAnimationController(context, mAppTransition, AnimationThread.getHandler(), animationHandler);