s.a.c. redesign, first checkin

Change-Id: I4dead2f18bc5e4a38f204c92198a267c286e775d
diff --git a/src/devices/audio.jd b/src/devices/audio.jd
new file mode 100644
index 0000000..a160782
--- /dev/null
+++ b/src/devices/audio.jd
@@ -0,0 +1,346 @@
+page.title=Audio
+@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>
+  Android's audio HAL connects the higher level, audio-specific
+  framework APIs in <a href="http://developer.android.com/reference/android/media/package-summary.html">android.media</a>
+  to the underlying audio driver and hardware. 
+</p>
+
+<p>
+  The following figure and list describe how audio functionality is implemented and the relevant
+  source code that is involved in the implementation:
+</p>
+<p>
+  <img src="images/audio_hal.png">
+</p>
+<dl>
+  <dt>
+    Application framework
+  </dt>
+  <dd>
+    At the application framework level is the app code, which utilizes the
+    <a href="http://developer.android.com/reference/android/media/package-summary.html">android.media</a>
+    APIs to interact with the audio hardware. Internally, this code calls corresponding JNI glue
+    classes to access the native code that interacts with the auido hardware.
+  </dd>
+  <dt>
+    JNI
+  </dt>
+  <dd>
+    The JNI code associated with <a href="http://developer.android.com/reference/android/media/package-summary.html">android.media</a> is located in the
+    <code>frameworks/base/core/jni/</code> and <code>frameworks/base/media/jni</code> directories.
+    This code calls the lower level native code to obtain access to the audio hardware.
+  </dd>
+  <dt>
+    Native framework
+  </dt>
+  <dd>
+    The native framework is defined in <code>frameworks/av/media/libmedia</code> and provides a
+    native equivalent to the <a href="http://developer.android.com/reference/android/media/package-summary.html">android.media</a> package. The native framework calls the Binder
+    IPC proxies to obtain access to audio-specific services of the media server.
+  </dd>
+  <dt>
+    Binder IPC
+  </dt>
+  <dd>
+    The Binder IPC proxies facilitate communication over process boundaries. They are located in
+    the <code>frameworks/av/media/libmedia</code> directory and begin with the letter "I".
+  </dd>
+  <dt>
+    Media Server
+  </dt>
+  <dd>
+    The audio services in the media server, located in
+    <code>frameworks/av/services/audioflinger</code>, is the actual code that interacts with your
+    HAL implementations.
+  </dd>
+  <dt>
+    HAL
+  </dt>
+  <dd>
+    The hardware abstraction layer defines the standard interface that audio services calls into
+    and that you must implement to have your audio hardware function correctly. The audio HAL
+    interfaces are located in <code>hardware/libhardware/include/hardware</code>.
+  </dd>
+  <dt>
+    Kernel Driver
+  </dt>
+  <dd>
+    The audio driver interacts with the hardware and your implementation of the HAL. You can choose
+    to use ALSA, OSS, or a custom driver of your own at this level. The HAL is driver-agnostic.
+    <p>
+  <strong>Note:</strong> If you do choose ALSA, we recommend using <code>external/tinyalsa</code>
+  for the user portion of the driver because of its compatible licensing (The standard user-mode
+  library is GPL licensed).
+</p>
+  </dd>
+</dl>
+<h2 id="implementing">
+  Implementing the HAL
+</h2>
+<p>
+  The audio HAL is composed of three different interfaces that you must implement:
+</p>
+<ul>
+  <li>
+    <code>hardware/libhardware/include/hardware/audio.h</code> - represents the main functions of
+    an audio device.
+  </li>
+  <li>
+    <code>hardware/libhardware/include/hardware/audio_policy.h</code> - represents the audio policy
+    manager, which handles things like audio routing and volume control policies.
+  </li>
+  <li>
+    <code>hardware/libhardware/include/hardware/audio_effect.h</code> - represents effects that can
+    be applied to audio such as downmixing, echo, or noise supression.
+  </li>
+</ul>
+<p>See the implementation for the Galaxy Nexus at <code>device/samsung/tuna/audio</code> for an example.</p>
+
+<p>In addition to implementing the HAL, you need to create a
+  <code>device/&lt;company_name&gt;/&lt;device_name&gt;/audio/audio_policy.conf</code> file
+  that declares the audio devices present on your product. For an example, see the file for
+  the Galaxy Nexus audio hardware in <code>device/samsung/tuna/audio/audio_policy.conf</code>. 
+Also, see
+  the <code>system/core/include/system/audio.h</code> and <code>system/core/include/system/audio_policy.h</code>
+   header files for a reference of the properties that you can define.
+</p>
+<h3 id="multichannel">Multi-channel support</h3>
+<p>If your hardware and driver supports multi-channel audio via HDMI, you can output the audio stream
+  directly to the audio hardware. This bypasses the AudioFlinger mixer so it doesn't get downmixed to two channels. 
+  
+  <p>
+  The audio HAL must expose whether an output stream profile supports multi-channel audio capabilities.
+  If the HAL exposes its capabilities, the default policy manager allows multichannel playback over 
+  HDMI.</p>
+ <p>For more implementation details, see the <code>device/samsung/tuna/audio/audio_hw.c</code> in the Jellybean release.</p>
+
+  <p>
+  To specify that your product contains a multichannel audio output, edit the <code>audio_policy.conf</code> file to describe the multichannel
+  output for your product. The following is an example from the Galaxy Nexus that shows a "dynamic" channel mask, which means the audio policy manager
+  queries the actual channel masks supported by the HDMI sink after connection. You can also specify a static channel mask like <code>AUDIO_CHANNEL_OUT_5POINT1</code>
+  </p>
+<pre>
+audio_hw_modules {
+  primary {
+    outputs {
+        ...
+        hdmi {  
+          sampling_rates 44100|48000
+          channel_masks dynamic
+          formats AUDIO_FORMAT_PCM_16_BIT
+          devices AUDIO_DEVICE_OUT_AUX_DIGITAL
+          flags AUDIO_OUTPUT_FLAG_DIRECT
+        }
+        ...
+    }
+    ...
+  }
+  ...
+}
+</pre>
+
+
+  <p>If your product does not support multichannel audio, AudioFlinger's mixer downmixes the content to stereo
+    automatically when sent to an audio device that does not support multichannel audio.</p>
+</p>
+
+<h3 id="codecs">Media Codecs</h3>
+
+<p>Ensure that the audio codecs that your hardware and drivers support are properly declared for your product. See
+  <a href="{@docRoot}guide/media.html#expose"> Exposing Codecs to the Framework</a> for information on how to do this.
+</p>
+
+<h2 id="configuring">
+  Configuring the Shared Library
+</h2>
+<p>
+  You need to package the HAL implementation into a shared library and copy it to the
+  appropriate location by creating an <code>Android.mk</code> file:
+</p>
+<ol>
+  <li>Create a <code>device/&lt;company_name&gt;/&lt;device_name&gt;/audio</code> directory
+  to contain your library's source files.
+  </li>
+  <li>Create an <code>Android.mk</code> file to build the shared library. Ensure that the
+  Makefile contains the following line:
+<pre>
+LOCAL_MODULE := audio.primary.&lt;device_name&gt;
+</pre>
+    <p>
+      Notice that your library must be named <code>audio_primary.&lt;device_name&gt;.so</code> so
+      that Android can correctly load the library. The "<code>primary</code>" portion of this
+      filename indicates that this shared library is for the primary audio hardware located on the
+      device. The module names <code>audio.a2dp.&lt;device_name&gt;</code> and
+      <code>audio.usb.&lt;device_name&gt;</code> are also available for bluetooth and USB audio
+      interfaces. Here is an example of an <code>Android.mk</code> from the Galaxy
+      Nexus audio hardware:
+    </p>
+    <pre>
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := audio.primary.tuna
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
+LOCAL_SRC_FILES := audio_hw.c ril_interface.c
+LOCAL_C_INCLUDES += \
+        external/tinyalsa/include \
+        $(call include-path-for, audio-utils) \
+        $(call include-path-for, audio-effects)
+LOCAL_SHARED_LIBRARIES := liblog libcutils libtinyalsa libaudioutils libdl
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_SHARED_LIBRARY)
+</pre>
+  </li>
+  <li>If your product supports low latency audio as specified by the Android CDD, copy the
+  corresponding XML feature file into your product. For example, in your product's
+   <code>device/&lt;company_name&gt;/&lt;device_name&gt;/device.mk</code> 
+  Makefile:
+    <pre>
+PRODUCT_COPY_FILES := ...
+
+PRODUCT_COPY_FILES += \
+frameworks/native/data/etc/android.android.hardware.audio.low_latency.xml:system/etc/permissions/android.hardware.audio.low_latency.xml \
+</pre>
+  </li>
+ 
+  <li>Copy the <code>audio_policy.conf</code> file that you created earlier to the <code>system/etc/</code> directory
+  in your product's <code>device/&lt;company_name&gt;/&lt;device_name&gt;/device.mk</code> 
+  Makefile. For example:
+    <pre>
+PRODUCT_COPY_FILES += \
+        device/samsung/tuna/audio/audio_policy.conf:system/etc/audio_policy.conf
+</pre>
+  </li>
+  <li>Declare the shared modules of your audio HAL that are required by your product in the product's
+    <code>device/&lt;company_name&gt;/&lt;device_name&gt;/device.mk</code> Makefile. For example, the
+  Galaxy Nexus requires the primary and bluetooth audio HAL modules:
+<pre>
+PRODUCT_PACKAGES += \
+        audio.primary.tuna \
+        audio.a2dp.default
+</pre>
+  </li>
+</ol>
+
+<h2>Audio preprocessing effects</h2>
+<p>You can expose audio preprocessing effects to application developers through your
+audio HAL so they can take advantage of platform features. Preprocessing effects
+are always paired with the use case mode in which the preprocessing is requested. In Android
+app development, a use case is referred to as an <code>AudioSource</code>, and app developers
+request to use the <code>AudioSource</code> abstraction instead of the actual audio hardware device to use.
+The following list shows the different
+<code>AudioSource</code> options available that an app developer can choose.
+</p>
+<ul>
+<code><li>android.media.MediaRecorder.AudioSource.CAMCORDER</li></code>
+<code><li>android.media.MediaRecorder.AudioSource.VOICE_COMMUNICATION</li></code>
+<code><li>android.media.MediaRecorder.AudioSource.VOICE_CALL</li></code>
+<code><li>android.media.MediaRecorder.AudioSource.VOICE_DOWNLINK</li></code>
+<code><li>android.media.MediaRecorder.AudioSource.VOICE_UPLINK</li></code>
+<code><li>android.media.MediaRecorder.AudioSource.VOICE_RECOGNITION</li></code>
+<code><li>android.media.MediaRecorder.AudioSource.MIC</li></code>
+<code><li>android.media.MediaRecorder.AudioSource.DEFAULT</li></code>
+</ul>
+
+<p>The default preprocessing effects to be applied for each of the <code>AudioSource</code> is 
+specified in the <code>/system/etc/audio_effects.conf</code> file. To specify
+your own effects, create a <code>/system/vendor/etc/audio_effects.conf</code> file
+and specify any preprocessing effects that you need to turn on for every <code>AudioSource</code> type.
+
+<p class="note"><strong>Note:</strong> Voice recognition does not have any preprocessing 
+effects by default</p>
+
+The following example for Nexus 10 enables preprocessing for the VOIP <code>AudioSource</code> and Camcorder <code>AudioSource</code>.
+</p>
+
+<pre>
+effects {
+ agc {
+   library audience_pre_processing
+   uuid e9e87eb0-0b55-11e2-892e-0800200c9a66
+ }
+ ...
+}
+
+pre_processing {
+   voice_communication {
+       aec {}
+       ns {}
+   }
+   camcorder {
+       agc {}
+   }
+}
+</pre>
+
+<h3>Source tuning</h3>
+<p>For source tuning, there are no explicit requirements on audio gain or audio processing
+with the exception of voice recognition (<code>VOICE_RECOGNITION</code>).</p>
+
+<p>The Android Audio Policy Manager maps sources to devices with <code>AudioPolicyManagerBase::getDeviceForInputSource(int 
+inputSource)</code>. In Android 4.2, the following sources are exposed to developers:
+</p>
+
+<pre>
+android.media.AcousticEchoCanceller
+android.media.AutomaticGainControl
+android.media.NoiseSuppressor
+</pre>
+
+<p>
+The audio preprocessing effects are developer facing APIs for platform effects that you 
+can tune on a use case basis. For example, you can tune noise suppressor and wind noise suppressor for <code>CAMCORDER</code>
+or stationary noise suppressor for <code>VOICE_COMMUNICATION</code>.
+Similarly, you can tune Automatic Gain Control (<code>agc</code>) for close-talk for 
+<code>VOICE_COMMUNICATION</code> and main phone mic for far-talk for <code>CAMCORDER</code>.
+</p>
+
+<h3>Voice recognition configuration and requirements</h3>
+<p>The following are the requirements for voice recognition:</p>
+
+<ul>
+<li>"flat" frequency response (+/- 3dB) from 100Hz to 4kHz</li>
+<li>close-talk config: 90dB SPL reads RMS of 2500 (16bit samples)</li>
+<li>level tracks linearly from -18dB to +12dB relative to 90dB SPL</li>
+<li>THD < 1% (90dB SPL in 100 to 4000Hz range)</li>
+<li>8kHz sampling rate (anti-aliasing)</li>
+<li>Effects / pre-processing must be disabled by default</li>
+</ul>
+
+<h3>Implementing audio preprocessing effects</h3>
+
+<h3>More information</h3>
+<p>For more information, see:</p>
+<ul>
+<li>Android Open Source Project documentation for 
+<a href="http://developer.android.com/reference/android/media/audiofx/packagesummary.html">audio effects</a>.</li>
+<li>Android Open Source project documentation for <a href="http://developer.android.com/reference/android/media/audiofx/NoiseSuppressor.
+html">Noise Suppression audio effect</a></li>
+</ul>
diff --git a/src/devices/audio_latency.jd b/src/devices/audio_latency.jd
new file mode 100644
index 0000000..476842b
--- /dev/null
+++ b/src/devices/audio_latency.jd
@@ -0,0 +1,307 @@
+page.title=Audio Latency
+@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>Audio latency is the time delay as an audio signal passes through a system.
+  For a complete description of audio latency for the purposes of Android
+  compatibility, see <em>Section 5.4 Audio Latency</em>
+  in the <a href="http://source.android.com/compatibility/index.html">Android CDD</a>.
+</p>
+
+<h2 id="contributors">Contributors to Latency</h2>
+
+<p>
+  This section focuses on the contributors to output latency,
+  but a similar discussion applies to input latency.
+</p>
+<p>
+  Assuming that the analog circuitry does not contribute significantly.
+  Then the major surface-level contributors to audio latency are the following:
+</p>
+
+<ul>
+  <li>Application</li>
+  <li>Total number of buffers in pipeline</li>
+  <li>Size of each buffer, in frames</li>
+  <li>Additional latency after the app processor, such as from a DSP</li>
+</ul>
+
+<p>
+  As accurate as the above list of contributors may be, it is also misleading.
+  The reason is that buffer count and buffer size are more of an
+  <em>effect</em> than a <em>cause</em>.  What usually happens is that
+  a given buffer scheme is implemented and tested, but during testing, an audio
+  underrun is heard as a "click" or "pop".  To compensate, the
+  system designer then increases buffer sizes or buffer counts.
+  This has the desired result of eliminating the underruns, but it also
+  has the undesired side effect of increasing latency.
+</p>
+
+<p>
+  A better approach is to understand the underlying causes of the
+  underruns and then correct those.  This eliminates the
+  audible artifacts and may even permit even smaller or fewer buffers
+  and thus reduce latency.
+</p>
+
+<p>
+  In our experience, the most common causes of underruns include:
+</p>
+<ul>
+  <li>Linux CFS (Completely Fair Scheduler)</li>
+  <li>high-priority threads with SCHED_FIFO scheduling</li>
+  <li>long scheduling latency</li>
+  <li>long-running interrupt handlers</li>
+  <li>long interrupt disable time</li>
+</ul>
+
+<h3>Linux CFS and SCHED_FIFO scheduling</h3>
+<p>
+  The Linux CFS is designed to be fair to competing workloads sharing a common CPU
+  resource. This fairness is represented by a per-thread <em>nice</em> parameter.
+  The nice value ranges from -19 (least nice, or most CPU time allocated)
+  to 20 (nicest, or least CPU time allocated). In general, all threads with a given
+  nice value receive approximately equal CPU time and threads with a
+  numerically lower nice value should expect to
+  receive more CPU time. However, CFS is "fair" only over relatively long
+  periods of observation. Over short-term observation windows,
+  CFS may allocate the CPU resource in unexpected ways. For example, it
+  may take the CPU away from a thread with numerically low niceness
+  onto a thread with a numerically high niceness.  In the case of audio,
+  this can result in an underrun.
+</p>
+
+<p>
+  The obvious solution is to avoid CFS for high-performance audio
+  threads. Beginning with Android 4.1 (Jelly Bean), such threads now use the
+  <code>SCHED_FIFO</code> scheduling policy rather than the <code>SCHED_NORMAL</code> (also called
+  <code>SCHED_OTHER</code>) scheduling policy implemented by CFS.
+</p>
+
+<p>
+  Though the high-performance audio threads now use <code>SCHED_FIFO</code>, they
+  are still susceptible to other higher priority <code>SCHED_FIFO</code> threads.
+  These are typically kernel worker threads, but there may also be a few
+  non-audio user threads with policy <code>SCHED_FIFO</code>. The available <code>SCHED_FIFO</code>
+  priorities range from 1 to 99.  The audio threads run at priority
+  2 or 3.  This leaves priority 1 available for lower priority threads,
+  and priorities 4 to 99 for higher priority threads.  We recommend that
+  you use priority 1 whenever possible, and reserve priorities 4 to 99 for
+  those threads that are guaranteed to complete within a bounded amount
+  of time, and are known to not interfere with scheduling of audio threads.
+</p>
+
+<h3>Scheduling latency</h3>
+<p>
+  Scheduling latency is the time between when a thread becomes
+  ready to run, and when the resulting context switch completes so that the
+  thread actually runs on a CPU. The shorter the latency the better and 
+  anything over two milliseconds causes problems for audio. Long scheduling
+  latency is most likely to occur during mode transitions, such as
+  bringing up or shutting down a CPU, switching between a security kernel
+  and the normal kernel, switching from full power to low-power mode,
+  or adjusting the CPU clock frequency and voltage.
+</p>
+
+<h3>Interrupts</h3>
+<p>
+  In many designs, CPU 0 services all external interrupts.  So a
+  long-running interrupt handler may delay other interrupts, in particular
+  audio DMA completion interrupts. Design interrupt handlers
+  to finish quickly and defer any lengthy work to a thread (preferably
+  a CFS thread or <code>SCHED_FIFO</code> thread of priority 1).
+</p>
+
+<p>
+  Equivalently, disabling interrupts on CPU 0 for a long period
+  has the same result of delaying the servicing of audio interrupts.
+  Long interrupt disable times typically happen while waiting for a kernel
+  <i>spin lock</i>.  Review these spin locks to ensure that
+  they are bounded.
+</p>
+
+
+
+<h2 id="measuringOutput">Measuring Output Latency</h2>
+
+<p>
+  There are several techniques available to measure output latency,
+  with varying degrees of accuracy and ease of running.
+</p>
+
+<h3>LED and oscilloscope test</h3>
+<p>
+This test measures latency in relation to the device's LED indicator.
+If your production device does not have an LED, you can install the
+  LED on a prototype form factor device. For even better accuracy
+  on prototype devices with exposed circuity, connect one
+  oscilloscope probe to the LED directly to bypass the light
+  sensor latency.
+  </p>
+
+<p>
+  If you cannot install an LED on either your production or prototype device,
+  try the following workarounds:
+</p>
+
+<ul>
+  <li>Use a General Purpose Input/Output (GPIO) pin for the same purpose</li>
+  <li>Use JTAG or another debugging port</li>
+  <li>Use the screen backlight. This might be risky as the
+  backlight may have a non-neglible latency, and can contribute to
+  an inaccurate latency reading.
+  </li>
+</ul>
+
+<p>To conduct this test:</p>
+
+<ol>
+  <li>Run an app that periodically pulses the LED at
+  the same time it outputs audio. 
+
+  <p class="note"><b>Note:</b> To get useful results, it is crucial to use the correct
+  APIs in the test app so that you're exercising the fast audio output path.
+  See the separate document "Application developer guidelines for reduced
+  audio latency". <!-- where is this ?-->
+  </p>
+  </li>
+  <li>Place a light sensor next to the LED.</li>
+  <li>Connect the probes of a dual-channel oscilloscope to both the wired headphone
+  jack (line output) and light sensor.</li>
+  <li>Use the oscilloscope to measure
+  the time difference between observing the line output signal versus the light
+  sensor signal.</li>
+</ol>
+
+  <p>The difference in time is the approximate audio output latency,
+  assuming that the LED latency and light sensor latency are both zero.
+  Typically, the LED and light sensor each have a relatively low latency
+  on the order of 1 millisecond or less, which is sufficiently low enough
+  to ignore.</p>
+
+<h3>Larsen test</h3>
+<p>
+  One of the easiest latency tests is an audio feedback
+  (Larsen effect) test. This provides a crude measure of combined output
+  and input latency by timing an impulse response loop. This test is not very useful
+  by itself because of the nature of the test, but</p>
+
+<p>To conduct this test:</p>
+<ol>
+  <li>Run an app that captures audio from the microphone and immediately plays the
+  captured data back over the speaker.</li>
+  <li>Create a sound externally,
+  such as tapping a pencil by the microphone. This noise generates a feedback loop.</li>
+  <li>Measure the time between feedback pulses to get the sum of the output latency, input latency, and application overhead.</li>
+</ol>
+
+  <p>This method does not break down the
+  component times, which is important when the output latency
+  and input latency are independent, so this method is not recommended for measuring output latency, but might be useful
+  to help measure output latency.</p>
+
+<h2 id="measuringInput">Measuring Input Latency</h2>
+
+<p>
+  Input latency is more difficult to measure than output latency. The following
+  tests might help.
+</p>
+
+<p>
+One approach is to first determine the output latency
+  using the LED and oscilloscope method and then use
+  the audio feedback (Larsen) test to determine the sum of output
+  latency and input latency. The difference between these two
+  measurements is the input latency.
+</p>
+
+<p>
+  Another technique is to use a GPIO pin on a prototype device.
+  Externally, pulse a GPIO input at the same time that you present
+  an audio signal to the device.  Run an app that compares the
+  difference in arrival times of the GPIO signal and audio data.
+</p>
+
+<h2 id="reducing">Reducing Latency</h2>
+
+<p>To achieve low audio latency, pay special attention throughout the
+system to scheduling, interrupt handling, power management, and device
+driver design. Your goal is to prevent any part of the platform from
+blocking a <code>SCHED_FIFO</code> audio thread for more than a couple
+of milliseconds. By adopting such a systematic approach, you can reduce
+audio latency and get the side benefit of more predictable performance
+overall.
+</p>
+
+
+ <p>
+  Audio underruns, when they do occur, are often detectable only under certain
+  conditions or only at the transitions. Try stressing the system by launching
+  new apps and scrolling quickly through various displays. But be aware
+  that some test conditions are so stressful as to be beyond the design
+  goals. For example, taking a bugreport puts such enormous load on the
+  system that it may be acceptable to have an underrun in that case.
+</p>
+
+<p>
+  When testing for underruns:
+</p>
+  <ul>
+  <li>Configure any DSP after the app processor so that it adds
+  minimal latency</li>
+  <li>Run tests under different conditions
+  such as having the screen on or off, USB plugged in or unplugged,
+  WiFi on or off, Bluetooth on or off, and telephony and data radios
+  on or off.</li>
+  <li>Select relatively quiet music that you're very familiar with, and which is easy
+  to hear underruns in.</li>
+  <li>Use wired headphones for extra sensitivity.</li>
+  <li>Give yourself breaks so that you don't experience "ear fatigue".</li>
+  </ul>
+
+<p>
+  Once you find the underlying causes of underruns, reduce
+  the buffer counts and sizes to take advantage of this.
+  The eager approach of reducing buffer counts and sizes <i>before</i>
+  analyzing underruns and fixing the causes of underruns only
+  results in frustration.
+</p>
+
+<h3 id="tools">Tools</h3>
+<p>
+  <code>systrace</code> is an excellent general-purpose tool
+  for diagnosing system-level performance glitches.
+</p>
+
+<p>
+  The output of <code>dumpsys media.audio_flinger</code> also contains a
+  useful section called "simple moving statistics". This has a summary
+  of the variability of elapsed times for each audio mix and I/O cycle.
+  Ideally, all the time measurements should be about equal to the mean or
+  nominal cycle time. If you see a very low minimum or high maximum, this is an
+  indication of a problem, which is probably a high scheduling latency or interrupt
+  disable time. The <i>tail</i> part of the output is especially helpful,
+  as it highlights the variability beyond +/- 3 standard deviations.
+</p>
\ No newline at end of file
diff --git a/src/devices/audio_preprocessing.jd b/src/devices/audio_preprocessing.jd
new file mode 100644
index 0000000..4beb7e0
--- /dev/null
+++ b/src/devices/audio_preprocessing.jd
@@ -0,0 +1,111 @@
+page.title=Audio Warmup
+@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>Audio warmup is the time for the audio amplifier circuit in your device to
+be fully powered and reach its normal operation state. The major contributors
+to audio warmup time are power management and any "de-pop" logic to stabilize
+the circuit.
+</p>
+
+<p>This document describes how to measure audio warmup time and possible ways to decrease
+warmup time.</p>
+
+<h2 id="measuringOutput">Measuring Output Warmup</h2>
+
+<p>
+  AudioFlinger's FastMixer thread automatically measures output warmup
+  and reports it as part of the output of the <code>dumpsys media.audio_flinger</code> command.
+  At warmup, FastMixer calls <code>write()</code>
+  repeatedly until the time between two <code>write()</code>s is the amount expected.
+  FastMixer determines audio warmup by seeing how long a HAL <code>write()</code> takes to stabilize. 
+</p>
+
+<p>To measure audio warmup, do the following
+steps for the built-in speaker and wired headphones and at different times after booting.
+Warmup times are usually different for each output device and right after booting the device:</p>
+
+<ol>
+  <li>Ensure that FastMixer is enabled.</li>
+  <li>Enable touch sounds by selecting <b>Settings > Sound > Touch sounds</b> on the device.</li>
+  <li>Ensure that audio has been off for at least three seconds. Five seconds or more is better, because
+  the hardware itself might have its own power logic beyond the three seconds that AudioFlinger has.</li>
+  <li>Press Home, and you should hear a click sound.</li>
+  <li>Run the following command to receive the measured warmup:
+  <pre>adb shell dumpsys media.audio_flinger | grep measuredWarmup</code></pre>
+
+<p>
+You should see output like this:
+</p>
+
+<pre>
+sampleRate=44100 frameCount=256 measuredWarmup=X ms, warmupCycles=X
+</pre>
+
+<p>
+  The <code>measuredWarmup=X</code> is X number of milliseconds
+  it took for the first set of HAL <code>write()</code>s to complete.
+</p>
+
+<p>
+  The <code>warmupCycles=X</code> is how many HAL write requests it took
+  until the execution time of <code>write()</code> matches what is expected.
+</p>
+</li>
+<li>
+  Take five measurements and report them all, as well as the mean.
+  If they are not all approximately the same,
+  then it’s likely that a measurement is incorrect.
+  For example, if you don’t wait long enough after the audio has been off,
+  you will see a lower warmup time than the mean value.
+</li>
+</ol>
+
+
+<h2 id="measuringInput">Measuring Input Warmup</h2>
+
+<p>
+  There are currently no tools provided for measuring audio input warmup.
+  However, input warmup time can be estimated by observing
+  the time required for <a href="http://developer.android.com/reference/android/media/AudioRecord.html#startRecording()">startRecording()</a>
+  to return. 
+</p>
+
+
+<h2 id="reducing">Reducing Warmup Time</h2>
+
+<p>
+  Warmup time can usually be reduced by a combination of:
+  <ul>
+  <li>Good circuit design</li>
+  <li>Accurate time delays in kernel device driver</li>
+  <li>Performing independent warmup operations concurrently rather than sequentially</li>
+  <li>Leaving circuits powered on or not reconfiguring clocks (increases idle power consumption).
+  <li>Caching computed parameters</li>
+  </ul>
+  However, beware of excessive optimization. You may find that you
+  need to tradeoff between low warmup time versus
+  lack of popping at power transitions.
+</p>
diff --git a/src/devices/audio_warmup.jd b/src/devices/audio_warmup.jd
new file mode 100644
index 0000000..4beb7e0
--- /dev/null
+++ b/src/devices/audio_warmup.jd
@@ -0,0 +1,111 @@
+page.title=Audio Warmup
+@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>Audio warmup is the time for the audio amplifier circuit in your device to
+be fully powered and reach its normal operation state. The major contributors
+to audio warmup time are power management and any "de-pop" logic to stabilize
+the circuit.
+</p>
+
+<p>This document describes how to measure audio warmup time and possible ways to decrease
+warmup time.</p>
+
+<h2 id="measuringOutput">Measuring Output Warmup</h2>
+
+<p>
+  AudioFlinger's FastMixer thread automatically measures output warmup
+  and reports it as part of the output of the <code>dumpsys media.audio_flinger</code> command.
+  At warmup, FastMixer calls <code>write()</code>
+  repeatedly until the time between two <code>write()</code>s is the amount expected.
+  FastMixer determines audio warmup by seeing how long a HAL <code>write()</code> takes to stabilize. 
+</p>
+
+<p>To measure audio warmup, do the following
+steps for the built-in speaker and wired headphones and at different times after booting.
+Warmup times are usually different for each output device and right after booting the device:</p>
+
+<ol>
+  <li>Ensure that FastMixer is enabled.</li>
+  <li>Enable touch sounds by selecting <b>Settings > Sound > Touch sounds</b> on the device.</li>
+  <li>Ensure that audio has been off for at least three seconds. Five seconds or more is better, because
+  the hardware itself might have its own power logic beyond the three seconds that AudioFlinger has.</li>
+  <li>Press Home, and you should hear a click sound.</li>
+  <li>Run the following command to receive the measured warmup:
+  <pre>adb shell dumpsys media.audio_flinger | grep measuredWarmup</code></pre>
+
+<p>
+You should see output like this:
+</p>
+
+<pre>
+sampleRate=44100 frameCount=256 measuredWarmup=X ms, warmupCycles=X
+</pre>
+
+<p>
+  The <code>measuredWarmup=X</code> is X number of milliseconds
+  it took for the first set of HAL <code>write()</code>s to complete.
+</p>
+
+<p>
+  The <code>warmupCycles=X</code> is how many HAL write requests it took
+  until the execution time of <code>write()</code> matches what is expected.
+</p>
+</li>
+<li>
+  Take five measurements and report them all, as well as the mean.
+  If they are not all approximately the same,
+  then it’s likely that a measurement is incorrect.
+  For example, if you don’t wait long enough after the audio has been off,
+  you will see a lower warmup time than the mean value.
+</li>
+</ol>
+
+
+<h2 id="measuringInput">Measuring Input Warmup</h2>
+
+<p>
+  There are currently no tools provided for measuring audio input warmup.
+  However, input warmup time can be estimated by observing
+  the time required for <a href="http://developer.android.com/reference/android/media/AudioRecord.html#startRecording()">startRecording()</a>
+  to return. 
+</p>
+
+
+<h2 id="reducing">Reducing Warmup Time</h2>
+
+<p>
+  Warmup time can usually be reduced by a combination of:
+  <ul>
+  <li>Good circuit design</li>
+  <li>Accurate time delays in kernel device driver</li>
+  <li>Performing independent warmup operations concurrently rather than sequentially</li>
+  <li>Leaving circuits powered on or not reconfiguring clocks (increases idle power consumption).
+  <li>Caching computed parameters</li>
+  </ul>
+  However, beware of excessive optimization. You may find that you
+  need to tradeoff between low warmup time versus
+  lack of popping at power transitions.
+</p>
diff --git a/src/devices/bluetooth.jd b/src/devices/bluetooth.jd
new file mode 100644
index 0000000..c974227
--- /dev/null
+++ b/src/devices/bluetooth.jd
@@ -0,0 +1,116 @@
+page.title=Bluetooth
+@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>Android provides a default Bluetooth stack, BlueDroid, that is divided into two layers: The Bluetooth Embedded System (BTE), which implements the core
+Bluetooth functionality and the Bluetooth Application Layer (BTA), which communicates
+with Android framework applications. A Bluetooth system service communicates with the Bluetooth stack through JNI and with applications through
+Binder IPC. The system service provides developers access to various Bluetooth profiles. The following
+diagram shows the general structure of the Bluetooth stack:
+</p>
+
+<p><img src="images/bt.png"></p>
+
+<dl>
+  <dt>Application framework</dt>
+  <dd>At the application framework level is the app's code, which utilizes the <a 
+  href="http://developer.android.com/reference/android/bluetooth/package-summary.html">android.bluetooth</a>
+  APIs to interact with the bluetooth hardware. Internally, this code calls the Bluetooth process through
+  the Binder IPC mechanism.</dd>
+  
+  <dt>Bluetooth system service</dt>
+  <dd>The Bluetooth system service, located in <code>packages/apps/Bluetooth</code>, is packaged as an Android
+  	app and implements the Bluetooth service and profiles at the Android framework layer. This app
+  	calls into the HAL layer via JNI.</p>
+
+  <dt>JNI</dt>
+  <dd>The JNI code associated with <a 
+  href="http://developer.android.com/reference/android/bluetooth/package-summary.html">android.bluetooth</a> is located in
+  <code>packages/apps/Bluetooth/jni</code>. The JNI code calls into the HAL layer and receives
+  callbacks from the HAL when certain Bluetooth operations occur, such as when devices are
+  discovered.</dd>
+
+  <dt>HAL</dt>
+  <dd>The hardware abstraction layer defines the standard interface that the <a 
+  href="http://developer.android.com/reference/android/bluetooth/package-summary.html">android.bluetooth</a> APIs
+  	and Bluetooth process calls into and that you must implement to have your bluetooth hardware
+  	function correctly. The header files for the Bluetooth HAL is located
+  in the <code>hardware/libhardware/include/hardware/bluetooth.h</code> and
+  <code>hardware/libhardware/include/hardware/bt_*.h</code> files.
+  </dd>
+
+    <dt>Bluetooth stack</dt>
+  <dd>The default Bluetooth stack is provided for you and is located in
+  <code>external/bluetooth/bluedroid</code>. The stack implements the generic Bluetooth HAL as well
+  as customizes it with extensions and configuration changes.
+  </dd>
+
+    <dt>Vendor extensions</dt>
+  <dd>To add custom extensions and an HCI layer for tracing, you can create a libbt-vendor module
+  	and specify these components.
+  </dd>
+
+  </dl>
+
+
+<h2 id="implementing">Implementing the HAL</h2>
+<p>The Bluetooth HAL is located in the <code>hardware/libhardware/include/hardware/</code> directory
+ and consists of the following header files:
+
+<ul>
+  <li><code>bluetooth.h</code>: Contains the HAL for the Bluetooth hardware on the device</li>
+  <li><code>bt_av.h</code>: Contains the HAL for the advanced audio profile.</li>
+  <li><code>bt_hf.h</code>: Contains the HAL for the handsfree profile.</li>
+  <li><code>bt_hh.h</code>: Contains the HAL for the HID host profile</li>
+  <li><code>bt_hl.h</code>: Contains the HAL for the health profile</li>
+  <li><code>bt_pan.h</code>: Contains the HAL for the pan profile</li>
+  <li><code>bt_sock.h</code>: Contains the HAL for the socket profile.</li>
+</ul>
+
+</p>
+
+<p>Keep in mind that your Bluetooth implementation is not constrained to the features
+	and profiles exposed in the HAL. You can find the default implementation located
+	in the BlueDroid Bluetooth stack in the <code>external/bluetooth/bluedroid</code> directory,
+	which implements the default HAL and also extra features and customizations.</p>
+</p>
+
+<h2>Customizing the BlueDroid Stack</h2>
+
+<p>If you are using the default BlueDroid stack, but want to make a few customizations, you can
+	do the following things:</p>
+
+<ul>
+	<li>Custom Bluetooth profiles - If you want to add Bluetooth profiles that do not have
+		HAL interfaces provided by Android, you must supply an SDK add-on download to make the profile available to app developers,
+		make the APIs available in the Bluetooth system	process app (<code>packages/apps/Bluetooth</code>), and add them
+		to the BlueDroid stack (<code>external/bluetooth/bluedroid</code>).</li>
+	<li>Custom vendor extensions and configuration changes - You can add things such as extra AT commands or device-specific configuration changes
+		by creating a <code>libbt-vendor</code> module. See the <code>vendor/broadcom/libbt-vendor</code> directory
+		for an example.</li>
+	<li>Host Controller Interface (HCI) - You can provide your own HCI by creating a <code>libbt-hci</code> module, which
+		is mainly used for debug tracing. See the <code>external/bluetooth/hci</code> directory for an example.</li>
+</ul>
diff --git a/src/devices/build_new_device.jd b/src/devices/build_new_device.jd
new file mode 100644
index 0000000..7f9cdd2
--- /dev/null
+++ b/src/devices/build_new_device.jd
@@ -0,0 +1,411 @@
+page.title=Configuring and Building a Product
+@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>
+  There are many ways to organize the source files for your device. We'll briefly go over how the
+  Galaxy Nexus implementation was organized as an example, but you can organize your source files
+  and build the way you see fit.
+</p>
+<p>
+  Galaxy Nexus was implemented with a main device configuration named <code>tuna</code> that has
+  two specific variations: <code>maguro</code> for GSM and <code>toro</code> for CDMA. The two
+  device variations inherited common characteristics from <code>tuna</code> by calling
+  <code>tuna</code>'s device Makefile and then defined their own device-specific characteristics.
+  From these device configurations, a product is created with a product definition Makefile that
+  declares product-specific information about the device such as the name and model.
+  You can view the <code>device/samsung/tuna</code>, <code>device/samsung/maguro</code>, and
+  <code>device/samsung/toro</code> directories to see how all of this is setup.
+</p>
+<h2 id="configuring">
+  Configuring a Product
+</h2>
+<p>
+  The following steps describe how to set up products in a way similar to that of the Galaxy Nexus
+  product line:
+</p>
+<ol>
+  <li>Create a <code>device/&lt;company_name&gt;/&lt;device_name&gt;</code> directory for your
+  product. For example, <code>device/samsung/tuna</code>. This directory will contain source code
+  for your device along with the Makefiles to build them.
+  </li>
+
+  <li>Create a <code>device.mk</code> Makefile that declares the files and modules needed for the
+  device. For an example, see <code>device/samsung/tuna/device.mk</code>.
+  </li>
+
+  <li>Create a product definition Makefile to create a specific product based on the device. The
+  following Makefile is taken from <code>device/samsung/tuna/full_tuna.mk</code> as an example.
+  Notice that the product is inheriting from the tuna and full (emulator) devices via their
+  Makefiles, while also declaring the product-specific information such as the name, brand, and model.
+  
+<pre>
+# Inherit from those products. Most specific first.
+$(call inherit-product, $(SRC_TARGET_DIR)/product/full_base.mk)
+# This is where we'd set a backup provider if we had one
+#$(call inherit-product, device/sample/products/backup_overlay.mk)
+# Inherit from tuna device
+$(call inherit-product, device/samsung/tuna/device.mk)
+
+# Set those variables here to overwrite the inherited values.
+PRODUCT_NAME := full_tuna
+PRODUCT_DEVICE := tuna
+PRODUCT_BRAND := Android
+PRODUCT_MODEL := Full AOSP on Tuna
+</pre>
+
+    <p>
+      See <a href="{@docRoot}devices/build_new_device.html#prod-def">Product Definition Variables</a> for additional product-specific
+      variables you can add to your Makefiles.
+    </p>    
+  </li>
+
+  <li>Create an <code>AndroidProducts.mk</code> file that points to the product's Makefiles. In
+  this example, only the product definition Makefile is needed. The example below is from
+  <code>device/samsung/tuna/AndroidProducts.mk</code>:
+    <pre>
+#
+# This file should set PRODUCT_MAKEFILES to a list of product makefiles
+# to expose to the build system.  LOCAL_DIR will already be set to
+# the directory containing this file. 
+#
+# This file may not rely on the value of any variable other than
+# LOCAL_DIR; do not use any conditionals, and do not look up the
+# value of any variable that isn't set in this file or in a file that
+# it includes.
+#
+
+PRODUCT_MAKEFILES := \
+    $(LOCAL_DIR)/full_tuna.mk
+</pre>
+  </li>
+
+  <li>Create a <code>BoardConfig.mk</code> Makefile that contains board-specific configurations.
+  For an example, see <code>device/samsung/tuna/BoardConfig.mk</code>.
+  </li>
+
+  <li>Create a <code>vendorsetup.sh</code> file to add your product (a "lunch combo") to the build
+  along with a <a href="{@docRoot}devices/build_system.html#variants">build variant</a> separated by a dash. For example:
+<pre>
+add_lunch_combo &lt;product_name&gt;-userdebug
+</pre>
+  </li>
+
+  <li>At this point, you can create more product variants based on the same device, like how the
+  Galaxy Nexus does with the <code>maguro</code> and <code>toro</code> products. For a complete
+  example, see the Galaxy Nexus implementation in <code>device/samsung/tuna</code>,
+  <code>device/samsung/maguro</code>, and <code>device/samsung/toro</code>.
+  </li>
+
+</ol>
+
+<h3 id="prod-def">
+  Product Definition Variables
+</h3>
+<p>
+  Product-specific variables are defined in the product's Makefile. Variables maintained in a
+  product definition files include:
+</p>
+<table>
+  <tbody>
+    <tr>
+      <th>
+        Parameter
+      </th>
+      <th>
+        Description
+      </th>
+      <th>
+        Example
+      </th>
+    </tr>
+    <tr>
+      <td>
+        PRODUCT_AAPT_CONFIG
+      </td>
+      <td>
+        <code>aapt</code> configurations to use when creating packages
+      </td>
+      <td></td>
+    </tr>
+    <tr>
+      <td>
+        PRODUCT_BRAND
+      </td>
+      <td>
+        The brand (e.g., carrier) the software is customized for, if any
+      </td>
+      <td></td>
+    </tr>
+    <tr>
+      <td>
+        PRODUCT_CHARACTERISTICS
+      </td>
+      <td>
+        <code>aapt</code> characteristics to allow adding variant-specific resources to a package.
+      </td>
+      <td>
+        tablet,nosdcard
+      </td>
+    </tr>
+    <tr>
+      <td>
+        PRODUCT_CONTRIBUTORS_FILE
+      </td>
+      <td>
+        HTML file containing the contributors to the project.
+      </td>
+      <td></td>
+    </tr>
+    <tr>
+      <td>
+        PRODUCT_COPY_FILES
+      </td>
+      <td>
+        List of words like <code>source_path:destination_path</code>. The file at the source path
+        should be copied to the destination path when building this product. The rules for the copy
+        steps are defined in config/Makefile
+      </td>
+      <td></td>
+    </tr>
+    <tr>
+      <td>
+        PRODUCT_DEVICE
+      </td>
+      <td>
+        Name of the industrial design
+      </td>
+      <td>
+        <code>tuna</code>
+      </td>
+    </tr>
+    <tr>
+      <td>
+        PRODUCT_LOCALES
+      </td>
+      <td>
+        A space-separated list of two-letter language code, two-letter country code pairs that
+        describe several settings for the user, such as the UI language and time, date and currency
+        formatting. The first locale listed in PRODUCT_LOCALES is is used if the locale has never
+        been set before.
+      </td>
+      <td>
+        <code>en_GB de_DE es_ES fr_CA</code>
+      </td>
+    </tr>
+    <tr>
+      <td>
+        PRODUCT_MANUFACTURER
+      </td>
+      <td>
+        Name of the manufacturer
+      </td>
+      <td>
+        <code>acme</code>
+      </td>
+    </tr>
+    <tr>
+      <td>
+        PRODUCT_MODEL
+      </td>
+      <td>
+        End-user-visible name for the end product
+      </td>
+      <td></td>
+    </tr>
+    <tr>
+      <td>
+        PRODUCT_NAME
+      </td>
+      <td>
+        End-user-visible name for the overall product. Appears in the Settings &gt; About screen.
+      </td>
+      <td></td>
+    </tr>
+    <tr>
+      <td>
+        PRODUCT_OTA_PUBLIC_KEYS
+      </td>
+      <td>
+        List of Over the Air (OTA) public keys for the product
+      </td>
+      <td></td>
+    </tr>
+    <tr>
+      <td>
+        PRODUCT_PACKAGES
+      </td>
+      <td>
+        Lists the APKs to install.
+      </td>
+      <td>
+        <code>Calendar Contacts</code>
+      </td>
+    </tr>
+    <tr>
+      <td>
+        PRODUCT_PACKAGE_OVERLAYS
+      </td>
+      <td>
+        Indicate whether to use default resources or add any product specific overlays
+      </td>
+      <td>
+        <code>vendor/acme/overlay</code>
+      </td>
+    </tr>
+    <tr>
+      <td>
+        PRODUCT_PROPERTY_OVERRIDES
+      </td>
+      <td>
+        List of property assignments in the format "key=value"
+      </td>
+      <td></td>
+    </tr>
+    <tr>
+      <td>
+        PRODUCT_TAGS
+      </td>
+      <td>
+        list of space-separated words for a given product
+      </td>
+      <td></td>
+    </tr>
+  </tbody>
+</table>
+
+
+<h2 id="building">Building a Product</h2>
+<p>To eventually build your product, add your HAL implementations and drivers to
+  your device's source tree and execute the following commands.</p>
+    <p>
+      For a Fusion build for armv7 with NEON:
+    </p>
+<pre>
+  build/envsetup.sh
+  lunch your_lunch_combo
+  PDK_FUSION_PLATFORM_ZIP=vendor/pdk/mini_armv7a_neon/mini_armv7a_neon-userdebug/platform/platform.zip make -j32
+</pre>
+    <p>
+      For a Fusion build for armv7:
+    </p>
+<pre>
+  build/envsetup.sh
+  lunch your_lunch_combo
+  PDK_FUSION_PLATFORM_ZIP=vendor/pdk/mini_armv7a/mini_armv7a-userdebug/platform/platform.zip make -j32
+</pre>
+    <p>
+      For a non-Fusion build for both architectures, run <code>make</code> like this instead:
+    </p>
+<pre>
+TARGET_BUILD_PDK=true make -j32
+</pre>
+
+<p class="note"><strong>Important:</strong> 
+If you are switching between different lunch combos or between fusion and non-fusion builds,
+run the following command
+to remove any remnants of the test build so that it doesn't interfere
+with your real product's build later on.
+
+<pre>make installclean</pre>
+</p>
+
+    <p>
+      You should find new binaries located in
+      <code>/out/target/product/&lt;device_name&gt;</code>.
+    </p>
+  </li>
+</ol>
+
+
+<h2 id="managing">
+  Managing Makefiles
+</h2>
+<p>
+  Building with the PDK is different from normal product builds that have access to all of the
+  Android sources. Existing product Makefiles require changes to build the product. This section
+  provides an overview of the available workarounds in the PDK to support product builds.
+</p>
+<p>
+  For product Makefiles:
+</p>
+<ul>
+  <li>Use the <code>inherit-product-if-exists</code> macro instead of <code>inherit-product</code>
+  if the target product file does not exist in the PDK.
+  </li>
+  <li>For the <code>PRODUCT_COPY_FILES</code> variable, use the
+  <code>add-to-product-copy-files-if-exists</code> macro, which excludes the component if it does
+  not exist.
+  </li>
+  <li>For an include sentence, use <code>-include</code> to ignore the error if the included file
+  does not exist.
+  </li>
+  <li>You can also check the presence of necessary files and include it in a PDK based build with
+  the <code>$(wildcard ...)</code> macro. For example, the following if statement executes the code
+  block if <code>frameworks/base/Android.mk</code> exists:
+    <pre>
+ifneq ($(wildcard frameworks/base/Android.mk),)
+
+...
+
+endif
+</pre>
+  </li>
+</ul>
+<p>
+  For <code>Android.mk</code> files:
+</p>
+<ul>
+  <li>
+    <code>TARGET_BUILD_PDK</code> is set to true for PDK builds. If you have a component that
+    cannot be built in the PDK build, wrap the code to build the component in an if statement:
+    <pre>
+ifeq ($(TARGET_BUILD_PDK),)
+...
+endif
+</pre>
+  </li>
+  <li>For building Android framework apps, the PDK uses the
+  <code>TARGET_BUILD_JAVA_SUPPORT_LEVEL</code> variable to notify you if building apps is
+  supported. The variable is set to <code>platform</code> if the platform APIs are available. The
+  variable is set to <code>sdk</code> when only SDK based builds are supported. Because the PDK is
+  shared pre-release and is based on a development tree, earlier versions of the PDK may not
+  support a Java build and the variable is set to null. The following statements can enable a Java
+  build only when it is supported:
+    <pre>
+ifneq ($(TARGET_BUILD_JAVA_SUPPORT_LEVEL),)
+...
+endif
+</pre>
+  </li>
+
+  <li style="list-style: none">
+    <p class="note">
+      <strong>Note:</strong> You cannot use <code>TARGET_BUILD_...</code> variables in product
+      definition Makefiles, because these variables are checked after the build reads the product
+      definition Makefiles.
+    </p>
+  </li>
+</ul>
diff --git a/src/devices/build_system.jd b/src/devices/build_system.jd
new file mode 100644
index 0000000..19fd8a3
--- /dev/null
+++ b/src/devices/build_system.jd
@@ -0,0 +1,179 @@
+page.title=Building the PDK
+@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>Android uses a custom build system to generate tools, binaries, and documentation.</p>
+
+<p>The build system is Make-based and requires a recent version of GNU Make (note that
+  Android uses advanced features of GNU Make that may not yet appear on the GNU Make web site).
+  Before continuing, check your version of make by running <code>% make -v</code>. If you
+  don't have version 3.80 or greater, you need to
+  <a href="http://www.gnu.org/software/make/">upgrade your version of make</a>.
+</p>
+
+
+<h2 id="layers">Build Layers</h2>
+
+<p>The build hierarchy includes the abstraction layers that correspond to the physical makeup of a device. These
+  layers are described in the table below. Each layer relates to the one above it in a one-to-many relationship.
+  For example, an architecture can have more than one board and each board can have more than one device.
+  You may define an element in a given layer as a specialization of an element in the same layer,
+  thus eliminating copying and simplifying maintenance.</p>
+ 
+<table>
+ <tbody><tr>
+  <th>Layer</th>
+  <th>Example</th>
+  <th>Description</th>
+ </tr>
+  <tr>
+    <td>Product</td>
+    <td>myProduct, myProduct_eu, myProduct_eu_fr, j2, sdk</td>
+    <td><p>The product layer defines the feature specification of a shipping product such as the modules to build,
+    locales supported, and the configuration for various locales. In other words, this is the name of the
+    overall product. Product-specific variables are defined in product definition Makefiles. A product 
+     can inherit from other product definitions,
+    which simplifies maintenance. A common method is to create a base product that contains features that apply
+    for all products, then creating product variants based on that base product. For example, you can have
+    two products that differ only by their radios (CDMA vs GSM) inherit from the same base product that does not define a radio.
+    <p>For a full list of product definition variables, see the
+    <a href="{@docRoot}devices/build_new_device.html#prod-def">Product Definition Files</a> section.</p>
+</td>
+
+  </tr>
+  <tr>
+    <td>Device</td>
+    <td>myDevice, myDevice_eu, myDevice_eu_lite</td>
+    <td>The device layer represents the physical layer of plastic on the device (i.e. the industrial design of the device). For example, North American devices probably include QWERTY keyboards whereas devices sold in France probably include AZERTY keyboards.</td>
+  </tr>
+  <tr>
+    <td>Board</td>
+    <td>sardine, trout, goldfish </td>
+    <td>The board layer represents the bare schematics of a product. This includes the peripherals on the board and their
+      configuraiton.</td>
+  </tr>
+  <tr>
+    <td>Arch</td>
+    <td>arm (armv7-a-neon, armv7), x86, 68k </td>
+    <td>The architecture layer describes the processor configuration and ABI (Application Binary Interface) running on the board. </td>
+  </tr>
+</table>
+
+
+<h2 id="variants">Build Variants</h2>
+
+<p> 
+When building for a particular product, it's often useful to have minor
+variations on what is ultimately the final release build.  These are the
+currently-defined build variants:
+</p> 
+ 
+<table border=1> 
+<tr> 
+    <td> 
+        <code>eng<code> 
+    </td> 
+    <td> 
+        This is the default flavor. A plain <code>make</code> is the
+        same as <code>make eng</code>.
+        <ul> 
+        <li>Installs modules tagged with: <code>eng</code>, <code>debug</code>,
+            <code>user</code>, and/or <code>development</code>.
+        <li>Installs non-APK modules that have no tags specified.
+        <li>Installs APKs according to the product definition files, in
+            addition to tagged APKs.
+        <li><code>ro.secure=0</code> 
+        <li><code>ro.debuggable=1</code> 
+        <li><code>ro.kernel.android.checkjni=1</code> 
+        <li><code>adb</code> is enabled by default.
+    </td> 
+</tr> 
+<tr>
+    <td>
+        <code>user<code>
+    </td>
+    <td>
+        <code>make user</code>
+        <p> 
+        This is the flavor intended to be the final release bits.
+        <ul> 
+        <li>Installs modules tagged with <code>user</code>.</li>
+        <li>Installs non-APK modules that have no tags specified.</li>
+        <li>Installs APKs according to the product definition files; tags
+            are ignored for APK modules.</li>
+        <li><code>ro.secure=1</code> </li>
+        <li><code>ro.debuggable=0</code> </li>
+        <li><code>adb</code> is disabled by default.</li>
+    </td>
+</tr>
+<tr>
+    <td>
+        <code>userdebug<code> 
+    </td> 
+    <td> 
+        <code>make userdebug</code>
+        <p> 
+        The same as <code>user</code>, except:
+        <ul> 
+        <li>Also installs modules tagged with <code>debug</code>.
+        <li><code>ro.debuggable=1</code> 
+        <li><code>adb</code> is enabled by default.
+    </td> 
+</tr> 
+</table> 
+
+<p class="note"><strong>Note:</strong> 
+If you build one flavor and then want to build another, you should run
+<code>make installclean</code> between the two makes to guarantee that
+you don't pick up files installed by the previous flavor.  <code>make
+clean</code> also suffices, but it takes a lot longer.
+</p>
+
+<h2 id="pdk-build">The PDK Build</h2>
+<p>The PDK build differs from a normal platform build in that it does not contain the entire Android source tree.
+  A <code>platform.zip</code> binary is provided that contains the missing pieces that aren't in the PDK source tree.
+  The PDK supports two different build flavors, Fusion and non-Fusion:
+</p>
+<ul>
+  <li>The Fusion build includes the <code>platform.zip</code>
+  components and allows your device to boot up into a usable Android system with a UI.
+  </li>
+  <li>The non-Fusion build omits the <code>platform.zip</code> components and boots
+  your device without a UI. In this mode,
+  you can <code>adb shell</code> into the device to run command line programs to test your
+  hardware in the early stages of development. This is useful when you only have a few HAL
+  implementations and drivers to test initially.
+  </li>
+</ul>
+
+  <h3 id="running-pdk-build">Running a default PDK build</h3>
+<p>When you have the PDK source synced, you can run a default build for the PDK to verify that your environment
+  is setup correctly. To do this, run the following commands:</p>
+
+<pre>
+source build/envsetup.sh
+lunch mini_armv7a_neon-userdebug
+PDK_FUSION_PLATFORM_ZIP=vendor/pdk/mini_armv7a_neon/mini_armv7a_neon-userdebug/platform/platform.zip make -j32
+</pre>
\ No newline at end of file
diff --git a/src/devices/camera.jd b/src/devices/camera.jd
new file mode 100644
index 0000000..1e709c8
--- /dev/null
+++ b/src/devices/camera.jd
@@ -0,0 +1,174 @@
+page.title=Camera Version 1
+@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>Android's camera HAL connects the higher level
+camera framework APIs in <a href="http://developer.android.com/reference/android/hardware/package-summary.html">android.hardware</a> to your underlying camera driver and hardware.
+The following figure and list describe the components involved and where to find the source for each:
+</p>
+
+<p><img src="images/camera_hal.png"></p>
+
+<dl>
+  
+  <dt>Application framework</dt>
+  <dd>At the application framework level is the app's code, which utilizes the <a 
+  href="http://developer.android.com/reference/android/hardware/Camera.html">android.hardware.Camera</a>
+  API to interact with the camera hardware. Internally, this code calls a corresponding JNI glue class
+   to access the native code that interacts with the camera.</dd>
+  
+  <dt>JNI</dt>
+  <dd>The JNI code associated with <a 
+  href="http://developer.android.com/reference/android/hardware/Camera.html">android.hardware.Camera</a> is located in
+  <code>frameworks/base/core/jni/android_hardware_Camera.cpp</code>. This code calls the lower level
+  native code to obtain access to the physical camera and returns data that is used to create the
+ <a href="http://developer.android.com/reference/android/hardware/Camera.html">android.hardware.Camera</a> object at the framework level.</dd>
+  
+  <dt>Native framework<dt>
+  <dd>The native framework defined in <code>frameworks/av/camera/Camera.cpp</code> provides a native equivalent
+  to the <a href="http://developer.android.com/reference/android/hardware/Camera.html">android.hardware.Camera</a> class.
+  This class calls the IPC binder proxies to obtain access to the camera service.</dd>
+  
+  <dt>Binder IPC proxies</dt>
+  <dd>The IPC binder proxies facilitate communication over process boundaries. There are three camera binder
+  classes that are located in the <code>frameworks/av/camera</code> directory that calls into
+  camera service.  ICameraService is the interface to the camera service, ICamera is the interface 
+  to a specific opened camera device, and ICameraClient is the device's interface back to the application framework.</dd>
+  
+  <dt>Camera service</dt>
+  <dd>The camera service, located in <code>frameworks/av/services/camera/libcameraservice/CameraService.cpp</code>, is  the actual code that interacts with the HAL.</p>
+
+  <dt>HAL</dt>
+  <dd>The hardware abstraction layer defines the standard interface that the camera service calls into and that
+  you must implement to have your camera hardware function correctly.
+  </dd>
+  
+  <dt>Kernel driver</dt>
+  <dd>The camera's driver interacts with the actual camera hardware and your implementation of the HAL. The
+  camera and driver must support YV12 and NV21 image formats to provide support for
+  previewing the camera image on the display and video recording.</dd>
+  </dl>
+
+
+<h2 id="implementing">Implementing the HAL</h2>
+<p>The HAL sits between the camera driver and the higher level Android framework
+and defines an interface that you must implement so that apps can
+correctly operate the camera hardware. The HAL interface is defined in the
+<code>hardware/libhardware/include/hardware/camera.h</code> and
+<code>hardware/libhardware/include/hardware/camera_common.h</code> header files.
+</p>
+
+<p>
+<code>camera_common.h</code> defines an important struct, <code>camera_module</code>, which defines a standard
+structure to obtain general information about the camera, such as its ID and properties
+that are common to all cameras such as whether or not it is a front or back-facing camera.
+</p>
+
+<p>
+<code>camera.h</code> contains the code that corresponds mainly with
+<a href="http://developer.android.com/reference/android/hardware/Camera.html">android.hardware.Camera</a>. This header file declares a <code>camera_device</code>
+struct that contains a <code>camera_device_ops</code> struct with function pointers
+that point to functions that implement the HAL interface. For documentation on the
+different types of camera parameters that a developer can set, 
+see the <code>frameworks/av/include/camera/CameraParameters.h</code> file.
+These parameters are set with the function pointed to by 
+<code>int (*set_parameters)(struct camera_device *, const char *parms)</code> in the HAL.
+</p>
+
+<p>For an example of a HAL implementation, see the implementation for the Galaxy Nexus HAL in
+<code>hardware/ti/omap4xxx/camera</code>.</p>
+
+
+<h2 id="configuring">Configuring the Shared Library</h2>
+<p>You need to set up the Android build system to
+  correctly package the HAL implementation into a shared library and copy it to the
+  appropriate location by creating an <code>Android.mk</code> file:
+
+<ol>
+  <li>Create a <code>device/&lt;company_name&gt;/&lt;device_name&gt;/camera</code> directory to contain your 
+  library's source files.</li> 
+  <li>Create an <code>Android.mk</code> file to build the shared library. Ensure that the Makefile contains the following lines:
+<pre>
+LOCAL_MODULE := camera.&lt;device_name&gt;
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
+</pre>
+<p>Notice that your library must be named <code>camera.&lt;device_name&gt;</code> (<code>.so</code> is appended automatically),
+so that Android can correctly load the library. For an example, see the Makefile
+for the Galaxy Nexus camera located in <code>hardware/ti/omap4xxx/Android.mk</code>.</p>
+
+</li>
+<li>Specify that your device has camera features by copying the necessary feature XML files in the
+<code>frameworks/native/data/etc</code> directory with your
+device's Makefile. For example, to specify that your device has a camera flash and can autofocus,
+add the following lines in your device's
+<code>&lt;device&gt;/&lt;company_name&gt;/&lt;device_name&gt;/device.mk</code> Makefile:
+
+<pre class="no-pretty-print">
+PRODUCT_COPY_FILES := \ ...
+
+PRODUCT_COPY_FILES += \
+frameworks/native/data/etc/android.hardware.camera.flash-autofocus.xml:system/etc/permissions/android.hardware.camera.flash-autofocus.xml \    
+</pre>
+
+<p>For an example of a device Makefile, see <code>device/samsung/tuna/device.mk</code>.</p>
+</li>
+
+<li>Declare your camera’s media codec, format, and resolution capabilities in
+<code>device/&lt;company_name&gt;/&lt;device_name&gt;/media_profiles.xml</code> and
+<code>device/&lt;company_name&gt;/&lt;device_name&gt;/media_codecs.xml</code> XML files.
+ For more information, see <a href="{@docRoot}guide/media.html#expose"> Exposing
+ Codecs and Profiles to the Framework</a> for information on how to do this.
+</p></code>
+
+</li>
+
+<li>Add the following lines in your device's
+   <code>device/&lt;company_name&gt;/&lt;device_name&gt;/device.mk</code> 
+  Makefile to copy the <code>media_profiles.xml</code>
+and <code>media_codecs.xml</code> files to the appropriate location:
+<pre>
+# media config xml file
+PRODUCT_COPY_FILES += \
+    &lt;device&gt;/&lt;company_name&gt;/&lt;device_name&gt;/media_profiles.xml:system/etc/media_profiles.xml
+
+# media codec config xml file
+PRODUCT_COPY_FILES += \
+    &lt;device&gt;/&lt;company_name&gt;/&lt;device_name&gt;/media_codecs.xml:system/etc/media_codecs.xml
+</pre>
+</li>
+
+<li>
+<p>Declare that you want to include the Camera app in your device's system image by
+specifying it in the <code>PRODUCT_PACKAGES</code> variable in your device's
+   <code>device/&lt;company_name&gt;/&lt;device_name&gt;/device.mk</code> 
+  Makefile:</p>
+<pre>
+PRODUCT_PACKAGES := \
+Gallery2 \
+...
+</pre>
+</li>
+
+</ol>
\ No newline at end of file
diff --git a/src/devices/compatibility.jd b/src/devices/compatibility.jd
new file mode 100644
index 0000000..3c43041
--- /dev/null
+++ b/src/devices/compatibility.jd
@@ -0,0 +1,197 @@
+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.
+-->
+<div id="qv-wrapper">
+  <div id="qv">
+    <h2>In this document</h2>
+    <ol id="auto-toc">
+    </ol>
+  </div>
+</div>
+
+
+<p>Welcome to the Android Platform Development Kit (PDK) Guide! The Android PDK allows partners to port 
+  their drivers as well as develop, optimize, and test against an upcoming Android platform release.
+  The Android PDK includes a set of interfaces for the Android hardware abstraction layer (HAL),
+  platform sources for integration, a binary system image, and HAL and integration documentation.
+  In addition, the PDK also ships with the Android Compatibility Test Suite (CTS).
+</p>
+
+<h2 id="arch">Android Low-Level System Architecture</h2>
+<p>Before you begin porting Android to your hardware, it is important to have an
+understanding of how Android works at a high level. Because your drivers and HAL code interact
+with many layers of Android code, this understanding can help you find
+your way through the many layers of code that are available to you through the AOSP
+(Android Open Source Project) source tree as well as the PDK.
+The following diagram shows a system level view of how Android works:
+</p>
+
+<img src="images/system-architecture.png">
+
+<p class="img-caption"><strong>Figure 1.</strong> Android System Architecture</p>
+
+  <h4>Application framework</h4>
+  <p>This is the level that most application developers concern themselves with. You should be
+    aware of the APIs available to developers as many of them map 1:1 to the underlying HAL
+    interfaces and can provide information as to how to implement your driver.
+  </p>
+
+  <h4>Binder IPC</h4>
+  <p>
+  The Binder Inter-Process Communication mechanism allows the application framework to
+  cross process boundaries and call into the Android system services code. This basically allows
+  high level framework APIs to interact with Android's system services. At the application framework level, all
+  of this communication is hidden from the developer and things appear to "just work." 
+  </p>
+
+  <h4>System services</h4>
+  <p>Most of the functionality exposed through the application framework APIs  must
+    communicate with some sort of system service to access the underlying hardware. Services
+    are divided into modular components with focused functionality 
+    such as the Window Manager, Search Service, or Notification Manager. System services are grouped
+    into two buckets: system and media. The system services include things such as the Window or
+    Notification Manager. The media services include all the services involved in playing and
+    recording media.
+  </p>
+  
+<h4>Hardware abstraction layer (HAL)</h4>
+<p>The HAL serves as a standard interface that allows the Android system to call into the device
+  driver layer while being agnostic about the lower-level implementations of your drivers and hardware.
+  You must implement the corresponding HAL (and driver) for the particular piece of hardware that your product
+  provides. Android does not mandate a standard interaction between your HAL implementation and your device drivers, so
+  you have free reign to do what is best for your situation. However, you must abide by the contract
+  defined in each hardware-specific HAL interface for the Android system to be able
+  to correctly interact with your hardware. HAL implementations are typically built into
+  shared library modules (<code>.so</code> files).
+</p>
+<h4>Linux Kernel</h4>
+<p>For the most part, developing your device drivers is the same as developing a typical Linux device driver.
+  Android uses a specialized version of the Linux kernel with a few special additions such as
+  wakelocks, a memory management system that is more agressive in preserving memory,
+  the Binder IPC driver, and other features that are important for a mobile embedded platform like Android.
+  These additions have less to do with driver development than with the system's functionality. The PDK
+  does not provide kernel sources, so you must provide your own. You can use any version of the kernel that
+  you want as long as it supports the required features, such as the binder driver. However, we recommend
+  using the latest version of the Android kernel. For the latest Android kernel, see
+  <a href="http://source.android.com/source/building-kernels.html" >Building Kernels</a>.
+</p>
+
+
+<h2 id="pdk">PDK Components</h2>
+<p>Now that you have a high-level overview of the Android system, we'll go over the PDK and what it provides
+  to port Android to your product. The PDK provides source files needed to implement
+  your product and a platform binary that lets you build a runnable system image. You can then install
+  this barebones image to test your product with the latest builds of Android. The most important source files
+  included in the PDK are located in the:</p>
+
+  <ul>
+    <li><code>frameworks/native</code> directory</li>
+    <li><code>frameworks/av</code> directory for media, camera, DRM, and the audio framework stack</code></li>
+    <li><code>hardware/libhardware/include/hardware</code> directory for the HAL interfaces </li>
+    <li><code>vendor/pdk/data/cts</code> directory for the CTS binaries</li>
+  </ul>
+</p>
+<p>In addition, the Android PDK includes the following source directories:</p>
+<ul>
+  <li>abi</li>
+  <li>bionic</li>
+  <li>bootable</li>
+  <li>build</li>
+  <li>device</li>
+  <li>external (Chromium and Webkit are not included)</li>
+  <li>hardware</li>
+  <li>libnativehelper</li>
+  <li>pdk</li>
+  <li>prebuilt</li>
+  <li>prebuilts</li>
+  <li>system</li>
+</ul>
+
+  <p>The PDK also contains documentation that is split into three different sections:</p>
+  <ul>
+    <li><a href="{@docRoot}guide/getting_started.html">Getting Started</a> - Explains how to download the PDK source, how the Android build system works, and how to configure a build for your specific product.</li>
+    <li><a href="{@docRoot}guide/hal.html">The Hardware Abstraction Layer</a> - Explains the various HALs provided by Android and the interfaces (C header files) that define them. </li>
+      <li><a href="{@docRoot}guide/reference/files.html">HAL reference</a> - A quick reference for the various HAL interfaces.</li>
+  </ul>
+
+<h3 id="cts">Compatibility Test Suite</h3>
+<p>CTS binaries for ARM, MIPS, and x86 are provided in the corresponding directories in <code>vendor/pdk/data/cts</code>. Only the ARM
+  variant is Google-verified as there is no Nexus device running on any other architecture. Not all of the CTS tests since the
+  complete Android platform is not present. The following CTS tests should work:</p>
+
+<ul>
+      <li>android.bluetooth</li>
+      <li>android.graphics</li>
+      <li>android.graphics2</li>
+      <li>android.hardware</li>
+      <li>android.location</li>
+      <li>android.opengl</li>
+      <li>android.openglperf</li>
+      <li>android.media</li>
+      <li>android.mediastress</li>
+      <li>android.nativemedia.sl</li>
+      <li>android.nativemedia.xa</li>
+      <li>android.net</li>
+      <li>android.renderscript</li>
+    </ul>
+    <p>You can run individual packages such as <code>android.media</code> with:</p>
+    <pre>cts-tradefed run singleCommand cts --skip-device-info --package android.media</pre>
+</ul>
+
+  <p>Because the PDK is missing many components compared to a full Android source tree,
+  there is a PDK test plan that is provided with CTS that limits the tests that are ran when using the PDK. You can run
+  this special test plan with the following command:</p>
+
+  <pre>run cts --plan PDK</pre>
+    
+<p>CTS is always actively under development, so we expect some tests to fail. CTS results
+  for the Galaxy Nexus are provided for you in the
+  the <code>vendor/pdk/data/cts/</code> directory and will show which tests fail on that
+  device. You can safely ignore the failed tests for your devices as well.</p>
+
+  <p>See the <a href="http://source.android.com/compatibility/cts-intro.html">CTS manual</a> for more information on CTS.</p>
+
+<h2 id="inc-ex">PDK Inclusions and Exclusions</h2>
+<p>The PDK is a subset of the complete Android source tree and might be missing things that you might need. Here is a list of what the PDK supports
+  and does not support:</p>
+<ul>
+  <li>Supports building Android apps using the publicly available, standard SDK. Builds with non-public platform APIs are not supported. The JNI build is supported.</li>
+  <li>Supports only <code>en_US</code> locale.</li>
+  <li>Supports only phone layouts. Tablet layouts are not included.</li>
+  <li>Enables support for software navigation buttons by default, which you can disable by setting <code>qemu.jw.mainkeys=1</code>.</li>
+  <li>Builds all binaries with SMP (symmetric multiprocessing) features enabled. This might have a small performance impact on non-SMP CPUs.</li>
+  <li>Includes a minimal amount of Java libraries. Obtain any additional Java libraries from the publicly released Android source tree.</li>
+  <li>Contains a minimum number of applications. Build and install necessary applications as needed.</li>
+  <li>Does not support media streaming.</li>
+  <li>Does not include non-Latin fonts. (set by <code>MINIMAL_FONT_FOOTPRINT</code> variable in <code>BoardConfig.mk</code>).
+  An app might crash if it requires such fonts. </li>
+  <li>Does not support replacing framework resources by using the overlay mechanism.
+    This means all configurations controlled by framework resources are fixed.</li>   
+  <li>Does not support NFC</li>
+  <li>Does not support DRM</li>
+</ul>
+
+<h2 id="knownissues">Support and Known Issues</h2>
+<p>
+For questions or to report issues related with the PDK, send a message to the <a href="https://groups.google.com/a/google.com/forum/?fromgroups#!forum/android-pdk-feedback">android-pdk@google.com</a> mailing list.</p>
+
+<p>The following list describes the known issues with the PDK:</p>
+<ul>
+  <li>After running the CTS (Compatibility Test Suite), <code>android.process.acore</code> crashes. This is caused by
+some missing components in PDK and does not affect the operation of CTS tests.</li>
+</p>
diff --git a/src/devices/debugtune.jd b/src/devices/debugtune.jd
new file mode 100644
index 0000000..c852073
--- /dev/null
+++ b/src/devices/debugtune.jd
@@ -0,0 +1,21 @@
+page.title=Debugging the Android platform
+@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 following sections contain information, documentation, tips and tricks
+about debugging Android at the platform level, typically during development
+of platform-level features.</p>
\ No newline at end of file
diff --git a/src/devices/devices_toc.cs b/src/devices/devices_toc.cs
new file mode 100644
index 0000000..7138177
--- /dev/null
+++ b/src/devices/devices_toc.cs
@@ -0,0 +1,177 @@
+<!--
+    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.
+-->
+<?cs # Table of contents for Dev pdk.?>
+<ul id="nav">
+
+<!-- Porting Android -->
+  <li class="nav-section">
+    <div class="nav-section-header">
+      <a href="<?cs var:toroot ?>devices/index.html">
+        <span class="en">Porting</span>
+      </a>
+    </div>    
+    <ul>
+      <li><a href="<?cs var:toroot ?>devices/media.html">Media</a></li>
+      <li class="nav-section">
+      <div class="nav-section-header">
+        <a href="<?cs var:toroot ?>devices/audio.html">
+          <span class="en">Audio</span>
+        </a>
+      </div>
+        <ul>
+          <li><a href="<?cs var:toroot ?>devices/audio_latency.html">Latency</a></li>
+          <li><a href="<?cs var:toroot ?>devices/audio_warmup.html">Warmup</a></li>
+        </ul>
+      </li>
+      <li><a href="<?cs var:toroot ?>devices/camera.html">Camera v1</a></li>
+      <li><a href="<?cs var:toroot ?>devices/drm.html">DRM</a></li>
+      <li><a href="<?cs var:toroot ?>devices/graphics.html">Graphics</a></li>
+      <li><a href="<?cs var:toroot ?>devices/bluetooth.html">Bluetooth</a></li>
+      <!-- Find a better section for these -->
+      <li class="nav-section">
+        <div class="nav-section-header empty">
+          <a href="<?cs var:toroot ?>devices/reference/files.html">
+            <span class="en">Reference</span>
+          </a>
+        </div>
+      </li>
+    </ul>
+  </li>
+<!-- End Porting Android -->
+  </li>
+
+  
+  <li class="nav-section">
+    <div class="nav-section-header">
+      <a href="<?cs var:toroot ?>devices/tech/index.html">
+        <span class="en">Technical Information</span>
+      </a>
+    </div>
+
+    <ul>
+      <li class="nav-section">
+        <div class="nav-section-header">
+          <a href="<?cs var:toroot ?>devices/tech/dalvik/index.html">
+          <span class="en">Dalvik</span></a>
+        </div>
+        <ul>
+          <li><a href="<?cs var:toroot ?>devices/tech/dalvik/dalvik-bytecode.html">Bytecode Format</a></li>
+          <li><a href="<?cs var:toroot ?>devices/tech/dalvik/dex-format.html">.Dex Format</a></li>
+          <li><a href="<?cs var:toroot ?>devices/tech/dalvik/instruction-formats.html">Instruction Formats</a></li>
+        </ul>
+      </li>
+
+      <li class="nav-section">
+        <div class="nav-section-header">
+          <a href="<?cs var:toroot ?>devices/tech/datausage/index.html">
+            <span class="en">Data Usage</span>
+          </a>
+        </div>
+        <ul>
+          <li><a href="<?cs var:toroot ?>devices/tech/datausage/iface-overview.html">Network interface statistics overview</a></li>
+          <li><a href="<?cs var:toroot ?>devices/tech/datausage/excluding-network-types.html">Excluding Network Types from Data Usage</a></li>
+          <li><a href="<?cs var:toroot ?>devices/tech/datausage/tethering-data.html">Tethering Data</a></li>
+          <li><a href="<?cs var:toroot ?>devices/tech/datausage/usage-cycle-resets-dates.html">Usage Cycle Reset Dates</a></li>
+          <li><a href="<?cs var:toroot ?>devices/tech/datausage/kernel-overview.html">Kernel Overview</a></li>
+          <li><a href="<?cs var:toroot ?>devices/tech/datausage/tags-explained.html">Data Usage Tags Explained</a></li>
+          <li><a href="<?cs var:toroot ?>devices/tech/datausage/kernel-changes.html">Kernel Changes</a></li>
+        </ul>
+      </li>
+      <li class="nav-section">
+        <div class="nav-section-header">
+          <a href="<?cs var:toroot ?>devices/debugtune.html">
+            <span class="en">Debugging and Tuning</span>
+          </a>
+        </div>
+        <ul>
+          <li><a href="<?cs var:toroot ?>devices/tuning.html">Performance Tuning</a></li>
+          <li><a href="<?cs var:toroot ?>devices/native-memory.html">Native Memory Usage</a></li>
+        </ul>
+      </li>
+
+      <li class="nav-section">
+        <div class="nav-section-header">
+          <a href="<?cs var:toroot ?>devices/tech/encryption/index.html">
+            <span class="en">Encryption</span>
+          </a>
+        </div>
+        <ul>
+          <li><a href="<?cs var:toroot ?>devices/tech/encryption/android_crypto_implementation.html">Encryption Technical Information</a></li>
+        </ul>
+      </li>
+      <li class="nav-section">
+        <div class="nav-section-header">
+          <a href="<?cs var:toroot ?>devices/tech/input/index.html">
+            <span class="en">Input</span>
+          </a>
+        </div>
+        <ul>
+          <li><a href="<?cs var:toroot ?>devices/tech/input/overview.html">Overview</a></li>
+          <li><a href="<?cs var:toroot ?>devices/tech/input/key-layout-files.html">Key Layout Files</a></li>
+          <li><a href="<?cs var:toroot ?>devices/tech/input/key-character-map-files.html">Key Character Map Files</a></li>
+          <li><a href="<?cs var:toroot ?>devices/tech/input/input-device-configuration-files.html">Input Device Configuration Files</a></li>
+          <li><a href="<?cs var:toroot ?>devices/tech/input/migration-guide.html">Migration Guide</a></li>
+          <li><a href="<?cs var:toroot ?>devices/tech/input/keyboard-devices.html">Keyboard Devices</a></li>
+          <li><a href="<?cs var:toroot ?>devices/tech/input/touch-devices.html">Touch Devices</a></li>
+          <li><a href="<?cs var:toroot ?>devices/tech/input/dumpsys.html">Dumpsys</a></li>
+          <li><a href="<?cs var:toroot ?>devices/tech/input/getevent.html">Getevent</a></li>
+          <li><a href="<?cs var:toroot ?>devices/tech/input/validate-keymaps.html">Validate Keymaps</a></li>
+        </ul>
+      </li>
+      
+      <li>      
+          <a href="<?cs var:toroot ?>devices/tech/kernel.html">
+            <span class="en">Kernel</span>
+          </a>
+      </li>
+      
+      <li>      
+          <a href="<?cs var:toroot ?>devices/tech/power.html">
+            <span class="en">Power</span>
+          </a>
+      </li>
+
+      <li>      
+          <a href="<?cs var:toroot ?>devices/tech/security/index.html">
+            <span class="en">Security</span>
+          </a>
+      </li>
+
+      
+
+      <li class="nav-section">
+        <div class="nav-section-header">
+          <a href="<?cs var:toroot ?>devices/tech/test_infra/tradefed/index.html">
+            <span class="en">Trade Federation Testing Infrastructure</span>
+          </a>
+        </div>
+        <ul>
+          <li><a href="<?cs var:toroot ?>devices/tech/test_infra/tradefed/tutorial.html">Tutorial</a></li>
+          <li><a href="<?cs var:toroot ?>devices/tech/test_infra/tradefed/commandfile_format.html">Command File Format</a></li>          
+           <li id="tradefed-tree-list" class="nav-section">
+            <div class="nav-section-header">
+              <a href="<?cs var:toroot ?>reference/packages.html">
+            <span class="en">Reference</span>
+          </a>
+        <div>
+      </li>
+        </ul>
+      </li>
+
+    </ul>
+  </li>
+
+</ul>
\ No newline at end of file
diff --git a/src/devices/drm.jd b/src/devices/drm.jd
new file mode 100644
index 0000000..92beaa0
--- /dev/null
+++ b/src/devices/drm.jd
@@ -0,0 +1,178 @@
+page.title=DRM
+@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>This document introduces Widevine DRM security levels
+  and certification requirements. It explains how to integrate and distribute Widevine DRM
+  for your product. Android provides the Widevine DRM solution with a royalty-free
+  license and we recommend that you use it for
+  your protected playback solution. </p>
+
+<h2 id="overview">Overview</h2>
+<p>
+Availability of rich digital content is important to users on mobile devices. To make their content widely available,
+Android developers and digital content publishers need a consistent DRM implementation supported across the Android
+ecosystem. In order to make that digital content available on Android devices and to ensure that there is at least
+one consistent DRM available across all devices, Google provides Widevine DRM for free on compatible Android devices.
+On Android 3.0 and higher platforms, the Widevine DRM plugin is integrated with the Android DRM framework and uses
+hardware-backed protection to secure movie content and user credentials.
+</p>
+
+<p>
+The content protection provided by the Widevine DRM plugin depends on the security and content protection capabilities of the underlying hardware platform. The hardware capabilities of the device include hardware secure boot to establish a chain of trust of security and protection of cryptographic keys. Content protection capabilities of the device include protection of decrypted frames in the device and content output protection via a trusted output protection mechanism. Not all hardware platforms support all the above security and content protection features. Security is never implemented in a single place in the stack, but instead relies on the integration of hardware, software, and services. The combination of hardware security functions, a trusted boot mechanism, and an isolated secure OS for handling security functions is critical to provide a secure device.</p>
+
+
+<h3 id="framework">Android DRM Framework</h3>
+<p>Android 3.0 and higher platforms provide an extensible DRM framework that lets applications manage protected content using a
+    choice of DRM mechanisms. For application developers, the framework offers an
+    abstract, unified API that simplifies the management of protected content.
+    The API hides the complexity of DRM operations and allows a consistent operation mode for both protected and unprotected
+    content across a variety of DRM schemes. For device manufacturers, content owners, and Internet digital media providers
+    the DRM framework plugin API provides a means of adding support for a DRM scheme of choice into the Android system, for
+    secure enforcement of content protection.
+
+    <p><strong>Note:</strong> We recommend that you integrate the Widevine
+    solution as it is already implemented and ready for you to use. </p>
+</p>
+
+<h3 id="plugin">Widevine DRM Plugin</h3>
+
+<p>
+Built on top of the Android DRM framework, the Widevine DRM plugin offers DRM and advanced copy protection features on Android devices. Widevine DRM is available in binary form under a royalty free license from Widevine. The Widevine DRM plugin provides the capability to license, securely distribute, and protect playback of multimedia content. Protected content is secured using an encryption scheme based on the open AES (Advanced Encryption Standard). An application can decrypt the content only if it obtains a license from the Widevine DRM licensing server for the current user. Widevine DRM functions on Android in the same way as it does on other platforms. Figure 1 shows how the WideVine Crypto Plugin fits into the Android stack:</p>
+
+
+ <img src="images/drm_hal.png" alt="" />
+
+ <p class="img-caption"><strong>Figure 1.</strong> Widevine Crypto Plugin</p>
+
+
+<h2 id="integrating">Integrating Widevine into Your Product</h2>
+
+<p>The following sections go over the different security levels that Widevine supports and the requirements that your product must meet to
+support Widevine. After reading the information, you need to determine the security level for your target hardware, integration, and Widevine keybox provisioning requirements.
+</p>
+<p >
+To integrate and distribute Widevine DRM on Android devices, contact your Android technical account manager to begin Widevine DRM integration.
+We recommend you engage early in your device development process with the Widevine team to provide the highest level of content protection on the device. 
+Certify devices using the Widevine test player and submit results to your Android technical account manager for approval.
+</p>
+
+<h3 id="security">
+Widevine DRM security levels
+</h3>
+
+<p>Security is never implemented in a single place in the stack, but instead relies on the integration of hardware, software, and services. The combination of hardware security functions, a trusted boot mechanism, and an isolated secure OS for handling security functions is critical to provide a secure device.</p>
+
+<p>
+At the system level, Android offers the core security features of the Linux kernel, extended and customized for mobile devices. In the application framework, Android provides an extensible DRM framework and system architecture for checking and enforcing digital rights. The Widevine DRM plugin integrates with the hardware platform to leverage the available security capabilities. The level of security offered is determined by a combination of the security capabilities of the hardware platform and the integration with Android and the Widevine DRM plugin. Widevine DRM security supports the three levels of security shown in the table below. 
+</p>
+
+<table>
+
+<tr>
+<th>Security Level</th>
+<th>Secure Bootloader</th>
+<th>Widevine Key Provisioning</th>
+<th>Security Hardware or ARM Trust Zone</th>
+<th>Widevine Keybox and Video Key Processing</th>
+<th>Hardware Video Path</th>
+</tr>
+<tr>
+  <td>Level 1</td>
+  <td>Yes</td>
+  <td>Factory provisioned Widevine Keys</td>
+  <td>Yes</td>
+  <td>Keys never exposed in clear to host CPU</td>
+  <td>Hardware protected video path</td>
+<tr>
+
+<tr>
+  <td>Level 2</td>
+  <td>Yes</td>
+  <td>Factory provisioned Widevine Keys</td>
+  <td>Yes</td>
+  <td>Keys never exposed in clear to host CPU</td>
+  <td>Hardware protected video path</td>
+<tr>
+
+<tr>
+  <td>Level 3</td>
+  <td>Yes*</td>
+  <td>Field provisioned Widevine Keys</td>
+  <td>No</td>
+  <td>Clear keys exposed to host CPU</td>
+  <td>Clear video streams delivered to video decoder</td>
+<tr>
+
+</table>
+
+<p><superscript>*</superscript>Device implementations may use a trusted bootloader, where in the bootloader is authenticated via an OEM key stored on a system partition.</p>
+
+<h3 id="security-details">
+Security level details
+</h3>
+<h4>
+Level 1
+</h4>
+<p>In this implementation Widevine DRM keys and decrypted content are never exposed to the host CPU. Only security hardware or a protected security co-processor uses clear key values and the media content is decrypted by the secure hardware. This level of security requires factory provisioning of the Widevine key-box or requires the Widevine key-box to be protected by a device key installed at the time of manufacturing. The following describes some key points to this security level:
+</p>
+
+<ul>
+  <li>Device manufacturers must provide a secure bootloader. The chain of trust from the bootloader must extend through any software or firmware components involved in the security implementation, such as the ARM TrustZone protected application and any components involved in the enforcement of the secure video path. </li>
+  <li>The Widevine key-box must be encrypted with a device-unique secret key that is not visible to software or probing methods outside of the TrustZone.</li>
+  <li>The Widevine key-box must be installed in the factory or delivered to the device using an approved secure delivery mechanism.</li>
+  <li>Device manufacturers must provide an implementation of the Widevine Level 1 OEMCrypto API that performs all key processing and decryption in a trusted environment.</li>
+</ul>
+
+<h4>Level 2</h4>
+<p>
+  In this security level, the Widevine keys are never exposed to the host CPU. Only security hardware or a protected security co-processor uses clear key values. An AES crypto block performs the high throughput AES decryption of the media stream.  The resulting clear media buffers are returned to the CPU for delivery to the video decoder. This level of security requires factory provisioning of the Widevine key-box or requires the Widevine key box to be protected by a key-box installed at the time of manufacturing.
+  The following list describes some key requirements of this security level:
+</p>
+
+<ul>
+  <li>Device manufacturers must provide a secure bootloader. The chain of trust from the bootloader must extend through any software or firmware components involved in the security implementation, such as the TrustZone protected application. </li>
+  <li>The Widevine key-box must be encrypted with a device-unique secret key that is not visible to software or probing methods outside of the TrustZone.</li>
+  <li>The Widevine key-box must be installed in the factory or delivered to the device using an approved secure delivery mechanism.</li>
+  <li>Device manufacturers must provide an implementation of the Widevine Level 2 OEMCrypto API that performs all key processing and decryption in a trusted environment.</li>
+  <li>Device manufacturers must provide a bootloader that loads signed system images only. For devices that allow users to load a custom operating system or gain root privileges on the device by unlocking the bootloader, device manufacturers must support the following:
+    <ul>
+      <li>Device manufacturers must provide a bootloader that allows a Widevine key-box to be written only when the bootloader is in a locked state.</li>
+      <li>The Widevine key-box must be stored in a region of memory that is erased or is inaccessible when the device bootloader is in an unlocked state.</li>
+    </ul>
+  </li>
+</ul>
+
+<h4>Level 3</h4>
+<p>
+This security level relies on the secure bootloader to verify the system image. An AES crypto block performs the AES decryption of the media stream and the resulting clear media buffers are returned to the CPU for delivery to the video decoder.
+</p>
+
+<p>Device manufacturers must provide a bootloader that loads signed system images only. For devices that allow users to load a custom operating system or gain root privileges on the device by unlocking the bootloader, device manufacturers must support the following:</p>
+    <ul>
+      <li>Device manufacturers must provide a bootloader that allows a Widevine key-box to be written only when the bootloader is in a locked state.</li>
+      <li>The Widevine key-box must be stored in a region of memory that is erased or is inaccessible when the device bootloader is in an unlocked state.</li>
+    </ul>
diff --git a/src/devices/getting_started.jd b/src/devices/getting_started.jd
new file mode 100644
index 0000000..df4fe89
--- /dev/null
+++ b/src/devices/getting_started.jd
@@ -0,0 +1,200 @@
+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.
+-->
+<div id="qv-wrapper">
+  <div id="qv">
+    <h2>In this document</h2>
+    <ol id="auto-toc">
+    </ol>
+  </div>
+</div>
+
+<p>Welcome to the Android Platform Development Kit (PDK) Guide! The Android PDK allows partners to port 
+  their drivers as well as develop, optimize, and test against an upcoming Android platform release.
+  The Android PDK includes a set of interfaces for the Android hardware abstraction layer (HAL),
+  platform sources for integration, a binary system image, and HAL and integration documentation.
+  In addition, the PDK also ships with the Android Compatibility Test Suite (CTS).
+</p>
+
+<h2 id="arch">Android Low-Level System Architecture</h2>
+<p>Before you begin porting Android to your hardware, it is important to have an
+understanding of how Android works at a high level. Because your drivers and HAL code interact
+with many layers of Android code, this understanding can help you find
+your way through the many layers of code that are available to you through the AOSP
+(Android Open Source Project) source tree as well as the PDK.
+The following diagram shows a system level view of how Android works:
+</p>
+
+<img src="images/system-architecture.png">
+
+<p class="img-caption"><strong>Figure 1.</strong> Android System Architecture</p>
+
+  <h4>Application framework</h4>
+  <p>This is the level that most application developers concern themselves with. You should be
+    aware of the APIs available to developers as many of them map 1:1 to the underlying HAL
+    interfaces and can provide information as to how to implement your driver.
+  </p>
+
+  <h4>Binder IPC</h4>
+  <p>
+  The Binder Inter-Process Communication mechanism allows the application framework to
+  cross process boundaries and call into the Android system services code. This basically allows
+  high level framework APIs to interact with Android's system services. At the application framework level, all
+  of this communication is hidden from the developer and things appear to "just work." 
+  </p>
+
+  <h4>System services</h4>
+  <p>Most of the functionality exposed through the application framework APIs  must
+    communicate with some sort of system service to access the underlying hardware. Services
+    are divided into modular components with focused functionality 
+    such as the Window Manager, Search Service, or Notification Manager. System services are grouped
+    into two buckets: system and media. The system services include things such as the Window or
+    Notification Manager. The media services include all the services involved in playing and
+    recording media.
+  </p>
+  
+<h4>Hardware abstraction layer (HAL)</h4>
+<p>The HAL serves as a standard interface that allows the Android system to call into the device
+  driver layer while being agnostic about the lower-level implementations of your drivers and hardware.
+  You must implement the corresponding HAL (and driver) for the particular piece of hardware that your product
+  provides. Android does not mandate a standard interaction between your HAL implementation and your device drivers, so
+  you have free reign to do what is best for your situation. However, you must abide by the contract
+  defined in each hardware-specific HAL interface for the Android system to be able
+  to correctly interact with your hardware. HAL implementations are typically built into
+  shared library modules (<code>.so</code> files).
+</p>
+<h4>Linux Kernel</h4>
+<p>For the most part, developing your device drivers is the same as developing a typical Linux device driver.
+  Android uses a specialized version of the Linux kernel with a few special additions such as
+  wakelocks, a memory management system that is more agressive in preserving memory,
+  the Binder IPC driver, and other features that are important for a mobile embedded platform like Android.
+  These additions have less to do with driver development than with the system's functionality. The PDK
+  does not provide kernel sources, so you must provide your own. You can use any version of the kernel that
+  you want as long as it supports the required features, such as the binder driver. However, we recommend
+  using the latest version of the Android kernel. For the latest Android kernel, see
+  <a href="{@docRoot}source/building-kernels.html" >Building Kernels</a>.
+</p>
+
+
+<h2 id="pdk">PDK Components</h2>
+<p>Now that you have a high-level overview of the Android system, we'll go over the PDK and what it provides
+  to port Android to your product. The PDK provides source files needed to implement
+  your product and a platform binary that lets you build a runnable system image. You can then install
+  this barebones image to test your product with the latest builds of Android. The most important source files
+  included in the PDK are located in the:</p>
+
+  <ul>
+    <li><code>frameworks/native</code> directory</li>
+    <li><code>frameworks/av</code> directory for media, camera, DRM, and the audio framework stack</code></li>
+    <li><code>hardware/libhardware/include/hardware</code> directory for the HAL interfaces </li>
+    <li><code>vendor/pdk/data/cts</code> directory for the CTS binaries</li>
+  </ul>
+</p>
+<p>In addition, the Android PDK includes the following source directories:</p>
+<ul>
+  <li>abi</li>
+  <li>bionic</li>
+  <li>bootable</li>
+  <li>build</li>
+  <li>device</li>
+  <li>external (Chromium and Webkit are not included)</li>
+  <li>hardware</li>
+  <li>libnativehelper</li>
+  <li>pdk</li>
+  <li>prebuilt</li>
+  <li>prebuilts</li>
+  <li>system</li>
+</ul>
+
+  <p>The PDK also contains documentation that is split into the following sections:</p>
+  <ul>
+    <li><a href="{@docRoot}devices/getting_started.html">Getting Started</a> - Explains how to download
+    the PDK source, how the Android build system works, and how to configure a build for your specific product.</li>
+    <li><a href="{@docRoot}devices/porting.html">Porting</a> - Explains the various HALs provided by Android
+    and the interfaces (C header files) that define them. This section also provides reference documentation
+    for the various HAL interfaces.</li>
+    <li><a href="{@docRoot}devices/debugtune.html">Debugging and Tuning</a> - Explains the debugging and tuning features of the PDK.</li>
+    <li><a href="{@docRoot}devices/tech/index.html">Technical Information</a> - Explains important concepts of the Android platform.</li>
+  </ul>
+
+<h3 id="cts">Compatibility Test Suite</h3>
+<p>CTS binaries for ARM, MIPS, and x86 are provided in the corresponding directories in <code>vendor/pdk/data/cts</code>. Only the ARM
+  variant is Google-verified as there is no Nexus device running on any other architecture. Not all of the CTS tests since the
+  complete Android platform is not present. The following CTS tests should work:</p>
+
+<ul>
+      <li>android.bluetooth</li>
+      <li>android.graphics</li>
+      <li>android.graphics2</li>
+      <li>android.hardware</li>
+      <li>android.location</li>
+      <li>android.opengl</li>
+      <li>android.openglperf</li>
+      <li>android.media</li>
+      <li>android.mediastress</li>
+      <li>android.nativemedia.sl</li>
+      <li>android.nativemedia.xa</li>
+      <li>android.net</li>
+      <li>android.renderscript</li>
+    </ul>
+    <p>You can run individual packages such as <code>android.media</code> with:</p>
+    <pre>cts-tradefed run singleCommand cts --skip-device-info --package android.media</pre>
+</ul>
+
+  <p>Because the PDK is missing many components compared to a full Android source tree,
+  there is a PDK test plan that is provided with CTS that limits the tests that are ran when using the PDK. You can run
+  this special test plan with the following command:</p>
+
+  <pre>run cts --plan PDK</pre>
+    
+<p>CTS is always actively under development, so we expect some tests to fail. CTS results
+  for the Galaxy Nexus are provided for you in the
+  the <code>vendor/pdk/data/cts/</code> directory and will show which tests fail on that
+  device. You can safely ignore the failed tests for your devices as well.</p>
+
+  <p>See <a href="{@docRoot}compatibility/index.html">Compatibility</a> for more information on CTS.</p>
+
+<h2 id="inc-ex">PDK Inclusions and Exclusions</h2>
+<p>The PDK is a subset of the complete Android source tree and might be missing things that you might need. Here is a list of what the PDK supports
+  and does not support:</p>
+<ul>
+  <li>Supports building Android apps using the publicly available, standard SDK. Builds with non-public platform APIs are not supported. The JNI build is supported.</li>
+  <li>Supports only <code>en_US</code> locale.</li>
+  <li>Supports only phone layouts. Tablet layouts are not included.</li>
+  <li>Enables support for software navigation buttons by default, which you can disable by setting <code>qemu.jw.mainkeys=1</code>.</li>
+  <li>Builds all binaries with SMP (symmetric multiprocessing) features enabled. This might have a small performance impact on non-SMP CPUs.</li>
+  <li>Includes a minimal amount of Java libraries. Obtain any additional Java libraries from the publicly released Android source tree.</li>
+  <li>Contains a minimum number of applications. Build and install necessary applications as needed.</li>
+  <li>Does not support media streaming.</li>
+  <li>Does not include non-Latin fonts. (set by <code>MINIMAL_FONT_FOOTPRINT</code> variable in <code>BoardConfig.mk</code>).
+  An app might crash if it requires such fonts. </li>
+  <li>Does not support replacing framework resources by using the overlay mechanism.
+    This means all configurations controlled by framework resources are fixed.</li>   
+  <li>Does not support NFC</li>
+  <li>Does not support DRM</li>
+</ul>
+
+<h2 id="knownissues">Support and Known Issues</h2>
+<p>
+For questions or to report issues related with the PDK, send a message to the <a href="https://groups.google.com/a/google.com/forum/?fromgroups#!forum/android-pdk-feedback">android-pdk@google.com</a> mailing list.</p>
+
+<p>The following list describes the known issues with the PDK:</p>
+<ul>
+  <li>After running the CTS (Compatibility Test Suite), <code>android.process.acore</code> crashes. This is caused by
+some missing components in PDK and does not affect the operation of CTS tests.</li>
+</p>
diff --git a/src/devices/graphics.jd b/src/devices/graphics.jd
new file mode 100644
index 0000000..357e8f9
--- /dev/null
+++ b/src/devices/graphics.jd
@@ -0,0 +1,381 @@
+page.title=Graphics
+@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>
+  The Android framework has a variety of graphics rendering APIs for 2D and 3D that interact with
+  your HAL implementations and graphics drivers, so it is important to have a good understanding of
+  how they work at a higher level. There are two general ways that app developers can draw things
+  to the screen: with Canvas or OpenGL.
+</p>
+<p>
+  <a href="http://developer.android.com/reference/android/graphics/Canvas.html">android.graphics.Canvas</a>
+  is a 2D graphics API and is the most widely used graphics API by
+  developers. Canvas operations draw all the stock <a href="http://developer.android.com/reference/android/view/View.html">android.view.View</a>s
+  and custom <a href="http://developer.android.com/reference/android/view/View.html">android.view.View</a>s in Android. Prior to Android 3.0, Canvas used the Skia 2D drawing library to
+  draw, which could not take advantage of hardware acceleration.
+</p>
+<p>
+  Introduced in Android 3.0, hardware acceleration for Canvas APIs uses a new drawing library
+  called OpenGLRenderer that translates Canvas operations to OpenGL operations so that they can
+  execute on the GPU. Developers had to opt-in to this feature previously, but beginning in Android
+  4.0, hardware-accelerated Canvas is enabled by default. Consequently, a hardware GPU that
+  supports OpenGL ES 2.0 is mandatory for Android 4.0 devices.
+</p>
+<p>
+  The OpenGLRenderer does not interact with Skia, so we
+  anticipate Skia to be slowly phased out without adverse effects to developers. Skia is currently
+  deprecated and in maintenance mode but will be neccessary for a while because most apps published
+  today still rely on non-hardware accelerated Canvas operations. In addition, not all Skia
+  operations are supported by OpenGL, so some operations are still done in software with Skia, even
+  with hardware acceleration turned on.
+</p>
+<p>
+  The other main way that developers render graphics is by using OpenGL ES 1.x or 2.0 to directly
+  render to a surface.  Android provides OpenGL ES interfaces in the
+  <a href="http://developer.android.com/reference/android/opengl/package-summary.html">android.opengl</a> package
+  that a developer can use to call into your GL implementation with the SDK or with native APIs
+  provided in the Android NDK. 
+
+  <p class="note"><strong>Note:</strong>A third option, Renderscript, was introduced in Android 3.0 to
+  serve as a platform-agnostic graphics rendering API (it used OpenGL ES 2.0 under the hood), but
+  will be deprecated starting in the Android 4.1 release.
+</p>
+<h2 id="render">
+  How Android Renders Graphics
+</h2>
+<p>
+  No matter what rendering API developers use, everything is rendered onto a buffer of pixel data
+  called a "surface." Every window that is created on the Android platform is backed by a surface.
+  All of the visible surfaces that are rendered to are composited onto the display
+  by the SurfaceFlinger, Android's system service that manages composition of surfaces.
+  Of course, there are more components that are involved in graphics rendering, and the
+  main ones are described below:
+</p>
+
+<dl>
+  <dt>
+    <strong>Image Stream Producers</strong>
+  </dt>
+    <dd>Image stream producers can be things such as an OpenGL ES game, video buffers from the media server,
+      a Canvas 2D application, or basically anything that produces graphic buffers for consumption.
+    </dd>
+
+  <dt>
+    <strong>Image Stream Consumers</strong>
+  </dt>
+  <dd>The most common consumer of image streams is SurfaceFlinger, the system service that consumes
+    the currently visible surfaces and composites them onto the display using
+    information provided by the Window Manager. SurfaceFlinger is the only service that can
+    modify the content of the display. SurfaceFlinger uses OpenGL and the
+    hardware composer to compose a group of surfaces. Other OpenGL ES apps can consume image
+    streams as well, such as the camera app consuming a camera preview image stream.
+  </dd>
+  <dt>
+    <strong>SurfaceTexture</strong>
+  </dt>
+  <dd>SurfaceTexture contains the logic that ties image stream producers and image stream consumers together
+    and is made of three parts: <code>SurfaceTextureClient</code>, <code>ISurfaceTexture</code>, and
+    <code>SurfaceTexture</code> (in this case, <code>SurfaceTexture</code> is the actual C++ class and not
+    the name of the overall component). These three parts facilitate the producer (<code>SurfaceTextureClient</code>),
+    binder (<code>ISurfaceTexture</code>), and consumer (<code>SurfaceTexture</code>)
+    components of SurfaceTexture in processes such as requesting memory from Gralloc,
+    sharing memory across process boundaries, synchronizing access to buffers, and pairing the appropriate consumer with the producer.
+    SurfaceTexture can operate in both asynchronous (producer never blocks waiting for consumer and drops frames) and
+    synchronous (producer waits for consumer to process textures) modes. Some examples of image
+    producers are the camera preview produced by the camera HAL or an OpenGL ES game. Some examples
+    of image consumers are SurfaceFlinger or another app that wants to display an OpenGL ES stream
+    such as the camera app displaying the camera viewfinder.
+  </dd>
+
+ <dt>
+    <strong>Window Manager</strong>
+  </dt>
+  <dd>
+    The Android system service that controls window lifecycles, input and focus events, screen
+    orientation, transitions, animations, position, transforms, z-order, and many other aspects of
+    a window (a container for views). A window is always backed by a surface. The Window Manager
+    sends all of the window metadata to SurfaceFlinger, so SurfaceFlinger can use that data
+    to figure out how to composite surfaces on the display.
+  </dd>
+  
+  <dt>
+    <strong>Hardware Composer</strong>
+  </dt>
+  <dd>
+    The hardware abstraction for the display subsystem. SurfaceFlinger can delegate certain
+    composition work to the hardware composer to offload work from the OpenGL and the GPU. This makes
+    compositing faster than having SurfaceFlinger do all the work. Starting with Jellybean MR1,
+    new versions of the hardware composer have been introduced. See the <code>hardware/libhardware/include/hardware/gralloc.h</code> <a href="#hwc">Hardware composer</a> section
+    for more information.
+  </dd>
+
+    <dt>
+    <strong>Gralloc</strong>
+  </dt>
+  <dd>Allocates memory for graphics buffers. See the  If you
+    are using version 1.1 or later of the <a href="#hwc">hardware composer</a>, this HAL is no longer needed.</dd>
+  
+ 
+</dl>
+<p>
+  The following diagram shows how these components work together:
+</p><img src="images/graphics_surface.png">
+<p class="img-caption">
+  <strong>Figure 1.</strong> How surfaces are rendered
+</p>
+
+</p>
+<h2 id="provide">
+  What You Need to Provide
+</h2>
+<p>
+ The following list and sections describe what you need to provide to support graphics in your product:
+</p>
+<ul>
+  <li>OpenGL ES 1.x Driver
+  </li>
+  <li>OpenGL ES 2.0 Driver
+  </li>
+  <li>EGL Driver
+  </li>
+  <li>Gralloc HAL implementation
+  </li>
+  <li>Hardware Composer HAL implementation
+  </li>
+  <li>Framebuffer HAL implementation
+  </li>
+</ul>
+<h3 id="gl">
+  OpenGL and EGL drivers
+</h3>
+<p>
+  You must provide drivers for OpenGL ES 1.x, OpenGL ES 2.0, and EGL. Some key things to keep in
+  mind are:
+</p>
+<ul>
+  <li>The GL driver needs to be robust and conformant to OpenGL ES standards.
+  </li>
+  <li>Do not limit the number of GL contexts. Because Android allows apps in the background and
+  tries to keep GL contexts alive, you should not limit the number of contexts in your driver. It
+  is not uncommon to have 20-30 active GL contexts at once, so you should also be careful with the
+  amount of memory allocated for each context.
+  </li>
+  <li>Support the YV12 image format and any other YUV image formats that come from other
+    components in the system such as media codecs or the camera.
+  </li>
+  <li>Support the mandatory extensions: <code>GL_OES_texture_external</code>,
+  <code>EGL_ANDROID_image_native_buffer</code>, and <code>EGL_ANDROID_recordable</code>. We highly
+  recommend supporting <code>EGL_ANDROID_blob_cache</code> and <code>EGL_KHR_fence_sync</code> as
+  well.</li>
+</ul>
+
+<p>
+  Note that the OpenGL API exposed to app developers is different from the OpenGL interface that
+  you are implementing. Apps do not have access to the GL driver layer, and must go through the
+  interface provided by the APIs.
+</p>
+<h4>
+  Pre-rotation
+</h4>
+<p>Many times, hardware overlays do not support rotation, so the solution is to pre-transform the buffer before
+  it reaches SurfaceFlinger. A query hint in ANativeWindow was added (<code>NATIVE_WINDOW_TRANSFORM_HINT</code>)
+  that represents the most likely transform to be be applied to the buffer by SurfaceFlinger.
+
+  Your GL driver can use this hint to pre-transform the buffer before it reaches SurfaceFlinger, so when the buffer
+  actually reaches SurfaceFlinger, it is correctly transformed. See the ANativeWindow
+  interface defined in <code>system/core/include/system/window.h</code> for more details. The following
+  is some pseudo-code that implements this in the hardware composer:
+</p>
+
+<pre>
+ANativeWindow->query(ANativeWindow, NATIVE_WINDOW_DEFAULT_WIDTH, &w);
+ANativeWindow->query(ANativeWindow, NATIVE_WINDOW_DEFAULT_HEIGHT, &h);
+ANativeWindow->query(ANativeWindow, NATIVE_WINDOW_TRANSFORM_HINT, &hintTransform);
+if (hintTransform & HAL_TRANSFORM_ROT_90)
+swap(w, h);
+
+native_window_set_buffers_dimensions(anw, w, h);
+ANativeWindow->dequeueBuffer(...);
+
+// here GL driver renders content transformed by " hintTransform "
+
+int inverseTransform;
+inverseTransform = hintTransform;
+if (hintTransform & HAL_TRANSFORM_ROT_90)
+   inverseTransform ^= HAL_TRANSFORM_ROT_180;
+
+native_window_set_buffers_transform(anw, inverseTransform);
+
+ANativeWindow->queueBuffer(...);
+</pre>
+
+<h3 id="gralloc">
+  Gralloc HAL
+</h3>
+<p>
+  The graphics memory allocator is needed to allocate memory that is requested by
+  SurfaceTextureClient in image producers. You can find a stub implementation of the HAL at
+  <code>hardware/libhardware/modules/gralloc.h</code>
+</p>
+<h4>
+  Protected buffers
+</h4>
+<p>
+  There is a gralloc usage flag <code>GRALLOC_USAGE_PROTECTED</code> that allows
+  the graphics buffer to be displayed only through a hardware protected path.
+</p>
+<h3 id="hwc">
+  Hardware Composer HAL
+</h3>
+<p>
+  The hardware composer is used by SurfaceFlinger to composite surfaces to the screen. The hardware
+  composer abstracts things like overlays and 2D blitters and helps offload some things that would
+  normally be done with OpenGL. 
+</p>
+
+<p>Jellybean MR1 introduces a new version of the HAL. We recommend that you start using version 1.1 of the hardware
+  composer HAL as it will provide support for the newest features (explicit synchronization, external displays, etc).
+  Keep in mind that in addition to 1.1 version, there is also a 1.0 version of the HAL that we used for internal
+  compatibility reasons and a 1.2 draft mode of the hardware composer HAL. We recommend that you implement
+  version 1.1 until 1.2 is out of draft mode.
+</p>
+
+ <p>Because the physical display hardware behind the hardware composer
+  abstraction layer can vary from device to device, it is difficult to define recommended features, but
+  here is some guidance:</p>
+
+<ul>
+  <li>The hardware composer should support at least 4 overlays (status bar, system bar, application,
+  and live wallpaper) for phones and 3 overlays for tablets (no status bar).</li>
+  <li>Layers can be bigger than the screen, so the hardware composer should be able to handle layers
+    that are larger than the display (For example, a wallpaper).</li>
+  <li>Pre-multiplied per-pixel alpha blending and per-plane alpha blending should be supported at the same time.</li>
+  <li>The hardware composer should be able to consume the same buffers that the GPU, camera, video decoder, and Skia buffers are producing,
+    so supporting some of the following properties is helpful:
+   <ul>
+     <li>RGBA packing order</li>
+     <li>YUV formats</li>
+     <li>Tiling, swizzling, and stride properties</li>
+   </ul>
+  </li>
+  <li>A hardware path for protected video playback must be present if you want to support protected content.</li>
+</ul>
+<p>
+  The general recommendation when implementing your hardware composer is to implement a no-op
+  hardware composer first. Once you have the structure done, implement a simple algorithm to
+  delegate composition to the hardware composer. For example, just delegate the first three or four
+  surfaces to the overlay hardware of the hardware composer. After that focus on common use cases,
+  such as:
+</p>
+<ul>
+  <li>Full-screen games in portrait and landscape mode
+  </li>
+  <li>Full-screen video with closed captioning and playback control
+  </li>
+  <li>The home screen (compositing the status bar, system bar, application window, and live
+  wallpapers)
+  </li>
+  <li>Protected video playback
+  </li>
+  <li>Multiple display support
+  </li>
+</ul>
+<p>
+  After implementing the common use cases, you can focus on optimizations such as intelligently
+  selecting the surfaces to send to the overlay hardware that maximizes the load taken off of the
+  GPU. Another optimization is to detect whether the screen is updating. If not, delegate composition
+  to OpenGL instead of the hardware composer to save power. When the screen updates again, contin`ue to
+  offload composition to the hardware composer.
+</p>
+
+<p>
+  You can find the HAL for the hardware composer in the
+  <code>hardware/libhardware/include/hardware/hwcomposer.h</code> and <code>hardware/libhardware/include/hardware/hwcomposer_defs.h</code>
+  files. A stub implementation is available in the <code>hardware/libhardware/modules/hwcomposer</code> directory.
+</p>
+
+<h4>
+  VSYNC
+</h4>
+<p>
+  VSYNC synchronizes certain events to the refresh cycle of the display. Applications always
+  start drawing on a VSYNC boundary and SurfaceFlinger always composites on a VSYNC boundary.
+  This eliminates stutters and improves visual performance of graphics.
+  The hardware composer has a function pointer</p>
+
+    <pre>int (waitForVsync*) (int64_t *timestamp)</pre>
+
+  <p>that points to a function you must implement for VSYNC. This function blocks until
+    a VSYNC happens and returns the timestamp of the actual VSYNC.
+    A client can receive a VSYNC timestamps once, at specified intervals, or continously (interval of 1). 
+    You must implement VSYNC to have no more than a 1ms lag at the maximum (1/2ms or less is recommended), and
+    the timestamps returned must be extremely accurate.
+</p>
+
+<h4>Explicit synchronization</h4>
+<p>Explicit synchronization is required in Jellybean MR1 and later and provides a mechanism
+for Gralloc buffers to be acquired and released in a synchronized way.
+Explicit synchronization allows producers and consumers of graphics buffers to signal when
+they are done with a buffer. This allows the Android system to asynchronously queue buffers
+to be read or written with the certainty that another consumer or producer does not currently need them.</p>
+<p>
+This communication is facilitated with the use of synchronization fences, which are now required when requesting
+a buffer for consuming or producing. The
+ synchronization framework consists of three main parts:</p>
+<ul>
+  <li><code>sync_timeline</code>: a monotonically increasing timeline that should be implemented
+    for each driver instance. This basically is a counter of jobs submitted to the kernel for a particular piece of hardware.</li>
+    <li><code>sync_pt</code>: a single value or point on a <code>sync_timeline</code>. A point
+      has three states: active, signaled, and error. Points start in the active state and transition
+      to the signaled or error states. For instance, when a buffer is no longer needed by an image
+      consumer, this <code>sync_point</code> is signaled so that image producers
+      know that it is okay to write into the buffer again.</li>
+    <li><code>sync_fence</code>: a collection of <code>sync_pt</code>s that often have different
+      <code>sync_timeline</code> parents (such as for the display controller and GPU). This allows
+      multiple consumers or producers to signal that
+      they are using a buffer and to allow this information to be communicated with one function parameter.
+      Fences are backed by a file descriptor and can be passed from kernel-space to user-space.
+      For instance, a fence can contain two <code>sync_point</code>s that signify when two separate
+      image consumers are done reading a buffer. When the fence is signaled,
+      the image producers now know that both consumers are done consuming.</li>
+    </ul>
+
+<p>To implement explicit synchronization, you need to do provide the following:
+
+<ul>
+  <li>A kernel-space driver that implements a synchronization timeline for a particular piece of hardware. Drivers that
+    need to be fence-aware are generally anything that accesses or communicates with the hardware composer.
+    See the <code>system/core/include/sync/sync.h</code> file for more implementation details. The
+    <code>system/core/libsync</code> directory includes a library to communicate with the kernel-space </li>
+  <li>A hardware composer HAL module (version 1.1 or later) that supports the new synchronization functionality. You will need to provide
+  the appropriate synchronization fences as parameters to the <code>set()</code> and <code>prepare()</code> functions in the HAL. As a last resort,
+you can pass in -1 for the file descriptor parameters if you cannot support explicit synchronization for some reason. This
+is not recommended, however.</li>
+  <li>Two GL specific extensions related to fences, <code>EGL_ANDROID_native_fence_sync</code> and <code>EGL_ANDROID_wait_sync</code>,
+    along with incorporating fence support into your graphics drivers.</ul>
+
+
+
diff --git a/src/devices/hal.jd b/src/devices/hal.jd
new file mode 100644
index 0000000..5a53ef7
--- /dev/null
+++ b/src/devices/hal.jd
@@ -0,0 +1,124 @@
+page.title=The Hardware Abstraction Layer
+@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>
+  The hardware abstraction layer (HAL) defines a standard interface for hardware vendors to
+  implement and allows Android to be agnostic about lower-level driver
+  implementations. The HAL allows you to implement functionality
+  without affecting or modifying the higher level system. HAL implementations
+  are packaged into modules (<code>.so</code>) file and loaded by the Android
+  system at the appropriate time.
+<h2 id="structure">
+  Standard HAL structure
+</h2>
+<p>
+  Each hardware-specific HAL interface has properties that are common to all HAL interfaces. These
+  properties are defined in <code>hardware/libhardware/include/hardware/hardware.h</code> and
+  guarantees that HALs have a predictable structure.
+  This interface allows the Android system to load the correct versions of your
+  HAL modules in a consistent way. There are two general components
+  that a HAL interface consists of: a module and a device.
+</p>
+<p>
+  A module represents your packaged HAL implementation, which is stored as a shared library (<code>.so file</code>). It contains
+  metadata such as the version, name, and author of the module, which helps Android find and load it correctly. The
+  <code>hardware/libhardware/include/hardware/hardware.h</code> header file defines a
+  struct, <code>hw_module_t</code>, that represents a module and contains information such as
+  the module version, author, and name.</p>
+
+  <p>In addition, the <code>hw_module_t</code> struct contains
+  a pointer to another struct, <code>hw_module_methods_t</code>, that contains a pointer to
+  an "open" function for the module. This open function is used to initate communication with
+  the hardware that the HAL is serving as an abstraction for. Each hardware-specific HAL usually 
+  extends the generic <code>hw_module_t</code> struct with additional information
+  for that specific piece of hardware. For example in the camera HAL, the <code>camera_module_t</code> struct
+  contains a <code>hw_module_t</code> struct along with other camera-specific function pointers:
+</p>
+
+<pre>
+typedef struct camera_module {
+    hw_module_t common;
+    int (*get_number_of_cameras)(void);
+    int (*get_camera_info)(int camera_id, struct camera_info *info);
+} camera_module_t;
+</pre>
+
+<p>When you implement a HAL and create the module struct, you must name it
+  <code>HAL_MODULE_INFO_SYM</code>. For instance, here is an example from the Galaxy Nexus audio HAL:</p>
+<pre>
+struct audio_module HAL_MODULE_INFO_SYM = {
+    .common = {
+        .tag = HARDWARE_MODULE_TAG,
+        .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
+        .hal_api_version = HARDWARE_HAL_API_VERSION,
+        .id = AUDIO_HARDWARE_MODULE_ID,
+        .name = "Tuna audio HW HAL",
+        .author = "The Android Open Source Project",
+        .methods = &hal_module_methods,
+    },
+};
+</pre>
+<p>
+  A device abstracts the actual hardware of your product. For example, an audio module can contain
+  a primary audio device, a USB audio device, or a Bluetooth A2DP audio device. A device
+  is represented by the <code>hw_device_t</code> struct. Like a module, each type of device
+  defines a more-detailed version of the generic <code>hw_device_t</code> that contains
+  function pointers for specific features of the hardware. For example, the
+  <code>audio_hw_device_t</code> struct type contains function pointers to audio device operations:
+</p>
+
+<pre>
+struct audio_hw_device {
+    struct hw_device_t common;
+
+    /**
+     * used by audio flinger to enumerate what devices are supported by
+     * each audio_hw_device implementation.
+     *
+     * Return value is a bitmask of 1 or more values of audio_devices_t
+     */
+    uint32_t (*get_supported_devices)(const struct audio_hw_device *dev);
+  ...
+};
+typedef struct audio_hw_device audio_hw_device_t;
+</pre>
+
+<p>
+  In addition to these standard properties, each hardware-specific HAL interface can define more of its
+  own features and requirements. See the <a href="{@docRoot}guide/reference/files.html">HAL reference documentation</a>
+  as well as the individual instructions for each HAL for more information on how to implement a specific interface.
+</p>
+
+<h2 id="modules">HAL modules</h2>
+<p>HAL implementations are built into modules (<code>.so</code>) files and are dynamically linked by Android when appropriate.
+  You can build your modules by creating <code>Android.mk</code> files for each of your HAL implementations
+  and pointing to your source files. In general, your shared libraries must be named in a certain format, so that
+  they can be found and loaded properly. The naming scheme varies slightly from module to module, but they follow
+  the general pattern of: <code>&lt;module_type&gt;.&lt;device_name&gt;</code>.</p>
+
+  <p>For more information about setting up the build for each HAL, see its respective documentation.</p>
+
+</p>
\ No newline at end of file
diff --git a/src/devices/images/audio_hal.png b/src/devices/images/audio_hal.png
new file mode 100644
index 0000000..273ac81
--- /dev/null
+++ b/src/devices/images/audio_hal.png
Binary files differ
diff --git a/src/devices/images/bt.png b/src/devices/images/bt.png
new file mode 100644
index 0000000..d2d941a
--- /dev/null
+++ b/src/devices/images/bt.png
Binary files differ
diff --git a/src/devices/images/camera2_block.png b/src/devices/images/camera2_block.png
new file mode 100644
index 0000000..b7a58eb
--- /dev/null
+++ b/src/devices/images/camera2_block.png
Binary files differ
diff --git a/src/devices/images/camera2_hal.png b/src/devices/images/camera2_hal.png
new file mode 100644
index 0000000..28fa927
--- /dev/null
+++ b/src/devices/images/camera2_hal.png
Binary files differ
diff --git a/src/devices/images/camera_hal.png b/src/devices/images/camera_hal.png
new file mode 100644
index 0000000..48b3b69
--- /dev/null
+++ b/src/devices/images/camera_hal.png
Binary files differ
diff --git a/src/devices/images/drm_hal.png b/src/devices/images/drm_hal.png
new file mode 100644
index 0000000..ef6379b
--- /dev/null
+++ b/src/devices/images/drm_hal.png
Binary files differ
diff --git a/src/devices/images/graphics_arch.png b/src/devices/images/graphics_arch.png
new file mode 100644
index 0000000..8d1749a
--- /dev/null
+++ b/src/devices/images/graphics_arch.png
Binary files differ
diff --git a/src/devices/images/graphics_surface.png b/src/devices/images/graphics_surface.png
new file mode 100644
index 0000000..e32792d
--- /dev/null
+++ b/src/devices/images/graphics_surface.png
Binary files differ
diff --git a/src/devices/images/ihv_req.png b/src/devices/images/ihv_req.png
new file mode 100644
index 0000000..5191568
--- /dev/null
+++ b/src/devices/images/ihv_req.png
Binary files differ
diff --git a/src/devices/images/media.png b/src/devices/images/media.png
new file mode 100644
index 0000000..7aaee93
--- /dev/null
+++ b/src/devices/images/media.png
Binary files differ
diff --git a/src/devices/images/overview.png b/src/devices/images/overview.png
new file mode 100644
index 0000000..3e54d1a
--- /dev/null
+++ b/src/devices/images/overview.png
Binary files differ
diff --git a/src/devices/images/system-architecture.png b/src/devices/images/system-architecture.png
new file mode 100644
index 0000000..bbddec9
--- /dev/null
+++ b/src/devices/images/system-architecture.png
Binary files differ
diff --git a/src/devices/images/system_architecture.png b/src/devices/images/system_architecture.png
new file mode 100644
index 0000000..3e54d1a
--- /dev/null
+++ b/src/devices/images/system_architecture.png
Binary files differ
diff --git a/src/devices/index.jd b/src/devices/index.jd
new file mode 100644
index 0000000..a54d339
--- /dev/null
+++ b/src/devices/index.jd
@@ -0,0 +1,98 @@
+page.title=Porting Android to 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.
+-->
+<div id="qv-wrapper">
+  <div id="qv">
+    <h2>In this document</h2>
+    <ol id="auto-toc">
+    </ol>
+  </div>
+</div>
+
+  <p>Android provides you with the freedom to implement your own device specifications
+  and the drivers to support them. The hardware abstraction layer (HAL) gives you a
+  standard way to create software hooks in between the Android
+  platform stack and your hardware. In addition, the Android operating system 
+  is open-sourced to help you through your device's bringup.</p>
+
+  <p>To ensure that your devices maintain a high level of quality and offers a consistent
+  experience for your users, they must must also
+  pass the tests in the compatibility test suite (CTS). CTS ensures that anyone
+  building a device meets a quality standard that ensures apps run reliabaly well
+  and gives users a good experience. For more information, see the 
+  <a href="{@docRoot}compatibility/index.html">Compatibility</a> section.</p>
+
+ <h2>Android Low-Level System Architecture</h2>
+
+<p>Before you begin porting Android to your hardware, it is important to have an
+understanding of how Android works at a high level. Because your drivers and HAL code interact
+with many layers of Android code, this understanding can help you find
+your way through the many layers of code that are available to you through the AOSP
+(Android Open Source Project) source tree. The following diagram shows a system
+level view of how Android works:
+</p>
+
+<img src="images/system-architecture.png">
+
+<p class="img-caption"><strong>Figure 1.</strong> Android System Architecture</p>
+
+  <h4>Application framework</h4>
+  <p>This is the level that most application developers concern themselves with. You should be
+    aware of the APIs available to developers as many of them map 1:1 to the underlying HAL
+    interfaces and can provide information as to how to implement your driver.
+  </p>
+
+  <h4>Binder IPC</h4>
+  <p>
+  The Binder Inter-Process Communication mechanism allows the application framework to
+  cross process boundaries and call into the Android system services code. This basically allows
+  high level framework APIs to interact with Android's system services. At the application framework level, all
+  of this communication is hidden from the developer and things appear to "just work." 
+  </p>
+
+  <h4>System services</h4>
+  <p>Most of the functionality exposed through the application framework APIs  must
+    communicate with some sort of system service to access the underlying hardware. Services
+    are divided into modular components with focused functionality 
+    such as the Window Manager, Search Service, or Notification Manager. System services are grouped
+    into two buckets: system and media. The system services include things such as the Window or
+    Notification Manager. The media services include all the services involved in playing and
+    recording media.
+  </p>
+  
+<h4>Hardware abstraction layer (HAL)</h4>
+<p>The HAL serves as a standard interface that allows the Android system to call into the device
+  driver layer while being agnostic about the lower-level implementations of your drivers and hardware.
+  You must implement the corresponding HAL (and driver) for the particular piece of hardware that your product
+  provides. Android does not mandate a standard interaction between your HAL implementation and your device drivers, so
+  you have free reign to do what is best for your situation. However, you must abide by the contract
+  defined in each hardware-specific HAL interface for the Android system to be able
+  to correctly interact with your hardware. HAL implementations are typically built into
+  shared library modules (<code>.so</code> files).
+</p>
+<h4>Linux Kernel</h4>
+<p>For the most part, developing your device drivers is the same as developing a typical Linux device driver.
+  Android uses a specialized version of the Linux kernel with a few special additions such as
+  wakelocks, a memory management system that is more agressive in preserving memory,
+  the Binder IPC driver, and other features that are important for a mobile embedded platform like Android.
+  These additions have less to do with driver development than with the system's functionality. The PDK
+  does not provide kernel sources, so you must provide your own. You can use any version of the kernel that
+  you want as long as it supports the required features, such as the binder driver. However, we recommend
+  using the latest version of the Android kernel. For the latest Android kernel, see
+  <a href="{@docRoot}source/building-kernels.html" >Building Kernels</a>.
+</p>
\ No newline at end of file
diff --git a/src/devices/media.jd b/src/devices/media.jd
new file mode 100644
index 0000000..eed62c9
--- /dev/null
+++ b/src/devices/media.jd
@@ -0,0 +1,114 @@
+page.title=Media
+@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>
+  Android provides a media playback engine at the native level called Stagefright that comes built-in with
+  software-based codecs for several popular media formats. Stagefright features for audio and video playback
+  include integration with OpenMAX codecs, session management, time-synchronized rendering, transport control,
+  and DRM. In addition, Stagefright supports integration with custom hardware codecs that you provide.
+  There actually isn't a HAL to implement for custom codecs, but to provide a hardware path to encode and
+  decode media, you must implement your hardware-based codec as an OpenMax IL (Integration Layer) component.
+</p>
+<h2 id="overview">
+Overview
+</h2>
+<p>The following diagram shows how media applications interact with the Android native multimedia framework.</p>
+<p>
+  <img src="images/media.png">
+</p>
+<dl>
+<dt>Application Framework</dt>
+  <dd>At the application framework level is the app's code, which utilizes the
+  <a href="http://developer.android.com/reference/android/media/package-summary.html">android.media</a>
+  APIs to interact with the multimedia hardware.</dd>
+  <dt>Binder IPC</dt>
+  <dd>The Binder IPC proxies facilitate communication over process boundaries. They are located in 
+    the <code>frameworks/av/media/libmedia</code> directory and begin with the letter "I".</dd>
+  <dt>Native Multimedia Framework</dt>
+  <dd>At the native level, Android provides a multimedia framework that utilizes the Stagefright engine for
+  audio and video recording and playback. Stagefright comes with a default list of supported software codecs
+  and you can implement your own hardware codec by using the OpenMax integration layer standard. For more
+  implementation details, see the various MediaPlayer and Stagefright components located in
+  <code>frameworks/av/media</code>.
+  </dd>
+  <dt>OpenMAX Integration Layer (IL)</dt>
+  <dd>The OpenMAX IL provides a standardized way for Stagefright to recognize and use custom hardware-based
+  multimedia codecs called components. You must provide an OpenMAX plugin in the form of a shared library
+  named <code>libstagefrighthw.so</code>. This plugin links your custom codec components to Stagefright.
+  Your custom codecs must be implemented according to the OpenMAX IL component standard.
+   </dd>
+</dl>
+
+
+<h2 id="codecs">
+Implementing Custom Codecs
+</h2>
+<p>Stagefright comes with built-in software codecs for common media formats, but you can also add your
+  own custom hardware codecs as OpenMAX components. To do this, you need to create OMX components and also an
+  OMX plugin that hooks together your custom codecs with the Stagefright framework. For an example, see
+  the <code>hardware/ti/omap4xxx/domx/</code> for example components and <code>hardware/ti/omap4xx/libstagefrighthw</code>
+  for an example plugin for the Galaxy Nexus.
+</p>
+  <p>To add your own codecs:</p>
+<ol>
+<li>Create your components according to the OpenMAX IL component standard. The component interface is located in the
+  <code>frameworks/native/include/media/OpenMAX/OMX_Component.h</code> file. To learn more about the
+  OpenMAX IL specification, see the <a href="http://www.khronos.org/openmax/">OpenMAX website</a>.</li>
+<li>Create a OpenMAX plugin that links your components with the Stagefright service.
+  See the <code>frameworks/native/include/media/hardware/OMXPluginBase.h</code> and <code>HardwareAPI.h</code> header
+  files for the interfaces to create the plugin.
+</li>
+<li>Build your plugin as a shared library with the name <code>libstagefrighthw.so</code> in your product Makefile. For example:
+<pre>LOCAL_MODULE := libstagefrighthw</pre>
+
+<p>In your device's Makefile, ensure that you declare the module as a product package:</p>
+<pre>
+PRODUCT_PACKAGES += \
+  libstagefrighthw \
+  ...
+</pre>
+</li>
+</ol>
+
+<h2 id="expose">Exposing Codecs to the Framework</h2>
+<p>The Stagefright service parses the <code>system/etc/media_codecs.xml</code> and <code>system/etc/media_profiles.xml</code>
+  to expose the supported codecs and profiles on the device to app developers via the <code>android.media.MediaCodecList</code> and
+  <code>android.media.CamcorderProfile</code> classes. You need to create both files in the
+  <code>device/&lt;company_name&gt;/&lt;device_name&gt;/</code> directory
+ and copy this over to the system image's <code>system/etc</code> directory in your device's Makefile.
+ For example:</p>
+
+ <pre>
+PRODUCT_COPY_FILES += \
+  device/samsung/tuna/media_profiles.xml:system/etc/media_profiles.xml \
+  device/samsung/tuna/media_codecs.xml:system/etc/media_codecs.xml \
+</pre>
+
+<p>See the <code>device/samsung/tuna/media_codecs.xml</code> and
+  <code>device/samsung/tuna/media_profiles.xml</code> file for complete examples.</p>
+
+<p class="note"><strong>Note:</strong> The <code>&lt;Quirk&gt;</code> element for media codecs is no longer supported
+  by Android starting in Jelly Bean.</p>
\ No newline at end of file
diff --git a/src/devices/native-memory.jd b/src/devices/native-memory.jd
new file mode 100644
index 0000000..d3beed7
--- /dev/null
+++ b/src/devices/native-memory.jd
@@ -0,0 +1,37 @@
+page.title=Debugging Native Memory Use
+@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 tip assume that you are working with an eng
+or userdebug build of the platform, not on a production device.</p>
+<p>Android's native memory allocator has some useful debugging features.  You
+can turn on memory tracking with:</p>
+<pre><code>  $ adb shell setprop libc.debug.malloc 1
+  $ adb shell stop
+  $ adb shell start
+</code></pre>
+<p>You need to restart the runtime so that zygote and all processes launched from
+it are restarted with the property set.  Now all Dalvik processes have memory
+tracking turned on.  You can look at these with DDMS, but first you need to
+turn on its native memory UI:</p>
+<ul>
+<li>Open ~/.android/ddms.cfg</li>
+<li>Add a line "native=true"</li>
+</ul>
+<p>Upon relaunching DDMS and selecting a process, you can switch to the new
+native allocation tab and populate it with a list of allocations.  This is
+especially useful for debugging memory leaks.</p>
diff --git a/src/devices/overview.jd b/src/devices/overview.jd
new file mode 100644
index 0000000..ddb34b9
--- /dev/null
+++ b/src/devices/overview.jd
@@ -0,0 +1,198 @@
+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.
+-->
+<div id="qv-wrapper">
+  <div id="qv">
+    <h2>
+      In this document
+    </h2>
+    <ol>
+    </ol>
+  </div>
+</div>
+
+<p>Welcome to the Android Platform Development Kit (PDK) Guide! The Android PDK allows partners to port 
+  their drivers as well as develop, optimize, and test against an upcoming Android platform release.
+  The Android PDK includes a set of interfaces for the Android hardware abstraction layer (HAL),
+  platform sources for integration, a binary system image, and HAL and integration documentation.
+  In addition, the PDK also ships with the Android Compatibility Test Suite (CTS).
+</p>
+
+<h2 id="arch">Android Low-Level System Architecture</h2>
+<p>Before you begin porting Android to your hardware, it is important to have an
+understanding of how Android works at a high level. Because your drivers and HAL code interact
+with many layers of Android code, this understanding can help you find
+your way through the many layers of code that are available to you through the AOSP
+(Android Open Source Project) source tree as well as the PDK.
+The following diagram shows a system level view of how Android works:
+</p>
+
+<img src="images/system-architecture.png">
+
+<p class="img-caption"><strong>Figure 1.</strong> Android System Architecture</p>
+
+  <h4>Application framework</h4>
+  <p>This is the level that most application developers concern themselves with. You should be
+    aware of the APIs available to developers as many of them map 1:1 to the underlying HAL
+    interfaces and can provide information as to how to implement your driver.
+  </p>
+
+  <h4>Binder IPC</h4>
+  <p>
+  The Binder Inter-Process Communication mechanism allows the application framework to
+  cross process boundaries and call into the Android system services code. This basically allows
+  high level framework APIs to interact with Android's system services. At the application framework level, all
+  of this communication is hidden from the developer and things appear to "just work." 
+  </p>
+
+  <h4>System services</h4>
+  <p>Most of the functionality exposed through the application framework APIs  must
+    communicate with some sort of system service to access the underlying hardware. Services
+    are divided into modular components with focused functionality 
+    such as the Window Manager, Search Service, or Notification Manager. System services are grouped
+    into two buckets: system and media. The system services include things such as the Window or
+    Notification Manager. The media services include all the services involved in playing and
+    recording media.
+  </p>
+  
+<h4>Hardware abstraction layer (HAL)</h4>
+<p>The HAL serves as a standard interface that allows the Android system to call into the device
+  driver layer while being agnostic about the lower-level implementations of your drivers and hardware.
+  You must implement the corresponding HAL (and driver) for the particular piece of hardware that your product
+  provides. Android does not mandate a standard interaction between your HAL implementation and your device drivers, so
+  you have free reign to do what is best for your situation. However, you must abide by the contract
+  defined in each hardware-specific HAL interface for the Android system to be able
+  to correctly interact with your hardware. HAL implementations are typically built into
+  shared library modules (<code>.so</code> files).
+</p>
+<h4>Linux Kernel</h4>
+<p>For the most part, developing your device drivers is the same as developing a typical Linux device driver.
+  Android uses a specialized version of the Linux kernel with a few special additions such as
+  wakelocks, a memory management system that is more agressive in preserving memory,
+  the Binder IPC driver, and other features that are important for a mobile embedded platform like Android.
+  These additions have less to do with driver development than with the system's functionality. The PDK
+  does not provide kernel sources, so you must provide your own. You can use any version of the kernel that
+  you want as long as it supports the required features, such as the binder driver. However, we recommend
+  using the latest version of the Android kernel. For the latest Android kernel, see
+  <a href="http://source.android.com/source/building-kernels.html" >Building Kernels</a>.
+</p>
+
+
+<h2 id="pdk">PDK Components</h2>
+<p>Now that you have a high-level overview of the Android system, we'll go over the PDK and what it provides
+  to port Android to your product. The PDK provides source files needed to implement
+  your product and a platform binary that lets you build a runnable system image. You can then install
+  this barebones image to test your product with the latest builds of Android. The most important source files
+  included in the PDK are located in the:</p>
+
+  <ul>
+    <li><code>frameworks/native</code> directory</li>
+    <li><code>frameworks/av</code> directory for media, camera, DRM, and the audio framework stack</code></li>
+    <li><code>hardware/libhardware/include/hardware</code> directory for the HAL interfaces </li>
+    <li><code>vendor/pdk/data/cts</code> directory for the CTS binaries</li>
+  </ul>
+</p>
+<p>In addition, the Android PDK includes the following source directories:</p>
+<ul>
+  <li>abi</li>
+  <li>bionic</li>
+  <li>bootable</li>
+  <li>build</li>
+  <li>device</li>
+  <li>external (Chromium and Webkit are not included)</li>
+  <li>hardware</li>
+  <li>libnativehelper</li>
+  <li>pdk</li>
+  <li>prebuilt</li>
+  <li>prebuilts</li>
+  <li>system</li>
+</ul>
+
+  <p>The PDK also contains documentation that is split into three different sections:</p>
+  <ul>
+    <li><a href="{@docRoot}guide/getting_started.html">Getting Started</a> - Explains how to download the PDK source, how the Android build system works, and how to configure a build for your specific product.</li>
+    <li><a href="{@docRoot}guide/hal.html">The Hardware Abstraction Layer</a> - Explains the various HALs provided by Android and the interfaces (C header files) that define them. </li>
+      <li><a href="{@docRoot}guide/reference/files.html">HAL reference</a> - A quick reference for the various HAL interfaces.</li>
+  </ul>
+
+<h3 id="cts">Compatibility Test Suite</h3>
+<p>CTS binaries for ARM, MIPS, and x86 are provided in the corresponding directories in <code>vendor/pdk/data/cts</code>. Only the ARM
+  variant is Google-verified as there is no Nexus device running on any other architecture. Not all of the CTS tests since the
+  complete Android platform is not present. The following CTS tests should work:</p>
+
+<ul>
+      <li>android.bluetooth</li>
+      <li>android.graphics</li>
+      <li>android.graphics2</li>
+      <li>android.hardware</li>
+      <li>android.location</li>
+      <li>android.opengl</li>
+      <li>android.openglperf</li>
+      <li>android.media</li>
+      <li>android.mediastress</li>
+      <li>android.nativemedia.sl</li>
+      <li>android.nativemedia.xa</li>
+      <li>android.net</li>
+      <li>android.renderscript</li>
+    </ul>
+    <p>You can run individual packages such as <code>android.media</code> with:</p>
+    <pre>cts-tradefed run singleCommand cts --skip-device-info --package android.media</pre>
+</ul>
+
+  <p>Because the PDK is missing many components compared to a full Android source tree,
+  there is a PDK test plan that is provided with CTS that limits the tests that are ran when using the PDK. You can run
+  this special test plan with the following command:</p>
+
+  <pre>run cts --plan PDK</pre>
+    
+<p>CTS is always actively under development, so we expect some tests to fail. CTS results
+  for the Galaxy Nexus are provided for you in the
+  the <code>vendor/pdk/data/cts/</code> directory and will show which tests fail on that
+  device. You can safely ignore the failed tests for your devices as well.</p>
+
+  <p>See the <a href="http://source.android.com/compatibility/cts-intro.html">CTS manual</a> for more information on CTS.</p>
+
+<h2 id="inc-ex">PDK Inclusions and Exclusions</h2>
+<p>The PDK is a subset of the complete Android source tree and might be missing things that you might need. Here is a list of what the PDK supports
+  and does not support:</p>
+<ul>
+  <li>Supports building Android apps using the publicly available, standard SDK. Builds with non-public platform APIs are not supported. The JNI build is supported.</li>
+  <li>Supports only <code>en_US</code> locale.</li>
+  <li>Supports only phone layouts. Tablet layouts are not included.</li>
+  <li>Enables support for software navigation buttons by default, which you can disable by setting <code>qemu.jw.mainkeys=1</code>.</li>
+  <li>Builds all binaries with SMP (symmetric multiprocessing) features enabled. This might have a small performance impact on non-SMP CPUs.</li>
+  <li>Includes a minimal amount of Java libraries. Obtain any additional Java libraries from the publicly released Android source tree.</li>
+  <li>Contains a minimum number of applications. Build and install necessary applications as needed.</li>
+  <li>Does not support media streaming.</li>
+  <li>Does not include non-Latin fonts. (set by <code>MINIMAL_FONT_FOOTPRINT</code> variable in <code>BoardConfig.mk</code>).
+  An app might crash if it requires such fonts. </li>
+  <li>Does not support replacing framework resources by using the overlay mechanism.
+    This means all configurations controlled by framework resources are fixed.</li>   
+  <li>Does not support NFC</li>
+  <li>Does not support DRM</li>
+</ul>
+
+<h2 id="knownissues">Support and Known Issues</h2>
+<p>
+For questions or to report issues related with the PDK, send a message to the <a href="https://groups.google.com/a/google.com/forum/?fromgroups#!forum/android-pdk-feedback">android-pdk@google.com</a> mailing list.</p>
+
+<p>The following list describes the known issues with the PDK:</p>
+<ul>
+  <li>After running the CTS (Compatibility Test Suite), <code>android.process.acore</code> crashes. This is caused by
+some missing components in PDK and does not affect the operation of CTS tests.</li>
+</p>
diff --git a/src/devices/porting.jd b/src/devices/porting.jd
new file mode 100644
index 0000000..e0b6eb8
--- /dev/null
+++ b/src/devices/porting.jd
@@ -0,0 +1,98 @@
+page.title=Porting
+@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>Android provides you with the freedom to implement your own device specifications
+  and the drivers to support them. The hardware abstraction layer (HAL) gives you a
+  standard way to create software hooks in between the Android
+  platform stack and your hardware. In addition, the Android operating system 
+  is open-sourced to help you through your device's bringup.</p>
+
+  <p>To ensure that your devices maintain a high level of quality and offers a consistent
+  experience for your users, they must must also
+  pass the tests in the compatibility test suite (CTS). CTS ensures that anyone
+  building a device meets a quality standard that ensures apps run reliabaly well
+  and gives users a good experience. For more information, see the 
+  <a href="{@docRoot}compatibility/index.html">Compatibility</a> section.</p>
+
+ <h2>Android Low-Level System Architecture</h2>
+
+<p>Before you begin porting Android to your hardware, it is important to have an
+understanding of how Android works at a high level. Because your drivers and HAL code interact
+with many layers of Android code, this understanding can help you find
+your way through the many layers of code that are available to you through the AOSP
+(Android Open Source Project) source tree. The following diagram shows a system
+level view of how Android works:
+</p>
+
+<img src="images/system-architecture.png">
+
+<p class="img-caption"><strong>Figure 1.</strong> Android System Architecture</p>
+
+  <h4>Application framework</h4>
+  <p>This is the level that most application developers concern themselves with. You should be
+    aware of the APIs available to developers as many of them map 1:1 to the underlying HAL
+    interfaces and can provide information as to how to implement your driver.
+  </p>
+
+  <h4>Binder IPC</h4>
+  <p>
+  The Binder Inter-Process Communication mechanism allows the application framework to
+  cross process boundaries and call into the Android system services code. This basically allows
+  high level framework APIs to interact with Android's system services. At the application framework level, all
+  of this communication is hidden from the developer and things appear to "just work." 
+  </p>
+
+  <h4>System services</h4>
+  <p>Most of the functionality exposed through the application framework APIs  must
+    communicate with some sort of system service to access the underlying hardware. Services
+    are divided into modular components with focused functionality 
+    such as the Window Manager, Search Service, or Notification Manager. System services are grouped
+    into two buckets: system and media. The system services include things such as the Window or
+    Notification Manager. The media services include all the services involved in playing and
+    recording media.
+  </p>
+  
+<h4>Hardware abstraction layer (HAL)</h4>
+<p>The HAL serves as a standard interface that allows the Android system to call into the device
+  driver layer while being agnostic about the lower-level implementations of your drivers and hardware.
+  You must implement the corresponding HAL (and driver) for the particular piece of hardware that your product
+  provides. Android does not mandate a standard interaction between your HAL implementation and your device drivers, so
+  you have free reign to do what is best for your situation. However, you must abide by the contract
+  defined in each hardware-specific HAL interface for the Android system to be able
+  to correctly interact with your hardware. HAL implementations are typically built into
+  shared library modules (<code>.so</code> files).
+</p>
+<h4>Linux Kernel</h4>
+<p>For the most part, developing your device drivers is the same as developing a typical Linux device driver.
+  Android uses a specialized version of the Linux kernel with a few special additions such as
+  wakelocks, a memory management system that is more agressive in preserving memory,
+  the Binder IPC driver, and other features that are important for a mobile embedded platform like Android.
+  These additions have less to do with driver development than with the system's functionality. The PDK
+  does not provide kernel sources, so you must provide your own. You can use any version of the kernel that
+  you want as long as it supports the required features, such as the binder driver. However, we recommend
+  using the latest version of the Android kernel. For the latest Android kernel, see
+  <a href="{@docRoot}source/building-kernels.html" >Building Kernels</a>.
+</p>
\ No newline at end of file
diff --git a/src/devices/source.jd b/src/devices/source.jd
new file mode 100644
index 0000000..0b9bc7a
--- /dev/null
+++ b/src/devices/source.jd
@@ -0,0 +1,72 @@
+page.title=Getting the Source
+@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>
+  Before you can use the PDK, ensure that your <a href="{@docRoot}source/initializing.html">build environment
+  is set up</a>. When you are done, follow these steps to obtain the Android PDK source:
+</p>
+<ol>
+  <li>
+    <a href=
+    "https://accounts.google.com/SignUp?continue=https%3A%2F%2Faccounts.google.com%2FManageAccount">
+    Create a Google Account</a> with a corporate email address (e.g. @htc.com or @motorola.com and
+    not @gmail.com) for each individual who needs access to the partner source server. This should
+    be a relatively small number of users.
+  </li>
+  <li>Sign into the <a href="https://partner-android-review.googlesource.com">Android Gerrit
+  server</a> with the Google Account you just created and go to <strong>Settings &gt; HTTP Password
+  &gt; Obtain Password</strong> to get a password that you can use to authenticate to the Android
+  source servers. Follow the directions on that page for more information.
+  </li>
+  <li>Send a list of the Google Accounts that were created to Google to add them to our access
+  list.
+  </li>
+  <li>There are four variants of the source that you can sync to. For armv7a, run the following commands:
+<pre>
+repo init -u https://partner-android.googlesource.com/platform/vendor/pdk/mini_armv7a_neon/mini_armv7a_neon-userdebug/manifest.git -b &lt;branch_name&gt;
+repo sync
+</pre>
+<p>For armv7a with NEON support, run the following commands:</p>
+<pre>
+repo init -u https://partner-android.googlesource.com/platform/vendor/pdk/mini_armv7a/mini_armv7a-userdebug/manifest.git -b &lt;branch_name&gt;
+repo sync 
+</pre>
+<p>For MIPS, run the following commands:</p>
+<pre>
+repo init -u https://partner-android.googlesource.com/a/platform/vendor/pdk/mini_mips/mini_mips-userdebug/manifest.git -b &lt;branch_name&gt;
+repo sync 
+</pre>
+<p>For x86, run the following commands:</p>
+<pre>
+repo init -u https://partner-android.googlesource.com/a/platform/vendor/pdk/mini_x86/mini_x86-userdebug/manifest.git -b &lt;branch_name&gt;
+repo sync 
+</pre>
+
+<p>For example, use the <code>jb-mr1-release</code> branch for the PDK release for Jelly Bean MR1.</p>
+</li>
+</ol>
+
+
+<p class="note"><strong>Note:</strong> The PDK repository might be updated many times a day,
+  so it might be a good idea to sync less often if bandwidth is a concern.
+  It is usually more beneficial to sync more frequently at the early development phases of a new platform release
+  as more drastic changes can happen. Additionally, any PDK repository update results in an
+  updated <code>manifest.xml</code> so if you manually change the <code>manifest.xml</code>
+to add your own projects, this blocks syncing of the repository.
+A solution to both these issues is to have a local repository set up that syncs with the PDK
+  repository and then have your developers sync with your local repository and not the main PDK one.</p>
\ No newline at end of file
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>
diff --git a/src/devices/tuning.jd b/src/devices/tuning.jd
new file mode 100644
index 0000000..b33e453
--- /dev/null
+++ b/src/devices/tuning.jd
@@ -0,0 +1,181 @@
+page.title=Performance tuning
+@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 describes performance tuninig that you can do to get the most out of your
+  hardware.</p>
+
+<h2>OpenGLRenderer (libhwui) Properties</h2>
+<p>This document lists all the properties that you can use to control
+Android’s 2D hardware accelerated rendering pipeline. Set these properties
+in the <code>device.mk</code> as <code>PRODUCT_PROPERTY_OVERRIDES</code>.
+</p>
+
+<table>
+<tr>
+  <th>Property</th>
+  <th>Type</th>
+  <th>Default Value</th>
+  <th>Description</th>
+</tr>
+
+<tr>
+  <td><code>ro.hwui.disable_scissor_opt</code></td>
+  <td><code>boolean</code></td>
+  <td><code>false</code></td>
+  <td><p>Used to enable or disable scissor optimization. The accepted values are true and false. When scissor optimization is enabled, OpenGLRenderer attempts to minimize the use of scissoring by selectively enabling and disabling the GL scissor test.</p>
+  <p>When the optimization is disabled, OpenGLRenderer keeps the GL scissor test enabled and changes the scissor rect as needed. Some GPUs (for instance, the SGX 540) perform better when changing the scissor rect more often than enabling or disabling the scissor test often.</p>
+  </td>
+</tr>
+
+<tr>
+
+  <td><code>ro.hwui.texture_cache_size</code></td>
+  <td><code>float</code></td>
+  <td><code>24</code></td>
+  <td>Defines the size, in megabytes, of the per process texture cache. We
+  recommend using a cache large enough to hold several screens worth of 32-bit textures (for instance, on a 1280x800 display, a full screen buffer uses about 4 MB so the cache should be at least 20 MB.)</td>
+</tr>
+
+<tr>
+  <td><code>ro.hwui.layer_cache_size</code></td>
+  <td><code>float</code></td>
+  <td><code>16</code></td>
+  <td>Defines the size, in megabytes, of the per process layers cache. We recommend
+  using a cache large enough to hold 4 times the screen in 32 bits. For instance,
+  on a 1280x800 display, a full screen buffer uses about 4 MB, so the cache should be at least 16 MB.</td>
+</tr>
+<tr>
+  <td><code>ro.hwui.gradient_cache_size</code></td>
+  <td><code>0.5</code></td>
+  <td><code>float</code></td>
+  <td>Defines the size, in megabytes, of the per process gradients cache. A single
+  gradient generally occupies between 1 and 4 KB of memory. It is recommended to use a
+  cache large enough to hold at least twelve gradients.</td>
+</tr>
+
+<tr>
+  <td><code>ro.hwui.path_cache_size</code></td>
+  <td><code>float</code></td>
+  <td><code>4</code></td>
+  <td>Defines the size, in megabytes, of the per process paths cache. We recommended using a
+  cache large enough to hold at least one screen worth of 32-bit textures. For instance,
+  on a 1280x800 display, a full screen buffer uses about 4 MB, so the cache should be at least 4 MB.</td>
+</tr>
+<tr>
+  <td><code>ro.hwui.shape_cache_size</code></td>
+  <td><code>float</code></td>
+  <td><code>1</code></td>
+  <td>Defines the size, in megabytes, of the per process shapes caches. This value is used by
+  several caches such as circles and rounded rectangles. We recommend using a cache
+  large enough to hold at least one 8-bit screen. For instance, on a 1280x800 display,
+  a full screen buffer uses about 1 MB, so the cache should be at least 1 MB.</td>
+</tr>
+<tr>
+  <td><code>ro.hwui.drop_shadow_cache_size</code></td>
+  <td><code>float</code></td>
+  <td><code>2</code></td>
+  <td>Defines the size, in megabytes, of the per process text drop shadows cache. We recommend
+  using a cache large enough to hold two screens worth of 8-bit textures. For instance, on a 1280x800 display, a full screen buffer uses about 1 MB, so the cache should be at least 2 MB.</td>
+</tr>
+<tr>
+
+
+  <td><code>ro.hwui.fbo_cache_size</code></td>
+  <td><code>integer</code></td>
+  <td><code>16</code></td>
+  <td>Defines the number of FBO names the renderer can hold in the cache at any given time.
+  We recommend keeping this number low.</td>
+</tr>
+
+<tr>
+  <td><code>ro.hwui.texture_cache_flush_rate</code></td>
+  <td><code>float</code></td>
+  <td><code>0.6</code></td>
+  <td>Defines the percentage of the texture cache to keep after a memory flush. Memory flushes are triggered when the system needs to reclaim memory across all applications. We recommend releasing about 50% of the cache in such situations.</td>
+</tr>
+<tr>
+  <td><code>ro.hwui.text_small_cache_width</code></td>
+  <td><code>integer</code></td>
+  <td><code>1024</code></td>
+  <td>Defines the width in pixels of the default font cache. The upper bound depends on how fast the GPU can upload textures.
+  We recommend using at least 1024 pixels but at most 2048 pixels. You should also use a power of two value.</td>
+</tr>
+<tr>
+  <td><code>ro.hwui.text_small_cache_height</code></td>
+  <td><code>integer</code></td>
+  <td><code>256</code></td>
+  <td>Defines the height in pixels of the default font cache. The upper bound depends on how fast the GPU can upload textures.
+  We recommend using at least 256 pixels but at most 1024 pixels. </td>
+</tr>
+<tr>
+  <td><code>ro.hwui.text_large_cache_width</code></td>
+  <td><code>integer</code></td>
+  <td><code>2048</code></td>
+  <td>Defines the width in pixels of the large font cache. This cache is used for glyphs too large to fit in the default font cache. The upper bound depends on how fast the GPU can upload textures. We recommended using at least 2048 pixels but at most 4096 pixels. You should also use a power of two value.</td>
+</tr>
+
+<tr>
+  <td><code>ro.hwui.text_large_cache_height</code></td>
+  <td><code>integer</code></td>
+  <td><code>512</code></td>
+  <td>Defines the height in pixels of the large font cache. The large font cache is used for glyphs too large to fit in the default font cache. The upper bound depends on how fast the GPU can upload textures. 
+  We recommend using at least 512 pixels but at most 2048 pixels. You should also use a power of two value.</td>
+</tr>
+
+<tr>
+  <td><code>hwui.text_gamma_correction</code></td>
+  <td><code>string</code></td>
+  <td><code>lookup</code></td>
+  <td>Selects the text gamma correction technique. There are four possible choices:
+  <ul>
+   <li><code>lookup3</code>: A correction based on lookup tables. Gamma correction is different for black
+  and white text (see thresholds below).</li>
+
+   <li><code>lookup</code>: A correction based on a single lookup table.</li>
+
+    <li><code>shader3</code>: A correction applied by a GLSL shader. Gamma correction is different
+    for black and white text (see thresholds below).</li>
+
+    <li><code>shader</code>: A correction applied by a GLSL shader.</li>
+  </ul>
+  Lookup gamma corrections function best on GPUs with limited shader math. Shader gamma corrections are best to save memory. We recommend using the default <code>lookup</code> technique, which offers a good compromise in terms of quality, speed, and memory usage.
+</td>
+</tr>
+
+<tr>
+  <td><code>hwui.text_gamma</code></td>
+  <td><code>float</code></td>
+  <td><code>1.4</code></td>
+  <td>Defines the gamma value used for text gamma correction.
+  This value can be adjusted based on the display that is used by the device.</td>
+</tr>
+<tr>
+  <td><code>hwui.text_gamma.black_threshold</code></td>
+  <td><code>integer</code></td>
+  <td><code>64</code></td>
+  <td>Defines the luminance threshold below which black gamma correction is applied.
+  The value must be defined in the range 0..255.</td>
+</tr>
+<tr>
+  <td><code>hwui.text_gamma.white_threshold</code></td>
+  <td><code>integer</code></td>
+  <td><code>192</code></td>
+  <td>Defines the luminance threshold above which white gamma correction is applied.
+  The value must be defined in the range 0..255.</td>
+</tr>
+</table>
\ No newline at end of file