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

Commit 072eeea8 authored by Vladimir Komsiyski's avatar Vladimir Komsiyski Committed by Android (Google) Code Review
Browse files

Merge "Virtual input API improvements" into main

parents 8530259b b05edb2f
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.annotation.SystemApi;
import android.companion.virtual.IVirtualDevice;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.KeyEvent;

import java.util.Arrays;
@@ -80,7 +81,10 @@ public class VirtualDpad extends VirtualInputDevice {
                                + event.getKeyCode()
                                + " sent to a VirtualDpad input device.");
            }
            mVirtualDevice.sendDpadKeyEvent(mToken, event);
            if (!mVirtualDevice.sendDpadKeyEvent(mToken, event)) {
                Log.w(TAG, "Failed to send key event to virtual dpad "
                        + mConfig.getInputDeviceName());
            }
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
+4 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.annotation.RequiresPermission;
import android.companion.virtual.IVirtualDevice;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

import java.io.Closeable;

@@ -32,6 +33,8 @@ import java.io.Closeable;
 */
abstract class VirtualInputDevice implements Closeable {

    protected static final String TAG = "VirtualInputDevice";

    /**
     * The virtual device to which this VirtualInputDevice belongs to.
     */
@@ -67,6 +70,7 @@ abstract class VirtualInputDevice implements Closeable {
    @Override
    @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
    public void close() {
        Log.d(TAG, "Closing virtual input device " + mConfig.getInputDeviceName());
        try {
            mVirtualDevice.unregisterInputDevice(mToken);
        } catch (RemoteException e) {
+60 −9
Original line number Diff line number Diff line
@@ -19,6 +19,10 @@ package android.hardware.input;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.view.Display;

import java.nio.charset.StandardCharsets;
import java.util.Objects;

/**
 * Common configurations to create virtual input devices.
@@ -27,6 +31,15 @@ import android.os.Parcel;
 */
@SystemApi
public abstract class VirtualInputDeviceConfig {

    /**
     * The maximum length of a device name (in bytes in UTF-8 encoding).
     *
     * This limitation comes directly from uinput.
     * See also UINPUT_MAX_NAME_SIZE in linux/uinput.h
     */
    private static final int DEVICE_NAME_MAX_LENGTH = 80;

    /** The vendor id uniquely identifies the company who manufactured the device. */
    private final int mVendorId;
    /**
@@ -44,18 +57,33 @@ public abstract class VirtualInputDeviceConfig {
        mVendorId = builder.mVendorId;
        mProductId = builder.mProductId;
        mAssociatedDisplayId = builder.mAssociatedDisplayId;
        mInputDeviceName = builder.mInputDeviceName;
        mInputDeviceName = Objects.requireNonNull(builder.mInputDeviceName);

        if (mAssociatedDisplayId == Display.INVALID_DISPLAY) {
            throw new IllegalArgumentException(
                    "Display association is required for virtual input devices.");
        }

        // Comparison is greater or equal because the device name must fit into a const char*
        // including the \0-terminator. Therefore the actual number of bytes that can be used
        // for device name is DEVICE_NAME_MAX_LENGTH - 1
        if (mInputDeviceName.getBytes(StandardCharsets.UTF_8).length >= DEVICE_NAME_MAX_LENGTH) {
            throw new IllegalArgumentException("Input device name exceeds maximum length of "
                    + DEVICE_NAME_MAX_LENGTH + "bytes: " + mInputDeviceName);
        }
    }

    protected VirtualInputDeviceConfig(@NonNull Parcel in) {
        mVendorId = in.readInt();
        mProductId = in.readInt();
        mAssociatedDisplayId = in.readInt();
        mInputDeviceName = in.readString8();
        mInputDeviceName = Objects.requireNonNull(in.readString8());
    }

    /**
     * The vendor id uniquely identifies the company who manufactured the device.
     *
     * @see Builder#setVendorId(int) (int)
     */
    public int getVendorId() {
        return mVendorId;
@@ -64,6 +92,8 @@ public abstract class VirtualInputDeviceConfig {
    /**
     * The product id uniquely identifies which product within the address space of a given vendor,
     * identified by the device's vendor id.
     *
     * @see Builder#setProductId(int)
     */
    public int getProductId() {
        return mProductId;
@@ -71,6 +101,8 @@ public abstract class VirtualInputDeviceConfig {

    /**
     * The associated display ID of the virtual input device.
     *
     * @see Builder#setAssociatedDisplayId(int)
     */
    public int getAssociatedDisplayId() {
        return mAssociatedDisplayId;
@@ -78,6 +110,8 @@ public abstract class VirtualInputDeviceConfig {

    /**
     * The name of the virtual input device.
     *
     * @see Builder#setInputDeviceName(String)
     */
    @NonNull
    public String getInputDeviceName() {
@@ -117,11 +151,12 @@ public abstract class VirtualInputDeviceConfig {

        private int mVendorId;
        private int mProductId;
        private int mAssociatedDisplayId;
        @NonNull
        private int mAssociatedDisplayId = Display.INVALID_DISPLAY;
        private String mInputDeviceName;

        /** @see VirtualInputDeviceConfig#getVendorId(). */
        /**
         * Sets the vendor id of the device, identifying the company who manufactured the device.
         */
        @NonNull
        public T setVendorId(int vendorId) {
            mVendorId = vendorId;
@@ -129,24 +164,40 @@ public abstract class VirtualInputDeviceConfig {
        }


        /** @see VirtualInputDeviceConfig#getProductId(). */
        /**
         * Sets the product id of the device, uniquely identifying the device within the address
         * space of a given vendor, identified by the device's vendor id.
         */
        @NonNull
        public T setProductId(int productId) {
            mProductId = productId;
            return self();
        }

        /** @see VirtualInputDeviceConfig#getAssociatedDisplayId(). */
        /**
         * Sets the associated display ID of the virtual input device. Required.
         *
         * <p>The input device is restricted to the display with the given ID and may not send
         * events to any other display.</p>
         */
        @NonNull
        public T setAssociatedDisplayId(int displayId) {
            mAssociatedDisplayId = displayId;
            return self();
        }

        /** @see VirtualInputDeviceConfig#getInputDeviceName(). */
        /**
         * Sets the name of the virtual input device. Required.
         *
         * <p>The name must be unique among all input devices that belong to the same virtual
         * device.</p>
         *
         * <p>The maximum allowed length of the name is 80 bytes in UTF-8 encoding, enforced by
         * {@code UINPUT_MAX_NAME_SIZE}.</p>
         */
        @NonNull
        public T setInputDeviceName(@NonNull String deviceName) {
            mInputDeviceName = deviceName;
            mInputDeviceName = Objects.requireNonNull(deviceName);
            return self();
        }

+5 −1
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.annotation.SystemApi;
import android.companion.virtual.IVirtualDevice;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.KeyEvent;

/**
@@ -57,7 +58,10 @@ public class VirtualKeyboard extends VirtualInputDevice {
                    "Unsupported key code " + event.getKeyCode()
                        + " sent to a VirtualKeyboard input device.");
            }
            mVirtualDevice.sendKeyEvent(mToken, event);
            if (!mVirtualDevice.sendKeyEvent(mToken, event)) {
                Log.w(TAG, "Failed to send key event to virtual keyboard "
                        + mConfig.getInputDeviceName());
            }
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
+13 −3
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.companion.virtual.IVirtualDevice;
import android.graphics.PointF;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.MotionEvent;

/**
@@ -52,7 +53,10 @@ public class VirtualMouse extends VirtualInputDevice {
    @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
    public void sendButtonEvent(@NonNull VirtualMouseButtonEvent event) {
        try {
            mVirtualDevice.sendButtonEvent(mToken, event);
            if (!mVirtualDevice.sendButtonEvent(mToken, event)) {
                Log.w(TAG, "Failed to send button event to virtual mouse "
                        + mConfig.getInputDeviceName());
            }
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
@@ -69,7 +73,10 @@ public class VirtualMouse extends VirtualInputDevice {
    @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
    public void sendScrollEvent(@NonNull VirtualMouseScrollEvent event) {
        try {
            mVirtualDevice.sendScrollEvent(mToken, event);
            if (!mVirtualDevice.sendScrollEvent(mToken, event)) {
                Log.w(TAG, "Failed to send scroll event to virtual mouse "
                        + mConfig.getInputDeviceName());
            }
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
@@ -85,7 +92,10 @@ public class VirtualMouse extends VirtualInputDevice {
    @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
    public void sendRelativeEvent(@NonNull VirtualMouseRelativeEvent event) {
        try {
            mVirtualDevice.sendRelativeEvent(mToken, event);
            if (!mVirtualDevice.sendRelativeEvent(mToken, event)) {
                Log.w(TAG, "Failed to send relative event to virtual mouse "
                        + mConfig.getInputDeviceName());
            }
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
Loading