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

Commit 58ec92d1 authored by mincheli's avatar mincheli Committed by Minche Li
Browse files

Resets the window magnifier after the a11y service is unbinded

After the service connection is ubineded or the binder died,
a11y framework should reset all the magnifiers that had been
controlled by the service connection.
Now the framework should also support reseting the
window magnfiers that had been controlled by the service.

Bug: 203532041
Test: atest AccessibilityMagnificationTest,
  atest AccessibilityServiceConnectionTest,
  atest MagnificationProcessorTest,
  atest MagnificationControllerTest,
  atest WindowMagnificationManagerTest,
Change-Id: I605a2cb17e3fb6677b9da0715ca7d7a84af70295
parent 4c9a0a0d
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -193,6 +193,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub

    private static final int OWN_PROCESS_ID = android.os.Process.myPid();

    public static final int INVALID_SERVICE_ID = -1;

    // Each service has an ID. Also provide one for magnification gesture handling
    public static final int MAGNIFICATION_GESTURE_HANDLER_ID = 0;

+7 −6
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@ package com.android.server.accessibility.magnification;
import static android.accessibilityservice.AccessibilityTrace.FLAGS_WINDOW_MANAGER_INTERNAL;
import static android.view.accessibility.MagnificationAnimationCallback.STUB_ANIMATION_CALLBACK;

import static com.android.server.accessibility.AccessibilityManagerService.INVALID_SERVICE_ID;

import android.animation.Animator;
import android.animation.ValueAnimator;
import android.annotation.NonNull;
@@ -117,8 +119,7 @@ public class FullScreenMagnificationController implements

        private final int mDisplayId;

        private static final int INVALID_ID = -1;
        private int mIdOfLastServiceToMagnify = INVALID_ID;
        private int mIdOfLastServiceToMagnify = INVALID_SERVICE_ID;
        private boolean mMagnificationActivated = false;

        DisplayMagnification(int displayId) {
@@ -425,7 +426,7 @@ public class FullScreenMagnificationController implements
                }

                final float scale = getScale();
                offsetMagnifiedRegion(scrollX * scale, scrollY * scale, INVALID_ID);
                offsetMagnifiedRegion(scrollX * scale, scrollY * scale, INVALID_SERVICE_ID);
            }
        }

@@ -472,7 +473,7 @@ public class FullScreenMagnificationController implements
                spec.clear();
                onMagnificationChangedLocked();
            }
            mIdOfLastServiceToMagnify = INVALID_ID;
            mIdOfLastServiceToMagnify = INVALID_SERVICE_ID;
            mForceShowMagnifiableBounds = false;
            sendSpecToAnimation(spec, animationCallback);
            return changed;
@@ -519,7 +520,7 @@ public class FullScreenMagnificationController implements
            }
            final boolean changed = updateMagnificationSpecLocked(scale, centerX, centerY);
            sendSpecToAnimation(mCurrentMagnificationSpec, animationCallback);
            if (isMagnifying() && (id != INVALID_ID)) {
            if (isMagnifying() && (id != INVALID_SERVICE_ID)) {
                mIdOfLastServiceToMagnify = id;
                mMagnificationInfoChangedCallback.onRequestMagnificationSpec(mDisplayId,
                        mIdOfLastServiceToMagnify);
@@ -583,7 +584,7 @@ public class FullScreenMagnificationController implements
            if (updateCurrentSpecWithOffsetsLocked(nonNormOffsetX, nonNormOffsetY)) {
                onMagnificationChangedLocked();
            }
            if (id != INVALID_ID) {
            if (id != INVALID_SERVICE_ID) {
                mIdOfLastServiceToMagnify = id;
            }
            sendSpecToAnimation(mCurrentMagnificationSpec, null);
+10 −6
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@ import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_
import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW;
import static android.view.accessibility.MagnificationAnimationCallback.STUB_ANIMATION_CALLBACK;

import static com.android.server.accessibility.AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID;

import android.accessibilityservice.MagnificationConfig;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -240,9 +242,10 @@ public class MagnificationController implements WindowMagnificationManager.Callb
     * @param config The targeting magnification config
     * @param animate    {@code true} to animate the transition, {@code false}
     *                   to transition immediately
     * @param id        The ID of the service requesting the change
     */
    public void transitionMagnificationConfigMode(int displayId, MagnificationConfig config,
            boolean animate) {
            boolean animate, int id) {
        synchronized (mLock) {
            final int targetMode = config.getMode();
            final PointF currentBoundsCenter = getCurrentMagnificationBoundsCenterLocked(displayId,
@@ -273,7 +276,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb
                screenMagnificationController.reset(displayId, false);
                windowMagnificationMgr.enableWindowMagnification(displayId,
                        scale, magnificationCenter.x, magnificationCenter.y,
                        animate ? STUB_ANIMATION_CALLBACK : null);
                        animate ? STUB_ANIMATION_CALLBACK : null, id);
            } else if (targetMode == ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN) {
                windowMagnificationMgr.disableWindowMagnification(displayId, false, null);
                if (!screenMagnificationController.isRegistered(displayId)) {
@@ -281,7 +284,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb
                }
                screenMagnificationController.setScaleAndCenter(displayId, scale,
                        magnificationCenter.x, magnificationCenter.y, animate,
                        AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID);
                        id);
            }
        }
    }
@@ -337,7 +340,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb
    public void onRequestMagnificationSpec(int displayId, int serviceId) {
        final WindowMagnificationManager windowMagnificationManager;
        synchronized (mLock) {
            if (serviceId == AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID) {
            if (serviceId == MAGNIFICATION_GESTURE_HANDLER_ID) {
                return;
            }
            updateMagnificationButton(displayId, ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
@@ -718,11 +721,12 @@ public class MagnificationController implements WindowMagnificationManager.Callb
                }
                fullScreenMagnificationController.setScaleAndCenter(mDisplayId, mCurrentScale,
                        mCurrentCenter.x, mCurrentCenter.y, mAnimate,
                        AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID);
                        MAGNIFICATION_GESTURE_HANDLER_ID);
            } else {
                getWindowMagnificationMgr().enableWindowMagnification(mDisplayId,
                        mCurrentScale, mCurrentCenter.x,
                        mCurrentCenter.y, mAnimate ? STUB_ANIMATION_CALLBACK : null);
                        mCurrentCenter.y, mAnimate ? STUB_ANIMATION_CALLBACK : null,
                        MAGNIFICATION_GESTURE_HANDLER_ID);
            }
        }
    }
+13 −7
Original line number Diff line number Diff line
@@ -99,7 +99,7 @@ public class MagnificationProcessor {
     */
    public boolean setMagnificationConfig(int displayId, @NonNull MagnificationConfig config,
            boolean animate, int id) {
        if (transitionModeIfNeeded(displayId, config, animate)) {
        if (transitionModeIfNeeded(displayId, config, animate, id)) {
            return true;
        }

@@ -114,7 +114,8 @@ public class MagnificationProcessor {
        } else if (configMode == MAGNIFICATION_MODE_WINDOW) {
            return mController.getWindowMagnificationMgr().enableWindowMagnification(displayId,
                    config.getScale(), config.getCenterX(), config.getCenterY(),
                    animate ? STUB_ANIMATION_CALLBACK : null);
                    animate ? STUB_ANIMATION_CALLBACK : null,
                    id);
        }
        return false;
    }
@@ -136,13 +137,13 @@ public class MagnificationProcessor {
     * mode when the controlling mode is unchanged or the controlling magnifier is not activated.
     */
    private boolean transitionModeIfNeeded(int displayId, MagnificationConfig config,
            boolean animate) {
            boolean animate, int id) {
        int currentMode = getControllingMode(displayId);
        if (currentMode == config.getMode()
                || !mController.hasDisableMagnificationCallback(displayId)) {
            return false;
        }
        mController.transitionMagnificationConfigMode(displayId, config, animate);
        mController.transitionMagnificationConfigMode(displayId, config, animate, id);
        return true;
    }

@@ -237,7 +238,8 @@ public class MagnificationProcessor {
        if (mode == MAGNIFICATION_MODE_FULLSCREEN) {
            return mController.getFullScreenMagnificationController().reset(displayId, animate);
        } else if (mode == MAGNIFICATION_MODE_WINDOW) {
            return mController.getWindowMagnificationMgr().reset(displayId);
            return mController.getWindowMagnificationMgr().disableWindowMagnification(displayId,
                    false, animate ? STUB_ANIMATION_CALLBACK : null);
        }
        return false;
    }
@@ -256,11 +258,15 @@ public class MagnificationProcessor {
    }

    /**
     * {@link FullScreenMagnificationController#resetIfNeeded(int, boolean)}
     * Resets all the magnifiers on all the displays.
     * Called when the a11y service connection that has changed the current magnification spec is
     * unbound or the binder died.
     *
     * @param connectionId The connection id
     */
    // TODO: support window magnification
    public void resetAllIfNeeded(int connectionId) {
        mController.getFullScreenMagnificationController().resetAllIfNeeded(connectionId);
        mController.getWindowMagnificationMgr().resetAllIfNeeded(connectionId);
    }

    /**
+59 −37
Original line number Diff line number Diff line
@@ -20,6 +20,9 @@ import static android.accessibilityservice.AccessibilityTrace.FLAGS_WINDOW_MAGNI
import static android.accessibilityservice.AccessibilityTrace.FLAGS_WINDOW_MAGNIFICATION_CONNECTION_CALLBACK;
import static android.view.accessibility.MagnificationAnimationCallback.STUB_ANIMATION_CALLBACK;

import static com.android.server.accessibility.AccessibilityManagerService.INVALID_SERVICE_ID;
import static com.android.server.accessibility.AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -253,7 +256,26 @@ public class WindowMagnificationManager implements
            }
            mWindowMagnifiers.clear();
        }
    }

    /**
     * Resets the window magnifier on all displays that had been controlled by the
     * specified service connection. Called when the service connection is unbound
     * or binder died.
     *
     * @param connectionId The connection id
     */
    public void resetAllIfNeeded(int connectionId) {
        synchronized (mLock) {
            for (int i = 0; i < mWindowMagnifiers.size(); i++) {
                final WindowMagnifier magnifier = mWindowMagnifiers.valueAt(i);
                if (magnifier != null
                        && magnifier.mEnabled
                        && connectionId == magnifier.getIdOfLastServiceToControl()) {
                    magnifier.disableWindowMagnificationInternal(null);
                }
            }
        }
    }

    private void resetWindowMagnifiers() {
@@ -310,7 +332,7 @@ public class WindowMagnificationManager implements
    public boolean enableWindowMagnification(int displayId, float scale, float centerX,
            float centerY) {
        return enableWindowMagnification(displayId, scale, centerX, centerY,
                STUB_ANIMATION_CALLBACK);
                STUB_ANIMATION_CALLBACK, MAGNIFICATION_GESTURE_HANDLER_ID);
    }

    /**
@@ -324,12 +346,13 @@ public class WindowMagnificationManager implements
     * @param centerY The screen-relative Y coordinate around which to center for magnification,
     *                or {@link Float#NaN} to leave unchanged.
     * @param animationCallback Called when the animation result is valid.
     * @param id The connection ID
     * @return {@code true} if the magnification is enabled successfully.
     */
    public boolean enableWindowMagnification(int displayId, float scale, float centerX,
            float centerY, @Nullable MagnificationAnimationCallback animationCallback) {
            float centerY, @Nullable MagnificationAnimationCallback animationCallback, int id) {
        return enableWindowMagnification(displayId, scale, centerX, centerY, animationCallback,
                WINDOW_POSITION_AT_CENTER);
                WINDOW_POSITION_AT_CENTER, id);
    }

    /**
@@ -348,7 +371,7 @@ public class WindowMagnificationManager implements
    public boolean enableWindowMagnification(int displayId, float scale, float centerX,
            float centerY, @WindowPosition int windowPosition) {
        return enableWindowMagnification(displayId, scale, centerX, centerY,
                STUB_ANIMATION_CALLBACK, windowPosition);
                STUB_ANIMATION_CALLBACK, windowPosition, MAGNIFICATION_GESTURE_HANDLER_ID);
    }

    /**
@@ -367,7 +390,7 @@ public class WindowMagnificationManager implements
     */
    public boolean enableWindowMagnification(int displayId, float scale, float centerX,
            float centerY, @Nullable MagnificationAnimationCallback animationCallback,
            @WindowPosition int windowPosition) {
            @WindowPosition int windowPosition, int id) {
        final boolean enabled;
        boolean previousEnabled;
        synchronized (mLock) {
@@ -380,7 +403,7 @@ public class WindowMagnificationManager implements
            }
            previousEnabled = magnifier.mEnabled;
            enabled = magnifier.enableWindowMagnificationInternal(scale, centerX, centerY,
                    animationCallback, windowPosition);
                    animationCallback, windowPosition, id);
        }

        if (enabled && !previousEnabled) {
@@ -394,9 +417,10 @@ public class WindowMagnificationManager implements
     *
     * @param displayId The logical display id.
     * @param clear {@true} Clears the state of window magnification.
     * @return {@code true} if the magnification is turned to be disabled successfully
     */
    void disableWindowMagnification(int displayId, boolean clear) {
        disableWindowMagnification(displayId, clear, STUB_ANIMATION_CALLBACK);
    boolean disableWindowMagnification(int displayId, boolean clear) {
        return disableWindowMagnification(displayId, clear, STUB_ANIMATION_CALLBACK);
    }

    /**
@@ -405,14 +429,15 @@ public class WindowMagnificationManager implements
     * @param displayId The logical display id.
     * @param clear {@true} Clears the state of window magnification.
     * @param animationCallback Called when the animation result is valid.
     * @return {@code true} if the magnification is turned to be disabled successfully
     */
    void disableWindowMagnification(int displayId, boolean clear,
    public boolean disableWindowMagnification(int displayId, boolean clear,
            MagnificationAnimationCallback animationCallback) {
        final boolean disabled;
        synchronized (mLock) {
            WindowMagnifier magnifier = mWindowMagnifiers.get(displayId);
            if (magnifier == null || mConnectionWrapper == null) {
                return;
                return false;
            }
            disabled = magnifier.disableWindowMagnificationInternal(animationCallback);
            if (clear) {
@@ -423,6 +448,7 @@ public class WindowMagnificationManager implements
        if (disabled) {
            mCallback.onWindowMagnificationActivationState(displayId, false);
        }
        return disabled;
    }

    /**
@@ -490,7 +516,7 @@ public class WindowMagnificationManager implements
    public float getScale(int displayId) {
        synchronized (mLock) {
            WindowMagnifier magnifier = mWindowMagnifiers.get(displayId);
            if (magnifier == null) {
            if (magnifier == null || !magnifier.mEnabled) {
                return 1.0f;
            }
            return magnifier.getScale();
@@ -548,7 +574,7 @@ public class WindowMagnificationManager implements
    public float getCenterX(int displayId) {
        synchronized (mLock) {
            WindowMagnifier magnifier = mWindowMagnifiers.get(displayId);
            if (magnifier == null) {
            if (magnifier == null || !magnifier.mEnabled) {
                return Float.NaN;
            }
            return magnifier.getCenterX();
@@ -564,7 +590,7 @@ public class WindowMagnificationManager implements
    public float getCenterY(int displayId) {
        synchronized (mLock) {
            WindowMagnifier magnifier = mWindowMagnifiers.get(displayId);
            if (magnifier == null) {
            if (magnifier == null || !magnifier.mEnabled) {
                return Float.NaN;
            }
            return magnifier.getCenterY();
@@ -581,7 +607,7 @@ public class WindowMagnificationManager implements
    public void getMagnificationSourceBounds(int displayId, @NonNull Region outRegion) {
        synchronized (mLock) {
            WindowMagnifier magnifier = mWindowMagnifiers.get(displayId);
            if (magnifier == null) {
            if (magnifier == null || !magnifier.mEnabled) {
                outRegion.setEmpty();
            } else {
                outRegion.set(magnifier.mSourceBounds);
@@ -589,24 +615,6 @@ public class WindowMagnificationManager implements
        }
    }

    /**
     * Resets the magnification scale and center.
     *
     * @param displayId The logical display id.
     * @return {@code true} if the magnification spec changed, {@code false} if
     * the spec did not change
     */
    public boolean reset(int displayId) {
        synchronized (mLock) {
            WindowMagnifier magnifier = mWindowMagnifiers.get(displayId);
            if (magnifier == null) {
                return false;
            }
            magnifier.reset();
            return true;
        }
    }

    /**
     * Creates the windowMagnifier based on the specified display and stores it.
     *
@@ -722,6 +730,9 @@ public class WindowMagnificationManager implements
    /**
     * A class manipulates window magnification per display and contains the magnification
     * information.
     * <p>
     * This class requires to hold the lock when controlling the magnifier.
     * </p>
     */
    private static class WindowMagnifier {

@@ -735,6 +746,8 @@ public class WindowMagnificationManager implements
        // The magnified bounds on the screen.
        private final Rect mSourceBounds = new Rect();

        private int mIdOfLastServiceToControl = INVALID_SERVICE_ID;

        private PointF mMagnificationFrameOffsetRatio = new PointF(0f, 0f);

        WindowMagnifier(int displayId, WindowMagnificationManager windowMagnificationManager) {
@@ -745,7 +758,7 @@ public class WindowMagnificationManager implements
        @GuardedBy("mLock")
        boolean enableWindowMagnificationInternal(float scale, float centerX, float centerY,
                @Nullable MagnificationAnimationCallback animationCallback,
                @WindowPosition int windowPosition) {
                @WindowPosition int windowPosition, int id) {
            // Handle defaults. The scale may be NAN when just updating magnification center.
            if (Float.isNaN(scale)) {
                scale = getScale();
@@ -757,7 +770,7 @@ public class WindowMagnificationManager implements
                    mMagnificationFrameOffsetRatio.y, animationCallback)) {
                mScale = normScale;
                mEnabled = true;

                mIdOfLastServiceToControl = id;
                return true;
            }
            return false;
@@ -785,7 +798,7 @@ public class WindowMagnificationManager implements
            if (mWindowMagnificationManager.disableWindowMagnificationInternal(
                    mDisplayId, animationResultCallback)) {
                mEnabled = false;

                mIdOfLastServiceToControl = INVALID_SERVICE_ID;
                return true;
            }
            return false;
@@ -813,6 +826,13 @@ public class WindowMagnificationManager implements
            mBounds.set(rect);
        }

        /**
         * Returns the ID of the last service that changed the magnification config.
         */
        int getIdOfLastServiceToControl() {
            return mIdOfLastServiceToControl;
        }

        @GuardedBy("mLock")
        int pointersInWindow(MotionEvent motionEvent) {
            int count = 0;
@@ -840,6 +860,8 @@ public class WindowMagnificationManager implements
        @GuardedBy("mLock")
        void reset() {
            mEnabled = false;
            mIdOfLastServiceToControl = INVALID_SERVICE_ID;
            mSourceBounds.setEmpty();
        }

        @GuardedBy("mLock")
@@ -849,12 +871,12 @@ public class WindowMagnificationManager implements

        @GuardedBy("mLock")
        float getCenterX() {
            return mEnabled ? mSourceBounds.exactCenterX() : Float.NaN;
            return mSourceBounds.exactCenterX();
        }

        @GuardedBy("mLock")
        float getCenterY() {
            return mEnabled ? mSourceBounds.exactCenterY() : Float.NaN;
            return mSourceBounds.exactCenterY();
        }
    }

Loading