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

Commit e6e55b53 authored by Eugene Susla's avatar Eugene Susla
Browse files

Fix inconsistent MagnificationGestureHandler state after delegation

Fixes: 71863482
Test: ensure attached bug no longer reproduces
Change-Id: I223484caefa01dd15066797e53a2f21607ee162d
parent fc027600
Loading
Loading
Loading
Loading
+30 −15
Original line number Diff line number Diff line
@@ -26,6 +26,8 @@ import android.util.SparseArray;
import dalvik.annotation.optimization.CriticalNative;
import dalvik.annotation.optimization.FastNative;

import java.util.Objects;

/**
 * Object used to report movement (mouse, pen, finger, trackball) events.
 * Motion events may hold either absolute or relative movements and other data,
@@ -173,6 +175,8 @@ public final class MotionEvent extends InputEvent implements Parcelable {
    private static final long NS_PER_MS = 1000000;
    private static final String LABEL_PREFIX = "AXIS_";

    private static final boolean DEBUG_CONCISE_TOSTRING = false;

    /**
     * An invalid pointer id.
     *
@@ -3236,31 +3240,42 @@ public final class MotionEvent extends InputEvent implements Parcelable {
    public String toString() {
        StringBuilder msg = new StringBuilder();
        msg.append("MotionEvent { action=").append(actionToString(getAction()));
        msg.append(", actionButton=").append(buttonStateToString(getActionButton()));
        appendUnless("0", msg, ", actionButton=", buttonStateToString(getActionButton()));

        final int pointerCount = getPointerCount();
        for (int i = 0; i < pointerCount; i++) {
            msg.append(", id[").append(i).append("]=").append(getPointerId(i));
            msg.append(", x[").append(i).append("]=").append(getX(i));
            msg.append(", y[").append(i).append("]=").append(getY(i));
            msg.append(", toolType[").append(i).append("]=").append(
                    toolTypeToString(getToolType(i)));
        }

        msg.append(", buttonState=").append(MotionEvent.buttonStateToString(getButtonState()));
        msg.append(", metaState=").append(KeyEvent.metaStateToString(getMetaState()));
        msg.append(", flags=0x").append(Integer.toHexString(getFlags()));
        msg.append(", edgeFlags=0x").append(Integer.toHexString(getEdgeFlags()));
        msg.append(", pointerCount=").append(pointerCount);
        msg.append(", historySize=").append(getHistorySize());
            appendUnless(i, msg, ", id[" + i + "]=", getPointerId(i));
            float x = getX(i);
            float y = getY(i);
            if (!DEBUG_CONCISE_TOSTRING || x != 0f || y != 0f) {
                msg.append(", x[").append(i).append("]=").append(x);
                msg.append(", y[").append(i).append("]=").append(y);
            }
            appendUnless(TOOL_TYPE_SYMBOLIC_NAMES.get(TOOL_TYPE_FINGER),
                    msg, ", toolType[" + i + "]=", toolTypeToString(getToolType(i)));
        }

        appendUnless("0", msg, ", buttonState=", MotionEvent.buttonStateToString(getButtonState()));
        appendUnless("0", msg, ", metaState=", KeyEvent.metaStateToString(getMetaState()));
        appendUnless("0", msg, ", flags=0x", Integer.toHexString(getFlags()));
        appendUnless("0", msg, ", edgeFlags=0x", Integer.toHexString(getEdgeFlags()));
        appendUnless(1, msg, ", pointerCount=", pointerCount);
        appendUnless(0, msg, ", historySize=", getHistorySize());
        msg.append(", eventTime=").append(getEventTime());
        if (!DEBUG_CONCISE_TOSTRING) {
            msg.append(", downTime=").append(getDownTime());
            msg.append(", deviceId=").append(getDeviceId());
            msg.append(", source=0x").append(Integer.toHexString(getSource()));
        }
        msg.append(" }");
        return msg.toString();
    }

    private static <T> void appendUnless(T defValue, StringBuilder sb, String key, T value) {
        if (DEBUG_CONCISE_TOSTRING && Objects.equals(defValue, value)) return;
        sb.append(key).append(value);
    }

    /**
     * Returns a string that represents the symbolic name of the specified unmasked action
     * such as "ACTION_DOWN", "ACTION_POINTER_DOWN(3)" or an equivalent numeric constant
+50 −1
Original line number Diff line number Diff line
@@ -52,6 +52,9 @@ import android.view.ViewConfiguration;

import com.android.internal.annotations.VisibleForTesting;

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

/**
 * This class handles magnification in response to touch events.
 *
@@ -108,6 +111,7 @@ class MagnificationGestureHandler extends BaseEventStreamTransformation {
    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;

    private static final float MIN_SCALE = 2.0f;
    private static final float MAX_SCALE = 5.0f;
@@ -139,6 +143,9 @@ class MagnificationGestureHandler extends BaseEventStreamTransformation {
    private PointerCoords[] mTempPointerCoords;
    private PointerProperties[] mTempPointerProperties;

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

    /**
     * @param context Context for resolving various magnification-related resources
     * @param magnificationController the {@link MagnificationController}
@@ -171,11 +178,28 @@ class MagnificationGestureHandler extends BaseEventStreamTransformation {
            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)
@@ -265,8 +289,28 @@ class MagnificationGestureHandler extends BaseEventStreamTransformation {
                    coords, 0, 0, 1.0f, 1.0f, event.getDeviceId(), 0, event.getSource(),
                    event.getFlags());
        }
        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;
@@ -536,6 +580,9 @@ class MagnificationGestureHandler extends BaseEventStreamTransformation {

        @Override
        public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) {

        	// Ensure that the state at the end of delegation is consistent with the last delegated
            // UP/DOWN event in queue: still delegating if pointer is down, detecting otherwise
            switch (event.getActionMasked()) {
                case ACTION_UP:
                case ACTION_CANCEL: {
@@ -543,9 +590,11 @@ class MagnificationGestureHandler extends BaseEventStreamTransformation {
                } break;

                case ACTION_DOWN: {
                	transitionTo(mDelegatingState);
                    mLastDelegatedDownEventTime = event.getDownTime();
                } break;
            }

            if (getNext() != null) {
                // We cache some events to see if the user wants to trigger magnification.
                // If no magnification is triggered we inject these events with adjusted