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

Commit d324c77f authored by Ambrus Weisz's avatar Ambrus Weisz
Browse files

Add new VirtualNavigationTouchpad.

The new virtual navigation touchpad can be used by connected devices that offer touch navigation through a touchpad. More details of implementation in the design doc below.

Design doc: http://go/virtual-touchpad
Test: atest cts/tests/tests/hardware/src/android/hardware/input/cts/tests/VirtualNavigationTouchpadTest, atest frameworks/native/services/inputflinger/tests/InputReader_test.cpp
Bug: 252767726

Change-Id: Ia4fdced1837c91d1534a6248d6d41d175a472fae
parent 0a9d5c28
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -2999,6 +2999,7 @@ package android.companion.virtual {
    method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualKeyboard createVirtualKeyboard(@NonNull android.hardware.display.VirtualDisplay, @NonNull String, int, int);
    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 @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();
@@ -4784,6 +4785,24 @@ package android.hardware.input {
    method @NonNull public android.hardware.input.VirtualMouseScrollEvent.Builder setYAxisMovement(@FloatRange(from=-1.0F, to=1.0f) float);
  }
  public class VirtualNavigationTouchpad 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);
  }
  public final class VirtualNavigationTouchpadConfig 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.VirtualNavigationTouchpadConfig> CREATOR;
  }
  public static final class VirtualNavigationTouchpadConfig.Builder extends android.hardware.input.VirtualInputDeviceConfig.Builder<android.hardware.input.VirtualNavigationTouchpadConfig.Builder> {
    ctor public VirtualNavigationTouchpadConfig.Builder(@IntRange(from=1) int, @IntRange(from=1) int);
    method @NonNull public android.hardware.input.VirtualNavigationTouchpadConfig build();
  }
  public final class VirtualTouchEvent implements android.os.Parcelable {
    method public int describeContents();
    method public int getAction();
+1 −0
Original line number Diff line number Diff line
@@ -2944,6 +2944,7 @@ package android.view {
  }

  public final class MotionEvent extends android.view.InputEvent implements android.os.Parcelable {
    method public int getDisplayId();
    method public void setActionButton(int);
    method public void setButtonState(int);
    method public void setDisplayId(int);
+5 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import android.hardware.input.VirtualMouseRelativeEvent;
import android.hardware.input.VirtualMouseScrollEvent;
import android.hardware.input.VirtualTouchEvent;
import android.hardware.input.VirtualTouchscreenConfig;
import android.hardware.input.VirtualNavigationTouchpadConfig;
import android.os.ResultReceiver;

/**
@@ -84,6 +85,10 @@ interface IVirtualDevice {
    void createVirtualTouchscreen(
            in VirtualTouchscreenConfig config,
            IBinder token);
    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)")
    void createVirtualNavigationTouchpad(
            in VirtualNavigationTouchpadConfig config,
            IBinder token);
    void unregisterInputDevice(IBinder token);
    int getInputDeviceId(IBinder token);
    boolean sendDpadKeyEvent(IBinder token, in VirtualKeyEvent event);
+26 −0
Original line number Diff line number Diff line
@@ -46,6 +46,8 @@ import android.hardware.input.VirtualKeyboard;
import android.hardware.input.VirtualKeyboardConfig;
import android.hardware.input.VirtualMouse;
import android.hardware.input.VirtualMouseConfig;
import android.hardware.input.VirtualNavigationTouchpad;
import android.hardware.input.VirtualNavigationTouchpadConfig;
import android.hardware.input.VirtualTouchscreen;
import android.hardware.input.VirtualTouchscreenConfig;
import android.os.Binder;
@@ -654,6 +656,30 @@ public final class VirtualDeviceManager {
            }
        }

        /**
         * Creates a virtual touchpad in navigation mode.
         *
         * A touchpad in navigation mode means that its events are interpreted as navigation events
         * (up, down, etc) instead of using them to update a cursor's absolute position. If the
         * events are not consumed they are converted to DPAD events.
         *
         * @param config the configurations of the virtual navigation touchpad.
         */
        @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
        @NonNull
        public VirtualNavigationTouchpad createVirtualNavigationTouchpad(
                 @NonNull VirtualNavigationTouchpadConfig config) {
            try {
                final IBinder token = new Binder(
                        "android.hardware.input.VirtualNavigationTouchpad:"
                            + config.getInputDeviceName());
                mVirtualDevice.createVirtualNavigationTouchpad(config, token);
                return new VirtualNavigationTouchpad(mVirtualDevice, token);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }

        /**
         * Creates a virtual touchscreen.
         *
+60 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 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.NonNull;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.companion.virtual.IVirtualDevice;
import android.os.IBinder;
import android.os.RemoteException;

/**
 * A virtual navigation touchpad representing a touch-based input mechanism on a remote device.
 *
 * <p>This registers an InputDevice that is interpreted like a physically-connected device and
 * dispatches received events to it.
 *
 * <p>The virtual touchpad will be in navigation mode. Motion results in focus traversal in the same
 * manner as D-Pad navigation if the events are not consumed.
 *
 * @see android.view.InputDevice#SOURCE_TOUCH_NAVIGATION
 *
 * @hide
 */
@SystemApi
public class VirtualNavigationTouchpad extends VirtualInputDevice {

    /** @hide */
    public VirtualNavigationTouchpad(IVirtualDevice virtualDevice, IBinder token) {
        super(virtualDevice, token);
    }

    /**
     * Sends a touch event to the system.
     *
     * @param event the event to send
     */
    @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
    public void sendTouchEvent(@NonNull VirtualTouchEvent event) {
        try {
            mVirtualDevice.sendTouchEvent(mToken, event);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }
}
Loading