s.a.c. redesign, first checkin

Change-Id: I4dead2f18bc5e4a38f204c92198a267c286e775d
diff --git a/src/devices/tech/dalvik/dalvik-bytecode.css b/src/devices/tech/dalvik/dalvik-bytecode.css
new file mode 100644
index 0000000..e4a5caa
--- /dev/null
+++ b/src/devices/tech/dalvik/dalvik-bytecode.css
@@ -0,0 +1,165 @@
+h1 {
+    font-family: serif;
+    color: #222266;
+}
+
+h2 {
+    font-family: serif;
+    border-top-style: solid;
+    border-top-width: 2px;
+    border-color: #ccccdd;
+    padding-top: 12px;
+    margin-top: 48px;
+    margin-bottom: 2px;
+    color: #222266;
+}
+
+@media print {
+    table {
+        font-size: 8pt;
+    }
+}
+
+@media screen {
+    table {
+        font-size: 10pt;
+    }
+}
+
+
+/* general for all tables */
+
+table {
+    border-collapse: collapse;
+    margin-top: 12px;
+}
+
+table th {
+    font-family: sans-serif;
+    background: #aabbff;
+}
+
+table td {
+    font-family: sans-serif;
+    border-top-style: solid;
+    border-bottom-style: solid;
+    border-width: 1px;
+    border-color: #aaaaff;
+    padding-top: 4px;
+    padding-bottom: 4px;
+    padding-left: 4px;
+    padding-right: 6px;
+    background: #eeeeff;
+}
+
+table td p {
+    margin-top: 4pt;
+    margin-bottom: 0pt;
+}
+
+
+
+/* opcodes table */
+
+table.instruc {
+    margin-top: 24px;
+    margin-bottom: 24px;
+    margin-left: 48px;
+    margin-right: 48px;
+}
+
+table.instruc td {
+    font-family: sans-serif;
+    border-top-style: solid;
+    border-bottom-style: solid;
+    border-width: 1px;
+    padding-top: 4px;
+    padding-bottom: 4px;
+    padding-left: 2px;
+    padding-right: 2px;
+}
+
+table.instruc td:first-child {
+    font-family: monospace;
+    font-size: 90%;
+    vertical-align: top;
+    width: 12%;
+}
+
+table.instruc td:first-child + td {
+    font-family: monospace;
+    font-size: 90%;
+    vertical-align: top;
+    width: 23%;
+}
+
+table.instruc td:first-child + td i {
+    font-family: sans-serif;
+    font-size: 90%;
+}
+
+table.instruc td:first-child + td + td {
+    vertical-align: top;
+    width: 28%;
+}
+
+table.instruc td:first-child + td + td + td {
+    vertical-align: top;
+    width: 37%;
+}
+
+
+/* supplemental opcode format table */
+
+table.supplement {
+    margin-top: 24px;
+    margin-bottom: 24px;
+    margin-left: 48px;
+    margin-right: 48px;
+}
+
+table.supplement td:first-child {
+    font-family: monospace;
+    vertical-align: top;
+    width: 20%;
+}
+
+table.supplement td:first-child + td {
+    font-family: monospace;
+    vertical-align: top;
+    width: 20%;
+}
+
+table.supplement td:first-child + td + td {
+    font-family: sans-serif;
+    vertical-align: top;
+    width: 60%;
+}
+
+
+/* math details table */
+
+table.math {
+    margin-top: 24px;
+    margin-bottom: 24px;
+    margin-left: 48px;
+    margin-right: 48px;
+}
+
+table.math td:first-child {
+    font-family: monospace;
+    vertical-align: top;
+    width: 10%;
+}
+
+table.math td:first-child + td {
+    font-family: monospace;
+    vertical-align: top;
+    width: 30%;
+}
+
+table.math td:first-child + td + td {
+    font-family: sans-serif;
+    vertical-align: top;
+    width: 60%;
+}
diff --git a/src/devices/tech/dalvik/dalvik-bytecode.jd b/src/devices/tech/dalvik/dalvik-bytecode.jd
new file mode 100644
index 0000000..7883850
--- /dev/null
+++ b/src/devices/tech/dalvik/dalvik-bytecode.jd
@@ -0,0 +1,1554 @@
+page.title=Bytecode for the Dalvik VM
+@jd:body
+
+<!--
+    Copyright 2010 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.
+-->
+<p>Copyright &copy; 2007 The Android Open Source Project
+
+<h2>General Design</h2>
+
+<ul>
+<li>The machine model and calling conventions are meant to approximately
+  imitate common real architectures and C-style calling conventions:
+  <ul>
+  <li>The VM is register-based, and frames are fixed in size upon creation.
+    Each frame consists of a particular number of registers (specified by
+    the method) as well as any adjunct data needed to execute the method,
+    such as (but not limited to) the program counter and a reference to the
+    <code>.dex</code> file that contains the method.
+  </li>
+  <li>When used for bit values (such as integers and floating point
+    numbers), registers are considered 32 bits wide. Adjacent register
+    pairs are used for 64-bit values. There is no alignment requirement
+    for register pairs.
+  </li>
+  <li>When used for object references, registers are considered wide enough
+    to hold exactly one such reference.
+  </li>
+  <li>In terms of bitwise representation, <code>(Object) null == (int)
+    0</code>.
+  </li>
+  <li>The <i>N</i> arguments to a method land in the last <i>N</i> registers
+    of the method's invocation frame, in order. Wide arguments consume
+    two registers. Instance methods are passed a <code>this</code> reference
+    as their first argument.
+  </li>
+  </ul>
+<li>The storage unit in the instruction stream is a 16-bit unsigned quantity.
+  Some bits in some instructions are ignored / must-be-zero.
+</li>
+<li>Instructions aren't gratuitously limited to a particular type. For
+  example, instructions that move 32-bit register values without interpretation
+  don't have to specify whether they are moving ints or floats.
+</li>
+<li>There are separately enumerated and indexed constant pools for
+  references to strings, types, fields, and methods.
+</li>
+<li>Bitwise literal data is represented in-line in the instruction stream.</li>
+<li>Because, in practice, it is uncommon for a method to need more than
+  16 registers, and because needing more than eight registers <i>is</i>
+  reasonably common, many instructions are limited to only addressing
+  the first 16
+  registers. When reasonably possible, instructions allow references to
+  up to the first 256 registers. In addition, some instructions have variants
+  that allow for much larger register counts, including a pair of catch-all
+  <code>move</code> instructions that can address registers in the range
+  <code>v0</code> &ndash; <code>v65535</code>.
+  In cases where an instruction variant isn't
+  available to address a desired register, it is expected that the register
+  contents get moved from the original register to a low register (before the
+  operation) and/or moved from a low result register to a high register
+  (after the operation).
+</li>
+<li>There are several "pseudo-instructions" that are used to hold
+  variable-length data payloads, which are referred to by regular
+  instructions (for example,
+  <code>fill-array-data</code>). Such instructions must never be
+  encountered during the normal flow of execution. In addition, the
+  instructions must be located on even-numbered bytecode offsets (that is,
+  4-byte aligned). In order to meet this requirement, dex generation tools
+  must emit an extra <code>nop</code> instruction as a spacer if such an
+  instruction would otherwise be unaligned. Finally, though not required,
+  it is expected that most tools will choose to emit these instructions at
+  the ends of methods, since otherwise it would likely be the case that
+  additional instructions would be needed to branch around them.
+</li>
+<li>When installed on a running system, some instructions may be altered,
+  changing their format, as an install-time static linking optimization.
+  This is to allow for faster execution once linkage is known.
+  See the associated
+  <a href="instruction-formats.html">instruction formats document</a>
+  for the suggested variants. The word "suggested" is used advisedly;
+  it is not mandatory to implement these.
+</li>
+<li>Human-syntax and mnemonics:
+  <ul>
+  <li>Dest-then-source ordering for arguments.</li>
+  <li>Some opcodes have a disambiguating name suffix to indicate the type(s)
+    they operate on:
+    <ul>
+    <li>Type-general 32-bit opcodes are unmarked.</li>
+    <li>Type-general 64-bit opcodes are suffixed with <code>-wide</code>.</li>
+    <li>Type-specific opcodes are suffixed with their type (or a
+    straightforward abbreviation), one of: <code>-boolean</code>
+    <code>-byte</code> <code>-char</code> <code>-short</code>
+    <code>-int</code> <code>-long</code> <code>-float</code>
+    <code>-double</code> <code>-object</code> <code>-string</code>
+    <code>-class</code> <code>-void</code>.</li>
+    </ul>
+  </li>
+  <li>Some opcodes have a disambiguating suffix to distinguish
+    otherwise-identical operations that have different instruction layouts
+    or options. These suffixes are separated from the main names with a slash
+    ("<code>/</code>") and mainly exist at all to make there be a one-to-one
+    mapping with static constants in the code that generates and interprets
+    executables (that is, to reduce ambiguity for humans).
+  </li>
+  <li>In the descriptions here, the width of a value (indicating, e.g., the
+    range of a constant or the number of registers possibly addressed) is
+    emphasized by the use of a character per four bits of width.
+  </li>
+  <li>For example, in the instruction
+    "<code>move-wide/from16 vAA, vBBBB</code>":
+    <ul>
+    <li>"<code>move</code>" is the base opcode, indicating the base operation
+    (move a register's value).</li>
+    <li>"<code>wide</code>" is the name suffix, indicating that it operates
+    on wide (64 bit) data.</li>
+    <li>"<code>from16</code>" is the opcode suffix, indicating a variant
+    that has a 16-bit register reference as a source.</li>
+    <li>"<code>vAA</code>" is the destination register (implied by the
+    operation; again, the rule is that destination arguments always come
+    first), which must be in the range <code>v0</code> &ndash;
+    <code>v255</code>.</li>
+    <li>"<code>vBBBB</code>" is the source register, which must be in the
+    range <code>v0</code> &ndash; <code>v65535</code>.</li>
+    </ul>
+  </li>
+  </ul>
+</li>
+<li>See the <a href="instruction-formats.html">instruction formats
+  document</a> for more details about the various instruction formats
+  (listed under "Op &amp; Format") as well as details about the opcode
+  syntax.
+</li>
+<li>See the <a href="dex-format.html"><code>.dex</code> file format
+  document</a> for more details about where the bytecode fits into
+  the bigger picture.
+</li>
+</ul>
+
+<h2>Summary of Instruction Set</h2>
+
+<table class="instruc">
+<thead>
+<tr>
+  <th>Op &amp; Format</th>
+  <th>Mnemonic / Syntax</th>
+  <th>Arguments</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>00 10x</td>
+  <td>nop</td>
+  <td>&nbsp;</td>
+  <td>Waste cycles.
+    <p><b>Note:</b>
+    Data-bearing pseudo-instructions are tagged with this opcode, in which
+    case the high-order byte of the opcode unit indicates the nature of
+    the data. See "<code>packed-switch-payload</code> Format",
+    "<code>sparse-switch-payload</code> Format", and
+    "<code>fill-array-data-payload</code> Format" below.</p>
+  </td>
+</tr>
+<tr>
+  <td>01 12x</td>
+  <td>move vA, vB</td>
+  <td><code>A:</code> destination register (4 bits)<br/>
+    <code>B:</code> source register (4 bits)</td>
+  <td>Move the contents of one non-object register to another.</td>
+</tr>
+<tr>
+  <td>02 22x</td>
+  <td>move/from16 vAA, vBBBB</td>
+  <td><code>A:</code> destination register (8 bits)<br/>
+    <code>B:</code> source register (16 bits)</td>
+  <td>Move the contents of one non-object register to another.</td>
+</tr>
+<tr>
+  <td>03 32x</td>
+  <td>move/16 vAAAA, vBBBB</td>
+  <td><code>A:</code> destination register (16 bits)<br/>
+    <code>B:</code> source register (16 bits)</td>
+  <td>Move the contents of one non-object register to another.</td>
+</tr>
+<tr>
+  <td>04 12x</td>
+  <td>move-wide vA, vB</td>
+  <td><code>A:</code> destination register pair (4 bits)<br/>
+    <code>B:</code> source register pair (4 bits)</td>
+  <td>Move the contents of one register-pair to another.
+    <p><b>Note:</b>
+    It is legal to move from <code>v<i>N</i></code> to either
+    <code>v<i>N-1</i></code> or <code>v<i>N+1</i></code>, so implementations
+    must arrange for both halves of a register pair to be read before
+    anything is written.</p>
+  </td>
+</tr>
+<tr>
+  <td>05 22x</td>
+  <td>move-wide/from16 vAA, vBBBB</td>
+  <td><code>A:</code> destination register pair (8 bits)<br/>
+    <code>B:</code> source register pair (16 bits)</td>
+  <td>Move the contents of one register-pair to another.
+    <p><b>Note:</b>
+    Implementation considerations are the same as <code>move-wide</code>,
+    above.</p>
+  </td>
+</tr>
+<tr>
+  <td>06 32x</td>
+  <td>move-wide/16 vAAAA, vBBBB</td>
+  <td><code>A:</code> destination register pair (16 bits)<br/>
+    <code>B:</code> source register pair (16 bits)</td>
+  <td>Move the contents of one register-pair to another.
+    <p><b>Note:</b>
+    Implementation considerations are the same as <code>move-wide</code>,
+    above.</p>
+  </td>
+</tr>
+<tr>
+  <td>07 12x</td>
+  <td>move-object vA, vB</td>
+  <td><code>A:</code> destination register (4 bits)<br/>
+    <code>B:</code> source register (4 bits)</td>
+  <td>Move the contents of one object-bearing register to another.</td>
+</tr>
+<tr>
+  <td>08 22x</td>
+  <td>move-object/from16 vAA, vBBBB</td>
+  <td><code>A:</code> destination register (8 bits)<br/>
+    <code>B:</code> source register (16 bits)</td>
+  <td>Move the contents of one object-bearing register to another.</td>
+</tr>
+<tr>
+  <td>09 32x</td>
+  <td>move-object/16 vAAAA, vBBBB</td>
+  <td><code>A:</code> destination register (16 bits)<br/>
+    <code>B:</code> source register (16 bits)</td>
+  <td>Move the contents of one object-bearing register to another.</td>
+</tr>
+<tr>
+  <td>0a 11x</td>
+  <td>move-result vAA</td>
+  <td><code>A:</code> destination register (8 bits)</td>
+  <td>Move the single-word non-object result of the most recent
+    <code>invoke-<i>kind</i></code> into the indicated register.
+    This must be done as the instruction immediately after an
+    <code>invoke-<i>kind</i></code> whose (single-word, non-object) result
+    is not to be ignored; anywhere else is invalid.</td>
+</tr>
+<tr>
+  <td>0b 11x</td>
+  <td>move-result-wide vAA</td>
+  <td><code>A:</code> destination register pair (8 bits)</td>
+  <td>Move the double-word result of the most recent
+    <code>invoke-<i>kind</i></code> into the indicated register pair.
+    This must be done as the instruction immediately after an
+    <code>invoke-<i>kind</i></code> whose (double-word) result
+    is not to be ignored; anywhere else is invalid.</td>
+</tr>
+<tr>
+  <td>0c 11x</td>
+  <td>move-result-object vAA</td>
+  <td><code>A:</code> destination register (8 bits)</td>
+  <td>Move the object result of the most recent <code>invoke-<i>kind</i></code>
+    into the indicated register. This must be done as the instruction
+    immediately after an <code>invoke-<i>kind</i></code> or
+    <code>filled-new-array</code>
+    whose (object) result is not to be ignored; anywhere else is invalid.</td>
+</tr>
+<tr>
+  <td>0d 11x</td>
+  <td>move-exception vAA</td>
+  <td><code>A:</code> destination register (8 bits)</td>
+  <td>Save a just-caught exception into the given register. This must
+    be the first instruction of any exception handler whose caught
+    exception is not to be ignored, and this instruction must <i>only</i>
+    ever occur as the first instruction of an exception handler; anywhere
+    else is invalid.</td>
+</tr>
+<tr>
+  <td>0e 10x</td>
+  <td>return-void</td>
+  <td>&nbsp;</td>
+  <td>Return from a <code>void</code> method.</td>
+</tr>
+<tr>
+  <td>0f 11x</td>
+  <td>return vAA</td>
+  <td><code>A:</code> return value register (8 bits)</td>
+  <td>Return from a single-width (32-bit) non-object value-returning
+    method.
+  </td>
+</tr>
+<tr>
+  <td>10 11x</td>
+  <td>return-wide vAA</td>
+  <td><code>A:</code> return value register-pair (8 bits)</td>
+  <td>Return from a double-width (64-bit) value-returning method.</td>
+</tr>
+<tr>
+  <td>11 11x</td>
+  <td>return-object vAA</td>
+  <td><code>A:</code> return value register (8 bits)</td>
+  <td>Return from an object-returning method.</td>
+</tr>
+<tr>
+  <td>12 11n</td>
+  <td>const/4 vA, #+B</td>
+  <td><code>A:</code> destination register (4 bits)<br/>
+    <code>B:</code> signed int (4 bits)</td>
+  <td>Move the given literal value (sign-extended to 32 bits) into
+    the specified register.</td>
+</tr>
+<tr>
+  <td>13 21s</td>
+  <td>const/16 vAA, #+BBBB</td>
+  <td><code>A:</code> destination register (8 bits)<br/>
+    <code>B:</code> signed int (16 bits)</td>
+  <td>Move the given literal value (sign-extended to 32 bits) into
+    the specified register.</td>
+</tr>
+<tr>
+  <td>14 31i</td>
+  <td>const vAA, #+BBBBBBBB</td>
+  <td><code>A:</code> destination register (8 bits)<br/>
+    <code>B:</code> arbitrary 32-bit constant</td>
+  <td>Move the given literal value into the specified register.</td>
+</tr>
+<tr>
+  <td>15 21h</td>
+  <td>const/high16 vAA, #+BBBB0000</td>
+  <td><code>A:</code> destination register (8 bits)<br/>
+    <code>B:</code> signed int (16 bits)</td>
+  <td>Move the given literal value (right-zero-extended to 32 bits) into
+    the specified register.</td>
+</tr>
+<tr>
+  <td>16 21s</td>
+  <td>const-wide/16 vAA, #+BBBB</td>
+  <td><code>A:</code> destination register (8 bits)<br/>
+    <code>B:</code> signed int (16 bits)</td>
+  <td>Move the given literal value (sign-extended to 64 bits) into
+    the specified register-pair.</td>
+</tr>
+<tr>
+  <td>17 31i</td>
+  <td>const-wide/32 vAA, #+BBBBBBBB</td>
+  <td><code>A:</code> destination register (8 bits)<br/>
+    <code>B:</code> signed int (32 bits)</td>
+  <td>Move the given literal value (sign-extended to 64 bits) into
+    the specified register-pair.</td>
+</tr>
+<tr>
+  <td>18 51l</td>
+  <td>const-wide vAA, #+BBBBBBBBBBBBBBBB</td>
+  <td><code>A:</code> destination register (8 bits)<br/>
+    <code>B:</code> arbitrary double-width (64-bit) constant</td>
+  <td>Move the given literal value into
+    the specified register-pair.</td>
+</tr>
+<tr>
+  <td>19 21h</td>
+  <td>const-wide/high16 vAA, #+BBBB000000000000</td>
+  <td><code>A:</code> destination register (8 bits)<br/>
+    <code>B:</code> signed int (16 bits)</td>
+  <td>Move the given literal value (right-zero-extended to 64 bits) into
+    the specified register-pair.</td>
+</tr>
+<tr>
+  <td>1a 21c</td>
+  <td>const-string vAA, string@BBBB</td>
+  <td><code>A:</code> destination register (8 bits)<br/>
+    <code>B:</code> string index</td>
+  <td>Move a reference to the string specified by the given index into the
+    specified register.</td>
+</tr>
+<tr>
+  <td>1b 31c</td>
+  <td>const-string/jumbo vAA, string@BBBBBBBB</td>
+  <td><code>A:</code> destination register (8 bits)<br/>
+    <code>B:</code> string index</td>
+  <td>Move a reference to the string specified by the given index into the
+    specified register.</td>
+</tr>
+<tr>
+  <td>1c 21c</td>
+  <td>const-class vAA, type@BBBB</td>
+  <td><code>A:</code> destination register (8 bits)<br/>
+    <code>B:</code> type index</td>
+  <td>Move a reference to the class specified by the given index into the
+    specified register. In the case where the indicated type is primitive,
+    this will store a reference to the primitive type's degenerate
+    class.</td>
+</tr>
+<tr>
+  <td>1d 11x</td>
+  <td>monitor-enter vAA</td>
+  <td><code>A:</code> reference-bearing register (8 bits)</td>
+  <td>Acquire the monitor for the indicated object.</td>
+</tr>
+<tr>
+  <td>1e 11x</td>
+  <td>monitor-exit vAA</td>
+  <td><code>A:</code> reference-bearing register (8 bits)</td>
+  <td>Release the monitor for the indicated object.
+    <p><b>Note:</b>
+    If this instruction needs to throw an exception, it must do
+    so as if the pc has already advanced past the instruction.
+    It may be useful to think of this as the instruction successfully
+    executing (in a sense), and the exception getting thrown <i>after</i>
+    the instruction but <i>before</i> the next one gets a chance to
+    run. This definition makes it possible for a method to use
+    a monitor cleanup catch-all (e.g., <code>finally</code>) block as
+    the monitor cleanup for that block itself, as a way to handle the
+    arbitrary exceptions that might get thrown due to the historical
+    implementation of <code>Thread.stop()</code>, while still managing
+    to have proper monitor hygiene.</p>
+  </td>
+</tr>
+<tr>
+  <td>1f 21c</td>
+  <td>check-cast vAA, type@BBBB</td>
+  <td><code>A:</code> reference-bearing register (8 bits)<br/>
+    <code>B:</code> type index (16 bits)</td>
+  <td>Throw a <code>ClassCastException</code> if the reference in the
+    given register cannot be cast to the indicated type.
+    <p><b>Note:</b> Since <code>A</code> must always be a reference
+    (and not a primitive value), this will necessarily fail at runtime
+    (that is, it will throw an exception) if <code>B</code> refers to a
+    primitive type.</p>
+  </td>
+</tr>
+<tr>
+  <td>20 22c</td>
+  <td>instance-of vA, vB, type@CCCC</td>
+  <td><code>A:</code> destination register (4 bits)<br/>
+    <code>B:</code> reference-bearing register (4 bits)<br/>
+    <code>C:</code> type index (16 bits)</td>
+  <td>Store in the given destination register <code>1</code>
+    if the indicated reference is an instance of the given type,
+    or <code>0</code> if not.
+    <p><b>Note:</b> Since <code>B</code> must always be a reference
+    (and not a primitive value), this will always result
+    in <code>0</code> being stored if <code>C</code> refers to a primitive
+    type.</td>
+</tr>
+<tr>
+  <td>21 12x</td>
+  <td>array-length vA, vB</td>
+  <td><code>A:</code> destination register (4 bits)<br/>
+    <code>B:</code> array reference-bearing register (4 bits)</td>
+  <td>Store in the given destination register the length of the indicated
+    array, in entries</td>
+</tr>
+<tr>
+  <td>22 21c</td>
+  <td>new-instance vAA, type@BBBB</td>
+  <td><code>A:</code> destination register (8 bits)<br/>
+    <code>B:</code> type index</td>
+  <td>Construct a new instance of the indicated type, storing a
+    reference to it in the destination. The type must refer to a
+    non-array class.</td>
+</tr>
+<tr>
+  <td>23 22c</td>
+  <td>new-array vA, vB, type@CCCC</td>
+  <td><code>A:</code> destination register (8 bits)<br/>
+    <code>B:</code> size register<br/>
+    <code>C:</code> type index</td>
+  <td>Construct a new array of the indicated type and size. The type
+    must be an array type.</td>
+</tr>
+<tr>
+  <td>24 35c</td>
+  <td>filled-new-array {vC, vD, vE, vF, vG}, type@BBBB</td>
+  <td>
+    <code>A:</code> array size and argument word count (4 bits)<br/>
+    <code>B:</code> type index (16 bits)<br/>
+    <code>C..G:</code> argument registers (4 bits each)
+  </td>
+  <td>Construct an array of the given type and size, filling it with the
+    supplied contents. The type must be an array type. The array's
+    contents must be single-word (that is,
+    no arrays of <code>long</code> or <code>double</code>, but reference
+    types are acceptable). The constructed
+    instance is stored as a "result" in the same way that the method invocation
+    instructions store their results, so the constructed instance must
+    be moved to a register with an immediately subsequent
+    <code>move-result-object</code> instruction (if it is to be used).</td>
+</tr>
+<tr>
+  <td>25 3rc</td>
+  <td>filled-new-array/range {vCCCC .. vNNNN}, type@BBBB</td>
+  <td><code>A:</code> array size and argument word count (8 bits)<br/>
+    <code>B:</code> type index (16 bits)<br/>
+    <code>C:</code> first argument register (16 bits)<br/>
+    <code>N = A + C - 1</code></td>
+  <td>Construct an array of the given type and size, filling it with
+    the supplied contents. Clarifications and restrictions are the same
+    as <code>filled-new-array</code>, described above.</td>
+</tr>
+<tr>
+  <td>26 31t</td>
+  <td>fill-array-data vAA, +BBBBBBBB <i>(with supplemental data as specified
+    below in "<code>fill-array-data-payload</code> Format")</i></td>
+  <td><code>A:</code> array reference (8 bits)<br/>
+    <code>B:</code> signed "branch" offset to table data pseudo-instruction
+    (32 bits)
+  </td>
+  <td>Fill the given array with the indicated data. The reference must be
+    to an array of primitives, and the data table must match it in type and
+    must contain no more elements than will fit in the array. That is,
+    the array may be larger than the table, and if so, only the initial
+    elements of the array are set, leaving the remainder alone.
+  </td>
+</tr>
+<tr>
+  <td>27 11x</td>
+  <td>throw vAA</td>
+  <td><code>A:</code> exception-bearing register (8 bits)<br/></td>
+  <td>Throw the indicated exception.</td>
+</tr>
+<tr>
+  <td>28 10t</td>
+  <td>goto +AA</td>
+  <td><code>A:</code> signed branch offset (8 bits)</td>
+  <td>Unconditionally jump to the indicated instruction.
+    <p><b>Note:</b>
+    The branch offset must not be <code>0</code>. (A spin
+    loop may be legally constructed either with <code>goto/32</code> or
+    by including a <code>nop</code> as a target before the branch.)</p>
+  </td>
+</tr>
+<tr>
+  <td>29 20t</td>
+  <td>goto/16 +AAAA</td>
+  <td><code>A:</code> signed branch offset (16 bits)<br/></td>
+  <td>Unconditionally jump to the indicated instruction.
+    <p><b>Note:</b>
+    The branch offset must not be <code>0</code>. (A spin
+    loop may be legally constructed either with <code>goto/32</code> or
+    by including a <code>nop</code> as a target before the branch.)</p>
+  </td>
+</tr>
+<tr>
+  <td>2a 30t</td>
+  <td>goto/32 +AAAAAAAA</td>
+  <td><code>A:</code> signed branch offset (32 bits)<br/></td>
+  <td>Unconditionally jump to the indicated instruction.</td>
+</tr>
+<tr>
+  <td>2b 31t</td>
+  <td>packed-switch vAA, +BBBBBBBB <i>(with supplemental data as
+    specified below in "<code>packed-switch-payload</code> Format")</i></td>
+  <td><code>A:</code> register to test<br/>
+    <code>B:</code> signed "branch" offset to table data pseudo-instruction
+    (32 bits)
+  </td>
+  <td>Jump to a new instruction based on the value in the
+    given register, using a table of offsets corresponding to each value
+    in a particular integral range, or fall through to the next
+    instruction if there is no match.
+  </td>
+</tr>
+<tr>
+  <td>2c 31t</td>
+  <td>sparse-switch vAA, +BBBBBBBB <i>(with supplemental data as
+    specified below in "<code>sparse-switch-payload</code> Format")</i></td>
+  <td><code>A:</code> register to test<br/>
+    <code>B:</code> signed "branch" offset to table data pseudo-instruction
+    (32 bits)
+  </td>
+  <td>Jump to a new instruction based on the value in the given
+    register, using an ordered table of value-offset pairs, or fall
+    through to the next instruction if there is no match.
+  </td>
+</tr>
+<tr>
+  <td>2d..31 23x</td>
+  <td>cmp<i>kind</i> vAA, vBB, vCC<br/>
+    2d: cmpl-float <i>(lt bias)</i><br/>
+    2e: cmpg-float <i>(gt bias)</i><br/>
+    2f: cmpl-double <i>(lt bias)</i><br/>
+    30: cmpg-double <i>(gt bias)</i><br/>
+    31: cmp-long
+  </td>
+  <td><code>A:</code> destination register (8 bits)<br/>
+    <code>B:</code> first source register or pair<br/>
+    <code>C:</code> second source register or pair</td>
+  <td>Perform the indicated floating point or <code>long</code> comparison,
+    setting <code>a</code> to <code>0</code> if <code>b == c</code>,
+    <code>1</code> if <code>b &gt; c</code>,
+    or <code>-1</code> if <code>b &lt; c</code>.
+    The "bias" listed for the floating point operations
+    indicates how <code>NaN</code> comparisons are treated: "gt bias"
+    instructions return <code>1</code> for <code>NaN</code> comparisons,
+    and "lt bias" instructions return <code>-1</code>.
+    <p>For example, to check to see if floating point
+    <code>x &lt; y</code> it is advisable to use
+    <code>cmpg-float</code>; a result of <code>-1</code> indicates that
+    the test was true, and the other values indicate it was false either
+    due to a valid comparison or because one of the values was
+    <code>NaN</code>.</p>
+  </td>
+</tr>
+<tr>
+  <td>32..37 22t</td>
+  <td>if-<i>test</i> vA, vB, +CCCC<br/>
+    32: if-eq<br/>
+    33: if-ne<br/>
+    34: if-lt<br/>
+    35: if-ge<br/>
+    36: if-gt<br/>
+    37: if-le<br/>
+  </td>
+  <td><code>A:</code> first register to test (4 bits)<br/>
+    <code>B:</code> second register to test (4 bits)<br/>
+    <code>C:</code> signed branch offset (16 bits)</td>
+  <td>Branch to the given destination if the given two registers' values
+    compare as specified.
+    <p><b>Note:</b>
+    The branch offset must not be <code>0</code>. (A spin
+    loop may be legally constructed either by branching around a
+    backward <code>goto</code> or by including a <code>nop</code> as
+    a target before the branch.)</p>
+  </td>
+</tr>
+<tr>
+  <td>38..3d 21t</td>
+  <td>if-<i>test</i>z vAA, +BBBB<br/>
+    38: if-eqz<br/>
+    39: if-nez<br/>
+    3a: if-ltz<br/>
+    3b: if-gez<br/>
+    3c: if-gtz<br/>
+    3d: if-lez<br/>
+  </td>
+  <td><code>A:</code> register to test (8 bits)<br/>
+    <code>B:</code> signed branch offset (16 bits)</td>
+  <td>Branch to the given destination if the given register's value compares
+    with 0 as specified.
+    <p><b>Note:</b>
+    The branch offset must not be <code>0</code>. (A spin
+    loop may be legally constructed either by branching around a
+    backward <code>goto</code> or by including a <code>nop</code> as
+    a target before the branch.)</p>
+  </td>
+</tr>
+<tr>
+  <td>3e..43 10x</td>
+  <td><i>(unused)</i></td>
+  <td>&nbsp;</td>
+  <td><i>(unused)</i></td>
+</tr>
+<tr>
+  <td>44..51 23x</td>
+  <td><i>arrayop</i> vAA, vBB, vCC<br/>
+    44: aget<br/>
+    45: aget-wide<br/>
+    46: aget-object<br/>
+    47: aget-boolean<br/>
+    48: aget-byte<br/>
+    49: aget-char<br/>
+    4a: aget-short<br/>
+    4b: aput<br/>
+    4c: aput-wide<br/>
+    4d: aput-object<br/>
+    4e: aput-boolean<br/>
+    4f: aput-byte<br/>
+    50: aput-char<br/>
+    51: aput-short
+  </td>
+  <td><code>A:</code> value register or pair; may be source or dest
+      (8 bits)<br/>
+    <code>B:</code> array register (8 bits)<br/>
+    <code>C:</code> index register (8 bits)</td>
+  <td>Perform the identified array operation at the identified index of
+    the given array, loading or storing into the value register.</td>
+</tr>
+<tr>
+  <td>52..5f 22c</td>
+  <td>i<i>instanceop</i> vA, vB, field@CCCC<br/>
+    52: iget<br/>
+    53: iget-wide<br/>
+    54: iget-object<br/>
+    55: iget-boolean<br/>
+    56: iget-byte<br/>
+    57: iget-char<br/>
+    58: iget-short<br/>
+    59: iput<br/>
+    5a: iput-wide<br/>
+    5b: iput-object<br/>
+    5c: iput-boolean<br/>
+    5d: iput-byte<br/>
+    5e: iput-char<br/>
+    5f: iput-short
+  </td>
+  <td><code>A:</code> value register or pair; may be source or dest
+      (4 bits)<br/>
+    <code>B:</code> object register (4 bits)<br/>
+    <code>C:</code> instance field reference index (16 bits)</td>
+  <td>Perform the identified object instance field operation with
+    the identified field, loading or storing into the value register.
+    <p><b>Note:</b> These opcodes are reasonable candidates for static linking,
+    altering the field argument to be a more direct offset.</p>
+  </td>
+</tr>
+<tr>
+  <td>60..6d 21c</td>
+  <td>s<i>staticop</i> vAA, field@BBBB<br/>
+    60: sget<br/>
+    61: sget-wide<br/>
+    62: sget-object<br/>
+    63: sget-boolean<br/>
+    64: sget-byte<br/>
+    65: sget-char<br/>
+    66: sget-short<br/>
+    67: sput<br/>
+    68: sput-wide<br/>
+    69: sput-object<br/>
+    6a: sput-boolean<br/>
+    6b: sput-byte<br/>
+    6c: sput-char<br/>
+    6d: sput-short
+  </td>
+  <td><code>A:</code> value register or pair; may be source or dest
+      (8 bits)<br/>
+    <code>B:</code> static field reference index (16 bits)</td>
+  <td>Perform the identified object static field operation with the identified
+    static field, loading or storing into the value register.
+    <p><b>Note:</b> These opcodes are reasonable candidates for static linking,
+    altering the field argument to be a more direct offset.</p>
+  </td>
+</tr>
+<tr>
+  <td>6e..72 35c</td>
+  <td>invoke-<i>kind</i> {vC, vD, vE, vF, vG}, meth@BBBB<br/>
+    6e: invoke-virtual<br/>
+    6f: invoke-super<br/>
+    70: invoke-direct<br/>
+    71: invoke-static<br/>
+    72: invoke-interface
+  </td>
+  <td>
+    <code>A:</code> argument word count (4 bits)<br/>
+    <code>B:</code> method reference index (16 bits)<br/>
+    <code>C..G:</code> argument registers (4 bits each)
+  </td>
+  <td>Call the indicated method. The result (if any) may be stored
+    with an appropriate <code>move-result*</code> variant as the immediately
+    subsequent instruction.
+    <p><code>invoke-virtual</code> is used to invoke a normal virtual
+    method (a method that is not <code>private</code>, <code>static</code>,
+    or <code>final</code>, and is also not a constructor).</p>
+    <p><code>invoke-super</code> is used to invoke the closest superclass's
+    virtual method (as opposed to the one with the same <code>method_id</code>
+    in the calling class). The same method restrictions hold as for
+    <code>invoke-virtual</code>.</p>
+    <p><code>invoke-direct</code> is used to invoke a non-<code>static</code>
+    direct method (that is, an instance method that is by its nature
+    non-overridable, namely either a <code>private</code> instance method
+    or a constructor).</p>
+    <p><code>invoke-static</code> is used to invoke a <code>static</code>
+    method (which is always considered a direct method).</p>
+    <p><code>invoke-interface</code> is used to invoke an
+    <code>interface</code> method, that is, on an object whose concrete
+    class isn't known, using a <code>method_id</code> that refers to
+    an <code>interface</code>.</p>
+    <p><b>Note:</b> These opcodes are reasonable candidates for static linking,
+    altering the method argument to be a more direct offset
+    (or pair thereof).</p>
+  </td>
+</tr>
+<tr>
+  <td>73 10x</td>
+  <td><i>(unused)</i></td>
+  <td>&nbsp;</td>
+  <td><i>(unused)</i></td>
+</tr>
+<tr>
+  <td>74..78 3rc</td>
+  <td>invoke-<i>kind</i>/range {vCCCC .. vNNNN}, meth@BBBB<br/>
+    74: invoke-virtual/range<br/>
+    75: invoke-super/range<br/>
+    76: invoke-direct/range<br/>
+    77: invoke-static/range<br/>
+    78: invoke-interface/range
+  </td>
+  <td><code>A:</code> argument word count (8 bits)<br/>
+    <code>B:</code> method reference index (16 bits)<br/>
+    <code>C:</code> first argument register (16 bits)<br/>
+    <code>N = A + C - 1</code></td>
+  <td>Call the indicated method. See first <code>invoke-<i>kind</i></code>
+    description above for details, caveats, and suggestions.
+  </td>
+</tr>
+<tr>
+  <td>79..7a 10x</td>
+  <td><i>(unused)</i></td>
+  <td>&nbsp;</td>
+  <td><i>(unused)</i></td>
+</tr>
+<tr>
+  <td>7b..8f 12x</td>
+  <td><i>unop</i> vA, vB<br/>
+    7b: neg-int<br/>
+    7c: not-int<br/>
+    7d: neg-long<br/>
+    7e: not-long<br/>
+    7f: neg-float<br/>
+    80: neg-double<br/>
+    81: int-to-long<br/>
+    82: int-to-float<br/>
+    83: int-to-double<br/>
+    84: long-to-int<br/>
+    85: long-to-float<br/>
+    86: long-to-double<br/>
+    87: float-to-int<br/>
+    88: float-to-long<br/>
+    89: float-to-double<br/>
+    8a: double-to-int<br/>
+    8b: double-to-long<br/>
+    8c: double-to-float<br/>
+    8d: int-to-byte<br/>
+    8e: int-to-char<br/>
+    8f: int-to-short
+  </td>
+  <td><code>A:</code> destination register or pair (4 bits)<br/>
+    <code>B:</code> source register or pair (4 bits)</td>
+  <td>Perform the identified unary operation on the source register,
+    storing the result in the destination register.</td>
+</tr>
+
+<tr>
+  <td>90..af 23x</td>
+  <td><i>binop</i> vAA, vBB, vCC<br/>
+    90: add-int<br/>
+    91: sub-int<br/>
+    92: mul-int<br/>
+    93: div-int<br/>
+    94: rem-int<br/>
+    95: and-int<br/>
+    96: or-int<br/>
+    97: xor-int<br/>
+    98: shl-int<br/>
+    99: shr-int<br/>
+    9a: ushr-int<br/>
+    9b: add-long<br/>
+    9c: sub-long<br/>
+    9d: mul-long<br/>
+    9e: div-long<br/>
+    9f: rem-long<br/>
+    a0: and-long<br/>
+    a1: or-long<br/>
+    a2: xor-long<br/>
+    a3: shl-long<br/>
+    a4: shr-long<br/>
+    a5: ushr-long<br/>
+    a6: add-float<br/>
+    a7: sub-float<br/>
+    a8: mul-float<br/>
+    a9: div-float<br/>
+    aa: rem-float<br/>
+    ab: add-double<br/>
+    ac: sub-double<br/>
+    ad: mul-double<br/>
+    ae: div-double<br/>
+    af: rem-double
+  </td>
+  <td><code>A:</code> destination register or pair (8 bits)<br/>
+    <code>B:</code> first source register or pair (8 bits)<br/>
+    <code>C:</code> second source register or pair (8 bits)</td>
+  <td>Perform the identified binary operation on the two source registers,
+    storing the result in the first source register.</td>
+</tr>
+<tr>
+  <td>b0..cf 12x</td>
+  <td><i>binop</i>/2addr vA, vB<br/>
+    b0: add-int/2addr<br/>
+    b1: sub-int/2addr<br/>
+    b2: mul-int/2addr<br/>
+    b3: div-int/2addr<br/>
+    b4: rem-int/2addr<br/>
+    b5: and-int/2addr<br/>
+    b6: or-int/2addr<br/>
+    b7: xor-int/2addr<br/>
+    b8: shl-int/2addr<br/>
+    b9: shr-int/2addr<br/>
+    ba: ushr-int/2addr<br/>
+    bb: add-long/2addr<br/>
+    bc: sub-long/2addr<br/>
+    bd: mul-long/2addr<br/>
+    be: div-long/2addr<br/>
+    bf: rem-long/2addr<br/>
+    c0: and-long/2addr<br/>
+    c1: or-long/2addr<br/>
+    c2: xor-long/2addr<br/>
+    c3: shl-long/2addr<br/>
+    c4: shr-long/2addr<br/>
+    c5: ushr-long/2addr<br/>
+    c6: add-float/2addr<br/>
+    c7: sub-float/2addr<br/>
+    c8: mul-float/2addr<br/>
+    c9: div-float/2addr<br/>
+    ca: rem-float/2addr<br/>
+    cb: add-double/2addr<br/>
+    cc: sub-double/2addr<br/>
+    cd: mul-double/2addr<br/>
+    ce: div-double/2addr<br/>
+    cf: rem-double/2addr
+  </td>
+  <td><code>A:</code> destination and first source register or pair
+      (4 bits)<br/>
+    <code>B:</code> second source register or pair (4 bits)</td>
+  <td>Perform the identified binary operation on the two source registers,
+    storing the result in the first source register.</td>
+</tr>
+<tr>
+  <td>d0..d7 22s</td>
+  <td><i>binop</i>/lit16 vA, vB, #+CCCC<br/>
+    d0: add-int/lit16<br/>
+    d1: rsub-int (reverse subtract)<br/>
+    d2: mul-int/lit16<br/>
+    d3: div-int/lit16<br/>
+    d4: rem-int/lit16<br/>
+    d5: and-int/lit16<br/>
+    d6: or-int/lit16<br/>
+    d7: xor-int/lit16
+  </td>
+  <td><code>A:</code> destination register (4 bits)<br/>
+    <code>B:</code> source register (4 bits)<br/>
+    <code>C:</code> signed int constant (16 bits)</td>
+  <td>Perform the indicated binary op on the indicated register (first
+    argument) and literal value (second argument), storing the result in
+    the destination register.
+    <p><b>Note:</b>
+    <code>rsub-int</code> does not have a suffix since this version is the
+    main opcode of its family. Also, see below for details on its semantics.
+    </p>
+  </td>
+</tr>
+<tr>
+  <td>d8..e2 22b</td>
+  <td><i>binop</i>/lit8 vAA, vBB, #+CC<br/>
+    d8: add-int/lit8<br/>
+    d9: rsub-int/lit8<br/>
+    da: mul-int/lit8<br/>
+    db: div-int/lit8<br/>
+    dc: rem-int/lit8<br/>
+    dd: and-int/lit8<br/>
+    de: or-int/lit8<br/>
+    df: xor-int/lit8<br/>
+    e0: shl-int/lit8<br/>
+    e1: shr-int/lit8<br/>
+    e2: ushr-int/lit8
+  </td>
+  <td><code>A:</code> destination register (8 bits)<br/>
+    <code>B:</code> source register (8 bits)<br/>
+    <code>C:</code> signed int constant (8 bits)</td>
+  <td>Perform the indicated binary op on the indicated register (first
+    argument) and literal value (second argument), storing the result
+    in the destination register.
+    <p><b>Note:</b> See below for details on the semantics of
+    <code>rsub-int</code>.</p>
+  </td>
+</tr>
+<tr>
+  <td>e3..ff 10x</td>
+  <td><i>(unused)</i></td>
+  <td>&nbsp;</td>
+  <td><i>(unused)</i></td>
+</tr>
+</tbody>
+</table>
+
+<h2><code>packed-switch-payload</code> Format</h2>
+
+<table class="supplement">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>ident</td>
+  <td>ushort = 0x0100</td>
+  <td>identifying pseudo-opcode</td>
+</tr>
+<tr>
+  <td>size</td>
+  <td>ushort</td>
+  <td>number of entries in the table</td>
+</tr>
+<tr>
+  <td>first_key</td>
+  <td>int</td>
+  <td>first (and lowest) switch case value</td>
+</tr>
+<tr>
+  <td>targets</td>
+  <td>int[]</td>
+  <td>list of <code>size</code> relative branch targets. The targets are
+    relative to the address of the switch opcode, not of this table.
+  </td>
+</tr>
+</tbody>
+</table>
+
+<p><b>Note:</b> The total number of code units for an instance of this
+table is <code>(size * 2) + 4</code>.</p>
+
+<h2><code>sparse-switch-payload</code> Format</h2>
+
+<table class="supplement">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>ident</td>
+  <td>ushort = 0x0200</td>
+  <td>identifying pseudo-opcode</td>
+</tr>
+<tr>
+  <td>size</td>
+  <td>ushort</td>
+  <td>number of entries in the table</td>
+</tr>
+<tr>
+  <td>keys</td>
+  <td>int[]</td>
+  <td>list of <code>size</code> key values, sorted low-to-high</td>
+</tr>
+<tr>
+  <td>targets</td>
+  <td>int[]</td>
+  <td>list of <code>size</code> relative branch targets, each corresponding
+    to the key value at the same index. The targets are
+    relative to the address of the switch opcode, not of this table.
+  </td>
+</tr>
+</tbody>
+</table>
+
+<p><b>Note:</b> The total number of code units for an instance of this
+table is <code>(size * 4) + 2</code>.</p>
+
+<h2><code>fill-array-data-payload</code> Format</h2>
+
+<table class="supplement">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>ident</td>
+  <td>ushort = 0x0300</td>
+  <td>identifying pseudo-opcode</td>
+</tr>
+<tr>
+  <td>element_width</td>
+  <td>ushort</td>
+  <td>number of bytes in each element</td>
+</tr>
+<tr>
+  <td>size</td>
+  <td>uint</td>
+  <td>number of elements in the table</td>
+</tr>
+<tr>
+  <td>data</td>
+  <td>ubyte[]</td>
+  <td>data values</td>
+</tr>
+</tbody>
+</table>
+
+<p><b>Note:</b> The total number of code units for an instance of this
+table is <code>(size * element_width + 1) / 2 + 4</code>.</p>
+
+
+<h2>Mathematical Operation Details</h2>
+
+<p><b>Note:</b> Floating point operations must follow IEEE 754 rules, using
+round-to-nearest and gradual underflow, except where stated otherwise.</p>
+
+<table class="math">
+<thead>
+<tr>
+  <th>Opcode</th>
+  <th>C Semantics</th>
+  <th>Notes</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>neg-int</td>
+  <td>int32 a;<br/>
+    int32 result = -a;
+  </td>
+  <td>Unary twos-complement.</td>
+</tr>
+<tr>
+  <td>not-int</td>
+  <td>int32 a;<br/>
+    int32 result = ~a;
+  </td>
+  <td>Unary ones-complement.</td>
+</tr>
+<tr>
+  <td>neg-long</td>
+  <td>int64 a;<br/>
+    int64 result = -a;
+  </td>
+  <td>Unary twos-complement.</td>
+</tr>
+<tr>
+  <td>not-long</td>
+  <td>int64 a;<br/>
+    int64 result = ~a;
+  </td>
+  <td>Unary ones-complement.</td>
+</tr>
+<tr>
+  <td>neg-float</td>
+  <td>float a;<br/>
+    float result = -a;
+  </td>
+  <td>Floating point negation.</td>
+</tr>
+<tr>
+  <td>neg-double</td>
+  <td>double a;<br/>
+    double result = -a;
+  </td>
+  <td>Floating point negation.</td>
+</tr>
+<tr>
+  <td>int-to-long</td>
+  <td>int32 a;<br/>
+    int64 result = (int64) a;
+  </td>
+  <td>Sign extension of <code>int32</code> into <code>int64</code>.</td>
+</tr>
+<tr>
+  <td>int-to-float</td>
+  <td>int32 a;<br/>
+    float result = (float) a;
+  </td>
+  <td>Conversion of <code>int32</code> to <code>float</code>, using
+    round-to-nearest. This loses precision for some values.
+  </td>
+</tr>
+<tr>
+  <td>int-to-double</td>
+  <td>int32 a;<br/>
+    double result = (double) a;
+  </td>
+  <td>Conversion of <code>int32</code> to <code>double</code>.</td>
+</tr>
+<tr>
+  <td>long-to-int</td>
+  <td>int64 a;<br/>
+    int32 result = (int32) a;
+  </td>
+  <td>Truncation of <code>int64</code> into <code>int32</code>.</td>
+</tr>
+<tr>
+  <td>long-to-float</td>
+  <td>int64 a;<br/>
+    float result = (float) a;
+  </td>
+  <td>Conversion of <code>int64</code> to <code>float</code>, using
+    round-to-nearest. This loses precision for some values.
+  </td>
+</tr>
+<tr>
+  <td>long-to-double</td>
+  <td>int64 a;<br/>
+    double result = (double) a;
+  </td>
+  <td>Conversion of <code>int64</code> to <code>double</code>, using
+    round-to-nearest. This loses precision for some values.
+  </td>
+</tr>
+<tr>
+  <td>float-to-int</td>
+  <td>float a;<br/>
+    int32 result = (int32) a;
+  </td>
+  <td>Conversion of <code>float</code> to <code>int32</code>, using
+    round-toward-zero. <code>NaN</code> and <code>-0.0</code> (negative zero)
+    convert to the integer <code>0</code>. Infinities and values with
+    too large a magnitude to be represented get converted to either
+    <code>0x7fffffff</code> or <code>-0x80000000</code> depending on sign.
+  </td>
+</tr>
+<tr>
+  <td>float-to-long</td>
+  <td>float a;<br/>
+    int64 result = (int64) a;
+  </td>
+  <td>Conversion of <code>float</code> to <code>int64</code>, using
+    round-toward-zero. The same special case rules as for
+    <code>float-to-int</code> apply here, except that out-of-range values
+    get converted to either <code>0x7fffffffffffffff</code> or
+    <code>-0x8000000000000000</code> depending on sign.
+  </td>
+</tr>
+<tr>
+  <td>float-to-double</td>
+  <td>float a;<br/>
+    double result = (double) a;
+  </td>
+  <td>Conversion of <code>float</code> to <code>double</code>, preserving
+    the value exactly.
+  </td>
+</tr>
+<tr>
+  <td>double-to-int</td>
+  <td>double a;<br/>
+    int32 result = (int32) a;
+  </td>
+  <td>Conversion of <code>double</code> to <code>int32</code>, using
+    round-toward-zero. The same special case rules as for
+    <code>float-to-int</code> apply here.
+  </td>
+</tr>
+<tr>
+  <td>double-to-long</td>
+  <td>double a;<br/>
+    int64 result = (int64) a;
+  </td>
+  <td>Conversion of <code>double</code> to <code>int64</code>, using
+    round-toward-zero. The same special case rules as for
+    <code>float-to-long</code> apply here.
+  </td>
+</tr>
+<tr>
+  <td>double-to-float</td>
+  <td>double a;<br/>
+    float result = (float) a;
+  </td>
+  <td>Conversion of <code>double</code> to <code>float</code>, using
+    round-to-nearest. This loses precision for some values.
+  </td>
+</tr>
+<tr>
+  <td>int-to-byte</td>
+  <td>int32 a;<br/>
+    int32 result = (a &lt;&lt; 24) &gt;&gt; 24;
+  </td>
+  <td>Truncation of <code>int32</code> to <code>int8</code>, sign
+    extending the result.
+  </td>
+</tr>
+<tr>
+  <td>int-to-char</td>
+  <td>int32 a;<br/>
+    int32 result = a &amp; 0xffff;
+  </td>
+  <td>Truncation of <code>int32</code> to <code>uint16</code>, without
+    sign extension.
+  </td>
+</tr>
+<tr>
+  <td>int-to-short</td>
+  <td>int32 a;<br/>
+    int32 result = (a &lt;&lt; 16) &gt;&gt; 16;
+  </td>
+  <td>Truncation of <code>int32</code> to <code>int16</code>, sign
+    extending the result.
+  </td>
+</tr>
+<tr>
+  <td>add-int</td>
+  <td>int32 a, b;<br/>
+    int32 result = a + b;
+  </td>
+  <td>Twos-complement addition.</td>
+</tr>
+<tr>
+  <td>sub-int</td>
+  <td>int32 a, b;<br/>
+    int32 result = a - b;
+  </td>
+  <td>Twos-complement subtraction.</td>
+</tr>
+<tr>
+  <td>rsub-int</td>
+  <td>int32 a, b;<br/>
+    int32 result = b - a;
+  </td>
+  <td>Twos-complement reverse subtraction.</td>
+</tr>
+<tr>
+  <td>mul-int</td>
+  <td>int32 a, b;<br/>
+    int32 result = a * b;
+  </td>
+  <td>Twos-complement multiplication.</td>
+</tr>
+<tr>
+  <td>div-int</td>
+  <td>int32 a, b;<br/>
+    int32 result = a / b;
+  </td>
+  <td>Twos-complement division, rounded towards zero (that is, truncated to
+    integer). This throws <code>ArithmeticException</code> if
+    <code>b == 0</code>.
+  </td>
+</tr>
+<tr>
+  <td>rem-int</td>
+  <td>int32 a, b;<br/>
+    int32 result = a % b;
+  </td>
+  <td>Twos-complement remainder after division. The sign of the result
+    is the same as that of <code>a</code>, and it is more precisely
+    defined as <code>result == a - (a / b) * b</code>. This throws
+    <code>ArithmeticException</code> if <code>b == 0</code>.
+  </td>
+</tr>
+<tr>
+  <td>and-int</td>
+  <td>int32 a, b;<br/>
+    int32 result = a &amp; b;
+  </td>
+  <td>Bitwise AND.</td>
+</tr>
+<tr>
+  <td>or-int</td>
+  <td>int32 a, b;<br/>
+    int32 result = a | b;
+  </td>
+  <td>Bitwise OR.</td>
+</tr>
+<tr>
+  <td>xor-int</td>
+  <td>int32 a, b;<br/>
+    int32 result = a ^ b;
+  </td>
+  <td>Bitwise XOR.</td>
+</tr>
+<tr>
+  <td>shl-int</td>
+  <td>int32 a, b;<br/>
+    int32 result = a &lt;&lt; (b &amp; 0x1f);
+  </td>
+  <td>Bitwise shift left (with masked argument).</td>
+</tr>
+<tr>
+  <td>shr-int</td>
+  <td>int32 a, b;<br/>
+    int32 result = a &gt;&gt; (b &amp; 0x1f);
+  </td>
+  <td>Bitwise signed shift right (with masked argument).</td>
+</tr>
+<tr>
+  <td>ushr-int</td>
+  <td>uint32 a, b;<br/>
+    int32 result = a &gt;&gt; (b &amp; 0x1f);
+  </td>
+  <td>Bitwise unsigned shift right (with masked argument).</td>
+</tr>
+<tr>
+  <td>add-long</td>
+  <td>int64 a, b;<br/>
+    int64 result = a + b;
+  </td>
+  <td>Twos-complement addition.</td>
+</tr>
+<tr>
+  <td>sub-long</td>
+  <td>int64 a, b;<br/>
+    int64 result = a - b;
+  </td>
+  <td>Twos-complement subtraction.</td>
+</tr>
+<tr>
+  <td>mul-long</td>
+  <td>int64 a, b;<br/>
+    int64 result = a * b;
+  </td>
+  <td>Twos-complement multiplication.</td>
+</tr>
+<tr>
+  <td>div-long</td>
+  <td>int64 a, b;<br/>
+    int64 result = a / b;
+  </td>
+  <td>Twos-complement division, rounded towards zero (that is, truncated to
+    integer). This throws <code>ArithmeticException</code> if
+    <code>b == 0</code>.
+  </td>
+</tr>
+<tr>
+  <td>rem-long</td>
+  <td>int64 a, b;<br/>
+    int64 result = a % b;
+  </td>
+  <td>Twos-complement remainder after division. The sign of the result
+    is the same as that of <code>a</code>, and it is more precisely
+    defined as <code>result == a - (a / b) * b</code>. This throws
+    <code>ArithmeticException</code> if <code>b == 0</code>.
+  </td>
+</tr>
+<tr>
+  <td>and-long</td>
+  <td>int64 a, b;<br/>
+    int64 result = a &amp; b;
+  </td>
+  <td>Bitwise AND.</td>
+</tr>
+<tr>
+  <td>or-long</td>
+  <td>int64 a, b;<br/>
+    int64 result = a | b;
+  </td>
+  <td>Bitwise OR.</td>
+</tr>
+<tr>
+  <td>xor-long</td>
+  <td>int64 a, b;<br/>
+    int64 result = a ^ b;
+  </td>
+  <td>Bitwise XOR.</td>
+</tr>
+<tr>
+  <td>shl-long</td>
+  <td>int64 a, b;<br/>
+    int64 result = a &lt;&lt; (b &amp; 0x3f);
+  </td>
+  <td>Bitwise shift left (with masked argument).</td>
+</tr>
+<tr>
+  <td>shr-long</td>
+  <td>int64 a, b;<br/>
+    int64 result = a &gt;&gt; (b &amp; 0x3f);
+  </td>
+  <td>Bitwise signed shift right (with masked argument).</td>
+</tr>
+<tr>
+  <td>ushr-long</td>
+  <td>uint64 a, b;<br/>
+    int64 result = a &gt;&gt; (b &amp; 0x3f);
+  </td>
+  <td>Bitwise unsigned shift right (with masked argument).</td>
+</tr>
+<tr>
+  <td>add-float</td>
+  <td>float a, b;<br/>
+    float result = a + b;
+  </td>
+  <td>Floating point addition.</td>
+</tr>
+<tr>
+  <td>sub-float</td>
+  <td>float a, b;<br/>
+    float result = a - b;
+  </td>
+  <td>Floating point subtraction.</td>
+</tr>
+<tr>
+  <td>mul-float</td>
+  <td>float a, b;<br/>
+    float result = a * b;
+  </td>
+  <td>Floating point multiplication.</td>
+</tr>
+<tr>
+  <td>div-float</td>
+  <td>float a, b;<br/>
+    float result = a / b;
+  </td>
+  <td>Floating point division.</td>
+</tr>
+<tr>
+  <td>rem-float</td>
+  <td>float a, b;<br/>
+    float result = a % b;
+  </td>
+  <td>Floating point remainder after division. This function is different
+    than IEEE 754 remainder and is defined as
+    <code>result == a - roundTowardZero(a / b) * b</code>.
+  </td>
+</tr>
+<tr>
+  <td>add-double</td>
+  <td>double a, b;<br/>
+    double result = a + b;
+  </td>
+  <td>Floating point addition.</td>
+</tr>
+<tr>
+  <td>sub-double</td>
+  <td>double a, b;<br/>
+    double result = a - b;
+  </td>
+  <td>Floating point subtraction.</td>
+</tr>
+<tr>
+  <td>mul-double</td>
+  <td>double a, b;<br/>
+    double result = a * b;
+  </td>
+  <td>Floating point multiplication.</td>
+</tr>
+<tr>
+  <td>div-double</td>
+  <td>double a, b;<br/>
+    double result = a / b;
+  </td>
+  <td>Floating point division.</td>
+</tr>
+<tr>
+  <td>rem-double</td>
+  <td>double a, b;<br/>
+    double result = a % b;
+  </td>
+  <td>Floating point remainder after division. This function is different
+    than IEEE 754 remainder and is defined as
+    <code>result == a - roundTowardZero(a / b) * b</code>.
+  </td>
+</tr>
+</tbody>
+</table>
\ No newline at end of file
diff --git a/src/devices/tech/dalvik/dex-format.css b/src/devices/tech/dalvik/dex-format.css
new file mode 100644
index 0000000..153dd4e
--- /dev/null
+++ b/src/devices/tech/dalvik/dex-format.css
@@ -0,0 +1,387 @@
+h1 {
+    font-family: serif;
+    border-top-style: solid;
+    border-top-width: 5px;
+    padding-top: 9pt;
+    margin-top: 40pt;
+    color: #222266;
+}
+
+h1.title {
+    border: none;
+}
+
+h2 {
+    font-family: serif;
+    border-top-style: solid;
+    border-top-width: 2px;
+    border-color: #ccccdd;
+    padding-top: 9pt;
+    margin-top: 40pt;
+    margin-bottom: 2pt;
+    color: #222266;
+}
+
+h3 {
+    font-family: serif;
+    font-style: bold;
+    margin-top: 20pt;
+    margin-bottom: 2pt;
+    color: #222266;
+}
+
+h4 {
+    font-family: serif;
+    font-style: italic;
+    margin-top: 2pt;
+    margin-bottom: 2pt;
+    color: #666688;
+}
+
+@media print {
+    table {
+        font-size: 8pt;
+    }
+}
+
+@media screen {
+    table {
+        font-size: 10pt;
+    }
+}
+
+pre {
+    background: #eeeeff;
+    border-color: #aaaaff;
+    border-style: solid;
+    border-width: 1px;
+    margin-left: 40pt;
+    margin-right: 40pt;
+    padding: 6pt;
+}
+
+table {
+    border-collapse: collapse;
+    margin-top: 10pt;
+    margin-left: 40pt;
+    margin-right: 40pt;
+}
+
+table th {
+    font-family: sans-serif;
+    background: #aabbff;
+}
+
+table td {
+    font-family: sans-serif;
+    border-top-style: solid;
+    border-bottom-style: solid;
+    border-width: 1px;
+    border-color: #aaaaff;
+    padding-top: 3pt;
+    padding-bottom: 3pt;
+    padding-left: 3pt;
+    padding-right: 4pt;
+    background: #eeeeff;
+}
+
+table p {
+    margin-bottom: 0pt;
+}
+
+/* for the bnf syntax sections */
+
+table.bnf {
+    background: #eeeeff;
+    border-color: #aaaaff;
+    border-style: solid;
+    border-width: 1px;
+    margin-top: 3pt;
+    margin-bottom: 3pt;
+    padding-top: 2pt;
+    padding-bottom: 6pt;
+    padding-left: 6pt;
+    padding-right: 6pt;
+}
+
+table.bnf td {
+    border: none;
+    padding-left: 6pt;
+    padding-right: 6pt;
+    padding-top: 1pt;
+    padding-bottom: 1pt;
+}
+
+table.bnf td:first-child {
+    padding-right: 0pt;
+    width: 8pt;
+}
+
+table.bnf td:first-child td {
+    padding-left: 0pt;
+}
+
+table.bnf td.def {
+    padding-top: 6pt;
+}
+
+table.bnf td.bar {
+    padding-left: 15pt;
+}
+
+table.bnf code {
+    font-weight: bold;
+}
+
+
+/* for the type name guide */
+
+table.guide {
+    margin-top: 20pt;
+    margin-bottom: 20pt;
+}
+
+table.guide td:first-child {
+    font-family: monospace;
+    width: 15%;
+}
+
+table.guide td:first-child + td {
+    font-family: sans-serif;
+    width: 85%;
+}
+
+
+/* for the LEB128 example tables */
+
+table.leb128Bits {
+    margin-top: 20pt;
+    margin-bottom: 20pt;
+}
+
+table.leb128Bits td {
+    border-left: solid #aaaaff 1px;
+    border-right: solid #aaaaff 1px;
+}
+
+table.leb128Bits td.start1 {
+    border-left: none;
+}
+
+table.leb128Bits td.start2 {
+    border-left: solid #000 2px;
+}
+
+table.leb128Bits td.end2 {
+    border-right: none;
+}
+
+table.leb128 {
+    margin-top: 20pt;
+    margin-bottom: 20pt;
+}
+
+table.leb128 td:first-child {
+    font-family: monospace;
+    text-align: center;
+    width: 31%;
+}
+
+table.leb128 td:first-child + td {
+    font-family: monospace;
+    text-align: center;
+    width: 23%;
+}
+
+table.leb128 td:first-child + td + td {
+    font-family: monospace;
+    text-align: center;
+    width: 23%;
+}
+
+table.leb128 td:first-child + td + td + td {
+    font-family: monospace;
+    text-align: center;
+    width: 23%;
+}
+
+
+/* for the general format tables */
+
+table.format {
+    margin-top: 20pt;
+    margin-bottom: 20pt;
+}
+
+table.format td:first-child {
+    font-family: monospace;
+    width: 20%;
+}
+
+table.format td:first-child + td {
+    font-family: monospace;
+    width: 20%;
+}
+
+table.format td:first-child + td + td {
+    width: 60%;
+}
+
+table.format td i {
+    font-family: sans-serif;
+}
+
+
+/* for the type code table */
+
+table.typeCodes {
+    margin-top: 20pt;
+    margin-bottom: 20pt;
+}
+
+table.typeCodes td:first-child {
+    font-family: monospace;
+    width: 30%;
+}
+
+table.typeCodes td:first-child + td {
+    font-family: monospace;
+    width: 30%;
+}
+
+table.typeCodes td:first-child + td + td {
+    font-family: monospace;
+    width: 10%;
+}
+
+table.typeCodes td:first-child + td + td + td {
+    font-family: monospace;
+    width: 30%;
+}
+
+table.typeCodes td i {
+    font-family: sans-serif;
+}
+
+
+/* for the access flags table */
+
+table.accessFlags {
+    margin-top: 20pt;
+    margin-bottom: 20pt;
+}
+
+table.accessFlags td:first-child {
+    font-family: monospace;
+    width: 10%;
+}
+
+table.accessFlags td:first-child + td {
+    font-family: monospace;
+    width: 6%;
+}
+
+table.accessFlags td:first-child + td + td {
+    width: 28%;
+}
+
+table.accessFlags td:first-child + td + td + td {
+    width: 28%;
+}
+
+table.accessFlags td:first-child + td + td + td + td {
+    width: 28%;
+}
+
+table.accessFlags i {
+    font-family: sans-serif;
+}
+
+
+/* for the descriptor table */
+
+table.descriptor {
+    margin-top: 20pt;
+    margin-bottom: 20pt;
+}
+
+table.descriptor td:first-child {
+    font-family: monospace;
+    width: 25%;
+}
+
+table.descriptor td:first-child + td {
+    font-family: sans-serif;
+    width: 75%;
+}
+
+
+/* for the debug bytecode table */
+
+table.debugByteCode {
+    margin-top: 20pt;
+    margin-bottom: 20pt;
+}
+
+table.debugByteCode td:first-child {
+    font-family: monospace;
+    width: 20%;
+}
+
+table.debugByteCode td:first-child + td {
+    font-family: monospace;
+    width: 5%;
+}
+
+table.debugByteCode td:first-child + td + td{
+    font-family: monospace;
+    width: 15%;
+}
+
+table.debugByteCode td:first-child + td + td + td {
+    width: 25%;
+}
+
+table.debugByteCode td:first-child + td + td + td + td {
+    width: 35%;
+}
+
+table.debugByteCode i {
+    font-family: sans-serif;
+}
+
+
+/* for the encoded value table */
+
+table.encodedValue {
+    margin-top: 20pt;
+    margin-bottom: 20pt;
+}
+
+table.encodedValue td:first-child {
+    font-family: monospace;
+    width: 12%;
+}
+
+table.encodedValue td:first-child + td {
+    font-family: monospace;
+    width: 10%;
+}
+
+table.encodedValue td:first-child + td + td {
+    font-family: monospace;
+    width: 15%;
+}
+
+table.encodedValue td:first-child + td + td + td {
+    font-family: monospace;
+    width: 15%;
+}
+
+table.encodedValue td:first-child + td + td + td + td {
+    width: 48%;
+}
+
+table.encodedValue td i {
+    font-family: sans-serif;
+}
diff --git a/src/devices/tech/dalvik/dex-format.jd b/src/devices/tech/dalvik/dex-format.jd
new file mode 100644
index 0000000..6128b9b
--- /dev/null
+++ b/src/devices/tech/dalvik/dex-format.jd
@@ -0,0 +1,3052 @@
+page.title=Dalvik Executable Format
+@jd:body
+
+<!--
+    Copyright 2010 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.
+-->
+<p>Copyright &copy; 2007 The Android Open Source Project
+
+<p>This document describes the layout and contents of <code>.dex</code>
+files, which are used to hold a set of class definitions and their associated
+adjunct data.</p>
+
+<h1>Guide To Types</h1>
+
+<table class="guide">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>byte</td>
+  <td>8-bit signed int</td>
+</tr>
+<tr>
+  <td>ubyte</td>
+  <td>8-bit unsigned int</td>
+</tr>
+<tr>
+  <td>short</td>
+  <td>16-bit signed int, little-endian</td>
+</tr>
+<tr>
+  <td>ushort</td>
+  <td>16-bit unsigned int, little-endian</td>
+</tr>
+<tr>
+  <td>int</td>
+  <td>32-bit signed int, little-endian</td>
+</tr>
+<tr>
+  <td>uint</td>
+  <td>32-bit unsigned int, little-endian</td>
+</tr>
+<tr>
+  <td>long</td>
+  <td>64-bit signed int, little-endian</td>
+</tr>
+<tr>
+  <td>ulong</td>
+  <td>64-bit unsigned int, little-endian</td>
+</tr>
+<tr>
+  <td>sleb128</td>
+  <td>signed LEB128, variable-length (see below)</td>
+</tr>
+<tr>
+  <td>uleb128</td>
+  <td>unsigned LEB128, variable-length (see below)</td>
+</tr>
+<tr>
+  <td>uleb128p1</td>
+  <td>unsigned LEB128 plus <code>1</code>, variable-length (see below)</td>
+</tr>
+</tbody>
+</table>
+
+<h3>LEB128</h3>
+
+<p>LEB128 ("<b>L</b>ittle-<b>E</b>ndian <b>B</b>ase <b>128</b>") is a
+variable-length encoding for
+arbitrary signed or unsigned integer quantities. The format was
+borrowed from the <a href="http://dwarfstd.org/Dwarf3Std.php">DWARF3</a>
+specification. In a <code>.dex</code> file, LEB128 is only ever used to
+encode 32-bit quantities.</p>
+
+<p>Each LEB128 encoded value consists of one to five
+bytes, which together represent a single 32-bit value. Each
+byte has its most significant bit set except for the final byte in the
+sequence, which has its most significant bit clear. The remaining
+seven bits of each byte are payload, with the least significant seven
+bits of the quantity in the first byte, the next seven in the second
+byte and so on. In the case of a signed LEB128 (<code>sleb128</code>),
+the most significant payload bit of the final byte in the sequence is
+sign-extended to produce the final value. In the unsigned case
+(<code>uleb128</code>), any bits not explicitly represented are
+interpreted as <code>0</code>.
+
+<table class="leb128Bits">
+<thead>
+<tr><th colspan="16">Bitwise diagram of a two-byte LEB128 value</th></tr>
+<tr>
+  <th colspan="8">First byte</td>
+  <th colspan="8">Second byte</td>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td class="start1"><code>1</code></td>
+  <td>bit<sub>6</sub></td>
+  <td>bit<sub>5</sub></td>
+  <td>bit<sub>4</sub></td>
+  <td>bit<sub>3</sub></td>
+  <td>bit<sub>2</sub></td>
+  <td>bit<sub>1</sub></td>
+  <td>bit<sub>0</sub></td>
+  <td class="start2"><code>0</code></td>
+  <td>bit<sub>13</sub></td>
+  <td>bit<sub>12</sub></td>
+  <td>bit<sub>11</sub></td>
+  <td>bit<sub>10</sub></td>
+  <td>bit<sub>9</sub></td>
+  <td>bit<sub>8</sub></td>
+  <td class="end2">bit<sub>7</sub></td>
+</tr>
+</tbody>
+</table>
+
+<p>The variant <code>uleb128p1</code> is used to represent a signed
+value, where the representation is of the value <i>plus one</i> encoded
+as a <code>uleb128</code>. This makes the encoding of <code>-1</code>
+(alternatively thought of as the unsigned value <code>0xffffffff</code>)
+&mdash; but no other negative number &mdash; a single byte, and is
+useful in exactly those cases where the represented number must either
+be non-negative or <code>-1</code> (or <code>0xffffffff</code>),
+and where no other negative values are allowed (or where large unsigned
+values are unlikely to be needed).</p>
+
+<p>Here are some examples of the formats:</p>
+
+<table class="leb128">
+<thead>
+<tr>
+  <th>Encoded Sequence</th>
+  <th>As <code>sleb128</code></th>
+  <th>As <code>uleb128</code></th>
+  <th>As <code>uleb128p1</code></th>
+</tr>
+</thead>
+<tbody>
+  <tr><td>00</td><td>0</td><td>0</td><td>-1</td></tr>
+  <tr><td>01</td><td>1</td><td>1</td><td>0</td></tr>
+  <tr><td>7f</td><td>-1</td><td>127</td><td>126</td></tr>
+  <tr><td>80 7f</td><td>-128</td><td>16256</td><td>16255</td></tr>
+</tbody>
+</table>
+
+<h1>Overall File Layout</h1>
+
+<table class="format">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>header</td>
+  <td>header_item</td>
+  <td>the header</td>
+</tr>
+<tr>
+  <td>string_ids</td>
+  <td>string_id_item[]</td>
+  <td>string identifiers list. These are identifiers for all the strings
+    used by this file, either for internal naming (e.g., type descriptors)
+    or as constant objects referred to by code. This list must be sorted
+    by string contents, using UTF-16 code point values (not in a
+    locale-sensitive manner), and it must not contain any duplicate entries.
+  </td>
+</tr>
+<tr>
+  <td>type_ids</td>
+  <td>type_id_item[]</td>
+  <td>type identifiers list. These are identifiers for all types (classes,
+    arrays, or primitive types) referred to by this file, whether defined
+    in the file or not. This list must be sorted by <code>string_id</code>
+    index, and it must not contain any duplicate entries.
+  </td>
+</tr>
+<tr>
+  <td>proto_ids</td>
+  <td>proto_id_item[]</td>
+  <td>method prototype identifiers list. These are identifiers for all
+    prototypes referred to by this file. This list must be sorted in
+    return-type (by <code>type_id</code> index) major order, and then
+    by arguments (also by <code>type_id</code> index). The list must not
+    contain any duplicate entries.
+  </td>
+</tr>
+<tr>
+  <td>field_ids</td>
+  <td>field_id_item[]</td>
+  <td>field identifiers list. These are identifiers for all fields
+    referred to by this file, whether defined in the file or not. This
+    list must be sorted, where the defining type (by <code>type_id</code>
+    index) is the major order, field name (by <code>string_id</code> index)
+    is the intermediate order, and type (by <code>type_id</code> index)
+    is the minor order. The list must not contain any duplicate entries.
+  </td>
+</tr>
+<tr>
+  <td>method_ids</td>
+  <td>method_id_item[]</td>
+  <td>method identifiers list. These are identifiers for all methods
+    referred to by this file, whether defined in the file or not. This
+    list must be sorted, where the defining type (by <code>type_id</code>
+    index) is the major order, method name (by <code>string_id</code>
+    index) is the intermediate order, and method prototype (by
+    <code>proto_id</code> index) is the minor order.  The list must not
+    contain any duplicate entries.
+  </td>
+</tr>
+<tr>
+  <td>class_defs</td>
+  <td>class_def_item[]</td>
+  <td>class definitions list. The classes must be ordered such that a given
+    class's superclass and implemented interfaces appear in the
+    list earlier than the referring class. Furthermore, it is invalid for
+    a definition for the same-named class to appear more than once in
+    the list.
+  </td>
+</tr>
+<tr>
+  <td>data</td>
+  <td>ubyte[]</td>
+  <td>data area, containing all the support data for the tables listed above.
+    Different items have different alignment requirements, and
+    padding bytes are inserted before each item if necessary to achieve
+    proper alignment.
+  </td>
+</tr>
+<tr>
+  <td>link_data</td>
+  <td>ubyte[]</td>
+  <td>data used in statically linked files. The format of the data in
+    this section is left unspecified by this document.
+    This section is empty in unlinked files, and runtime implementations
+    may use it as they see fit.
+  </td>
+</tr>
+</tbody>
+</table>
+
+<h1>Bitfield, String, and Constant Definitions</h1>
+
+<h2><code>DEX_FILE_MAGIC</code></h2>
+<h4>embedded in <code>header_item</code></h4>
+
+<p>The constant array/string <code>DEX_FILE_MAGIC</code> is the list of
+bytes that must appear at the beginning of a <code>.dex</code> file
+in order for it to be recognized as such. The value intentionally
+contains a newline (<code>"\n"</code> or <code>0x0a</code>) and a
+null byte (<code>"\0"</code> or <code>0x00</code>) in order to help
+in the detection of certain forms of corruption. The value also
+encodes a format version number as three decimal digits, which is
+expected to increase monotonically over time as the format evolves.</p>
+
+<pre>
+ubyte[8] DEX_FILE_MAGIC = { 0x64 0x65 0x78 0x0a 0x30 0x33 0x35 0x00 }
+                        = "dex\n035\0"
+</pre>
+
+<p><b>Note:</b> At least a couple earlier versions of the format have
+been used in widely-available public software releases. For example,
+version <code>009</code> was used for the M3 releases of the
+Android platform (November&ndash;December 2007),
+and version <code>013</code> was used for the M5 releases of the Android
+platform (February&ndash;March 2008). In several respects, these earlier
+versions of the format differ significantly from the version described in this
+document.</p>
+
+<h2><code>ENDIAN_CONSTANT</code> and <code>REVERSE_ENDIAN_CONSTANT</code></h2>
+<h4>embedded in <code>header_item</code></h4>
+
+<p>The constant <code>ENDIAN_CONSTANT</code> is used to indicate the
+endianness of the file in which it is found. Although the standard
+<code>.dex</code> format is little-endian, implementations may choose
+to perform byte-swapping. Should an implementation come across a
+header whose <code>endian_tag</code> is <code>REVERSE_ENDIAN_CONSTANT</code>
+instead of <code>ENDIAN_CONSTANT</code>, it would know that the file
+has been byte-swapped from the expected form.</p>
+
+<pre>
+uint ENDIAN_CONSTANT = 0x12345678;
+uint REVERSE_ENDIAN_CONSTANT = 0x78563412;
+</pre>
+
+<h2><code>NO_INDEX</code></h2>
+<h4>embedded in <code>class_def_item</code> and
+<code>debug_info_item</code></h4>
+
+<p>The constant <code>NO_INDEX</code> is used to indicate that
+an index value is absent.</p>
+
+<p><b>Note:</b> This value isn't defined to be
+<code>0</code>, because that is in fact typically a valid index.</p>
+
+<p><b>Also Note:</b> The chosen value for <code>NO_INDEX</code> is
+representable as a single byte in the <code>uleb128p1</code> encoding.</p>
+
+<pre>
+uint NO_INDEX = 0xffffffff;    // == -1 if treated as a signed int
+</pre>
+
+<h2><code>access_flags</code> Definitions</h2>
+<h4>embedded in <code>class_def_item</code>,
+<code>encoded_field</code>, <code>encoded_method</code>, and
+<code>InnerClass</code></h4>
+
+<p>Bitfields of these flags are used to indicate the accessibility and
+overall properties of classes and class members.</p>
+
+<table class="accessFlags">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Value</th>
+  <th>For Classes (and <code>InnerClass</code> annotations)</th>
+  <th>For Fields</th>
+  <th>For Methods</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>ACC_PUBLIC</td>
+  <td>0x1</td>
+  <td><code>public</code>: visible everywhere</td>
+  <td><code>public</code>: visible everywhere</td>
+  <td><code>public</code>: visible everywhere</td>
+</tr>
+<tr>
+  <td>ACC_PRIVATE</td>
+  <td>0x2</td>
+  <td><super>*</super>
+    <code>private</code>: only visible to defining class
+  </td>
+  <td><code>private</code>: only visible to defining class</td>
+  <td><code>private</code>: only visible to defining class</td>
+</tr>
+<tr>
+  <td>ACC_PROTECTED</td>
+  <td>0x4</td>
+  <td><super>*</super>
+    <code>protected</code>: visible to package and subclasses
+  </td>
+  <td><code>protected</code>: visible to package and subclasses</td>
+  <td><code>protected</code>: visible to package and subclasses</td>
+</tr>
+<tr>
+  <td>ACC_STATIC</td>
+  <td>0x8</td>
+  <td><super>*</super>
+    <code>static</code>: is not constructed with an outer
+    <code>this</code> reference</td>
+  <td><code>static</code>: global to defining class</td>
+  <td><code>static</code>: does not take a <code>this</code> argument</td>
+</tr>
+<tr>
+  <td>ACC_FINAL</td>
+  <td>0x10</td>
+  <td><code>final</code>: not subclassable</td>
+  <td><code>final</code>: immutable after construction</td>
+  <td><code>final</code>: not overridable</td>
+</tr>
+<tr>
+  <td>ACC_SYNCHRONIZED</td>
+  <td>0x20</td>
+  <td>&nbsp;</td>
+  <td>&nbsp;</td>
+  <td><code>synchronized</code>: associated lock automatically acquired
+    around call to this method. <b>Note:</b> This is only valid to set when
+    <code>ACC_NATIVE</code> is also set.</td>
+</tr>
+<tr>
+  <td>ACC_VOLATILE</td>
+  <td>0x40</td>
+  <td>&nbsp;</td>
+  <td><code>volatile</code>: special access rules to help with thread
+    safety</td>
+  <td>&nbsp;</td>
+</tr>
+<tr>
+  <td>ACC_BRIDGE</td>
+  <td>0x40</td>
+  <td>&nbsp;</td>
+  <td>&nbsp;</td>
+  <td>bridge method, added automatically by compiler as a type-safe
+    bridge</td>
+</tr>
+<tr>
+  <td>ACC_TRANSIENT</td>
+  <td>0x80</td>
+  <td>&nbsp;</td>
+  <td><code>transient</code>: not to be saved by default serialization</td>
+  <td>&nbsp;</td>
+</tr>
+<tr>
+  <td>ACC_VARARGS</td>
+  <td>0x80</td>
+  <td>&nbsp;</td>
+  <td>&nbsp;</td>
+  <td>last argument should be treated as a "rest" argument by compiler</td>
+</tr>
+<tr>
+  <td>ACC_NATIVE</td>
+  <td>0x100</td>
+  <td>&nbsp;</td>
+  <td>&nbsp;</td>
+  <td><code>native</code>: implemented in native code</td>
+</tr>
+<tr>
+  <td>ACC_INTERFACE</td>
+  <td>0x200</td>
+  <td><code>interface</code>: multiply-implementable abstract class</td>
+  <td>&nbsp;</td>
+  <td>&nbsp;</td>
+</tr>
+<tr>
+  <td>ACC_ABSTRACT</td>
+  <td>0x400</td>
+  <td><code>abstract</code>: not directly instantiable</td>
+  <td>&nbsp;</td>
+  <td><code>abstract</code>: unimplemented by this class</td>
+</tr>
+<tr>
+  <td>ACC_STRICT</td>
+  <td>0x800</td>
+  <td>&nbsp;</td>
+  <td>&nbsp;</td>
+  <td><code>strictfp</code>: strict rules for floating-point arithmetic</td>
+</tr>
+<tr>
+  <td>ACC_SYNTHETIC</td>
+  <td>0x1000</td>
+  <td>not directly defined in source code</td>
+  <td>not directly defined in source code</td>
+  <td>not directly defined in source code</td>
+</tr>
+<tr>
+  <td>ACC_ANNOTATION</td>
+  <td>0x2000</td>
+  <td>declared as an annotation class</td>
+  <td>&nbsp;</td>
+  <td>&nbsp;</td>
+</tr>
+<tr>
+  <td>ACC_ENUM</td>
+  <td>0x4000</td>
+  <td>declared as an enumerated type</td>
+  <td>declared as an enumerated value</td>
+  <td>&nbsp;</td>
+</tr>
+<tr>
+  <td><i>(unused)</i></td>
+  <td>0x8000</td>
+  <td>&nbsp;</td>
+  <td>&nbsp;</td>
+  <td>&nbsp;</td>
+</tr>
+<tr>
+  <td>ACC_CONSTRUCTOR</td>
+  <td>0x10000</td>
+  <td>&nbsp;</td>
+  <td>&nbsp;</td>
+  <td>constructor method (class or instance initializer)</td>
+</tr>
+<tr>
+  <td>ACC_DECLARED_<br/>SYNCHRONIZED</td>
+  <td>0x20000</td>
+  <td>&nbsp;</td>
+  <td>&nbsp;</td>
+  <td>declared <code>synchronized</code>. <b>Note:</b> This has no effect on
+    execution (other than in reflection of this flag, per se).
+  </td>
+</tr>
+</tbody>
+</table>
+
+<p><super>*</super> Only allowed on for <code>InnerClass</code> annotations,
+and must not ever be on in a <code>class_def_item</code>.</p>
+
+<h2>MUTF-8 (Modified UTF-8) Encoding</h2>
+
+<p>As a concession to easier legacy support, the <code>.dex</code> format
+encodes its string data in a de facto standard modified UTF-8 form, hereafter
+referred to as MUTF-8. This form is identical to standard UTF-8, except:</p>
+
+<ul>
+  <li>Only the one-, two-, and three-byte encodings are used.</li>
+  <li>Code points in the range <code>U+10000</code> &hellip;
+    <code>U+10ffff</code> are encoded as a surrogate pair, each of
+    which is represented as a three-byte encoded value.</li>
+  <li>The code point <code>U+0000</code> is encoded in two-byte form.</li>
+  <li>A plain null byte (value <code>0</code>) indicates the end of
+    a string, as is the standard C language interpretation.</li>
+</ul>
+
+<p>The first two items above can be summarized as: MUTF-8
+is an encoding format for UTF-16, instead of being a more direct
+encoding format for Unicode characters.</p>
+
+<p>The final two items above make it simultaneously possible to include
+the code point <code>U+0000</code> in a string <i>and</i> still manipulate
+it as a C-style null-terminated string.</p>
+
+<p>However, the special encoding of <code>U+0000</code> means that, unlike
+normal UTF-8, the result of calling the standard C function
+<code>strcmp()</code> on a pair of MUTF-8 strings does not always
+indicate the properly signed result of comparison of <i>unequal</i> strings.
+When ordering (not just equality) is a concern, the most straightforward
+way to compare MUTF-8 strings is to decode them character by character,
+and compare the decoded values. (However, more clever implementations are
+also possible.)</p>
+
+<p>Please refer to <a href="http://unicode.org">The Unicode
+Standard</a> for further information about character encoding.
+MUTF-8 is actually closer to the (relatively less well-known) encoding
+<a href="http://www.unicode.org/reports/tr26/">CESU-8</a> than to UTF-8
+per se.</p>
+
+<h2><code>encoded_value</code> Encoding</h2>
+<h4>embedded in <code>annotation_element</code> and
+<code>encoded_array_item</code></h4>
+
+<p>An <code>encoded_value</code> is an encoded piece of (nearly)
+arbitrary hierarchically structured data. The encoding is meant to
+be both compact and straightforward to parse.</p>
+
+<table class="format">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>(value_arg &lt;&lt; 5) | value_type</td>
+  <td>ubyte</td>
+  <td>byte indicating the type of the immediately subsequent
+    <code>value</code> along
+    with an optional clarifying argument in the high-order three bits.
+    See below for the various <code>value</code> definitions.
+    In most cases, <code>value_arg</code> encodes the length of
+    the immediately-subsequent <code>value</code> in bytes, as
+    <code>(size - 1)</code>, e.g., <code>0</code> means that
+    the value requires one byte, and <code>7</code> means it requires
+    eight bytes; however, there are exceptions as noted below.
+  </td>
+</tr>
+<tr>
+  <td>value</td>
+  <td>ubyte[]</td>
+  <td>bytes representing the value, variable in length and interpreted
+    differently for different <code>value_type</code> bytes, though
+    always little-endian. See the various value definitions below for
+    details.
+  </td>
+</tr>
+</tbody>
+</table>
+
+<h3>Value Formats</h3>
+
+<table class="encodedValue">
+<thead>
+<tr>
+  <th>Type Name</th>
+  <th><code>value_type</code></th>
+  <th><code>value_arg</code> Format</th>
+  <th><code>value</code> Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>VALUE_BYTE</td>
+  <td>0x00</td>
+  <td><i>(none; must be <code>0</code>)</i></td>
+  <td>ubyte[1]</td>
+  <td>signed one-byte integer value</td>
+</tr>
+<tr>
+  <td>VALUE_SHORT</td>
+  <td>0x02</td>
+  <td>size - 1 (0&hellip;1)</td>
+  <td>ubyte[size]</td>
+  <td>signed two-byte integer value, sign-extended</td>
+</tr>
+<tr>
+  <td>VALUE_CHAR</td>
+  <td>0x03</td>
+  <td>size - 1 (0&hellip;1)</td>
+  <td>ubyte[size]</td>
+  <td>unsigned two-byte integer value, zero-extended</td>
+</tr>
+<tr>
+  <td>VALUE_INT</td>
+  <td>0x04</td>
+  <td>size - 1 (0&hellip;3)</td>
+  <td>ubyte[size]</td>
+  <td>signed four-byte integer value, sign-extended</td>
+</tr>
+<tr>
+  <td>VALUE_LONG</td>
+  <td>0x06</td>
+  <td>size - 1 (0&hellip;7)</td>
+  <td>ubyte[size]</td>
+  <td>signed eight-byte integer value, sign-extended</td>
+</tr>
+<tr>
+  <td>VALUE_FLOAT</td>
+  <td>0x10</td>
+  <td>size - 1 (0&hellip;3)</td>
+  <td>ubyte[size]</td>
+  <td>four-byte bit pattern, zero-extended <i>to the right</i>, and
+    interpreted as an IEEE754 32-bit floating point value
+  </td>
+</tr>
+<tr>
+  <td>VALUE_DOUBLE</td>
+  <td>0x11</td>
+  <td>size - 1 (0&hellip;7)</td>
+  <td>ubyte[size]</td>
+  <td>eight-byte bit pattern, zero-extended <i>to the right</i>, and
+    interpreted as an IEEE754 64-bit floating point value
+  </td>
+</tr>
+<tr>
+  <td>VALUE_STRING</td>
+  <td>0x17</td>
+  <td>size - 1 (0&hellip;3)</td>
+  <td>ubyte[size]</td>
+  <td>unsigned (zero-extended) four-byte integer value,
+    interpreted as an index into
+    the <code>string_ids</code> section and representing a string value
+  </td>
+</tr>
+<tr>
+  <td>VALUE_TYPE</td>
+  <td>0x18</td>
+  <td>size - 1 (0&hellip;3)</td>
+  <td>ubyte[size]</td>
+  <td>unsigned (zero-extended) four-byte integer value,
+    interpreted as an index into
+    the <code>type_ids</code> section and representing a reflective
+    type/class value
+  </td>
+</tr>
+<tr>
+  <td>VALUE_FIELD</td>
+  <td>0x19</td>
+  <td>size - 1 (0&hellip;3)</td>
+  <td>ubyte[size]</td>
+  <td>unsigned (zero-extended) four-byte integer value,
+    interpreted as an index into
+    the <code>field_ids</code> section and representing a reflective
+    field value
+  </td>
+</tr>
+<tr>
+  <td>VALUE_METHOD</td>
+  <td>0x1a</td>
+  <td>size - 1 (0&hellip;3)</td>
+  <td>ubyte[size]</td>
+  <td>unsigned (zero-extended) four-byte integer value,
+    interpreted as an index into
+    the <code>method_ids</code> section and representing a reflective
+    method value
+  </td>
+</tr>
+<tr>
+  <td>VALUE_ENUM</td>
+  <td>0x1b</td>
+  <td>size - 1 (0&hellip;3)</td>
+  <td>ubyte[size]</td>
+  <td>unsigned (zero-extended) four-byte integer value,
+    interpreted as an index into
+    the <code>field_ids</code> section and representing the value of
+    an enumerated type constant
+  </td>
+</tr>
+<tr>
+  <td>VALUE_ARRAY</td>
+  <td>0x1c</td>
+  <td><i>(none; must be <code>0</code>)</i></td>
+  <td>encoded_array</td>
+  <td>an array of values, in the format specified by
+    "<code>encoded_array</code> Format" below. The size
+    of the <code>value</code> is implicit in the encoding.
+  </td>
+</tr>
+<tr>
+  <td>VALUE_ANNOTATION</td>
+  <td>0x1d</td>
+  <td><i>(none; must be <code>0</code>)</i></td>
+  <td>encoded_annotation</td>
+  <td>a sub-annotation, in the format specified by
+    "<code>encoded_annotation</code> Format" below. The size
+    of the <code>value</code> is implicit in the encoding.
+  </td>
+</tr>
+<tr>
+  <td>VALUE_NULL</td>
+  <td>0x1e</td>
+  <td><i>(none; must be <code>0</code>)</i></td>
+  <td><i>(none)</i></td>
+  <td><code>null</code> reference value</td>
+</tr>
+<tr>
+  <td>VALUE_BOOLEAN</td>
+  <td>0x1f</td>
+  <td>boolean (0&hellip;1)</td>
+  <td><i>(none)</i></td>
+  <td>one-bit value; <code>0</code> for <code>false</code> and
+    <code>1</code> for <code>true</code>. The bit is represented in the
+    <code>value_arg</code>.
+  </td>
+</tr>
+</tbody>
+</table>
+
+<h3><code>encoded_array</code> Format</h3>
+
+<table class="format">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>size</td>
+  <td>uleb128</td>
+  <td>number of elements in the array</td>
+</tr>
+<tr>
+  <td>values</td>
+  <td>encoded_value[size]</td>
+  <td>a series of <code>size</code> <code>encoded_value</code> byte
+    sequences in the format specified by this section, concatenated
+    sequentially.
+  </td>
+</tr>
+</tbody>
+</table>
+
+<h3><code>encoded_annotation</code> Format</h3>
+
+<table class="format">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>type_idx</td>
+  <td>uleb128</td>
+  <td>type of the annotation. This must be a class (not array or primitive)
+    type.
+  </td>
+</tr>
+<tr>
+  <td>size</td>
+  <td>uleb128</td>
+  <td>number of name-value mappings in this annotation</td>
+</tr>
+<tr>
+  <td>elements</td>
+  <td>annotation_element[size]</td>
+  <td>elements of the annotataion, represented directly in-line (not as
+    offsets). Elements must be sorted in increasing order by
+    <code>string_id</code> index.
+  </td>
+</tr>
+</tbody>
+</table>
+
+<h3><code>annotation_element</code> Format</h3>
+
+<table class="format">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>name_idx</td>
+  <td>uleb128</td>
+  <td>element name, represented as an index into the
+    <code>string_ids</code> section. The string must conform to the
+    syntax for <i>MemberName</i>, defined above.
+  </td>
+</tr>
+<tr>
+  <td>value</td>
+  <td>encoded_value</td>
+  <td>element value</td>
+</tr>
+</tbody>
+</table>
+
+<h2>String Syntax</h2>
+
+<p>There are several kinds of item in a <code>.dex</code> file which
+ultimately refer to a string. The following BNF-style definitions
+indicate the acceptable syntax for these strings.</p>
+
+<h3><i>SimpleName</i></h3>
+
+<p>A <i>SimpleName</i> is the basis for the syntax of the names of other
+things. The <code>.dex</code> format allows a fair amount of latitude
+here (much more than most common source languages). In brief, a simple
+name consists of any low-ASCII alphabetic character or digit, a few
+specific low-ASCII symbols, and most non-ASCII code points that are not
+control, space, or special characters. Note that surrogate code points
+(in the range <code>U+d800</code> &hellip; <code>U+dfff</code>) are not
+considered valid name characters, per se, but Unicode supplemental
+characters <i>are</i> valid (which are represented by the final
+alternative of the rule for <i>SimpleNameChar</i>), and they should be
+represented in a file as pairs of surrogate code points in the MUTF-8
+encoding.</p>
+
+<table class="bnf">
+  <tr><td colspan="2" class="def"><i>SimpleName</i> &rarr;</td></tr>
+  <tr>
+    <td/>
+    <td><i>SimpleNameChar</i> (<i>SimpleNameChar</i>)*</td>
+  </tr>
+
+  <tr><td colspan="2" class="def"><i>SimpleNameChar</i> &rarr;</td></tr>
+  <tr>
+    <td/>
+    <td><code>'A'</code> &hellip; <code>'Z'</code></td>
+  </tr>
+  <tr>
+    <td class="bar">|</td>
+    <td><code>'a'</code> &hellip; <code>'z'</code></td>
+  </tr>
+  <tr>
+    <td class="bar">|</td>
+    <td><code>'0'</code> &hellip; <code>'9'</code></td>
+  </tr>
+  <tr>
+    <td class="bar">|</td>
+    <td><code>'$'</code></td>
+  </tr>
+  <tr>
+    <td class="bar">|</td>
+    <td><code>'-'</code></td>
+  </tr>
+  <tr>
+    <td class="bar">|</td>
+    <td><code>'_'</code></td>
+  </tr>
+  <tr>
+    <td class="bar">|</td>
+    <td><code>U+00a1</code> &hellip; <code>U+1fff</code></td>
+  </tr>
+  <tr>
+    <td class="bar">|</td>
+    <td><code>U+2010</code> &hellip; <code>U+2027</code></td>
+  </tr>
+  <tr>
+    <td class="bar">|</td>
+    <td><code>U+2030</code> &hellip; <code>U+d7ff</code></td>
+  </tr>
+  <tr>
+    <td class="bar">|</td>
+    <td><code>U+e000</code> &hellip; <code>U+ffef</code></td>
+  </tr>
+  <tr>
+    <td class="bar">|</td>
+    <td><code>U+10000</code> &hellip; <code>U+10ffff</code></td>
+  </tr>
+</table>
+
+<h3><i>MemberName</i></h3>
+<h4>used by <code>field_id_item</code> and <code>method_id_item</code></h4>
+
+<p>A <i>MemberName</i> is the name of a member of a class, members being
+fields, methods, and inner classes.</p>
+
+<table class="bnf">
+  <tr><td colspan="2" class="def"><i>MemberName</i> &rarr;</td></tr>
+  <tr>
+    <td/>
+    <td><i>SimpleName</i></td>
+  </tr>
+  <tr>
+    <td class="bar">|</td>
+    <td><code>'&lt;'</code> <i>SimpleName</i> <code>'&gt;'</code></td>
+  </tr>
+</table>
+
+<h3><i>FullClassName</i></h3>
+
+<p>A <i>FullClassName</i> is a fully-qualified class name, including an
+optional package specifier followed by a required name.</p>
+
+<table class="bnf">
+  <tr><td colspan="2" class="def"><i>FullClassName</i> &rarr;</td></tr>
+  <tr>
+    <td/>
+    <td><i>OptionalPackagePrefix</i> <i>SimpleName</i></td>
+  </tr>
+
+  <tr><td colspan="2" class="def"><i>OptionalPackagePrefix</i> &rarr;</td></tr>
+  <tr>
+    <td/>
+    <td>(<i>SimpleName</i> <code>'/'</code>)*</td>
+  </tr>
+</table>
+
+<h3><i>TypeDescriptor</i></h3>
+<h4>used by <code>type_id_item</code></h4>
+
+<p>A <i>TypeDescriptor</i> is the representation of any type, including
+primitives, classes, arrays, and <code>void</code>. See below for
+the meaning of the various versions.</p>
+
+<table class="bnf">
+  <tr><td colspan="2" class="def"><i>TypeDescriptor</i> &rarr;</td></tr>
+  <tr>
+    <td/>
+    <td><code>'V'</code></td>
+  </tr>
+  <tr>
+    <td class="bar">|</td>
+    <td><i>FieldTypeDescriptor</i></td>
+  </tr>
+
+  <tr><td colspan="2" class="def"><i>FieldTypeDescriptor</i> &rarr;</td></tr>
+  <tr>
+    <td/>
+    <td><i>NonArrayFieldTypeDescriptor</i></td>
+  </tr>
+  <tr>
+    <td class="bar">|</td>
+    <td>(<code>'['</code> * 1&hellip;255)
+      <i>NonArrayFieldTypeDescriptor</i></td>
+  </tr>
+
+  <tr>
+    <td colspan="2" class="def"><i>NonArrayFieldTypeDescriptor</i>&rarr;</td>
+  </tr>
+  <tr>
+    <td/>
+    <td><code>'Z'</code></td>
+  </tr>
+  <tr>
+    <td class="bar">|</td>
+    <td><code>'B'</code></td>
+  </tr>
+  <tr>
+    <td class="bar">|</td>
+    <td><code>'S'</code></td>
+  </tr>
+  <tr>
+    <td class="bar">|</td>
+    <td><code>'C'</code></td>
+  </tr>
+  <tr>
+    <td class="bar">|</td>
+    <td><code>'I'</code></td>
+  </tr>
+  <tr>
+    <td class="bar">|</td>
+    <td><code>'J'</code></td>
+  </tr>
+  <tr>
+    <td class="bar">|</td>
+    <td><code>'F'</code></td>
+  </tr>
+  <tr>
+    <td class="bar">|</td>
+    <td><code>'D'</code></td>
+  </tr>
+  <tr>
+    <td class="bar">|</td>
+    <td><code>'L'</code> <i>FullClassName</i> <code>';'</code></td>
+  </tr>
+</table>
+
+<h3><i>ShortyDescriptor</i></h3>
+<h4>used by <code>proto_id_item</code></h4>
+
+<p>A <i>ShortyDescriptor</i> is the short form representation of a method
+prototype, including return and parameter types, except that there is
+no distinction between various reference (class or array) types. Instead,
+all reference types are represented by a single <code>'L'</code> character.</p>
+
+<table class="bnf">
+  <tr><td colspan="2" class="def"><i>ShortyDescriptor</i> &rarr;</td></tr>
+  <tr>
+    <td/>
+    <td><i>ShortyReturnType</i> (<i>ShortyFieldType</i>)*</td>
+  </tr>
+
+  <tr><td colspan="2" class="def"><i>ShortyReturnType</i> &rarr;</td></tr>
+  <tr>
+    <td/>
+    <td><code>'V'</code></td>
+  </tr>
+  <tr>
+    <td class="bar">|</td>
+    <td><i>ShortyFieldType</i></td>
+  </tr>
+
+  <tr><td colspan="2" class="def"><i>ShortyFieldType</i> &rarr;</td></tr>
+  <tr>
+    <td/>
+    <td><code>'Z'</code></td>
+  </tr>
+  <tr>
+    <td class="bar">|</td>
+    <td><code>'B'</code></td>
+  </tr>
+  <tr>
+    <td class="bar">|</td>
+    <td><code>'S'</code></td>
+  </tr>
+  <tr>
+    <td class="bar">|</td>
+    <td><code>'C'</code></td>
+  </tr>
+  <tr>
+    <td class="bar">|</td>
+    <td><code>'I'</code></td>
+  </tr>
+  <tr>
+    <td class="bar">|</td>
+    <td><code>'J'</code></td>
+  </tr>
+  <tr>
+    <td class="bar">|</td>
+    <td><code>'F'</code></td>
+  </tr>
+  <tr>
+    <td class="bar">|</td>
+    <td><code>'D'</code></td>
+  </tr>
+  <tr>
+    <td class="bar">|</td>
+    <td><code>'L'</code></td>
+  </tr>
+</table>
+
+<h2><i>TypeDescriptor</i> Semantics</h2>
+
+<p>This is the meaning of each of the variants of <i>TypeDescriptor</i>.</p>
+
+<table class="descriptor">
+<thead>
+<tr>
+  <th>Syntax</th>
+  <th>Meaning</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>V</td>
+  <td><code>void</code>; only valid for return types</td>
+</tr>
+<tr>
+  <td>Z</td>
+  <td><code>boolean</code></td>
+</tr>
+<tr>
+  <td>B</td>
+  <td><code>byte</code></td>
+</tr>
+<tr>
+  <td>S</td>
+  <td><code>short</code></td>
+</tr>
+<tr>
+  <td>C</td>
+  <td><code>char</code></td>
+</tr>
+<tr>
+  <td>I</td>
+  <td><code>int</code></td>
+</tr>
+<tr>
+  <td>J</td>
+  <td><code>long</code></td>
+</tr>
+<tr>
+  <td>F</td>
+  <td><code>float</code></td>
+</tr>
+<tr>
+  <td>D</td>
+  <td><code>double</code></td>
+</tr>
+<tr>
+  <td>L<i>fully/qualified/Name</i>;</td>
+  <td>the class <code><i>fully.qualified.Name</i></code></td>
+</tr>
+<tr>
+  <td>[<i>descriptor</i></td>
+  <td>array of <code><i>descriptor</i></code>, usable recursively for
+    arrays-of-arrays, though it is invalid to have more than 255
+    dimensions.
+  </td>
+</tr>
+</tbody>
+</table>
+
+<h1>Items and Related Structures</h1>
+
+<p>This section includes definitions for each of the top-level items that
+may appear in a <code>.dex</code> file.
+
+<h2><code>header_item</code></h2>
+<h4>appears in the <code>header</code> section</h4>
+<h4>alignment: 4 bytes</h4>
+
+<table class="format">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>magic</td>
+  <td>ubyte[8] = DEX_FILE_MAGIC</td>
+  <td>magic value. See discussion above under "<code>DEX_FILE_MAGIC</code>"
+    for more details.
+  </td>
+</tr>
+<tr>
+  <td>checksum</td>
+  <td>uint</td>
+  <td>adler32 checksum of the rest of the file (everything but
+    <code>magic</code> and this field); used to detect file corruption
+  </td>
+</tr>
+<tr>
+  <td>signature</td>
+  <td>ubyte[20]</td>
+  <td>SHA-1 signature (hash) of the rest of the file (everything but
+    <code>magic</code>, <code>checksum</code>, and this field); used
+    to uniquely identify files
+  </td>
+</tr>
+<tr>
+  <td>file_size</td>
+  <td>uint</td>
+  <td>size of the entire file (including the header), in bytes
+</tr>
+<tr>
+  <td>header_size</td>
+  <td>uint = 0x70</td>
+  <td>size of the header (this entire section), in bytes. This allows for at
+    least a limited amount of backwards/forwards compatibility without
+    invalidating the format.
+  </td>
+</tr>
+<tr>
+  <td>endian_tag</td>
+  <td>uint = ENDIAN_CONSTANT</td>
+  <td>endianness tag. See discussion above under "<code>ENDIAN_CONSTANT</code>
+    and <code>REVERSE_ENDIAN_CONSTANT</code>" for more details.
+  </td>
+</tr>
+<tr>
+  <td>link_size</td>
+  <td>uint</td>
+  <td>size of the link section, or <code>0</code> if this file isn't
+    statically linked</td>
+</tr>
+<tr>
+  <td>link_off</td>
+  <td>uint</td>
+  <td>offset from the start of the file to the link section, or
+    <code>0</code> if <code>link_size == 0</code>. The offset, if non-zero,
+    should be to an offset into the <code>link_data</code> section. The
+    format of the data pointed at is left unspecified by this document;
+    this header field (and the previous) are left as hooks for use by
+    runtime implementations.
+  </td>
+</tr>
+<tr>
+  <td>map_off</td>
+  <td>uint</td>
+  <td>offset from the start of the file to the map item, or
+    <code>0</code> if this file has no map. The offset, if non-zero,
+    should be to an offset into the <code>data</code> section,
+    and the data should be in the format specified by "<code>map_list</code>"
+    below.
+  </td>
+</tr>
+<tr>
+  <td>string_ids_size</td>
+  <td>uint</td>
+  <td>count of strings in the string identifiers list</td>
+</tr>
+<tr>
+  <td>string_ids_off</td>
+  <td>uint</td>
+  <td>offset from the start of the file to the string identifiers list, or
+    <code>0</code> if <code>string_ids_size == 0</code> (admittedly a
+    strange edge case). The offset, if non-zero,
+    should be to the start of the <code>string_ids</code> section.
+  </td>
+</tr>
+<tr>
+  <td>type_ids_size</td>
+  <td>uint</td>
+  <td>count of elements in the type identifiers list</td>
+</tr>
+<tr>
+  <td>type_ids_off</td>
+  <td>uint</td>
+  <td>offset from the start of the file to the type identifiers list, or
+    <code>0</code> if <code>type_ids_size == 0</code> (admittedly a
+    strange edge case). The offset, if non-zero,
+    should be to the start of the <code>type_ids</code>
+    section.
+  </td>
+</tr>
+<tr>
+  <td>proto_ids_size</td>
+  <td>uint</td>
+  <td>count of elements in the prototype identifiers list</td>
+</tr>
+<tr>
+  <td>proto_ids_off</td>
+  <td>uint</td>
+  <td>offset from the start of the file to the prototype identifiers list, or
+    <code>0</code> if <code>proto_ids_size == 0</code> (admittedly a
+    strange edge case). The offset, if non-zero,
+    should be to the start of the <code>proto_ids</code>
+    section.
+  </td>
+</tr>
+<tr>
+  <td>field_ids_size</td>
+  <td>uint</td>
+  <td>count of elements in the field identifiers list</td>
+</tr>
+<tr>
+  <td>field_ids_off</td>
+  <td>uint</td>
+  <td>offset from the start of the file to the field identifiers list, or
+    <code>0</code> if <code>field_ids_size == 0</code>. The offset, if
+    non-zero, should be to the start of the <code>field_ids</code>
+    section.</td>
+</td>
+</tr>
+<tr>
+  <td>method_ids_size</td>
+  <td>uint</td>
+  <td>count of elements in the method identifiers list</td>
+</tr>
+<tr>
+  <td>method_ids_off</td>
+  <td>uint</td>
+  <td>offset from the start of the file to the method identifiers list, or
+    <code>0</code> if <code>method_ids_size == 0</code>. The offset, if
+    non-zero, should be to the start of the <code>method_ids</code>
+    section.</td>
+</tr>
+<tr>
+  <td>class_defs_size</td>
+  <td>uint</td>
+  <td>count of elements in the class definitions list</td>
+</tr>
+<tr>
+  <td>class_defs_off</td>
+  <td>uint</td>
+  <td>offset from the start of the file to the class definitions list, or
+    <code>0</code> if <code>class_defs_size == 0</code> (admittedly a
+    strange edge case). The offset, if non-zero,
+    should be to the start of the <code>class_defs</code> section.
+  </td>
+</tr>
+<tr>
+  <td>data_size</td>
+  <td>uint</td>
+  <td>Size of <code>data</code> section in bytes. Must be an even
+    multiple of sizeof(uint).</td>
+</tr>
+<tr>
+  <td>data_off</td>
+  <td>uint</td>
+  <td>offset from the start of the file to the start of the
+   <code>data</code> section.
+  </td>
+</tr>
+</tbody>
+</table>
+
+<h2><code>map_list</code></h2>
+<h4>appears in the <code>data</code> section</h4>
+<h4>referenced from <code>header_item</code></h4>
+<h4>alignment: 4 bytes</h4>
+
+<p>This is a list of the entire contents of a file, in order. It
+contains some redundancy with respect to the <code>header_item</code>
+but is intended to be an easy form to use to iterate over an entire
+file. A given type must appear at most once in a map, but there is no
+restriction on what order types may appear in, other than the
+restrictions implied by the rest of the format (e.g., a
+<code>header</code> section must appear first, followed by a
+<code>string_ids</code> section, etc.). Additionally, the map entries must
+be ordered by initial offset and must not overlap.</p>
+
+<table class="format">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>size</td>
+  <td>uint</td>
+  <td>size of the list, in entries</td>
+</tr>
+<tr>
+  <td>list</td>
+  <td>map_item[size]</td>
+  <td>elements of the list</td>
+</tr>
+</tbody>
+</table>
+
+<h3><code>map_item</code> Format</h3>
+
+<table class="format">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>type</td>
+  <td>ushort</td>
+  <td>type of the items; see table below</td>
+</tr>
+<tr>
+  <td>unused</td>
+  <td>ushort</td>
+  <td><i>(unused)</i></td>
+</tr>
+<tr>
+  <td>size</td>
+  <td>uint</td>
+  <td>count of the number of items to be found at the indicated offset</td>
+</tr>
+<tr>
+  <td>offset</td>
+  <td>uint</td>
+  <td>offset from the start of the file to the items in question</td>
+</tr>
+</tbody>
+</table>
+
+
+<h3>Type Codes</h3>
+
+<table class="typeCodes">
+<thead>
+<tr>
+  <th>Item Type</th>
+  <th>Constant</th>
+  <th>Value</th>
+  <th>Item Size In Bytes</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>header_item</td>
+  <td>TYPE_HEADER_ITEM</td>
+  <td>0x0000</td>
+  <td>0x70</td>
+</tr>
+<tr>
+  <td>string_id_item</td>
+  <td>TYPE_STRING_ID_ITEM</td>
+  <td>0x0001</td>
+  <td>0x04</td>
+</tr>
+<tr>
+  <td>type_id_item</td>
+  <td>TYPE_TYPE_ID_ITEM</td>
+  <td>0x0002</td>
+  <td>0x04</td>
+</tr>
+<tr>
+  <td>proto_id_item</td>
+  <td>TYPE_PROTO_ID_ITEM</td>
+  <td>0x0003</td>
+  <td>0x0c</td>
+</tr>
+<tr>
+  <td>field_id_item</td>
+  <td>TYPE_FIELD_ID_ITEM</td>
+  <td>0x0004</td>
+  <td>0x08</td>
+</tr>
+<tr>
+  <td>method_id_item</td>
+  <td>TYPE_METHOD_ID_ITEM</td>
+  <td>0x0005</td>
+  <td>0x08</td>
+</tr>
+<tr>
+  <td>class_def_item</td>
+  <td>TYPE_CLASS_DEF_ITEM</td>
+  <td>0x0006</td>
+  <td>0x20</td>
+</tr>
+<tr>
+  <td>map_list</td>
+  <td>TYPE_MAP_LIST</td>
+  <td>0x1000</td>
+  <td>4 + (item.size * 12)</td>
+</tr>
+<tr>
+  <td>type_list</td>
+  <td>TYPE_TYPE_LIST</td>
+  <td>0x1001</td>
+  <td>4 + (item.size * 2)</td>
+</tr>
+<tr>
+  <td>annotation_set_ref_list</td>
+  <td>TYPE_ANNOTATION_SET_REF_LIST</td>
+  <td>0x1002</td>
+  <td>4 + (item.size * 4)</td>
+</tr>
+<tr>
+  <td>annotation_set_item</td>
+  <td>TYPE_ANNOTATION_SET_ITEM</td>
+  <td>0x1003</td>
+  <td>4 + (item.size * 4)</td>
+</tr>
+<tr>
+  <td>class_data_item</td>
+  <td>TYPE_CLASS_DATA_ITEM</td>
+  <td>0x2000</td>
+  <td><i>implicit; must parse</i></td>
+</tr>
+<tr>
+  <td>code_item</td>
+  <td>TYPE_CODE_ITEM</td>
+  <td>0x2001</td>
+  <td><i>implicit; must parse</i></td>
+</tr>
+<tr>
+  <td>string_data_item</td>
+  <td>TYPE_STRING_DATA_ITEM</td>
+  <td>0x2002</td>
+  <td><i>implicit; must parse</i></td>
+</tr>
+<tr>
+  <td>debug_info_item</td>
+  <td>TYPE_DEBUG_INFO_ITEM</td>
+  <td>0x2003</td>
+  <td><i>implicit; must parse</i></td>
+</tr>
+<tr>
+  <td>annotation_item</td>
+  <td>TYPE_ANNOTATION_ITEM</td>
+  <td>0x2004</td>
+  <td><i>implicit; must parse</i></td>
+</tr>
+<tr>
+  <td>encoded_array_item</td>
+  <td>TYPE_ENCODED_ARRAY_ITEM</td>
+  <td>0x2005</td>
+  <td><i>implicit; must parse</i></td>
+</tr>
+<tr>
+  <td>annotations_directory_item</td>
+  <td>TYPE_ANNOTATIONS_DIRECTORY_ITEM</td>
+  <td>0x2006</td>
+  <td><i>implicit; must parse</i></td>
+</tr>
+</tbody>
+</table>
+
+
+<h2><code>string_id_item</code></h2>
+<h4>appears in the <code>string_ids</code> section</h4>
+<h4>alignment: 4 bytes</h4>
+
+<table class="format">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>string_data_off</td>
+  <td>uint</td>
+  <td>offset from the start of the file to the string data for this
+    item. The offset should be to a location
+    in the <code>data</code> section, and the data should be in the
+    format specified by "<code>string_data_item</code>" below.
+    There is no alignment requirement for the offset.
+  </td>
+</tr>
+</tbody>
+</table>
+
+<h2><code>string_data_item</code></h2>
+<h4>appears in the <code>data</code> section</h4>
+<h4>alignment: none (byte-aligned)</h4>
+
+<table class="format">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>utf16_size</td>
+  <td>uleb128</td>
+  <td>size of this string, in UTF-16 code units (which is the "string
+    length" in many systems). That is, this is the decoded length of
+    the string. (The encoded length is implied by the position of
+    the <code>0</code> byte.)</td>
+</tr>
+<tr>
+  <td>data</td>
+  <td>ubyte[]</td>
+  <td>a series of MUTF-8 code units (a.k.a. octets, a.k.a. bytes)
+    followed by a byte of value <code>0</code>. See
+    "MUTF-8 (Modified UTF-8) Encoding" above for details and
+    discussion about the data format.
+    <p><b>Note:</b> It is acceptable to have a string which includes
+    (the encoded form of) UTF-16 surrogate code units (that is,
+    <code>U+d800</code> &hellip; <code>U+dfff</code>)
+    either in isolation or out-of-order with respect to the usual
+    encoding of Unicode into UTF-16. It is up to higher-level uses of
+    strings to reject such invalid encodings, if appropriate.</p>
+  </td>
+</tr>
+</tbody>
+</table>
+
+<h2><code>type_id_item</code></h2>
+<h4>appears in the <code>type_ids</code> section</h4>
+<h4>alignment: 4 bytes</h4>
+
+<table class="format">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>descriptor_idx</td>
+  <td>uint</td>
+  <td>index into the <code>string_ids</code> list for the descriptor
+    string of this type. The string must conform to the syntax for
+    <i>TypeDescriptor</i>, defined above.
+  </td>
+</tr>
+</tbody>
+</table>
+
+<h2><code>proto_id_item</code></h2>
+<h4>appears in the <code>proto_ids</code> section</h4>
+<h4>alignment: 4 bytes</h4>
+
+<table class="format">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>shorty_idx</td>
+  <td>uint</td>
+  <td>index into the <code>string_ids</code> list for the short-form
+    descriptor string of this prototype. The string must conform to the
+    syntax for <i>ShortyDescriptor</i>, defined above, and must correspond
+    to the return type and parameters of this item.
+  </td>
+</tr>
+<tr>
+  <td>return_type_idx</td>
+  <td>uint</td>
+  <td>index into the <code>type_ids</code> list for the return type
+    of this prototype
+  </td>
+</tr>
+<tr>
+  <td>parameters_off</td>
+  <td>uint</td>
+  <td>offset from the start of the file to the list of parameter types
+    for this prototype, or <code>0</code> if this prototype has no
+    parameters. This offset, if non-zero, should be in the
+    <code>data</code> section, and the data there should be in the
+    format specified by <code>"type_list"</code> below. Additionally, there
+    should be no reference to the type <code>void</code> in the list.
+  </td>
+</tr>
+</tbody>
+</table>
+
+<h2><code>field_id_item</code></h2>
+<h4>appears in the <code>field_ids</code> section</h4>
+<h4>alignment: 4 bytes</h4>
+
+<table class="format">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>class_idx</td>
+  <td>ushort</td>
+  <td>index into the <code>type_ids</code> list for the definer of this
+    field. This must be a class type, and not an array or primitive type.
+  </td>
+</tr>
+<tr>
+  <td>type_idx</td>
+  <td>ushort</td>
+  <td>index into the <code>type_ids</code> list for the type of
+    this field
+  </td>
+</tr>
+<tr>
+  <td>name_idx</td>
+  <td>uint</td>
+  <td>index into the <code>string_ids</code> list for the name of this
+    field. The string must conform to the syntax for <i>MemberName</i>,
+    defined above.
+  </td>
+</tr>
+</tbody>
+</table>
+
+<h2><code>method_id_item</code></h2>
+<h4>appears in the <code>method_ids</code> section</h4>
+<h4>alignment: 4 bytes</h4>
+
+<table class="format">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>class_idx</td>
+  <td>ushort</td>
+  <td>index into the <code>type_ids</code> list for the definer of this
+    method. This must be a class or array type, and not a primitive type.
+  </td>
+</tr>
+<tr>
+  <td>proto_idx</td>
+  <td>ushort</td>
+  <td>index into the <code>proto_ids</code> list for the prototype of
+    this method
+  </td>
+</tr>
+<tr>
+  <td>name_idx</td>
+  <td>uint</td>
+  <td>index into the <code>string_ids</code> list for the name of this
+    method. The string must conform to the syntax for <i>MemberName</i>,
+    defined above.
+  </td>
+</tr>
+</tbody>
+</table>
+
+<h2><code>class_def_item</code></h2>
+<h4>appears in the <code>class_defs</code> section</h4>
+<h4>alignment: 4 bytes</h4>
+
+<table class="format">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>class_idx</td>
+  <td>uint</td>
+  <td>index into the <code>type_ids</code> list for this class.
+    This must be a class type, and not an array or primitive type.
+  </td>
+</tr>
+<tr>
+  <td>access_flags</td>
+  <td>uint</td>
+  <td>access flags for the class (<code>public</code>, <code>final</code>,
+    etc.). See "<code>access_flags</code> Definitions" for details.
+  </td>
+</tr>
+<tr>
+  <td>superclass_idx</td>
+  <td>uint</td>
+  <td>index into the <code>type_ids</code> list for the superclass, or
+    the constant value <code>NO_INDEX</code> if this class has no
+    superclass (i.e., it is a root class such as <code>Object</code>).
+    If present, this must be a class type, and not an array or primitive type.
+  </td>
+</tr>
+<tr>
+  <td>interfaces_off</td>
+  <td>uint</td>
+  <td>offset from the start of the file to the list of interfaces, or
+    <code>0</code> if there are none. This offset
+    should be in the <code>data</code> section, and the data
+    there should be in the format specified by
+    "<code>type_list</code>" below. Each of the elements of the list
+    must be a class type (not an array or primitive type), and there
+    must not be any duplicates.
+  </td>
+</tr>
+<tr>
+  <td>source_file_idx</td>
+  <td>uint</td>
+  <td>index into the <code>string_ids</code> list for the name of the
+    file containing the original source for (at least most of) this class,
+    or the special value <code>NO_INDEX</code> to represent a lack of
+    this information. The <code>debug_info_item</code> of any given method
+    may override this source file, but the expectation is that most classes
+    will only come from one source file.
+  </td>
+</tr>
+<tr>
+  <td>annotations_off</td>
+  <td>uint</td>
+  <td>offset from the start of the file to the annotations structure
+    for this class, or <code>0</code> if there are no annotations on
+    this class. This offset, if non-zero, should be in the
+    <code>data</code> section, and the data there should be in
+    the format specified by "<code>annotations_directory_item</code>" below,
+    with all items referring to this class as the definer.
+  </td>
+</tr>
+<tr>
+  <td>class_data_off</td>
+  <td>uint</td>
+  <td>offset from the start of the file to the associated
+    class data for this item, or <code>0</code> if there is no class
+    data for this class. (This may be the case, for example, if this class
+    is a marker interface.) The offset, if non-zero, should be in the
+    <code>data</code> section, and the data there should be in the
+    format specified by "<code>class_data_item</code>" below, with all
+    items referring to this class as the definer.
+  </td>
+</tr>
+<tr>
+  <td>static_values_off</td>
+  <td>uint</td>
+  <td>offset from the start of the file to the list of initial
+    values for <code>static</code> fields, or <code>0</code> if there
+    are none (and all <code>static</code> fields are to be initialized with
+    <code>0</code> or <code>null</code>). This offset should be in the
+    <code>data</code> section, and the data there should be in the
+    format specified by "<code>encoded_array_item</code>" below. The size
+    of the array must be no larger than the number of <code>static</code>
+    fields declared by this class, and the elements correspond to the
+    <code>static</code> fields in the same order as declared in the
+    corresponding <code>field_list</code>. The type of each array
+    element must match the declared type of its corresponding field.
+    If there are fewer elements in the array than there are
+    <code>static</code> fields, then the leftover fields are initialized
+    with a type-appropriate <code>0</code> or <code>null</code>.
+  </td>
+</tr>
+</tbody>
+</table>
+
+<h2><code>class_data_item</code></h2>
+<h4>referenced from <code>class_def_item</code></h4>
+<h4>appears in the <code>data</code> section</h4>
+<h4>alignment: none (byte-aligned)</h4>
+
+<table class="format">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>static_fields_size</td>
+  <td>uleb128</td>
+  <td>the number of static fields defined in this item</td>
+</tr>
+<tr>
+  <td>instance_fields_size</td>
+  <td>uleb128</td>
+  <td>the number of instance fields defined in this item</td>
+</tr>
+<tr>
+  <td>direct_methods_size</td>
+  <td>uleb128</td>
+  <td>the number of direct methods defined in this item</td>
+</tr>
+<tr>
+  <td>virtual_methods_size</td>
+  <td>uleb128</td>
+  <td>the number of virtual methods defined in this item</td>
+</tr>
+<tr>
+  <td>static_fields</td>
+  <td>encoded_field[static_fields_size]</td>
+  <td>the defined static fields, represented as a sequence of
+    encoded elements. The fields must be sorted by
+    <code>field_idx</code> in increasing order.
+  </td>
+</tr>
+<tr>
+  <td>instance_fields</td>
+  <td>encoded_field[instance_fields_size]</td>
+  <td>the defined instance fields, represented as a sequence of
+    encoded elements. The fields must be sorted by
+    <code>field_idx</code> in increasing order.
+  </td>
+</tr>
+<tr>
+  <td>direct_methods</td>
+  <td>encoded_method[direct_methods_size]</td>
+  <td>the defined direct (any of <code>static</code>, <code>private</code>,
+    or constructor) methods, represented as a sequence of
+    encoded elements. The methods must be sorted by
+    <code>method_idx</code> in increasing order.
+  </td>
+</tr>
+<tr>
+  <td>virtual_methods</td>
+  <td>encoded_method[virtual_methods_size]</td>
+  <td>the defined virtual (none of <code>static</code>, <code>private</code>,
+    or constructor) methods, represented as a sequence of
+    encoded elements. This list should <i>not</i> include inherited
+    methods unless overridden by the class that this item represents. The
+    methods must be sorted by <code>method_idx</code> in increasing order.
+  </td>
+</tr>
+</tbody>
+</table>
+
+<p><b>Note:</b> All elements' <code>field_id</code>s and
+<code>method_id</code>s must refer to the same defining class.</p>
+
+<h3><code>encoded_field</code> Format</h3>
+
+<table class="format">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>field_idx_diff</td>
+  <td>uleb128</td>
+  <td>index into the <code>field_ids</code> list for the identity of this
+    field (includes the name and descriptor), represented as a difference
+    from the index of previous element in the list. The index of the
+    first element in a list is represented directly.
+  </td>
+</tr>
+<tr>
+  <td>access_flags</td>
+  <td>uleb128</td>
+  <td>access flags for the field (<code>public</code>, <code>final</code>,
+    etc.). See "<code>access_flags</code> Definitions" for details.
+  </td>
+</tr>
+</tbody>
+</table>
+
+<h3><code>encoded_method</code> Format</h3>
+
+<table class="format">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>method_idx_diff</td>
+  <td>uleb128</td>
+  <td>index into the <code>method_ids</code> list for the identity of this
+    method (includes the name and descriptor), represented as a difference
+    from the index of previous element in the list. The index of the
+    first element in a list is represented directly.
+  </td>
+</tr>
+<tr>
+  <td>access_flags</td>
+  <td>uleb128</td>
+  <td>access flags for the method (<code>public</code>, <code>final</code>,
+    etc.). See "<code>access_flags</code> Definitions" for details.
+  </td>
+</tr>
+<tr>
+  <td>code_off</td>
+  <td>uleb128</td>
+  <td>offset from the start of the file to the code structure for this
+    method, or <code>0</code> if this method is either <code>abstract</code>
+    or <code>native</code>. The offset should be to a location in the
+    <code>data</code> section. The format of the data is specified by
+    "<code>code_item</code>" below.
+  </td>
+</tr>
+</tbody>
+</table>
+
+<h2><code>type_list</code></h2>
+<h4>referenced from <code>class_def_item</code> and
+<code>proto_id_item</code></h4>
+<h4>appears in the <code>data</code> section</h4>
+<h4>alignment: 4 bytes</h4>
+
+<table class="format">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>size</td>
+  <td>uint</td>
+  <td>size of the list, in entries</td>
+</tr>
+<tr>
+  <td>list</td>
+  <td>type_item[size]</td>
+  <td>elements of the list</td>
+</tr>
+</tbody>
+</table>
+
+<h3><code>type_item</code> Format</h3>
+
+<table class="format">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>type_idx</td>
+  <td>ushort</td>
+  <td>index into the <code>type_ids</code> list</td>
+</tr>
+</tbody>
+</table>
+
+<h2><code>code_item</code></h2>
+<h4>referenced from <code>encoded_method</code></h4>
+<h4>appears in the <code>data</code> section</h4>
+<h4>alignment: 4 bytes</h4>
+
+<table class="format">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>registers_size</td>
+  <td>ushort</td>
+  <td>the number of registers used by this code</td>
+</tr>
+<tr>
+  <td>ins_size</td>
+  <td>ushort</td>
+  <td>the number of words of incoming arguments to the method that this
+    code is for</td>
+</tr>
+<tr>
+  <td>outs_size</td>
+  <td>ushort</td>
+  <td>the number of words of outgoing argument space required by this
+    code for method invocation
+  </td>
+</tr>
+<tr>
+  <td>tries_size</td>
+  <td>ushort</td>
+  <td>the number of <code>try_item</code>s for this instance. If non-zero,
+    then these appear as the <code>tries</code> array just after the
+    <code>insns</code> in this instance.
+  </td>
+</tr>
+<tr>
+  <td>debug_info_off</td>
+  <td>uint</td>
+  <td>offset from the start of the file to the debug info (line numbers +
+    local variable info) sequence for this code, or <code>0</code> if
+    there simply is no information. The offset, if non-zero, should be
+    to a location in the <code>data</code> section. The format of
+    the data is specified by "<code>debug_info_item</code>" below.
+  </td>
+</tr>
+<tr>
+  <td>insns_size</td>
+  <td>uint</td>
+  <td>size of the instructions list, in 16-bit code units</td>
+</tr>
+<tr>
+  <td>insns</td>
+  <td>ushort[insns_size]</td>
+  <td>actual array of bytecode. The format of code in an <code>insns</code>
+    array is specified by the companion document
+    <a href="dalvik-bytecode.html">"Bytecode for the Dalvik VM"</a>. Note
+    that though this is defined as an array of <code>ushort</code>, there
+    are some internal structures that prefer four-byte alignment. Also,
+    if this happens to be in an endian-swapped file, then the swapping is
+    <i>only</i> done on individual <code>ushort</code>s and not on the
+    larger internal structures.
+  </td>
+</tr>
+<tr>
+  <td>padding</td>
+  <td>ushort <i>(optional)</i> = 0</td>
+  <td>two bytes of padding to make <code>tries</code> four-byte aligned.
+    This element is only present if <code>tries_size</code> is non-zero
+    and <code>insns_size</code> is odd.
+  </td>
+</tr>
+<tr>
+  <td>tries</td>
+  <td>try_item[tries_size] <i>(optional)</i></td>
+  <td>array indicating where in the code exceptions are caught and
+    how to handle them. Elements of the array must be non-overlapping in
+    range and in order from low to high address. This element is only
+    present if <code>tries_size</code> is non-zero.
+  </td>
+</tr>
+<tr>
+  <td>handlers</td>
+  <td>encoded_catch_handler_list <i>(optional)</i></td>
+  <td>bytes representing a list of lists of catch types and associated
+    handler addresses. Each <code>try_item</code> has a byte-wise offset
+    into this structure. This element is only present if
+    <code>tries_size</code> is non-zero.
+  </td>
+</tr>
+</tbody>
+</table>
+
+<h3><code>try_item</code> Format </h3>
+
+<table class="format">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>start_addr</td>
+  <td>uint</td>
+  <td>start address of the block of code covered by this entry. The address
+    is a count of 16-bit code units to the start of the first covered
+    instruction.
+  </td>
+</tr>
+<tr>
+  <td>insn_count</td>
+  <td>ushort</td>
+  <td>number of 16-bit code units covered by this entry. The last code
+    unit covered (inclusive) is <code>start_addr + insn_count - 1</code>.
+  </td>
+</tr>
+<tr>
+  <td>handler_off</td>
+  <td>ushort</td>
+  <td>offset in bytes from the start of the associated
+    <code>encoded_catch_hander_list</code> to the
+    <code>encoded_catch_handler</code> for this entry. This must be an
+    offset to the start of an <code>encoded_catch_handler</code>.
+  </td>
+</tr>
+</tbody>
+</table>
+
+<h3><code>encoded_catch_handler_list</code> Format</h3>
+
+<table class="format">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>size</td>
+  <td>uleb128</td>
+  <td>size of this list, in entries</td>
+</tr>
+<tr>
+  <td>list</td>
+  <td>encoded_catch_handler[handlers_size]</td>
+  <td>actual list of handler lists, represented directly (not as offsets),
+    and concatenated sequentially</td>
+</tr>
+</tbody>
+</table>
+
+<h3><code>encoded_catch_handler</code> Format</h3>
+
+<table class="format">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>size</td>
+  <td>sleb128</td>
+  <td>number of catch types in this list. If non-positive, then this is
+    the negative of the number of catch types, and the catches are followed
+    by a catch-all handler. For example: A <code>size</code> of <code>0</code>
+    means that there is a catch-all but no explicitly typed catches.
+    A <code>size</code> of <code>2</code> means that there are two explicitly
+    typed catches and no catch-all. And a <code>size</code> of <code>-1</code>
+    means that there is one typed catch along with a catch-all.
+  </td>
+</tr>
+<tr>
+  <td>handlers</td>
+  <td>encoded_type_addr_pair[abs(size)]</td>
+  <td>stream of <code>abs(size)</code> encoded items, one for each caught
+    type, in the order that the types should be tested.
+  </td>
+</tr>
+<tr>
+  <td>catch_all_addr</td>
+  <td>uleb128 <i>(optional)</i></td>
+  <td>bytecode address of the catch-all handler. This element is only
+    present if <code>size</code> is non-positive.
+  </td>
+</tr>
+</tbody>
+</table>
+
+<h3><code>encoded_type_addr_pair</code> Format</h3>
+
+<table class="format">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>type_idx</td>
+  <td>uleb128</td>
+  <td>index into the <code>type_ids</code> list for the type of the
+    exception to catch
+  </td>
+</tr>
+<tr>
+  <td>addr</td>
+  <td>uleb128</td>
+  <td>bytecode address of the associated exception handler</td>
+</tr>
+</tbody>
+</table>
+
+<h2><code>debug_info_item</code></h2>
+<h4>referenced from <code>code_item</code></h4>
+<h4>appears in the <code>data</code> section</h4>
+<h4>alignment: none (byte-aligned)</h4>
+
+<p>Each <code>debug_info_item</code> defines a DWARF3-inspired byte-coded
+state machine that, when interpreted, emits the positions
+table and (potentially) the local variable information for a
+<code>code_item</code>. The sequence begins with a variable-length
+header (the length of which depends on the number of method
+parameters), is followed by the state machine bytecodes, and ends
+with an <code>DBG_END_SEQUENCE</code> byte.</p>
+
+<p>The state machine consists of five registers. The
+<code>address</code> register represents the instruction offset in the
+associated <code>insns_item</code> in 16-bit code units. The
+<code>address</code> register starts at <code>0</code> at the beginning of each
+<code>debug_info</code> sequence and must only monotonically increase.
+The <code>line</code> register represents what source line number
+should be associated with the next positions table entry emitted by
+the state machine. It is initialized in the sequence header, and may
+change in positive or negative directions but must never be less than
+<code>1</code>. The <code>source_file</code> register represents the
+source file that the line number entries refer to. It is initialized to
+the value of <code>source_file_idx</code> in <code>class_def_item</code>.
+The other two variables, <code>prologue_end</code> and
+<code>epilogue_begin</code>, are boolean flags (initialized to
+<code>false</code>) that indicate whether the next position emitted
+should be considered a method prologue or epilogue. The state machine
+must also track the name and type of the last local variable live in
+each register for the <code>DBG_RESTART_LOCAL</code> code.</p>
+
+<p>The header is as follows:</p>
+
+<table class="format">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+ <td>line_start</td>
+ <td>uleb128</td>
+ <td>the initial value for the state machine's <code>line</code> register.
+    Does not represent an actual positions entry.
+ </td>
+</tr>
+<tr>
+ <td>parameters_size</td>
+ <td>uleb128</td>
+ <td>the number of parameter names that are encoded. There should be
+   one per method parameter, excluding an instance method's <code>this</code>,
+   if any.
+ </td>
+</tr>
+<tr>
+ <td>parameter_names</td>
+ <td>uleb128p1[parameters_size]</td>
+ <td>string index of the method parameter name. An encoded value of
+   <code>NO_INDEX</code> indicates that no name
+   is available for the associated parameter. The type descriptor
+   and signature are implied from the method descriptor and signature.
+ </td>
+</tr>
+</tbody>
+</table>
+
+<p>The byte code values are as follows:</p>
+
+<table class="debugByteCode">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Value</th>
+  <th>Format</th>
+  <th>Arguments</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>DBG_END_SEQUENCE</td>
+  <td>0x00</td>
+  <td></td>
+  <td><i>(none)</i></td>
+  <td>terminates a debug info sequence for a <code>code_item</code></td>
+</tr>
+<tr>
+  <td>DBG_ADVANCE_PC</td>
+  <td>0x01</td>
+  <td>uleb128&nbsp;addr_diff</td>
+  <td><code>addr_diff</code>: amount to add to address register</td>
+  <td>advances the address register without emitting a positions entry</td>
+</tr>
+<tr>
+  <td>DBG_ADVANCE_LINE</td>
+  <td>0x02</td>
+  <td>sleb128&nbsp;line_diff</td>
+  <td><code>line_diff</code>: amount to change line register by</td>
+  <td>advances the line register without emitting a positions entry</td>
+</tr>
+<tr>
+  <td>DBG_START_LOCAL</td>
+  <td>0x03</td>
+  <td>uleb128&nbsp;register_num<br/>
+    uleb128p1&nbsp;name_idx<br/>
+    uleb128p1&nbsp;type_idx
+  </td>
+  <td><code>register_num</code>: register that will contain local<br/>
+    <code>name_idx</code>: string index of the name<br/>
+    <code>type_idx</code>: type index of the type
+  </td>
+  <td>introduces a local variable at the current address. Either
+    <code>name_idx</code> or <code>type_idx</code> may be
+    <code>NO_INDEX</code> to indicate that that value is unknown.
+  </td>
+</tr>
+<tr>
+  <td>DBG_START_LOCAL_EXTENDED</td>
+  <td>0x04</td>
+  <td>uleb128&nbsp;register_num<br/>
+    uleb128p1&nbsp;name_idx<br/>
+    uleb128p1&nbsp;type_idx<br/>
+    uleb128p1&nbsp;sig_idx
+  </td>
+  <td><code>register_num</code>: register that will contain local<br/>
+    <code>name_idx</code>: string index of the name<br/>
+    <code>type_idx</code>: type index of the type<br/>
+    <code>sig_idx</code>: string index of the type signature
+  </td>
+  <td>introduces a local with a type signature at the current address.
+    Any of <code>name_idx</code>, <code>type_idx</code>, or
+    <code>sig_idx</code> may be <code>NO_INDEX</code>
+    to indicate that that value is unknown. (If <code>sig_idx</code> is
+    <code>-1</code>, though, the same data could be represented more
+    efficiently using the opcode <code>DBG_START_LOCAL</code>.)
+    <p><b>Note:</b> See the discussion under
+    "<code>dalvik.annotation.Signature</code>" below for caveats about
+    handling signatures.</p>
+  </td>
+</tr>
+<tr>
+  <td>DBG_END_LOCAL</td>
+  <td>0x05</td>
+  <td>uleb128&nbsp;register_num</td>
+  <td><code>register_num</code>: register that contained local</td>
+  <td>marks a currently-live local variable as out of scope at the current
+    address
+  </td>
+</tr>
+<tr>
+  <td>DBG_RESTART_LOCAL</td>
+  <td>0x06</td>
+  <td>uleb128&nbsp;register_num</td>
+  <td><code>register_num</code>: register to restart</td>
+  <td>re-introduces a local variable at the current address. The name
+    and type are the same as the last local that was live in the specified
+    register.
+  </td>
+</tr>
+<tr>
+  <td>DBG_SET_PROLOGUE_END</td>
+  <td>0x07</td>
+  <td></td>
+  <td><i>(none)</i></td>
+  <td>sets the <code>prologue_end</code> state machine register,
+    indicating that the next position entry that is added should be
+    considered the end of a method prologue (an appropriate place for
+    a method breakpoint). The <code>prologue_end</code> register is
+    cleared by any special (<code>&gt;= 0x0a</code>) opcode.
+  </td>
+</tr>
+<tr>
+  <td>DBG_SET_EPILOGUE_BEGIN</td>
+  <td>0x08</td>
+  <td></td>
+  <td><i>(none)</i></td>
+  <td>sets the <code>epilogue_begin</code> state machine register,
+    indicating that the next position entry that is added should be
+    considered the beginning of a method epilogue (an appropriate place
+    to suspend execution before method exit).
+    The <code>epilogue_begin</code> register is cleared by any special
+    (<code>&gt;= 0x0a</code>) opcode.
+  </td>
+</tr>
+<tr>
+  <td>DBG_SET_FILE</td>
+  <td>0x09</td>
+  <td>uleb128p1&nbsp;name_idx</td>
+  <td><code>name_idx</code>: string index of source file name;
+    <code>NO_INDEX</code> if unknown
+  </td>
+  <td>indicates that all subsequent line number entries make reference to this
+    source file name, instead of the default name specified in
+    <code>code_item</code>
+  </td>
+</tr>
+<tr>
+  <td><i>Special Opcodes</i></td>
+  <!-- When updating the range below, make sure to search for other
+  instances of 0x0a in this section. -->
+  <td>0x0a&hellip;0xff</td>
+  <td></td>
+  <td><i>(none)</i></td>
+  <td>advances the <code>line</code> and <code>address</code> registers,
+    emits a position entry, and clears <code>prologue_end</code> and
+    <code>epilogue_begin</code>. See below for description.
+  </td>
+</tr>
+</tbody>
+</table>
+
+<h3>Special Opcodes</h3>
+
+<p>Opcodes with values between <code>0x0a</code> and <code>0xff</code>
+(inclusive) move both the <code>line</code> and <code>address</code>
+registers by a small amount and then emit a new position table entry.
+The formula for the increments are as follows:</p>
+
+<pre>
+DBG_FIRST_SPECIAL = 0x0a  // the smallest special opcode
+DBG_LINE_BASE   = -4      // the smallest line number increment
+DBG_LINE_RANGE  = 15      // the number of line increments represented
+
+adjusted_opcode = opcode - DBG_FIRST_SPECIAL
+
+line += DBG_LINE_BASE + (adjusted_opcode % DBG_LINE_RANGE)
+address += (adjusted_opcode / DBG_LINE_RANGE)
+</pre>
+
+<h2><code>annotations_directory_item</code></h2>
+<h4>referenced from <code>class_def_item</code></h4>
+<h4>appears in the <code>data</code> section</h4>
+<h4>alignment: 4 bytes</h4>
+
+<table class="format">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>class_annotations_off</td>
+  <td>uint</td>
+  <td>offset from the start of the file to the annotations made directly
+    on the class, or <code>0</code> if the class has no direct annotations.
+    The offset, if non-zero, should be to a location in the
+    <code>data</code> section. The format of the data is specified
+    by "<code>annotation_set_item</code>" below.
+  </td>
+</tr>
+<tr>
+  <td>fields_size</td>
+  <td>uint</td>
+  <td>count of fields annotated by this item</td>
+</tr>
+<tr>
+  <td>annotated_methods_size</td>
+  <td>uint</td>
+  <td>count of methods annotated by this item</td>
+</tr>
+<tr>
+  <td>annotated_parameters_size</td>
+  <td>uint</td>
+  <td>count of method parameter lists annotated by this item</td>
+</tr>
+<tr>
+  <td>field_annotations</td>
+  <td>field_annotation[fields_size] <i>(optional)</i></td>
+  <td>list of associated field annotations. The elements of the list must
+    be sorted in increasing order, by <code>field_idx</code>.
+  </td>
+</tr>
+<tr>
+  <td>method_annotations</td>
+  <td>method_annotation[methods_size] <i>(optional)</i></td>
+  <td>list of associated method annotations. The elements of the list must
+    be sorted in increasing order, by <code>method_idx</code>.
+  </td>
+</tr>
+<tr>
+  <td>parameter_annotations</td>
+  <td>parameter_annotation[parameters_size] <i>(optional)</i></td>
+  <td>list of associated method parameter annotations. The elements of the
+    list must be sorted in increasing order, by <code>method_idx</code>.
+  </td>
+</tr>
+</tbody>
+</table>
+
+<p><b>Note:</b> All elements' <code>field_id</code>s and
+<code>method_id</code>s must refer to the same defining class.</p>
+
+<h3><code>field_annotation</code> Format</h3>
+
+<table class="format">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>field_idx</td>
+  <td>uint</td>
+  <td>index into the <code>field_ids</code> list for the identity of the
+    field being annotated
+  </td>
+</tr>
+<tr>
+  <td>annotations_off</td>
+  <td>uint</td>
+  <td>offset from the start of the file to the list of annotations for
+    the field. The offset should be to a location in the <code>data</code>
+    section. The format of the data is specified by
+    "<code>annotation_set_item</code>" below.
+  </td>
+</tr>
+</tbody>
+</table>
+
+<h3><code>method_annotation</code> Format</h3>
+
+<table class="format">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>method_idx</td>
+  <td>uint</td>
+  <td>index into the <code>method_ids</code> list for the identity of the
+    method being annotated
+  </td>
+</tr>
+<tr>
+  <td>annotations_off</td>
+  <td>uint</td>
+  <td>offset from the start of the file to the list of annotations for
+    the method. The offset should be to a location in the
+    <code>data</code> section. The format of the data is specified by
+    "<code>annotation_set_item</code>" below.
+  </td>
+</tr>
+</tbody>
+</table>
+
+<h3><code>parameter_annotation</code> Format</h2>
+
+<table class="format">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>method_idx</td>
+  <td>uint</td>
+  <td>index into the <code>method_ids</code> list for the identity of the
+    method whose parameters are being annotated
+  </td>
+</tr>
+<tr>
+  <td>annotations_off</td>
+  <td>uint</td>
+  <td>offset from the start of the file to the list of annotations for
+    the method parameters. The offset should be to a location in the
+    <code>data</code> section. The format of the data is specified by
+    "<code>annotation_set_ref_list</code>" below.
+  </td>
+</tr>
+</tbody>
+</table>
+
+<h2><code>annotation_set_ref_list</code></h2>
+<h4>referenced from <code>parameter_annotations_item</code></h4>
+<h4>appears in the <code>data</code> section</h4>
+<h4>alignment: 4 bytes</h4>
+
+<table class="format">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>size</td>
+  <td>uint</td>
+  <td>size of the list, in entries</td>
+</tr>
+<tr>
+  <td>list</td>
+  <td>annotation_set_ref_item[size]</td>
+  <td>elements of the list</td>
+</tr>
+</tbody>
+</table>
+
+<h3><code>annotation_set_ref_item</code> Format</h3>
+
+<table class="format">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>annotations_off</td>
+  <td>uint</td>
+  <td>offset from the start of the file to the referenced annotation set
+    or <code>0</code> if there are no annotations for this element.
+    The offset, if non-zero, should be to a location in the <code>data</code>
+    section. The format of the data is specified by
+    "<code>annotation_set_item</code>" below.
+  </td>
+</tr>
+</tbody>
+</table>
+
+<h2><code>annotation_set_item</code></h2>
+<h4>referenced from <code>annotations_directory_item</code>,
+<code>field_annotations_item</code>,
+<code>method_annotations_item</code>, and
+<code>annotation_set_ref_item</code></h4>
+<h4>appears in the <code>data</code> section</h4>
+<h4>alignment: 4 bytes</h4>
+
+<table class="format">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>size</td>
+  <td>uint</td>
+  <td>size of the set, in entries</td>
+</tr>
+<tr>
+  <td>entries</td>
+  <td>annotation_off_item[size]</td>
+  <td>elements of the set. The elements must be sorted in increasing order,
+    by <code>type_idx</code>.
+  </td>
+</tr>
+</tbody>
+</table>
+
+<h3><code>annotation_off_item</code> Format</h3>
+
+<table class="format">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>annotation_off</td>
+  <td>uint</td>
+  <td>offset from the start of the file to an annotation.
+    The offset should be to a location in the <code>data</code> section,
+    and the format of the data at that location is specified by
+    "<code>annotation_item</code>" below.
+  </td>
+</tr>
+</tbody>
+</table>
+
+
+<h2><code>annotation_item</code></h2>
+<h4>referenced from <code>annotation_set_item</code></h4>
+<h4>appears in the <code>data</code> section</h4>
+<h4>alignment: none (byte-aligned)</h4>
+
+<table class="format">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>visibility</td>
+  <td>ubyte</td>
+  <td>intended visibility of this annotation (see below)</td>
+</tr>
+<tr>
+  <td>annotation</td>
+  <td>encoded_annotation</td>
+  <td>encoded annotation contents, in the format described by
+    "<code>encoded_annotation</code> Format" under
+    "<code>encoded_value</code> Encoding" above.
+  </td>
+</tr>
+</tbody>
+</table>
+
+<h3>Visibility values</h3>
+
+<p>These are the options for the <code>visibility</code> field in an
+<code>annotation_item</code>:</p>
+
+<table class="format">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Value</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>VISIBILITY_BUILD</td>
+  <td>0x00</td>
+  <td>intended only to be visible at build time (e.g., during compilation
+    of other code)
+  </td>
+</tr>
+<tr>
+  <td>VISIBILITY_RUNTIME</td>
+  <td>0x01</td>
+  <td>intended to visible at runtime</td>
+</tr>
+<tr>
+  <td>VISIBILITY_SYSTEM</td>
+  <td>0x02</td>
+  <td>intended to visible at runtime, but only to the underlying system
+    (and not to regular user code)
+  </td>
+</tr>
+</tbody>
+</table>
+
+<h2><code>encoded_array_item</code></h2>
+<h4>referenced from <code>class_def_item</code></h4>
+<h4>appears in the <code>data</code> section</h4>
+<h4>alignment: none (byte-aligned)</h4>
+
+<table class="format">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>value</td>
+  <td>encoded_array</td>
+  <td>bytes representing the encoded array value, in the format specified
+    by "<code>encoded_array</code> Format" under "<code>encoded_value</code>
+    Encoding" above.
+  </td>
+</tr>
+</tbody>
+</table>
+
+<h1>System Annotations</h1>
+
+<p>System annotations are used to represent various pieces of reflective
+information about classes (and methods and fields). This information is
+generally only accessed indirectly by client (non-system) code.</p>
+
+<p>System annotations are represented in <code>.dex</code> files as
+annotations with visibility set to <code>VISIBILITY_SYSTEM</code>.
+
+<h2><code>dalvik.annotation.AnnotationDefault</code></h2>
+<h4>appears on methods in annotation interfaces</h4>
+
+<p>An <code>AnnotationDefault</code> annotation is attached to each
+annotation interface which wishes to indicate default bindings.</p>
+
+<table class="format">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>value</td>
+  <td>Annotation</td>
+  <td>the default bindings for this annotation, represented as an annotation
+    of this type. The annotation need not include all names defined by the
+    annotation; missing names simply do not have defaults.
+  </td>
+</tr>
+</tbody>
+</table>
+
+<h2><code>dalvik.annotation.EnclosingClass</code></h2>
+<h4>appears on classes</h4>
+
+<p>An <code>EnclosingClass</code> annotation is attached to each class
+which is either defined as a member of another class, per se, or is
+anonymous but not defined within a method body (e.g., a synthetic
+inner class). Every class that has this annotation must also have an
+<code>InnerClass</code> annotation. Additionally, a class must not have
+both an <code>EnclosingClass</code> and an
+<code>EnclosingMethod</code> annotation.</p>
+
+<table class="format">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>value</td>
+  <td>Class</td>
+  <td>the class which most closely lexically scopes this class</td>
+</tr>
+</tbody>
+</table>
+
+<h2><code>dalvik.annotation.EnclosingMethod</code></h2>
+<h4>appears on classes</h4>
+
+<p>An <code>EnclosingMethod</code> annotation is attached to each class
+which is defined inside a method body. Every class that has this
+annotation must also have an <code>InnerClass</code> annotation.
+Additionally, a class must not have both an <code>EnclosingClass</code>
+and an <code>EnclosingMethod</code> annotation.</p>
+
+<table class="format">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>value</td>
+  <td>Method</td>
+  <td>the method which most closely lexically scopes this class</td>
+</tr>
+</tbody>
+</table>
+
+<h2><code>dalvik.annotation.InnerClass</code></h2>
+<h4>appears on classes</h4>
+
+<p>An <code>InnerClass</code> annotation is attached to each class
+which is defined in the lexical scope of another class's definition.
+Any class which has this annotation must also have <i>either</i> an
+<code>EnclosingClass</code> annotation <i>or</i> an
+<code>EnclosingMethod</code> annotation.</p>
+
+<table class="format">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>name</td>
+  <td>String</td>
+  <td>the originally declared simple name of this class (not including any
+    package prefix). If this class is anonymous, then the name is
+    <code>null</code>.
+  </td>
+</tr>
+<tr>
+  <td>accessFlags</td>
+  <td>int</td>
+  <td>the originally declared access flags of the class (which may differ
+    from the effective flags because of a mismatch between the execution
+    models of the source language and target virtual machine)
+  </td>
+</tr>
+</tbody>
+</table>
+
+<h2><code>dalvik.annotation.MemberClasses</code></h2>
+<h4>appears on classes</h4>
+
+<p>A <code>MemberClasses</code> annotation is attached to each class
+which declares member classes. (A member class is a direct inner class
+that has a name.)</p>
+
+<table class="format">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>value</td>
+  <td>Class[]</td>
+  <td>array of the member classes</td>
+</tr>
+</tbody>
+</table>
+
+<h2><code>dalvik.annotation.Signature</code></h2>
+<h4>appears on classes, fields, and methods</h4>
+
+<p>A <code>Signature</code> annotation is attached to each class,
+field, or method which is defined in terms of a more complicated type
+than is representable by a <code>type_id_item</code>. The
+<code>.dex</code> format does not define the format for signatures; it
+is merely meant to be able to represent whatever signatures a source
+language requires for successful implementation of that language's
+semantics. As such, signatures are not generally parsed (or verified)
+by virtual machine implementations. The signatures simply get handed
+off to higher-level APIs and tools (such as debuggers). Any use of a
+signature, therefore, should be written so as not to make any
+assumptions about only receiving valid signatures, explicitly guarding
+itself against the possibility of coming across a syntactically
+invalid signature.</p>
+
+<p>Because signature strings tend to have a lot of duplicated content,
+a <code>Signature</code> annotation is defined as an <i>array</i> of
+strings, where duplicated elements naturally refer to the same
+underlying data, and the signature is taken to be the concatenation of
+all the strings in the array. There are no rules about how to pull
+apart a signature into separate strings; that is entirely up to the
+tools that generate <code>.dex</code> files.</p>
+
+<table class="format">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>value</td>
+  <td>String[]</td>
+  <td>the signature of this class or member, as an array of strings that
+    is to be concatenated together</td>
+</tr>
+</tbody>
+</table>
+
+<h2><code>dalvik.annotation.Throws</code></h2>
+<h4>appears on methods</h4>
+
+<p>A <code>Throws</code> annotation is attached to each method which is
+declared to throw one or more exception types.</p>
+
+<table class="format">
+<thead>
+<tr>
+  <th>Name</th>
+  <th>Format</th>
+  <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>value</td>
+  <td>Class[]</td>
+  <td>the array of exception types thrown</td>
+</tr>
+</tbody>
+</table>
diff --git a/src/devices/tech/dalvik/index.jd b/src/devices/tech/dalvik/index.jd
new file mode 100644
index 0000000..ed36231
--- /dev/null
+++ b/src/devices/tech/dalvik/index.jd
@@ -0,0 +1,25 @@
+page.title=Dalvik Technical Information
+@jd:body
+
+<!--
+    Copyright 2010 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.
+-->
+<p>Dalvik is the managed runtime used by applications and some system
+services on Android. Dalvik was originally created specifically for
+the Android project.</p>
+<p>Much of the documentation in this directory is intended to help
+with the ongoing development of Dalvik, as opposed to most of the
+other documentation on this site, which is geared more towards
+application development.</p>
\ No newline at end of file
diff --git a/src/devices/tech/dalvik/instruction-formats.css b/src/devices/tech/dalvik/instruction-formats.css
new file mode 100644
index 0000000..a2dc42f
--- /dev/null
+++ b/src/devices/tech/dalvik/instruction-formats.css
@@ -0,0 +1,129 @@
+h1 {
+    font-family: serif;
+    color: #222266;
+}
+
+h2 {
+    font-family: serif;
+    border-top-style: solid;
+    border-top-width: 2px;
+    border-color: #ccccdd;
+    padding-top: 12px;
+    margin-top: 48px;
+    margin-bottom: 2px;
+    color: #222266;
+}
+
+h3 {
+    font-family: serif;
+    color: #222266;
+}
+
+@media print {
+    table {
+        font-size: 8pt;
+    }
+}
+
+@media screen {
+    table {
+        font-size: 10pt;
+    }
+}
+
+table th {
+    font-family: sans-serif;
+    background: #aaaaff;
+}
+
+table {
+    border-collapse: collapse;
+}
+
+table td {
+    font-family: sans-serif;
+    border-top-style: solid;
+    border-bottom-style: solid;
+    border-width: 1px;
+    border-color: #aaaaff;
+    padding-top: 4px;
+    padding-bottom: 4px;
+    padding-left: 2px;
+    padding-right: 2px;
+    background: #eeeeff;
+}
+
+
+/* the mnemonic guide */
+
+table.letters {
+    margin-top: 24px;
+    margin-bottom: 24px;
+    margin-left: 48px;
+    margin-right: 48px;
+}
+
+table.letters td:first-child {
+    font-family: monospace;
+    width: 10%;
+    text-align: center;
+}
+
+table.letters td:first-child + td {
+    width: 10%;
+    text-align: center;
+}
+
+table.letters td:first-child + td + td {
+    width: 80%;
+}
+
+
+/* the formats, per se */
+
+table.format {
+    background: #aaaaaa;
+    border-collapse: collapse;
+    margin-top: 24px;
+    margin-bottom: 24px;
+    margin-left: 48px;
+    margin-right: 48px;
+}
+
+table.format td {
+    font-family: monospace;
+}
+
+table.format td + td i {
+    font-family: sans-serif;
+}
+
+table.format td sub {
+    font-family: sans-serif;
+}
+
+table.format td sub {
+    font-family: sans-serif;
+    font-style: italic;
+    font-size: 70%
+}
+
+table.format th:first-child {
+    width: 28%;
+}
+
+table.format th:first-child + th {
+    width: 5%;
+}
+
+table.format th:first-child + th + th {
+    width: 45%;
+}
+
+table.format th:first-child + th + th + th {
+    width: 22%;
+}
+
+table.format p {
+    margin-bottom: 0pt;
+}
\ No newline at end of file
diff --git a/src/devices/tech/dalvik/instruction-formats.jd b/src/devices/tech/dalvik/instruction-formats.jd
new file mode 100644
index 0000000..37a7438
--- /dev/null
+++ b/src/devices/tech/dalvik/instruction-formats.jd
@@ -0,0 +1,464 @@
+page.title=Dalvik VM Instruction Formats
+@jd:body
+
+<!--
+    Copyright 2010 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.
+-->
+<p>Copyright &copy; 2007 The Android Open Source Project
+
+<h2>Introduction and Overview</h2>
+
+<p>This document lists the instruction formats used by Dalvik bytecode
+and is meant to be used in conjunction with the
+<a href="dalvik-bytecode.html">bytecode reference document</a>.</p>
+
+<h3>Bitwise descriptions</h3>
+
+<p>The first column in the format table lists the bitwise layout of
+the format. It consists of one or more space-separated "words" each of
+which describes a 16-bit code unit. Each character in a word
+represents four bits, read from high bits to low, with vertical bars
+("<code>|</code>") interspersed to aid in reading. Uppercase letters
+in sequence from "<code>A</code>" are used to indicate fields within
+the format (which then get defined further by the syntax column). The term
+"<code>op</code>" is used to indicate the position of an eight-bit
+opcode within the format. A slashed zero
+("<code>&Oslash;</code>") is used to indicate that all bits must be
+zero in the indicated position.</p>
+
+<p>For the most part, lettering proceeds from earlier code units to
+later code units, and low-order to high-order within a code unit.
+However, there are a few exceptions to this general rule, which are
+done in order to make the naming of similar-meaning parts be the same
+across different instruction formats. These cases are noted explicitly
+in the format descriptions.</p>
+
+<p>For example, the format "<code>B|A|<i>op</i> CCCC</code>" indicates
+that the format consists of two 16-bit code units. The first word
+consists of the opcode in the low eight bits and a pair of four-bit
+values in the high eight bits; and the second word consists of a single
+16-bit value.</p>
+
+<h3>Format IDs</h3>
+
+<p>The second column in the format table indicates the short identifier
+for the format, which is used in other documents and in code to identify
+the format.</p>
+
+<p>Most format IDs consist of three characters, two digits followed by a
+letter. The first digit indicates the number of 16-bit code units in the
+format. The second digit indicates the maximum number of registers that the
+format contains (maximum, since some formats can accomodate a variable
+number of registers), with the special designation "<code>r</code>" indicating
+that a range of registers is encoded. The final letter semi-mnemonically
+indicates the type of any extra data encoded by the format. For example,
+format "<code>21t</code>" is of length two, contains one register reference,
+and additionally contains a branch target.</p>
+
+<p>Suggested static linking formats have an additional
+"<code>s</code>" suffix, making them four characters total. Similarly,
+suggested "inline" linking formats have an additional "<code>i</code>"
+suffix. (In this context, inline linking is like static linking,
+except with more direct ties into a virtual machine's implementation.)
+Finally, a couple oddball suggested formats (e.g.,
+"<code>20bc</code>") include two pieces of data which are both
+represented in its format ID.</p>
+
+<p>The full list of typecode letters are as follows. Note that some
+forms have different sizes, depending on the format:</p>
+
+<table class="letters">
+<thead>
+<tr>
+  <th>Mnemonic</th>
+  <th>Bit Sizes</th>
+  <th>Meaning</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>b</td>
+  <td>8</td>
+  <td>immediate signed <b>b</b>yte</td>
+</tr>
+<tr>
+  <td>c</td>
+  <td>16, 32</td>
+  <td><b>c</b>onstant pool index</td>
+</tr>
+<tr>
+  <td>f</td>
+  <td>16</td>
+  <td>inter<b>f</b>ace constants (only used in statically linked formats)
+  </td>
+</tr>
+<tr>
+  <td>h</td>
+  <td>16</td>
+  <td>immediate signed <b>h</b>at (high-order bits of a 32- or 64-bit
+    value; low-order bits are all <code>0</code>)
+  </td>
+</tr>
+<tr>
+  <td>i</td>
+  <td>32</td>
+  <td>immediate signed <b>i</b>nt, or 32-bit float</td>
+</tr>
+<tr>
+  <td>l</td>
+  <td>64</td>
+  <td>immediate signed <b>l</b>ong, or 64-bit double</td>
+</tr>
+<tr>
+  <td>m</td>
+  <td>16</td>
+  <td><b>m</b>ethod constants (only used in statically linked formats)</td>
+</tr>
+<tr>
+  <td>n</td>
+  <td>4</td>
+  <td>immediate signed <b>n</b>ibble</td>
+</tr>
+<tr>
+  <td>s</td>
+  <td>16</td>
+  <td>immediate signed <b>s</b>hort</td>
+</tr>
+<tr>
+  <td>t</td>
+  <td>8, 16, 32</td>
+  <td>branch <b>t</b>arget</td>
+</tr>
+<tr>
+  <td>x</td>
+  <td>0</td>
+  <td>no additional data</td>
+</tr>
+</tbody>
+</table>
+
+<h3>Syntax</h3>
+
+<p>The third column of the format table indicates the human-oriented
+syntax for instructions which use the indicated format. Each instruction
+starts with the named opcode and is optionally followed by one or
+more arguments, themselves separated with commas.</p>
+
+<p>Wherever an argument refers to a field from the first column, the
+letter for that field is indicated in the syntax, repeated once for
+each four bits of the field. For example, an eight-bit field labeled
+"<code>BB</code>" in the first column would also be labeled
+"<code>BB</code>" in the syntax column.</p>
+
+<p>Arguments which name a register have the form "<code>v<i>X</i></code>".
+The prefix "<code>v</code>" was chosen instead of the more common
+"<code>r</code>" exactly to avoid conflicting with (non-virtual) architectures
+on which a Dalvik virtual machine might be implemented which themselves
+use the prefix "<code>r</code>" for their registers. (That is, this
+decision makes it possible to talk about both virtual and real registers
+together without the need for circumlocution.)</p>
+
+<p>Arguments which indicate a literal value have the form
+"<code>#+<i>X</i></code>". Some formats indicate literals that only
+have non-zero bits in their high-order bits; for these, the zeroes
+are represented explicitly in the syntax, even though they do not
+appear in the bitwise representation.</p>
+
+<p>Arguments which indicate a relative instruction address offset have the
+form "<code>+<i>X</i></code>".</p>
+
+<p>Arguments which indicate a literal constant pool index have the form
+"<code><i>kind</i>@<i>X</i></code>", where "<code><i>kind</i></code>"
+indicates which constant pool is being referred to. Each opcode that
+uses such a format explicitly allows only one kind of constant; see
+the opcode reference to figure out the correspondence. The four
+kinds of constant pool are "<code>string</code>" (string pool index),
+"<code>type</code>" (type pool index), "<code>field</code>" (field
+pool index), and "<code>meth</code>" (method pool index).</p>
+
+<p>Similar to the representation of constant pool indices, there are
+also suggested (optional) forms that indicate prelinked offsets or
+indices. There are two types of suggested prelinked value: vtable offsets
+(indicated as "<code>vtaboff</code>") and field offsets (indicated as
+"<code>fieldoff</code>").</p>
+
+<p>In the cases where a format value isn't explictly part of the syntax
+but instead picks a variant, each variant is listed with the prefix
+"<code>[<i>X</i>=<i>N</i>]</code>" (e.g., "<code>[A=2]</code>") to indicate
+the correspondence.</p>
+
+<h2>The Formats</h2>
+
+<table class="format">
+<thead>
+<tr>
+  <th>Format</th>
+  <th>ID</th>
+  <th>Syntax</th>
+  <th>Notable Opcodes Covered</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td><i>N/A</i></td>
+  <td>00x</td>
+  <td><i><code>N/A</code></i></td>
+  <td><i>pseudo-format used for unused opcodes; suggested for use as the
+    nominal format for a breakpoint opcode</i></td>
+</tr>
+<tr>
+  <td>&Oslash;&Oslash;|<i>op</i></td>
+  <td>10x</td>
+  <td><i><code>op</code></i></td>
+  <td>&nbsp;</td>
+</tr>
+<tr>
+  <td rowspan="2">B|A|<i>op</i></td>
+  <td>12x</td>
+  <td><i><code>op</code></i> vA, vB</td>
+  <td>&nbsp;</td>
+</tr>
+<tr>
+  <td>11n</td>
+  <td><i><code>op</code></i> vA, #+B</td>
+  <td>&nbsp;</td>
+</tr>
+<tr>
+  <td rowspan="2">AA|<i>op</i></td>
+  <td>11x</td>
+  <td><i><code>op</code></i> vAA</td>
+  <td>&nbsp;</td>
+</tr>
+<tr>
+  <td>10t</td>
+  <td><i><code>op</code></i> +AA</td>
+  <td>goto</td>
+</tr>
+<tr>
+  <td>&Oslash;&Oslash;|<i>op</i> AAAA</td></td>
+  <td>20t</td>
+  <td><i><code>op</code></i> +AAAA</td>
+  <td>goto/16</td>
+</tr>
+<tr>
+  <td>AA|<i>op</i> BBBB</td></td>
+  <td>20bc</td>
+  <td><i><code>op</code></i> AA, kind@BBBB</td>
+  <td><i>suggested format for statically determined verification errors;
+    A is the type of error and B is an index into a type-appropriate
+    table (e.g. method references for a no-such-method error)</i></td>
+</tr>
+<tr>
+  <td rowspan="5">AA|<i>op</i> BBBB</td>
+  <td>22x</td>
+  <td><i><code>op</code></i> vAA, vBBBB</td>
+  <td>&nbsp;</td>
+</tr>
+<tr>
+  <td>21t</td>
+  <td><i><code>op</code></i> vAA, +BBBB</td>
+  <td>&nbsp;</td>
+</tr>
+<tr>
+  <td>21s</td>
+  <td><i><code>op</code></i> vAA, #+BBBB</td>
+  <td>&nbsp;</td>
+</tr>
+<tr>
+  <td>21h</td>
+  <td><i><code>op</code></i> vAA, #+BBBB0000<br/>
+    <i><code>op</code></i> vAA, #+BBBB000000000000
+  </td>
+  <td>&nbsp;</td>
+</tr>
+<tr>
+  <td>21c</td>
+  <td><i><code>op</code></i> vAA, type@BBBB<br/>
+    <i><code>op</code></i> vAA, field@BBBB<br/>
+    <i><code>op</code></i> vAA, string@BBBB
+  </td>
+  <td>check-cast<br/>
+    const-class<br/>
+    const-string
+  </td>
+</tr>
+<tr>
+  <td rowspan="2">AA|<i>op</i> CC|BB</td>
+  <td>23x</td>
+  <td><i><code>op</code></i> vAA, vBB, vCC</td>
+  <td>&nbsp;</td>
+</tr>
+<tr>
+  <td>22b</td>
+  <td><i><code>op</code></i> vAA, vBB, #+CC</td>
+  <td>&nbsp;</td>
+</tr>
+<tr>
+  <td rowspan="4">B|A|<i>op</i> CCCC</td>
+  <td>22t</td>
+  <td><i><code>op</code></i> vA, vB, +CCCC</td>
+  <td>&nbsp;</td>
+</tr>
+<tr>
+  <td>22s</td>
+  <td><i><code>op</code></i> vA, vB, #+CCCC</td>
+  <td>&nbsp;</td>
+</tr>
+<tr>
+  <td>22c</td>
+  <td><i><code>op</code></i> vA, vB, type@CCCC<br/>
+    <i><code>op</code></i> vA, vB, field@CCCC
+  </td>
+  <td>instance-of</td>
+</tr>
+<tr>
+  <td>22cs</td>
+  <td><i><code>op</code></i> vA, vB, fieldoff@CCCC</td>
+  <td><i>suggested format for statically linked field access instructions of
+    format 22c</i>
+  </td>
+</tr>
+<tr>
+  <td>&Oslash;&Oslash;|<i>op</i> AAAA<sub>lo</sub> AAAA<sub>hi</sub></td></td>
+  <td>30t</td>
+  <td><i><code>op</code></i> +AAAAAAAA</td>
+  <td>goto/32</td>
+</tr>
+<tr>
+  <td>&Oslash;&Oslash;|<i>op</i> AAAA BBBB</td>
+  <td>32x</td>
+  <td><i><code>op</code></i> vAAAA, vBBBB</td>
+  <td>&nbsp;</td>
+</tr>
+<tr>
+  <td rowspan="3">AA|<i>op</i> BBBB<sub>lo</sub> BBBB<sub>hi</sub></td>
+  <td>31i</td>
+  <td><i><code>op</code></i> vAA, #+BBBBBBBB</td>
+  <td>&nbsp;</td>
+</tr>
+<tr>
+  <td>31t</td>
+  <td><i><code>op</code></i> vAA, +BBBBBBBB</td>
+  <td>&nbsp;</td>
+</tr>
+<tr>
+  <td>31c</td>
+  <td><i><code>op</code></i> vAA, string@BBBBBBBB</td>
+  <td>const-string/jumbo</td>
+</tr>
+<tr>
+  <td rowspan="3">A|G|<i>op</i> BBBB F|E|D|C</td>
+  <td>35c</td>
+  <td><i>[<code>A=5</code>] <code>op</code></i> {vC, vD, vE, vF, vG},
+    meth@BBBB<br/>
+    <i>[<code>A=5</code>] <code>op</code></i> {vC, vD, vE, vF, vG},
+    type@BBBB<br/>
+    <i>[<code>A=4</code>] <code>op</code></i> {vC, vD, vE, vF},
+    <i><code>kind</code></i>@BBBB<br/>
+    <i>[<code>A=3</code>] <code>op</code></i> {vC, vD, vE},
+    <i><code>kind</code></i>@BBBB<br/>
+    <i>[<code>A=2</code>] <code>op</code></i> {vC, vD},
+    <i><code>kind</code></i>@BBBB<br/>
+    <i>[<code>A=1</code>] <code>op</code></i> {vC},
+    <i><code>kind</code></i>@BBBB<br/>
+    <i>[<code>A=0</code>] <code>op</code></i> {},
+    <i><code>kind</code></i>@BBBB<br/>
+    <p><i>The unusual choice in lettering here reflects a desire to make
+    the count and the reference index have the same label as in format
+    3rc.</i></p>
+  </td>
+  <td>&nbsp;</td>
+</tr>
+<tr>
+  <td>35ms</td>
+  <td><i>[<code>A=5</code>] <code>op</code></i> {vC, vD, vE, vF, vG},
+    vtaboff@BBBB<br/>
+    <i>[<code>A=4</code>] <code>op</code></i> {vC, vD, vE, vF},
+    vtaboff@BBBB<br/>
+    <i>[<code>A=3</code>] <code>op</code></i> {vC, vD, vE},
+    vtaboff@BBBB<br/>
+    <i>[<code>A=2</code>] <code>op</code></i> {vC, vD},
+    vtaboff@BBBB<br/>
+    <i>[<code>A=1</code>] <code>op</code></i> {vC},
+    vtaboff@BBBB<br/>
+    <p><i>The unusual choice in lettering here reflects a desire to make
+    the count and the reference index have the same label as in format
+    3rms.</i></p>
+  </td>
+  <td><i>suggested format for statically linked <code>invoke-virtual</code>
+    and <code>invoke-super</code> instructions of format 35c</i>
+  </td>
+</tr>
+<tr>
+  <td>35mi</td>
+  <td><i>[<code>A=5</code>] <code>op</code></i> {vC, vD, vE, vF, vG},
+    inline@BBBB<br/>
+    <i>[<code>A=4</code>] <code>op</code></i> {vC, vD, vE, vF},
+    inline@BBBB<br/>
+    <i>[<code>A=3</code>] <code>op</code></i> {vC, vD, vE},
+    inline@BBBB<br/>
+    <i>[<code>A=2</code>] <code>op</code></i> {vC, vD},
+    inline@BBBB<br/>
+    <i>[<code>A=1</code>] <code>op</code></i> {vC},
+    inline@BBBB<br/>
+    <p><i>The unusual choice in lettering here reflects a desire to make
+    the count and the reference index have the same label as in format
+    3rmi.</i></p>
+  </td>
+  <td><i>suggested format for inline linked <code>invoke-static</code>
+    and <code>invoke-virtual</code> instructions of format 35c</i>
+  </td>
+</tr>
+<tr>
+  <td rowspan="3">AA|<i>op</i> BBBB CCCC</td>
+  <td>3rc</td>
+  <td><i><code>op</code></i> {vCCCC .. vNNNN}, meth@BBBB<br/>
+    <i><code>op</code></i> {vCCCC .. vNNNN}, type@BBBB<br/>
+    <p><i>where <code>NNNN = CCCC+AA-1</code>, that is <code>A</code>
+    determines the count <code>0..255</code>, and <code>C</code>
+    determines the first register</i></p>
+  </td>
+  <td>&nbsp;</td>
+</tr>
+<tr>
+  <td>3rms</td>
+  <td><i><code>op</code></i> {vCCCC .. vNNNN}, vtaboff@BBBB<br/>
+    <p><i>where <code>NNNN = CCCC+AA-1</code>, that is <code>A</code>
+    determines the count <code>0..255</code>, and <code>C</code>
+    determines the first register</i></p>
+  </td>
+  <td><i>suggested format for statically linked <code>invoke-virtual</code>
+    and <code>invoke-super</code> instructions of format <code>3rc</code></i>
+  </td>
+</tr>
+<tr>
+  <td>3rmi</td>
+  <td><i><code>op</code></i> {vCCCC .. vNNNN}, inline@BBBB<br/>
+    <p><i>where <code>NNNN = CCCC+AA-1</code>, that is <code>A</code>
+    determines the count <code>0..255</code>, and <code>C</code>
+    determines the first register</i></p>
+  </td>
+  <td><i>suggested format for inline linked <code>invoke-static</code>
+    and <code>invoke-virtual</code> instructions of format 3rc</i>
+  </td>
+</tr>
+<tr>
+  <td>AA|<i>op</i> BBBB<sub>lo</sub> BBBB BBBB BBBB<sub>hi</sub></td>
+  <td>51l</td>
+  <td><i><code>op</code></i> vAA, #+BBBBBBBBBBBBBBBB</td>
+  <td>const-wide</td>
+</tr>
+</tbody>
+</table>
\ No newline at end of file
diff --git a/src/devices/tech/datausage/excluding-network-types.jd b/src/devices/tech/datausage/excluding-network-types.jd
new file mode 100644
index 0000000..528b402
--- /dev/null
+++ b/src/devices/tech/datausage/excluding-network-types.jd
@@ -0,0 +1,30 @@
+page.title=Excluding Network Types from Usage Data
+@jd:body
+
+<!--
+    Copyright 2010 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.
+-->
+<p>A mobile operator may wish to exclude specific network types from the
+total data usage calculated by a device.  For example, network traffic
+over an MMS APN may be “zero-rated” by a mobile operator.  To support
+this, the set of network types used to calculate total data usage can
+be configured through the <code>config_data_usage_network_types</code> resource
+at build time.</p>
+<p>Some mobile radio implementations may have unique Linux network
+interfaces for each active APN, while other radios may force multiple
+APNs to coexist on a single interface.  Android can collect network
+statistics from both designs, but <code>config_data_usage_network_types</code> is
+not be effective at excluding APNs forced to coexist on a single
+interface.</p>
\ No newline at end of file
diff --git a/src/devices/tech/datausage/iface-overview.jd b/src/devices/tech/datausage/iface-overview.jd
new file mode 100644
index 0000000..7608aa8
--- /dev/null
+++ b/src/devices/tech/datausage/iface-overview.jd
@@ -0,0 +1,47 @@
+page.title=Network Interface Statistics Overview
+@jd:body
+
+<!--
+    Copyright 2010 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.
+-->
+<p>In Android 4.0, statistics reported by Linux network interfaces are
+recorded over time, and are used to enforce network quota limits,
+render user-visible charts, and more.</p>
+<p>Each network device driver (Wi-Fi included) must follow the standard
+kernel device lifecycle, and return correct statistics through
+<code>dev_get_stats()</code>. In particular, statistics returned must remain
+strictly monotonic while the interface is active. Drivers may reset
+statistics only after successfully completing an <code>unregister_netdev()</code>
+or the equivalent that generates a <code>NETDEV_UNREGISTER</code> event for
+callbacks registered with <code>register_netdevice_notifier()</code> /
+<code>register_inetaddr_notifier()</code> / <code>register_inet6addr_notifier()</code>.</p>
+<p>Mobile operators typically measure data usage at the Internet layer
+(IP). To match this approach in Android 4.0, we rely on the fact that
+for the kernel devices we care about the <code>rx_bytes</code> and <code>tx_bytes</code>
+values returned by <code>dev_get_stats()</code> return exactly the Internet layer
+(<code>IP</code>) bytes transferred.  But we understand that for other devices it
+might not be the case. For now, the feature relies on this
+peculiarity. New drivers should have that property also, and the
+<code>dev_get_stats()</code> values must not include any encapsulation overhead
+of lower network layers (such as Ethernet headers), and should
+preferably not include other traffic (such as ARP) unless it is
+negligible.</p>
+<p>The Android framework only collects statistics from network interfaces
+associated with a <code>NetworkStateTracker</code> in <code>ConnectivityService</code>. This
+enables the framework to concretely identify each network interface,
+including its type (such as <code>TYPE_MOBILE</code> or <code>TYPE_WIFI</code>) and
+subscriber identity (such as IMSI).  All network interfaces used to
+route data should be represented by a <code>NetworkStateTracker</code> so that
+statistics can be accounted correctly.</p>
diff --git a/src/devices/tech/datausage/index.jd b/src/devices/tech/datausage/index.jd
new file mode 100644
index 0000000..adce77c
--- /dev/null
+++ b/src/devices/tech/datausage/index.jd
@@ -0,0 +1,33 @@
+page.title=Data Usage Technical Information
+@jd:body
+
+<!--
+    Copyright 2010 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.
+-->
+<p>Android 4.0 (Ice Cream Sandwich) introduces new features that help
+users understand and control how their device uses network data.  It
+monitors overall data usage, and supports warning or limit thresholds
+which will trigger notifications or disable mobile data when usage
+exceeds a specific quota.</p>
+<p>Data usage is also tracked on a per-application basis, enabling users
+to visually explore historical usage in the Settings app. Users can
+also restrict how specific applications are allowed to use data when
+running in the background.</p>
+<p>The documentation in this section is intended for systems integrators
+and mobile operators, to help explain technical details they should be
+aware of when porting Android to specific devices.  These details are
+summarized below, and the
+<a href="mailto:android-porting+subscribe@googlegroups.com">android-porting</a>
+mailing list is a good place for further discussion.</p>
diff --git a/src/devices/tech/datausage/kernel-changes.jd b/src/devices/tech/datausage/kernel-changes.jd
new file mode 100644
index 0000000..98624ed
--- /dev/null
+++ b/src/devices/tech/datausage/kernel-changes.jd
@@ -0,0 +1,32 @@
+page.title=Kernel Changes
+@jd:body
+
+<!--
+    Copyright 2010 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.
+-->
+<p>This is a summary of the main changes in the kernel that diverge from mainline.</p>
+<ul>
+<li>added net/netfilter/xt_qtaguid*</li>
+<li>imported then modified net/netfilter/xt_quota2.c from xtables-addons project</li>
+<li>fixes in net/netfilter/ip6_tables.c</li>
+<li>modified ip*t_REJECT.c</li>
+<li>modified net/netfilter/xt_socket.c</li>
+</ul>
+<p>A few comments on the kernel configuration:</p>
+<ul>
+<li>xt_qtaguid masquerades as xt_owner and relies on xt_socket and itself relies on the connection tracker.</li>
+<li>The connection tracker can't handle large SIP packets, it must be disabled.</li>
+<li>The modified xt_quota2 uses the NFLOG support to notify userspace.</li>
+</ul>
diff --git a/src/devices/tech/datausage/kernel-overview.jd b/src/devices/tech/datausage/kernel-overview.jd
new file mode 100644
index 0000000..7d4248b
--- /dev/null
+++ b/src/devices/tech/datausage/kernel-overview.jd
@@ -0,0 +1,51 @@
+page.title=Overview
+@jd:body
+
+<!--
+    Copyright 2010 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.
+-->
+<p>The per-application/delegated data usage monitoring and tracking
+functionality relies on the xt_qtaguid module in the android-3.0 Linux
+kernel (<code>kernel/net/netfilter/xt_qtaguid</code>). The socket tagging
+functionality in the framework (<code>system/core/libcutils/qtaguid.c</code>)
+relies mainly on the existence of <code>/proc/net/xt_qtaguid/ctrl</code>
+interface exported by the <code>xt_qtaguid</code> kernel module.</p>
+<p>The <code>quota2</code> netfilter module (originally part of <code>xtables-addons</code>)
+allows the functionality to set named quota limits and was extended to
+support notifying userspace when certain limits are reached. Once the
+quota limit is reached, the <code>quota2</code> module discards all subsequent
+network traffic. The framework can also specify additional rules to
+restrict background data traffic for an application (refer to
+<code>com.android.server.NetworkManagementSocketTagger.setKernelCounterSet</code>
+and
+<code>android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND</code>).</p>
+<h1 id="how-does-it-work">How does it work?</h1>
+<p>The <code>qtaguid</code> netfilter module tracks the network traffic on a
+per-socket basis for every application using the unique UID of the
+owning application.  There are two tag components associated with any
+socket in the system. The first is the UID which uniquely identifies
+the application which is responsible for the data transfer (Linux
+allows the ability to ascribe the ownership of each network socket to
+the UID of the calling application). The second tag component is used
+to support additional characterization of the traffic into application
+developer specified categories. Using these application level tags, an
+application can profile the traffic into several sub-categories.</p>
+<p>In the case of applications that provide network data transfer as a
+service, such as the download manager, media streaming service, etc,
+it is possible to attribute the ownership of the network data transfer
+to the UID of the requesting application using the
+<code>TrafficStats.setThreadStatsUid()</code> function call. The caller must hold
+the “<code>android.permission.MODIFY_NETWORK_ACCOUNTING</code>” permission to
+re-assign the ownership of the network traffic.</p>
diff --git a/src/devices/tech/datausage/tags-explained.jd b/src/devices/tech/datausage/tags-explained.jd
new file mode 100644
index 0000000..bacd395
--- /dev/null
+++ b/src/devices/tech/datausage/tags-explained.jd
@@ -0,0 +1,45 @@
+page.title=Data Usage Tags Explained
+@jd:body
+
+<!--
+    Copyright 2010 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.
+-->
+<p>Tags represent one of the metrics the data usage counters will be
+tracked against. By default, and implicitly, a tag is just based on
+the UID. The UID is used as the base for policing, and cannot be
+ignored. So a tag will always at least represent a UID (uid_tag). A
+tag can be explicitly augmented with an "accounting tag" which is
+associated with a UID. User space can use
+<code>TrafficStats.setThreadStatsTag()</code> to set the acct_tag portion of the
+tag which is then used  with sockets: all data belonging to that
+socket will be counted against the tag. The policing is then based on
+the tag's uid_tag portion, and stats are collected for the acct_tag
+portion separately.</p>
+<p>Without explicit tagging, the qtaguid module will assume the
+<code>default_tag:  {acct_tag=0, uid_tag=10003}</code></p>
+<pre><code>    a:  {acct_tag=1, uid_tag=10003}
+    b:  {acct_tag=2, uid_tag=10003}
+    c:  {acct_tag=3, uid_tag=10003}
+</code></pre>
+<p><code>a, b, c…</code> represent explicit tags associated with specific sockets.</p>
+<p><code>default_tag (acct_tag=0)</code> is the default accounting tag that contains
+the total traffic for that uid, including all untagged
+traffic, and is typically used to enforce policing/quota rules.</p>
+<p>These tags can be used to profile the network traffic of an
+application into separate logical categories (at a network socket
+level). Such tags can be removed, reapplied, or modified during
+runtime.</p>
+<p>The qtaguid module has been implemented on <a href="https://android-review.googlesource.com/#/q/project:kernel/common+branch:android-3.0,n,z">kernel/common branch of
+android-3.0</a></p>
\ No newline at end of file
diff --git a/src/devices/tech/datausage/tethering-data.jd b/src/devices/tech/datausage/tethering-data.jd
new file mode 100644
index 0000000..62d1733
--- /dev/null
+++ b/src/devices/tech/datausage/tethering-data.jd
@@ -0,0 +1,22 @@
+page.title=Tethering data
+@jd:body
+
+<!--
+    Copyright 2010 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.
+-->
+<p>Tethering involves forwarding of traffic from one network interface to
+another using <code>iptables</code> forwarding rules.  The framework periodically
+records tethering statistics between any interface pairs returned by
+<code>ConnectivityService.getTetheredIfacePairs()</code>.</p>
diff --git a/src/devices/tech/datausage/usage-cycle-resets-dates.jd b/src/devices/tech/datausage/usage-cycle-resets-dates.jd
new file mode 100644
index 0000000..f9bddbd
--- /dev/null
+++ b/src/devices/tech/datausage/usage-cycle-resets-dates.jd
@@ -0,0 +1,24 @@
+page.title=Usage Cycle Reset Dates
+@jd:body
+
+<!--
+    Copyright 2010 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.
+-->
+<p>Users can specify a day of month upon which their data usage
+resets. Internally, cycle boundaries are defined to end at midnight
+<code>(00:00) UTC</code> on the requested day. When a month is shorter than the
+requested day, the cycle resets on the first day of the subsequent
+month. For example, a cycle reset day of the 30th would cause a reset
+on January 30 at <code>00:00 UTC</code> and March 1 at <code>00:00 UTC</code>.</p>
\ No newline at end of file
diff --git a/src/devices/tech/encryption/android_crypto_implementation.jd b/src/devices/tech/encryption/android_crypto_implementation.jd
new file mode 100644
index 0000000..c81c4f5
--- /dev/null
+++ b/src/devices/tech/encryption/android_crypto_implementation.jd
@@ -0,0 +1,350 @@
+page.title=Notes on the implementation of encryption in Android 3.0
+@jd:body
+
+<!--
+    Copyright 2010 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.
+-->
+<h2 id="quick-summary-for-3rd-parties">Quick summary for 3rd parties.</h2>
+<p>If you want to enable encryption on your device based on Android 3.0
+aka Honeycomb, there are only a few requirements:</p>
+<ol>
+<li>
+<p>The /data filesystem must be on a device that presents a block device
+    interface.  eMMC is used in the first devices.  This is because the
+    encryption is done by the dm-crypt layer in the kernel, which works
+    at the block device layer.</p>
+</li>
+<li>
+<p>The function get_fs_size() in system/vold/cryptfs.c assumes the filesystem
+    used for /data is ext4.  It's just error checking code to make sure the
+    filesystem doesn't extend into the last 16 Kbytes of the partition where
+    the crypto footer is kept.  It was useful for development when sizes were
+    changing, but should not be required for release.  If you are not using
+    ext4, you can either delete it and the call to it, or fix it to understand
+    the filesystem you are using.</p>
+</li>
+<li>
+<p>Most of the code to handle the setup and teardown of the temporary framework
+    is in files that are not usually required to be changed on a per device
+    basis.  However, the init.<device>.rc file will require some changes.  All
+    services must be put in one of three classes: core, main or late_state.
+    Services in the core class are not shutdown and restarted when the
+    temporary framework gets the disk password.  Services in the main class
+    are restarted when the framework is restarted.  Services in late_start are
+    not started until after the temporary framework is restarted.  Put services
+    here that are not required to be running while the temporary framework
+    gets the disk password.</p>
+<p>Also any directories that need to be created on /data that are device
+specific need to be in the Action for post-fs-data, and that Action must end
+with the command "setprop vold.post_fs_data_done 1".  If your
+init.<device>.rc file does not have a post-fs-data Action, then the
+post-fs-data Action in the main init.rc file must end with the command
+"setprop vold.post_fs_data_done 1".</p>
+</li>
+</ol>
+<h2 id="how-android-encryption-works">How Android encryption works</h2>
+<p>Disk encryption on Android is based on dm-crypt, which is a kernel feature that
+works at the block device layer.  Therefore, it is not usable with YAFFS, which
+talks directly to a raw nand flash chip, but does work with emmc and similar
+flash devices which present themselves to the kernel as a block device.  The
+current preferred filesystem to use on these devices is ext4, though that is
+independent of whether encryption is used or not.</p>
+<p>While the actual encryption work is a standard linux kernel feature, enabling it
+on an Android device proved somewhat tricky.  The Android system tries to avoid
+incorporating GPL components, so using the cryptsetup command or libdevmapper
+were not available options.  So making the appropriate ioctl(2) calls into the
+kernel was the best choice.  The Android volume daemon (vold) already did this
+to support moving apps to the SD card, so I chose to leverage that work
+for whole disk encryption.  The actual encryption used for the filesystem for
+first release is 128 AES with CBC and ESSIV:SHA256.  The master key is
+encrypted with 128 bit AES via calls to the openssl library.</p>
+<p>Once it was decided to put the smarts in vold, it became obvious that invoking
+the encryption features would be done like invoking other vold commands, by
+adding a new module to vold (called cryptfs) and teaching it various commands.
+The commands are checkpw, restart, enablecrypto, changepw and cryptocomplete.
+They will be described in more detail below.</p>
+<p>The other big issue was how to get the password from the user on boot.  The
+initial plan was to implement a minimal UI that could be invoked from init
+in the initial ramdisk, and then init would decrypt and mount /data.  However,
+the UI engineer said that was a lot of work, and suggested instead that init
+communicate upon startup to tell the framework to pop up the password entry
+screen, get the password, and then shutdown and have the real framework started.
+It was decided to go this route, and this then led to a host of other decisions
+described below.  In particular, init set a property to tell the framework to go
+into the special password entry mode, and that set the stage for much
+communication between vold, init and the framework using properties.  The
+details are described below.</p>
+<p>Finally, there were problems around killing and restarting various services
+so that /data could be unmounted and remounted.  Bringing up the temporary
+framework to get the user password requires that a tmpfs /data filesystem be
+mounted, otherwise the framework will not run.  But to unmount the tmpfs /data
+filesystem so the real decrypted /data filesystem could be mounted meant that
+every process that had open files on the tmpfs /data filesystem had to be killed
+and restarted on the real /data filesystem.  This magic was accomplished by
+requiring all services to be in 1 of 3 groups: core, main and late_start.
+Core services are never shut down after starting.  main services are shutdown
+and then restarted after the disk password is entered.  late_start services
+are not started until after /data has been decrypted and mounted.  The magic
+to trigger these actions is by setting the property vold.decrypt to various
+magic strings, which is described below.  Also, a new init command "class_reset"
+was invented to stop a service, but allow it to be restarted with a
+"class_start" command.  If the command "class_stop" was used instead of the
+new command "class_reset" the flag SVC_DISABLED was added to the state of
+any service stopped, which means it would not be started when the command
+class_start was used on its class.</p>
+<h2 id="booting-an-encrypted-system">Booting an encrypted system.</h2>
+<ol>
+<li>
+<p>When init fails to mount /data, it assumes the filesystem  is encrypted,
+    and sets several properties:
+      ro.crypto.state = "encrypted"
+      vold.decrypt = 1
+    It then mounts a /data on a tmpfs ramdisk, using parameters it picks
+    up from ro.crypto.tmpfs_options, which is set in init.rc.</p>
+<p>If init was able to mount /data, it sets ro.crypto.state to "unencrypted".</p>
+<p>In either case, init then sets 5 properties to save the initial mount
+options given for /data in these properties:
+    ro.crypto.fs_type
+    ro.crypto.fs_real_blkdev
+    ro.crypto.fs_mnt_point
+    ro.crypto.fs_options
+    ro.crypto.fs_flags (saved as an ascii 8 digit hex number preceded by 0x)</p>
+</li>
+<li>
+<p>The framework starts up, and sees that vold.decrypt is set to "1".  This
+    tells the framework that it is booting on a tmpfs /data disk, and it needs
+    to get the user password.  First, however, it needs to make sure that the
+    disk was properly encrypted.  It sends the command "cryptfs cryptocomplete"
+    to vold, and vold returns 0 if encryption was completed successfully, or -1
+    on internal error, or -2 if encryption was not completed successfully. 
+    Vold determines this by looking in the crypto footer for the
+    CRYPTO_ENCRYPTION_IN_PROGRESS flag.  If it's set, the encryption process
+    was interrupted, and there is no usable data on the device.  If vold returns
+    an error, the UI should pop up a message saying the user needs to reboot and
+    factory reset the device, and give the user a button to press to do so.</p>
+</li>
+<li>
+<p>Assuming the "cryptfs cryptocomplete" command returned success, the
+    framework should pop up a UI asking for the disk password.  The UI then
+    sends the command "cryptfs checkpw <passwd>" to vold.  If the password
+    is correct (which is determined by successfully mounting the decrypted
+    at a temporary location, then unmounting it), vold saves the name of the
+    decrypted block device in the property ro.crypto.fs_crypto_blkdev, and
+    returns status 0 to the UI.  If the password is incorrect, it returns -1
+    to the UI.</p>
+</li>
+<li>
+<p>The UI puts up a crypto boot graphic, and then calls vold with the command
+    "cryptfs restart".  vold sets the property vold.decrypt to
+    "trigger_reset_main", which causes init.rc to do "class_reset main".  This
+    stops all services in the main class, which allows the tmpfs /data to be
+    unmounted.  vold then mounts the decrypted real /data partition, and then
+    preps the new partition (which may never have been prepped if it was
+    encrypted with the wipe option, which is not supported on first release).
+    It sets the property vold.post_fs_data_done to "0", and then sets
+    vold.decrypt to "trigger_post_fs_dat".  This causes init.rc to run the
+    post-fs-data commands in init.rc and init.<device>.rc.  They will create
+    any necessary directories, links, et al, and then set vold.post_fs_data_done
+    to "1".  Vold waits until it sees the "1" in that property.  Finally, vold
+    sets the property vold.decrypt to "trigger_restart_framework" which causes
+    init.rc to start services in class main again, and also start services
+    in class late_start for the first time since boot.</p>
+<p>Now the framework boots all its services using the decrypted /data
+filesystem, and the system is ready for use.</p>
+</li>
+</ol>
+<h2 id="enabling-encryption-on-the-device">Enabling encryption on the device.</h2>
+<p>For first release, we only support encrypt in place, which requires the
+framework to be shutdown, /data unmounted, and then every sector of the
+device encrypted, after which the device reboots to go through the process
+described above.  Here are the details:</p>
+<ol>
+<li>
+<p>From the UI, the user selects to encrypt the device.  The UI ensures that
+    there is a full charge on the battery, and the AC adapter is plugged in.
+    It does this to make sure there is enough power to finish the encryption
+    process, because if the device runs out of power and shuts down before it
+    has finished encrypting, file data is left in a partially encrypted state,
+    and the device must be factory reset (and all data lost).</p>
+<p>Once the user presses the final button to encrypt the device, the UI calls
+vold with the command "cryptfs enablecrypto inplace <passwd>" where passwd
+is the user's lock screen password.</p>
+</li>
+<li>
+<p>vold does some error checking, and returns -1 if it can't encrypt, and
+    prints a reason in the log.  If it thinks it can, it sets the property
+    vold.decrypt to "trigger_shutdown_framework".  This causes init.rc to
+    stop services in the classes late_start and main.  vold then unmounts
+    /mnt/sdcard and then /data.</p>
+</li>
+<li>
+<p>If doing an inplace encryption, vold then mounts a tmpfs /data (using the
+    tmpfs options from ro.crypto.tmpfs_options) and sets the property
+    vold.encrypt_progress to "0".  It then preps the tmpfs /data filesystem as
+    mentioned in step 3 for booting an encrypted system, and then sets the
+    property vold.decrypt to "trigger_restart_min_framework".  This causes
+    init.rc to start the main class of services.  When the framework sees that
+    vold.encrypt_progress is set to "0", it will bring up the progress bar UI,
+    which queries that property every 5 seconds and updates a progress bar.</p>
+</li>
+<li>
+<p>vold then sets up the crypto mapping, which creates a virtual crypto block
+    device that maps onto the real block device, but encrypts each sector as it
+    is written, and decrypts each sector as it is read.  vold then creates and
+    writes out the crypto footer.</p>
+<p>The crypto footer contains details on the type of encryption, and an
+encrypted copy of the master key to decrypt the filesystem.  The master key
+is a 128 bit number created by reading from /dev/urandom.  It is encrypted
+with a hash of the user password created with the PBKDF2 function from the
+SSL library.  The footer also contains a random salt (also read from
+/dev/urandom) used to add entropy to the hash from PBKDF2, and prevent
+rainbow table attacks on the password.  Also, the flag
+CRYPT_ENCRYPTION_IN_PROGRESS is set in the crypto footer to detect failure
+to complete the encryption process.  See the file cryptfs.h for details
+on the crypto footer layout.  The crypto footer is kept in the last 16
+Kbytes of the partition, and the /data filesystem cannot extend into that
+part of the partition.</p>
+</li>
+<li>
+<p>If told was to enable encryption with wipe, vold invokes the command
+    "make_ext4fs" on the crypto block device, taking care to not include
+    the last 16 Kbytes of the partition in the filesystem.</p>
+<p>If the command was to enable inplace, vold starts a loop to read each sector
+of the real block device, and then write it to the crypto block device.
+This takes about an hour on a 30 Gbyte partition on the Motorola Xoom.
+This will vary on other hardware.  The loop updates the property
+vold.encrypt_progress every time it encrypts another 1 percent of the
+partition.  The UI checks this property every 5 seconds and updates
+the progress bar when it changes.</p>
+</li>
+<li>
+<p>When either encryption method has finished successfully, vold clears the
+    flag ENCRYPTION_IN_PROGRESS in the footer, and reboots the system.
+    If the reboot fails for some reason, vold sets the property
+    vold.encrypt_progress to "error_reboot_failed" and the UI should
+    display a message asking the user to press a button to reboot.
+    This is not expected to ever occur.</p>
+</li>
+<li>
+<p>If vold detects an error during the encryption process, and if no data has
+    been destroyed yet and the framework is up, vold sets the property
+    vold.encrypt_progress to "error_not_encrypted" and the UI should give the
+    user the option to reboot, telling them that the encryption process
+    never started.  If the error occurs after the framework has been torn
+    down, but before the progress bar UI is up, vold will just reboot the
+    system.  If the reboot fails, it sets vold.encrypt_progress to
+    "error_shutting_down" and returns -1, but there will not be anyone
+    to catch the error.  This is not expected to happen.</p>
+<p>If vold detects an error during the encryption process, it sets
+vold.encrypt_progress to "error_partially_encrypted" and returns -1.
+The UI should then display a message saying the encryption failed, and
+provide a button for the user to factory reset the device.</p>
+</li>
+</ol>
+<h2 id="changing-the-password">Changing the password</h2>
+<p>To change the password for the disk encryption, the UI sends the command
+"cryptfs changepw <newpw>" to vold, and vold re-encrypts the disk master
+key with the new password.</p>
+<h2 id="summary-of-related-properties">Summary of related properties</h2>
+<p>Here is a table summarizing the various properties, their possible values,
+and what they mean:</p>
+<pre><code>vold.decrypt  1                               Set by init to tell the UI to ask
+                                              for the disk pw
+
+vold.decrypt  trigger_reset_main              Set by vold to shutdown the UI
+                                              asking for the disk password
+
+vold.decrypt  trigger_post_fs_data            Set by vold to prep /data with
+                                              necessary dirs, et al.
+
+vold.decrypt  trigger_restart_framework       Set by vold to start the real
+                                              framework and all services
+
+vold.decrypt  trigger_shutdown_framework      Set by vold to shutdown the full
+                                              framework to start encryption
+
+vold.decrypt  trigger_restart_min_framework   Set by vold to start the progress
+                                              bar UI for encryption.
+
+vold.enrypt_progress                          When the framework starts up, if
+                                              this property is set, enter the
+                                              progress bar UI mode.
+
+vold.encrypt_progress  0 to 100               The progress bar UI should display
+                                              the percentage value set.
+
+vold.encrypt_progress  error_partially_encrypted  The progress bar UI should
+                                                  display a message that the
+                                                  encryption failed, and give
+                                                  the user an option to factory
+                                                  reset the device.
+
+vold.encrypt_progress  error_reboot_failed    The progress bar UI should display
+                                              a message saying encryption
+                                              completed, and give the user a
+                                              button to reboot the device.
+                                              This error is not expected to
+                                              happen.
+
+vold.encrypt_progress  error_not_encrypted    The progress bar UI should display
+                                              a message saying an error occured,
+                                              and no data was encrypted or lost,
+                                              and give the user a button to
+                                              reboot the system.
+
+vold.encrypt_progress  error_shutting_down    The progress bar UI is not
+                                              running, so it's unclear who
+                                              will respond to this error,
+                                              and it should never happen
+                                              anyway.
+
+vold.post_fs_data_done  0                     Set by vold just before setting
+                                              vold.decrypt to
+                                              trigger_post_fs_data.
+
+vold.post_fs_data_done  1                     Set by init.rc or init.&lt;device&gt;.rc
+                                              just after finishing the task
+                                              post-fs-data.
+
+ro.crypto.fs_crypto_blkdev                    Set by the vold command checkpw
+                                              for later use by the vold command
+                                              restart.
+
+ro.crypto.state unencrypted                   Set by init to say this system is
+                                              running with an unencrypted /data
+
+ro.crypto.state encrypted                     Set by init to say this system is
+                                              running with an encrypted /data
+
+ro.crypto.fs_type                             These 5 properties are set by init
+ro.crypto.fs_real_blkdev                      when it tries to mount /data with
+ro.crypto.fs_mnt_point                        parameters passed in from init.rc.
+ro.crypto.fs_options                          vold uses these to setup the
+ro.crypto.fs_flags                            crypto mapping.
+
+ro.crypto.tmpfs_options                       Set by init.rc with the options
+                                              init should use when mounting
+                                              the tmpfs /data filesystem.
+</code></pre>
+<h2 id="summary-of-new-init-actions">Summary of new init actions</h2>
+<p>A list of the new Actions that are added to init.rc and/or init.<device>.rc:</p>
+<pre><code>on post-fs-data
+on nonencrypted
+on property:vold.decrypt=trigger_reset_main
+on property:vold.decrypt=trigger_post_fs_data
+on property:vold.decrypt=trigger_restart_min_framework
+on property:vold.decrypt=trigger_restart_framework
+on property:vold.decrypt=trigger_shutdown_framework
+</code></pre>
diff --git a/src/devices/tech/encryption/index.jd b/src/devices/tech/encryption/index.jd
new file mode 100644
index 0000000..42fce0d
--- /dev/null
+++ b/src/devices/tech/encryption/index.jd
@@ -0,0 +1,21 @@
+page.title=Encryption Technical Information
+@jd:body
+
+<!--
+    Copyright 2010 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.
+-->
+<p>Encryption on Android uses the dm-crypt layer in the Linux kernel.  Read the
+detailed description of how it is tied into the Android system and what must
+be done on a new device to get this feature working.</p>
\ No newline at end of file
diff --git a/src/devices/tech/index.jd b/src/devices/tech/index.jd
new file mode 100644
index 0000000..c528210
--- /dev/null
+++ b/src/devices/tech/index.jd
@@ -0,0 +1,82 @@
+page.title=Android Technical Information
+@jd:body
+
+<!--
+    Copyright 2010 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.
+-->
+<div id="qv-wrapper">
+  <div id="qv">
+    <h2>In this document</h2>
+    <ol id="auto-toc">
+    </ol>
+  </div>
+</div>
+
+
+<p>Welcome to the Android technical documentation section of the site. Here you
+can find technical information useful to people and organizations who are
+looking to modify, contribute to, or port the Android software. This is "under
+the hood" information intended for engineers.</p>
+
+<h2 id="dalvik-technical-information">Dalvik Technical Information</h2>
+<p>The Dalvik Virtual Machine is the heart of Android. It's a fast, just-in-time
+compiled, optimized bytecode virtual machine. Android applications are
+compiled to Dalvik bytecode and run on the Dalvik VM. This section includes
+detailed information such as the Dalvik bytecode format specification,
+design information on the VM itself, and so on.</p>
+
+<p><a href="{@docRoot}devices/tech/dalvik/index.html">&raquo; Dalvik Information</a></p>
+<h2 id="debugging">Debugging</h2>
+<p>Android is a large and complex system. This section includes tips and tricks
+about debugging at the platform level.</p>
+<p><a href="devices/tech/debugging/index.html">&raquo; Debugging Information</a></p>
+<h2 id="encryption-technical-information">Encryption Technical Information</h2>
+<p>The Android Open-Source Project includes the ability to encrypt the user's data.
+This document is written for 3rd parties developing Android devices who want to
+include support for encryption on their device.  It covers the few things that
+must be done so encryption will work.</p>
+
+<p><a href="{@docRoot}devices/tech/encryption/index.html">&raquo; Encryption Information</a></p>
+<h2 id="security-technical-information">Security Technical Information</h2>
+<p>Android provides a robust multi-layered security architecture that provides the
+flexibility required for an open platform, while providing protection for all
+users of the platform. This document focuses on the security features of the
+core Android platform.</p>
+
+<p><a href="{@docRoot}devices/tech/security/index.html">&raquo; Android Security Overview</a></p>
+<h2 id="input-technical-information">Input Technical Information</h2>
+<p>Android's input subsystem is responsible for supporting touch screens,
+keyboard, joysticks, mice and other devices.</p>
+
+<p><a href="{@docRoot}devices/tech/input/index.html">&raquo; Input Information</a></p>
+<h2 id="data-usage-technical-information">Data Usage Technical Information</h2>
+<p>Android's data usage features allow users to understand and control how their
+device uses network data. This document is designed for systems integrators
+and mobile operators, to help explain technical details they should be aware
+of when porting Android to specific devices.</p>
+
+<p><a href="{@docRoot}devices/tech/datausage/index.html">&raquo; Data Usage Information</a></p>
+<h2 id="accessory-protocol-information">Accessory Protocol Information</h2>
+<p>Android devices can connect to hardware accessories, such as audio docks,
+keyboards and custom hardware, through USB or Bluetooth. This document
+describes the Android Open Accessory protocol for accessory hardware builders.</p>
+
+<p><a href="{@docRoot}devices/tech/accessories/index.html">&raquo; Accessory Protocol Information</a></p>
+<h2 id="external-storage-technical-information">External Storage Technical Information</h2>
+<p>Android supports devices with external storage, typically provided by physical
+media or an emulation layer.  This document is designed to help systems
+integrators configure Android devices.</p>
+
+<p><a href="{@docRoot}devices/tech/storage/index.html">&raquo; External Storage Technical Information</a></p>
diff --git a/src/devices/tech/input/dumpsys.jd b/src/devices/tech/input/dumpsys.jd
new file mode 100644
index 0000000..a37584f
--- /dev/null
+++ b/src/devices/tech/input/dumpsys.jd
@@ -0,0 +1,344 @@
+page.title=Dumpsys
+@jd:body
+
+<!--
+    Copyright 2010 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.
+-->
+<p>The <code>dumpsys</code> tool runs on the device and dumps interesting information
+about the status of system services.</p>
+<h2 id="usage">Usage</h2>
+<p>The input system is part of the window manager.  To dump its state,
+run the following command.</p>
+<pre><code>$ adb shell su -- dumpsys window
+
+WINDOW MANAGER INPUT (dumpsys window input)
+Event Hub State:
+  BuiltInKeyboardId: -1
+  Devices:
+...
+</code></pre>
+<p>The set of information that is reported varies depending on the version of Android.</p>
+<h3 id="event-hub-state">Event Hub State</h3>
+<p>The <code>EventHub</code> component is responsible for communicating with the kernel device
+drivers and identifying device capabilities.  Accordingly, its state shows
+information about how devices are configured.</p>
+<pre><code>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:
+</code></pre>
+<h4 id="things-to-look-for">Things To Look For</h4>
+<ol>
+<li>
+<p>All of the expected input devices are present.</p>
+</li>
+<li>
+<p>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.</p>
+</li>
+<li>
+<p>Each input device is being classified correctly.  The bits in the <code>Classes</code>
+    field correspond to flags in <code>EventHub.h</code> such as <code>INPUT_DEVICE_CLASS_TOUCH_MT</code>.</p>
+</li>
+<li>
+<p>The <code>BuiltInKeyboardId</code> is correct.  If the device does not have a built-in keyboard,
+    then the id must be <code>-1</code>, otherwise it should be the id of the built-in keyboard.</p>
+<p>If you observe that the <code>BuiltInKeyboardId</code> is not <code>-1</code> 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 <code>type SPECIAL_FUNCTION</code> (that's what in the <code>tuna-gpio-keykad.kcm</code>
+file we see mentioned above).</p>
+</li>
+</ol>
+<h3 id="input-reader-state">Input Reader State</h3>
+<p>The <code>InputReader</code> 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.</p>
+<p>This is what a special function keypad looks like:</p>
+<pre><code>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
+</code></pre>
+<p>Here is a touch screen.  Notice all of the information about the resolution of
+the device and the calibration parameters that were used.</p>
+<pre><code>  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
+</code></pre>
+<p>Here is an external keyboard / mouse combo HID device.  (This device doesn't actually
+have a mouse but its HID descriptor says it does.)</p>
+<pre><code>  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
+</code></pre>
+<p>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.</p>
+<pre><code>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
+</code></pre>
+<p>At the end of the input reader dump there is some information about global configuration
+parameters such as the mouse pointer speed.</p>
+<pre><code>  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
+</code></pre>
+<h4 id="things-to-look-for_1">Things To Look For</h4>
+<ol>
+<li>
+<p>All of the expected input devices are present.</p>
+</li>
+<li>
+<p>Each input device has been configured appropriately.  Especially check the
+    touch screen and joystick axes.</p>
+</li>
+</ol>
+<h3 id="input-dispatcher-state">Input Dispatcher State</h3>
+<p>The <code>InputDispatcher</code> 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.</p>
+<pre><code>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: &lt;none&gt;
+  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: &lt;none&gt;
+  InboundQueue: length=0
+  ActiveConnections: &lt;none&gt;
+  AppSwitch: not pending
+  Configuration:
+    MaxEventsPerSecond: 90
+    KeyRepeatDelay: 50.0ms
+    KeyRepeatTimeout: 500.0ms
+</code></pre>
+<h4 id="things-to-look-for_2">Things To Look For</h4>
+<ol>
+<li>
+<p>In general, all input events are being processed as expected.</p>
+</li>
+<li>
+<p>If you touch the touch screen and run dumpsys at the same time, then the <code>TouchedWindows</code>
+    line should show the window that you are touching.</p>
+</li>
+</ol>
+
diff --git a/src/devices/tech/input/getevent.jd b/src/devices/tech/input/getevent.jd
new file mode 100644
index 0000000..19499d1
--- /dev/null
+++ b/src/devices/tech/input/getevent.jd
@@ -0,0 +1,103 @@
+page.title=Getevent
+@jd:body
+
+<!--
+    Copyright 2010 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.
+-->
+<p>The <code>getevent</code> tool runs on the device and provides information about input
+devices and a live dump of kernel input events.</p>
+<p>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.</p>
+<h2 id="usage">Usage</h2>
+<h3 id="showing-device-capabilities">Showing Device Capabilities</h3>
+<p>It is often quite useful to see all of the keys and axes that a device reports.
+Use the <code>-p</code> option to do that.</p>
+<p>Here is a list of all of the Linux key codes and other events that a
+particular keyboard says it supports.</p>
+<pre><code>$ 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:
+    &lt;none&gt;
+</code></pre>
+<p>The <code>-i</code> option shows even more information than <code>-p</code>, including HID mapping tables
+and debugging information.</p>
+<p>The <code>-l</code> option uses textual labels for all event codes, which is handy.</p>
+<pre><code>$ 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
+</code></pre>
+<h3 id="showing-live-events">Showing Live Events</h3>
+<p>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 <code>-l</code> option
+to show textual labels and <code>-t</code> to show timestamps.</p>
+<pre><code>$ 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
+</code></pre>
diff --git a/src/devices/tech/input/index.jd b/src/devices/tech/input/index.jd
new file mode 100644
index 0000000..80cc997
--- /dev/null
+++ b/src/devices/tech/input/index.jd
@@ -0,0 +1,22 @@
+page.title=Input Technical Information
+@jd:body
+
+<!--
+    Copyright 2010 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.
+-->
+<p>The Android input subsystem supports many different device classes,
+including keyboard, joystick, trackball, mouse and touch screen.</p>
+<p>The documentation in this section describes how to configure,
+calibrate, test, and write drivers for input devices.</p>
\ No newline at end of file
diff --git a/src/devices/tech/input/input-device-configuration-files.jd b/src/devices/tech/input/input-device-configuration-files.jd
new file mode 100644
index 0000000..e5629c3
--- /dev/null
+++ b/src/devices/tech/input/input-device-configuration-files.jd
@@ -0,0 +1,127 @@
+page.title=Input Device Configuration Files
+@jd:body
+
+<!--
+    Copyright 2010 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.
+-->
+<p>Input device configuration files (<code>.idc</code> files) contain device-specific
+configuration properties that affect the behavior of input devices.</p>
+<p>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.</p>
+<h2 id="rationale">Rationale</h2>
+<p>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.</p>
+<p>For example, if an input device supports the <code>EV_REL</code> event type and codes
+<code>REL_X</code> and <code>REL_Y</code> as well as the <code>EV_KEY</code> event type and <code>BTN_MOUSE</code>,
+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.</p>
+<p>Certain classes of input devices are more ambiguous.  For example, multi-touch
+touch screens and touch pads both support the <code>EV_ABS</code> event type and codes
+<code>ABS_MT_POSITION_X</code> and <code>ABS_MT_POSITION_Y</code> 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.</p>
+<h2 id="location">Location</h2>
+<p>Input device configuration files are located by USB vendor, product (and
+optionally version) id or by input device name.</p>
+<p>The following paths are consulted in order.</p>
+<ul>
+<li><code>/system/usr/idc/Vendor_XXXX_Product_XXXX_Version_XXXX.idc</code></li>
+<li><code>/system/usr/idc/Vendor_XXXX_Product_XXXX.idc</code></li>
+<li><code>/system/usr/idc/DEVICE_NAME.idc</code></li>
+<li><code>/data/system/devices/idc/Vendor_XXXX_Product_XXXX_Version_XXXX.idc</code></li>
+<li><code>/data/system/devices/idc/Vendor_XXXX_Product_XXXX.idc</code></li>
+<li><code>/data/system/devices/idc/DEVICE_NAME.idc</code></li>
+</ul>
+<p>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 '_'.</p>
+<h2 id="syntax">Syntax</h2>
+<p>An input device configuration file is a plain text file consisting of property
+assignments and comments.</p>
+<h3 id="properties">Properties</h3>
+<p>Property assignments each consist of a property name, an <code>=</code>, a property value,
+and a new line.  Like this:</p>
+<pre><code>property = value
+</code></pre>
+<p>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.</p>
+<p>Property values are non-empty string literals, integers or floating point numbers.
+They must not contain whitespace or the reserved characters <code>\</code> or <code>"</code>.</p>
+<p>Property names and values are case-sensitive.</p>
+<h3 id="comments">Comments</h3>
+<p>Comment lines begin with '#' and continue to the end of the line.  Like this:</p>
+<pre><code># A comment!
+</code></pre>
+<p>Blank lines are ignored.</p>
+<h3 id="example">Example</h3>
+<pre><code># 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...
+</code></pre>
+<h2 id="common-properties">Common Properties</h2>
+<p>The following properties are common to all input device classes.</p>
+<p>Refer to the documentation of each input device class for information about the
+special properties used by each class.</p>
+<h4 id="deviceinternal"><code>device.internal</code></h4>
+<p><em>Definition:</em> <code>device.internal</code> = <code>0</code> | <code>1</code></p>
+<p>Specifies whether the input device is an internal built-in component as opposed to an
+externally attached (most likely removable) peripheral.</p>
+<ul>
+<li>
+<p>If the value is <code>0</code>, the device is external.</p>
+</li>
+<li>
+<p>If the value is <code>1</code>, the device is internal.</p>
+</li>
+<li>
+<p>If the value is not specified, the default value is <code>0</code> for all devices on the
+    USB (BUS_USB) or Bluetooth (BUS_BLUETOOTH) bus, <code>1</code> otherwise.</p>
+</li>
+</ul>
+<p>This property determines default policy decisions regarding wake events.</p>
+<p>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.</p>
+<p>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.</p>
+<p>It is important to ensure that the value of the <code>device.internal</code> property is set
+correctly for all internal input devices.</p>
+<h2 id="validation">Validation</h2>
+<p>Make sure to validate your input device configuration files using the
+<a href="/tech/input/validate-keymaps.html">Validate Keymaps</a> tool.</p>
+
diff --git a/src/devices/tech/input/key-character-map-files.jd b/src/devices/tech/input/key-character-map-files.jd
new file mode 100644
index 0000000..7b1ac5b
--- /dev/null
+++ b/src/devices/tech/input/key-character-map-files.jd
@@ -0,0 +1,425 @@
+page.title=Key Character Map Files
+@jd:body
+
+<!--
+    Copyright 2010 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.
+-->
+<p>Key character map files (<code>.kcm</code> files) are responsible for mapping combinations
+of Android key codes with modifiers to Unicode characters.</p>
+<p>Device-specific key layout files are <em>required</em> 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).</p>
+<p>Device-specific key layout files are <em>optional</em> 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.</p>
+<p>If no device-specific key layout file is available, then the system will
+choose a default instead.</p>
+<h2 id="location">Location</h2>
+<p>Key character map files are located by USB vendor, product (and optionally version)
+id or by input device name.</p>
+<p>The following paths are consulted in order.</p>
+<ul>
+<li><code>/system/usr/keychars/Vendor_XXXX_Product_XXXX_Version_XXXX.kcm</code></li>
+<li><code>/system/usr/keychars/Vendor_XXXX_Product_XXXX.kcm</code></li>
+<li><code>/system/usr/keychars/DEVICE_NAME.kcm</code></li>
+<li><code>/data/system/devices/keychars/Vendor_XXXX_Product_XXXX_Version_XXXX.kcm</code></li>
+<li><code>/data/system/devices/keychars/Vendor_XXXX_Product_XXXX.kcm</code></li>
+<li><code>/data/system/devices/keychars/DEVICE_NAME.kcm</code></li>
+<li><code>/system/usr/keychars/Generic.kcm</code></li>
+<li><code>/data/system/devices/keychars/Generic.kcm</code></li>
+<li><code>/system/usr/keychars/Virtual.kcm</code></li>
+<li><code>/data/system/devices/keychars/Virtual.kcm</code></li>
+</ul>
+<p>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 '<em>' are replaced by '</em>'.</p>
+<h2 id="generic-key-character-map-file">Generic Key Character Map File</h2>
+<p>The system provides a special built-in key character map file called <code>Generic.kcm</code>.
+This key character map is intended to support a variety of standard external
+keyboards.</p>
+<p><em>Do not modify the generic key character map!</em></p>
+<h2 id="virtual-key-character-map-file">Virtual Key Character Map File</h2>
+<p>The system provides a special built-in key character map file called <code>Virtual.kcm</code>
+that is used by the virtual keyboard devices.</p>
+<p>The virtual keyboard device is a synthetic input device whose id is -1
+(see <code>KeyCharacterMap.VIRTUAL_KEYBOARD</code>).  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.</p>
+<p>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.</p>
+<p><em>Do not modify the virtual key character map!</em></p>
+<h2 id="syntax">Syntax</h2>
+<p>A key character map file is a plain text file consisting of a keyboard type
+declaration and a set of key declarations.</p>
+<h3 id="keyboard-type-declaration">Keyboard Type Declaration</h3>
+<p>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.</p>
+<pre><code>type FULL
+</code></pre>
+<p>The following keyboard types are recognized:</p>
+<ul>
+<li>
+<p><code>NUMERIC</code>: A numeric (12-key) keyboard.</p>
+<p>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.</p>
+<p>This type of keyboard is generally designed for thumb typing.</p>
+<p>Corresponds to <code>KeyCharacterMap.NUMERIC</code>.</p>
+</li>
+<li>
+<p><code>PREDICTIVE</code>: A keyboard with all the letters, but with more than one letter per key.</p>
+<p>This type of keyboard is generally designed for thumb typing.</p>
+<p>Corresponds to <code>KeyCharacterMap.PREDICTIVE</code>.</p>
+</li>
+<li>
+<p><code>ALPHA</code>: A keyboard with all the letters, and maybe some numbers.</p>
+<p>An alphabetic keyboard supports text entry directly but may have a condensed
+layout with a small form factor.  In contrast to a <code>FULL</code> 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.</p>
+<p>This type of keyboard is generally designed for thumb typing.</p>
+</li>
+<li>
+<p><code>FULL</code>: A full PC-style keyboard.</p>
+<p>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.</p>
+<p>This type of keyboard is generally designed for full two hand typing.</p>
+</li>
+<li>
+<p><code>SPECIAL_FUNCTION</code>: A keyboard that is only used to perform system control functions
+    rather than for typing.</p>
+<p>A special function keyboard consists only of non-printing keys such as
+HOME and POWER that are not actually used for typing.</p>
+</li>
+</ul>
+<p>The <code>Generic.kcm</code> and <code>Virtual.kcm</code> key character maps are both <code>FULL</code> keyboards.</p>
+<h3 id="key-declarations">Key Declarations</h3>
+<p>Key declarations each consist of the keyword <code>key</code> followed by an Android key code
+name, an open curly brace, a set of properties and behaviors and a close curly brace.</p>
+<pre><code>key A {
+    label:                              'A'
+    base:                               'a'
+    shift, capslock:                    'A'
+    ctrl, alt, meta:                    none
+}
+</code></pre>
+<h4 id="properties">Properties</h4>
+<p>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.</p>
+<p>In the above example, the <code>label</code> property is assigned the <code>'A'</code> behavior.
+Likewise, the <code>ctrl</code>, <code>alt</code> and <code>meta</code> properties are all simultaneously assigned
+the <code>none</code> behavior.</p>
+<p>The following properties are recognized:</p>
+<ul>
+<li>
+<p><code>label</code>: 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 <code>KeyCharacterMap.getDisplayLabel</code> method.</p>
+</li>
+<li>
+<p><code>number</code>: 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.</p>
+<p>Compact keyboards often combine multiple symbols into a single key, such that
+the same key might be used to type <code>'1'</code> and <code>'a'</code> or <code>'#'</code> and <code>'q'</code>, perhaps.
+For these keys, the <code>number</code> property should be set to indicate which symbol
+should be typed in a numeric context, if any.</p>
+<p>Some typical "numeric" symbols are digits <code>'0'</code> through <code>'9'</code>, <code>'#'</code>, <code>'+'</code>,
+<code>'('</code>, <code>')'</code>, <code>','</code>, and <code>'.'</code>.</p>
+</li>
+<li>
+<p><code>base</code>: Specifies the behavior (character that should be typed) when no modifiers
+    are pressed.</p>
+</li>
+<li>
+<p>&lt;modifier&gt; or &lt;modifier1&gt;<code>+</code>&lt;modifier2&gt;<code>+</code>...: Specifies the
+    behavior (character that should be typed) when the key is pressed and all of the
+    specified modifiers are active.</p>
+<p>For example, the modifier property <code>shift</code> specifies a behavior that applies when
+the either the LEFT SHIFT or RIGHT SHIFT modifier is pressed.</p>
+<p>Similarly, the modifier property <code>rshift+ralt</code> specifies a behavior that applies
+when the both RIGHT SHIFT and RIGHT ALT modifiers are pressed together.</p>
+</li>
+</ul>
+<p>The following modifiers are recognized in modifier properties:</p>
+<ul>
+<li><code>shift</code>: Applies when either the LEFT SHIFT or RIGHT SHIFT modifier is pressed.</li>
+<li><code>lshift</code>: Applies when the LEFT SHIFT modifier is pressed.</li>
+<li><code>rshift</code>: Applies when the RIGHT SHIFT modifier is pressed.</li>
+<li><code>alt</code>: Applies when either the LEFT ALT or RIGHT ALT modifier is pressed.</li>
+<li><code>lalt</code>: Applies when the LEFT ALT modifier is pressed.</li>
+<li><code>ralt</code>: Applies when the RIGHT ALT modifier is pressed.</li>
+<li><code>ctrl</code>: Applies when either the LEFT CONTROL or RIGHT CONTROL modifier is pressed.</li>
+<li><code>lctrl</code>: Applies when the LEFT CONTROL modifier is pressed.</li>
+<li><code>rctrl</code>: Applies when the RIGHT CONTROL modifier is pressed.</li>
+<li><code>meta</code>: Applies when either the LEFT META or RIGHT META modifier is pressed.</li>
+<li><code>lmeta</code>: Applies when the LEFT META modifier is pressed.</li>
+<li><code>rmeta</code>: Applies when the RIGHT META modifier is pressed.</li>
+<li><code>sym</code>: Applies when the SYMBOL modifier is pressed.</li>
+<li><code>fn</code>: Applies when the FUNCTION modifier is pressed.</li>
+<li><code>capslock</code>: Applies when the CAPS LOCK modifier is locked.</li>
+<li><code>numlock</code>: Applies when the NUM LOCK modifier is locked.</li>
+<li><code>scrolllock</code>: Applies when the SCROLL LOCK modifier is locked.</li>
+</ul>
+<p>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.</p>
+<p>Consequently, properties that are specified later override properties that are
+specified earlier for a given key.</p>
+<h4 id="behaviors">Behaviors</h4>
+<p>Each property maps to a behavior.  The most common behavior is typing a character
+but there are others.</p>
+<p>The following behaviors are recognized:</p>
+<ul>
+<li>
+<p><code>none</code>: Don't type a character.</p>
+<p>This behavior is the default when no character is specified.  Specifying <code>none</code>
+is optional but it improves clarity.</p>
+</li>
+<li>
+<p><code>'X'</code>: Type the specified character literal.</p>
+<p>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:</p>
+<ul>
+<li><code>'\\'</code>: Type a backslash character.</li>
+<li><code>'\n'</code>: Type a new line character (use this for ENTER / RETURN).</li>
+<li><code>'\t'</code>: Type a TAB character.</li>
+<li><code>'\''</code>: Type an apostrophe character.</li>
+<li><code>'\"'</code>: Type a quote character.</li>
+<li><code>'\uXXXX'</code>: Type the Unicode character whose code point is given in hex by XXXX.</li>
+</ul>
+</li>
+<li>
+<p><code>fallback</code> &lt;Android key code name&gt;: Perform a default action if the key is not
+    handled by the application.</p>
+<p>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).</p>
+<p>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 (<code>KeyEvent.isCanceled</code> will return <code>true</code>).</p>
+</li>
+</ul>
+<p>The system reserves two Unicode characters to perform special functions:</p>
+<ul>
+<li>
+<p><code>'\uef00'</code>: 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.</p>
+</li>
+<li>
+<p><code>'\uef01'</code>: When this behavior is performed, the text view displays a
+    character picker dialog that contains miscellaneous symbols.</p>
+</li>
+</ul>
+<p>The system recognizes the following Unicode characters as combining diacritical dead
+key characters:</p>
+<ul>
+<li><code>'\u0300'</code>: Grave accent.</li>
+<li><code>'\u0301'</code>: Acute accent.</li>
+<li><code>'\u0302'</code>: Circumflex accent.</li>
+<li><code>'\u0303'</code>: Tilde accent.</li>
+<li><code>'\u0308'</code>: Umlaut accent.</li>
+</ul>
+<p>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;'.</p>
+<p>Refer to <code>KeyCharacterMap.getDeadChar</code> for more information about dead key handling.</p>
+<h3 id="comments">Comments</h3>
+<p>Comment lines begin with '#' and continue to the end of the line.  Like this:</p>
+<pre><code># A comment!
+</code></pre>
+<p>Blank lines are ignored.</p>
+<h3 id="how-key-combinations-are-mapped-to-behaviors">How Key Combinations are Mapped to Behaviors</h3>
+<p>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.</p>
+<h4 id="shift-a">SHIFT + A</h4>
+<p>Suppose the user pressed A and SHIFT together.  The system first locates
+the set of properties and behaviors associated with <code>KEYCODE_A</code>.</p>
+<pre><code>key A {
+    label:                              'A'
+    base:                               'a'
+    shift, capslock:                    'A'
+    ctrl, alt, meta:                    none
+}
+</code></pre>
+<p>The system scans the properties from first to last and left to right, ignoring
+the <code>label</code> and <code>number</code> properties, which are special.</p>
+<p>The first property encountered is <code>base</code>.  The <code>base</code> 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 <code>base</code> property applies to this key press, the system makes note
+of the fact that its behavior is <code>'a'</code> (type the character <code>a</code>).</p>
+<p>The system then continues to scan subsequent properties in case any of them
+are more specific than <code>base</code> and override it.  It encounters <code>shift</code> which
+also applies to the key press SHIFT + A.  So the system decides to ignore
+the <code>base</code> property's behavior and chooses the behavior associated with
+the <code>shift</code> property, which is <code>'A'</code> (type the character <code>A</code>).</p>
+<p>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).</p>
+<p>So the resulting behavior for the key combination SHIFT + A is <code>'A'</code>.</p>
+<h4 id="control-a">CONTROL + A</h4>
+<p>Now consider what would happen if the user pressed A and CONTROL together.</p>
+<p>As before, the system would scan the table of properties.  It would notice
+that the <code>base</code> property applied but would also continue scanning until
+it eventually reached the <code>control</code> property.  As it happens, the <code>control</code>
+property appears after <code>base</code> so its behavior overrides the <code>base</code> behavior.</p>
+<p>So the resulting behavior for the key combination CONTROL + A is <code>none</code>.</p>
+<h4 id="escape">ESCAPE</h4>
+<p>Now suppose the user pressed ESCAPE.</p>
+<pre><code>key ESCAPE {
+    base:                               fallback BACK
+    alt, meta:                          fallback HOME
+    ctrl:                               fallback MENU
+}
+</code></pre>
+<p>This time the system obtains the behavior <code>fallback BACK</code>, a fallback behavior.
+Because no character literal appears, no character will be typed.</p>
+<p>When processing the key, the system will first deliver <code>KEYCODE_ESCAPE</code> to the
+application.  If the application does not handle it, then the system will try
+again but this time it will deliver <code>KEYCODE_BACK</code> to the application as
+requested by the fallback behavior.</p>
+<p>So applications that recognize and support <code>KEYCODE_ESCAPE</code> 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 <code>KEYCODE_BACK</code>.</p>
+<h4 id="numpad_0-with-or-without-num-lock">NUMPAD_0 with or without NUM LOCK</h4>
+<p>The numeric keypad keys have very different interpretations depending on whether
+the NUM LOCK key is locked.</p>
+<p>The following key declaration ensures that <code>KEYCODE_NUMPAD_0</code> types <code>0</code>
+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 <code>KEYCODE_INSERT</code> is delivered instead.</p>
+<pre><code>key NUMPAD_0 {
+    label, number:                      '0'
+    base:                               fallback INSERT
+    numlock:                            '0'
+    ctrl, alt, meta:                    none
+}
+</code></pre>
+<p>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.</p>
+<h3 id="examples">Examples</h3>
+<h4 id="full-keyboard">Full Keyboard</h4>
+<pre><code># 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
+}
+</code></pre>
+<h4 id="alphanumeric-keyboard">Alphanumeric Keyboard</h4>
+<pre><code># 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'
+}
+</code></pre>
+<h4 id="game-pad">Game Pad</h4>
+<pre><code># 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
+}
+</code></pre>
+<h2 id="compatibility-note">Compatibility Note</h2>
+<p>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
+(<code>.kcm.bin</code>) at build time.</p>
+<p>Although the new format uses the same extension <code>.kcm</code>, the syntax is quite
+different (and much more powerful).</p>
+<p>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 <code>.kcm.bin</code> files are not recognized
+by the system.</p>
+<h2 id="language-note">Language Note</h2>
+<p>Android does not currently support multilingual keyboards.  Moreover, the
+built-in generic key character map assumes a US English keyboard layout.</p>
+<p>OEMs are encouraged to provide custom key character maps for their keyboards
+if they are designed for other languages.</p>
+<p>Future versions of Android may provide better support for multilingual keyboards
+or user-selectable keyboard layouts.</p>
+<h2 id="validation">Validation</h2>
+<p>Make sure to validate your key character map files using the
+<a href="/tech/input/validate-keymaps.html">Validate Keymaps</a> tool.</p>
diff --git a/src/devices/tech/input/key-layout-files.jd b/src/devices/tech/input/key-layout-files.jd
new file mode 100644
index 0000000..d416341
--- /dev/null
+++ b/src/devices/tech/input/key-layout-files.jd
@@ -0,0 +1,277 @@
+page.title=Key Layout Files
+@jd:body
+
+<!--
+    Copyright 2010 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.
+-->
+<p>Key layout files (<code>.kl</code> files) are responsible for mapping Linux key codes
+and axis codes to Android key codes and axis codes and specifying associated
+policy flags.</p>
+<p>Device-specific key layout files are <em>required</em> for all internal (built-in)
+input devices that have keys, including special keys such as volume, power
+and headset media keys.</p>
+<p>Device-specific key layout files are <em>optional</em> for other input devices but
+they are <em>recommended</em> for special-purpose keyboards and joysticks.</p>
+<p>If no device-specific key layout file is available, then the system will
+choose a default instead.</p>
+<h2 id="location">Location</h2>
+<p>Key layout files are located by USB vendor, product (and optionally version)
+id or by input device name.</p>
+<p>The following paths are consulted in order.</p>
+<ul>
+<li><code>/system/usr/keylayout/Vendor_XXXX_Product_XXXX_Version_XXXX.kl</code></li>
+<li><code>/system/usr/keylayout/Vendor_XXXX_Product_XXXX.kl</code></li>
+<li><code>/system/usr/keylayout/DEVICE_NAME.kl</code></li>
+<li><code>/data/system/devices/keylayout/Vendor_XXXX_Product_XXXX_Version_XXXX.kl</code></li>
+<li><code>/data/system/devices/keylayout/Vendor_XXXX_Product_XXXX.kl</code></li>
+<li><code>/data/system/devices/keylayout/DEVICE_NAME.kl</code></li>
+<li><code>/system/usr/keylayout/Generic.kl</code></li>
+<li><code>/data/system/devices/keylayout/Generic.kl</code></li>
+</ul>
+<p>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 '<em>' are replaced by '</em>'.</p>
+<h2 id="generic-key-layout-file">Generic Key Layout File</h2>
+<p>The system provides a special built-in generic key layout file called <code>Generic.kl</code>.
+This key layout is intended to support a variety of standard external
+keyboards and joysticks.</p>
+<p><em>Do not modify the generic key layout!</em></p>
+<h2 id="syntax">Syntax</h2>
+<p>A key layout file is a plain text file consisting of key or axis declarations
+and flags.</p>
+<h3 id="key-declarations">Key Declarations</h3>
+<p>Key declarations each consist of the keyword <code>key</code> followed by a Linux key code
+number, an Android key code name, and optional set of whitespace delimited policy flags.</p>
+<pre><code>key 1     ESCAPE
+key 114   VOLUME_DOWN       WAKE
+key 16    Q                 VIRTUAL     WAKE
+</code></pre>
+<p>The following policy flags are recognized:</p>
+<ul>
+<li><code>WAKE</code>: The key should wake the device when it is asleep.  For historical reasons,
+    this flag behaves in the same manner as <code>WAKE_DROPPED</code> below.</li>
+<li><code>WAKE_DROPPED</code>: 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.</li>
+<li><code>SHIFT</code>: The key should be interpreted as if the SHIFT key were also pressed.</li>
+<li><code>CAPS_LOCK</code>: The key should be interpreted as if the CAPS LOCK key were also pressed.</li>
+<li><code>ALT</code>: The key should be interpreted as if the ALT key were also pressed.</li>
+<li><code>ALT_GR</code>: The key should be interpreted as if the RIGHT ALT key were also pressed.</li>
+<li><code>FUNCTION</code>: The key should be interpreted as if the FUNCTION key were also pressed.</li>
+<li><code>VIRTUAL</code>: 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.</li>
+<li><code>MENU</code>: Deprecated.  Do not use.</li>
+<li><code>LAUNCHER</code>: Deprecated.  Do not use.</li>
+</ul>
+<h3 id="axis-declarations">Axis Declarations</h3>
+<p>Axis declarations each consist of the keyword <code>axis</code> followed by a Linux axis code
+number, and qualifiers that control the behavior of the axis including at least
+one Android axis code name.</p>
+<h4 id="basic-axes">Basic Axes</h4>
+<p>A basic axis simply maps a Linux axis code to an Android axis code name.</p>
+<p>The following declaration maps <code>ABS_X</code> (indicated by <code>0x00</code>) to <code>AXIS_X</code> (indicated by <code>X</code>).</p>
+<pre><code>axis 0x00 X
+</code></pre>
+<p>In the above example, if the value of <code>ABS_X</code> is <code>5</code> then <code>AXIS_X</code> will be set to <code>5</code>.</p>
+<h4 id="split-axes">Split Axes</h4>
+<p>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.</p>
+<p>The following declaration maps values of the <code>ABS_Y</code> axis (indicated by <code>0x01</code>) to
+<code>AXIS_GAS</code> when less than <code>0x7f</code> or to <code>AXIS_BRAKE</code> when greater than <code>0x7f</code>.</p>
+<pre><code>axis 0x01 split 0x7f GAS BRAKE
+</code></pre>
+<p>In the above example, if the value of <code>ABS_Y</code> is <code>0x7d</code> then <code>AXIS_GAS</code> is set
+to <code>2</code> (<code>0x7f - 0x7d</code>) and <code>AXIS_BRAKE</code> is set to <code>0</code>.  Conversely, if the value of
+<code>ABS_Y</code> is <code>0x83</code> then <code>AXIS_GAS</code> is set to <code>0</code> and <code>AXIS_BRAKE</code> is set to <code>4</code>
+(<code>0x83 - 0x7f</code>).  Finally, if the value of <code>ABS_Y</code> equals the split value of <code>0x7f</code>
+then both <code>AXIS_GAS</code> and <code>AXIS_BRAKE</code> are set to <code>0</code>.</p>
+<h4 id="inverted-axes">Inverted Axes</h4>
+<p>An inverted axis inverts the sign of the axis value.</p>
+<p>The following declaration maps <code>ABS_RZ</code> (indicated by <code>0x05</code>) to <code>AXIS_BRAKE</code>
+(indicated by <code>BRAKE</code>), and inverts the output by negating it.</p>
+<pre><code>axis 0x05 invert AXIS_RZ
+</code></pre>
+<p>In the above example, if the value of <code>ABS_RZ</code> is <code>2</code> then <code>AXIS_RZ</code> is set to <code>-2</code>.</p>
+<h4 id="center-flat-position-option">Center Flat Position Option</h4>
+<p>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.</p>
+<p>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.</p>
+<p>To resolve this issue, an axis declaration may be followed by a <code>flat</code>
+option that specifies the value of the center flat position for the axis.</p>
+<pre><code>axis 0x03 Z flat 4096
+</code></pre>
+<p>In the above example, the center flat position is set to <code>4096</code>.</p>
+<h3 id="comments">Comments</h3>
+<p>Comment lines begin with '#' and continue to the end of the line.  Like this:</p>
+<pre><code># A comment!
+</code></pre>
+<p>Blank lines are ignored.</p>
+<h3 id="examples">Examples</h3>
+<h4 id="keyboard">Keyboard</h4>
+<pre><code># 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...
+</code></pre>
+<h4 id="system-controls">System Controls</h4>
+<pre><code># 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
+</code></pre>
+<h4 id="capacitive-buttons">Capacitive Buttons</h4>
+<pre><code># 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
+</code></pre>
+<h4 id="headset-jack-media-controls">Headset Jack Media Controls</h4>
+<pre><code># 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
+</code></pre>
+<h4 id="joystick">Joystick</h4>
+<pre><code># 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
+</code></pre>
+<h2 id="wake-keys">Wake Keys</h2>
+<p>Wake keys are special keys that wake the device from sleep, such as the power key.</p>
+<p>By default, for internal keyboard devices, no key is a wake key.  For external
+keyboard device, all keys are wake keys.</p>
+<p>To make a key be a wake key, set the <code>WAKE_DROPPED</code> flag in the key layout file
+for the keyboard device.</p>
+<p>Note that the <code>WindowManagerPolicy</code> 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
+<code>PhoneWindowManager.interceptKeyBeforeQueueing</code>.</p>
+<h2 id="virtual-soft-keys">Virtual Soft Keys</h2>
+<p>The input system provides special features for implementing virtual soft keys.</p>
+<p>There are three cases:</p>
+<ol>
+<li>
+<p>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.</p>
+<p>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.</p>
+</li>
+<li>
+<p>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.</p>
+<p>Refer to the section on <a href="/tech/input/touch-devices.html">Touch Devices</a>
+for more details about virtual key map files.</p>
+<p>The key layout file for the touch screen input device must specify the
+appropriate key mapping and include the <code>VIRTUAL</code> flag for each key.</p>
+</li>
+<li>
+<p>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.</p>
+<p>The key layout file for the capacitive button input device must specify the
+appropriate key mapping and include the <code>VIRTUAL</code> flag for each key.</p>
+</li>
+</ol>
+<p>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.</p>
+<p>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.</p>
+<p>To enable virtual soft key debouncing, we must do two things.</p>
+<p>First, we provide a key layout file for the touch screen or capacitive button
+input device with the <code>VIRTUAL</code> flag set for each key.</p>
+<pre><code>key 139    MENU           VIRTUAL
+key 102    HOME           VIRTUAL
+key 158    BACK           VIRTUAL
+key 217    SEARCH         VIRTUAL
+</code></pre>
+<p>Then, we set the value of the virtual key quiet time in a resource overlay
+for the framework <code>config.xml</code> resource.</p>
+<pre><code>&lt;!-- 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. --&gt;
+&lt;integer name="config_virtualKeyQuietTimeMillis"&gt;250&lt;/integer&gt;
+</code></pre>
+<h2 id="validation">Validation</h2>
+<p>Make sure to validate your key layout files using the
+<a href="/tech/input/validate-keymaps.html">Validate Keymaps</a> tool.</p>
diff --git a/src/devices/tech/input/keyboard-devices.jd b/src/devices/tech/input/keyboard-devices.jd
new file mode 100644
index 0000000..aa968ac
--- /dev/null
+++ b/src/devices/tech/input/keyboard-devices.jd
@@ -0,0 +1,6438 @@
+page.title=Keyboard Devices
+@jd:body
+
+<!--
+    Copyright 2010 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.
+-->
+<p>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.</p>
+<p>This document decribes physical keyboards only.  Refer to the Android SDK
+for information about soft keyboards (Input Method Editors).</p>
+<h2 id="keyboard-classification">Keyboard Classification</h2>
+<p>An input device is classified as a keyboard if either of the following
+conditions hold:</p>
+<ul>
+<li>
+<p>The input device reports the presence of any Linux key codes used on keyboards
+    including <code>0</code> through <code>0xff</code> or <code>KEY_OK</code> through <code>KEY_MAX</code>.</p>
+</li>
+<li>
+<p>The input device reports the presence of any Linux key codes used on joysticks
+    and gamepads including <code>BTN_0</code> through <code>BTN_9</code>, <code>BTN_TRIGGER</code> through <code>BTN_DEAD</code>,
+    or <code>BTN_A</code> through <code>BTN_THUMBR</code>.</p>
+</li>
+</ul>
+<p>Joysticks are currently classified as keyboards because joystick and gamepad buttons
+are reported by <code>EV_KEY</code> 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 <a href="/tech/input/joystick-devices.html">Joystick Devices</a> for
+more information.</p>
+<p>Once an input device has been classified as a keyboard, the system loads the
+input device configuration file and keyboard layout for the keyboard.</p>
+<p>The system then tries to determine additional characteristics of the device.</p>
+<ul>
+<li>
+<p>If the input device has any keys that are mapped to <code>KEYCODE_Q</code>, then the
+    device is considered to have an alphabetic keypad (as opposed to numeric).
+    The alphabetic keypad capability is reported in the resource <code>Configuration</code>
+    object as <code>KEYBOARD_QWERTY</code>.</p>
+</li>
+<li>
+<p>If the input device has any keys that are mapped to <code>KEYCODE_DPAD_UP</code>,
+    <code>KEYCODE_DPAD_DOWN</code>, <code>KEYCODE_DPAD_LEFT</code>, <code>KEYCODE_DPAD_RIGHT</code>, and
+    <code>KEYCODE_DPAD_CENTER</code> (all must be present), then the device is considered
+    to have a directional keypad.
+    The directional keypad capability is reported in the resource <code>Configuration</code>
+    object as <code>NAVIGATION_DPAD</code>.</p>
+</li>
+<li>
+<p>If the input device has any keys that are mapped to <code>KEYCODE_BUTTON_A</code>
+    or other gamepad related keys, then the device is considered to have a gamepad.</p>
+</li>
+</ul>
+<h2 id="keyboard-driver-requirements">Keyboard Driver Requirements</h2>
+<ol>
+<li>
+<p>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.</p>
+</li>
+<li>
+<p>Keyboard drivers should use <code>EV_KEY</code> to report key presses, using a value
+    of <code>0</code> to indicate that a key is released, a value of <code>1</code> to indicate that
+    a key is pressed, and a value greater than or equal to <code>2</code> to indicate that
+    the key is being repeated automatically.</p>
+</li>
+<li>
+<p>Android performs its own keyboard repeating.  Auto-repeat functionality
+    should be disabled in the driver.</p>
+</li>
+<li>
+<p>Keyboard drivers may optionally indicate the HID usage or low-level scan
+    code by sending <code>EV_MSC</code> with <code>MSC_SCANCODE</code> and a valud indicating the usage
+    or scan code when the key is pressed.  This information is not currently
+    used by Android.</p>
+</li>
+<li>
+<p>Keyboard drivers should support setting LED states when <code>EV_LED</code> is written
+    to the device.  The <code>hid-input</code> driver handles this automatically.
+    At the time of this writing, Android uses <code>LED_CAPSLOCK</code>, <code>LED_SCROLLLOCK</code>,
+    and <code>LED_NUMLOCK</code>.  These LEDs only need to be supported when the
+    keyboard actually has the associated indicator lights.</p>
+</li>
+<li>
+<p>Keyboard drivers for embedded keypads (for example, using a GPIO matrix)
+    should make sure to send <code>EV_KEY</code> events with a value of <code>0</code> 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.</p>
+</li>
+</ol>
+<h2 id="keyboard-operation">Keyboard Operation</h2>
+<p>The following is a brief summary of the keyboard operation on Android.</p>
+<ol>
+<li>
+<p>The <code>EventHub</code> reads raw events from the <code>evdev</code> driver and maps Linux key codes
+    (sometimes referred to as scan codes) into Android key codes using the
+    keyboard's key layout map.</p>
+</li>
+<li>
+<p>The <code>InputReader</code> 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 <code>META_SHIFT_LEFT_ON</code> and <code>META_SHIFT_ON</code> bits accordingly.</p>
+</li>
+<li>
+<p>The <code>InputReader</code> notifies the <code>InputDispatcher</code> about the key event.</p>
+</li>
+<li>
+<p>The <code>InputDispatcher</code> asks the <code>WindowManagerPolicy</code> what to do with the key
+    event by calling <code>WindowManagerPolicy.interceptKeyBeforeQueueing</code>.  This method
+    is part of a critical path that is responsible for waking the device when
+    certain keys are pressed.  The <code>EventHub</code> effectively holds a wake lock
+    along this critical path to ensure that it will run to completion.</p>
+</li>
+<li>
+<p>If an <code>InputFilter</code> is currently in use, the <code>InputDispatcher</code> gives it a
+    chance to consume or transform the key.  The <code>InputFilter</code> may be used to implement
+    low-level system-wide accessibility policies.</p>
+</li>
+<li>
+<p>The <code>InputDispatcher</code> enqueues the key for processing on the dispatch thread.</p>
+</li>
+<li>
+<p>When the <code>InputDispatcher</code> dequeues the key, it gives the <code>WindowManagerPolicy</code>
+    a second chance to intercept the key event by calling
+    <code>WindowManagerPolicy.interceptKeyBeforeDispatching</code>.  This method handles system
+    shortcuts and other functions.</p>
+</li>
+<li>
+<p>The <code>InputDispatcher</code> then identifies the key event target (the focused window)
+    and waits for them to become ready.  Then, the <code>InputDispatcher</code> delivers the
+    key event to the application.</p>
+</li>
+<li>
+<p>Inside the application, the key event propagates down the view hierarchy to
+    the focused view for pre-IME key dispatch.</p>
+</li>
+<li>
+<p>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.</p>
+</li>
+<li>
+<p>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.</p>
+</li>
+<li>
+<p>The application reports back to the <code>InputDispatcher</code> as to whether the key
+    event was consumed.  If the event was not consumed, the <code>InputDispatcher</code>
+    calls <code>WindowManagerPolicy.dispatchUnhandledKey</code> 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
+    <code>KEYCODE_ESCAPE</code>, the system may redispatch the key event as <code>KEYCODE_BACK</code> instead.</p>
+</li>
+</ol>
+<h2 id="keyboard-configuration">Keyboard Configuration</h2>
+<p>Keyboard behavior is determined by the keyboard's key layout, key character
+map and input device configuration.</p>
+<p>Refer to the following sections for more details about the files that
+participate in keyboard configuration:</p>
+<ul>
+<li><a href="/tech/input/key-layout-files.html">Key Layout Files</a></li>
+<li><a href="/tech/input/key-character-map-files.html">Key Character Map Files</a></li>
+<li><a href="/tech/input/input-device-configuration-files.html">Input Device Configuration Files</a></li>
+</ul>
+<h3 id="properties">Properties</h3>
+<p>The following input device configuration properties are used for keyboards.</p>
+<h4 id="keyboardlayout"><code>keyboard.layout</code></h4>
+<p><em>Definition:</em> <code>keyboard.layout</code> = &lt;name&gt;</p>
+<p>Specifies the name of the key layout file associated with the input device,
+excluding the <code>.kl</code> extension.  If this file is not found, the input system
+will use the default key layout instead.</p>
+<p>Spaces in the name are converted to underscores during lookup.</p>
+<p>Refer to the key layout file documentation for more details.</p>
+<h4 id="keyboardcharactermap"><code>keyboard.characterMap</code></h4>
+<p><em>Definition:</em> <code>keyboard.characterMap</code> = &lt;name&gt;</p>
+<p>Specifies the name of the key character map file associated with the input device,
+excluding the <code>.kcm</code> extension.  If this file is not found, the input system
+will use the default key character map instead.</p>
+<p>Spaces in the name are converted to underscores during lookup.</p>
+<p>Refer to the key character map file documentation for more details.</p>
+<h4 id="keyboardorientationaware"><code>keyboard.orientationAware</code></h4>
+<p><em>Definition:</em> <code>keyboard.orientationAware</code> = <code>0</code> | <code>1</code></p>
+<p>Specifies whether the keyboard should react to display orientation changes.</p>
+<ul>
+<li>
+<p>If the value is <code>1</code>, the directional keypad keys are rotated when the
+    associated display orientation changes.</p>
+</li>
+<li>
+<p>If the value is <code>0</code>, the keyboard is immune to display orientation changes.</p>
+</li>
+</ul>
+<p>The default value is <code>0</code>.</p>
+<p>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, <code>KEYCODE_DPAD_UP</code> is
+remapped to produce <code>KEYCODE_DPAD_RIGHT</code> since the 'up' key ends up pointing
+'right' when the device is held in that orientation.</p>
+<h4 id="keyboardbuiltin"><code>keyboard.builtIn</code></h4>
+<p><em>Definition:</em> <code>keyboard.builtIn</code> = <code>0</code> | <code>1</code></p>
+<p>Specifies whether the keyboard is the built-in (physically attached)
+keyboard.</p>
+<p>The default value is <code>1</code> if the device name ends with <code>-keypad</code>, <code>0</code> otherwise.</p>
+<p>The built-in keyboard is always assigned a device id of <code>0</code>.  Other keyboards
+that are not built-in are assigned unique non-zero device ids.</p>
+<p>Using an id of <code>0</code> for the built-in keyboard is important for maintaining
+compatibility with the <code>KeyCharacterMap.BUILT_IN_KEYBOARD</code> field, which specifies
+the id of the built-in keyboard and has a value of <code>0</code>.  This field has been
+deprecated in the API but older applications might still be using it.</p>
+<p>A special-function keyboard (one whose key character map specifies a
+type of <code>SPECIAL_FUNCTION</code>) 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.</p>
+<h3 id="example-configurations">Example Configurations</h3>
+<pre><code># 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
+</code></pre>
+<h3 id="compatibility-notes">Compatibility Notes</h3>
+<p>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 <code>qwerty</code> instead of <code>Generic</code>.  The key
+character map format was also very different and the framework did not support
+PC-style full keyboards or external keyboards.</p>
+<p>When upgrading devices to Honeycomb, make sure to create or update the necessary
+configuration and key map files.</p>
+<h2 id="hid-usages-linux-key-codes-and-android-key-codes">HID Usages, Linux Key Codes and Android Key Codes</h2>
+<p>The system refers to keys using several different identifiers, depending on the
+layer of abstraction.</p>
+<p>For HID devices, each key has an associated HID usage.  The Linux <code>hid-input</code>
+driver and related vendor and device-specific HID drivers are responsible
+for parsing HID reports and mapping HID usages to Linux key codes.</p>
+<p>As Android reads <code>EV_KEY</code> 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.</p>
+<p>When the key event is dispatched to an application, the <code>android.view.KeyEvent</code>
+instance reports the Linux key code as the value of <code>getScanCode()</code> and the
+Android key code as the value of <code>getKeyCode()</code>.  For the purposes of the
+framework, only the value of <code>getKeyCode()</code> is important.</p>
+<p>Note that the HID usage information is not used by Android itself or
+passed to applications.</p>
+<h2 id="code-tables">Code Tables</h2>
+<p>The following tables show how HID usages, Linux key codes and Android
+key codes are related to one another.</p>
+<p>The LKC column specifies the Linux key code in hexadecimal.</p>
+<p>The AKC column specifies the Android key code in hexadecimal.</p>
+<p>The Notes column refers to notes that are posted after the table.</p>
+<p>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.</p>
+<ul>
+<li>
+<p>In Gingerbread (2.3) and earlier releases, the default key map was
+    <code>qwerty.kl</code>. 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 <code>qwerty.kl</code> 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 <code>HOME</code> key.  It is recommended
+    that all new peripherals be developed according to the Honeycomb or more
+    recent key maps (ie. standard HID).</p>
+</li>
+<li>
+<p>As of Honeycomb (3.0), the default key map is <code>Generic.kl</code>.
+    This key map was designed to support full PC style keyboards.
+    Most functionality of standard HID keyboards should just work out
+    of the box.</p>
+</li>
+</ul>
+<p>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.</p>
+<p>Device-specific HID drivers and key maps may apply different mappings
+than are indicated here.</p>
+<h3 id="hid-keyboard-and-keypad-page-0x07">HID Keyboard and Keypad Page (0x07)</h3>
+<table>
+<thead>
+<tr>
+<th>HID Usage</th>
+<th>HID Usage Name</th>
+<th>LKC</th>
+<th>Linux Key Code Name</th>
+<th>Version</th>
+<th>AKC</th>
+<th>Android Key Code Name</th>
+<th>Notes</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>0x07 0x0001</td>
+<td>Keyboard Error Roll Over</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0002</td>
+<td>Keyboard POST Fail</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0003</td>
+<td>Keyboard Error Undefined</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0004</td>
+<td>Keyboard a and A</td>
+<td>0x001e</td>
+<td>KEY_A</td>
+<td>1.6</td>
+<td>0x001d</td>
+<td>KEYCODE_A</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0005</td>
+<td>Keyboard b and B</td>
+<td>0x0030</td>
+<td>KEY_B</td>
+<td>1.6</td>
+<td>0x001e</td>
+<td>KEYCODE_B</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0006</td>
+<td>Keyboard c and C</td>
+<td>0x002e</td>
+<td>KEY_C</td>
+<td>1.6</td>
+<td>0x001f</td>
+<td>KEYCODE_C</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0007</td>
+<td>Keyboard d and D</td>
+<td>0x0020</td>
+<td>KEY_D</td>
+<td>1.6</td>
+<td>0x0020</td>
+<td>KEYCODE_D</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0008</td>
+<td>Keyboard e and E</td>
+<td>0x0012</td>
+<td>KEY_E</td>
+<td>1.6</td>
+<td>0x0021</td>
+<td>KEYCODE_E</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0009</td>
+<td>Keyboard f and F</td>
+<td>0x0021</td>
+<td>KEY_F</td>
+<td>1.6</td>
+<td>0x0022</td>
+<td>KEYCODE_F</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x000a</td>
+<td>Keyboard g and G</td>
+<td>0x0022</td>
+<td>KEY_G</td>
+<td>1.6</td>
+<td>0x0023</td>
+<td>KEYCODE_G</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x000b</td>
+<td>Keyboard h and H</td>
+<td>0x0023</td>
+<td>KEY_H</td>
+<td>1.6</td>
+<td>0x0024</td>
+<td>KEYCODE_H</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x000c</td>
+<td>Keyboard i and I</td>
+<td>0x0017</td>
+<td>KEY_I</td>
+<td>1.6</td>
+<td>0x0025</td>
+<td>KEYCODE_I</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x000d</td>
+<td>Keyboard j and J</td>
+<td>0x0024</td>
+<td>KEY_J</td>
+<td>1.6</td>
+<td>0x0026</td>
+<td>KEYCODE_J</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x000e</td>
+<td>Keyboard k and K</td>
+<td>0x0025</td>
+<td>KEY_K</td>
+<td>1.6</td>
+<td>0x0027</td>
+<td>KEYCODE_K</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x000f</td>
+<td>Keyboard l and L</td>
+<td>0x0026</td>
+<td>KEY_L</td>
+<td>1.6</td>
+<td>0x0028</td>
+<td>KEYCODE_L</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0010</td>
+<td>Keyboard m and M</td>
+<td>0x0032</td>
+<td>KEY_M</td>
+<td>1.6</td>
+<td>0x0029</td>
+<td>KEYCODE_M</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0011</td>
+<td>Keyboard n and N</td>
+<td>0x0031</td>
+<td>KEY_N</td>
+<td>1.6</td>
+<td>0x002a</td>
+<td>KEYCODE_N</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0012</td>
+<td>Keyboard o and O</td>
+<td>0x0018</td>
+<td>KEY_O</td>
+<td>1.6</td>
+<td>0x002b</td>
+<td>KEYCODE_O</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0013</td>
+<td>Keyboard p and P</td>
+<td>0x0019</td>
+<td>KEY_P</td>
+<td>1.6</td>
+<td>0x002c</td>
+<td>KEYCODE_P</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0014</td>
+<td>Keyboard q and Q</td>
+<td>0x0010</td>
+<td>KEY_Q</td>
+<td>1.6</td>
+<td>0x002d</td>
+<td>KEYCODE_Q</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0015</td>
+<td>Keyboard r and R</td>
+<td>0x0013</td>
+<td>KEY_R</td>
+<td>1.6</td>
+<td>0x002e</td>
+<td>KEYCODE_R</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0016</td>
+<td>Keyboard s and S</td>
+<td>0x001f</td>
+<td>KEY_S</td>
+<td>1.6</td>
+<td>0x002f</td>
+<td>KEYCODE_S</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0017</td>
+<td>Keyboard t and T</td>
+<td>0x0014</td>
+<td>KEY_T</td>
+<td>1.6</td>
+<td>0x0030</td>
+<td>KEYCODE_T</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0018</td>
+<td>Keyboard u and U</td>
+<td>0x0016</td>
+<td>KEY_U</td>
+<td>1.6</td>
+<td>0x0031</td>
+<td>KEYCODE_U</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0019</td>
+<td>Keyboard v and V</td>
+<td>0x002f</td>
+<td>KEY_V</td>
+<td>1.6</td>
+<td>0x0032</td>
+<td>KEYCODE_V</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x001a</td>
+<td>Keyboard w and W</td>
+<td>0x0011</td>
+<td>KEY_W</td>
+<td>1.6</td>
+<td>0x0033</td>
+<td>KEYCODE_W</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x001b</td>
+<td>Keyboard x and X</td>
+<td>0x002d</td>
+<td>KEY_X</td>
+<td>1.6</td>
+<td>0x0034</td>
+<td>KEYCODE_X</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x001c</td>
+<td>Keyboard y and Y</td>
+<td>0x0015</td>
+<td>KEY_Y</td>
+<td>1.6</td>
+<td>0x0035</td>
+<td>KEYCODE_Y</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x001d</td>
+<td>Keyboard z and Z</td>
+<td>0x002c</td>
+<td>KEY_Z</td>
+<td>1.6</td>
+<td>0x0036</td>
+<td>KEYCODE_Z</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x001e</td>
+<td>Keyboard 1 and !</td>
+<td>0x0002</td>
+<td>KEY_1</td>
+<td>1.6</td>
+<td>0x0008</td>
+<td>KEYCODE_1</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x001f</td>
+<td>Keyboard 2 and @</td>
+<td>0x0003</td>
+<td>KEY_2</td>
+<td>1.6</td>
+<td>0x0009</td>
+<td>KEYCODE_2</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0020</td>
+<td>Keyboard 3 and #</td>
+<td>0x0004</td>
+<td>KEY_3</td>
+<td>1.6</td>
+<td>0x000a</td>
+<td>KEYCODE_3</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0021</td>
+<td>Keyboard 4 and $</td>
+<td>0x0005</td>
+<td>KEY_4</td>
+<td>1.6</td>
+<td>0x000b</td>
+<td>KEYCODE_4</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0022</td>
+<td>Keyboard 5 and %</td>
+<td>0x0006</td>
+<td>KEY_5</td>
+<td>1.6</td>
+<td>0x000c</td>
+<td>KEYCODE_5</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0023</td>
+<td>Keyboard 6 and ^</td>
+<td>0x0007</td>
+<td>KEY_6</td>
+<td>1.6</td>
+<td>0x000d</td>
+<td>KEYCODE_6</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0024</td>
+<td>Keyboard 7 and &amp;</td>
+<td>0x0008</td>
+<td>KEY_7</td>
+<td>1.6</td>
+<td>0x000e</td>
+<td>KEYCODE_7</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0025</td>
+<td>Keyboard 8 and *</td>
+<td>0x0009</td>
+<td>KEY_8</td>
+<td>1.6</td>
+<td>0x000f</td>
+<td>KEYCODE_8</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0026</td>
+<td>Keyboard 9 and (</td>
+<td>0x000a</td>
+<td>KEY_9</td>
+<td>1.6</td>
+<td>0x0010</td>
+<td>KEYCODE_9</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0027</td>
+<td>Keyboard 0 and )</td>
+<td>0x000b</td>
+<td>KEY_0</td>
+<td>1.6</td>
+<td>0x0007</td>
+<td>KEYCODE_0</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0028</td>
+<td>Keyboard Return (ENTER)</td>
+<td>0x001c</td>
+<td>KEY_ENTER</td>
+<td>1.6</td>
+<td>0x0042</td>
+<td>KEYCODE_ENTER</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0029</td>
+<td>Keyboard ESCAPE</td>
+<td>0x0001</td>
+<td>KEY_ESC</td>
+<td>3.0</td>
+<td>0x006f</td>
+<td>KEYCODE_ESCAPE</td>
+<td></td>
+</tr>
+<tr>
+<td>""</td>
+<td>""</td>
+<td>""</td>
+<td>""</td>
+<td>2.3</td>
+<td>0x0004</td>
+<td>KEYCODE_BACK</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x002a</td>
+<td>Keyboard DELETE (Backspace)</td>
+<td>0x000e</td>
+<td>KEY_BACKSPACE</td>
+<td>1.6</td>
+<td>0x0043</td>
+<td>KEYCODE_DEL</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x002b</td>
+<td>Keyboard Tab</td>
+<td>0x000f</td>
+<td>KEY_TAB</td>
+<td>1.6</td>
+<td>0x003d</td>
+<td>KEYCODE_TAB</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x002c</td>
+<td>Keyboard Spacebar</td>
+<td>0x0039</td>
+<td>KEY_SPACE</td>
+<td>1.6</td>
+<td>0x003e</td>
+<td>KEYCODE_SPACE</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x002d</td>
+<td>Keyboard - and _</td>
+<td>0x000c</td>
+<td>KEY_MINUS</td>
+<td>1.6</td>
+<td>0x0045</td>
+<td>KEYCODE_MINUS</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x002e</td>
+<td>Keyboard = and +</td>
+<td>0x000d</td>
+<td>KEY_EQUAL</td>
+<td>1.6</td>
+<td>0x0046</td>
+<td>KEYCODE_EQUALS</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x002f</td>
+<td>Keyboard [ and {</td>
+<td>0x001a</td>
+<td>KEY_LEFTBRACE</td>
+<td>1.6</td>
+<td>0x0047</td>
+<td>KEYCODE_LEFT_BRACKET</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0030</td>
+<td>Keyboard ] and }</td>
+<td>0x001b</td>
+<td>KEY_RIGHTBRACE</td>
+<td>1.6</td>
+<td>0x0048</td>
+<td>KEYCODE_RIGHT_BRACKET</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0031</td>
+<td>Keyboard \ and &#124;</td>
+<td>0x002b</td>
+<td>KEY_BACKSLASH</td>
+<td>1.6</td>
+<td>0x0049</td>
+<td>KEYCODE_BACKSLASH</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0032</td>
+<td>Keyboard Non-US # and ~</td>
+<td>0x002b</td>
+<td>KEY_BACKSLASH</td>
+<td>1.6</td>
+<td>0x0049</td>
+<td>KEYCODE_BACKSLASH</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0033</td>
+<td>Keyboard ; and :</td>
+<td>0x0027</td>
+<td>KEY_SEMICOLON</td>
+<td>1.6</td>
+<td>0x004a</td>
+<td>KEYCODE_SEMICOLON</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0034</td>
+<td>Keyboard ' and "</td>
+<td>0x0028</td>
+<td>KEY_APOSTROPHE</td>
+<td>1.6</td>
+<td>0x004b</td>
+<td>KEYCODE_APOSTROPHE</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0035</td>
+<td>Keyboard ` and ~</td>
+<td>0x0029</td>
+<td>KEY_GRAVE</td>
+<td>3.0</td>
+<td>0x0044</td>
+<td>KEYCODE_GRAVE</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0036</td>
+<td>Keyboard , and &lt;</td>
+<td>0x0033</td>
+<td>KEY_COMMA</td>
+<td>1.6</td>
+<td>0x0037</td>
+<td>KEYCODE_COMMA</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0037</td>
+<td>Keyboard . and &gt;</td>
+<td>0x0034</td>
+<td>KEY_DOT</td>
+<td>1.6</td>
+<td>0x0038</td>
+<td>KEYCODE_PERIOD</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0038</td>
+<td>Keyboard / and ?</td>
+<td>0x0035</td>
+<td>KEY_SLASH</td>
+<td>1.6</td>
+<td>0x004c</td>
+<td>KEYCODE_SLASH</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0039</td>
+<td>Keyboard Caps Lock</td>
+<td>0x003a</td>
+<td>KEY_CAPSLOCK</td>
+<td>3.0</td>
+<td>0x0073</td>
+<td>KEYCODE_CAPS_LOCK</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x003a</td>
+<td>Keyboard F1</td>
+<td>0x003b</td>
+<td>KEY_F1</td>
+<td>3.0</td>
+<td>0x0083</td>
+<td>KEYCODE_F1</td>
+<td></td>
+</tr>
+<tr>
+<td>""</td>
+<td>""</td>
+<td>""</td>
+<td>""</td>
+<td>1.6</td>
+<td>0x0052</td>
+<td>KEYCODE_MENU</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x003b</td>
+<td>Keyboard F2</td>
+<td>0x003c</td>
+<td>KEY_F2</td>
+<td>3.0</td>
+<td>0x0084</td>
+<td>KEYCODE_F2</td>
+<td></td>
+</tr>
+<tr>
+<td>""</td>
+<td>""</td>
+<td>""</td>
+<td>""</td>
+<td>1.6</td>
+<td>0x0002</td>
+<td>KEYCODE_SOFT_RIGHT</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x003c</td>
+<td>Keyboard F3</td>
+<td>0x003d</td>
+<td>KEY_F3</td>
+<td>3.0</td>
+<td>0x0085</td>
+<td>KEYCODE_F3</td>
+<td></td>
+</tr>
+<tr>
+<td>""</td>
+<td>""</td>
+<td>""</td>
+<td>""</td>
+<td>1.6</td>
+<td>0x0005</td>
+<td>KEYCODE_CALL</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x003d</td>
+<td>Keyboard F4</td>
+<td>0x003e</td>
+<td>KEY_F4</td>
+<td>3.0</td>
+<td>0x0086</td>
+<td>KEYCODE_F4</td>
+<td></td>
+</tr>
+<tr>
+<td>""</td>
+<td>""</td>
+<td>""</td>
+<td>""</td>
+<td>1.6</td>
+<td>0x0006</td>
+<td>KEYCODE_ENDCALL</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x003e</td>
+<td>Keyboard F5</td>
+<td>0x003f</td>
+<td>KEY_F5</td>
+<td>3.0</td>
+<td>0x0087</td>
+<td>KEYCODE_F5</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x003f</td>
+<td>Keyboard F6</td>
+<td>0x0040</td>
+<td>KEY_F6</td>
+<td>3.0</td>
+<td>0x0088</td>
+<td>KEYCODE_F6</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0040</td>
+<td>Keyboard F7</td>
+<td>0x0041</td>
+<td>KEY_F7</td>
+<td>3.0</td>
+<td>0x0089</td>
+<td>KEYCODE_F7</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0041</td>
+<td>Keyboard F8</td>
+<td>0x0042</td>
+<td>KEY_F8</td>
+<td>3.0</td>
+<td>0x008a</td>
+<td>KEYCODE_F8</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0042</td>
+<td>Keyboard F9</td>
+<td>0x0043</td>
+<td>KEY_F9</td>
+<td>3.0</td>
+<td>0x008b</td>
+<td>KEYCODE_F9</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0043</td>
+<td>Keyboard F10</td>
+<td>0x0044</td>
+<td>KEY_F10</td>
+<td>3.0</td>
+<td>0x008c</td>
+<td>KEYCODE_F10</td>
+<td></td>
+</tr>
+<tr>
+<td>""</td>
+<td>""</td>
+<td>""</td>
+<td>""</td>
+<td>2.3</td>
+<td>0x0052</td>
+<td>KEYCODE_MENU</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0044</td>
+<td>Keyboard F11</td>
+<td>0x0057</td>
+<td>KEY_F11</td>
+<td>3.0</td>
+<td>0x008d</td>
+<td>KEYCODE_F11</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0045</td>
+<td>Keyboard F12</td>
+<td>0x0058</td>
+<td>KEY_F12</td>
+<td>3.0</td>
+<td>0x008e</td>
+<td>KEYCODE_F12</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0046</td>
+<td>Keyboard Print Screen</td>
+<td>0x0063</td>
+<td>KEY_SYSRQ</td>
+<td>3.0</td>
+<td>0x0078</td>
+<td>KEYCODE_SYSRQ</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0047</td>
+<td>Keyboard Scroll Lock</td>
+<td>0x0046</td>
+<td>KEY_SCROLLLOCK</td>
+<td>3.0</td>
+<td>0x0074</td>
+<td>KEYCODE_SCROLL_LOCK</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0048</td>
+<td>Keyboard Pause</td>
+<td>0x0077</td>
+<td>KEY_PAUSE</td>
+<td>3.0</td>
+<td>0x0079</td>
+<td>KEYCODE_BREAK</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0049</td>
+<td>Keyboard Insert</td>
+<td>0x006e</td>
+<td>KEY_INSERT</td>
+<td>3.0</td>
+<td>0x007c</td>
+<td>KEYCODE_INSERT</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x004a</td>
+<td>Keyboard Home</td>
+<td>0x0066</td>
+<td>KEY_HOME</td>
+<td>3.0</td>
+<td>0x007a</td>
+<td>KEYCODE_MOVE_HOME</td>
+<td></td>
+</tr>
+<tr>
+<td>""</td>
+<td>""</td>
+<td>""</td>
+<td>""</td>
+<td>1.6</td>
+<td>0x0003</td>
+<td>KEYCODE_HOME</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x004b</td>
+<td>Keyboard Page Up</td>
+<td>0x0068</td>
+<td>KEY_PAGEUP</td>
+<td>3.0</td>
+<td>0x005c</td>
+<td>KEYCODE_PAGE_UP</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x004c</td>
+<td>Keyboard Delete Forward</td>
+<td>0x006f</td>
+<td>KEY_DELETE</td>
+<td>3.0</td>
+<td>0x0070</td>
+<td>KEYCODE_FORWARD_DEL</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x004d</td>
+<td>Keyboard End</td>
+<td>0x006b</td>
+<td>KEY_END</td>
+<td>3.0</td>
+<td>0x007b</td>
+<td>KEYCODE_MOVE_END</td>
+<td></td>
+</tr>
+<tr>
+<td>""</td>
+<td>""</td>
+<td>""</td>
+<td>""</td>
+<td>1.6</td>
+<td>0x0006</td>
+<td>KEYCODE_ENDCALL</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x004e</td>
+<td>Keyboard Page Down</td>
+<td>0x006d</td>
+<td>KEY_PAGEDOWN</td>
+<td>3.0</td>
+<td>0x005d</td>
+<td>KEYCODE_PAGE_DOWN</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x004f</td>
+<td>Keyboard Right Arrow</td>
+<td>0x006a</td>
+<td>KEY_RIGHT</td>
+<td>1.6</td>
+<td>0x0016</td>
+<td>KEYCODE_DPAD_RIGHT</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0050</td>
+<td>Keyboard Left Arrow</td>
+<td>0x0069</td>
+<td>KEY_LEFT</td>
+<td>1.6</td>
+<td>0x0015</td>
+<td>KEYCODE_DPAD_LEFT</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0051</td>
+<td>Keyboard Down Arrow</td>
+<td>0x006c</td>
+<td>KEY_DOWN</td>
+<td>1.6</td>
+<td>0x0014</td>
+<td>KEYCODE_DPAD_DOWN</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0052</td>
+<td>Keyboard Up Arrow</td>
+<td>0x0067</td>
+<td>KEY_UP</td>
+<td>1.6</td>
+<td>0x0013</td>
+<td>KEYCODE_DPAD_UP</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0053</td>
+<td>Keyboard Num Lock and Clear</td>
+<td>0x0045</td>
+<td>KEY_NUMLOCK</td>
+<td>3.0</td>
+<td>0x008f</td>
+<td>KEYCODE_NUM_LOCK</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0054</td>
+<td>Keypad /</td>
+<td>0x0062</td>
+<td>KEY_KPSLASH</td>
+<td>3.0</td>
+<td>0x009a</td>
+<td>KEYCODE_NUMPAD_DIVIDE</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0055</td>
+<td>Keypad *</td>
+<td>0x0037</td>
+<td>KEY_KPASTERISK</td>
+<td>3.0</td>
+<td>0x009b</td>
+<td>KEYCODE_NUMPAD_MULTIPLY</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0056</td>
+<td>Keypad -</td>
+<td>0x004a</td>
+<td>KEY_KPMINUS</td>
+<td>3.0</td>
+<td>0x009c</td>
+<td>KEYCODE_NUMPAD_SUBTRACT</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0057</td>
+<td>Keypad +</td>
+<td>0x004e</td>
+<td>KEY_KPPLUS</td>
+<td>3.0</td>
+<td>0x009d</td>
+<td>KEYCODE_NUMPAD_ADD</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0058</td>
+<td>Keypad ENTER</td>
+<td>0x0060</td>
+<td>KEY_KPENTER</td>
+<td>3.0</td>
+<td>0x00a0</td>
+<td>KEYCODE_NUMPAD_ENTER</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0059</td>
+<td>Keypad 1 and End</td>
+<td>0x004f</td>
+<td>KEY_KP1</td>
+<td>3.0</td>
+<td>0x0091</td>
+<td>KEYCODE_NUMPAD_1</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x005a</td>
+<td>Keypad 2 and Down Arrow</td>
+<td>0x0050</td>
+<td>KEY_KP2</td>
+<td>3.0</td>
+<td>0x0092</td>
+<td>KEYCODE_NUMPAD_2</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x005b</td>
+<td>Keypad 3 and PageDn</td>
+<td>0x0051</td>
+<td>KEY_KP3</td>
+<td>3.0</td>
+<td>0x0093</td>
+<td>KEYCODE_NUMPAD_3</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x005c</td>
+<td>Keypad 4 and Left Arrow</td>
+<td>0x004b</td>
+<td>KEY_KP4</td>
+<td>3.0</td>
+<td>0x0094</td>
+<td>KEYCODE_NUMPAD_4</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x005d</td>
+<td>Keypad 5</td>
+<td>0x004c</td>
+<td>KEY_KP5</td>
+<td>3.0</td>
+<td>0x0095</td>
+<td>KEYCODE_NUMPAD_5</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x005e</td>
+<td>Keypad 6 and Right Arrow</td>
+<td>0x004d</td>
+<td>KEY_KP6</td>
+<td>3.0</td>
+<td>0x0096</td>
+<td>KEYCODE_NUMPAD_6</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x005f</td>
+<td>Keypad 7 and Home</td>
+<td>0x0047</td>
+<td>KEY_KP7</td>
+<td>3.0</td>
+<td>0x0097</td>
+<td>KEYCODE_NUMPAD_7</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0060</td>
+<td>Keypad 8 and Up Arrow</td>
+<td>0x0048</td>
+<td>KEY_KP8</td>
+<td>3.0</td>
+<td>0x0098</td>
+<td>KEYCODE_NUMPAD_8</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0061</td>
+<td>Keypad 9 and Page Up</td>
+<td>0x0049</td>
+<td>KEY_KP9</td>
+<td>3.0</td>
+<td>0x0099</td>
+<td>KEYCODE_NUMPAD_9</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0062</td>
+<td>Keypad 0 and Insert</td>
+<td>0x0052</td>
+<td>KEY_KP0</td>
+<td>3.0</td>
+<td>0x0090</td>
+<td>KEYCODE_NUMPAD_0</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0063</td>
+<td>Keypad . and Delete</td>
+<td>0x0053</td>
+<td>KEY_KPDOT</td>
+<td>3.0</td>
+<td>0x009e</td>
+<td>KEYCODE_NUMPAD_DOT</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0064</td>
+<td>Keyboard Non-US \ and &#124;</td>
+<td>0x0056</td>
+<td>KEY_102ND</td>
+<td>4.0</td>
+<td>0x0049</td>
+<td>KEYCODE_BACKSLASH</td>
+<td>1</td>
+</tr>
+<tr>
+<td>0x07 0x0065</td>
+<td>Keyboard Application</td>
+<td>0x007f</td>
+<td>KEY_COMPOSE</td>
+<td>3.0</td>
+<td>0x0052</td>
+<td>KEYCODE_MENU</td>
+<td></td>
+</tr>
+<tr>
+<td>""</td>
+<td>""</td>
+<td>""</td>
+<td>""</td>
+<td>1.6</td>
+<td>0x0054</td>
+<td>KEYCODE_SEARCH</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0066</td>
+<td>Keyboard Power</td>
+<td>0x0074</td>
+<td>KEY_POWER</td>
+<td>1.6</td>
+<td>0x001a</td>
+<td>KEYCODE_POWER</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0067</td>
+<td>Keypad =</td>
+<td>0x0075</td>
+<td>KEY_KPEQUAL</td>
+<td>3.0</td>
+<td>0x00a1</td>
+<td>KEYCODE_NUMPAD_EQUALS</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0068</td>
+<td>Keyboard F13</td>
+<td>0x00b7</td>
+<td>KEY_F13</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0069</td>
+<td>Keyboard F14</td>
+<td>0x00b8</td>
+<td>KEY_F14</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x006a</td>
+<td>Keyboard F15</td>
+<td>0x00b9</td>
+<td>KEY_F15</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x006b</td>
+<td>Keyboard F16</td>
+<td>0x00ba</td>
+<td>KEY_F16</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x006c</td>
+<td>Keyboard F17</td>
+<td>0x00bb</td>
+<td>KEY_F17</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x006d</td>
+<td>Keyboard F18</td>
+<td>0x00bc</td>
+<td>KEY_F18</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x006e</td>
+<td>Keyboard F19</td>
+<td>0x00bd</td>
+<td>KEY_F19</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x006f</td>
+<td>Keyboard F20</td>
+<td>0x00be</td>
+<td>KEY_F20</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0070</td>
+<td>Keyboard F21</td>
+<td>0x00bf</td>
+<td>KEY_F21</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0071</td>
+<td>Keyboard F22</td>
+<td>0x00c0</td>
+<td>KEY_F22</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0072</td>
+<td>Keyboard F23</td>
+<td>0x00c1</td>
+<td>KEY_F23</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0073</td>
+<td>Keyboard F24</td>
+<td>0x00c2</td>
+<td>KEY_F24</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0074</td>
+<td>Keyboard Execute</td>
+<td>0x0086</td>
+<td>KEY_OPEN</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0075</td>
+<td>Keyboard Help</td>
+<td>0x008a</td>
+<td>KEY_HELP</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0076</td>
+<td>Keyboard Menu</td>
+<td>0x0082</td>
+<td>KEY_PROPS</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0077</td>
+<td>Keyboard Select</td>
+<td>0x0084</td>
+<td>KEY_FRONT</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0078</td>
+<td>Keyboard Stop</td>
+<td>0x0080</td>
+<td>KEY_STOP</td>
+<td>3.0</td>
+<td>0x0056</td>
+<td>KEYCODE_MEDIA_STOP</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0079</td>
+<td>Keyboard Again</td>
+<td>0x0081</td>
+<td>KEY_AGAIN</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x007a</td>
+<td>Keyboard Undo</td>
+<td>0x0083</td>
+<td>KEY_UNDO</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x007b</td>
+<td>Keyboard Cut</td>
+<td>0x0089</td>
+<td>KEY_CUT</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x007c</td>
+<td>Keyboard Copy</td>
+<td>0x0085</td>
+<td>KEY_COPY</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x007d</td>
+<td>Keyboard Paste</td>
+<td>0x0087</td>
+<td>KEY_PASTE</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x007e</td>
+<td>Keyboard Find</td>
+<td>0x0088</td>
+<td>KEY_FIND</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x007f</td>
+<td>Keyboard Mute</td>
+<td>0x0071</td>
+<td>KEY_MUTE</td>
+<td>3.0</td>
+<td>0x00a4</td>
+<td>KEYCODE_VOLUME_MUTE</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0080</td>
+<td>Keyboard Volume Up</td>
+<td>0x0073</td>
+<td>KEY_VOLUMEUP</td>
+<td>1.6</td>
+<td>0x0018</td>
+<td>KEYCODE_VOLUME_UP</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0081</td>
+<td>Keyboard Volume Down</td>
+<td>0x0072</td>
+<td>KEY_VOLUMEDOWN</td>
+<td>1.6</td>
+<td>0x0019</td>
+<td>KEYCODE_VOLUME_DOWN</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0082</td>
+<td>Keyboard Locking Caps Lock</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0083</td>
+<td>Keyboard Locking Num Lock</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0084</td>
+<td>Keyboard Locking Scroll Lock</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0085</td>
+<td>Keypad Comma</td>
+<td>0x0079</td>
+<td>KEY_KPCOMMA</td>
+<td>3.0</td>
+<td>0x009f</td>
+<td>KEYCODE_NUMPAD_COMMA</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0086</td>
+<td>Keypad Equal Sign</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0087</td>
+<td>Keyboard International1</td>
+<td>0x0059</td>
+<td>KEY_RO</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0088</td>
+<td>Keyboard International2</td>
+<td>0x005d</td>
+<td>KEY_KATAKANAHIRAGANA</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0089</td>
+<td>Keyboard International3</td>
+<td>0x007c</td>
+<td>KEY_YEN</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x008a</td>
+<td>Keyboard International4</td>
+<td>0x005c</td>
+<td>KEY_HENKAN</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x008b</td>
+<td>Keyboard International5</td>
+<td>0x005e</td>
+<td>KEY_MUHENKAN</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x008c</td>
+<td>Keyboard International6</td>
+<td>0x005f</td>
+<td>KEY_KPJPCOMMA</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x008d</td>
+<td>Keyboard International7</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x008e</td>
+<td>Keyboard International8</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x008f</td>
+<td>Keyboard International9</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0090</td>
+<td>Keyboard LANG1</td>
+<td>0x007a</td>
+<td>KEY_HANGEUL</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0091</td>
+<td>Keyboard LANG2</td>
+<td>0x007b</td>
+<td>KEY_HANJA</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0092</td>
+<td>Keyboard LANG3</td>
+<td>0x005a</td>
+<td>KEY_KATAKANA</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0093</td>
+<td>Keyboard LANG4</td>
+<td>0x005b</td>
+<td>KEY_HIRAGANA</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0094</td>
+<td>Keyboard LANG5</td>
+<td>0x0055</td>
+<td>KEY_ZENKAKUHANKAKU</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0095</td>
+<td>Keyboard LANG6</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0096</td>
+<td>Keyboard LANG7</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0097</td>
+<td>Keyboard LANG8</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0098</td>
+<td>Keyboard LANG9</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x0099</td>
+<td>Keyboard Alternate Erase</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x009a</td>
+<td>Keyboard SysReq/Attention</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x009b</td>
+<td>Keyboard Cancel</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x009c</td>
+<td>Keyboard Clear</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x009d</td>
+<td>Keyboard Prior</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x009e</td>
+<td>Keyboard Return</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x009f</td>
+<td>Keyboard Separator</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00a0</td>
+<td>Keyboard Out</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00a1</td>
+<td>Keyboard Oper</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00a2</td>
+<td>Keyboard Clear/Again</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00a3</td>
+<td>Keyboard CrSel/Props</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00a4</td>
+<td>Keyboard ExSel</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00b0</td>
+<td>Keypad 00</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00b1</td>
+<td>Keypad 000</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00b2</td>
+<td>Thousands Separator</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00b3</td>
+<td>Decimal Separator</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00b4</td>
+<td>Currency Unit</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00b5</td>
+<td>Currency Sub-unit</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00b6</td>
+<td>Keypad (</td>
+<td>0x00b3</td>
+<td>KEY_KPLEFTPAREN</td>
+<td>3.0</td>
+<td>0x00a2</td>
+<td>KEYCODE_NUMPAD_LEFT_PAREN</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00b7</td>
+<td>Keypad )</td>
+<td>0x00b4</td>
+<td>KEY_KPRIGHTPAREN</td>
+<td>3.0</td>
+<td>0x00a3</td>
+<td>KEYCODE_NUMPAD_RIGHT_PAREN</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00b8</td>
+<td>Keypad {</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00b9</td>
+<td>Keypad }</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00ba</td>
+<td>Keypad Tab</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00bb</td>
+<td>Keypad Backspace</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00bc</td>
+<td>Keypad A</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00bd</td>
+<td>Keypad B</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00be</td>
+<td>Keypad C</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00bf</td>
+<td>Keypad D</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00c0</td>
+<td>Keypad E</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00c1</td>
+<td>Keypad F</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00c2</td>
+<td>Keypad XOR</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00c3</td>
+<td>Keypad ^</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00c4</td>
+<td>Keypad %</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00c5</td>
+<td>Keypad &lt;</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00c6</td>
+<td>Keypad &gt;</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00c7</td>
+<td>Keypad &amp;</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00c8</td>
+<td>Keypad &amp;&amp;</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00c9</td>
+<td>Keypad &#124;</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00ca</td>
+<td>Keypad &#124;&#124;</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00cb</td>
+<td>Keypad :</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00cc</td>
+<td>Keypad #</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00cd</td>
+<td>Keypad Space</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00ce</td>
+<td>Keypad @</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00cf</td>
+<td>Keypad !</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00d0</td>
+<td>Keypad Memory Store</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00d1</td>
+<td>Keypad Memory Recall</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00d2</td>
+<td>Keypad Memory Clear</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00d3</td>
+<td>Keypad Memory Add</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00d4</td>
+<td>Keypad Memory Subtract</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00d5</td>
+<td>Keypad Memory Multiply</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00d6</td>
+<td>Keypad Memory Divide</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00d7</td>
+<td>Keypad +/-</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00d8</td>
+<td>Keypad Clear</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00d9</td>
+<td>Keypad Clear Entry</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00da</td>
+<td>Keypad Binary</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00db</td>
+<td>Keypad Octal</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00dc</td>
+<td>Keypad Decimal</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00dd</td>
+<td>Keypad Hexadecimal</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00e0</td>
+<td>Keyboard Left Control</td>
+<td>0x001d</td>
+<td>KEY_LEFTCTRL</td>
+<td>3.0</td>
+<td>0x0071</td>
+<td>KEYCODE_CTRL_LEFT</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00e1</td>
+<td>Keyboard Left Shift</td>
+<td>0x002a</td>
+<td>KEY_LEFTSHIFT</td>
+<td>1.6</td>
+<td>0x003b</td>
+<td>KEYCODE_SHIFT_LEFT</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00e2</td>
+<td>Keyboard Left Alt</td>
+<td>0x0038</td>
+<td>KEY_LEFTALT</td>
+<td>1.6</td>
+<td>0x0039</td>
+<td>KEYCODE_ALT_LEFT</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00e3</td>
+<td>Keyboard Left GUI</td>
+<td>0x007d</td>
+<td>KEY_LEFTMETA</td>
+<td>3.0</td>
+<td>0x0075</td>
+<td>KEYCODE_META_LEFT</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00e4</td>
+<td>Keyboard Right Control</td>
+<td>0x0061</td>
+<td>KEY_RIGHTCTRL</td>
+<td>3.0</td>
+<td>0x0072</td>
+<td>KEYCODE_CTRL_RIGHT</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00e5</td>
+<td>Keyboard Right Shift</td>
+<td>0x0036</td>
+<td>KEY_RIGHTSHIFT</td>
+<td>1.6</td>
+<td>0x003c</td>
+<td>KEYCODE_SHIFT_RIGHT</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00e6</td>
+<td>Keyboard Right Alt</td>
+<td>0x0064</td>
+<td>KEY_RIGHTALT</td>
+<td>1.6</td>
+<td>0x003a</td>
+<td>KEYCODE_ALT_RIGHT</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00e7</td>
+<td>Keyboard Right GUI</td>
+<td>0x007e</td>
+<td>KEY_RIGHTMETA</td>
+<td>3.0</td>
+<td>0x0076</td>
+<td>KEYCODE_META_RIGHT</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00e8</td>
+<td></td>
+<td>0x00a4</td>
+<td>KEY_PLAYPAUSE</td>
+<td>3.0</td>
+<td>0x0055</td>
+<td>KEYCODE_MEDIA_PLAY_PAUSE</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00e9</td>
+<td></td>
+<td>0x00a6</td>
+<td>KEY_STOPCD</td>
+<td>3.0</td>
+<td>0x0056</td>
+<td>KEYCODE_MEDIA_STOP</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00ea</td>
+<td></td>
+<td>0x00a5</td>
+<td>KEY_PREVIOUSSONG</td>
+<td>3.0</td>
+<td>0x0058</td>
+<td>KEYCODE_MEDIA_PREVIOUS</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00eb</td>
+<td></td>
+<td>0x00a3</td>
+<td>KEY_NEXTSONG</td>
+<td>3.0</td>
+<td>0x0057</td>
+<td>KEYCODE_MEDIA_NEXT</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00ec</td>
+<td></td>
+<td>0x00a1</td>
+<td>KEY_EJECTCD</td>
+<td>3.0</td>
+<td>0x0081</td>
+<td>KEYCODE_MEDIA_EJECT</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00ed</td>
+<td></td>
+<td>0x0073</td>
+<td>KEY_VOLUMEUP</td>
+<td>1.6</td>
+<td>0x0018</td>
+<td>KEYCODE_VOLUME_UP</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00ee</td>
+<td></td>
+<td>0x0072</td>
+<td>KEY_VOLUMEDOWN</td>
+<td>1.6</td>
+<td>0x0019</td>
+<td>KEYCODE_VOLUME_DOWN</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00ef</td>
+<td></td>
+<td>0x0071</td>
+<td>KEY_MUTE</td>
+<td>3.0</td>
+<td>0x00a4</td>
+<td>KEYCODE_VOLUME_MUTE</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00f0</td>
+<td></td>
+<td>0x0096</td>
+<td>KEY_WWW</td>
+<td>1.6</td>
+<td>0x0040</td>
+<td>KEYCODE_EXPLORER</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00f1</td>
+<td></td>
+<td>0x009e</td>
+<td>KEY_BACK</td>
+<td>1.6</td>
+<td>0x0004</td>
+<td>KEYCODE_BACK</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00f2</td>
+<td></td>
+<td>0x009f</td>
+<td>KEY_FORWARD</td>
+<td>3.0</td>
+<td>0x007d</td>
+<td>KEYCODE_FORWARD</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00f3</td>
+<td></td>
+<td>0x0080</td>
+<td>KEY_STOP</td>
+<td>3.0</td>
+<td>0x0056</td>
+<td>KEYCODE_MEDIA_STOP</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00f4</td>
+<td></td>
+<td>0x0088</td>
+<td>KEY_FIND</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00f5</td>
+<td></td>
+<td>0x00b1</td>
+<td>KEY_SCROLLUP</td>
+<td>3.0</td>
+<td>0x005c</td>
+<td>KEYCODE_PAGE_UP</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00f6</td>
+<td></td>
+<td>0x00b2</td>
+<td>KEY_SCROLLDOWN</td>
+<td>3.0</td>
+<td>0x005d</td>
+<td>KEYCODE_PAGE_DOWN</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00f7</td>
+<td></td>
+<td>0x00b0</td>
+<td>KEY_EDIT</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00f8</td>
+<td></td>
+<td>0x008e</td>
+<td>KEY_SLEEP</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00f9</td>
+<td></td>
+<td>0x0098</td>
+<td>KEY_COFFEE</td>
+<td>4.0</td>
+<td>0x001a</td>
+<td>KEYCODE_POWER</td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00fa</td>
+<td></td>
+<td>0x00ad</td>
+<td>KEY_REFRESH</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x07 0x00fb</td>
+<td></td>
+<td>0x008c</td>
+<td>KEY_CALC</td>
+<td>4.0.3</td>
+<td>0x00d2</td>
+<td>KEYCODE_CALCULATOR</td>
+<td></td>
+</tr>
+</tbody>
+</table>
+<h3 id="hid-generic-desktop-page-0x01">HID Generic Desktop Page (0x01)</h3>
+<table>
+<thead>
+<tr>
+<th>HID Usage</th>
+<th>HID Usage Name</th>
+<th>LKC</th>
+<th>Linux Key Code Name</th>
+<th>Version</th>
+<th>AKC</th>
+<th>Android Key Code Name</th>
+<th>Notes</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>0x01 0x0081</td>
+<td>System Power Down</td>
+<td>0x0074</td>
+<td>KEY_POWER</td>
+<td>1.6</td>
+<td>0x001a</td>
+<td>KEYCODE_POWER</td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x0082</td>
+<td>System Sleep</td>
+<td>0x008e</td>
+<td>KEY_SLEEP</td>
+<td>4.0</td>
+<td>0x001a</td>
+<td>KEYCODE_POWER</td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x0083</td>
+<td>System Wake Up</td>
+<td>0x008f</td>
+<td>KEY_WAKEUP</td>
+<td>4.0</td>
+<td>0x001a</td>
+<td>KEYCODE_POWER</td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x0084</td>
+<td>System Context Menu</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x0085</td>
+<td>System Main Menu</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x0086</td>
+<td>System App Menu</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x0087</td>
+<td>System Menu Help</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x0088</td>
+<td>System Menu Exit</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x0089</td>
+<td>System Menu Select</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x008a</td>
+<td>System Menu Right</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x008b</td>
+<td>System Menu Left</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x008c</td>
+<td>System Menu Up</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x008d</td>
+<td>System Menu Down</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x008e</td>
+<td>System Cold Restart</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x008f</td>
+<td>System Warm Restart</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x00a0</td>
+<td>System Dock</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x00a1</td>
+<td>System Undock</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x00a2</td>
+<td>System Setup</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x00a3</td>
+<td>System Break</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x00a4</td>
+<td>System Debugger Break</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x00a5</td>
+<td>Application Break</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x00a6</td>
+<td>Application Debugger Break</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x00a7</td>
+<td>System Speaker Mute</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x00a8</td>
+<td>System Hibernate</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x00b0</td>
+<td>System Display Invert</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x00b1</td>
+<td>System Display Internal</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x00b2</td>
+<td>System Display External</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x00b3</td>
+<td>System Display Both</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x00b4</td>
+<td>System Display Dual</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x00b5</td>
+<td>System Display Toggle Int/Ext</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x00b6</td>
+<td>System Display Swap Prim./Sec.</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x01 0x00b7</td>
+<td>System Display LCD Autoscale</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+</tbody>
+</table>
+<h3 id="hid-consumer-page-0x0c">HID Consumer Page (0x0c)</h3>
+<table>
+<thead>
+<tr>
+<th>HID Usage</th>
+<th>HID Usage Name</th>
+<th>LKC</th>
+<th>Linux Key Code Name</th>
+<th>Version</th>
+<th>AKC</th>
+<th>Android Key Code Name</th>
+<th>Notes</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>0x0c 0x0030</td>
+<td>Power</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0031</td>
+<td>Reset</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0032</td>
+<td>Sleep</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0033</td>
+<td>Sleep After</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0034</td>
+<td>Sleep Mode</td>
+<td>0x008e</td>
+<td>KEY_SLEEP</td>
+<td>4.0</td>
+<td>0x001a</td>
+<td>KEYCODE_POWER</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0040</td>
+<td>Menu</td>
+<td>0x008b</td>
+<td>KEY_MENU</td>
+<td>1.6</td>
+<td>0x0052</td>
+<td>KEYCODE_MENU</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0041</td>
+<td>Menu Pick</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0042</td>
+<td>Menu Up</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0043</td>
+<td>Menu Down</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0044</td>
+<td>Menu Left</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0045</td>
+<td>Menu Right</td>
+<td>0x0181</td>
+<td>KEY_RADIO</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0046</td>
+<td>Menu Escape</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0047</td>
+<td>Menu Value Increase</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0048</td>
+<td>Menu Value Decrease</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0081</td>
+<td>Assign Selection</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0082</td>
+<td>Mode Step</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0083</td>
+<td>Recall Last</td>
+<td>0x0195</td>
+<td>KEY_LAST</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0084</td>
+<td>Enter Channel</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0085</td>
+<td>Order Movie</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0088</td>
+<td>Media Select Computer</td>
+<td>0x0178</td>
+<td>KEY_PC</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0089</td>
+<td>Media Select TV</td>
+<td>0x0179</td>
+<td>KEY_TV</td>
+<td>3.0</td>
+<td>0x00aa</td>
+<td>KEYCODE_TV</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x008a</td>
+<td>Media Select WWW</td>
+<td>0x0096</td>
+<td>KEY_WWW</td>
+<td>1.6</td>
+<td>0x0040</td>
+<td>KEYCODE_EXPLORER</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x008b</td>
+<td>Media Select DVD</td>
+<td>0x0185</td>
+<td>KEY_DVD</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x008c</td>
+<td>Media Select Telephone</td>
+<td>0x00a9</td>
+<td>KEY_PHONE</td>
+<td>3.0</td>
+<td>0x0005</td>
+<td>KEYCODE_CALL</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x008d</td>
+<td>Media Select Program Guide</td>
+<td>0x016a</td>
+<td>KEY_PROGRAM</td>
+<td>3.0</td>
+<td>0x00ac</td>
+<td>KEYCODE_GUIDE</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x008e</td>
+<td>Media Select Video Phone</td>
+<td>0x01a0</td>
+<td>KEY_VIDEOPHONE</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x008f</td>
+<td>Media Select Games</td>
+<td>0x01a1</td>
+<td>KEY_GAMES</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0090</td>
+<td>Media Select Messages</td>
+<td>0x018c</td>
+<td>KEY_MEMO</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0091</td>
+<td>Media Select CD</td>
+<td>0x017f</td>
+<td>KEY_CD</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0092</td>
+<td>Media Select VCR</td>
+<td>0x017b</td>
+<td>KEY_VCR</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0093</td>
+<td>Media Select Tuner</td>
+<td>0x0182</td>
+<td>KEY_TUNER</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0094</td>
+<td>Quit</td>
+<td>0x00ae</td>
+<td>KEY_EXIT</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0095</td>
+<td>Help</td>
+<td>0x008a</td>
+<td>KEY_HELP</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0096</td>
+<td>Media Select Tape</td>
+<td>0x0180</td>
+<td>KEY_TAPE</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0097</td>
+<td>Media Select Cable</td>
+<td>0x017a</td>
+<td>KEY_TV2</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0098</td>
+<td>Media Select Satellite</td>
+<td>0x017d</td>
+<td>KEY_SAT</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0099</td>
+<td>Media Select Security</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x009a</td>
+<td>Media Select Home</td>
+<td>0x016e</td>
+<td>KEY_PVR</td>
+<td>3.0</td>
+<td>0x00ad</td>
+<td>KEYCODE_DVR</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x009c</td>
+<td>Channel Increment</td>
+<td>0x0192</td>
+<td>KEY_CHANNELUP</td>
+<td>3.0</td>
+<td>0x00a6</td>
+<td>KEYCODE_CHANNEL_UP</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x009d</td>
+<td>Channel Decrement</td>
+<td>0x0193</td>
+<td>KEY_CHANNELDOWN</td>
+<td>3.0</td>
+<td>0x00a7</td>
+<td>KEYCODE_CHANNEL_DOWN</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x009e</td>
+<td>Media Select SAP</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00a0</td>
+<td>VCR Plus</td>
+<td>0x017c</td>
+<td>KEY_VCR2</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00a1</td>
+<td>Once</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00a2</td>
+<td>Daily</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00a3</td>
+<td>Weekly</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00a4</td>
+<td>Monthly</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00b0</td>
+<td>Play</td>
+<td>0x00cf</td>
+<td>KEY_PLAY</td>
+<td>3.0</td>
+<td>0x007e</td>
+<td>KEYCODE_MEDIA_PLAY</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00b1</td>
+<td>Pause</td>
+<td>0x0077</td>
+<td>KEY_PAUSE</td>
+<td>3.0</td>
+<td>0x0079</td>
+<td>KEYCODE_BREAK</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00b2</td>
+<td>Record</td>
+<td>0x00a7</td>
+<td>KEY_RECORD</td>
+<td>3.0</td>
+<td>0x0082</td>
+<td>KEYCODE_MEDIA_RECORD</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00b3</td>
+<td>Fast Forward</td>
+<td>0x00d0</td>
+<td>KEY_FASTFORWARD</td>
+<td>3.0</td>
+<td>0x005a</td>
+<td>KEYCODE_MEDIA_FAST_FORWARD</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00b4</td>
+<td>Rewind</td>
+<td>0x00a8</td>
+<td>KEY_REWIND</td>
+<td>3.0</td>
+<td>0x0059</td>
+<td>KEYCODE_MEDIA_REWIND</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00b5</td>
+<td>Scan Next Track</td>
+<td>0x00a3</td>
+<td>KEY_NEXTSONG</td>
+<td>3.0</td>
+<td>0x0057</td>
+<td>KEYCODE_MEDIA_NEXT</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00b6</td>
+<td>Scan Previous Track</td>
+<td>0x00a5</td>
+<td>KEY_PREVIOUSSONG</td>
+<td>3.0</td>
+<td>0x0058</td>
+<td>KEYCODE_MEDIA_PREVIOUS</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00b7</td>
+<td>Stop</td>
+<td>0x00a6</td>
+<td>KEY_STOPCD</td>
+<td>3.0</td>
+<td>0x0056</td>
+<td>KEYCODE_MEDIA_STOP</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00b8</td>
+<td>Eject</td>
+<td>0x00a1</td>
+<td>KEY_EJECTCD</td>
+<td>3.0</td>
+<td>0x0081</td>
+<td>KEYCODE_MEDIA_EJECT</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00b9</td>
+<td>Random Play</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00ba</td>
+<td>Select Disc</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00bb</td>
+<td>Enter Disc</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00bc</td>
+<td>Repeat</td>
+<td>0x01b7</td>
+<td>KEY_MEDIA_REPEAT</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00be</td>
+<td>Track Normal</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00c0</td>
+<td>Frame Forward</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00c1</td>
+<td>Frame Back</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00c2</td>
+<td>Mark</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00c3</td>
+<td>Clear Mark</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00c4</td>
+<td>Repeat From Mark</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00c5</td>
+<td>Return To Mark</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00c6</td>
+<td>Search Mark Forward</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00c7</td>
+<td>Search Mark Backwards</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00c8</td>
+<td>Counter Reset</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00c9</td>
+<td>Show Counter</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00ca</td>
+<td>Tracking Increment</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00cb</td>
+<td>Tracking Decrement</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00cc</td>
+<td>Stop / Eject</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00cd</td>
+<td>Play / Pause</td>
+<td>0x00a4</td>
+<td>KEY_PLAYPAUSE</td>
+<td>3.0</td>
+<td>0x0055</td>
+<td>KEYCODE_MEDIA_PLAY_PAUSE</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00ce</td>
+<td>Play / Skip</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00e2</td>
+<td>Mute</td>
+<td>0x0071</td>
+<td>KEY_MUTE</td>
+<td>3.0</td>
+<td>0x00a4</td>
+<td>KEYCODE_VOLUME_MUTE</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00e5</td>
+<td>Bass Boost</td>
+<td>0x00d1</td>
+<td>KEY_BASSBOOST</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00e6</td>
+<td>Surround Mode</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00e7</td>
+<td>Loudness</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00e8</td>
+<td>MPX</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00e9</td>
+<td>Volume Increment</td>
+<td>0x0073</td>
+<td>KEY_VOLUMEUP</td>
+<td>1.6</td>
+<td>0x0018</td>
+<td>KEYCODE_VOLUME_UP</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x00ea</td>
+<td>Volume Decrement</td>
+<td>0x0072</td>
+<td>KEY_VOLUMEDOWN</td>
+<td>1.6</td>
+<td>0x0019</td>
+<td>KEYCODE_VOLUME_DOWN</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0181</td>
+<td>AL Launch Button Config. Tool</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0182</td>
+<td>AL Programmable Button Config.</td>
+<td>0x009c</td>
+<td>KEY_BOOKMARKS</td>
+<td>3.0</td>
+<td>0x00ae</td>
+<td>KEYCODE_BOOKMARK</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0183</td>
+<td>AL Consumer Control Config.</td>
+<td>0x00ab</td>
+<td>KEY_CONFIG</td>
+<td>4.0.3</td>
+<td>0x00d1</td>
+<td>KEYCODE_MUSIC</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0184</td>
+<td>AL Word Processor</td>
+<td>0x01a5</td>
+<td>KEY_WORDPROCESSOR</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0185</td>
+<td>AL Text Editor</td>
+<td>0x01a6</td>
+<td>KEY_EDITOR</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0186</td>
+<td>AL Spreadsheet</td>
+<td>0x01a7</td>
+<td>KEY_SPREADSHEET</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0187</td>
+<td>AL Graphics Editor</td>
+<td>0x01a8</td>
+<td>KEY_GRAPHICSEDITOR</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0188</td>
+<td>AL Presentation App</td>
+<td>0x01a9</td>
+<td>KEY_PRESENTATION</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0189</td>
+<td>AL Database App</td>
+<td>0x01aa</td>
+<td>KEY_DATABASE</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x018a</td>
+<td>AL Email Reader</td>
+<td>0x009b</td>
+<td>KEY_MAIL</td>
+<td>1.6</td>
+<td>0x0041</td>
+<td>KEYCODE_ENVELOPE</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x018b</td>
+<td>AL Newsreader</td>
+<td>0x01ab</td>
+<td>KEY_NEWS</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x018c</td>
+<td>AL Voicemail</td>
+<td>0x01ac</td>
+<td>KEY_VOICEMAIL</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x018d</td>
+<td>AL Contacts / Address Book</td>
+<td>0x01ad</td>
+<td>KEY_ADDRESSBOOK</td>
+<td>4.0.3</td>
+<td>0x00cf</td>
+<td>KEYCODE_CONTACTS</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x018e</td>
+<td>AL Calendar / Schedule</td>
+<td>0x018d</td>
+<td>KEY_CALENDAR</td>
+<td>4.0.3</td>
+<td>0x00d0</td>
+<td>KEYCODE_CALENDAR</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x018f</td>
+<td>AL Task / Project Manager</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0190</td>
+<td>AL Log / Journal / Timecard</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0191</td>
+<td>AL Checkbook / Finance</td>
+<td>0x00db</td>
+<td>KEY_FINANCE</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0192</td>
+<td>AL Calculator</td>
+<td>0x008c</td>
+<td>KEY_CALC</td>
+<td>4.0.3</td>
+<td>0x00d2</td>
+<td>KEYCODE_CALCULATOR</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0193</td>
+<td>AL A/V Capture / Playback</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0194</td>
+<td>AL Local Machine Browser</td>
+<td>0x0090</td>
+<td>KEY_FILE</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0195</td>
+<td>AL LAN/WAN Browser</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0196</td>
+<td>AL Internet Browser</td>
+<td>0x0096</td>
+<td>KEY_WWW</td>
+<td>1.6</td>
+<td>0x0040</td>
+<td>KEYCODE_EXPLORER</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0197</td>
+<td>AL Remote Networking/ISP Connect</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0198</td>
+<td>AL Network Conference</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0199</td>
+<td>AL Network Chat</td>
+<td>0x00d8</td>
+<td>KEY_CHAT</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x019a</td>
+<td>AL Telephony / Dialer</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x019b</td>
+<td>AL Logon</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x019c</td>
+<td>AL Logoff</td>
+<td>0x01b1</td>
+<td>KEY_LOGOFF</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x019d</td>
+<td>AL Logon / Logoff</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x019e</td>
+<td>AL Terminal Lock / Screensaver</td>
+<td>0x0098</td>
+<td>KEY_COFFEE</td>
+<td>4.0</td>
+<td>0x001a</td>
+<td>KEYCODE_POWER</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x019f</td>
+<td>AL Control Panel</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01a0</td>
+<td>AL Command Line Processor / Run</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01a1</td>
+<td>AL Process / Task Manager</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01a2</td>
+<td>AL Select Task / Application</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01a3</td>
+<td>AL Next Task / Application</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01a4</td>
+<td>AL Previous Task / Application</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01a5</td>
+<td>AL Preemptive Halt Task / App.</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01a6</td>
+<td>AL Integrated Help Center</td>
+<td>0x008a</td>
+<td>KEY_HELP</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01a7</td>
+<td>AL Documents</td>
+<td>0x00eb</td>
+<td>KEY_DOCUMENTS</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01a8</td>
+<td>AL Thesaurus</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01a9</td>
+<td>AL Dictionary</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01aa</td>
+<td>AL Desktop</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01ab</td>
+<td>AL Spell Check</td>
+<td>0x01b0</td>
+<td>KEY_SPELLCHECK</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01ac</td>
+<td>AL Grammar Check</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01ad</td>
+<td>AL Wireless Status</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01ae</td>
+<td>AL Keyboard Layout</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01af</td>
+<td>AL Virus Protection</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01b0</td>
+<td>AL Encryption</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01b1</td>
+<td>AL Screen Saver</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01b2</td>
+<td>AL Alarms</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01b3</td>
+<td>AL Clock</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01b4</td>
+<td>AL File Browser</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01b5</td>
+<td>AL Power Status</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01b6</td>
+<td>AL Image Browser</td>
+<td>0x00e2</td>
+<td>KEY_MEDIA</td>
+<td>3.0</td>
+<td>0x004f</td>
+<td>KEYCODE_HEADSETHOOK</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01b7</td>
+<td>AL Audio Browser</td>
+<td>0x00d5</td>
+<td>KEY_SOUND</td>
+<td>4.0.3</td>
+<td>0x00d1</td>
+<td>KEYCODE_MUSIC</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01b8</td>
+<td>AL Movie Browser</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01b9</td>
+<td>AL Digital Rights Manager</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01ba</td>
+<td>AL Digital Wallet</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01bc</td>
+<td>AL Instant Messaging</td>
+<td>0x01ae</td>
+<td>KEY_MESSENGER</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01bd</td>
+<td>AL OEM Features / Tips Browser</td>
+<td>0x0166</td>
+<td>KEY_INFO</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01be</td>
+<td>AL OEM Help</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01bf</td>
+<td>AL Online Community</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01c0</td>
+<td>AL Entertainment Content Browser</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01c1</td>
+<td>AL Online Shopping Browser</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01c2</td>
+<td>AL SmartCard Information / Help</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01c3</td>
+<td>AL Market / Finance Browser</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01c4</td>
+<td>AL Customized Corp. News Browser</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01c5</td>
+<td>AL Online Activity Browser</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01c6</td>
+<td>AL Research / Search Browser</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x01c7</td>
+<td>AL Audio Player</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0201</td>
+<td>AC New</td>
+<td>0x00b5</td>
+<td>KEY_NEW</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0202</td>
+<td>AC Open</td>
+<td>0x0086</td>
+<td>KEY_OPEN</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0203</td>
+<td>AC Close</td>
+<td>0x00ce</td>
+<td>KEY_CLOSE</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0204</td>
+<td>AC Exit</td>
+<td>0x00ae</td>
+<td>KEY_EXIT</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0205</td>
+<td>AC Maximize</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0206</td>
+<td>AC Minimize</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0207</td>
+<td>AC Save</td>
+<td>0x00ea</td>
+<td>KEY_SAVE</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0208</td>
+<td>AC Print</td>
+<td>0x00d2</td>
+<td>KEY_PRINT</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0209</td>
+<td>AC Properties</td>
+<td>0x0082</td>
+<td>KEY_PROPS</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x021a</td>
+<td>AC Undo</td>
+<td>0x0083</td>
+<td>KEY_UNDO</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x021b</td>
+<td>AC Copy</td>
+<td>0x0085</td>
+<td>KEY_COPY</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x021c</td>
+<td>AC Cut</td>
+<td>0x0089</td>
+<td>KEY_CUT</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x021d</td>
+<td>AC Paste</td>
+<td>0x0087</td>
+<td>KEY_PASTE</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x021e</td>
+<td>AC Select All</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x021f</td>
+<td>AC Find</td>
+<td>0x0088</td>
+<td>KEY_FIND</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0220</td>
+<td>AC Find and Replace</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0221</td>
+<td>AC Search</td>
+<td>0x00d9</td>
+<td>KEY_SEARCH</td>
+<td>1.6</td>
+<td>0x0054</td>
+<td>KEYCODE_SEARCH</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0222</td>
+<td>AC Go To</td>
+<td>0x0162</td>
+<td>KEY_GOTO</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0223</td>
+<td>AC Home</td>
+<td>0x00ac</td>
+<td>KEY_HOMEPAGE</td>
+<td>3.0</td>
+<td>0x0003</td>
+<td>KEYCODE_HOME</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0224</td>
+<td>AC Back</td>
+<td>0x009e</td>
+<td>KEY_BACK</td>
+<td>1.6</td>
+<td>0x0004</td>
+<td>KEYCODE_BACK</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0225</td>
+<td>AC Forward</td>
+<td>0x009f</td>
+<td>KEY_FORWARD</td>
+<td>3.0</td>
+<td>0x007d</td>
+<td>KEYCODE_FORWARD</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0226</td>
+<td>AC Stop</td>
+<td>0x0080</td>
+<td>KEY_STOP</td>
+<td>3.0</td>
+<td>0x0056</td>
+<td>KEYCODE_MEDIA_STOP</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0227</td>
+<td>AC Refresh</td>
+<td>0x00ad</td>
+<td>KEY_REFRESH</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0228</td>
+<td>AC Previous Link</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0229</td>
+<td>AC Next Link</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x022a</td>
+<td>AC Bookmarks</td>
+<td>0x009c</td>
+<td>KEY_BOOKMARKS</td>
+<td>3.0</td>
+<td>0x00ae</td>
+<td>KEYCODE_BOOKMARK</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x022b</td>
+<td>AC History</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x022c</td>
+<td>AC Subscriptions</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x022d</td>
+<td>AC Zoom In</td>
+<td>0x01a2</td>
+<td>KEY_ZOOMIN</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x022e</td>
+<td>AC Zoom Out</td>
+<td>0x01a3</td>
+<td>KEY_ZOOMOUT</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x022f</td>
+<td>AC Zoom</td>
+<td>0x01a4</td>
+<td>KEY_ZOOMRESET</td>
+<td></td>
+<td></td>
+<td></td>
+<td>2</td>
+</tr>
+<tr>
+<td>0x0c 0x0230</td>
+<td>AC Full Screen View</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0231</td>
+<td>AC Normal View</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0232</td>
+<td>AC View Toggle</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0233</td>
+<td>AC Scroll Up</td>
+<td>0x00b1</td>
+<td>KEY_SCROLLUP</td>
+<td>3.0</td>
+<td>0x005c</td>
+<td>KEYCODE_PAGE_UP</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0234</td>
+<td>AC Scroll Down</td>
+<td>0x00b2</td>
+<td>KEY_SCROLLDOWN</td>
+<td>3.0</td>
+<td>0x005d</td>
+<td>KEYCODE_PAGE_DOWN</td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0236</td>
+<td>AC Pan Left</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0237</td>
+<td>AC Pan Right</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0239</td>
+<td>AC New Window</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x023a</td>
+<td>AC Tile Horizontally</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x023b</td>
+<td>AC Tile Vertically</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x023c</td>
+<td>AC Format</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x023d</td>
+<td>AC Edit</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x023e</td>
+<td>AC Bold</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x023f</td>
+<td>AC Italics</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0240</td>
+<td>AC Underline</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0241</td>
+<td>AC Strikethrough</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0242</td>
+<td>AC Subscript</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0243</td>
+<td>AC Superscript</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0244</td>
+<td>AC All Caps</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0245</td>
+<td>AC Rotate</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0246</td>
+<td>AC Resize</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0247</td>
+<td>AC Flip horizontal</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0248</td>
+<td>AC Flip Vertical</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0249</td>
+<td>AC Mirror Horizontal</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x024a</td>
+<td>AC Mirror Vertical</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x024b</td>
+<td>AC Font Select</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x024c</td>
+<td>AC Font Color</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x024d</td>
+<td>AC Font Size</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x024e</td>
+<td>AC Justify Left</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x024f</td>
+<td>AC Justify Center H</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0250</td>
+<td>AC Justify Right</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0251</td>
+<td>AC Justify Block H</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0252</td>
+<td>AC Justify Top</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0253</td>
+<td>AC Justify Center V</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0254</td>
+<td>AC Justify Bottom</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0255</td>
+<td>AC Justify Block V</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0256</td>
+<td>AC Indent Decrease</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0257</td>
+<td>AC Indent Increase</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0258</td>
+<td>AC Numbered List</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0259</td>
+<td>AC Restart Numbering</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x025a</td>
+<td>AC Bulleted List</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x025b</td>
+<td>AC Promote</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x025c</td>
+<td>AC Demote</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x025d</td>
+<td>AC Yes</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x025e</td>
+<td>AC No</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x025f</td>
+<td>AC Cancel</td>
+<td>0x00df</td>
+<td>KEY_CANCEL</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0260</td>
+<td>AC Catalog</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0261</td>
+<td>AC Buy / Checkout</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0262</td>
+<td>AC Add to Cart</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0263</td>
+<td>AC Expand</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0264</td>
+<td>AC Expand All</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0265</td>
+<td>AC Collapse</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0266</td>
+<td>AC Collapse All</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0267</td>
+<td>AC Print Preview</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0268</td>
+<td>AC Paste Special</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0269</td>
+<td>AC Insert Mode</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x026a</td>
+<td>AC Delete</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x026b</td>
+<td>AC Lock</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x026c</td>
+<td>AC Unlock</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x026d</td>
+<td>AC Protect</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x026e</td>
+<td>AC Unprotect</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x026f</td>
+<td>AC Attach Comment</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0270</td>
+<td>AC Delete Comment</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0271</td>
+<td>AC View Comment</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0272</td>
+<td>AC Select Word</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0273</td>
+<td>AC Select Sentence</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0274</td>
+<td>AC Select Paragraph</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0275</td>
+<td>AC Select Column</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0276</td>
+<td>AC Select Row</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0277</td>
+<td>AC Select Table</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0278</td>
+<td>AC Select Object</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0279</td>
+<td>AC Redo / Repeat</td>
+<td>0x00b6</td>
+<td>KEY_REDO</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x027a</td>
+<td>AC Sort</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x027b</td>
+<td>AC Sort Ascending</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x027c</td>
+<td>AC Sort Descending</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x027d</td>
+<td>AC Filter</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x027e</td>
+<td>AC Set Clock</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x027f</td>
+<td>AC View Clock</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0280</td>
+<td>AC Select Time Zone</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0281</td>
+<td>AC Edit Time Zones</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0282</td>
+<td>AC Set Alarm</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0283</td>
+<td>AC Clear Alarm</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0284</td>
+<td>AC Snooze Alarm</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0285</td>
+<td>AC Reset Alarm</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0286</td>
+<td>AC Synchronize</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0287</td>
+<td>AC Send/Receive</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0288</td>
+<td>AC Send To</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0289</td>
+<td>AC Reply</td>
+<td>0x00e8</td>
+<td>KEY_REPLY</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x028a</td>
+<td>AC Reply All</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x028b</td>
+<td>AC Forward Msg</td>
+<td>0x00e9</td>
+<td>KEY_FORWARDMAIL</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x028c</td>
+<td>AC Send</td>
+<td>0x00e7</td>
+<td>KEY_SEND</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x028d</td>
+<td>AC Attach File</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x028e</td>
+<td>AC Upload</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x028f</td>
+<td>AC Download (Save Target As)</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0290</td>
+<td>AC Set Borders</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0291</td>
+<td>AC Insert Row</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0292</td>
+<td>AC Insert Column</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0293</td>
+<td>AC Insert File</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0294</td>
+<td>AC Insert Picture</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0295</td>
+<td>AC Insert Object</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0296</td>
+<td>AC Insert Symbol</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0297</td>
+<td>AC Save and Close</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0298</td>
+<td>AC Rename</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x0299</td>
+<td>AC Merge</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x029a</td>
+<td>AC Split</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x029b</td>
+<td>AC Distribute Horizontally</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>0x0c 0x029c</td>
+<td>AC Distribute Vertically</td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+</tbody>
+</table>
+<h3 id="additional-non-hid-mappings">Additional non-HID Mappings</h3>
+<p>These mappings describe functions that do not appear in HID but for which Linux
+key codes exist.</p>
+<table>
+<thead>
+<tr>
+<th>LKC</th>
+<th>Linux Key Code Name</th>
+<th>Version</th>
+<th>AKC</th>
+<th>Android Key Code Name</th>
+<th>Notes</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>0x01d0</td>
+<td>KEY_FN</td>
+<td>3.0</td>
+<td>0x0077</td>
+<td>KEYCODE_FUNCTION</td>
+<td></td>
+</tr>
+<tr>
+<td>0x01d1</td>
+<td>KEY_FN_ESC</td>
+<td>3.0</td>
+<td>0x006f</td>
+<td>KEYCODE_ESCAPE</td>
+<td>3</td>
+</tr>
+<tr>
+<td>0x01d2</td>
+<td>KEY_FN_F1</td>
+<td>3.0</td>
+<td>0x0083</td>
+<td>KEYCODE_F1</td>
+<td>3</td>
+</tr>
+<tr>
+<td>0x01d3</td>
+<td>KEY_FN_F2</td>
+<td>3.0</td>
+<td>0x0084</td>
+<td>KEYCODE_F2</td>
+<td>3</td>
+</tr>
+<tr>
+<td>0x01d4</td>
+<td>KEY_FN_F3</td>
+<td>3.0</td>
+<td>0x0085</td>
+<td>KEYCODE_F3</td>
+<td>3</td>
+</tr>
+<tr>
+<td>0x01d5</td>
+<td>KEY_FN_F4</td>
+<td>3.0</td>
+<td>0x0086</td>
+<td>KEYCODE_F4</td>
+<td>3</td>
+</tr>
+<tr>
+<td>0x01d6</td>
+<td>KEY_FN_F5</td>
+<td>3.0</td>
+<td>0x0087</td>
+<td>KEYCODE_F5</td>
+<td>3</td>
+</tr>
+<tr>
+<td>0x01d7</td>
+<td>KEY_FN_F6</td>
+<td>3.0</td>
+<td>0x0088</td>
+<td>KEYCODE_F6</td>
+<td>3</td>
+</tr>
+<tr>
+<td>0x01d8</td>
+<td>KEY_FN_F7</td>
+<td>3.0</td>
+<td>0x0089</td>
+<td>KEYCODE_F7</td>
+<td>3</td>
+</tr>
+<tr>
+<td>0x01d9</td>
+<td>KEY_FN_F8</td>
+<td>3.0</td>
+<td>0x008a</td>
+<td>KEYCODE_F8</td>
+<td>3</td>
+</tr>
+<tr>
+<td>0x01da</td>
+<td>KEY_FN_F9</td>
+<td>3.0</td>
+<td>0x008b</td>
+<td>KEYCODE_F9</td>
+<td>3</td>
+</tr>
+<tr>
+<td>0x01db</td>
+<td>KEY_FN_F10</td>
+<td>3.0</td>
+<td>0x008c</td>
+<td>KEYCODE_F10</td>
+<td>3</td>
+</tr>
+<tr>
+<td>0x01dc</td>
+<td>KEY_FN_F11</td>
+<td>3.0</td>
+<td>0x008d</td>
+<td>KEYCODE_F11</td>
+<td>3</td>
+</tr>
+<tr>
+<td>0x01dd</td>
+<td>KEY_FN_F12</td>
+<td>3.0</td>
+<td>0x008e</td>
+<td>KEYCODE_F12</td>
+<td>3</td>
+</tr>
+<tr>
+<td>0x01de</td>
+<td>KEY_FN_1</td>
+<td>3.0</td>
+<td>0x0008</td>
+<td>KEYCODE_1</td>
+<td>3</td>
+</tr>
+<tr>
+<td>0x01df</td>
+<td>KEY_FN_2</td>
+<td>3.0</td>
+<td>0x0009</td>
+<td>KEYCODE_2</td>
+<td>3</td>
+</tr>
+<tr>
+<td>0x01e0</td>
+<td>KEY_FN_D</td>
+<td>3.0</td>
+<td>0x0020</td>
+<td>KEYCODE_D</td>
+<td>3</td>
+</tr>
+<tr>
+<td>0x01e1</td>
+<td>KEY_FN_E</td>
+<td>3.0</td>
+<td>0x0021</td>
+<td>KEYCODE_E</td>
+<td>3</td>
+</tr>
+<tr>
+<td>0x01e2</td>
+<td>KEY_FN_F</td>
+<td>3.0</td>
+<td>0x0022</td>
+<td>KEYCODE_F</td>
+<td>3</td>
+</tr>
+<tr>
+<td>0x01e3</td>
+<td>KEY_FN_S</td>
+<td>3.0</td>
+<td>0x002f</td>
+<td>KEYCODE_S</td>
+<td>3</td>
+</tr>
+<tr>
+<td>0x01e4</td>
+<td>KEY_FN_B</td>
+<td>3.0</td>
+<td>0x001e</td>
+<td>KEYCODE_B</td>
+<td>3</td>
+</tr>
+</tbody>
+</table>
+<h3 id="legacy-unsupported-keys">Legacy Unsupported Keys</h3>
+<p>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.</p>
+<table>
+<thead>
+<tr>
+<th>LKC</th>
+<th>Linux Key Code Name</th>
+<th>Version</th>
+<th>AKC</th>
+<th>Android Key Code Name</th>
+<th>Notes</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>0x00db</td>
+<td>KEY_EMAIL</td>
+<td>1.6</td>
+<td>0x004d</td>
+<td>KEYCODE_AT</td>
+<td>4</td>
+</tr>
+<tr>
+<td>""</td>
+<td>""</td>
+<td>4.0</td>
+<td></td>
+<td></td>
+<td>4</td>
+</tr>
+<tr>
+<td>0x00e3</td>
+<td>KEY_STAR</td>
+<td>1.6</td>
+<td>0x0011</td>
+<td>KEYCODE_STAR</td>
+<td>4</td>
+</tr>
+<tr>
+<td>""</td>
+<td>""</td>
+<td>4.0</td>
+<td></td>
+<td></td>
+<td>4</td>
+</tr>
+<tr>
+<td>0x00e4</td>
+<td>KEY_SHARP</td>
+<td>1.6</td>
+<td>0x0012</td>
+<td>KEYCODE_POUND</td>
+<td>4</td>
+</tr>
+<tr>
+<td>""</td>
+<td>""</td>
+<td>4.0</td>
+<td></td>
+<td></td>
+<td>4</td>
+</tr>
+<tr>
+<td>0x00e5</td>
+<td>KEY_SOFT1</td>
+<td>1.6</td>
+<td>0x0052</td>
+<td>KEYCODE_MENU</td>
+<td>4</td>
+</tr>
+<tr>
+<td>""</td>
+<td>""</td>
+<td>4.0</td>
+<td></td>
+<td></td>
+<td>4</td>
+</tr>
+<tr>
+<td>0x00e6</td>
+<td>KEY_SOFT2</td>
+<td>1.6</td>
+<td>0x0002</td>
+<td>KEYCODE_SOFT_RIGHT</td>
+<td>4</td>
+</tr>
+<tr>
+<td>""</td>
+<td>""</td>
+<td>4.0</td>
+<td></td>
+<td></td>
+<td>4</td>
+</tr>
+<tr>
+<td>0x00e7</td>
+<td>KEY_SEND</td>
+<td>1.6</td>
+<td>0x0005</td>
+<td>KEYCODE_CALL</td>
+<td>4</td>
+</tr>
+<tr>
+<td>""</td>
+<td>""</td>
+<td>4.0</td>
+<td></td>
+<td></td>
+<td>4</td>
+</tr>
+<tr>
+<td>0x00e8</td>
+<td>KEY_CENTER</td>
+<td>1.6</td>
+<td>0x0017</td>
+<td>KEYCODE_DPAD_CENTER</td>
+<td>4</td>
+</tr>
+<tr>
+<td>""</td>
+<td>""</td>
+<td>4.0</td>
+<td></td>
+<td></td>
+<td>4</td>
+</tr>
+<tr>
+<td>0x00e9</td>
+<td>KEY_HEADSETHOOK</td>
+<td>1.6</td>
+<td>0x004f</td>
+<td>KEYCODE_HEADSETHOOK</td>
+<td>4</td>
+</tr>
+<tr>
+<td>""</td>
+<td>""</td>
+<td>4.0</td>
+<td></td>
+<td></td>
+<td>4</td>
+</tr>
+<tr>
+<td>0x00ea</td>
+<td>KEY_0_5</td>
+<td>1.6</td>
+<td></td>
+<td></td>
+<td>4</td>
+</tr>
+<tr>
+<td>0x00eb</td>
+<td>KEY_2_5</td>
+<td>1.6</td>
+<td></td>
+<td></td>
+<td>4</td>
+</tr>
+</tbody>
+</table>
+<h3 id="notes">Notes</h3>
+<ol>
+<li>
+<p>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.</p>
+<p>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.</p>
+<p>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'.</p>
+<p>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.</p>
+</li>
+<li>
+<p><code>0x0c 0x022f AC Zoom</code> is defined in the HID as a linear control but
+    the kernel maps it as a key, which is probably incorrect.</p>
+</li>
+<li>
+<p>The Linux function keys <code>KEY_FN_*</code> are mapped to simpler
+    key codes but are dispatched with the <code>META_FUNCTION</code> meta state
+    bit set to true.</p>
+</li>
+<li>
+<p>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.</p>
+</li>
+</ol>
+<h3 id="sources">Sources</h3>
+<ol>
+<li><a href="http://www.usb.org/developers/devclass_docs/Hut1_12v2.pdf">USB HID Usage Tables v1.12</a></li>
+<li>Linux 2.6.39 kernel: include/linux/input.h, drivers/hid/hid-input.c</li>
+<li>Android ICS: qwerty.kl, Generic.kl, KeyEvent.java</li>
+</ol>
diff --git a/src/devices/tech/input/migration-guide.jd b/src/devices/tech/input/migration-guide.jd
new file mode 100644
index 0000000..dbdf666
--- /dev/null
+++ b/src/devices/tech/input/migration-guide.jd
@@ -0,0 +1,55 @@
+page.title=Migration Guide
+@jd:body
+
+<!--
+    Copyright 2010 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.
+-->
+<p>This document contains a few helpful tips when migrating to new Android releases.</p>
+<h2 id="migrating-to-android-gingerbread-23">Migrating to Android Gingerbread 2.3</h2>
+<p>In Gingerbread, we added the concept of input device configuration files
+(also referred to as input device calibration files in this release).</p>
+<p>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.</p>
+<h2 id="migrating-to-android-honeycomb-30">Migrating to Android Honeycomb 3.0</h2>
+<p>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.)</p>
+<p>Make sure to update all of your key character map files to use the new syntax.</p>
+<p>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.</p>
+<p>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 <code>SPECIAL_FUNCTION</code>.</p>
+<p>A good way to ensure that all built-in input devices are appropriately configured
+is to run <a href="/tech/input/dumpsys.html">Dumpsys</a> and look for devices that
+are inappropriately using <code>Generic.kcm</code>.</p>
+<h2 id="migrating-to-android-honeycomb-32">Migrating to Android Honeycomb 3.2</h2>
+<p>In Honeycomb 3.2, we added support for joysticks and extended the key layout file
+format to enable joystick axis mapping.</p>
+<h2 id="migrating-to-android-ice-cream-sandwich-40">Migrating to Android Ice Cream Sandwich 4.0</h2>
+<p>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.</p>
+<p>You will probably need to update your input device driver to implement the Linux
+multitouch input protocol correctly according to the standard.</p>
+<p>You will also need to update your input device configuration files because some
+properties have been changed to be simpler and more systematic.</p>
+<p>Refer to <a href="/tech/input/touch-devices.html">Touch Devices</a> for more details about
+driver requirements.</p>
\ No newline at end of file
diff --git a/src/devices/tech/input/overview.jd b/src/devices/tech/input/overview.jd
new file mode 100644
index 0000000..cbf86b9
--- /dev/null
+++ b/src/devices/tech/input/overview.jd
@@ -0,0 +1,237 @@
+page.title=Overview
+@jd:body
+
+<!--
+    Copyright 2010 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.
+-->
+<p>The Android input subsystem nominally consists of an event pipeline
+that traverses multiple layers of the system.</p>
+<h2 id="input-pipeline">Input Pipeline</h2>
+<p>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.</p>
+<p>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.</p>
+<p>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 <code>linux/input.h</code> 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.</p>
+<p>Next, the Android <code>EventHub</code> component reads input events from the kernel
+by opening the <code>evdev</code> 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.</p>
+<p>Finally, the <code>InputReader</code> sends input events to the InputDispatcher
+which forwards them to the appropriate window.</p>
+<h2 id="control-points">Control Points</h2>
+<p>There are several stages in the input pipeline which effect control
+over the behavior of the input device.</p>
+<h3 id="driver-and-firmware-configuration">Driver and Firmware Configuration</h3>
+<p>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.</p>
+<p>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.</p>
+<p>This documentation does attempt to describe driver or firmware
+configuration, but it does offer guidance as to device calibration
+in general.</p>
+<h3 id="board-configuration-properties">Board Configuration Properties</h3>
+<p>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.</p>
+<p>Refer to the device class sections for details about how different
+devices use board configuration properties.</p>
+<h3 id="resource-overlays">Resource Overlays</h3>
+<p>A few input behaviors are configured by way of resource overlays
+in <code>config.xml</code> such as the operation of lid switch.</p>
+<p>Here are a few examples:</p>
+<ul>
+<li>
+<p><code>config_lidKeyboardAccessibility</code>: Specifies the effect of the
+    lid switch on whether the hardware keyboard is accessible or hidden.</p>
+</li>
+<li>
+<p><code>config_lidNavigationAccessibility</code>: Specifies the effect of the
+    lid switch on whether the trackpad is accessible or hidden.</p>
+</li>
+<li>
+<p><code>config_longPressOnPowerBehavior</code>: Specifies what should happen when
+    the user holds down the power button.</p>
+</li>
+<li>
+<p><code>config_lidOpenRotation</code>: Specifies the effect of the lid switch
+    on screen orientation.</p>
+</li>
+</ul>
+<p>Refer to the documentation within <code>frameworks/base/core/res/res/values/config.xml</code>
+for details about each configuration option.</p>
+<h3 id="key-maps">Key Maps</h3>
+<p>Key maps are used by the Android <code>EventHub</code> and <code>InputReader</code> 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.</p>
+<p>Refer to the device class sections for details about how different
+devices use key maps.</p>
+<h3 id="input-device-configuration-files">Input Device Configuration Files</h3>
+<p>Input device configuration files are used by the Android <code>EventHub</code> and
+<code>InputReader</code> components to configure special device characteristics
+such as how touch size information is reported.</p>
+<p>Refer to the device class sections for details about how different
+devices use input device configuration maps.</p>
+<h2 id="understanding-hid-usages-and-event-codes">Understanding HID Usages and Event Codes</h2>
+<p>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.</p>
+<dl>
+<dt>Physical Scan Code</dt>
+<dd>
+<p>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.</p>
+<p>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.</p>
+</dd>
+<dt>HID Usage</dt>
+<dd>
+<p>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.</p>
+<p>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.</p>
+</dd>
+<dt>Linux Key Code</dt>
+<dd>
+<p>A Linux key code is a standard identifier for a key or button.
+Linux key codes are defined in the <code>linux/input.h</code> header file using
+constants that begin with the prefix <code>KEY_</code> or <code>BTN_</code>.  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
+<code>EV_KEY</code> events.</p>
+<p>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.</p>
+</dd>
+<dt>Linux Relative or Absolute Axis Code</dt>
+<dd>
+<p>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 <code>linux/input.h</code> header file using
+constants that begin with the prefix <code>REL_</code> or <code>ABS_</code>.  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 <code>EV_REL</code> and
+<code>EV_ABS</code> events.</p>
+</dd>
+<dt>Linux Switch Code</dt>
+<dd>
+<p>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 <code>linux/input.h</code> header file
+using constants that begin with the prefix <code>SW_</code>.  The Linux
+kernel input drivers report switch state changes as <code>EV_SW</code> events.</p>
+<p>Android applications generally do not receive events from switches,
+but the system may use them interally to control various
+device-specific functions.</p>
+</dd>
+<dt>Android Key Code</dt>
+<dd>
+<p>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 <code>android.view.KeyEvent</code> class as constants that
+begin with the prefix <code>KEYCODE_</code>.</p>
+<p>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.</p>
+<p>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 <code>KEYCODE_SHIFT</code> and <code>KEYCODE_A</code> 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.</p>
+</dd>
+<dt>Android Axis Code</dt>
+<dd>
+<p>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 <code>android.view.MotionEvent</code> class as constants that
+begin with the prefix <code>AXIS_</code>.</p>
+<p>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.</p>
+</dd>
+<dt>Android Meta State</dt>
+<dd>
+<p>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 <code>android.view.KeyEvent</code> class as constants that
+begin with the prefix <code>META_</code>.</p>
+<p>The current meta state is determined by the Android InputReader
+component which monitors when modifier keys such as <code>KEYCODE_SHIFT_LEFT</code>
+are pressed / released and sets / resets the appropriate meta state flag.</p>
+<p>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.</p>
+</dd>
+<dt>Android Button State</dt>
+<dd>
+<p>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 <code>android.view.MotionEvent</code>
+class as constants that begin with the prefix <code>BUTTON_</code>.</p>
+<p>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.</p>
+<p>The relationship between buttons and button states is hardcoded.</p>
+</dd>
+</dl>
+<h2 id="further-reading">Further Reading</h2>
+<ol>
+<li><a href="http://www.kernel.org/doc/Documentation/input/event-codes.txt">Linux input event codes</a></li>
+<li><a href="http://www.kernel.org/doc/Documentation/input/multi-touch-protocol.txt">Linux multi-touch protocol</a></li>
+<li><a href="http://www.kernel.org/doc/Documentation/input/input.txt">Linux input drivers</a></li>
+<li><a href="http://www.kernel.org/doc/Documentation/input/ff.txt">Linux force feedback</a></li>
+<li><a href="http://www.usb.org/developers/hidpage">HID information, including HID usage tables</a></li>
+</ol>
diff --git a/src/devices/tech/input/touch-devices.jd b/src/devices/tech/input/touch-devices.jd
new file mode 100644
index 0000000..21567d3
--- /dev/null
+++ b/src/devices/tech/input/touch-devices.jd
@@ -0,0 +1,1163 @@
+page.title=Touch Devices
+@jd:body
+
+<!--
+    Copyright 2010 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.
+-->
+<p>Android supports a variety of touch screens and touch pads, including
+stylus-based digitizer tablets.</p>
+<p>Touch screens are touch devices that are associated with a display such that
+the user has the impression of directly manipulating items on screen.</p>
+<p>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.</p>
+<p>Touch devices may have buttons whose functions are similar to mouse buttons.</p>
+<p>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.</p>
+<p>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.</p>
+<p>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.</p>
+<h2 id="touch-device-classification">Touch Device Classification</h2>
+<p>An input device is classified as a <em>multi-touch</em> device if both of
+the following conditions hold:</p>
+<ul>
+<li>
+<p>The input device reports the presence of the <code>ABS_MT_POSITION_X</code> and
+    <code>ABS_MT_POSITION_Y</code> absolute axes.</p>
+</li>
+<li>
+<p>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.</p>
+</li>
+</ul>
+<p>An input device is classified as a <em>single-touch</em> device if both of the
+following conditions hold:</p>
+<ul>
+<li>
+<p>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.</p>
+</li>
+<li>
+<p>The input device reports the presence of the <code>ABS_X</code> and <code>ABS_Y</code> absolute
+    axes, and the presence of the <code>BTN_TOUCH</code> key code.</p>
+</li>
+</ul>
+<p>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.</p>
+<p>Refer to the section below about the location and format of virtual key map
+files.</p>
+<p>Next, the system loads the input device configuration file for the touch device.</p>
+<p><strong>All built-in touch devices should have input device configuration files.</strong>
+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.</p>
+<p>After the input device configuration loaded, the system will classify the
+input device as a <em>touch screen</em>, <em>touch pad</em> or <em>pointer</em> device.</p>
+<ul>
+<li>
+<p>A <em>touch screen</em> 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.</p>
+</li>
+<li>
+<p>A <em>touch pad</em> 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.</p>
+</li>
+<li>
+<p>A <em>pointer</em> 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.</p>
+<p>See <a href="#indirect-multi-touch-pointer-gestures">Indirect Multi-touch Pointer Gestures</a>
+for more information.</p>
+</li>
+</ul>
+<p>The following rules are used to classify the input device as a <em>touch screen</em>,
+<em>touch pad</em> or <em>pointer</em> device.</p>
+<ul>
+<li>
+<p>If the <code>touch.deviceType</code> property is set, then the device type will be
+    set as indicated.</p>
+</li>
+<li>
+<p>If the input device reports the presence of the <code>INPUT_PROP_DIRECT</code>
+    input property (via the <code>EVIOCGPROP</code> ioctl), then the device type will
+    be set to <em>touch screen</em>.  This condition assumes that direct input touch
+    devices are attached to a display that is also connected.</p>
+</li>
+<li>
+<p>If the input device reports the presence of the <code>INPUT_PROP_POINTER</code>
+    input property (via the <code>EVIOCGPROP</code> ioctl), then the device type will
+    be set to <em>pointer</em>.</p>
+</li>
+<li>
+<p>If the input device reports the presence of the <code>REL_X</code> or <code>REL_Y</code> relative
+    axes, then the device type will be set to <em>touch pad</em>.  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.</p>
+</li>
+<li>
+<p>Otherwise, the device type will be set to <em>pointer</em>.  This default ensures
+    that touch pads that have not been designated any other special purpose
+    will serve to control the pointer.</p>
+</li>
+</ul>
+<h2 id="buttons">Buttons</h2>
+<p>Buttons are <em>optional</em> 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 <em>pointer</em> type touch devices or with a
+stylus.</p>
+<p>The following buttons are supported:</p>
+<ul>
+<li>
+<p><code>BTN_LEFT</code>: mapped to <code>MotionEvent.BUTTON_PRIMARY</code>.</p>
+</li>
+<li>
+<p><code>BTN_RIGHT</code>: mapped to <code>MotionEvent.BUTTON_SECONDARY</code>.</p>
+</li>
+<li>
+<p><code>BTN_MIDDLE</code>: mapped to <code>MotionEvent.BUTTON_MIDDLE</code>.</p>
+</li>
+<li>
+<p><code>BTN_BACK</code> and <code>BTN_SIDE</code>: mapped to <code>MotionEvent.BUTTON_BACK</code>.
+    Pressing this button also synthesizes a key press with the key code
+    <code>KeyEvent.KEYCODE_BACK</code>.</p>
+</li>
+<li>
+<p><code>BTN_FORWARD</code> and <code>BTN_EXTRA</code>: mapped to <code>MotionEvent.BUTTON_FORWARD</code>.
+    Pressing this button also synthesizes a key press with the key code
+    <code>KeyEvent.KEYCODE_FORWARD</code>.</p>
+</li>
+<li>
+<p><code>BTN_STYLUS</code>: mapped to <code>MotionEvent.BUTTON_SECONDARY</code>.</p>
+</li>
+<li>
+<p><code>BTN_STYLUS2</code>: mapped to <code>MotionEvent.BUTTON_TERTIARY</code>.</p>
+</li>
+</ul>
+<h2 id="tools-and-tool-types">Tools and Tool Types</h2>
+<p>A <em>tool</em> 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.</p>
+<p>Elsewhere in Android, as in the <code>MotionEvent</code> API, a <em>tool</em> is often referred
+to as a <em>pointer</em>.</p>
+<p>The following tool types are supported:</p>
+<ul>
+<li>
+<p><code>BTN_TOOL_FINGER</code> and <code>MT_TOOL_FINGER</code>: mapped to <code>MotionEvent.TOOL_TYPE_FINGER</code>.</p>
+</li>
+<li>
+<p><code>BTN_TOOL_PEN</code> and <code>MT_TOOL_PEN</code>: mapped to <code>MotionEvent.TOOL_TYPE_STYLUS</code>.</p>
+</li>
+<li>
+<p><code>BTN_TOOL_RUBBER</code>: mapped to <code>MotionEvent.TOOL_TYPE_ERASER</code>.</p>
+</li>
+<li>
+<p><code>BTN_TOOL_BRUSH</code>: mapped to <code>MotionEvent.TOOL_TYPE_STYLUS</code>.</p>
+</li>
+<li>
+<p><code>BTN_TOOL_PENCIL</code>: mapped to <code>MotionEvent.TOOL_TYPE_STYLUS</code>.</p>
+</li>
+<li>
+<p><code>BTN_TOOL_AIRBRUSH</code>: mapped to <code>MotionEvent.TOOL_TYPE_STYLUS</code>.</p>
+</li>
+<li>
+<p><code>BTN_TOOL_MOUSE</code>: mapped to <code>MotionEvent.TOOL_TYPE_MOUSE</code>.</p>
+</li>
+<li>
+<p><code>BTN_TOOL_LENS</code>: mapped to <code>MotionEvent.TOOL_TYPE_MOUSE</code>.</p>
+</li>
+<li>
+<p><code>BTN_TOOL_DOUBLETAP</code>, <code>BTN_TOOL_TRIPLETAP</code>, and <code>BTN_TOOL_QUADTAP</code>:
+    mapped to <code>MotionEvent.TOOL_TYPE_FINGER</code>.</p>
+</li>
+</ul>
+<h2 id="hovering-vs-touching-tools">Hovering vs. Touching Tools</h2>
+<p>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.</p>
+<p>The <code>InputReader</code> component takes care to distinguish touching tools from hovering
+tools.  Likewise, touching tools and hovering tools are reported to applications
+in different ways.</p>
+<p>Touching tools are reported to applications as touch events
+using <code>MotionEvent.ACTION_DOWN</code>, <code>MotionEvent.ACTION_MOVE</code>, <code>MotionEvent.ACTION_DOWN</code>,
+<code>MotionEvent.ACTION_POINTER_DOWN</code> and <code>MotionEvent.ACTION_POINTER_UP</code>.</p>
+<p>Hovering tools are reported to applications as generic motion events using
+<code>MotionEvent.ACTION_HOVER_ENTER</code>, <code>MotionEvent.ACTION_HOVER_MOVE</code>
+and <code>MotionEvent.ACTION_HOVER_EXIT</code>.</p>
+<h2 id="touch-device-driver-requirements">Touch Device Driver Requirements</h2>
+<ol>
+<li>
+<p>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.</p>
+<p>For example, if the device reports the <code>BTN_TOUCH</code> key code, the system will
+assume that <code>BTN_TOUCH</code> will always be used to indicate whether the tool is
+actually touching the screen or is merely in range and hovering.</p>
+</li>
+<li>
+<p>Single-touch devices use the following Linux input events:</p>
+<ul>
+<li>
+<p><code>ABS_X</code>: <em>(REQUIRED)</em> Reports the X coordinate of the tool.</p>
+</li>
+<li>
+<p><code>ABS_Y</code>: <em>(REQUIRED)</em> Reports the Y coordinate of the tool.</p>
+</li>
+<li>
+<p><code>ABS_PRESSURE</code>: <em>(optional)</em> Reports the physical pressure applied to the tip
+    of the tool or the signal strength of the touch contact.</p>
+</li>
+<li>
+<p><code>ABS_TOOL_WIDTH</code>: <em>(optional)</em> Reports the cross-sectional area or width of the
+    touch contact or of the tool itself.</p>
+</li>
+<li>
+<p><code>ABS_DISTANCE</code>: <em>(optional)</em> Reports the distance of the tool from the surface of
+    the touch device.</p>
+</li>
+<li>
+<p><code>ABS_TILT_X</code>: <em>(optional)</em> Reports the tilt of the tool from the surface of the
+    touch device along the X axis.</p>
+</li>
+<li>
+<p><code>ABS_TILT_Y</code>: <em>(optional)</em> Reports the tilt of the tool from the surface of the
+    touch device along the Y axis.</p>
+</li>
+<li>
+<p><code>BTN_TOUCH</code>: <em>(REQUIRED)</em> Indicates whether the tool is touching the device.</p>
+</li>
+<li>
+<p><code>BTN_LEFT</code>, <code>BTN_RIGHT</code>, <code>BTN_MIDDLE</code>, <code>BTN_BACK</code>, <code>BTN_SIDE</code>, <code>BTN_FORWARD</code>,
+    <code>BTN_EXTRA</code>, <code>BTN_STYLUS</code>, <code>BTN_STYLUS2</code>:
+    <em>(optional)</em> Reports <a href="#buttons">button</a> states.</p>
+</li>
+<li>
+<p><code>BTN_TOOL_FINGER</code>, <code>BTN_TOOL_PEN</code>, <code>BTN_TOOL_RUBBER</code>, <code>BTN_TOOL_BRUSH</code>,
+    <code>BTN_TOOL_PENCIL</code>, <code>BTN_TOOL_AIRBRUSH</code>, <code>BTN_TOOL_MOUSE</code>, <code>BTN_TOOL_LENS</code>,
+    <code>BTN_TOOL_DOUBLETAP</code>, <code>BTN_TOOL_TRIPLETAP</code>, <code>BTN_TOOL_QUADTAP</code>:
+    <em>(optional)</em> Reports the <a href="#tools-and-tool-types">tool type</a>.</p>
+</li>
+</ul>
+</li>
+<li>
+<p>Multi-touch devices use the following Linux input events:</p>
+<ul>
+<li>
+<p><code>ABS_MT_POSITION_X</code>: <em>(REQUIRED)</em> Reports the X coordinate of the tool.</p>
+</li>
+<li>
+<p><code>ABS_MT_POSITION_Y</code>: <em>(REQUIRED)</em> Reports the Y coordinate of the tool.</p>
+</li>
+<li>
+<p><code>ABS_MT_PRESSURE</code>: <em>(optional)</em> Reports the physical pressure applied to the
+    tip of the tool or the signal strength of the touch contact.</p>
+</li>
+<li>
+<p><code>ABS_MT_TOUCH_MAJOR</code>: <em>(optional)</em> Reports the cross-sectional area of the
+    touch contact, or the length of the longer dimension of the touch contact.</p>
+</li>
+<li>
+<p><code>ABS_MT_TOUCH_MINOR</code>: <em>(optional)</em> Reports the length of the shorter dimension of the
+    touch contact.  This axis should not be used if <code>ABS_MT_TOUCH_MAJOR</code> is reporting an
+    area measurement.</p>
+</li>
+<li>
+<p><code>ABS_MT_WIDTH_MAJOR</code>: <em>(optional)</em> 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.</p>
+</li>
+<li>
+<p><code>ABS_MT_WIDTH_MINOR</code>: <em>(optional)</em> Reports the length of the shorter dimension of
+    the tool itself. This axis should not be used if <code>ABS_MT_WIDTH_MAJOR</code> is reporting
+    an area measurement or if the dimensions of the tool itself are unknown.</p>
+</li>
+<li>
+<p><code>ABS_MT_ORIENTATION</code>: <em>(optional)</em> Reports the orientation of the tool.</p>
+</li>
+<li>
+<p><code>ABS_MT_DISTANCE</code>: <em>(optional)</em> Reports the distance of the tool from the
+    surface of the touch device.</p>
+</li>
+<li>
+<p><code>ABS_MT_TOOL_TYPE</code>: <em>(optional)</em> Reports the <a href="#tools-and-tool-types">tool type</a> as
+    <code>MT_TOOL_FINGER</code> or <code>MT_TOOL_PEN</code>.</p>
+</li>
+<li>
+<p><code>ABS_MT_TRACKING_ID</code>: <em>(optional)</em> 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.</p>
+</li>
+<li>
+<p><code>ABS_MT_SLOT</code>: <em>(optional)</em> 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.</p>
+</li>
+<li>
+<p><code>BTN_TOUCH</code>: <em>(REQUIRED)</em> Indicates whether the tool is touching the device.</p>
+</li>
+<li>
+<p><code>BTN_LEFT</code>, <code>BTN_RIGHT</code>, <code>BTN_MIDDLE</code>, <code>BTN_BACK</code>, <code>BTN_SIDE</code>, <code>BTN_FORWARD</code>,
+    <code>BTN_EXTRA</code>, <code>BTN_STYLUS</code>, <code>BTN_STYLUS2</code>:
+    <em>(optional)</em> Reports <a href="#buttons">button</a> states.</p>
+</li>
+<li>
+<p><code>BTN_TOOL_FINGER</code>, <code>BTN_TOOL_PEN</code>, <code>BTN_TOOL_RUBBER</code>, <code>BTN_TOOL_BRUSH</code>,
+    <code>BTN_TOOL_PENCIL</code>, <code>BTN_TOOL_AIRBRUSH</code>, <code>BTN_TOOL_MOUSE</code>, <code>BTN_TOOL_LENS</code>,
+    <code>BTN_TOOL_DOUBLETAP</code>, <code>BTN_TOOL_TRIPLETAP</code>, <code>BTN_TOOL_QUADTAP</code>:
+    <em>(optional)</em> Reports the <a href="#tools-and-tool-types">tool type</a>.</p>
+</li>
+</ul>
+</li>
+<li>
+<p>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.</p>
+</li>
+<li>
+<p>The minimum and maximum values of the <code>ABS_X</code>, <code>ABS_Y</code>, <code>ABS_MT_POSITION_X</code>
+    and <code>ABS_MT_POSITION_Y</code> 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.</p>
+<p>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:</p>
+<pre><code>displayX = (x - minX) * displayWidth / (maxX - minX + 1)
+displayY = (y - minY) * displayHeight / (maxY - minY + 1)
+</code></pre>
+<p>A touch screen may report touches outside of the reported active area.</p>
+<p>Touches that are initiated outside the active area are not delivered to applications
+but may be used for virtual keys.</p>
+<p>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.</p>
+<p>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.</p>
+<p>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 <em>not</em> be reporting (minX, minY)
+when the user's finger is really touching outside of the active area.</p>
+<p>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.</p>
+</li>
+<li>
+<p>The values reported by <code>ABS_PRESSURE</code> or <code>ABS_MT_PRESSURE</code>, 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.</p>
+<p>Reporting pressure information is <em>optional</em> but strongly recommended.
+Applications can use pressure information to implement pressure-sensitive drawing
+and other effects.</p>
+</li>
+<li>
+<p>The values reported by <code>ABS_TOOL_WIDTH</code>, <code>ABS_MT_TOUCH_MAJOR</code>, <code>ABS_MT_TOUCH_MINOR</code>,
+    <code>ABS_MT_WIDTH_MAJOR</code>, or <code>ABS_MT_WIDTH_MINOR</code> 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.</p>
+<p>Reporting size information is <em>optional</em> but strongly recommended.
+Applications can use pressure information to implement size-sensitive drawing
+and other effects.</p>
+</li>
+<li>
+<p>The values reported by <code>ABS_DISTANCE</code> or <code>ABS_MT_DISTANCE</code> 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.</p>
+<p>Reporting distance information is <em>optional</em> but recommended for
+stylus devices.</p>
+</li>
+<li>
+<p>The values reported by <code>ABS_TILT_X</code> and <code>ABS_TILT_Y</code> 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.</p>
+<p>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 <code>(max + min) / 2</code> 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.</p>
+<p>The <code>InputReader</code> converts the X and Y tilt components into a perpendicular
+tilt angle ranging from 0 to <code>PI / 2</code> radians and a planar orientation angle
+ranging from <code>-PI</code> to <code>PI</code> radians.  This representation results in a
+description of orientation that is compatible with what is used to describe
+finger touches.</p>
+<p>Reporting tilt information is <em>optional</em> but recommended for stylus devices.</p>
+</li>
+<li>
+<p>If the tool type is reported by <code>ABS_MT_TOOL_TYPE</code>, it will supercede any tool
+    type information reported by <code>BTN_TOOL_*</code>.
+    If no tool type information is available at all, the tool type defaults to
+    <code>MotionEvent.TOOL_TYPE_FINGER</code>.</p>
+</li>
+<li>
+<p>A tool is determined to be active based on the following conditions:</p>
+<ul>
+<li>
+<p>When using the single-touch protocol, the tool is active if <code>BTN_TOUCH</code>,
+    or <code>BTN_TOOL_*</code> is 1.</p>
+<p>This condition implies that the <code>InputReader</code> 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).</p>
+</li>
+<li>
+<p>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.</p>
+</li>
+<li>
+<p>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.</p>
+</li>
+</ul>
+</li>
+<li>
+<p>A tool is determined to be hovering based on the following conditions:</p>
+<ul>
+<li>
+<p>If the tool is <code>BTN_TOOL_MOUSE</code> or <code>BTN_TOOL_LENS</code>, then the tool
+    is not hovering, even if either of the following conditions are true.</p>
+</li>
+<li>
+<p>If the tool is active and the driver reports pressure information,
+    and the reported pressure is zero, then the tool is hovering.</p>
+</li>
+<li>
+<p>If the tool is active and the driver supports the <code>BTN_TOUCH</code> key code and
+    <code>BTN_TOUCH</code> has a value of zero, then the tool is hovering.</p>
+</li>
+</ul>
+</li>
+<li>
+<p>The <code>InputReader</code> supports both multi-touch protocol 'A' and 'B'.  New drivers
+    should use the 'B' protocol but either will work.</p>
+</li>
+<li>
+<p><strong>As of Android Ice Cream Sandwich 4.0, touch screen drivers may need to be changed
+    to comply with the Linux input protocol specification.</strong></p>
+<p>The following changes may be required:</p>
+<ul>
+<li>
+<p>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 <code>SYN_MT_REPORT</code> followed by <code>SYN_REPORT</code>.</p>
+<p>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.</p>
+</li>
+<li>
+<p>Physical pressure or signal strength information should be reported using
+    <code>ABS_MT_PRESSURE</code>.</p>
+<p>Previous versions of Android retrieved pressure information from
+<code>ABS_MT_TOUCH_MAJOR</code>.  The old behavior was incompatible with the
+Linux input protocol specification and is no longer supported.</p>
+</li>
+<li>
+<p>Touch size information should be reported using <code>ABS_MT_TOUCH_MAJOR</code>.</p>
+<p>Previous versions of Android retrieved size information from
+<code>ABS_MT_TOOL_MAJOR</code>.  The old behavior was incompatible with the
+Linux input protocol specification and is no longer supported.</p>
+</li>
+</ul>
+<p>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.</p>
+</li>
+</ol>
+<h2 id="touch-device-operation">Touch Device Operation</h2>
+<p>The following is a brief summary of the touch device operation on Android.</p>
+<ol>
+<li>
+<p>The <code>EventHub</code> reads raw events from the <code>evdev</code> driver.</p>
+</li>
+<li>
+<p>The <code>InputReader</code> consumes the raw events and updates internal state about
+    the position and other characteristics of each tool.  It also tracks
+    button states.</p>
+</li>
+<li>
+<p>If the BACK or FORWARD buttons were pressed or released, the <code>InputReader</code>
+    notifies the <code>InputDispatcher</code> about the key event.</p>
+</li>
+<li>
+<p>The <code>InputReader</code> determines whether a virtual key press occurred.  If so,
+    it notifies the <code>InputDispatcher</code> about the key event.</p>
+</li>
+<li>
+<p>The <code>InputReader</code> determines whether the touch was initiated within the
+    bounds of the display.  If so, it notifies the <code>InputDispatcher</code> about
+    the touch event.</p>
+</li>
+<li>
+<p>If there are no touching tools but there is at least one hovering tool,
+    the <code>InputReader</code> notifies the <code>InputDispatcher</code> about the hover event.</p>
+</li>
+<li>
+<p>If the touch device type is <em>pointer</em>, the <code>InputReader</code> performs pointer
+    gesture detection, moves the pointer and spots accordingly and notifies
+    the <code>InputDispatcher</code> about the pointer event.</p>
+</li>
+<li>
+<p>The <code>InputDispatcher</code> uses the <code>WindowManagerPolicy</code> to determine whether
+    the events should be dispatched and whether they should wake the device.
+    Then, the <code>InputDispatcher</code> delivers the events to the appropriate applications.</p>
+</li>
+</ol>
+<h2 id="touch-device-configuration">Touch Device Configuration</h2>
+<p>Touch device behavior is determined by the device's axes, buttons, input properties,
+input device configuration, virtual key map and key layout.</p>
+<p>Refer to the following sections for more details about the files that
+participate in keyboard configuration:</p>
+<ul>
+<li><a href="/tech/input/input-device-configuration-files.html">Input Device Configuration Files</a></li>
+<li><a href="#virtual-key-map-files">Virtual Key Map Files</a></li>
+</ul>
+<h3 id="properties">Properties</h3>
+<p>The system relies on many input device configuration properties to configure
+and calibrate touch device behavior.</p>
+<p>One reason for this is that the device drivers for touch devices often report
+the characteristics of touches using device-specific units.</p>
+<p>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.</p>
+<p>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.</p>
+<h3 id="documentation-conventions">Documentation Conventions</h3>
+<p>For documentation purposes, we will use the following conventions to describe
+the values used by the system during the calibration process.</p>
+<h4 id="raw-axis-values">Raw Axis Values</h4>
+<p>The following expressions denote the raw values reported by the touch
+device driver as <code>EV_ABS</code> events.</p>
+<dl>
+<dt><code>raw.x</code></dt>
+<dd>The value of the <code>ABS_X</code> or <code>ABS_MT_POSITION_X</code> axis.</dd>
+<dt><code>raw.y</code></dt>
+<dd>The value of the <code>ABS_Y</code> or <code>ABS_MT_POSITION_Y</code> axis.</dd>
+<dt><code>raw.pressure</code></dt>
+<dd>The value of the <code>ABS_PRESSURE</code> or <code>ABS_MT_PRESSURE</code> axis, or 0 if not available.</dd>
+<dt><code>raw.touchMajor</code></dt>
+<dd>The value of the <code>ABS_MT_TOUCH_MAJOR</code> axis, or 0 if not available.</dd>
+<dt><code>raw.touchMinor</code></dt>
+<dd>The value of the <code>ABS_MT_TOUCH_MINOR</code> axis, or <code>raw.touchMajor</code> if not available.</dd>
+<dt><code>raw.toolMajor</code></dt>
+<dd>The value of the <code>ABS_TOOL_WIDTH</code> or <code>ABS_MT_WIDTH_MAJOR</code> axis, or 0 if not available.</dd>
+<dt><code>raw.toolMinor</code></dt>
+<dd>The value of the <code>ABS_MT_WIDTH_MINOR</code> axis, or <code>raw.toolMajor</code> if not available.</dd>
+<dt><code>raw.orientation</code></dt>
+<dd>The value of the <code>ABS_MT_ORIENTATION</code> axis, or 0 if not available.</dd>
+<dt><code>raw.distance</code></dt>
+<dd>The value of the <code>ABS_DISTANCE</code> or <code>ABS_MT_DISTANCE</code> axis, or 0 if not available.</dd>
+<dt><code>raw.tiltX</code></dt>
+<dd>The value of the <code>ABS_TILT_X</code> axis, or 0 if not available.</dd>
+<dt><code>raw.tiltY</code></dt>
+<dd>The value of the <code>ABS_TILT_Y</code> axis, or 0 if not available.</dd>
+</dl>
+<h4 id="raw-axis-ranges">Raw Axis Ranges</h4>
+<p>The following expressions denote the bounds of raw values.  They are obtained
+by calling <code>EVIOCGABS</code> ioctl for each axis.</p>
+<dl>
+<dt><code>raw.*.min</code></dt>
+<dd>The inclusive minimum value of the raw axis.</dd>
+<dt><code>raw.*.max</code></dt>
+<dd>The inclusive maximum value of the raw axis.</dd>
+<dt><code>raw.*.range</code></dt>
+<dd>Equivalent to <code>raw.*.max - raw.*.min</code>.</dd>
+<dt><code>raw.*.fuzz</code></dt>
+<dd>The accuracy of the raw axis.  eg. fuzz = 1 implies values are accurate to +/- 1 unit.</dd>
+<dt><code>raw.width</code></dt>
+<dd>The inclusive width of the touch area, equivalent to <code>raw.x.range + 1</code>.</dd>
+<dt><code>raw.height</code></dt>
+<dd>The inclusive height of the touch area, equivalent to <code>raw.y.range + 1</code>.</dd>
+</dl>
+<h4 id="output-ranges">Output Ranges</h4>
+<p>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.</p>
+<dl>
+<dt><code>output.width</code></dt>
+<dd>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 <code>raw.width</code>, indicating that no interpolation will
+be performed.</dd>
+<dt><code>output.height</code></dt>
+<dd>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 <code>raw.height</code>, indicating that no interpolation will
+be performed.</dd>
+<dt><code>output.diag</code></dt>
+<dd>The diagonal length of the output coordinate system, equivalent to
+<code>sqrt(output.width ^2 + output.height ^2)</code>.</dd>
+</dl>
+<h3 id="basic-configuration">Basic Configuration</h3>
+<p>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.</p>
+<h4 id="touchdevicetype"><code>touch.deviceType</code></h4>
+<p><em>Definition:</em> <code>touch.deviceType</code> = <code>touchScreen</code> | <code>touchPad</code> | <code>pointer</code> | <code>default</code></p>
+<p>Specifies the touch device type.</p>
+<ul>
+<li>
+<p>If the value is <code>touchScreen</code>, the touch device is a touch screen associated
+    with a display.</p>
+</li>
+<li>
+<p>If the value is <code>touchPad</code>, the touch device is a touch pad not associated
+    with a display.</p>
+</li>
+<li>
+<p>If the value is <code>pointer</code>, the touch device is a touch pad not associated
+    with a display, and its motions are used for
+    <a href="#indirect-multi-touch-pointer-gestures">indirect multi-touch pointer gestures</a>.</p>
+</li>
+<li>
+<p>If the value is <code>default</code>, the system automatically detects the device type
+    according to the classification algorithm.</p>
+</li>
+</ul>
+<p>Refer to the <a href="#touch-device-classification">Classification</a> section for more details
+about how the device type influences the behavior of the touch device.</p>
+<p>Prior to Honeycomb, all touch devices were assumed to be touch screens.</p>
+<h4 id="touchorientationaware"><code>touch.orientationAware</code></h4>
+<p><em>Definition:</em> <code>touch.orientationAware</code> = <code>0</code> | <code>1</code></p>
+<p>Specifies whether the touch device should react to display orientation changes.</p>
+<ul>
+<li>
+<p>If the value is <code>1</code>, touch positions reported by the touch device are rotated
+    whenever the display orientation changes.</p>
+</li>
+<li>
+<p>If the value is <code>0</code>, touch positions reported by the touch device are immune
+    to display orientation changes.</p>
+</li>
+</ul>
+<p>The default value is <code>1</code> if the device is a touch screen, <code>0</code> otherwise.</p>
+<p>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.</p>
+<p>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.</p>
+<p>Prior to Honeycomb, all touch devices were assumed to be orientation aware.</p>
+<h4 id="touchgesturemode"><code>touch.gestureMode</code></h4>
+<p><em>Definition:</em> <code>touch.gestureMode</code> = <code>pointer</code> | <code>spots</code> | <code>default</code></p>
+<p>Specifies the presentation mode for pointer gestures.  This configuration property
+is only relevant when the touch device is of type <em>pointer</em>.</p>
+<ul>
+<li>
+<p>If the value is <code>pointer</code>, the touch pad gestures are presented by way of a cursor
+    similar to a mouse pointer.</p>
+</li>
+<li>
+<p>If the value is <code>spots</code>, 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.</p>
+</li>
+</ul>
+<p>The default value is <code>pointer</code> when the <code>INPUT_PROP_SEMI_MT</code> input property
+is set, or <code>spots</code> otherwise.</p>
+<h3 id="x-and-y-fields"><code>X</code> and <code>Y</code> Fields</h3>
+<p>The X and Y fields provide positional information for the center of the contact area.</p>
+<h4 id="calculation">Calculation</h4>
+<p>The calculation is straightforward: positional information from the touch driver is
+linearly interpolated to the output coordinate system.</p>
+<pre><code>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
+</code></pre>
+<h3 id="touchmajor-touchminor-toolmajor-toolminor-size-fields"><code>TouchMajor</code>, <code>TouchMinor</code>, <code>ToolMajor</code>, <code>ToolMinor</code>, <code>Size</code> Fields</h3>
+<p>The <code>TouchMajor</code> and <code>TouchMinor</code> fields describe the approximate dimensions
+of the contact area in output units (pixels).</p>
+<p>The <code>ToolMajor</code> and <code>ToolMinor</code> fields describe the approximate dimensions
+of the <a href="#tools-and-tool-types">tool</a> itself in output units (pixels).</p>
+<p>The <code>Size</code> 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).</p>
+<p>When both the approximate length and breadth can be measured, then the <code>TouchMajor</code> field
+specifies the longer dimension and the <code>TouchMinor</code> field specifies the shorter dimension
+of the contact area.  When only the approximate diameter of the contact area can be measured,
+then the <code>TouchMajor</code> and <code>TouchMinor</code> fields will be equal.</p>
+<p>Likewise, the <code>ToolMajor</code> field specifies the longer dimension and the <code>ToolMinor</code>
+field specifies the shorter dimension of the tool's cross-sectional area.</p>
+<p>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.</p>
+<p>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.</p>
+<h4 id="touchsizecalibration"><code>touch.size.calibration</code></h4>
+<p><em>Definition:</em> <code>touch.size.calibration</code> = <code>none</code> | <code>geometric</code> | <code>diameter</code>
+| <code>area</code> | <code>default</code></p>
+<p>Specifies the kind of measurement used by the touch driver to report the
+touch size and tool size.</p>
+<ul>
+<li>
+<p>If the value is <code>none</code>, the size is set to zero.</p>
+</li>
+<li>
+<p>If the value is <code>geometric</code>, the size is assumed to be specified in the same
+    surface units as the position, so it is scaled in the same manner.</p>
+</li>
+<li>
+<p>If the value is <code>diameter</code>, the size is assumed to be proportional to
+    the diameter (width) of the touch or tool.</p>
+</li>
+<li>
+<p>If the value is <code>area</code>, the size is assumed to be proportional to the
+    area of the touch or tool.</p>
+</li>
+<li>
+<p>If the value is <code>default</code>, the system uses the <code>geometric</code> calibration if the
+    <code>raw.touchMajor</code> or <code>raw.toolMajor</code> axis is available, otherwise it uses
+    the <code>none</code> calibration.</p>
+</li>
+</ul>
+<h4 id="touchsizescale"><code>touch.size.scale</code></h4>
+<p><em>Definition:</em> <code>touch.size.scale</code> = &lt;a non-negative floating point number&gt;</p>
+<p>Specifies a constant scale factor used in the calibration.</p>
+<p>The default value is <code>1.0</code>.</p>
+<h4 id="touchsizebias"><code>touch.size.bias</code></h4>
+<p><em>Definition:</em> <code>touch.size.bias</code> = &lt;a non-negative floating point number&gt;</p>
+<p>Specifies a constant bias value used in the calibration.</p>
+<p>The default value is <code>0.0</code>.</p>
+<h4 id="touchsizeissummed"><code>touch.size.isSummed</code></h4>
+<p><em>Definition:</em> <code>touch.size.isSummed</code> = <code>0</code> | <code>1</code></p>
+<p>Specifies whether the size is reported as the sum of the sizes of all
+active contacts, or is reported individually for each contact.</p>
+<ul>
+<li>
+<p>If the value is <code>1</code>, the reported size will be divided by the number
+    of contacts prior to use.</p>
+</li>
+<li>
+<p>If the value is <code>0</code>, the reported size will be used as is.</p>
+</li>
+</ul>
+<p>The default value is <code>0</code>.</p>
+<p>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
+<code>1</code> for such devices.  If in doubt, set this value to <code>0</code>.</p>
+<h4 id="calculation_1">Calculation</h4>
+<p>The calculation of the <code>TouchMajor</code>, <code>TouchMinor</code>, <code>ToolMajor</code>, <code>ToolMinor</code>
+and <code>Size</code> fields depends on the specified calibration parameters.</p>
+<pre><code>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
+</code></pre>
+<h3 id="pressure-field"><code>Pressure</code> Field</h3>
+<p>The <code>Pressure</code> 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).</p>
+<p>A zero pressure indicates that the tool is hovering.</p>
+<h4 id="touchpressurecalibration"><code>touch.pressure.calibration</code></h4>
+<p><em>Definition:</em> <code>touch.pressure.calibration</code> = <code>none</code> | <code>physical</code> | <code>amplitude</code> | <code>default</code></p>
+<p>Specifies the kind of measurement used by the touch driver to report the pressure.</p>
+<ul>
+<li>
+<p>If the value is <code>none</code>, the pressure is unknown so it is set to 1.0 when
+    touching and 0.0 when hovering.</p>
+</li>
+<li>
+<p>If the value is <code>physical</code>, the pressure axis is assumed to measure the actual
+    physical intensity of pressure applied to the touch pad.</p>
+</li>
+<li>
+<p>If the value is <code>amplitude</code>, the pressure axis is assumed to measure the signal
+    amplitude, which is related to the size of the contact and the pressure applied.</p>
+</li>
+<li>
+<p>If the value is <code>default</code>, the system uses the <code>physical</code> calibration if the
+    pressure axis available, otherwise uses <code>none</code>.</p>
+</li>
+</ul>
+<h4 id="touchpressurescale"><code>touch.pressure.scale</code></h4>
+<p><em>Definition:</em> <code>touch.pressure.scale</code> = &lt;a non-negative floating point number&gt;</p>
+<p>Specifies a constant scale factor used in the calibration.</p>
+<p>The default value is <code>1.0 / raw.pressure.max</code>.</p>
+<h4 id="calculation_2">Calculation</h4>
+<p>The calculation of the <code>Pressure</code> field depends on the specified calibration parameters.</p>
+<pre><code>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
+</code></pre>
+<h3 id="orientation-and-tilt-fields"><code>Orientation</code> and <code>Tilt</code> Fields</h3>
+<p>The <code>Orientation</code> field describes the orientation of the touch and tool as an
+angular measurement.  An orientation of <code>0</code> indicates that the major axis is
+oriented vertically, <code>-PI/2</code> indicates that the major axis is oriented to the left,
+<code>PI/2</code> 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 <code>-PI</code> or <code>PI</code>.</p>
+<p>The <code>Tilt</code> field describes the inclination of the tool as an angular measurement.
+A tilt of <code>0</code> indicates that the tool is perpendicular to the surface.
+A tilt of <code>PI/2</code> indicates that the tool is flat on the surface.</p>
+<h4 id="touchorientationcalibration"><code>touch.orientation.calibration</code></h4>
+<p><em>Definition:</em> <code>touch.orientation.calibration</code> = <code>none</code> | <code>interpolated</code> | <code>vector</code> | <code>default</code></p>
+<p>Specifies the kind of measurement used by the touch driver to report the orientation.</p>
+<ul>
+<li>
+<p>If the value is <code>none</code>, the orientation is unknown so it is set to 0.</p>
+</li>
+<li>
+<p>If the value is <code>interpolated</code>, the orientation is linearly interpolated such that a
+    raw value of <code>raw.orientation.min</code> maps to <code>-PI/2</code> and a raw value of
+    <code>raw.orientation.max</code> maps to <code>PI/2</code>.  The center value of
+    <code>(raw.orientation.min + raw.orientation.max) / 2</code> maps to <code>0</code>.</p>
+</li>
+<li>
+<p>If the value is <code>vector</code>, 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.</p>
+</li>
+<li>
+<p>If the value is <code>default</code>, the system uses the <code>interpolated</code> calibration if the
+    orientation axis available, otherwise uses <code>none</code>.</p>
+</li>
+</ul>
+<h4 id="calculation_3">Calculation</h4>
+<p>The calculation of the <code>Orientation</code> and <code>Tilt</code> fields depends on the specified
+calibration parameters and available input.</p>
+<pre><code>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 &amp; 0xF0) &gt;&gt; 4
+    c2 = raw.orientation &amp; 0x0F
+
+    If c1 != 0 or c2 != 0:
+        If c1 &gt;= 8 Then c1 = c1 - 16
+        If c2 &gt;= 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
+</code></pre>
+<h3 id="distance-field"><code>Distance</code> Field</h3>
+<p>The <code>Distance</code> 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.</p>
+<h4 id="touchdistancecalibration"><code>touch.distance.calibration</code></h4>
+<p><em>Definition:</em> <code>touch.distance.calibration</code> = <code>none</code> | <code>scaled</code> | <code>default</code></p>
+<p>Specifies the kind of measurement used by the touch driver to report the distance.</p>
+<ul>
+<li>
+<p>If the value is <code>none</code>, the distance is unknown so it is set to 0.</p>
+</li>
+<li>
+<p>If the value is <code>scaled</code>, the reported distance is multiplied by a
+    constant scale factor.</p>
+</li>
+<li>
+<p>If the value is <code>default</code>, the system uses the <code>scaled</code> calibration if the
+    distance axis available, otherwise uses <code>none</code>.</p>
+</li>
+</ul>
+<h4 id="touchdistancescale"><code>touch.distance.scale</code></h4>
+<p><em>Definition:</em> <code>touch.distance.scale</code> = &lt;a non-negative floating point number&gt;</p>
+<p>Specifies a constant scale factor used in the calibration.</p>
+<p>The default value is <code>1.0</code>.</p>
+<h4 id="calculation_4">Calculation</h4>
+<p>The calculation of the <code>Distance</code> field depends on the specified calibration parameters.</p>
+<pre><code>If touch.distance.calibration == "scaled":
+    output.distance = raw.distance * touch.distance.scale
+Else
+    output.distance = 0
+End If
+</code></pre>
+<h3 id="example">Example</h3>
+<pre><code># 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
+</code></pre>
+<h3 id="compatibility-notes">Compatibility Notes</h3>
+<p>The configuration properties for touch devices changed significantly in
+Android Ice Cream Sandwich 4.0.  <strong>All input device configuration files for touch
+devices must be updated to use the new configuration properties.</strong></p>
+<p>Older touch device <a href="#touch-device-driver-requirements">drivers</a> may also need to be
+updated.</p>
+<h2 id="virtual-key-map-files">Virtual Key Map Files</h2>
+<p>Touch devices are often used to implement virtual keys.</p>
+<p>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.</p>
+<p>When virtual keys are implemented in software, the kernel must export a virtual key map
+file called <code>virtualkeys.&lt;devicename&gt;</code> 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 <code>/sys/board_properties/virtualkeys.touchyfeely</code>.</p>
+<p>A virtual key map file describes the coordinates and Linux key codes of virtual keys
+on the touch screen.</p>
+<p>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 <code>SPECIAL_FUNCTION</code>).</p>
+<h3 id="syntax">Syntax</h3>
+<p>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.</p>
+<p>Comment lines begin with '#' and continue to the end of the line.</p>
+<p>Each virtual key is described by 6 colon-delimited components:</p>
+<ul>
+<li><code>0x01</code>: A version code.  Must always be <code>0x01</code>.</li>
+<li>&lt;Linux key code&gt;: The Linux key code of the virtual key.</li>
+<li>&lt;centerX&gt;: The X pixel coordinate of the center of the virtual key.</li>
+<li>&lt;centerY&gt;: The Y pixel coordinate of the center of the virtual key.</li>
+<li>&lt;width&gt;: The width of the virtual key in pixels.</li>
+<li>&lt;height&gt;: The height of the virtual key in pixels.</li>
+</ul>
+<p>All coordinates and sizes are specified in terms of the display coordinate system.</p>
+<p>Here is a virtual key map file all written on one line.</p>
+<pre><code># 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
+</code></pre>
+<p>The same virtual key map file can also be written on multiple lines.</p>
+<pre><code># 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
+</code></pre>
+<p>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.</p>
+<p>The first key has a Linux scan code of <code>158</code> (<code>KEY_BACK</code>), centerX of <code>55</code>,
+centerY of <code>835</code>, width of <code>90</code> and height of <code>55</code>.</p>
+<h3 id="example_1">Example</h3>
+<p>Virtual key map file: <code>/sys/board_properties/virtualkeys.touchyfeely</code>.</p>
+<pre><code>0x01:158:55:835:90:55
+0x01:139:172:835:125:55
+0x01:102:298:835:115:55
+0x01:217:412:835:95:55
+</code></pre>
+<p>Key layout file: <code>/system/usr/keylayout/touchyfeely.kl</code>.</p>
+<pre><code>key 158 BACK
+key 139 MENU
+key 102 HOME
+key 217 SEARCH
+</code></pre>
+<p>Key character map file: <code>/system/usr/keychars/touchyfeely.kcm</code>.</p>
+<pre><code>type SPECIAL_FUNCTION
+</code></pre>
+<h2 id="indirect-multi-touch-pointer-gestures">Indirect Multi-touch Pointer Gestures</h2>
+<p>In pointer mode, the system interprets the following gestures:</p>
+<ol>
+<li>
+<p>Single finger tap: click.</p>
+</li>
+<li>
+<p>Single finger motion: move the pointer.</p>
+</li>
+<li>
+<p>Single finger motion plus button presses: drag the pointer.</p>
+</li>
+<li>
+<p>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.</p>
+</li>
+<li>
+<p>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.</p>
+</li>
+<li>
+<p>Multiple finger motion: freeform gesture.</p>
+</li>
+</ol>
+<h2 id="further-reading">Further Reading</h2>
+<ol>
+<li><a href="http://www.kernel.org/doc/Documentation/input/multi-touch-protocol.txt">Linux multi-touch protocol</a></li>
+<li><a href="http://lii-enac.fr/en/architecture/linux-input/multitouch-devices.html">ENAC list of available multitouch devices on Linux</a></li>
+</ol>
diff --git a/src/devices/tech/input/validate-keymaps.jd b/src/devices/tech/input/validate-keymaps.jd
new file mode 100644
index 0000000..7730f11
--- /dev/null
+++ b/src/devices/tech/input/validate-keymaps.jd
@@ -0,0 +1,85 @@
+page.title=Validate Keymaps Tool
+@jd:body
+
+<!--
+    Copyright 2010 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.
+-->
+<p>The Android framework has a small tool called <code>validatekeymaps</code> to validate the
+syntax of input device configuration files, key layout files, key character
+maps files and virtual key definition files.</p>
+<h2 id="compilation">Compilation</h2>
+<p>To compile <code>validatekeymaps</code>, set up the development environment, download
+the Android source tree, compile it, then run:</p>
+<pre><code>$ mmm frameworks/base/tools/validatekeymaps
+</code></pre>
+<p>This command should compile a host tool called validatekeymaps into the
+<code>out/host/&amp;lt;os&amp;gt;/bin</code> directory.</p>
+<h2 id="usage">Usage</h2>
+<p>If you ran <code>envsetup.sh</code> to set up your development environment, then the
+<code>validatekeymaps</code> tool should already be on your path.  You can verify
+this by running <code>validatekeymaps</code>.</p>
+<pre><code>$ 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.
+</code></pre>
+<p>Then all you need to do is run <code>validatekeymaps</code> an give it the path of
+one or more files to validate.</p>
+<pre><code>$ validatekeymaps frameworks/base/data/keyboards/Generic.kl
+
+Validating file 'frameworks/base/data/keyboards/Generic.kl'...
+No errors.
+
+Success.
+</code></pre>
+<p>And if there is an error...</p>
+<pre><code>$ validatekeymaps Bad.kl
+
+Validating file 'Bad.kl'...
+E/KeyLayoutMap(87688): Bad.kl:24: Expected keyword, got 'ke'.
+Error -22 parsing key layout file.
+
+Failed!
+</code></pre>
+<h2 id="automation">Automation</h2>
+<p>It is a <em>very</em> good idea to run <code>validatekeymaps</code> on all configuration files
+before installing them on a device.</p>
+<p>The process can easily be automated as part of the build system by using a
+script or a makefile.</p>
+<p>The following sample makefile is based on the contents of
+<code>frameworks/base/data/keyboards/Android.mk</code>.</p>
+<pre><code># 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)
+</code></pre>
diff --git a/src/devices/tech/kernel.jd b/src/devices/tech/kernel.jd
new file mode 100644
index 0000000..af4700b
--- /dev/null
+++ b/src/devices/tech/kernel.jd
@@ -0,0 +1,290 @@
+page.title=Android Kernel Configuration
+@jd:body
+
+<!--
+    Copyright 2010 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.
+-->
+<p>The kernel configuration settings in this document are meant to be used as a base for an Android kernel configuration. All devices should have the options in android-base configuration enabled. While not mandatory, the options in android-recommended configuration enable advanced Android 
+features.</p>
+
+<p>
+Generating kernel config: Assuming you already have a minimalist defconfig for your device, a possible
+way to enable these options would be:</p>
+
+<pre>ARCH=<arch> scripts/kconfig/merge_config.sh <path_to>/<device>_defconfig android/configs/android-base.cfg 
+android/configs/android-recommended.cfg</pre>
+<p>
+This will generate a .config that can then be used to save a new defconfig or
+compile a new kernel with Android features enabled.
+</p>
+<h3>
+Base Configuration
+</h3>
+<pre>
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_CGROUPS=y
+CONFIG_CGROUP_DEBUG=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_RESOURCE_COUNTERS=y
+CONFIG_CGROUP_SCHED=y
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_EMBEDDED=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT=y
+CONFIG_PM_AUTOSLEEP=y
+CONFIG_PM_WAKELOCKS=y
+CONFIG_BLK_DEV_DM=y
+CONFIG_DM_CRYPT=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_INET_ESP=y
+# CONFIG_INET_LRO is not set
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+CONFIG_INET6_AH=y
+CONFIG_INET6_ESP=y
+CONFIG_INET6_IPCOMP=y
+CONFIG_IPV6_MIP6=y
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_NETFILTER=y
+CONFIG_NF_CONNTRACK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_DCCP=y
+CONFIG_NF_CT_PROTO_SCTP=y
+CONFIG_NF_CT_PROTO_UDPLITE=y
+CONFIG_NF_CONNTRACK_AMANDA=y
+CONFIG_NF_CONNTRACK_FTP=y
+CONFIG_NF_CONNTRACK_H323=y
+CONFIG_NF_CONNTRACK_IRC=y
+CONFIG_NF_CONNTRACK_NETBIOS_NS=y
+CONFIG_NF_CONNTRACK_PPTP=y
+CONFIG_NF_CONNTRACK_SANE=y
+CONFIG_NF_CONNTRACK_TFTP=y
+CONFIG_NF_CT_NETLINK=y
+CONFIG_NETFILTER_TPROXY=y
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
+CONFIG_NETFILTER_XT_TARGET_MARK=y
+CONFIG_NETFILTER_XT_TARGET_NFLOG=y
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
+CONFIG_NETFILTER_XT_TARGET_TPROXY=y
+CONFIG_NETFILTER_XT_TARGET_TRACE=y
+CONFIG_NETFILTER_XT_MATCH_COMMENT=y
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_HELPER=y
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
+CONFIG_NETFILTER_XT_MATCH_LENGTH=y
+CONFIG_NETFILTER_XT_MATCH_LIMIT=y
+CONFIG_NETFILTER_XT_MATCH_MAC=y
+CONFIG_NETFILTER_XT_MATCH_MARK=y
+CONFIG_NETFILTER_XT_MATCH_POLICY=y
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+CONFIG_NETFILTER_XT_MATCH_QTAGUID=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA2=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG=y
+CONFIG_NETFILTER_XT_MATCH_SOCKET=y
+CONFIG_NETFILTER_XT_MATCH_STATE=y
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
+CONFIG_NETFILTER_XT_MATCH_STRING=y
+CONFIG_NETFILTER_XT_MATCH_TIME=y
+CONFIG_NETFILTER_XT_MATCH_U32=y
+CONFIG_NF_CONNTRACK_IPV4=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_MATCH_AH=y
+CONFIG_IP_NF_MATCH_ECN=y
+CONFIG_IP_NF_MATCH_TTL=y
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+CONFIG_IP_NF_TARGET_REJECT_SKERR=y
+CONFIG_NF_NAT=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_IP_NF_TARGET_NETMAP=y
+CONFIG_IP_NF_TARGET_REDIRECT=y
+CONFIG_IP_NF_MANGLE=y
+CONFIG_IP_NF_RAW=y
+CONFIG_IP_NF_ARPTABLES=y
+CONFIG_IP_NF_ARPFILTER=y
+CONFIG_IP_NF_ARP_MANGLE=y
+CONFIG_NF_CONNTRACK_IPV6=y
+CONFIG_IP6_NF_IPTABLES=y
+CONFIG_IP6_NF_FILTER=y
+CONFIG_IP6_NF_TARGET_REJECT=y
+CONFIG_IP6_NF_TARGET_REJECT_SKERR=y
+CONFIG_IP6_NF_MANGLE=y
+CONFIG_IP6_NF_RAW=y
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_HTB=y
+CONFIG_NET_CLS_U32=y
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_U32=y
+CONFIG_NET_CLS_ACT=y
+CONFIG_NETDEVICES=y
+CONFIG_TUN=y
+CONFIG_PPP=y
+CONFIG_PPP_BSDCOMP=y
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_MPPE=y
+CONFIG_PPPOLAC=y
+CONFIG_PPPOPNS=y
+CONFIG_FB=y
+CONFIG_SYNC=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_G_ANDROID=y
+CONFIG_USB_OTG_WAKELOCK=y
+CONFIG_SWITCH=y
+CONFIG_RTC_CLASS=y
+CONFIG_STAGING=y
+CONFIG_ANDROID=y
+CONFIG_ANDROID_BINDER_IPC=y
+CONFIG_ASHMEM=y
+CONFIG_ANDROID_LOGGER=y
+CONFIG_ANDROID_LOW_MEMORY_KILLER=y
+CONFIG_ANDROID_INTF_ALARM_DEV=y
+</pre>
+
+<h3>Recommended Configuration</h3>
+
+<pre>
+CONFIG_PANIC_TIMEOUT=5
+CONFIG_KALLSYMS_ALL=y
+CONFIG_PERF_EVENTS=y
+CONFIG_COMPACTION=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_PM_WAKELOCKS_LIMIT=0
+# CONFIG_PM_WAKELOCKS_GC is not set
+CONFIG_PM_RUNTIME=y
+CONFIG_PM_DEBUG=y
+CONFIG_SUSPEND_TIME=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_UID_STAT=y
+CONFIG_MD=y
+CONFIG_DM_UEVENT=y
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_KEYRESET=y
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_XPAD=y
+CONFIG_JOYSTICK_XPAD_FF=y
+CONFIG_JOYSTICK_XPAD_LEDS=y
+CONFIG_INPUT_TABLET=y
+CONFIG_TABLET_USB_ACECAD=y
+CONFIG_TABLET_USB_AIPTEK=y
+CONFIG_TABLET_USB_GTCO=y
+CONFIG_TABLET_USB_HANWANG=y
+CONFIG_TABLET_USB_KBTAB=y
+CONFIG_TABLET_USB_WACOM=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_KEYCHORD=y
+CONFIG_INPUT_UINPUT=y
+CONFIG_INPUT_GPIO=y
+# CONFIG_VT is not set
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_POWER_SUPPLY=y
+CONFIG_BATTERY_ANDROID=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_UHID=y
+CONFIG_USB_HIDDEV=y
+CONFIG_HID_A4TECH=y
+CONFIG_HID_ACRUX=y
+CONFIG_HID_ACRUX_FF=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_BELKIN=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+CONFIG_HID_PRODIKEYS=y
+CONFIG_HID_CYPRESS=y
+CONFIG_HID_DRAGONRISE=y
+CONFIG_DRAGONRISE_FF=y
+CONFIG_HID_EMS_FF=y
+CONFIG_HID_ELECOM=y
+CONFIG_HID_EZKEY=y
+CONFIG_HID_HOLTEK=y
+CONFIG_HID_KEYTOUCH=y
+CONFIG_HID_KYE=y
+CONFIG_HID_UCLOGIC=y
+CONFIG_HID_WALTOP=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_TWINHAN=y
+CONFIG_HID_KENSINGTON=y
+CONFIG_HID_LCPOWER=y
+CONFIG_HID_LOGITECH=y
+CONFIG_LOGITECH_FF=y
+CONFIG_LOGIRUMBLEPAD2_FF=y
+CONFIG_LOGIG940_FF=y
+CONFIG_HID_MAGICMOUSE=y
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+CONFIG_HID_MULTITOUCH=y
+CONFIG_HID_NTRIG=y
+CONFIG_HID_ORTEK=y
+CONFIG_HID_PANTHERLORD=y
+CONFIG_PANTHERLORD_FF=y
+CONFIG_HID_PETALYNX=y
+CONFIG_HID_PICOLCD=y
+CONFIG_HID_PRIMAX=y
+CONFIG_HID_ROCCAT=y
+CONFIG_HID_SAITEK=y
+CONFIG_HID_SAMSUNG=y
+CONFIG_HID_SONY=y
+CONFIG_HID_SPEEDLINK=y
+CONFIG_HID_SUNPLUS=y
+CONFIG_HID_GREENASIA=y
+CONFIG_GREENASIA_FF=y
+CONFIG_HID_SMARTJOYPLUS=y
+CONFIG_SMARTJOYPLUS_FF=y
+CONFIG_HID_TIVO=y
+CONFIG_HID_TOPSEED=y
+CONFIG_HID_THRUSTMASTER=y
+CONFIG_HID_WACOM=y
+CONFIG_HID_WIIMOTE=y
+CONFIG_HID_ZEROPLUS=y
+CONFIG_HID_ZYDACRON=y
+CONFIG_USB_USBNET=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_ION=y
+CONFIG_ANDROID_RAM_CONSOLE=y
+CONFIG_ANDROID_TIMED_GPIO=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_FUSE_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_SCHEDSTATS=y
+CONFIG_TIMER_STATS=y
+CONFIG_SCHED_TRACER=y
+</pre>
\ No newline at end of file
diff --git a/src/devices/tech/power.jd b/src/devices/tech/power.jd
new file mode 100644
index 0000000..3247fbb
--- /dev/null
+++ b/src/devices/tech/power.jd
@@ -0,0 +1,608 @@
+page.title=Power Profiles for Android
+@jd:body
+
+<!--
+    Copyright 2010 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.
+-->
+<div id="qv-wrapper">
+  <div id="qv">
+    <h2>In this document</h2>
+    <ol id="auto-toc"></ol>
+  </div>
+</div>
+
+<p>
+Battery usage information is derived from battery usage statistics and power profile
+values.
+</p>
+
+<h2>
+Battery Usage Statistics
+</h2>
+
+<p>
+Battery usage statistics are tracked by the framework. This involves keeping track of time
+spent by different device components in different states. This includes components such as
+WiFi chipset, Cellular Radio, Bluetooth, GPS, Display and CPU. When these components change
+state from off to on, or from idle to full power, low brightness to high brightness, etc.,
+their controlling service reports to the framework’s BatteryStats service, which collects
+such information over time and persists to storage so that it is available across reboots.
+</p>
+
+<p>
+The service isn’t keeping track of battery current draw information directly. It’s collecting
+mostly timing information so that it can be used to approximate battery consumption by
+different components.
+</p>
+
+<p>
+Consumption of these resources is also (where possible) attributed to the applications using
+the resources, sometimes sharing the blame across multiple applications using a resource
+simultaneously. For instance, multiple apps could be holding wakelocks, keeping the system
+from going into suspend state. Blame is shared across these apps (not necessarily equally).
+</p>
+
+<p>
+Statistics are persisted to flash periodically (approximately every half hour or so) to avoid
+losing the information on a shutdown (such as due to battery reaching zero remaining
+capacity, which may indicate a battery power consumption problem).
+</p>
+
+<p>
+Statistics gathering can happen in two ways - push or pull. When services are aware of
+changes happening to a component, they will push state changes to the BatteryStats service.
+With components such as the CPU usage by apps, we pull the data periodically (at certain
+transition points such as starting or stopping an activity, etc) to take a snapshot.
+</p>
+
+<p>
+All of the above is automatically done by the framework, and OEMs don’t need to do anything
+in addition to that.
+</p>
+
+<h2>
+Power Profile Values
+</h2>
+
+<p>
+The power profile is where the device manufacturer needs to provide current consumption
+values for various components and their states in order to approximate the actual battery
+drain caused by these components over time. The power consumption of a component is specified
+in units of milliamps (mA) of current draw (at a nominal voltage) in the power profile, and
+can be a fractional value specifying microamps. The value specified should be the mA consumed
+at the battery (and not a value applicable to a power rail that does not correspond to
+current consumed from the battery).
+</p>
+
+<p>
+For instance, to attribute the cost of keeping the display on for a duration of time, the
+framework gathers brightness levels and times spent at each level (quantized to some number
+of bins). The power profile values specify how many milliamps of current are required to keep
+the display on at minimum brightness and at maximum brightness. The time spent at each
+brightness level can then be multiplied by an interpolated display brightness cost to compute
+an approximation of how much battery was drained by the display component.
+</p>
+
+<p>
+Similarly, CPU time for each application is multiplied by the mA to keep the CPU running at a
+certain speed to get a comparative ranking of how much battery each app is consuming due to
+executing CPU code (time as the foreground app and total time including background activity
+are reported separately).
+</p>
+
+<h2>
+Computing power consumption for individual components
+</h2>
+
+<p class="note">
+<strong>Note:</strong> manufacturers usually supply information about how much current an
+individual component consumes. It may be possible to use these values if they are an accurate
+representation of the the current drawn from the device’s battery in practice. However, we
+encourage you validate manufacturer-provided values before entering them in your device’s
+power profile.
+</p>
+
+<p>
+Current consumption for an individual component is calculated by:
+</p>
+
+<ul>
+<li>
+Measuring the current drawn by the device when the component is in the desired state (e.g.,
+on, active, or scanning)
+</li>
+<li>
+Measuring the current drawn by the device when the component is
+off
+</li>
+<li>subtracting (2) from (1).</li>
+
+
+<img></img><p class="img-caption"></p>
+<p>
+We recommend that you measure the current (usually the average instantaneous current) drawn
+on the device at a nominal voltage. This can be accomplished using a bench power supply or
+using specialized battery-monitoring tools (such as Monsoon Solution Inc.’s Power Monitor and
+Power Tool software).
+</p>
+<p>
+Take the measurements with no external charger connected to the device, including no USB
+connection to a host (as used for connecting to development hosts via the adb Android Debug
+Bridge), which may draw current from the host and lower the measurements at the battery. If
+the device supports USB On The Go (OTG) then having an OTG device connected may draw
+additional power from the device being measured, so disconnect any such OTG device.
+</p>
+<p>
+While taking measurements, you’ll want to try to keep the rest of the system other than the
+component being measured running at a constant level of power consumption, to avoid
+introducing inaccuracies in the measurements due to changes in other components. System
+activities that may introduce unwanted changes to power measurements include:
+</p>
+<ul>
+<li>
+Cellular, Wi-Fi, and Bluetooth receive, transmit, or scanning activity. You may want to put
+the device into airplane mode when not measuring cell radio power, and individually enable
+Wi-Fi or Bluetooth when appropriate.
+</li>
+<li>
+Screen/backlight on or off. The colors displayed while screen is on can also affect power
+draw on certain screen technologies. Measurements for components other than the screen on
+values should be made with screen turned off. But see the next item for an important
+consideration when the screen is off.
+</p>
+<li>
+System suspended/resumed state. When the screen is off the system may enter a suspend state
+where much of the device may be powered off or placed in a low-power state, probably
+affecting power consumption of the component being measured and possibly introducing large
+variances in power readings as the system periodically resumes to service alarms and such.
+See Controlling and Measuring System Suspend State for more instructions.
+</li>
+<li>
+CPUs changing speed and entering/exiting low-power scheduler idle state. The system may make
+frequent adjustments to the speeds of CPUs, how many CPU cores are online, and other system
+core state such as memory bus speed and voltages of power rails associated with CPUs and
+memory. If these are changing during your measurements then you may want to prevent CPU speed
+scaling operations, which may also reduce the amount of clock and voltage scaling of memory
+busses and other system core components. Scheduling activity may also affect what percentage
+of the time the CPUs spend in low-power idle states. See Controlling and Measuring CPU Speeds
+for more instructions.
+</li>
+</ul>
+<p>
+For instance, to compute the value for <code>screen.on</code>, you would run the device in a stable state,
+with CPU speed held constant, device in airplane mode, with a partial wakelock held to
+prevent system suspend. The current readings in this state should be stable. Take the reading
+- say 200mA. Now turn on the screen at minimum brightness. If the power monitor shows 300mA,
+then <code>screen.on</code> = (300 - 200) = 100mA.
+</p>
+<p>
+For components that don’t have a flat waveform of current consumption when active (such as
+the cellular radio or wifi), you may need to measure an average current over a period of
+time. Your power monitoring tool may be able to compute this average for you.
+</p>
+<p>
+Replacing the battery with an external power source may require working around problems that
+can occur due to not connecting battery thermistor or integrated fuel gauge pins. For
+example, the system might take an invalid battery temperature reading or remaining battery
+capacity reading that could cause the kernel or Android system to shut down. Sometimes these
+problems are avoided through the use of “fake batteries” that replace normal batteries for
+power measurement purposes, constructed to match the dimensions and electrical properties of
+the batteries for the product being measured. Fake batteries can provide signals on
+thermistor or fuel gauge pins that mimic temperature and state of charge readings for a
+normally running system, and may also provide convenient leads for connecting to external
+power supplies. In other cases it may be easier to modify the system to ignore the invalid
+data from the missing battery.
+</p>
+<h3>
+Controlling and Measuring System Suspend State
+</h3>
+<p>
+As mentioned above, system suspend can introduce unwanted variance in power measurements and
+place system components in low power states not appropriate for measuring active power use.
+But at some point you’ll also need to measure the power draw of system suspend state. This
+section describes how to avoid system suspend state when you don’t want it to interfere with
+other measurements, and how to measure the power draw of system suspend state when you do
+want to measure it.
+</p>
+<p>
+To avoid system suspend you can temporarily connect the device to a development host and
+issue the following command to hold a “partial wakelock”:
+</p>
+<pre>
+$ adb shell "echo temporary &gt; /sys/power/wake_lock"
+</pre>
+<p>
+which will prevent the system from suspending while the screen is off. Disconnect the USB
+cable before making measurements.
+</p>
+<p>
+You can undo the effect of this later with:
+</p>
+<pre>
+$ adb shell "echo temporary &gt; /sys/power/wake_unlock"
+</pre>
+<p>
+The power consumption of the system suspend state is measured for the value of cpu.idle in
+the power profile. For this measurement it may be best to place the device in airplane mode
+to avoid any concurrent activity by the cellular radio, which may run on a processor separate
+from the portions of the SoC controlled by the system suspend. To ensure the measurement is
+made while the system is in the correct state, it may be necessary to first confirm the
+current readings settle to a steady value within the expected range for the consumption of
+the suspend state of the SoC entered plus the consumption of additional system components
+that remain powered (such as the USB PHY). A system console or other external indication of
+system status (such as turning off an LED when not in suspend) may also be observed during
+the measurement.
+</p>
+<h3>
+Controlling and Measuring CPU Speeds
+</h3>
+<p>
+While active, CPUs can be brought online or put offline, change clock speeds and associated
+voltages (possibly also affecting memory bus speeds and other system core power state), and
+can enter lower power idle states while in the kernel idle loop. Not only are these different
+CPU power states measured for the power profile, it may be necessary to avoid the power draw
+variance when measuring other parameters.
+</p>
+<p>
+The power profile currently assumes all CPUs have the same available speeds and power
+characteristics.
+</p>
+<p>
+While measuring CPU power, or holding CPU power constant in order to make other measurements,
+it may be best to hold the number of CPUs brought online constant, such as to have one CPU
+online and the rest offline / hotplugged out. Keeping all CPUs but one in scheduling idle may
+deliver acceptable results. Stopping the Android framework with adb shell stop can help
+reduce system scheduling activity.
+</p>
+<p>
+You’ll specify the available CPU speeds for your device in the power profile cpu.speeds
+entry. You can get a list of these using
+</p>
+<pre>
+adb shell cat /sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state
+</pre>
+<p>
+These speeds are matched with their corresponding power measurements in value <code>cpu.active</code>.
+</p>
+<p>
+If your platform’s power consumption is significantly affected by how many cores are brought
+online then you may need to modify the cpufreq driver or governor for your platform to
+control this. For many platforms, the easiest way to control CPU speed is to use the
+“userspace” cpufreq governor and use sysfs interfaces to set the speed. The exact commands
+differ depending on your platform’s cpufreq implementation. The following commands from the
+system console or adb shell could be used to set a speed for 200MHz on a system with only 1
+CPU, or all CPUs sharing a common cpufreq policy:
+</p>
+<pre>
+echo userspace &gt; /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
+echo 200000 &gt; /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq
+echo 200000 &gt; /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq
+echo 200000 &gt; /sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed
+cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq
+</pre>
+<p>
+which makes sure the new speed is not outside the allowed bounds, sets the new speed, and
+then prints which speed the CPU is actually running at for verification. (If the current
+minimum speed prior to executing the above is above 200000, you may have to reverse the order
+of the first two lines, or execute the first line again, to drop the minimum speed prior to
+setting the maximum speed.)
+</p>
+<p>
+To measure current consumed by a CPU while running at various speeds, you may need to place a
+CPU in a CPU-bound loop such as:
+</p>
+<pre>
+# while true; do true; done
+</pre>
+<p>
+on the system console and take the measurement while the above runs.
+</p>
+<p>
+If your device may limit maximum CPU speed while thermal throttling due to a high temperature
+measurement, possibly as a result of running CPUs at high speeds for sustained periods, then
+watch out for this while taking measurements. You may need to watch system console output, or
+check the kernel log after measuring.
+</p>
+<p>
+For the <code>cpu.active</code> value you can measure the power consumed when the system is not in suspend
+but not executing tasks. The CPU should be in a low-power scheduler “idle loop”, possibly
+executing an ARM Wait For Event instruction or in an SoC-specific low power state with a fast
+exit latency suitable for idle use. There may be more than one idle state in use on your
+platform with differing levels of power consumption; choose a representative idle state for
+longer periods of scheduler idle (several milliseconds). You may need to examine the power
+graph on your measurement equipment and choose samples where the CPU is at its lowest
+consumption, discarding higher samples where the CPU exited idle.
+</p>
+<h3>
+Measuring Screen Power
+</h3>
+<p>
+Screen on power is typically measured with all other devices that are turned on with the
+screen also enabled. For example, the touchscreen and any display backlight would normally
+also be turned on during the measurement, to get a more realistic example of screen on power
+usage.
+</p>
+<p>
+Some display technologies vary in power consumption according to the colors displayed, and so
+power measurements may vary considerably depending on what is on the screen at the time. It’s
+best to choose to display something that has power characteristics of a realistic screen,
+somewhere between the extremes of an all-black screen (which consumes the lowest power for
+some technologies) and an all-white screen. A common choice is a view of a schedule in the
+calendar app, which has a mix of white background and non-white elements.
+</p>
+<p>
+The cost of having the screen on is measured at two points: at minimum display/backlight
+brightness, and at maximum brightness. Setting the display brightness to minimum using the
+Settings app Display Brightness slider might not produce accurate results. The Android UI
+will typically only allow you to set the brightness to a minimum of about 10-20% of the
+possible panel/backlight brightness -- it doesn't allow the user to set brightness so low
+that the screen might not be visible without great effort. If you have a sysfs file that
+controls panel brightness all the way down to the minimum brightness supported by the
+hardware then that's even better.
+</p>
+<p>
+If your platform provides sysfs files that turns the LCD panel, backlight, and touchscreen on
+and off then that’s a good way to take measurements with the screen on and off. Otherwise,
+holding a partial wakelock so the system doesn't go to suspend, and turning on and off the
+screen with the power button, should be fine.
+</p>
+<h3>
+Measuring Wi-Fi Power
+</h3>
+<p>
+It’s recommended to perform Wi-Fi measurements on a relatively quiet network, without
+introducing a lot of additional work processing high volumes of broadcast traffic unrelated
+to the activity being measured.
+</p>
+<p>
+The <code>wifi.on</code> value measures the power consumed when Wi-Fi is enabled but not actively
+transmitting or receiving. This is often measured as the delta between the current draw in
+system suspend (sleep) state with Wi-Fi enabled vs. disabled.
+</p>
+<p>
+The <code>wifi.scan</code> value measures the power consumed during a Wi-Fi scan for access points. Wi-Fi
+scans can be triggered by an app using the WifiManager class <code>startScan()</code> API, which is
+documented at http://developer.android.com/reference/android/net/wifi/WifiManager.html . You
+can also open Settings &gt; Wi-Fi, which will perform scans for access points every few
+seconds with an apparent jump in power consumption, but the screen power must be subtracted
+from these measurements.
+</p>
+<p>
+Network receive and transmit traffic can be generated using controlled setup such as 
+<a href="http://en.wikipedia.org/wiki/Iperf">iperf</a> if desired.
+</p>
+<h2>
+List of values and their meaning
+</h2>
+<table>
+<tr>
+  <th>Name</th>
+  <th>Meaning</th>
+  <th>Example value</th>
+  <th>Notes</th>
+</tr>
+<tr>
+  <td>none</td>
+  <td>Nothing</td>
+  <td>0</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>screen.on</td>
+  <td>Additional power used when screen is turned on at minimum brightness </td>
+  <td>200mA</td>
+  <td>Includes touch controller and display backlight. At 0 brightness, not the Android minimum which tends to be 10 or 20%.</td>
+</tr>
+
+<tr>
+  <td>screen.full</td>
+  <td>Additional power used when screen is at maximum brightness, compared to screen at minimum brightness</td>
+  <td>100- 300mA</td>
+  <td>A fraction of this value (based on screen brightness) is added to the screen.on value to compute the power usage of the screen.</td>
+</tr>
+
+<tr>
+  <td>bluetooth.active </td>
+  <td>Additional power used when playing audio through bluetooth A2DP</td>
+  <td>14mA</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>bluetooth.on</td>
+  <td> Additional power used when bluetooth
+is turned on but idle </td>
+  <td>1.4mA</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>wifi.on </td>
+  <td>Additional power used when wifi is turned on but not
+receiving, transmitting, or scanning</td>
+  <td> 2mA </td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>wifi.active  </td>
+  <td>Additional power used when transmitting
+or receiving over Wifi </td>
+  <td>31mA</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>wifi.scan </td>
+  <td>Additional power used when wifi is scanning for access
+points  </td>
+  <td>100mA</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>dsp.audio </td>
+  <td>Additional power used when audio decoding/encoding via DSP  </td>
+  <td>14.1mA </td>
+  <td>Not
+currently used</td>
+</tr>
+
+
+<tr>
+  <td>dsp.video </td>
+  <td>Additional power used when video decoding via DSP</td>
+  <td> 54mA</td>
+  <td> Not currently
+used </td>
+</tr>
+
+<tr>
+  <td>gps.on </td>
+  <td>Additional power used when GPS is acquiring a signal  </td>
+  <td>50mA</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>radio.active </td>
+  <td>Additional
+power used when cellular radio is transmitting/receiving </td>
+  <td>100- 300mA </td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>radio.scanning </td>
+  <td>Additional
+power used when cellular radio is paging the tower  </td>
+  <td>1.2mA</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>radio.on Additional power used when
+the cellular radio is on. </td>
+  <td>This is a multi-value entry, one per signal strength (no signal,
+weak, moderate, strong)  </td>
+  <td>1.2mA </td>
+  <td>Some radios boost up their power when there’s no signal and
+they’re trying to find a cell tower. So these numbers could all be the same or decreasing
+with increasing signal strength. If you provide only one value, the same value will be used
+for all strengths. If you provide 2 values, the first will be for no-signal and the second
+for all other strengths, and so on.</td>
+</tr>
+
+<tr>
+  <td>cpu.speeds </td>
+  <td>Multi-value entry that lists each possible CPU
+speed in KHz </td>
+  <td>125000, 250000, 500000, 1000000, 1500000 </td>
+  <td>The number and order of entries need to
+correspond to the mA entries in cpu.active </td>
+</tr>
+
+<tr>
+  <td>cpu.idle  </td>
+  <td>Total power drawn by the system when CPUs
+(and the SoC) are in system suspend state </td>
+  <td>3mA</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>cpu.awake 
+</td>
+  <td>Additional power used when CPUs are
+in scheduling idle state (kernel idle loop); system is not in system suspend state </td>
+  <td>50mA</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>cpu.active  </td>
+  <td>Additional power used by CPUs when running at different speeds </td>
+  <td>100, 120, 140, 160,
+200</td>
+  <td>Set the max speed in the kernel to each of the allowed speeds and peg the CPU at that
+speed. The number of entries here correspond to the number of entries in cpu.speeds, in the
+same order. </td>
+</tr>
+
+<tr>
+  <td>battery.capacity  </td>
+  <td>The total battery capacity in mAh</td>
+  <td>3000mAh</td>
+  <td></td>
+</tr>
+
+</table>
+ 
+<p>
+The power_profile.xml file is placed in an overlay in
+device///frameworks/base/core/res/res/xml/power_profile.xml
+</p>
+<h3>
+Sample file
+</h3>
+<pre>
+&lt;!-- Most values are the incremental current used by a feature, in mA (measured at
+nominal voltage). OEM's must measure and provide actual values before shipping a device.
+Example real-world values are given, but they are totally dependent on the platform
+and can vary significantly, so should be measured on the shipping platform with a power meter.
+--&gt;
+0
+200
+160
+10
+&lt;!-- Bluetooth stereo audio playback 10.0 mA --&gt;
+1.3
+0.5
+30
+100
+12
+50
+50
+75
+1.1
+&lt;!-- Strength 0 to BINS-1 (4) --&gt;
+1.1
+
+&lt;!-- Different CPU speeds as reported in
+/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state --&gt;
+
+250000  <!-- 250 MHz -->
+500000  <!-- 500 MHz -->
+750000  <!-- 750 MHz -->
+1000000 <!-- 1   GHz -->
+1200000 <!-- 1.2 GHz -->
+
+&lt;!-- Power consumption when CPU is idle --&gt;
+3.0
+50.1
+&lt;!-- Power consumption at different speeds --&gt;
+
+100 &lt;!-- 250 MHz --&gt;
+120 &lt;!-- 500 MHz --&gt;
+140 &lt;!-- 750 MHz --&gt;
+155 &lt;!-- 1   GHz --&gt;
+175 &lt;!-- 1.2 GHz --&gt;
+
+&lt;!-- This is the battery capacity in mAh --&gt;
+3000
+&lt;!-- Battery capacity is 3000 mAH (at 3.6 Volts) --&gt;
+
+</pre>
\ No newline at end of file
diff --git a/src/devices/tech/security/images/image00.png b/src/devices/tech/security/images/image00.png
new file mode 100644
index 0000000..789dc4e
--- /dev/null
+++ b/src/devices/tech/security/images/image00.png
Binary files differ
diff --git a/src/devices/tech/security/images/image02.png b/src/devices/tech/security/images/image02.png
new file mode 100644
index 0000000..1696a97
--- /dev/null
+++ b/src/devices/tech/security/images/image02.png
Binary files differ
diff --git a/src/devices/tech/security/images/image03.png b/src/devices/tech/security/images/image03.png
new file mode 100644
index 0000000..a231fb3
--- /dev/null
+++ b/src/devices/tech/security/images/image03.png
Binary files differ
diff --git a/src/devices/tech/security/images/image_gmail_installed.png b/src/devices/tech/security/images/image_gmail_installed.png
new file mode 100644
index 0000000..aef5aeb
--- /dev/null
+++ b/src/devices/tech/security/images/image_gmail_installed.png
Binary files differ
diff --git a/src/devices/tech/security/images/image_install.png b/src/devices/tech/security/images/image_install.png
new file mode 100644
index 0000000..87f7516
--- /dev/null
+++ b/src/devices/tech/security/images/image_install.png
Binary files differ
diff --git a/src/devices/tech/security/index.jd b/src/devices/tech/security/index.jd
new file mode 100644
index 0000000..8c5a864
--- /dev/null
+++ b/src/devices/tech/security/index.jd
@@ -0,0 +1,749 @@
+page.title=Android Security Overview
+@jd:body
+
+<!--
+    Copyright 2010 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.
+-->
+<h2 id="introduction">Introduction</h2>
+<p>Android is a modern mobile platform that was designed to be truly open. Android
+applications make use of advanced hardware and software, as well as local and
+served data, exposed through the platform to bring innovation and value to
+consumers. To protect that value, the platform must offer an application
+environment that ensures the security of users, data, applications, the device,
+and the network.</p>
+<p>Securing an open platform requires a robust security architecture and rigorous
+security programs.  Android was designed with multi-layered security that
+provides the flexibility required for an open platform, while providing
+protection for all users of the platform.</p>
+<p>Android was designed with developers in mind. Security controls were designed
+to reduce the burden on developers. Security-savvy developers can easily work
+with and rely on flexible security controls.  Developers less familiar with
+security will be protected by safe defaults.</p>
+<p>Android was designed with device users in mind. Users are provided visibility
+into how applications work, and control over those applications.  This design
+includes the expectation that attackers would attempt to perform common
+attacks, such as social engineering attacks to convince device users to install
+malware, and attacks on third-party applications on Android. Android was
+designed to both reduce the probability of these attacks and greatly limit the
+impact of the attack in the event it was successful.</p>
+<p>This document outlines the goals of the Android security program, describes the
+fundamentals of the Android security architecture, and answers the most
+pertinent questions for system architects and security analysts.  This document
+focuses on the security features of Android's core platform and does not
+discuss security issues that are unique to specific applications, such as those
+related to the browser or SMS application. Recommended best practices for
+building Android devices, deploying Android devices, or developing applications
+for Android are not the goal of this document and are provided elsewhere.</p>
+<h1 id="background">Background</h1>
+<p>Android provides an open source platform and application environment for mobile
+devices.</p>
+<p>The main Android platform building blocks are:</p>
+<ul>
+<li>
+<p><strong>Device Hardware</strong>: Android runs on a wide range of hardware configurations
+including smart phones, tablets, and set-top-boxes.  Android is
+processor-agnostic, but it does take advantage of some hardware-specific
+security capabilities such as ARM v6 eXecute-Never.</p>
+</li>
+<li>
+<p><strong>Android Operating System</strong>: The core operating system is built on top of
+the Linux kernel. All device resources, like camera functions, GPS data,
+Bluetooth functions, telephony functions, network connections, etc. are
+accessed through the operating system.</p>
+</li>
+<li>
+<p><strong>Android Application Runtime</strong>: Android applications are most often written
+in the Java programming language and run in the Dalvik virtual machine.
+However, many applications, including core Android services and applications
+are native applications or include native libraries. Both Dalvik and native
+applications run within the same security environment, contained within the
+Application Sandbox. Applications get a dedicated part of the filesystem in
+which they can write private data, including databases and raw files.</p>
+</li>
+</ul>
+<p>Android applications extend the core Android operating system.  There are two
+primary sources for applications:</p>
+<ul>
+<li>
+<p><strong>Pre-Installed Applications</strong>: Android includes a set of pre-installed
+applications including phone, email, calendar, web browser, and contacts. These
+function both as user applications and to provide key device capabilities that
+can be accessed by other applications.  Pre-installed applications may be part
+of the open source Android platform, or they may be developed by an OEM for a
+specific device.</p>
+</li>
+<li>
+<p><strong>User-Installed Applications</strong>: Android provides an open development
+environment supporting any third-party application. Google Play offers
+users hundreds of thousands of applications.</p>
+</li>
+</ul>
+<p>Google provides a set of cloud-based services that are available to any
+compatible Android device.  The primary services are:</p>
+<ul>
+<li>
+<p><strong>Google Play</strong>: Google Play is a collection of services that
+allow users to discover, install, and purchase applications from their Android
+device or the web.  Google Play makes it easy for developers to reach Android
+users and potential customers.   Google Play also provides community review,
+application <a href="https://developer.android.com/guide/publishing/licensing.html">license
+verification</a>,
+and other security services.</p>
+</li>
+<li>
+<p><strong>Android Updates</strong>: The Android update service delivers new capabilities and
+security updates to Android devices, including updates through the web or over
+the air (OTA).</p>
+</li>
+<li>
+<p><strong>Application Services</strong>: Frameworks that allow Android applications to use
+cloud capabilities such as (<a href="https://developer.android.com/guide/topics/data/backup.html">backing
+up</a>) application
+data and settings and cloud-to-device messaging
+(<a href="https://code.google.com/android/c2dm/index.html">C2DM</a>)
+for push messaging.</p>
+</li>
+</ul>
+<p>These services are not part of the Android Open Source Project and are out
+of scope for this document.  But they are relevant to the security of most
+Android devices, so a related security document titled “Google Services for
+Android: Security Overview” is available.</p>
+<h2 id="android-security-program-overview">Android Security Program Overview</h2>
+<p>Early on in development, the core Android development team recognized that a
+robust security model was required to enable a vigorous ecosystem of
+applications and devices built on and around the Android platform and supported
+by cloud services. As a result, through its entire development lifecycle,
+Android has been subjected to a professional security program. The Android team
+has had the opportunity to observe how other mobile, desktop, and server platforms
+prevented and reacted to security issues and built a security
+program to address weak points observed in other offerings.</p>
+<p>The key components of the Android Security Program include:</p>
+<ul>
+<li><strong>Design Review</strong>: The Android security process begins early in the
+development lifecycle with the creation of a rich and configurable security
+model and design. Each major feature of the platform is reviewed by engineering
+and security resources, with appropriate security controls integrated into the
+architecture of the system.</li>
+<li><strong>Penetration Testing and Code Review</strong>: During the development of the
+platform, Android-created and open-source components are subject to vigorous
+security reviews. These reviews are performed by the Android Security Team,
+Google’s Information Security Engineering team, and independent security
+consultants. The goal of these reviews is to identify weaknesses and possible
+vulnerabilities well before the platform is open-sourced, and to simulate the
+types of analysis that will be performed by external security experts upon
+release.</li>
+<li><strong>Open Source and Community Review</strong>: The Android Open Source Project enables
+broad security review by any interested party. Android also uses open source
+technologies that have undergone significant external security review,
+such as the Linux kernel.  Google Play provides a forum for users and companies
+to provide information about specific applications directly to users.</li>
+<li><strong>Incident Response</strong>: Even with all of these precautions, security issues
+may occur after shipping, which is why the Android project has created a
+comprehensive security response process. A full-time Android security team
+constantly monitors Android-specific and the general security community for
+discussion of potential vulnerabilities. Upon the discovery of legitimate
+issues, the Android team has a response process that enables the rapid
+mitigation of vulnerabilities to ensure that potential risk to all Android
+users is minimized.  These cloud-supported responses can include updating the
+Android platform (over-the-air updates), removing applications from Google
+Play, and removing applications from devices in the field.</li>
+</ul>
+<h2 id="android-platform-security-architecture">Android Platform Security Architecture</h2>
+<p>Android seeks to be the most secure and usable operating system for mobile
+platforms by re-purposing traditional operating system security controls to:</p>
+<ul>
+<li>Protect user data</li>
+<li>Protect system resources (including the network)</li>
+<li>Provide application isolation</li>
+</ul>
+<p>To achieve these objectives, Android provides these key security features:</p>
+<ul>
+<li>Robust security at the OS level through the Linux kernel</li>
+<li>Mandatory application sandbox for all applications</li>
+<li>Secure interprocess communication</li>
+<li>Application signing</li>
+<li>Application-defined and user-granted permissions</li>
+</ul>
+<p>The sections below describe these and other security features of the Android
+platform. <em>Figure 1</em> summarizes the security components and considerations of
+the various levels of the Android software stack. Each component assumes that
+the components below are properly secured. With the exception of a small amount
+of Android OS code running as root, all code above the Linux Kernel is
+restricted by the Application Sandbox.</p>
+<p><img alt="Figure 1: Android software stack" src="images/image00.png" /></p>
+<p><em>Figure 1: Android software stack.</em></p>
+<h1 id="system-and-kernel-level-security">System and Kernel Level Security</h1>
+<p>At the operating system level, the Android platform provides the security of
+the Linux kernel, as well as a secure inter-process communication (IPC)
+facility to enable secure communication between applications running in
+different processes. These security features at the OS level ensure that even
+native code is constrained by the Application Sandbox.  Whether that code is
+the result of included application behavior or a exploitation of an application
+vulnerability, the system would prevent the rogue application from harming
+other applications, the Android system, or the device itself.</p>
+<h2 id="linux-security">Linux Security</h2>
+<p>The foundation of the Android platform is the Linux kernel. The Linux kernel
+itself has been in widespread use for years, and is used in millions of
+security-sensitive environments. Through its history of constantly being
+researched, attacked, and fixed by thousands of developers, Linux has become a
+stable and secure kernel trusted by many corporations and security
+professionals.</p>
+<p>As the base for a mobile computing environment, the Linux kernel provides
+Android with several key security features, including:</p>
+<ul>
+<li>A user-based permissions model</li>
+<li>Process isolation</li>
+<li>Extensible mechanism for secure IPC</li>
+<li>The ability to remove unnecessary and potentially insecure parts of the kernel</li>
+</ul>
+<p>As a multiuser operating system, a fundamental security objective of the Linux
+kernel is to isolate user resources from one another.  The Linux security
+philosophy is to protect user resources from one another. Thus, Linux:</p>
+<ul>
+<li>Prevents user A from reading user B's files</li>
+<li>Ensures that user A does not exhaust user B's memory</li>
+<li>Ensures that user A does not exhaust user B's CPU resources</li>
+<li>Ensures that user A does not exhaust user B's devices (e.g. telephony, GPS,
+bluetooth)</li>
+</ul>
+<h2 id="the-application-sandbox">The Application Sandbox</h2>
+<p>The Android platform takes advantage of the Linux user-based protection as a
+means of identifying and isolating application resources.  The Android system
+assigns a unique user ID (UID) to each Android application and runs it as that user
+in a separate process.  This approach is different from other operating systems
+(including the traditional Linux configuration), where multiple applications
+run with the same user permissions.</p>
+<p>This sets up a kernel-level Application Sandbox. The kernel enforces security
+between applications and the system at the process level through standard Linux
+facilities, such as user and group IDs that are assigned to applications.  By
+default, applications cannot interact with each other and applications have
+limited access to the operating system. If application A tries to do something
+malicious like read application B's data or dial the phone without permission
+(which is a separate application), then the operating system protects against
+this because application A does not have the appropriate user privileges. The
+sandbox is simple, auditable, and based on decades-old UNIX-style user
+separation of processes and file permissions.</p>
+<p>Since the Application Sandbox is in the kernel, this security model extends to
+native code and to operating system applications. All of the software above the
+kernel in <em>Figure 1</em>, including operating system libraries, application
+framework, application runtime, and all applications run within the Application
+Sandbox. On some platforms, developers are constrained to a specific
+development framework, set of APIs, or language in order to enforce security.
+On Android, there are no restrictions on how an application can be written that
+are required to enforce security; in this respect, native code is just as
+secure as interpreted code.</p>
+<p>In some operating systems, memory corruption errors generally lead to
+completely compromising the security of the device. This is not the case in
+Android due to all applications and their resources being sandboxed at the OS
+level. A memory corruption error will only allow arbitrary code execution in
+the context of that particular application, with the permissions established by
+the operating system.</p>
+<p>Like all security features, the Application Sandbox is not unbreakable.
+However, to break out of the Application Sandbox in a properly configured
+device, one must compromise the security of the the Linux kernel.</p>
+<h2 id="system-partition-and-safe-mode">System Partition and Safe Mode</h2>
+<p>The system partition contains Android's kernel as well as the operating system
+libraries, application runtime, application framework, and applications.  This
+partition is set to read-only. When a user boots the device into Safe Mode,
+only core Android applications are available. This ensures that the user can
+boot their phone into an environment that is free of third-party software.</p>
+<h2 id="filesystem-permissions">Filesystem Permissions</h2>
+<p>In a UNIX-style environment, filesystem permissions ensure that one user cannot
+alter or read another user's files. In the case of Android, each application
+runs as its own user. Unless the developer explicitly exposes files to other
+applications, files created by one application cannot be read or altered by
+another application.</p>
+<h2 id="filesystem-encryption">Filesystem Encryption</h2>
+<p>Android 3.0 and later provides full filesystem encryption, so all user data can
+be encrypted in the kernel using the dmcrypt implementation of AES128 with CBC
+and ESSIV:SHA256.   The encryption key is protected by AES128 using a key
+derived from the user password, preventing unauthorized access to stored data
+without the user device password.   To provide resistance against systematic
+password guessing attacks (e.g. “rainbow tables” or brute force), the
+password is combined with a random salt and hashed repeatedly with SHA1 using
+the standard PBKDF2 algorithm prior to being used to decrypt the filesystem
+key. To provide resistance against dictionary password guessing attacks,
+Android provides password complexity rules that can be set by the device
+administrator and enforced by the operating system. Filesystem encryption
+requires the use of a user password, pattern-based screen lock is not supported.</p>
+<p>More details on implementation of filesystem encryption are available at
+<a href="/
+tech/encryption/android_crypto_implementation.html">https://source.android.com/tech/encryption/android_crypto_implementation.html</a></p>
+<h2 id="password-protection">Password Protection</h2>
+<p>Android can be configured to verify a user-supplied password prior to providing
+access to a device. In addition to preventing unauthorized use of the device,
+this password protects the cryptographic key for full filesystem encryption.</p>
+<p>Use of a password and/or password complexity rules can be required by a device
+administrator.</p>
+<h2 id="device-administration">Device Administration</h2>
+<p>Android 2.2 and later provide the Android Device Administration API, which
+provides device administration features at the system level. For example, the
+built-in Android Email application uses the APIs to improve Exchange support.
+Through the Email application, Exchange administrators can enforce password
+policies — including alphanumeric passwords or numeric PINs — across
+devices. Administrators can also remotely wipe (that is, restore factory
+defaults on) lost or stolen handsets.</p>
+<p>In addition to use in applications included with the Android system, these APIs
+are available to third-party providers of Device Management solutions. Details
+on the API are provided here:
+<a href="https://devel
+oper.android.com/guide/topics/admin/device-admin.html">https://developer.android.com/guide/topics/admin/device-admin.html</a>.</p>
+<h2 id="memory-management-security-enhancements">Memory Management Security Enhancements</h2>
+<p>Android includes many features that make common security issues harder to
+exploit. The Android SDK, compilers, and OS use tools to make common memory
+corruption issues significantly harder to exploit, including:</p>
+<p><strong>Android 1.5+</strong></p>
+<ul>
+<li>ProPolice to prevent stack buffer overruns (-fstack-protector)</li>
+<li>safe_iop to reduce integer overflows</li>
+<li>Extensions to OpenBSD dlmalloc to prevent double free() vulnerabilities and
+to prevent chunk consolidation attacks.  Chunk consolidation attacks are a
+common way to exploit heap corruption.</li>
+<li>OpenBSD calloc to prevent integer overflows during memory allocation</li>
+</ul>
+<p><strong>Android 2.3+</strong></p>
+<ul>
+<li>Format string vulnerability protections (-Wformat-security -Werror=format-security)</li>
+<li>Hardware-based No eXecute (NX) to prevent code execution on the stack and heap</li>
+<li>Linux mmap_min_addr to mitigate null pointer dereference privilege
+escalation (further enhanced in Android 4.1)</li>
+</ul>
+<p><strong>Android 4.0+</strong></p>
+<ul>
+<li>Address Space Layout Randomization (ASLR) to randomize key locations in memory</li>
+</ul>
+<p><strong>Android 4.1+</strong></p>
+<ul>
+<li>PIE (Position Independent Executable) support</li>
+<li>Read-only relocations / immediate binding (-Wl,-z,relro -Wl,-z,now)</li>
+<li>dmesg_restrict enabled (avoid leaking kernel addresses)</li>
+<li>kptr_restrict enabled (avoid leaking kernel addresses)</li>
+</ul>
+<h2 id="rooting-of-devices">Rooting of Devices</h2>
+<p>By default, on Android only the kernel and a small subset of the core
+applications run with root permissions. Android does not prevent a user or
+application with root permissions from modifying the operating system, kernel,
+and any other application.  In general, root has full access to all
+applications and all application data. Users that change the permissions on an
+Android device to grant root access to applications increase the security
+exposure to malicious applications and potential application flaws.</p>
+<p>The ability to modify an Android device they own is important to developers
+working with the Android platform. On many Android devices users have the
+ability to unlock the bootloader in order to allow installation of an alternate
+operating system. These alternate operating systems may allow an owner to gain
+root access for purposes of debugging applications and system components or to
+access features not presented to applications by Android APIs.</p>
+<p>On some devices, a person with physical control of a device and a USB cable is
+able to install a new operating system that provides root privileges to the
+user. To protect any existing user data from compromise the bootloader unlock
+mechanism requires that the bootloader erase any existing user data as part of
+the unlock step. Root access gained via exploiting a kernel bug or security
+hole can bypass this protection.</p>
+<p>Encrypting data with a key stored on-device does not protect the application
+data from root users. Applications can add a layer of data protection using
+encryption with a key stored off-device, such as on a server or a user
+password.  This approach can provide temporary protection while the key is not
+present, but at some point the key must be provided to the application and it
+then becomes accessible to root users.</p>
+<p>A more robust approach to protecting data from root users is through the use of
+hardware solutions. OEMs may choose to implement hardware solutions that limit
+access to specific types of content such as DRM for video playback, or the
+NFC-related trusted storage for Google wallet.</p>
+<p>In the case of a lost or stolen device, full filesystem encryption on Android
+devices uses the device password to protect the encryption key, so modifying
+the bootloader or operating system is not sufficient to access user data
+without the user’s device password.</p>
+<h1 id="android-application-security">Android Application Security</h1>
+<h2 id="elements-of-applications">Elements of Applications</h2>
+<p>Android provides an open source platform and application environment for mobile
+devices. The core operating system is based on the Linux kernel. Android
+applications are most often written in the Java programming language and run in
+the Dalvik virtual machine. However, applications can also be written in native
+code. Applications are installed from a single file with the .apk file
+extension.</p>
+<p>The main Android application building blocks are:</p>
+<ul>
+<li>
+<p><strong>AndroidManifest.xml</strong>: The
+<a href="https://developer.android.com/guide/topics/manifest/manifes
+t-intro.html">AndroidManifest.xml</a> file is the control file that tells the system what to do with
+all the top-level components (specifically activities, services, broadcast
+receivers, and content providers described below) in an application. This also
+specifies which permissions are required.</p>
+</li>
+<li>
+<p><strong>Activities</strong>: An
+<a href="https://developer.android.com/guide/topics/fundamentals/activities.htm
+l">Activity</a> is, generally, the code for a single, user-focused task.  It usually
+includes displaying a UI to the user, but it does not have to -- some
+Activities never display UIs.  Typically, one of the application's Activities
+is the entry point to an application.</p>
+</li>
+<li>
+<p><strong>Services</strong>: A
+<a href="https://developer.android.com/guide/topics/fundamentals/services.html">Service</a>
+is a body of code that runs in the background. It can run in its own process,
+or in the context of another application's process. Other components "bind" to
+a Service and invoke methods on it via remote procedure calls. An example of a
+Service is a media player: even when the user quits the media-selection UI, the
+user probably still intends for music to keep playing. A Service keeps the
+music going even when the UI has completed.</p>
+</li>
+<li>
+<p><strong>Broadcast Receiver</strong>: A
+<a href="https://developer.android.com/reference/android/content/Broad
+castReceiver.html">BroadcastReceiver</a> is an object that is instantiated when an IPC mechanism
+known as an
+<a href="https://developer.android.com/reference/android/content/Intent.html">Intent</a>
+is issued by the operating system or another application.  An application may
+register a receiver for the low battery message, for example, and change its
+behavior based on that information.</p>
+</li>
+</ul>
+<h2 id="the-android-permission-model-accessing-protected-apis">The Android Permission Model: Accessing Protected APIs</h2>
+<p>By default, an Android application can only access a limited range of system
+resources. The system manages Android application access to resources that, if
+used incorrectly or maliciously, could adversely impact the user experience,
+the network, or data on the device.</p>
+<p>These restrictions are implemented in a variety of different forms.  Some
+capabilities are restricted by an intentional lack of APIs to the sensitive
+functionality (e.g. there is no Android API for directly manipulating the SIM
+card).  In some instances, separation of roles provides a security measure, as
+with the per-application isolation of storage. In other instances, the
+sensitive APIs are intended for use by trusted applications and protected
+through a security mechanism known as Permissions.</p>
+<p>These protected APIs include:</p>
+<ul>
+<li>Camera functions</li>
+<li>Location data (GPS)</li>
+<li>Bluetooth functions</li>
+<li>Telephony functions</li>
+<li>SMS/MMS functions</li>
+<li>Network/data connections</li>
+</ul>
+<p>These resources are only accessible through the operating system.  To make use
+of the protected APIs on the device, an application must define the
+capabilities it needs in its manifest.  When preparing to install an
+application, the system displays a dialog to the user that indicates the
+permissions requested and asks whether to continue the installation.  If the
+user continues with the installation, the system accepts that the user has
+granted all of the requested permissions. The user can not grant or deny
+individual permissions -- the user must grant or deny all of the requested
+permissions as a block.</p>
+<p>Once granted, the permissions are applied to the application as long as it is
+installed.  To avoid user confusion, the system does not notify the user again
+of the permissions granted to the application, and applications that are
+included in the core operating system or bundled by an OEM do not request
+permissions from the user. Permissions are removed if an application is
+uninstalled, so a subsequent re-installation will again result in display of
+permissions.</p>
+<p>Within the device settings, users are able to view permissions for applications
+they have previously installed. Users can also turn off some functionality
+globally when they choose, such as disabling GPS, radio, or wi-fi.</p>
+<p>In the event that an application attempts to use a protected feature which has
+not been declared in the application's manifest, the permission failure will
+typically result in a security exception being thrown back to the application.
+Protected API permission checks are enforced at the lowest possible level to
+prevent circumvention. An example of the user messaging when an application is
+installed while requesting access to protected APIs is shown in <em>Figure 2</em>.</p>
+<p>The system default permissions are described at
+<a href="https://developer.android.com/reference/android/Manifest.permission.html">https://developer.android.com/reference/android/Manifest.permission.html</a>.
+Applications may declare their own permissions for other applications to use.
+Such permissions are not listed in the above location.</p>
+<p>When defining a permission a protectionLevel attribute tells the system how the
+user is to be informed of applications requiring the permission, or who is
+allowed to hold a permission. Details on creating and using application
+specific permissions are described at
+<a href="https://develo
+per.android.com/guide/topics/security/security.html">https://developer.android.com/guide/topics/security/security.html</a>.</p>
+<p>There are some device capabilities, such as the ability to send SMS broadcast
+intents, that are not available to third-party applications, but that may be
+used by applications pre-installed by the OEM. These permissions use the
+signatureOrSystem permission.</p>
+<h2 id="how-users-understand-third-party-applications">How Users Understand Third-Party Applications</h2>
+<p>Android strives to make it clear to users when they are interacting with
+third-party applications and inform the user of the capabilities those
+applications have.  Prior to installation of any application, the user is shown
+a clear message about the different permissions the application is requesting.
+After install, the user is not prompted again to confirm any permissions.</p>
+<p>There are many reasons to show permissions immediately prior to installation
+time. This is when user is actively reviewing information about the
+application, developer, and functionality to determine whether it matches their
+needs and expectations.  It is also important that they have not yet
+established a mental or financial commitment to the app, and can easily compare
+the application to other alternative applications.</p>
+<p>Some other platforms use a different approach to user notification, requesting
+permission at the start of each session or while applications are in use. The
+vision of Android is to have users switching seamlessly between applications at
+will. Providing confirmations each time would slow down the user and prevent
+Android from delivering a great user experience. Having the user review
+permissions at install time gives the user the option to not install the
+application if they feel uncomfortable.</p>
+<p>Also, many user interface studies have shown that over-prompting the user
+causes the user to start saying "OK" to any dialog that is shown. One of
+Android's security goals is to effectively convey important security
+information to the user, which cannot be done using dialogs that the user will
+be trained to ignore. By presenting the important information once, and only
+when it is important, the user is more likely to think about what they are
+agreeing to.</p>
+<p>Some platforms choose not to show any information at all about application
+functionality. That approach prevents users from easily understanding and
+discussing application capabilities. While it is not possible for all users to
+always make fully informed decisions, the Android permissions model makes
+information about applications easily accessible to a wide range of users.  For
+example, unexpected permissions requests can prompt more sophisticated users to
+ask critical questions about application functionality and share their concerns
+in places such as <a href="htts://play.google.com">Google Play</a> where they
+are visible to all users.</p>
+<table>
+<tr>
+<td><strong>Permissions at Application Install -- Google Maps</strong></td>
+<td><strong>Permissions of an Installed Application -- gMail</strong></td>
+</tr>
+<tr>
+<td>
+<img alt="Permissions at Application Install -- Google Maps" width=250
+src="images/image_install.png"/>
+</td>
+<td>
+<img alt="Permissions of an Installed Application -- gMail" width=250
+src="images/image_gmail_installed.png"/>
+</td>
+</tr>
+</table>
+
+<p><em>Figure 2: Display of permissions for applications</em></p>
+<h2 id="interprocess-communication">Interprocess Communication</h2>
+<p>Processes can communicate using any of the traditional UNIX-type mechanisms.
+Examples include the filesystem, local sockets, or signals. However, the Linux
+permissions still apply.</p>
+<p>Android also provides new IPC mechanisms:</p>
+<ul>
+<li>
+<p><strong>Binder</strong>: A lightweight capability-based remote procedure call mechanism
+designed for high performance when performing in-process and cross-process
+calls. Binder is implemented using a custom Linux driver. See
+<a href="https://developer
+.android.com/reference/android/os/Binder.html">https://developer.android.com/reference/android/os/Binder.html</a>.</p>
+</li>
+<li>
+<p><strong>Services</strong>: Services (discussed above) can provide interfaces directly
+accessible using binder.</p>
+</li>
+<li>
+<p><strong>Intents</strong>: An Intent is a simple message object that represents an
+"intention" to do something. For example, if your application wants to display
+a web page, it expresses its "Intent" to view the URL by creating an Intent
+instance and handing it off to the system. The system locates some other piece
+of code (in this case, the Browser) that knows how to handle that Intent, and
+runs it. Intents can also be used to broadcast interesting events (such as a
+notification) system-wide. See
+[https://developer.android.com/reference/android/content/Intent.html](https://developer.android.com/reference/android/content/Intent.html.</p>
+</li>
+<li>
+<p><strong>ContentProviders</strong>: A ContentProvider is a data storehouse that provides
+access to data on the device; the classic example is the ContentProvider that
+is used to access the user's list of contacts. An application can access data
+that other applications have exposed via a ContentProvider, and an application
+can also define its own ContentProviders to expose data of its own. See
+<a href="https://developer.android.com/reference/android/content/ContentProvider.html">https://developer.android.com/reference/android/content/ContentProvider.html</a>.</p>
+</li>
+</ul>
+<p>While it is possible to implement IPC using other mechanisms such as network
+sockets or world-writable files, these are the recommended Android IPC
+frameworks. Android developers will be encouraged to use best practices around
+securing users' data and avoiding the introduction of security vulnerabilities.</p>
+<h2 id="cost-sensitive-apis">Cost-Sensitive APIs</h2>
+<p>A cost sensitive API is any function that might generate a cost for the user or
+the network. The Android platform has placed cost sensitive APIs in the list of
+protected APIs controlled by the OS. The user will have to grant explicit
+permission to third-party applications requesting use of cost sensitive APIs.
+These APIs include:</p>
+<ul>
+<li>Telephony</li>
+<li>SMS/MMS</li>
+<li>Network/Data</li>
+<li>In-App Billing</li>
+<li>NFC Access</li>
+</ul>
+<h2 id="sim-card-access">SIM Card Access</h2>
+<p>Low level access to the SIM card is not available to third-party apps. The OS
+handles all communications with the SIM card including access to personal
+information (contacts) on the SIM card memory. Applications also cannot access
+AT commands, as these are managed exclusively by the Radio Interface Layer
+(RIL). The RIL provides no high level APIs for these commands.</p>
+<h2 id="personal-information">Personal Information</h2>
+<p>Android has placed APIs that provide access to user data into the set of
+protected APIs.  With normal usage, Android devices will also accumulate user
+data within third-party applications installed by users.   Applications that
+choose to share this information can use Android OS permission checks to
+protect the data from third-party applications.</p>
+<p><img alt="Figure 3: Access to sensitive user data is only available through protected
+APIs" src="images/image03.png" /></p>
+<p><em>Figure 3: Access to sensitive user data is only available through protected
+APIs</em></p>
+<p>System content providers that are likely to contain personal or personally
+identifiable information such as contacts and calendar have been created with
+clearly identified permissions. This granularity provides the user with clear
+indication of the types of information that may be provided to the application.
+ During installation, a third-party application may request permission to
+access these resources.  If permission is granted, the application can be
+installed and will have access to the data requested at any time when it is
+installed.</p>
+<p>Any applications which collect personal information will, by default, have that
+data restricted only to the specific application.  If an application chooses to
+make the data available to other applications though IPC, the application
+granting access can apply permissions to the IPC mechanism that are enforced by
+the operating system.</p>
+<h2 id="sensitive-data-input-devices">Sensitive Data Input Devices</h2>
+<p>Android devices frequently provide sensitive data input devices that allow
+applications to interact with the surrounding environment, such as camera,
+microphone or GPS.  For a third-party application to access these devices, it
+must first be explicitly provided access by the user through the use of Android
+OS Permissions.  Upon installation, the installer will prompt the user
+requesting permission to the sensor by name.</p>
+<p>If an application wants to know the user's location, the application requires a
+permission to access the user's location. Upon installation, the installer will
+prompt the user asking if the application can access the user's location. At
+any time, if the user does not want any application to access their location,
+then the user can run the "Settings" application, go to "Location &amp; Security",
+and uncheck the "Use wireless networks" and "Enable GPS satellites". This will
+disable location based services for all applications on the user's device.</p>
+<h2 id="device-metadata">Device Metadata</h2>
+<p>Android also strives to restrict access to data that is not intrinsically
+sensitive, but may indirectly reveal characteristics about the user, user
+preferences, and the manner in which they use a device.</p>
+<p>By default applications do not have access to operating system logs,
+browser history, phone number, or hardware / network identification
+information.  If an application requests access to this information at install
+time, the installer will prompt the user asking if the application can access
+the information. If the user does not grant access, the application will not be
+installed.</p>
+<h2 id="application-signing">Application Signing</h2>
+<p>Code signing allows developers to identify the author of the application and to
+update their application without creating complicated interfaces and
+permissions. Every application that is run on the Android platform must be
+signed by the developer.  Applications that attempt to install without being
+signed will rejected by either Google Play or the package installer on
+the Android device.</p>
+<p>On Google Play, application signing bridges the trust Google has with the
+developer and the trust the developer has with their application.  Developers
+know their application is provided, unmodified to the Android device; and
+developers can be held accountable for behavior of their application.</p>
+<p>On Android, application signing is the first step to placing an application in
+its Application Sandbox. The signed application certificate defines which user
+id is associated with which application; different applications run under
+different user IDs. Application signing ensures that one application cannot
+access any other application except through well-defined IPC.</p>
+<p>When an application (APK file) is installed onto an Android device, the Package
+Manager verifies that the APK has been properly signed with the certificate
+included in that APK.  If the certificate (or, more accurately, the public key
+in the certificate) matches the key used to sign any other APK on the device,
+the new APK has the option to specify in the manifest that it will share a UID
+with the other similarly-signed APKs.</p>
+<p>Applications can be signed by a third-party (OEM, operator, alternative market)
+or self-signed. Android provides code signing using self-signed certificates
+that developers can generate without external assistance or permission.
+Applications do not have to be signed by a central authority. Android currently
+does not perform CA verification for application certificates.</p>
+<p>Applications are also able to declare security permissions at the Signature
+protection level, restricting access only to applications signed with the same
+key while maintaining distinct UIDs and Application Sandboxes. A closer
+relationship with a shared Application Sandbox is allowed via the <a href="https://developer.android.com/guide/topics/manifest/manifest-element.html#uid">shared UID
+feature</a>
+where two or more applications signed with same developer key can
+declare a shared UID in their manifest.</p>
+<h2 id="digital-rights-management">Digital Rights Management</h2>
+<p>The Android platform provides an extensible DRM framework that lets
+applications manage rights-protected content according to the license
+constraints that are associated with the content. The DRM framework supports
+many DRM schemes; which DRM schemes a device supports is left to the device
+manufacturer.</p>
+<p>The <a href="https://developer.android.com/reference/android/drm/package-summary.html">Android DRM
+framework</a>
+is implemented in two architectural layers (see figure below):</p>
+<ul>
+<li>
+<p>A DRM framework API, which is exposed to applications through the Android
+application framework and runs through the Dalvik VM for standard applications.</p>
+</li>
+<li>
+<p>A native code DRM manager, which implements the DRM framework and exposes an
+interface for DRM plug-ins (agents) to handle rights management and decryption
+for various DRM schemes</p>
+</li>
+</ul>
+<p><img alt="Figure 4: Architecture of Digital Rights Management on Android
+platform" src="images/image02.png" /></p>
+<p><em>Figure 4: Architecture of Digital Rights Management on Android platform</em></p>
+<h1 id="android-updates">Android Updates</h1>
+<p>Android provides system updates for both security and feature related purposes.</p>
+<p>There are two ways to update the code on most Android devices: over-the-air
+(OTA updates) or side-loaded updates. OTA updates can be rolled out over a
+defined time period or be pushed to all devices at once, depending on how the
+OEM and/or carrier would like to push the updates. Side-loaded updates can be
+provided from a central location for users to download as a zip file to their
+local desktop machine or directly to their handset. Once the update is copied
+or downloaded to the SD card on the device, Android will recognize the update,
+verify its integrity and authenticity, and automatically update the device.</p>
+<p>If a dangerous vulnerability is discovered internally or responsibly reported
+to Google or the Android Open Source Project, the Android security team will
+start the following process.</p>
+<ol>
+<li>The Android team will notify companies who have signed NDAs regarding the
+problem and begin discussing the solution.</li>
+<li>The owners of code will begin the fix.</li>
+<li>The Android team will fix Android-related security issues.</li>
+<li>When a patch is available, the fix is provided to the NDA companies.</li>
+<li>The Android team will publish the patch in the Android Open Source Project</li>
+<li>OEM/carrier will push an update to customers.</li>
+</ol>
+<p>The NDA is required to ensure that the security issue does not become public
+prior to availabilty of a fix and put users at risk. Many OHA members run their
+own code on Android devices such as the bootloader, wifi drivers, and the
+radio. Once the Android Security team is notified of a security issue in this
+partner code, they will consult with OHA partners to quickly find a fix for the
+problem at hand and similar problems. However, the OHA member who wrote the
+faulty code is ultimately responsible for fixing the problem.</p>
+<p>If a dangerous vulnerability is not responsibly disclosed (e.g., if it is
+posted to a public forum without warning), then Google and/or the Android Open
+Source Project will work as quickly as possible to create a patch. The patch
+will released to the public (and any partners) when the patch is tested and
+ready for use.</p>
+<p>At Google I/O 2011, many of the largest OHA partners committed to providing
+updates to devices for 18 months after initial shipment. This will provide
+users with access to the most recent Android features, as well as security
+updates.</p>
+<p>Any developer, Android user, or security researcher can notify the Android
+security team of potential security issues by sending email to
+security@android.com. If desired, communication can be encrypted using the
+Android security team PGP key available here:
+<a href="https://developer.android.com/security_at_android_dot_com.txt">https://developer.android.com/security_at_android_dot_com.txt</a>.</p>
+<h1 id="other-resources">Other Resources</h1>
+<p>Information about the Android Open Source Project is available at
+<a href="https://source.android.com">https://source.android.com</a>.</p>
+<p>Information for Android application developers is here:
+<a href="https://developer.android.com">https://developer.android.com</a>.</p>
+<p>The Android Security team can be reached at
+<a href="mailto:security@android.com">security@android.com</a>.</p>
+<p>Security information exists throughout the Android Open Source and Developer
+Sites. A good place to start is here:
+<a href="https://developer.android.com/guide/topics/security/security.html">https://developer.android.com/guide/topics/security/security.html</a>.</p>
+<p>A Security FAQ for developers is located here:
+<a href="https://developer.android.com/resources/faq/security.html">https://developer.android.com/resources/faq/security.html</a>.</p>
+<p>Security Best Practices for developers is located here:
+<a href="https://developer.android.com/guide/practices/security.html">https://developer.android.com/guide/practices/security.html</a>.</p>
+<p>A community resource for discussion about Android security exists here:
+<a href="https://groups.google.com/forum/?fromgroups#!forum/android-security-discuss">https://groups.google.com/forum/?fromgroups#!forum/android-security-discuss</a>.</p>
diff --git a/src/devices/tech/storage/index.jd b/src/devices/tech/storage/index.jd
new file mode 100644
index 0000000..71ea31c
--- /dev/null
+++ b/src/devices/tech/storage/index.jd
@@ -0,0 +1,121 @@
+page.title=External Storage Technical Information
+@jd:body
+
+<!--
+    Copyright 2010 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.
+-->
+<p>Android supports devices with external storage, which is defined to be a
+case-insensitive and permissionless filesystem.  External storage can be
+provided by physical media (such as an SD card), or by an emulation layer backed
+by internal storage.  Devices may contain multiple instances of external
+storage, but currently only the primary external storage is exposed to
+developers through API.</p>
+<h2 id="device-specific-configuration">Device specific configuration</h2>
+<p>External storage is managed by a combination of the <code>vold</code> init service and
+<code>MountService</code> system service.</p>
+<p>Mounting of physical external storage volumes is handled by <code>vold</code>, which
+performs staging operations to prepare the media before exposing it to apps.
+The device-specific <code>vold.fstab</code> configuration file defines mappings from sysfs
+devices to filesystem mount points, and each line follows this format:</p>
+<pre><code>dev_mount &lt;label&gt; &lt;mount_point&gt; &lt;partition&gt; &lt;sysfs_path&gt; [flags]
+</code></pre>
+<ul>
+<li><code>label</code>: Label for the volume.</li>
+<li><code>mount_point</code>: Filesystem path where the volume should be mounted.</li>
+<li><code>partition</code>: Partition number (1 based), or 'auto' for first usable partition.</li>
+<li><code>sysfs_path</code>: One or more sysfs paths to devices that can provide this mount
+point.  Separated by spaces, and each must start with <code>/</code>.</li>
+<li><code>flags</code>: Optional comma separated list of flags, must not contain <code>/</code>.
+Possible values include <code>nonremovable</code> and <code>encryptable</code>.</li>
+</ul>
+<p>External storage interactions at and above the framework level are handled
+through <code>MountService</code>.  The device-specific <code>storage_list.xml</code> configuration
+file, typically provided through a <code>frameworks/base</code> overlay, defines the
+attributes and constraints of storage devices.  The <code>&lt;StorageList&gt;</code> element
+contains one or more <code>&lt;storage&gt;</code> elements, exactly one of which should be marked
+primary.  <code>&lt;storage&gt;</code> attributes include:</p>
+<ul>
+<li><code>mountPoint</code>: filesystem path of this mount.</li>
+<li><code>storageDescription</code>: string resource that describes this mount.</li>
+<li><code>primary</code>: true if this mount is the primary external storage.</li>
+<li><code>removable</code>: true if this mount has removable media, such as a physical SD
+card.</li>
+<li><code>emulated</code>: true if this mount is emulated and is backed by internal storage,
+possibly using a FUSE daemon.</li>
+<li><code>mtp-reserve</code>: number of MB of storage that MTP should reserve for free
+storage.  Only used when mount is marked as emulated.</li>
+<li><code>allowMassStorage</code>: true if this mount can be shared via USB mass storage.</li>
+<li><code>maxFileSize</code>: maximum file size in MB.</li>
+</ul>
+<p>Devices may provide external storage by emulating a case-insensitive,
+permissionless filesystem backed by internal storage.  One possible
+implementation is provided by the FUSE daemon in <code>system/core/sdcard</code>, which can
+be added as a device-specific <code>init.rc</code> service:</p>
+<pre><code># virtual sdcard daemon running as media_rw (1023)
+service sdcard /system/bin/sdcard &lt;source_path&gt; &lt;dest_path&gt; 1023 1023
+    class late_start
+</code></pre>
+<p>Where <code>source_path</code> is the backing internal storage and <code>dest_path</code> is the
+target mount point.</p>
+<p>When configuring a device-specific <code>init.rc</code> script, the <code>EXTERNAL_STORAGE</code>
+environment variable must be defined as the path to the primary external
+storage.  The <code>/sdcard</code> path must also resolve to the same location, possibly
+through a symlink.  If a device adjusts the location of external storage between
+platform updates, symlinks should be created so that old paths continue working.</p>
+<p>As an example, here’s the storage configuration for Xoom, which uses a FUSE
+daemon to provide primary external storage, and includes a physical SD card as
+secondary external storage:</p>
+<ul>
+<li><a href="https://android.googlesource.com/device/moto/wingray/+/master/vold.fstab">vold.fstab</a></li>
+<li><a href="https://android.googlesource.com/device/moto/wingray/+/master/overlay/frameworks/base/core/res/res/xml/storage_list.xml">storage_list.xml</a></li>
+</ul>
+<p>Access to external storage is protected by various Android permissions.
+Starting in Android 1.0, write access is protected with the
+<code>WRITE_EXTERNAL_STORAGE</code> permission, implemented using the <code>sdcard_rw</code> GID.
+Starting in Android 4.1, read access is protected with the new
+<code>READ_EXTERNAL_STORAGE</code> permission, implemented using the <code>sdcard_r</code> GID.  To
+implement the read permission, a new top-level <code>/storage</code> directory was created
+such that processes must hold the <code>sdcard_r</code> GID to traverse into it.</p>
+<p>Since external storage offers no support for traditional POSIX filesystem
+permissions, system code should not store sensitive data on external storage.
+Specifically, configuration and log files should only be stored on internal
+storage where they can be effectively protected.</p>
+<h2 id="multi-user-external-storage">Multi-user external storage</h2>
+<p>Starting in Android 4.2, devices can support multiple users, and external
+storage must meet the following constraints:</p>
+<ul>
+<li>Each user must have their own isolated primary external storage, and must not
+have access to the primary external storage of other users.</li>
+<li>The <code>/sdcard</code> path must resolve to the correct user-specific primary external
+storage based on the user a process is running as.</li>
+<li>Storage for large OBB files in the <code>Android/obb</code> directory may be shared
+between multiple users as an optimization.</li>
+<li>Secondary external storage must not be writable by apps.</li>
+</ul>
+<p>The default platform implementation of this feature leverages Linux kernel
+namespaces to create isolated mount tables for each Zygote-forked process, and
+then uses bind mounts to offer the correct user-specific primary external
+storage into that private namespace.</p>
+<p>At boot, the system mounts a single emulated external storage FUSE daemon at
+<code>EMULATED_STORAGE_SOURCE</code>, which is hidden from apps.  After the Zygote forks,
+it bind mounts the appropriate user-specific subdirectory from under the FUSE
+daemon to <code>EMULATED_STORAGE_TARGET</code> so that external storage paths resolve
+correctly for the app.  Because an app lacks accessible mount points for other
+users’ storage, they can only access storage for the user it was started as.</p>
+<p>This implementation also uses the shared subtree kernel feature to propagate
+mount events from the default root namespace into app namespaces, which ensures
+that features like ASEC containers and OBB mounting continue working correctly.
+It does this by mounting the rootfs as shared, and then remounting it as slave
+after each Zygote namespace is created.</p>
diff --git a/src/devices/tech/test_infra/tradefed/commandfile_format.jd b/src/devices/tech/test_infra/tradefed/commandfile_format.jd
new file mode 100644
index 0000000..cd5102a
--- /dev/null
+++ b/src/devices/tech/test_infra/tradefed/commandfile_format.jd
@@ -0,0 +1,121 @@
+page.title=Command File Format
+@jd:body
+
+<!--
+    Copyright 2010 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.
+-->
+<p>A command file allows one to specify sets of TF commands (that is, configurations with their
+associated arguments) to be specified all at once.  Further, the format used in the command file
+supports simple macro expansions, which makes it very useful without being unwieldy.  You can see a
+relatively involved example at the bottom of the page, as well as more gradual documentation
+immediately below.</p>
+<h2 id="lines">Lines</h2>
+<p>The format is line-based.</p>
+<ul>
+<li>Each output line will be considered as the arguments for a single Configuration for Trade
+    Federation to run.</li>
+<li>Each input line will turn into one or more output lines.</li>
+</ul>
+<p>In essence, the command file format combinatorially creates a sequence of Configuration specifications that it passes to Trade Federation to run.  Blank lines are ignored.  Comments are delimited by the "#" character and may only be preceded by whitespace.</p>
+<h2 id="macros">Macros</h2>
+<p>The specific syntax for defining a macro is discussed below in the Short Macro and Long Macro sections.  The following rules apply to all macros</p>
+<ul>
+<li>The name of a macro must begin with an alpha character.  Each subsequent character may be any
+    alphanumeric, an underscore, or a hyphen.</li>
+<li>A macro with name "macro_name" is invoked by adding macro_name() as an argument on some subsequent
+    line.</li>
+<li>The macro format does not support passing arguments to macros.  It allows only concatenation.</li>
+<li>A macro's expansion may contain invocations of other macros.  Technically, a macro's expansion may
+    contain invocations of itself, but in that case, the macro will never fully expand.</li>
+<li>The parser currently has a hard limit of 10 iterations of expansion.  This will be made
+    configurable at some point.</li>
+<li>During a single iteration of expansion:<ul>
+<li>All short macro invocations on a line will be expanded a single level — macro invocations
+    embedded within the first-level expansions will not be expanded yet</li>
+<li>Only one long macro invocation on a line will be expanded.  This will be the left-most long
+    macro invocation.</li>
+</ul>
+</li>
+</ul>
+<h2 id="short-macros">Short Macros</h2>
+<p>A short macro can be defined with the syntax:</p>
+<pre><code>MACRO macro_name = this is the macro expansion
+</code></pre>
+<p>The macro expansion terminates at the end of the line.  For multi-line expansion, see Long Macros
+below.</p>
+<h3 id="short-macro-expansion">Short Macro Expansion</h3>
+<ul>
+<li><code>a macro_name() invocation</code><br />
+  will be replaced by<br />
+  <code>a this is the macro expansion invocation</code></li>
+<li><code>three macro_name() A macro_name() B macro_name()</code><br />
+  will be replaced by (all during the first iteration)<br />
+  <code>three this is the macro expansion A this is the macro expansion B this is the macro expansion</code></li>
+</ul>
+<h2 id="long-macros">Long Macros</h2>
+<p>A long macro can be defined with the syntax:</p>
+<pre><code>LONG MACRO macro_name
+  expansion line 1
+  expansion line 2
+  expansion line 3
+END MACRO
+</code></pre>
+<p>The macro is then invoked with th enormal <code>macro_name()</code> syntax.  Leading whitespace/indentation
+will be ignored.</p>
+<h3 id="long-macro-expansion">Long Macro Expansion</h3>
+<p>The output of a single input line will include one line for each combination of macro expansions on
+that line.  That is, the number of output lines is multiplicatively related to the number of macro
+expansions on that line:</p>
+<ul>
+<li>Only a single long macro invocation per line will be expanded during a single iteration.  This
+    means that a line may only contain 10 long macro invocations to stay under the iteration count
+    limit.</li>
+<li>
+<p>A single invocation of a long macro on a single line will cause that line to expand to the number
+    of lines of the long macro's expansion.  On each expanded line, the invocation will be replaced
+    by the corresponding line of the macro's expansion.</p>
+</li>
+<li>
+<p>Example 1:</p>
+<pre><code>a macro_name() invocation
+</code></pre>
+<p>will be replaced by (in a single iteration)</p>
+<pre><code>a expansion line 1 invocation
+a expansion line 2 invocation
+a expansion line 3 invocation
+</code></pre>
+</li>
+<li>
+<p>Example 2:</p>
+<pre><code>alpha macro_name() beta macro_name()
+</code></pre>
+<p>will be replaced by (during the first iteration)</p>
+<pre><code>alpha expansion line 1 beta macro_name()
+alpha expansion line 2 beta macro_name()
+alpha expansion line 3 beta macro_name()
+</code></pre>
+<p>which will be replaced by (during the second iteration)</p>
+<pre><code>alpha expansion line 1 beta expansion line 1
+alpha expansion line 1 beta expansion line 2
+alpha expansion line 1 beta expansion line 3
+alpha expansion line 2 beta expansion line 1
+alpha expansion line 2 beta expansion line 2
+alpha expansion line 2 beta expansion line 3
+alpha expansion line 3 beta expansion line 1
+alpha expansion line 3 beta expansion line 2
+alpha expansion line 3 beta expansion line 3
+</code></pre>
+</li>
+</ul>
diff --git a/src/devices/tech/test_infra/tradefed/getting_started.jd b/src/devices/tech/test_infra/tradefed/getting_started.jd
new file mode 100644
index 0000000..8219ee7
--- /dev/null
+++ b/src/devices/tech/test_infra/tradefed/getting_started.jd
@@ -0,0 +1,203 @@
+page.title=Getting Started
+@jd:body
+
+<!--
+    Copyright 2010 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.
+-->
+<h2 id="using-the-console">Using the console</h2>
+<p>TF is based around an interactive console.  You can fire up the console by going to the
+<code>tools/tradefederation/</code> directory and running</p>
+<pre><code>$ ./tradefed.sh
+</code></pre>
+<p>You should end up at a <code>tf &gt;</code> prompt.</p>
+<p>The console is self-documenting.  Try entering "help"</p>
+<pre><code>tf &gt;help
+Enter 'q' or 'exit' to exit
+Enter 'kill' to attempt to forcibly exit, by shutting down adb
+
+Enter 'help list'  for help with 'list' commands
+[...]
+</code></pre>
+<p>As the help text suggests, the help menus are organized hierarchically</p>
+<pre><code>tf &gt;help list
+l(?:ist)? help:
+    i[nvocations]  List all invocation threads
+    d[evices]      List all detected or known devices
+[...]
+</code></pre>
+<p>The majority of commands have a convenient short form, which the help text displays.  The
+<code>l(?:ist)?</code> is a regular expression.  As an example, here are the four equivalent ways to list
+invocations:
+<em> <code>list invocations</code>
+</em> <code>list i</code>
+<em> <code>l invocations</code>
+</em> <code>l i</code></p>
+<h2 id="running-a-configcommand">Running a config/command</h2>
+<p>This is documented by the <code>help run</code> command in the console.</p>
+<p>As a reminder, a command is a config along with all of its command-line arguments.  A command <em>must</em>
+begin with the name of the respective config.</p>
+<p>As a quick example, you could run the calculator unit tests like so:</p>
+<pre><code>$./tradefed.sh
+tf &gt;run instrument --package com.android.calculator2.tests
+</code></pre>
+<p>As a shortcut, if you specify any arguments to <code>tradefed.sh</code>, it will attempt to execute them as if
+they were typed on the commandline.  So the short version of the above would be</p>
+<pre><code>$./tradefed.sh run instrument --package com.android.calculator2.tests
+</code></pre>
+<p>In both of these cases, the name of the config is "instrument", and
+"--class com.android.calculator2.tests" is a command-line argument.  The command that is being run
+is "instrument --class com.android.calculator2.tests".</p>
+<p>TF can run both configs that are compiled in (such as the "instrument" config above), as well as
+configs that exist as xml files on the local filesystem.  You can see a list of compiled-in configs
+with the <code>list configs</code> console command.  Furthermore, you can investigate any config (compiled-in
+or local) by passing the "--help" or "--help-all" command-line arguments.  The "--help" argument
+will only show "important" arguments, and "--help-all" will show all arguments, regardless of
+whether they've been marked as "important" or not.  To take the final step, you can tell TF to print
+the contents of any config (compiled-in or local) with the <code>dump config &lt;configname&gt;</code> console
+command.</p>
+<h3 id="so-lets-say-you-want-to-run-the-calculator-instrumentation-tests-but-dont-know-where-to-start">So, let's say you want to run the calculator instrumentation tests, but don't know where to start.</h3>
+<p>You could try something like this sequence of steps.  First, look for a config that looks like it
+might do what you want:</p>
+<pre><code>tf &gt;list configs
+Use 'run command --help &lt;configuration_name&gt;' to get list of options for a configuration
+Use 'dump config &lt;configuration_name&gt;' to display the configuration's XML content.
+
+Available configurations include:
+[...]
+  instrument: Runs a single Android instrumentation test on an existing device
+[...]
+</code></pre>
+<p>Now that you've found something reasonable-looking, see what options it takes.  The <code>list configs</code> output suggests trying <code>run command instrument --help</code></p>
+<pre><code>tf &gt;run command --help instrument
+'instrument' configuration: Runs a single Android instrumentation test on an existing device
+
+Printing help for only the important options. To see help for all options, use the --help-all flag
+[...]
+  'instrumentation' test options:
+    -p, --package        The manifest package name of the Android test application to run.
+</code></pre>
+<p>As the message suggests, if you need more options, use the "--help-all" flag instead of "--help".  In this case, we've got all we need.  You could figure out the package by checking with <code>runtest</code>, or reading testdefs.xml directly.  We use <code>runtest -n</code> to simply show what would be run without actually running it:</p>
+<pre><code>$runtest -n calculator
+adb root
+ONE_SHOT_MAKEFILE="packages/apps/Calculator/Android.mk" make -j4 -C "/srv/xsdg/master2" files
+adb sync
+adb  shell am instrument -w com.android.calculator2.tests/android.test.InstrumentationTestRunner
+</code></pre>
+<p>The argument to <code>am instrument</code> that comes before the slash is the manifest package.  <code>android.test.InstrumentationTestRunner</code> is the default runner, so no need to set it if that's the
+right one.  Otherwise, using "--help-all" will tell you about the "--runner" argument, which you can
+use to specify an alternate runner.  Ok, so at this point, we've got the following command, which
+you'll recognize from above</p>
+<pre><code>tf &gt;run instrument --package com.android.calculator2.tests
+</code></pre>
+<h2 id="interacting-with-a-device">Interacting with a device</h2>
+<h3 id="generic-device-behavior-in-tf">Generic device behavior in TF</h3>
+<p>The running version of a command is called in <code>invocation</code>.  First and foremost, every invocation
+requires a device before it can run.  In addition to physical Android devices, TF can run tests with
+a mock device (by specifying the "-n" argument for the command), or with the Android emulator (by
+specifying the "-e" argument").</p>
+<p>The primary console command to figure out what devices are up to is <code>list devices</code>:</p>
+<pre><code>$./tradefed.sh
+06-07 17:03:22 I/: Detected new device 016B756E03018007
+06-07 17:03:22 I/: Detected new device 1700614743c14397
+06-07 17:03:22 I/: Detected new device 3531C342606300EC
+tf &gt;l d
+Serial            State      Product   Variant   Build   Battery
+016B756E03018007  Available  tuna      toro      MASTER  100
+1700614743c14397  Available  stingray  stingray  MASTER  100
+3531C342606300EC  Available  herring   crespo4g  MASTER  92
+</code></pre>
+<p>As far as the invocations are concerned, there are three device states: available, unavailable, and
+allocated.  An <code>Available</code> device is ready to be allocated for an invocation.  An <code>Unavailable</code>
+device is not ready for allocation, for any of a variety of reasons — TF may have deemed to the
+device as unstable, the device may be critically low on storage, or something else may be amiss.
+Finally, an <code>Allocated</code> device is a device that is already being used by an invocation.</p>
+<p>When you start TF, all detected physical devices will be checked for responsiveness with a simple
+shell command.  If the command completes successfully, the device will be listed as Available.  If
+the command fails, the device state will be shown as Unavailable.  Thereafter, a device will typically bounce between the Available and Allocated states as invocation requirements dictate.</p>
+<p>Finally, once invocations are already underway, you can see what's going on with the <code>list
+invocations</code> command</p>
+<pre><code>tf &gt;run instrument --package com.android.calculator2.tests
+06-07 17:18:31 I/TestInvocation: Starting invocation for 'stub' on build '0' on device 1700614743c14397
+[...]
+tf &gt;l d
+Serial            State      Product   Variant   Build   Battery
+1700614743c14397  Allocated  stingray  stingray  MASTER  100
+3531C342606300EC  Available  herring   crespo4g  JRN11   93
+016B756E03018007  Available  tuna      toro      MASTER  100
+
+tf &gt;l i
+Command Id  Exec Time  Device            State
+1           0m:02      1700614743c14397  running stub on build 0
+</code></pre>
+<h3 id="running-invocations-on-specific-devices">Running invocations on specific devices</h3>
+<p>TF supports a number of filtering mechanisms for specifying which device or devices to use for a
+particular invocation.  Since the filtering mechanisms are run before a command turns into an
+invocation, you can find all of the filtering options in the help for any config:</p>
+<p>tf &gt;run instrument --help-all
+[...]
+  device_requirements options:
+    -s, --serial         run this test on a specific device with given serial number(s).
+    --exclude-serial     run this test on any device except those with this serial number(s).
+    --product-type       run this test on device with this product type(s).  May also filter by variant using product:variant.
+    --property           run this test on device with this property value. Expected format <propertyname>=<propertyvalue>.
+    -e, --[no-]emulator  force this test to run on emulator. Default: false.
+    -d, --[no-]device    force this test to run on a physical device, not an emulator. Default: false.
+    --[no-]new-emulator  allocate a placeholder emulator. Should be used when config intends to launch an emulator Default: false.
+    -n, --[no-]null-device
+                         do not allocate a device for this test. Default: false.
+    --min-battery        only run this test on a device whose battery level is at least the given amount. Scale: 0-100
+    --max-battery        only run this test on a device whose battery level is strictly less than the given amount. Scale: 0-100
+[...]</p>
+<p>The built-in help should be pretty self-explanatory.  All of the filtering options excluding "-n",
+"-e", and "-d" may be specified as many times as needed.  So, for instance, to run an invocation
+using any Verizon Galaxy Nexus, you could do the following:</p>
+<pre><code>tf &gt;run instrument --package com.android.calculator2.tests --product-type tuna:toro
+</code></pre>
+<p>As another example, to run on a GSM device with a SIM, you could do the following:</p>
+<pre><code>tf &gt;run instrument --package com.android.calculator2.tests --property gsm.sim.state=READY
+</code></pre>
+<p>The filtering works by exclusion from the pool of Available devices, so the "--serial" option simply
+excludes devices that aren't in the list of required serials, and --exclude-serial excludes devices
+that <em>are</em> in its list.  As such, an argument like --exclude-serial XXX --serial XXX will simply
+make the respective command un-runnable — it will never match any device, since all devices are
+excluded.</p>
+<h2 id="logging">Logging</h2>
+<p>There are a few different aspects to logging in TF.  First and foremost, TF has a built-in logging
+infrastructure that's based on DDMLib's Log class.  For the common case, where the log tag is just
+the classname of the current class, you can use our CLog convenience shim.  In short, if you might
+have originally done this:</p>
+<pre><code>class ClassName {
+private static final LOG_TAG = "ClassName";
+[...]
+Log.v(LOG_TAG, "This is a simple verbose log message");
+Log.w(LOG_TAG, String.format("This warning message brought to you by the number %d", 17));
+</code></pre>
+<p>You can now accomplish the same thing with the shim like this:</p>
+<pre><code>class ClassName {
+[...]
+CLog.v("This is a simple verbose log message");
+CLog.w("This warning message brought to you by the number %d", 17);
+</code></pre>
+<p>Each Invocation has its own ThreadGroup.  Any host-side logging that happens inside of that thread
+group is associated with the Invocation, and will be reported as that invocation's "host_log" after
+the Invocation completes.</p>
+<p>Device logging is performed as part of TradeFed's device wrapper.  We keep a buffer of up to 20 MB
+that captures log data as the device churns it out.  In particular, we are not limited by the size
+of the on-device logcat buffer.</p>
+<p>The next important piece is the ITestInvocationListener.  This is one of the components of an
+Invocation that handles results reporting.  Each reporter has the option to implement the #testLog
+method, which will be used to pass logfiles to that result reporter.  Among the files that are
+passed by TF itself will be the aforementioned host_log, as well as the device logcat for the device
+associated with the Invocation.</p>
diff --git a/src/devices/tech/test_infra/tradefed/index.jd b/src/devices/tech/test_infra/tradefed/index.jd
new file mode 100644
index 0000000..9331369
--- /dev/null
+++ b/src/devices/tech/test_infra/tradefed/index.jd
@@ -0,0 +1,52 @@
+page.title=Trade Federation Overview
+@jd:body
+
+<!--
+    Copyright 2010 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.
+-->
+<p>TradeFederation (tradefed or TF for short) is a continuous test framework designed for running tests
+on Android devices. Its a Java application which runs on a host computer, and communicates to one or
+more Android devices using ddmlib (the library behind DDMS) over adb.</p>
+<h2 id="features">Features</h2>
+<ul>
+<li>modular, flexible design</li>
+<li>has built in support for running many different types of Android tests: instrumentation, native/gtest, host-based JUnit, etc</li>
+<li>provides reliability and recovery mechanism on top of adb</li>
+<li>supports scheduling and running tests on multiple devices in parallel</li>
+</ul>
+<h2 id="fundamentals">Fundamentals</h2>
+<p>The lifecycle of a test executed using TradeFederation is composed of four separate stages, designed
+around formally defined interfaces.</p>
+<ul>
+<li><a href="bp.html">Build provider</a>: Provides a build to test, downloading appropriate files if necessary</li>
+<li><a href="tp.html">Target preparer</a>: Prepares the test environment, e.g. software installation and setup</li>
+<li><a href="test.html">Test</a>: Executes test(s) and gathers test results</li>
+<li><a href="result.html">Result reporter</a>: Listens for test results, usually for the purpose of forwarding
+  test results to a repository</li>
+</ul>
+<p>The fundamental entity in TradeFederation is a Configuration. A Configuration is an XML file that
+declares the lifecycle components of a test.</p>
+<p>This separation of the test's lifecycle is intended to allow for reuse.  Using this design, you can
+create a Test, and then different Configurations to run it in different environments. For example,
+you could create a Configuration that will run a test on your local machine, and dump the result to
+stdout.  You could then create a second Configuration that would execute that same test, but use a
+different Result reporter to store the test results in a database.</p>
+<h3 id="additional-components-of-a-configuration">Additional components of a configuration</h3>
+<ul>
+<li><a href="recovery.html">Device recovery</a>: mechanism to recover device communication if lost</li>
+<li><a href="logger.html">Logger</a>: collects tradefed logging data</li>
+</ul>
+<p>A complete TradeFederation test execution, across its entire lifecycle, is referred to as an
+Invocation.</p>
\ No newline at end of file
diff --git a/src/devices/tech/test_infra/tradefed/tutorial.jd b/src/devices/tech/test_infra/tradefed/tutorial.jd
new file mode 100644
index 0000000..eb42aa0
--- /dev/null
+++ b/src/devices/tech/test_infra/tradefed/tutorial.jd
@@ -0,0 +1,334 @@
+page.title=Tutorial
+@jd:body
+
+<!--
+    Copyright 2010 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.
+-->
+<p>This tutorial guides you through the construction of a "hello world" Trade Federation test
+configuration, and gives you a hands-on introduction to the Trade Federation framework.  Starting
+from the Tf development environment, it guides you through the process of creating a simple Trade
+Federation config and gradually adding more features to it.</p>
+<p>The tutorial presents the TF test development process as a set of exercises, each consisting of
+several steps.  The exercises demonstrate how to gradually build and refine your configuration, and
+provide all the sample code you need to complete the test configuration.</p>
+<p>When you are finished with the tutorial, you will have created a functioning TF configuration and
+will have learned many of the most important concepts in the TF framework.</p>
+<h2 id="set-up-tradefederation-development-environment">Set up TradeFederation development environment</h2>
+<p>See (FIXME: link) for how to setup the development environment. The rest of this tutorial assumes you have a shell open that has been initialized to the TradeFederation environment. </p>
+<p>For simplicity, this tutorial will illustrate adding a configuration and its classes to the TradeFederation framework core library. Later tutorials/documentation will show how to create your own library that extends TradeFederation.</p>
+<h2 id="creating-a-test-class">Creating a test class</h2>
+<p>Lets create a hello world test that just dumps a message to stdout. A TradeFederation test must
+implement the (FIXME: link) IRemoteTest interface.</p>
+<p>Here's an implementation for the HelloWorldTest:</p>
+<pre><code>package com.android.tradefed.example;
+
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.result.ITestInvocationListener;
+import com.android.tradefed.testtype.IRemoteTest;
+
+public class HelloWorldTest implements IRemoteTest {
+    &#64;Override
+    public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
+        System.out.println("Hello, TF World!");
+    }
+}
+</code></pre>
+<p>FIXME: prod-tests
+Save this sample code to
+<code>&lt;git home&gt;/tools/tradefederation/prod-tests/src/com/android/tradefed/example/HelloWorldTest.java</code>
+and rebuild tradefed from your shell:</p>
+<pre><code>m -j6
+</code></pre>
+<p>If the build does not succeed, please consult the (FIXME: link)Development Environment page to
+ensure you did not miss any steps.</p>
+<h2 id="creating-a-configuration">Creating a configuration</h2>
+<p>Trade Federation tests are defined in a "Configuration". A Configuration is an XML file that
+instructs tradefed which test (or set of tests) to run.</p>
+<p>Lets create a new Configuration for our HelloWorldTest.</p>
+<pre><code>&lt;configuration description="Runs the hello world test"&gt;
+    &lt;test class="com.android.tradefed.example.HelloWorldTest" /&gt;
+&lt;/configuration&gt;
+</code></pre>
+<p>TF will parse the Configuration XML file, load the specified class using reflection, instantiate it,
+cast it to a IRemoteTest, and call its 'run' method.</p>
+<p>Note that we've specified the full class name of the HelloWorldTest. Save this data to a
+<code>helloworld.xml</code> file anywhere on your local filesystem (eg <code>/tmp/helloworld.xml</code>).</p>
+<h2 id="running-the-configuration">Running the configuration</h2>
+<p>From your shell, launch the tradefed console</p>
+<pre><code>$ ./tradefed.sh
+</code></pre>
+<p>Ensure a device is connected to the host machine that is visible to tradefed</p>
+<pre><code>tf&gt; list devices
+</code></pre>
+<p>Configurations can be run using the <code>run &lt;config&gt;</code> console command.  Try this now</p>
+<p>FIXME: redo this</p>
+<pre><code>tf&gt; run /tmp/helloworld.xml
+05-12 13:19:36 I/TestInvocation: Starting invocation for target stub on build 0 on device 30315E38655500EC
+Hello, TF World!
+</code></pre>
+<p>You should see "Hello, TF World!" outputted on the terminal.</p>
+<h2 id="adding-the-configuration-to-the-classpath">Adding the configuration to the classpath</h2>
+<p>FIXME: prod-tests
+For convenience of deployment, you can also bundle configuration files into the TradeFederation jars
+themselves. Tradefed will automatically recognize all configurations placed in 'config' folders on
+the classpath.</p>
+<p>Lets illustrate this now by moving the helloworld.xml into the tradefed core library.</p>
+<p>Move the <code>helloworld.xml</code> file into 
+<code>&lt;git root&gt;/tools/tradefederation/prod-tests/res/config/example/helloworld.xml</code>.</p>
+<p>Rebuild tradefed, and restart the tradefed console. </p>
+<p>Ask tradefed to display the list of configurations on the classpath:</p>
+<pre><code>tf&gt; list configs
+[…]
+example/helloworld: Runs the hello world test
+</code></pre>
+<p>You can now run the helloworld config via the following command</p>
+<pre><code>tf &gt;run example/helloworld
+05-12 13:21:21 I/TestInvocation: Starting invocation for target stub on build 0 on device 30315E38655500EC
+Hello, TF World!
+</code></pre>
+<h2 id="interacting-with-a-device">Interacting with a device</h2>
+<p>So far our hello world test isn't doing anything interesting. Tradefed is intended to run tests using Android devices, so lets add an Android device to the test.</p>
+<p>Tests can get a reference to an Android device by implementing the IDeviceTest interface. </p>
+<p>Here's a sample implementation of what this looks like:</p>
+<pre><code>public class HelloWorldTest implements IRemoteTest, IDeviceTest {
+    private ITestDevice mDevice;
+    &#64;Override
+    public void setDevice(ITestDevice device) {
+        mDevice = device;
+    }
+
+    &#64;Override
+    public ITestDevice getDevice() {
+        return mDevice;
+    }
+…
+}
+</code></pre>
+<p>The TradeFederation framework will inject the ITestDevice reference into your test via the
+IDeviceTest#setDevice method, before the IRemoteTest#run method is called.</p>
+<p>Lets add an additional print message to the HelloWorldTest displaying the serial number of the
+device.</p>
+<pre><code>&#64;Override
+public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
+    System.out.println("Hello, TF World! I have a device " + getDevice().getSerialNumber());
+}
+</code></pre>
+<p>Now rebuild tradefed, and do (FIXME: update)</p>
+<pre><code>$ tradefed.sh
+tf&gt; list devices
+Available devices:   [30315E38655500EC]
+…
+</code></pre>
+<p>Take note of the serial number listed in Available devices above. That is the device that should be allocated to HelloWorld.</p>
+<pre><code>tf &gt;run example/helloworld
+05-12 13:26:18 I/TestInvocation: Starting invocation for target stub on build 0 on device 30315E38655500EC
+Hello world, TF! I have a device 30315E38655500EC
+</code></pre>
+<p>You should see the new print message displaying the serial number of the device.</p>
+<h2 id="sending-test-results">Sending test results</h2>
+<p>IRemoteTests report results by calling methods on the ITestInvocationListener instance provided to
+their <code>#run</code> method.</p>
+<p>The TradeFederation framework is responsible for reporting the start and end of an Invocation (via
+the ITestInvocationListener#invocationStarted and ITestInvocationListener#invocationEnded methods
+respectively).</p>
+<p>A <code>test run</code> is a logical collection of tests. To report test results, IRemoteTests are responsible
+for reporting the start of a test run, the start and end of each test, and the end of the test run.</p>
+<p>Here's what the HelloWorldTest implementation looks like with a single failed test result.</p>
+<pre><code>&#64;SuppressWarnings("unchecked")
+&#64;Override
+public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
+    System.out.println("Hello, TF World! I have a device " + getDevice().getSerialNumber());
+
+    TestIdentifier testId = new TestIdentifier("com.example.MyTestClassName", "sampleTest");
+    listener.testRunStarted("helloworldrun", 1);
+    listener.testStarted(testId);
+    listener.testFailed(TestFailure.FAILURE, testId, "oh noes, test failed");
+    listener.testEnded(testId, Collections.EMPTY_MAP);
+    listener.testRunEnded(0, Collections.EMPTY_MAP);
+}
+</code></pre>
+<p>Note that TradeFederation also includes several IRemoteTest implementations that you can reuse
+instead of writing your own from scratch. (such as InstrumentationTest, which can run an Android
+application's tests remotely on an Android device, parse the results, and forward them to the
+ITestInvocationListener). See the Test Types documentation for more details.</p>
+<h2 id="storing-test-results">Storing test results</h2>
+<p>By default, a TradeFederation configuration will use the TextResultReporter as the test listener
+implementation for the configuration.  TextResultReporter will dump the results of an invocation to
+stdout. To illustrate, try running the hello-world config from previous section now:</p>
+<pre><code>$ ./tradefed.sh
+tf &gt;run example/helloworld
+05-16 20:03:15 I/TestInvocation: Starting invocation for target stub on build 0 on device 30315E38655500EC
+Hello world, TF! I have a device 30315E38655500EC
+05-16 20:03:15 I/InvocationToJUnitResultForwarder: run helloworldrun started: 1 tests
+Test FAILURE: com.example.MyTestClassName#sampleTest 
+ stack: oh noes, test failed 
+05-16 20:03:15 I/InvocationToJUnitResultForwarder: run ended 0 ms
+</code></pre>
+<p>If you want to store the results of an invocation elsewhere, say to a file, you would need to
+specify a custom "result_reporter" in your configuration, that specifies the custom
+ITestInvocationListener class you want to use.</p>
+<p>The TradeFederation framework includes a result_reporter (XmlResultReporter)  that will write test
+results to an XML file, in a format similar to the ant JUnit XML writer. </p>
+<p>Lets specify the result_reporter in the configuration now. Edit the
+<code>tools/tradefederation/res/config/example/helloworld.xml</code> like this:</p>
+<pre><code>&lt;configuration description="Runs the hello world test"&gt;
+    &lt;test class="com.android.tradefed.example.HelloWorldTest" /&gt;
+    &lt;result_reporter class="com.android.tradefed.result.XmlResultReporter" /&gt;
+&lt;/configuration&gt;
+</code></pre>
+<p>Now rebuild tradefed and re-run the hello world sample:
+FIXME: paths</p>
+<pre><code>tf &gt;run example/helloworld
+05-16 21:07:07 I/TestInvocation: Starting invocation for target stub on build 0 on device 30315E38655500EC
+Hello world, TF! I have a device 30315E38655500EC
+05-16 21:07:07 I/XmlResultReporter: Saved device_logcat log to /var/folders/++/++2Pz+++6+0++4RjPqRgNE+-4zk/-Tmp-/0/inv_2991649128735283633/device_logcat_6999997036887173857.txt
+05-16 21:07:07 I/XmlResultReporter: Saved host_log log to /var/folders/++/++2Pz+++6+0++4RjPqRgNE+-4zk/-Tmp-/0/inv_2991649128735283633/host_log_6307746032218561704.txt
+05-16 21:07:07 I/XmlResultReporter: XML test result file generated at /var/folders/++/++2Pz+++6+0++4RjPqRgNE+-4zk/-Tmp-/0/inv_2991649128735283633/test_result_536358148261684076.xml. Total tests 1, Failed 1, Error 0
+</code></pre>
+<p>Notice the log message stating an XML file has been generated. The generated file should look like this:</p>
+<pre><code>&lt;?xml version='1.0' encoding='UTF-8' ?&gt;
+&lt;testsuite name="stub" tests="1" failures="1" errors="0" time="9" timestamp="2011-05-17T04:07:07" hostname="localhost"&gt;
+  &lt;properties /&gt;
+  &lt;testcase name="sampleTest" classname="com.example.MyTestClassName" time="0"&gt;
+    &lt;failure&gt;oh noes, test failed
+    &lt;/failure&gt;
+  &lt;/testcase&gt;
+&lt;/testsuite&gt;
+</code></pre>
+<p>Note that you can write your own custom result_reporter. It just needs to implement the
+ITestInvocationListener interface. </p>
+<p>Also note that Tradefed supports multiple result_reporters, meaning that you can send test results
+to multiple independent destinations. Just specify multiple <result_reporter> tags in your config to
+do this.</p>
+<h2 id="logging">Logging</h2>
+<p>TradeFederation includes two logging facilities:</p>
+<ol>
+<li>ability to capture logs from the device (aka device logcat)</li>
+<li>ability to record logs from the TradeFederation framework running on the host machine (aka the
+    host log)</li>
+</ol>
+<p>Lets focus on 2 for now. Trade Federation's host logs are reported using the CLog wrapper for the
+ddmlib Log class. </p>
+<p>Lets convert the previous System.out.println call in HelloWorldTest to a CLog call:</p>
+<pre><code>&#64;Override
+public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
+    CLog.i("Hello world, TF! I have a device " + getDevice().getSerialNumber());
+</code></pre>
+<p>Now rebuild and rerun. You should see the log message on stdout. </p>
+<pre><code>tf&gt; run example/helloworld
+…
+05-16 21:30:46 I/HelloWorldTest: Hello world, TF! I have a device 30315E38655500EC
+…
+</code></pre>
+<p>By default, TradeFederation will output host log messages to stdout. TradeFederation also includes a
+log implementation that will write messages to a file: FileLogger. To add file logging, add a
+'logger' tag to the configuration xml, specifying the full class name of FileLogger.</p>
+<pre><code>&lt;configuration description="Runs the hello world test"&gt;
+    &lt;test class="com.android.tradefed.example.HelloWorldTest" /&gt;
+    &lt;result_reporter class="com.android.tradefed.result.XmlResultReporter" /&gt;
+    &lt;logger class="com.android.tradefed.log.FileLogger" /&gt;
+&lt;/configuration&gt;
+</code></pre>
+<p>Now rebuild and run the helloworld example again.</p>
+<pre><code>tf &gt;run example/helloworld 
+…
+05-16 21:38:21 I/XmlResultReporter: Saved device_logcat log to /var/folders/++/++2Pz+++6+0++4RjPqRgNE+-4zk/-Tmp-/0/inv_6390011618174565918/device_logcat_1302097394309452308.txt
+05-16 21:38:21 I/XmlResultReporter: Saved host_log log to /tmp/0/inv_6390011618174565918/host_log_4255420317120216614.txt
+…
+</code></pre>
+<p>Note the log message indicating the path of the host log. View the contents of that file, and you
+should see your HelloWorldTest log message</p>
+<pre><code>$ more /tmp/0/inv_6390011618174565918/host_log_4255420317120216614.txt
+…
+05-16 21:38:21 I/HelloWorldTest: Hello world, TF! I have a device 30315E38655500EC
+</code></pre>
+<p>The TradeFederation framework will also automatically capture the logcat from the allocated device,
+and send it the the result_reporter for processing. XmlResultReporter will save the captured device
+logcat as a file.</p>
+<h2 id="command-line-options">Command line options</h2>
+<p>Objects loaded from a TradeFederation Configuration (aka "Configuration objects") also have the
+ability to receive data from command line arguments.</p>
+<p>This is accomplished via the <code>@Option</code> annotation. To participate, a Configuration object class
+would apply the <code>@Option</code> annotation to a member field, and provide it a unique name. This would
+allow that member field's value to be populated via a command line option, and would also
+automatically add that option to the configuration help system (Note: not all field types are
+supported: see the OptionSetter javadoc for a description of supported types).</p>
+<p>Lets add an Option to the HelloWorldTest.</p>
+<pre><code>@Option(name="my_option",
+        shortName='m',
+        description="this is the option's help text",
+        // always display this option in the default help text
+        importance=Importance.ALWAYS)
+private String mMyOption = "thisisthedefault";
+</code></pre>
+<p>And lets add a log message to display the value of the option in HelloWorldTest, so we can
+demonstrate that it was received correctly.</p>
+<pre><code>@SuppressWarnings("unchecked")
+&#64;Override
+public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
+    …
+    Log.logAndDisplay(LogLevel.INFO, "HelloWorldTest", "I received this option " + mMyOption);
+</code></pre>
+<p>Rebuild TF and run helloworld: you should see a log message with the my_option's default value.</p>
+<pre><code>tf&gt; run example/helloworld
+…
+05-24 18:30:05 I/HelloWorldTest: I received this option thisisthedefault
+</code></pre>
+<p>Now pass in a value for my_option: you should see my_option getting populated with that value</p>
+<pre><code>tf&gt; run example/helloworld --my_option foo
+…
+05-24 18:33:44 I/HelloWorldTest: I received this option foo
+</code></pre>
+<p>TF configurations also include a help system, which automatically displays help text for @Option
+fields. Try it now, and you should see the help text for 'my_option':</p>
+<pre><code>tf&gt; run --help example/helloworld
+Printing help for only the important options. To see help for all options, use the --help-all flag
+
+  cmd_options options:
+    --[no-]help          display the help text for the most important/critical options. Default: false.
+    --[no-]help-all      display the full help text for all options. Default: false.
+    --[no-]loop          keep running continuously. Default: false.
+
+  test options:
+    -m, --my_option      this is the option's help text Default: thisisthedefault.
+
+  'file' logger options:
+    --log-level-display  the minimum log level to display on stdout. Must be one of verbose, debug, info, warn, error, assert. Default: error.
+</code></pre>
+<p>FIXME: redo with enum help</p>
+<p>Note the message at the top about 'printing only the important options'. To reduce option help
+clutter, TF uses the Option#importance attribute to determine whether to show an Option's help text
+when '--help' is specified. '--help-all' will always show all options' help regardless of
+importance. See Option.Importance javadoc for details.</p>
+<p>You can also specify an Option's value within the configuration xml by adding a
+<code>&lt;option name="" value=""&gt;</code> element. Lets see how this looks in the helloworld.xml:</p>
+<pre><code>&lt;test class="com.android.tradefed.example.HelloWorldTest" &gt;
+    &lt;option name="my_option" value="fromxml" /&gt;
+&lt;/test&gt;
+</code></pre>
+<p>Re-building and running helloworld should now produce this output:</p>
+<pre><code>05-24 20:38:25 I/HelloWorldTest: I received this option fromxml
+</code></pre>
+<p>The configuration help should also be updated to indicate my_option's new default value:</p>
+<pre><code>tf&gt; run --help example/helloworld
+  test options:
+    -m, --my_option      this is the option's help text Default: fromxml.
+</code></pre>
+<p>Also note that other configuration objects included in the helloworld config, like FileLogger, also have options. '--log-level-display' is of interest because it filters the logs that show up on stdout. You may have noticed from earlier in the tutorial the 'Hello world, TF! I have a device ..' log message stopped getting displayed on stdout once we switched to using FileLogger. You can increase the verbosity of logging to stdout by passing in log-level-display arg.</p>
+<p>Try this now, and you should see the 'I have a device' log message reappear on stdout, in addition to getting logged to a file.</p>
+<pre><code>tf &gt;run --log-level-display info example/helloworld
+…
+05-24 18:53:50 I/HelloWorldTest: Hello world, TF! I have a device XXXXXX
+</code></pre>