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

Commit 2e51a15b authored by Vladimir Komsiyski's avatar Vladimir Komsiyski
Browse files

Add IVirtualInputDevice.

Step 1 of decoupling virtual input from VDM: Factor out the input
related logic from IVirtualDevice to a new interface.

Purely no-op, just moving stuff around.

Bug: 419493538
Test: atest & presubmit
Flag: EXEMPT no-op refactor
Change-Id: I88a06a0346ee699327f303a45f52b06b8635189b
parent 7805d8ff
Loading
Loading
Loading
Loading
+10 −78
Original line number Diff line number Diff line
@@ -31,22 +31,14 @@ import android.companion.virtual.camera.VirtualCameraConfig;
import android.content.ComponentName;
import android.content.IntentFilter;
import android.graphics.Point;
import android.graphics.PointF;
import android.hardware.display.IVirtualDisplayCallback;
import android.hardware.display.VirtualDisplayConfig;
import android.hardware.input.IVirtualInputDevice;
import android.hardware.input.VirtualDpadConfig;
import android.hardware.input.VirtualKeyboardConfig;
import android.hardware.input.VirtualKeyEvent;
import android.hardware.input.VirtualMouseButtonEvent;
import android.hardware.input.VirtualMouseConfig;
import android.hardware.input.VirtualMouseRelativeEvent;
import android.hardware.input.VirtualMouseScrollEvent;
import android.hardware.input.VirtualRotaryEncoderConfig;
import android.hardware.input.VirtualRotaryEncoderScrollEvent;
import android.hardware.input.VirtualStylusButtonEvent;
import android.hardware.input.VirtualStylusConfig;
import android.hardware.input.VirtualStylusMotionEvent;
import android.hardware.input.VirtualTouchEvent;
import android.hardware.input.VirtualTouchscreenConfig;
import android.hardware.input.VirtualNavigationTouchpadConfig;
import android.os.ResultReceiver;
@@ -152,94 +144,40 @@ interface IVirtualDevice {
    /**
     * Creates a new dpad and registers it with the input framework with the given token.
     */
    void createVirtualDpad(in VirtualDpadConfig config, IBinder token);
    IVirtualInputDevice createVirtualDpad(in VirtualDpadConfig config, IBinder token);

    /**
     * Creates a new keyboard and registers it with the input framework with the given token.
     */
    void createVirtualKeyboard(in VirtualKeyboardConfig config, IBinder token);
    IVirtualInputDevice createVirtualKeyboard(in VirtualKeyboardConfig config, IBinder token);

    /**
     * Creates a new mouse and registers it with the input framework with the given token.
     */
    void createVirtualMouse(in VirtualMouseConfig config, IBinder token);
    IVirtualInputDevice createVirtualMouse(in VirtualMouseConfig config, IBinder token);

    /**
     * Creates a new touchscreen and registers it with the input framework with the given token.
     */
    void createVirtualTouchscreen(in VirtualTouchscreenConfig config, IBinder token);
    IVirtualInputDevice createVirtualTouchscreen(in VirtualTouchscreenConfig config, IBinder token);

    /**
     * Creates a new navigation touchpad and registers it with the input framework with the given
     * token.
     */
    void createVirtualNavigationTouchpad(in VirtualNavigationTouchpadConfig config, IBinder token);
    IVirtualInputDevice createVirtualNavigationTouchpad(in VirtualNavigationTouchpadConfig config,
            IBinder token);

    /**
     * Creates a new stylus and registers it with the input framework with the given token.
     */
    void createVirtualStylus(in VirtualStylusConfig config, IBinder token);
    IVirtualInputDevice createVirtualStylus(in VirtualStylusConfig config, IBinder token);

    /**
     * Creates a new rotary encoder and registers it with the input framework with the given token.
     */
    void createVirtualRotaryEncoder(in VirtualRotaryEncoderConfig config, IBinder token);

    /**
     * Removes the input device corresponding to the given token from the framework.
     */
    void unregisterInputDevice(IBinder token);

    /**
     * Returns the ID of the device corresponding to the given token, as registered with the input
     * framework.
     */
    int getInputDeviceId(IBinder token);

    /**
     * Injects a key event to the virtual dpad corresponding to the given token.
     */
    boolean sendDpadKeyEvent(IBinder token, in VirtualKeyEvent event);

    /**
     * Injects a key event to the virtual keyboard corresponding to the given token.
     */
    boolean sendKeyEvent(IBinder token, in VirtualKeyEvent event);

    /**
     * Injects a button event to the virtual mouse corresponding to the given token.
     */
    boolean sendButtonEvent(IBinder token, in VirtualMouseButtonEvent event);

    /**
     * Injects a relative event to the virtual mouse corresponding to the given token.
     */
    boolean sendRelativeEvent(IBinder token, in VirtualMouseRelativeEvent event);

    /**
     * Injects a scroll event to the virtual mouse corresponding to the given token.
     */
    boolean sendScrollEvent(IBinder token, in VirtualMouseScrollEvent event);

    /**
    * Injects a touch event to the virtual touch input device corresponding to the given token.
    */
    boolean sendTouchEvent(IBinder token, in VirtualTouchEvent event);

    /**
     * Injects a motion event from the virtual stylus input device corresponding to the given token.
     */
    boolean sendStylusMotionEvent(IBinder token, in VirtualStylusMotionEvent event);

    /**
     * Injects a button event from the virtual stylus input device corresponding to the given token.
     */
    boolean sendStylusButtonEvent(IBinder token, in VirtualStylusButtonEvent event);

    /**
     * Injects a scroll event from the virtual rotary encoder corresponding to the given token.
     */
    boolean sendRotaryEncoderScrollEvent(IBinder token, in VirtualRotaryEncoderScrollEvent event);
    IVirtualInputDevice createVirtualRotaryEncoder(in VirtualRotaryEncoderConfig config,
            IBinder token);

    /**
     * Returns all virtual sensors created for this device.
@@ -262,12 +200,6 @@ interface IVirtualDevice {
    void launchPendingIntent(int displayId, in PendingIntent pendingIntent,
            in ResultReceiver resultReceiver);

    /**
     * Returns the current cursor position of the mouse corresponding to the given token, in x and y
     * coordinates.
     */
    PointF getCursorPosition(IBinder token);

    /** Sets whether to show or hide the cursor while this virtual device is active. */
    void setShowPointerIcon(boolean showPointerIcon);

+16 −14
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ import android.hardware.display.DisplayManagerGlobal;
import android.hardware.display.IVirtualDisplayCallback;
import android.hardware.display.VirtualDisplay;
import android.hardware.display.VirtualDisplayConfig;
import android.hardware.input.IVirtualInputDevice;
import android.hardware.input.VirtualDpad;
import android.hardware.input.VirtualDpadConfig;
import android.hardware.input.VirtualKeyboard;
@@ -400,8 +401,8 @@ public class VirtualDeviceInternal {
        try {
            final IBinder token = new Binder(
                    "android.hardware.input.VirtualDpad:" + config.getInputDeviceName());
            mVirtualDevice.createVirtualDpad(config, token);
            return new VirtualDpad(config, mVirtualDevice, token);
            IVirtualInputDevice device = mVirtualDevice.createVirtualDpad(config, token);
            return new VirtualDpad(config, device);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
@@ -412,8 +413,8 @@ public class VirtualDeviceInternal {
        try {
            final IBinder token = new Binder(
                    "android.hardware.input.VirtualKeyboard:" + config.getInputDeviceName());
            mVirtualDevice.createVirtualKeyboard(config, token);
            return new VirtualKeyboard(config, mVirtualDevice, token);
            IVirtualInputDevice device = mVirtualDevice.createVirtualKeyboard(config, token);
            return new VirtualKeyboard(config, device);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
@@ -424,8 +425,8 @@ public class VirtualDeviceInternal {
        try {
            final IBinder token = new Binder(
                    "android.hardware.input.VirtualMouse:" + config.getInputDeviceName());
            mVirtualDevice.createVirtualMouse(config, token);
            return new VirtualMouse(config, mVirtualDevice, token);
            IVirtualInputDevice device = mVirtualDevice.createVirtualMouse(config, token);
            return new VirtualMouse(config, device);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
@@ -437,8 +438,8 @@ public class VirtualDeviceInternal {
        try {
            final IBinder token = new Binder(
                    "android.hardware.input.VirtualTouchscreen:" + config.getInputDeviceName());
            mVirtualDevice.createVirtualTouchscreen(config, token);
            return new VirtualTouchscreen(config, mVirtualDevice, token);
            IVirtualInputDevice device = mVirtualDevice.createVirtualTouchscreen(config, token);
            return new VirtualTouchscreen(config, device);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
@@ -449,8 +450,8 @@ public class VirtualDeviceInternal {
        try {
            final IBinder token = new Binder(
                    "android.hardware.input.VirtualStylus:" + config.getInputDeviceName());
            mVirtualDevice.createVirtualStylus(config, token);
            return new VirtualStylus(config, mVirtualDevice, token);
            IVirtualInputDevice device = mVirtualDevice.createVirtualStylus(config, token);
            return new VirtualStylus(config, device);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
@@ -461,8 +462,8 @@ public class VirtualDeviceInternal {
        try {
            final IBinder token = new Binder(
                    "android.hardware.input.VirtualRotaryEncoder:" + config.getInputDeviceName());
            mVirtualDevice.createVirtualRotaryEncoder(config, token);
            return new VirtualRotaryEncoder(config, mVirtualDevice, token);
            IVirtualInputDevice device = mVirtualDevice.createVirtualRotaryEncoder(config, token);
            return new VirtualRotaryEncoder(config, device);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
@@ -475,8 +476,9 @@ public class VirtualDeviceInternal {
            final IBinder token = new Binder(
                    "android.hardware.input.VirtualNavigationTouchpad:"
                            + config.getInputDeviceName());
            mVirtualDevice.createVirtualNavigationTouchpad(config, token);
            return new VirtualNavigationTouchpad(config, mVirtualDevice, token);
            IVirtualInputDevice device = mVirtualDevice.createVirtualNavigationTouchpad(config,
                    token);
            return new VirtualNavigationTouchpad(config, device);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
+99 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.hardware.input;

import android.graphics.PointF;
import android.hardware.input.VirtualKeyEvent;
import android.hardware.input.VirtualMouseButtonEvent;
import android.hardware.input.VirtualMouseRelativeEvent;
import android.hardware.input.VirtualMouseScrollEvent;
import android.hardware.input.VirtualRotaryEncoderScrollEvent;
import android.hardware.input.VirtualStylusButtonEvent;
import android.hardware.input.VirtualStylusMotionEvent;
import android.hardware.input.VirtualTouchEvent;

/**
 * Interface for a virtual input device to communication between the system server and the process
 * of owner of that device.
 *
 * @hide
 */
 // TODO(b/419771135): Split IVirtualInputDevice into IVirtual[Mouse|Keyboard|etc]
interface IVirtualInputDevice {

    /**
     * Removes the input device from the framework.
     */
    void close();

    /**
     * Returns the ID of the device corresponding to this virtual input device, as registered with
     * the input framework.
     */
    int getInputDeviceId();

    /**
     * Injects a virtual dpad key event.
     */
    boolean sendDpadKeyEvent(in VirtualKeyEvent event);

    /**
     * Injects a virtual keyboard key event.
     */
    boolean sendKeyEvent(in VirtualKeyEvent event);

    /**
     * Injects a virtual mouse button event.
     */
    boolean sendMouseButtonEvent(in VirtualMouseButtonEvent event);

    /**
     * Injects a virtual mouse relative event.
     */
    boolean sendMouseRelativeEvent(in VirtualMouseRelativeEvent event);

    /**
     * Injects a virtual mouse scroll event.
     */
    boolean sendMouseScrollEvent(in VirtualMouseScrollEvent event);

    /**
    * Injects a virtual touchscreen / touchpad touch event.
    */
    boolean sendTouchEvent(in VirtualTouchEvent event);

    /**
     * Injects a virtual stylus motion event.
     */
    boolean sendStylusMotionEvent(in VirtualStylusMotionEvent event);

    /**
     * Injects a virtual stylus button event.
     */
    boolean sendStylusButtonEvent(in VirtualStylusButtonEvent event);

    /**
     * Injects a virtual rotary encoder scroll event.
     */
    boolean sendRotaryEncoderScrollEvent(in VirtualRotaryEncoderScrollEvent event);

    /**
     * Returns the current cursor position of the mouse corresponding to this device, in x and y
     * coordinates.
     */
    PointF getCursorPosition();
}
+11 −19
Original line number Diff line number Diff line
@@ -18,15 +18,10 @@ package android.hardware.input;

import android.annotation.NonNull;
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;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

/**
@@ -40,20 +35,17 @@ import java.util.Set;
@SystemApi
public class VirtualDpad extends VirtualInputDevice {

    private final Set<Integer> mSupportedKeyCodes =
            Collections.unmodifiableSet(
                    new HashSet<>(
                            Arrays.asList(
    private static final Set<Integer> SUPPORTED_KEY_CODES = Set.of(
            KeyEvent.KEYCODE_BACK,
            KeyEvent.KEYCODE_DPAD_UP,
            KeyEvent.KEYCODE_DPAD_DOWN,
            KeyEvent.KEYCODE_DPAD_LEFT,
            KeyEvent.KEYCODE_DPAD_RIGHT,
                                    KeyEvent.KEYCODE_DPAD_CENTER)));
            KeyEvent.KEYCODE_DPAD_CENTER);

    /** @hide */
    public VirtualDpad(VirtualDpadConfig config, IVirtualDevice virtualDevice, IBinder token) {
        super(config, virtualDevice, token);
    public VirtualDpad(VirtualDpadConfig config, IVirtualInputDevice virtualInputDevice) {
        super(config, virtualInputDevice);
    }

    /**
@@ -73,13 +65,13 @@ public class VirtualDpad extends VirtualInputDevice {
     */
    public void sendKeyEvent(@NonNull VirtualKeyEvent event) {
        try {
            if (!mSupportedKeyCodes.contains(event.getKeyCode())) {
            if (!SUPPORTED_KEY_CODES.contains(event.getKeyCode())) {
                throw new IllegalArgumentException(
                        "Unsupported key code "
                                + event.getKeyCode()
                                + " sent to a VirtualDpad input device.");
            }
            if (!mVirtualDevice.sendDpadKeyEvent(mToken, event)) {
            if (!mVirtualInputDevice.sendDpadKeyEvent(event)) {
                Log.w(TAG, "Failed to send key event to virtual dpad "
                        + mConfig.getInputDeviceName());
            }
+5 −17
Original line number Diff line number Diff line
@@ -16,8 +16,6 @@

package android.hardware.input;

import android.companion.virtual.IVirtualDevice;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

@@ -34,24 +32,14 @@ abstract class VirtualInputDevice implements Closeable {

    protected static final String TAG = "VirtualInputDevice";

    /**
     * The virtual device to which this VirtualInputDevice belongs to.
     */
    protected final IVirtualDevice mVirtualDevice;

    /**
     * The token used to uniquely identify the virtual input device.
     */
    protected final IBinder mToken;
    protected final IVirtualInputDevice mVirtualInputDevice;

    protected final VirtualInputDeviceConfig mConfig;

    /** @hide */
    VirtualInputDevice(VirtualInputDeviceConfig config,
            IVirtualDevice virtualDevice, IBinder token) {
    VirtualInputDevice(VirtualInputDeviceConfig config, IVirtualInputDevice virtualDevice) {
        mConfig = config;
        mVirtualDevice = virtualDevice;
        mToken = token;
        mVirtualInputDevice = virtualDevice;
    }

    /**
@@ -60,7 +48,7 @@ abstract class VirtualInputDevice implements Closeable {
     */
    public int getInputDeviceId() {
        try {
            return mVirtualDevice.getInputDeviceId(mToken);
            return mVirtualInputDevice.getInputDeviceId();
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
@@ -70,7 +58,7 @@ abstract class VirtualInputDevice implements Closeable {
    public void close() {
        Log.d(TAG, "Closing virtual input device " + mConfig.getInputDeviceName());
        try {
            mVirtualDevice.unregisterInputDevice(mToken);
            mVirtualInputDevice.close();
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
Loading