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

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

Refactoring for magnification [2/n]

This change doesn't change any user behavior.
It's refactoring that reduce the common code and logic.
1. Moves the common logic of onMotionEvent to the parent
class, MagnificationGestureHandler.
2. Moves some of the debug flags to the parent class.

Bug: 174291719
Test: atest com.android.server.accessibility.magnification
Change-Id: If0a4a5e934a650b40e064dc3a0b72ce68780409b
parent 9f0f172a
Loading
Loading
Loading
Loading
+11 −70
Original line number Diff line number Diff line
@@ -62,9 +62,6 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.server.accessibility.AccessibilityManagerService;
import com.android.server.accessibility.gestures.GestureUtils;

import java.util.ArrayDeque;
import java.util.Queue;

/**
 * This class handles full screen magnification in response to touch events.
 *
@@ -115,13 +112,10 @@ import java.util.Queue;
 */
@SuppressWarnings("WeakerAccess")
public class FullScreenMagnificationGestureHandler extends MagnificationGestureHandler {
    private static final String LOG_TAG = "FullScreenMagnificationGestureHandler";

    private static final boolean DEBUG_ALL = false;
    private static final boolean DEBUG_STATE_TRANSITIONS = false | DEBUG_ALL;
    private static final boolean DEBUG_DETECTING = false | DEBUG_ALL;
    private static final boolean DEBUG_PANNING_SCALING = false | DEBUG_ALL;
    private static final boolean DEBUG_EVENT_STREAM = false | DEBUG_ALL;

    // The MIN_SCALE is different from MagnificationController.MIN_SCALE due
    // to AccessibilityService.MagnificationController#setScale() has
@@ -145,9 +139,6 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
    private PointerCoords[] mTempPointerCoords;
    private PointerProperties[] mTempPointerProperties;

    private final Queue<MotionEvent> mDebugInputEventHistory;
    private final Queue<MotionEvent> mDebugOutputEventHistory;

    public FullScreenMagnificationGestureHandler(Context context,
            FullScreenMagnificationController fullScreenMagnificationController,
            ScaleChangedListener listener,
@@ -157,7 +148,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
            int displayId) {
        super(displayId, detectTripleTap, detectShortcutTrigger, listener);
        if (DEBUG_ALL) {
            Log.i(LOG_TAG,
            Log.i(mLogTag,
                    "FullScreenMagnificationGestureHandler(detectTripleTap = " + detectTripleTap
                            + ", detectShortcutTrigger = " + detectShortcutTrigger + ")");
        }
@@ -176,36 +167,11 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
            mScreenStateReceiver = null;
        }

        mDebugInputEventHistory = DEBUG_EVENT_STREAM ? new ArrayDeque<>() : null;
        mDebugOutputEventHistory = DEBUG_EVENT_STREAM ? new ArrayDeque<>() : null;

        transitionTo(mDetectingState);
    }

    @Override
    public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
        if (DEBUG_EVENT_STREAM) {
            storeEventInto(mDebugInputEventHistory, event);
            try {
                onMotionEventInternal(event, rawEvent, policyFlags);
            } catch (Exception e) {
                throw new RuntimeException(
                        "Exception following input events: " + mDebugInputEventHistory, e);
            }
        } else {
            onMotionEventInternal(event, rawEvent, policyFlags);
        }
    }

    private void onMotionEventInternal(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
        if (DEBUG_ALL) Slog.i(LOG_TAG, "onMotionEvent(" + event + ")");

        if ((!mDetectTripleTap && !mDetectShortcutTrigger)
                || !event.isFromSource(SOURCE_TOUCHSCREEN)) {
            dispatchTransformedEvent(event, rawEvent, policyFlags);
            return;
        }

    void onMotionEventInternal(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
        handleEventWith(mCurrentState, event, rawEvent, policyFlags);
    }

@@ -230,7 +196,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
    @Override
    public void onDestroy() {
        if (DEBUG_STATE_TRANSITIONS) {
            Slog.i(LOG_TAG, "onDestroy(); delayed = "
            Slog.i(mLogTag, "onDestroy(); delayed = "
                    + MotionEventInfo.toString(mDetectingState.mDelayedEventQueue));
        }

@@ -270,31 +236,6 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
        mPanningScalingState.clear();
    }

    private void dispatchTransformedEvent(MotionEvent event, MotionEvent rawEvent,
            int policyFlags) {
        if (DEBUG_EVENT_STREAM) {
            storeEventInto(mDebugOutputEventHistory, event);
            try {
                super.onMotionEvent(event, rawEvent, policyFlags);
            } catch (Exception e) {
                throw new RuntimeException(
                        "Exception downstream following input events: " + mDebugInputEventHistory
                                + "\nTransformed into output events: " + mDebugOutputEventHistory,
                        e);
            }
        } else {
            super.onMotionEvent(event, rawEvent, policyFlags);
        }
    }

    private static void storeEventInto(Queue<MotionEvent> queue, MotionEvent event) {
        queue.add(MotionEvent.obtain(event));
        // Prune old events
        while (!queue.isEmpty() && (event.getEventTime() - queue.peek().getEventTime() > 5000)) {
            queue.remove().recycle();
        }
    }

    private PointerCoords[] getTempPointerCoordsWithMinSize(int size) {
        final int oldSize = (mTempPointerCoords != null) ? mTempPointerCoords.length : 0;
        if (oldSize < size) {
@@ -329,7 +270,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH

    private void transitionTo(State state) {
        if (DEBUG_STATE_TRANSITIONS) {
            Slog.i(LOG_TAG,
            Slog.i(mLogTag,
                    (State.nameOf(mCurrentState) + " -> " + State.nameOf(state)
                    + " at " + asList(copyOfRange(new RuntimeException().getStackTrace(), 1, 5)))
                    .replace(getClass().getName(), ""));
@@ -411,7 +352,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
                return true;
            }
            if (DEBUG_PANNING_SCALING) {
                Slog.i(LOG_TAG, "Panned content by scrollX: " + distanceX
                Slog.i(mLogTag, "Panned content by scrollX: " + distanceX
                        + " scrollY: " + distanceY);
            }
            mFullScreenMagnificationController.offsetMagnifiedRegion(mDisplayId, distanceX,
@@ -451,7 +392,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH

            final float pivotX = detector.getFocusX();
            final float pivotY = detector.getFocusY();
            if (DEBUG_PANNING_SCALING) Slog.i(LOG_TAG, "Scaled content to: " + scale + "x");
            if (DEBUG_PANNING_SCALING) Slog.i(mLogTag, "Scaled content to: " + scale + "x");
            mFullScreenMagnificationController.setScale(mDisplayId, scale, pivotX, pivotY, false,
                    AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID);
            mListener.onMagnificationScaleChanged(mDisplayId, getMode());
@@ -916,7 +857,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH

        private void onTripleTap(MotionEvent up) {
            if (DEBUG_DETECTING) {
                Slog.i(LOG_TAG, "onTripleTap(); delayed: "
                Slog.i(mLogTag, "onTripleTap(); delayed: "
                        + MotionEventInfo.toString(mDelayedEventQueue));
            }
            clear();
@@ -936,7 +877,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH

        void transitionToViewportDraggingStateAndClear(MotionEvent down) {

            if (DEBUG_DETECTING) Slog.i(LOG_TAG, "onTripleTapAndHold()");
            if (DEBUG_DETECTING) Slog.i(mLogTag, "onTripleTapAndHold()");
            clear();

            mViewportDraggingState.mZoomedInBeforeDrag =
@@ -968,7 +909,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
            if (mShortcutTriggered == state) {
                return;
            }
            if (DEBUG_DETECTING) Slog.i(LOG_TAG, "setShortcutTriggered(" + state + ")");
            if (DEBUG_DETECTING) Slog.i(mLogTag, "setShortcutTriggered(" + state + ")");

            mShortcutTriggered = state;
            mFullScreenMagnificationController.setForceShowMagnifiableBounds(mDisplayId, state);
@@ -1001,7 +942,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
    }

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

        final float scale = MathUtils.constrain(
                mFullScreenMagnificationController.getPersistedScale(),
@@ -1013,7 +954,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
    }

    private void zoomOff() {
        if (DEBUG_DETECTING) Slog.i(LOG_TAG, "zoomOff()");
        if (DEBUG_DETECTING) Slog.i(mLogTag, "zoomOff()");
        mFullScreenMagnificationController.reset(mDisplayId, /* animate */ true);
    }

+72 −2
Original line number Diff line number Diff line
@@ -16,15 +16,30 @@

package com.android.server.accessibility.magnification;

import static android.view.InputDevice.SOURCE_TOUCHSCREEN;

import android.annotation.NonNull;
import android.util.Log;
import android.util.Slog;
import android.view.MotionEvent;

import com.android.server.accessibility.BaseEventStreamTransformation;

import java.util.ArrayDeque;
import java.util.Queue;

/**
 * A base class that detects gestures and defines common methods for magnification.
 */
public abstract class MagnificationGestureHandler extends BaseEventStreamTransformation {

    protected final String mLogTag = this.getClass().getSimpleName();
    protected static final boolean DEBUG_ALL = Log.isLoggable("MagnificationGestureHandler",
            Log.DEBUG);
    protected static final boolean DEBUG_EVENT_STREAM = false | DEBUG_ALL;
    private final Queue<MotionEvent> mDebugInputEventHistory;
    private final Queue<MotionEvent> mDebugOutputEventHistory;

    /**
     * The logical display id.
     */
@@ -64,8 +79,64 @@ public abstract class MagnificationGestureHandler extends BaseEventStreamTransfo
        mDetectTripleTap = detectTripleTap;
        mDetectShortcutTrigger = detectShortcutTrigger;
        mListener = listener;

        mDebugInputEventHistory = DEBUG_EVENT_STREAM ? new ArrayDeque<>() : null;
        mDebugOutputEventHistory = DEBUG_EVENT_STREAM ? new ArrayDeque<>() : null;
    }

    @Override
    public final void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
        if (DEBUG_ALL) {
            Slog.i(mLogTag, "onMotionEvent(" + event + ")");
        }
        if (DEBUG_EVENT_STREAM) {
            storeEventInto(mDebugInputEventHistory, event);
        }
        if (shouldDispatchTransformedEvent(event)) {
            dispatchTransformedEvent(event, rawEvent, policyFlags);
        } else {
            onMotionEventInternal(event, rawEvent, policyFlags);
        }
    }

    private boolean shouldDispatchTransformedEvent(MotionEvent event) {
        if ((!mDetectTripleTap && !mDetectShortcutTrigger) || !event.isFromSource(
                SOURCE_TOUCHSCREEN)) {
            return true;
        }
        return false;
    }

    final void dispatchTransformedEvent(MotionEvent event, MotionEvent rawEvent,
            int policyFlags) {
        if (DEBUG_EVENT_STREAM) {
            storeEventInto(mDebugOutputEventHistory, event);
            try {
                super.onMotionEvent(event, rawEvent, policyFlags);
                return;
            } catch (Exception e) {
                throw new RuntimeException(
                        "Exception downstream following input events: " + mDebugInputEventHistory
                                + "\nTransformed into output events: " + mDebugOutputEventHistory,
                        e);
            }
        }
        super.onMotionEvent(event, rawEvent, policyFlags);
    }

    private static void storeEventInto(Queue<MotionEvent> queue, MotionEvent event) {
        queue.add(MotionEvent.obtain(event));
        // Prune old events
        while (!queue.isEmpty() && (event.getEventTime() - queue.peek().getEventTime() > 5000)) {
            queue.remove().recycle();
        }
    }

    /**
     * Called when this MagnificationGestureHandler handles the motion event.
     */
    abstract void onMotionEventInternal(MotionEvent event, MotionEvent rawEvent, int policyFlags);

    /**
     * Called when the shortcut target is magnification.
     */
@@ -75,7 +146,6 @@ public abstract class MagnificationGestureHandler extends BaseEventStreamTransfo
     * Indicates the magnification mode.
     *
     * @return the magnification mode of the handler
     *
     * @see android.provider.Settings.Secure#ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN
     * @see android.provider.Settings.Secure#ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW
     */
+16 −58
Original line number Diff line number Diff line
@@ -27,7 +27,6 @@ import android.annotation.Nullable;
import android.content.Context;
import android.graphics.Point;
import android.provider.Settings;
import android.util.Log;
import android.util.MathUtils;
import android.util.Slog;
import android.view.Display;
@@ -38,9 +37,7 @@ import com.android.server.accessibility.EventStreamTransformation;
import com.android.server.accessibility.gestures.MultiTap;
import com.android.server.accessibility.gestures.MultiTapAndHold;

import java.util.ArrayDeque;
import java.util.List;
import java.util.Queue;

/**
 * This class handles window magnification in response to touch events and shortcut.
@@ -64,12 +61,9 @@ import java.util.Queue;
 */
@SuppressWarnings("WeakerAccess")
public class WindowMagnificationGestureHandler extends MagnificationGestureHandler {
    private static final String LOG_TAG = "WindowMagnificationGestureHandler";

    private static final boolean DEBUG_ALL = Log.isLoggable(LOG_TAG, Log.DEBUG);
    private static final boolean DEBUG_STATE_TRANSITIONS = false | DEBUG_ALL;
    private static final boolean DEBUG_DETECTING = false | DEBUG_ALL;
    private static final boolean DEBUG_EVENT_STREAM = false | DEBUG_ALL;

    //Ensure the range has consistency with FullScreenMagnificationGestureHandler.
    private static final float MIN_SCALE = 2.0f;
@@ -92,22 +86,20 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl
    private final Context mContext;
    private final Point mTempPoint = new Point();

    private final Queue<MotionEvent> mDebugOutputEventHistory;

    public WindowMagnificationGestureHandler(Context context,
            WindowMagnificationManager windowMagnificationMgr,
            ScaleChangedListener listener,
            boolean detectTripleTap, boolean detectShortcutTrigger, int displayId) {
        super(displayId, detectTripleTap, detectShortcutTrigger, listener);
        if (DEBUG_ALL) {
            Slog.i(LOG_TAG,
            Slog.i(mLogTag,
                    "WindowMagnificationGestureHandler() , displayId = " + displayId + ")");
        }
        mContext = context;
        mWindowMagnificationMgr = windowMagnificationMgr;
        mMotionEventDispatcherDelegate = new MotionEventDispatcherDelegate(context,
                (event, rawEvent, policyFlags) -> super.onMotionEvent(
                        event, rawEvent, policyFlags));
                (event, rawEvent, policyFlags) -> dispatchTransformedEvent(event, rawEvent,
                        policyFlags));
        mDelegatingState = new DelegatingState(mMotionEventDispatcherDelegate);
        mDetectingState = new DetectingState(context, mDetectTripleTap);
        mObservePanningScalingState = new PanningScalingGestureState(
@@ -132,25 +124,15 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl
                            }
                        }));

        mDebugOutputEventHistory = DEBUG_EVENT_STREAM ? new ArrayDeque<>() : null;

        transitionTo(mDetectingState);
    }

    @Override
    public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
        if (DEBUG_ALL) {
            Slog.i(LOG_TAG, "onMotionEvent(" + event + ")");
        }
        if (!event.isFromSource(SOURCE_TOUCHSCREEN)) {
            dispatchTransformedEvent(event, rawEvent, policyFlags);
            return;
        } else {
    void onMotionEventInternal(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
        // To keep InputEventConsistencyVerifiers within GestureDetectors happy.
        mObservePanningScalingState.mPanningScalingHandler.onTouchEvent(event);
        mCurrentState.onMotionEvent(event, rawEvent, policyFlags);
    }
    }

    @Override
    public void clearEvents(int inputSource) {
@@ -163,7 +145,7 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl
    @Override
    public void onDestroy() {
        if (DEBUG_ALL) {
            Slog.i(LOG_TAG, "onDestroy(); delayed = "
            Slog.i(mLogTag, "onDestroy(); delayed = "
                    + mDetectingState.toString());
        }
        mWindowMagnificationMgr.disableWindowMagnification(mDisplayId, true);
@@ -173,7 +155,7 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl
    @Override
    public void notifyShortcutTriggered() {
        if (DEBUG_ALL) {
            Slog.i(LOG_TAG, "notifyShortcutTriggered():");
            Slog.i(mLogTag, "notifyShortcutTriggered():");
        }
        if (!mDetectShortcutTrigger) {
            return;
@@ -195,7 +177,7 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl

    private void enableWindowMagnifier(float centerX, float centerY) {
        if (DEBUG_ALL) {
            Slog.i(LOG_TAG, "enableWindowMagnifier :" + centerX + ", " + centerY);
            Slog.i(mLogTag, "enableWindowMagnifier :" + centerX + ", " + centerY);
        }

        final float scale = MathUtils.constrain(
@@ -206,7 +188,7 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl

    private void disableWindowMagnifier() {
        if (DEBUG_ALL) {
            Slog.i(LOG_TAG, "disableWindowMagnifier()");
            Slog.i(mLogTag, "disableWindowMagnifier()");
        }
        mWindowMagnificationMgr.disableWindowMagnification(mDisplayId, false);
    }
@@ -221,7 +203,7 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl

    private void onTripleTap(MotionEvent up) {
        if (DEBUG_DETECTING) {
            Slog.i(LOG_TAG, "onTripleTap()");
            Slog.i(mLogTag, "onTripleTap()");
        }
        toggleMagnification(up.getX(), up.getY());
    }
@@ -230,30 +212,6 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl
        transitionTo(mDetectingState);
    }

    private void dispatchTransformedEvent(MotionEvent event, MotionEvent rawEvent,
            int policyFlags) {
        if (DEBUG_EVENT_STREAM) {
            storeEventInto(mDebugOutputEventHistory, event);
            try {
                super.onMotionEvent(event, rawEvent, policyFlags);
            } catch (Exception e) {
                throw new RuntimeException(
                        "Exception downstream following input events: " + mDebugOutputEventHistory,
                        e);
            }
        } else {
            super.onMotionEvent(event, rawEvent, policyFlags);
        }
    }

    private static void storeEventInto(Queue<MotionEvent> queue, MotionEvent event) {
        queue.add(MotionEvent.obtain(event));
        // Prune old events.
        while (!queue.isEmpty() && (event.getEventTime() - queue.peek().getEventTime() > 5000)) {
            queue.remove().recycle();
        }
    }

    /**
     * An interface to intercept the {@link MotionEvent} for gesture detection. The intercepted
     * events should be delivered to next {@link EventStreamTransformation} with {
@@ -283,7 +241,7 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl

    private void transitionTo(State state) {
        if (DEBUG_STATE_TRANSITIONS) {
            Slog.i(LOG_TAG, "state transition: " + (State.nameOf(mCurrentState) + " -> "
            Slog.i(mLogTag, "state transition: " + (State.nameOf(mCurrentState) + " -> "
                    + State.nameOf(state) + " at "
                    + asList(copyOfRange(new RuntimeException().getStackTrace(), 1, 5)))
                    .replace(getClass().getName(), ""));
@@ -441,10 +399,10 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl
                List<MotionEventInfo> delayedEventQueue,
                MotionEvent motionEvent) {
            if (DEBUG_DETECTING) {
                Slog.d(LOG_TAG, "onGestureDetected : gesture = "
                Slog.d(mLogTag, "onGestureDetected : gesture = "
                        + MagnificationGestureMatcher.gestureIdToString(
                        gestureId));
                Slog.d(LOG_TAG,
                Slog.d(mLogTag,
                        "onGestureDetected : delayedEventQueue = " + delayedEventQueue);
            }
            if (gestureId == MagnificationGestureMatcher.GESTURE_TWO_FINGER_DOWN
@@ -464,7 +422,7 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl
                List<MotionEventInfo> delayedEventQueue,
                MotionEvent motionEvent) {
            if (DEBUG_DETECTING) {
                Slog.d(LOG_TAG,
                Slog.d(mLogTag,
                        "onGestureCancelled : delayedEventQueue = " + delayedEventQueue);
            }
            mMotionEventDispatcherDelegate.sendDelayedMotionEvents(delayedEventQueue,