Hacking with Android and hardware keyboards

I’ve owned a Lenovo Thinkpad tablet for a while now.  More recently I became tired of waiting for Lenovo to upgrade the stock Honeycomb (3.1) to Ice cream sandwich (4.0) so I decided to install a promising ROM that is being developed by some developers at XDA.

The ROM is at version alpha 5 at the time of writing and is surprisingly usable at this early stage.  The one thing that wasn’t working was the folio keyboard that came with my tablet.  I’m going to document the steps that myself and some others went through to get it working because it may come in handy for others.  This post assumes that you are comfortable with adb, logcat and the command line.  You will also need root access to the device.

Thanks to all of the people in the XDA forums who helped me understand all of this stuff. The credit goes to them.

First try – just plug it in

After this we got something like this reported in logcat

D/EventHub(  149): No input device configuration file found for device 'Lenovo ThinkPad Tablet'.
E/KeyLayoutMap(  149): /system/usr/keylayout/Generic.kl:108: Expected key code label, got 'KEYBOARD_LESS'.
E/Keyboard(  149): Could not determine key map for device 'Lenovo ThinkPad Tablet' and no default key maps were found!
I/EventHub(  149): New device: id=10, fd=166, path='/dev/input/event6', name='Lenovo ThinkPad Tablet', classes=0x80000001, configuration='', keyLayout='', keyCharacterMap='/system/usr/keychars/Generic.kcm', builtinKeyboard=false
I/InputReader(  149): Device added: id=10, name='Lenovo ThinkPad Tablet', sources=0x00000101
D/EventHub(  149): No input device configuration file found for device 'Lenovo ThinkPad Tablet'.
E/KeyLayoutMap(  149): /system/usr/keylayout/Generic.kl:108: Expected key code label, got 'KEYBOARD_LESS'.

 The interesting bit here is:

/system/usr/keylayout/Generic.kl:108: Expected key code label, got 'KEYBOARD_LESS'.

 This is saying that it attempted to load the generic keyboard layout file but encountered a problem on line 108 of Generic.kl.  If you open that file up you’d see this on line 108:

key 86 KEYBOARD_LESS

For whatever reason the system doesn’t recognise this symbol.  You can comment it out with a # symbol at the start of the line:

# key 86 KEYBOARD_LESS

It is not recommended to modify the Generic.kl file although that is what we did.  The more correct way is to create a new file that will match only to your specific hardware keyboard.  This is not that difficult but does require a little bit more effort.

Making the keyboard layout file

The keyboard layout file is made up of the usb vendor id, device id and version id.  You’ll need to get this information from a system dump like so:

1) Generate the dump. This will write to a file called ‘sysdump’ in your current directory.

adb shell sysdump > sysdump

2) Find the IDs that we need. Use some sort of text editor to open that file and search for, we’re looking for “KeyLayoutFile”.

1: Lenovo ThinkPad TabletClasses: 0x80000009Path: /dev/input/event8Location: usb-tegra-ehci.2-1/input1UniqueId: Identifier: bus=0x0003, vendor=0x1241, product=0x0003, version=0x0110KeyLayoutFile: /system/usr/keylayout/Generic.klKeyCharacterMapFile: /system/usr/keychars/Generic.kcmConfigurationFile:

There will be many stanzas like this but it should be relatively easy to find the correct one for your hardware keyboard.  The interesting bits here are the vendor, product and version IDs in the “Identifier:” line and the “KeyLayoutFile” and “KeyCharacterMapFile” lines which tell us which key layout and character map files are being used.

We can now start to assemble our fixed layout file for the keyboard.  Start by getting a copy of the offending Generic.kl file from the device.  This command will copy the file from the device to your local directory.

adb pull /system/usr/keylayout/Generic.kl

The file must be renamed according to the specified format. (mv is rename in Unix / Linux OSs). Note how this relates the vendor, produce and version IDs from above.

mv Generic.kl Vendor_1241_Product_0003_Version_0110.kl

Now you must edit the file locally to comment out the offending line like this:

# key 86 KEYBOARD_LESS

Now all we have to do is to get the file back onto the device and reboot so it can pick up the changes.  I find it more reliable to push the modified file onto somewhere like the sd card first and then move it into place

This will copy the new layout file to the sd card

adb push Vendor_1241_Product_0003_Version_0110.kl /sdcard/

Next we need to logon to the device itself.

adb shell

What we’re doing requires root privileges so we’ll need to login as root. Note this may cause a prompt on your device to allow root access. Just click yes if this happens.

su

The file needs to go onto the /system partition, which is mounted as read-only.  We can open it up for writing like so:

mount -o rw,remount /system

Next we simply copy the new file from /sdcard/ to the key layout directory.

cp /sdcard/Vendor_1241_Product_0003_Version_0110.kl /system/usr/keylayout/

All you need to do now is to reboot and try your keyboard again.  If you have any issues then the chances are that there is yet another problem similar to the KEYBOARD_LESS symbol above, but this time the process should be easier as you now know the steps to go through.

That’s it for this post.  In subsequent posts I will write about key maps and what to do if you have a non-US keyboard layout.

3 thoughts on “Hacking with Android and hardware keyboards

  1. Thanks! I have successfully changed the layout of my old Nokia SU-8W foldable keyboard to support MENU and BACK android keys with my Samsung Galaxy S III

    Unfortunately I ended up modifying the standard Generic.kl layout, because I was not sure about vendor id and product id, I tried a Vendor_5555_Product_00DD.kl (based on Mac Os X Bluetooth Preferences Information after pairing with the keyboard), but it didn’t seem to get it.

    sysdump does not exist on my SGS3 – rooted standard ROM – (called with adb from Mac Os X terminal) is it a script on some specific ROM?

    $ adb shell sysdump
    /system/bin/sh: sysdump: not found

    also tried to su, before

    $ adb shell
    shell@android:/ $ su
    shell@android:/ # systemdump
    sh: systemdump: not found

    Anyway I’m quite happy with my old little gadget working like a charm.

    Thanks again!

  2. P.S. I just modified codes for keys 125 and 126 in

    /system/usr/keylayout/Generic.kl

    this way:

    key 125 MENU
    key 126 BACK

    Following the instructions in this post you can easily update the file.

    At the end, after all modifications are done, you should
    mount -o ro,remount /system
    (before leaving su) to revert permissions back as they were.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s