blob: 57b659d9ee0712a86d745ad067a0f6f469c9cca3 [file] [log] [blame]
/*
* Copyright (C) 2012 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.
*/
#pragma once
#include <android/sensor.h>
#include <ftl/flags.h>
#include <ftl/mixins.h>
#include <input/Input.h>
#include <input/KeyCharacterMap.h>
#include <set>
#include <unordered_map>
#include <vector>
#include <android/os/IInputConstants.h>
namespace android {
/*
* Identifies a device.
*/
struct InputDeviceIdentifier {
inline InputDeviceIdentifier() :
bus(0), vendor(0), product(0), version(0) {
}
// Information provided by the kernel.
std::string name;
std::string location;
std::string uniqueId;
uint16_t bus;
uint16_t vendor;
uint16_t product;
uint16_t version;
// A composite input device descriptor string that uniquely identifies the device
// even across reboots or reconnections. The value of this field is used by
// upper layers of the input system to associate settings with individual devices.
// It is hashed from whatever kernel provided information is available.
// Ideally, the way this value is computed should not change between Android releases
// because that would invalidate persistent settings that rely on it.
std::string descriptor;
// A value added to uniquely identify a device in the absence of a unique id. This
// is intended to be a minimum way to distinguish from other active devices and may
// reuse values that are not associated with an input anymore.
uint16_t nonce;
// The bluetooth address of the device, if known.
std::optional<std::string> bluetoothAddress;
/**
* Return InputDeviceIdentifier.name that has been adjusted as follows:
* - all characters besides alphanumerics, dash,
* and underscore have been replaced with underscores.
* This helps in situations where a file that matches the device name is needed,
* while conforming to the filename limitations.
*/
std::string getCanonicalName() const;
bool operator==(const InputDeviceIdentifier&) const = default;
bool operator!=(const InputDeviceIdentifier&) const = default;
};
/**
* Holds View related behaviors for an InputDevice.
*/
struct InputDeviceViewBehavior {
/**
* The smooth scroll behavior that applies for all source/axis, if defined by the device.
* Empty optional if the device has not specified the default smooth scroll behavior.
*/
std::optional<bool> shouldSmoothScroll;
};
/* Types of input device sensors. Keep sync with core/java/android/hardware/Sensor.java */
enum class InputDeviceSensorType : int32_t {
ACCELEROMETER = ASENSOR_TYPE_ACCELEROMETER,
MAGNETIC_FIELD = ASENSOR_TYPE_MAGNETIC_FIELD,
ORIENTATION = 3,
GYROSCOPE = ASENSOR_TYPE_GYROSCOPE,
LIGHT = ASENSOR_TYPE_LIGHT,
PRESSURE = ASENSOR_TYPE_PRESSURE,
TEMPERATURE = 7,
PROXIMITY = ASENSOR_TYPE_PROXIMITY,
GRAVITY = ASENSOR_TYPE_GRAVITY,
LINEAR_ACCELERATION = ASENSOR_TYPE_LINEAR_ACCELERATION,
ROTATION_VECTOR = ASENSOR_TYPE_ROTATION_VECTOR,
RELATIVE_HUMIDITY = ASENSOR_TYPE_RELATIVE_HUMIDITY,
AMBIENT_TEMPERATURE = ASENSOR_TYPE_AMBIENT_TEMPERATURE,
MAGNETIC_FIELD_UNCALIBRATED = ASENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED,
GAME_ROTATION_VECTOR = ASENSOR_TYPE_GAME_ROTATION_VECTOR,
GYROSCOPE_UNCALIBRATED = ASENSOR_TYPE_GYROSCOPE_UNCALIBRATED,
SIGNIFICANT_MOTION = ASENSOR_TYPE_SIGNIFICANT_MOTION,
ftl_first = ACCELEROMETER,
ftl_last = SIGNIFICANT_MOTION
};
enum class InputDeviceSensorAccuracy : int32_t {
ACCURACY_NONE = 0,
ACCURACY_LOW = 1,
ACCURACY_MEDIUM = 2,
ACCURACY_HIGH = 3,
};
enum class InputDeviceSensorReportingMode : int32_t {
CONTINUOUS = 0,
ON_CHANGE = 1,
ONE_SHOT = 2,
SPECIAL_TRIGGER = 3,
};
enum class InputDeviceLightType : int32_t {
INPUT = 0,
PLAYER_ID = 1,
KEYBOARD_BACKLIGHT = 2,
ftl_last = KEYBOARD_BACKLIGHT
};
enum class InputDeviceLightCapability : uint32_t {
/** Capability to change brightness of the light */
BRIGHTNESS = 0x00000001,
/** Capability to change color of the light */
RGB = 0x00000002,
};
struct InputDeviceSensorInfo {
explicit InputDeviceSensorInfo(std::string name, std::string vendor, int32_t version,
InputDeviceSensorType type, InputDeviceSensorAccuracy accuracy,
float maxRange, float resolution, float power, int32_t minDelay,
int32_t fifoReservedEventCount, int32_t fifoMaxEventCount,
std::string stringType, int32_t maxDelay, int32_t flags,
int32_t id)
: name(name),
vendor(vendor),
version(version),
type(type),
accuracy(accuracy),
maxRange(maxRange),
resolution(resolution),
power(power),
minDelay(minDelay),
fifoReservedEventCount(fifoReservedEventCount),
fifoMaxEventCount(fifoMaxEventCount),
stringType(stringType),
maxDelay(maxDelay),
flags(flags),
id(id) {}
// Name string of the sensor.
std::string name;
// Vendor string of this sensor.
std::string vendor;
// Version of the sensor's module.
int32_t version;
// Generic type of this sensor.
InputDeviceSensorType type;
// The current accuracy of sensor event.
InputDeviceSensorAccuracy accuracy;
// Maximum range of the sensor in the sensor's unit.
float maxRange;
// Resolution of the sensor in the sensor's unit.
float resolution;
// The power in mA used by this sensor while in use.
float power;
// The minimum delay allowed between two events in microsecond or zero if this sensor only
// returns a value when the data it's measuring changes.
int32_t minDelay;
// Number of events reserved for this sensor in the batch mode FIFO.
int32_t fifoReservedEventCount;
// Maximum number of events of this sensor that could be batched.
int32_t fifoMaxEventCount;
// The type of this sensor as a string.
std::string stringType;
// The delay between two sensor events corresponding to the lowest frequency that this sensor
// supports.
int32_t maxDelay;
// Sensor flags
int32_t flags;
// Sensor id, same as the input device ID it belongs to.
int32_t id;
};
struct BrightnessLevel : ftl::DefaultConstructible<BrightnessLevel, std::uint8_t>,
ftl::Equatable<BrightnessLevel>,
ftl::Orderable<BrightnessLevel>,
ftl::Addable<BrightnessLevel> {
using DefaultConstructible::DefaultConstructible;
};
struct InputDeviceLightInfo {
explicit InputDeviceLightInfo(std::string name, int32_t id, InputDeviceLightType type,
ftl::Flags<InputDeviceLightCapability> capabilityFlags,
int32_t ordinal,
std::set<BrightnessLevel> preferredBrightnessLevels)
: name(name),
id(id),
type(type),
capabilityFlags(capabilityFlags),
ordinal(ordinal),
preferredBrightnessLevels(std::move(preferredBrightnessLevels)) {}
// Name string of the light.
std::string name;
// Light id
int32_t id;
// Type of the light.
InputDeviceLightType type;
// Light capabilities.
ftl::Flags<InputDeviceLightCapability> capabilityFlags;
// Ordinal of the light
int32_t ordinal;
// Custom brightness levels for the light
std::set<BrightnessLevel> preferredBrightnessLevels;
};
struct InputDeviceBatteryInfo {
explicit InputDeviceBatteryInfo(std::string name, int32_t id) : name(name), id(id) {}
// Name string of the battery.
std::string name;
// Battery id
int32_t id;
};
struct KeyboardLayoutInfo {
explicit KeyboardLayoutInfo(std::string languageTag, std::string layoutType)
: languageTag(languageTag), layoutType(layoutType) {}
// A BCP 47 conformant language tag such as "en-US".
std::string languageTag;
// The layout type such as QWERTY or AZERTY.
std::string layoutType;
inline bool operator==(const KeyboardLayoutInfo& other) const {
return languageTag == other.languageTag && layoutType == other.layoutType;
}
inline bool operator!=(const KeyboardLayoutInfo& other) const { return !(*this == other); }
};
// The version of the Universal Stylus Initiative (USI) protocol supported by the input device.
struct InputDeviceUsiVersion {
int32_t majorVersion = -1;
int32_t minorVersion = -1;
};
/*
* Describes the characteristics and capabilities of an input device.
*/
class InputDeviceInfo {
public:
InputDeviceInfo();
InputDeviceInfo(const InputDeviceInfo& other);
~InputDeviceInfo();
struct MotionRange {
int32_t axis;
uint32_t source;
float min;
float max;
float flat;
float fuzz;
float resolution;
};
void initialize(int32_t id, int32_t generation, int32_t controllerNumber,
const InputDeviceIdentifier& identifier, const std::string& alias,
bool isExternal, bool hasMic, int32_t associatedDisplayId,
InputDeviceViewBehavior viewBehavior = {{}});
inline int32_t getId() const { return mId; }
inline int32_t getControllerNumber() const { return mControllerNumber; }
inline int32_t getGeneration() const { return mGeneration; }
inline const InputDeviceIdentifier& getIdentifier() const { return mIdentifier; }
inline const std::string& getAlias() const { return mAlias; }
inline const std::string& getDisplayName() const {
return mAlias.empty() ? mIdentifier.name : mAlias;
}
inline bool isExternal() const { return mIsExternal; }
inline bool hasMic() const { return mHasMic; }
inline uint32_t getSources() const { return mSources; }
const MotionRange* getMotionRange(int32_t axis, uint32_t source) const;
void addSource(uint32_t source);
void addMotionRange(int32_t axis, uint32_t source,
float min, float max, float flat, float fuzz, float resolution);
void addMotionRange(const MotionRange& range);
void addSensorInfo(const InputDeviceSensorInfo& info);
void addBatteryInfo(const InputDeviceBatteryInfo& info);
void addLightInfo(const InputDeviceLightInfo& info);
void setKeyboardType(int32_t keyboardType);
inline int32_t getKeyboardType() const { return mKeyboardType; }
void setKeyboardLayoutInfo(KeyboardLayoutInfo keyboardLayoutInfo);
inline const std::optional<KeyboardLayoutInfo>& getKeyboardLayoutInfo() const {
return mKeyboardLayoutInfo;
}
inline const InputDeviceViewBehavior& getViewBehavior() const { return mViewBehavior; }
inline void setKeyCharacterMap(const std::shared_ptr<KeyCharacterMap> value) {
mKeyCharacterMap = value;
}
inline const std::shared_ptr<KeyCharacterMap> getKeyCharacterMap() const {
return mKeyCharacterMap;
}
inline void setVibrator(bool hasVibrator) { mHasVibrator = hasVibrator; }
inline bool hasVibrator() const { return mHasVibrator; }
inline void setHasBattery(bool hasBattery) { mHasBattery = hasBattery; }
inline bool hasBattery() const { return mHasBattery; }
inline void setButtonUnderPad(bool hasButton) { mHasButtonUnderPad = hasButton; }
inline bool hasButtonUnderPad() const { return mHasButtonUnderPad; }
inline void setHasSensor(bool hasSensor) { mHasSensor = hasSensor; }
inline bool hasSensor() const { return mHasSensor; }
inline const std::vector<MotionRange>& getMotionRanges() const {
return mMotionRanges;
}
std::vector<InputDeviceSensorInfo> getSensors();
std::vector<InputDeviceLightInfo> getLights();
inline void setUsiVersion(std::optional<InputDeviceUsiVersion> usiVersion) {
mUsiVersion = std::move(usiVersion);
}
inline std::optional<InputDeviceUsiVersion> getUsiVersion() const { return mUsiVersion; }
inline int32_t getAssociatedDisplayId() const { return mAssociatedDisplayId; }
private:
int32_t mId;
int32_t mGeneration;
int32_t mControllerNumber;
InputDeviceIdentifier mIdentifier;
std::string mAlias;
bool mIsExternal;
bool mHasMic;
std::optional<KeyboardLayoutInfo> mKeyboardLayoutInfo;
uint32_t mSources;
int32_t mKeyboardType;
std::shared_ptr<KeyCharacterMap> mKeyCharacterMap;
std::optional<InputDeviceUsiVersion> mUsiVersion;
int32_t mAssociatedDisplayId;
bool mHasVibrator;
bool mHasBattery;
bool mHasButtonUnderPad;
bool mHasSensor;
std::vector<MotionRange> mMotionRanges;
std::unordered_map<InputDeviceSensorType, InputDeviceSensorInfo> mSensors;
/* Map from light ID to light info */
std::unordered_map<int32_t, InputDeviceLightInfo> mLights;
/* Map from battery ID to battery info */
std::unordered_map<int32_t, InputDeviceBatteryInfo> mBatteries;
/** The View related behaviors for the device. */
InputDeviceViewBehavior mViewBehavior;
};
/* Types of input device configuration files. */
enum class InputDeviceConfigurationFileType : int32_t {
CONFIGURATION = 0, /* .idc file */
KEY_LAYOUT = 1, /* .kl file */
KEY_CHARACTER_MAP = 2, /* .kcm file */
};
/*
* Gets the path of an input device configuration file, if one is available.
* Considers both system provided and user installed configuration files.
* The optional suffix is appended to the end of the file name (before the
* extension).
*
* The device identifier is used to construct several default configuration file
* names to try based on the device name, vendor, product, and version.
*
* Returns an empty string if not found.
*/
extern std::string getInputDeviceConfigurationFilePathByDeviceIdentifier(
const InputDeviceIdentifier& deviceIdentifier, InputDeviceConfigurationFileType type,
const char* suffix = "");
/*
* Gets the path of an input device configuration file, if one is available.
* Considers both system provided and user installed configuration files.
*
* The name is case-sensitive and is used to construct the filename to resolve.
* All characters except 'a'-'z', 'A'-'Z', '0'-'9', '-', and '_' are replaced by underscores.
*
* Returns an empty string if not found.
*/
extern std::string getInputDeviceConfigurationFilePathByName(
const std::string& name, InputDeviceConfigurationFileType type);
enum ReservedInputDeviceId : int32_t {
// Device id representing an invalid device
INVALID_INPUT_DEVICE_ID = android::os::IInputConstants::INVALID_INPUT_DEVICE_ID,
// Device id of a special "virtual" keyboard that is always present.
VIRTUAL_KEYBOARD_ID = -1,
// Device id of the "built-in" keyboard if there is one.
BUILT_IN_KEYBOARD_ID = 0,
// First device id available for dynamic devices
END_RESERVED_ID = 1,
};
} // namespace android