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

Commit e7a9ae8b authored by Michael Wright's avatar Michael Wright
Browse files

Add touch navigation input source

Bug: 8276741
Change-Id: I674b9804bf9ae76d694ae7073b54a7d43474a43c
parent 74e4156e
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -24171,6 +24171,7 @@ package android.view {
    field public static final int SOURCE_CLASS_BUTTON = 1; // 0x1
    field public static final int SOURCE_CLASS_JOYSTICK = 16; // 0x10
    field public static final int SOURCE_CLASS_MASK = 255; // 0xff
    field public static final int SOURCE_CLASS_NONE = 0; // 0x0
    field public static final int SOURCE_CLASS_POINTER = 2; // 0x2
    field public static final int SOURCE_CLASS_POSITION = 8; // 0x8
    field public static final int SOURCE_CLASS_TRACKBALL = 4; // 0x4
@@ -24182,6 +24183,7 @@ package android.view {
    field public static final int SOURCE_STYLUS = 16386; // 0x4002
    field public static final int SOURCE_TOUCHPAD = 1048584; // 0x100008
    field public static final int SOURCE_TOUCHSCREEN = 4098; // 0x1002
    field public static final int SOURCE_TOUCH_NAVIGATION = 2097152; // 0x200000
    field public static final int SOURCE_TRACKBALL = 65540; // 0x10004
    field public static final int SOURCE_UNKNOWN = 0; // 0x0
  }
+19 −1
Original line number Diff line number Diff line
@@ -63,6 +63,13 @@ public final class InputDevice implements Parcelable {
     */
    public static final int SOURCE_CLASS_MASK = 0x000000ff;

    /**
     * The input source has no class.
     *
     * It is up to the application to determine how to handle the device based on the device type.
     */
    public static final int SOURCE_CLASS_NONE = 0x00000000;

    /**
     * The input source has buttons or keys.
     * Examples: {@link #SOURCE_KEYBOARD}, {@link #SOURCE_DPAD}.
@@ -201,6 +208,17 @@ public final class InputDevice implements Parcelable {
     */
    public static final int SOURCE_TOUCHPAD = 0x00100000 | SOURCE_CLASS_POSITION;

    /**
     * The input source is a touch device whose motions should be interpreted as navigation events.
     *
     * For example, an upward swipe should be as an upward focus traversal in the same manner as
     * pressing up on a D-Pad would be. Swipes to the left, right and down should be treated in a
     * similar manner.
     *
     * @see #SOURCE_CLASS_NONE
     */
    public static final int SOURCE_TOUCH_NAVIGATION = 0x00200000 | SOURCE_CLASS_NONE;

    /**
     * The input source is a joystick.
     * (It may also be a {@link #SOURCE_GAMEPAD}).
+35 −35
Original line number Diff line number Diff line
@@ -28,7 +28,7 @@ import android.os.UserHandle;
import android.util.Log;

/**
 * This class creates DPAD events from touchpad events.
 * This class creates DPAD events from TouchNavigation events.
 * 
 * @see ViewRootImpl
 */
@@ -47,18 +47,18 @@ class SimulatedDpad {
    private static final int MSG_FLICK = 313;
    // TODO: Pass touch slop from the input device
    private static final int TOUCH_SLOP = 30;
    // The position of the previous touchpad event
    private float mLastTouchpadXPosition;
    private float mLastTouchpadYPosition;
    // Where the touchpad was initially pressed
    private float mTouchpadEnterXPosition;
    private float mTouchpadEnterYPosition;
    // The position of the previous TouchNavigation event
    private float mLastTouchNavigationXPosition;
    private float mLastTouchNavigationYPosition;
    // Where the Touch Navigation was initially pressed
    private float mTouchNavigationEnterXPosition;
    private float mTouchNavigationEnterYPosition;
    // When the most recent ACTION_HOVER_ENTER occurred
    private long mLastTouchPadStartTimeMs = 0;
    private long mLastTouchNavigationStartTimeMs = 0;
    // When the most recent direction key was sent
    private long mLastTouchPadKeySendTimeMs = 0;
    private long mLastTouchNavigationKeySendTimeMs = 0;
    // When the most recent touch event of any type occurred
    private long mLastTouchPadEventTimeMs = 0;
    private long mLastTouchNavigationEventTimeMs = 0;
    // Did the swipe begin in a valid region
    private boolean mEdgeSwipePossible;

@@ -140,7 +140,7 @@ class SimulatedDpad {
        }
    };

    public void updateTouchPad(ViewRootImpl viewroot, MotionEvent event,
    public void updateTouchNavigation(ViewRootImpl viewroot, MotionEvent event,
            boolean synthesizeNewKeys) {
        if (!synthesizeNewKeys) {
            mHandler.removeMessages(MSG_FLICK);
@@ -149,14 +149,14 @@ class SimulatedDpad {
        if (device == null) {
            return;
        }
        // Store what time the touchpad event occurred
        // Store what time the TouchNavigation event occurred
        final long time = SystemClock.uptimeMillis();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mLastTouchPadStartTimeMs = time;
                mLastTouchNavigationStartTimeMs = time;
                mAlwaysInTapRegion = true;
                mTouchpadEnterXPosition = event.getX();
                mTouchpadEnterYPosition = event.getY();
                mTouchNavigationEnterXPosition = event.getX();
                mTouchNavigationEnterYPosition = event.getY();
                mAccumulatedX = 0;
                mAccumulatedY = 0;
                mLastMoveX = 0;
@@ -173,8 +173,8 @@ class SimulatedDpad {
                break;
            case MotionEvent.ACTION_MOVE:
                // Determine whether the move is slop or an intentional move
                float deltaX = event.getX() - mTouchpadEnterXPosition;
                float deltaY = event.getY() - mTouchpadEnterYPosition;
                float deltaX = event.getX() - mTouchNavigationEnterXPosition;
                float deltaY = event.getY() - mTouchNavigationEnterYPosition;
                if (mTouchSlopSquared < deltaX * deltaX + deltaY * deltaY) {
                    mAlwaysInTapRegion = false;
                }
@@ -199,9 +199,9 @@ class SimulatedDpad {
                    }
                }
                // Find the difference in position between the two most recent
                // touchpad events
                mLastMoveX = event.getX() - mLastTouchpadXPosition;
                mLastMoveY = event.getY() - mLastTouchpadYPosition;
                // TouchNavigation events
                mLastMoveX = event.getX() - mLastTouchNavigationXPosition;
                mLastMoveY = event.getY() - mLastTouchNavigationYPosition;
                mAccumulatedX += mLastMoveX;
                mAccumulatedY += mLastMoveY;
                float mAccumulatedXSquared = mAccumulatedX * mAccumulatedX;
@@ -251,19 +251,19 @@ class SimulatedDpad {
                    mAccumulatedY = isXAxis ? 0 : dominantAxis;

                    mLastKeySent = key;
                    mKeySendRateMs = (int) ((time - mLastTouchPadKeySendTimeMs) / repeatCount);
                    mLastTouchPadKeySendTimeMs = time;
                    mKeySendRateMs = (int) (time - mLastTouchNavigationKeySendTimeMs) / repeatCount;
                    mLastTouchNavigationKeySendTimeMs = time;
                }
                break;
            case MotionEvent.ACTION_UP:
                if (time - mLastTouchPadStartTimeMs < MAX_TAP_TIME && mAlwaysInTapRegion) {
                if (time - mLastTouchNavigationStartTimeMs < MAX_TAP_TIME && mAlwaysInTapRegion) {
                    if (synthesizeNewKeys) {
                        viewroot.enqueueInputEvent(new KeyEvent(mLastTouchPadStartTimeMs, time,
                                KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_CENTER, 0,
                        viewroot.enqueueInputEvent(new KeyEvent(mLastTouchNavigationStartTimeMs,
                                    time, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_CENTER, 0,
                                    event.getMetaState(), event.getDeviceId(), 0,
                                    KeyEvent.FLAG_FALLBACK, event.getSource()));
                        viewroot.enqueueInputEvent(new KeyEvent(mLastTouchPadStartTimeMs, time,
                                KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_CENTER, 0,
                        viewroot.enqueueInputEvent(new KeyEvent(mLastTouchNavigationStartTimeMs,
                                    time, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_CENTER, 0,
                                    event.getMetaState(), event.getDeviceId(), 0,
                                    KeyEvent.FLAG_FALLBACK, event.getSource()));
                    }
@@ -272,7 +272,7 @@ class SimulatedDpad {
                    float yMoveSquared = mLastMoveY * mLastMoveY;
                    // Determine whether the last gesture was a fling.
                    if (mMinFlickDistanceSquared <= xMoveSquared + yMoveSquared &&
                            time - mLastTouchPadEventTimeMs <= MAX_TAP_TIME &&
                            time - mLastTouchNavigationEventTimeMs <= MAX_TAP_TIME &&
                            mKeySendRateMs <= mMaxRepeatDelay && mKeySendRateMs > 0) {
                        mLastDeviceId = event.getDeviceId();
                        mLastSource = event.getSource();
@@ -291,8 +291,8 @@ class SimulatedDpad {
        }

        // Store touch event position and time
        mLastTouchPadEventTimeMs = time;
        mLastTouchpadXPosition = event.getX();
        mLastTouchpadYPosition = event.getY();
        mLastTouchNavigationEventTimeMs = time;
        mLastTouchNavigationXPosition = event.getX();
        mLastTouchNavigationYPosition = event.getY();
    }
}
+8 −8
Original line number Diff line number Diff line
@@ -3559,15 +3559,15 @@ public final class ViewRootImpl implements ViewParent,
    private int deliverGenericMotionEventPostIme(QueuedInputEvent q) {
        final MotionEvent event = (MotionEvent) q.mEvent;
        final int source = event.getSource();
        final boolean isJoystick = (source & InputDevice.SOURCE_CLASS_JOYSTICK) != 0;
        final boolean isTouchPad = (source & InputDevice.SOURCE_CLASS_POSITION) != 0;
        final boolean isJoystick = event.isFromSource(InputDevice.SOURCE_CLASS_JOYSTICK);
        final boolean isTouchNavigation = event.isFromSource(InputDevice.SOURCE_TOUCH_NAVIGATION);

        // If there is no view, then the event will not be handled.
        if (mView == null || !mAdded) {
            if (isJoystick) {
                updateJoystickDirection(event, false);
            } else if (isTouchPad) {
              mSimulatedDpad.updateTouchPad(this, event, false);
            } else if (isTouchNavigation) {
                mSimulatedDpad.updateTouchNavigation(this, event, false);
            }
            return EVENT_NOT_HANDLED;
        }
@@ -3576,8 +3576,8 @@ public final class ViewRootImpl implements ViewParent,
        if (mView.dispatchGenericMotionEvent(event)) {
            if (isJoystick) {
                updateJoystickDirection(event, false);
            } else if (isTouchPad) {
              mSimulatedDpad.updateTouchPad(this, event, false);
            } else if (isTouchNavigation) {
                mSimulatedDpad.updateTouchNavigation(this, event, false);
            }
            return EVENT_HANDLED;
        }
@@ -3588,8 +3588,8 @@ public final class ViewRootImpl implements ViewParent,
            updateJoystickDirection(event, true);
            return EVENT_HANDLED;
        }
        if (isTouchPad) {
            mSimulatedDpad.updateTouchPad(this, event, true);
        if (isTouchNavigation) {
            mSimulatedDpad.updateTouchNavigation(this, event, true);
            return EVENT_HANDLED;
        }
        return EVENT_NOT_HANDLED;
+8 −0
Original line number Diff line number Diff line
@@ -2788,6 +2788,8 @@ void TouchInputMapper::configureParameters() {
            mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_SCREEN;
        } else if (deviceTypeString == "touchPad") {
            mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_PAD;
        } else if (deviceTypeString == "touchNavigation") {
            mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_NAVIGATION;
        } else if (deviceTypeString == "pointer") {
            mParameters.deviceType = Parameters::DEVICE_TYPE_POINTER;
        } else if (deviceTypeString != "default") {
@@ -2832,6 +2834,9 @@ void TouchInputMapper::dumpParameters(String8& dump) {
    case Parameters::DEVICE_TYPE_TOUCH_PAD:
        dump.append(INDENT4 "DeviceType: touchPad\n");
        break;
    case Parameters::DEVICE_TYPE_TOUCH_NAVIGATION:
        dump.append(INDENT4 "DeviceType: touchNavigation\n");
        break;
    case Parameters::DEVICE_TYPE_POINTER:
        dump.append(INDENT4 "DeviceType: pointer\n");
        break;
@@ -2885,6 +2890,9 @@ void TouchInputMapper::configureSurface(nsecs_t when, bool* outResetNeeded) {
        if (hasStylus()) {
            mSource |= AINPUT_SOURCE_STYLUS;
        }
    } else if (mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_NAVIGATION) {
        mSource = AINPUT_SOURCE_TOUCH_NAVIGATION;
        mDeviceMode = DEVICE_MODE_UNSCALED;
    } else {
        mSource = AINPUT_SOURCE_TOUCHPAD;
        mDeviceMode = DEVICE_MODE_UNSCALED;
Loading