Merge "fix(window magnification): call notifySourceBoundsChanged when the animation ends" into main
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationAnimationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationAnimationController.java
index 7e96e48..615363d 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationAnimationController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationAnimationController.java
@@ -72,6 +72,7 @@
     private boolean mEndAnimationCanceled = false;
     @MagnificationState
     private int mState = STATE_DISABLED;
+    private Runnable mOnAnimationEndRunnable;
 
     WindowMagnificationAnimationController(@UiContext Context context) {
         this(context, newValueAnimator(context.getResources()));
@@ -303,12 +304,7 @@
             return;
         }
 
-        // If the animation is playing backwards, mStartSpec will be the final spec we would
-        // like to reach.
-        AnimationSpec spec = isReverse ? mStartSpec : mEndSpec;
-        mController.updateWindowMagnificationInternal(
-                spec.mScale, spec.mCenterX, spec.mCenterY,
-                mMagnificationFrameOffsetRatioX, mMagnificationFrameOffsetRatioY);
+        mOnAnimationEndRunnable.run();
 
         if (mState == STATE_DISABLING) {
             mController.deleteWindowMagnification();
@@ -333,6 +329,10 @@
     public void onAnimationRepeat(Animator animation) {
     }
 
+    void setOnAnimationEndRunnable(Runnable runnable) {
+        mOnAnimationEndRunnable = runnable;
+    }
+
     private void sendAnimationCallback(boolean success) {
         if (mAnimationCallback != null) {
             try {
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
index a847c3d..9837e36 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
@@ -260,6 +260,11 @@
         mContext = context;
         mHandler = handler;
         mAnimationController = animationController;
+        mAnimationController.setOnAnimationEndRunnable(() -> {
+            if (Flags.createWindowlessWindowMagnifier()) {
+                notifySourceBoundsChanged();
+            }
+        });
         mAnimationController.setWindowMagnificationController(this);
         mWindowMagnifierCallback = callback;
         mSysUiState = sysUiState;
@@ -1051,11 +1056,15 @@
 
             // Notify source bounds change when the magnifier is not animating.
             if (!mAnimationController.isAnimating()) {
-                mWindowMagnifierCallback.onSourceBoundsChanged(mDisplayId, mSourceBounds);
+                notifySourceBoundsChanged();
             }
         }
     }
 
+    private void notifySourceBoundsChanged() {
+        mWindowMagnifierCallback.onSourceBoundsChanged(mDisplayId, mSourceBounds);
+    }
+
     /**
      * Updates the position of {@link mSurfaceControlViewHost} and layout params of MirrorView based
      * on the position and size of {@link #mMagnificationFrame}.
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java
index e076420..44207a0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java
@@ -477,9 +477,8 @@
         });
 
         // Verify the method is called in
-        // {@link ValueAnimator.AnimatorUpdateListener#onAnimationUpdate} once and
-        // {@link Animator.AnimatorListener#onAnimationEnd} once in {@link ValueAnimator#end()}
-        verify(mSpyController, times(2)).updateWindowMagnificationInternal(
+        // {@link ValueAnimator.AnimatorUpdateListener#onAnimationUpdate} once
+        verify(mSpyController).updateWindowMagnificationInternal(
                 mScaleCaptor.capture(),
                 mCenterXCaptor.capture(), mCenterYCaptor.capture(),
                 mOffsetXCaptor.capture(), mOffsetYCaptor.capture());
@@ -594,10 +593,10 @@
         final float expectedY = (int) (windowBounds.exactCenterY() + expectedOffset
                 - defaultMagnificationWindowSize / 2);
 
-        // This is called 5 times when (1) first creating WindowlessMirrorWindow (2) SurfaceView is
+        // This is called 4 times when (1) first creating WindowlessMirrorWindow (2) SurfaceView is
         // created and we place the mirrored content as a child of the SurfaceView
-        // (3) the animation starts (4) the animation updates (5) the animation ends
-        verify(mTransaction, times(5))
+        // (3) the animation starts (4) the animation updates
+        verify(mTransaction, times(4))
                 .setPosition(any(SurfaceControl.class), eq(expectedX), eq(expectedY));
     }
 
@@ -788,9 +787,8 @@
         waitForIdleSync();
 
         // Verify the method is called in
-        // {@link ValueAnimator.AnimatorUpdateListener#onAnimationUpdate} once and
-        // {@link Animator.AnimatorListener#onAnimationEnd} once in {@link ValueAnimator#end()}
-        verify(mSpyController, times(2)).updateWindowMagnificationInternal(
+        // {@link ValueAnimator.AnimatorUpdateListener#onAnimationUpdate} once
+        verify(mSpyController).updateWindowMagnificationInternal(
                 mScaleCaptor.capture(),
                 mCenterXCaptor.capture(), mCenterYCaptor.capture(),
                 mOffsetXCaptor.capture(), mOffsetYCaptor.capture());
@@ -832,10 +830,8 @@
         deleteWindowMagnificationAndWaitAnimating(mWaitAnimationDuration, mAnimationCallback2);
 
         // Verify the method is called in
-        // {@link ValueAnimator.AnimatorUpdateListener#onAnimationUpdate} once and
-        // {@link Animator.AnimatorListener#onAnimationEnd} once when running the animation at
-        // the final duration time.
-        verify(mSpyController, times(2)).updateWindowMagnificationInternal(
+        // {@link ValueAnimator.AnimatorUpdateListener#onAnimationUpdate} once
+        verify(mSpyController).updateWindowMagnificationInternal(
                 mScaleCaptor.capture(),
                 mCenterXCaptor.capture(), mCenterYCaptor.capture(),
                 mOffsetXCaptor.capture(), mOffsetYCaptor.capture());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerWindowlessMagnifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerWindowlessMagnifierTest.java
index a88654b..01e4d58 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerWindowlessMagnifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerWindowlessMagnifierTest.java
@@ -46,6 +46,7 @@
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.timeout;
 import static org.mockito.Mockito.times;
@@ -459,6 +460,7 @@
         final float targetCenterX = sourceBoundsCaptor.getValue().exactCenterX() + 10;
         final float targetCenterY = sourceBoundsCaptor.getValue().exactCenterY() + 10;
 
+        reset(mWindowMagnifierCallback);
         mInstrumentation.runOnMainSync(() -> {
             mWindowMagnificationController.moveWindowMagnifierToPosition(
                     targetCenterX, targetCenterY, mAnimationCallback);
@@ -491,6 +493,7 @@
         final float centerX = sourceBoundsCaptor.getValue().exactCenterX();
         final float centerY = sourceBoundsCaptor.getValue().exactCenterY();
 
+        reset(mWindowMagnifierCallback);
         mInstrumentation.runOnMainSync(() -> {
             mWindowMagnificationController.moveWindowMagnifierToPosition(
                     centerX + 10, centerY + 10, mAnimationCallback);