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

Commit e135c148 authored by Vaibhav Devmurari's avatar Vaibhav Devmurari Committed by Android (Google) Code Review
Browse files

Merge "[2/n] Mouse keys filter should not work for VDM keyboards" into main

parents cb50c1f2 44d3d9a4
Loading
Loading
Loading
Loading
+24 −9
Original line number Diff line number Diff line
@@ -648,11 +648,17 @@ public class MouseKeysInterceptor extends BaseEventStreamTransformation

    @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
    private void onKeyEventInternal(KeyEvent event, int policyFlags) {
        boolean isDown = event.getAction() == KeyEvent.ACTION_DOWN;
        int keyCode = event.getKeyCode();
        mActiveInputDeviceId = event.getDeviceId();
        InputDevice inputDevice = mInputManager.getInputDevice(mActiveInputDeviceId);
        final boolean isDown = event.getAction() == KeyEvent.ACTION_DOWN;
        final int keyCode = event.getKeyCode();
        final int deviceId = event.getDeviceId();

        InputDevice inputDevice = mInputManager.getInputDevice(deviceId);
        if (!isDeviceEligible(inputDevice)) {
            // Pass non-mouse key events to the next handler
            super.onKeyEvent(event, policyFlags);
            return;
        }
        mActiveInputDeviceId = deviceId;
        boolean usePrimaryKeys = shouldUsePrimaryKeysForDevice(inputDevice);

        if (!mDeviceKeyCodeMap.contains(mActiveInputDeviceId)) {
@@ -874,10 +880,11 @@ public class MouseKeysInterceptor extends BaseEventStreamTransformation
     */
    @Override
    public void onInputDeviceAdded(int deviceId) {
        final InputDevice device = mInputManager.getInputDevice(deviceId);
        if (device != null && device.isFullKeyboard()) {
            deviceHasNumpad(device);
        final InputDevice inputDevice = mInputManager.getInputDevice(deviceId);
        if (isDeviceEligible(inputDevice)) {
            deviceHasNumpad(inputDevice);
        }
        onInputDeviceChangedInternal(inputDevice);
    }

    @Override
@@ -896,13 +903,21 @@ public class MouseKeysInterceptor extends BaseEventStreamTransformation
    @Override
    public void onInputDeviceChanged(int deviceId) {
        InputDevice inputDevice = mInputManager.getInputDevice(deviceId);
        onInputDeviceChangedInternal(inputDevice);
    }

    private void onInputDeviceChangedInternal(@NonNull InputDevice inputDevice) {
        // Update the enum mapping only if input device that changed is a keyboard
        if (inputDevice.isFullKeyboard()) {
        if (isDeviceEligible(inputDevice)) {
            initializeDeviceToEnumMap(inputDevice, shouldUsePrimaryKeysForDevice(inputDevice));
            Slog.i(LOG_TAG, "Updating key code enum map for device ID: " + deviceId);
            Slog.i(LOG_TAG, "Updating key code enum map for device ID: " + inputDevice.getId());
        }
    }

    private boolean isDeviceEligible(@Nullable InputDevice device) {
        return device != null && device.isFullKeyboard() && device.isPhysicalDevice();
    }

    /**
     * Observes and updates various mouse keys setting values.
     */
+37 −10
Original line number Diff line number Diff line
@@ -67,6 +67,7 @@ class MouseKeysInterceptorTest {
    companion object {
        const val DISPLAY_ID = 1
        const val DEVICE_ID = 123
        const val VIRTUAL_DEVICE_ID = 456
        // This delay is required for key events to be sent and handled correctly.
        // The handler only performs a move/scroll event if it receives the key event
        // at INTERVAL_MILLIS (which happens in practice). Hence, we need this delay in the tests.
@@ -92,6 +93,7 @@ class MouseKeysInterceptorTest {

    private lateinit var mouseKeysInterceptor: MouseKeysInterceptor
    private lateinit var inputDevice: InputDevice
    private lateinit var virtualInputDevice: InputDevice

    private val clock = OffsettableClock()
    private val testLooper = TestLooper { clock.now() }
@@ -135,9 +137,12 @@ class MouseKeysInterceptorTest {
        testSession = InputManagerGlobal.createTestSession(iInputManager)
        mockInputManager = InputManager(testableContext)

        inputDevice = createInputDevice(DEVICE_ID)
        inputDevice = createInputDevice(DEVICE_ID, /* isVirtual= */ false)
        virtualInputDevice = createInputDevice(VIRTUAL_DEVICE_ID, /* isVirtual */ true)
        Mockito.`when`(iInputManager.getInputDevice(DEVICE_ID))
                .thenReturn(inputDevice)
        Mockito.`when`(iInputManager.getInputDevice(VIRTUAL_DEVICE_ID))
            .thenReturn(virtualInputDevice)

        Mockito.`when`(mockVirtualDeviceManagerInternal.getDeviceIdsForUid(Mockito.anyInt()))
            .thenReturn(ArraySet(setOf(DEVICE_ID)))
@@ -153,7 +158,8 @@ class MouseKeysInterceptorTest {
            Mockito.any(VirtualMouseConfig::class.java)
        )).thenReturn(mockVirtualMouse)

        Mockito.`when`(iInputManager.inputDeviceIds).thenReturn(intArrayOf(DEVICE_ID))
        Mockito.`when`(iInputManager.inputDeviceIds)
            .thenReturn(intArrayOf(DEVICE_ID, VIRTUAL_DEVICE_ID))
        Mockito.`when`(mockAms.traceManager).thenReturn(mockTraceManager)
    }

@@ -605,6 +611,23 @@ class MouseKeysInterceptorTest {
        verifyKeyEventsEqual(primaryKeyDownEvent, nextInterceptor.events.poll()!!)
    }

    @Test
    fun whenMouseKeyEventArrives_fromVirtualKeyboard_eventIsPassedToNextInterceptor() {
        setupMouseKeysInterceptor(usePrimaryKeys = true)
        for (ev in MouseKeysInterceptor.MouseKeyEvent.entries) {
            val downTime = clock.now()
            val keyCode = ev.getKeyCodeValue(USE_PRIMARY_KEYS)
            val downEvent = KeyEvent(downTime, downTime, KeyEvent.ACTION_DOWN,
                keyCode, 0, 0, VIRTUAL_DEVICE_ID, 0
            )
            mouseKeysInterceptor.onKeyEvent(downEvent, 0)
            testLooper.dispatchAll()

            assertThat(nextInterceptor.events).hasSize(1)
            verifyKeyEventsEqual(downEvent, nextInterceptor.events.poll()!!)
        }
    }

    private fun verifyRelativeEvents(expectedX: FloatArray, expectedY: FloatArray) {
        assertThat(expectedX.size).isEqualTo(expectedY.size)
        val expectedSize = expectedX.size
@@ -668,6 +691,7 @@ class MouseKeysInterceptorTest {

    private fun createInputDevice(
        deviceId: Int,
        isVirtual: Boolean,
        generation: Int = -1
    ): InputDevice =
        InputDevice.Builder()
@@ -675,6 +699,9 @@ class MouseKeysInterceptorTest {
            .setName("Device $deviceId")
            .setDescriptor("descriptor $deviceId")
            .setGeneration(generation)
            .setIsVirtualDevice(isVirtual)
            .setSources(InputDevice.SOURCE_KEYBOARD)
            .setKeyboardType(InputDevice.KEYBOARD_TYPE_ALPHABETIC)
            .build()

    private class TrackingInterceptor : BaseEventStreamTransformation() {