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

Commit 568e0558 authored by Ryan Lin's avatar Ryan Lin Committed by Android (Google) Code Review
Browse files

Merge "Add callback for enabling/disabling window magnification"

parents cf259d52 6045db95
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.view.accessibility;

import android.graphics.PointF;
import android.graphics.Rect;
import android.os.RemoteCallback;
import android.view.accessibility.IWindowMagnificationConnectionCallback;

/**
@@ -37,8 +38,10 @@ oneway interface IWindowMagnificationConnection {
     *                or {@link Float#NaN} to leave unchanged.
     * @param centerY the screen-relative Y coordinate around which to center,
     *                or {@link Float#NaN} to leave unchanged.
     * @param endCallback The callback called when the animation is completed.
     */
    void enableWindowMagnification(int displayId, float scale, float centerX, float centerY);
    void enableWindowMagnification(int displayId, float scale, float centerX, float centerY,
        in RemoteCallback endCallback);

    /**
     * Sets the scale of the window magnifier on specified display.
@@ -52,8 +55,9 @@ oneway interface IWindowMagnificationConnection {
     * Disables window magnification on specified display with animation.
     *
     * @param displayId The logical display id.
     * @param endCallback The callback called when the animation is completed.
     */
    void disableWindowMagnification(int displayId);
    void disableWindowMagnification(int displayId, in RemoteCallback endCallback);

    /**
     * Moves the window magnifier on the specified display. It has no effect while animating.
+14 −8
Original line number Diff line number Diff line
@@ -18,11 +18,13 @@ package com.android.systemui.accessibility;

import android.annotation.MainThread;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.Handler;
import android.os.RemoteCallback;
import android.os.RemoteException;
import android.util.Log;
import android.view.SurfaceControl;
@@ -98,9 +100,11 @@ public class WindowMagnification extends SystemUI implements WindowMagnifierCall
    }

    @MainThread
    void enableWindowMagnification(int displayId, float scale, float centerX, float centerY) {
    void enableWindowMagnification(int displayId, float scale, float centerX, float centerY,
            @Nullable RemoteCallback endCallback) {
        //TODO: b/144080869 support multi-display.
        mWindowMagnificationAnimationController.enableWindowMagnification(scale, centerX, centerY);
        mWindowMagnificationAnimationController.enableWindowMagnification(scale, centerX, centerY,
                endCallback != null ? () -> endCallback.sendResult(null) : null);
    }

    @MainThread
@@ -116,9 +120,10 @@ public class WindowMagnification extends SystemUI implements WindowMagnifierCall
    }

    @MainThread
    void disableWindowMagnification(int displayId) {
    void disableWindowMagnification(int displayId, @Nullable RemoteCallback endCallback) {
        //TODO: b/144080869 support multi-display.
        mWindowMagnificationAnimationController.deleteWindowMagnification();
        mWindowMagnificationAnimationController.deleteWindowMagnification(
                endCallback != null ? () -> endCallback.sendResult(null) : null);
    }

    @Override
@@ -177,10 +182,10 @@ public class WindowMagnification extends SystemUI implements WindowMagnifierCall

        @Override
        public void enableWindowMagnification(int displayId, float scale, float centerX,
                float centerY) {
                float centerY, RemoteCallback remoteCallback) {
            mHandler.post(
                    () -> mWindowMagnification.enableWindowMagnification(displayId, scale, centerX,
                            centerY));
                            centerY, remoteCallback));
        }

        @Override
@@ -189,8 +194,9 @@ public class WindowMagnification extends SystemUI implements WindowMagnifierCall
        }

        @Override
        public void disableWindowMagnification(int displayId) {
            mHandler.post(() -> mWindowMagnification.disableWindowMagnification(displayId));
        public void disableWindowMagnification(int displayId, RemoteCallback remoteCallback) {
            mHandler.post(() -> mWindowMagnification.disableWindowMagnification(displayId,
                    remoteCallback));
        }

        @Override
+58 −22
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.systemui.accessibility;
import android.animation.Animator;
import android.animation.ValueAnimator;
import android.annotation.IntDef;
import android.annotation.Nullable;
import android.content.Context;
import android.content.res.Resources;
import android.util.Log;
@@ -58,7 +59,11 @@ class WindowMagnificationAnimationController implements ValueAnimator.AnimatorUp
    private final AnimationSpec mStartSpec = new AnimationSpec();
    private final AnimationSpec mEndSpec = new AnimationSpec();
    private final Context mContext;

    // Called when the animation is ended successfully without cancelling or mStartSpec and
    // mEndSpec are equal.
    private Runnable mAnimationEndCallback;
    // The flag to ignore the animation end callback.
    private boolean mEndAnimationCanceled = false;
    @MagnificationState
    private int mState = STATE_DISABLED;

@@ -83,26 +88,35 @@ class WindowMagnificationAnimationController implements ValueAnimator.AnimatorUp
     * from 1.0 and the center won't be changed during the animation. If {@link #mState} is
     * {@code STATE_DISABLING}, the animation runs in reverse.
     *
     * @param scale   the target scale, or {@link Float#NaN} to leave unchanged.
     * @param centerX the screen-relative X coordinate around which to center,
     * @param scale   The target scale, or {@link Float#NaN} to leave unchanged.
     * @param centerX The screen-relative X coordinate around which to center,
     *                or {@link Float#NaN} to leave unchanged.
     * @param centerY the screen-relative Y coordinate around which to center,
     * @param centerY The screen-relative Y coordinate around which to center,
     *                or {@link Float#NaN} to leave unchanged.
     * @param animationEndCallback Called when the transition is complete or the given arguments
     *                      are as same as current values.
     *
     * @see #onAnimationUpdate(ValueAnimator)
     */
    void enableWindowMagnification(float scale, float centerX, float centerY) {
        if (mState == STATE_ENABLING) {
            mValueAnimator.cancel();
        }
    void enableWindowMagnification(float scale, float centerX, float centerY,
            @Nullable Runnable animationEndCallback) {
        mAnimationEndCallback = animationEndCallback;
        setupEnableAnimationSpecs(scale, centerX, centerY);

        if (mEndSpec.equals(mStartSpec)) {
            if (mState == STATE_DISABLED) {
                mController.enableWindowMagnification(scale, centerX, centerY);
            } else if (mState == STATE_ENABLING || mState == STATE_DISABLING) {
                mValueAnimator.cancel();
            }
            sendCallbackIfNeeded();
            setState(STATE_ENABLED);
        } else {
            if (mState == STATE_DISABLING) {
                mValueAnimator.reverse();
            } else {
                if (mState == STATE_ENABLING) {
                    mValueAnimator.cancel();
                }
                mValueAnimator.start();
            }
            setState(STATE_ENABLING);
@@ -145,9 +159,16 @@ class WindowMagnificationAnimationController implements ValueAnimator.AnimatorUp
    /**
     * Wraps {@link WindowMagnificationController#deleteWindowMagnification()}} with transition
     * animation. If the window magnification is enabling, it runs the animation in reverse.
     *
     * @param animationEndCallback Called when the transition is complete or the window
     *                    magnification is disabled already.
     */
    void deleteWindowMagnification() {
    void deleteWindowMagnification(@Nullable Runnable animationEndCallback) {
        mAnimationEndCallback = animationEndCallback;
        if (mState == STATE_DISABLED || mState == STATE_DISABLING) {
            if (mState == STATE_DISABLED) {
                sendCallbackIfNeeded();
            }
            return;
        }
        mStartSpec.set(/* scale*/ 1.0f, Float.NaN, Float.NaN);
@@ -160,9 +181,9 @@ class WindowMagnificationAnimationController implements ValueAnimator.AnimatorUp
    /**
     * Wraps {@link WindowMagnificationController#moveWindowMagnifier(float, float)}. If the
     * animation is running, it has no effect.
     * @param offsetX the amount in pixels to offset the window magnifier in the X direction, in
     * @param offsetX The amount in pixels to offset the window magnifier in the X direction, in
     *                current screen pixels.
     * @param offsetY the amount in pixels to offset the window magnifier in the Y direction, in
     * @param offsetY The amount in pixels to offset the window magnifier in the Y direction, in
     *                current screen pixels.
     */
    void moveWindowMagnifier(float offsetX, float offsetY) {
@@ -185,28 +206,43 @@ class WindowMagnificationAnimationController implements ValueAnimator.AnimatorUp

    @Override
    public void onAnimationStart(Animator animation) {
        mEndAnimationCanceled = false;
    }

    @Override
    public void onAnimationEnd(Animator animation) {
        if (mState == STATE_DISABLING) {
    public void onAnimationEnd(Animator animation, boolean isReverse) {
        if (mEndAnimationCanceled) {
            return;
        }
        if (isReverse) {
            mController.deleteWindowMagnification();
            setState(STATE_DISABLED);
        } else if (mState == STATE_ENABLING) {
            setState(STATE_ENABLED);
        } else {
            Log.w(TAG, "onAnimationEnd unexpected state:" + mState);
            setState(STATE_ENABLED);
        }
        sendCallbackIfNeeded();
    }

    @Override
    public void onAnimationEnd(Animator animation) {
    }

    @Override
    public void onAnimationCancel(Animator animation) {
        mEndAnimationCanceled = true;
    }

    @Override
    public void onAnimationRepeat(Animator animation) {
    }

    private void sendCallbackIfNeeded() {
        if (mAnimationEndCallback != null) {
            mAnimationEndCallback.run();
            mAnimationEndCallback = null;
        }
    }

    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        final float fract = animation.getAnimatedFraction();
+20 −10
Original line number Diff line number Diff line
@@ -18,10 +18,12 @@ package com.android.systemui.accessibility;

import static org.junit.Assert.assertNotNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.verify;

import android.content.Context;
import android.os.RemoteCallback;
import android.os.RemoteException;
import android.provider.Settings;
import android.testing.AndroidTestingRunner;
@@ -39,6 +41,7 @@ import com.android.systemui.statusbar.CommandQueue;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

@@ -62,6 +65,9 @@ public class IWindowMagnificationConnectionTest extends SysuiTestCase {
    private WindowMagnificationAnimationController mWindowMagnificationAnimationController;
    @Mock
    private ModeSwitchesController mModeSwitchesController;
    @Mock
    private RemoteCallback mRemoteCallback;
    private ArgumentCaptor<Runnable> mRunnableCaptor = ArgumentCaptor.forClass(Runnable.class);
    private IWindowMagnificationConnection mIWindowMagnificationConnection;
    private WindowMagnification mWindowMagnification;

@@ -84,25 +90,24 @@ public class IWindowMagnificationConnectionTest extends SysuiTestCase {
    }

    @Test
    public void enableWindowMagnification() throws RemoteException {
    public void enableWindowMagnification_passThrough() throws RemoteException {
        mIWindowMagnificationConnection.enableWindowMagnification(TEST_DISPLAY, 3.0f, Float.NaN,
                Float.NaN);
                Float.NaN, mRemoteCallback);
        waitForIdleSync();

        verify(mWindowMagnificationAnimationController).enableWindowMagnification(3.0f, Float.NaN,
                Float.NaN);
        verify(mWindowMagnificationAnimationController).enableWindowMagnification(eq(3.0f),
                eq(Float.NaN), eq(Float.NaN), mRunnableCaptor.capture());
        verifyRunnableWrapsRemoteCallback(mRunnableCaptor.getValue());
    }

    @Test
    public void disableWindowMagnification_deleteWindowMagnification() throws RemoteException {
        mIWindowMagnificationConnection.enableWindowMagnification(TEST_DISPLAY, 3.0f, Float.NaN,
                Float.NaN);
        waitForIdleSync();

        mIWindowMagnificationConnection.disableWindowMagnification(TEST_DISPLAY);
        mIWindowMagnificationConnection.disableWindowMagnification(TEST_DISPLAY, mRemoteCallback);
        waitForIdleSync();

        verify(mWindowMagnificationAnimationController).deleteWindowMagnification();
        verify(mWindowMagnificationAnimationController).deleteWindowMagnification(
                mRunnableCaptor.capture());
        verifyRunnableWrapsRemoteCallback(mRunnableCaptor.getValue());
    }

    @Test
@@ -138,5 +143,10 @@ public class IWindowMagnificationConnectionTest extends SysuiTestCase {

        verify(mModeSwitchesController).removeButton(TEST_DISPLAY);
    }

    private void verifyRunnableWrapsRemoteCallback(Runnable runnable) {
        runnable.run();
        verify(mRemoteCallback).sendResult(null);
    }
}
+138 −31

File changed.

Preview size limit exceeded, changes collapsed.

Loading