Discussing the nuts and bolts of software development

Monday, April 02, 2012


Disabling the console switching keys for Android

Some time ago I was doing development on an Android phone and using a BlueTooth keyboard I came across an intriguing behaviour.  Hitting the Alt+Left or Alt+Right key combo, the phone would seemingly stop working and give all the symptoms of a frozen device, no more animated wallpaper and unresponsive touchscreen.  This stems from a functionality inherited from Linux for the desktop.  In this article I will describe the origin of the issue, how to recover from it and how it can be fixed at the kernel level.

Background information

In Linux there exist some special key combinations that are handled at the kernel level.  In this article we'll be looking at the console key combinations, specifically:
* Alt refers to the left Alt key on the keyboard

Let's start with Alt+F1 through F12; these allow accessing the tty's.  On a typical Linux installation Alt+F1 through F6 allows the user to switch between tty1 through tty6 respectively directly and Alt+F7 (F1 in Fedora) is a special tty in which the graphical interface runs.  This can change from distro to distro.

These Alt commands work from the tty's, but don't from the graphical interface.  That's where the Ctrl+Alt+Fn combinations come in, to let you leave the graphical interface.  Now the Alt+Left and Alt+Right commands let you cycle through the tty's to the left or to the right.  i.e. using Alt+Right from tty3 will lead you to tty4.

I don't have these keys on my Android phone...

That's right!  For the most part these key combinations do not come into play on an Android phone as you can't find them on the touchscreen.

When users start connecting BlueTooth or USB keyboards to interface with their Android mobile, that's when the surprise comes for the unsuspecting user.  On my Galaxy S for example, pressing the Alt+Right combo freezes the display.  The live wallpaper stops moving; and the touchscreen becomes unresponsive.  This can be fixed by any of these three options:
That gets the user back to the graphical interface tty and make it responsive again.

Modifying the kernel default key map

The Default kernel keymap in the Android source is located in kernel/drivers/char/defkeymap.map as of Gingerbread (2.3).  Entries in this file look like the following:

keycode  59 = F1               F11              Console_13
        control keycode  59 = F1
        alt     keycode  59 = Console_1
        control alt     keycode  59 = Console_1
keycode 105 = Left
        alt     keycode 105 = Decr_Console
keycode 106 = Right
        alt     keycode 106 = Incr_Console

In our case, we want to disable the combinations associated to Console so in the above entries we simply need to comment the lines that declare these.

keycode  59 = F1               F11              Console_13
        control keycode  59 = F1
#        alt     keycode  59 = Console_1
#        control alt     keycode  59 = Console_1
keycode 105 = Left
#        alt     keycode 105 = Decr_Console
keycode 106 = Right
#        alt     keycode 106 = Incr_Console

There are more entries not shown here that declare Console related key combinations.  The instructions at the top of the defkeymap.c_shipped file read:

/* Do not edit this file! It was automatically generated by   */
/*    loadkeys --mktable defkeymap.map > defkeymap.c          */

When I do run this loadkeys command, the generated file does not match the shipped file provided in the Android source as can be seen by difference in the files size.

$ ll defkeymap.c*
-rw-rw-r--. 1 jpl jpl 18433 Oct 19 12:46 defkeymap.c
-rw-rw-r--. 1 jpl jpl 11007 Oct 12 19:35 defkeymap.c_shipped

Running diff also shows that the provided shipped file has not been generated from the accompanying defkeymap.map file.  Simply generating defkeymap.c from our modified defkeymap.map won't do either as our new defkeymap.c is overwritten with a copy of defkeymap.c_shipped during the build.

What do we do now?  The way I worked around this is a bit tedious but will make sure that we don't lose changes that were applied to the shipped file and not reflected in the defkeymap.map.

Workaround: I generated a defkeymap.c file from the original defkeymap.map and a defkeymap.c from the modified defkeymap.map to remove the Alt+X combinations.  Then I generated the diff of the 2 files and manually applied it to the shipped file.

Labels: , , ,

Comments: Post a Comment

<< Home

This page is powered by Blogger. Isn't yours?