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

Commit a00e9468 authored by Vladimir Komsiyski's avatar Vladimir Komsiyski
Browse files

Disallow reusing tokens for virtual input devices

Now the devices are successfully created but since the token is used
as a map key, the old device becomes a zombie

Also improve some messaging by s/virtual device/virtual input device

Bug: 434145006
Test: presubmit
Flag: EXEMPT trivial bugfix
Change-Id: Id112b4ad4c4d065bd2e2797b7497fb431c8df2d5
parent 539679cd
Loading
Loading
Loading
Loading
+20 −13
Original line number Diff line number Diff line
@@ -102,7 +102,7 @@ class VirtualInputDeviceController {

    VirtualInputDeviceController(@NonNull Handler handler, @NonNull InputManagerService service) {
        this(new NativeWrapper(), handler, service,
                // Verify that virtual devices are not created on the handler thread.
                // Verify that virtual input devices are not created on the handler thread.
                () -> !handler.getLooper().isCurrentThread());
    }

@@ -848,7 +848,10 @@ class VirtualInputDeviceController {
        }
    }

    /** An internal exception that is thrown to indicate an error when opening a virtual device. */
    /**
     * An internal exception that is thrown to indicate an error when opening a virtual input
     * device.
     */
    static class DeviceCreationException extends Exception {
        DeviceCreationException(String message) {
            super(message);
@@ -876,8 +879,8 @@ class VirtualInputDeviceController {
            String phys, Supplier<Long> deviceOpener) throws DeviceCreationException {
        if (!mThreadVerifier.isValidThread()) {
            throw new IllegalStateException(
                    "Virtual device creation should happen on an auxiliary thread (e.g. binder "
                            + "thread) and not from the handler's thread.");
                    "Virtual input device creation should happen on an auxiliary thread (e.g. "
                            + "binder thread) and not from the handler's thread.");
        }
        validateDeviceName(deviceName);

@@ -908,12 +911,24 @@ class VirtualInputDeviceController {
                    deviceToken.linkToDeath(binderDeathRecipient, /* flags= */ 0);
                } catch (RemoteException e) {
                    throw new DeviceCreationException(
                            "Client died before virtual device could be created.", e);
                            "Client died before virtual input device could be created.", e);
                }
            } catch (DeviceCreationException e) {
                mNativeWrapper.closeUinput(ptr);
                throw e;
            }

            InputDeviceDescriptor device = new InputDeviceDescriptor(this, ptr,
                binderDeathRecipient, type, displayId, phys, deviceName, inputDeviceId,
                deviceToken);
            synchronized (mLock) {
                if (mInputDeviceDescriptors.containsKey(deviceToken)) {
                    throw new DeviceCreationException("Cannot create new virtual input device "
                        + "with an existing token.");
                }
                mInputDeviceDescriptors.put(deviceToken, device);
            }
            return device;
        } catch (DeviceCreationException e) {
            mService.removeUniqueIdAssociationByPort(phys);
            if (disableSettingsForVirtualDevices()) {
@@ -921,14 +936,6 @@ class VirtualInputDeviceController {
            }
            throw e;
        }

        InputDeviceDescriptor device = new InputDeviceDescriptor(this, ptr, binderDeathRecipient,
                type, displayId, phys, deviceName, inputDeviceId, deviceToken);
        synchronized (mLock) {
            mInputDeviceDescriptors.put(deviceToken, device);
        }

        return device;
    }

    @VisibleForTesting
+10 −0
Original line number Diff line number Diff line
@@ -80,6 +80,7 @@ public class VirtualInputDeviceControllerTest {
    private static final String LANGUAGE_TAG = "en-US";
    private static final String LAYOUT_TYPE = "qwerty";
    private static final String NAME = "testInputDeviceName";
    private static final String NAME_2 = "testInputDeviceName2";
    private static final long EVENT_TIMESTAMP = 5000L;

    private TestableLooper mTestableLooper;
@@ -228,6 +229,15 @@ public class VirtualInputDeviceControllerTest {
                        NAME, VENDOR_ID, PRODUCT_ID, TOKEN_2, DISPLAY_ID_2));
    }

    @Test
    public void createInputDevice_duplicateTokensAreNotAllowed() {
        mInputController.createDpad(NAME, VENDOR_ID, PRODUCT_ID, TOKEN_1, DISPLAY_ID_1);
        assertThrows("Device tokens need to be unique",
                IllegalArgumentException.class,
                () -> mInputController.createDpad(
                        NAME_2, VENDOR_ID, PRODUCT_ID, TOKEN_1, DISPLAY_ID_2));
    }

    @Test
    public void getCursorPosition_returnsPositionFromService() {
        mInputController.createMouse(NAME, VENDOR_ID, PRODUCT_ID, TOKEN_1, DISPLAY_ID_1);