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/event7name: "sm8150-tavil-snd-card USB_3_5 Jack"
add device 2: /dev/input/event6name: "sm8150-tavil-snd-card Button Jack"
add device 3: /dev/input/event5name: "sm8150-tavil-snd-card Headset Jack"
add device 4: /dev/input/event3name: "gpio-keys"
add device 5: /dev/input/event2name: "uinput-goodix"
add device 6: /dev/input/event0name: "qpnp_pon"
add device 7: /dev/input/event1name: "qti-haptics"
add device 8: /dev/input/event4name: "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-keysClasses: KEYBOARDPath: /dev/input/event3Enabled: trueDescriptor: 485d69228e24f5e46da1598745890b214130dbc4Location: gpio-keys/input0ControllerNumber: 0UniqueId: Identifier: bus=0x0019, vendor=0x0001, product=0x0001, version=0x0100KeyLayoutFile: /system/usr/keylayout/gpio-keys.klKeyCharacterMapFile: /system/usr/keychars/Generic.kcmConfigurationFile: VideoDevice: <none>Device 5: gpio-keysEventHub Devices: [ 4 ] Generation: 15IsExternal: falseAssociatedDisplayPort: <none>AssociatedDisplayUniqueId: <none>HasMic: falseSources: 0x00000101KeyboardType: 1ControllerNum: 0Keyboard Input Mapper:Parameters:OrientationAware: falseHandlesKeyRepeat: falseKeyboardType: 1Orientation: 0KeyDowns: 0 keys currently downMetaState: 0x0DownTime: 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 listfor (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 kbdif (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 modulesstd::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_PROBEALOGD("Probing for system provided input device configuration file: path='%s'",path.c_str());
#endifif (!access(path.c_str(), R_OK)) {
#if DEBUG_PROBEALOGD("Found");
#endifreturn 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_PROBEALOGD("Probing for system user input device configuration file: path='%s'", path.c_str());
#endifif (!access(path.c_str(), R_OK)) {
#if DEBUG_PROBEALOGD("Found");
#endifreturn path;}// Not found.
#if DEBUG_PROBEALOGD("Probe failed to find input device configuration file: name='%s', type=%d",name.c_str(), type);
#endifreturn "";
}
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 setmDevices.insert({eventHubId, std::make_pair(std::move(contextPtr), std::move(mappers))});// Must change generation to flag this device as changedbumpGeneration();
}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 setmDevices.insert({eventHubId, std::make_pair(std::move(contextPtr), std::move(mappers))});// Must change generation to flag this device as changedbumpGeneration();
}
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*/@TestApipublic static final int LAST_KEYCODE = KEYCODE_MACRO_4;