Learning Resources
 

Keyboard events handling in Android


Android supports a variety of keyboard devices including special function keypads (volume and power controls), compact embedded QWERTY keyboards, and fully featured PC-style external keyboards.

This document describes physical keyboards only. Refer to the Android SDK for information about soft keyboards (Input Method Editors).

Keyboard Classification

An input device is classified as a keyboard if either of the following conditions hold:

  • The input device reports the presence of any Linux key codes used on keyboards including 0through 0xffor KEY_OKthrough KEY_MAX.

  • The input device reports the presence of any Linux key codes used on joysticks and gamepads including BTN_0through BTN_9, BTN_TRIGGERthrough BTN_DEAD, or BTN_Athrough BTN_THUMBR.

Joysticks are currently classified as keyboards because joystick and gamepad buttons are reported by EV_KEYevents in the same way keyboard keys are reported. Thus joysticks and gamepads also make use of key map files for configuration. Refer to the section on Joystick Devices for more information.

Once an input device has been classified as a keyboard, the system loads the input device configuration file and keyboard layout for the keyboard.

The system then tries to determine additional characteristics of the device.

  • If the input device has any keys that are mapped to KEYCODE_Q, then the device is considered to have an alphabetic keypad (as opposed to numeric). The alphabetic keypad capability is reported in the resource Configurationobject as KEYBOARD_QWERTY.

  • If the input device has any keys that are mapped to KEYCODE_DPAD_UP, KEYCODE_DPAD_DOWN, KEYCODE_DPAD_LEFT, KEYCODE_DPAD_RIGHT, and KEYCODE_DPAD_CENTER(all must be present), then the device is considered to have a directional keypad. The directional keypad capability is reported in the resource Configurationobject as NAVIGATION_DPAD.

  • If the input device has any keys that are mapped to KEYCODE_BUTTON_Aor other gamepad related keys, then the device is considered to have a gamepad.

Keyboard Driver Requirements

  1. Keyboard drivers should only register key codes for the keys that they actually support. Registering excess key codes may confuse the device classification algorithm or cause the system to incorrectly detect the supported keyboard capabilities of the device.

  2. Keyboard drivers should use EV_KEYto report key presses, using a value of 0to indicate that a key is released, a value of 1to indicate that a key is pressed, and a value greater than or equal to 2to indicate that the key is being repeated automatically.

  3. Android performs its own keyboard repeating. Auto-repeat functionality should be disabled in the driver.

  4. Keyboard drivers may optionally indicate the HID usage or low-level scan code by sending EV_MSCwith MSC_SCANCODEand a valud indicating the usage or scan code when the key is pressed. This information is not currently used by Android.

  5. Keyboard drivers should support setting LED states when EV_LEDis written to the device. The hid-inputdriver handles this automatically. At the time of this writing, Android uses LED_CAPSLOCK, LED_SCROLLLOCK, and LED_NUMLOCK. These LEDs only need to be supported when the keyboard actually has the associated indicator lights.

  6. Keyboard drivers for embedded keypads (for example, using a GPIO matrix) should make sure to send EV_KEYevents with a value of 0for any keys that are still pressed when the device is going to sleep. Otherwise keys might get stuck down and will auto-repeat forever.

Keyboard Operation

The following is a brief summary of the keyboard operation on Android.

  1. The EventHubreads raw events from the evdevdriver and maps Linux key codes (sometimes referred to as scan codes) into Android key codes using the keyboard's key layout map.

  2. The InputReaderconsumes the raw events and updates the meta key state. For example, if the left shift key is pressed or released, the reader will set or reset the META_SHIFT_LEFT_ONand META_SHIFT_ONbits accordingly.

  3. The InputReadernotifies the InputDispatcherabout the key event.

  4. The InputDispatcherasks the WindowManagerPolicywhat to do with the key event by calling WindowManagerPolicy.interceptKeyBeforeQueueing. This method is part of a critical path that is responsible for waking the device when certain keys are pressed. The EventHubeffectively holds a wake lock along this critical path to ensure that it will run to completion.

  5. If an InputFilteris currently in use, the InputDispatchergives it a chance to consume or transform the key. The InputFiltermay be used to implement low-level system-wide accessibility policies.

  6. The InputDispatcherenqueues the key for processing on the dispatch thread.

  7. When the InputDispatcherdequeues the key, it gives the WindowManagerPolicya second chance to intercept the key event by calling WindowManagerPolicy.interceptKeyBeforeDispatching. This method handles system shortcuts and other functions.

  8. The InputDispatcherthen identifies the key event target (the focused window) and waits for them to become ready. Then, the InputDispatcherdelivers the key event to the application.

  9. Inside the application, the key event propagates down the view hierarchy to the focused view for pre-IME key dispatch.

  10. If the key event is not handled in the pre-IME dispatch and an IME is in use, the key event is delivered to the IME.

  11. If the key event was not consumed by the IME, then the key event propagates down the view hierarchy to the focused view for standard key dispatch.

  12. The application reports back to the InputDispatcheras to whether the key event was consumed. If the event was not consumed, the InputDispatchercalls WindowManagerPolicy.dispatchUnhandledKeyto apply "fallback" behavior. Depending on the fallback action, the key event dispatch cycle may be restarted using a different key code. For example, if an application does not handle KEYCODE_ESCAPE, the system may redispatch the key event as KEYCODE_BACKinstead.

Keyboard Configuration

Keyboard behavior is determined by the keyboard's key layout, key character map and input device configuration.

Properties

The following input device configuration properties are used for keyboards.

keyboard.layout

Definition: keyboard.layout=

Specifies the name of the key layout file associated with the input device, excluding the .klextension. If this file is not found, the input system will use the default key layout instead.

Spaces in the name are converted to underscores during lookup.

Refer to the key layout file documentation for more details.

keyboard.characterMap

Definition: keyboard.characterMap=

Specifies the name of the key character map file associated with the input device, excluding the .kcmextension. If this file is not found, the input system will use the default key character map instead.

Spaces in the name are converted to underscores during lookup.

Refer to the key character map file documentation for more details.

keyboard.orientationAware

Definition: keyboard.orientationAware= 0| 1

Specifies whether the keyboard should react to display orientation changes.

  • If the value is 1, the directional keypad keys are rotated when the associated display orientation changes.

  • If the value is 0, the keyboard is immune to display orientation changes.

The default value is 0.

Orientation awareness is used to support rotation of directional keypad keys, such as on the Motorola Droid. For example, when the device is rotated clockwise 90 degrees from its natural orientation, KEYCODE_DPAD_UPis remapped to produce KEYCODE_DPAD_RIGHTsince the 'up' key ends up pointing 'right' when the device is held in that orientation.

keyboard.builtIn

Definition: keyboard.builtIn= 0| 1

Specifies whether the keyboard is the built-in (physically attached) keyboard.

The default value is 1if the device name ends with -keypad, 0otherwise.

The built-in keyboard is always assigned a device id of 0. Other keyboards that are not built-in are assigned unique non-zero device ids.

Using an id of 0for the built-in keyboard is important for maintaining compatibility with the KeyCharacterMap.BUILT_IN_KEYBOARDfield, which specifies the id of the built-in keyboard and has a value of 0. This field has been deprecated in the API but older applications might still be using it.

A special-function keyboard (one whose key character map specifies a type of SPECIAL_FUNCTION) will never be registered as the built-in keyboard, regardless of the setting of this property. This is because a special-function keyboard is by definition not intended to be used for general purpose typing.

Example Configurations

# This is an example input device configuration file for a built-in
# keyboard that has a DPad.

# The keyboard is internal because it is part of the device.
device.internal = 1

# The keyboard is the default built-in keyboard so it should be assigned
# an id of 0.
keyboard.builtIn = 1

# The keyboard includes a DPad which is mounted on the device.  As the device
# is rotated the orientation of the DPad rotates along with it, so the DPad must
# be aware of the display orientation.  This ensures that pressing 'up' on the
# DPad always means 'up' from the perspective of the user, even when the entire
# device has been rotated.
keyboard.orientationAware = 1

Compatibility Notes

Prior to Honeycomb, the keyboard input mapper did not use any configuration properties. All keyboards were assumed to be physically attached and orientation aware. The default key layout and key character map was named qwertyinstead of Generic. The key character map format was also very different and the framework did not support PC-style full keyboards or external keyboards.

When upgrading devices to Honeycomb, make sure to create or update the necessary configuration and key map files.

HID Usages, Linux Key Codes and Android Key Codes

The system refers to keys using several different identifiers, depending on the layer of abstraction.

For HID devices, each key has an associated HID usage. The Linux hid-inputdriver and related vendor and device-specific HID drivers are responsible for parsing HID reports and mapping HID usages to Linux key codes.

As Android reads EV_KEYevents from the Linux kernel, it translates each Linux key code into its corresponding Android key code according to the key layout file of the device.

When the key event is dispatched to an application, the android.view.KeyEventinstance reports the Linux key code as the value of getScanCode()and the Android key code as the value of getKeyCode(). For the purposes of the framework, only the value of getKeyCode()is important.

Note that the HID usage information is not used by Android itself or passed to applications.

Code Tables

The following

The LKC column specifies the Linux key code in hexadecimal.

The AKC column specifies the Android key code in hexadecimal.

The Notes column refers to notes that are posted after the

The Version column specifies the first version of the Android platform to have included this key in its default key map. Multiple rows are shown in cases where the default key map has changed between versions. The oldest version indicated is 1.6.

  • In Gingerbread (2.3) and earlier releases, the default key map was qwerty.kl. This key map was only intended for use with the Android Emulator and was not intended to be used to support arbitrary external keyboards. Nevertheless, a few OEMs added Bluetooth keyboard support to the platform and relied on qwerty.klto provide the necessary keyboard mappings. Consequently these older mappings may be of interest to OEMs who are building peripherals for these particular devices. Note that the mappings are substantially different from the current ones, particularly with respect to the treatment of the HOMEkey. It is recommended that all new peripherals be developed according to the Honeycomb or more recent key maps (ie. standard HID).

  • As of Honeycomb (3.0), the default key map is Generic.kl. This key map was designed to support full PC style keyboards. Most functionality of standard HID keyboards should just work out of the box.

The key code mapping may vary across versions of the Linux kernel and Android. When changes are known to have occurred in the Android default key maps, they are indicated in the version column.

Device-specific HID drivers and key maps may apply different mappings than are indicated here.

 

--Google