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

Commit f20a8855 authored by Biswarup Pal's avatar Biswarup Pal
Browse files

Virtual stylus API

Test: atest VirtualStylusTest, VirtualStylusMotionEventTest,
VirtualStylusButtonEventTest, VirtualInputDeviceConfigTest
Bug: 304829446

Change-Id: I8d812780641c3dafda323c30ad7c94e307af0c0a
parent a5e8da1f
Loading
Loading
Loading
Loading
+73 −0
Original line number Diff line number Diff line
@@ -3229,6 +3229,7 @@ package android.companion.virtual {
    method @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualMouse createVirtualMouse(@NonNull android.hardware.input.VirtualMouseConfig);
    method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualMouse createVirtualMouse(@NonNull android.hardware.display.VirtualDisplay, @NonNull String, int, int);
    method @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualNavigationTouchpad createVirtualNavigationTouchpad(@NonNull android.hardware.input.VirtualNavigationTouchpadConfig);
    method @FlaggedApi("android.companion.virtual.flags.virtual_stylus") @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualStylus createVirtualStylus(@NonNull android.hardware.input.VirtualStylusConfig);
    method @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualTouchscreen createVirtualTouchscreen(@NonNull android.hardware.input.VirtualTouchscreenConfig);
    method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualTouchscreen createVirtualTouchscreen(@NonNull android.hardware.display.VirtualDisplay, @NonNull String, int, int);
    method public int getDeviceId();
@@ -5304,6 +5305,78 @@ package android.hardware.input {
    method @NonNull public android.hardware.input.VirtualNavigationTouchpadConfig build();
  }
  @FlaggedApi("android.companion.virtual.flags.virtual_stylus") public class VirtualStylus implements java.io.Closeable {
    method @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void close();
    method @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void sendButtonEvent(@NonNull android.hardware.input.VirtualStylusButtonEvent);
    method @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void sendMotionEvent(@NonNull android.hardware.input.VirtualStylusMotionEvent);
  }
  @FlaggedApi("android.companion.virtual.flags.virtual_stylus") public final class VirtualStylusButtonEvent implements android.os.Parcelable {
    method public int describeContents();
    method public int getAction();
    method public int getButtonCode();
    method public long getEventTimeNanos();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field public static final int ACTION_BUTTON_PRESS = 11; // 0xb
    field public static final int ACTION_BUTTON_RELEASE = 12; // 0xc
    field public static final int BUTTON_PRIMARY = 32; // 0x20
    field public static final int BUTTON_SECONDARY = 64; // 0x40
    field @NonNull public static final android.os.Parcelable.Creator<android.hardware.input.VirtualStylusButtonEvent> CREATOR;
  }
  @FlaggedApi("android.companion.virtual.flags.virtual_stylus") public static final class VirtualStylusButtonEvent.Builder {
    ctor public VirtualStylusButtonEvent.Builder();
    method @NonNull public android.hardware.input.VirtualStylusButtonEvent build();
    method @NonNull public android.hardware.input.VirtualStylusButtonEvent.Builder setAction(int);
    method @NonNull public android.hardware.input.VirtualStylusButtonEvent.Builder setButtonCode(int);
    method @NonNull public android.hardware.input.VirtualStylusButtonEvent.Builder setEventTimeNanos(long);
  }
  @FlaggedApi("android.companion.virtual.flags.virtual_stylus") public final class VirtualStylusConfig extends android.hardware.input.VirtualInputDeviceConfig implements android.os.Parcelable {
    method public int describeContents();
    method public int getHeight();
    method public int getWidth();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.hardware.input.VirtualStylusConfig> CREATOR;
  }
  @FlaggedApi("android.companion.virtual.flags.virtual_stylus") public static final class VirtualStylusConfig.Builder extends android.hardware.input.VirtualInputDeviceConfig.Builder<android.hardware.input.VirtualStylusConfig.Builder> {
    ctor public VirtualStylusConfig.Builder(@IntRange(from=1) int, @IntRange(from=1) int);
    method @NonNull public android.hardware.input.VirtualStylusConfig build();
  }
  @FlaggedApi("android.companion.virtual.flags.virtual_stylus") public final class VirtualStylusMotionEvent implements android.os.Parcelable {
    method public int describeContents();
    method public int getAction();
    method public long getEventTimeNanos();
    method public int getPressure();
    method public int getTiltX();
    method public int getTiltY();
    method public int getToolType();
    method public int getX();
    method public int getY();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field public static final int ACTION_DOWN = 0; // 0x0
    field public static final int ACTION_MOVE = 2; // 0x2
    field public static final int ACTION_UP = 1; // 0x1
    field @NonNull public static final android.os.Parcelable.Creator<android.hardware.input.VirtualStylusMotionEvent> CREATOR;
    field public static final int TOOL_TYPE_ERASER = 4; // 0x4
    field public static final int TOOL_TYPE_STYLUS = 2; // 0x2
  }
  @FlaggedApi("android.companion.virtual.flags.virtual_stylus") public static final class VirtualStylusMotionEvent.Builder {
    ctor public VirtualStylusMotionEvent.Builder();
    method @NonNull public android.hardware.input.VirtualStylusMotionEvent build();
    method @NonNull public android.hardware.input.VirtualStylusMotionEvent.Builder setAction(int);
    method @NonNull public android.hardware.input.VirtualStylusMotionEvent.Builder setEventTimeNanos(long);
    method @NonNull public android.hardware.input.VirtualStylusMotionEvent.Builder setPressure(@IntRange(from=0x0, to=0xff) int);
    method @NonNull public android.hardware.input.VirtualStylusMotionEvent.Builder setTiltX(@IntRange(from=0xffffffa6, to=0x5a) int);
    method @NonNull public android.hardware.input.VirtualStylusMotionEvent.Builder setTiltY(@IntRange(from=0xffffffa6, to=0x5a) int);
    method @NonNull public android.hardware.input.VirtualStylusMotionEvent.Builder setToolType(int);
    method @NonNull public android.hardware.input.VirtualStylusMotionEvent.Builder setX(int);
    method @NonNull public android.hardware.input.VirtualStylusMotionEvent.Builder setY(int);
  }
  public final class VirtualTouchEvent implements android.os.Parcelable {
    method public int describeContents();
    method public int getAction();
+31 −10
Original line number Diff line number Diff line
@@ -35,6 +35,9 @@ import android.hardware.input.VirtualMouseButtonEvent;
import android.hardware.input.VirtualMouseConfig;
import android.hardware.input.VirtualMouseRelativeEvent;
import android.hardware.input.VirtualMouseScrollEvent;
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;
@@ -143,6 +146,12 @@ interface IVirtualDevice {
    @EnforcePermission("CREATE_VIRTUAL_DEVICE")
    void createVirtualNavigationTouchpad(in VirtualNavigationTouchpadConfig config, IBinder token);

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

    /**
     * Removes the input device corresponding to the given token from the framework.
     */
@@ -191,6 +200,18 @@ interface IVirtualDevice {
    @EnforcePermission("CREATE_VIRTUAL_DEVICE")
    boolean sendTouchEvent(IBinder token, in VirtualTouchEvent event);

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

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

    /**
     * Returns all virtual sensors created for this device.
     */
+15 −0
Original line number Diff line number Diff line
@@ -42,6 +42,8 @@ import android.hardware.input.VirtualMouse;
import android.hardware.input.VirtualMouseConfig;
import android.hardware.input.VirtualNavigationTouchpad;
import android.hardware.input.VirtualNavigationTouchpadConfig;
import android.hardware.input.VirtualStylus;
import android.hardware.input.VirtualStylusConfig;
import android.hardware.input.VirtualTouchscreen;
import android.hardware.input.VirtualTouchscreenConfig;
import android.media.AudioManager;
@@ -316,6 +318,19 @@ public class VirtualDeviceInternal {
        }
    }

    @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
    @NonNull
    VirtualStylus createVirtualStylus(@NonNull VirtualStylusConfig config) {
        try {
            final IBinder token = new Binder(
                    "android.hardware.input.VirtualStylus:" + config.getInputDeviceName());
            mVirtualDevice.createVirtualStylus(config, token);
            return new VirtualStylus(config, mVirtualDevice, token);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    @NonNull
    VirtualNavigationTouchpad createVirtualNavigationTouchpad(
            @NonNull VirtualNavigationTouchpadConfig config) {
+15 −0
Original line number Diff line number Diff line
@@ -55,6 +55,8 @@ import android.hardware.input.VirtualMouse;
import android.hardware.input.VirtualMouseConfig;
import android.hardware.input.VirtualNavigationTouchpad;
import android.hardware.input.VirtualNavigationTouchpadConfig;
import android.hardware.input.VirtualStylus;
import android.hardware.input.VirtualStylusConfig;
import android.hardware.input.VirtualTouchscreen;
import android.hardware.input.VirtualTouchscreenConfig;
import android.media.AudioManager;
@@ -858,6 +860,19 @@ public final class VirtualDeviceManager {
            return mVirtualDeviceInternal.createVirtualNavigationTouchpad(config);
        }

        /**
         * Creates a virtual stylus.
         *
         * @param config the touchscreen configurations for the virtual stylus.
         */
        @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
        @NonNull
        @FlaggedApi(Flags.FLAG_VIRTUAL_STYLUS)
        public VirtualStylus createVirtualStylus(
                @NonNull VirtualStylusConfig config) {
            return mVirtualDeviceInternal.createVirtualStylus(config);
        }

        /**
         * Creates a VirtualAudioDevice, capable of recording audio emanating from this device,
         * or injecting audio from another device.
+7 −0
Original line number Diff line number Diff line
@@ -100,3 +100,10 @@ flag {
  description: "Enable interactive screen mirroring using Virtual Devices"
  bug: "292212199"
}

flag {
  name: "virtual_stylus"
  namespace: "virtual_devices"
  description: "Enable virtual stylus input"
  bug: "304829446"
}
Loading