Ensure that we use SF Vsync Choreographer for the PiP transition.
- Move the bounds animation onto the animation thread
- Remove existing code referencing the old sf-vsync choreographer
- Add ability for ValueAnimator subclasses to reference a different
AnimationHandler, which uses a different FrameCallbackProvider with the
sf-vsync choreographer in the animations that require it
- Ensure that PiP touch events are batched and sent aligned with the
sf-vsync
- Move GC onto its own thread to not block other BackgroundThread calls
Bug: 36371375
Test: android.server.cts.ActivityManagerPinnedStackTests
Test: bit FrameworksServicesTests:com.android.server.wm.BoundsAnimationControllerTests
Test: go/wm-smoke
Change-Id: I6a41b35a4e4d4d6dbea82c2673452825fe3ffa58
diff --git a/services/core/java/com/android/server/wm/BoundsAnimationController.java b/services/core/java/com/android/server/wm/BoundsAnimationController.java
index 410efcd..7d13889 100644
--- a/services/core/java/com/android/server/wm/BoundsAnimationController.java
+++ b/services/core/java/com/android/server/wm/BoundsAnimationController.java
@@ -20,6 +20,8 @@
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+import android.animation.AnimationHandler;
+import android.animation.AnimationHandler.AnimationFrameCallbackProvider;
import android.animation.Animator;
import android.animation.ValueAnimator;
import android.annotation.IntDef;
@@ -30,11 +32,13 @@
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 android.view.WindowManagerInternal;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -49,7 +53,7 @@
*
* The object that is resized needs to implement {@link BoundsAnimationTarget} interface.
*
- * NOTE: All calls to methods in this class should be done on the UI thread
+ * NOTE: All calls to methods in this class should be done on the Animation thread
*/
public class BoundsAnimationController {
private static final boolean DEBUG_LOCAL = false;
@@ -111,20 +115,24 @@
private final AppTransitionNotifier mAppTransitionNotifier = new AppTransitionNotifier();
private final Interpolator mFastOutSlowInInterpolator;
private boolean mFinishAnimationAfterTransition = false;
+ private final AnimationHandler mAnimationHandler;
private static final int WAIT_FOR_DRAW_TIMEOUT_MS = 3000;
- BoundsAnimationController(Context context, AppTransition transition, Handler handler) {
+ BoundsAnimationController(Context context, AppTransition transition, Handler handler,
+ AnimationHandler animationHandler) {
mHandler = handler;
mAppTransition = transition;
mAppTransition.registerListenerLocked(mAppTransitionNotifier);
mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
com.android.internal.R.interpolator.fast_out_slow_in);
+ mAnimationHandler = animationHandler;
}
@VisibleForTesting
final class BoundsAnimator extends ValueAnimator
implements ValueAnimator.AnimatorUpdateListener, ValueAnimator.AnimatorListener {
+
private final BoundsAnimationTarget mTarget;
private final Rect mFrom = new Rect();
private final Rect mTo = new Rect();
@@ -350,6 +358,14 @@
public void onAnimationRepeat(Animator animation) {
// Do nothing
}
+
+ @Override
+ public AnimationHandler getAnimationHandler() {
+ if (mAnimationHandler != null) {
+ return mAnimationHandler;
+ }
+ return super.getAnimationHandler();
+ }
}
public void animateBounds(final BoundsAnimationTarget target, Rect from, Rect to,
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 768b03a..77e2f71 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -103,6 +103,7 @@
import android.Manifest;
import android.Manifest.permission;
+import android.animation.AnimationHandler;
import android.animation.ValueAnimator;
import android.annotation.IntDef;
import android.annotation.NonNull;
@@ -211,6 +212,7 @@
import com.android.internal.R;
import com.android.internal.app.IAssistScreenshotReceiver;
+import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
import com.android.internal.os.IResultReceiver;
import com.android.internal.policy.IKeyguardDismissCallback;
import com.android.internal.policy.IShortcutService;
@@ -1046,8 +1048,10 @@
mAppTransition = new AppTransition(context, this);
mAppTransition.registerListenerLocked(mActivityManagerAppTransitionNotifier);
+ final AnimationHandler animationHandler = new AnimationHandler();
+ animationHandler.setProvider(new SfVsyncFrameCallbackProvider());
mBoundsAnimationController = new BoundsAnimationController(context, mAppTransition,
- UiThread.getHandler());
+ AnimationThread.getHandler(), animationHandler);
mActivityManager = ActivityManager.getService();
mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
diff --git a/services/tests/servicestests/src/com/android/server/wm/BoundsAnimationControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/BoundsAnimationControllerTests.java
index ee09f4b..9d32496 100644
--- a/services/tests/servicestests/src/com/android/server/wm/BoundsAnimationControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/BoundsAnimationControllerTests.java
@@ -395,7 +395,7 @@
mMockAppTransition = new MockAppTransition(context);
mMockAnimator = new MockValueAnimator();
mTarget = new TestBoundsAnimationTarget();
- mController = new BoundsAnimationController(context, mMockAppTransition, handler);
+ mController = new BoundsAnimationController(context, mMockAppTransition, handler, null);
mDriver = new BoundsAnimationDriver(mController, mTarget);
}