212 lines
6.7 KiB
Java
212 lines
6.7 KiB
Java
/*
|
|
* 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.SystemApi;
|
|
import android.os.Parcel;
|
|
import android.view.Display;
|
|
|
|
import java.nio.charset.StandardCharsets;
|
|
import java.util.Objects;
|
|
|
|
/**
|
|
* Common configurations to create virtual input devices.
|
|
*
|
|
* @hide
|
|
*/
|
|
@SystemApi
|
|
public abstract class VirtualInputDeviceConfig {
|
|
|
|
/**
|
|
* The maximum length of a device name (in bytes in UTF-8 encoding).
|
|
*
|
|
* This limitation comes directly from uinput.
|
|
* See also UINPUT_MAX_NAME_SIZE in linux/uinput.h
|
|
*/
|
|
private static final int DEVICE_NAME_MAX_LENGTH = 80;
|
|
|
|
/** The vendor id uniquely identifies the company who manufactured the device. */
|
|
private final int mVendorId;
|
|
/**
|
|
* The product id uniquely identifies which product within the address space of a given vendor,
|
|
* identified by the device's vendor id.
|
|
*/
|
|
private final int mProductId;
|
|
/** The associated display ID of the virtual input device. */
|
|
private final int mAssociatedDisplayId;
|
|
/** The name of the virtual input device. */
|
|
@NonNull
|
|
private final String mInputDeviceName;
|
|
|
|
protected VirtualInputDeviceConfig(@NonNull Builder<? extends Builder<?>> builder) {
|
|
mVendorId = builder.mVendorId;
|
|
mProductId = builder.mProductId;
|
|
mAssociatedDisplayId = builder.mAssociatedDisplayId;
|
|
mInputDeviceName = Objects.requireNonNull(builder.mInputDeviceName);
|
|
|
|
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
|
|
// for device name is DEVICE_NAME_MAX_LENGTH - 1
|
|
if (mInputDeviceName.getBytes(StandardCharsets.UTF_8).length >= DEVICE_NAME_MAX_LENGTH) {
|
|
throw new IllegalArgumentException("Input device name exceeds maximum length of "
|
|
+ DEVICE_NAME_MAX_LENGTH + "bytes: " + mInputDeviceName);
|
|
}
|
|
}
|
|
|
|
protected VirtualInputDeviceConfig(@NonNull Parcel in) {
|
|
mVendorId = in.readInt();
|
|
mProductId = in.readInt();
|
|
mAssociatedDisplayId = in.readInt();
|
|
mInputDeviceName = Objects.requireNonNull(in.readString8());
|
|
}
|
|
|
|
/**
|
|
* The vendor id uniquely identifies the company who manufactured the device.
|
|
*
|
|
* @see Builder#setVendorId(int) (int)
|
|
*/
|
|
public int getVendorId() {
|
|
return mVendorId;
|
|
}
|
|
|
|
/**
|
|
* The product id uniquely identifies which product within the address space of a given vendor,
|
|
* identified by the device's vendor id.
|
|
*
|
|
* @see Builder#setProductId(int)
|
|
*/
|
|
public int getProductId() {
|
|
return mProductId;
|
|
}
|
|
|
|
/**
|
|
* The associated display ID of the virtual input device.
|
|
*
|
|
* @see Builder#setAssociatedDisplayId(int)
|
|
*/
|
|
public int getAssociatedDisplayId() {
|
|
return mAssociatedDisplayId;
|
|
}
|
|
|
|
/**
|
|
* The name of the virtual input device.
|
|
*
|
|
* @see Builder#setInputDeviceName(String)
|
|
*/
|
|
@NonNull
|
|
public String getInputDeviceName() {
|
|
return mInputDeviceName;
|
|
}
|
|
|
|
void writeToParcel(@NonNull Parcel dest, int flags) {
|
|
dest.writeInt(mVendorId);
|
|
dest.writeInt(mProductId);
|
|
dest.writeInt(mAssociatedDisplayId);
|
|
dest.writeString8(mInputDeviceName);
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return getClass().getName() + "( "
|
|
+ " name=" + mInputDeviceName
|
|
+ " vendorId=" + mVendorId
|
|
+ " productId=" + mProductId
|
|
+ " associatedDisplayId=" + mAssociatedDisplayId
|
|
+ additionalFieldsToString() + ")";
|
|
}
|
|
|
|
/** @hide */
|
|
@NonNull
|
|
String additionalFieldsToString() {
|
|
return "";
|
|
}
|
|
|
|
/**
|
|
* A builder for {@link VirtualInputDeviceConfig}
|
|
*
|
|
* @param <T> The subclass to be built.
|
|
*/
|
|
@SuppressWarnings({"StaticFinalBuilder", "MissingBuildMethod"})
|
|
public abstract static class Builder<T extends Builder<T>> {
|
|
|
|
private int mVendorId;
|
|
private int mProductId;
|
|
private int mAssociatedDisplayId = Display.INVALID_DISPLAY;
|
|
private String mInputDeviceName;
|
|
|
|
/**
|
|
* Sets the vendor id of the device, identifying the company who manufactured the device.
|
|
*/
|
|
@NonNull
|
|
public T setVendorId(int vendorId) {
|
|
mVendorId = vendorId;
|
|
return self();
|
|
}
|
|
|
|
|
|
/**
|
|
* Sets the product id of the device, uniquely identifying the device within the address
|
|
* space of a given vendor, identified by the device's vendor id.
|
|
*/
|
|
@NonNull
|
|
public T setProductId(int productId) {
|
|
mProductId = productId;
|
|
return self();
|
|
}
|
|
|
|
/**
|
|
* Sets the associated display ID of the virtual input device. Required.
|
|
*
|
|
* <p>The input device is restricted to the display with the given ID and may not send
|
|
* events to any other display.</p>
|
|
*/
|
|
@NonNull
|
|
public T setAssociatedDisplayId(int displayId) {
|
|
mAssociatedDisplayId = displayId;
|
|
return self();
|
|
}
|
|
|
|
/**
|
|
* Sets the name of the virtual input device. Required.
|
|
*
|
|
* <p>The name must be unique among all input devices that belong to the same virtual
|
|
* device.</p>
|
|
*
|
|
* <p>The maximum allowed length of the name is 80 bytes in UTF-8 encoding, enforced by
|
|
* {@code UINPUT_MAX_NAME_SIZE}.</p>
|
|
*/
|
|
@NonNull
|
|
public T setInputDeviceName(@NonNull String deviceName) {
|
|
mInputDeviceName = Objects.requireNonNull(deviceName);
|
|
return self();
|
|
}
|
|
|
|
/**
|
|
* Each subclass should return itself to allow the builder to chain properly
|
|
*/
|
|
T self() {
|
|
return (T) this;
|
|
}
|
|
}
|
|
}
|