Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ef890004 authored by Candice's avatar Candice
Browse files

fix(window magnification): call notifySourceBoundsChanged when the animation ends

In original design, we only call onSourceBoundsChanged after setting
geometry with the check of `calculateSourceBounds` returning
true(getting new source bounds) and animation is not animating. However,
since onAnimationUpdate will be called on animation 100%
(`calculateSourceBounds`=true, isAnimating=true) and the calling
`enableWindowMagnificationInternal` in onAnimationEnd has the same
source bounds as in animation 100% (`calculateSourceBounds`=false,
isAnimating=false), onSourceBoundsChanged never get called.
Therefore, we do the following change:
1. Create a new method `notifySourceBoundsChanged` for the
   process(sending onSourceBoundsChanged callback) we would like
   to go through when the source bounds change is finalized.
2. onSourceBoundsChanged is only called in following two cases: (1)
   In onAnimationEnd if the animation is applied to the window magnifier
   (2) After setGeometry if no animation is running.

Bug: 332010994
Test: atest AccessibilityMagnificationTest
      atest WindowMagnificationControllerTest
      atest WindowMagnificationControllerWindowlessMagnifierTest
      atest WindowMagnificationAnimationController
Flag: ACONFIG com.android.systemui.create_windowless_window_magnifier DEVELOPMENT
Change-Id: Icbb3d19c2db02050da071fbccf79dd0e65eda1a9
parent f1f87d88
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -72,6 +72,7 @@ class WindowMagnificationAnimationController implements ValueAnimator.AnimatorUp
    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 @@ class WindowMagnificationAnimationController implements ValueAnimator.AnimatorUp
            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 @@ class WindowMagnificationAnimationController implements ValueAnimator.AnimatorUp
    public void onAnimationRepeat(Animator animation) {
    }

    void setOnAnimationEndRunnable(Runnable runnable) {
        mOnAnimationEndRunnable = runnable;
    }

    private void sendAnimationCallback(boolean success) {
        if (mAnimationCallback != null) {
            try {
+10 −1
Original line number Diff line number Diff line
@@ -260,6 +260,11 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
        mContext = context;
        mHandler = handler;
        mAnimationController = animationController;
        mAnimationController.setOnAnimationEndRunnable(() -> {
            if (Flags.createWindowlessWindowMagnifier()) {
                notifySourceBoundsChanged();
            }
        });
        mAnimationController.setWindowMagnificationController(this);
        mWindowMagnifierCallback = callback;
        mSysUiState = sysUiState;
@@ -1051,11 +1056,15 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold

            // 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}.
+9 −13
Original line number Diff line number Diff line
@@ -477,9 +477,8 @@ public class WindowMagnificationAnimationControllerTest extends SysuiTestCase {
        });

        // 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 @@ public class WindowMagnificationAnimationControllerTest extends SysuiTestCase {
        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 @@ public class WindowMagnificationAnimationControllerTest extends SysuiTestCase {
        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 @@ public class WindowMagnificationAnimationControllerTest extends SysuiTestCase {
        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());
+3 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ import static org.mockito.Mockito.atLeastOnce;
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 @@ public class WindowMagnificationControllerWindowlessMagnifierTest extends SysuiT
        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 @@ public class WindowMagnificationControllerWindowlessMagnifierTest extends SysuiT
        final float centerX = sourceBoundsCaptor.getValue().exactCenterX();
        final float centerY = sourceBoundsCaptor.getValue().exactCenterY();

        reset(mWindowMagnifierCallback);
        mInstrumentation.runOnMainSync(() -> {
            mWindowMagnificationController.moveWindowMagnifierToPosition(
                    centerX + 10, centerY + 10, mAnimationCallback);