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

Commit f649d795 authored by Jimmy's avatar Jimmy
Browse files

Remove display ID association requirement for VirtualInputDevices

Allow no display ID associations, i.e. Display.INVALID_DISPLAY, so that
virtual input devices can target any display.

Bug: 422265772
Test: atest VirtualInputDeviceControllerTest

Flag: com.android.hardware.input.create_virtual_keyboard_api

Change-Id: Ie5e3a05ce86314d1e00e20cf30274b9cfa486d03
parent c2099b12
Loading
Loading
Loading
Loading
+45 −7
Original line number Diff line number Diff line
@@ -16,7 +16,10 @@

package android.hardware.input;

import static com.android.hardware.input.Flags.createVirtualKeyboardApi;

import android.annotation.NonNull;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.view.Display;
@@ -59,10 +62,13 @@ public abstract class VirtualInputDeviceConfig {
        mAssociatedDisplayId = builder.mAssociatedDisplayId;
        mInputDeviceName = Objects.requireNonNull(builder.mInputDeviceName, "Missing device name");

        // Check if no display association is allowed.
        if (!createVirtualKeyboardApi()) {
            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
@@ -118,6 +124,21 @@ public abstract class VirtualInputDeviceConfig {
        return mInputDeviceName;
    }

    /**
     * Checks if a display ID is valid.
     * @throws IllegalArgumentException if an invalid display is associated with this device.
     *
     * @see Builder#setAssociatedDisplayId(int)
     *
     * @hide
     */
    public void checkForAssociatedDisplay() {
        if (getAssociatedDisplayId() == Display.INVALID_DISPLAY) {
            throw new IllegalArgumentException(
                    "Display association is required for virtual devices.");
        }
    }

    void writeToParcel(@NonNull Parcel dest, int flags) {
        dest.writeInt(mVendorId);
        dest.writeInt(mProductId);
@@ -174,15 +195,32 @@ public abstract class VirtualInputDeviceConfig {
        }

        /**
         * Sets the associated display ID of the virtual input device. Required.
         * Sets the associated display ID of the virtual input device.
         *
         * <p>If an explicit display association is specified, the associated display must be owned
         * by the caller. The virtual input device is restricted to the display with the given ID
         * and may not send events to any other display.</p>
         * <p>The specified display must be trusted or mirror display.</p>
         *
         * <p>If there is no specific display ID to associate with, use
         * {@link Display.DEFAULT_DISPLAY} or {@link Display.INVALID_DISPLAY}.
         * Using {@link Display.INVALID_DISPLAY} requires the caller to be have either
         * {@link android.Manifest.permission#INJECT_KEY_EVENTS} or
         * {@link android.Manifest.permission#INJECT_EVENTS}
         * </p>
         *
         * <p>The input device is restricted to the display with the given ID and may not send
         * events to any other display.</p>
         * <p>The corresponding display must be trusted or mirror display.</p>
         * <p>Use {@link Display.DEFAULT_DISPLAY} if the virtual input device should only send
         * events to the primary default display. Events will not be sent to focused windows of the
         * non-primary display, e.g. extended monitor.</p>
         * <p>Use {@link Display.INVALID_DISPLAY} if there is no display association and
         * will only send events to the currently focused window of the currently focused display.
         * ONLY allowed for virtual input devices that exclusively sends key events, i.e. keyboard
         * and dpad, and if the caller has either of the aforementioned permissions.</p>
         *
         * @see android.hardware.display.DisplayManager#VIRTUAL_DISPLAY_FLAG_TRUSTED
         * @see android.hardware.display.DisplayManager#VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR
         */
        @SuppressLint("RequiresPermission")
        @NonNull
        public T setAssociatedDisplayId(int displayId) {
            mAssociatedDisplayId = displayId;
+2 −0
Original line number Diff line number Diff line
@@ -43,10 +43,12 @@ public final class VirtualMouseConfig extends VirtualInputDeviceConfig implement

    private VirtualMouseConfig(@NonNull VirtualMouseConfig.Builder builder) {
        super(builder);
        checkForAssociatedDisplay();
    }

    private VirtualMouseConfig(@NonNull Parcel in) {
        super(in);
        checkForAssociatedDisplay();
    }

    @Override
+4 −0
Original line number Diff line number Diff line
@@ -38,12 +38,16 @@ public final class VirtualNavigationTouchpadConfig extends VirtualInputDeviceCon

    private VirtualNavigationTouchpadConfig(@NonNull Builder builder) {
        super(builder);
        checkForAssociatedDisplay();

        mHeight = builder.mHeight;
        mWidth = builder.mWidth;
    }

    private VirtualNavigationTouchpadConfig(@NonNull Parcel in) {
        super(in);
        checkForAssociatedDisplay();

        mHeight = in.readInt();
        mWidth = in.readInt();
    }
+2 −0
Original line number Diff line number Diff line
@@ -49,10 +49,12 @@ public final class VirtualRotaryEncoderConfig extends VirtualInputDeviceConfig

    private VirtualRotaryEncoderConfig(@NonNull VirtualRotaryEncoderConfig.Builder builder) {
        super(builder);
        checkForAssociatedDisplay();
    }

    private VirtualRotaryEncoderConfig(@NonNull Parcel in) {
        super(in);
        checkForAssociatedDisplay();
    }

    @Override
+4 −0
Original line number Diff line number Diff line
@@ -34,12 +34,16 @@ abstract class VirtualTouchDeviceConfig extends VirtualInputDeviceConfig {

    VirtualTouchDeviceConfig(@NonNull Builder<? extends Builder<?>> builder) {
        super(builder);
        checkForAssociatedDisplay();

        mWidth = builder.mWidth;
        mHeight = builder.mHeight;
    }

    VirtualTouchDeviceConfig(@NonNull Parcel in) {
        super(in);
        checkForAssociatedDisplay();

        mWidth = in.readInt();
        mHeight = in.readInt();
    }