IMS添加实体按键流程 - Android14
- 1、实体按键信息(Mi 9 左侧实体按键)
- 2、硬件添加
- 2.1 内核添加设备节点
- 2.2 Generic.kl映射文件
- 2.3 映射文件文件加载loadKeyMapLocked
- 2.4 addDeviceLocked 添加设备相关对象
- 3、keycode对应scankode
- 4、KeyEvent.java 添加对应keycode
InputReader线程获取输入事件-Android12
1、实体按键信息(Mi 9 左侧实体按键)
getevent
获取按键节点/dev/input/event3
,scancode对应0x02b1
(即底层硬件上报的对应scancode)dumpsys input
获取对应按键映射文件KeyLayoutFile: /system/usr/keylayout/gpio-keys.kl
、KeyCharacterMapFile: /system/usr/keychars/Generic.kcm
,对应Sources: 0x00000101
一般默认在
frameworks/base/data/keyboards/Generic.kl
mk配置文件:frameworks/base/data/keyboards/common.mk
、frameworks/base/data/keyboards/Android.mk
getevent
cepheus:/ $ getevent
add device 1: /dev/input/event7
name: "sm8150-tavil-snd-card USB_3_5 Jack"
add device 2: /dev/input/event6
name: "sm8150-tavil-snd-card Button Jack"
add device 3: /dev/input/event5
name: "sm8150-tavil-snd-card Headset Jack"
add device 4: /dev/input/event3
name: "gpio-keys"
add device 5: /dev/input/event2
name: "uinput-goodix"
add device 6: /dev/input/event0
name: "qpnp_pon"
add device 7: /dev/input/event1
name: "qti-haptics"
add device 8: /dev/input/event4
name: "fts"
/dev/input/event3: 0001 02b1 00000001
/dev/input/event3: 0000 0000 00000000
/dev/input/event3: 0001 02b1 00000000
/dev/input/event3: 0000 0000 00000000
/dev/input/event3: 0001 0073 00000001
/dev/input/event3: 0000 0000 00000000
/dev/input/event3: 0001 0073 00000000
/dev/input/event3: 0000 0000 00000000
/dev/input/event0: 0001 0072 00000001
/dev/input/event0: 0000 0000 00000000
/dev/input/event0: 0001 0072 00000000
/dev/input/event0: 0000 0000 00000000
/dev/input/event0: 0001 0074 00000001
/dev/input/event0: 0000 0000 00000000
/dev/input/event0: 0001 0074 00000000
/dev/input/event0: 0000 0000 00000000
adb shell dumpsys input > dumpsys_input.txt
4: gpio-keys
Classes: KEYBOARD
Path: /dev/input/event3
Enabled: true
Descriptor: 485d69228e24f5e46da1598745890b214130dbc4
Location: gpio-keys/input0
ControllerNumber: 0
UniqueId:
Identifier: bus=0x0019, vendor=0x0001, product=0x0001, version=0x0100
KeyLayoutFile: /system/usr/keylayout/gpio-keys.kl
KeyCharacterMapFile: /system/usr/keychars/Generic.kcm
ConfigurationFile:
VideoDevice: <none>
Device 5: gpio-keys
EventHub Devices: [ 4 ]
Generation: 15
IsExternal: false
AssociatedDisplayPort: <none>
AssociatedDisplayUniqueId: <none>
HasMic: false
Sources: 0x00000101
KeyboardType: 1
ControllerNum: 0
Keyboard Input Mapper:
Parameters:
OrientationAware: false
HandlesKeyRepeat: false
KeyboardType: 1
Orientation: 0
KeyDowns: 0 keys currently down
MetaState: 0x0
DownTime: 0
2、硬件添加
2.1 内核添加设备节点
在Linux内核中提供了按键的驱动程序
drivers/input/keyboard/gpio_keys.c
解析,一般都是dts
配置文件,scancode
查看linux,code
- POWER 按键:0074
/dev/input/event0: 0001 0074 00000001
- 音量上下键:0073、0072
/dev/input/event3: 0001 0073 00000001
/dev/input/event0: 0001 0072 00000001
- MI 9 左侧按键:02b1
/dev/input/event3: 0001 02b1 00000001
gpio-keys {
compatible = "gpio-keys";
input-name = "gpio-keys";
pinctrl-names = "default";
pinctrl-0 = <&gpio_keys_pin_a>;
camera-snapshot {
label = "camera_snapshot";
gpios = <&pm8941_gpios 1 GPIO_ACTIVE_LOW>;
linux,code = <KEY_CAMERA>;
wakeup-source;
debounce-interval = <15>;
};
volume-down {
label = "volume_down";
gpios = <&pm8941_gpios 2 GPIO_ACTIVE_LOW>;
linux,code = <KEY_VOLUMEDOWN>;
wakeup-source;
debounce-interval = <15>;
};
volume-up {
label = "volume_up";
gpios = <&pm8941_gpios 5 GPIO_ACTIVE_LOW>;
linux,code = <KEY_VOLUMEUP>;
wakeup-source;
debounce-interval = <15>;
};
};
2.2 Generic.kl映射文件
系统提供了一个特殊的内置常规按键布局文件,名为
Generic.kl
。此按键布局旨在支持各种标准外部键盘和操纵杆。请勿修改常规按键布局!
按键布局文件
按键字符映射文件
输入设备配置文件
2.3 映射文件文件加载loadKeyMapLocked
device->loadConfigurationLocked()
:这里导入kl配置文件,首先"Vendor_%04x_Product_%04x_Version_%04x%s"
,再次"Vendor_%04x_Product_%04x%s"
。查看dumpsys input
信息查看ConfigurationFile:
一般为空。
loadKeyMapLocked
这里导入默认kl配置文件。这里左侧按键对应KeyLayoutFile: /system/usr/keylayout/gpio-keys.kl
、power按键KeyLayoutFile: /system/usr/keylayout/Generic.kl
frameworks/native/services/inputflinger/reader/EventHub.cpp
status_t EventHub::Device::loadKeyMapLocked() {
return keyMap.load(identifier, configuration.get());
}
void EventHub::openDeviceLocked(const std::string& devicePath) {
// If an input device happens to register around the time when EventHub's constructor runs, it
// is possible that the same input event node (for example, /dev/input/event3) will be noticed
// in both 'inotify' callback and also in the 'scanDirLocked' pass. To prevent duplicate devices
// from getting registered, ensure that this path is not already covered by an existing device.
for (const auto& [deviceId, device] : mDevices) {
if (device->path == devicePath) {
return; // device was already registered
}
}
char buffer[80];
ALOGV("Opening device: %s", devicePath.c_str());
int fd = open(devicePath.c_str(), O_RDWR | O_CLOEXEC | O_NONBLOCK);
if (fd < 0) {
ALOGE("could not open %s, %s\n", devicePath.c_str(), strerror(errno));
return;
}
InputDeviceIdentifier identifier;
// Get device name.
if (ioctl(fd, EVIOCGNAME(sizeof(buffer) - 1), &buffer) < 1) {
ALOGE("Could not get device name for %s: %s", devicePath.c_str(), strerror(errno));
} else {
buffer[sizeof(buffer) - 1] = '\0';
identifier.name = buffer;
}
// Check to see if the device is on our excluded list
for (size_t i = 0; i < mExcludedDevices.size(); i++) {
const std::string& item = mExcludedDevices[i];
if (identifier.name == item) {
ALOGI("ignoring event id %s driver %s\n", devicePath.c_str(), item.c_str());
close(fd);
return;
}
}
// Get device driver version.
int driverVersion;
if (ioctl(fd, EVIOCGVERSION, &driverVersion)) {
ALOGE("could not get driver version for %s, %s\n", devicePath.c_str(), strerror(errno));
close(fd);
return;
}
// Get device identifier.
struct input_id inputId;
if (ioctl(fd, EVIOCGID, &inputId)) {
ALOGE("could not get device input id for %s, %s\n", devicePath.c_str(), strerror(errno));
close(fd);
return;
}
identifier.bus = inputId.bustype;
identifier.product = inputId.product;
identifier.vendor = inputId.vendor;
identifier.version = inputId.version;
// Get device physical location.
if (ioctl(fd, EVIOCGPHYS(sizeof(buffer) - 1), &buffer) < 1) {
// fprintf(stderr, "could not get location for %s, %s\n", devicePath, strerror(errno));
} else {
buffer[sizeof(buffer) - 1] = '\0';
identifier.location = buffer;
}
// Get device unique id.
if (ioctl(fd, EVIOCGUNIQ(sizeof(buffer) - 1), &buffer) < 1) {
// fprintf(stderr, "could not get idstring for %s, %s\n", devicePath, strerror(errno));
} else {
buffer[sizeof(buffer) - 1] = '\0';
identifier.uniqueId = buffer;
}
// Attempt to get the bluetooth address of an input device from the uniqueId.
if (identifier.bus == BUS_BLUETOOTH &&
std::regex_match(identifier.uniqueId,
std::regex("^[A-Fa-f0-9]{2}(?::[A-Fa-f0-9]{2}){5}$"))) {
identifier.bluetoothAddress = identifier.uniqueId;
// The Bluetooth stack requires alphabetic characters to be uppercase in a valid address.
for (auto& c : *identifier.bluetoothAddress) {
c = ::toupper(c);
}
}
// Fill in the descriptor.
assignDescriptorLocked(identifier);
// Allocate device. (The device object takes ownership of the fd at this point.)
int32_t deviceId = mNextDeviceId++;
std::unique_ptr<Device> device =
std::make_unique<Device>(fd, deviceId, devicePath, identifier,
obtainAssociatedDeviceLocked(devicePath));
ALOGV("add device %d: %s\n", deviceId, devicePath.c_str());
ALOGV(" bus: %04x\n"
" vendor %04x\n"
" product %04x\n"
" version %04x\n",
identifier.bus, identifier.vendor, identifier.product, identifier.version);
ALOGV(" name: \"%s\"\n", identifier.name.c_str());
ALOGV(" location: \"%s\"\n", identifier.location.c_str());
ALOGV(" unique id: \"%s\"\n", identifier.uniqueId.c_str());
ALOGV(" descriptor: \"%s\"\n", identifier.descriptor.c_str());
ALOGV(" driver: v%d.%d.%d\n", driverVersion >> 16, (driverVersion >> 8) & 0xff,
driverVersion & 0xff);
// Load the configuration file for the device.
device->loadConfigurationLocked();
// Figure out the kinds of events the device reports.
device->readDeviceBitMask(EVIOCGBIT(EV_KEY, 0), device->keyBitmask);
device->readDeviceBitMask(EVIOCGBIT(EV_ABS, 0), device->absBitmask);
device->readDeviceBitMask(EVIOCGBIT(EV_REL, 0), device->relBitmask);
device->readDeviceBitMask(EVIOCGBIT(EV_SW, 0), device->swBitmask);
device->readDeviceBitMask(EVIOCGBIT(EV_LED, 0), device->ledBitmask);
device->readDeviceBitMask(EVIOCGBIT(EV_FF, 0), device->ffBitmask);
device->readDeviceBitMask(EVIOCGBIT(EV_MSC, 0), device->mscBitmask);
device->readDeviceBitMask(EVIOCGPROP(0), device->propBitmask);
// See if this is a device with keys. This could be full keyboard, or other devices like
// gamepads, joysticks, and styluses with buttons that should generate key presses.
bool haveKeyboardKeys =
device->keyBitmask.any(0, BTN_MISC) || device->keyBitmask.any(BTN_WHEEL, KEY_MAX + 1);
bool haveGamepadButtons = device->keyBitmask.any(BTN_MISC, BTN_MOUSE) ||
device->keyBitmask.any(BTN_JOYSTICK, BTN_DIGI);
bool haveStylusButtons = device->keyBitmask.test(BTN_STYLUS) ||
device->keyBitmask.test(BTN_STYLUS2) || device->keyBitmask.test(BTN_STYLUS3);
if (haveKeyboardKeys || haveGamepadButtons || haveStylusButtons) {
device->classes |= InputDeviceClass::KEYBOARD;
}
// See if this is a cursor device such as a trackball or mouse.
if (device->keyBitmask.test(BTN_MOUSE) && device->relBitmask.test(REL_X) &&
device->relBitmask.test(REL_Y)) {
device->classes |= InputDeviceClass::CURSOR;
}
// See if the device is specially configured to be of a certain type.
if (device->configuration) {
std::string deviceType = device->configuration->getString("device.type").value_or("");
if (deviceType == "rotaryEncoder") {
device->classes |= InputDeviceClass::ROTARY_ENCODER;
} else if (deviceType == "externalStylus") {
device->classes |= InputDeviceClass::EXTERNAL_STYLUS;
}
}
// See if this is a touch pad.
// Is this a new modern multi-touch driver?
if (device->absBitmask.test(ABS_MT_POSITION_X) && device->absBitmask.test(ABS_MT_POSITION_Y)) {
// Some joysticks such as the PS3 controller report axes that conflict
// with the ABS_MT range. Try to confirm that the device really is
// a touch screen.
if (device->keyBitmask.test(BTN_TOUCH) || !haveGamepadButtons) {
device->classes |= (InputDeviceClass::TOUCH | InputDeviceClass::TOUCH_MT);
if (device->propBitmask.test(INPUT_PROP_POINTER) &&
!device->keyBitmask.any(BTN_TOOL_PEN, BTN_TOOL_FINGER) && !haveStylusButtons) {
device->classes |= InputDeviceClass::TOUCHPAD;
}
}
// Is this an old style single-touch driver?
} else if (device->keyBitmask.test(BTN_TOUCH) && device->absBitmask.test(ABS_X) &&
device->absBitmask.test(ABS_Y)) {
device->classes |= InputDeviceClass::TOUCH;
// Is this a stylus that reports contact/pressure independently of touch coordinates?
} else if ((device->absBitmask.test(ABS_PRESSURE) || device->keyBitmask.test(BTN_TOUCH)) &&
!device->absBitmask.test(ABS_X) && !device->absBitmask.test(ABS_Y)) {
device->classes |= InputDeviceClass::EXTERNAL_STYLUS;
}
// See if this device is a joystick.
// Assumes that joysticks always have gamepad buttons in order to distinguish them
// from other devices such as accelerometers that also have absolute axes.
if (haveGamepadButtons) {
auto assumedClasses = device->classes | InputDeviceClass::JOYSTICK;
for (int i = 0; i <= ABS_MAX; i++) {
if (device->absBitmask.test(i) &&
(getAbsAxisUsage(i, assumedClasses).test(InputDeviceClass::JOYSTICK))) {
device->classes = assumedClasses;
break;
}
}
}
// Check whether this device is an accelerometer.
if (device->propBitmask.test(INPUT_PROP_ACCELEROMETER)) {
device->classes |= InputDeviceClass::SENSOR;
}
// Check whether this device has switches.
for (int i = 0; i <= SW_MAX; i++) {
if (device->swBitmask.test(i)) {
device->classes |= InputDeviceClass::SWITCH;
break;
}
}
// Check whether this device supports the vibrator.
if (device->ffBitmask.test(FF_RUMBLE)) {
device->classes |= InputDeviceClass::VIBRATOR;
}
// Configure virtual keys.
if ((device->classes.test(InputDeviceClass::TOUCH))) {
// Load the virtual keys for the touch screen, if any.
// We do this now so that we can make sure to load the keymap if necessary.
bool success = device->loadVirtualKeyMapLocked();
if (success) {
device->classes |= InputDeviceClass::KEYBOARD;
}
}
// Load the key map.
// We need to do this for joysticks too because the key layout may specify axes, and for
// sensor as well because the key layout may specify the axes to sensor data mapping.
status_t keyMapStatus = NAME_NOT_FOUND;
if (device->classes.any(InputDeviceClass::KEYBOARD | InputDeviceClass::JOYSTICK |
InputDeviceClass::SENSOR)) {
// Load the keymap for the device.
keyMapStatus = device->loadKeyMapLocked();
}
// Configure the keyboard, gamepad or virtual keyboard.
if (device->classes.test(InputDeviceClass::KEYBOARD)) {
// Register the keyboard as a built-in keyboard if it is eligible.
if (!keyMapStatus && mBuiltInKeyboardId == NO_BUILT_IN_KEYBOARD &&
isEligibleBuiltInKeyboard(device->identifier, device->configuration.get(),
&device->keyMap)) {
mBuiltInKeyboardId = device->id;
}
// 'Q' key support = cheap test of whether this is an alpha-capable kbd
if (device->hasKeycodeLocked(AKEYCODE_Q)) {
device->classes |= InputDeviceClass::ALPHAKEY;
}
// See if this device has a DPAD.
if (device->hasKeycodeLocked(AKEYCODE_DPAD_UP) &&
device->hasKeycodeLocked(AKEYCODE_DPAD_DOWN) &&
device->hasKeycodeLocked(AKEYCODE_DPAD_LEFT) &&
device->hasKeycodeLocked(AKEYCODE_DPAD_RIGHT) &&
device->hasKeycodeLocked(AKEYCODE_DPAD_CENTER)) {
device->classes |= InputDeviceClass::DPAD;
}
// See if this device has a gamepad.
for (size_t i = 0; i < sizeof(GAMEPAD_KEYCODES) / sizeof(GAMEPAD_KEYCODES[0]); i++) {
if (device->hasKeycodeLocked(GAMEPAD_KEYCODES[i])) {
device->classes |= InputDeviceClass::GAMEPAD;
break;
}
}
// See if this device has any stylus buttons that we would want to fuse with touch data.
if (!device->classes.any(InputDeviceClass::TOUCH | InputDeviceClass::TOUCH_MT)) {
for (int32_t keycode : STYLUS_BUTTON_KEYCODES) {
if (device->hasKeycodeLocked(keycode)) {
device->classes |= InputDeviceClass::EXTERNAL_STYLUS;
break;
}
}
}
}
// If the device isn't recognized as something we handle, don't monitor it.
if (device->classes == ftl::Flags<InputDeviceClass>(0)) {
ALOGV("Dropping device: id=%d, path='%s', name='%s'", deviceId, devicePath.c_str(),
device->identifier.name.c_str());
return;
}
// Classify InputDeviceClass::BATTERY.
if (device->associatedDevice && !device->associatedDevice->batteryInfos.empty()) {
device->classes |= InputDeviceClass::BATTERY;
}
// Classify InputDeviceClass::LIGHT.
if (device->associatedDevice && !device->associatedDevice->lightInfos.empty()) {
device->classes |= InputDeviceClass::LIGHT;
}
// Determine whether the device has a mic.
if (device->deviceHasMicLocked()) {
device->classes |= InputDeviceClass::MIC;
}
// Determine whether the device is external or internal.
if (device->isExternalDeviceLocked()) {
device->classes |= InputDeviceClass::EXTERNAL;
}
if (device->classes.any(InputDeviceClass::JOYSTICK | InputDeviceClass::DPAD) &&
device->classes.test(InputDeviceClass::GAMEPAD)) {
device->controllerNumber = getNextControllerNumberLocked(device->identifier.name);
device->setLedForControllerLocked();
}
if (registerDeviceForEpollLocked(*device) != OK) {
return;
}
device->configureFd();
ALOGI("New device: id=%d, fd=%d, path='%s', name='%s', classes=%s, "
"configuration='%s', keyLayout='%s', keyCharacterMap='%s', builtinKeyboard=%s, ",
deviceId, fd, devicePath.c_str(), device->identifier.name.c_str(),
device->classes.string().c_str(), device->configurationFile.c_str(),
device->keyMap.keyLayoutFile.c_str(), device->keyMap.keyCharacterMapFile.c_str(),
toString(mBuiltInKeyboardId == deviceId));
addDeviceLocked(std::move(device));
}
frameworks/native/libs/input/Keyboard.cpp
static std::string getPath(const InputDeviceIdentifier& deviceIdentifier, const std::string& name,
InputDeviceConfigurationFileType type) {
return name.empty()
? getInputDeviceConfigurationFilePathByDeviceIdentifier(deviceIdentifier, type)
: getInputDeviceConfigurationFilePathByName(name, type);
}
status_t KeyMap::load(const InputDeviceIdentifier& deviceIdentifier,
const PropertyMap* deviceConfiguration) {
// Use the configured key layout if available.
if (deviceConfiguration) {
std::optional<std::string> keyLayoutName =
deviceConfiguration->getString("keyboard.layout");
if (keyLayoutName.has_value()) {
status_t status = loadKeyLayout(deviceIdentifier, *keyLayoutName);
if (status == NAME_NOT_FOUND) {
ALOGE("Configuration for keyboard device '%s' requested keyboard layout '%s' but "
"it was not found.",
deviceIdentifier.name.c_str(), keyLayoutName->c_str());
}
}
std::optional<std::string> keyCharacterMapName =
deviceConfiguration->getString("keyboard.characterMap");
if (keyCharacterMapName.has_value()) {
status_t status = loadKeyCharacterMap(deviceIdentifier, *keyCharacterMapName);
if (status == NAME_NOT_FOUND) {
ALOGE("Configuration for keyboard device '%s' requested keyboard character "
"map '%s' but it was not found.",
deviceIdentifier.name.c_str(), keyCharacterMapName->c_str());
}
}
if (isComplete()) {
return OK;
}
}
// Try searching by device identifier.
if (probeKeyMap(deviceIdentifier, "")) {
return OK;
}
// Fall back on the Generic key map.
// TODO Apply some additional heuristics here to figure out what kind of
// generic key map to use (US English, etc.) for typical external keyboards.
if (probeKeyMap(deviceIdentifier, "Generic")) {
return OK;
}
// Try the Virtual key map as a last resort.
if (probeKeyMap(deviceIdentifier, "Virtual")) {
return OK;
}
// Give up!
ALOGE("Could not determine key map for device '%s' and no default key maps were found!",
deviceIdentifier.name.c_str());
return NAME_NOT_FOUND;
}
bool KeyMap::probeKeyMap(const InputDeviceIdentifier& deviceIdentifier,
const std::string& keyMapName) {
if (!haveKeyLayout()) {
loadKeyLayout(deviceIdentifier, keyMapName);
}
if (!haveKeyCharacterMap()) {
loadKeyCharacterMap(deviceIdentifier, keyMapName);
}
return isComplete();
}
status_t KeyMap::loadKeyLayout(const InputDeviceIdentifier& deviceIdentifier,
const std::string& name) {
std::string path(getPath(deviceIdentifier, name, InputDeviceConfigurationFileType::KEY_LAYOUT));
if (path.empty()) {
return NAME_NOT_FOUND;
}
base::Result<std::shared_ptr<KeyLayoutMap>> ret = KeyLayoutMap::load(path);
if (ret.ok()) {
keyLayoutMap = *ret;
keyLayoutFile = path;
return OK;
}
// Try to load fallback layout if the regular layout could not be loaded due to missing
// kernel modules
std::string fallbackPath(
getInputDeviceConfigurationFilePathByDeviceIdentifier(deviceIdentifier,
InputDeviceConfigurationFileType::
KEY_LAYOUT,
"_fallback"));
ret = KeyLayoutMap::load(fallbackPath);
if (!ret.ok()) {
return ret.error().code();
}
keyLayoutMap = *ret;
keyLayoutFile = fallbackPath;
return OK;
}
frameworks/native/libs/input/InputDevice.cpp
std::string getInputDeviceConfigurationFilePathByDeviceIdentifier(
const InputDeviceIdentifier& deviceIdentifier, InputDeviceConfigurationFileType type,
const char* suffix) {
if (deviceIdentifier.vendor !=0 && deviceIdentifier.product != 0) {
if (deviceIdentifier.version != 0) {
// Try vendor product version.
std::string versionPath =
getInputDeviceConfigurationFilePathByName(StringPrintf("Vendor_%04x_Product_%"
"04x_Version_%04x%s",
deviceIdentifier.vendor,
deviceIdentifier.product,
deviceIdentifier.version,
suffix),
type);
if (!versionPath.empty()) {
return versionPath;
}
}
// Try vendor product.
std::string productPath =
getInputDeviceConfigurationFilePathByName(StringPrintf("Vendor_%04x_Product_%04x%s",
deviceIdentifier.vendor,
deviceIdentifier.product,
suffix),
type);
if (!productPath.empty()) {
return productPath;
}
}
// Try device name.
return getInputDeviceConfigurationFilePathByName(deviceIdentifier.getCanonicalName() + suffix,
type);
}
std::string getInputDeviceConfigurationFilePathByName(
const std::string& name, InputDeviceConfigurationFileType type) {
// Search system repository.
std::string path;
// Treblized input device config files will be located /product/usr, /system_ext/usr,
// /odm/usr or /vendor/usr.
// These files may also be in the com.android.input.config APEX.
const char* rootsForPartition[]{
"/product",
"/system_ext",
"/odm",
"/vendor",
"/apex/com.android.input.config/etc",
getenv("ANDROID_ROOT"),
};
for (size_t i = 0; i < size(rootsForPartition); i++) {
if (rootsForPartition[i] == nullptr) {
continue;
}
path = rootsForPartition[i];
path += "/usr/";
appendInputDeviceConfigurationFileRelativePath(path, name, type);
#if DEBUG_PROBE
ALOGD("Probing for system provided input device configuration file: path='%s'",
path.c_str());
#endif
if (!access(path.c_str(), R_OK)) {
#if DEBUG_PROBE
ALOGD("Found");
#endif
return path;
}
}
// Search user repository.
// TODO Should only look here if not in safe mode.
path = "";
char *androidData = getenv("ANDROID_DATA");
if (androidData != nullptr) {
path += androidData;
}
path += "/system/devices/";
appendInputDeviceConfigurationFileRelativePath(path, name, type);
#if DEBUG_PROBE
ALOGD("Probing for system user input device configuration file: path='%s'", path.c_str());
#endif
if (!access(path.c_str(), R_OK)) {
#if DEBUG_PROBE
ALOGD("Found");
#endif
return path;
}
// Not found.
#if DEBUG_PROBE
ALOGD("Probe failed to find input device configuration file: name='%s', type=%d",
name.c_str(), type);
#endif
return "";
}
2.4 addDeviceLocked 添加设备相关对象
addDeviceLocked 添加设备、IMS:EventHub 设备添加和InputDevice转化 其中
EventHub::scanDevicesLocked()
查询DEVICE_INPUT_PATH = "/dev/input"
路径添加/dev/input/event3
- InputDeviceIdentifier
- Device
InputDevice
InputMapper
: frameworks/native/services/inputflinger/reader/mapper;Classes: KEYBOARD
/Sources: 0x00000101
这里对应KeyboardInputMapper.cpp
(AINPUT_SOURCE_KEYBOARD = 0x00000100 | AINPUT_SOURCE_CLASS_BUTTON
)- InputDeviceInfo
frameworks/native/services/inputflinger/reader/InputReader.cpp
void InputReader::addDeviceLocked(nsecs_t when, int32_t eventHubId) {
if (mDevices.find(eventHubId) != mDevices.end()) {
ALOGW("Ignoring spurious device added event for eventHubId %d.", eventHubId);
return;
}
InputDeviceIdentifier identifier = mEventHub->getDeviceIdentifier(eventHubId);
std::shared_ptr<InputDevice> device = createDeviceLocked(eventHubId, identifier);
notifyAll(device->configure(when, mConfig, /*changes=*/{}));
notifyAll(device->reset(when));
if (device->isIgnored()) {
ALOGI("Device added: id=%d, eventHubId=%d, name='%s', descriptor='%s' "
"(ignored non-input device)",
device->getId(), eventHubId, identifier.name.c_str(), identifier.descriptor.c_str());
} else {
ALOGI("Device added: id=%d, eventHubId=%d, name='%s', descriptor='%s',sources=%s",
device->getId(), eventHubId, identifier.name.c_str(), identifier.descriptor.c_str(),
inputEventSourceToString(device->getSources()).c_str());
}
mDevices.emplace(eventHubId, device);
// Add device to device to EventHub ids map.
const auto mapIt = mDeviceToEventHubIdsMap.find(device);
if (mapIt == mDeviceToEventHubIdsMap.end()) {
std::vector<int32_t> ids = {eventHubId};
mDeviceToEventHubIdsMap.emplace(device, ids);
} else {
mapIt->second.push_back(eventHubId);
}
bumpGenerationLocked();
if (device->getClasses().test(InputDeviceClass::EXTERNAL_STYLUS)) {
notifyExternalStylusPresenceChangedLocked();
}
// Sensor input device is noisy, to save power disable it by default.
// Input device is classified as SENSOR when any sub device is a SENSOR device, check Eventhub
// device class to disable SENSOR sub device only.
if (mEventHub->getDeviceClasses(eventHubId).test(InputDeviceClass::SENSOR)) {
mEventHub->disableDevice(eventHubId);
}
}
std::shared_ptr<InputDevice> InputReader::createDeviceLocked(
int32_t eventHubId, const InputDeviceIdentifier& identifier) {
auto deviceIt = std::find_if(mDevices.begin(), mDevices.end(), [identifier](auto& devicePair) {
const InputDeviceIdentifier identifier2 =
devicePair.second->getDeviceInfo().getIdentifier();
return isSubDevice(identifier, identifier2);
});
std::shared_ptr<InputDevice> device;
if (deviceIt != mDevices.end()) {
device = deviceIt->second;
} else {
int32_t deviceId = (eventHubId < END_RESERVED_ID) ? eventHubId : nextInputDeviceIdLocked();
device = std::make_shared<InputDevice>(&mContext, deviceId, bumpGenerationLocked(),
identifier);
}
device->addEventHubDevice(eventHubId, mConfig);
return device;
}
frameworks/native/services/inputflinger/reader/InputDevice.cpp
InputDevice::InputDevice(InputReaderContext* context, int32_t id, int32_t generation,
const InputDeviceIdentifier& identifier)
: mContext(context),
mId(id),
mGeneration(generation),
mControllerNumber(0),
mIdentifier(identifier),
mClasses(0),
mSources(0),
mIsExternal(false),
mHasMic(false),
mDropUntilNextSync(false) {}
void InputDevice::addEventHubDevice(int32_t eventHubId,
const InputReaderConfiguration& readerConfig) {
if (mDevices.find(eventHubId) != mDevices.end()) {
return;
}
std::unique_ptr<InputDeviceContext> contextPtr(new InputDeviceContext(*this, eventHubId));
std::vector<std::unique_ptr<InputMapper>> mappers = createMappers(*contextPtr, readerConfig);
// insert the context into the devices set
mDevices.insert({eventHubId, std::make_pair(std::move(contextPtr), std::move(mappers))});
// Must change generation to flag this device as changed
bumpGeneration();
}
std::vector<std::unique_ptr<InputMapper>> InputDevice::createMappers(
InputDeviceContext& contextPtr, const InputReaderConfiguration& readerConfig) {
ftl::Flags<InputDeviceClass> classes = contextPtr.getDeviceClasses();
std::vector<std::unique_ptr<InputMapper>> mappers;
// Switch-like devices.
if (classes.test(InputDeviceClass::SWITCH)) {
mappers.push_back(createInputMapper<SwitchInputMapper>(contextPtr, readerConfig));
}
// Scroll wheel-like devices.
if (classes.test(InputDeviceClass::ROTARY_ENCODER)) {
mappers.push_back(createInputMapper<RotaryEncoderInputMapper>(contextPtr, readerConfig));
}
// Vibrator-like devices.
if (classes.test(InputDeviceClass::VIBRATOR)) {
mappers.push_back(createInputMapper<VibratorInputMapper>(contextPtr, readerConfig));
}
// Battery-like devices or light-containing devices.
// PeripheralController will be created with associated EventHub device.
if (classes.test(InputDeviceClass::BATTERY) || classes.test(InputDeviceClass::LIGHT)) {
mController = std::make_unique<PeripheralController>(contextPtr);
}
// Keyboard-like devices.
uint32_t keyboardSource = 0;
int32_t keyboardType = AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC;
if (classes.test(InputDeviceClass::KEYBOARD)) {
keyboardSource |= AINPUT_SOURCE_KEYBOARD;
}
if (classes.test(InputDeviceClass::ALPHAKEY)) {
keyboardType = AINPUT_KEYBOARD_TYPE_ALPHABETIC;
}
if (classes.test(InputDeviceClass::DPAD)) {
keyboardSource |= AINPUT_SOURCE_DPAD;
}
if (classes.test(InputDeviceClass::GAMEPAD)) {
keyboardSource |= AINPUT_SOURCE_GAMEPAD;
}
if (keyboardSource != 0) {
mappers.push_back(createInputMapper<KeyboardInputMapper>(contextPtr, readerConfig,
keyboardSource, keyboardType));
}
// Cursor-like devices.
if (classes.test(InputDeviceClass::CURSOR)) {
mappers.push_back(createInputMapper<CursorInputMapper>(contextPtr, readerConfig));
}
// Touchscreens and touchpad devices.
static const bool ENABLE_TOUCHPAD_GESTURES_LIBRARY =
sysprop::InputProperties::enable_touchpad_gestures_library().value_or(true);
// TODO(b/272518665): Fix the new touchpad stack for Sony DualShock 4 (5c4, 9cc) touchpads, or
// at least load this setting from the IDC file.
const InputDeviceIdentifier identifier = contextPtr.getDeviceIdentifier();
const bool isSonyDualShock4Touchpad = identifier.vendor == 0x054c &&
(identifier.product == 0x05c4 || identifier.product == 0x09cc);
if (ENABLE_TOUCHPAD_GESTURES_LIBRARY && classes.test(InputDeviceClass::TOUCHPAD) &&
classes.test(InputDeviceClass::TOUCH_MT) && !isSonyDualShock4Touchpad) {
mappers.push_back(createInputMapper<TouchpadInputMapper>(contextPtr, readerConfig));
} else if (classes.test(InputDeviceClass::TOUCH_MT)) {
mappers.push_back(std::make_unique<MultiTouchInputMapper>(contextPtr, readerConfig));
} else if (classes.test(InputDeviceClass::TOUCH)) {
mappers.push_back(std::make_unique<SingleTouchInputMapper>(contextPtr, readerConfig));
}
// Joystick-like devices.
if (classes.test(InputDeviceClass::JOYSTICK)) {
mappers.push_back(createInputMapper<JoystickInputMapper>(contextPtr, readerConfig));
}
// Motion sensor enabled devices.
if (classes.test(InputDeviceClass::SENSOR)) {
mappers.push_back(createInputMapper<SensorInputMapper>(contextPtr, readerConfig));
}
// External stylus-like devices.
if (classes.test(InputDeviceClass::EXTERNAL_STYLUS)) {
mappers.push_back(createInputMapper<ExternalStylusInputMapper>(contextPtr, readerConfig));
}
return mappers;
}
void InputDevice::addEventHubDevice(int32_t eventHubId,
const InputReaderConfiguration& readerConfig) {
if (mDevices.find(eventHubId) != mDevices.end()) {
return;
}
std::unique_ptr<InputDeviceContext> contextPtr(new InputDeviceContext(*this, eventHubId));
std::vector<std::unique_ptr<InputMapper>> mappers = createMappers(*contextPtr, readerConfig);
// insert the context into the devices set
mDevices.insert({eventHubId, std::make_pair(std::move(contextPtr), std::move(mappers))});
// Must change generation to flag this device as changed
bumpGeneration();
}
frameworks/native/include/input/InputDevice.h
inline uint32_t getSources() const { return mSources; }
frameworks/native/libs/input/InputDevice.cpp
void InputDeviceInfo::initialize(int32_t id, int32_t generation, int32_t controllerNumber,
const InputDeviceIdentifier& identifier, const std::string& alias,
bool isExternal, bool hasMic, int32_t associatedDisplayId) {
mId = id;
mGeneration = generation;
mControllerNumber = controllerNumber;
mIdentifier = identifier;
mAlias = alias;
mIsExternal = isExternal;
mHasMic = hasMic;
mSources = 0;
mKeyboardType = AINPUT_KEYBOARD_TYPE_NONE;
mAssociatedDisplayId = associatedDisplayId;
mHasVibrator = false;
mHasBattery = false;
mHasButtonUnderPad = false;
mHasSensor = false;
mUsiVersion.reset();
mMotionRanges.clear();
mSensors.clear();
mLights.clear();
}
void InputDeviceInfo::addSource(uint32_t source) {
mSources |= source;
}
3、keycode对应scankode
2.3 映射文件文件加载loadKeyMapLocked
加载KeyLayoutMap::load(path)
时对应转换,对照kl文件解析,如POWER按键key 114 VOLUME_DOWN key 115 VOLUME_UP key 116 POWER
keywordToken == "key"
:kl文件每行开头关键字key
parseKey() -> code = parseInt(codeToken.string())
: kl文件关键字key
之后的116
,对应底层上报的scancode
keyCode = InputEventLookup::getKeyCodeByLabel(keyCodeToken.string())
:kl文件关键字key
之后最后的关键字POWER
转换keycode
DEFINE_KEYCODE(POWER)
:对应到AKEYCODE_POWER = 26
frameworks/native/libs/input/KeyLayoutMap.cpp
status_t KeyLayoutMap::Parser::parse() {
while (!mTokenizer->isEof()) {
ALOGD_IF(DEBUG_PARSER, "Parsing %s: '%s'.", mTokenizer->getLocation().string(),
mTokenizer->peekRemainderOfLine().string());
mTokenizer->skipDelimiters(WHITESPACE);
if (!mTokenizer->isEol() && mTokenizer->peekChar() != '#') {
String8 keywordToken = mTokenizer->nextToken(WHITESPACE);
if (keywordToken == "key") {
mTokenizer->skipDelimiters(WHITESPACE);
status_t status = parseKey();
if (status) return status;
} else if (keywordToken == "axis") {
mTokenizer->skipDelimiters(WHITESPACE);
status_t status = parseAxis();
if (status) return status;
} else if (keywordToken == "led") {
mTokenizer->skipDelimiters(WHITESPACE);
status_t status = parseLed();
if (status) return status;
} else if (keywordToken == "sensor") {
mTokenizer->skipDelimiters(WHITESPACE);
status_t status = parseSensor();
if (status) return status;
} else if (keywordToken == "requires_kernel_config") {
mTokenizer->skipDelimiters(WHITESPACE);
status_t status = parseRequiredKernelConfig();
if (status) return status;
} else {
ALOGE("%s: Expected keyword, got '%s'.", mTokenizer->getLocation().string(),
keywordToken.string());
return BAD_VALUE;
}
mTokenizer->skipDelimiters(WHITESPACE);
if (!mTokenizer->isEol() && mTokenizer->peekChar() != '#') {
ALOGE("%s: Expected end of line or trailing comment, got '%s'.",
mTokenizer->getLocation().string(),
mTokenizer->peekRemainderOfLine().string());
return BAD_VALUE;
}
}
mTokenizer->nextLine();
}
return NO_ERROR;
}
status_t KeyLayoutMap::Parser::parseKey() {
String8 codeToken = mTokenizer->nextToken(WHITESPACE);
bool mapUsage = false;
if (codeToken == "usage") {
mapUsage = true;
mTokenizer->skipDelimiters(WHITESPACE);
codeToken = mTokenizer->nextToken(WHITESPACE);
}
std::optional<int> code = parseInt(codeToken.string());
if (!code) {
ALOGE("%s: Expected key %s number, got '%s'.", mTokenizer->getLocation().string(),
mapUsage ? "usage" : "scan code", codeToken.string());
return BAD_VALUE;
}
std::unordered_map<int32_t, Key>& map =
mapUsage ? mMap->mKeysByUsageCode : mMap->mKeysByScanCode;
if (map.find(*code) != map.end()) {
ALOGE("%s: Duplicate entry for key %s '%s'.", mTokenizer->getLocation().string(),
mapUsage ? "usage" : "scan code", codeToken.string());
return BAD_VALUE;
}
mTokenizer->skipDelimiters(WHITESPACE);
String8 keyCodeToken = mTokenizer->nextToken(WHITESPACE);
std::optional<int> keyCode = InputEventLookup::getKeyCodeByLabel(keyCodeToken.string());
if (!keyCode) {
ALOGE("%s: Expected key code label, got '%s'.", mTokenizer->getLocation().string(),
keyCodeToken.string());
return BAD_VALUE;
}
uint32_t flags = 0;
for (;;) {
mTokenizer->skipDelimiters(WHITESPACE);
if (mTokenizer->isEol() || mTokenizer->peekChar() == '#') break;
String8 flagToken = mTokenizer->nextToken(WHITESPACE);
std::optional<int> flag = InputEventLookup::getKeyFlagByLabel(flagToken.string());
if (!flag) {
ALOGE("%s: Expected key flag label, got '%s'.", mTokenizer->getLocation().string(),
flagToken.string());
return BAD_VALUE;
}
if (flags & *flag) {
ALOGE("%s: Duplicate key flag '%s'.", mTokenizer->getLocation().string(),
flagToken.string());
return BAD_VALUE;
}
flags |= *flag;
}
ALOGD_IF(DEBUG_PARSER, "Parsed key %s: code=%d, keyCode=%d, flags=0x%08x.",
mapUsage ? "usage" : "scan code", *code, *keyCode, flags);
Key key;
key.keyCode = *keyCode;
key.flags = flags;
map.insert({*code, key});
return NO_ERROR;
}
bionic/libc/kernel/uapi/linux/input-event-codes.h
frameworks/native/libs/input/InputEventLabels.cpp
#define DEFINE_KEYCODE(key) { #key, AKEYCODE_##key }
// NOTE: If you add a new keycode here you must also add it to several other files.
// Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list.
#define KEYCODES_SEQUENCE \
DEFINE_KEYCODE(UNKNOWN), \
DEFINE_KEYCODE(SOFT_LEFT), \
DEFINE_KEYCODE(SOFT_RIGHT), \
DEFINE_KEYCODE(HOME), \
DEFINE_KEYCODE(BACK), \
DEFINE_KEYCODE(CALL), \
DEFINE_KEYCODE(ENDCALL), \
DEFINE_KEYCODE(0), \
DEFINE_KEYCODE(1), \
DEFINE_KEYCODE(2), \
DEFINE_KEYCODE(3), \
DEFINE_KEYCODE(4), \
DEFINE_KEYCODE(5), \
DEFINE_KEYCODE(6), \
DEFINE_KEYCODE(7), \
DEFINE_KEYCODE(8), \
DEFINE_KEYCODE(9), \
DEFINE_KEYCODE(STAR), \
DEFINE_KEYCODE(POUND), \
DEFINE_KEYCODE(DPAD_UP), \
DEFINE_KEYCODE(DPAD_DOWN), \
DEFINE_KEYCODE(DPAD_LEFT), \
DEFINE_KEYCODE(DPAD_RIGHT), \
DEFINE_KEYCODE(DPAD_CENTER), \
DEFINE_KEYCODE(VOLUME_UP), \
DEFINE_KEYCODE(VOLUME_DOWN), \
DEFINE_KEYCODE(POWER), \
DEFINE_KEYCODE(CAMERA), \
DEFINE_KEYCODE(CLEAR), \
DEFINE_KEYCODE(A), \
DEFINE_KEYCODE(B), \
DEFINE_KEYCODE(C), \
DEFINE_KEYCODE(D), \
DEFINE_KEYCODE(E), \
DEFINE_KEYCODE(F), \
DEFINE_KEYCODE(G), \
DEFINE_KEYCODE(H), \
DEFINE_KEYCODE(I), \
DEFINE_KEYCODE(J), \
DEFINE_KEYCODE(K), \
DEFINE_KEYCODE(L), \
DEFINE_KEYCODE(M), \
DEFINE_KEYCODE(N), \
DEFINE_KEYCODE(O), \
DEFINE_KEYCODE(P), \
DEFINE_KEYCODE(Q), \
DEFINE_KEYCODE(R), \
DEFINE_KEYCODE(S), \
DEFINE_KEYCODE(T), \
DEFINE_KEYCODE(U), \
DEFINE_KEYCODE(V), \
DEFINE_KEYCODE(W), \
DEFINE_KEYCODE(X), \
DEFINE_KEYCODE(Y), \
DEFINE_KEYCODE(Z), \
DEFINE_KEYCODE(COMMA), \
DEFINE_KEYCODE(PERIOD), \
DEFINE_KEYCODE(ALT_LEFT), \
DEFINE_KEYCODE(ALT_RIGHT), \
DEFINE_KEYCODE(SHIFT_LEFT), \
DEFINE_KEYCODE(SHIFT_RIGHT), \
DEFINE_KEYCODE(TAB), \
DEFINE_KEYCODE(SPACE), \
DEFINE_KEYCODE(SYM), \
DEFINE_KEYCODE(EXPLORER), \
DEFINE_KEYCODE(ENVELOPE), \
DEFINE_KEYCODE(ENTER), \
DEFINE_KEYCODE(DEL), \
DEFINE_KEYCODE(GRAVE), \
DEFINE_KEYCODE(MINUS), \
DEFINE_KEYCODE(EQUALS), \
DEFINE_KEYCODE(LEFT_BRACKET), \
DEFINE_KEYCODE(RIGHT_BRACKET), \
DEFINE_KEYCODE(BACKSLASH), \
DEFINE_KEYCODE(SEMICOLON), \
DEFINE_KEYCODE(APOSTROPHE), \
DEFINE_KEYCODE(SLASH), \
DEFINE_KEYCODE(AT), \
DEFINE_KEYCODE(NUM), \
DEFINE_KEYCODE(HEADSETHOOK), \
DEFINE_KEYCODE(FOCUS), \
DEFINE_KEYCODE(PLUS), \
DEFINE_KEYCODE(MENU), \
DEFINE_KEYCODE(NOTIFICATION), \
DEFINE_KEYCODE(SEARCH), \
DEFINE_KEYCODE(MEDIA_PLAY_PAUSE), \
DEFINE_KEYCODE(MEDIA_STOP), \
DEFINE_KEYCODE(MEDIA_NEXT), \
DEFINE_KEYCODE(MEDIA_PREVIOUS), \
DEFINE_KEYCODE(MEDIA_REWIND), \
DEFINE_KEYCODE(MEDIA_FAST_FORWARD), \
DEFINE_KEYCODE(MUTE), \
DEFINE_KEYCODE(PAGE_UP), \
DEFINE_KEYCODE(PAGE_DOWN), \
DEFINE_KEYCODE(PICTSYMBOLS), \
DEFINE_KEYCODE(SWITCH_CHARSET), \
DEFINE_KEYCODE(BUTTON_A), \
DEFINE_KEYCODE(BUTTON_B), \
DEFINE_KEYCODE(BUTTON_C), \
DEFINE_KEYCODE(BUTTON_X), \
DEFINE_KEYCODE(BUTTON_Y), \
DEFINE_KEYCODE(BUTTON_Z), \
DEFINE_KEYCODE(BUTTON_L1), \
DEFINE_KEYCODE(BUTTON_R1), \
DEFINE_KEYCODE(BUTTON_L2), \
DEFINE_KEYCODE(BUTTON_R2), \
DEFINE_KEYCODE(BUTTON_THUMBL), \
DEFINE_KEYCODE(BUTTON_THUMBR), \
DEFINE_KEYCODE(BUTTON_START), \
DEFINE_KEYCODE(BUTTON_SELECT), \
DEFINE_KEYCODE(BUTTON_MODE), \
DEFINE_KEYCODE(ESCAPE), \
DEFINE_KEYCODE(FORWARD_DEL), \
DEFINE_KEYCODE(CTRL_LEFT), \
DEFINE_KEYCODE(CTRL_RIGHT), \
DEFINE_KEYCODE(CAPS_LOCK), \
DEFINE_KEYCODE(SCROLL_LOCK), \
DEFINE_KEYCODE(META_LEFT), \
DEFINE_KEYCODE(META_RIGHT), \
DEFINE_KEYCODE(FUNCTION), \
DEFINE_KEYCODE(SYSRQ), \
DEFINE_KEYCODE(BREAK), \
DEFINE_KEYCODE(MOVE_HOME), \
DEFINE_KEYCODE(MOVE_END), \
DEFINE_KEYCODE(INSERT), \
DEFINE_KEYCODE(FORWARD), \
DEFINE_KEYCODE(MEDIA_PLAY), \
DEFINE_KEYCODE(MEDIA_PAUSE), \
DEFINE_KEYCODE(MEDIA_CLOSE), \
DEFINE_KEYCODE(MEDIA_EJECT), \
DEFINE_KEYCODE(MEDIA_RECORD), \
DEFINE_KEYCODE(F1), \
DEFINE_KEYCODE(F2), \
DEFINE_KEYCODE(F3), \
DEFINE_KEYCODE(F4), \
DEFINE_KEYCODE(F5), \
DEFINE_KEYCODE(F6), \
DEFINE_KEYCODE(F7), \
DEFINE_KEYCODE(F8), \
DEFINE_KEYCODE(F9), \
DEFINE_KEYCODE(F10), \
DEFINE_KEYCODE(F11), \
DEFINE_KEYCODE(F12), \
DEFINE_KEYCODE(NUM_LOCK), \
DEFINE_KEYCODE(NUMPAD_0), \
DEFINE_KEYCODE(NUMPAD_1), \
DEFINE_KEYCODE(NUMPAD_2), \
DEFINE_KEYCODE(NUMPAD_3), \
DEFINE_KEYCODE(NUMPAD_4), \
DEFINE_KEYCODE(NUMPAD_5), \
DEFINE_KEYCODE(NUMPAD_6), \
DEFINE_KEYCODE(NUMPAD_7), \
DEFINE_KEYCODE(NUMPAD_8), \
DEFINE_KEYCODE(NUMPAD_9), \
DEFINE_KEYCODE(NUMPAD_DIVIDE), \
DEFINE_KEYCODE(NUMPAD_MULTIPLY), \
DEFINE_KEYCODE(NUMPAD_SUBTRACT), \
DEFINE_KEYCODE(NUMPAD_ADD), \
DEFINE_KEYCODE(NUMPAD_DOT), \
DEFINE_KEYCODE(NUMPAD_COMMA), \
DEFINE_KEYCODE(NUMPAD_ENTER), \
DEFINE_KEYCODE(NUMPAD_EQUALS), \
DEFINE_KEYCODE(NUMPAD_LEFT_PAREN), \
DEFINE_KEYCODE(NUMPAD_RIGHT_PAREN), \
DEFINE_KEYCODE(VOLUME_MUTE), \
DEFINE_KEYCODE(INFO), \
DEFINE_KEYCODE(CHANNEL_UP), \
DEFINE_KEYCODE(CHANNEL_DOWN), \
DEFINE_KEYCODE(ZOOM_IN), \
DEFINE_KEYCODE(ZOOM_OUT), \
DEFINE_KEYCODE(TV), \
DEFINE_KEYCODE(WINDOW), \
DEFINE_KEYCODE(GUIDE), \
DEFINE_KEYCODE(DVR), \
DEFINE_KEYCODE(BOOKMARK), \
DEFINE_KEYCODE(CAPTIONS), \
DEFINE_KEYCODE(SETTINGS), \
DEFINE_KEYCODE(TV_POWER), \
DEFINE_KEYCODE(TV_INPUT), \
DEFINE_KEYCODE(STB_POWER), \
DEFINE_KEYCODE(STB_INPUT), \
DEFINE_KEYCODE(AVR_POWER), \
DEFINE_KEYCODE(AVR_INPUT), \
DEFINE_KEYCODE(PROG_RED), \
DEFINE_KEYCODE(PROG_GREEN), \
DEFINE_KEYCODE(PROG_YELLOW), \
DEFINE_KEYCODE(PROG_BLUE), \
DEFINE_KEYCODE(APP_SWITCH), \
DEFINE_KEYCODE(BUTTON_1), \
DEFINE_KEYCODE(BUTTON_2), \
DEFINE_KEYCODE(BUTTON_3), \
DEFINE_KEYCODE(BUTTON_4), \
DEFINE_KEYCODE(BUTTON_5), \
DEFINE_KEYCODE(BUTTON_6), \
DEFINE_KEYCODE(BUTTON_7), \
DEFINE_KEYCODE(BUTTON_8), \
DEFINE_KEYCODE(BUTTON_9), \
DEFINE_KEYCODE(BUTTON_10), \
DEFINE_KEYCODE(BUTTON_11), \
DEFINE_KEYCODE(BUTTON_12), \
DEFINE_KEYCODE(BUTTON_13), \
DEFINE_KEYCODE(BUTTON_14), \
DEFINE_KEYCODE(BUTTON_15), \
DEFINE_KEYCODE(BUTTON_16), \
DEFINE_KEYCODE(LANGUAGE_SWITCH), \
DEFINE_KEYCODE(MANNER_MODE), \
DEFINE_KEYCODE(3D_MODE), \
DEFINE_KEYCODE(CONTACTS), \
DEFINE_KEYCODE(CALENDAR), \
DEFINE_KEYCODE(MUSIC), \
DEFINE_KEYCODE(CALCULATOR), \
DEFINE_KEYCODE(ZENKAKU_HANKAKU), \
DEFINE_KEYCODE(EISU), \
DEFINE_KEYCODE(MUHENKAN), \
DEFINE_KEYCODE(HENKAN), \
DEFINE_KEYCODE(KATAKANA_HIRAGANA), \
DEFINE_KEYCODE(YEN), \
DEFINE_KEYCODE(RO), \
DEFINE_KEYCODE(KANA), \
DEFINE_KEYCODE(ASSIST), \
DEFINE_KEYCODE(BRIGHTNESS_DOWN), \
DEFINE_KEYCODE(BRIGHTNESS_UP), \
DEFINE_KEYCODE(MEDIA_AUDIO_TRACK), \
DEFINE_KEYCODE(SLEEP), \
DEFINE_KEYCODE(WAKEUP), \
DEFINE_KEYCODE(PAIRING), \
DEFINE_KEYCODE(MEDIA_TOP_MENU), \
DEFINE_KEYCODE(11), \
DEFINE_KEYCODE(12), \
DEFINE_KEYCODE(LAST_CHANNEL), \
DEFINE_KEYCODE(TV_DATA_SERVICE), \
DEFINE_KEYCODE(VOICE_ASSIST), \
DEFINE_KEYCODE(TV_RADIO_SERVICE), \
DEFINE_KEYCODE(TV_TELETEXT), \
DEFINE_KEYCODE(TV_NUMBER_ENTRY), \
DEFINE_KEYCODE(TV_TERRESTRIAL_ANALOG), \
DEFINE_KEYCODE(TV_TERRESTRIAL_DIGITAL), \
DEFINE_KEYCODE(TV_SATELLITE), \
DEFINE_KEYCODE(TV_SATELLITE_BS), \
DEFINE_KEYCODE(TV_SATELLITE_CS), \
DEFINE_KEYCODE(TV_SATELLITE_SERVICE), \
DEFINE_KEYCODE(TV_NETWORK), \
DEFINE_KEYCODE(TV_ANTENNA_CABLE), \
DEFINE_KEYCODE(TV_INPUT_HDMI_1), \
DEFINE_KEYCODE(TV_INPUT_HDMI_2), \
DEFINE_KEYCODE(TV_INPUT_HDMI_3), \
DEFINE_KEYCODE(TV_INPUT_HDMI_4), \
DEFINE_KEYCODE(TV_INPUT_COMPOSITE_1), \
DEFINE_KEYCODE(TV_INPUT_COMPOSITE_2), \
DEFINE_KEYCODE(TV_INPUT_COMPONENT_1), \
DEFINE_KEYCODE(TV_INPUT_COMPONENT_2), \
DEFINE_KEYCODE(TV_INPUT_VGA_1), \
DEFINE_KEYCODE(TV_AUDIO_DESCRIPTION), \
DEFINE_KEYCODE(TV_AUDIO_DESCRIPTION_MIX_UP), \
DEFINE_KEYCODE(TV_AUDIO_DESCRIPTION_MIX_DOWN), \
DEFINE_KEYCODE(TV_ZOOM_MODE), \
DEFINE_KEYCODE(TV_CONTENTS_MENU), \
DEFINE_KEYCODE(TV_MEDIA_CONTEXT_MENU), \
DEFINE_KEYCODE(TV_TIMER_PROGRAMMING), \
DEFINE_KEYCODE(HELP), \
DEFINE_KEYCODE(NAVIGATE_PREVIOUS), \
DEFINE_KEYCODE(NAVIGATE_NEXT), \
DEFINE_KEYCODE(NAVIGATE_IN), \
DEFINE_KEYCODE(NAVIGATE_OUT), \
DEFINE_KEYCODE(STEM_PRIMARY), \
DEFINE_KEYCODE(STEM_1), \
DEFINE_KEYCODE(STEM_2), \
DEFINE_KEYCODE(STEM_3), \
DEFINE_KEYCODE(DPAD_UP_LEFT), \
DEFINE_KEYCODE(DPAD_DOWN_LEFT), \
DEFINE_KEYCODE(DPAD_UP_RIGHT), \
DEFINE_KEYCODE(DPAD_DOWN_RIGHT), \
DEFINE_KEYCODE(MEDIA_SKIP_FORWARD), \
DEFINE_KEYCODE(MEDIA_SKIP_BACKWARD), \
DEFINE_KEYCODE(MEDIA_STEP_FORWARD), \
DEFINE_KEYCODE(MEDIA_STEP_BACKWARD), \
DEFINE_KEYCODE(SOFT_SLEEP), \
DEFINE_KEYCODE(CUT), \
DEFINE_KEYCODE(COPY), \
DEFINE_KEYCODE(PASTE), \
DEFINE_KEYCODE(SYSTEM_NAVIGATION_UP), \
DEFINE_KEYCODE(SYSTEM_NAVIGATION_DOWN), \
DEFINE_KEYCODE(SYSTEM_NAVIGATION_LEFT), \
DEFINE_KEYCODE(SYSTEM_NAVIGATION_RIGHT), \
DEFINE_KEYCODE(ALL_APPS), \
DEFINE_KEYCODE(REFRESH), \
DEFINE_KEYCODE(THUMBS_UP), \
DEFINE_KEYCODE(THUMBS_DOWN), \
DEFINE_KEYCODE(PROFILE_SWITCH), \
DEFINE_KEYCODE(VIDEO_APP_1), \
DEFINE_KEYCODE(VIDEO_APP_2), \
DEFINE_KEYCODE(VIDEO_APP_3), \
DEFINE_KEYCODE(VIDEO_APP_4), \
DEFINE_KEYCODE(VIDEO_APP_5), \
DEFINE_KEYCODE(VIDEO_APP_6), \
DEFINE_KEYCODE(VIDEO_APP_7), \
DEFINE_KEYCODE(VIDEO_APP_8), \
DEFINE_KEYCODE(FEATURED_APP_1), \
DEFINE_KEYCODE(FEATURED_APP_2), \
DEFINE_KEYCODE(FEATURED_APP_3), \
DEFINE_KEYCODE(FEATURED_APP_4), \
DEFINE_KEYCODE(DEMO_APP_1), \
DEFINE_KEYCODE(DEMO_APP_2), \
DEFINE_KEYCODE(DEMO_APP_3), \
DEFINE_KEYCODE(DEMO_APP_4), \
DEFINE_KEYCODE(KEYBOARD_BACKLIGHT_DOWN), \
DEFINE_KEYCODE(KEYBOARD_BACKLIGHT_UP), \
DEFINE_KEYCODE(KEYBOARD_BACKLIGHT_TOGGLE), \
DEFINE_KEYCODE(STYLUS_BUTTON_PRIMARY), \
DEFINE_KEYCODE(STYLUS_BUTTON_SECONDARY), \
DEFINE_KEYCODE(STYLUS_BUTTON_TERTIARY), \
DEFINE_KEYCODE(STYLUS_BUTTON_TAIL), \
DEFINE_KEYCODE(RECENT_APPS), \
DEFINE_KEYCODE(MACRO_1), \
DEFINE_KEYCODE(MACRO_2), \
DEFINE_KEYCODE(MACRO_3), \
DEFINE_KEYCODE(MACRO_4)
const std::unordered_map<std::string, int> InputEventLookup::KEYCODES = {KEYCODES_SEQUENCE};
const std::vector<InputEventLabel> InputEventLookup::KEY_NAMES = {KEYCODES_SEQUENCE};
std::optional<int> InputEventLookup::getKeyCodeByLabel(const char* label) {
return lookupValueByLabel(KEYCODES, label);
}
frameworks/native/include/android/keycodes.h
/**
* Key codes.
*/
enum {
/** Unknown key code. */
AKEYCODE_UNKNOWN = 0,
/** Soft Left key.
* Usually situated below the display on phones and used as a multi-function
* feature key for selecting a software defined function shown on the bottom left
* of the display. */
AKEYCODE_SOFT_LEFT = 1,
/** Soft Right key.
* Usually situated below the display on phones and used as a multi-function
* feature key for selecting a software defined function shown on the bottom right
* of the display. */
AKEYCODE_SOFT_RIGHT = 2,
/** Home key.
* This key is handled by the framework and is never delivered to applications. */
AKEYCODE_HOME = 3,
/** Back key. */
AKEYCODE_BACK = 4,
/** Call key. */
AKEYCODE_CALL = 5,
/** End Call key. */
AKEYCODE_ENDCALL = 6,
/** '0' key. */
AKEYCODE_0 = 7,
/** '1' key. */
AKEYCODE_1 = 8,
/** '2' key. */
AKEYCODE_2 = 9,
/** '3' key. */
AKEYCODE_3 = 10,
/** '4' key. */
AKEYCODE_4 = 11,
/** '5' key. */
AKEYCODE_5 = 12,
/** '6' key. */
AKEYCODE_6 = 13,
/** '7' key. */
AKEYCODE_7 = 14,
/** '8' key. */
AKEYCODE_8 = 15,
/** '9' key. */
AKEYCODE_9 = 16,
/** '*' key. */
AKEYCODE_STAR = 17,
/** '#' key. */
AKEYCODE_POUND = 18,
/** Directional Pad Up key.
* May also be synthesized from trackball motions. */
AKEYCODE_DPAD_UP = 19,
/** Directional Pad Down key.
* May also be synthesized from trackball motions. */
AKEYCODE_DPAD_DOWN = 20,
/** Directional Pad Left key.
* May also be synthesized from trackball motions. */
AKEYCODE_DPAD_LEFT = 21,
/** Directional Pad Right key.
* May also be synthesized from trackball motions. */
AKEYCODE_DPAD_RIGHT = 22,
/** Directional Pad Center key.
* May also be synthesized from trackball motions. */
AKEYCODE_DPAD_CENTER = 23,
/** Volume Up key.
* Adjusts the speaker volume up. */
AKEYCODE_VOLUME_UP = 24,
/** Volume Down key.
* Adjusts the speaker volume down. */
AKEYCODE_VOLUME_DOWN = 25,
/** Power key. */
AKEYCODE_POWER = 26,
/** Camera key.
* Used to launch a camera application or take pictures. */
AKEYCODE_CAMERA = 27,
/** Clear key. */
AKEYCODE_CLEAR = 28,
/** 'A' key. */
AKEYCODE_A = 29,
/** 'B' key. */
AKEYCODE_B = 30,
/** 'C' key. */
AKEYCODE_C = 31,
/** 'D' key. */
AKEYCODE_D = 32,
/** 'E' key. */
AKEYCODE_E = 33,
/** 'F' key. */
AKEYCODE_F = 34,
/** 'G' key. */
AKEYCODE_G = 35,
/** 'H' key. */
AKEYCODE_H = 36,
/** 'I' key. */
AKEYCODE_I = 37,
/** 'J' key. */
AKEYCODE_J = 38,
/** 'K' key. */
AKEYCODE_K = 39,
/** 'L' key. */
AKEYCODE_L = 40,
/** 'M' key. */
AKEYCODE_M = 41,
/** 'N' key. */
AKEYCODE_N = 42,
/** 'O' key. */
AKEYCODE_O = 43,
/** 'P' key. */
AKEYCODE_P = 44,
/** 'Q' key. */
AKEYCODE_Q = 45,
/** 'R' key. */
AKEYCODE_R = 46,
/** 'S' key. */
AKEYCODE_S = 47,
/** 'T' key. */
AKEYCODE_T = 48,
/** 'U' key. */
AKEYCODE_U = 49,
/** 'V' key. */
AKEYCODE_V = 50,
/** 'W' key. */
AKEYCODE_W = 51,
/** 'X' key. */
AKEYCODE_X = 52,
/** 'Y' key. */
AKEYCODE_Y = 53,
/** 'Z' key. */
AKEYCODE_Z = 54,
/** ',' key. */
AKEYCODE_COMMA = 55,
/** '.' key. */
AKEYCODE_PERIOD = 56,
/** Left Alt modifier key. */
AKEYCODE_ALT_LEFT = 57,
/** Right Alt modifier key. */
AKEYCODE_ALT_RIGHT = 58,
/** Left Shift modifier key. */
AKEYCODE_SHIFT_LEFT = 59,
/** Right Shift modifier key. */
AKEYCODE_SHIFT_RIGHT = 60,
/** Tab key. */
AKEYCODE_TAB = 61,
/** Space key. */
AKEYCODE_SPACE = 62,
/** Symbol modifier key.
* Used to enter alternate symbols. */
AKEYCODE_SYM = 63,
/** Explorer special function key.
* Used to launch a browser application. */
AKEYCODE_EXPLORER = 64,
/** Envelope special function key.
* Used to launch a mail application. */
AKEYCODE_ENVELOPE = 65,
/** Enter key. */
AKEYCODE_ENTER = 66,
/** Backspace key.
* Deletes characters before the insertion point, unlike {@link AKEYCODE_FORWARD_DEL}. */
AKEYCODE_DEL = 67,
/** '`' (backtick) key. */
AKEYCODE_GRAVE = 68,
/** '-'. */
AKEYCODE_MINUS = 69,
/** '=' key. */
AKEYCODE_EQUALS = 70,
/** '[' key. */
AKEYCODE_LEFT_BRACKET = 71,
/** ']' key. */
AKEYCODE_RIGHT_BRACKET = 72,
/** '\' key. */
AKEYCODE_BACKSLASH = 73,
/** ';' key. */
AKEYCODE_SEMICOLON = 74,
/** ''' (apostrophe) key. */
AKEYCODE_APOSTROPHE = 75,
/** '/' key. */
AKEYCODE_SLASH = 76,
/** '@' key. */
AKEYCODE_AT = 77,
/** Number modifier key.
* Used to enter numeric symbols.
* This key is not {@link AKEYCODE_NUM_LOCK}; it is more like {@link AKEYCODE_ALT_LEFT}. */
AKEYCODE_NUM = 78,
/** Headset Hook key.
* Used to hang up calls and stop media. */
AKEYCODE_HEADSETHOOK = 79,
/** Camera Focus key.
* Used to focus the camera. */
AKEYCODE_FOCUS = 80,
/** '+' key. */
AKEYCODE_PLUS = 81,
/** Menu key. */
AKEYCODE_MENU = 82,
/** Notification key. */
AKEYCODE_NOTIFICATION = 83,
/** Search key. */
AKEYCODE_SEARCH = 84,
/** Play/Pause media key. */
AKEYCODE_MEDIA_PLAY_PAUSE= 85,
/** Stop media key. */
AKEYCODE_MEDIA_STOP = 86,
/** Play Next media key. */
AKEYCODE_MEDIA_NEXT = 87,
/** Play Previous media key. */
AKEYCODE_MEDIA_PREVIOUS = 88,
/** Rewind media key. */
AKEYCODE_MEDIA_REWIND = 89,
/** Fast Forward media key. */
AKEYCODE_MEDIA_FAST_FORWARD = 90,
/** Mute key.
* Mutes the microphone, unlike {@link AKEYCODE_VOLUME_MUTE}. */
AKEYCODE_MUTE = 91,
/** Page Up key. */
AKEYCODE_PAGE_UP = 92,
/** Page Down key. */
AKEYCODE_PAGE_DOWN = 93,
/** Picture Symbols modifier key.
* Used to switch symbol sets (Emoji, Kao-moji). */
AKEYCODE_PICTSYMBOLS = 94,
/** Switch Charset modifier key.
* Used to switch character sets (Kanji, Katakana). */
AKEYCODE_SWITCH_CHARSET = 95,
/** A Button key.
* On a game controller, the A button should be either the button labeled A
* or the first button on the bottom row of controller buttons. */
AKEYCODE_BUTTON_A = 96,
/** B Button key.
* On a game controller, the B button should be either the button labeled B
* or the second button on the bottom row of controller buttons. */
AKEYCODE_BUTTON_B = 97,
/** C Button key.
* On a game controller, the C button should be either the button labeled C
* or the third button on the bottom row of controller buttons. */
AKEYCODE_BUTTON_C = 98,
/** X Button key.
* On a game controller, the X button should be either the button labeled X
* or the first button on the upper row of controller buttons. */
AKEYCODE_BUTTON_X = 99,
/** Y Button key.
* On a game controller, the Y button should be either the button labeled Y
* or the second button on the upper row of controller buttons. */
AKEYCODE_BUTTON_Y = 100,
/** Z Button key.
* On a game controller, the Z button should be either the button labeled Z
* or the third button on the upper row of controller buttons. */
AKEYCODE_BUTTON_Z = 101,
/** L1 Button key.
* On a game controller, the L1 button should be either the button labeled L1 (or L)
* or the top left trigger button. */
AKEYCODE_BUTTON_L1 = 102,
/** R1 Button key.
* On a game controller, the R1 button should be either the button labeled R1 (or R)
* or the top right trigger button. */
AKEYCODE_BUTTON_R1 = 103,
/** L2 Button key.
* On a game controller, the L2 button should be either the button labeled L2
* or the bottom left trigger button. */
AKEYCODE_BUTTON_L2 = 104,
/** R2 Button key.
* On a game controller, the R2 button should be either the button labeled R2
* or the bottom right trigger button. */
AKEYCODE_BUTTON_R2 = 105,
/** Left Thumb Button key.
* On a game controller, the left thumb button indicates that the left (or only)
* joystick is pressed. */
AKEYCODE_BUTTON_THUMBL = 106,
/** Right Thumb Button key.
* On a game controller, the right thumb button indicates that the right
* joystick is pressed. */
AKEYCODE_BUTTON_THUMBR = 107,
/** Start Button key.
* On a game controller, the button labeled Start. */
AKEYCODE_BUTTON_START = 108,
/** Select Button key.
* On a game controller, the button labeled Select. */
AKEYCODE_BUTTON_SELECT = 109,
/** Mode Button key.
* On a game controller, the button labeled Mode. */
AKEYCODE_BUTTON_MODE = 110,
/** Escape key. */
AKEYCODE_ESCAPE = 111,
/** Forward Delete key.
* Deletes characters ahead of the insertion point, unlike {@link AKEYCODE_DEL}. */
AKEYCODE_FORWARD_DEL = 112,
/** Left Control modifier key. */
AKEYCODE_CTRL_LEFT = 113,
/** Right Control modifier key. */
AKEYCODE_CTRL_RIGHT = 114,
/** Caps Lock key. */
AKEYCODE_CAPS_LOCK = 115,
/** Scroll Lock key. */
AKEYCODE_SCROLL_LOCK = 116,
/** Left Meta modifier key. */
AKEYCODE_META_LEFT = 117,
/** Right Meta modifier key. */
AKEYCODE_META_RIGHT = 118,
/** Function modifier key. */
AKEYCODE_FUNCTION = 119,
/** System Request / Print Screen key. */
AKEYCODE_SYSRQ = 120,
/** Break / Pause key. */
AKEYCODE_BREAK = 121,
/** Home Movement key.
* Used for scrolling or moving the cursor around to the start of a line
* or to the top of a list. */
AKEYCODE_MOVE_HOME = 122,
/** End Movement key.
* Used for scrolling or moving the cursor around to the end of a line
* or to the bottom of a list. */
AKEYCODE_MOVE_END = 123,
/** Insert key.
* Toggles insert / overwrite edit mode. */
AKEYCODE_INSERT = 124,
/** Forward key.
* Navigates forward in the history stack. Complement of {@link AKEYCODE_BACK}. */
AKEYCODE_FORWARD = 125,
/** Play media key. */
AKEYCODE_MEDIA_PLAY = 126,
/** Pause media key. */
AKEYCODE_MEDIA_PAUSE = 127,
/** Close media key.
* May be used to close a CD tray, for example. */
AKEYCODE_MEDIA_CLOSE = 128,
/** Eject media key.
* May be used to eject a CD tray, for example. */
AKEYCODE_MEDIA_EJECT = 129,
/** Record media key. */
AKEYCODE_MEDIA_RECORD = 130,
/** F1 key. */
AKEYCODE_F1 = 131,
/** F2 key. */
AKEYCODE_F2 = 132,
/** F3 key. */
AKEYCODE_F3 = 133,
/** F4 key. */
AKEYCODE_F4 = 134,
/** F5 key. */
AKEYCODE_F5 = 135,
/** F6 key. */
AKEYCODE_F6 = 136,
/** F7 key. */
AKEYCODE_F7 = 137,
/** F8 key. */
AKEYCODE_F8 = 138,
/** F9 key. */
AKEYCODE_F9 = 139,
/** F10 key. */
AKEYCODE_F10 = 140,
/** F11 key. */
AKEYCODE_F11 = 141,
/** F12 key. */
AKEYCODE_F12 = 142,
/** Num Lock key.
* This is the Num Lock key; it is different from {@link AKEYCODE_NUM}.
* This key alters the behavior of other keys on the numeric keypad. */
AKEYCODE_NUM_LOCK = 143,
/** Numeric keypad '0' key. */
AKEYCODE_NUMPAD_0 = 144,
/** Numeric keypad '1' key. */
AKEYCODE_NUMPAD_1 = 145,
/** Numeric keypad '2' key. */
AKEYCODE_NUMPAD_2 = 146,
/** Numeric keypad '3' key. */
AKEYCODE_NUMPAD_3 = 147,
/** Numeric keypad '4' key. */
AKEYCODE_NUMPAD_4 = 148,
/** Numeric keypad '5' key. */
AKEYCODE_NUMPAD_5 = 149,
/** Numeric keypad '6' key. */
AKEYCODE_NUMPAD_6 = 150,
/** Numeric keypad '7' key. */
AKEYCODE_NUMPAD_7 = 151,
/** Numeric keypad '8' key. */
AKEYCODE_NUMPAD_8 = 152,
/** Numeric keypad '9' key. */
AKEYCODE_NUMPAD_9 = 153,
/** Numeric keypad '/' key (for division). */
AKEYCODE_NUMPAD_DIVIDE = 154,
/** Numeric keypad '*' key (for multiplication). */
AKEYCODE_NUMPAD_MULTIPLY = 155,
/** Numeric keypad '-' key (for subtraction). */
AKEYCODE_NUMPAD_SUBTRACT = 156,
/** Numeric keypad '+' key (for addition). */
AKEYCODE_NUMPAD_ADD = 157,
/** Numeric keypad '.' key (for decimals or digit grouping). */
AKEYCODE_NUMPAD_DOT = 158,
/** Numeric keypad ',' key (for decimals or digit grouping). */
AKEYCODE_NUMPAD_COMMA = 159,
/** Numeric keypad Enter key. */
AKEYCODE_NUMPAD_ENTER = 160,
/** Numeric keypad '=' key. */
AKEYCODE_NUMPAD_EQUALS = 161,
/** Numeric keypad '(' key. */
AKEYCODE_NUMPAD_LEFT_PAREN = 162,
/** Numeric keypad ')' key. */
AKEYCODE_NUMPAD_RIGHT_PAREN = 163,
/** Volume Mute key.
* Mutes the speaker, unlike {@link AKEYCODE_MUTE}.
* This key should normally be implemented as a toggle such that the first press
* mutes the speaker and the second press restores the original volume. */
AKEYCODE_VOLUME_MUTE = 164,
/** Info key.
* Common on TV remotes to show additional information related to what is
* currently being viewed. */
AKEYCODE_INFO = 165,
/** Channel up key.
* On TV remotes, increments the television channel. */
AKEYCODE_CHANNEL_UP = 166,
/** Channel down key.
* On TV remotes, decrements the television channel. */
AKEYCODE_CHANNEL_DOWN = 167,
/** Zoom in key. */
AKEYCODE_ZOOM_IN = 168,
/** Zoom out key. */
AKEYCODE_ZOOM_OUT = 169,
/** TV key.
* On TV remotes, switches to viewing live TV. */
AKEYCODE_TV = 170,
/** Window key.
* On TV remotes, toggles picture-in-picture mode or other windowing functions. */
AKEYCODE_WINDOW = 171,
/** Guide key.
* On TV remotes, shows a programming guide. */
AKEYCODE_GUIDE = 172,
/** DVR key.
* On some TV remotes, switches to a DVR mode for recorded shows. */
AKEYCODE_DVR = 173,
/** Bookmark key.
* On some TV remotes, bookmarks content or web pages. */
AKEYCODE_BOOKMARK = 174,
/** Toggle captions key.
* Switches the mode for closed-captioning text, for example during television shows. */
AKEYCODE_CAPTIONS = 175,
/** Settings key.
* Starts the system settings activity. */
AKEYCODE_SETTINGS = 176,
/** TV power key.
* On TV remotes, toggles the power on a television screen. */
AKEYCODE_TV_POWER = 177,
/** TV input key.
* On TV remotes, switches the input on a television screen. */
AKEYCODE_TV_INPUT = 178,
/** Set-top-box power key.
* On TV remotes, toggles the power on an external Set-top-box. */
AKEYCODE_STB_POWER = 179,
/** Set-top-box input key.
* On TV remotes, switches the input mode on an external Set-top-box. */
AKEYCODE_STB_INPUT = 180,
/** A/V Receiver power key.
* On TV remotes, toggles the power on an external A/V Receiver. */
AKEYCODE_AVR_POWER = 181,
/** A/V Receiver input key.
* On TV remotes, switches the input mode on an external A/V Receiver. */
AKEYCODE_AVR_INPUT = 182,
/** Red "programmable" key.
* On TV remotes, acts as a contextual/programmable key. */
AKEYCODE_PROG_RED = 183,
/** Green "programmable" key.
* On TV remotes, actsas a contextual/programmable key. */
AKEYCODE_PROG_GREEN = 184,
/** Yellow "programmable" key.
* On TV remotes, acts as a contextual/programmable key. */
AKEYCODE_PROG_YELLOW = 185,
/** Blue "programmable" key.
* On TV remotes, acts as a contextual/programmable key. */
AKEYCODE_PROG_BLUE = 186,
/** App switch key.
* Should bring up the application switcher dialog. */
AKEYCODE_APP_SWITCH = 187,
/** Generic Game Pad Button #1.*/
AKEYCODE_BUTTON_1 = 188,
/** Generic Game Pad Button #2.*/
AKEYCODE_BUTTON_2 = 189,
/** Generic Game Pad Button #3.*/
AKEYCODE_BUTTON_3 = 190,
/** Generic Game Pad Button #4.*/
AKEYCODE_BUTTON_4 = 191,
/** Generic Game Pad Button #5.*/
AKEYCODE_BUTTON_5 = 192,
/** Generic Game Pad Button #6.*/
AKEYCODE_BUTTON_6 = 193,
/** Generic Game Pad Button #7.*/
AKEYCODE_BUTTON_7 = 194,
/** Generic Game Pad Button #8.*/
AKEYCODE_BUTTON_8 = 195,
/** Generic Game Pad Button #9.*/
AKEYCODE_BUTTON_9 = 196,
/** Generic Game Pad Button #10.*/
AKEYCODE_BUTTON_10 = 197,
/** Generic Game Pad Button #11.*/
AKEYCODE_BUTTON_11 = 198,
/** Generic Game Pad Button #12.*/
AKEYCODE_BUTTON_12 = 199,
/** Generic Game Pad Button #13.*/
AKEYCODE_BUTTON_13 = 200,
/** Generic Game Pad Button #14.*/
AKEYCODE_BUTTON_14 = 201,
/** Generic Game Pad Button #15.*/
AKEYCODE_BUTTON_15 = 202,
/** Generic Game Pad Button #16.*/
AKEYCODE_BUTTON_16 = 203,
/** Language Switch key.
* Toggles the current input language such as switching between English and Japanese on
* a QWERTY keyboard. On some devices, the same function may be performed by
* pressing Shift+Spacebar. */
AKEYCODE_LANGUAGE_SWITCH = 204,
/** Manner Mode key.
* Toggles silent or vibrate mode on and off to make the device behave more politely
* in certain settings such as on a crowded train. On some devices, the key may only
* operate when long-pressed. */
AKEYCODE_MANNER_MODE = 205,
/** 3D Mode key.
* Toggles the display between 2D and 3D mode. */
AKEYCODE_3D_MODE = 206,
/** Contacts special function key.
* Used to launch an address book application. */
AKEYCODE_CONTACTS = 207,
/** Calendar special function key.
* Used to launch a calendar application. */
AKEYCODE_CALENDAR = 208,
/** Music special function key.
* Used to launch a music player application. */
AKEYCODE_MUSIC = 209,
/** Calculator special function key.
* Used to launch a calculator application. */
AKEYCODE_CALCULATOR = 210,
/** Japanese full-width / half-width key. */
AKEYCODE_ZENKAKU_HANKAKU = 211,
/** Japanese alphanumeric key. */
AKEYCODE_EISU = 212,
/** Japanese non-conversion key. */
AKEYCODE_MUHENKAN = 213,
/** Japanese conversion key. */
AKEYCODE_HENKAN = 214,
/** Japanese katakana / hiragana key. */
AKEYCODE_KATAKANA_HIRAGANA = 215,
/** Japanese Yen key. */
AKEYCODE_YEN = 216,
/** Japanese Ro key. */
AKEYCODE_RO = 217,
/** Japanese kana key. */
AKEYCODE_KANA = 218,
/** Assist key.
* Launches the global assist activity. Not delivered to applications. */
AKEYCODE_ASSIST = 219,
/** Brightness Down key.
* Adjusts the screen brightness down. */
AKEYCODE_BRIGHTNESS_DOWN = 220,
/** Brightness Up key.
* Adjusts the screen brightness up. */
AKEYCODE_BRIGHTNESS_UP = 221,
/** Audio Track key.
* Switches the audio tracks. */
AKEYCODE_MEDIA_AUDIO_TRACK = 222,
/** Sleep key.
* Puts the device to sleep. Behaves somewhat like {@link AKEYCODE_POWER} but it
* has no effect if the device is already asleep. */
AKEYCODE_SLEEP = 223,
/** Wakeup key.
* Wakes up the device. Behaves somewhat like {@link AKEYCODE_POWER} but it
* has no effect if the device is already awake. */
AKEYCODE_WAKEUP = 224,
/** Pairing key.
* Initiates peripheral pairing mode. Useful for pairing remote control
* devices or game controllers, especially if no other input mode is
* available. */
AKEYCODE_PAIRING = 225,
/** Media Top Menu key.
* Goes to the top of media menu. */
AKEYCODE_MEDIA_TOP_MENU = 226,
/** '11' key. */
AKEYCODE_11 = 227,
/** '12' key. */
AKEYCODE_12 = 228,
/** Last Channel key.
* Goes to the last viewed channel. */
AKEYCODE_LAST_CHANNEL = 229,
/** TV data service key.
* Displays data services like weather, sports. */
AKEYCODE_TV_DATA_SERVICE = 230,
/** Voice Assist key.
* Launches the global voice assist activity. Not delivered to applications. */
AKEYCODE_VOICE_ASSIST = 231,
/** Radio key.
* Toggles TV service / Radio service. */
AKEYCODE_TV_RADIO_SERVICE = 232,
/** Teletext key.
* Displays Teletext service. */
AKEYCODE_TV_TELETEXT = 233,
/** Number entry key.
* Initiates to enter multi-digit channel nubmber when each digit key is assigned
* for selecting separate channel. Corresponds to Number Entry Mode (0x1D) of CEC
* User Control Code. */
AKEYCODE_TV_NUMBER_ENTRY = 234,
/** Analog Terrestrial key.
* Switches to analog terrestrial broadcast service. */
AKEYCODE_TV_TERRESTRIAL_ANALOG = 235,
/** Digital Terrestrial key.
* Switches to digital terrestrial broadcast service. */
AKEYCODE_TV_TERRESTRIAL_DIGITAL = 236,
/** Satellite key.
* Switches to digital satellite broadcast service. */
AKEYCODE_TV_SATELLITE = 237,
/** BS key.
* Switches to BS digital satellite broadcasting service available in Japan. */
AKEYCODE_TV_SATELLITE_BS = 238,
/** CS key.
* Switches to CS digital satellite broadcasting service available in Japan. */
AKEYCODE_TV_SATELLITE_CS = 239,
/** BS/CS key.
* Toggles between BS and CS digital satellite services. */
AKEYCODE_TV_SATELLITE_SERVICE = 240,
/** Toggle Network key.
* Toggles selecting broacast services. */
AKEYCODE_TV_NETWORK = 241,
/** Antenna/Cable key.
* Toggles broadcast input source between antenna and cable. */
AKEYCODE_TV_ANTENNA_CABLE = 242,
/** HDMI #1 key.
* Switches to HDMI input #1. */
AKEYCODE_TV_INPUT_HDMI_1 = 243,
/** HDMI #2 key.
* Switches to HDMI input #2. */
AKEYCODE_TV_INPUT_HDMI_2 = 244,
/** HDMI #3 key.
* Switches to HDMI input #3. */
AKEYCODE_TV_INPUT_HDMI_3 = 245,
/** HDMI #4 key.
* Switches to HDMI input #4. */
AKEYCODE_TV_INPUT_HDMI_4 = 246,
/** Composite #1 key.
* Switches to composite video input #1. */
AKEYCODE_TV_INPUT_COMPOSITE_1 = 247,
/** Composite #2 key.
* Switches to composite video input #2. */
AKEYCODE_TV_INPUT_COMPOSITE_2 = 248,
/** Component #1 key.
* Switches to component video input #1. */
AKEYCODE_TV_INPUT_COMPONENT_1 = 249,
/** Component #2 key.
* Switches to component video input #2. */
AKEYCODE_TV_INPUT_COMPONENT_2 = 250,
/** VGA #1 key.
* Switches to VGA (analog RGB) input #1. */
AKEYCODE_TV_INPUT_VGA_1 = 251,
/** Audio description key.
* Toggles audio description off / on. */
AKEYCODE_TV_AUDIO_DESCRIPTION = 252,
/** Audio description mixing volume up key.
* Louden audio description volume as compared with normal audio volume. */
AKEYCODE_TV_AUDIO_DESCRIPTION_MIX_UP = 253,
/** Audio description mixing volume down key.
* Lessen audio description volume as compared with normal audio volume. */
AKEYCODE_TV_AUDIO_DESCRIPTION_MIX_DOWN = 254,
/** Zoom mode key.
* Changes Zoom mode (Normal, Full, Zoom, Wide-zoom, etc.) */
AKEYCODE_TV_ZOOM_MODE = 255,
/** Contents menu key.
* Goes to the title list. Corresponds to Contents Menu (0x0B) of CEC User Control
* Code */
AKEYCODE_TV_CONTENTS_MENU = 256,
/** Media context menu key.
* Goes to the context menu of media contents. Corresponds to Media Context-sensitive
* Menu (0x11) of CEC User Control Code. */
AKEYCODE_TV_MEDIA_CONTEXT_MENU = 257,
/** Timer programming key.
* Goes to the timer recording menu. Corresponds to Timer Programming (0x54) of
* CEC User Control Code. */
AKEYCODE_TV_TIMER_PROGRAMMING = 258,
/** Help key. */
AKEYCODE_HELP = 259,
AKEYCODE_NAVIGATE_PREVIOUS = 260,
AKEYCODE_NAVIGATE_NEXT = 261,
AKEYCODE_NAVIGATE_IN = 262,
AKEYCODE_NAVIGATE_OUT = 263,
/** Primary stem key for Wear
* Main power/reset button on watch. */
AKEYCODE_STEM_PRIMARY = 264,
/** Generic stem key 1 for Wear */
AKEYCODE_STEM_1 = 265,
/** Generic stem key 2 for Wear */
AKEYCODE_STEM_2 = 266,
/** Generic stem key 3 for Wear */
AKEYCODE_STEM_3 = 267,
/** Directional Pad Up-Left */
AKEYCODE_DPAD_UP_LEFT = 268,
/** Directional Pad Down-Left */
AKEYCODE_DPAD_DOWN_LEFT = 269,
/** Directional Pad Up-Right */
AKEYCODE_DPAD_UP_RIGHT = 270,
/** Directional Pad Down-Right */
AKEYCODE_DPAD_DOWN_RIGHT = 271,
/** Skip forward media key */
AKEYCODE_MEDIA_SKIP_FORWARD = 272,
/** Skip backward media key */
AKEYCODE_MEDIA_SKIP_BACKWARD = 273,
/** Step forward media key.
* Steps media forward one from at a time. */
AKEYCODE_MEDIA_STEP_FORWARD = 274,
/** Step backward media key.
* Steps media backward one from at a time. */
AKEYCODE_MEDIA_STEP_BACKWARD = 275,
/** Put device to sleep unless a wakelock is held. */
AKEYCODE_SOFT_SLEEP = 276,
/** Cut key. */
AKEYCODE_CUT = 277,
/** Copy key. */
AKEYCODE_COPY = 278,
/** Paste key. */
AKEYCODE_PASTE = 279,
/** fingerprint navigation key, up. */
AKEYCODE_SYSTEM_NAVIGATION_UP = 280,
/** fingerprint navigation key, down. */
AKEYCODE_SYSTEM_NAVIGATION_DOWN = 281,
/** fingerprint navigation key, left. */
AKEYCODE_SYSTEM_NAVIGATION_LEFT = 282,
/** fingerprint navigation key, right. */
AKEYCODE_SYSTEM_NAVIGATION_RIGHT = 283,
/** all apps */
AKEYCODE_ALL_APPS = 284,
/** refresh key */
AKEYCODE_REFRESH = 285,
/** Thumbs up key. Apps can use this to let user upvote content. */
AKEYCODE_THUMBS_UP = 286,
/** Thumbs down key. Apps can use this to let user downvote content. */
AKEYCODE_THUMBS_DOWN = 287,
/** Used to switch current account that is consuming content.
* May be consumed by system to switch current viewer profile. */
AKEYCODE_PROFILE_SWITCH = 288,
/** Video Application key #1. */
AKEYCODE_VIDEO_APP_1 = 289,
/** Video Application key #2. */
AKEYCODE_VIDEO_APP_2 = 290,
/** Video Application key #3. */
AKEYCODE_VIDEO_APP_3 = 291,
/** Video Application key #4. */
AKEYCODE_VIDEO_APP_4 = 292,
/** Video Application key #5. */
AKEYCODE_VIDEO_APP_5 = 293,
/** Video Application key #6. */
AKEYCODE_VIDEO_APP_6 = 294,
/** Video Application key #7. */
AKEYCODE_VIDEO_APP_7 = 295,
/** Video Application key #8. */
AKEYCODE_VIDEO_APP_8 = 296,
/** Featured Application key #1. */
AKEYCODE_FEATURED_APP_1 = 297,
/** Featured Application key #2. */
AKEYCODE_FEATURED_APP_2 = 298,
/** Featured Application key #3. */
AKEYCODE_FEATURED_APP_3 = 299,
/** Featured Application key #4. */
AKEYCODE_FEATURED_APP_4 = 300,
/** Demo Application key #1. */
AKEYCODE_DEMO_APP_1 = 301,
/** Demo Application key #2. */
AKEYCODE_DEMO_APP_2 = 302,
/** Demo Application key #3. */
AKEYCODE_DEMO_APP_3 = 303,
/** Demo Application key #4. */
AKEYCODE_DEMO_APP_4 = 304,
/** Keyboard backlight Down key.
* Adjusts the keyboard backlight brightness down. */
AKEYCODE_KEYBOARD_BACKLIGHT_DOWN = 305,
/** Keyboard backlight Up key.
* Adjusts the keyboard backlight brightness up. */
AKEYCODE_KEYBOARD_BACKLIGHT_UP = 306,
/** Keyboard backlight Toggle key.
* Toggles the keyboard backlight on/off. */
AKEYCODE_KEYBOARD_BACKLIGHT_TOGGLE = 307,
/** The primary button on the barrel of a stylus.
* This is usually the button closest to the tip of the stylus. */
AKEYCODE_STYLUS_BUTTON_PRIMARY = 308,
/** The secondary button on the barrel of a stylus.
* This is usually the second button from the tip of the stylus. */
AKEYCODE_STYLUS_BUTTON_SECONDARY = 309,
/** The tertiary button on the barrel of a stylus.
* This is usually the third button from the tip of the stylus. */
AKEYCODE_STYLUS_BUTTON_TERTIARY = 310,
/** A button on the tail end of a stylus. */
AKEYCODE_STYLUS_BUTTON_TAIL = 311,
/** Key to open recent apps (a.k.a. Overview) */
AKEYCODE_RECENT_APPS = 312,
/** User customizable key #1. */
AKEYCODE_MACRO_1 = 313,
/** User customizable key #2. */
AKEYCODE_MACRO_2 = 314,
/** User customizable key #3. */
AKEYCODE_MACRO_3 = 315,
/** User customizable key #4. */
AKEYCODE_MACRO_4 = 316,
// NOTE: If you add a new keycode here you must also add it to several other files.
// Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list.
};
4、KeyEvent.java 添加对应keycode
frameworks/base/core/java/android/view/KeyEvent.java
/**
* Key code constant: A button whose usage can be customized by the user through
* the system.
* User customizable key #4.
*/
public static final int KEYCODE_MACRO_4 = 316;
/**
* Integer value of the last KEYCODE. Increases as new keycodes are added to KeyEvent.
* @hide
*/
@TestApi
public static final int LAST_KEYCODE = KEYCODE_MACRO_4;