Add section on input devices.

Change-Id: Ib9c4909881df505b11537c28bd08182933a5565a
diff --git a/scripts/build.py b/scripts/build.py
index 8188f51..1325a38 100755
--- a/scripts/build.py
+++ b/scripts/build.py
@@ -9,7 +9,7 @@
 
 # call markdown as a subprocess, and capture the output
 def markdown(raw_file):
-  extensions = '-x tables' + ' ' + '-x "toc(title=In This Document)"'
+  extensions = '-x tables -x "toc(title=In This Document)" -x def_list'
   command = 'markdown' + ' ' + extensions + ' ' + raw_file
   p = subprocess.Popen(command, stdout = subprocess.PIPE, shell = True)
   return p.communicate()[0]
diff --git a/src/assets/main.css b/src/assets/main.css
index 59f2dd1..18662a1 100644
--- a/src/assets/main.css
+++ b/src/assets/main.css
@@ -241,6 +241,15 @@
   padding: 1em;
 }
 
+dt {
+  color: #1f2a33;
+  font-size: 110%;
+}
+
+dd {
+  margin: 1em 1em 1em 1em;
+}
+
 /* TABLE OF CONTENTS */
 
 .toc {
diff --git a/src/tech/index.md b/src/tech/index.md
index f7aa958..5653bda 100644
--- a/src/tech/index.md
+++ b/src/tech/index.md
@@ -52,3 +52,9 @@
 core Android platform.
 
 [» Android Security Overview](/tech/security/index.html)
+
+## Input Technical Information ##
+Android's input subsystem is responsible for supporting touch screens,
+keyboard, joysticks, mice and other devices.
+
+[» Input Information](/tech/input/index.html)
diff --git a/src/tech/input/dumpsys.md b/src/tech/input/dumpsys.md
new file mode 100644
index 0000000..883e8c4
--- /dev/null
+++ b/src/tech/input/dumpsys.md
@@ -0,0 +1,347 @@
+<!--
+   Copyright 2011 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+# Dumpsys #
+
+The `dumpsys` tool runs on the device and dumps interesting information
+about the status of system services.
+
+## Usage ##
+
+The input system is part of the window manager.  To dump its state,
+run the following command.
+
+    $ adb shell su -- dumpsys window
+
+    WINDOW MANAGER INPUT (dumpsys window input)
+    Event Hub State:
+      BuiltInKeyboardId: -1
+      Devices:
+    ...
+
+The set of information that is reported varies depending on the version of Android.
+
+### Event Hub State ###
+
+The `EventHub` component is responsible for communicating with the kernel device
+drivers and identifying device capabilities.  Accordingly, its state shows
+information about how devices are configured.
+
+    Event Hub State:
+      BuiltInKeyboardId: -1
+      Devices:
+        3: tuna-gpio-keypad
+          Classes: 0x00000001
+          Path: /dev/input/event2
+          Location:
+          UniqueId:
+          Identifier: bus=0x0000, vendor=0x0000, product=0x0000, version=0x0000
+          KeyLayoutFile: /system/usr/keylayout/tuna-gpio-keypad.kl
+          KeyCharacterMapFile: /system/usr/keychars/tuna-gpio-keypad.kcm
+          ConfigurationFile:
+        5: Tuna Headset Jack
+          Classes: 0x00000080
+          Path: /dev/input/event5
+          Location: ALSA
+          UniqueId:
+          Identifier: bus=0x0000, vendor=0x0000, product=0x0000, version=0x0000
+          KeyLayoutFile:
+          KeyCharacterMapFile:
+          ConfigurationFile:
+        6: Melfas MMSxxx Touchscreen
+          Classes: 0x00000014
+          Path: /dev/input/event1
+          Location: 3-0048/input0
+          UniqueId:
+          Identifier: bus=0x0018, vendor=0x0000, product=0x0000, version=0x0000
+          KeyLayoutFile:
+          KeyCharacterMapFile:
+          ConfigurationFile: /system/usr/idc/Melfas_MMSxxx_Touchscreen.idc
+        7: Motorola Bluetooth Wireless Keyboard
+          Classes: 0x8000000b
+          Path: /dev/input/event6
+          Location: 0C:DF:A4:B3:2D:BA
+          UniqueId: 00:0F:F6:80:02:CD
+          Identifier: bus=0x0005, vendor=0x22b8, product=0x093d, version=0x0288
+          KeyLayoutFile: /system/usr/keylayout/Vendor_22b8_Product_093d.kl
+          KeyCharacterMapFile: /system/usr/keychars/Generic.kcm
+          ConfigurationFile:
+
+#### Things To Look For ####
+
+1.  All of the expected input devices are present.
+
+2.  Each input device has an appropriate key layout file, key character map file
+    and input device configuration file.  If the files are missing or contain
+    syntax errors, then they will not be loaded.
+
+3.  Each input device is being classified correctly.  The bits in the `Classes`
+    field correspond to flags in `EventHub.h` such as `INPUT_DEVICE_CLASS_TOUCH_MT`.
+
+4.  The `BuiltInKeyboardId` is correct.  If the device does not have a built-in keyboard,
+    then the id must be `-1`, otherwise it should be the id of the built-in keyboard.
+
+    If you observe that the `BuiltInKeyboardId` is not `-1` but it should be, then
+    you are missing a key character map file for a special function keypad somewhere.
+    Special function keypad devices should have key character map files that contain
+    just the line `type SPECIAL_FUNCTION` (that's what in the `tuna-gpio-keykad.kcm`
+    file we see mentioned above).
+
+### Input Reader State ###
+
+The `InputReader` is responsible for decoding input events from the kernel.
+Its state dump shows information about how each input device is configured
+and recent state changes that occurred, such as key presses or touches on
+the touch screen.
+
+This is what a special function keypad looks like:
+
+    Input Reader State:
+      Device 3: tuna-gpio-keypad
+        IsExternal: false
+        Sources: 0x00000101
+        KeyboardType: 1
+        Keyboard Input Mapper:
+          Parameters:
+            AssociatedDisplayId: -1
+            OrientationAware: false
+          KeyboardType: 1
+          Orientation: 0
+          KeyDowns: 0 keys currently down
+          MetaState: 0x0
+          DownTime: 75816923828000
+
+Here is a touch screen.  Notice all of the information about the resolution of
+the device and the calibration parameters that were used.
+
+      Device 6: Melfas MMSxxx Touchscreen
+        IsExternal: false
+        Sources: 0x00001002
+        KeyboardType: 0
+        Motion Ranges:
+          X: source=0x00001002, min=0.000, max=719.001, flat=0.000, fuzz=0.999
+          Y: source=0x00001002, min=0.000, max=1279.001, flat=0.000, fuzz=0.999
+          PRESSURE: source=0x00001002, min=0.000, max=1.000, flat=0.000, fuzz=0.000
+          SIZE: source=0x00001002, min=0.000, max=1.000, flat=0.000, fuzz=0.000
+          TOUCH_MAJOR: source=0x00001002, min=0.000, max=1468.605, flat=0.000, fuzz=0.000
+          TOUCH_MINOR: source=0x00001002, min=0.000, max=1468.605, flat=0.000, fuzz=0.000
+          TOOL_MAJOR: source=0x00001002, min=0.000, max=1468.605, flat=0.000, fuzz=0.000
+          TOOL_MINOR: source=0x00001002, min=0.000, max=1468.605, flat=0.000, fuzz=0.000
+        Touch Input Mapper:
+          Parameters:
+            GestureMode: spots
+            DeviceType: touchScreen
+            AssociatedDisplay: id=0, isExternal=false
+            OrientationAware: true
+          Raw Touch Axes:
+            X: min=0, max=720, flat=0, fuzz=0, resolution=0
+            Y: min=0, max=1280, flat=0, fuzz=0, resolution=0
+            Pressure: min=0, max=255, flat=0, fuzz=0, resolution=0
+            TouchMajor: min=0, max=30, flat=0, fuzz=0, resolution=0
+            TouchMinor: unknown range
+            ToolMajor: unknown range
+            ToolMinor: unknown range
+            Orientation: unknown range
+            Distance: unknown range
+            TiltX: unknown range
+            TiltY: unknown range
+            TrackingId: min=0, max=65535, flat=0, fuzz=0, resolution=0
+            Slot: min=0, max=9, flat=0, fuzz=0, resolution=0
+          Calibration:
+            touch.size.calibration: diameter
+            touch.size.scale: 10.000
+            touch.size.bias: 0.000
+            touch.size.isSummed: false
+            touch.pressure.calibration: amplitude
+            touch.pressure.scale: 0.005
+            touch.orientation.calibration: none
+            touch.distance.calibration: none
+          SurfaceWidth: 720px
+          SurfaceHeight: 1280px
+          SurfaceOrientation: 0
+          Translation and Scaling Factors:
+            XScale: 0.999
+            YScale: 0.999
+            XPrecision: 1.001
+            YPrecision: 1.001
+            GeometricScale: 0.999
+            PressureScale: 0.005
+            SizeScale: 0.033
+            OrientationCenter: 0.000
+            OrientationScale: 0.000
+            DistanceScale: 0.000
+            HaveTilt: false
+            TiltXCenter: 0.000
+            TiltXScale: 0.000
+            TiltYCenter: 0.000
+            TiltYScale: 0.000
+          Last Button State: 0x00000000
+          Last Raw Touch: pointerCount=0
+          Last Cooked Touch: pointerCount=0
+
+Here is an external keyboard / mouse combo HID device.  (This device doesn't actually
+have a mouse but its HID descriptor says it does.)
+
+      Device 7: Motorola Bluetooth Wireless Keyboard
+        IsExternal: true
+        Sources: 0x00002103
+        KeyboardType: 2
+        Motion Ranges:
+          X: source=0x00002002, min=0.000, max=719.000, flat=0.000, fuzz=0.000
+          Y: source=0x00002002, min=0.000, max=1279.000, flat=0.000, fuzz=0.000
+          PRESSURE: source=0x00002002, min=0.000, max=1.000, flat=0.000, fuzz=0.000
+          VSCROLL: source=0x00002002, min=-1.000, max=1.000, flat=0.000, fuzz=0.000
+        Keyboard Input Mapper:
+          Parameters:
+            AssociatedDisplayId: -1
+            OrientationAware: false
+          KeyboardType: 2
+          Orientation: 0
+          KeyDowns: 0 keys currently down
+          MetaState: 0x0
+          DownTime: 75868832946000
+        Cursor Input Mapper:
+          Parameters:
+            AssociatedDisplayId: 0
+            Mode: pointer
+            OrientationAware: false
+          XScale: 1.000
+          YScale: 1.000
+          XPrecision: 1.000
+          YPrecision: 1.000
+          HaveVWheel: true
+          HaveHWheel: false
+          VWheelScale: 1.000
+          HWheelScale: 1.000
+          Orientation: 0
+          ButtonState: 0x00000000
+          Down: false
+          DownTime: 0
+
+Here is a joystick.  Notice how all of the axes have been scaled to a normalized
+range.  The axis mapping can be configured using key layout files.
+
+    Device 18: Logitech Logitech Cordless RumblePad 2
+        IsExternal: true
+        Sources: 0x01000511
+        KeyboardType: 1
+        Motion Ranges:
+          X: source=0x01000010, min=-1.000, max=1.000, flat=0.118, fuzz=0.000
+          Y: source=0x01000010, min=-1.000, max=1.000, flat=0.118, fuzz=0.000
+          Z: source=0x01000010, min=-1.000, max=1.000, flat=0.118, fuzz=0.000
+          RZ: source=0x01000010, min=-1.000, max=1.000, flat=0.118, fuzz=0.000
+          HAT_X: source=0x01000010, min=-1.000, max=1.000, flat=0.000, fuzz=0.000
+          HAT_Y: source=0x01000010, min=-1.000, max=1.000, flat=0.000, fuzz=0.000
+        Keyboard Input Mapper:
+          Parameters:
+            AssociatedDisplayId: -1
+            OrientationAware: false
+          KeyboardType: 1
+          Orientation: 0
+          KeyDowns: 0 keys currently down
+          MetaState: 0x0
+          DownTime: 675270841000
+        Joystick Input Mapper:
+          Axes:
+            X: min=-1.00000, max=1.00000, flat=0.11765, fuzz=0.00000
+              scale=0.00784, offset=-1.00000, highScale=0.00784, highOffset=-1.00000
+              rawAxis=0, rawMin=0, rawMax=255, rawFlat=15, rawFuzz=0, rawResolution=0
+            Y: min=-1.00000, max=1.00000, flat=0.11765, fuzz=0.00000
+              scale=0.00784, offset=-1.00000, highScale=0.00784, highOffset=-1.00000
+              rawAxis=1, rawMin=0, rawMax=255, rawFlat=15, rawFuzz=0, rawResolution=0
+            Z: min=-1.00000, max=1.00000, flat=0.11765, fuzz=0.00000
+              scale=0.00784, offset=-1.00000, highScale=0.00784, highOffset=-1.00000
+              rawAxis=2, rawMin=0, rawMax=255, rawFlat=15, rawFuzz=0, rawResolution=0
+            RZ: min=-1.00000, max=1.00000, flat=0.11765, fuzz=0.00000
+              scale=0.00784, offset=-1.00000, highScale=0.00784, highOffset=-1.00000
+              rawAxis=5, rawMin=0, rawMax=255, rawFlat=15, rawFuzz=0, rawResolution=0
+            HAT_X: min=-1.00000, max=1.00000, flat=0.00000, fuzz=0.00000
+              scale=1.00000, offset=0.00000, highScale=1.00000, highOffset=0.00000
+              rawAxis=16, rawMin=-1, rawMax=1, rawFlat=0, rawFuzz=0, rawResolution=0
+            HAT_Y: min=-1.00000, max=1.00000, flat=0.00000, fuzz=0.00000
+              scale=1.00000, offset=0.00000, highScale=1.00000, highOffset=0.00000
+              rawAxis=17, rawMin=-1, rawMax=1, rawFlat=0, rawFuzz=0, rawResolution=0
+
+At the end of the input reader dump there is some information about global configuration
+parameters such as the mouse pointer speed.
+
+      Configuration:
+        ExcludedDeviceNames: []
+        VirtualKeyQuietTime: 0.0ms
+        PointerVelocityControlParameters: scale=1.000, lowThreshold=500.000, highThreshold=3000.000, acceleration=3.000
+        WheelVelocityControlParameters: scale=1.000, lowThreshold=15.000, highThreshold=50.000, acceleration=4.000
+        PointerGesture:
+          Enabled: true
+          QuietInterval: 100.0ms
+          DragMinSwitchSpeed: 50.0px/s
+          TapInterval: 150.0ms
+          TapDragInterval: 300.0ms
+          TapSlop: 20.0px
+          MultitouchSettleInterval: 100.0ms
+          MultitouchMinDistance: 15.0px
+          SwipeTransitionAngleCosine: 0.3
+          SwipeMaxWidthRatio: 0.2
+          MovementSpeedRatio: 0.8
+          ZoomSpeedRatio: 0.3
+
+#### Things To Look For ####
+
+1.  All of the expected input devices are present.
+
+2.  Each input device has been configured appropriately.  Especially check the
+    touch screen and joystick axes.
+
+### Input Dispatcher State ###
+
+The `InputDispatcher` is responsible for sending input events to applications.
+Its state dump shows information about which window is being touched, the
+state of the input queue, whether an ANR is in progress, and so on.
+
+    Input Dispatcher State:
+      DispatchEnabled: 1
+      DispatchFrozen: 0
+      FocusedApplication: name='AppWindowToken{41b03a10 token=Token{41bdcf78 ActivityRecord{418ab728 com.android.settings/.Settings}}}', dispatchingTimeout=5000.000ms
+      FocusedWindow: name='Window{41908458 Keyguard paused=false}'
+      TouchDown: false
+      TouchSplit: false
+      TouchDeviceId: -1
+      TouchSource: 0x00000000
+      TouchedWindows: <none>
+      Windows:
+        0: name='Window{41bd5b18 NavigationBar paused=false}', paused=false, hasFocus=false, hasWallpaper=false, visible=true, canReceiveKeys=false, flags=0x05800068, type=0x000007e3, layer=181000, frame=[0,1184][720,1280], scale=1.000000, touchableRegion=[0,1184][720,1280], inputFeatures=0x00000000, ownerPid=306, ownerUid=1000, dispatchingTimeout=5000.000ms
+        1: name='Window{41a19770 RecentsPanel paused=false}', paused=false, hasFocus=false, hasWallpaper=false, visible=false, canReceiveKeys=false, flags=0x01820100, type=0x000007de, layer=151000, frame=[0,0][720,1184], scale=1.000000, touchableRegion=[0,0][720,1184], inputFeatures=0x00000000, ownerPid=306, ownerUid=1000, dispatchingTimeout=5000.000ms
+        2: name='Window{41a78768 StatusBar paused=false}', paused=false, hasFocus=false, hasWallpaper=false, visible=true, canReceiveKeys=false, flags=0x00800048, type=0x000007d0, layer=141000, frame=[0,0][720,50], scale=1.000000, touchableRegion=[0,0][720,50], inputFeatures=0x00000000, ownerPid=306, ownerUid=1000, dispatchingTimeout=5000.000ms
+        3: name='Window{41877570 StatusBarExpanded paused=false}', paused=false, hasFocus=false, hasWallpaper=false, visible=true, canReceiveKeys=false, flags=0x01811328, type=0x000007e1, layer=131005, frame=[0,-1184][720,-114], scale=1.000000, touchableRegion=[0,-1184][720,-114], inputFeatures=0x00000000, ownerPid=306, ownerUid=1000, dispatchingTimeout=5000.000ms
+        4: name='Window{41bedf20 TrackingView paused=false}', paused=false, hasFocus=false, hasWallpaper=false, visible=false, canReceiveKeys=false, flags=0x01020300, type=0x000007e1, layer=131000, frame=[0,-1032][720,102], scale=1.000000, touchableRegion=[0,-1032][720,102], inputFeatures=0x00000000, ownerPid=306, ownerUid=1000, dispatchingTimeout=5000.000ms
+        5: name='Window{41908458 Keyguard paused=false}', paused=false, hasFocus=true, hasWallpaper=false, visible=true, canReceiveKeys=true, flags=0x15120800, type=0x000007d4, layer=111000, frame=[0,50][720,1184], scale=1.000000, touchableRegion=[0,50][720,1184], inputFeatures=0x00000000, ownerPid=205, ownerUid=1000, dispatchingTimeout=5000.000ms
+        6: name='Window{4192cc30 com.android.phasebeam.PhaseBeamWallpaper paused=false}', paused=false, hasFocus=false, hasWallpaper=false, visible=true, canReceiveKeys=false, flags=0x00000308, type=0x000007dd, layer=21010, frame=[0,0][720,1184], scale=1.000000, touchableRegion=[0,0][720,1184], inputFeatures=0x00000000, ownerPid=429, ownerUid=10046, dispatchingTimeout=5000.000ms
+        7: name='Window{41866c00 com.android.settings/com.android.settings.Settings paused=false}', paused=false, hasFocus=false, hasWallpaper=false, visible=false, canReceiveKeys=false, flags=0x01810100, type=0x00000001, layer=21005, frame=[0,0][720,1184], scale=1.000000, touchableRegion=[0,0][720,1184], inputFeatures=0x00000000, ownerPid=19000, ownerUid=1000, dispatchingTimeout=5000.000ms
+        8: name='Window{4197c858 com.android.launcher/com.android.launcher2.Launcher paused=false}', paused=false, hasFocus=false, hasWallpaper=false, visible=false, canReceiveKeys=false, flags=0x01910100, type=0x00000001, layer=21000, frame=[0,0][720,1184], scale=1.000000, touchableRegion=[0,0][720,1184], inputFeatures=0x00000000, ownerPid=515, ownerUid=10032, dispatchingTimeout=5000.000ms
+      MonitoringChannels: <none>
+      InboundQueue: length=0
+      ActiveConnections: <none>
+      AppSwitch: not pending
+      Configuration:
+        MaxEventsPerSecond: 90
+        KeyRepeatDelay: 50.0ms
+        KeyRepeatTimeout: 500.0ms
+
+#### Things To Look For ####
+
+1.  In general, all input events are being processed as expected.
+
+2.  If you touch the touch screen and run dumpsys at the same time, then the `TouchedWindows`
+    line should show the window that you are touching.
diff --git a/src/tech/input/getevent.md b/src/tech/input/getevent.md
new file mode 100644
index 0000000..5807753
--- /dev/null
+++ b/src/tech/input/getevent.md
@@ -0,0 +1,112 @@
+<!--
+   Copyright 2011 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+# Getevent #
+
+The `getevent` tool runs on the device and provides information about input
+devices and a live dump of kernel input events.
+
+It is very useful tool for ensuring that device drivers are reporing the
+expected set of capabilities for each input device and are generating the
+desired stream of input events.
+
+## Usage ##
+
+### Showing Device Capabilities ###
+
+It is often quite useful to see all of the keys and axes that a device reports.
+Use the `-p` option to do that.
+
+Here is a list of all of the Linux key codes and other events that a
+particular keyboard says it supports.
+
+    $ adb shell su -- getevent -p
+
+      name:     "Motorola Bluetooth Wireless Keyboard"
+      events:
+        KEY (0001): 0001  0002  0003  0004  0005  0006  0007  0008 
+                    0009  000a  000b  000c  000d  000e  000f  0010 
+                    0011  0012  0013  0014  0015  0016  0017  0018 
+                    0019  001a  001b  001c  001d  001e  001f  0020 
+                    0021  0022  0023  0024  0025  0026  0027  0028 
+                    0029  002a  002b  002c  002d  002e  002f  0030 
+                    0031  0032  0033  0034  0035  0036  0037  0038 
+                    0039  003a  003b  003c  003d  003e  003f  0040 
+                    0041  0042  0043  0044  0045  0046  0047  0048 
+                    0049  004a  004b  004c  004d  004e  004f  0050 
+                    0051  0052  0053  0055  0056  0057  0058  0059 
+                    005a  005b  005c  005d  005e  005f  0060  0061 
+                    0062  0063  0064  0066  0067  0068  0069  006a 
+                    006b  006c  006d  006e  006f  0071  0072  0073 
+                    0074  0075  0077  0079  007a  007b  007c  007d 
+                    007e  007f  0080  0081  0082  0083  0084  0085 
+                    0086  0087  0088  0089  008a  008c  008e  0090 
+                    0096  0098  009b  009c  009e  009f  00a1  00a3 
+                    00a4  00a5  00a6  00ab  00ac  00ad  00b0  00b1 
+                    00b2  00b3  00b4  00b7  00b8  00b9  00ba  00bb 
+                    00bc  00bd  00be  00bf  00c0  00c1  00c2  00d9 
+                    00f0  0110  0111  0112  01ba 
+        REL (0002): 0000  0001  0008 
+        ABS (0003): 0028  : value 223, min 0, max 255, fuzz 0, flat 0, resolution 0
+                    0029  : value 0, min 0, max 255, fuzz 0, flat 0, resolution 0
+                    002a  : value 0, min 0, max 255, fuzz 0, flat 0, resolution 0
+                    002b  : value 0, min 0, max 255, fuzz 0, flat 0, resolution 0
+        MSC (0004): 0004 
+        LED (0011): 0000  0001  0002  0003  0004 
+      input props:
+        <none>
+
+The `-i` option shows even more information than `-p`, including HID mapping tables
+and debugging information.
+
+The `-l` option uses textual labels for all event codes, which is handy.
+
+    $ adb shell su -- getevent -lp /dev/input/event1
+
+      name:     "Melfas MMSxxx Touchscreen"
+      events:
+        ABS (0003): ABS_MT_SLOT           : value 0, min 0, max 9, fuzz 0, flat 0, resolution 0
+                    ABS_MT_TOUCH_MAJOR    : value 0, min 0, max 30, fuzz 0, flat 0, resolution 0
+                    ABS_MT_POSITION_X     : value 0, min 0, max 720, fuzz 0, flat 0, resolution 0
+                    ABS_MT_POSITION_Y     : value 0, min 0, max 1280, fuzz 0, flat 0, resolution 0
+                    ABS_MT_TRACKING_ID    : value 0, min 0, max 65535, fuzz 0, flat 0, resolution 0
+                    ABS_MT_PRESSURE       : value 0, min 0, max 255, fuzz 0, flat 0, resolution 0
+      input props:
+        INPUT_PROP_DIRECT
+
+### Showing Live Events ###
+
+This is what a two finger multitouch gesture looks like for a touch screen
+that is using the Linux multitouch input protocol "B".  We use the `-l` option
+to show textual labels and `-t` to show timestamps.
+
+    $ adb shell su -- getevent -lt /dev/input/event1
+
+    [   78826.389007] EV_ABS       ABS_MT_TRACKING_ID   0000001f
+    [   78826.389038] EV_ABS       ABS_MT_PRESSURE      000000ab
+    [   78826.389038] EV_ABS       ABS_MT_POSITION_X    000000ab
+    [   78826.389068] EV_ABS       ABS_MT_POSITION_Y    0000025b
+    [   78826.389068] EV_ABS       ABS_MT_SLOT          00000001
+    [   78826.389068] EV_ABS       ABS_MT_TRACKING_ID   00000020
+    [   78826.389068] EV_ABS       ABS_MT_PRESSURE      000000b9
+    [   78826.389099] EV_ABS       ABS_MT_POSITION_X    0000019e
+    [   78826.389099] EV_ABS       ABS_MT_POSITION_Y    00000361
+    [   78826.389099] EV_SYN       SYN_REPORT           00000000
+    [   78826.468688] EV_ABS       ABS_MT_SLOT          00000000
+    [   78826.468688] EV_ABS       ABS_MT_TRACKING_ID   ffffffff
+    [   78826.468719] EV_ABS       ABS_MT_SLOT          00000001
+    [   78826.468719] EV_ABS       ABS_MT_TRACKING_ID   ffffffff
+    [   78826.468719] EV_SYN       SYN_REPORT           00000000
diff --git a/src/tech/input/index.md b/src/tech/input/index.md
new file mode 100644
index 0000000..e01f200
--- /dev/null
+++ b/src/tech/input/index.md
@@ -0,0 +1,24 @@
+<!--
+   Copyright 2011 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+# Input Technical Information #
+
+The Android input subsystem supports many different device classes,
+including keyboard, joystick, trackball, mouse and touch screen.
+
+The documentation in this section describes how to configure,
+calibrate, test, and write drivers for input devices.
+
diff --git a/src/tech/input/input-device-configuration-files.md b/src/tech/input/input-device-configuration-files.md
new file mode 100644
index 0000000..0a477d0
--- /dev/null
+++ b/src/tech/input/input-device-configuration-files.md
@@ -0,0 +1,152 @@
+<!--
+   Copyright 2011 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+# Input Device Configuration Files #
+
+Input device configuration files (`.idc` files) contain device-specific
+configuration properties that affect the behavior of input devices.
+
+Input device configuration files are typically not necessary for standard
+peripherals such as HID keyboards and mice since the default system behavior
+usually ensures that they will work out of the box.  On the other hand,
+built-in embedded devices, particularly touch screens, almost always
+require input device configuration files to specify their behavior.
+
+## Rationale ##
+
+Android automatically detects and configures most input device capabilities
+based on the event types and properties that are reported by the associated
+Linux kernel input device driver.
+
+For example, if an input device supports the `EV_REL` event type and codes
+`REL_X` and `REL_Y` as well as the `EV_KEY` event type and `BTN_MOUSE`,
+then Android will classify the input device as a mouse.  The default behavior
+for a mouse is to present an on-screen cursor which tracks the mouse's movements
+and simulates touches when the mouse is clicked.  Although the mouse can
+be configured differently, the default behavior is usually sufficient for
+standard mouse peripherals.
+
+Certain classes of input devices are more ambiguous.  For example, multi-touch
+touch screens and touch pads both support the `EV_ABS` event type and codes
+`ABS_MT_POSITION_X` and `ABS_MT_POSITION_Y` at a minimum.  However, the intended
+uses of these devices are quite different and cannot always be determined
+automatically.  Also, additional information is required to make sense of the
+pressure and size information reported by touch devices.  Hence touch devices,
+especially built-in touch screens, usually need IDC files.
+
+## Location ##
+
+Input device configuration files are located by USB vendor, product (and
+optionally version) id or by input device name.
+
+The following paths are consulted in order.
+
+*   `/system/usr/idc/Vendor_XXXX_Product_XXXX_Version_XXXX.idc`
+*   `/system/usr/idc/Vendor_XXXX_Product_XXXX.idc`
+*   `/system/usr/idc/DEVICE_NAME.idc`
+*   `/data/system/devices/idc/Vendor_XXXX_Product_XXXX_Version_XXXX.idc`
+*   `/data/system/devices/idc/Vendor_XXXX_Product_XXXX.idc`
+*   `/data/system/devices/idc/DEVICE_NAME.idc`
+
+When constructing a file path that contains the device name, all characters
+in the device name other than '0'-'9', 'a'-'z', 'A'-'Z', '-' or '_' are replaced by '_'.
+
+## Syntax ##
+
+An input device configuration file is a plain text file consisting of property
+assignments and comments.
+
+### Properties ###
+
+Property assignments each consist of a property name, an `=`, a property value,
+and a new line.  Like this:
+
+    property = value
+
+Property names are non-empty literal text identifiers.  They must not contain
+whitespace.  Each components of the input system defines a set of properties
+that are used to configure its function.
+
+Property values are non-empty string literals, integers or floating point numbers.
+They must not contain whitespace or the reserved characters `\` or `"`.
+
+Property names and values are case-sensitive.
+
+### Comments ###
+
+Comment lines begin with '#' and continue to the end of the line.  Like this:
+
+    # A comment!
+
+Blank lines are ignored.
+
+### Example ###
+
+    # This is an example of an input device configuration file.
+    # It might be used to describe the characteristics of a built-in touch screen.
+
+    # This is an internal device, not an external peripheral attached to the USB
+    # or Bluetooth bus.
+    device.internal = 1
+
+    # The device should behave as a touch screen, which uses the same orientation
+    # as the built-in display.
+    touch.deviceType = touchScreen
+    touch.orientationAware = 1
+
+    # Additional calibration properties...
+    # etc...
+
+## Common Properties ##
+
+The following properties are common to all input device classes.
+
+Refer to the documentation of each input device class for information about the
+special properties used by each class.
+
+#### `device.internal` ####
+
+*Definition:* `device.internal` = `0` | `1`
+
+Specifies whether the input device is an internal built-in component as opposed to an
+externally attached (most likely removable) peripheral.
+
+*   If the value is `0`, the device is external.
+
+*   If the value is `1`, the device is internal.
+
+*   If the value is not specified, the default value is `0` for all devices on the
+    USB (BUS_USB) or Bluetooth (BUS_BLUETOOTH) bus, `1` otherwise.
+
+This property determines default policy decisions regarding wake events.
+
+Internal input devices generally do not wake the display from sleep unless explicitly
+configured to do so in the key layout file or in a hardcoded policy rule.  This
+distinction prevents key presses and touches from spuriously waking up your phone
+when it is in your pocket.  Usually there are only a small handful of wake keys defined.
+
+Conversely, external input devices usually wake the device more aggressively because
+they are assumed to be turned off or not plugged in during transport.  For example,
+pressing any key on an external keyboard is a good indicator that the user wants the
+device to wake up and respond.
+
+It is important to ensure that the value of the `device.internal` property is set
+correctly for all internal input devices.
+
+## Validation ##
+
+Make sure to validate your input device configuration files using the
+[Validate Keymaps](/tech/input/validate-keymaps.html) tool.
diff --git a/src/tech/input/key-character-map-files.md b/src/tech/input/key-character-map-files.md
new file mode 100644
index 0000000..4a9ec34
--- /dev/null
+++ b/src/tech/input/key-character-map-files.md
@@ -0,0 +1,493 @@
+<!--
+   Copyright 2011 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+# Key Character Map Files #
+
+Key character map files (`.kcm` files) are responsible for mapping combinations
+of Android key codes with modifiers to Unicode characters.
+
+Device-specific key layout files are *required* for all internal (built-in)
+input devices that have keys, if only to tell the system that the device
+is special purpose only (not a full keyboard).
+
+Device-specific key layout files are *optional* for external keyboards, and
+often aren't needed at all.  The system provides a generic key character map
+that is suitable for many external keyboards.
+
+If no device-specific key layout file is available, then the system will
+choose a default instead.
+
+## Location ##
+
+Key character map files are located by USB vendor, product (and optionally version)
+id or by input device name.
+
+The following paths are consulted in order.
+
+*   `/system/usr/keychars/Vendor_XXXX_Product_XXXX_Version_XXXX.kcm`
+*   `/system/usr/keychars/Vendor_XXXX_Product_XXXX.kcm`
+*   `/system/usr/keychars/DEVICE_NAME.kcm`
+*   `/data/system/devices/keychars/Vendor_XXXX_Product_XXXX_Version_XXXX.kcm`
+*   `/data/system/devices/keychars/Vendor_XXXX_Product_XXXX.kcm`
+*   `/data/system/devices/keychars/DEVICE_NAME.kcm`
+*   `/system/usr/keychars/Generic.kcm`
+*   `/data/system/devices/keychars/Generic.kcm`
+*   `/system/usr/keychars/Virtual.kcm`
+*   `/data/system/devices/keychars/Virtual.kcm`
+
+When constructing a file path that contains the device name, all characters
+in the device name other than '0'-'9', 'a'-'z', 'A'-'Z', '-' or '_' are replaced by '_'.
+
+## Generic Key Character Map File ##
+
+The system provides a special built-in key character map file called `Generic.kcm`.
+This key character map is intended to support a variety of standard external
+keyboards.
+
+*Do not modify the generic key character map!*
+
+## Virtual Key Character Map File ##
+
+The system provides a special built-in key character map file called `Virtual.kcm`
+that is used by the virtual keyboard devices.
+
+The virtual keyboard device is a synthetic input device whose id is -1
+(see `KeyCharacterMap.VIRTUAL_KEYBOARD`).  It is present on all Android devices
+beginning with Android Honeycomb 3.0.  The purpose of the virtual keyboard device
+is to provide a known built-in input device that can be used for injecting
+keystokes into applications by the IME or by test instrumentation, even
+for devices that do not have built-in keyboards.
+
+The virtual keyboard is assumed to have a full QWERTY layout that is the
+same on all devices.  This makes it possible for applications to inject
+keystrokes using the virtual keyboard device and always get the same results.
+
+*Do not modify the virtual key character map!*
+
+## Syntax ##
+
+A key character map file is a plain text file consisting of a keyboard type
+declaration and a set of key declarations.
+
+### Keyboard Type Declaration ###
+
+A keyboard type declaration describes the overall behavior of the keyboard.
+A character map file must contain a keyboard type declaration.  For clarity,
+it is often placed at the top of the file.
+
+    type FULL
+
+The following keyboard types are recognized:
+
+*   `NUMERIC`: A numeric (12-key) keyboard.
+
+    A numeric keyboard supports text entry using a multi-tap approach.
+    It may be necessary to tap a key multiple times to generate the desired letter or symbol.
+
+    This type of keyboard is generally designed for thumb typing.
+
+    Corresponds to `KeyCharacterMap.NUMERIC`.
+
+*   `PREDICTIVE`: A keyboard with all the letters, but with more than one letter per key.
+
+    This type of keyboard is generally designed for thumb typing.
+
+    Corresponds to `KeyCharacterMap.PREDICTIVE`.
+
+*   `ALPHA`: A keyboard with all the letters, and maybe some numbers.
+
+    An alphabetic keyboard supports text entry directly but may have a condensed
+    layout with a small form factor.  In contrast to a `FULL` keyboard, some
+    symbols may only be accessible using special on-screen character pickers.
+    In addition, to improve typing speed and accuracy, the framework provides
+    special affordances for alphabetic keyboards such as auto-capitalization
+    and toggled / locked SHIFT and ALT keys.
+
+    This type of keyboard is generally designed for thumb typing.
+
+*   `FULL`: A full PC-style keyboard.
+
+    A full keyboard behaves like a PC keyboard.  All symbols are accessed directly
+    by pressing keys on the keyboard without on-screen support or affordances such
+    as auto-capitalization.
+
+    This type of keyboard is generally designed for full two hand typing.
+
+*   `SPECIAL_FUNCTION`: A keyboard that is only used to perform system control functions
+    rather than for typing.
+
+    A special function keyboard consists only of non-printing keys such as
+    HOME and POWER that are not actually used for typing.
+
+The `Generic.kcm` and `Virtual.kcm` key character maps are both `FULL` keyboards.
+
+### Key Declarations ###
+
+Key declarations each consist of the keyword `key` followed by an Android key code
+name, an open curly brace, a set of properties and behaviors and a close curly brace.
+
+    key A {
+        label:                              'A'
+        base:                               'a'
+        shift, capslock:                    'A'
+        ctrl, alt, meta:                    none
+    }
+
+#### Properties ####
+
+Each key property establishes a mapping from a key to a behavior.  To make the
+key character map files more compact, several properties can be mapped to the
+same behavior by separating them with a comma.
+
+In the above example, the `label` property is assigned the `'A'` behavior.
+Likewise, the `ctrl`, `alt` and `meta` properties are all simultaneously assigned
+the `none` behavior.
+
+The following properties are recognized:
+
+*   `label`: Specifies the label that is physically printed on the key, when it
+    consists of a single character.  This is the value that is returned by
+    the `KeyCharacterMap.getDisplayLabel` method.
+
+*   `number`: Specifies the behavior (character that should be typed) when a numeric
+    text view has focus, such as when the user is typing a phone number.
+
+    Compact keyboards often combine multiple symbols into a single key, such that
+    the same key might be used to type `'1'` and `'a'` or `'#'` and `'q'`, perhaps.
+    For these keys, the `number` property should be set to indicate which symbol
+    should be typed in a numeric context, if any.
+
+    Some typical "numeric" symbols are digits `'0'` through `'9'`, `'#'`, `'+'`,
+    `'('`, `')'`, `','`, and `'.'`.
+
+*   `base`: Specifies the behavior (character that should be typed) when no modifiers
+    are pressed.
+
+*   &lt;modifier&gt; or &lt;modifier1&gt;`+`&lt;modifier2&gt;`+`...: Specifies the
+    behavior (character that should be typed) when the key is pressed and all of the
+    specified modifiers are active.
+
+    For example, the modifier property `shift` specifies a behavior that applies when
+    the either the LEFT SHIFT or RIGHT SHIFT modifier is pressed.
+
+    Similarly, the modifier property `rshift+ralt` specifies a behavior that applies
+    when the both RIGHT SHIFT and RIGHT ALT modifiers are pressed together.
+
+The following modifiers are recognized in modifier properties:
+
+*   `shift`: Applies when either the LEFT SHIFT or RIGHT SHIFT modifier is pressed.
+*   `lshift`: Applies when the LEFT SHIFT modifier is pressed.
+*   `rshift`: Applies when the RIGHT SHIFT modifier is pressed.
+*   `alt`: Applies when either the LEFT ALT or RIGHT ALT modifier is pressed.
+*   `lalt`: Applies when the LEFT ALT modifier is pressed.
+*   `ralt`: Applies when the RIGHT ALT modifier is pressed.
+*   `ctrl`: Applies when either the LEFT CONTROL or RIGHT CONTROL modifier is pressed.
+*   `lctrl`: Applies when the LEFT CONTROL modifier is pressed.
+*   `rctrl`: Applies when the RIGHT CONTROL modifier is pressed.
+*   `meta`: Applies when either the LEFT META or RIGHT META modifier is pressed.
+*   `lmeta`: Applies when the LEFT META modifier is pressed.
+*   `rmeta`: Applies when the RIGHT META modifier is pressed.
+*   `sym`: Applies when the SYMBOL modifier is pressed.
+*   `fn`: Applies when the FUNCTION modifier is pressed.
+*   `capslock`: Applies when the CAPS LOCK modifier is locked.
+*   `numlock`: Applies when the NUM LOCK modifier is locked.
+*   `scrolllock`: Applies when the SCROLL LOCK modifier is locked.
+
+The order in which the properties are listed is significant.  When mapping a key to
+a behavior, the system scans all relevant properties in order and returns the last
+applicable behavior that it found.
+
+Consequently, properties that are specified later override properties that are
+specified earlier for a given key.
+
+#### Behaviors ####
+
+Each property maps to a behavior.  The most common behavior is typing a character
+but there are others.
+
+The following behaviors are recognized:
+
+*   `none`: Don't type a character.
+
+    This behavior is the default when no character is specified.  Specifying `none`
+    is optional but it improves clarity.
+
+*   `'X'`: Type the specified character literal.
+
+    This behavior causes the specified character to be entered into the focused
+    text view.  The character literal may be any ASCII character, or one of the
+    following escape sequences:
+
+    *   `'\\'`: Type a backslash character.
+    *   `'\n'`: Type a new line character (use this for ENTER / RETURN).
+    *   `'\t'`: Type a TAB character.
+    *   `'\''`: Type an apostrophe character.
+    *   `'\"'`: Type a quote character.
+    *   `'\uXXXX'`: Type the Unicode character whose code point is given in hex by XXXX.
+
+*   `fallback` &lt;Android key code name&gt;: Perform a default action if the key is not
+    handled by the application.
+
+    This behavior causes the system to simulate a different key press when an application
+    does not handle the specified key natively.  It is used to support default behavior
+    for new keys that not all applications know how to handle, such as ESCAPE or
+    numeric keypad keys (when numlock is not pressed).
+
+    When a fallback behavior is performed, the application will receive two key presses:
+    one for the original key and another for the fallback key that was selected.
+    If the application handles the original key during key up, then the fallback key
+    event will be canceled (`KeyEvent.isCanceled` will return `true`).
+
+The system reserves two Unicode characters to perform special functions:
+
+*   `'\uef00'`: When this behavior is performed, the text view consumes and removes the
+    four characters preceding the cursor, interprets them as hex digits, and inserts the
+    corresponding Unicode code point.
+
+*   `'\uef01'`: When this behavior is performed, the text view displays a
+    character picker dialog that contains miscellaneous symbols.
+
+The system recognizes the following Unicode characters as combining diacritical dead
+key characters:
+
+*   `'\u0300'`: Grave accent.
+*   `'\u0301'`: Acute accent.
+*   `'\u0302'`: Circumflex accent.
+*   `'\u0303'`: Tilde accent.
+*   `'\u0308'`: Umlaut accent.
+
+When a dead key is typed followed by another character, the dead key and the following
+characters are composed.  For example, when the user types a grave accent dead
+key followed by the letter 'a', the result is '&agrave;'.
+
+Refer to `KeyCharacterMap.getDeadChar` for more information about dead key handling.
+
+### Comments ###
+
+Comment lines begin with '#' and continue to the end of the line.  Like this:
+
+    # A comment!
+
+Blank lines are ignored.
+
+### How Key Combinations are Mapped to Behaviors ###
+
+When the user presses a key, the system looks up the behavior associated with
+the combination of that key press and the currently pressed modifiers.
+
+#### SHIFT + A ####
+
+Suppose the user pressed A and SHIFT together.  The system first locates
+the set of properties and behaviors associated with `KEYCODE_A`.
+
+    key A {
+        label:                              'A'
+        base:                               'a'
+        shift, capslock:                    'A'
+        ctrl, alt, meta:                    none
+    }
+
+The system scans the properties from first to last and left to right, ignoring
+the `label` and `number` properties, which are special.
+
+The first property encountered is `base`.  The `base` property always applies to
+a key, no matter what modifiers are pressed.  It essentially specifies the default
+behavior for the key unless it is overridden by following properties.
+Since the `base` property applies to this key press, the system makes note
+of the fact that its behavior is `'a'` (type the character `a`).
+
+The system then continues to scan subsequent properties in case any of them
+are more specific than `base` and override it.  It encounters `shift` which
+also applies to the key press SHIFT + A.  So the system decides to ignore
+the `base` property's behavior and chooses the behavior associated with
+the `shift` property, which is `'A'` (type the character `A`).
+
+It then continues to scan the table, however no other properties apply to this
+key press (CAPS LOCK is not locked, neither CONTROL key is pressed, neither
+ALT key is pressed and neither META key is pressed).
+
+So the resulting behavior for the key combination SHIFT + A is `'A'`.
+
+#### CONTROL + A ####
+
+Now consider what would happen if the user pressed A and CONTROL together.
+
+As before, the system would scan the table of properties.  It would notice
+that the `base` property applied but would also continue scanning until
+it eventually reached the `control` property.  As it happens, the `control`
+property appears after `base` so its behavior overrides the `base` behavior.
+
+So the resulting behavior for the key combination CONTROL + A is `none`.
+
+#### ESCAPE ####
+
+Now suppose the user pressed ESCAPE.
+
+    key ESCAPE {
+        base:                               fallback BACK
+        alt, meta:                          fallback HOME
+        ctrl:                               fallback MENU
+    }
+
+This time the system obtains the behavior `fallback BACK`, a fallback behavior.
+Because no character literal appears, no character will be typed.
+
+When processing the key, the system will first deliver `KEYCODE_ESCAPE` to the
+application.  If the application does not handle it, then the system will try
+again but this time it will deliver `KEYCODE_BACK` to the application as
+requested by the fallback behavior.
+
+So applications that recognize and support `KEYCODE_ESCAPE` have the
+opportunity to handle it as is, but other applications that do not can instead
+perform the fallback action of treating the key as if it were `KEYCODE_BACK`.
+
+#### NUMPAD_0 with or without NUM LOCK ####
+
+The numeric keypad keys have very different interpretations depending on whether
+the NUM LOCK key is locked.
+
+The following key declaration ensures that `KEYCODE_NUMPAD_0` types `0`
+when NUM LOCK is pressed.  When NUM LOCK is not pressed, the key is delivered
+to the application as usual, and if it is not handled, then the fallback
+key `KEYCODE_INSERT` is delivered instead.
+
+    key NUMPAD_0 {
+        label, number:                      '0'
+        base:                               fallback INSERT
+        numlock:                            '0'
+        ctrl, alt, meta:                    none
+    }
+
+As we can see, fallback key declarations greatly improve compatibility
+with older applications that do not recognize or directly support all of the keys
+that are present on a full PC style keyboard.
+
+### Examples ###
+
+#### Full Keyboard ####
+
+    # This is an example of part of a key character map file for a full keyboard
+    # include a few fallback behaviors for special keys that few applications
+    # handle themselves.
+
+    type FULL
+
+    key C {
+        label:                              'C'
+        base:                               'c'
+        shift, capslock:                    'C'
+        alt:                                '\u00e7'
+        shift+alt:                          '\u00c7'
+        ctrl, meta:                         none
+    }
+    
+    key SPACE {
+        label:                              ' '
+        base:                               ' '
+        ctrl:                               none
+        alt, meta:                          fallback SEARCH
+    }
+    
+    key NUMPAD_9 {
+        label, number:                      '9'
+        base:                               fallback PAGE_UP
+        numlock:                            '9'
+        ctrl, alt, meta:                    none
+    }
+
+#### Alphanumeric Keyboard ####
+
+    # This is an example of part of a key character map file for an alphanumeric
+    # thumb keyboard.  Some keys are combined, such as `A` and `2`.  Here we
+    # specify `number` labels to tell the system what to do when the user is
+    # typing a number into a dial pad.
+    #
+    # Also note the special character '\uef01' mapped to ALT+SPACE.
+    # Pressing this combination of keys invokes an on-screen character picker.
+
+    type ALPHA
+    
+    key A {
+        label:                              'A'
+        number:                             '2'
+        base:                               'a'
+        shift, capslock:                    'A'
+        alt:                                '#'
+        shift+alt, capslock+alt:            none
+    }
+
+    key SPACE {
+        label:                              ' '
+        number:                             ' '
+        base:                               ' '
+        shift:                              ' '
+        alt:                                '\uef01'
+        shift+alt:                          '\uef01'
+    }
+
+#### Game Pad ####
+
+    # This is an example of part of a key character map file for a game pad.
+    # It defines fallback actions that enable the user to navigate the user interface
+    # by pressing buttons.
+
+    type SPECIAL_FUNCTION
+
+    key BUTTON_A {
+        base:                               fallback BACK
+    }
+
+    key BUTTON_X {
+        base:                               fallback DPAD_CENTER
+    }
+
+    key BUTTON_START {
+        base:                               fallback HOME
+    }
+
+    key BUTTON_SELECT {
+        base:                               fallback MENU
+    }
+
+## Compatibility Note ##
+
+Prior to Android Honeycomb 3.0, the Android key character map was specified
+using a very different syntax and was compiled into a binary file format
+(`.kcm.bin`) at build time.
+
+Although the new format uses the same extension `.kcm`, the syntax is quite
+different (and much more powerful).
+
+As of Android Honeycomb 3.0, all Android key character map files must use
+the new syntax and plain text file format that is described in this document.
+The old syntax is not supported and the old `.kcm.bin` files are not recognized
+by the system.
+
+## Language Note ##
+
+Android does not currently support multilingual keyboards.  Moreover, the
+built-in generic key character map assumes a US English keyboard layout.
+
+OEMs are encouraged to provide custom key character maps for their keyboards
+if they are designed for other languages.
+
+Future versions of Android may provide better support for multilingual keyboards
+or user-selectable keyboard layouts.
+
+## Validation ##
+
+Make sure to validate your key character map files using the
+[Validate Keymaps](/tech/input/validate-keymaps.html) tool.
diff --git a/src/tech/input/key-layout-files.md b/src/tech/input/key-layout-files.md
new file mode 100644
index 0000000..9a2760d
--- /dev/null
+++ b/src/tech/input/key-layout-files.md
@@ -0,0 +1,332 @@
+<!--
+   Copyright 2011 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+# Key Layout Files #
+
+Key layout files (`.kl` files) are responsible for mapping Linux key codes
+and axis codes to Android key codes and axis codes and specifying associated
+policy flags.
+
+Device-specific key layout files are *required* for all internal (built-in)
+input devices that have keys, including special keys such as volume, power
+and headset media keys.
+
+Device-specific key layout files are *optional* for other input devices but
+they are *recommended* for special-purpose keyboards and joysticks.
+
+If no device-specific key layout file is available, then the system will
+choose a default instead.
+
+## Location ##
+
+Key layout files are located by USB vendor, product (and optionally version)
+id or by input device name.
+
+The following paths are consulted in order.
+
+*   `/system/usr/keylayout/Vendor_XXXX_Product_XXXX_Version_XXXX.kl`
+*   `/system/usr/keylayout/Vendor_XXXX_Product_XXXX.kl`
+*   `/system/usr/keylayout/DEVICE_NAME.kl`
+*   `/data/system/devices/keylayout/Vendor_XXXX_Product_XXXX_Version_XXXX.kl`
+*   `/data/system/devices/keylayout/Vendor_XXXX_Product_XXXX.kl`
+*   `/data/system/devices/keylayout/DEVICE_NAME.kl`
+*   `/system/usr/keylayout/Generic.kl`
+*   `/data/system/devices/keylayout/Generic.kl`
+
+When constructing a file path that contains the device name, all characters
+in the device name other than '0'-'9', 'a'-'z', 'A'-'Z', '-' or '_' are replaced by '_'.
+
+## Generic Key Layout File ##
+
+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!*
+
+## Syntax ##
+
+A key layout file is a plain text file consisting of key or axis declarations
+and flags.
+
+### Key Declarations ###
+
+Key declarations each consist of the keyword `key` followed by a Linux key code
+number, an Android key code name, and optional set of whitespace delimited policy flags.
+
+    key 1     ESCAPE
+    key 114   VOLUME_DOWN       WAKE
+    key 16    Q                 VIRTUAL     WAKE
+
+The following policy flags are recognized:
+
+*   `WAKE`: The key should wake the device when it is asleep.  For historical reasons,
+    this flag behaves in the same manner as `WAKE_DROPPED` below.
+*   `WAKE_DROPPED`: The key should wake the device when it is asleep but the key itself
+    should be dropped when the wake-up occurs.  In a sense, the key's action was to
+    wake the device, but the key itself is not processed.
+*   `SHIFT`: The key should be interpreted as if the SHIFT key were also pressed.
+*   `CAPS_LOCK`: The key should be interpreted as if the CAPS LOCK key were also pressed.
+*   `ALT`: The key should be interpreted as if the ALT key were also pressed.
+*   `ALT_GR`: The key should be interpreted as if the RIGHT ALT key were also pressed.
+*   `FUNCTION`: The key should be interpreted as if the FUNCTION key were also pressed.
+*   `VIRTUAL`: The key is a virtual soft key (capacitive button) that is adjacent to
+    the main touch screen.  This causes special debouncing logic to be enabled, see below.
+*   `MENU`: Deprecated.  Do not use.
+*   `LAUNCHER`: Deprecated.  Do not use.
+
+### Axis Declarations ###
+
+Axis declarations each consist of the keyword `axis` followed by a Linux axis code
+number, and qualifiers that control the behavior of the axis including at least
+one Android axis code name.
+
+#### Basic Axes ####
+
+A basic axis simply maps a Linux axis code to an Android axis code name.
+
+The following declaration maps `ABS_X` (indicated by `0x00`) to `AXIS_X` (indicated by `X`).
+
+    axis 0x00 X
+
+In the above example, if the value of `ABS_X` is `5` then `AXIS_X` will be set to `5`.
+
+#### Split Axes ####
+
+A split axis maps a Linux axis code to two Android axis code names, such that
+values less than or greater than a threshold are split across two different axes when
+mapped.  This mapping is useful when a single physical axis reported by the device
+encodes two different mutually exclusive logical axes.
+
+The following declaration maps values of the `ABS_Y` axis (indicated by `0x01`) to
+`AXIS_GAS` when less than `0x7f` or to `AXIS_BRAKE` when greater than `0x7f`.
+
+    axis 0x01 split 0x7f GAS BRAKE
+
+In the above example, if the value of `ABS_Y` is `0x7d` then `AXIS_GAS` is set
+to `2` (`0x7f - 0x7d`) and `AXIS_BRAKE` is set to `0`.  Conversely, if the value of
+`ABS_Y` is `0x83` then `AXIS_GAS` is set to `0` and `AXIS_BRAKE` is set to `4`
+(`0x83 - 0x7f`).  Finally, if the value of `ABS_Y` equals the split value of `0x7f`
+then both `AXIS_GAS` and `AXIS_BRAKE` are set to `0`.
+
+#### Inverted Axes ####
+
+An inverted axis inverts the sign of the axis value.
+
+The following declaration maps `ABS_RZ` (indicated by `0x05`) to `AXIS_BRAKE`
+(indicated by `BRAKE`), and inverts the output by negating it.
+
+    axis 0x05 invert AXIS_RZ
+
+In the above example, if the value of `ABS_RZ` is `2` then `AXIS_RZ` is set to `-2`.
+
+#### Center Flat Position Option ####
+
+The Linux input protocol provides a way for input device drivers to specify the
+center flat position of joystick axes but not all of them do and some of them
+provide incorrect values.
+
+The center flat position is the neutral position of the axis, such as when
+a directional pad is in the very middle of its range and the user is not
+touching it.
+
+To resolve this issue, an axis declaration may be followed by a `flat`
+option that specifies the value of the center flat position for the axis.
+
+    axis 0x03 Z flat 4096
+
+In the above example, the center flat position is set to `4096`.
+
+### Comments ###
+
+Comment lines begin with '#' and continue to the end of the line.  Like this:
+
+    # A comment!
+
+Blank lines are ignored.
+
+### Examples ###
+
+#### Keyboard ####
+
+    # This is an example of a key layout file for a keyboard.
+
+    key 1     ESCAPE
+    key 2     1
+    key 3     2
+    key 4     3
+    key 5     4
+    key 6     5
+    key 7     6
+    key 8     7
+    key 9     8
+    key 10    9
+    key 11    0
+    key 12    MINUS
+    key 13    EQUALS
+    key 14    DEL
+
+    # etc...
+
+#### System Controls ####
+
+    # This is an example of a key layout file for basic system controls, such as
+    # volume and power keys which are typically implemented as GPIO pins that
+    # the device decodes into key presses.
+
+    key 114   VOLUME_DOWN       WAKE
+    key 115   VOLUME_UP         WAKE
+    key 116   POWER             WAKE
+
+#### Capacitive Buttons ####
+
+    # This is an example of a key layout file for a touch device with capacitive buttons.
+
+    key 139    MENU           VIRTUAL
+    key 102    HOME           VIRTUAL
+    key 158    BACK           VIRTUAL
+    key 217    SEARCH         VIRTUAL
+
+#### Headset Jack Media Controls ####
+
+    # This is an example of a key layout file for headset mounted media controls.
+    # A typical headset jack interface might have special control wires or detect known
+    # resistive loads as corresponding to media functions or volume controls.
+    # This file assumes that the driver decodes these signals and reports media
+    # controls as key presses.
+
+    key 163   MEDIA_NEXT        WAKE
+    key 165   MEDIA_PREVIOUS    WAKE
+    key 226   HEADSETHOOK       WAKE
+
+#### Joystick ####
+
+    # This is an example of a key layout file for a joystick.
+
+    # These are the buttons that the joystick supports, represented as keys.
+    key 304   BUTTON_A
+    key 305   BUTTON_B
+    key 307   BUTTON_X
+    key 308   BUTTON_Y
+    key 310   BUTTON_L1
+    key 311   BUTTON_R1
+    key 314   BUTTON_SELECT
+    key 315   BUTTON_START
+    key 316   BUTTON_MODE
+    key 317   BUTTON_THUMBL
+    key 318   BUTTON_THUMBR
+
+    # Left and right stick.
+    # The reported value for flat is 128 out of a range from -32767 to 32768, which is absurd.
+    # This confuses applications that rely on the flat value because the joystick actually
+    # settles in a flat range of +/- 4096 or so.  We override it here.
+    axis 0x00 X flat 4096
+    axis 0x01 Y flat 4096
+    axis 0x03 Z flat 4096
+    axis 0x04 RZ flat 4096
+
+    # Triggers.
+    axis 0x02 LTRIGGER
+    axis 0x05 RTRIGGER
+
+    # Hat.
+    axis 0x10 HAT_X
+    axis 0x11 HAT_Y
+
+## Wake Keys ##
+
+Wake keys are special keys that wake the device from sleep, such as the power key.
+
+By default, for internal keyboard devices, no key is a wake key.  For external
+keyboard device, all keys are wake keys.
+
+To make a key be a wake key, set the `WAKE_DROPPED` flag in the key layout file
+for the keyboard device.
+
+Note that the `WindowManagerPolicy` component is responsible for implementing wake
+key behavior.  Moreover, the key guard may prevent certain keys from functioning
+as wake keys.  A good place to start understanding wake key behavior is
+`PhoneWindowManager.interceptKeyBeforeQueueing`.
+
+## Virtual Soft Keys ##
+
+The input system provides special features for implementing virtual soft keys.
+
+There are three cases:
+
+1.  If the virtual soft keys are displayed graphically on the screen, as on the
+    Galaxy Nexus, then they are implemented by the Navigation Bar component in
+    the System UI package.
+
+    Because graphical virtual soft keys are implemented at a high layer in the
+    system, key layout files are not involved and the following information does
+    not apply.
+
+2.  If the virtual soft keys are implemented as an extended touchable region
+    that is part of the main touch screen, as on the Nexus One, then the
+    input system uses a virtual key map file to translate X / Y touch coordinates
+    into Linux key codes, then uses the key layout file to translate
+    Linux key codes into Android key codes.
+
+    Refer to the section on [Touch Devices](/tech/input/touch-devices.html)
+    for more details about virtual key map files.
+
+    The key layout file for the touch screen input device must specify the
+    appropriate key mapping and include the `VIRTUAL` flag for each key.
+
+3.  If the virtual soft keys are implemented as capacitive buttons that are
+    separate from the main touch screen, as on the Nexus S, then the kernel
+    device driver or firmware is responsible for translating touches into
+    Linux key codes which the input system then translates into Android
+    key codes using the key layout file.
+
+    The key layout file for the capacitive button input device must specify the
+    appropriate key mapping and include the `VIRTUAL` flag for each key.
+
+When virtual soft key are located within or in close physical proximity of the
+touch screen, it is easy for the user to accidentally press one of the buttons
+when touching near the bottom of the screen or when sliding a finger from top
+to bottom or from bottom to top on the screen.
+
+To prevent this from happening, the input system applies a little debouncing
+such that virtual soft key presses are ignored for a brief period of time
+after the most recent touch on the touch screen.  The delay is called the
+virtual key quiet time.
+
+To enable virtual soft key debouncing, we must do two things.
+
+First, we provide a key layout file for the touch screen or capacitive button
+input device with the `VIRTUAL` flag set for each key.
+
+    key 139    MENU           VIRTUAL
+    key 102    HOME           VIRTUAL
+    key 158    BACK           VIRTUAL
+    key 217    SEARCH         VIRTUAL
+
+Then, we set the value of the virtual key quiet time in a resource overlay
+for the framework `config.xml` resource.
+
+    <!-- Specifies the amount of time to disable virtual keys after the screen is touched
+         in order to filter out accidental virtual key presses due to swiping gestures
+         or taps near the edge of the display.  May be 0 to disable the feature.
+         It is recommended that this value be no more than 250 ms.
+         This feature should be disabled for most devices. -->
+    <integer name="config_virtualKeyQuietTimeMillis">250</integer>
+
+## Validation ##
+
+Make sure to validate your key layout files using the
+[Validate Keymaps](/tech/input/validate-keymaps.html) tool.
diff --git a/src/tech/input/keyboard-devices.md b/src/tech/input/keyboard-devices.md
new file mode 100644
index 0000000..76564d9
--- /dev/null
+++ b/src/tech/input/keyboard-devices.md
@@ -0,0 +1,1002 @@
+<!--
+   Copyright 2011 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+# Keyboard Devices #
+
+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 decribes 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 `0` through `0xff` or `KEY_OK` through `KEY_MAX`.
+
+*   The input device reports the presence of any Linux key codes used on joysticks
+    and gamepads including `BTN_0` through `BTN_9`, `BTN_TRIGGER` through `BTN_DEAD`,
+    or `BTN_A` through `BTN_THUMBR`.
+
+Joysticks are currently classified as keyboards because joystick and gamepad buttons
+are reported by `EV_KEY` events 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](/tech/input/joystick-devices.html) 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 `Configuration`
+    object 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 `Configuration`
+    object as `NAVIGATION_DPAD`.
+
+*   If the input device has any keys that are mapped to `KEYCODE_BUTTON_A`
+    or 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_KEY` to report key presses, using a value
+    of `0` to indicate that a key is released, a value of `1` to indicate that
+    a key is pressed, and a value greater than or equal to `2` to 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_MSC` with `MSC_SCANCODE` and 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_LED` is written
+    to the device.  The `hid-input` driver 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_KEY` events with a value of `0` for 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 `EventHub` reads raw events from the `evdev` driver and maps Linux key codes
+    (sometimes referred to as scan codes) into Android key codes using the
+    keyboard's key layout map.
+
+2.  The `InputReader` consumes 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_ON` and `META_SHIFT_ON` bits accordingly.
+
+3.  The `InputReader` notifies the `InputDispatcher` about the key event.
+
+4.  The `InputDispatcher` asks the `WindowManagerPolicy` what 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 `EventHub` effectively holds a wake lock
+    along this critical path to ensure that it will run to completion.
+
+5.  If an `InputFilter` is currently in use, the `InputDispatcher` gives it a
+    chance to consume or transform the key.  The `InputFilter` may be used to implement
+    low-level system-wide accessibility policies.
+
+6.  The `InputDispatcher` enqueues the key for processing on the dispatch thread.
+
+7.  When the `InputDispatcher` dequeues the key, it gives the `WindowManagerPolicy`
+    a second chance to intercept the key event by calling
+    `WindowManagerPolicy.interceptKeyBeforeDispatching`.  This method handles system
+    shortcuts and other functions.
+
+8.  The `InputDispatcher` then identifies the key event target (the focused window)
+    and waits for them to become ready.  Then, the `InputDispatcher` delivers 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 `InputDispatcher` as to whether the key
+    event was consumed.  If the event was not consumed, the `InputDispatcher`
+    calls `WindowManagerPolicy.dispatchUnhandledKey` to 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_BACK` instead.
+
+## Keyboard Configuration ##
+
+Keyboard behavior is determined by the keyboard's key layout, key character
+map and input device configuration.
+
+Refer to the following sections for more details about the files that
+participate in keyboard configuration:
+
+*   [Key Layout Files](/tech/input/key-layout-files.html)
+*   [Key Character Map Files](/tech/input/key-character-map-files.html)
+*   [Input Device Configuration Files](/tech/input/input-device-configuration-files.html)
+
+### Properties ###
+
+The following input device configuration properties are used for keyboards.
+
+#### `keyboard.layout` ####
+
+*Definition:* `keyboard.layout` = &lt;name&gt;
+
+Specifies the name of the key layout file associated with the input device,
+excluding the `.kl` extension.  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` = &lt;name&gt;
+
+Specifies the name of the key character map file associated with the input device,
+excluding the `.kcm` extension.  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_UP` is
+remapped to produce `KEYCODE_DPAD_RIGHT` since 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 `1` if the device name ends with `-keypad`, `0` otherwise.
+
+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 `0` for the built-in keyboard is important for maintaining
+compatibility with the `KeyCharacterMap.BUILT_IN_KEYBOARD` field, 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 `qwerty` instead 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-input`
+driver 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_KEY` events 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.KeyEvent`
+instance 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 tables show how HID usages, Linux key codes and Android
+key codes are related to one another.
+
+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 table.
+
+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.kl` to
+    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 `HOME` key.  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.
+
+### HID Keyboard and Keypad Page (0x07) ###
+
+| HID Usage   | HID Usage Name                   | LKC    | Linux Key Code Name              | Version | AKC    | Android Key Code Name            | Notes |
+| ----------- | -------------------------------- | ------ | -------------------------------- | ------- | ------ | -------------------------------- | ----- |
+| 0x07 0x0001 | Keyboard Error Roll Over         |        |                                  |         |        |                                  |       |
+| 0x07 0x0002 | Keyboard POST Fail               |        |                                  |         |        |                                  |       |
+| 0x07 0x0003 | Keyboard Error Undefined         |        |                                  |         |        |                                  |       |
+| 0x07 0x0004 | Keyboard a and A                 | 0x001e | KEY_A                            | 1.6     | 0x001d | KEYCODE_A                        | 1     |
+| 0x07 0x0005 | Keyboard b and B                 | 0x0030 | KEY_B                            | 1.6     | 0x001e | KEYCODE_B                        | 1     |
+| 0x07 0x0006 | Keyboard c and C                 | 0x002e | KEY_C                            | 1.6     | 0x001f | KEYCODE_C                        | 1     |
+| 0x07 0x0007 | Keyboard d and D                 | 0x0020 | KEY_D                            | 1.6     | 0x0020 | KEYCODE_D                        | 1     |
+| 0x07 0x0008 | Keyboard e and E                 | 0x0012 | KEY_E                            | 1.6     | 0x0021 | KEYCODE_E                        | 1     |
+| 0x07 0x0009 | Keyboard f and F                 | 0x0021 | KEY_F                            | 1.6     | 0x0022 | KEYCODE_F                        | 1     |
+| 0x07 0x000a | Keyboard g and G                 | 0x0022 | KEY_G                            | 1.6     | 0x0023 | KEYCODE_G                        | 1     |
+| 0x07 0x000b | Keyboard h and H                 | 0x0023 | KEY_H                            | 1.6     | 0x0024 | KEYCODE_H                        | 1     |
+| 0x07 0x000c | Keyboard i and I                 | 0x0017 | KEY_I                            | 1.6     | 0x0025 | KEYCODE_I                        | 1     |
+| 0x07 0x000d | Keyboard j and J                 | 0x0024 | KEY_J                            | 1.6     | 0x0026 | KEYCODE_J                        | 1     |
+| 0x07 0x000e | Keyboard k and K                 | 0x0025 | KEY_K                            | 1.6     | 0x0027 | KEYCODE_K                        | 1     |
+| 0x07 0x000f | Keyboard l and L                 | 0x0026 | KEY_L                            | 1.6     | 0x0028 | KEYCODE_L                        | 1     |
+| 0x07 0x0010 | Keyboard m and M                 | 0x0032 | KEY_M                            | 1.6     | 0x0029 | KEYCODE_M                        | 1     |
+| 0x07 0x0011 | Keyboard n and N                 | 0x0031 | KEY_N                            | 1.6     | 0x002a | KEYCODE_N                        | 1     |
+| 0x07 0x0012 | Keyboard o and O                 | 0x0018 | KEY_O                            | 1.6     | 0x002b | KEYCODE_O                        | 1     |
+| 0x07 0x0013 | Keyboard p and P                 | 0x0019 | KEY_P                            | 1.6     | 0x002c | KEYCODE_P                        | 1     |
+| 0x07 0x0014 | Keyboard q and Q                 | 0x0010 | KEY_Q                            | 1.6     | 0x002d | KEYCODE_Q                        | 1     |
+| 0x07 0x0015 | Keyboard r and R                 | 0x0013 | KEY_R                            | 1.6     | 0x002e | KEYCODE_R                        | 1     |
+| 0x07 0x0016 | Keyboard s and S                 | 0x001f | KEY_S                            | 1.6     | 0x002f | KEYCODE_S                        | 1     |
+| 0x07 0x0017 | Keyboard t and T                 | 0x0014 | KEY_T                            | 1.6     | 0x0030 | KEYCODE_T                        | 1     |
+| 0x07 0x0018 | Keyboard u and U                 | 0x0016 | KEY_U                            | 1.6     | 0x0031 | KEYCODE_U                        | 1     |
+| 0x07 0x0019 | Keyboard v and V                 | 0x002f | KEY_V                            | 1.6     | 0x0032 | KEYCODE_V                        | 1     |
+| 0x07 0x001a | Keyboard w and W                 | 0x0011 | KEY_W                            | 1.6     | 0x0033 | KEYCODE_W                        | 1     |
+| 0x07 0x001b | Keyboard x and X                 | 0x002d | KEY_X                            | 1.6     | 0x0034 | KEYCODE_X                        | 1     |
+| 0x07 0x001c | Keyboard y and Y                 | 0x0015 | KEY_Y                            | 1.6     | 0x0035 | KEYCODE_Y                        | 1     |
+| 0x07 0x001d | Keyboard z and Z                 | 0x002c | KEY_Z                            | 1.6     | 0x0036 | KEYCODE_Z                        | 1     |
+| 0x07 0x001e | Keyboard 1 and !                 | 0x0002 | KEY_1                            | 1.6     | 0x0008 | KEYCODE_1                        | 1     |
+| 0x07 0x001f | Keyboard 2 and @                 | 0x0003 | KEY_2                            | 1.6     | 0x0009 | KEYCODE_2                        | 1     |
+| 0x07 0x0020 | Keyboard 3 and #                 | 0x0004 | KEY_3                            | 1.6     | 0x000a | KEYCODE_3                        | 1     |
+| 0x07 0x0021 | Keyboard 4 and $                 | 0x0005 | KEY_4                            | 1.6     | 0x000b | KEYCODE_4                        | 1     |
+| 0x07 0x0022 | Keyboard 5 and %                 | 0x0006 | KEY_5                            | 1.6     | 0x000c | KEYCODE_5                        | 1     |
+| 0x07 0x0023 | Keyboard 6 and ^                 | 0x0007 | KEY_6                            | 1.6     | 0x000d | KEYCODE_6                        | 1     |
+| 0x07 0x0024 | Keyboard 7 and &                 | 0x0008 | KEY_7                            | 1.6     | 0x000e | KEYCODE_7                        | 1     |
+| 0x07 0x0025 | Keyboard 8 and *                 | 0x0009 | KEY_8                            | 1.6     | 0x000f | KEYCODE_8                        | 1     |
+| 0x07 0x0026 | Keyboard 9 and (                 | 0x000a | KEY_9                            | 1.6     | 0x0010 | KEYCODE_9                        | 1     |
+| 0x07 0x0027 | Keyboard 0 and )                 | 0x000b | KEY_0                            | 1.6     | 0x0007 | KEYCODE_0                        | 1     |
+| 0x07 0x0028 | Keyboard Return (ENTER)          | 0x001c | KEY_ENTER                        | 1.6     | 0x0042 | KEYCODE_ENTER                    | 1     |
+| 0x07 0x0029 | Keyboard ESCAPE                  | 0x0001 | KEY_ESC                          | 3.0     | 0x006f | KEYCODE_ESCAPE                   |       |
+| ""          | ""                               | ""     | ""                               | 2.3     | 0x0004 | KEYCODE_BACK                     |       |
+| 0x07 0x002a | Keyboard DELETE (Backspace)      | 0x000e | KEY_BACKSPACE                    | 1.6     | 0x0043 | KEYCODE_DEL                      |       |
+| 0x07 0x002b | Keyboard Tab                     | 0x000f | KEY_TAB                          | 1.6     | 0x003d | KEYCODE_TAB                      |       |
+| 0x07 0x002c | Keyboard Spacebar                | 0x0039 | KEY_SPACE                        | 1.6     | 0x003e | KEYCODE_SPACE                    |       |
+| 0x07 0x002d | Keyboard - and _                 | 0x000c | KEY_MINUS                        | 1.6     | 0x0045 | KEYCODE_MINUS                    | 1     |
+| 0x07 0x002e | Keyboard = and +                 | 0x000d | KEY_EQUAL                        | 1.6     | 0x0046 | KEYCODE_EQUALS                   | 1     |
+| 0x07 0x002f | Keyboard \[ and \{               | 0x001a | KEY_LEFTBRACE                    | 1.6     | 0x0047 | KEYCODE_LEFT_BRACKET             | 1     |
+| 0x07 0x0030 | Keyboard \] and \}               | 0x001b | KEY_RIGHTBRACE                   | 1.6     | 0x0048 | KEYCODE_RIGHT_BRACKET            | 1     |
+| 0x07 0x0031 | Keyboard \\ and &#124;           | 0x002b | KEY_BACKSLASH                    | 1.6     | 0x0049 | KEYCODE_BACKSLASH                | 1     |
+| 0x07 0x0032 | Keyboard Non-US # and ~          | 0x002b | KEY_BACKSLASH                    | 1.6     | 0x0049 | KEYCODE_BACKSLASH                | 1     |
+| 0x07 0x0033 | Keyboard ; and :                 | 0x0027 | KEY_SEMICOLON                    | 1.6     | 0x004a | KEYCODE_SEMICOLON                | 1     |
+| 0x07 0x0034 | Keyboard ' and "                 | 0x0028 | KEY_APOSTROPHE                   | 1.6     | 0x004b | KEYCODE_APOSTROPHE               | 1     |
+| 0x07 0x0035 | Keyboard \` and ~                | 0x0029 | KEY_GRAVE                        | 3.0     | 0x0044 | KEYCODE_GRAVE                    | 1     |
+| 0x07 0x0036 | Keyboard , and <                 | 0x0033 | KEY_COMMA                        | 1.6     | 0x0037 | KEYCODE_COMMA                    | 1     |
+| 0x07 0x0037 | Keyboard . and >                 | 0x0034 | KEY_DOT                          | 1.6     | 0x0038 | KEYCODE_PERIOD                   | 1     |
+| 0x07 0x0038 | Keyboard / and ?                 | 0x0035 | KEY_SLASH                        | 1.6     | 0x004c | KEYCODE_SLASH                    | 1     |
+| 0x07 0x0039 | Keyboard Caps Lock               | 0x003a | KEY_CAPSLOCK                     | 3.0     | 0x0073 | KEYCODE_CAPS_LOCK                |       |
+| 0x07 0x003a | Keyboard F1                      | 0x003b | KEY_F1                           | 3.0     | 0x0083 | KEYCODE_F1                       |       |
+| ""          | ""                               | ""     | ""                               | 1.6     | 0x0052 | KEYCODE_MENU                     |       |
+| 0x07 0x003b | Keyboard F2                      | 0x003c | KEY_F2                           | 3.0     | 0x0084 | KEYCODE_F2                       |       |
+| ""          | ""                               | ""     | ""                               | 1.6     | 0x0002 | KEYCODE_SOFT_RIGHT               |       |
+| 0x07 0x003c | Keyboard F3                      | 0x003d | KEY_F3                           | 3.0     | 0x0085 | KEYCODE_F3                       |       |
+| ""          | ""                               | ""     | ""                               | 1.6     | 0x0005 | KEYCODE_CALL                     |       |
+| 0x07 0x003d | Keyboard F4                      | 0x003e | KEY_F4                           | 3.0     | 0x0086 | KEYCODE_F4                       |       |
+| ""          | ""                               | ""     | ""                               | 1.6     | 0x0006 | KEYCODE_ENDCALL                  |       |
+| 0x07 0x003e | Keyboard F5                      | 0x003f | KEY_F5                           | 3.0     | 0x0087 | KEYCODE_F5                       |       |
+| 0x07 0x003f | Keyboard F6                      | 0x0040 | KEY_F6                           | 3.0     | 0x0088 | KEYCODE_F6                       |       |
+| 0x07 0x0040 | Keyboard F7                      | 0x0041 | KEY_F7                           | 3.0     | 0x0089 | KEYCODE_F7                       |       |
+| 0x07 0x0041 | Keyboard F8                      | 0x0042 | KEY_F8                           | 3.0     | 0x008a | KEYCODE_F8                       |       |
+| 0x07 0x0042 | Keyboard F9                      | 0x0043 | KEY_F9                           | 3.0     | 0x008b | KEYCODE_F9                       |       |
+| 0x07 0x0043 | Keyboard F10                     | 0x0044 | KEY_F10                          | 3.0     | 0x008c | KEYCODE_F10                      |       |
+| ""          | ""                               | ""     | ""                               | 2.3     | 0x0052 | KEYCODE_MENU                     |       |
+| 0x07 0x0044 | Keyboard F11                     | 0x0057 | KEY_F11                          | 3.0     | 0x008d | KEYCODE_F11                      |       |
+| 0x07 0x0045 | Keyboard F12                     | 0x0058 | KEY_F12                          | 3.0     | 0x008e | KEYCODE_F12                      |       |
+| 0x07 0x0046 | Keyboard Print Screen            | 0x0063 | KEY_SYSRQ                        | 3.0     | 0x0078 | KEYCODE_SYSRQ                    |       |
+| 0x07 0x0047 | Keyboard Scroll Lock             | 0x0046 | KEY_SCROLLLOCK                   | 3.0     | 0x0074 | KEYCODE_SCROLL_LOCK              |       |
+| 0x07 0x0048 | Keyboard Pause                   | 0x0077 | KEY_PAUSE                        | 3.0     | 0x0079 | KEYCODE_BREAK                    |       |
+| 0x07 0x0049 | Keyboard Insert                  | 0x006e | KEY_INSERT                       | 3.0     | 0x007c | KEYCODE_INSERT                   |       |
+| 0x07 0x004a | Keyboard Home                    | 0x0066 | KEY_HOME                         | 3.0     | 0x007a | KEYCODE_MOVE_HOME                |       |
+| ""          | ""                               | ""     | ""                               | 1.6     | 0x0003 | KEYCODE_HOME                     |       |
+| 0x07 0x004b | Keyboard Page Up                 | 0x0068 | KEY_PAGEUP                       | 3.0     | 0x005c | KEYCODE_PAGE_UP                  |       |
+| 0x07 0x004c | Keyboard Delete Forward          | 0x006f | KEY_DELETE                       | 3.0     | 0x0070 | KEYCODE_FORWARD_DEL              |       |
+| 0x07 0x004d | Keyboard End                     | 0x006b | KEY_END                          | 3.0     | 0x007b | KEYCODE_MOVE_END                 |       |
+| ""          | ""                               | ""     | ""                               | 1.6     | 0x0006 | KEYCODE_ENDCALL                  |       |
+| 0x07 0x004e | Keyboard Page Down               | 0x006d | KEY_PAGEDOWN                     | 3.0     | 0x005d | KEYCODE_PAGE_DOWN                |       |
+| 0x07 0x004f | Keyboard Right Arrow             | 0x006a | KEY_RIGHT                        | 1.6     | 0x0016 | KEYCODE_DPAD_RIGHT               |       |
+| 0x07 0x0050 | Keyboard Left Arrow              | 0x0069 | KEY_LEFT                         | 1.6     | 0x0015 | KEYCODE_DPAD_LEFT                |       |
+| 0x07 0x0051 | Keyboard Down Arrow              | 0x006c | KEY_DOWN                         | 1.6     | 0x0014 | KEYCODE_DPAD_DOWN                |       |
+| 0x07 0x0052 | Keyboard Up Arrow                | 0x0067 | KEY_UP                           | 1.6     | 0x0013 | KEYCODE_DPAD_UP                  |       |
+| 0x07 0x0053 | Keyboard Num Lock and Clear      | 0x0045 | KEY_NUMLOCK                      | 3.0     | 0x008f | KEYCODE_NUM_LOCK                 |       |
+| 0x07 0x0054 | Keypad /                         | 0x0062 | KEY_KPSLASH                      | 3.0     | 0x009a | KEYCODE_NUMPAD_DIVIDE            |       |
+| 0x07 0x0055 | Keypad *                         | 0x0037 | KEY_KPASTERISK                   | 3.0     | 0x009b | KEYCODE_NUMPAD_MULTIPLY          |       |
+| 0x07 0x0056 | Keypad -                         | 0x004a | KEY_KPMINUS                      | 3.0     | 0x009c | KEYCODE_NUMPAD_SUBTRACT          |       |
+| 0x07 0x0057 | Keypad +                         | 0x004e | KEY_KPPLUS                       | 3.0     | 0x009d | KEYCODE_NUMPAD_ADD               |       |
+| 0x07 0x0058 | Keypad ENTER                     | 0x0060 | KEY_KPENTER                      | 3.0     | 0x00a0 | KEYCODE_NUMPAD_ENTER             |       |
+| 0x07 0x0059 | Keypad 1 and End                 | 0x004f | KEY_KP1                          | 3.0     | 0x0091 | KEYCODE_NUMPAD_1                 |       |
+| 0x07 0x005a | Keypad 2 and Down Arrow          | 0x0050 | KEY_KP2                          | 3.0     | 0x0092 | KEYCODE_NUMPAD_2                 |       |
+| 0x07 0x005b | Keypad 3 and PageDn              | 0x0051 | KEY_KP3                          | 3.0     | 0x0093 | KEYCODE_NUMPAD_3                 |       |
+| 0x07 0x005c | Keypad 4 and Left Arrow          | 0x004b | KEY_KP4                          | 3.0     | 0x0094 | KEYCODE_NUMPAD_4                 |       |
+| 0x07 0x005d | Keypad 5                         | 0x004c | KEY_KP5                          | 3.0     | 0x0095 | KEYCODE_NUMPAD_5                 |       |
+| 0x07 0x005e | Keypad 6 and Right Arrow         | 0x004d | KEY_KP6                          | 3.0     | 0x0096 | KEYCODE_NUMPAD_6                 |       |
+| 0x07 0x005f | Keypad 7 and Home                | 0x0047 | KEY_KP7                          | 3.0     | 0x0097 | KEYCODE_NUMPAD_7                 |       |
+| 0x07 0x0060 | Keypad 8 and Up Arrow            | 0x0048 | KEY_KP8                          | 3.0     | 0x0098 | KEYCODE_NUMPAD_8                 |       |
+| 0x07 0x0061 | Keypad 9 and Page Up             | 0x0049 | KEY_KP9                          | 3.0     | 0x0099 | KEYCODE_NUMPAD_9                 |       |
+| 0x07 0x0062 | Keypad 0 and Insert              | 0x0052 | KEY_KP0                          | 3.0     | 0x0090 | KEYCODE_NUMPAD_0                 |       |
+| 0x07 0x0063 | Keypad . and Delete              | 0x0053 | KEY_KPDOT                        | 3.0     | 0x009e | KEYCODE_NUMPAD_DOT               |       |
+| 0x07 0x0064 | Keyboard Non-US \\ and &#124;    | 0x0056 | KEY_102ND                        | 4.0     | 0x0049 | KEYCODE_BACKSLASH                | 1     |
+| 0x07 0x0065 | Keyboard Application             | 0x007f | KEY_COMPOSE                      | 3.0     | 0x0052 | KEYCODE_MENU                     |       |
+| ""          | ""                               | ""     | ""                               | 1.6     | 0x0054 | KEYCODE_SEARCH                   |       |
+| 0x07 0x0066 | Keyboard Power                   | 0x0074 | KEY_POWER                        | 1.6     | 0x001a | KEYCODE_POWER                    |       |
+| 0x07 0x0067 | Keypad =                         | 0x0075 | KEY_KPEQUAL                      | 3.0     | 0x00a1 | KEYCODE_NUMPAD_EQUALS            |       |
+| 0x07 0x0068 | Keyboard F13                     | 0x00b7 | KEY_F13                          |         |        |                                  |       |
+| 0x07 0x0069 | Keyboard F14                     | 0x00b8 | KEY_F14                          |         |        |                                  |       |
+| 0x07 0x006a | Keyboard F15                     | 0x00b9 | KEY_F15                          |         |        |                                  |       |
+| 0x07 0x006b | Keyboard F16                     | 0x00ba | KEY_F16                          |         |        |                                  |       |
+| 0x07 0x006c | Keyboard F17                     | 0x00bb | KEY_F17                          |         |        |                                  |       |
+| 0x07 0x006d | Keyboard F18                     | 0x00bc | KEY_F18                          |         |        |                                  |       |
+| 0x07 0x006e | Keyboard F19                     | 0x00bd | KEY_F19                          |         |        |                                  |       |
+| 0x07 0x006f | Keyboard F20                     | 0x00be | KEY_F20                          |         |        |                                  |       |
+| 0x07 0x0070 | Keyboard F21                     | 0x00bf | KEY_F21                          |         |        |                                  |       |
+| 0x07 0x0071 | Keyboard F22                     | 0x00c0 | KEY_F22                          |         |        |                                  |       |
+| 0x07 0x0072 | Keyboard F23                     | 0x00c1 | KEY_F23                          |         |        |                                  |       |
+| 0x07 0x0073 | Keyboard F24                     | 0x00c2 | KEY_F24                          |         |        |                                  |       |
+| 0x07 0x0074 | Keyboard Execute                 | 0x0086 | KEY_OPEN                         |         |        |                                  |       |
+| 0x07 0x0075 | Keyboard Help                    | 0x008a | KEY_HELP                         |         |        |                                  |       |
+| 0x07 0x0076 | Keyboard Menu                    | 0x0082 | KEY_PROPS                        |         |        |                                  |       |
+| 0x07 0x0077 | Keyboard Select                  | 0x0084 | KEY_FRONT                        |         |        |                                  |       |
+| 0x07 0x0078 | Keyboard Stop                    | 0x0080 | KEY_STOP                         | 3.0     | 0x0056 | KEYCODE_MEDIA_STOP               |       |
+| 0x07 0x0079 | Keyboard Again                   | 0x0081 | KEY_AGAIN                        |         |        |                                  |       |
+| 0x07 0x007a | Keyboard Undo                    | 0x0083 | KEY_UNDO                         |         |        |                                  |       |
+| 0x07 0x007b | Keyboard Cut                     | 0x0089 | KEY_CUT                          |         |        |                                  |       |
+| 0x07 0x007c | Keyboard Copy                    | 0x0085 | KEY_COPY                         |         |        |                                  |       |
+| 0x07 0x007d | Keyboard Paste                   | 0x0087 | KEY_PASTE                        |         |        |                                  |       |
+| 0x07 0x007e | Keyboard Find                    | 0x0088 | KEY_FIND                         |         |        |                                  |       |
+| 0x07 0x007f | Keyboard Mute                    | 0x0071 | KEY_MUTE                         | 3.0     | 0x00a4 | KEYCODE_VOLUME_MUTE              |       |
+| 0x07 0x0080 | Keyboard Volume Up               | 0x0073 | KEY_VOLUMEUP                     | 1.6     | 0x0018 | KEYCODE_VOLUME_UP                |       |
+| 0x07 0x0081 | Keyboard Volume Down             | 0x0072 | KEY_VOLUMEDOWN                   | 1.6     | 0x0019 | KEYCODE_VOLUME_DOWN              |       |
+| 0x07 0x0082 | Keyboard Locking Caps Lock       |        |                                  |         |        |                                  |       |
+| 0x07 0x0083 | Keyboard Locking Num Lock        |        |                                  |         |        |                                  |       |
+| 0x07 0x0084 | Keyboard Locking Scroll Lock     |        |                                  |         |        |                                  |       |
+| 0x07 0x0085 | Keypad Comma                     | 0x0079 | KEY_KPCOMMA                      | 3.0     | 0x009f | KEYCODE_NUMPAD_COMMA             |       |
+| 0x07 0x0086 | Keypad Equal Sign                |        |                                  |         |        |                                  |       |
+| 0x07 0x0087 | Keyboard International1          | 0x0059 | KEY_RO                           |         |        |                                  |       |
+| 0x07 0x0088 | Keyboard International2          | 0x005d | KEY_KATAKANAHIRAGANA             |         |        |                                  |       |
+| 0x07 0x0089 | Keyboard International3          | 0x007c | KEY_YEN                          |         |        |                                  |       |
+| 0x07 0x008a | Keyboard International4          | 0x005c | KEY_HENKAN                       |         |        |                                  |       |
+| 0x07 0x008b | Keyboard International5          | 0x005e | KEY_MUHENKAN                     |         |        |                                  |       |
+| 0x07 0x008c | Keyboard International6          | 0x005f | KEY_KPJPCOMMA                    |         |        |                                  |       |
+| 0x07 0x008d | Keyboard International7          |        |                                  |         |        |                                  |       |
+| 0x07 0x008e | Keyboard International8          |        |                                  |         |        |                                  |       |
+| 0x07 0x008f | Keyboard International9          |        |                                  |         |        |                                  |       |
+| 0x07 0x0090 | Keyboard LANG1                   | 0x007a | KEY_HANGEUL                      |         |        |                                  |       |
+| 0x07 0x0091 | Keyboard LANG2                   | 0x007b | KEY_HANJA                        |         |        |                                  |       |
+| 0x07 0x0092 | Keyboard LANG3                   | 0x005a | KEY_KATAKANA                     |         |        |                                  |       |
+| 0x07 0x0093 | Keyboard LANG4                   | 0x005b | KEY_HIRAGANA                     |         |        |                                  |       |
+| 0x07 0x0094 | Keyboard LANG5                   | 0x0055 | KEY_ZENKAKUHANKAKU               |         |        |                                  |       |
+| 0x07 0x0095 | Keyboard LANG6                   |        |                                  |         |        |                                  |       |
+| 0x07 0x0096 | Keyboard LANG7                   |        |                                  |         |        |                                  |       |
+| 0x07 0x0097 | Keyboard LANG8                   |        |                                  |         |        |                                  |       |
+| 0x07 0x0098 | Keyboard LANG9                   |        |                                  |         |        |                                  |       |
+| 0x07 0x0099 | Keyboard Alternate Erase         |        |                                  |         |        |                                  |       |
+| 0x07 0x009a | Keyboard SysReq/Attention        |        |                                  |         |        |                                  |       |
+| 0x07 0x009b | Keyboard Cancel                  |        |                                  |         |        |                                  |       |
+| 0x07 0x009c | Keyboard Clear                   |        |                                  |         |        |                                  |       |
+| 0x07 0x009d | Keyboard Prior                   |        |                                  |         |        |                                  |       |
+| 0x07 0x009e | Keyboard Return                  |        |                                  |         |        |                                  |       |
+| 0x07 0x009f | Keyboard Separator               |        |                                  |         |        |                                  |       |
+| 0x07 0x00a0 | Keyboard Out                     |        |                                  |         |        |                                  |       |
+| 0x07 0x00a1 | Keyboard Oper                    |        |                                  |         |        |                                  |       |
+| 0x07 0x00a2 | Keyboard Clear/Again             |        |                                  |         |        |                                  |       |
+| 0x07 0x00a3 | Keyboard CrSel/Props             |        |                                  |         |        |                                  |       |
+| 0x07 0x00a4 | Keyboard ExSel                   |        |                                  |         |        |                                  |       |
+| 0x07 0x00b0 | Keypad 00                        |        |                                  |         |        |                                  |       |
+| 0x07 0x00b1 | Keypad 000                       |        |                                  |         |        |                                  |       |
+| 0x07 0x00b2 | Thousands Separator              |        |                                  |         |        |                                  |       |
+| 0x07 0x00b3 | Decimal Separator                |        |                                  |         |        |                                  |       |
+| 0x07 0x00b4 | Currency Unit                    |        |                                  |         |        |                                  |       |
+| 0x07 0x00b5 | Currency Sub-unit                |        |                                  |         |        |                                  |       |
+| 0x07 0x00b6 | Keypad (                         | 0x00b3 | KEY_KPLEFTPAREN                  | 3.0     | 0x00a2 | KEYCODE_NUMPAD_LEFT_PAREN        |       |
+| 0x07 0x00b7 | Keypad )                         | 0x00b4 | KEY_KPRIGHTPAREN                 | 3.0     | 0x00a3 | KEYCODE_NUMPAD_RIGHT_PAREN       |       |
+| 0x07 0x00b8 | Keypad \{                        |        |                                  |         |        |                                  |       |
+| 0x07 0x00b9 | Keypad \}                        |        |                                  |         |        |                                  |       |
+| 0x07 0x00ba | Keypad Tab                       |        |                                  |         |        |                                  |       |
+| 0x07 0x00bb | Keypad Backspace                 |        |                                  |         |        |                                  |       |
+| 0x07 0x00bc | Keypad A                         |        |                                  |         |        |                                  |       |
+| 0x07 0x00bd | Keypad B                         |        |                                  |         |        |                                  |       |
+| 0x07 0x00be | Keypad C                         |        |                                  |         |        |                                  |       |
+| 0x07 0x00bf | Keypad D                         |        |                                  |         |        |                                  |       |
+| 0x07 0x00c0 | Keypad E                         |        |                                  |         |        |                                  |       |
+| 0x07 0x00c1 | Keypad F                         |        |                                  |         |        |                                  |       |
+| 0x07 0x00c2 | Keypad XOR                       |        |                                  |         |        |                                  |       |
+| 0x07 0x00c3 | Keypad ^                         |        |                                  |         |        |                                  |       |
+| 0x07 0x00c4 | Keypad %                         |        |                                  |         |        |                                  |       |
+| 0x07 0x00c5 | Keypad <                         |        |                                  |         |        |                                  |       |
+| 0x07 0x00c6 | Keypad >                         |        |                                  |         |        |                                  |       |
+| 0x07 0x00c7 | Keypad &                         |        |                                  |         |        |                                  |       |
+| 0x07 0x00c8 | Keypad &&                        |        |                                  |         |        |                                  |       |
+| 0x07 0x00c9 | Keypad &#124;                    |        |                                  |         |        |                                  |       |
+| 0x07 0x00ca | Keypad &#124;&#124;              |        |                                  |         |        |                                  |       |
+| 0x07 0x00cb | Keypad :                         |        |                                  |         |        |                                  |       |
+| 0x07 0x00cc | Keypad #                         |        |                                  |         |        |                                  |       |
+| 0x07 0x00cd | Keypad Space                     |        |                                  |         |        |                                  |       |
+| 0x07 0x00ce | Keypad @                         |        |                                  |         |        |                                  |       |
+| 0x07 0x00cf | Keypad !                         |        |                                  |         |        |                                  |       |
+| 0x07 0x00d0 | Keypad Memory Store              |        |                                  |         |        |                                  |       |
+| 0x07 0x00d1 | Keypad Memory Recall             |        |                                  |         |        |                                  |       |
+| 0x07 0x00d2 | Keypad Memory Clear              |        |                                  |         |        |                                  |       |
+| 0x07 0x00d3 | Keypad Memory Add                |        |                                  |         |        |                                  |       |
+| 0x07 0x00d4 | Keypad Memory Subtract           |        |                                  |         |        |                                  |       |
+| 0x07 0x00d5 | Keypad Memory Multiply           |        |                                  |         |        |                                  |       |
+| 0x07 0x00d6 | Keypad Memory Divide             |        |                                  |         |        |                                  |       |
+| 0x07 0x00d7 | Keypad +/-                       |        |                                  |         |        |                                  |       |
+| 0x07 0x00d8 | Keypad Clear                     |        |                                  |         |        |                                  |       |
+| 0x07 0x00d9 | Keypad Clear Entry               |        |                                  |         |        |                                  |       |
+| 0x07 0x00da | Keypad Binary                    |        |                                  |         |        |                                  |       |
+| 0x07 0x00db | Keypad Octal                     |        |                                  |         |        |                                  |       |
+| 0x07 0x00dc | Keypad Decimal                   |        |                                  |         |        |                                  |       |
+| 0x07 0x00dd | Keypad Hexadecimal               |        |                                  |         |        |                                  |       |
+| 0x07 0x00e0 | Keyboard Left Control            | 0x001d | KEY_LEFTCTRL                     | 3.0     | 0x0071 | KEYCODE_CTRL_LEFT                |       |
+| 0x07 0x00e1 | Keyboard Left Shift              | 0x002a | KEY_LEFTSHIFT                    | 1.6     | 0x003b | KEYCODE_SHIFT_LEFT               |       |
+| 0x07 0x00e2 | Keyboard Left Alt                | 0x0038 | KEY_LEFTALT                      | 1.6     | 0x0039 | KEYCODE_ALT_LEFT                 |       |
+| 0x07 0x00e3 | Keyboard Left GUI                | 0x007d | KEY_LEFTMETA                     | 3.0     | 0x0075 | KEYCODE_META_LEFT                |       |
+| 0x07 0x00e4 | Keyboard Right Control           | 0x0061 | KEY_RIGHTCTRL                    | 3.0     | 0x0072 | KEYCODE_CTRL_RIGHT               |       |
+| 0x07 0x00e5 | Keyboard Right Shift             | 0x0036 | KEY_RIGHTSHIFT                   | 1.6     | 0x003c | KEYCODE_SHIFT_RIGHT              |       |
+| 0x07 0x00e6 | Keyboard Right Alt               | 0x0064 | KEY_RIGHTALT                     | 1.6     | 0x003a | KEYCODE_ALT_RIGHT                |       |
+| 0x07 0x00e7 | Keyboard Right GUI               | 0x007e | KEY_RIGHTMETA                    | 3.0     | 0x0076 | KEYCODE_META_RIGHT               |       |
+| 0x07 0x00e8 |                                  | 0x00a4 | KEY_PLAYPAUSE                    | 3.0     | 0x0055 | KEYCODE_MEDIA_PLAY_PAUSE         |       |
+| 0x07 0x00e9 |                                  | 0x00a6 | KEY_STOPCD                       | 3.0     | 0x0056 | KEYCODE_MEDIA_STOP               |       |
+| 0x07 0x00ea |                                  | 0x00a5 | KEY_PREVIOUSSONG                 | 3.0     | 0x0058 | KEYCODE_MEDIA_PREVIOUS           |       |
+| 0x07 0x00eb |                                  | 0x00a3 | KEY_NEXTSONG                     | 3.0     | 0x0057 | KEYCODE_MEDIA_NEXT               |       |
+| 0x07 0x00ec |                                  | 0x00a1 | KEY_EJECTCD                      | 3.0     | 0x0081 | KEYCODE_MEDIA_EJECT              |       |
+| 0x07 0x00ed |                                  | 0x0073 | KEY_VOLUMEUP                     | 1.6     | 0x0018 | KEYCODE_VOLUME_UP                |       |
+| 0x07 0x00ee |                                  | 0x0072 | KEY_VOLUMEDOWN                   | 1.6     | 0x0019 | KEYCODE_VOLUME_DOWN              |       |
+| 0x07 0x00ef |                                  | 0x0071 | KEY_MUTE                         | 3.0     | 0x00a4 | KEYCODE_VOLUME_MUTE              |       |
+| 0x07 0x00f0 |                                  | 0x0096 | KEY_WWW                          | 1.6     | 0x0040 | KEYCODE_EXPLORER                 |       |
+| 0x07 0x00f1 |                                  | 0x009e | KEY_BACK                         | 1.6     | 0x0004 | KEYCODE_BACK                     |       |
+| 0x07 0x00f2 |                                  | 0x009f | KEY_FORWARD                      | 3.0     | 0x007d | KEYCODE_FORWARD                  |       |
+| 0x07 0x00f3 |                                  | 0x0080 | KEY_STOP                         | 3.0     | 0x0056 | KEYCODE_MEDIA_STOP               |       |
+| 0x07 0x00f4 |                                  | 0x0088 | KEY_FIND                         |         |        |                                  |       |
+| 0x07 0x00f5 |                                  | 0x00b1 | KEY_SCROLLUP                     | 3.0     | 0x005c | KEYCODE_PAGE_UP                  |       |
+| 0x07 0x00f6 |                                  | 0x00b2 | KEY_SCROLLDOWN                   | 3.0     | 0x005d | KEYCODE_PAGE_DOWN                |       |
+| 0x07 0x00f7 |                                  | 0x00b0 | KEY_EDIT                         |         |        |                                  |       |
+| 0x07 0x00f8 |                                  | 0x008e | KEY_SLEEP                        |         |        |                                  |       |
+| 0x07 0x00f9 |                                  | 0x0098 | KEY_COFFEE                       | 4.0     | 0x001a | KEYCODE_POWER                    |       |
+| 0x07 0x00fa |                                  | 0x00ad | KEY_REFRESH                      |         |        |                                  |       |
+| 0x07 0x00fb |                                  | 0x008c | KEY_CALC                         |         |        |                                  |       |
+
+### HID Generic Desktop Page (0x01) ###
+
+| HID Usage   | HID Usage Name                   | LKC    | Linux Key Code Name              | Version | AKC    | Android Key Code Name            | Notes |
+| ----------- | -------------------------------- | ------ | -------------------------------- | ------- | ------ | -------------------------------- | ----- |
+| 0x01 0x0081 | System Power Down                | 0x0074 | KEY_POWER                        | 1.6     | 0x001a | KEYCODE_POWER                    |       |
+| 0x01 0x0082 | System Sleep                     | 0x008e | KEY_SLEEP                        | 4.0     | 0x001a | KEYCODE_POWER                    |       |
+| 0x01 0x0083 | System Wake Up                   | 0x008f | KEY_WAKEUP                       | 4.0     | 0x001a | KEYCODE_POWER                    |       |
+| 0x01 0x0084 | System Context Menu              |        |                                  |         |        |                                  |       |
+| 0x01 0x0085 | System Main Menu                 |        |                                  |         |        |                                  |       |
+| 0x01 0x0086 | System App Menu                  |        |                                  |         |        |                                  |       |
+| 0x01 0x0087 | System Menu Help                 |        |                                  |         |        |                                  |       |
+| 0x01 0x0088 | System Menu Exit                 |        |                                  |         |        |                                  |       |
+| 0x01 0x0089 | System Menu Select               |        |                                  |         |        |                                  |       |
+| 0x01 0x008a | System Menu Right                |        |                                  |         |        |                                  |       |
+| 0x01 0x008b | System Menu Left                 |        |                                  |         |        |                                  |       |
+| 0x01 0x008c | System Menu Up                   |        |                                  |         |        |                                  |       |
+| 0x01 0x008d | System Menu Down                 |        |                                  |         |        |                                  |       |
+| 0x01 0x008e | System Cold Restart              |        |                                  |         |        |                                  |       |
+| 0x01 0x008f | System Warm Restart              |        |                                  |         |        |                                  |       |
+| 0x01 0x00a0 | System Dock                      |        |                                  |         |        |                                  |       |
+| 0x01 0x00a1 | System Undock                    |        |                                  |         |        |                                  |       |
+| 0x01 0x00a2 | System Setup                     |        |                                  |         |        |                                  |       |
+| 0x01 0x00a3 | System Break                     |        |                                  |         |        |                                  |       |
+| 0x01 0x00a4 | System Debugger Break            |        |                                  |         |        |                                  |       |
+| 0x01 0x00a5 | Application Break                |        |                                  |         |        |                                  |       |
+| 0x01 0x00a6 | Application Debugger Break       |        |                                  |         |        |                                  |       |
+| 0x01 0x00a7 | System Speaker Mute              |        |                                  |         |        |                                  |       |
+| 0x01 0x00a8 | System Hibernate                 |        |                                  |         |        |                                  |       |
+| 0x01 0x00b0 | System Display Invert            |        |                                  |         |        |                                  |       |
+| 0x01 0x00b1 | System Display Internal          |        |                                  |         |        |                                  |       |
+| 0x01 0x00b2 | System Display External          |        |                                  |         |        |                                  |       |
+| 0x01 0x00b3 | System Display Both              |        |                                  |         |        |                                  |       |
+| 0x01 0x00b4 | System Display Dual              |        |                                  |         |        |                                  |       |
+| 0x01 0x00b5 | System Display Toggle Int/Ext    |        |                                  |         |        |                                  |       |
+| 0x01 0x00b6 | System Display Swap Prim./Sec.   |        |                                  |         |        |                                  |       |
+| 0x01 0x00b7 | System Display LCD Autoscale     |        |                                  |         |        |                                  |       |
+
+### HID Consumer Page (0x0c) ###
+
+| HID Usage   | HID Usage Name                   | LKC    | Linux Key Code Name              | Version | AKC    | Android Key Code Name            | Notes |
+| ----------- | -------------------------------- | ------ | -------------------------------- | ------- | ------ | -------------------------------- | ----- |
+| 0x0c 0x0030 | Power                            |        |                                  |         |        |                                  |       |
+| 0x0c 0x0031 | Reset                            |        |                                  |         |        |                                  |       |
+| 0x0c 0x0032 | Sleep                            |        |                                  |         |        |                                  |       |
+| 0x0c 0x0033 | Sleep After                      |        |                                  |         |        |                                  |       |
+| 0x0c 0x0034 | Sleep Mode                       | 0x008e | KEY_SLEEP                        | 4.0     | 0x001a | KEYCODE_POWER                    |       |
+| 0x0c 0x0040 | Menu                             | 0x008b | KEY_MENU                         | 1.6     | 0x0052 | KEYCODE_MENU                     |       |
+| 0x0c 0x0041 | Menu Pick                        |        |                                  |         |        |                                  |       |
+| 0x0c 0x0042 | Menu Up                          |        |                                  |         |        |                                  |       |
+| 0x0c 0x0043 | Menu Down                        |        |                                  |         |        |                                  |       |
+| 0x0c 0x0044 | Menu Left                        |        |                                  |         |        |                                  |       |
+| 0x0c 0x0045 | Menu Right                       | 0x0181 | KEY_RADIO                        |         |        |                                  |       |
+| 0x0c 0x0046 | Menu Escape                      |        |                                  |         |        |                                  |       |
+| 0x0c 0x0047 | Menu Value Increase              |        |                                  |         |        |                                  |       |
+| 0x0c 0x0048 | Menu Value Decrease              |        |                                  |         |        |                                  |       |
+| 0x0c 0x0081 | Assign Selection                 |        |                                  |         |        |                                  |       |
+| 0x0c 0x0082 | Mode Step                        |        |                                  |         |        |                                  |       |
+| 0x0c 0x0083 | Recall Last                      | 0x0195 | KEY_LAST                         |         |        |                                  |       |
+| 0x0c 0x0084 | Enter Channel                    |        |                                  |         |        |                                  |       |
+| 0x0c 0x0085 | Order Movie                      |        |                                  |         |        |                                  |       |
+| 0x0c 0x0088 | Media Select Computer            | 0x0178 | KEY_PC                           |         |        |                                  |       |
+| 0x0c 0x0089 | Media Select TV                  | 0x0179 | KEY_TV                           | 3.0     | 0x00aa | KEYCODE_TV                       |       |
+| 0x0c 0x008a | Media Select WWW                 | 0x0096 | KEY_WWW                          | 1.6     | 0x0040 | KEYCODE_EXPLORER                 |       |
+| 0x0c 0x008b | Media Select DVD                 | 0x0185 | KEY_DVD                          |         |        |                                  |       |
+| 0x0c 0x008c | Media Select Telephone           | 0x00a9 | KEY_PHONE                        | 3.0     | 0x0005 | KEYCODE_CALL                     |       |
+| 0x0c 0x008d | Media Select Program Guide       | 0x016a | KEY_PROGRAM                      | 3.0     | 0x00ac | KEYCODE_GUIDE                    |       |
+| 0x0c 0x008e | Media Select Video Phone         | 0x01a0 | KEY_VIDEOPHONE                   |         |        |                                  |       |
+| 0x0c 0x008f | Media Select Games               | 0x01a1 | KEY_GAMES                        |         |        |                                  |       |
+| 0x0c 0x0090 | Media Select Messages            | 0x018c | KEY_MEMO                         |         |        |                                  |       |
+| 0x0c 0x0091 | Media Select CD                  | 0x017f | KEY_CD                           |         |        |                                  |       |
+| 0x0c 0x0092 | Media Select VCR                 | 0x017b | KEY_VCR                          |         |        |                                  |       |
+| 0x0c 0x0093 | Media Select Tuner               | 0x0182 | KEY_TUNER                        |         |        |                                  |       |
+| 0x0c 0x0094 | Quit                             | 0x00ae | KEY_EXIT                         |         |        |                                  |       |
+| 0x0c 0x0095 | Help                             | 0x008a | KEY_HELP                         |         |        |                                  |       |
+| 0x0c 0x0096 | Media Select Tape                | 0x0180 | KEY_TAPE                         |         |        |                                  |       |
+| 0x0c 0x0097 | Media Select Cable               | 0x017a | KEY_TV2                          |         |        |                                  |       |
+| 0x0c 0x0098 | Media Select Satellite           | 0x017d | KEY_SAT                          |         |        |                                  |       |
+| 0x0c 0x0099 | Media Select Security            |        |                                  |         |        |                                  |       |
+| 0x0c 0x009a | Media Select Home                | 0x016e | KEY_PVR                          | 3.0     | 0x00ad | KEYCODE_DVR                      |       |
+| 0x0c 0x009c | Channel Increment                | 0x0192 | KEY_CHANNELUP                    | 3.0     | 0x00a6 | KEYCODE_CHANNEL_UP               |       |
+| 0x0c 0x009d | Channel Decrement                | 0x0193 | KEY_CHANNELDOWN                  | 3.0     | 0x00a7 | KEYCODE_CHANNEL_DOWN             |       |
+| 0x0c 0x009e | Media Select SAP                 |        |                                  |         |        |                                  |       |
+| 0x0c 0x00a0 | VCR Plus                         | 0x017c | KEY_VCR2                         |         |        |                                  |       |
+| 0x0c 0x00a1 | Once                             |        |                                  |         |        |                                  |       |
+| 0x0c 0x00a2 | Daily                            |        |                                  |         |        |                                  |       |
+| 0x0c 0x00a3 | Weekly                           |        |                                  |         |        |                                  |       |
+| 0x0c 0x00a4 | Monthly                          |        |                                  |         |        |                                  |       |
+| 0x0c 0x00b0 | Play                             | 0x00cf | KEY_PLAY                         | 3.0     | 0x007e | KEYCODE_MEDIA_PLAY               |       |
+| 0x0c 0x00b1 | Pause                            | 0x0077 | KEY_PAUSE                        | 3.0     | 0x0079 | KEYCODE_BREAK                    |       |
+| 0x0c 0x00b2 | Record                           | 0x00a7 | KEY_RECORD                       | 3.0     | 0x0082 | KEYCODE_MEDIA_RECORD             |       |
+| 0x0c 0x00b3 | Fast Forward                     | 0x00d0 | KEY_FASTFORWARD                  | 3.0     | 0x005a | KEYCODE_MEDIA_FAST_FORWARD       |       |
+| 0x0c 0x00b4 | Rewind                           | 0x00a8 | KEY_REWIND                       | 3.0     | 0x0059 | KEYCODE_MEDIA_REWIND             |       |
+| 0x0c 0x00b5 | Scan Next Track                  | 0x00a3 | KEY_NEXTSONG                     | 3.0     | 0x0057 | KEYCODE_MEDIA_NEXT               |       |
+| 0x0c 0x00b6 | Scan Previous Track              | 0x00a5 | KEY_PREVIOUSSONG                 | 3.0     | 0x0058 | KEYCODE_MEDIA_PREVIOUS           |       |
+| 0x0c 0x00b7 | Stop                             | 0x00a6 | KEY_STOPCD                       | 3.0     | 0x0056 | KEYCODE_MEDIA_STOP               |       |
+| 0x0c 0x00b8 | Eject                            | 0x00a1 | KEY_EJECTCD                      | 3.0     | 0x0081 | KEYCODE_MEDIA_EJECT              |       |
+| 0x0c 0x00b9 | Random Play                      |        |                                  |         |        |                                  |       |
+| 0x0c 0x00ba | Select Disc                      |        |                                  |         |        |                                  |       |
+| 0x0c 0x00bb | Enter Disc                       |        |                                  |         |        |                                  |       |
+| 0x0c 0x00bc | Repeat                           | 0x01b7 | KEY_MEDIA_REPEAT                 |         |        |                                  |       |
+| 0x0c 0x00be | Track Normal                     |        |                                  |         |        |                                  |       |
+| 0x0c 0x00c0 | Frame Forward                    |        |                                  |         |        |                                  |       |
+| 0x0c 0x00c1 | Frame Back                       |        |                                  |         |        |                                  |       |
+| 0x0c 0x00c2 | Mark                             |        |                                  |         |        |                                  |       |
+| 0x0c 0x00c3 | Clear Mark                       |        |                                  |         |        |                                  |       |
+| 0x0c 0x00c4 | Repeat From Mark                 |        |                                  |         |        |                                  |       |
+| 0x0c 0x00c5 | Return To Mark                   |        |                                  |         |        |                                  |       |
+| 0x0c 0x00c6 | Search Mark Forward              |        |                                  |         |        |                                  |       |
+| 0x0c 0x00c7 | Search Mark Backwards            |        |                                  |         |        |                                  |       |
+| 0x0c 0x00c8 | Counter Reset                    |        |                                  |         |        |                                  |       |
+| 0x0c 0x00c9 | Show Counter                     |        |                                  |         |        |                                  |       |
+| 0x0c 0x00ca | Tracking Increment               |        |                                  |         |        |                                  |       |
+| 0x0c 0x00cb | Tracking Decrement               |        |                                  |         |        |                                  |       |
+| 0x0c 0x00cc | Stop / Eject                     |        |                                  |         |        |                                  |       |
+| 0x0c 0x00cd | Play / Pause                     | 0x00a4 | KEY_PLAYPAUSE                    | 3.0     | 0x0055 | KEYCODE_MEDIA_PLAY_PAUSE         |       |
+| 0x0c 0x00ce | Play / Skip                      |        |                                  |         |        |                                  |       |
+| 0x0c 0x00e2 | Mute                             | 0x0071 | KEY_MUTE                         | 3.0     | 0x00a4 | KEYCODE_VOLUME_MUTE              |       |
+| 0x0c 0x00e5 | Bass Boost                       | 0x00d1 | KEY_BASSBOOST                    |         |        |                                  |       |
+| 0x0c 0x00e6 | Surround Mode                    |        |                                  |         |        |                                  |       |
+| 0x0c 0x00e7 | Loudness                         |        |                                  |         |        |                                  |       |
+| 0x0c 0x00e8 | MPX                              |        |                                  |         |        |                                  |       |
+| 0x0c 0x00e9 | Volume Increment                 | 0x0073 | KEY_VOLUMEUP                     | 1.6     | 0x0018 | KEYCODE_VOLUME_UP                |       |
+| 0x0c 0x00ea | Volume Decrement                 | 0x0072 | KEY_VOLUMEDOWN                   | 1.6     | 0x0019 | KEYCODE_VOLUME_DOWN              |       |
+| 0x0c 0x0181 | AL Launch Button Config. Tool    |        |                                  |         |        |                                  |       |
+| 0x0c 0x0182 | AL Programmable Button Config.   | 0x009c | KEY_BOOKMARKS                    | 3.0     | 0x00ae | KEYCODE_BOOKMARK                 |       |
+| 0x0c 0x0183 | AL Consumer Control Config.      | 0x00ab | KEY_CONFIG                       |         |        |                                  |       |
+| 0x0c 0x0184 | AL Word Processor                | 0x01a5 | KEY_WORDPROCESSOR                |         |        |                                  |       |
+| 0x0c 0x0185 | AL Text Editor                   | 0x01a6 | KEY_EDITOR                       |         |        |                                  |       |
+| 0x0c 0x0186 | AL Spreadsheet                   | 0x01a7 | KEY_SPREADSHEET                  |         |        |                                  |       |
+| 0x0c 0x0187 | AL Graphics Editor               | 0x01a8 | KEY_GRAPHICSEDITOR               |         |        |                                  |       |
+| 0x0c 0x0188 | AL Presentation App              | 0x01a9 | KEY_PRESENTATION                 |         |        |                                  |       |
+| 0x0c 0x0189 | AL Database App                  | 0x01aa | KEY_DATABASE                     |         |        |                                  |       |
+| 0x0c 0x018a | AL Email Reader                  | 0x009b | KEY_MAIL                         | 1.6     | 0x0041 | KEYCODE_ENVELOPE                 |       |
+| 0x0c 0x018b | AL Newsreader                    | 0x01ab | KEY_NEWS                         |         |        |                                  |       |
+| 0x0c 0x018c | AL Voicemail                     | 0x01ac | KEY_VOICEMAIL                    |         |        |                                  |       |
+| 0x0c 0x018d | AL Contacts / Address Book       | 0x01ad | KEY_ADDRESSBOOK                  |         |        |                                  |       |
+| 0x0c 0x018e | AL Calendar / Schedule           | 0x018d | KEY_CALENDAR                     |         |        |                                  |       |
+| 0x0c 0x018f | AL Task / Project Manager        |        |                                  |         |        |                                  |       |
+| 0x0c 0x0190 | AL Log / Journal / Timecard      |        |                                  |         |        |                                  |       |
+| 0x0c 0x0191 | AL Checkbook / Finance           | 0x00db | KEY_FINANCE                      |         |        |                                  |       |
+| 0x0c 0x0192 | AL Calculator                    | 0x008c | KEY_CALC                         |         |        |                                  |       |
+| 0x0c 0x0193 | AL A/V Capture / Playback        |        |                                  |         |        |                                  |       |
+| 0x0c 0x0194 | AL Local Machine Browser         | 0x0090 | KEY_FILE                         |         |        |                                  |       |
+| 0x0c 0x0195 | AL LAN/WAN Browser               |        |                                  |         |        |                                  |       |
+| 0x0c 0x0196 | AL Internet Browser              | 0x0096 | KEY_WWW                          | 1.6     | 0x0040 | KEYCODE_EXPLORER                 |       |
+| 0x0c 0x0197 | AL Remote Networking/ISP Connect |        |                                  |         |        |                                  |       |
+| 0x0c 0x0198 | AL Network Conference            |        |                                  |         |        |                                  |       |
+| 0x0c 0x0199 | AL Network Chat                  | 0x00d8 | KEY_CHAT                         |         |        |                                  |       |
+| 0x0c 0x019a | AL Telephony / Dialer            |        |                                  |         |        |                                  |       |
+| 0x0c 0x019b | AL Logon                         |        |                                  |         |        |                                  |       |
+| 0x0c 0x019c | AL Logoff                        | 0x01b1 | KEY_LOGOFF                       |         |        |                                  |       |
+| 0x0c 0x019d | AL Logon / Logoff                |        |                                  |         |        |                                  |       |
+| 0x0c 0x019e | AL Terminal Lock / Screensaver   | 0x0098 | KEY_COFFEE                       | 4.0     | 0x001a | KEYCODE_POWER                    |       |
+| 0x0c 0x019f | AL Control Panel                 |        |                                  |         |        |                                  |       |
+| 0x0c 0x01a0 | AL Command Line Processor / Run  |        |                                  |         |        |                                  |       |
+| 0x0c 0x01a1 | AL Process / Task Manager        |        |                                  |         |        |                                  |       |
+| 0x0c 0x01a2 | AL Select Task / Application     |        |                                  |         |        |                                  |       |
+| 0x0c 0x01a3 | AL Next Task / Application       |        |                                  |         |        |                                  |       |
+| 0x0c 0x01a4 | AL Previous Task / Application   |        |                                  |         |        |                                  |       |
+| 0x0c 0x01a5 | AL Preemptive Halt Task / App.   |        |                                  |         |        |                                  |       |
+| 0x0c 0x01a6 | AL Integrated Help Center        | 0x008a | KEY_HELP                         |         |        |                                  |       |
+| 0x0c 0x01a7 | AL Documents                     | 0x00eb | KEY_DOCUMENTS                    |         |        |                                  |       |
+| 0x0c 0x01a8 | AL Thesaurus                     |        |                                  |         |        |                                  |       |
+| 0x0c 0x01a9 | AL Dictionary                    |        |                                  |         |        |                                  |       |
+| 0x0c 0x01aa | AL Desktop                       |        |                                  |         |        |                                  |       |
+| 0x0c 0x01ab | AL Spell Check                   | 0x01b0 | KEY_SPELLCHECK                   |         |        |                                  |       |
+| 0x0c 0x01ac | AL Grammar Check                 |        |                                  |         |        |                                  |       |
+| 0x0c 0x01ad | AL Wireless Status               |        |                                  |         |        |                                  |       |
+| 0x0c 0x01ae | AL Keyboard Layout               |        |                                  |         |        |                                  |       |
+| 0x0c 0x01af | AL Virus Protection              |        |                                  |         |        |                                  |       |
+| 0x0c 0x01b0 | AL Encryption                    |        |                                  |         |        |                                  |       |
+| 0x0c 0x01b1 | AL Screen Saver                  |        |                                  |         |        |                                  |       |
+| 0x0c 0x01b2 | AL Alarms                        |        |                                  |         |        |                                  |       |
+| 0x0c 0x01b3 | AL Clock                         |        |                                  |         |        |                                  |       |
+| 0x0c 0x01b4 | AL File Browser                  |        |                                  |         |        |                                  |       |
+| 0x0c 0x01b5 | AL Power Status                  |        |                                  |         |        |                                  |       |
+| 0x0c 0x01b6 | AL Image Browser                 | 0x00e2 | KEY_MEDIA                        |         |        |                                  |       |
+| 0x0c 0x01b7 | AL Audio Browser                 | 0x00d5 | KEY_SOUND                        |         |        |                                  |       |
+| 0x0c 0x01b8 | AL Movie Browser                 |        |                                  |         |        |                                  |       |
+| 0x0c 0x01b9 | AL Digital Rights Manager        |        |                                  |         |        |                                  |       |
+| 0x0c 0x01ba | AL Digital Wallet                |        |                                  |         |        |                                  |       |
+| 0x0c 0x01bc | AL Instant Messaging             | 0x01ae | KEY_MESSENGER                    |         |        |                                  |       |
+| 0x0c 0x01bd | AL OEM Features / Tips Browser   | 0x0166 | KEY_INFO                         |         |        |                                  |       |
+| 0x0c 0x01be | AL OEM Help                      |        |                                  |         |        |                                  |       |
+| 0x0c 0x01bf | AL Online Community              |        |                                  |         |        |                                  |       |
+| 0x0c 0x01c0 | AL Entertainment Content Browser |        |                                  |         |        |                                  |       |
+| 0x0c 0x01c1 | AL Online Shopping Browser       |        |                                  |         |        |                                  |       |
+| 0x0c 0x01c2 | AL SmartCard Information / Help  |        |                                  |         |        |                                  |       |
+| 0x0c 0x01c3 | AL Market / Finance Browser      |        |                                  |         |        |                                  |       |
+| 0x0c 0x01c4 | AL Customized Corp. News Browser |        |                                  |         |        |                                  |       |
+| 0x0c 0x01c5 | AL Online Activity Browser       |        |                                  |         |        |                                  |       |
+| 0x0c 0x01c6 | AL Research / Search Browser     |        |                                  |         |        |                                  |       |
+| 0x0c 0x01c7 | AL Audio Player                  |        |                                  |         |        |                                  |       |
+| 0x0c 0x0201 | AC New                           | 0x00b5 | KEY_NEW                          |         |        |                                  |       |
+| 0x0c 0x0202 | AC Open                          | 0x0086 | KEY_OPEN                         |         |        |                                  |       |
+| 0x0c 0x0203 | AC Close                         | 0x00ce | KEY_CLOSE                        |         |        |                                  |       |
+| 0x0c 0x0204 | AC Exit                          | 0x00ae | KEY_EXIT                         |         |        |                                  |       |
+| 0x0c 0x0205 | AC Maximize                      |        |                                  |         |        |                                  |       |
+| 0x0c 0x0206 | AC Minimize                      |        |                                  |         |        |                                  |       |
+| 0x0c 0x0207 | AC Save                          | 0x00ea | KEY_SAVE                         |         |        |                                  |       |
+| 0x0c 0x0208 | AC Print                         | 0x00d2 | KEY_PRINT                        |         |        |                                  |       |
+| 0x0c 0x0209 | AC Properties                    | 0x0082 | KEY_PROPS                        |         |        |                                  |       |
+| 0x0c 0x021a | AC Undo                          | 0x0083 | KEY_UNDO                         |         |        |                                  |       |
+| 0x0c 0x021b | AC Copy                          | 0x0085 | KEY_COPY                         |         |        |                                  |       |
+| 0x0c 0x021c | AC Cut                           | 0x0089 | KEY_CUT                          |         |        |                                  |       |
+| 0x0c 0x021d | AC Paste                         | 0x0087 | KEY_PASTE                        |         |        |                                  |       |
+| 0x0c 0x021e | AC Select All                    |        |                                  |         |        |                                  |       |
+| 0x0c 0x021f | AC Find                          | 0x0088 | KEY_FIND                         |         |        |                                  |       |
+| 0x0c 0x0220 | AC Find and Replace              |        |                                  |         |        |                                  |       |
+| 0x0c 0x0221 | AC Search                        | 0x00d9 | KEY_SEARCH                       | 1.6     | 0x0054 | KEYCODE_SEARCH                   |       |
+| 0x0c 0x0222 | AC Go To                         | 0x0162 | KEY_GOTO                         |         |        |                                  |       |
+| 0x0c 0x0223 | AC Home                          | 0x00ac | KEY_HOMEPAGE                     | 3.0     | 0x0003 | KEYCODE_HOME                     |       |
+| 0x0c 0x0224 | AC Back                          | 0x009e | KEY_BACK                         | 1.6     | 0x0004 | KEYCODE_BACK                     |       |
+| 0x0c 0x0225 | AC Forward                       | 0x009f | KEY_FORWARD                      | 3.0     | 0x007d | KEYCODE_FORWARD                  |       |
+| 0x0c 0x0226 | AC Stop                          | 0x0080 | KEY_STOP                         | 3.0     | 0x0056 | KEYCODE_MEDIA_STOP               |       |
+| 0x0c 0x0227 | AC Refresh                       | 0x00ad | KEY_REFRESH                      |         |        |                                  |       |
+| 0x0c 0x0228 | AC Previous Link                 |        |                                  |         |        |                                  |       |
+| 0x0c 0x0229 | AC Next Link                     |        |                                  |         |        |                                  |       |
+| 0x0c 0x022a | AC Bookmarks                     | 0x009c | KEY_BOOKMARKS                    | 3.0     | 0x00ae | KEYCODE_BOOKMARK                 |       |
+| 0x0c 0x022b | AC History                       |        |                                  |         |        |                                  |       |
+| 0x0c 0x022c | AC Subscriptions                 |        |                                  |         |        |                                  |       |
+| 0x0c 0x022d | AC Zoom In                       | 0x01a2 | KEY_ZOOMIN                       |         |        |                                  |       |
+| 0x0c 0x022e | AC Zoom Out                      | 0x01a3 | KEY_ZOOMOUT                      |         |        |                                  |       |
+| 0x0c 0x022f | AC Zoom                          | 0x01a4 | KEY_ZOOMRESET                    |         |        |                                  | 2     |
+| 0x0c 0x0230 | AC Full Screen View              |        |                                  |         |        |                                  |       |
+| 0x0c 0x0231 | AC Normal View                   |        |                                  |         |        |                                  |       |
+| 0x0c 0x0232 | AC View Toggle                   |        |                                  |         |        |                                  |       |
+| 0x0c 0x0233 | AC Scroll Up                     | 0x00b1 | KEY_SCROLLUP                     | 3.0     | 0x005c | KEYCODE_PAGE_UP                  |       |
+| 0x0c 0x0234 | AC Scroll Down                   | 0x00b2 | KEY_SCROLLDOWN                   | 3.0     | 0x005d | KEYCODE_PAGE_DOWN                |       |
+| 0x0c 0x0236 | AC Pan Left                      |        |                                  |         |        |                                  |       |
+| 0x0c 0x0237 | AC Pan Right                     |        |                                  |         |        |                                  |       |
+| 0x0c 0x0239 | AC New Window                    |        |                                  |         |        |                                  |       |
+| 0x0c 0x023a | AC Tile Horizontally             |        |                                  |         |        |                                  |       |
+| 0x0c 0x023b | AC Tile Vertically               |        |                                  |         |        |                                  |       |
+| 0x0c 0x023c | AC Format                        |        |                                  |         |        |                                  |       |
+| 0x0c 0x023d | AC Edit                          |        |                                  |         |        |                                  |       |
+| 0x0c 0x023e | AC Bold                          |        |                                  |         |        |                                  |       |
+| 0x0c 0x023f | AC Italics                       |        |                                  |         |        |                                  |       |
+| 0x0c 0x0240 | AC Underline                     |        |                                  |         |        |                                  |       |
+| 0x0c 0x0241 | AC Strikethrough                 |        |                                  |         |        |                                  |       |
+| 0x0c 0x0242 | AC Subscript                     |        |                                  |         |        |                                  |       |
+| 0x0c 0x0243 | AC Superscript                   |        |                                  |         |        |                                  |       |
+| 0x0c 0x0244 | AC All Caps                      |        |                                  |         |        |                                  |       |
+| 0x0c 0x0245 | AC Rotate                        |        |                                  |         |        |                                  |       |
+| 0x0c 0x0246 | AC Resize                        |        |                                  |         |        |                                  |       |
+| 0x0c 0x0247 | AC Flip horizontal               |        |                                  |         |        |                                  |       |
+| 0x0c 0x0248 | AC Flip Vertical                 |        |                                  |         |        |                                  |       |
+| 0x0c 0x0249 | AC Mirror Horizontal             |        |                                  |         |        |                                  |       |
+| 0x0c 0x024a | AC Mirror Vertical               |        |                                  |         |        |                                  |       |
+| 0x0c 0x024b | AC Font Select                   |        |                                  |         |        |                                  |       |
+| 0x0c 0x024c | AC Font Color                    |        |                                  |         |        |                                  |       |
+| 0x0c 0x024d | AC Font Size                     |        |                                  |         |        |                                  |       |
+| 0x0c 0x024e | AC Justify Left                  |        |                                  |         |        |                                  |       |
+| 0x0c 0x024f | AC Justify Center H              |        |                                  |         |        |                                  |       |
+| 0x0c 0x0250 | AC Justify Right                 |        |                                  |         |        |                                  |       |
+| 0x0c 0x0251 | AC Justify Block H               |        |                                  |         |        |                                  |       |
+| 0x0c 0x0252 | AC Justify Top                   |        |                                  |         |        |                                  |       |
+| 0x0c 0x0253 | AC Justify Center V              |        |                                  |         |        |                                  |       |
+| 0x0c 0x0254 | AC Justify Bottom                |        |                                  |         |        |                                  |       |
+| 0x0c 0x0255 | AC Justify Block V               |        |                                  |         |        |                                  |       |
+| 0x0c 0x0256 | AC Indent Decrease               |        |                                  |         |        |                                  |       |
+| 0x0c 0x0257 | AC Indent Increase               |        |                                  |         |        |                                  |       |
+| 0x0c 0x0258 | AC Numbered List                 |        |                                  |         |        |                                  |       |
+| 0x0c 0x0259 | AC Restart Numbering             |        |                                  |         |        |                                  |       |
+| 0x0c 0x025a | AC Bulleted List                 |        |                                  |         |        |                                  |       |
+| 0x0c 0x025b | AC Promote                       |        |                                  |         |        |                                  |       |
+| 0x0c 0x025c | AC Demote                        |        |                                  |         |        |                                  |       |
+| 0x0c 0x025d | AC Yes                           |        |                                  |         |        |                                  |       |
+| 0x0c 0x025e | AC No                            |        |                                  |         |        |                                  |       |
+| 0x0c 0x025f | AC Cancel                        | 0x00df | KEY_CANCEL                       |         |        |                                  |       |
+| 0x0c 0x0260 | AC Catalog                       |        |                                  |         |        |                                  |       |
+| 0x0c 0x0261 | AC Buy / Checkout                |        |                                  |         |        |                                  |       |
+| 0x0c 0x0262 | AC Add to Cart                   |        |                                  |         |        |                                  |       |
+| 0x0c 0x0263 | AC Expand                        |        |                                  |         |        |                                  |       |
+| 0x0c 0x0264 | AC Expand All                    |        |                                  |         |        |                                  |       |
+| 0x0c 0x0265 | AC Collapse                      |        |                                  |         |        |                                  |       |
+| 0x0c 0x0266 | AC Collapse All                  |        |                                  |         |        |                                  |       |
+| 0x0c 0x0267 | AC Print Preview                 |        |                                  |         |        |                                  |       |
+| 0x0c 0x0268 | AC Paste Special                 |        |                                  |         |        |                                  |       |
+| 0x0c 0x0269 | AC Insert Mode                   |        |                                  |         |        |                                  |       |
+| 0x0c 0x026a | AC Delete                        |        |                                  |         |        |                                  |       |
+| 0x0c 0x026b | AC Lock                          |        |                                  |         |        |                                  |       |
+| 0x0c 0x026c | AC Unlock                        |        |                                  |         |        |                                  |       |
+| 0x0c 0x026d | AC Protect                       |        |                                  |         |        |                                  |       |
+| 0x0c 0x026e | AC Unprotect                     |        |                                  |         |        |                                  |       |
+| 0x0c 0x026f | AC Attach Comment                |        |                                  |         |        |                                  |       |
+| 0x0c 0x0270 | AC Delete Comment                |        |                                  |         |        |                                  |       |
+| 0x0c 0x0271 | AC View Comment                  |        |                                  |         |        |                                  |       |
+| 0x0c 0x0272 | AC Select Word                   |        |                                  |         |        |                                  |       |
+| 0x0c 0x0273 | AC Select Sentence               |        |                                  |         |        |                                  |       |
+| 0x0c 0x0274 | AC Select Paragraph              |        |                                  |         |        |                                  |       |
+| 0x0c 0x0275 | AC Select Column                 |        |                                  |         |        |                                  |       |
+| 0x0c 0x0276 | AC Select Row                    |        |                                  |         |        |                                  |       |
+| 0x0c 0x0277 | AC Select Table                  |        |                                  |         |        |                                  |       |
+| 0x0c 0x0278 | AC Select Object                 |        |                                  |         |        |                                  |       |
+| 0x0c 0x0279 | AC Redo / Repeat                 | 0x00b6 | KEY_REDO                         |         |        |                                  |       |
+| 0x0c 0x027a | AC Sort                          |        |                                  |         |        |                                  |       |
+| 0x0c 0x027b | AC Sort Ascending                |        |                                  |         |        |                                  |       |
+| 0x0c 0x027c | AC Sort Descending               |        |                                  |         |        |                                  |       |
+| 0x0c 0x027d | AC Filter                        |        |                                  |         |        |                                  |       |
+| 0x0c 0x027e | AC Set Clock                     |        |                                  |         |        |                                  |       |
+| 0x0c 0x027f | AC View Clock                    |        |                                  |         |        |                                  |       |
+| 0x0c 0x0280 | AC Select Time Zone              |        |                                  |         |        |                                  |       |
+| 0x0c 0x0281 | AC Edit Time Zones               |        |                                  |         |        |                                  |       |
+| 0x0c 0x0282 | AC Set Alarm                     |        |                                  |         |        |                                  |       |
+| 0x0c 0x0283 | AC Clear Alarm                   |        |                                  |         |        |                                  |       |
+| 0x0c 0x0284 | AC Snooze Alarm                  |        |                                  |         |        |                                  |       |
+| 0x0c 0x0285 | AC Reset Alarm                   |        |                                  |         |        |                                  |       |
+| 0x0c 0x0286 | AC Synchronize                   |        |                                  |         |        |                                  |       |
+| 0x0c 0x0287 | AC Send/Receive                  |        |                                  |         |        |                                  |       |
+| 0x0c 0x0288 | AC Send To                       |        |                                  |         |        |                                  |       |
+| 0x0c 0x0289 | AC Reply                         | 0x00e8 | KEY_REPLY                        |         |        |                                  |       |
+| 0x0c 0x028a | AC Reply All                     |        |                                  |         |        |                                  |       |
+| 0x0c 0x028b | AC Forward Msg                   | 0x00e9 | KEY_FORWARDMAIL                  |         |        |                                  |       |
+| 0x0c 0x028c | AC Send                          | 0x00e7 | KEY_SEND                         |         |        |                                  |       |
+| 0x0c 0x028d | AC Attach File                   |        |                                  |         |        |                                  |       |
+| 0x0c 0x028e | AC Upload                        |        |                                  |         |        |                                  |       |
+| 0x0c 0x028f | AC Download (Save Target As)     |        |                                  |         |        |                                  |       |
+| 0x0c 0x0290 | AC Set Borders                   |        |                                  |         |        |                                  |       |
+| 0x0c 0x0291 | AC Insert Row                    |        |                                  |         |        |                                  |       |
+| 0x0c 0x0292 | AC Insert Column                 |        |                                  |         |        |                                  |       |
+| 0x0c 0x0293 | AC Insert File                   |        |                                  |         |        |                                  |       |
+| 0x0c 0x0294 | AC Insert Picture                |        |                                  |         |        |                                  |       |
+| 0x0c 0x0295 | AC Insert Object                 |        |                                  |         |        |                                  |       |
+| 0x0c 0x0296 | AC Insert Symbol                 |        |                                  |         |        |                                  |       |
+| 0x0c 0x0297 | AC Save and Close                |        |                                  |         |        |                                  |       |
+| 0x0c 0x0298 | AC Rename                        |        |                                  |         |        |                                  |       |
+| 0x0c 0x0299 | AC Merge                         |        |                                  |         |        |                                  |       |
+| 0x0c 0x029a | AC Split                         |        |                                  |         |        |                                  |       |
+| 0x0c 0x029b | AC Distribute Horizontally       |        |                                  |         |        |                                  |       |
+| 0x0c 0x029c | AC Distribute Vertically         |        |                                  |         |        |                                  |       |
+
+### Additional non-HID Mappings ###
+
+These mappings describe functions that do not appear in HID but for which Linux
+key codes exist.
+
+| LKC    | Linux Key Code Name              | Version | AKC    | Android Key Code Name            | Notes |
+| ------ | -------------------------------- | ------- | ------ | -------------------------------- | ----- |
+| 0x01d0 | KEY_FN                           | 3.0     | 0x0077 | KEYCODE_FUNCTION                 |       |
+| 0x01d1 | KEY_FN_ESC                       | 3.0     | 0x006f | KEYCODE_ESCAPE                   | 3     |
+| 0x01d2 | KEY_FN_F1                        | 3.0     | 0x0083 | KEYCODE_F1                       | 3     |
+| 0x01d3 | KEY_FN_F2                        | 3.0     | 0x0084 | KEYCODE_F2                       | 3     |
+| 0x01d4 | KEY_FN_F3                        | 3.0     | 0x0085 | KEYCODE_F3                       | 3     |
+| 0x01d5 | KEY_FN_F4                        | 3.0     | 0x0086 | KEYCODE_F4                       | 3     |
+| 0x01d6 | KEY_FN_F5                        | 3.0     | 0x0087 | KEYCODE_F5                       | 3     |
+| 0x01d7 | KEY_FN_F6                        | 3.0     | 0x0088 | KEYCODE_F6                       | 3     |
+| 0x01d8 | KEY_FN_F7                        | 3.0     | 0x0089 | KEYCODE_F7                       | 3     |
+| 0x01d9 | KEY_FN_F8                        | 3.0     | 0x008a | KEYCODE_F8                       | 3     |
+| 0x01da | KEY_FN_F9                        | 3.0     | 0x008b | KEYCODE_F9                       | 3     |
+| 0x01db | KEY_FN_F10                       | 3.0     | 0x008c | KEYCODE_F10                      | 3     |
+| 0x01dc | KEY_FN_F11                       | 3.0     | 0x008d | KEYCODE_F11                      | 3     |
+| 0x01dd | KEY_FN_F12                       | 3.0     | 0x008e | KEYCODE_F12                      | 3     |
+| 0x01de | KEY_FN_1                         | 3.0     | 0x0008 | KEYCODE_1                        | 3     |
+| 0x01df | KEY_FN_2                         | 3.0     | 0x0009 | KEYCODE_2                        | 3     |
+| 0x01e0 | KEY_FN_D                         | 3.0     | 0x0020 | KEYCODE_D                        | 3     |
+| 0x01e1 | KEY_FN_E                         | 3.0     | 0x0021 | KEYCODE_E                        | 3     |
+| 0x01e2 | KEY_FN_F                         | 3.0     | 0x0022 | KEYCODE_F                        | 3     |
+| 0x01e3 | KEY_FN_S                         | 3.0     | 0x002f | KEYCODE_S                        | 3     |
+| 0x01e4 | KEY_FN_B                         | 3.0     | 0x001e | KEYCODE_B                        | 3     |
+
+### Legacy Unsupported Keys ###
+
+These mappings appeared in previous versions of Android but were inconsistent with
+HID or used non-standard Linux key codes.  They are no longer supported.
+
+| LKC    | Linux Key Code Name              | Version | AKC    | Android Key Code Name            | Notes |
+| ------ | -------------------------------- | ------- | ------ | -------------------------------- | ----- |
+| 0x00db | KEY_EMAIL                        | 1.6     | 0x004d | KEYCODE_AT                       | 4     |
+| ""     | ""                               | 4.0     |        |                                  | 4     |
+| 0x00e3 | KEY_STAR                         | 1.6     | 0x0011 | KEYCODE_STAR                     | 4     |
+| ""     | ""                               | 4.0     |        |                                  | 4     |
+| 0x00e4 | KEY_SHARP                        | 1.6     | 0x0012 | KEYCODE_POUND                    | 4     |
+| ""     | ""                               | 4.0     |        |                                  | 4     |
+| 0x00e5 | KEY_SOFT1                        | 1.6     | 0x0052 | KEYCODE_MENU                     | 4     |
+| ""     | ""                               | 4.0     |        |                                  | 4     |
+| 0x00e6 | KEY_SOFT2                        | 1.6     | 0x0002 | KEYCODE_SOFT_RIGHT               | 4     |
+| ""     | ""                               | 4.0     |        |                                  | 4     |
+| 0x00e7 | KEY_SEND                         | 1.6     | 0x0005 | KEYCODE_CALL                     | 4     |
+| ""     | ""                               | 4.0     |        |                                  | 4     |
+| 0x00e8 | KEY_CENTER                       | 1.6     | 0x0017 | KEYCODE_DPAD_CENTER              | 4     |
+| ""     | ""                               | 4.0     |        |                                  | 4     |
+| 0x00e9 | KEY_HEADSETHOOK                  | 1.6     | 0x004f | KEYCODE_HEADSETHOOK              | 4     |
+| ""     | ""                               | 4.0     |        |                                  | 4     |
+| 0x00ea | KEY_0_5                          | 1.6     |        |                                  | 4     |
+| 0x00eb | KEY_2_5                          | 1.6     |        |                                  | 4     |
+
+### Notes ###
+
+1.  The Android key code associated with common alphanumeric and symbolic
+    keys may vary based on the keyboard layout and language.
+    For historical reasons, the physical scan codes and HID usages
+    associated with keys on a keyboard are often defined positionally
+    even though the labels printed on those keys may vary from one
+    language to another.
+
+    On a US English (QWERTY) keyboard, the top-left alphabetic key is
+    labeled Q.  On a French (AZERTY) keyboard, the key in the same
+    position is labeled A.  Despite the label, on both keyboards the
+    top-left alphabetic key is referred to using the HID usage
+    0x07 0x0014 which is mapped to the Linux key code KEY_Q.
+
+    When Android is configured with a US English keyboard layout, then
+    the Linux key code KEY_Q will be mapped to the Android key code
+    KEYCODE_Q and will produce the characters 'Q' and 'q'.
+    However, when Android is configured with a French keyboard layout,
+    then the Linux key code KEY_Q will be mapped to the Android key code
+    KEYCODE_A and will produce the characters 'A' and 'a'.
+
+    The Android key code typically reflects the language-specific
+    interpretation of the key, so a different Android key code may
+    be used for different languages.
+
+2.  `0x0c 0x022f AC Zoom` is defined in the HID as a linear control but
+    the kernel maps it as a key, which is probably incorrect.
+
+3.  The Linux function keys `KEY_FN_*` are mapped to simpler
+    key codes but are dispatched with the `META_FUNCTION` meta state
+    bit set to true.
+
+4.  Prior to Android Ice Cream Sandwich 4.0, the default key layout
+    contained mappings for some extra key codes that were not defined
+    in the mainline Linux kernel headers.  These mappings have since
+    been removed because these previously undefined key codes have
+    since been assigned different meanings in more recent versions
+    of the Linux kernel.
+
+### Sources ###
+
+1.  [USB HID Usage Tables v1.12](http://www.usb.org/developers/devclass_docs/Hut1_12v2.pdf)
+2.  Linux 2.6.39 kernel: include/linux/input.h, drivers/hid/hid-input.c
+3.  Android ICS: qwerty.kl, Generic.kl, KeyEvent.java
diff --git a/src/tech/input/migration-guide.md b/src/tech/input/migration-guide.md
new file mode 100644
index 0000000..e2aee60
--- /dev/null
+++ b/src/tech/input/migration-guide.md
@@ -0,0 +1,71 @@
+<!--
+   Copyright 2011 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+# Migration Guide #
+
+This document contains a few helpful tips when migrating to new Android releases.
+
+## Migrating to Android Gingerbread 2.3 ##
+
+In Gingerbread, we added the concept of input device configuration files
+(also referred to as input device calibration files in this release).
+
+Make sure to provide an input device configuration file for all touch screens.
+In particular, it is worth spending time providing a calibration reference for
+touch size information.
+
+## Migrating to Android Honeycomb 3.0 ##
+
+In Honeycomb, we revised the key character map file format and started making
+greater use of input device configuration files.  We also added support for full
+PC-style keyboards and introduced a new "Generic" key map, which
+replaced the older emulator-specific "qwerty" key map (which was never
+intended to be used as a general-purpose key map.)
+
+Make sure to update all of your key character map files to use the new syntax.
+
+If your peripherals relied on the old "qwerty" key map, then you
+may need to provide new device-specific key maps to emulate the old behavior.
+You should create a new key map for each device identified either by
+USB product id / vendor id or by device name.
+
+It is especially important to provide key character map files for all special
+function input devices.  These files should simple contain a line to set
+the keyboard type to `SPECIAL_FUNCTION`.
+
+A good way to ensure that all built-in input devices are appropriately configured
+is to run [Dumpsys](/tech/input/dumpsys.html) and look for devices that
+are inappropriately using `Generic.kcm`.
+
+## Migrating to Android Honeycomb 3.2 ##
+
+In Honeycomb 3.2, we added support for joysticks and extended the key layout file
+format to enable joystick axis mapping.
+
+## Migrating to Android Ice Cream Sandwich 4.0 ##
+
+In Ice Cream Sandwich 4.0, we changed the device driver requirements for touch screens
+to follow the standard Linux multitouch input protocol and added support for
+protocol "B".  We also support digitizer tablets and stylus-based touch devices.
+
+You will probably need to update your input device driver to implement the Linux
+multitouch input protocol correctly according to the standard.
+
+You will also need to update your input device configuration files because some
+properties have been changed to be simpler and more systematic.
+
+Refer to [Touch Devices](/tech/input/touch-devices.html) for more details about
+driver requirements.
diff --git a/src/tech/input/overview.md b/src/tech/input/overview.md
new file mode 100644
index 0000000..79e3de7
--- /dev/null
+++ b/src/tech/input/overview.md
@@ -0,0 +1,259 @@
+<!--
+   Copyright 2011 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+# Overview #
+
+The Android input subsystem nominally consists of an event pipeline
+that traverses multiple layers of the system.
+
+## Input Pipeline ##
+
+At the lowest layer, the physical input device produces signals that
+describe state changes such as key presses and touch contact points.
+The device firmware encodes and transmits these signals in some way
+such as by sending USB HID reports to the system or by producing
+interrupts on an I2C bus.
+
+The signals are then decoded by a device driver in the Linux kernel.
+The Linux kernel provides drivers for many standard peripherals,
+particularly those that adhere to the HID protocol.  However, an OEM
+must often provide custom drivers for embedded devices that are
+tightly integrated into the system at a low-level, such as touch screens.
+
+The input device drivers are responsible for translating device-specific
+signals into a standard input event format, by way of the Linux
+input protocol.  The Linux input protocol defines a standard set of
+event types and codes in the `linux/input.h` kernel header file.
+In this way, components outside the kernel do not need to care about
+the details such as physical scan codes, HID usages, I2C messages,
+GPIO pins, and the like.
+
+Next, the Android `EventHub` component reads input events from the kernel
+by opening the `evdev` driver associated with each input device.
+The Android InputReader component then decodes the input events
+according to the device class and produces a stream of Android input
+events.  As part of this process, the Linux input protocol event codes
+are translated into Android event codes according to the
+input device configuration, keyboard layout files, and various
+mapping tables.
+
+Finally, the `InputReader` sends input events to the InputDispatcher
+which forwards them to the appropriate window.
+
+## Control Points ##
+
+There are several stages in the input pipeline which effect control
+over the behavior of the input device.
+
+### Driver and Firmware Configuration ###
+
+Input device drivers frequently configure the behavior of the input
+device by setting parameters in registers or even uploading the
+firmware itself.  This is particularly the case for embedded
+devices such as touch screens where a large part of the calibration
+process involves tuning these parameters or fixing the firmware
+to provide the desired accuracy and responsiveness and to suppress
+noise.
+
+Driver configuration options are often specified as module parameters
+in the kernel board support package (BSP) so that the same driver
+can support multiple different hardware implementations.
+
+This documentation does attempt to describe driver or firmware
+configuration, but it does offer guidance as to device calibration
+in general.
+
+### Board Configuration Properties ###
+
+The kernel board support package (BSP) may export board configuration
+properties via SysFS that are used by the Android InputReader component,
+such as the placement of virtual keys on a touch screen.
+
+Refer to the device class sections for details about how different
+devices use board configuration properties.
+
+### Resource Overlays ###
+
+A few input behaviors are configured by way of resource overlays
+in `config.xml` such as the operation of lid switch.
+
+Here are a few examples:
+
+*   `config_lidKeyboardAccessibility`: Specifies the effect of the
+    lid switch on whether the hardware keyboard is accessible or hidden.
+
+*   `config_lidNavigationAccessibility`: Specifies the effect of the
+    lid switch on whether the trackpad is accessible or hidden.
+
+*   `config_longPressOnPowerBehavior`: Specifies what should happen when
+    the user holds down the power button.
+
+*   `config_lidOpenRotation`: Specifies the effect of the lid switch
+    on screen orientation.
+
+Refer to the documentation within `frameworks/base/core/res/res/values/config.xml`
+for details about each configuration option.
+
+### Key Maps ###
+
+Key maps are used by the Android `EventHub` and `InputReader` components
+to configure the mapping from Linux event codes to Android event codes
+for keys, joystick buttons and joystick axes.  The mapping may
+be device or language dependent.
+
+Refer to the device class sections for details about how different
+devices use key maps.
+
+### Input Device Configuration Files ###
+
+Input device configuration files are used by the Android `EventHub` and
+`InputReader` components to configure special device characteristics
+such as how touch size information is reported.
+
+Refer to the device class sections for details about how different
+devices use input device configuration maps.
+
+## Understanding HID Usages and Event Codes ##
+
+There are often several different identifiers used to refer to any
+given key on a keyboard, button on a game controller, joystick axis
+or other control.  The relationships between these identifiers
+are not always the same: they are dependent on a set of mapping tables,
+some of which are fixed, and some which vary based on characteristics
+of the device, the device driver, the current locale, the system
+configuration, user preferences and other factors.
+
+Physical Scan Code
+:   A physical scan code is a device-specific identifier that is associated
+    with each key, button or other control.  Because physical scan codes
+    often vary from one device to another, the firmware or device driver
+    is responsible for mapping them to standard identifiers such as
+    HID Usages or Linux key codes.
+
+    Scan codes are mainly of interest for keyboards.  Other devices
+    typically communicate at a low-level using GPIO pins, I2C messages
+    or other means.  Consequently, the upper layers of the software
+    stack rely on the device drivers to make sense of what is going on.
+
+HID Usage
+:   A HID usage is a standard identifier that is used to report the
+    state of a control such as a keyboard key, joystick axis,
+    mouse button, or touch contact point.  Most USB and Bluetooth
+    input devices conform to the HID specification, which enables
+    the system to interface with them in a uniform manner.
+
+    The Android Framework relies on the Linux kernel HID drivers to
+    translate HID usage codes into Linux key codes and other identifiers.
+    Therefore HID usages are mainly of interest to peripheral manufacturers.
+
+Linux Key Code
+:   A Linux key code is a standard identifier for a key or button.
+    Linux key codes are defined in the `linux/input.h` header file using
+    constants that begin with the prefix `KEY_` or `BTN_`.  The Linux
+    kernel input drivers are responsible for translating physical
+    scan codes, HID usages and other device-specific signals into Linux
+    key codes and delivering information about them as part of
+    `EV_KEY` events.
+
+    The Android API sometimes refers to the Linux key code associated
+    with a key as its "scan code".  This is technically incorrect in
+    but it helps to distinguish Linux key codes from Android key codes
+    in the API.
+
+Linux Relative or Absolute Axis Code
+:   A Linux relative or absolute axis code is a standard identifier
+    for reporting relative movements or absolute positions along an
+    axis, such as the relative movements of a mouse along its X axis
+    or the absolute position of a joystick along its X axis.
+    Linux axis code are defined in the `linux/input.h` header file using
+    constants that begin with the prefix `REL_` or `ABS_`.  The Linux
+    kernel input drivers are responsible for translating HID usages
+    and other device-specific signals into Linux axis codes and
+    delivering information about them as part of `EV_REL` and
+    `EV_ABS` events.
+
+Linux Switch Code
+:   A Linux switch code is a standard identifier for reporting the
+    state of a switch on a device, such as a lid switch.  Linux
+    switch codes are defined in the `linux/input.h` header file
+    using constants that begin with the prefix `SW_`.  The Linux
+    kernel input drivers report switch state changes as `EV_SW` events.
+
+    Android applications generally do not receive events from switches,
+    but the system may use them interally to control various
+    device-specific functions.
+
+Android Key Code
+:   An Android key code is a standard identifier defined in the Android
+    API for indicating a particular key such as 'HOME'.  Android key codes
+    are defined by the `android.view.KeyEvent` class as constants that
+    begin with the prefix `KEYCODE_`.
+
+    The key layout specifies how Linux key codes are mapped to Android
+    key codes.  Different key layouts may be used depending on the keyboard
+    model, language, country, layout, or special functions.
+
+    Combinations of Android key codes are transformed into character codes
+    using a device and locale specific key character map.  For example,
+    when the keys identified as `KEYCODE_SHIFT` and `KEYCODE_A` are both
+    pressed together, the system looks up the combination in the key
+    character map and finds the capital letter 'A', which is then inserted
+    into the currently focused text widget.
+
+Android Axis Code
+:   An Android axis code is a standard identifier defined in the Android
+    API for indicating a particular device axis.  Android axis codes are
+    defined by the `android.view.MotionEvent` class as constants that
+    begin with the prefix `AXIS_`.
+
+    The key layout specifies how Linux Axis Codes are mapped to Android
+    axis codes.  Different key layouts may be used depending on the device
+    model, language, country, layout, or special functions.
+
+Android Meta State
+:   An Android meta state is a standard identifier defined in the Android
+    API for indicating which modifier keys are pressed.  Android meta states
+    are defined by the `android.view.KeyEvent` class as constants that
+    begin with the prefix `META_`.
+
+    The current meta state is determined by the Android InputReader
+    component which monitors when modifier keys such as `KEYCODE_SHIFT_LEFT`
+    are pressed / released and sets / resets the appropriate meta state flag.
+
+    The relationship between modifier keys and meta states is hardcoded
+    but the key layout can alter how the modifier keys themselves are
+    mapped which in turns affects the meta states.
+
+Android Button State
+:   An Android button state is a standard identifier defined in the Android
+    API for indicating which buttons (on a mouse or stylus) are pressed.
+    Android button states are defined by the `android.view.MotionEvent`
+    class as constants that begin with the prefix `BUTTON_`.
+
+    The current button state is determined by the Android InputReader
+    component which monitors when buttons (on a mouse or stylus) are
+    pressed / released and sets / resets appropriate button state flag.
+
+    The relationship between buttons and button states is hardcoded.
+
+## Further Reading ##
+
+1. [Linux input event codes](http://www.kernel.org/doc/Documentation/input/event-codes.txt)
+2. [Linux multi-touch protocol](http://www.kernel.org/doc/Documentation/input/multi-touch-protocol.txt)
+3. [Linux input drivers](http://www.kernel.org/doc/Documentation/input/input.txt)
+4. [Linux force feedback](http://www.kernel.org/doc/Documentation/input/ff.txt)
+5. [HID information, including HID usage tables](http://www.usb.org/developers/hidpage)
+
diff --git a/src/tech/input/sidebar2.md b/src/tech/input/sidebar2.md
new file mode 100644
index 0000000..6746bcd
--- /dev/null
+++ b/src/tech/input/sidebar2.md
@@ -0,0 +1,18 @@
+# Input Concepts #
+
+- [Overview](/tech/input/overview.html)
+- [Key Layout Files](/tech/input/key-layout-files.html)
+- [Key Character Map Files](/tech/input/key-character-map-files.html)
+- [Input Device Configuration Files](/tech/input/input-device-configuration-files.html)
+- [Migration Guide](/tech/input/migration-guide.html)
+
+# Input Device Classes #
+
+- [Keyboard Devices](/tech/input/keyboard-devices.html)
+- [Touch Devices](/tech/input/touch-devices.html)
+
+# Tools #
+
+- [Dumpsys](/tech/input/dumpsys.html)
+- [Getevent](/tech/input/getevent.html)
+- [Validate Keymaps](/tech/input/validate-keymaps.html)
diff --git a/src/tech/input/touch-devices.md b/src/tech/input/touch-devices.md
new file mode 100644
index 0000000..234188f
--- /dev/null
+++ b/src/tech/input/touch-devices.md
@@ -0,0 +1,1186 @@
+<!--
+   Copyright 2011 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+# Touch Devices #
+
+Android supports a variety of touch screens and touch pads, including
+stylus-based digitizer tablets.
+
+Touch screens are touch devices that are associated with a display such that
+the user has the impression of directly manipulating items on screen.
+
+Touch pads are touch devices that are not associated with a display such as a
+digitizer tablet.  Touch pads are typically used for pointing or for
+absolute indirect positioning or gesture-based control of a user interface.
+
+Touch devices may have buttons whose functions are similar to mouse buttons.
+
+Touch devices can sometimes be manipulated using a variety of different tools
+such as fingers or a stylus depending on the underlying touch sensor technology.
+
+Touch devices are sometimes used to implement virtual keys.  For example, on
+some Android devices, the touch screen sensor area extends beyond the edge of
+the display and serves dual purpose as part of a touch sensitive key pad.
+
+Due to the great variety of touch devices, Android relies on a large number of
+configuration properties to describe the characteristics and desired behavior
+of each device.
+
+## Touch Device Classification ##
+
+An input device is classified as a *multi-touch* device if both of
+the following conditions hold:
+
+*   The input device reports the presence of the `ABS_MT_POSITION_X` and
+    `ABS_MT_POSITION_Y` absolute axes.
+
+*   The input device does not have any gamepad buttons.  This condition
+    resolves an ambiguity with certain gamepads that report axes with codes
+    that overlaps those of the MT axes.
+
+An input device is classified as a *single-touch* device if both of the
+following conditions hold:
+
+*   The input device is not classified as a multi-touch device.  An input device
+    is either classified as a single-touch device or as a multi-touch device,
+    never both.
+
+*   The input device reports the presence of the `ABS_X` and `ABS_Y` absolute
+    axes, and the presence of the `BTN_TOUCH` key code.
+
+Once an input device has been classified as a touch device, the presence
+of virtual keys is determined by attempting to load the virtual key map file
+for the device.  If a virtual key map is available, then the key layout
+file for the device is also loaded.
+
+Refer to the section below about the location and format of virtual key map
+files.
+
+Next, the system loads the input device configuration file for the touch device.
+
+**All built-in touch devices should have input device configuration files.**
+If no input device configuration file is present, the system will
+choose a default configuration that is appropriate for typical general-purpose
+touch peripherals such as external USB or Bluetooth HID touch screens
+or touch pads.  These defaults are not designed for built-in touch screens and
+will most likely result in incorrect behavior.
+
+After the input device configuration loaded, the system will classify the
+input device as a *touch screen*, *touch pad* or *pointer* device.
+
+*   A *touch screen* device is used for direct manipulation of objects on the
+    screen.  Since the user is directly touching the screen, the system does
+    not require any additional affordances to indicate the objects being
+    manipulated.
+
+*   A *touch pad* device is used to provide absolute positioning information
+    to an application about touches on a given sensor area.  It may be useful
+    for digitizer tablets.
+
+*   A *pointer* device is used for indirect manipulation of objects on the
+    screen using a cursor.  Fingers are interpreted as multi-touch pointer
+    gestures.  Other tools, such as styluses, are interpreted using
+    absolute positions.
+
+    See [Indirect Multi-touch Pointer Gestures](#indirect-multi-touch-pointer-gestures)
+    for more information.
+
+The following rules are used to classify the input device as a *touch screen*,
+*touch pad* or *pointer* device.
+
+*   If the `touch.deviceType` property is set, then the device type will be
+    set as indicated.
+
+*   If the input device reports the presence of the `INPUT_PROP_DIRECT`
+    input property (via the `EVIOCGPROP` ioctl), then the device type will
+    be set to *touch screen*.  This condition assumes that direct input touch
+    devices are attached to a display that is also connected.
+
+*   If the input device reports the presence of the `INPUT_PROP_POINTER`
+    input property (via the `EVIOCGPROP` ioctl), then the device type will
+    be set to *pointer*.
+
+*   If the input device reports the presence of the `REL_X` or `REL_Y` relative
+    axes, then the device type will be set to *touch pad*.  This condition
+    resolves an ambiguity for input devices that consist of both a mouse and
+    a touch pad.  In this case, the touch pad will not be used to control
+    the pointer because the mouse already controls it.
+
+*   Otherwise, the device type will be set to *pointer*.  This default ensures
+    that touch pads that have not been designated any other special purpose
+    will serve to control the pointer.
+
+## Buttons ##
+
+Buttons are *optional* controls that may be used by applications to perform
+additional functions.  Buttons on touch devices behave similarly to mouse
+buttons and are mainly of use with *pointer* type touch devices or with a
+stylus.
+
+The following buttons are supported:
+
+*   `BTN_LEFT`: mapped to `MotionEvent.BUTTON_PRIMARY`.
+
+*   `BTN_RIGHT`: mapped to `MotionEvent.BUTTON_SECONDARY`.
+
+*   `BTN_MIDDLE`: mapped to `MotionEvent.BUTTON_MIDDLE`.
+
+*   `BTN_BACK` and `BTN_SIDE`: mapped to `MotionEvent.BUTTON_BACK`.
+    Pressing this button also synthesizes a key press with the key code
+    `KeyEvent.KEYCODE_BACK`.
+
+*   `BTN_FORWARD` and `BTN_EXTRA`: mapped to `MotionEvent.BUTTON_FORWARD`.
+    Pressing this button also synthesizes a key press with the key code
+    `KeyEvent.KEYCODE_FORWARD`.
+
+*   `BTN_STYLUS`: mapped to `MotionEvent.BUTTON_SECONDARY`.
+
+*   `BTN_STYLUS2`: mapped to `MotionEvent.BUTTON_TERTIARY`.
+
+## Tools and Tool Types ##
+
+A *tool* is a finger, stylus or other apparatus that is used to interact with
+the touch device.  Some touch devices can distinguish between different
+types of tools.
+
+Elsewhere in Android, as in the `MotionEvent` API, a *tool* is often referred
+to as a *pointer*.
+
+The following tool types are supported:
+
+*   `BTN_TOOL_FINGER` and `MT_TOOL_FINGER`: mapped to `MotionEvent.TOOL_TYPE_FINGER`.
+
+*   `BTN_TOOL_PEN` and `MT_TOOL_PEN`: mapped to `MotionEvent.TOOL_TYPE_STYLUS`.
+
+*   `BTN_TOOL_RUBBER`: mapped to `MotionEvent.TOOL_TYPE_ERASER`.
+
+*   `BTN_TOOL_BRUSH`: mapped to `MotionEvent.TOOL_TYPE_STYLUS`.
+
+*   `BTN_TOOL_PENCIL`: mapped to `MotionEvent.TOOL_TYPE_STYLUS`.
+
+*   `BTN_TOOL_AIRBRUSH`: mapped to `MotionEvent.TOOL_TYPE_STYLUS`.
+
+*   `BTN_TOOL_MOUSE`: mapped to `MotionEvent.TOOL_TYPE_MOUSE`.
+
+*   `BTN_TOOL_LENS`: mapped to `MotionEvent.TOOL_TYPE_MOUSE`.
+
+*   `BTN_TOOL_DOUBLETAP`, `BTN_TOOL_TRIPLETAP`, and `BTN_TOOL_QUADTAP`:
+    mapped to `MotionEvent.TOOL_TYPE_FINGER`.
+
+## Hovering vs. Touching Tools ##
+
+Tools can either be in contact with the touch device or in range and hovering
+above it.  Not all touch devices are able to sense the presence of a tool
+hovering above the touch device.  Those that do, such as RF-based stylus digitizers,
+can often detect when the tool is within a limited range of the digitizer.
+
+The `InputReader` component takes care to distinguish touching tools from hovering
+tools.  Likewise, touching tools and hovering tools are reported to applications
+in different ways.
+
+Touching tools are reported to applications as touch events
+using `MotionEvent.ACTION_DOWN`, `MotionEvent.ACTION_MOVE`, `MotionEvent.ACTION_DOWN`,
+`MotionEvent.ACTION_POINTER_DOWN` and `MotionEvent.ACTION_POINTER_UP`.
+
+Hovering tools are reported to applications as generic motion events using
+`MotionEvent.ACTION_HOVER_ENTER`, `MotionEvent.ACTION_HOVER_MOVE`
+and `MotionEvent.ACTION_HOVER_EXIT`.
+
+## Touch Device Driver Requirements ##
+
+1.  Touch device drivers should only register axes and key codes for the axes
+    and buttons that they actually support.  Registering excess axes or key codes
+    may confuse the device classification algorithm or cause the system to incorrectly
+    detect the capabilities of the device.
+
+    For example, if the device reports the `BTN_TOUCH` key code, the system will
+    assume that `BTN_TOUCH` will always be used to indicate whether the tool is
+    actually touching the screen or is merely in range and hovering.
+
+2.  Single-touch devices use the following Linux input events:
+
+    *   `ABS_X`: *(REQUIRED)* Reports the X coordinate of the tool.
+
+    *   `ABS_Y`: *(REQUIRED)* Reports the Y coordinate of the tool.
+
+    *   `ABS_PRESSURE`: *(optional)* Reports the physical pressure applied to the tip
+        of the tool or the signal strength of the touch contact.
+
+    *   `ABS_TOOL_WIDTH`: *(optional)* Reports the cross-sectional area or width of the
+        touch contact or of the tool itself.
+
+    *   `ABS_DISTANCE`: *(optional)* Reports the distance of the tool from the surface of
+        the touch device.
+
+    *   `ABS_TILT_X`: *(optional)* Reports the tilt of the tool from the surface of the
+        touch device along the X axis.
+
+    *   `ABS_TILT_Y`: *(optional)* Reports the tilt of the tool from the surface of the
+        touch device along the Y axis.
+
+    *   `BTN_TOUCH`: *(REQUIRED)* Indicates whether the tool is touching the device.
+
+    *   `BTN_LEFT`, `BTN_RIGHT`, `BTN_MIDDLE`, `BTN_BACK`, `BTN_SIDE`, `BTN_FORWARD`,
+        `BTN_EXTRA`, `BTN_STYLUS`, `BTN_STYLUS2`:
+        *(optional)* Reports [button](#buttons) states.
+
+    *   `BTN_TOOL_FINGER`, `BTN_TOOL_PEN`, `BTN_TOOL_RUBBER`, `BTN_TOOL_BRUSH`,
+        `BTN_TOOL_PENCIL`, `BTN_TOOL_AIRBRUSH`, `BTN_TOOL_MOUSE`, `BTN_TOOL_LENS`,
+        `BTN_TOOL_DOUBLETAP`, `BTN_TOOL_TRIPLETAP`, `BTN_TOOL_QUADTAP`:
+        *(optional)* Reports the [tool type](#tools-and-tool-types).
+
+3.  Multi-touch devices use the following Linux input events:
+
+    *   `ABS_MT_POSITION_X`: *(REQUIRED)* Reports the X coordinate of the tool.
+
+    *   `ABS_MT_POSITION_Y`: *(REQUIRED)* Reports the Y coordinate of the tool.
+
+    *   `ABS_MT_PRESSURE`: *(optional)* Reports the physical pressure applied to the
+        tip of the tool or the signal strength of the touch contact.
+
+    *   `ABS_MT_TOUCH_MAJOR`: *(optional)* Reports the cross-sectional area of the
+        touch contact, or the length of the longer dimension of the touch contact.
+
+    *   `ABS_MT_TOUCH_MINOR`: *(optional)* Reports the length of the shorter dimension of the
+        touch contact.  This axis should not be used if `ABS_MT_TOUCH_MAJOR` is reporting an
+        area measurement.
+
+    *   `ABS_MT_WIDTH_MAJOR`: *(optional)* Reports the cross-sectional area of the tool itself,
+        or the length of the longer dimension of the tool itself.
+        This axis should not be used if the dimensions of the tool itself are unknown.
+
+    *   `ABS_MT_WIDTH_MINOR`: *(optional)* Reports the length of the shorter dimension of
+        the tool itself. This axis should not be used if `ABS_MT_WIDTH_MAJOR` is reporting
+        an area measurement or if the dimensions of the tool itself are unknown.
+
+    *   `ABS_MT_ORIENTATION`: *(optional)* Reports the orientation of the tool.
+
+    *   `ABS_MT_DISTANCE`: *(optional)* Reports the distance of the tool from the
+        surface of the touch device.
+
+    *   `ABS_MT_TOOL_TYPE`: *(optional)* Reports the [tool type](#tools-and-tool-types) as
+        `MT_TOOL_FINGER` or `MT_TOOL_PEN`.
+
+    *   `ABS_MT_TRACKING_ID`: *(optional)* Reports the tracking id of the tool.
+        The tracking id is an arbitrary non-negative integer that is used to identify
+        and track each tool independently when multiple tools are active.  For example,
+        when multiple fingers are touching the device, each finger should be assigned a distinct
+        tracking id that is used as long as the finger remains in contact.  Tracking ids
+        may be reused when their associated tools move out of range.
+
+    *   `ABS_MT_SLOT`: *(optional)* Reports the slot id of the tool, when using the Linux
+        multi-touch protocol 'B'.  Refer to the Linux multi-touch protocol documentation
+        for more details.
+
+    *   `BTN_TOUCH`: *(REQUIRED)* Indicates whether the tool is touching the device.
+
+    *   `BTN_LEFT`, `BTN_RIGHT`, `BTN_MIDDLE`, `BTN_BACK`, `BTN_SIDE`, `BTN_FORWARD`,
+        `BTN_EXTRA`, `BTN_STYLUS`, `BTN_STYLUS2`:
+        *(optional)* Reports [button](#buttons) states.
+
+    *   `BTN_TOOL_FINGER`, `BTN_TOOL_PEN`, `BTN_TOOL_RUBBER`, `BTN_TOOL_BRUSH`,
+        `BTN_TOOL_PENCIL`, `BTN_TOOL_AIRBRUSH`, `BTN_TOOL_MOUSE`, `BTN_TOOL_LENS`,
+        `BTN_TOOL_DOUBLETAP`, `BTN_TOOL_TRIPLETAP`, `BTN_TOOL_QUADTAP`:
+        *(optional)* Reports the [tool type](#tools-and-tool-types).
+
+4.  If axes for both the single-touch and multi-touch protocol are defined, then
+    only the multi-touch axes will be used and the single-touch axes will be ignored.
+
+5.  The minimum and maximum values of the `ABS_X`, `ABS_Y`, `ABS_MT_POSITION_X`
+    and `ABS_MT_POSITION_Y` axes define the bounds of the active area of the device
+    in device-specific surface units.  In the case of a touch screen, the active area
+    describes the part of the touch device that actually covers the display.
+
+    For a touch screen, the system automatically interpolates the reported touch
+    positions in surface units to obtain touch positions in display pixels according
+    to the following calculation:
+
+        displayX = (x - minX) * displayWidth / (maxX - minX + 1)
+        displayY = (y - minY) * displayHeight / (maxY - minY + 1)
+
+    A touch screen may report touches outside of the reported active area.
+
+    Touches that are initiated outside the active area are not delivered to applications
+    but may be used for virtual keys.
+
+    Touches that are initiated inside the active area, or that enter and exit the display
+    area are delivered to applications.  Consequently, if a touch starts within the
+    bounds of an application and then moves outside of the active area, the application
+    may receive touch events with display coordinates that are negative or beyond the
+    bounds of the display.  This is expected behavior.
+
+    A touch device should never clamp touch coordinates to the bounds of the active
+    area.  If a touch exits the active area, it should be reported as being outside of
+    the active area, or it should not be reported at all.
+
+    For example, if the user's finger is touching near the top-left corner of the
+    touch screen, it may report a coordinate of (minX, minY).  If the finger continues
+    to move further outside of the active area, the touch screen should either start
+    reporting coordinates with components less than minX and minY, such as
+    (minX - 2, minY - 3), or it should stop reporting the touch altogether.
+    In other words, the touch screen should *not* be reporting (minX, minY)
+    when the user's finger is really touching outside of the active area.
+
+    Clamping touch coordinates to the display edge creates an artificial
+    hard boundary around the edge of the screen which prevents the system from
+    smoothly tracking motions that enter or exit the bounds of the display area.
+
+6.  The values reported by `ABS_PRESSURE` or `ABS_MT_PRESSURE`, if they
+    are reported at all, must be non-zero when the tool is touching the device
+    and zero otherwise to indicate that the tool is hovering.
+
+    Reporting pressure information is *optional* but strongly recommended.
+    Applications can use pressure information to implement pressure-sensitive drawing
+    and other effects.
+
+7.  The values reported by `ABS_TOOL_WIDTH`, `ABS_MT_TOUCH_MAJOR`, `ABS_MT_TOUCH_MINOR`,
+    `ABS_MT_WIDTH_MAJOR`, or `ABS_MT_WIDTH_MINOR` should be non-zero when the tool
+    is touching the device and zero otherwise, but this is not required.
+    For example, the touch device may be able to measure the size of finger touch
+    contacts but not stylus touch contacts.
+
+    Reporting size information is *optional* but strongly recommended.
+    Applications can use pressure information to implement size-sensitive drawing
+    and other effects.
+
+8.  The values reported by `ABS_DISTANCE` or `ABS_MT_DISTANCE` should approach
+    zero when the tool is touching the device.  The distance may remain non-zero
+    even when the tool is in direct contact.  The exact values reported depend
+    on the manner in which the hardware measures distance.
+
+    Reporting distance information is *optional* but recommended for
+    stylus devices.
+
+9.  The values reported by `ABS_TILT_X` and `ABS_TILT_Y` should be zero when the
+    tool is perpendicular to the device.  A non-zero tilt is taken as an indication
+    that the tool is held at an incline.
+
+    The tilt angles along the X and Y axes are assumed to be specified in degrees
+    from perpendicular.  The center point (perfectly perpendicular) is given
+    by `(max + min) / 2` for each axis.  Values smaller than the center point
+    represent a tilt up or to the left, values larger than the center point
+    represent a tilt down or to the right.
+
+    The `InputReader` converts the X and Y tilt components into a perpendicular
+    tilt angle ranging from 0 to `PI / 2` radians and a planar orientation angle
+    ranging from `-PI` to `PI` radians.  This representation results in a
+    description of orientation that is compatible with what is used to describe
+    finger touches.
+
+    Reporting tilt information is *optional* but recommended for stylus devices.
+
+10. If the tool type is reported by `ABS_MT_TOOL_TYPE`, it will supercede any tool
+    type information reported by `BTN_TOOL_*`.
+    If no tool type information is available at all, the tool type defaults to
+    `MotionEvent.TOOL_TYPE_FINGER`.
+
+11. A tool is determined to be active based on the following conditions:
+
+    *   When using the single-touch protocol, the tool is active if `BTN_TOUCH`,
+        or `BTN_TOOL_*` is 1.
+
+        This condition implies that the `InputReader` needs to have at least some
+        information about the nature of the tool, either whether it is touching,
+        or at least its tool type.  If no information is available,
+        then the tool is assumed to be inactive (out of range).
+
+    *   When using the multi-touch protocol 'A', the tool is active whenever it
+        appears in the most recent sync report.  When the tool stops appearing in
+        sync reports, it ceases to exist.
+
+    *   When using the multi-touch protocol 'B', the tool is active as long as
+        it has an active slot.  When the slot it cleared, the tool ceases to exist.
+
+12.  A tool is determined to be hovering based on the following conditions:
+
+    *   If the tool is `BTN_TOOL_MOUSE` or `BTN_TOOL_LENS`, then the tool
+        is not hovering, even if either of the following conditions are true.
+
+    *   If the tool is active and the driver reports pressure information,
+        and the reported pressure is zero, then the tool is hovering.
+
+    *   If the tool is active and the driver supports the `BTN_TOUCH` key code and
+        `BTN_TOUCH` has a value of zero, then the tool is hovering.
+
+13. The `InputReader` supports both multi-touch protocol 'A' and 'B'.  New drivers
+    should use the 'B' protocol but either will work.
+
+14. **As of Android Ice Cream Sandwich 4.0, touch screen drivers may need to be changed
+    to comply with the Linux input protocol specification.**
+
+    The following changes may be required:
+
+    *   When a tool becomes inactive (finger goes "up"), it should stop appearing
+        in subsequent multi-touch sync reports.  When all tools become inactive
+        (all fingers go "up"), the driver should send an empty sync report packet,
+        such as `SYN_MT_REPORT` followed by `SYN_REPORT`.
+
+        Previous versions of Android expected "up" events to be reported by sending
+        a pressure value of 0.  The old behavior was incompatible with the
+        Linux input protocol specification and is no longer supported.
+
+    *   Physical pressure or signal strength information should be reported using
+        `ABS_MT_PRESSURE`.
+
+        Previous versions of Android retrieved pressure information from
+        `ABS_MT_TOUCH_MAJOR`.  The old behavior was incompatible with the
+        Linux input protocol specification and is no longer supported.
+
+    *   Touch size information should be reported using `ABS_MT_TOUCH_MAJOR`.
+
+        Previous versions of Android retrieved size information from
+        `ABS_MT_TOOL_MAJOR`.  The old behavior was incompatible with the
+        Linux input protocol specification and is no longer supported.
+
+    Touch device drivers no longer need Android-specific customizations.
+    By relying on the standard Linux input protocol, Android can support a
+    wider variety of touch peripherals, such as external HID multi-touch
+    touch screens, using unmodified drivers.
+
+## Touch Device Operation ##
+
+The following is a brief summary of the touch device operation on Android.
+
+1.  The `EventHub` reads raw events from the `evdev` driver.
+
+2.  The `InputReader` consumes the raw events and updates internal state about
+    the position and other characteristics of each tool.  It also tracks
+    button states.
+
+3.  If the BACK or FORWARD buttons were pressed or released, the `InputReader`
+    notifies the `InputDispatcher` about the key event.
+
+4.  The `InputReader` determines whether a virtual key press occurred.  If so,
+    it notifies the `InputDispatcher` about the key event.
+
+5.  The `InputReader` determines whether the touch was initiated within the
+    bounds of the display.  If so, it notifies the `InputDispatcher` about
+    the touch event.
+
+6.  If there are no touching tools but there is at least one hovering tool,
+    the `InputReader` notifies the `InputDispatcher` about the hover event.
+
+7.  If the touch device type is *pointer*, the `InputReader` performs pointer
+    gesture detection, moves the pointer and spots accordingly and notifies
+    the `InputDispatcher` about the pointer event.
+
+8.  The `InputDispatcher` uses the `WindowManagerPolicy` to determine whether
+    the events should be dispatched and whether they should wake the device.
+    Then, the `InputDispatcher` delivers the events to the appropriate applications.
+
+## Touch Device Configuration ##
+
+Touch device behavior is determined by the device's axes, buttons, input properties,
+input device configuration, virtual key map and key layout.
+
+Refer to the following sections for more details about the files that
+participate in keyboard configuration:
+
+*   [Input Device Configuration Files](/tech/input/input-device-configuration-files.html)
+*   [Virtual Key Map Files](#virtual-key-map-files)
+
+### Properties ###
+
+The system relies on many input device configuration properties to configure
+and calibrate touch device behavior.
+
+One reason for this is that the device drivers for touch devices often report
+the characteristics of touches using device-specific units.
+
+For example, many touch devices measure the touch contact area
+using an internal device-specific scale, such as the total number of
+sensor nodes that were triggered by the touch.  This raw size value would
+not be meaningful applications because they would need to know about the
+physical size and other characteristics of the touch device sensor nodes.
+
+The system uses calibration parameters encoded in input device configuration
+files to decode, transform, and normalize the values reported by the touch
+device into a simpler standard representation that applications can understand.
+
+### Documentation Conventions ###
+
+For documentation purposes, we will use the following conventions to describe
+the values used by the system during the calibration process.
+
+#### Raw Axis Values ####
+
+The following expressions denote the raw values reported by the touch
+device driver as `EV_ABS` events.
+
+`raw.x`
+:   The value of the `ABS_X` or `ABS_MT_POSITION_X` axis.
+
+`raw.y`
+:   The value of the `ABS_Y` or `ABS_MT_POSITION_Y` axis.
+
+`raw.pressure`
+:   The value of the `ABS_PRESSURE` or `ABS_MT_PRESSURE` axis, or 0 if not available.
+
+`raw.touchMajor`
+:   The value of the `ABS_MT_TOUCH_MAJOR` axis, or 0 if not available.
+
+`raw.touchMinor`
+:   The value of the `ABS_MT_TOUCH_MINOR` axis, or `raw.touchMajor` if not available.
+
+`raw.toolMajor`
+:   The value of the `ABS_TOOL_WIDTH` or `ABS_MT_WIDTH_MAJOR` axis, or 0 if not available.
+
+`raw.toolMinor`
+:   The value of the `ABS_MT_WIDTH_MINOR` axis, or `raw.toolMajor` if not available.
+
+`raw.orientation`
+:   The value of the `ABS_MT_ORIENTATION` axis, or 0 if not available.
+
+`raw.distance`
+:   The value of the `ABS_DISTANCE` or `ABS_MT_DISTANCE` axis, or 0 if not available.
+
+`raw.tiltX`
+:   The value of the `ABS_TILT_X` axis, or 0 if not available.
+
+`raw.tiltY`
+:   The value of the `ABS_TILT_Y` axis, or 0 if not available.
+
+#### Raw Axis Ranges ####
+
+The following expressions denote the bounds of raw values.  They are obtained
+by calling `EVIOCGABS` ioctl for each axis.
+
+`raw.*.min`
+:   The inclusive minimum value of the raw axis.
+
+`raw.*.max`
+:   The inclusive maximum value of the raw axis.
+
+`raw.*.range`
+:   Equivalent to `raw.*.max - raw.*.min`.
+
+`raw.*.fuzz`
+:   The accuracy of the raw axis.  eg. fuzz = 1 implies values are accurate to +/- 1 unit.
+
+`raw.width`
+:   The inclusive width of the touch area, equivalent to `raw.x.range + 1`.
+
+`raw.height`
+:   The inclusive height of the touch area, equivalent to `raw.y.range + 1`.
+
+#### Output Ranges ####
+
+The following expressions denote the characteristics of the output coordinate system.
+The system uses linear interpolation to translate touch position information from
+the surface units used by the touch device into the output units that will
+be reported to applications such as display pixels.
+
+`output.width`
+:   The output width.  For touch screens (associated with a display), this
+    is the display width in pixels.  For touch pads (not associated with a display),
+    the output width equals `raw.width`, indicating that no interpolation will
+    be performed.
+
+`output.height`
+:   The output height.  For touch screens (associated with a display), this
+    is the display height in pixels.  For touch pads (not associated with a display),
+    the output height equals `raw.height`, indicating that no interpolation will
+    be performed.
+
+`output.diag`
+:   The diagonal length of the output coordinate system, equivalent to
+    `sqrt(output.width ^2 + output.height ^2)`.
+
+### Basic Configuration ###
+
+The touch input mapper uses many configuration properties in the input device
+configuration file to specify calibration values.  The following table describes
+some general purpose configuration properties.  All other properties are described
+in the following sections along with the fields they are used to calibrate.
+
+#### `touch.deviceType` ####
+
+*Definition:* `touch.deviceType` = `touchScreen` | `touchPad` | `pointer` | `default`
+
+Specifies the touch device type.
+
+*   If the value is `touchScreen`, the touch device is a touch screen associated
+    with a display.
+
+*   If the value is `touchPad`, the touch device is a touch pad not associated
+    with a display.
+
+*   If the value is `pointer`, the touch device is a touch pad not associated
+    with a display, and its motions are used for
+    [indirect multi-touch pointer gestures](#indirect-multi-touch-pointer-gestures).
+
+*   If the value is `default`, the system automatically detects the device type
+    according to the classification algorithm.
+
+Refer to the [Classification](#touch-device-classification) section for more details
+about how the device type influences the behavior of the touch device.
+
+Prior to Honeycomb, all touch devices were assumed to be touch screens.
+
+#### `touch.orientationAware` ####
+
+*Definition:* `touch.orientationAware` = `0` | `1`
+
+Specifies whether the touch device should react to display orientation changes.
+
+*   If the value is `1`, touch positions reported by the touch device are rotated
+    whenever the display orientation changes.
+
+*   If the value is `0`, touch positions reported by the touch device are immune
+    to display orientation changes.
+
+The default value is `1` if the device is a touch screen, `0` otherwise.
+
+The system distinguishes between internal and external touch screens and displays.
+An orientation aware internal touch screen is rotated based on the orientation
+of the internal display.  An orientation aware external touch screen is rotated
+based on the orientation of the external display.
+
+Orientation awareness is used to support rotation of touch screens on devices
+like the Nexus One.  For example, when the device is rotated clockwise 90 degrees
+from its natural orientation, the absolute positions of touches are remapped such
+that a touch in the top-left corner of the touch screen's absolute coordinate system
+is reported as a touch in the top-left corner of the display's rotated coordinate system.
+This is done so that touches are reported with the same coordinate system that
+applications use to draw their visual elements.
+
+Prior to Honeycomb, all touch devices were assumed to be orientation aware.
+
+#### `touch.gestureMode` ####
+
+*Definition:* `touch.gestureMode` = `pointer` | `spots` | `default`
+
+Specifies the presentation mode for pointer gestures.  This configuration property
+is only relevant when the touch device is of type *pointer*.
+
+*   If the value is `pointer`, the touch pad gestures are presented by way of a cursor
+    similar to a mouse pointer.
+
+*   If the value is `spots`, the touch pad gestures are presented by an anchor
+    that represents the centroid of the gesture and a set of circular spots
+    that represent the position of individual fingers.
+
+The default value is `pointer` when the `INPUT_PROP_SEMI_MT` input property
+is set, or `spots` otherwise.
+
+### `X` and `Y` Fields ###
+
+The X and Y fields provide positional information for the center of the contact area.
+
+#### Calculation ####
+
+The calculation is straightforward: positional information from the touch driver is
+linearly interpolated to the output coordinate system.
+
+    xScale = output.width / raw.width
+    yScale = output.height / raw.height
+
+    If not orientation aware or screen rotation is 0 degrees:
+    output.x = (raw.x - raw.x.min) * xScale
+    output.y = (raw.y - raw.y.min) * yScale
+    Else If rotation is 90 degrees:
+        output.x = (raw.y - raw.y.min) * yScale
+        output.y = (raw.x.max - raw.x) * xScale
+    Else If rotation is 180 degrees:
+        output.x = (raw.x.max - raw.x) * xScale
+        output.y = (raw.y.max - raw.y) * yScale
+    Else If rotation is 270 degrees:
+        output.x = (raw.y.max - raw.y) * yScale
+        output.y = (raw.x - raw.x.min) * xScale
+    End If
+
+### `TouchMajor`, `TouchMinor`, `ToolMajor`, `ToolMinor`, `Size` Fields ###
+
+The `TouchMajor` and `TouchMinor` fields describe the approximate dimensions
+of the contact area in output units (pixels).
+
+The `ToolMajor` and `ToolMinor` fields describe the approximate dimensions
+of the [tool](#tools-and-tool-types) itself in output units (pixels).
+
+The `Size` field describes the normalized size of the touch relative to
+the largest possible touch that the touch device can sense.  The smallest
+possible normalized size is 0.0 (no contact, or it is unmeasurable), and the largest
+possible normalized size is 1.0 (sensor area is saturated).
+
+When both the approximate length and breadth can be measured, then the `TouchMajor` field
+specifies the longer dimension and the `TouchMinor` field specifies the shorter dimension
+of the contact area.  When only the approximate diameter of the contact area can be measured,
+then the `TouchMajor` and `TouchMinor` fields will be equal.
+
+Likewise, the `ToolMajor` field specifies the longer dimension and the `ToolMinor`
+field specifies the shorter dimension of the tool's cross-sectional area.
+
+If the touch size is unavailable but the tool size is available, then the tool size
+will be set equal to the touch size.  Conversely, if the tool size is unavailable
+but the touch size is available, then the touch size will be set equal to the tool size.
+
+Touch devices measure or report the touch size and tool size in various ways.
+The current implementation supports three different kinds of measurements:
+diameter, area, and geometric bounding box in surface units.
+
+#### `touch.size.calibration` ####
+
+*Definition:* `touch.size.calibration` = `none` | `geometric` | `diameter`
+| `area` | `default`
+
+Specifies the kind of measurement used by the touch driver to report the
+touch size and tool size.
+
+*   If the value is `none`, the size is set to zero.
+
+*   If the value is `geometric`, the size is assumed to be specified in the same
+    surface units as the position, so it is scaled in the same manner.
+
+*   If the value is `diameter`, the size is assumed to be proportional to
+    the diameter (width) of the touch or tool.
+
+*   If the value is `area`, the size is assumed to be proportional to the
+    area of the touch or tool.
+
+*   If the value is `default`, the system uses the `geometric` calibration if the
+    `raw.touchMajor` or `raw.toolMajor` axis is available, otherwise it uses
+    the `none` calibration.
+
+#### `touch.size.scale` ####
+
+*Definition:* `touch.size.scale` = &lt;a non-negative floating point number&gt;
+
+Specifies a constant scale factor used in the calibration.
+
+The default value is `1.0`.
+
+#### `touch.size.bias` ####
+
+*Definition:* `touch.size.bias` = &lt;a non-negative floating point number&gt;
+
+Specifies a constant bias value used in the calibration.
+
+The default value is `0.0`.
+
+#### `touch.size.isSummed` ####
+
+*Definition:* `touch.size.isSummed` = `0` | `1`
+
+Specifies whether the size is reported as the sum of the sizes of all
+active contacts, or is reported individually for each contact.
+
+*   If the value is `1`, the reported size will be divided by the number
+    of contacts prior to use.
+
+*   If the value is `0`, the reported size will be used as is.
+
+The default value is `0`.
+
+Some touch devices, particularly "Semi-MT" devices cannot distinguish the
+individual dimensions of multiple contacts so they report a size measurement
+that represents their total area or width.  This property should only be set to
+`1` for such devices.  If in doubt, set this value to `0`.
+
+#### Calculation ####
+
+The calculation of the `TouchMajor`, `TouchMinor`, `ToolMajor`, `ToolMinor`
+and `Size` fields depends on the specified calibration parameters.
+
+    If raw.touchMajor and raw.toolMajor are available:
+        touchMajor = raw.touchMajor
+        touchMinor = raw.touchMinor
+        toolMajor = raw.toolMajor
+        toolMinor = raw.toolMinor
+    Else If raw.touchMajor is available:
+        toolMajor = touchMajor = raw.touchMajor
+        toolMinor = touchMinor = raw.touchMinor
+    Else If raw.toolMajor is available:
+        touchMajor = toolMajor = raw.toolMajor
+        touchMinor = toolMinor = raw.toolMinor
+    Else
+        touchMajor = toolMajor = 0
+        touchMinor = toolMinor = 0
+        size = 0
+    End If
+
+    size = avg(touchMajor, touchMinor)
+
+    If touch.size.isSummed == 1:
+        touchMajor = touchMajor / numberOfActiveContacts
+        touchMinor = touchMinor / numberOfActiveContacts
+        toolMajor = toolMajor / numberOfActiveContacts
+        toolMinor = toolMinor / numberOfActiveContacts
+        size = size / numberOfActiveContacts
+    End If
+
+    If touch.size.calibration == "none":
+        touchMajor = toolMajor = 0
+        touchMinor = toolMinor = 0
+        size = 0
+    Else If touch.size.calibration == "geometric":
+        outputScale = average(output.width / raw.width, output.height / raw.height)
+        touchMajor = touchMajor * outputScale
+        touchMinor = touchMinor * outputScale
+        toolMajor = toolMajor * outputScale
+        toolMinor = toolMinor * outputScale
+    Else If touch.size.calibration == "area":
+        touchMajor = sqrt(touchMajor)
+        touchMinor = touchMajor
+        toolMajor = sqrt(toolMajor)
+        toolMinor = toolMajor
+    Else If touch.size.calibration == "diameter":
+        touchMinor = touchMajor
+        toolMinor = toolMajor
+    End If
+
+    If touchMajor != 0:
+        output.touchMajor = touchMajor * touch.size.scale + touch.size.bias
+    Else
+        output.touchMajor = 0
+    End If
+
+    If touchMinor != 0:
+        output.touchMinor = touchMinor * touch.size.scale + touch.size.bias
+    Else
+        output.touchMinor = 0
+    End If
+
+    If toolMajor != 0:
+        output.toolMajor = toolMajor * touch.size.scale + touch.size.bias
+    Else
+        output.toolMajor = 0
+    End If
+
+    If toolMinor != 0:
+        output.toolMinor = toolMinor * touch.size.scale + touch.size.bias
+    Else
+        output.toolMinor = 0
+    End If
+
+    output.size = size
+
+### `Pressure` Field ###
+
+The `Pressure` field describes the approximate physical pressure applied to the
+touch device as a normalized value between 0.0 (no touch) and 1.0 (full force).
+
+A zero pressure indicates that the tool is hovering.
+
+#### `touch.pressure.calibration` ####
+
+*Definition:* `touch.pressure.calibration` = `none` | `physical` | `amplitude` | `default`
+
+Specifies the kind of measurement used by the touch driver to report the pressure.
+
+*   If the value is `none`, the pressure is unknown so it is set to 1.0 when
+    touching and 0.0 when hovering.
+
+*   If the value is `physical`, the pressure axis is assumed to measure the actual
+    physical intensity of pressure applied to the touch pad.
+
+*   If the value is `amplitude`, the pressure axis is assumed to measure the signal
+    amplitude, which is related to the size of the contact and the pressure applied.
+
+*   If the value is `default`, the system uses the `physical` calibration if the
+    pressure axis available, otherwise uses `none`.
+
+#### `touch.pressure.scale` ####
+
+*Definition:* `touch.pressure.scale` = &lt;a non-negative floating point number&gt;
+
+Specifies a constant scale factor used in the calibration.
+
+The default value is `1.0 / raw.pressure.max`.
+
+#### Calculation ####
+
+The calculation of the `Pressure` field depends on the specified calibration parameters.
+
+    If touch.pressure.calibration == "physical" or "amplitude":
+        output.pressure = raw.pressure * touch.pressure.scale
+    Else
+        If hovering:
+            output.pressure = 0
+        Else
+            output.pressure = 1
+        End If
+    End If
+
+### `Orientation` and `Tilt` Fields ###
+
+The `Orientation` field describes the orientation of the touch and tool as an
+angular measurement.  An orientation of `0` indicates that the major axis is
+oriented vertically, `-PI/2` indicates that the major axis is oriented to the left,
+`PI/2` indicates that the major axis is oriented to the right.  When a stylus
+tool is present, the orientation range may be described in a full circle range
+from `-PI` or `PI`.
+
+The `Tilt` field describes the inclination of the tool as an angular measurement.
+A tilt of `0` indicates that the tool is perpendicular to the surface.
+A tilt of `PI/2` indicates that the tool is flat on the surface.
+
+#### `touch.orientation.calibration` ####
+
+*Definition:* `touch.orientation.calibration` = `none` | `interpolated` | `vector` | `default`
+
+Specifies the kind of measurement used by the touch driver to report the orientation.
+
+*   If the value is `none`, the orientation is unknown so it is set to 0.
+
+*   If the value is `interpolated`, the orientation is linearly interpolated such that a
+    raw value of `raw.orientation.min` maps to `-PI/2` and a raw value of
+    `raw.orientation.max` maps to `PI/2`.  The center value of
+    `(raw.orientation.min + raw.orientation.max) / 2` maps to `0`.
+
+*   If the value is `vector`, the orientation is interpreted as a packed vector consisiting
+    of two signed 4-bit fields.  This representation is used on Atmel Object Based Protocol
+    parts.  When decoded, the vector yields an orientation angle and confidence
+    magnitude.  The confidence magnitude is used to scale the size information,
+    unless it is geometric.
+
+*   If the value is `default`, the system uses the `interpolated` calibration if the
+    orientation axis available, otherwise uses `none`.
+
+#### Calculation ####
+
+The calculation of the `Orientation` and `Tilt` fields depends on the specified
+calibration parameters and available input.
+
+    If touch.tiltX and touch.tiltY are available:
+        tiltXCenter = average(raw.tiltX.min, raw.tiltX.max)
+        tiltYCenter = average(raw.tiltY.min, raw.tiltY.max)
+        tiltXAngle = (raw.tiltX - tiltXCenter) * PI / 180
+        tiltYAngle = (raw.tiltY - tiltYCenter) * PI / 180
+        output.orientation = atan2(-sin(tiltXAngle), sinf(tiltYAngle))
+        output.tilt = acos(cos(tiltXAngle) * cos(tiltYAngle))
+    Else If touch.orientation.calibration == "interpolated":
+        center = average(raw.orientation.min, raw.orientation.max)
+        output.orientation = PI / (raw.orientation.max - raw.orientation.min)
+        output.tilt = 0
+    Else If touch.orientation.calibration == "vector":
+        c1 = (raw.orientation & 0xF0) >> 4
+        c2 = raw.orientation & 0x0F
+
+        If c1 != 0 or c2 != 0:
+            If c1 >= 8 Then c1 = c1 - 16
+            If c2 >= 8 Then c2 = c2 - 16
+            angle = atan2(c1, c2) / 2
+            confidence = sqrt(c1*c1 + c2*c2)
+
+            output.orientation = angle
+
+            If touch.size.calibration == "diameter" or "area":
+                scale = 1.0 + confidence / 16
+                output.touchMajor *= scale
+                output.touchMinor /= scale
+                output.toolMajor *= scale
+                output.toolMinor /= scale
+            End If
+        Else
+            output.orientation = 0
+        End If
+        output.tilt = 0
+    Else
+        output.orientation = 0
+        output.tilt = 0
+    End If
+
+    If orientation aware:
+        If screen rotation is 90 degrees:
+            output.orientation = output.orientation - PI / 2
+        Else If screen rotation is 270 degrees:
+            output.orientation = output.orientation + PI / 2
+        End If
+    End If
+
+### `Distance` Field ###
+
+The `Distance` field describes the distance between the tool and the touch device
+surface.  A value of 0.0 indicates direct contact and larger values indicate
+increasing distance from the surface.
+
+#### `touch.distance.calibration` ####
+
+*Definition:* `touch.distance.calibration` = `none` | `scaled` | `default`
+
+Specifies the kind of measurement used by the touch driver to report the distance.
+
+*   If the value is `none`, the distance is unknown so it is set to 0.
+
+*   If the value is `scaled`, the reported distance is multiplied by a
+    constant scale factor.
+
+*   If the value is `default`, the system uses the `scaled` calibration if the
+    distance axis available, otherwise uses `none`.
+
+#### `touch.distance.scale` ####
+
+*Definition:* `touch.distance.scale` = &lt;a non-negative floating point number&gt;
+
+Specifies a constant scale factor used in the calibration.
+
+The default value is `1.0`.
+
+#### Calculation ####
+
+The calculation of the `Distance` field depends on the specified calibration parameters.
+
+    If touch.distance.calibration == "scaled":
+        output.distance = raw.distance * touch.distance.scale
+    Else
+        output.distance = 0
+    End If
+
+### Example ###
+
+    # Input device configuration file for a touch screen that supports pressure,
+    # size and orientation.  The pressure and size scale factors were obtained
+    # by measuring the characteristics of the device itself and deriving
+    # useful approximations based on the resolution of the touch sensor and the
+    # display.
+    #
+    # Note that these parameters are specific to a particular device model.
+    # Different parameters will need to be used for other devices.
+
+    # Basic Parameters
+    touch.deviceType = touchScreen
+    touch.orientationAware = 1
+
+    # Size
+    # Based on empirical measurements, we estimate the size of the contact
+    # using size = sqrt(area) * 28 + 0.
+    touch.size.calibration = area
+    touch.size.scale = 28
+    touch.size.bias = 0
+    touch.size.isSummed = 0
+
+    # Pressure
+    # Driver reports signal strength as pressure.
+    #
+    # A normal index finger touch typically registers about 80 signal strength
+    # units although we don't expect these values to be accurate.
+    touch.pressure.calibration = amplitude
+    touch.pressure.scale = 0.0125
+
+    # Orientation
+    touch.orientation.calibration = vector
+
+### Compatibility Notes ###
+
+The configuration properties for touch devices changed significantly in
+Android Ice Cream Sandwich 4.0.  **All input device configuration files for touch
+devices must be updated to use the new configuration properties.**
+
+Older touch device [drivers](#touch-device-driver-requirements) may also need to be
+updated.
+
+## Virtual Key Map Files ##
+
+Touch devices are often used to implement virtual keys.
+
+There are several ways of doing this, depending on the capabilities of the
+touch controller.  Some touch controllers can be directly configured to implement
+soft keys by setting firmware registers.  Other times it is desirable to perform
+the mapping from touch coordinates to key codes in software.
+
+When virtual keys are implemented in software, the kernel must export a virtual key map
+file called `virtualkeys.<devicename>` as a board property.  For example,
+if the touch screen device drivers reports its name as "touchyfeely" then
+the virtual key map file must have the path `/sys/board_properties/virtualkeys.touchyfeely`.
+
+A virtual key map file describes the coordinates and Linux key codes of virtual keys
+on the touch screen.
+
+In addition to the virtual key map file, there must be a corresponding key layout
+file and key character map file to map the Linux key codes to Android key codes and
+to specify the type of the keyboard device (usually `SPECIAL_FUNCTION`).
+
+### Syntax ###
+
+A virtual key map file is a plain text file consisting of a sequence of virtual key
+layout descriptions either separated by newlines or by colons.
+
+Comment lines begin with '#' and continue to the end of the line.
+
+Each virtual key is described by 6 colon-delimited components:
+
+*   `0x01`: A version code.  Must always be `0x01`.
+*   &lt;Linux key code&gt;: The Linux key code of the virtual key.
+*   &lt;centerX&gt;: The X pixel coordinate of the center of the virtual key.
+*   &lt;centerY&gt;: The Y pixel coordinate of the center of the virtual key.
+*   &lt;width&gt;: The width of the virtual key in pixels.
+*   &lt;height&gt;: The height of the virtual key in pixels.
+
+All coordinates and sizes are specified in terms of the display coordinate system.
+
+Here is a virtual key map file all written on one line.
+
+    # All on one line
+    0x01:158:55:835:90:55:0x01:139:172:835:125:55:0x01:102:298:835:115:55:0x01:217:412:835:95:55
+
+The same virtual key map file can also be written on multiple lines.
+
+    # One key per line
+    0x01:158:55:835:90:55
+    0x01:139:172:835:125:55
+    0x01:102:298:835:115:55
+    0x01:217:412:835:95:55
+
+In the above example, the touch screen has a resolution of 480x800.  Accordingly, all of
+the virtual keys have a &lt;centerY&gt; coordinate of 835, which is a little bit below
+the visible area of the touch screen.
+
+The first key has a Linux scan code of `158` (`KEY_BACK`), centerX of `55`,
+centerY of `835`, width of `90` and height of `55`.
+
+### Example ###
+
+Virtual key map file: `/sys/board_properties/virtualkeys.touchyfeely`.
+
+    0x01:158:55:835:90:55
+    0x01:139:172:835:125:55
+    0x01:102:298:835:115:55
+    0x01:217:412:835:95:55
+
+Key layout file: `/system/usr/keylayout/touchyfeely.kl`.
+
+    key 158 BACK
+    key 139 MENU
+    key 102 HOME
+    key 217 SEARCH
+
+Key character map file: `/system/usr/keychars/touchyfeely.kcm`.
+
+    type SPECIAL_FUNCTION
+
+## Indirect Multi-touch Pointer Gestures ##
+
+In pointer mode, the system interprets the following gestures:
+
+1.  Single finger tap: click.
+
+2.  Single finger motion: move the pointer.
+
+3.  Single finger motion plus button presses: drag the pointer.
+
+4.  Two finger motion both fingers moving in the same direction: drag the area under the pointer
+    in that direction.  The pointer itself does not move.
+
+5.  Two finger motion both fingers moving towards each other or apart in
+    different directions: pan/scale/rotate the area surrounding the pointer.
+    The pointer itself does not move.
+
+6.  Multiple finger motion: freeform gesture.
+
+## Further Reading ##
+
+1. [Linux multi-touch protocol](http://www.kernel.org/doc/Documentation/input/multi-touch-protocol.txt)
+2. [ENAC list of available multitouch devices on Linux](http://lii-enac.fr/en/architecture/linux-input/multitouch-devices.html)
diff --git a/src/tech/input/validate-keymaps.md b/src/tech/input/validate-keymaps.md
new file mode 100644
index 0000000..8d8df9a
--- /dev/null
+++ b/src/tech/input/validate-keymaps.md
@@ -0,0 +1,96 @@
+<!--
+   Copyright 2011 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+# Validate Keymaps Tool #
+
+The Android framework has a small tool called `validatekeymaps` to validate the
+syntax of input device configuration files, key layout files, key character
+maps files and virtual key definition files.
+
+## Compilation ##
+
+To compile `validatekeymaps`, set up the development environment, download
+the Android source tree, compile it, then run:
+
+    $ mmm frameworks/base/tools/validatekeymaps
+
+This command should compile a host tool called validatekeymaps into the
+`out/host/&lt;os&gt;/bin` directory.
+
+## Usage ##
+
+If you ran `envsetup.sh` to set up your development environment, then the
+`validatekeymaps` tool should already be on your path.  You can verify
+this by running `validatekeymaps`.
+
+    $ validatekeymaps
+
+    Keymap Validation Tool
+
+    Usage:
+     validatekeymaps [*.kl] [*.kcm] [*.idc] [virtualkeys.*] [...]
+       Validates the specified key layouts, key character maps, 
+       input device configurations, or virtual key definitions.
+
+Then all you need to do is run `validatekeymaps` an give it the path of
+one or more files to validate.
+
+    $ validatekeymaps frameworks/base/data/keyboards/Generic.kl
+
+    Validating file 'frameworks/base/data/keyboards/Generic.kl'...
+    No errors.
+
+    Success.
+
+And if there is an error...
+
+    $ validatekeymaps Bad.kl
+
+    Validating file 'Bad.kl'...
+    E/KeyLayoutMap(87688): Bad.kl:24: Expected keyword, got 'ke'.
+    Error -22 parsing key layout file.
+
+    Failed!
+
+## Automation ##
+
+It is a *very* good idea to run `validatekeymaps` on all configuration files
+before installing them on a device.
+
+The process can easily be automated as part of the build system by using a
+script or a makefile.
+
+The following sample makefile is based on the contents of
+`frameworks/base/data/keyboards/Android.mk`.
+
+    # This makefile performs build time validation of framework keymap files.
+
+    LOCAL_PATH := $(call my-dir)
+
+    # Validate all key maps.
+    include $(CLEAR_VARS)
+
+    validatekeymaps := $(HOST_OUT_EXECUTABLES)/validatekeymaps$(HOST_EXECUTABLE_SUFFIX)
+    files := MyKeyboard.kl MyKeyboard.kcm MyTouchScreen.idc
+
+    LOCAL_MODULE := validate_framework_keymaps
+    LOCAL_MODULE_TAGS := optional
+    LOCAL_REQUIRED_MODULES := validatekeymaps
+
+    validate_framework_keymaps: $(files)
+        $(hide) $(validatekeymaps) $(files)
+
+    include $(BUILD_PHONY_PACKAGE)
diff --git a/src/tech/sidebar.md b/src/tech/sidebar.md
index 67ec0a4..3f81124 100644
--- a/src/tech/sidebar.md
+++ b/src/tech/sidebar.md
@@ -3,3 +3,4 @@
 - [Debugging](/tech/debugging/index.html)
 - [Encryption](/tech/encryption/index.html)
 - [Security](/tech/security/index.html)
+- [Input](/tech/input/index.html)