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

Commit ad97b5e9 authored by Asmita Poddar's avatar Asmita Poddar
Browse files

Add left/ right scrolling for mouse keys

Earlier we could only scroll up and down if the scroll toggle was on
for mouse keys. This CL adds the ability to scroll left and right
when the scroll toggle is on.

Bug: 341799888
Test: atest FrameworksServicesTests:MouseKeysInterceptorTest
Flag: EXEMPT bugfix
Change-Id: I75025a39bc9a67015664475e0f2abaeb9e026d8f
parent 93be8227
Loading
Loading
Loading
Loading
+44 −20
Original line number Diff line number Diff line
@@ -138,8 +138,8 @@ public class MouseKeysInterceptor extends BaseEventStreamTransformation
        DIAGONAL_UP_LEFT_MOVE(KeyEvent.KEYCODE_7),
        UP_MOVE_OR_SCROLL(KeyEvent.KEYCODE_8),
        DIAGONAL_UP_RIGHT_MOVE(KeyEvent.KEYCODE_9),
        LEFT_MOVE(KeyEvent.KEYCODE_U),
        RIGHT_MOVE(KeyEvent.KEYCODE_O),
        LEFT_MOVE_OR_SCROLL(KeyEvent.KEYCODE_U),
        RIGHT_MOVE_OR_SCROLL(KeyEvent.KEYCODE_O),
        DIAGONAL_DOWN_LEFT_MOVE(KeyEvent.KEYCODE_J),
        DOWN_MOVE_OR_SCROLL(KeyEvent.KEYCODE_K),
        DIAGONAL_DOWN_RIGHT_MOVE(KeyEvent.KEYCODE_L),
@@ -267,6 +267,16 @@ public class MouseKeysInterceptor extends BaseEventStreamTransformation
        );
    }

    @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
    private void sendVirtualMouseScrollEvent(float x, float y) {
        waitForVirtualMouseCreation();
        mVirtualMouse.sendScrollEvent(new VirtualMouseScrollEvent.Builder()
                .setXAxisMovement(x)
                .setYAxisMovement(y)
                .build()
        );
    }

    /**
     * Performs a mouse scroll action based on the provided key code.
     * The scroll action will only be performed if the scroll toggle is on.
@@ -284,19 +294,31 @@ public class MouseKeysInterceptor extends BaseEventStreamTransformation
    private void performMouseScrollAction(int keyCode) {
        MouseKeyEvent mouseKeyEvent = MouseKeyEvent.from(
                keyCode, mActiveInputDeviceId, mDeviceKeyCodeMap);
        float y = switch (mouseKeyEvent) {
            case UP_MOVE_OR_SCROLL -> MOUSE_SCROLL_STEP;
            case DOWN_MOVE_OR_SCROLL -> -MOUSE_SCROLL_STEP;
            default -> 0.0f;
        };
        waitForVirtualMouseCreation();
        mVirtualMouse.sendScrollEvent(new VirtualMouseScrollEvent.Builder()
                .setYAxisMovement(y)
                .build()
        );
        float x = 0f;
        float y = 0f;

        switch (mouseKeyEvent) {
            case UP_MOVE_OR_SCROLL -> {
                y = MOUSE_SCROLL_STEP;
            }
            case DOWN_MOVE_OR_SCROLL -> {
                y = -MOUSE_SCROLL_STEP;
            }
            case LEFT_MOVE_OR_SCROLL -> {
                x = MOUSE_SCROLL_STEP;
            }
            case RIGHT_MOVE_OR_SCROLL -> {
                x = -MOUSE_SCROLL_STEP;
            }
            default -> {
                x = 0.0f;
                y = 0.0f;
            }
        }
        sendVirtualMouseScrollEvent(x, y);
        if (DEBUG) {
            Slog.d(LOG_TAG, "Performed mouse key event: " + mouseKeyEvent.name()
                    + " for scroll action with axis movement (y=" + y + ")");
                    + " for scroll action with axis movement (x=" + x + ", y=" + y + ")");
        }
    }

@@ -344,8 +366,8 @@ public class MouseKeysInterceptor extends BaseEventStreamTransformation
     * The method calculates the relative movement of the mouse pointer
     * and sends the corresponding event to the virtual mouse.
     *
     * The UP and DOWN pointer actions will only take place for their respective keys
     * if the scroll toggle is off.
     * The UP, DOWN, LEFT, RIGHT  pointer actions will only take place for their
     * respective keys if the scroll toggle is off.
     *
     * @param keyCode The key code representing the direction or button press.
     *                Supported keys are:
@@ -353,8 +375,8 @@ public class MouseKeysInterceptor extends BaseEventStreamTransformation
     *                  <li>{@link MouseKeysInterceptor.MouseKeyEvent#DIAGONAL_DOWN_LEFT_MOVE}
     *                  <li>{@link MouseKeysInterceptor.MouseKeyEvent#DOWN_MOVE_OR_SCROLL}
     *                  <li>{@link MouseKeysInterceptor.MouseKeyEvent#DIAGONAL_DOWN_RIGHT_MOVE}
     *                  <li>{@link MouseKeysInterceptor.MouseKeyEvent#LEFT_MOVE}
     *                  <li>{@link MouseKeysInterceptor.MouseKeyEvent#RIGHT_MOVE}
     *                  <li>{@link MouseKeysInterceptor.MouseKeyEvent#LEFT_MOVE_OR_SCROLL}
     *                  <li>{@link MouseKeysInterceptor.MouseKeyEvent#RIGHT_MOVE_OR_SCROLL}
     *                  <li>{@link MouseKeysInterceptor.MouseKeyEvent#DIAGONAL_UP_LEFT_MOVE}
     *                  <li>{@link MouseKeysInterceptor.MouseKeyEvent#UP_MOVE_OR_SCROLL}
     *                  <li>{@link MouseKeysInterceptor.MouseKeyEvent#DIAGONAL_UP_RIGHT_MOVE}
@@ -381,10 +403,10 @@ public class MouseKeysInterceptor extends BaseEventStreamTransformation
                x = MOUSE_POINTER_MOVEMENT_STEP / sqrt(2);
                y = MOUSE_POINTER_MOVEMENT_STEP / sqrt(2);
            }
            case LEFT_MOVE -> {
            case LEFT_MOVE_OR_SCROLL -> {
                x = -MOUSE_POINTER_MOVEMENT_STEP;
            }
            case RIGHT_MOVE -> {
            case RIGHT_MOVE_OR_SCROLL -> {
                x = MOUSE_POINTER_MOVEMENT_STEP;
            }
            case DIAGONAL_UP_LEFT_MOVE -> {
@@ -424,7 +446,9 @@ public class MouseKeysInterceptor extends BaseEventStreamTransformation

    private boolean isMouseScrollKey(int keyCode, InputDevice inputDevice) {
        return keyCode == MouseKeyEvent.UP_MOVE_OR_SCROLL.getKeyCode(inputDevice)
                || keyCode == MouseKeyEvent.DOWN_MOVE_OR_SCROLL.getKeyCode(inputDevice);
                || keyCode == MouseKeyEvent.DOWN_MOVE_OR_SCROLL.getKeyCode(inputDevice)
                || keyCode == MouseKeyEvent.LEFT_MOVE_OR_SCROLL.getKeyCode(inputDevice)
                || keyCode == MouseKeyEvent.RIGHT_MOVE_OR_SCROLL.getKeyCode(inputDevice);
    }

    /**
+21 −0
Original line number Diff line number Diff line
@@ -235,6 +235,27 @@ class MouseKeysInterceptorTest {
	    arrayOf<Float>(MouseKeysInterceptor.MOUSE_SCROLL_STEP))
    }

    @Test
    fun whenScrollToggleOn_ScrollRightKeyIsPressed_scrollEventIsSent() {
        // There should be some delay between the downTime of the key event and calling onKeyEvent
        val downTime = clock.now() - KEYBOARD_POST_EVENT_DELAY_MILLIS
        val keyCodeScrollToggle = MouseKeysInterceptor.MouseKeyEvent.SCROLL_TOGGLE.keyCodeValue
        val keyCodeScroll = MouseKeysInterceptor.MouseKeyEvent.RIGHT_MOVE_OR_SCROLL.keyCodeValue

        val scrollToggleDownEvent = KeyEvent(downTime, downTime, KeyEvent.ACTION_DOWN,
            keyCodeScrollToggle, 0, 0, DEVICE_ID, 0)
        val scrollDownEvent = KeyEvent(downTime, downTime, KeyEvent.ACTION_DOWN,
            keyCodeScroll, 0, 0, DEVICE_ID, 0)

        mouseKeysInterceptor.onKeyEvent(scrollToggleDownEvent, 0)
        mouseKeysInterceptor.onKeyEvent(scrollDownEvent, 0)
        testLooper.dispatchAll()

        // Verify the sendScrollEvent method is called once and capture the arguments
        verifyScrollEvents(arrayOf<Float>(-MouseKeysInterceptor.MOUSE_SCROLL_STEP),
	    arrayOf<Float>(0f))
    }

    @Test
    fun whenScrollToggleOff_DirectionalUpKeyIsPressed_RelativeEventIsSent() {
        // There should be some delay between the downTime of the key event and calling onKeyEvent