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

Commit 2b4e5685 authored by Sandro Meier's avatar Sandro Meier Committed by Android (Google) Code Review
Browse files

Merge "Add id to InputDeviceDesc of VirtualInputDevice"

parents 67a5af8c b03a7b7d
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -88,6 +88,7 @@ interface IVirtualDevice {
            IBinder token,
            in Point screenSize);
    void unregisterInputDevice(IBinder token);
    int getInputDeviceId(IBinder token);
    boolean sendDpadKeyEvent(IBinder token, in VirtualKeyEvent event);
    boolean sendKeyEvent(IBinder token, in VirtualKeyEvent event);
    boolean sendButtonEvent(IBinder token, in VirtualMouseButtonEvent event);
+11 −0
Original line number Diff line number Diff line
@@ -49,6 +49,17 @@ abstract class VirtualInputDevice implements Closeable {
        mToken = token;
    }

    /**
     * @return The device id of this device.
     * @hide
     */
    public int getInputDeviceId() {
        try {
            return mVirtualDevice.getInputDeviceId(mToken);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    @Override
    @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
+57 −6
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import android.hardware.input.VirtualMouseScrollEvent;
import android.hardware.input.VirtualTouchEvent;
import android.os.Handler;
import android.os.IBinder;
import android.os.IInputConstants;
import android.os.RemoteException;
import android.util.ArrayMap;
import android.util.Slog;
@@ -75,7 +76,7 @@ class InputController {
    @interface PhysType {
    }

    private final Object mLock;
    final Object mLock;

    /* Token -> file descriptor associations. */
    @VisibleForTesting
@@ -220,6 +221,19 @@ class InputController {
        }
    }

    /**
     * @return the device id for a given token (identifiying a device)
     */
    int getInputDeviceId(IBinder token) {
        synchronized (mLock) {
            final InputDeviceDescriptor inputDeviceDescriptor = mInputDeviceDescriptors.get(token);
            if (inputDeviceDescriptor == null) {
                throw new IllegalArgumentException("Could not get device id for given token");
            }
            return inputDeviceDescriptor.getInputDeviceId();
        }
    }

    void setShowPointerIcon(boolean visible, int displayId) {
        mInputManagerInternal.setPointerIconVisible(visible, displayId);
    }
@@ -393,8 +407,20 @@ class InputController {
                        + inputDeviceDescriptor.getCreationOrderNumber());
                fout.println("          type: " + inputDeviceDescriptor.getType());
                fout.println("          phys: " + inputDeviceDescriptor.getPhys());
                fout.println(
                        "          inputDeviceId: " + inputDeviceDescriptor.getInputDeviceId());
            }
        }
    }

    @VisibleForTesting
    void addDeviceForTesting(IBinder deviceToken, int fd, int type, int displayId,
            String phys, int inputDeviceId) {
        synchronized (mLock) {
            mInputDeviceDescriptors.put(deviceToken,
                    new InputDeviceDescriptor(fd, () -> {}, type, displayId, phys,
                            inputDeviceId));
        }
    }

    private static native int nativeOpenUinputDpad(String deviceName, int vendorId,
@@ -493,16 +519,20 @@ class InputController {
        private final @Type int mType;
        private final int mDisplayId;
        private final String mPhys;
        // The input device id that was associated to the device by the InputReader on device
        // creation.
        private final int mInputDeviceId;
        // Monotonically increasing number; devices with lower numbers were created earlier.
        private final long mCreationOrderNumber;

        InputDeviceDescriptor(int fd, IBinder.DeathRecipient deathRecipient, @Type int type,
                int displayId, String phys) {
                int displayId, String phys, int inputDeviceId) {
            mFd = fd;
            mDeathRecipient = deathRecipient;
            mType = type;
            mDisplayId = displayId;
            mPhys = phys;
            mInputDeviceId = inputDeviceId;
            mCreationOrderNumber = sNextCreationOrderNumber.getAndIncrement();
        }

@@ -533,6 +563,10 @@ class InputController {
        public String getPhys() {
            return mPhys;
        }

        public int getInputDeviceId() {
            return mInputDeviceId;
        }
    }

    private final class BinderDeathRecipient implements IBinder.DeathRecipient {
@@ -558,6 +592,8 @@ class InputController {
        private final CountDownLatch mDeviceAddedLatch = new CountDownLatch(1);
        private final InputManager.InputDeviceListener mListener;

        private int mInputDeviceId = IInputConstants.INVALID_INPUT_DEVICE_ID;

        WaitForDevice(String deviceName, int vendorId, int productId) {
            mListener = new InputManager.InputDeviceListener() {
                @Override
@@ -572,6 +608,7 @@ class InputController {
                    if (id.getVendorId() != vendorId || id.getProductId() != productId) {
                        return;
                    }
                    mInputDeviceId = deviceId;
                    mDeviceAddedLatch.countDown();
                }

@@ -588,8 +625,13 @@ class InputController {
            InputManager.getInstance().registerInputDeviceListener(mListener, mHandler);
        }

        /** Note: This must not be called from {@link #mHandler}'s thread. */
        void waitForDeviceCreation() throws DeviceCreationException {
        /**
         * Note: This must not be called from {@link #mHandler}'s thread.
         * @throws DeviceCreationException if the device was not created successfully within the
         * timeout.
         * @return The id of the created input device.
         */
        int waitForDeviceCreation() throws DeviceCreationException {
            try {
                if (!mDeviceAddedLatch.await(1, TimeUnit.MINUTES)) {
                    throw new DeviceCreationException(
@@ -599,6 +641,12 @@ class InputController {
                throw new DeviceCreationException(
                        "Interrupted while waiting for virtual device to be created.", e);
            }
            if (mInputDeviceId == IInputConstants.INVALID_INPUT_DEVICE_ID) {
                throw new IllegalStateException(
                        "Virtual input device was created with an invalid "
                                + "id=" + mInputDeviceId);
            }
            return mInputDeviceId;
        }

        @Override
@@ -643,6 +691,8 @@ class InputController {
        final int fd;
        final BinderDeathRecipient binderDeathRecipient;

        final int inputDeviceId;

        setUniqueIdAssociation(displayId, phys);
        try (WaitForDevice waiter = new WaitForDevice(deviceName, vendorId, productId)) {
            fd = deviceOpener.get();
@@ -652,7 +702,7 @@ class InputController {
            }
            // The fd is valid from here, so ensure that all failures close the fd after this point.
            try {
                waiter.waitForDeviceCreation();
                inputDeviceId = waiter.waitForDeviceCreation();

                binderDeathRecipient = new BinderDeathRecipient(deviceToken);
                try {
@@ -672,7 +722,8 @@ class InputController {

        synchronized (mLock) {
            mInputDeviceDescriptors.put(deviceToken,
                    new InputDeviceDescriptor(fd, binderDeathRecipient, type, displayId, phys));
                    new InputDeviceDescriptor(fd, binderDeathRecipient, type, displayId, phys,
                            inputDeviceId));
        }
    }

+11 −0
Original line number Diff line number Diff line
@@ -497,6 +497,17 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
        }
    }

    @Override // Binder call
    public int getInputDeviceId(IBinder token) {
        final long binderToken = Binder.clearCallingIdentity();
        try {
            return mInputController.getInputDeviceId(token);
        } finally {
            Binder.restoreCallingIdentity(binderToken);
        }
    }


    @Override // Binder call
    public boolean sendDpadKeyEvent(IBinder token, VirtualKeyEvent event) {
        final long binderToken = Binder.clearCallingIdentity();
+28 −0
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.server.companion.virtual;

import static com.google.common.truth.Truth.assertWithMessage;

import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
@@ -25,6 +27,7 @@ import static org.mockito.Mockito.verify;

import android.hardware.display.DisplayManagerInternal;
import android.hardware.input.IInputManager;
import android.hardware.input.InputManager;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
@@ -87,6 +90,30 @@ public class InputControllerTest {
                threadVerifier);
    }

    @Test
    public void registerInputDevice_deviceCreation_hasDeviceId() {
        final IBinder device1Token = new Binder("device1");
        mInputController.createMouse("mouse", /*vendorId= */ 1, /*productId= */ 1, device1Token,
                /* displayId= */ 1);
        int device1Id = mInputController.getInputDeviceId(device1Token);

        final IBinder device2Token = new Binder("device2");
        mInputController.createKeyboard("keyboard", /*vendorId= */2, /*productId= */ 2,
                device2Token, 2);
        int device2Id = mInputController.getInputDeviceId(device2Token);

        assertWithMessage("Different devices should have different id").that(
                device1Id).isNotEqualTo(device2Id);


        int[] deviceIds = InputManager.getInstance().getInputDeviceIds();
        assertWithMessage("InputManager's deviceIds list should contain id of device 1").that(
                deviceIds).asList().contains(device1Id);
        assertWithMessage("InputManager's deviceIds list should contain id of device 2").that(
                deviceIds).asList().contains(device2Id);

    }

    @Test
    public void unregisterInputDevice_allMiceUnregistered_clearPointerDisplayId() {
        final IBinder deviceToken = new Binder();
@@ -115,4 +142,5 @@ public class InputControllerTest {
        mInputController.unregisterInputDevice(deviceToken);
        verify(mInputManagerInternalMock).setVirtualMousePointerDisplayId(eq(1));
    }

}
Loading