Android: alter behavior of key event reported by usb keypad/keyboard

If you ever required to alter the key events of specific keypad/keyboard in android, for example, a specific key press on keypad is generating scan code 2  which is by default mapped to key code 1. You need to alter this behavior so that if scan code 2 is reported then it should up system volume instead of reporting number 1 or if scan code 3 is reported it should down system volume instead of reporting number 2.

Let’s have a look how to achive this in android. First get basic idea of,

scan code - keyboard reports key press event in form of number
            or sequence of number and it is part of internal
            keyboard firmware.
 key code - mapping of scan code to values that are used to
            identify the keys.

The system provides a special built-in generic key layout file called Generic.kl. This key layout is intended to support a variety of standard external keyboards and joysticks. Do not modify the generic key layout! as it’s will be generic for any input device connected to device running android. Generik.kl is responsible for mapping linux scan codes to android key codes and it’s located at /system/usr/keylayout/Generic.kl on device running android.

For any input device to work with android it needs,

key layout file(.kl) - responsible for mapping scan code to
android key code
key character map file(.kcm) - responsible for mapping of
android key codes to characters
input device configuration file(.idc) - needed for touch screen
input devices

For generic HID keyboard device only .kl file is important if you also want to alter its character mapping then you
also need to make that device specific .kcm file, reference example of .kcm file can be found at frameworks/base/data/keyboards/*.kcm

If you want to customize mapping for your keyboard device you can make device specific layout file like, Vendor_ID_Product_ID.kl

Check kernel log message to get your keypad devices Product and Vendor id when you connect it, and create file name using this ids,
in AOSP – frameworks/base/data/keyboards/Vendor_0079_Product_0011.kl is reference file you can use.

Now here by default scancode 2 is mapped to keycode 1, later it is mapped to VOLUME_DOWN
#key scancode keycode
key          2           1
key          3           2

#key scancode      keycode
key         2        VOLUME_DOWN
key         3        VOLUME_UP

Don’t forget to validate your layout file if it contain any error your device will fallback to use default layout file as described in android help. Once you validate newly created file push (for adb push – you need to be root) it to /system/usr/keylayout/ on device and reboot. After reboot specific key event will be handled as you have described it in key layout file.

Also note that if you wish to use policy flags as described here under key declaration, then note that in lollipop only FUNCTION and VIRTUAL flags will work.

You can also debug parsing and mapping of key layout(.kl)
and ke character map(.kcm) files by enabling,

#define DEBUG_MAPPING 1
#define DEBUG_PARSER 1 in,

frameworks/native/libs/input/KeyLayoutMap.cpp
frameworks/native/libs/input/KeyCharacterMap.cpp

filter this in logcat by using,
adb logcat | grep -iE "KeyLayout|KeyCharacterMap"

About sudousr

coding, photography, apple fan, love to talk to smart people, TED
This entry was posted in /android and tagged , , . Bookmark the permalink.

1 Response to Android: alter behavior of key event reported by usb keypad/keyboard

  1. Andre says:

    Hello, thanks for this guide. I was in need of this, m also doing this kind of work on android.
    by the way can please guide me to add custom button event in android??
    Thanks.

    Like

Leave a comment