Docs: Porting new sensors content to site.

Bug: 17410055
Change-Id: Ice1a842e90f1c644b1bc94727383ad7c095cc650
diff --git a/src/devices/devices_toc.cs b/src/devices/devices_toc.cs
index 7fd0900..38134c4 100644
--- a/src/devices/devices_toc.cs
+++ b/src/devices/devices_toc.cs
@@ -167,18 +167,48 @@
           </div>
           <ul>
             <li>
-              <a href="<?cs var:toroot ?>devices/sensors/base_triggers.html">
-                <span class="en">Base sensors</span>
+              <a href="<?cs var:toroot ?>devices/sensors/sensor-stack.html">
+                <span class="en">Sensor stack</span>
               </a>
             </li>
             <li>
-              <a href="<?cs var:toroot ?>devices/sensors/composite_sensors.html">
-                <span class="en">Composite sensors</span>
+              <a href="<?cs var:toroot ?>devices/sensors/report-modes.html">
+                <span class="en">Reporting modes</span>
+              </a>
+            </li>
+            <li>
+              <a href="<?cs var:toroot ?>devices/sensors/suspend-mode.html">
+                <span class="en">Suspend mode</span>
+              </a>
+            </li>
+            <li>
+              <a href="<?cs var:toroot ?>devices/sensors/power-use.html">
+                <span class="en">Power consumption</span>
+              </a>
+            </li>
+            <li>
+              <a href="<?cs var:toroot ?>devices/sensors/interaction.html">
+                <span class="en">Interaction</span>
+              </a>
+            </li>
+            <li>
+              <a href="<?cs var:toroot ?>devices/sensors/hal-interface.html">
+                <span class="en">HAL interface</span>
               </a>
             </li>
             <li>
               <a href="<?cs var:toroot ?>devices/sensors/batching.html">
-                <span class="en">Batching results</span>
+                <span class="en">Batching</span>
+              </a>
+            </li>
+            <li>
+              <a href="<?cs var:toroot ?>devices/sensors/sensor-types.html">
+                <span class="en">Sensor types</span>
+              </a>
+            </li>
+            <li>
+              <a href="<?cs var:toroot ?>devices/sensors/versioning.html">
+                <span class="en">Version deprecation</span>
               </a>
             </li>
           </ul>
diff --git a/src/devices/sensors/base_triggers.jd b/src/devices/sensors/base_triggers.jd
deleted file mode 100644
index 81d2547..0000000
--- a/src/devices/sensors/base_triggers.jd
+++ /dev/null
@@ -1,152 +0,0 @@
-page.title=Base sensors and trigger modes
-@jd:body
-
-<!--
-    Copyright 2013 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>
-
-<h2 id="triggers">Trigger modes</h2>
-<p>Sensors can report events in different ways called trigger modes; each sensor 
-  type has one and only one trigger mode associated to it. Four trigger modes 
-  exist:</p>
-
-<h3 id="continuous">Continuous</h3>
-<p>Events are reported at a constant rate defined by setDelay(). Example sensors 
-  using the continuous trigger mode are accelerometers and gyroscopes.</p>
-
-<h3 id="on-change">On-change</h3>
-<p>Events are reported only if the sensor's value has changed. Activating the
-sensor also triggers an event, meaning the HAL must return an event immediately
-when an on-change sensor is activated. Example sensors using the on-change
-trigger mode are the step counter and proximity sensor types.</p>
-
-<p>Here is how the <code>period_ns</code> parameter affects setDelay(...) and
-batch(...). The <code>period_ns</code> parameter is used to set a lower limit
-to the reporting period, meaning the minimum time between consecutive events.
-Here is an example: If activating the step counter with period_ns = 10 seconds,
-walking for 1 minute, and then not walking for 1 minute, the events will
-be generated every 10 seconds during the first minute, and no event will be
-generated in the second minute.</p>
-
-<h3 id="one-shot">One-shot</h3>
-<p>Upon detection of an event, the sensor deactivates itself and then sends a 
-  single event. Order matters to avoid race conditions. No other event is sent 
-  until the sensor is reactivated. setDelay() is ignored. 
-<a
-href="{@docRoot}devices/sensors/composite_sensors.html#Significant">Significant
-motion</a> is an example of this kind of sensor.</p>
-<h3 id="special">Special</h3>
-<p>See the individual sensor type descriptions for details.</p>
-<h2 id="categories">Categories</h2>
-<p>Sensors fall into four primary categories:</p>
-<blockquote>
-  <p><em>Base</em> - records core measurements from which all other sensors are derived <br/>
-    <em>Activity</em> - detects user or device movement<br/>
-    <em>Attitude</em> - measures the orientation of the device<br/>
-    <em>Uncalibrated</em> - is identical to the corresponding base sensor except the 
-    dynamic calibration is reported separately rather than applied to the results</p>
-</blockquote>
-<h2 id="base">Base sensors</h2>
-<p>These sensor types are listed first because they are the fundamental sensors 
-  upon which all other sensor types are based.</p>
-<h3 id="Accelerometer">Accelerometer</h3>
-<p><em>Trigger-mode: Continuous<br/>
-Wake-up sensor: No</em></p>
-<p>All values are in SI units (m/s^2) and measure the acceleration of the device 
-  minus the force of gravity.</p>
-<p>Acceleration sensors return sensor events for all three axes at a constant rate 
-  defined by setDelay().</p>
-<ul>
-  <li>x: Acceleration on the x-axis</li>
-  <li>y: Acceleration on the y-axis</li>
-  <li>z: Acceleration on the z-axis</li>
-</ul>
-<p>Note the readings from the accelerometer include the acceleration due to gravity 
-  (which is opposite the direction of the gravity vector).</p>
-<p>Here are examples:</p>
-<ul>
-  <li>The norm of (x, y, z)  should be close to 0 when in free fall.</li>
-  <li>When the device lies flat on a table and is pushed on its left side toward the 
-    right, the x acceleration value is positive.</li>
-  <li>When the device lies flat on a table, the acceleration value is +9.81, which 
-    corresponds to the acceleration of the device (0 m/s^2) minus the force of 
-    gravity (-9.81 m/s^2).</li>
-  <li>When the device lies flat on a table and is pushed toward the sky, the 
-    acceleration value is greater than +9.81, which corresponds to the 
-    acceleration of the device (+A m/s^2) minus the force of gravity (-9.81 
-    m/s^2).</li>
-</ul>
-<h3 id="Ambient">Ambient temperature</h3>
-<p><em>Trigger-mode: On-change<br/>
-Wake-up sensor: No</em></p>
-<p>This sensor provides the ambient (room) temperature in degrees Celsius.</p>
-<h3 id="Geomagnetic">Geomagnetic field</h3>
-<p><em>Trigger-mode: Continuous<br/>
-Wake-up sensor: No</em></p>
-<p>All values are in micro-Tesla (uT) and measure the geomagnetic field in the X, Y 
-  and Z axis.</p>
-<p>Returned values include calibration mechanisms so the vector is aligned with the 
-  magnetic declination and heading of the earth's geomagnetic field.</p>
-<p>Magnetic field sensors return sensor events for all three axes at a constant 
-  rate defined by setDelay().</p>
-<h3 id="Gyroscope">Gyroscope</h3>
-<p><em>Trigger-mode: Continuous<br/>
-Wake-up sensor: No</em></p>
-<p>All values are in radians/second and measure the rate of rotation around the X, 
-  Y and Z axis.  The coordinate system is the same as is used for the acceleration 
-  sensor. Rotation is positive in the counter-clockwise direction (right-hand 
-  rule).</p>
-<p>That is, an observer looking from some positive location on the x, y or z axis 
-  at a device positioned on the origin would report positive rotation if the 
-  device appeared to be rotating counter clockwise. Note that this is the standard 
-  mathematical definition of positive rotation and does not agree with the 
-  definition of roll given elsewhere.</p>
-<p>The range should at least be 17.45 rad/s (ie: ~1000 deg/s).</p>
-<p>Automatic gyro-drift compensation is required.</p>
-<h3 id="Light">Light</h3>
-<p><em>Trigger-mode: On-change<br/>
-Wake-up sensor: No</em></p>
-<p>The light sensor value is returned in SI lux units.</p>
-<h3 id="Proximity">Proximity</h3>
-<p><em>Trigger-mode: On-change<br/>
-Wake-up sensor: Yes</em></p>
-<p>Measures the distance from the sensor to the closest visible surface. As this is 
-  a wake-up sensor, it should wake up the SoC when it is running and detects a 
-  change in proximity. The distance value is measured in centimeters. Note that 
-  some proximity sensors only support a binary &quot;near&quot; or &quot;far&quot; measurement. In 
-  this case, the sensor should report its maxRange value in the &quot;far&quot; state and a 
-  value less than maxRange in the &quot;near&quot; state.</p>
-<p>To ensure the applications have the time to receive the event before the 
-  application processor goes back to sleep, the driver must hold a &quot;timeout wake 
-  lock&quot; for 200 milliseconds for every wake-up sensor. That is, the application 
-  processor should not be allowed to go back to sleep in the 200 milliseconds 
-  following a wake-up interrupt.</p>
-<h3 id="Pressure">Pressure</h3>
-<p><em>Trigger-mode: Continuous<br/>
-Wake-up sensor: No</em></p>
-<p>The pressure sensor uses a barometer to return the atmospheric pressure in 
-  hectopascal (hPa).</p>
-<h3 id="humidity">Relative humidity</h3>
-<p><em>Trigger-mode: On-change<br/>
-Wake-up sensor: No</em></p>
-<p>A relative humidity sensor measures relative ambient air humidity and returns a 
-  value in percent.</p>
diff --git a/src/devices/sensors/batching.jd b/src/devices/sensors/batching.jd
index 405df88..4986f6a 100644
--- a/src/devices/sensors/batching.jd
+++ b/src/devices/sensors/batching.jd
@@ -1,8 +1,8 @@
-page.title=Batching sensor results
+page.title=Batching
 @jd:body
 
 <!--
-    Copyright 2013 The Android Open Source Project
+    Copyright 2014 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.
@@ -24,178 +24,196 @@
   </div>
 </div>
 
-<h2 id="Why">Why batch?</h2>
-<p>This page presents the specificities of Batch mode and the expected behaviors
-  of sensors while in batch mode. Batching can enable significant power savings by 
-  preventing the application processor from waking up to receive each event. Instead, these 
-  events can be grouped and processed together.</p>
-<h2 id="batch-function">batch(int handle, int flags, int64_t period_ns, int64_t
-  max_report_latency)</h2>
-<p>Enabling batch mode for a given sensor sets the delay between events.
-  <code>max_report_latency</code> sets the maximum time by which events can be delayed and
-  batched together before being reported to the applications. A value of zero 
-  disables batch mode for the given sensor. The <code>period_ns</code> parameter is equivalent
-  to calling setDelay() -- this function both enables or disables the batch mode 
-  AND sets the event's period in nanoseconds. See setDelay() for a detailed 
-  explanation of the <code>period_ns</code> parameter.</p>
-<p>In non-batch mode, all sensor events must be reported as soon as they are 
-  detected. For example, an accelerometer activated at 50Hz will trigger 
-  interrupts 50 times per second.<br/>
-  While in batch mode, sensor events do not need to be reported as soon as they 
-  are detected. They can be temporarily stored and reported in batches, as long as 
-  no event is delayed by more than <code>maxReportingLatency</code> nanoseconds. That is, all events 
-  since the previous batch are recorded and returned at once. This reduces the 
-  amount of interrupts sent to the SoC and allows the SoC to switch to a lower 
-  power mode (idle) while the sensor is capturing and batching data.</p>
-<p>setDelay() is not affected and it behaves as usual. <br/>
-  <br/>
-  Each event has a timestamp associated with it. The timestamp must be accurate 
-  and correspond to the time at which the event physically happened.</p>
-<p>Batching does not modify the behavior of poll(): batches from different sensors 
-  can be interleaved and split. As usual, all events from the same sensor are 
-  time-ordered.</p>
-<h2 id="Suspend">Behavior outside of suspend mode</h2>
-<p>These are the power modes of the application processor: on, idle, and suspend. 
-  The sensors behave differently in each of these modes. As you would imagine, on 
-  mode is when the application processor is running. Idle mode is a medium power mode 
-  where the application processor is powered but doesn't perform any tasks.
-  Suspend is a low-power mode where the application processor is not powered. The
-  power consumption of the device in this mode is usually 100 times less than in the On
-  mode.</p>
-<p>When the SoC is awake (not in suspend mode), events must be reported in batches 
-  at least every maxReportingLatency. No event shall be dropped or lost. If internal 
-  hardware FIFOs fill up before the maxReportingLatency, then events are reported at that 
-  point to ensure no event is lost.</p>
-<h2 id="Normal">Normal behavior in suspend mode</h2>
-<p>By default, batch mode doesn't significantly change the interaction with suspend 
-  mode. That is, sensors must continue to allow the SoC to go into suspend mode 
-  and sensors must stay active to fill their internal FIFO. In this mode, when the 
-  FIFO fills up, it shall wrap around and behave like a circular buffer, 
-  overwriting older events.<br/>
-  <br/>
-  As soon as the SoC comes out of suspend mode, a batch is produced with as much 
-as the recent history as possible, and batch operation resumes as usual.</p>
-<p>The behavior described above allows applications to record the recent history of 
-  a set of sensor types while keeping the SoC in suspend. It also allows the 
-  hardware to not have to rely on a wake-up interrupt line.</p>
-<h2 id="WAKE_UPON_FIFO_FULL">WAKE_UPON_FIFO_FULL behavior in suspend mode</h2>
-<p>There are cases, however, where an application cannot afford to lose any events, 
-  even when the device goes into suspend mode.</p>
-<p>For a given rate, if a sensor has the capability to store at least 10 seconds 
-  worth of events in its FIFO and is able to wake up the SoC, it can implement an 
-  optional secondary mode: the <code>WAKE_UPON_FIFO_FULL</code> mode.</p>
-<p>The caller will set the <code>SENSORS_BATCH_WAKE_UPON_FIFO_FULL</code> flag to activate this
-  mode. If the sensor does not support this mode, batch() will fail when the flag 
-  is set.</p>
-<p>In batch mode, and only when the flag
-<code>SENSORS_BATCH_WAKE_UPON_FIFO_FULL</code> is
-  set and supported, the specified sensor must be able to wake-up the SoC and be
-  able to buffer at least 10 seconds worth of the requested sensor events.</p>
-<p>When running with the <code>WAKE_UPON_FIFO_FULL</code> flag set, no events can be lost. When
-  the FIFO is getting full, the sensor must wake up the SoC from suspend and 
-  return a batch before the FIFO fills-up.</p>
-<p>Depending on the device, it might take a few milliseconds for the SoC to 
-  entirely come out of suspend and start flushing the FIFO. Enough head room must 
-  be allocated in the FIFO to allow the device to entirely come out of suspend 
-  without the FIFO overflowing (no events shall be lost).</p>
-<p>Implementing the <code>WAKE_UPON_FIFO_FULL</code> mode is optional. If the hardware cannot
-  support this mode, or if the physical FIFO is so small that the device would 
-  never be allowed to go into suspend for at least 10 seconds, then this function 
-  <strong>must</strong> fail when the flag
-<code>SENSORS_BATCH_WAKE_UPON_FIFO_FULL</code> is set, regardless
-  of the value of the maxReportingLatency parameter.</p>
-<h2 id="Implementing">Implementing batching</h2>
-<p>Batch mode, if supported, should happen at the hardware level, typically using 
-  hardware FIFOs. In particular, it SHALL NOT be implemented in the HAL, as this 
-  would be counter productive. The goal here is to save significant amounts of 
-  power. Batching should be implemented without the aid of the SoC, which should
-  be allowed to be in suspend mode during batching.</p>
-<p>In some implementations, events from several sensors can share the same physical 
-  FIFO. In that case, all events in the FIFO can be sent and processed by the HAL 
-  as soon as one batch must be reported.</p>
+<h2 id="what_is_batching">What is batching?</h2>
+<p>“Batching” refers to storing sensor events in a hardware FIFO before reporting
+  them through the <a href="hal-interface.html">HAL</a> instead of reporting them immediately.</p>
+<p>Batching can enable significant power savings by preventing the SoC from waking
+  up to receive each event. Instead, the events can be grouped and processed
+  together. </p>
+<p>The bigger the FIFOs, the more power can be saved. Implementing batching is an
+  exercise of trading off hardware memory for reduced power consumption.</p>
+<p>Batching happens when a sensor possesses a hardware FIFO
+  (<code>sensor_t.fifoMaxEventCount &gt; 0</code>) and we are in one of two situations:</p>
+<ul>
+  <li> <code>max_report_latency &gt; 0</code>, meaning the sensor events for this specific sensor can
+    be delayed up to <code>max_report_latency</code> before being reported through the HAL. </li>
+  <li> or the SoC is in suspend mode and the sensor is a non-wake-up sensor, meaning
+    events must be stored while waiting for the SoC to wake up. </li>
+</ul>
+<p>See the paragraph on the <a
+  href="hal-interface.html#batch_sensor_flags_sampling_period_maximum_report_latency">HAL
+  batch function</a> for more details.</p>
+<p>The opposite of batching is the continuous operation, where events are not
+  buffered, meaning they are reported immediately. Continuous operation
+  corresponds to:</p>
+<ul>
+  <li> when <code>max_report_latency = 0</code> and the events can be delivered to the application,
+    meaning
+    <ul>
+      <li> the SoC is awake </li>
+      <li> or the sensor is a wake-up sensor </li>
+    </ul>
+  </li>
+  <li> or when the sensor doesn’t have a hardware FIFO (<code>sensor_t.fifoMaxEventCount =
+    0</code>), in which case
+    <ul>
+      <li> the events are reported if the SoC is awake or the sensor is a wake-up sensor </li>
+      <li> the events are lost when the SoC is asleep and the sensor is not a wake-up
+        sensor </li>
+    </ul>
+  </li>
+</ul>
+<h2 id="wake-up_fifos_and_non-wake-up_fifos">Wake-up FIFOs and non-wake-up FIFOs</h2>
+<p>Sensor events from <a href="suspend-mode.html#wake-up_sensors">wake-up
+  sensors</a> must be stored into a wake-up FIFO. There can be one wake-up FIFO
+  per sensor, or, more commonly, one big shared wake-up FIFO where events from all wake-up
+  sensors are interleaved. Other options are also possible, with for example some
+  wake-up sensors having a dedicated FIFO, and the rest of the wake-up sensors
+  all sharing the same one.</p>
+<p>Similarly, sensor events from <a
+  href="suspend-mode.html#non-wake-up_sensors">non-wake-up sensors</a> must be
+  stored into a non-wake-up FIFOs, and there can be one or several
+  non-wake-up FIFOs.</p>
+<p>In all cases, wake-up sensor events and non-wake-up sensor events cannot be
+  interleaved into the same FIFO. Wake-up events go in wake-up FIFOs, and
+  non-wake-up events go in non-wake-up FIFOs.</p>
+<p>For the wake-up FIFO, the “one big shared FIFO” design provides the best power
+  benefits. For the non-wake-up FIFO, there is no preference between the “one big
+  shared FIFO” and “several small reserved FIFOs”. See <a
+  href="#fifo_allocation_priority">FIFO allocation priority</a> for suggestions
+  on how to dimension each FIFO.</p>
+<h2 id="behavior_outside_of_suspend_mode">Behavior outside of suspend mode</h2>
+<p>When the SoC is awake (not in suspend mode), the events can be stored
+  temporarily in their FIFO, as long as they are not delayed by more than
+  <code>max_report_latency</code>.</p>
+<p>As long as the SoC doesn’t enter the suspend mode, no event shall be dropped or
+  lost. If internal hardware FIFOs is getting full before <code>max_report_latency</code>
+  elapsed, then events are reported at that point to ensure that no event is
+  lost.</p>
+<p>If several sensors share the same FIFO and the <code>max_report_latency</code> of one of
+  them elapses, all events from the FIFO are reported, even if the
+  <code>max_report_latency</code> of the other sensors didn’t elapse yet. The general goal is
+  to reduce the number of times batches of events must be reported, so as soon as
+  one event must be reported, all events from all sensors can be reported.</p>
 <p>For example, if the following sensors are activated:</p>
 <ul>
-  <li>accelerometer batched with <code>maxReportingLatency</code> = 20s</li>
-  <li>gyroscope batched with <code>maxReportingLatency</code> = 5s</li>
+  <li> accelerometer batched with <code>max_report_latency</code> = 20s </li>
+  <li> gyroscope batched with <code>max_report_latency</code> = 5s </li>
 </ul>
-<p>Then the accelerometer batches can be reported at the same time the gyroscope 
-  batches are reported (every 5 seconds).<br/>
-  <br/>
-  Batch mode can be enabled or disabled at any time, in particular while the 
-  specified sensor is already enabled; and this shall not result in the loss of 
+<p>Then the accelerometer batches can be reported at the same time the gyroscope
+  batches are reported (every 5 seconds), even if the accelerometer and the
+  gyroscope do not share the same FIFO.</p>
+<h2 id="behavior_in_suspend_mode">Behavior in suspend mode</h2>
+<p>Batching is particularly beneficial when wanting to collect sensor data in the
+  background without keeping the SoC awake. Because the sensor drivers and HAL
+  implementation are not allowed to hold a wake-lock*, the SoC can enter the
+  suspend mode even while sensor data is being collected.</p>
+<p>The behavior of sensors while the SoC is suspended depends on whether the
+  sensor is a wake-up sensor. See <a
+href="suspend-mode.html#wake-up_sensors">Wake-up sensors</a> for some
+details.</p>
+<p>When a non-wake-up FIFO fills up, it must wrap around and behave like a
+  circular buffer, overwriting older events: the new events replace the old ones.
+  <code>max_report_latency</code> has no impact on non-wake-up FIFOs while in suspend mode.</p>
+<p>When a wake-up FIFO fills up, or when the <code>max_report_latency</code> of one of the
+  wake-up sensor elapsed, the hardware must wake up the SoC and report the data.</p>
+<p>In both cases (wake-up and non-wake-up), as soon as the SoC comes out of
+  suspend mode, a batch is produced with the content of all FIFOs, even if
+  <code>max_report_latency</code> of some sensors didn’t elapse yet. This minimizes the risk
+  of having to wake-up the SoC again soon if it goes back to suspend. Hence, it
+  minimizes power consumption.</p>
+<p>*One notable exception of drivers not being allowed to hold a wake lock is when
+  a wake-up sensor with <a href="report-modes.html#continuous">continuous
+  reporting mode</a> is activated with <code>max_report_latency</code> &lt; 1
+  second. In that case, the driver can hold a wake lock because the SoC would
+  anyway not have the time to enter the suspend mode, as it would be awoken by
+  a wake-up event before reaching the suspend mode.</p>
+<h2 id="precautions_to_take_when_batching_wake-up_sensors">Precautions to take when batching wake-up sensors</h2>
+<p>Depending on the device, it might take a few milliseconds for the SoC to
+  entirely come out of suspend and start flushing the FIFO. Enough head room must
+  be allocated in the FIFO to allow the device to entirely come out of suspend
+  without the wake-up FIFO overflowing. No events shall be lost, and the
+  <code>max_report_latency</code> must be respected.</p>
+<h2 id="precautions_to_take_when_batching_non-wake-up_on-change_sensors">Precautions to take when batching non-wake-up on-change sensors</h2>
+<p>On-change sensors only generate events when the value they are measuring is
+  changing. If the measured value changes while the SoC is in suspend mode,
+  applications expect to receive an event as soon as the SoC wakes up. Because of
+  this, batching of <a href="suspend-mode.html#non-wake-up_sensors">non-wake-up</a> on-change sensor events must be performed carefully if the sensor shares its
+  FIFO with other sensors. The last event generated by each on-change sensor must
+  always be saved outside of the shared FIFO so it can never be overwritten by
+  other events. When the SoC wakes up, after all events from the FIFO have been
+  reported, the last on-change sensor event must be reported.</p>
+<p>Here is a situation we want to avoid:</p>
+<ol>
+  <li> An application registers to the non-wake-up step counter (on-change) and the
+    non-wake-up accelerometer (continuous), both sharing the same FIFO </li>
+  <li> The application receives a step counter event “step_count=1000 steps” </li>
+  <li> The SoC goes to suspend </li>
+  <li> The user walks 20 steps, causing step counter and accelerometer events to be
+    interleaved, the last step counter event being “step_count = 1020 steps” </li>
+  <li> The user doesn’t move for a long time, causing accelerometer events to continue
+    accumulating in the FIFO, eventually overwriting every step_count event in the
+    shared FIFO </li>
+  <li> SoC wakes up and all events from the FIFO are sent to the application </li>
+  <li> The application receives only accelerometer events and thinks that the user
+    didn’t walk (bad!) </li>
+</ol>
+<p>By saving the last step counter event outside of the FIFO, the HAL can report
+  this event when the SoC wakes up, even if all other step counter events were
+  overwritten by accelerometer events. This way, the application receives
+  “step_count = 1020 steps” when the SoC wakes up.</p>
+<h2 id="implementing_batching">Implementing batching</h2>
+<p>Batching cannot be emulated in software. It must be implemented entirely in
+  hardware, with hardware FIFOs. In particular, it cannot be implemented on the
+  SoC, for example in the HAL implementation, as this would be
+  counter-productive. The goal here is to save significant amounts of power.
+  Batching must be implemented without the aid of the SoC, which should be
+  allowed to be in suspend mode during batching.</p>
+<p><code>max_report_latency</code> can be modified at any time, in particular while the
+  specified sensor is already enabled; and this shall not result in the loss of
   events.</p>
-<h2 id="fifo-allocation">FiFo allocation priority</h2>
-<p>On platforms in which hardware FIFO size is limited, the system designers may 
-  have to choose how much FIFO to reserve for each sensor. To help with this 
-  choice, here is a list of applications made possible when batching is 
+<h2 id="fifo_allocation_priority">FIFO allocation priority</h2>
+<p>On platforms in which hardware FIFO size is limited, the system designers may
+  have to choose how much FIFO to reserve for each sensor. To help with this
+  choice, here is a list of applications made possible when batching is
   implemented on the different sensors.</p>
-<p><strong>High value: Low power pedestrian dead reckoning</strong><br/>
-  Target batching time: 20 seconds to 1 minute<br/>
-  Sensors to batch:<br/>
-  - Step detector<br/>
-  - Rotation vector or game rotation vector at 5Hz<br/>
-  Gives us step and heading while letting the SoC go to Suspend.<br/>
-  <br/>
-  <strong>High value: Medium power activity/gesture recognition</strong><br/>
-  Target batching time: 3 seconds<br/>
-  Sensors to batch: accelerometer between 20Hz and 50Hz<br/>
-  Allows recognizing arbitrary activities and gestures without having<br/>
-  to keep the SoC fully awake while the data is collected.<br/>
-  <br/>
-  <strong>Medium-high value: Interrupt load reduction</strong><br/>
-  Target batching time: &lt; 1 second<br/>
-  Sensors to batch: any high frequency sensor.<br/>
-  If the gyroscope is set at 240Hz, even batching just 10 gyro events can<br/>
-  reduce the number of interrupts from 240/second to 24/second.<br/>
-  <br/>
-  <strong>Medium value: Continuous low frequency data collection</strong><br/>
-  Target batching time: &gt; 1 minute<br/>
-  Sensors to batch: barometer, humidity sensor, other low frequency<br/>
-  sensors.<br/>
-  Allows creating monitoring applications at low power.<br/>
-  <br/>
-  <strong>Medium value: Continuous full-sensors collection</strong><br/>
-  Target batching time: &gt; 1 minute<br/>
-  Sensors to batch: all, at high frequencies<br/>
-  Allows full collection of sensor data while leaving the SoC in<br/>
-  suspend mode. Only to consider if fifo space is not an issue.<br/>
-  <br/>
-  In each of the cases above, if <code>WAKE_UPON_FIFO_FULL</code> is implemented, the<br/>
-  applications might decide to let the SoC go to suspend, allowing for even<br/>
-  more power savings.</p>
-<h2 id="Dry-run">Dry run</h2>
-<p>If the flag <code>SENSORS_BATCH_DRY_RUN</code> is set, this function returns without
-  modifying the batch mode or the event period and has no side effects, but 
-  returns errors as usual (as it would if this flag was not set). This flag is 
-  used to check if batch mode is available for a given configuration, in 
-  particular for a given sensor at a given rate.</p>
-<h2 id="Return-values">Return values</h2>
-<p>Because sensors must be independent, the return value must not depend on the 
-  state of the system (whether another sensor is on or not), nor on whether the 
-  flag <code>SENSORS_BATCH_DRY_RUN</code> is set (in other words, if a batch call with
-  <code>SENSORS_BATCH_DRY_RUN</code> is successful, the same call without
-<code>SENSORS_BATCH_DRY_RUN</code>
-  must succeed as well).</p>
-<p>If successful, 0 is returned.</p>
-<p>If the specified sensor doesn't support batch mode, -EINVAL is returned.<br/>
-  If the specified sensor's trigger-mode is one-shot, -EINVAL is returned.</p>
-<p>If WAKE UPON FIFO_FULL is specified and the specified sensor's internal FIFO is 
-  too small to store at least 10 seconds worth of data at the given rate, -EINVAL 
-  is returned. Note that as stated above, this has to be determined at compile 
-  time and not based on the state of the system.</p>
-<p>If some other constraints above cannot be satisfied, -EINVAL is returned.<br/>
-  <br/>
-  Note: The <code>maxReportingLatency</code> parameter when &gt; 0 has no impact on
-  whether this function succeeds or fails.<br/>
-  <br/>
-  If <code>maxReportingLatency</code> is set to 0, this function must succeed.</p>
-<h2 id="Supporting-docs">Supporting documentation</h2>
-<p><a href="http://developer.android.com/guide/topics/sensors/index.html">Developer - Location and Sensors 
-  APIs</a></p>
-<p><a href="http://developer.android.com/guide/topics/sensors/sensors_overview.html">Developer - Sensors 
-  Overview</a></p>
-<p><a href="http://developer.android.com/reference/android/hardware/Sensor.html">Sensors SDK API 
-  reference</a></p>
-<p><a href="{@docRoot}devices/reference/sensors_8h_source.html">Android 
-  Hardware Abstraction Layer - sensors.h</a></p>
-<p><a href="http://developer.android.com/reference/android/hardware/SensorManager.html">SensorManager</a></p>
+<h3 id="high_value_low_power_pedestrian_dead_reckoning">High value: Low power pedestrian dead reckoning</h3>
+<p>Target batching time: 1 to 10 minutes</p>
+<p>Sensors to batch:</p>
+<ul>
+  <li> Wake-up Step detector </li>
+  <li> Wake-up Game rotation vector at 5Hz </li>
+  <li> Wake-up Barometer at 5Hz </li>
+  <li> Wake-up Uncalibrated Magnetometer at 5Hz </li>
+</ul>
+<p>Batching this data allows performing pedestrian dead reckoning while letting
+  the SoC go to suspend.</p>
+<h3 id="high_value_medium_power_intermittent_activity_gesture_recognition">High value: Medium power intermittent activity/gesture recognition</h3>
+<p>Target batching time: 3 seconds</p>
+<p>Sensors to batch: Non-wake-up Accelerometer at 50Hz</p>
+<p>Batching this data allows periodically recognizing arbitrary activities and
+  gestures without having to keep the SoC awake while the data is collected.</p>
+<h3 id="medium_value_medium_power_continuous_activity_gesture_recognition">Medium value: Medium power continuous activity/gesture recognition</h3>
+<p>Target batching time: 1 to 3 minutes</p>
+<p>Sensors to batch: Wake-up Accelerometer at 50Hz</p>
+<p>Batching this data allows continuously recognizing arbitrary activities and
+  gestures without having to keep the SoC awake while the data is collected.</p>
+<h3 id="medium-high_value_interrupt_load_reduction">Medium-high value: Interrupt load reduction</h3>
+<p>Target batching time: &lt; 1 second</p>
+<p>Sensors to batch: any high frequency sensor, usually non-wake-up.</p>
+<p>If the gyroscope is set at 240Hz, even batching just 10 gyro events can reduce
+  the number of interrupts from 240/second to 24/second.</p>
+<h3 id="medium_value_continuous_low_frequency_data_collection">Medium value: Continuous low frequency data collection</h3>
+<p>Target batching time: 1 to 10 minutes</p>
+<p>Sensors to batch:</p>
+<ul>
+  <li> Wake-up barometer at 1Hz, </li>
+  <li> Wake-up humidity sensor at 1Hz </li>
+  <li> Other low frequency wake-up sensors at similar rates </li>
+</ul>
+<p>Allows creating monitoring applications at low power.</p>
+<h3 id="medium-low_value_continuous_full-sensors_collection">Medium-low value: Continuous full-sensors collection</h3>
+<p>Target batching time: 1 to 10 minutes</p>
+<p>Sensors to batch: all wake-up sensors, at high frequencies</p>
+<p>Allows full collection of sensor data while leaving the SoC in suspend mode.
+  Only to consider if FIFO space is not an issue.</p>
diff --git a/src/devices/sensors/composite_sensors.jd b/src/devices/sensors/composite_sensors.jd
deleted file mode 100644
index d3fbed2..0000000
--- a/src/devices/sensors/composite_sensors.jd
+++ /dev/null
@@ -1,534 +0,0 @@
-page.title=Composite sensors
-@jd:body
-
-<!--
-    Copyright 2013 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>
-
-<h2 id="summary">Composite sensor type summary</h2>
-
-<p>The following table lists the composite sensor types and their categories, 
-underlying base sensors, and trigger modes. Certain base sensors are required of 
-each sensor for accuracy. Using other tools to approximate results should be 
-avoided as they will invariably provide a poor user experience.</p>
-
-<p>When there is no gyroscope on the device, and
-only when there is no gyroscope, you may implement the rotation vector and
-other composite sensors without using the gyroscope.</p>
-<table>
-  <tr>
-<th>Sensor type</th>
-<th>Category</th>
-<th>Underlying base sensor</th>
-<th>Trigger mode</th>
-</tr>
-<tr>
-<td>Game rotation vector</td>
-<td>Attitude</td>
-<td>Accelerometer, Gyroscope
-MUST NOT USE Magnetometer</td>
-<td>Continuous</td>
-</tr>
-<tr>
-<td>Geomagnetic rotation vector (Magnetometer) <img src="images/battery_icon.png" width="20" height="20" alt="Low power sensor" /></td>
-<td>Attitude</td>
-<td>Accelerometer, Magnetometer
-NOT Gyroscope</td>
-<td>Continuous</td>
-</tr>
-<tr>
-<td>Gravity</td>
-<td>Attitude</td>
-<td>Accelerometer, Gyroscope</td>
-<td>Continuous</td>
-</tr>
-<tr>
-<td>Gyroscope uncalibrated</td>
-<td>Uncalibrated</td>
-<td>Gyroscope</td>
-<td>Continuous</td>
-</tr>
-<tr>
-<td>Linear acceleration</td>
-<td>Activity</td>
-<td>Accelerometer, Gyroscope
-AND Magnetometer</td>
-<td>Continuous</td>
-</tr>
-<tr>
-<td>Magnetic field uncalibrated</td>
-<td>Uncalibrated</td>
-<td>Magnetometer</td>
-<td>Continuous</td>
-</tr>
-<tr>
-<td>Orientation</td>
-<td>Attitude</td>
-<td>Accelerometer, Magnetometer
-PREFERRED Gyroscope</td>
-<td>Continuous</td>
-</tr>
-<tr>
-<td>Rotation vector</td>
-<td>Attitude</td>
-<td>Accelerometer, Gyroscope
-AND Magnetometer</td>
-<td>Continuous</td>
-</tr>
-<tr>
-<td>Significant motion
-  <img src="images/battery_icon.png" width="20" height="20" alt="Low power sensor" /></td>
-<td>Activity</td>
-<td>Accelerometer (or another as long as very low power)</td>
-<td>One-shot</td>
-</tr>
-<tr>
-<td>Step counter
-  <img src="images/battery_icon.png" width="20" height="20" alt="Low power sensor" /></td>
-<td>Activity</td>
-<td>Accelerometer</td>
-<td>On-
-change</td>
-</tr>
-<tr>
-<td>Step detector
-  <img src="images/battery_icon.png" width="20" height="20" alt="Low power sensor" /></td>
-<td>Activity</td>
-<td>Accelerometer</td>
-<td>Special</td>
-</tr>
-</table>
-
-<p><img src="images/battery_icon.png" alt="low power icon"/> = 
-Low power sensor</p>
-
-<h2 id="Activity">Activity sensors</h2>
-
-<h3 id="acceleration">Linear acceleration</h3>
-
-<p><em>Underlying base sensor(s): Accelerometer, Gyroscope AND Magnetometer<br/>
-Trigger-mode: Continuous<br/>
-Wake-up sensor: No</em></p>
-
-<p>Indicates the linear acceleration of the device in device coordinates, not 
-including gravity. The output is conceptually:<br/>
-output of <code>TYPE_ACCELERATION</code> minus output of
-<code>TYPE_GRAVITY</code>.</p>
-
-<p>Readings on all axes should be close to 0 when the device is immobile. Units are 
-m/s^2. The coordinate system is the same as is used for the acceleration sensor.</p>
-
-<h3 id="Significant">Significant motion</h3>
-
-<p><em>Underlying base sensor(s): Accelerometer (or another as long as low power)<br/>
-Trigger-mode: One-shot<br/>
-Wake-up sensor: Yes</em></p>
-
-<p>Significant motion allows a device to stay in suspend and idle modes longer and 
-save power. It does this by relying upon last known location until the device 
-experiences "significant motion." Such a movement would trigger on mode and a 
-call to retrieve new location.</p>
-
-<p>Here is an example on how the platform can use significant motion to save
-power. When users are moving, their locations are updated frequently. After some period 
-of inactivity, significant motion presumes the device is static and stops 
-seeking location updates. It instead registers the last known location as valid. 
-The device is then allowed to go into idle and then suspend mode.</p>
-
-<p>This sensor exists to save power by keeping the SoC in suspend mode when the 
-device is at rest. A sensor of this type triggers an event each time significant 
-motion is detected and automatically disables itself. The only allowed value to 
-return is 1.0.</p>
-
-<p>A significant motion is a motion that might lead to a change in the user 
-location. Examples of such significant motions are:</p>
-
-<ul>
-<li>walking or biking</li>
-<li>sitting in a moving car, coach or train</li>
-</ul>
-
-<p>Examples of situations that should not trigger significant motion:</p>
-
-<ul>
-<li>phone in pocket and person is not moving</li>
-<li>phone is on a table and the table shakes a bit due to nearby traffic or 
-washing machine</li>
-</ul>
-
-<p>This sensor makes a tradeoff for power consumption that may result in a small 
-amount of false negatives. This is done for a few reasons:</p>
-
-<ol>
-<li>The goal of this sensor is to save power.</li>
-<li>Triggering an event when the user is not moving (false positive) is costly in 
-terms of power, so it should be avoided.</li>
-<li>Not triggering an event when the user is moving (false negative) is 
-acceptable as long as it is not done repeatedly. If the user has been walking 
-for 10 seconds, not triggering an event within those 10 seconds is not 
-acceptable.</li>
-</ol>
-
-<p>To ensure the applications have the time to receive the significant motion event 
-before the application processor goes back to sleep, the driver must hold a 
-"timeout wake lock" for 200 milliseconds for every wake-up sensor. That is, the 
-application processor should not be allowed to go back to sleep in the 200 
-milliseconds following a wake-up interrupt.</p>
-
-<p><strong>Important</strong>: This sensor is very different from the other types in that it
-must work when the screen is off without the need for holding a partial wake 
-lock (other than the timeout wake lock) and MUST allow the SoC to go into 
-suspend. When significant motion is detected, the sensor must awaken the SoC and 
-the event be reported.</p>
-
-<p>If a particular device cannot support this mode of operation, then this sensor 
-type <strong>must not</strong> be reported by the HAL. ie: it is not acceptable to "emulate" 
-this sensor in the HAL.</p>
-
-<p>When the sensor is not activated, it must also be deactivated in the hardware; 
-it must not wake up the SoC anymore, even in case of significant motion.</p>
-
-<p>setDelay() has no effect and is ignored.</p>
-
-<p>Once a "significant motion" event is returned, a sensor of this type must 
-disable itself automatically, as if activate(..., 0) had been called.</p>
-
-<h3 id="detector">Step detector</h3>
-
-<p><em>Underlying base sensor(s): Accelerometer<br/>
-Trigger-mode: Special<br/>
-Wake-up sensor: No</em></p>
-
-<p>A sensor of this type triggers an event each time a step is taken by the user. 
-The only allowed value to return is 1.0 and an event is generated for each step. 
-Like with any other event, the timestamp indicates when the event (here the 
-step) occurred. This corresponds to when the foot hit the ground, generating a 
-high variation in acceleration.</p>
-
-<p>Compared to the step counter, the step detector should have a lower latency 
-(less than 2 seconds). Both the step detector and the step counter detect when 
-the user is walking, running and walking up the stairs. They should not trigger 
-when the user is biking, driving or in other vehicles.</p>
-
-<p>While this sensor operates, it shall not disrupt any other sensors, in 
-particular, the accelerometer; it might very well be in use.</p>
-
-<p>This sensor must be low power. That is, if the step detection cannot be done in 
-hardware, this sensor should not be defined. Also, when the step detector is 
-activated and the accelerometer is not, only steps should trigger interrupts 
-(not accelerometer data).</p>
-
-<p>setDelay() has no impact on this sensor type.</p>
-
-<h3 id="counter">Step counter</h3>
-
-<p><em>Underlying base sensor(s): Accelerometer<br/>
-Trigger-mode: On-change<br/>
-Wake-up sensor: No</em></p>
-
-<p>A sensor of this type returns the number of steps taken by the user since the 
-last reboot while activated. The value is returned as a uint64_t and is reset to 
-zero only on a system reboot.</p>
-
-<p>The timestamp of the event is set to the time when the last step for that event 
-was taken.<br/>
-See the <a href="#detector">Step detector</a> 
-sensor type for the signification of the time of a step.</p>
-
-<p>Compared to the step detector, the step counter can have a higher latency (less 
-than 10 seconds).  Thanks to this latency, this sensor has a high accuracy; the 
-step count after a full day of measures should be within 10% of the real step 
-count. Both the step detector and the step counter detect when the user is 
-walking, running and walking up the stairs. They should not trigger when the 
-user is biking, driving or in other vehicles.</p>
-
-<p><strong>Important note</strong>: This sensor is different from other types in that it must work 
-when the screen is off without the need of holding a partial wake-lock and MUST 
-allow the SoC to go into suspend.</p>
-
-<p>While in suspend mode this sensor must stay active. No events are reported 
-during that time but steps continue to be accounted for; an event will be 
-reported as soon as the SoC resumes if the timeout has expired.</p>
-
-<p>In other words, when the screen is off and the device is allowed to go into 
-suspend mode, it should not be woken up, regardless of the setDelay() value. But 
-the steps shall continue to be counted.</p>
-
-<p>The driver must however ensure the internal step count never overflows. The 
-minimum size of the hardware's internal counter shall be 16 bits. (This 
-restriction is here to avoid too frequent wake-ups when the delay is very 
-large.) It is allowed in this situation to wake the SoC up so the driver can do 
-the counter maintenance.</p>
-
-<p>While this sensor operates, it shall not disrupt any other sensors, in 
-particular, the accelerometer; it might very well be in use.</p>
-
-<p>If a particular device cannot support these modes of operation, then this sensor 
-type <strong>must not</strong> be reported by the HAL. ie: it is not acceptable to "emulate" 
-this sensor in the HAL.</p>
-
-<p>This sensor must be low power. That is, if the step detection cannot be done in 
-hardware, this sensor should not be defined. Also, when the step counter is 
-activated and the accelerometer is not, only steps should trigger interrupts 
-(not accelerometer data).</p>
-
-<h2 id="Attitude">Attitude sensors</h2>
-
-<h3 id="Rotation-vector">Rotation vector</h3>
-
-<p><em>Underlying base sensor(s): Accelerometer, Gyroscope AND Magnetometer<br/>
-Trigger-mode: Continuous<br/>
-Wake-up sensor: No</em></p>
-
-<p>The rotation vector symbolizes the orientation of the device relative to the 
-East-North-Up coordinates frame. It is usually obtained by integration of 
-accelerometer, gyroscope and magnetometer readings.</p>
-
-<p>The East-North-Up coordinate system is defined as a direct orthonormal basis 
-where:</p>
-
-<ul>
-<li>X points east and is tangential to the ground.</li>
-<li>Y points north and is tangential to the ground.</li>
-<li>Z points towards the sky and is perpendicular to the ground.</li>
-</ul>
-
-<p>The orientation of the phone is represented by the rotation necessary to align 
-the East-North-Up coordinates with the phone's coordinates. That is, applying 
-the rotation to the world frame (X,Y,Z) would align them with the phone 
-coordinates (x,y,z).</p>
-
-<p>The rotation can be seen as rotating the phone by an angle theta around an axis 
-rot_axis to go from the reference (East-North-Up aligned) device orientation to 
-the current device orientation.</p>
-
-<p>The rotation is encoded as the four (reordered) components of a unit quaternion:</p>
-
-<ul>
-<li><code>sensors_event_t.data[0]</code> = rot_axis.x*sin(theta/2)</li>
-<li><code>sensors_event_t.data[1]</code> = rot_axis.y*sin(theta/2)</li>
-<li><code>sensors_event_t.data[2]</code> = rot_axis.z*sin(theta/2)</li>
-<li><code>sensors_event_t.data[3]</code> = cos(theta/2)</li>
-</ul>
-
-<p>Where:</p>
-
-<ul>
-<li>rot_axis.x,y,z are the North-East-Up coordinates of a unit length vector 
-representing the rotation axis</li>
-<li>theta is the rotation angle</li>
-</ul>
-
-<p>The quaternion must be of norm 1. (It is a unit quaternion.) Failure to ensure 
-this will cause erratic client behaviour.</p>
-
-<p>In addition, this sensor reports an estimated heading accuracy:<br/>
-<code>sensors_event_t.data[4]</code> = estimated_accuracy (in radians)</p>
-
-<p>The heading error must be less than estimated_accuracy 95% of the time. This 
-sensor must use a gyroscope and an accelerometer as main orientation change 
-input.</p>
-
-<p>This sensor should also include magnetometer input to make up for gyro drift, 
-but it cannot be implemented using only a magnetometer.</p>
-
-<h3 id="Game-rotation">Game rotation vector</h3>
-
-<p><em>Underlying base sensor(s): Accelerometer, Gyroscope NOT Magnetometer<br/>
-Trigger-mode: Continuous<br/>
-Wake-up sensor: No</em></p>
-
-<p>Similar to the <a href="#Rotation-vector">rotation vector</a> sensor but not using 
-the geomagnetic field. Therefore the Y axis doesn't point north but instead to 
-some other reference. That reference is allowed to drift by the same order of 
-magnitude as the gyroscope drifts around the Z axis.</p>
-
-<p>This sensor does not report an estimated heading accuracy:<br/>
-<code>sensors_event_t.data[4]</code> is reserved and should be set to 0</p>
-
-<p>In an ideal case, a phone rotated and returned to the same real-world 
-orientation should report the same game rotation vector (without using the 
-earth's geomagnetic field).</p>
-
-<p>This sensor must be based on a gyroscope. It cannot be implemented using a 
-magnetometer.</p>
-
-<h3 id="Gravity">Gravity</h3>
-
-<p><em>Underlying base sensor(s): Accelerometer, Gyroscope NOT Magnetometer<br/>
-Trigger-mode: Continuous<br/>
-Wake-up sensor: No</em></p>
-
-<p>The gravity output of this sensor indicates the direction and magnitude of 
-gravity in the device's coordinates. Units are m/s^2. On Earth, the magnitude is 
-9.8 m/s^2. The coordinate system is the same as is used for the acceleration 
-sensor. When the device is at rest, the output of the gravity sensor should be 
-identical to that of the accelerometer.</p>
-
-<h3 id="Magnetometer">Geomagnetic rotation vector (Magnetometer)</h3>
-
-<p><em>Underlying base sensor(s): Accelerometer, Magnetometer NOT Gyroscope<br/>
-Trigger-mode: Continuous<br/>
-Wake-up sensor: No</em></p>
-
-<p>This sensor is similar to the <a href="#Rotation-vector">rotation vector</a> sensor 
-but using a magnetometer instead of a gyroscope.</p>
-
-<p>This sensor must be based on a magnetometer. It cannot be implemented using a 
-gyroscope, and gyroscope input cannot be used by this sensor.</p>
-
-<p>Just like the rotation vector sensor, this sensor reports an estimated heading 
-accuracy:<br/>
-<code>sensors_event_t.data[4]</code> = estimated_accuracy (in radians)</p>
-
-<p>The heading error must be less than estimated_accuracy 95% of the time.</p>
-
-<p>See the <a href="#Rotation-vector">rotation vector</a> sensor description for more 
-details.</p>
-
-<h3 id="Orientation">Orientation</h3>
-
-<p><em>Underlying base sensor(s): Accelerometer, Magnetometer PREFERRED Gyroscope<br/>
-Trigger-mode: Continuous<br/>
-Wake-up sensor: No</em></p>
-
-<p><strong>Note</strong>: This is an older sensor type that has been 
-deprecated in the Android SDK although not yet in the HAL. It has been replaced 
-by the rotation vector sensor, which is more clearly defined, requires a 
-gyroscope, and therefore provides more accurate results. Use the rotation vector 
-sensor over the orientation sensor whenever possible.</p>
-
-<p>The orientation sensor tracks the attitude of the device. All values are angles 
-in degrees. Orientation sensors return sensor events for all three axes at a 
-constant rate defined by setDelay().</p>
-
-<ul>
-<li>azimuth: angle between the magnetic north direction and the Y axis, around <br />
-the Z axis (0&lt;=azimuth&lt;360). 0=North, 90=East, 180=South, 270=West</li>
-<li>pitch: Rotation around X axis (-180&lt;=pitch&lt;=180), with positive values when 
-the z-axis moves toward the y-axis.</li>
-<li>roll: Rotation around Y axis (-90&lt;=roll&lt;=90), with positive values when the 
-x-axis moves towards the z-axis.</li>
-</ul>
-
-<p>Please note, for historical reasons the roll angle is positive in the clockwise 
-direction. (Mathematically speaking, it should be positive in the 
-counter-clockwise direction):</p>
-
-<div class="figure" style="width:264px">
-  <img src="images/axis_positive_roll.png" alt="Depiction of orientation relative to a device" height="253" />
-  <p class="img-caption">
-    <strong>Figure 2.</strong> Orientation relative to a device.
-  </p>
-</div>
-
-<p>This definition is different from yaw, pitch and roll used in aviation where the 
-X axis is along the long side of the plane (tail to nose).</p>
-
-<h2 id="Uncalibrated">Uncalibrated sensors</h2>
-
-<p>Uncalibrated sensors provide more raw results and may include some bias but also 
-contain fewer "jumps" from corrections applied through calibration. Some 
-applications may prefer these uncalibrated results as smoother and more 
-reliable. For instance, if an application is attempting to conduct its own 
-sensor fusion, introducing calibrations can actually distort results.</p>
-
-<h3 id="Gyroscope-uncalibrated">Gyroscope uncalibrated</h3>
-
-<p><em>Underlying base sensor(s): Gyroscope<br/>
-Trigger-mode: Continuous<br/>
-Wake-up sensor: No</em></p>
-
-<p>The uncalibrated gyroscope is useful for post-processing and melding orientation 
-data. All values are in radians/second and measure the rate of rotation around 
-the X, Y and Z axis. An estimation of the drift on each axis is reported as 
-well.</p>
-
-<p>No gyro-drift compensation shall be performed. Factory calibration and 
-temperature compensation should still be applied to the rate of rotation 
-(angular speeds).</p>
-
-<p>The coordinate system is the same as is used for the acceleration sensor. 
-Rotation is positive in the counter-clockwise direction (right-hand rule). That 
-is, an observer looking from some positive location on the x, y or z axis at a 
-device positioned on the origin would report positive rotation if the device 
-appeared to be rotating counter clockwise. Note that this is the standard 
-mathematical definition of positive rotation and does not agree with the 
-definition of roll given elsewhere.</p>
-
-<p>The range should at least be 17.45 rad/s (ie: ~1000 deg/s).</p>
-
-<p>Content of an uncalibrated_gyro event (units are rad/sec):</p>
-
-<ul>
-<li>x_uncalib : angular speed (w/o drift compensation) around the X axis</li>
-<li>y_uncalib : angular speed (w/o drift compensation) around the Y axis</li>
-<li>z_uncalib : angular speed (w/o drift compensation) around the Z axis</li>
-<li>x_bias : estimated drift around X axis in rad/s</li>
-<li>y_bias : estimated drift around Y axis in rad/s</li>
-<li>z_bias : estimated drift around Z axis in rad/s</li>
-</ul>
-
-<p>If the implementation is not able to estimate the drift, then this sensor <strong>must 
-not</strong> be reported by this HAL. Instead, the regular 
-<a href="{@docRoot}devices/sensors/base_triggers.html#Gyroscope">Gyroscope</a> sensor is used without drift compensation.</p>
-
-<p>If this sensor is present, then the corresponding Gyroscope sensor must be 
-present and both must return the same <code>sensor_t::name</code> and
-<code>sensor_t::vendor</code>.</p>
-
-<h3 id="Magnetic-field-uncalibrated">Magnetic field uncalibrated</h3>
-
-<p><em>Underlying base sensor(s): Magnetometer<br/>
-Trigger-mode: Continuous<br/>
-Wake-up sensor: No</em></p>
-
-<p>Similar to <a href="{@docRoot}devices/sensors/base_triggers.html#Geomagnetic">Geomagnetic field</a> sensor, but the hard 
-iron calibration is reported separately instead of being included in the 
-measurement. The uncalibrated magnetometer allows the system to handle bad hard 
-iron estimation.</p>
-
-<p>Factory calibration and temperature compensation should still be applied to the 
-"uncalibrated" measurement. Separating away the hard iron calibration estimation 
-allows the system to better recover from bad hard iron estimation.</p>
-
-<p>All values are in micro-Tesla (uT) and measure the ambient magnetic field in the 
-X, Y and Z axis. Assumptions that the magnetic field is due to the Earth's poles 
-should be avoided.</p>
-
-<p>The uncalibrated_magnetic event contains three fields for uncalibrated measurement: x_uncalib, y_uncalib, z_uncalib. Each is a component of the 
-measured magnetic field, with soft iron and temperature compensation applied, 
-but not hard iron calibration. These values should be continuous (no 
-re-calibration should cause a jump).</p>
-
-<p>The uncalibrated_magnetic event contains three fields for hard iron bias estimates: x_bias, y_bias, z_bias. Each field is a component of the estimated 
-hard iron calibration. They represent the offsets to apply to the calibrated 
-readings to obtain uncalibrated readings (x_uncalib ~= x_calibrated + x_bias). 
-These values are expected to jump as soon as the estimate of the hard iron 
-changes, and they should be stable the rest of the time.</p>
-
-<p>If this sensor is present, then the corresponding Geomagnetic field sensor must 
-be present and both must return the same  <code>sensor_t::name</code> and
-<code>sensor_t::vendor</code>.</p>
-
-<p>See the <a href="{@docRoot}devices/sensors/base_triggers.html#Geomagnetic">geomagnetic field</a> sensor description for more 
-information.<br/></p>
diff --git a/src/devices/sensors/hal-interface.jd b/src/devices/sensors/hal-interface.jd
new file mode 100644
index 0000000..5c232fa
--- /dev/null
+++ b/src/devices/sensors/hal-interface.jd
@@ -0,0 +1,367 @@
+page.title=HAL interface
+@jd:body
+
+<!--
+    Copyright 2014 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 HAL interface, declared in <a href="{@docRoot}devices/reference/sensors_8h.html">sensors.h</a>, represents the interface between the Android <a href="sensor-stack.html#framework">framework</a> and the hardware-specific software. A HAL implementation must define each
+  function declared in sensors.h. The main functions are:</p>
+<ul>
+  <li><code>get_sensors_list</code> - Returns the list of all sensors. </li>
+  <li><code>activate</code> - Starts or stops a sensor. </li>
+  <li><code>batch</code> - Sets a sensor’s parameters such as sampling frequency and maximum
+    reporting latency. </li>
+  <li><code>setDelay</code> - Used only in HAL version 1.0. Sets the sampling frequency for a
+    given sensor. </li>
+  <li><code>flush</code> - Flushes the FIFO of the specified sensor and reports a flush complete
+    event when this is done. </li>
+  <li><code>poll</code> - Returns available sensor events. </li>
+</ul>
+<p>The implementation must be thread safe and allow these functions to be called
+  from different threads.</p>
+<p>The interface also defines several types used by those functions. The main
+  types are:</p>
+<ul>
+  <li><code>sensors_module_t</code></li>
+  <li><code>sensors_poll_device_t</code></li>
+  <li><code>sensor_t</code></li>
+  <li><code>sensors_event_t</code></li>
+</ul>
+<p>In addition to the sections below, see <a href="{@docRoot}devices/reference/sensors_8h.html">sensors.h</a> for more information on those types.</p>
+<h2 id="get_sensors_list_list">get_sensors_list(list)</h2>
+<pre>int (*get_sensors_list)(struct sensors_module_t* module, struct sensor_t
+  const** list);</pre>
+<p>Provides the list of sensors implemented by the HAL. See <a href="#sensor_t">sensor_t</a> for details on how the sensors are defined.</p>
+<p>The order in which the sensors appear in the list is the order in which the
+  sensors will be reported to the applications. Usually, the base sensors appear
+  first, followed by the composite sensors.</p>
+<p>If several sensors share the same sensor type and wake-up property, the first
+  one in the list is called the “default” sensor. It is the one returned by
+  <code>getDefaultSensor(int sensorType, bool wakeUp)</code>.</p>
+<p>This function returns the number of sensors in the list.</p>
+<h2 id="activate_sensor_true_false">activate(sensor, true/false)</h2>
+<pre>int (*activate)(struct sensors_poll_device_t *dev, int sensor_handle, int
+  enabled);</pre>
+<p>Activates or deactivates a sensor.</p>
+<p><code>sensor_handle</code> is the handle of the sensor to activate/deactivate. A sensor’s
+  handle is defined by the <code>handle</code> field of its <a href="#sensor_t">sensor_t</a> structure.</p>
+<p><code>enabled</code> is set to 1 to enable or 0 to disable the sensor.</p>
+<p>One-shot sensors deactivate themselves automatically upon receiving an event,
+  and they must still accept to be deactivated through a call to <code>activate(...,
+  enabled=0)</code>.</p>
+<p>Non-wake-up sensors never prevent the SoC from going into suspend mode; that
+  is, the HAL shall not hold a partial wake-lock on behalf of applications.</p>
+<p>Wake-up sensors, when delivering events continuously, can prevent the SoC from
+  going into suspend mode, but if no event needs to be delivered, the partial
+  wake-lock must be released.</p>
+<p>If <code>enabled</code> is 1 and the sensor is already activated, this function is a no-op
+  and succeeds.</p>
+<p>If <code>enabled</code> is 0 and the sensor is already deactivated, this function is a no-op
+  and succeeds.</p>
+<p>This function returns 0 on success and a negative error number otherwise.</p>
+<h2 id="batch_sensor_flags_sampling_period_maximum_report_latency">batch(sensor, flags, sampling period, maximum report latency)</h2>
+<pre>
+int (*batch)(
+     struct sensors_poll_device_1* dev,
+     int sensor_handle,
+     int flags,
+     int64_t sampling_period_ns,
+     int64_t max_report_latency_ns);
+</pre>
+<p>Sets a sensor’s parameters, including <a href="#sampling_period_ns">sampling frequency</a> and <a href="#max_report_latency_ns">maximum report latency</a>. This function can be called while the sensor is activated, in which case it
+  must not cause any sensor measurements to be lost: Transitioning from one
+  sampling rate to the other cannot cause lost events, nor can transitioning from
+  a high maximum report latency to a low maximum report latency.</p>
+<p><code>sensor_handle</code> is the handle of the sensor to configure.</p>
+<p><code>flags</code> is currently unused.</p>
+<p><code>sampling_period_ns</code> is the sampling period at which the sensor should run, in
+  nanoseconds. See <a href="#sampling_period_ns">sampling_period_ns</a> for more details.</p>
+<p><code>max_report_latency_ns</code> is the maximum time by which events can be delayed before
+  being reported through the HAL, in nanoseconds. See the <a href="#max_report_latency_ns">max_report_latency_ns</a> paragraph for more details.</p>
+<p>This function returns 0 on success and a negative error number otherwise.</p>
+<h3 id="sampling_period_ns">sampling_period_ns</h3>
+<p>What the <code>sampling_period_ns</code> parameter means depends on the specified sensor's
+  reporting mode:</p>
+<ul>
+  <li> Continuous: <code>sampling_period_ns</code> is the sampling rate, meaning the rate at which
+    events are generated. </li>
+  <li> On-change: <code>sampling_period_ns</code> limits the sampling rate of events, meaning
+    events are generated no faster than every <code>sampling_period_ns</code> nanoseconds. There
+    might be periods longer than <code>sampling_period_ns</code> where no event is generated if
+    the measured values do not change for long periods. See <a
+    href="report-modes.html#on-change">on-change</a> reporting mode for more
+    details. </li>
+  <li> One-shot: <code>sampling_period_ns</code> is ignored. It has no effect. </li>
+  <li> Special: See the specific <a href="sensor-types.html">sensor type
+  descriptions</a> for details on how <code>sampling_period_ns</code> is used
+  for special sensors. </li>
+</ul>
+<p>See <a href="report-modes.html">Reporting modes</a> for more information
+  about the impact of <code>sampling_period_ns</code> in the different modes.</p>
+<p>For continuous and on-change sensors,</p>
+<ul>
+  <li> if <code>sampling_period_ns</code> is less than
+    <code>sensor_t.minDelay</code>, then the HAL implementation must silently
+    clamp it to <code>max(sensor_t.minDelay, 1ms)</code>. Android
+    does not support the generation of events at more than 1000Hz. </li>
+  <li> if <code>sampling_period_ns</code> is greater than
+    <code>sensor_t.maxDelay</code>, then the HAL
+    implementation must silently truncate it to <code>sensor_t.maxDelay</code>. </li>
+</ul>
+<p>Physical sensors sometimes have limitations on the rates at which they can run
+  and the accuracy of their clocks. To account for this, we allow the actual
+  sampling frequency to differ from the requested frequency, as long as it
+  satisfies the requirements in the table below.</p>
+<table>
+  <tr>
+    <th><p>If the requested frequency is</p></th>
+    <th><p>Then the actual frequency must be</p></th>
+  </tr>
+  <tr>
+    <td><p>below min frequency (&lt;1/maxDelay)</p></td>
+    <td><p>between 90% and 110% of the min frequency</p></td>
+  </tr>
+  <tr>
+    <td><p>between min and max frequency</p></td>
+    <td><p>between 90% and 220% of the requested frequency</p></td>
+  </tr>
+  <tr>
+    <td><p>above max frequency (&gt;1/minDelay)</p></td>
+    <td><p>between 90% and 110% of the max frequency</p>
+      <p>and below 1100Hz</p></td>
+  </tr>
+</table>
+<p>Note that this contract is valid only at the HAL level, where there is always a
+  single client. At the SDK level, applications might get different rates, due to
+  the multiplexing happening in the Framework. See <a
+  href="sensor-stack.html#framework">Framework</a> for more details.</p>
+<h3 id="max_report_latency_ns">max_report_latency_ns</h3>
+<p><code>max_report_latency_ns</code> sets the maximum time in nanoseconds, by which events can
+  be delayed and stored in the hardware FIFO before being reported through the
+  HAL while the SoC is awake.</p>
+<p>A value of zero signifies that the events must be reported as soon as they are
+  measured, either skipping the FIFO altogether, or emptying the FIFO as soon as
+  one event from this sensor is present in it.</p>
+<p>For example, an accelerometer activated at 50Hz with <code>max_report_latency_ns=0</code>
+  will trigger interrupts 50 times per second when the SoC is awake.</p>
+<p>When <code>max_report_latency_ns&gt;0</code>, sensor events do not need to be reported as soon
+  as they are detected. They can be temporarily stored in the hardware FIFO and
+  reported in batches, as long as no event is delayed by more than
+  max_report_latency_ns nanoseconds. That is, all events since the previous batch
+  are recorded and returned at once. This reduces the amount of interrupts sent
+  to the SoC and allows the SoC to switch to a lower power mode (idle) while the
+  sensor is capturing and batching data.</p>
+<p>Each event has a timestamp associated with it. Delaying the time at which an
+  event is reported does not impact the event timestamp. The timestamp must be
+  accurate and correspond to the time at which the event physically happened, not
+  the time it is being reported. </p>
+<p>Allowing sensor events to be stored temporarily in the hardware FIFO does not
+  modify the behavior of <code>poll</code>: events from different sensors can be interleaved,
+  and as usual, all events from the same sensor are time-ordered.</p>
+<p>See <a href="batching.html">Batching</a> for more details on sensor
+batching, including behaviors in suspend mode and out of suspend mode.</p>
+<h2 id="setdelay_sensor_sampling_period">setDelay(sensor, sampling period)</h2>
+<pre>
+int (*setDelay)(
+     struct sensors_poll_device_t *dev,
+     int sensor_handle,
+     int64_t sampling_period_ns);
+</pre>
+<p>After HAL version 1.0, this function is deprecated and is never called.
+  Instead, the <code>batch</code> function is called to set the
+  <code>sampling_period_ns</code> parameter.</p>
+<p>In HAL version 1.0, setDelay was used instead of batch to set <a href="#sampling_period_ns">sampling_period_ns</a>.</p>
+<h2 id="flush_sensor">flush(sensor)</h2>
+<pre>int (*flush)(struct sensors_poll_device_1* dev, int sensor_handle);</pre>
+<p>Add a <a href="#metadata_flush_complete_events">flush complete event</a> to the end of the hardware FIFO for the specified sensor and flushes the FIFO;
+  those events are delivered as usual (i.e.: as if the maximum reporting latency
+  had expired) and removed from the FIFO.</p>
+<p>The flush happens asynchronously (i.e.: this function must return immediately).
+  If the implementation uses a single FIFO for several sensors, that FIFO is
+  flushed and the flush complete event is added only for the specified sensor.</p>
+<p>If the specified sensor has no FIFO (no buffering possible), or if the FIFO,
+  was empty at the time of the call, <code>flush</code> must still succeed and send a flush
+  complete event for that sensor. This applies to all sensors other than one-shot
+  sensors.</p>
+<p>When <code>flush</code> is called, even if a flush event is already in the FIFO for that
+  sensor, an additional one must be created and added to the end of the FIFO, and
+  the FIFO must be flushed. The number of <code>flush</code> calls must be
+  equal to the number of flush complete events created.</p>
+<p><code>flush</code> does not apply to <a href="report-modes.html#one-shot">one-shot</a>
+  sensors; if <code>sensor_handle</code> refers to a one-shot sensor,
+  <code>flush</code> must return <code>-EINVAL</code> and not generate any
+  flush complete metadata event.</p>
+<p>This function returns 0 on success, <code>-EINVAL</code> if the specified sensor is a
+  one-shot sensor or wasn’t enabled, and a negative error number otherwise.</p>
+<h2 id="poll">poll()</h2>
+<pre>int (*poll)(struct sensors_poll_device_t *dev, sensors_event_t* data, int
+  count);</pre>
+<p>Returns an array of sensor data by filling the <code>data</code> argument. This function
+  must block until events are available. It will return the number of events read
+  on success, or a negative error number in case of an error.</p>
+<p>The number of events returned in <code>data</code> must be less or equal to
+  the <code>count</code> argument. This function shall never return 0 (no event).</p>
+<h2 id="sequence_of_calls">Sequence of calls</h2>
+<p>When the device boots, <code>get_sensors_list</code> is called.</p>
+<p>When a sensor gets activated, the <code>batch</code> function will be called with the
+  requested parameters, followed by <code>activate(..., enable=1)</code>.</p>
+<p>Note that in HAL version 1_0, the order was the opposite: <code>activate</code> was called
+  first, followed by <code>set_delay</code>.</p>
+<p>When the requested characteristics of a sensor are changing while it is
+  activated, the <code>batch</code> function is called.</p>
+<p><code>flush</code> can be called at any time, even on non-activated sensors (in which case
+  it must return <code>-EINVAL</code>)</p>
+<p>When a sensor gets deactivated, <code>activate(..., enable=0)</code> will be called.</p>
+<p>In parallel to those calls, the <code>poll</code> function will be called repeatedly to
+  request data. <code>poll</code> can be called even when no sensors are activated.</p>
+<h2 id="sensors_module_t">sensors_module_t</h2>
+<p><code>sensors_module_t</code> is the type used to create the Android hardware module for the
+  sensors. The implementation of the HAL must define an object
+  <code>HAL_MODULE_INFO_SYM</code> of this type to expose the <a
+  href="#get_sensors_list_list">get_sensors_list</a> function. See the definition
+  of <code>sensors_module_t</code> in <a
+  href="{@docRoot}devices/reference/sensors_8h.html">sensors.h</a> and the
+  definition of <code>hw_module_t</code> for more information.</p>
+<h2 id="sensors_poll_device_t_sensors_poll_device_1_t">sensors_poll_device_t / sensors_poll_device_1_t</h2>
+<p><code>sensors_poll_device_1_t</code> contains the rest of the methods defined above:
+  <code>activate</code>, <code>batch</code>, <code>flush</code> and
+  <code>poll</code>. Its <code>common</code> field (of type <a
+  href="{@docRoot}devices/reference/structhw__device__t.html">hw_device_t</a>)
+  defines the version number of the HAL.</p>
+<h2 id="sensor_t">sensor_t</h2>
+<p><code>sensor_t</code> represents an <a href="index.html">Android sensor</a>. Here are some of its important fields:</p>
+<p><strong>name:</strong> A user-visible string that represents the sensor. This string often
+  contains the part name of the underlying sensor, the type of the sensor, and
+  whether it is a wake-up sensor. For example, “LIS2HH12 Accelerometer”,
+  “MAX21000 Uncalibrated Gyroscope”, “BMP280 Wake-up Barometer”, “MPU6515 Game
+  Rotation Vector”</p>
+<p><strong>handle:</strong> The integer used to refer to the sensor when registering to it or
+  generating events from it.</p>
+<p><strong>type:</strong> The type of the sensor. See the explanation of sensor
+type in <a href="index.html">What are Android sensors?</a> for more details, and see <a
+href="sensor-types.html">Sensor types</a> for official sensor types. For
+non-official sensor types, <code>type</code> must start with <code>SENSOR_TYPE_DEVICE_PRIVATE_BASE</code></p>
+<p><strong>stringType:</strong> The type of the sensor as a string. When the sensor has an official
+  type, set to <code>SENSOR_STRING_TYPE_*</code>. When the sensor has a manufacturer specific
+  type, <code>stringType</code> must start with the manufacturer reverse domain name. For
+  example, a sensor (say a unicorn detector) defined by the
+  <em>Cool-product</em> team at Fictional-Company could use
+  <code>stringType=”com.fictional_company.cool_product.unicorn_detector”</code>.
+  The <code>stringType</code> is used to uniquely identify non-official sensors types. See <a
+  href="{@docRoot}devices/reference/sensors_8h.html">sensors.h</a> for more
+  information on types and string types.</p>
+<p><strong>requiredPermission:</strong> A string representing the permission that applications must
+  possess to see the sensor, register to it and receive its data. An empty string
+  means applications do not require any permission to access this sensor. Some
+  sensor types like the <a href="sensor-types.html#heart_rate">heart rate
+  monitor</a> have a mandatory <code>requiredPermission</code>. All sensors
+  providing sensitive user information (such as the heart rate) must be protected by a permission.</p>
+<p><strong>flags:</strong> Flags for this sensor, defining the sensor’s reporting mode and whether
+  the sensor is a wake-up sensor or not. For example, a one-shot wake-up sensor
+  will have <code>flags = SENSOR_FLAG_ONE_SHOT_MODE | SENSOR_FLAG_WAKE_UP</code>. The bits of
+  the flag that are not used in the current HAL version must be left equal to 0.</p>
+<p><strong>maxRange:</strong> The maximum value the sensor can report, in the same unit as the
+  reported values. The sensor must be able to report values without saturating
+  within <code>[-maxRange; maxRange]</code>. Note that this means the total range of the
+  sensor in the generic sense is <code>2*maxRange</code>. When the sensor reports values over
+  several axes, the range applies to each axis. For example, a “+/- 2g”
+  accelerometer will report <code>maxRange = 2*9.81 = 2g</code>.</p>
+<p><strong>resolution:</strong> The smallest difference in value that the sensor can measure.
+  Usually computed based on <code>maxRange</code> and the number of bits in the measurement.</p>
+<p><strong>power:</strong> The power cost of enabling the sensor, in milliAmps. This is nearly
+  always more that the power consumption reported in the datasheet of the
+  underlying sensor. See <a
+href="sensor-types.html#base_sensors_=_not_equal_to_physical_sensors">Base
+sensors != physical sensors</a> for more details and see <a
+href="power-use.html#power_measurement_process">Power measurement process</a> for details on
+how to measure the power consumption of a sensor. If the
+  sensor’s power consumption depends on whether the device is moving, the power
+  consumption while moving is the one reported in the <code>power</code> field.</p>
+<p><strong>minDelay:</strong> For continuous sensors, the sampling period, in microseconds,
+  corresponding to the fastest rate the sensor supports. See <a href="#sampling_period_ns">sampling_period_ns</a> for details on how this value is used. Beware that <code>minDelay</code> is expressed in
+  microseconds while <code>sampling_period_ns</code> is in nanoseconds. For on-change and
+  special reporting mode sensors, unless otherwise specified, <code>minDelay</code> must be 0.
+  For one-shot sensors, it must be -1.</p>
+<p><strong>maxDelay:</strong> For continuous and on-change sensors, the sampling period, in
+  microseconds, corresponding to the slowest rate the sensor supports. See <a href="#sampling_period_ns">sampling_period_ns</a> for details on how this value is used. Beware that <code>maxDelay</code> is expressed in
+  microseconds while <code>sampling_period_ns</code> is in nanoseconds. For special and
+  one-shot sensors, <code>maxDelay</code> must be 0.</p>
+<p><strong>fifoReservedEventCount:</strong> The number of events reserved for this sensor in the
+  hardware FIFO. If there is a dedicated FIFO for this sensor, then
+  <code>fifoReservedEventCount</code> is the size of this dedicated FIFO. If the FIFO is
+  shared with other sensors, <code>fifoReservedEventCount</code> is the size of the part of
+  the FIFO that is reserved for that sensor. On most shared-FIFO systems, and on
+  systems that do not have a hardware FIFO this value is 0.</p>
+<p><strong>fifoMaxEventCount:</strong> The maximum number of events that could be stored in the
+  FIFOs for this sensor. This is always greater or equal to
+  <code>fifoReservedEventCount</code>. This value is used to estimate how quickly the FIFO
+  will get full when registering to the sensor at a specific rate, supposing no
+  other sensors are activated. On systems that do not have a hardware FIFO,
+  <code>fifoMaxEventCount</code> is 0. See <a href="batching.html">Batching</a> for more details.</p>
+<p>For sensors with an official sensor type, some of the fields are overwritten by
+  the framework. For example, <a
+  href="sensor-types.html#accelerometer">accelerometer</a> sensors are forced to
+  have a continuous reporting mode, and <a
+  href="sensor-types.html#heart_rate">heart rate</a> monitors are forced to be
+  protected by the <code>SENSOR_PERMISSION_BODY_SENSORS</code> permission.</p>
+<h2 id="sensors_event_t">sensors_event_t</h2>
+<p>Sensor events generated by Android sensors and reported through the <a
+href="#poll">poll</a> function are of <code>type sensors_event_t</code>. Here are some
+important fields of <code>sensors_event_t</code>:</p>
+<p>version: must be <code>sizeof(struct sensors_event_t)</code></p>
+<p><strong>sensor:</strong> The handle of the sensor that generated the event, as defined by
+  <code>sensor_t.handle</code>.</p>
+<p><strong>type:</strong> The sensor type of the sensor that generated the event, as defined by
+  <code>sensor_t.type</code>.</p>
+<p><strong>timestamp:</strong> The timestamp of the event in nanoseconds. This is the time the
+  event happened (a step was taken, or an accelerometer measurement was made),
+  not the time the event was reported. <code>timestamp</code> must be synchronized with the
+  <code>elapsedRealtimeNano</code> clock, and in the case of continuous sensors, the jitter
+  must be small. Timestamp filtering is sometimes necessary to satisfy the CDD
+  requirements, as using only the SoC interrupt time to set the timestamps
+  causes too high jitter, and using only the sensor chip time to set the
+  timestamps can cause de-synchronization from the
+  <code>elapsedRealtimeNano</code> clock, as the sensor clock drifts.</p>
+<p>data and overlapping fields: The values measured by the sensor. The meaning and
+  units of those fields are specific to each sensor type. See <a
+  href="{@docRoot}devices/reference/sensors_8h.html">sensors.h</a> and the
+  definition of the different <a href="sensor-types.html">Sensor types</a> for a
+  description of the data fields. For some sensors, the accuracy of the
+  readings is also reported as part of the data, through a <code>status</code> field. This
+  field is only piped through for those select sensor types, appearing at the SDK
+  layer as an accuracy value. For those sensors, the fact that the status field
+  must be set is mentioned in their <a href="sensor-types.html">sensor type</a> definition.</p>
+<h3 id="metadata_flush_complete_events">Metadata flush complete events</h3>
+<p>Metadata events have the same type as normal sensor events:
+  <code>sensors_event_meta_data_t = sensors_event_t</code>. They are returned together with
+  other sensor events through poll. They possess the following fields:</p>
+<p>version must be <code>META_DATA_VERSION</code></p>
+<p>type must be <code>SENSOR_TYPE_META_DATA</code></p>
+<p>sensor, reserved, and <strong>timestamp </strong>must be 0</p>
+<p>meta_data.what contains the metadata type for this event. There is currently a
+  single valid metadata type: <code>META_DATA_FLUSH_COMPLETE</code>.</p>
+<p><code>META_DATA_FLUSH_COMPLETE</code> events represent the completion of the flush of a
+  sensor FIFO. When <code>meta_data.what=META_DATA_FLUSH_COMPLETE</code>, <code>meta_data.sensor</code>
+  must be set to the handle of the sensor that has been flushed. They are
+  generated when and only when <code>flush</code> is called on a sensor. See the section on
+  the <a href="#flush_sensor">flush</a> function for more information.</p>
diff --git a/src/devices/sensors/images/sensor_layers.png b/src/devices/sensors/images/sensor_layers.png
new file mode 100644
index 0000000..7d1ca25
--- /dev/null
+++ b/src/devices/sensors/images/sensor_layers.png
Binary files differ
diff --git a/src/devices/sensors/index.jd b/src/devices/sensors/index.jd
index e5fa438..6f21488 100644
--- a/src/devices/sensors/index.jd
+++ b/src/devices/sensors/index.jd
@@ -1,8 +1,8 @@
-page.title=Sensors HAL overview
+page.title=Sensors
 @jd:body
 
 <!--
-    Copyright 2013 The Android Open Source Project
+    Copyright 2014 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.
@@ -24,238 +24,138 @@
   </div>
 </div>
 
-<h2 id="intro">Introduction</h2>
-<p><a href="http://developer.android.com/guide/topics/sensors/sensors_overview.html">Android 
-  sensors</a> give applications access to a mobile device's underlying base sensor(s): 
-  accelerometer, gyroscope, and magnetometer. Manufacturers develop the drivers 
-  that define additional composite sensor types from those base sensors. For 
-  instance, Android offers both calibrated and uncalibrated gyroscopes, a 
-  geomagnetic rotation vector and a game rotation vector. This variety gives 
-  developers some flexibility in tuning applications for battery life optimization 
-  and accuracy.</p>
-<p>The <a href="{@docRoot}devices/reference/sensors_8h_source.html">Sensors
-Hardware Abstraction Layer (HAL) API</a> is the interface between the hardware drivers 
-and the Android framework; the <a href="http://developer.android.com/reference/android/hardware/Sensor.html">Sensors Software Development Kit (SDK) 
-  API</a> is the interface between the Android framework and the Java applications. Please note, 
-  the Sensors HAL API described in this documentation is not identical to the 
-  Sensors SDK API described on <a href="http://developer.android.com/reference/android/hardware/Sensor.html">developer.android.com</a>. 
-  For example, some sensors that are deprecated in the SDK may still exist in the 
-  HAL, and vice versa.</p>
-<p>Similarly, audio recorders, Global Positioning System (GPS) devices, and 
-  accessory (pluggable) sensors are not supported by the Android Sensors HAL API 
-  described here. This API covers sensors that are physically part of the device 
-  only. Please see the <a href="{@docRoot}devices/audio.html">Audio</a>, <a href="{@docRoot}devices/reference/gps_8h.html">Location </a><a href="{@docRoot}devices/reference/gps_8h.html">Strategies</a>, 
-  and the <a href="{@docRoot}accessories/index.html">Accessories</a> section 
-  for information on those devices.</p>
-<p>Application framework<br/>
-  At the application framework level is the app code, which utilizes the <a href="http://developer.android.com/reference/android/hardware/package-summary.html">android.hardware</a> APIs to interact with the sensors hardware. Internally, this code calls 
-  corresponding JNI glue classes to access the native code that interacts with the 
-  sensors hardware.</p>
-<p>JNI<br/>
-  The JNI code associated with <a href="http://developer.android.com/reference/android/hardware/package-summary.html">android.hardware</a> is located in the frameworks/base/core/jni/ directory. This code calls the lower 
-  level native code to obtain access to the sensor hardware.</p>
-<p>Native framework<br/>
-  The native framework is defined in <code>frameworks/native/</code> and provides a native
-  equivalent to the <a href="http://developer.android.com/reference/android/hardware/package-summary.html">android.hardware</a> package. The native framework calls the Binder IPC proxies to obtain access to 
-  sensor-specific services.</p>
-<p>Binder IPC<br/>
-  The Binder IPC proxies facilitate communication over process boundaries.</p>
-<p>HAL<br/>
-  The Hardware Abstraction Layer (HAL) defines the standard interface that sensor 
-  services call into and that you must implement to have your sensor hardware 
-  function correctly. The sensor HAL interfaces are located in 
-  <code>hardware/libhardware/include/hardware</code>. See <a
-href="http://source.android.com/devices/reference/sensors_8h.html">sensors.h</a> for
-additional details.</p>
-<p>Kernel Driver<br/>
-  The sensors driver interacts with the hardware and your implementation of the 
-  HAL. The HAL is driver-agnostic.</p>
-<h3 id="axis-def">Sensor axis definition</h3>
-<p>The sensor event values are expressed in a specific frame that is static 
-  relative to the phone. This API is relative only to the NATURAL orientation of 
-  the screen. In other words:</p>
-<ul>
-  <li>the axes are not swapped when the device's screen orientation changes.</li>
-  <li>higher level services <em>may</em> perform this transformation.</li>
-</ul>
-<div class="figure" style="width:269px"> <img src="http://developer.android.com/images/axis_device.png" alt="Coordinate system relative to device for Sensor
-    API" height="225" />
-  <p class="img-caption"> <strong>Figure 1.</strong> Coordinate system (relative to a device) that's used by the Sensor
-    API. </p>
-</div>
-<h3 id="accuracy">Accuracy</h3>
-<p>The sensors included by the manufacturer must be accurate and precise to meet
-the expectations of application developers. The sensors included in Android devices are 
-  tested for sensor interaction and accuracy as part of the <a href="{@docRoot}compatibility/index.html">Android Compatibility 
-    program</a> starting in the 
-  Android 4.4 release. Testing will continue to be improved in future releases. 
-  See the <em>Sensors</em> section of the Android Compatibility Definition Document (CDD) 
-  for the exact requirements.</p>
-<h3 id="power">Power consumption</h3>
-<p>Some defined sensor are higher power than others. Others are lower power by 
-  design and should be implemented as such with their processing done in the 
-  hardware. This means they should not require the application processor to be 
-  running. Here are the low-power sensors:</p>
-<ul>
-  <li><a href="{@docRoot}devices/sensors/composite_sensors.html#Magnetometer">Geomagnetic rotation vector</a></li>
-  <li><a href="{@docRoot}devices/sensors/composite_sensors.html#Significant">Significant motion</a></li>
-  <li><a href="{@docRoot}devices/sensors/composite_sensors.html#counter">Step counter</a></li>
-  <li><a href="{@docRoot}devices/sensors/composite_sensors.html#detector">Step detector</a></li>
-</ul>
-<p>They are accompanied by a low-power <img src="images/battery_icon.png"
-alt="low-power sensors"/>
-  icon in the <a href="{@docRoot}devices/sensors/composite_sensors.html#summary">Sensor summary</a> table. </p>
-<p>These sensor types cannot be implemented at high power as their primary benefit 
-  is low battery use. It is better to not implement a low-power sensor at all 
-  rather than implement it as high power.</p>
-<p>Composite low-power sensor types, such as the step detector, must have their 
-  processing conducted in the hardware; power use is much lower than if done in 
-  the software. Power use is low on small microprocessors and even lower still on 
-  application-specific integrated circuits (ASICs). A hardware implementation of 
-  composite sensor types can also make use of more raw sensor data and a better 
-  synchronization between sensors.</p>
-<h3 id="release">HAL release cycle</h3>
-<p>Functionality is tied to versions of the API. Android maintains two versions of 
-  the Sensors HAL API per release. For instance, if version 1 was the latest and 
-  version 1.1 is released, the version prior to 1 will no longer be supported upon 
-  that release. Only the two latest versions of the Sensors HAL API are supported.</p>
-<h2 id="interaction">Interaction</h2>
-<h3 id="concurrent">Concurrent running</h3>
-<p>Android sensors must work independently of one another. Activating one sensor 
-  shall not deactivate another sensor. Activating one shall not reduce the rate of 
-  another. This is a key element of compatibility testing.</p>
-<h3 id="suspend">Interaction with suspend mode</h3>
-<p>Unless otherwise noted, an enabled sensor shall not prevent the system on a chip 
-  (SoC) from going into suspend mode. It is the responsibility of applications to keep a 
-  partial <a href="http://developer.android.com/reference/android/os/PowerManager.WakeLock.html">wake 
-    lock</a> should they wish to receive sensor events while the screen is off. While in 
-  suspend mode, and unless otherwise noted (<a
-href="{@docRoot}devices/sensors/batching.html">batch</a> mode 
-  and sensor particularities), enabled sensors' events are lost.</p>
-<p>Note that conceptually, the sensor itself is not deactivated while in suspend 
-  mode. Instead, the data it returns is missing. The oldest data is dropped to 
-  accommodate the latest data. As soon as the SoC gets out of suspend mode, 
-  operations resume as normal.</p>
-<p>Most applications should either hold a wake lock to ensure the system doesn't go 
-  to suspend, or unregister from the sensors when they do not need them, unless 
-  batch mode is active. When batching, sensors must continue to fill their 
-  internal FIFO. (See the documentation of <a
-href="{@docRoot}devices/sensors/batching.html">batch</a> mode 
-  to learn how suspend interacts with batch mode.)</p>
-<p>Wake-up sensors are a notable exception to the above. Wake-up sensors must
-wake up the SoC to deliver events. They must still let the SoC go into suspend
-mode, but must also wake it up when an event is triggered.</p>
-<h3 id="fusion">Sensor fusion and virtual sensors</h3>
-<p>Many composite sensor types are or can be implemented as virtual sensors from 
-  underlying base sensors on the device. Examples of composite sensors types 
-  include the rotation vector sensor, orientation sensor, step detector and step 
-  counter.</p>
-<p>From the point of view of this API, these virtual sensors <strong>must</strong> appear as 
-  real, individual sensors. It is the responsibility of the driver and HAL to make 
-  sure this is the case.</p>
-<p>In particular, all sensors must be able to function concurrently. For example, 
-  if defining both an accelerometer and a step counter, then both must be able to 
-  work concurrently.</p>
-<h3 id="hal">HAL interface</h3>
-<p>These are the common sensor calls expected at the HAL level:</p>
-<ol>
-  <li><em>getSensorList()</em> - Gets the list of all sensors.</li>
-  <li><em>activate()</em> - Starts or stops the specified sensor.</li>
-  <li><em>batch()</em> - Sets parameters to group event data collection and optimize power use.</li>
-  <li><em>setDelay()</em> - Sets the event's period in 
-    nanoseconds for a given sensor.</li>
-  <li><em>flush()</em> - Flush adds an event to the end of the 
-    &quot;batch mode&quot; FIFO for the specified sensor and flushes the FIFO.</li>
-  <li><em>poll()</em> - Returns an array of sensor data. </li>
-</ol>
-<p>Please note, the implementation must be thread safe and allow these values to be 
-  called from different threads.</p>
-<h4 id="getSensorList">getSensorList(sensor_type)</h4>
-<p>Provide the list of sensors implemented by the HAL for the given sensor type. </p>
-<p>Developers may then make multiple calls to get sensors of different types or use 
-  <code>Sensor.TYPE_ALL</code> to get all the sensors. See getSensorList() defined on
-  developer.android.com for more details.</p>
-<h4 id="activate">activate(sensor, true/false)</h4>
-<pre>
-            int (*activate)(struct sensors_poll_device_t *dev,
-                    int handle, int enabled);</pre>
-<p>Activates or deactivates the sensor with the specified handle. Handles must be 
-  higher than <code>SENSORS_HANDLE_BASE</code> and must be unique. A handle identifies a given
-  sensor. The handle is used to activate and/or deactivate sensors. In this 
-  version of the API, there can only be 256 handles.</p>
-<p>The handle is the handle of the sensor to change. The enabled argument is set to 
-  1 to enable or 0 to disable the sensor.</p>
-<p>Unless otherwise noted in the individual sensor type descriptions, an activated 
-  sensor never prevents the SoC from going into suspend mode; that is, the HAL 
-  shall not hold a partial wake lock on behalf of applications.<br/>
-  <br/>
-  One-shot sensors deactivate themselves automatically upon receiving an event, 
-  and they must still accept to be deactivated through a call to activate(..., 
-  ..., 0).<br/>
-  <br/>
-  If &quot;enabled&quot; is 1 and the sensor is already activated, this function is a no-op 
-  and succeeds. If &quot;enabled&quot; is 0 and the sensor is already deactivated, this 
-  function is a no-op and succeeds. This returns 0 on success and a negative errno 
-  code otherwise.</p>
-<h4 id="batch">batch(sensor, batching parameters)</h4>
-<pre>
-            int (*batch)(struct sensors_poll_device_1* dev,
-                   int handle, int flags, int64_t period_ns, int64_t timeout);
-</pre>
-<p>Sets parameters to group event data collection and reduce power use. Batching 
-  can enable significant power savings by allowing the application processor to 
-  sleep rather than awake for each notification. Instead, these notifications can 
-  be grouped and processed together. See the <a
-href="{@docRoot}devices/sensors/batching.html">Batching</a> section for details.</p>
-<h4 id="setDelay">setDelay(sensor, delay)</h4>
-<pre>
-            int (*setDelay)(struct sensors_poll_device_t *dev,
-                    int handle, int64_t period_ns);
-</pre>
-<p>Sets the event's period in nanoseconds for a given sensor. What the
-<code>period_ns</code> parameter means depends on the specified sensor's trigger mode:</p>
-<ul>
-  <li>Continuous: setDelay() sets the sampling rate.</li>
-  <li>On-change: setDelay() limits the delivery rate of events.</li>
-  <li>One-shot: setDelay() is ignored. It has no effect.</li>
-  <li>Special: See specific sensor type descriptions.</li>
-</ul>
-<p>For continuous and on-change sensors, if the requested value is less than
-<code>sensor_t::minDelay</code>, then it's silently clamped to
-<code>sensor_t::minDelay</code> unless <code>sensor_t::minDelay</code> is 0,
-in which case it is clamped to &gt;= 1ms. setDelay will not be called when the sensor is
-in batching mode. In this case, batch() will be called with the new period. Return 0 if successful, 
-&lt; 0 on error.</p>
-<p>When calculating the sampling period T in setDelay (or batch), the actual period
-should be smaller than T and no smaller than T/2. Finer granularity is not
-necessary.</p>
-<h4 id="flush">flush()</h4>
-<pre>
-            int (*flush)(struct sensors_poll_device_1* dev, int handle);
-</pre>
-<p>Flush adds a <code>META_DATA_FLUSH_COMPLETE</code> event
-(<code>sensors_event_meta_data_t</code>) to the
-  end of the &quot;batch mode&quot; FIFO for the specified sensor and flushes the FIFO; 
-  those events are delivered as usual (i.e.: as if the batch timeout had expired) 
-  and removed from the FIFO.<br/>
-  <br/>
-  The flush happens asynchronously (i.e.: this function must return immediately). 
-  If the implementation uses a single FIFO for several sensors, that FIFO is 
-  flushed and the <code>META_DATA_FLUSH_COMPLETE</code> event is added only for the specified
-  sensor.<br/>
-  <br/>
-  If the specified sensor wasn't in batch mode, flush succeeds and promptly sends 
-  a <code>META_DATA_FLUSH_COMPLETE</code> event for that sensor.</p>
-<p>If the FIFO was empty at the time of the call, flush returns 0 (success) and 
-  promptly sends a <code>META_DATA_FLUSH_COMPLETE</code> event for that sensor.<br/>
-  <br/>
-  If the specified sensor wasn't enabled, flush returns -EINVAL. return 0 on 
-  success, negative errno code otherwise.</p>
-<h4 id="poll">poll()</h4>
-<pre>            int (*poll)(struct sensors_poll_device_t *dev,
-                    sensors_event_t* data, int count);</pre>
-<p>Returns an array of sensor data. This function must block until events are 
-  available. It will return the number of events read on success, or -errno in 
-  case of an error.</p>
-<p>The number of events returned in data must be less or equal to the &quot;count&quot; 
-  argument. This function shall never return 0 (no event).</p>
+    <h2 id="what_are_“android_sensors”">What are Android sensors?</h2>
+    <p>Android sensors give applications access to a mobile device's underlying
+      physical sensors. They are data-providing virtual devices defined by the
+      implementation of <a
+      href="{@docRoot}devices/reference/sensors_8h.html">sensors.h</a>,
+      the sensor Hardware Abstraction Layer (HAL).</p>
+    <ul>
+      <li> Those virtual devices provide data coming from a set of physical sensors:
+        accelerometers, gyroscopes, magnetometers, barometer, humidity, pressure,
+        light, proximity and heart rate sensors… </li>
+      <li> Notably, camera, fingerprint sensor, microphone and touch screen are currently
+        not in the list of physical devices providing data through “Android sensors.”
+        They have their own reporting mechanism. </li>
+      <li> The separation is arbitrary, but in general, Android sensors provide lower
+        bandwidth data. For example, “100hz x 3 channels” for an accelerometer versus
+        “25hz x 8 MP x 3 channels” for a camera or “44kHz x 1 channel” for a
+        microphone. </li>
+    </ul>
+    <p>How the different physical sensors are connected to the system on chip
+       (SoC) is not defined by Android.</p>
+    <ul>
+      <li> Often, sensor chips are connected to the SoC through a <a href="sensor-stack.html#sensor_hub">sensor hub</a>, allowing some low-power monitoring and processing of the data. </li>
+      <li> Often, Inter-Integrated Circuit (I2C) or Serial Peripheral Interface
+        (SPI) is used as the transport mechanism. </li>
+      <li> To reduce power consumption, some architectures are hierarchical, with some
+	minimal processing being done in the application-specific integrated
+	circuit (ASIC - like motion detection on the accelerometer chip), and
+        more is done in a microcontroller (like step detection
+        in a sensor hub). </li>
+      <li> It is up to the device manufacturer to choose an architecture based on
+	accuracy, power, price and package-size characteristics. See <a
+        href="sensor-stack.html">Sensor stack</a> for more information. </li>
+      <li> Batching capabilities are an important consideration for power optimization.
+        See <a href="batching.html">Batching</a> for more information. </li>
+    </ul>
+    <p>Each Android sensor has a “type” representing how the sensor behaves and what
+      data it provides.</p>
+    <ul>
+      <li> The official Android <a href="sensor-types.html">Sensor types</a> are defined in <a href="{@docRoot}devices/reference/sensors_8h.html">sensors.h</a> under the names SENSOR_TYPE_…
+        <ul>
+          <li> The vast majority of sensors have an official sensor type. </li>
+          <li> Those types are documented in the Android SDK. </li>
+	  <li> Behavior of sensors with those types are tested in the Android
+               Compatibility Test Suite (CTS). </li>
+        </ul>
+      </li>
+      <li> If a manufacturer integrates a new kind of sensor on an Android device, the
+        manufacturer can define its own temporary type to refer to it.
+        <ul>
+          <li> Those types are undocumented, so application developers are unlikely to use
+            them, either because they don’t know about them, or know that they are rarely
+            present (only on some devices from this specific manufacturer). </li>
+          <li> They are not tested by CTS. </li>
+	  <li> Once Android defines an official sensor type for this kind of
+	       sensor, manufacturers must stop using their own temporary type
+	       and use the official type instead. This way, the sensor will be
+               used by more application developers. </li>
+        </ul>
+      </li>
+      <li> The list of all sensors present on the device is reported by the HAL
+        implementation.
+        <ul>
+          <li> There can be several sensors of the same type. For example, two proximity
+            sensors or two accelerometers. </li>
+          <li> The vast majority of applications request only a single sensor of a given type.
+            For example, an application requesting the default accelerometer will get the
+            first accelerometer in the list. </li>
+          <li> Sensors are often defined by <a href="suspend-mode.html#wake-up_sensors">wake-up</a> and <a href="suspend-mode.html#non-wake-up_sensors">non-wake-up</a> pairs, both sensors sharing the same type, but differing by their wake-up
+            characteristic. </li>
+        </ul>
+      </li>
+    </ul>
+<p>Android sensors provide data as a series of sensor events.</p>
+      <p> Each <a href="hal-interface.html#sensors_event_t">event</a> contains:</p>
+        <ul>
+          <li> a handle to the sensor that generated it </li>
+          <li> the timestamp at which the event was detected or measured </li>
+          <li> and some data </li>
+        </ul>
+      <p>The interpretation of the reported data depends on the sensor type.
+          See the <a href="sensor-types.html">sensor type</a> definitions for details on
+          what data is reported for each sensor type.</p>
+
+<h2 id="existing_documentation2">Existing documentation</h2>
+    <h3 id="targeted_at_developers">Targeted at developers</h3>
+    <ul>
+      <li> Overview
+        <ul>
+          <li><a href="https://developer.android.com/guide/topics/sensors/sensors_overview.html"> https://developer.android.com/guide/topics/sensors/sensors_overview.html </a></li>
+        </ul>
+      </li>
+      <li> SDK reference
+        <ul>
+          <li> <a href="https://developer.android.com/reference/android/hardware/SensorManager.html">https://developer.android.com/reference/android/hardware/SensorManager.html</a></li>
+          <li><a href="https://developer.android.com/reference/android/hardware/SensorEventListener.html"> https://developer.android.com/reference/android/hardware/SensorEventListener.html</a></li>
+          <li> <a href="https://developer.android.com/reference/android/hardware/SensorEvent.html">https://developer.android.com/reference/android/hardware/SensorEvent.html</a></li>
+          <li><a href="https://developer.android.com/reference/android/hardware/Sensor.html"> https://developer.android.com/reference/android/hardware/Sensor.html</a></li>
+        </ul>
+      </li>
+      <li> StackOverflow and tutorial websites
+        <ul>
+          <li> Because sensors documentation was sometimes lacking, developers resorted to Q&amp;A
+            websites like StackOverflow to find answers. </li>
+          <li> Some tutorial websites exist as well, but do not cover the latest features like
+            batching, significant motion and game rotation vectors. </li>
+          <li> The answers over there are not always right, and show where more documentation
+            is needed. </li>
+        </ul>
+      </li>
+    </ul>
+<h3 id="targeted_at_manufacturers_public">Targeted at manufacturers</h3>
+    <ul>
+      <li> Overview
+        <ul>
+	  <li>This <a href="{@docRoot}devices/sensors/index.html">Sensors</a>
+            page and its sub-pages. </li>
+        </ul>
+      </li>
+      <li> Hardware abstraction layer (HAL)
+        <ul>
+          <li> <a href="{@docRoot}devices/reference/sensors_8h_source.html">https://source.android.com/devices/reference/sensors_8h_source.html</a></li>
+          <li> Also known as “sensors.h” </li>
+          <li> The source of truth. First document to be updated when new features are
+            developed. </li>
+        </ul>
+      </li>
+      <li> Android CDD (Compatibility Definition Document)
+        <ul>
+          <li><a href="{@docRoot}compatibility/android-cdd.pdf">https://source.android.com/compatibility/android-cdd.pdf</a></li>
+          <li> See sections relative to sensors. </li>
+          <li> The CDD is lenient, so satisfying the CDD requirements is not enough to ensure
+            high quality sensors. </li>
+        </ul>
+      </li>
+    </ul>
diff --git a/src/devices/sensors/interaction.jd b/src/devices/sensors/interaction.jd
new file mode 100644
index 0000000..bb60b2e
--- /dev/null
+++ b/src/devices/sensors/interaction.jd
@@ -0,0 +1,52 @@
+page.title=Interaction
+@jd:body
+
+<!--
+    Copyright 2014 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>From the perspective of Android applications, every Android sensor is an
+  independent entity, meaning there is no interaction between the different
+  sensors.</p>
+<ul>
+  <li> This is true even though several Android sensors might share the same
+    underlying physical sensor </li>
+  <li> For example: step counter, significant motion and accelerometer, all relying on
+    the same physical accelerometer, must be able to work concurrently </li>
+  <li> This is also true for wake-up and non-wake-up versions of the same sensor </li>
+</ul>
+<p>Android sensors must be able to work simultaneously and independently of one
+  another. That is, any action on one Android sensor must not impact the behavior
+  of the other sensors.</p>
+<p>Specifically, at the HAL level:</p>
+<ul>
+  <li> activating a sensor </li>
+  <li> deactivating a sensor </li>
+  <li> changing the sampling frequency of a sensor </li>
+  <li> changing the maximum reporting latency of a sensor </li>
+</ul>
+<p>cannot cause:</p>
+<ul>
+  <li> another activated sensor to stop working </li>
+  <li> another activated sensor to change sampling rate </li>
+  <li> another activated sensor to decrease the quality of its measurements </li>
+  <li> another non-activated sensor to start delivering events </li>
+</ul>
+<p>Nor can any of the actions above prevent actions (activation, deactivation,
+  and parameter changes) on another sensor from succeeding. For instance,
+  whether we can activate the step counter must be independent of whether the
+  accelerometer is currently activated. </p>
+<p>As another important example, a wake-up sensor activated at 5Hz must generate events
+  at around 5Hz, even if its non-wake-up variant is being activated at 100Hz.</p>
diff --git a/src/devices/sensors/power-use.jd b/src/devices/sensors/power-use.jd
new file mode 100644
index 0000000..00c3882
--- /dev/null
+++ b/src/devices/sensors/power-use.jd
@@ -0,0 +1,67 @@
+page.title=Power consumption
+@jd:body
+
+<!--
+    Copyright 2014 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>
+
+<h2 id="low_power_sensors">Low-power sensors</h2>
+<p>Some sensor types are defined as being low power. Low-power sensors must
+  function at low power, with their processing done in the hardware. This means
+  they should not require the SoC to be running. Here are some low-power sensor
+  types:</p>
+<ul>
+  <li> Geomagnetic rotation vector </li>
+  <li> Significant motion </li>
+  <li> Step counter </li>
+  <li> Step detector </li>
+  <li> Tilt detector </li>
+</ul>
+<p>They are accompanied by a low-power (<img src="images/battery_icon.png"
+width="20" height="20" alt="Low power sensor" />) icon in the <a
+href="sensor-types.html#composite_sensor_type_summary">Composite sensor type
+summary</a> table.</p>
+<p>These sensor types cannot be implemented at high power as their primary benefit
+  is low battery use. These sensors are expected to be activated for very long
+  periods, possibly 24/7. It is better to not implement a low-power sensor at all
+  rather than implement it as high power, as it would cause dramatic battery
+  drain.</p>
+<p>Composite low-power sensor types, such as the step detector, must have their
+  processing conducted in the hardware.</p>
+<p>See the CDD for specific power requirements, and expect tests in CTS to
+  verify those power requirements.</p>
+<h2 id="power_measurement_process">Power measurement process</h2>
+<p>The power is measured at the battery. For values in milliWatts, we use the
+  nominal voltage of the battery, meaning a 1mA current at 4V must be counted as
+  4mW.</p>
+<p>The power is measured when the SoC is asleep, and averaged over a few seconds
+  of the SoC being asleep, so that periodic spikes in power from the sensor chips
+  are taken into account.</p>
+<p>For one-shot wake-up sensors, the power is measured while the sensor doesn’t
+  trigger (so it doesn’t wake the SoC up). Similarly, for other sensors, the
+  power is measured while the sensor data is stored in the hardware FIFO, so the
+  SoC is not woken up.</p>
+<p>The power normally is measured as a delta with when no sensor is activated.
+  When several sensors are activated, the delta in power must be no greater than
+  the sum of the power of each activated sensor. If an accelerometer consumes
+  0.5mA and a step detector consumes 0.5mA, then activating both at the same time
+  must consume less than 0.5+0.5=1mA.</p>
diff --git a/src/devices/sensors/report-modes.jd b/src/devices/sensors/report-modes.jd
new file mode 100644
index 0000000..b800326
--- /dev/null
+++ b/src/devices/sensors/report-modes.jd
@@ -0,0 +1,66 @@
+page.title=Reporting modes
+@jd:body
+
+<!--
+    Copyright 2014 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>Sensors can generate events in different ways called reporting modes; each
+  sensor type has one and only one reporting mode associated with it. Four
+  reporting modes exist.</p>
+<h2 id="continuous">Continuous</h2>
+<p>Events are generated at a constant rate defined by the <a href="hal-interface.html#sampling_period_ns">sampling_period_ns</a> parameter passed to the <code>batch</code> function. Example sensors using the continuous
+  reporting mode are <a href="sensor-types.html#accelerometer">accelerometers</a> and <a href="sensor-types.html#gyroscope">gyroscopes</a>.</p>
+<h2 id="on-change">On-change</h2>
+<p>Events are generated only if the measured values have changed. Activating the
+  sensor at the HAL level (calling <code>activate(..., enable=1)</code> on it) also triggers
+  an event, meaning the HAL must return an event immediately when an on-change
+  sensor is activated. Example sensors using the on-change reporting mode are the
+  step counter, proximity, and heart rate sensor types.</p>
+<p>The <a href="hal-interface.html#sampling_period_ns">sampling_period_ns</a>
+  parameter passed to the <code>batch</code> function is used to set the minimum
+  time between consecutive events, meaning an event should not be generated until
+  sampling_period_ns nanoseconds elapsed since the last event, even if the value
+  changed since then. If the value changed, an event must be generated as soon as
+  <code>sampling_period_ns</code> has elapsed since the last event.</p>
+<p>For example, suppose:</p>
+<ul>
+  <li> We activate the step counter with <code>sampling_period_ns = 10 * 10^9</code> (10 seconds). </li>
+  <li> And walk for 55 seconds, then stand still for one minute. </li>
+  <li> Then the events will be generated about every 10 seconds during the first
+    minute (including at time t=0 because of the activation of the sensor, and t=60
+    seconds), for a total of seven events, and no event will be generated in the second
+    minute because the value of the step count didn’t change after t=60 seconds. </li>
+</ul>
+<h2 id="one-shot">One-shot</h2>
+<p>Upon detection of an event, the sensor deactivates itself and then sends a
+  single event through the HAL. Order matters to avoid race conditions. (The
+  sensor must be deactivated before the event is reported through the HAL). No
+  other event is sent until the sensor is reactivated. <a href="sensor-types.html#significant_motion">Significant motion</a> is an example of this kind of sensor.</p>
+<p>One-shot sensors are sometimes referred to as trigger sensors.</p>
+<p>The <code>sampling_period_ns</code> and <code>max_report_latency_ns</code>
+  parameters passed to the <code>batch</code> function are ignored. Events from
+  one-shot events cannot be stored in hardware FIFOs; the events must be
+  reported as soon as they are generated.</p>
+<h2 id="special">Special</h2>
+<p>See the individual <a href="sensor-types.html">sensor type descriptions</a>
+for details on when the events are generated.</p>
diff --git a/src/devices/sensors/sensor-stack.jd b/src/devices/sensors/sensor-stack.jd
new file mode 100644
index 0000000..9776c44
--- /dev/null
+++ b/src/devices/sensors/sensor-stack.jd
@@ -0,0 +1,182 @@
+page.title=Sensor stack
+@jd:body
+
+<!--
+    Copyright 2014 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 figure below represents the Android sensor stack. Each component
+  communicates only with the components directly above and below it, though some
+  sensors can bypass the sensor hub when it is present. Control flows from the
+  applications down to the sensors, and data flows from the sensors up to the
+  applications.</p>
+<img src="images/sensor_layers.png" alt="Layers and owners of the Android sensor stack" />
+<p class="img-caption"><strong>Figure 1.</strong> Layers of the Android sensor stack and their respective owners</p>
+
+<h2 id="sdk">SDK</h2>
+<p>Applications access sensors through the <a href="http://developer.android.com/reference/android/hardware/SensorManager.html">Sensors SDK (Software Development Kit) API</a>. The SDK contains functions to list available sensors and to register to a
+  sensor.</p>
+<p>When registering to a sensor, the application specifies its preferred sampling
+  frequency and its latency requirements.</p>
+<ul>
+  <li> For example, an application might register to the default accelerometer,
+    requesting events at 100Hz, and allowing events to be reported with a 1-second
+    latency. </li>
+  <li> The application will receive events from the accelerometer at a rate of at
+    least 100Hz, and possibly delayed up to 1 second. </li>
+</ul>
+<p>See the <a href="index.html#targeted_at_developers">developer documentation</a> for more information on the SDK.</p>
+<h2 id="framework">Framework</h2>
+<p>The framework is in charge of linking the several applications to the <a href="hal-interface.html">HAL</a>. The HAL itself is single-client. Without this multiplexing happening at the
+  framework level, only a single application could access each sensor at any
+  given time.</p>
+<ul>
+  <li> When a first application registers to a sensor, the framework sends a request
+    to the HAL to activate the sensor. </li>
+  <li> When additional applications register to the same sensor, the framework takes
+    into account requirements from each application and sends the updated requested
+    parameters to the HAL.
+    <ul>
+      <li> The <a href="hal-interface.html#sampling_period_ns">sampling frequency</a> will be the maximum of the requested sampling frequencies, meaning some
+        applications will receive events at a frequency higher than the one they
+        requested. </li>
+      <li> The <a href="hal-interface.html#max_report_latency_ns">maximum reporting latency</a> will be the minimum of the requested ones. If one application requests one
+        sensor with a maximum reporting latency of 0, all applications will receive the
+        events from this sensor in continuous mode even if some requested the sensor
+        with a non-zero maximum reporting latency. See <a href="batching.html">Batching</a> for more details. </li>
+    </ul>
+  </li>
+  <li> When the last application registered to one sensor unregisters from it, the
+    frameworks sends a request to the HAL to deactivate the sensor so power is not
+    consumed unnecessarily. </li>
+</ul>
+<h3 id="impact_of_multiplexing">Impact of multiplexing</h3>
+<p>This need for a multiplexing layer in the framework explains some design
+  decisions.</p>
+<ul>
+  <li> When an application requests a specific sampling frequency, there is no
+    guarantee that events won’t arrive at a faster rate. If another application
+    requested the same sensor at a faster rate, the first application will also
+    receive them at the fast rate. </li>
+  <li> The same lack of guarantee applies to the requested maximum reporting latency:
+    applications might receive events with much less latency than they requested. </li>
+  <li> Besides sampling frequency and maximum reporting latency, applications cannot
+    configure sensor parameters.
+    <ul>
+      <li> For example, imagine a physical sensor that can function both in “high
+        accuracy” and “low power” modes. </li>
+      <li> Only one of those two modes can be used on an Android device, because
+        otherwise, an application could request the high accuracy mode, and another one
+        a low power mode; there would be no way for the framework to satisfy both
+        applications. The framework must always be able to satisfy all its clients, so
+        this is not an option. </li>
+    </ul>
+  </li>
+  <li> There is no mechanism to send data down from the applications to the sensors or
+    their drivers. This ensures one application cannot modify the behavior of the
+    sensors, breaking other applications. </li>
+</ul>
+<h3 id="sensor_fusion">Sensor fusion</h3>
+<p>The Android framework provides a default implementation for some composite
+  sensors. When a <a href="sensor-types.html#gyroscope">gyroscope</a>, an <a href="sensor-types.html#accelerometer">accelerometer</a> and a <a href="sensor-types.html#magnetic_field_sensor">magnetometer</a> are present on a device, but no <a href="sensor-types.html#rotation_vector">rotation vector</a>, <a href="sensor-types.html#gravity">gravity</a> and <a href="sensor-types.html#linear_acceleration">linear acceleration</a> sensors are present, the framework implements those sensors so applications
+  can still use them.</p>
+<p>The default implementation does not have access to all the data that other
+  implementations have access to, and it must run on the SoC, so it is not as
+  accurate nor as power efficient as other implementations can be. As much as
+  possible, device manufacturers should define their own fused sensors (rotation
+  vector, gravity and linear acceleration, as well as newer composite sensors like
+  the <a href="sensor-types.html#game_rotation_vector">game rotation vector</a>) rather than rely on this default implementation. Device manufacturers can
+  also request sensor chip vendors to provide them with an implementation.</p>
+<p>The default sensor fusion implementation is not being maintained and
+  might cause devices relying on it to fail CTS.</p>
+<h3 id="under_the_hood">Under the Hood</h3>
+<p>This section is provided as background information for those maintaining the
+  Android Open Source Project (AOSP) framework code. It is not relevant for
+  hardware manufacturers.</p>
+<h4 id="jni">JNI</h4>
+<p>The framework uses a Java Native Interface (JNI) associated with <a href="http://developer.android.com/reference/android/hardware/package-summary.html">android.hardware</a> and located in the <code>frameworks/base/core/jni/</code> directory. This code calls the
+  lower level native code to obtain access to the sensor hardware.</p>
+<h4 id="native_framework">Native framework</h4>
+<p>The native framework is defined in <code>frameworks/native/</code> and provides a native
+  equivalent to the <a href="http://developer.android.com/reference/android/hardware/package-summary.html">android.hardware</a> package. The native framework calls the Binder IPC proxies to obtain access to
+  sensor-specific services.</p>
+<h4 id="binder_ipc">Binder IPC</h4>
+<p>The Binder IPC proxies facilitate communication over process boundaries.</p>
+<h2 id="hal">HAL</h2>
+<p>The Sensors Hardware Abstraction Layer (HAL) API is the interface between the
+  hardware drivers and the Android framework. It consists of one HAL interface
+  sensors.h and one HAL implementation we refer to as sensors.cpp.</p>
+<p>The interface is defined by Android and AOSP contributors, and the
+  implementation is provided by the manufacturer of the device.</p>
+<p>The sensor HAL interface is located in <code>hardware/libhardware/include/hardware</code>.
+  See <a href="{@docRoot}devices/reference/sensors_8h.html">sensors.h</a> for additional details.</p>
+<h3 id="release_cycle">Release cycle</h3>
+<p>The HAL implementation specifies what version of the HAL interface it
+  implements by setting <code>your_poll_device.common.version</code>. The existing HAL
+  interface versions are defined in sensors.h, and functionality is tied to those
+  versions.</p>
+<p>The Android framework currently supports versions 1.0 and 1.3, but 1.0 will
+  soon not be supported anymore. This documentation describes the behavior of version
+  1.3, to which all devices should upgrade. For details on how to upgrade to
+  1.3, see <a href="versioning.html">HAL version deprecation</a>.</p>
+<h2 id="kernel_driver">Kernel driver</h2>
+<p>The sensor drivers interact with the physical devices. In some cases, the HAL
+  implementation and the drivers are the same software entity. In other cases,
+  the hardware integrator requests sensor chip manufacturers to provide the
+  drivers, but they are the ones writing the HAL implementation.</p>
+<p>In all cases, HAL implementation and kernel drivers are the responsibility of
+  the hardware manufacturers, and Android does not provide preferred approaches to
+  write them.</p>
+<h2 id="sensor_hub">Sensor hub</h2>
+<p>The sensor stack of a device can optionally include a sensor hub, useful to
+  perform some low-level computation at low power while the SoC can be in a
+  suspend mode. For example, step counting or sensor fusion can be performed on
+  those chips. It is also a good place to implement sensor batching, adding
+  hardware FIFOs for the sensor events. See <a
+href="batching.html">Batching</a> for more information.</p>
+<p>How the sensor hub is materialized depends on the architecture. It is sometimes
+  a separate chip, and sometimes included on the same chip as the SoC. Important
+  characteristics of the sensor hub is that it should contain sufficient memory
+  for batching and consume very little power to enable implementation of the low
+  power Android sensors. Some sensor hubs contain a microcontroller for generic
+  computation, and hardware accelerators to enable very low power computation for
+  low power sensors.</p>
+<p>How the sensor hub is architectured and how it communicates with the sensors
+  and the SoC (I2C bus, SPI bus, …) is not specified by Android, but it should aim
+  at minimizing overall power use.</p>
+<p>One option that appears to have a significant impact on implementation
+  simplicity is having two interrupt lines going from the sensor hub to the SoC:
+  one for wake-up interrupts (for wake-up sensors), and the other for non-wake-up
+  interrupts (for non-wake-up sensors).</p>
+<h2 id="sensors">Sensors</h2>
+<p>Those are the physical MEMs chips making the measurements. In many cases,
+  several physical sensors are present on the same chip. For example, some chips
+  include an accelerometer, a gyroscope and a magnetometer. (Such chips are often
+  called 9-axis chips, as each sensor provides data over 3 axes.)</p>
+<p>Some of those chips also contain some logic to perform usual computations such
+  as motion detection, step detection and 9-axis sensor fusion.</p>
+<p>Although the CDD power and accuracy requirements and recommendations target the
+  Android sensor and not the physical sensors, those requirements impact the
+  choice of physical sensors. For example, the accuracy requirement on the game
+  rotation vector has implications on the required accuracy for the physical
+  gyroscope. It is up to the device manufacturer to derive the requirements for
+  physical sensors.</p>
diff --git a/src/devices/sensors/sensor-types.jd b/src/devices/sensors/sensor-types.jd
new file mode 100644
index 0000000..824680f
--- /dev/null
+++ b/src/devices/sensors/sensor-types.jd
@@ -0,0 +1,748 @@
+page.title=Sensor types
+@jd:body
+
+<!--
+    Copyright 2014 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>
+
+<h2 id="sensor_axis_definition">Sensor axis definition</h2>
+<p>Sensor event values from many sensors are expressed in a specific frame that is
+  static relative to the phone. This API is relative only to the NATURAL
+  orientation of the screen. In other words, the axes are not swapped when the
+  device's screen orientation changes.</p>
+
+<div class="figure" style="width:269px">
+  <img src="http://developer.android.com/images/axis_device.png"
+alt="Coordinate system of sensor API" height="225" />
+  <p class="img-caption">
+    <strong>Figure 1.</strong> Coordinate system (relative to a device) that's
+     used by the Sensor API.
+  </p>
+</div>
+
+<h2 id="base_sensors">Base sensors</h2>
+<p>Some sensor types are named directly after the physical sensors they represent.
+  Sensors with such types are called “base” sensors, referring to the fact they
+  relay data from a single physical sensor, contrary to “composite” sensors, for
+  which the data is generated out of other sensors.</p>
+<p>Examples of base sensor types:</p>
+<ul>
+  <li><code>SENSOR_TYPE_ACCELEROMETER</code></li>
+  <li><code>SENSOR_TYPE_GYROSCOPE</code></li>
+  <li><code>SENSOR_TYPE_MAGNETOMETER</code></li>
+</ul>
+  <p> See the list of Android sensor types below for more details on each
+<h3 id="base_sensors_=_not_equal_to_physical_sensors">Base sensors != (not equal to) physical sensors</h3>
+<p>Base sensors are not to be confused with their underlying physical sensor. The
+  data from a base sensor is not the raw output of the physical sensor:
+  corrections are be applied, such as bias compensation and temperature
+  compensation.</p>
+<p>The characteristics of a base sensor might be different from the
+  characteristics of its underlying physical sensor.</p>
+<ul>
+  <li> For example, a gyroscope chip might be rated to have a bias range of 1 deg/sec.
+    <ul>
+      <li> After factory calibration, temperature compensation and bias compensation are
+        applied, the actual bias of the Android sensor will be reduced, may be to a
+        point where the bias is guaranteed to be below 0.01deg/sec. </li>
+      <li> In this situation, we say that the Android sensor has a bias below 0.01
+        deg/sec, even though the data sheet of the underlying sensor said 1 deg/sec. </li>
+    </ul>
+  </li>
+  <li> As another example, a barometer might have a power consumption of 100uW.
+    <ul>
+      <li> Because the generated data needs to be transported from the chip to the SoC,
+        the actual power cost to gather data from the barometer Android sensor might be
+        much higher, for example 1000uW. </li>
+      <li> In this situation, we say that the Android sensor has a power consumption of
+        1000uW, even though the power consumption measured at the barometer chip leads
+        is 100uW. </li>
+    </ul>
+  </li>
+  <li> As a third example, a magnetometer might consume 100uW when calibrated, but
+    consume more when calibrating.
+    <ul>
+      <li> Its calibration routine might require activating the gyroscope, consuming
+        5000uW, and running some algorithm, costing another 900uW. </li>
+      <li> In this situation, we say that the maximum power consumption of the
+        (magnetometer) Android sensor is 6000uW. </li>
+      <li> In this case, the average power consumption is the more useful measure, and it
+        is what is reported in the sensor static characteristics through the HAL. </li>
+    </ul>
+  </li>
+</ul>
+<h3 id="accelerometer">Accelerometer</h3>
+<p>Reporting-mode: <em><a href="report-modes.html#continuous">Continuous</a></em></p>
+<p><code>getDefaultSensor(SENSOR_TYPE_ACCELEROMETER)</code> <em>returns a non-wake-up sensor</em></p>
+<p>An accelerometer sensor reports the acceleration of the device along the 3
+  sensor axes. The measured acceleration includes both the physical acceleration
+  (change of velocity) and the gravity. The measurement is reported in the x, y
+  and z fields of sensors_event_t.acceleration.</p>
+<p>All values are in SI units (m/s^2) and measure the acceleration of the device
+  minus the force of gravity along the 3 sensor axes.</p>
+<p>Here are examples:</p>
+<ul>
+  <li> The norm of (x, y, z) should be close to 0 when in free fall. </li>
+  <li> When the device lies flat on a table and is pushed on its left side toward the
+    right, the x acceleration value is positive. </li>
+  <li> When the device lies flat on a table, the acceleration value along z is +9.81
+    alo, which corresponds to the acceleration of the device (0 m/s^2) minus the
+    force of gravity (-9.81 m/s^2). </li>
+  <li> When the device lies flat on a table and is pushed toward the sky, the
+    acceleration value is greater than +9.81, which corresponds to the acceleration
+    of the device (+A m/s^2) minus the force of gravity (-9.81 m/s^2). </li>
+</ul>
+<p>The readings are calibrated using:</p>
+<ul>
+  <li> temperature compensation </li>
+  <li> online bias calibration </li>
+  <li> online scale calibration </li>
+</ul>
+<p>The bias and scale calibration must only be updated while the sensor is
+  deactivated, so as to avoid causing jumps in values during streaming.</p>
+<p>The accelerometer also reports how accurate it expects its readings to be
+  through <code>sensors_event_t.acceleration.status</code>. See the <a
+  href="http://developer.android.com/reference/android/hardware/SensorManager.html">SensorManager</a>’s
+  <a href="http://developer.android.com/reference/android/hardware/SensorManager.html#SENSOR_STATUS_ACCURACY_HIGH"><code>SENSOR_STATUS_*  </code></a> constants for more information on possible values for this field.</p>
+<h3 id="ambient_temperature">Ambient temperature</h3>
+<p>Reporting-mode: <em><a href="report-modes.html#on-change">On-change</a></em></p>
+<p><code>getDefaultSensor(SENSOR_TYPE_AMBIENT_TEMPERATURE)</code> <em>returns a non-wake-up sensor</em></p>
+<p>This sensor provides the ambient (room) temperature in degrees Celsius.</p>
+<h3 id="magnetic_field_sensor">Magnetic field sensor</h3>
+<p>Reporting-mode: <em><a href="report-modes.html#continuous">Continuous</a></em></p>
+<p><code>getDefaultSensor(SENSOR_TYPE_MAGNETIC_FIELD)</code> <em>returns a non-wake-up sensor</em></p>
+<p><code>SENSOR_TYPE_GEOMAGNETIC_FIELD == SENSOR_TYPE_MAGNETIC_FIELD</code></p>
+<p>A magnetic field sensor (also known as magnetometer) reports the ambient
+  magnetic field, as measured along the 3 sensor axes.</p>
+<p>The measurement is reported in the x, y and z fields of
+  <code>sensors_event_t.magnetic</code> and all values are in micro-Tesla (uT).</p>
+<p>The magnetometer also reports how accurate it expects its readings to be
+  through <code>sensors_event_t.magnetic.status</code>. See the <a
+href="http://developer.android.com/reference/android/hardware/SensorManager.html">SensorManager</a>’s
+<a href="http://developer.android.com/reference/android/hardware/SensorManager.html#SENSOR_STATUS_ACCURACY_HIGH"><code>SENSOR_STATUS_*</code></a> constants for more information on possible values for this field.</p>
+<p>The readings are calibrated using:</p>
+<ul>
+  <li> temperature compensation </li>
+  <li> factory (or online) soft-iron calibration </li>
+  <li> online hard-iron calibration </li>
+</ul>
+<h3 id="gyroscope">Gyroscope</h3>
+<p>Reporting-mode: <em><a href="report-modes.html#continuous">Continuous</a></em></p>
+<p><code>getDefaultSensor(SENSOR_TYPE_GYROSCOPE)</code> <em>returns a non-wake-up sensor</em></p>
+<p>A gyroscope sensor reports the rate of rotation of the device around the 3
+  sensor axes.</p>
+<p>Rotation is positive in the counterclockwise direction (right-hand rule). That
+  is, an observer looking from some positive location on the x, y or z axis at a
+  device positioned on the origin would report positive rotation if the device
+  appeared to be rotating counter clockwise. Note that this is the standard
+  mathematical definition of positive rotation and does not agree with the
+  aerospace definition of roll.</p>
+<p>The measurement is reported in the x, y and z fields of <code>sensors_event_t.gyro</code>
+  and all values are in radians per second (rad/s).</p>
+<p>The readings are calibrated using:</p>
+<ul>
+  <li> temperature compensation </li>
+  <li> factory (or online) scale compensation </li>
+  <li> online bias calibration (to remove drift) </li>
+</ul>
+<p>The gyroscope also reports how accurate it expects its readings to be through
+  <code>sensors_event_t.gyro.status</code>. See the <a
+  href="http://developer.android.com/reference/android/hardware/SensorManager.html">SensorManager</a>’s
+  <a
+href="http://developer.android.com/reference/android/hardware/SensorManager.html#SENSOR_STATUS_ACCURACY_HIGH"><code>SENSOR_STATUS_*</code></a> constants for more information on possible values for this field.</p>
+<p>The gyroscope cannot be emulated based on magnetometers and accelerometers, as
+  this would cause it to have reduced local consistency and responsiveness. It
+  must be based on a usual gyroscope chip.</p>
+<h3 id="heart_rate">Heart Rate</h3>
+<p>Reporting-mode: <em><a href="report-modes.html#on-change">On-change</a></em></p>
+<p><code>getDefaultSensor(SENSOR_TYPE_HEART_RATE)</code> <em>returns a non-wake-up sensor</em></p>
+<p>A heart rate sensor reports the current heart rate of the person touching the
+  device.</p>
+<p>The current heart rate in beats per minute (BPM) is reported in
+  <code>sensors_event_t.heart_rate.bpm</code> and the status of the sensor is reported in
+  <code>sensors_event_t.heart_rate.status</code>. See the <a
+  href="http://developer.android.com/reference/android/hardware/SensorManager.html">SensorManager</a>’s
+  <a href="http://developer.android.com/reference/android/hardware/SensorManager.html#SENSOR_STATUS_ACCURACY_HIGH"><code>SENSOR_STATUS_*</code></a> constants for more information on possible values for this field. In
+  particular, upon the first activation, unless the device is known to not be on
+  the body, the status field of the first event must be set to
+  <code>SENSOR_STATUS_UNRELIABLE</code>. Because this sensor is on-change,
+  events are generated when and only when <code>heart_rate.bpm</code> or
+  <code>heart_rate.status</code> have changed since the last event. The events
+  are generated no faster than every <code>sampling_period</code>.</p>
+<p><code>sensor_t.requiredPermission</code> is always <code>SENSOR_PERMISSION_BODY_SENSORS</code>.</p>
+<h3 id="light">Light</h3>
+<p>Reporting-mode: <em><a href="report-modes.html#on-change">On-change</a></em></p>
+<p><code>getDefaultSensor(SENSOR_TYPE_LIGHT)</code> <em>returns a non-wake-up sensor</em></p>
+<p>A light sensor reports the current illumination in SI lux units.</p>
+<p>The measurement is reported in <code>sensors_event_t.light</code>.</p>
+<h3 id="proximity">Proximity</h3>
+<p>Reporting-mode: <em><a href="report-modes.html#on-change">On-change</a></em></p>
+<p>Usually defined as a wake-up sensor</p>
+<p><code>getDefaultSensor(SENSOR_TYPE_PROXIMITY)</code> <em>returns a wake-up sensor</em></p>
+<p>A proximity sensor reports the distance from the sensor to the closest visible
+  surface.</p>
+<p>Up to Android KitKat, the proximity sensors were always wake-up sensors, waking
+  up the SoC when detecting a change in proximity. After Android KitKat, we
+  advise to implement the wake-up version of this sensor first, as it is the one
+  that is used to turn the screen on and off while making phone calls.</p>
+<p>The measurement is reported in centimeters in <code>sensors_event_t.distance</code>. Note
+  that some proximity sensors only support a binary &quot;near&quot; or &quot;far&quot; measurement.
+  In this case, the sensor report its <code>sensor_t.maxRange</code> value in the &quot;far&quot; state
+  and a value less than <code>sensor_t.maxRange</code> in the &quot;near&quot; state.</p>
+<h3 id="pressure">Pressure</h3>
+<p>Reporting-mode: <em><a href="report-modes.html#continuous">Continuous</a></em></p>
+<p><code>getDefaultSensor(SENSOR_TYPE_PRESSURE)</code> <em>returns a non-wake-up sensor</em></p>
+<p>A pressure sensor (also known as barometer) reports the atmospheric pressure in
+  hectopascal (hPa).</p>
+<p>The readings are calibrated using</p>
+<ul>
+  <li> temperature compensation </li>
+  <li> factory bias calibration </li>
+  <li> factory scale calibration </li>
+</ul>
+<p>The barometer is often used to estimate elevation changes. To estimate absolute
+  elevation, the sea-level pressure (changing depending on the weather) must be
+  used as a reference.</p>
+<h3 id="relative_humidity">Relative humidity</h3>
+<p>Reporting-mode: <em><a href="report-modes.html#on-change">On-change</a></em></p>
+<p><code>getDefaultSensor(SENSOR_TYPE_RELATIVE_HUMIDITY)</code> <em>returns a non-wake-up sensor</em></p>
+<p>A relative humidity sensor measures relative ambient air humidity and returns a
+  value in percent.</p>
+<h2 id="composite_sensor_types">Composite sensor types</h2>
+<p>Any sensor that is not a base sensor is called a composite sensor. Composite
+  sensors generate their data by processing and/or fusing data from one or
+  several physical sensors.</p>
+<p>Examples of composite sensor types:</p>
+<ul>
+  <li><a href="#step_detector">Step detector</a> and <a href="#significant_motion">Significant motion</a>, which are usually based on an accelerometer, but could be based on other
+    sensors as well, if the power consumption and accuracy was acceptable. </li>
+  <li><a href="#game_rotation_vector">Game rotation vector</a>, based on an
+    accelerometer and a gyroscope. </li>
+  <li><a href="#gyroscope_uncalibrated">Uncalibrated gyroscope</a>, which is
+    similar to the gyroscope base sensor, but with
+    the bias calibration being reported separately instead of being corrected in
+    the measurement. </li>
+</ul>
+<p>Just like base sensors, the characteristics of the composite sensors come from
+  the characteristics of their final data.</p>
+<ul>
+  <li> For example, the power consumption of a game rotation vector is probably equal
+    to the sum of the power consumptions of: the accelerometer chip, the gyroscope
+    chip, the chip processing the data, and the busses transporting the data. </li>
+  <li> As another example, the drift of a game rotation vector will depend as much on
+    the quality of the calibration algorithm as on the physical sensor
+    characteristics. </li>
+</ul>
+<h2 id="composite_sensor_type_summary">Composite sensor type summary</h2>
+<p>The following table lists the composite sensor types. Each composite sensor
+  relies on data from one or several physical sensors. Choosing other underlying
+  physical sensors to approximate results should be avoided as they will provide
+  a poor user experience.</p>
+<p>When there is no gyroscope on the device, and only when there is no gyroscope,
+  you may implement the rotation vector, linear acceleration and gravity sensors
+  without using the gyroscope.</p>
+<table>
+  <tr>
+    <th><p>Sensor type</p></th>
+    <th><p>Category</p></th>
+    <th><p>Underlying physical sensors</p></th>
+    <th><p>Reporting mode</p></th>
+  </tr>
+  <tr>
+    <td><p><a href="#game_rotation_vector">Game rotation vector</a></p></td>
+    <td><p>Attitude</p></td>
+    <td><p>Accelerometer, Gyroscope MUST NOT USE Magnetometer</p></td>
+    <td><p>Continuous</p></td>
+  </tr>
+  <tr>
+    <td><img src="images/battery_icon.png" width="20" height="20" alt="Low power sensor" />
+      <p>i<a href="#geomagnetic_rotation_vector"Geomagnetic rotation vector</a></p></td>
+    <td><p>Attitude</p></td>
+    <td><p>Accelerometer, Magnetometer, MUST NOT USE Gyroscope</p></td>
+    <td><p>Continuous</p></td>
+  </tr>
+  <tr>
+    <td><img src="images/battery_icon.png" width="20" height="20" alt="Low power sensor" />
+      <p><a href="#glance_gesture">Glance gesture</a></p></td>
+    <td><p>Interaction</p></td>
+    <td><p>Undefined</p></td>
+    <td><p>One-shot</p></td>
+  </tr>
+  <tr>
+    <td><p><a href="#gravity">Gravity</a></p></td>
+    <td><p>Attitude</p></td>
+    <td><p>Accelerometer, Gyroscope</p></td>
+    <td><p>Continuous</p></td>
+  </tr>
+  <tr>
+    <td><p><a href="#gyroscope_uncalibrated">Gyroscope uncalibrated</a></p></td>
+    <td><p>Uncalibrated</p></td>
+    <td><p>Gyroscope</p></td>
+    <td><p>Continuous</p></td>
+  </tr>
+  <tr>
+    <td><p><a href="#linear_acceleration">Linear acceleration</a></p></td>
+    <td><p>Activity</p></td>
+    <td><p>Accelerometer, Gyroscope (if present) or Magnetometer (if gyro not present)</p></td>
+    <td><p>Continuous</p></td>
+  </tr>
+  <tr>
+    <td><p><a href="#magnetic_field_uncalibrated">Magnetic field uncalibrated</a></p></td>
+    <td><p>Uncalibrated</p></td>
+    <td><p>Magnetometer</p></td>
+    <td><p>Continuous</p></td>
+  </tr>
+  <tr>
+    <td><p><a href="#orientation_deprecated">Orientation</a> (deprecated)</p></td>
+    <td><p>Attitude</p></td>
+    <td><p>Accelerometer, Magnetometer PREFERRED Gyroscope</p></td>
+    <td><p>Continuous</p></td>
+  </tr>
+  <tr>
+    <td><img src="images/battery_icon.png" width="20" height="20" alt="Low power sensor" />
+      <p><a href="#pick_up_gesture">Pick up gesture</a></p></td>
+    <td><p>Interaction</p></td>
+    <td><p>Undefined</p></td>
+    <td><p>One-shot</p></td>
+  </tr>
+  <tr>
+    <td><p><a href="#rotation_vector">Rotation vector</a></p></td>
+    <td><p>Attitude</p></td>
+    <td><p>Accelerometer, Magnetometer, AND (when present) <em>Gyroscope </em></p></td>
+    <td><p>Continuous</p></td>
+  </tr>
+  <tr>
+    <td><img src="images/battery_icon.png" width="20" height="20" alt="Low power sensor" />
+      <p><a href="#significant_motion">Significant motion</a></p></td>
+    <td><p>Activity</p></td>
+    <td><p>Accelerometer (or another as long as very low power)</p></td>
+    <td><p>One-shot</p></td>
+  </tr>
+  <tr>
+    <td><img src="images/battery_icon.png" width="20" height="20" alt="Low power sensor" />
+      <p><a href="#step_counter">Step counter</a></p></td>
+    <td><p>Activity</p></td>
+    <td><p>Accelerometer</p></td>
+    <td><p>On-change</p></td>
+  </tr>
+  <tr>
+    <td><img src="images/battery_icon.png" width="20" height="20" alt="Low power sensor" />
+      <p><a href="#step_detector">Step detector</a></p></td>
+    <td><p>Activity</p></td>
+    <td><p>Accelerometer</p></td>
+    <td><p>Special</p></td>
+  </tr>
+  <tr>
+    <td><img src="images/battery_icon.png" width="20" height="20" alt="Low power sensor" />
+      <p><a href="#tilt_detector">Tilt detector</a></p></td>
+    <td><p>Activity</p></td>
+    <td><p>Accelerometer</p></td>
+    <td><p>Special</p></td>
+  </tr>
+  <tr>
+    <td><img src="images/battery_icon.png" width="20" height="20" alt="Low power sensor" />
+      <p><a href="#wake_up_gesture">Wake up gesture</a></p></td>
+    <td><p>Interaction</p></td>
+    <td><p>Undefined</p></td>
+    <td><p>One-shot</p></td>
+  </tr>
+</table>
+<img src="images/battery_icon.png" width="20" height="20" alt="Low power sensor" />
+<p> = Low power sensor</p>
+<h2 id="activity_composite_sensors">Activity composite sensors</h2>
+<h3 id="linear_acceleration">Linear acceleration</h3>
+<p>Underlying physical sensors:  Accelerometer and (if present) Gyroscope (or
+  magnetometer if gyroscope not present)</p>
+<p>Reporting-mode: <em><a href="report-modes.html#continuous">Continuous</a></em></p>
+<p><code>getDefaultSensor(SENSOR_TYPE_LINEAR_ACCELERATION)</code> <em>returns a non-wake-up sensor</em></p>
+<p>A linear acceleration sensor reports the linear acceleration of the device in
+  the sensor frame, not including gravity.</p>
+<p>The output is conceptually: output of the <a
+  href="#accelerometer">accelerometer</a> minus the output of the <a
+  href="#gravity">gravity sensor</a>. It is reported in m/s^2 in the x, y and z
+  fields of <code>sensors_event_t.acceleration</code>.</p>
+<p>Readings on all axes should be close to 0 when the device is immobile.</p>
+<p>If the device possesses a gyroscope, the linear acceleration sensor must use
+  the accelerometer gyroscope and accelerometer as input.</p>
+<p>If the device doesn’t possess a gyroscope, the linear acceleration sensor must
+  use the accelerometer and the magnetometer as input.</p>
+<h3 id="significant_motion">Significant motion</h3>
+<p>Underlying physical sensor: Accelerometer (or another as long as low power)</p>
+<p>Reporting-mode: <em><a href="report-modes.html#one-shot">One-shot</a></em></p>
+<p>Low-power</p>
+<p>Implement only the wake-up version of this sensor.</p>
+<p><code>getDefaultSensor(SENSOR_TYPE_SIGNIFICANT_MOTION)</code> <em>returns a non-wake-up sensor</em></p>
+<p>A significant motion detector triggers when the detecting a “significant
+  motion”: a motion that might lead to a change in the user location.</p>
+<p>Examples of such significant motions are:</p>
+<ul>
+  <li> walking or biking </li>
+  <li> sitting in a moving car, coach or train </li>
+</ul>
+<p>Examples of situations that do not trigger significant motion:</p>
+<ul>
+  <li> phone in pocket and person is not moving </li>
+  <li> phone is on a table and the table shakes a bit due to nearby traffic or washing
+    machine </li>
+</ul>
+<p>At the high level, the significant motion detector is used to reduce the power
+  consumption of location determination. When the localization algorithms detect
+  that the device is static, they can switch to a low power mode, where they rely
+  on significant motion to wake the device up when the user is changing location.</p>
+<p>This sensor must be low power. It makes a tradeoff for power consumption that
+  may result in a small amount of false negatives. This is done for a few
+  reasons:</p>
+<ul>
+  <li> The goal of this sensor is to save power. </li>
+  <li> Triggering an event when the user is not moving (false positive) is costly in
+    terms of power, so it should be avoided. </li>
+  <li> Not triggering an event when the user is moving (false negative) is acceptable
+    as long as it is not done repeatedly. If the user has been walking for 10
+    seconds, not triggering an event within those 10 seconds is not acceptable. </li>
+</ul>
+<p>Each sensor event reports 1 in <code>sensors_event_t.data[0]</code></p>
+<h3 id="step_detector">Step detector</h3>
+<p>Underlying physical sensor: Accelerometer (+ possibly others as long as low
+  power)</p>
+<p>Reporting-mode: <em><a href="report-modes.html#special">Special</a> (one event per step taken)</em></p>
+<p>Low-power</p>
+<p><code>getDefaultSensor(SENSOR_TYPE_STEP_DETECTOR)</code> <em>returns a non-wake-up sensor</em></p>
+<p>A step detector generates an event each time a step is taken by the user.</p>
+<p>The timestamp of the event <code>sensors_event_t.timestamp</code> corresponds to when the
+  foot hit the ground, generating a high variation in acceleration.</p>
+<p>Compared to the step counter, the step detector should have a lower latency
+  (less than 2 seconds). Both the step detector and the step counter detect when
+  the user is walking, running and walking up the stairs. They should not trigger
+  when the user is biking, driving or in other vehicles.</p>
+<p>This sensor must be low power. That is, if the step detection cannot be done in
+  hardware, this sensor should not be defined. In particular, when the step
+  detector is activated and the accelerometer is not, only steps should trigger
+  interrupts (not every accelerometer reading).</p>
+<p><code>sampling_period_ns</code> has no impact on step detectors.</p>
+<p>Each sensor event reports 1 in <code>sensors_event_t.data[0]</code></p>
+<h3 id="step_counter">Step counter</h3>
+<p>Underlying physical sensor: Accelerometer (+ possibly others as long as low
+  power)</p>
+<p>Reporting-mode: <em><a href="report-modes.html#on-change">On-change</a></em></p>
+<p>Low-power</p>
+<p><code>getDefaultSensor(SENSOR_TYPE_STEP_COUNTER)</code> <em>returns a non-wake-up sensor</em></p>
+<p>A step counter reports the number of steps taken by the user since the last
+  reboot while activated.</p>
+<p>The measurement is reported as a <code>uint64_t</code> in
+  <code>sensors_event_t.step_counter</code> and
+  is reset to zero only on a system reboot.</p>
+<p>The timestamp of the event is set to the time when the last step for that event
+  was taken.</p>
+<p>See the <a href="#step_detector">Step detector</a> sensor type for the signification of the time of a step.</p>
+<p>Compared to the step detector, the step counter can have a higher latency (up
+  to 10 seconds). Thanks to this latency, this sensor has a high accuracy; the
+  step count after a full day of measures should be within 10% of the actual step
+  count. Both the step detector and the step counter detect when the user is
+  walking, running and walking up the stairs. They should not trigger when the
+  user is biking, driving or in other vehicles.</p>
+<p>The hardware must ensure the internal step count never overflows. The minimum
+  size of the hardware's internal counter shall be 16 bits. In case of imminent
+  overflow (at most every ~2^16 steps), the SoC can be woken up so the driver can
+  do the counter maintenance.</p>
+<p>As stated in <a href="interaction.html">Interaction</a>, while this sensor
+  operates, it shall not disrupt any other sensors, in particular, the
+  accelerometer, which might very well be in use.</p>
+<p>If a particular device cannot support these modes of operation, then this
+  sensor type must not be reported by the HAL. ie: it is not acceptable to
+  &quot;emulate&quot; this sensor in the HAL.</p>
+<p>This sensor must be low power. That is, if the step detection cannot be done in
+  hardware, this sensor should not be defined. In particular, when the step
+  counter is activated and the accelerometer is not, only steps should trigger
+  interrupts (not accelerometer data).</p>
+<h3 id="tilt_detector">Tilt detector</h3>
+<p>Underlying physical sensor: Accelerometer (+ possibly others as long as low
+  power)</p>
+<p>Reporting-mode: <em><a href="report-modes.html#special">Special</a></em></p>
+<p>Low-power</p>
+<p>Implement only the wake-up version of this sensor.</p>
+<p><code>getDefaultSensor(SENSOR_TYPE_TILT_DETECTOR)</code> <em>returns a wake-up sensor</em></p>
+<p>A tilt detector generates an event each time a tilt event is detected.</p>
+<p>A tilt event is defined by the direction of the 2-seconds window average
+  gravity changing by at least 35 degrees since the activation or the last event
+  generated by the sensor. Here is the algorithm:</p>
+<ul>
+  <li> <code>reference_estimated_gravity</code> = average of accelerometer measurements over the
+    first second after activation or the estimated gravity when the last tilt event
+    was generated. </li>
+  <li> <code>current_estimated_gravity</code> = average of accelerometer measurements over the last
+    2 seconds. </li>
+  <li> trigger when <code>angle(reference_estimated_gravity, current_estimated_gravity) &gt; 35
+    degrees</code> </li>
+</ul>
+<p>Large accelerations without a change in phone orientation should not trigger a
+  tilt event. For example, a sharp turn or strong acceleration while driving a
+  car should not trigger a tilt event, even though the angle of the average
+  acceleration might vary by more than 35 degrees.
+  Typically, this sensor is
+  implemented with the help of only an accelerometer. Other sensors can be used
+  as well if they do not increase the power consumption significantly. This is a
+  low power sensor that should allow the SoC to go into suspend mode. Do not
+  emulate this sensor in the HAL. Each sensor event reports 1 in
+  <code>sensors_event_t.data[0]</code>.</p>
+<h2 id="attitude_composite_sensors">Attitude composite sensors</h2>
+<h3 id="rotation_vector">Rotation vector</h3>
+<p>Underlying physical sensors: Accelerometer, Magnetometer, and (when present)
+  Gyroscope</p>
+<p>Reporting-mode: <em><a href="report-modes.html#continuous">Continuous</a></em></p>
+<p><code>getDefaultSensor(SENSOR_TYPE_ROTATION_VECTOR)</code> <em>returns a non-wake-up sensor</em></p>
+<p>A rotation vector sensor reports the orientation of the device relative to the
+  East-North-Up coordinates frame. It is usually obtained by integration of
+  accelerometer, gyroscope and magnetometer readings.</p>
+<p>The East-North-Up coordinate system is defined as a direct orthonormal basis
+  where:</p>
+<ul>
+  <li> X points east and is tangential to the ground. </li>
+  <li> Y points north and is tangential to the ground. </li>
+  <li> Z points towards the sky and is perpendicular to the ground. </li>
+</ul>
+<p>The orientation of the phone is represented by the rotation necessary to align
+  the East-North-Up coordinates with the phone's coordinates. That is, applying
+  the rotation to the world frame (X,Y,Z) would align them with the phone
+  coordinates (x,y,z).</p>
+<p>The rotation can be seen as rotating the phone by an angle theta around an axis
+  rot_axis to go from the reference (East-North-Up aligned) device orientation to
+  the current device orientation.</p>
+<p>The rotation is encoded as the four unit-less x, y, z, w components of a unit
+  quaternion:</p>
+<ul>
+  <li> <code>sensors_event_t.data[0] = rot_axis.x*sin(theta/2)</code> </li>
+  <li> <code>sensors_event_t.data[1] = rot_axis.y*sin(theta/2)</code> </li>
+  <li> <code>sensors_event_t.data[2] = rot_axis.z*sin(theta/2)</code> </li>
+  <li> <code>sensors_event_t.data[3] = cos(theta/2)</code> </li>
+</ul>
+<p>Where:</p>
+<ul>
+  <li> the  x, y and z fields of <code>rot_axis</code> are the East-North-Up
+  coordinates of a unit length vector representing the rotation axis </li>
+  <li> <code>theta</code> is the rotation angle </li>
+</ul>
+<p>The quaternion is a unit quaternion: it must be of norm 1. Failure to ensure
+  this will cause erratic client behaviour.</p>
+<p>In addition, this sensor reports an estimated heading accuracy:</p>
+<p><code>sensors_event_t.data[4] = estimated_accuracy</code> (in radians)</p>
+<p>The heading error must be less than <code>estimated_accuracy</code> 95% of the time. This
+  sensor must use a gyroscope as main orientation change input unless there is no
+  gyroscope on the device.</p>
+<p>This sensor also includes the accelerometer and magnetometer input to make up
+  for gyroscope drift, but it cannot be implemented using only the magnetometer
+  and accelerometer, unless there is no gyroscope on the device.</p>
+<h3 id="game_rotation_vector">Game rotation vector</h3>
+<p>Underlying physical sensors: Accelerometer and Gyroscope (no Magnetometer)</p>
+<p>Reporting-mode: <em><a href="report-modes.html#continuous">Continuous</a></em></p>
+<p><code>getDefaultSensor(SENSOR_TYPE_GAME_ROTATION_VECTOR)</code> <em>returns a non-wake-up sensor</em></p>
+<p>A game rotation vector sensor is similar to a rotation vector sensor but not
+  using the geomagnetic field. Therefore the Y axis doesn't point north but
+  instead to some other reference. That reference is allowed to drift by the same
+  order of magnitude as the gyroscope drifts around the Z axis.</p>
+<p>See the <a href="#rotation_vector">Rotation vector</a> sensor for details on
+  how to set <code>sensors_event_t.data[0-3]</code>. This sensor does
+  not report an estimated heading accuracy:
+  <code>sensors_event_t.data[4]</code> is reserved and should be set to 0.</p>
+<p>In an ideal case, a phone rotated and returned to the same real-world
+  orientation should report the same game rotation vector.</p>
+<p>This sensor must be based on a gyroscope and an accelerometer. It cannot use
+  magnetometer as an input, besides, indirectly, through estimation of the
+  gyroscope bias.</p>
+<h3 id="gravity">Gravity</h3>
+<p>Underlying physical sensors: Accelerometer and (if present) Gyroscope (or
+  magnetometer if gyroscope not present)</p>
+<p>Reporting-mode: <em><a href="report-modes.html#continuous">Continuous</a></em></p>
+<p><code>getDefaultSensor(SENSOR_TYPE_GRAVITY)</code> <em>returns a non-wake-up sensor</em></p>
+<p>A gravity sensor reports the direction and magnitude of gravity in the device's
+  coordinates.</p>
+<p>The gravity vector components are reported in m/s^2 in the x, y and z fields of
+  <code>sensors_event_t.acceleration</code>.</p>
+<p>When the device is at rest, the output of the gravity sensor should be
+  identical to that of the accelerometer. On Earth, the magnitude is around 9.8
+  m/s^2.</p>
+<p>If the device possesses a gyroscope, the gravity sensor must use the
+  accelerometer gyroscope and accelerometer as input.</p>
+<p>If the device doesn’t possess a gyroscope, the gravity sensor must use the
+  accelerometer and the magnetometer as input.</p>
+<h3 id="geomagnetic_rotation_vector">Geomagnetic rotation vector</h3>
+<p>Underlying physical sensors: Accelerometer and Magnetometer (no Gyroscope)</p>
+<p>Reporting-mode: <em><a href="report-modes.html#continuous">Continuous</a></em></p>
+<p>Low-power</p>
+<p><code>getDefaultSensor(SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR)</code> <em>returns a non-wake-up sensor</em></p>
+<p>A geomagnetic rotation vector is similar to a rotation vector sensor but using
+  a magnetometer and no gyroscope.</p>
+<p>This sensor must be based on a magnetometer. It cannot be implemented using a
+  gyroscope, and gyroscope input cannot be used by this sensor.</p>
+<p>See the <a href="#rotation_vector">Rotation vector</a> sensor for details on
+  how to set <code>sensors_event_t.data[0-4]</code>.</p>
+<p>Just like for the rotation vector sensor, the heading error must be less than
+  the estimated accuracy (<code>sensors_event_t.data[4]</code>) 95% of the time.</p>
+<p>This sensor must be low power, so it has to be implemented in hardware.</p>
+<h3 id="orientation_deprecated">Orientation (deprecated)</h3>
+<p>Underlying physical sensors: Accelerometer, Magnetometer and (if present)
+  Gyroscope</p>
+<p>Reporting-mode: <em><a href="report-modes.html#continuous">Continuous</a></em></p>
+<p><code>getDefaultSensor(SENSOR_TYPE_ORIENTATION)</code> <em>returns a non-wake-up sensor</em></p>
+<p>Note: This is an older sensor type that has been deprecated in the Android SDK.
+  It has been replaced by the rotation vector sensor, which is more clearly
+  defined. Use the rotation vector sensor over the orientation sensor whenever
+  possible.</p>
+<p>An orientation sensor reports the attitude of the device. The measurements are
+  reported in degrees in the x, y and z fields of <code>sensors_event_t.orientation</code>:</p>
+<ul>
+  <li> <code>sensors_event_t.orientation.x</code>: azimuth, the angle between the magnetic north
+    direction and the Y axis, around the Z axis (<code>0&lt;=azimuth&lt;360</code>). 0=North, 90=East,
+    180=South, 270=West </li>
+  <li> <code>sensors_event_t.orientation.y</code>: pitch, rotation around X axis
+    (<code>-180&lt;=pitch&lt;=180</code>), with positive values when the z-axis moves toward the
+    y-axis. </li>
+  <li> <code>sensors_event_t.orientation.z</code>: roll, rotation around Y axis (<code>-90&lt;=roll&lt;=90</code>),
+    with positive values when the x-axis moves towards the z-axis. </li>
+</ul>
+<p>Please note, for historical reasons the roll angle is positive in the clockwise
+  direction. (Mathematically speaking, it should be positive in the
+  counter-clockwise direction):</p>
+<div class="figure" style="width:264px">
+  <imgsrc="images/axis_positive_roll.png" alt="Depiction of orientation
+   relative to a device" height="253" />
+  <p class="img-caption">
+    <strong>Figure 2.</strong> Orientation relative to a device.
+  </p>
+</div>
+<p>This definition is different from yaw, pitch and roll used in aviation where
+  the X axis is along the long side of the plane (tail to nose).</p>
+<p>The orientation sensor also reports how accurate it expects its readings to be
+  through sensors_event_t.orientation.status. See the <a href="http://developer.android.com/reference/android/hardware/SensorManager.html">SensorManager</a>’s <a href="http://developer.android.com/reference/android/hardware/SensorManager.html#SENSOR_STATUS_ACCURACY_HIGH">SENSOR_STATUS_</a>* constants for more information on possible values for this field.</p>
+<h2 id="uncalibrated_sensors">Uncalibrated sensors</h2>
+<p>Uncalibrated sensors provide more raw results and may include some bias but
+  also contain fewer &quot;jumps&quot; from corrections applied through calibration. Some
+  applications may prefer these uncalibrated results as smoother and more
+  reliable. For instance, if an application is attempting to conduct its own
+  sensor fusion, introducing calibrations can actually distort results.</p>
+<h3 id="gyroscope_uncalibrated">Gyroscope uncalibrated</h3>
+<p>Underlying physical sensor: Gyroscope</p>
+<p>Reporting-mode: <em><a href="report-modes.html#continuous">Continuous</a></em></p>
+<p><code>getDefaultSensor(SENSOR_TYPE_GYROSCOPE_UNCALIBRATED)</code> <em>returns a non-wake-up sensor</em></p>
+<p>An uncalibrated gyroscope reports the rate of rotation around the sensor axes
+  without applying bias compensation to them, along with a bias estimate. All
+  values are in radians/second and are reported in the fields of
+  <code>sensors_event_t.uncalibrated_gyro</code>:</p>
+<ul>
+  <li> <code>x_uncalib</code>: angular speed (w/o drift compensation) around the X axis </li>
+  <li> <code>y_uncalib</code>: angular speed (w/o drift compensation) around the Y axis </li>
+  <li> <code>z_uncalib</code>: angular speed (w/o drift compensation) around the Z axis </li>
+  <li> <code>x_bias</code>: estimated drift around X axis </li>
+  <li> <code>y_bias</code>: estimated drift around Y axis </li>
+  <li> <code>z_bias</code>: estimated drift around Z axis </li>
+</ul>
+<p>Conceptually, the uncalibrated measurement is the sum of the calibrated
+  measurement and the bias estimate: <code>_uncalibrated = _calibrated + _bias</code>.</p>
+<p>The <code>x/y/z_bias</code> values are expected to jump as soon as the estimate of the bias
+  changes, and they should be stable the rest of the time.</p>
+<p>See the definition of the <a href="#gyroscope">gyroscope</a> sensor for
+  details on the coordinate system used.</p>
+<p>Factory calibration and temperature compensation must be applied to the
+  measurements. Also, gyroscope drift estimation must be implemented so that
+  reasonable estimates can be reported in <code>x_bias</code>,
+  <code>y_bias</code> and <code>z_bias</code>. If the
+  implementation is not able to estimate the drift, then this sensor must not be
+  implemented.</p>
+<p>If this sensor is present, then the corresponding Gyroscope sensor must also be
+  present and both sensors must share the same <code>sensor_t.name</code> and
+  <code>sensor_t.vendor</code> values.</p>
+<h3 id="magnetic_field_uncalibrated">Magnetic field uncalibrated</h3>
+<p>Underlying physical sensor: Magnetometer</p>
+<p>Reporting-mode: <em><a href="report-modes.html#continuous">Continuous</a></em></p>
+<p><code>getDefaultSensor(SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED)</code> <em>returns a non-wake-up sensor</em></p>
+<p>An uncalibrated magnetic field sensor reports the ambient magnetic field
+  together with a hard iron calibration estimate. All values are in micro-Tesla
+  (uT) and are reported in the fields of <code>sensors_event_t.uncalibrated_magnetic</code>:</p>
+<ul>
+  <li> <code>x_uncalib</code>: magnetic field (w/o hard-iron compensation) along the X axis </li>
+  <li> <code>y_uncalib</code>: magnetic field (w/o hard-iron compensation) along the Y axis </li>
+  <li> <code>z_uncalib</code>: magnetic field (w/o hard-iron compensation) along the Z axis </li>
+  <li> <code>x_bias</code>: estimated hard-iron bias along the X axis </li>
+  <li> <code>y_bias</code>: estimated hard-iron bias along the Y axis </li>
+  <li> <code>z_bias</code>: estimated hard-iron bias along the Z axis </li>
+</ul>
+<p>Conceptually, the uncalibrated measurement is the sum of the calibrated
+  measurement and the bias estimate: <code>_uncalibrated = _calibrated + _bias</code>.</p>
+<p>The uncalibrated magnetometer allows higher level algorithms to handle bad hard
+  iron estimation. The <code>x/y/z_bias</code> values are expected to jump as soon as the
+  estimate of the hard-iron changes, and they should be stable the rest of the
+  time.</p>
+<p>Soft-iron calibration and temperature compensation must be applied to the
+  measurements. Also, hard-iron estimation must be implemented so that reasonable
+  estimates can be reported in <code>x_bias</code>, <code>y_bias</code> and
+  <code>z_bias</code>. If the implementation is not able to estimate the bias,
+  then this sensor must not be implemented.</p>
+<p>If this sensor is present, then the corresponding magnetic field sensor must be
+  present and both sensors must share the same <code>sensor_t.name</code> and
+  <code>sensor_t.vendor</code> values.</p>
+<h2 id="interaction_composite_sensors">Interaction composite sensors</h2>
+<p>Some sensors are mostly used to detect interactions with the user. We do not
+  define how those sensors must be implemented, but they must be low power and it
+  is the responsibility of the device manufacturer to verify their quality in
+  terms of user experience.</p>
+<h3 id="wake_up_gesture">Wake up gesture</h3>
+<p>Underlying physical sensors: Undefined (anything low power)</p>
+<p>Reporting-mode: <em><a href="report-modes.html#one-shot">One-shot</a></em></p>
+<p>Low-power</p>
+<p>Implement only the wake-up version of this sensor.</p>
+<p><code>getDefaultSensor(SENSOR_TYPE_WAKE_GESTURE)</code> <em>returns a wake-up sensor</em></p>
+<p>A wake up gesture sensor enables waking up the device based on a device
+  specific motion. When this sensor triggers, the device behaves as if the power
+  button was pressed, turning the screen on. This behavior (turning on the screen
+  when this sensor triggers) might be deactivated by the user in the device
+  settings. Changes in settings do not impact the behavior of the sensor: only
+  whether the framework turns the screen on when it triggers.
+  The actual gesture to be detected is not specified, and can be chosen by the
+  manufacturer of the device.</p>
+<p>This sensor must be low power, as it is likely to be activated 24/7.</p>
+<p>Each sensor event reports 1 in <code>sensors_event_t.data[0]</code>.</p>
+<h3 id="pick_up_gesture">Pick up gesture</h3>
+<p>Underlying physical sensors: Undefined (anything low power)</p>
+<p>Reporting-mode: <em><a href="report-modes.html#one-shot">One-shot</a></em></p>
+<p>Low-power</p>
+<p>Implement only the wake-up version of this sensor.</p>
+<p><code>getDefaultSensor(SENSOR_TYPE_PICK_UP_GESTURE)</code> <em>returns a wake-up sensor</em></p>
+<p>A pick-up gesture sensor sensor triggers when the device is picked up
+  regardless of wherever is was before (desk, pocket, bag).</p>
+<p>Each sensor event reports 1 in <code>sensors_event_t.data[0]</code>.</p>
+<h3 id="glance_gesture">Glance gesture</h3>
+<p>Underlying physical sensors: Undefined (anything low power)</p>
+<p>Reporting-mode: <em><a href="report-modes.html#one-shot">One-shot</a></em></p>
+<p>Low-power</p>
+<p>Implement only the wake-up version of this sensor.</p>
+<p><code>getDefaultSensor(SENSOR_TYPE_GLANCE_GESTURE)</code> <em>returns a wake-up sensor</em></p>
+<p>A glance gesture sensor enables briefly turning the screen on to enable the
+  user to glance content on screen based on a specific motion. When this sensor
+  triggers, the device will turn the screen on momentarily to allow the user to
+  glance notifications or other content while the device remains locked in a
+  non-interactive state (dozing), then the screen will turn off again. This
+  behavior (briefly turning on the screen when this sensor triggers) might be
+  deactivated by the user in the device settings. Changes in settings do not
+  impact the behavior of the sensor: only whether the framework briefly turns the
+  screen on when it triggers. The actual gesture to be detected is not specified,
+  and can be chosen by the manufacturer of the device.</p>
+<p>This sensor must be low power, as it is likely to be activated 24/7.
+  Each sensor event reports 1 in <code>sensors_event_t.data[0]</code>.</p>
diff --git a/src/devices/sensors/suspend-mode.jd b/src/devices/sensors/suspend-mode.jd
new file mode 100644
index 0000000..1f9c351
--- /dev/null
+++ b/src/devices/sensors/suspend-mode.jd
@@ -0,0 +1,81 @@
+page.title=Suspend mode
+@jd:body
+
+<!--
+    Copyright 2014 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>
+
+<h2 id="soc_power_states">SoC power states</h2>
+<p>The power states of the system on a chip (SoC) are: on, idle, and suspend. “On” is when the
+  SoC is running. “Idle” is a medium power mode where the SoC is powered but
+  doesn't perform any tasks. “Suspend” is a low-power mode where the SoC is not
+  powered. The power consumption of the device in this mode is usually 100 times
+  less than in the “On” mode.</p>
+<h2 id="non-wake-up_sensors">Non-wake-up sensors</h2>
+<p>Non-wake-up sensors are sensors that do not prevent the SoC
+  from going into suspend mode and do not wake the SoC up to report data. In
+  particular, the drivers are not allowed to hold wake-locks. It is the
+  responsibility of applications to keep a partial wake lock should they wish to
+  receive events from non-wake-up sensors while the screen is off. While the SoC
+  is in suspend mode, the sensors must continue to function and generate events,
+  which are put in a hardware FIFO. (See <a
+  href="batching.html">Batching</a> for more details.) The events in the
+  FIFO are delivered to the applications when the SoC wakes up. If the FIFO is
+  too small to store all events, the older events are lost; the oldest data is dropped to accommodate
+  the latest data. In the extreme case where the FIFO is nonexistent, all events
+  generated while the SoC is in suspend mode are lost. One exception is the
+  latest event from each on-change sensor: the last event <a href="batching.html#precautions_to_take_when_batching_non-wake-up_on-change_sensors">must be saved </a>outside of the FIFO so it cannot be lost.</p>
+<p>As soon as the SoC gets out of suspend mode, all events from the FIFO are
+  reported and operations resume as normal.</p>
+<p>Applications using non-wake-up sensors should either hold a wake lock to ensure
+  the system doesn't go to suspend, unregister from the sensors when they do
+  not need them, or expect to lose events while the SoC is in suspend mode.</p>
+<h2 id="wake-up_sensors">Wake-up sensors</h2>
+<p>In opposition to non-wake-up sensors, wake-up sensors ensure that their data is
+  delivered independently of the state of the SoC. While the SoC is awake, the
+  wake-up sensors behave like non-wake-up-sensors. When the SoC is asleep,
+  wake-up sensors must wake up the SoC to deliver events. They must still let the
+  SoC go into suspend mode, but must also wake it up when an event needs to be
+  reported. That is, the sensor must wake the SoC up and deliver the events
+  before the maximum reporting latency has elapsed or the hardware FIFO gets full.
+  See <a href="batching.html">Batching</a> for more details.</p>
+<p>To ensure the applications have the time to receive the event before the SoC
+  goes back to sleep, the driver must hold a &quot;timeout wake lock&quot; for 200
+  milliseconds each time an event is being reported. <em>That is, the SoC should not
+  be allowed to go back to sleep in the 200 milliseconds following a wake-up
+  interrupt.</em> This requirement will disappear in a future Android release, and we
+  need this timeout wake lock until then.</p>
+<h2 id="how_to_define_wake-up_and_non-wake-up_sensors">How to define wake-up and non-wake-up sensors?</h2>
+<p>Up to KitKat, whether a sensor was a wake-up or a non-wake-up sensor was
+  dictated by the sensor type: most were non-wake-up sensors, with the exception
+  of the <a href="sensor-types.html#proximity">proximity</a> sensor and the <a href="sensor-types.html#significant_motion">significant motion detector</a>.</p>
+<p>Starting in L, whether a given sensor is a wake-up sensor or not is specified
+  by a flag in the sensor definition. Most sensors can be defined by pairs of
+  wake-up and non-wake-up variants of the same sensor, in which case they must
+  behave as two independent sensors, not interacting with one another. See
+  <a href="interaction.html">Interaction</a> for more details.</p>
+<p>Unless specified otherwise in the sensor type definition, it is recommended to
+  implement one wake-up sensor and one non-wake-up sensor for each sensor type
+  listed in <a href="sensor-types.html">Sensor types</a>. In each sensor type
+  definition, see what sensor (wake-up or non-wake-up) will be returned by
+  <code>SensorManager.getDefaultSensor(sensorType)</code>. It is the sensor
+  that most applications will use.</p>
diff --git a/src/devices/sensors/versioning.jd b/src/devices/sensors/versioning.jd
new file mode 100644
index 0000000..130c58c
--- /dev/null
+++ b/src/devices/sensors/versioning.jd
@@ -0,0 +1,183 @@
+page.title=HAL version deprecation
+@jd:body
+
+<!--
+    Copyright 2014 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>In the L release of Android, we are halting support for some sensor HAL
+versions. The only supported versions are <code>SENSORS_DEVICE_API_VERSION_1_0
+</code>and <code>SENSORS_DEVICE_API_VERSION_1_3</code>.</p>
+
+<p>In the next releases, we are likely to drop support for 1_0 as well.</p>
+
+<p>1_0 has no concept of batching. If possible, all devices using 1_0 SHOULD
+upgrade to 1_3.</p>
+
+<p>1_1 and 1_2 suffer from poor definition of the batching concept, and are not
+supported anymore</p>
+
+<p>All devices currently using 1_1 or 1_2 MUST upgrade to 1_3.</p>
+
+<p>In 1_3, we simplified the notion of batching, and we introduced wake up
+sensors.</p>
+
+<p>To upgrade to 1_3, follow the changes listed below.</p>
+
+<h2>Implement the batch function</h2>
+
+<p>Even if you do not implement batching (your hardware has no FIFO), you must
+implement the <code>batch</code> function. <code>batch</code> is used to set
+the sampling period and the maximum reporting latency for a given sensor. It
+replaces <code>setDelay</code>. <code>setDelay</code> will not be called
+anymore.</p>
+
+<p>If you do not implement batching, you can implement <code>batch</code> by
+simply calling your existing <code>setDelay</code> function with the provided
+<code>sampling_period_ns</code> parameter.</p>
+
+<h2>Implement the flush function</h2>
+
+<p>Even if you do not implement batching, you must implement the
+<code>flush</code> function.</p>
+
+<p>If you do not implement batching, <code>flush</code> must generate one
+<code>META_DATA_FLUSH_COMPLETE</code> event and return 0 (success).</p>
+
+<h2>Change your sensors_poll_device_t.common.version</h2>
+
+<pre class=prettyprint>
+your_poll_device.common.version = SENSORS_DEVICE_API_VERSION_1_3
+</pre>
+
+<h2>Add the new fields to the definition of your sensors</h2>
+
+<p>When defining each sensor, in addition to the usual <a
+href="{@docRoot}devices/sensors/hal-interface.html#sensor_t">sensor_t</a>
+fields:</p>
+
+<pre class=prettyprint>
+.name =       "My magnetic field Sensor",
+.vendor =     "My company",
+.version
+=    1,
+.handle =     mag_handle,
+.type =       SENSOR_TYPE_MAGNETIC_FIELD,
+.maxRange =   200.0f,
+.resolution = CONVERT_M,
+.power =      5.0f,
+.minDelay =
+ 16667,
+</pre>
+
+<p>you also must set the new fields, defined between 1_0 and 1_3:</p>
+
+<pre class=prettyprint>
+.fifoReservedEventCount = 0,
+.fifoMaxEventCount =   0,
+.stringType =         0,
+.requiredPermission = 0,
+.maxDelay =      200000
+.flags =
+SENSOR_FLAG_CONTINUOUS_MODE,
+</pre>
+
+<p><em>fifoReservedEventCount</em>: If not implementing batching, set this one to 0.</p>
+
+<p><em>fifoMaxEventCount</em>: If not implementing batching, set this one to 0</p>
+
+<p><em>stringType</em>: Set to 0 for all official android sensors (those that are defined in
+sensors.h), as this value will be overwritten by the framework. For
+non-official sensors, see <a
+href="{@docRoot}devices/sensors/hal-interface.html#sensor_t">sensor_t</a> for
+details on how to set it.</p>
+
+<p><em>requiredPermission</em>: This is the permission that applications will be required to have to get
+access to your sensor. You can usually set this to 0 for all of your sensors,
+but sensors with type <code>HEART_RATE</code> must set this to <code>SENSOR_PERMISSION_BODY_SENSORS.</code></p>
+
+<p><em>maxDelay</em>: This value is important and you will need to set it according to the
+capabilities of the sensor and of its driver.</p>
+
+<p>This value is defined only for continuous and on-change sensors. It is the
+delay between two sensor events corresponding to the lowest frequency that this
+sensor supports. When lower frequencies are requested through the
+<code>batch</code> function, the events will be generated at this frequency
+instead. It can be used by the framework or applications to estimate when the
+batch FIFO may be full. If this value is not set properly, CTS will fail.
+For one-shot and special reporting mode sensors, set <code>maxDelay</code> to 0.</p>
+
+<p>For continuous sensors, set it to the maximum sampling period allowed in
+microseconds.</p>
+
+<p>Note:</p>
+<ul>
+<li><code>period_ns</code> is in nanoseconds whereas
+<code>maxDelay</code>/<code>minDelay</code> are in microseconds.</li>
+<li><code>maxDelay </code>should always fit within a 32-bit signed integer. It
+is declared as 64 bit on 64 bit architectures only for binary compatibility reasons.</li>
+</ul>
+
+<p><em>flags</em>: This field defines the reporting mode of the sensor and whether the sensor is
+a wake up sensor.</p>
+
+<p>If you do not implement batching, and are just moving from 1.0 to 1.3, set this
+to:</p>
+
+<p><code>SENSOR_FLAG_WAKE_UP | SENSOR_FLAG_ONE_SHOT_MODE</code> for <a
+href="{@docRoot}devices/sensors/report-modes.html#one-shot">one-shot</a>
+sensors</p>
+
+<p><code>SENSOR_FLAG_CONTINUOUS_MODE</code> for <a
+href="{@docRoot}devices/sensors/report-modes.html#continuous">continuous</a>
+sensors <code>SENSOR_FLAG_ON_CHANGE_MODE</code> for <a
+href="{@docRoot}devices/sensors/report-modes.html#on-change">on-change</a>
+sensors except <a href="#proximity">proximity</a>
+<code>SENSOR_FLAG_SPECIAL_REPORTING_MODE</code> for sensors with <a
+href="{@docRoot}devices/sensors/report-modes.html#special">special</a>
+reporting mode except for the <a
+href="{@docRoot}devices/sensors/sensor-types.html#tilt_detector">tilt
+detector</a>.</p>
+
+<p><code>SENSOR_FLAG_WAKE_UP | SENSOR_FLAG_ON_CHANGE_MODE</code> for the <a
+href="{@docRoot}devices/sensors/sensor-types.html#proximity">proximity</a> sensor and the Android official <a
+href="{@docRoot}devices/sensors/sensor-types.html#tilt_detector">tilt detector</a> sensor.</p>
+
+<h2>Notes when upgrading from 1_1 or 1_2</h2>
+<ul>
+  <li> The <code>batch</code> function now nearly-always succeeds, even for sensors that do not support
+batching, independently of the value of the timeout argument. The only cases
+where the <code>batch </code>function might fail are internal errors, or a bad
+<code>sensor_handle,</code> or negative <code>sampling_period_ns </code>or
+negative <code>max_report_latency_ns</code>.
+  <li> Whether a sensor supports batching is defined by whether it has a
+<code>fifoMaxEventCount </code>greater than 0. (In previous versions, it was
+based on the return value of <code>batch()</code>.
+  <li> Sensors that support batching are always in what we called the “batch
+mode” in previous versions: even if the <code>max_report_latency_ns</code> parameter is 0, the sensor must still be batched, meaning the events must be
+stored in the FIFO when the SoC goes to suspend mode.
+  <li> The <code>flags </code>parameter of the <code>batch</code> function is
+not used anymore. <code>DRY_RUN</code> and <code>WAKE_UPON_FIFO_FULL</code> are
+both deprecated, and will never be passed to the <code>batch</code> function.
+  <li> The batch timeout argument is now referred to as the
+<code>max_report_latency</code> argument.
+</ul>