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

Commit e5b7455e authored by Roy Chou's avatar Roy Chou Committed by Android (Google) Code Review
Browse files

Merge "feat(#AlwaysOnMagnifier)!: Supports magnification zooming to 100% [1/2]"

parents 29b5e40a 23143762
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -3248,7 +3248,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
        if (targetName.equals(MAGNIFICATION_CONTROLLER_NAME)) {
            final boolean enabled =
                    !getMagnificationController().getFullScreenMagnificationController()
                            .isMagnifying(displayId);
                            .isActivated(displayId);
            logAccessibilityShortcutActivated(mContext, MAGNIFICATION_COMPONENT_NAME, shortcutType,
                    enabled);
            sendAccessibilityButtonToInputFilter(displayId);
+35 −62
Original line number Diff line number Diff line
@@ -126,8 +126,6 @@ public class FullScreenMagnificationController implements
        private boolean mUnregisterPending;
        private boolean mDeleteAfterUnregister;

        private boolean mForceShowMagnifiableBounds;

        private final int mDisplayId;

        private int mIdOfLastServiceToMagnify = INVALID_SERVICE_ID;
@@ -213,8 +211,8 @@ public class FullScreenMagnificationController implements
            return mRegistered;
        }

        boolean isMagnifying() {
            return mCurrentMagnificationSpec.scale > 1.0f;
        boolean isActivated() {
            return mMagnificationActivated;
        }

        float getScale() {
@@ -370,12 +368,6 @@ public class FullScreenMagnificationController implements
        @GuardedBy("mLock")
        void onMagnificationChangedLocked() {
            final float scale = getScale();
            final boolean lastMagnificationActivated = mMagnificationActivated;
            mMagnificationActivated = scale > 1.0f;
            if (mMagnificationActivated != lastMagnificationActivated) {
                mMagnificationInfoChangedCallback.onFullScreenMagnificationActivationState(
                        mDisplayId, mMagnificationActivated);
            }

            final MagnificationConfig config = new MagnificationConfig.Builder()
                    .setMode(MAGNIFICATION_MODE_FULLSCREEN)
@@ -384,7 +376,7 @@ public class FullScreenMagnificationController implements
                    .setCenterY(getCenterY()).build();
            mMagnificationInfoChangedCallback.onFullScreenMagnificationChanged(mDisplayId,
                    mMagnificationRegion, config);
            if (mUnregisterPending && !isMagnifying()) {
            if (mUnregisterPending && !isActivated()) {
                unregister(mDeleteAfterUnregister);
            }
        }
@@ -476,21 +468,22 @@ public class FullScreenMagnificationController implements
        }

        @GuardedBy("mLock")
        void setForceShowMagnifiableBounds(boolean show) {
            if (mRegistered) {
                mForceShowMagnifiableBounds = show;
                if (traceEnabled()) {
                    logTrace("setForceShowMagnifiableBounds",
                            "displayID=" + mDisplayId + ";show=" + show);
        private boolean setActivated(boolean activated) {
            if (DEBUG) {
                Slog.i(LOG_TAG, "setActivated(activated = " + activated + ")");
            }

            final boolean changed = (mMagnificationActivated != activated);

            if (changed) {
                mMagnificationActivated = activated;
                mMagnificationInfoChangedCallback.onFullScreenMagnificationActivationState(
                        mDisplayId, mMagnificationActivated);
                mControllerCtx.getWindowManager().setForceShowMagnifiableBounds(
                        mDisplayId, show);
            }
                        mDisplayId, activated);
            }

        @GuardedBy("mLock")
        boolean isForceShowMagnifiableBounds() {
            return mRegistered && mForceShowMagnifiableBounds;
            return changed;
        }

        @GuardedBy("mLock")
@@ -504,13 +497,13 @@ public class FullScreenMagnificationController implements
                return false;
            }
            final MagnificationSpec spec = mCurrentMagnificationSpec;
            final boolean changed = !spec.isNop();
            final boolean changed = isActivated();
            setActivated(false);
            if (changed) {
                spec.clear();
                onMagnificationChangedLocked();
            }
            mIdOfLastServiceToMagnify = INVALID_SERVICE_ID;
            mForceShowMagnifiableBounds = false;
            sendSpecToAnimation(spec, animationCallback);
            return changed;
        }
@@ -554,9 +547,10 @@ public class FullScreenMagnificationController implements
                                + ", centerY = " + centerY + ", endCallback = "
                                + animationCallback + ", id = " + id + ")");
            }
            final boolean changed = updateMagnificationSpecLocked(scale, centerX, centerY);
            boolean changed = setActivated(true);
            changed |= updateMagnificationSpecLocked(scale, centerX, centerY);
            sendSpecToAnimation(mCurrentMagnificationSpec, animationCallback);
            if (isMagnifying() && (id != INVALID_SERVICE_ID)) {
            if (isActivated() && (id != INVALID_SERVICE_ID)) {
                mIdOfLastServiceToMagnify = id;
                mMagnificationInfoChangedCallback.onRequestMagnificationSpec(mDisplayId,
                        mIdOfLastServiceToMagnify);
@@ -779,7 +773,7 @@ public class FullScreenMagnificationController implements
            if (display == null) {
                return;
            }
            if (!display.isMagnifying()) {
            if (!display.isActivated()) {
                return;
            }
            final Rect magnifiedRegionBounds = mTempRect;
@@ -831,16 +825,16 @@ public class FullScreenMagnificationController implements

    /**
     * @param displayId The logical display id.
     * @return {@code true} if magnification is active, e.g. the scale
     *         is > 1, {@code false} otherwise
     * @return {@code true} if magnification is activated,
     *         {@code false} otherwise
     */
    public boolean isMagnifying(int displayId) {
    public boolean isActivated(int displayId) {
        synchronized (mLock) {
            final DisplayMagnification display = mDisplays.get(displayId);
            if (display == null) {
                return false;
            }
            return display.isMagnifying();
            return display.isActivated();
        }
    }

@@ -1166,6 +1160,9 @@ public class FullScreenMagnificationController implements
     */
    public void persistScale(int displayId) {
        final float scale = getScale(Display.DEFAULT_DISPLAY);
        if (scale < 2.0f) {
            return;
        }
        mScaleProvider.putScale(scale, displayId);
    }

@@ -1177,7 +1174,8 @@ public class FullScreenMagnificationController implements
     *         scale if none is available
     */
    public float getPersistedScale(int displayId) {
        return mScaleProvider.getScale(displayId);
        return MathUtils.constrain(mScaleProvider.getScale(displayId),
                2.0f, MagnificationScaleProvider.MAX_SCALE);
    }

    /**
@@ -1198,12 +1196,12 @@ public class FullScreenMagnificationController implements
     *
     * @param displayId The logical display id.
     * @param animate whether the animate the transition
     * @return whether was {@link #isMagnifying(int) magnifying}
     * @return whether was {@link #isActivated(int)}  activated}
     */
    boolean resetIfNeeded(int displayId, boolean animate) {
        synchronized (mLock) {
            final DisplayMagnification display = mDisplays.get(displayId);
            if (display == null || !display.isMagnifying()) {
            if (display == null || !display.isActivated()) {
                return false;
            }
            display.reset(animate);
@@ -1221,7 +1219,7 @@ public class FullScreenMagnificationController implements
    boolean resetIfNeeded(int displayId, int connectionId) {
        synchronized (mLock) {
            final DisplayMagnification display = mDisplays.get(displayId);
            if (display == null || !display.isMagnifying()
            if (display == null || !display.isActivated()
                    || connectionId != display.getIdOfLastServiceToMagnify()) {
                return false;
            }
@@ -1230,16 +1228,6 @@ public class FullScreenMagnificationController implements
        }
    }

    void setForceShowMagnifiableBounds(int displayId, boolean show) {
        synchronized (mLock) {
            final DisplayMagnification display = mDisplays.get(displayId);
            if (display == null) {
                return;
            }
            display.setForceShowMagnifiableBounds(show);
        }
    }

    /**
     * Notifies that the IME window visibility changed.
     *
@@ -1251,21 +1239,6 @@ public class FullScreenMagnificationController implements
        mMagnificationInfoChangedCallback.onImeWindowVisibilityChanged(displayId, shown);
    }

    /**
     * Returns {@code true} if the magnifiable regions of the display is forced to be shown.
     *
     * @param displayId The logical display id.
     */
    public boolean isForceShowMagnifiableBounds(int displayId) {
        synchronized (mLock) {
            final DisplayMagnification display = mDisplays.get(displayId);
            if (display == null) {
                return false;
            }
            return display.isForceShowMagnifiableBounds();
        }
    }

    private void onScreenTurnedOff() {
        final Message m = PooledLambda.obtainMessage(
                FullScreenMagnificationController::resetAllIfNeeded, this, false);
@@ -1295,7 +1268,7 @@ public class FullScreenMagnificationController implements
            }
            return;
        }
        if (!display.isMagnifying()) {
        if (!display.isActivated()) {
            display.unregister(delete);
        } else {
            display.unregisterPending(delete);
+83 −28
Original line number Diff line number Diff line
@@ -122,7 +122,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
    // The MIN_SCALE is different from MagnificationScaleProvider.MIN_SCALE due
    // to AccessibilityService.MagnificationController#setScale() has
    // different scale range
    private static final float MIN_SCALE = 2.0f;
    private static final float MIN_SCALE = 1.0f;
    private static final float MAX_SCALE = MagnificationScaleProvider.MAX_SCALE;

    @VisibleForTesting final FullScreenMagnificationController mFullScreenMagnificationController;
@@ -220,14 +220,19 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH

    @Override
    public void handleShortcutTriggered() {
        boolean wasMagnifying = mFullScreenMagnificationController.resetIfNeeded(mDisplayId,
                /* animate */ true);
        if (wasMagnifying) {
        final boolean isActivated = mFullScreenMagnificationController.isActivated(mDisplayId);

        if (isActivated) {
            zoomOff();
            clearAndTransitionToStateDetecting();
        } else {
            mPromptController.showNotificationIfNeeded();
            mDetectingState.toggleShortcutTriggered();
        }

        if (mDetectingState.isShortcutTriggered()) {
            mPromptController.showNotificationIfNeeded();
            zoomToScale(1.0f, Float.NaN, Float.NaN);
        }
    }

    @Override
@@ -441,7 +446,12 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
    final class ViewportDraggingState implements State {

        /** Whether to disable zoom after dragging ends */
        boolean mZoomedInBeforeDrag;
        @VisibleForTesting boolean mActivatedBeforeDrag;
        /** Whether to restore scale after dragging ends */
        private boolean mZoomedInTemporary;
        /** The cached scale for recovering after dragging ends */
        private float mScaleBeforeZoomedInTemporary;

        private boolean mLastMoveOutsideMagnifiedRegion;

        @Override
@@ -474,7 +484,13 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH

                case ACTION_UP:
                case ACTION_CANCEL: {
                    if (!mZoomedInBeforeDrag) zoomOff();
                    if (mActivatedBeforeDrag) {
                        if (mZoomedInTemporary) {
                            zoomToScale(mScaleBeforeZoomedInTemporary, event.getX(), event.getY());
                        }
                    } else {
                        zoomOff();
                    }
                    clear();
                    transitionTo(mDetectingState);
                }
@@ -488,15 +504,27 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
            }
        }

        public void prepareForZoomInTemporary() {
            mViewportDraggingState.mActivatedBeforeDrag =
                    mFullScreenMagnificationController.isActivated(mDisplayId);

            mViewportDraggingState.mZoomedInTemporary = true;
            mViewportDraggingState.mScaleBeforeZoomedInTemporary =
                    mFullScreenMagnificationController.getScale(mDisplayId);
        }

        @Override
        public void clear() {
            mLastMoveOutsideMagnifiedRegion = false;

            mZoomedInTemporary = false;
            mScaleBeforeZoomedInTemporary = 1.0f;
        }

        @Override
        public String toString() {
            return "ViewportDraggingState{"
                    + "mZoomedInBeforeDrag=" + mZoomedInBeforeDrag
                    + "mActivatedBeforeDrag=" + mActivatedBeforeDrag
                    + ", mLastMoveOutsideMagnifiedRegion=" + mLastMoveOutsideMagnifiedRegion
                    + '}';
        }
@@ -625,10 +653,10 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
                        transitionToDelegatingStateAndClear();

                    } else if (mDetectTripleTap
                            // If magnified, delay an ACTION_DOWN for mMultiTapMaxDelay
                            // If activated, delay an ACTION_DOWN for mMultiTapMaxDelay
                            // to ensure reachability of
                            // STATE_PANNING_SCALING(triggerable with ACTION_POINTER_DOWN)
                            || mFullScreenMagnificationController.isMagnifying(mDisplayId)) {
                            || isActivated()) {

                        afterMultiTapTimeoutTransitionToDelegatingState();

@@ -640,8 +668,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
                }
                break;
                case ACTION_POINTER_DOWN: {
                    if (mFullScreenMagnificationController.isMagnifying(mDisplayId)
                            && event.getPointerCount() == 2) {
                    if (isActivated() && event.getPointerCount() == 2) {
                        storeSecondPointerDownLocation(event);
                        mHandler.sendEmptyMessageDelayed(MESSAGE_TRANSITION_TO_PANNINGSCALING_STATE,
                                ViewConfiguration.getTapTimeout());
@@ -665,13 +692,13 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
                        // (which is a rare combo to be used aside from magnification)
                        if (isMultiTapTriggered(2 /* taps */) && event.getPointerCount() == 1) {
                            transitionToViewportDraggingStateAndClear(event);
                        } else if (isMagnifying() && event.getPointerCount() == 2) {
                        } else if (isActivated() && event.getPointerCount() == 2) {
                            //Primary pointer is swiping, so transit to PanningScalingState
                            transitToPanningScalingStateAndClear();
                        } else {
                            transitionToDelegatingStateAndClear();
                        }
                    } else if (isMagnifying() && secondPointerDownValid()
                    } else if (isActivated() && secondPointerDownValid()
                            && distanceClosestPointerToPoint(
                            mSecondPointerDownLocation, /* move */ event) > mSwipeMinDistance) {
                        //Second pointer is swiping, so transit to PanningScalingState
@@ -734,7 +761,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH

            // Only log the triple tap event, use numTaps to filter.
            if (multitapTriggered && numTaps > 2) {
                final boolean enabled = mFullScreenMagnificationController.isMagnifying(mDisplayId);
                final boolean enabled = isActivated();
                logMagnificationTripleTap(enabled);
            }
            return multitapTriggered;
@@ -862,24 +889,33 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
            mSecondPointerDownLocation.set(Float.NaN, Float.NaN);
        }

        /**
         * This method could be triggered by both 2 cases.
         *      1. direct three tap gesture
         *      2. one tap while shortcut triggered (it counts as two taps).
         */
        private void onTripleTap(MotionEvent up) {
            if (DEBUG_DETECTING) {
                Slog.i(mLogTag, "onTripleTap(); delayed: "
                        + MotionEventInfo.toString(mDelayedEventQueue));
            }
            clear();

            // Toggle zoom
            if (mFullScreenMagnificationController.isMagnifying(mDisplayId)) {
                zoomOff();
            } else {
            // We put mShortcutTriggered into conditions.
            // The reason is when the shortcut is triggered,
            //   the magnifier is activated and keeps in scale 1.0,
            //   and in this case, we still want to zoom on the magnifier.
            if (!isActivated() || mShortcutTriggered) {
                mPromptController.showNotificationIfNeeded();
                zoomOn(up.getX(), up.getY());
            } else {
                zoomOff();
            }

            clear();
        }

        private boolean isMagnifying() {
            return mFullScreenMagnificationController.isMagnifying(mDisplayId);
        private boolean isActivated() {
            return mFullScreenMagnificationController.isActivated(mDisplayId);
        }

        void transitionToViewportDraggingStateAndClear(MotionEvent down) {
@@ -887,14 +923,13 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
            if (DEBUG_DETECTING) Slog.i(mLogTag, "onTripleTapAndHold()");
            clear();

            mViewportDraggingState.mZoomedInBeforeDrag =
                    mFullScreenMagnificationController.isMagnifying(mDisplayId);

            // Triple tap and hold also belongs to triple tap event.
            final boolean enabled = !mViewportDraggingState.mZoomedInBeforeDrag;
            final boolean enabled = !isActivated();
            logMagnificationTripleTap(enabled);

            zoomOn(down.getX(), down.getY());
            mViewportDraggingState.prepareForZoomInTemporary();

            zoomInTemporary(down.getX(), down.getY());

            transitionTo(mViewportDraggingState);
        }
@@ -919,7 +954,10 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
            if (DEBUG_DETECTING) Slog.i(mLogTag, "setShortcutTriggered(" + state + ")");

            mShortcutTriggered = state;
            mFullScreenMagnificationController.setForceShowMagnifiableBounds(mDisplayId, state);
        }

        private boolean isShortcutTriggered() {
            return mShortcutTriggered;
        }

        /**
@@ -948,12 +986,29 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
        }
    }

    private void zoomInTemporary(float centerX, float centerY) {
        final float currentScale = mFullScreenMagnificationController.getScale(mDisplayId);
        final float persistedScale = MathUtils.constrain(
                mFullScreenMagnificationController.getPersistedScale(mDisplayId),
                MIN_SCALE, MAX_SCALE);

        final float scale = MathUtils.constrain(Math.max(currentScale + 1.0f, persistedScale),
                MIN_SCALE, MAX_SCALE);

        zoomToScale(scale, centerX, centerY);
    }

    private void zoomOn(float centerX, float centerY) {
        if (DEBUG_DETECTING) Slog.i(mLogTag, "zoomOn(" + centerX + ", " + centerY + ")");

        final float scale = MathUtils.constrain(
                mFullScreenMagnificationController.getPersistedScale(mDisplayId),
                MIN_SCALE, MAX_SCALE);
        zoomToScale(scale, centerX, centerY);
    }

    private void zoomToScale(float scale, float centerX, float centerY) {
        scale = MathUtils.constrain(scale, MIN_SCALE, MAX_SCALE);
        mFullScreenMagnificationController.setScaleAndCenter(mDisplayId,
                scale, centerX, centerY,
                /* animate */ true,
+10 −10
Original line number Diff line number Diff line
@@ -254,13 +254,15 @@ public class MagnificationController implements WindowMagnificationManager.Callb
        final DisableMagnificationCallback animationEndCallback =
                new DisableMagnificationCallback(transitionCallBack, displayId, targetMode,
                        scale, currentCenter, true);

        setDisableMagnificationCallbackLocked(displayId, animationEndCallback);

        if (targetMode == ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW) {
            screenMagnificationController.reset(displayId, animationEndCallback);
        } else {
            windowMagnificationMgr.disableWindowMagnification(displayId, false,
                    animationEndCallback);
        }
        setDisableMagnificationCallbackLocked(displayId, animationEndCallback);
    }

    /**
@@ -481,17 +483,17 @@ public class MagnificationController implements WindowMagnificationManager.Callb
     */
    private boolean shouldNotifyMagnificationChange(int displayId, int changeMode) {
        synchronized (mLock) {
            final boolean fullScreenMagnifying = mFullScreenMagnificationController != null
                    && mFullScreenMagnificationController.isMagnifying(displayId);
            final boolean fullScreenActivated = mFullScreenMagnificationController != null
                    && mFullScreenMagnificationController.isActivated(displayId);
            final boolean windowEnabled = mWindowMagnificationMgr != null
                    && mWindowMagnificationMgr.isWindowMagnifierEnabled(displayId);
            final Integer transitionMode = mTransitionModes.get(displayId);
            if (((changeMode == MAGNIFICATION_MODE_FULLSCREEN && fullScreenMagnifying)
            if (((changeMode == MAGNIFICATION_MODE_FULLSCREEN && fullScreenActivated)
                    || (changeMode == MAGNIFICATION_MODE_WINDOW && windowEnabled))
                    && (transitionMode == null)) {
                return true;
            }
            if ((!fullScreenMagnifying && !windowEnabled)
            if ((!fullScreenActivated && !windowEnabled)
                    && (transitionMode == null)) {
                return true;
            }
@@ -742,7 +744,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb
                    mWindowMagnificationMgr.getCenterY(displayId));
        } else {
            if (mFullScreenMagnificationController == null
                    || !mFullScreenMagnificationController.isMagnifying(displayId)) {
                    || !mFullScreenMagnificationController.isActivated(displayId)) {
                return null;
            }
            mTempPoint.set(mFullScreenMagnificationController.getCenterX(displayId),
@@ -766,9 +768,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb
                if (mFullScreenMagnificationController == null) {
                    return false;
                }
                isActivated = mFullScreenMagnificationController.isMagnifying(displayId)
                        || mFullScreenMagnificationController.isForceShowMagnifiableBounds(
                        displayId);
                isActivated = mFullScreenMagnificationController.isActivated(displayId);
            }
        } else if (mode == ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW) {
            synchronized (mLock) {
@@ -829,7 +829,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb
                    final FullScreenMagnificationController screenMagnificationController =
                            getFullScreenMagnificationController();
                    if (mCurrentMode == ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN
                            && !screenMagnificationController.isMagnifying(mDisplayId)) {
                            && !screenMagnificationController.isActivated(mDisplayId)) {
                        MagnificationConfig.Builder configBuilder =
                                new MagnificationConfig.Builder();
                        Region region = new Region();
+2 −2
Original line number Diff line number Diff line
@@ -313,13 +313,13 @@ public class MagnificationProcessor {
    }

    /**
     * {@link FullScreenMagnificationController#isMagnifying(int)}
     * {@link FullScreenMagnificationController#isActivated(int)}
     * {@link WindowMagnificationManager#isWindowMagnifierEnabled(int)}
     */
    public boolean isMagnifying(int displayId) {
        int mode = getControllingMode(displayId);
        if (mode == MAGNIFICATION_MODE_FULLSCREEN) {
            return mController.getFullScreenMagnificationController().isMagnifying(displayId);
            return mController.getFullScreenMagnificationController().isActivated(displayId);
        } else if (mode == MAGNIFICATION_MODE_WINDOW) {
            return mController.getWindowMagnificationMgr().isWindowMagnifierEnabled(displayId);
        }
Loading