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

Commit 4e2aa36c authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes from topic "refactoring"

* changes:
  Refactoring for magnification [2/n]
  Refactoring for magnification [1/n]
parents a9c6b43a a8c9dd08
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -558,12 +558,13 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo
        if (mAms.getMagnificationMode(displayId)
                == Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW) {
            magnificationGestureHandler = new WindowMagnificationGestureHandler(displayContext,
                    mAms.getWindowMagnificationMgr(), mAms::onMagnificationScaleChanged,
                    detectControlGestures, triggerable, displayId);
                    mAms.getWindowMagnificationMgr(), mAms.getMagnificationController(),
                    detectControlGestures, triggerable,
                    displayId);
        } else {
            magnificationGestureHandler = new FullScreenMagnificationGestureHandler(displayContext,
                    mAms.getFullScreenMagnificationController(),
                    mAms::onMagnificationScaleChanged, detectControlGestures, triggerable,
                    mAms.getFullScreenMagnificationController(), mAms.getMagnificationController(),
                    detectControlGestures, triggerable,
                    new WindowMagnificationPromptController(displayContext, mUserId), displayId);
        }
        return magnificationGestureHandler;
+12 −13
Original line number Diff line number Diff line
@@ -119,7 +119,6 @@ import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.accessibility.magnification.FullScreenMagnificationController;
import com.android.server.accessibility.magnification.MagnificationController;
import com.android.server.accessibility.magnification.MagnificationGestureHandler;
import com.android.server.accessibility.magnification.WindowMagnificationManager;
import com.android.server.pm.UserManagerInternal;
import com.android.server.wm.ActivityTaskManagerInternal;
@@ -153,7 +152,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
        AccessibilityUserState.ServiceInfoChangeListener,
        AccessibilityWindowManager.AccessibilityEventSender,
        AccessibilitySecurityPolicy.AccessibilityUserManager,
        MagnificationGestureHandler.ScaleChangedListener,
        SystemActionPerformer.SystemActionsChangedListener {

    private static final boolean DEBUG = false;
@@ -1066,17 +1064,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
        }
    }

    @Override
    public void onMagnificationScaleChanged(int displayId, int mode) {
        synchronized (mLock) {
            final int capabilities =
                    getCurrentUserStateLocked().getMagnificationCapabilitiesLocked();
            if (capabilities == Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL) {
                getWindowMagnificationMgr().showMagnificationButton(displayId, mode);
            }
        }
    }

    /**
     * Called by AccessibilityInputFilter when it creates or destroys the motionEventInjector.
     * Not using a getter because the AccessibilityInputFilter isn't thread-safe
@@ -3000,6 +2987,17 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
        }
    }

    /**
     * Getter of {@link MagnificationController}.
     *
     * @return MagnificationController
     */
    MagnificationController getMagnificationController() {
        synchronized (mLock) {
            return mMagnificationController;
        }
    }

    @Override
    public void associateEmbeddedHierarchy(@NonNull IBinder host, @NonNull IBinder embedded) {
        synchronized (mLock) {
@@ -3584,6 +3582,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
                Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN, userState.mUserId);
        if (capabilities != userState.getMagnificationCapabilitiesLocked()) {
            userState.setMagnificationCapabilitiesLocked(capabilities);
            mMagnificationController.setMagnificationCapabilities(capabilities);
            return true;
        }
        return false;
+12 −100
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
@@ -139,41 +133,12 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
    private final ScreenStateReceiver mScreenStateReceiver;
    private final WindowMagnificationPromptController mPromptController;

    /**
     * {@code true} if this detector should detect and respond to triple-tap
     * gestures for engaging and disengaging magnification,
     * {@code false} if it should ignore such gestures
     */
    final boolean mDetectTripleTap;

    /**
     * Whether {@link DetectingState#mShortcutTriggered shortcut} is enabled
     */
    final boolean mDetectShortcutTrigger;

    @VisibleForTesting State mCurrentState;
    @VisibleForTesting State mPreviousState;

    private PointerCoords[] mTempPointerCoords;
    private PointerProperties[] mTempPointerProperties;

    private final int mDisplayId;

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

    /**
     * @param context Context for resolving various magnification-related resources
     * @param fullScreenMagnificationController the {@link FullScreenMagnificationController}
     *
     * @param detectTripleTap {@code true} if this detector should detect and respond to triple-tap
     *                                gestures for engaging and disengaging magnification,
     *                                {@code false} if it should ignore such gestures
     * @param detectShortcutTrigger {@code true} if this detector should be "triggerable" by some
     *                           external shortcut invoking {@link #notifyShortcutTriggered},
     *                           {@code false} if it should ignore such triggers.
     * @param displayId The logical display id.
     */
    public FullScreenMagnificationGestureHandler(Context context,
            FullScreenMagnificationController fullScreenMagnificationController,
            ScaleChangedListener listener,
@@ -181,23 +146,20 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
            boolean detectShortcutTrigger,
            @NonNull WindowMagnificationPromptController promptController,
            int displayId) {
        super(listener);
        super(displayId, detectTripleTap, detectShortcutTrigger, listener);
        if (DEBUG_ALL) {
            Log.i(LOG_TAG,
            Log.i(mLogTag,
                    "FullScreenMagnificationGestureHandler(detectTripleTap = " + detectTripleTap
                            + ", detectShortcutTrigger = " + detectShortcutTrigger + ")");
        }
        mFullScreenMagnificationController = fullScreenMagnificationController;
        mPromptController = promptController;
        mDisplayId = displayId;

        mDelegatingState = new DelegatingState();
        mDetectingState = new DetectingState(context);
        mViewportDraggingState = new ViewportDraggingState();
        mPanningScalingState = new PanningScalingState(context);

        mDetectTripleTap = detectTripleTap;
        mDetectShortcutTrigger = detectShortcutTrigger;
        if (mDetectShortcutTrigger) {
            mScreenStateReceiver = new ScreenStateReceiver(context, this);
            mScreenStateReceiver.register();
@@ -205,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);
    }

@@ -259,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));
        }

@@ -299,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) {
@@ -358,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(), ""));
@@ -440,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,
@@ -480,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());
@@ -945,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();
@@ -965,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 =
@@ -997,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);
@@ -1030,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(),
@@ -1042,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);
    }

+16 −2
Original line number Diff line number Diff line
@@ -37,7 +37,8 @@ import com.android.server.accessibility.AccessibilityManagerService;
 * Handles all magnification controllers initialization, generic interactions
 * and magnification mode transition.
 */
public class MagnificationController implements WindowMagnificationManager.Callback {
public class MagnificationController implements WindowMagnificationManager.Callback,
        MagnificationGestureHandler.ScaleChangedListener {

    private static final boolean DEBUG = false;
    private static final String TAG = "MagnificationController";
@@ -50,6 +51,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb

    private FullScreenMagnificationController mFullScreenMagnificationController;
    private WindowMagnificationManager mWindowMagnificationMgr;
    private int mMagnificationCapabilities = ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;

    /**
     * A callback to inform the magnification transition result.
@@ -82,10 +84,18 @@ public class MagnificationController implements WindowMagnificationManager.Callb
    public void onPerformScaleAction(int displayId, float scale) {
        getWindowMagnificationMgr().setScale(displayId, scale);
        getWindowMagnificationMgr().persistScale(displayId);
        mAms.onMagnificationScaleChanged(displayId,
        onMagnificationScaleChanged(displayId,
                Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
    }

    @Override
    public void onMagnificationScaleChanged(int displayId, int mode) {
        if (mMagnificationCapabilities != Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL) {
            return;
        }
        getWindowMagnificationMgr().showMagnificationButton(displayId, mode);
    }

    /**
     * Transitions to the target Magnification mode with current center of the magnification mode
     * if it is available.
@@ -182,6 +192,10 @@ public class MagnificationController implements WindowMagnificationManager.Callb
        }
    }

    public void setMagnificationCapabilities(int capabilities) {
        mMagnificationCapabilities = capabilities;
    }

    private DisableMagnificationCallback getDisableMagnificationEndRunnableLocked(
            int displayId) {
        return mMagnificationEndRunnableSparseArray.get(displayId);
+101 −7
Original line number Diff line number Diff line
@@ -16,22 +16,50 @@

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 ScaleChangedListener mListener;
    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;

    protected MagnificationGestureHandler(ScaleChangedListener listener) {
        mListener = listener;
    }
    /**
     * The logical display id.
     */
    protected final int mDisplayId;

    /**
     * Interface for listening to the magnification scaling gesture.
     * {@code true} if this detector should be "triggerable" by some
     * external shortcut invoking {@link #notifyShortcutTriggered},
     * {@code false} if it should ignore such triggers.
     */
    protected final boolean mDetectShortcutTrigger;

    /**
     * {@code true} if this detector should detect and respond to triple-tap
     * gestures for engaging and disengaging magnification,
     * {@code false} if it should ignore such gestures
     */
    protected final boolean mDetectTripleTap;

    /** Interface for listening to the magnification scaling gesture. */
    public interface ScaleChangedListener {
        /**
         * Called when the magnification scale is changed by users.
@@ -42,6 +70,73 @@ public abstract class MagnificationGestureHandler extends BaseEventStreamTransfo
        void onMagnificationScaleChanged(int displayId, int mode);
    }

    protected final ScaleChangedListener mListener;

    protected MagnificationGestureHandler(int displayId, boolean detectTripleTap,
            boolean detectShortcutTrigger,
            @NonNull ScaleChangedListener listener) {
        mDisplayId = displayId;
        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.
     */
@@ -51,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
     */
Loading