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

Commit c74e2e0e authored by Christine Franks's avatar Christine Franks Committed by Android (Google) Code Review
Browse files

Merge "Remote input interfaces, events, and injection"

parents 8e06c9bd c4cf03b1
Loading
Loading
Loading
Loading
+121 −0
Original line number Diff line number Diff line
@@ -3899,6 +3899,127 @@ package android.hardware.hdmi {
}
package android.hardware.input {
  public final class VirtualKeyEvent implements android.os.Parcelable {
    method public int describeContents();
    method public int getAction();
    method public int getKeyCode();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field public static final int ACTION_DOWN = 0; // 0x0
    field public static final int ACTION_UP = 1; // 0x1
    field @NonNull public static final android.os.Parcelable.Creator<android.hardware.input.VirtualKeyEvent> CREATOR;
  }
  public static final class VirtualKeyEvent.Builder {
    ctor public VirtualKeyEvent.Builder();
    method @NonNull public android.hardware.input.VirtualKeyEvent build();
    method @NonNull public android.hardware.input.VirtualKeyEvent.Builder setAction(int);
    method @NonNull public android.hardware.input.VirtualKeyEvent.Builder setKeyCode(int);
  }
  public class VirtualKeyboard 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 sendKeyEvent(@NonNull android.hardware.input.VirtualKeyEvent);
  }
  public class VirtualMouse 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.VirtualMouseButtonEvent);
    method @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void sendRelativeEvent(@NonNull android.hardware.input.VirtualMouseRelativeEvent);
    method @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void sendScrollEvent(@NonNull android.hardware.input.VirtualMouseScrollEvent);
  }
  public final class VirtualMouseButtonEvent implements android.os.Parcelable {
    method public int describeContents();
    method public int getAction();
    method public int getButtonCode();
    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_BACK = 8; // 0x8
    field public static final int BUTTON_FORWARD = 16; // 0x10
    field public static final int BUTTON_PRIMARY = 1; // 0x1
    field public static final int BUTTON_SECONDARY = 2; // 0x2
    field public static final int BUTTON_TERTIARY = 4; // 0x4
    field @NonNull public static final android.os.Parcelable.Creator<android.hardware.input.VirtualMouseButtonEvent> CREATOR;
  }
  public static final class VirtualMouseButtonEvent.Builder {
    ctor public VirtualMouseButtonEvent.Builder();
    method @NonNull public android.hardware.input.VirtualMouseButtonEvent build();
    method @NonNull public android.hardware.input.VirtualMouseButtonEvent.Builder setAction(int);
    method @NonNull public android.hardware.input.VirtualMouseButtonEvent.Builder setButtonCode(int);
  }
  public final class VirtualMouseRelativeEvent implements android.os.Parcelable {
    method public int describeContents();
    method public float getRelativeX();
    method public float getRelativeY();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.hardware.input.VirtualMouseRelativeEvent> CREATOR;
  }
  public static final class VirtualMouseRelativeEvent.Builder {
    ctor public VirtualMouseRelativeEvent.Builder();
    method @NonNull public android.hardware.input.VirtualMouseRelativeEvent build();
    method @NonNull public android.hardware.input.VirtualMouseRelativeEvent.Builder setRelativeX(float);
    method @NonNull public android.hardware.input.VirtualMouseRelativeEvent.Builder setRelativeY(float);
  }
  public final class VirtualMouseScrollEvent implements android.os.Parcelable {
    method public int describeContents();
    method public float getXAxisMovement();
    method public float getYAxisMovement();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.hardware.input.VirtualMouseScrollEvent> CREATOR;
  }
  public static final class VirtualMouseScrollEvent.Builder {
    ctor public VirtualMouseScrollEvent.Builder();
    method @NonNull public android.hardware.input.VirtualMouseScrollEvent build();
    method @NonNull public android.hardware.input.VirtualMouseScrollEvent.Builder setXAxisMovement(@FloatRange(from=-1.0F, to=1.0f) float);
    method @NonNull public android.hardware.input.VirtualMouseScrollEvent.Builder setYAxisMovement(@FloatRange(from=-1.0F, to=1.0f) float);
  }
  public final class VirtualTouchEvent implements android.os.Parcelable {
    method public int describeContents();
    method public int getAction();
    method public float getMajorAxisSize();
    method public int getPointerId();
    method public float getPressure();
    method public int getToolType();
    method public float getX();
    method public float getY();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field public static final int ACTION_CANCEL = 3; // 0x3
    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.VirtualTouchEvent> CREATOR;
    field public static final int TOOL_TYPE_FINGER = 1; // 0x1
    field public static final int TOOL_TYPE_PALM = 5; // 0x5
  }
  public static final class VirtualTouchEvent.Builder {
    ctor public VirtualTouchEvent.Builder();
    method @NonNull public android.hardware.input.VirtualTouchEvent build();
    method @NonNull public android.hardware.input.VirtualTouchEvent.Builder setAction(int);
    method @NonNull public android.hardware.input.VirtualTouchEvent.Builder setMajorAxisSize(@FloatRange(from=0.0f) float);
    method @NonNull public android.hardware.input.VirtualTouchEvent.Builder setPointerId(int);
    method @NonNull public android.hardware.input.VirtualTouchEvent.Builder setPressure(@FloatRange(from=0.0f) float);
    method @NonNull public android.hardware.input.VirtualTouchEvent.Builder setToolType(int);
    method @NonNull public android.hardware.input.VirtualTouchEvent.Builder setX(float);
    method @NonNull public android.hardware.input.VirtualTouchEvent.Builder setY(float);
  }
  public class VirtualTouchscreen 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 sendTouchEvent(@NonNull android.hardware.input.VirtualTouchEvent);
  }
}
package android.hardware.lights {
  public final class LightState implements android.os.Parcelable {
+32 −0
Original line number Diff line number Diff line
@@ -16,6 +16,13 @@

package android.companion.virtual;

import android.graphics.Point;
import android.hardware.input.VirtualKeyEvent;
import android.hardware.input.VirtualMouseButtonEvent;
import android.hardware.input.VirtualMouseRelativeEvent;
import android.hardware.input.VirtualMouseScrollEvent;
import android.hardware.input.VirtualTouchEvent;

/**
 * Interface for a virtual device.
 *
@@ -34,4 +41,29 @@ interface IVirtualDevice {
     * Closes the virtual device and frees all associated resources.
     */
    void close();
    void createVirtualKeyboard(
            int displayId,
            String inputDeviceName,
            int vendorId,
            int productId,
            IBinder token);
    void createVirtualMouse(
            int displayId,
            String inputDeviceName,
            int vendorId,
            int productId,
            IBinder token);
    void createVirtualTouchscreen(
            int displayId,
            String inputDeviceName,
            int vendorId,
            int productId,
            IBinder token,
            in Point screenSize);
    void unregisterInputDevice(IBinder token);
    boolean sendKeyEvent(IBinder token, in VirtualKeyEvent event);
    boolean sendButtonEvent(IBinder token, in VirtualMouseButtonEvent event);
    boolean sendRelativeEvent(IBinder token, in VirtualMouseRelativeEvent event);
    boolean sendScrollEvent(IBinder token, in VirtualMouseScrollEvent event);
    boolean sendTouchEvent(IBinder token, in VirtualTouchEvent event);
}
+91 −0
Original line number Diff line number Diff line
@@ -23,7 +23,13 @@ import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.companion.AssociationInfo;
import android.content.Context;
import android.graphics.Point;
import android.hardware.display.VirtualDisplay;
import android.hardware.input.VirtualKeyboard;
import android.hardware.input.VirtualMouse;
import android.hardware.input.VirtualTouchscreen;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;

/**
@@ -73,6 +79,8 @@ public final class VirtualDeviceManager {
     * A virtual device has its own virtual display, audio output, microphone, and camera etc. The
     * creator of a virtual device can take the output from the virtual display and stream it over
     * to another device, and inject input events that are received from the remote device.
     *
     * TODO(b/204081582): Consider using a builder pattern for the input APIs.
     */
    public static class VirtualDevice implements AutoCloseable {

@@ -95,5 +103,88 @@ public final class VirtualDeviceManager {
                throw e.rethrowFromSystemServer();
            }
        }

        /**
         * Creates a virtual keyboard.
         *
         * @param display the display that the events inputted through this device should target
         * @param inputDeviceName the name to call this input device
         * @param vendorId the vendor id
         * @param productId the product id
         * @hide
         */
        @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
        @NonNull
        public VirtualKeyboard createVirtualKeyboard(
                @NonNull VirtualDisplay display,
                @NonNull String inputDeviceName,
                int vendorId,
                int productId) {
            try {
                final IBinder token = new Binder(
                        "android.hardware.input.VirtualKeyboard:" + inputDeviceName);
                mVirtualDevice.createVirtualKeyboard(display.getDisplay().getDisplayId(),
                        inputDeviceName, vendorId, productId, token);
                return new VirtualKeyboard(mVirtualDevice, token);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }

        /**
         * Creates a virtual mouse.
         *
         * @param display the display that the events inputted through this device should target
         * @param inputDeviceName the name to call this input device
         * @param vendorId the vendor id
         * @param productId the product id
         * @hide
         */
        @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
        @NonNull
        public VirtualMouse createVirtualMouse(
                @NonNull VirtualDisplay display,
                @NonNull String inputDeviceName,
                int vendorId,
                int productId) {
            try {
                final IBinder token = new Binder(
                        "android.hardware.input.VirtualMouse:" + inputDeviceName);
                mVirtualDevice.createVirtualMouse(display.getDisplay().getDisplayId(),
                        inputDeviceName, vendorId, productId, token);
                return new VirtualMouse(mVirtualDevice, token);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }

        /**
         * Creates a virtual touchscreen.
         *
         * @param display the display that the events inputted through this device should target
         * @param inputDeviceName the name to call this input device
         * @param vendorId the vendor id
         * @param productId the product id
         * @hide
         */
        @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
        @NonNull
        public VirtualTouchscreen createVirtualTouchscreen(
                @NonNull VirtualDisplay display,
                @NonNull String inputDeviceName,
                int vendorId,
                int productId) {
            try {
                final IBinder token = new Binder(
                        "android.hardware.input.VirtualTouchscreen:" + inputDeviceName);
                final Point size = new Point();
                display.getDisplay().getSize(size);
                mVirtualDevice.createVirtualTouchscreen(display.getDisplay().getDisplayId(),
                        inputDeviceName, vendorId, productId, token, size);
                return new VirtualTouchscreen(mVirtualDevice, token);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }
    }
}
+19 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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;

parcelable VirtualKeyEvent;
 No newline at end of file
+152 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.view.KeyEvent;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * An event describing a keyboard interaction originating from a remote device.
 *
 * When the user presses a key, an {@code ACTION_DOWN} event should be reported. When the user
 * releases the key, an {@code ACTION_UP} event should be reported.
 *
 * See {@link android.view.KeyEvent}.
 *
 * @hide
 */
@SystemApi
public final class VirtualKeyEvent implements Parcelable {

    /** @hide */
    public static final int ACTION_UNKNOWN = -1;
    /** Action indicating the given key has been pressed. */
    public static final int ACTION_DOWN = KeyEvent.ACTION_DOWN;
    /** Action indicating the previously pressed key has been lifted. */
    public static final int ACTION_UP = KeyEvent.ACTION_UP;

    /** @hide */
    @IntDef(prefix = { "ACTION_" }, value = {
            ACTION_UNKNOWN,
            ACTION_DOWN,
            ACTION_UP,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface Action {
    }

    private final @Action int mAction;
    private final int mKeyCode;

    private VirtualKeyEvent(@Action int action, int keyCode) {
        mAction = action;
        mKeyCode = keyCode;
    }

    private VirtualKeyEvent(@NonNull Parcel parcel) {
        mAction = parcel.readInt();
        mKeyCode = parcel.readInt();
    }

    @Override
    public void writeToParcel(@NonNull Parcel parcel, int parcelableFlags) {
        parcel.writeInt(mAction);
        parcel.writeInt(mKeyCode);
    }

    @Override
    public int describeContents() {
        return 0;
    }

    /**
     * Returns the key code associated with this event.
     */
    public int getKeyCode() {
        return mKeyCode;
    }

    /**
     * Returns the action associated with this event.
     */
    public @Action int getAction() {
        return mAction;
    }

    /**
     * Builder for {@link VirtualKeyEvent}.
     */
    public static final class Builder {

        private @Action int mAction = ACTION_UNKNOWN;
        private int mKeyCode = -1;

        /**
         * Creates a {@link VirtualKeyEvent} object with the current builder configuration.
         */
        public @NonNull VirtualKeyEvent build() {
            if (mAction == ACTION_UNKNOWN || mKeyCode == -1) {
                throw new IllegalArgumentException(
                        "Cannot build virtual key event with unset fields");
            }
            return new VirtualKeyEvent(mAction, mKeyCode);
        }

        /**
         * Sets the Android key code of the event. The set of allowed characters include digits 0-9,
         * characters A-Z, and standard punctuation, as well as numpad keys, function keys F1-F12,
         * and meta keys (caps lock, shift, etc.).
         *
         * @return this builder, to allow for chaining of calls
         */
        public @NonNull Builder setKeyCode(int keyCode) {
            mKeyCode = keyCode;
            return this;
        }

        /**
         * Sets the action of the event.
         *
         * @return this builder, to allow for chaining of calls
         */
        public @NonNull Builder setAction(@Action int action) {
            if (action != ACTION_DOWN && action != ACTION_UP) {
                throw new IllegalArgumentException("Unsupported action type");
            }
            mAction = action;
            return this;
        }
    }

    public static final @NonNull Parcelable.Creator<VirtualKeyEvent> CREATOR =
            new Parcelable.Creator<VirtualKeyEvent>() {
        public VirtualKeyEvent createFromParcel(Parcel source) {
            return new VirtualKeyEvent(source);
        }

        public VirtualKeyEvent[] newArray(int size) {
            return new VirtualKeyEvent[size];
        }
    };
}
Loading