Docs: Changes to source.android.com

  - 168737726 Removed "The" from strong tag, looked a little odd. by blamb <blamb@google.com>
  - 168627558 Add AOSP links to September bulletin by daroberts <daroberts@google.com>
  - 168588117 Update build numbers for Sep security releases by Android Partner Docs <noreply@android.com>
  - 168570150 Devsite localized content from translation request 5bfc63... by Android Partner Docs <noreply@android.com>
  - 168561824 Fix typos by Android Partner Docs <noreply@android.com>
  - 168485063 Add GNSS signal source to CTS Physical Environment Setup by claym <claym@google.com>
  - 168454940 Updating kernel patch instructions by hvm <hvm@google.com>
  - 168448636 Remove older version of the CDD from main dir. by gdimino <gdimino@google.com>
  - 168442618 Add "CTS Media 1.4" to "CTS Media Files" section by claym <claym@google.com>
  - 168413238 Updating AB image, splitting file, rewriting overview, up... by hvm <hvm@google.com>
  - 168364087 Added Armis folks to Acknowledgements page. by Android Partner Docs <noreply@android.com>
  - 168363885 Added CVE-2017-0781, CVE-2017-0782, CVE-2017-0783 and CVE... by Android Partner Docs <noreply@android.com>
  - 168035538 Updating link to Samsung blog (as it has changed) by Android Partner Docs <noreply@android.com>
  - 168022608 Added CVE to researcher acknowledgement section by Android Partner Docs <noreply@android.com>
  - 167909551 Updating CONFIG_MODVERSIONS description, O > 8.0 by hvm <hvm@google.com>
  - 167799301 Update CTS/CTS-Verifier downloads for CTS-Sep-2017 Releases by claym <claym@google.com>
  - 167784315 Add device manifest fragments doc by Android Partner Docs <noreply@android.com>
  - 167739678 Devsite localized content from translation request 01ecb1... by Android Partner Docs <noreply@android.com>
  - 167665215 Fix copy commands in hikey960 kernel steps to reflect new... by claym <claym@google.com>
  - 167620398 android.framework -> android.frameworks by Android Partner Docs <noreply@android.com>
  - 167606212 Add note about Google device updates in september bulletin by daroberts <daroberts@google.com>
  - 167603735 Adding block allocation tool by hvm <hvm@google.com>
  - 167601882 September 2017 security bulletin by daroberts <daroberts@google.com>
  - 167353047 Fixes for 8.0 CDD by gdimino <gdimino@google.com>
  - 167339303 Publishing the 8.0 CDD. by gdimino <gdimino@google.com>
  - 167332534 Remove orphaned page for devices/input/index.html. by blamb <blamb@google.com>
  - 167173631 Adding Jack images and minor tweaks to page for layout, s... by hvm <hvm@google.com>
  - 167022969 Add Keymaster 3 updates to site changes by daroberts <daroberts@google.com>
  - 167008059 Fix b.android.com link by daroberts <daroberts@google.com>
  - 166917869 Fix typo. by cqn <cqn@google.com>
  - 166905822 Keymaster 3 changes by daroberts <daroberts@google.com>
  - 166897040 Fix FMQ doc blockingRead/Write -> read/writeBlocking by Android Partner Docs <noreply@android.com>
  - 166768894 changing < to &lt; by hvm <hvm@google.com>
  - 166756537 Automated g4 rollback of changelist 163505078. by Android Partner Docs <noreply@android.com>

PiperOrigin-RevId: 168737726
Change-Id: Icc461a0b49b173fbdd59a0a01704d72539d972bc
diff --git a/en/compatibility/8.0/android-8.0-cdd.html b/en/compatibility/8.0/android-8.0-cdd.html
new file mode 100644
index 0000000..30b613d
--- /dev/null
+++ b/en/compatibility/8.0/android-8.0-cdd.html
@@ -0,0 +1,9433 @@
+<html devsite="" xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <title>
+      Android 8.0 Compatibility Definition
+    </title>
+    <meta name="project_path" value="/_project.yaml" />
+    <meta name="book_path" value="/_book.yaml" />
+  </head>
+  <body>
+    <!--
+      Copyright 2017 The Android Open Source Project
+
+      Licensed under the Apache License, Version 2.0 (the "License");
+      you may not use this file except in compliance with the License.
+      You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      See the License for the specific language governing permissions and
+      limitations under the License.
+  -->
+    <h2 id="1_introduction">
+      1. Introduction
+    </h2>
+    <p>
+      This document enumerates the requirements that must be met in order for devices to be compatible with Android 8.0.
+    </p>
+    <p>
+      The use of “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” is per the IETF standard defined in <a href="http://www.ietf.org/rfc/rfc2119.txt">RFC2119</a>.
+    </p>
+    <p>
+      As used in this document, a “device implementer” or “implementer” is a person or organization developing a hardware/software solution running Android 8.0. A “device implementation” or “implementation is the hardware/software solution so developed.
+    </p>
+    <p>
+      To be considered compatible with Android 8.0, device implementations MUST meet the requirements presented in this Compatibility Definition, including any documents incorporated via reference.
+    </p>
+    <p>
+      Where this definition or the software tests described in <a href="#10_software_compatibility_testing">section 10</a> is silent, ambiguous, or incomplete, it is the responsibility of the device implementer to ensure compatibility with existing implementations.
+    </p>
+    <p>
+      For this reason, the <a href="http://source.android.com/">Android Open Source Project</a> is both the reference and preferred implementation of Android. Device implementers are STRONGLY RECOMMENDED to base their implementations to the greatest extent possible on the “upstream” source code available from the Android Open Source Project. While some components can hypothetically be replaced with alternate implementations, it is STRONGLY RECOMMENDED to not follow this practice, as passing the software tests will become substantially more difficult. It is the implementer’s responsibility to ensure full behavioral compatibility with the standard Android implementation, including and beyond the Compatibility Test Suite. Finally, note that certain component substitutions and modifications are explicitly forbidden by this document.
+    </p>
+    <p>
+      Many of the resources linked to in this document are derived directly or indirectly from the Android SDK and will be functionally identical to the information in that SDK’s documentation. In any cases where this Compatibility Definition or the Compatibility Test Suite disagrees with the SDK documentation, the SDK documentation is considered authoritative. Any technical details provided in the linked resources throughout this document are considered by inclusion to be part of this Compatibility Definition.
+    </p>
+    <h3 id="1_1_document_structure">
+      1.1 Document Structure
+    </h3>
+    <h4 id="1_1_1_requirements_by_device_type">
+      1.1.1. Requirements by Device Type
+    </h4>
+    <p>
+      <a href="#2_device_types">Section 2</a> contains all the MUST and STRONGLY RECOMMENDED requirements that apply to a specific device type. Each subsection of <a href="#2_device_types">Section 2</a> is dedicated to a specific device type.
+    </p>
+    <p>
+      All the other requirements, that universally apply to any Android device implementations, are listed in the sections after <a href="#2_device_types">Section 2</a>. These requirements are referenced as "Core Requirements" in this document.
+    </p>
+    <h4 id="1_1_2_requirement_id">
+      1.1.2. Requirement ID
+    </h4>
+    <p>
+      Requirement ID is assigned for MUST requirements.
+    </p>
+    <ul>
+      <li>The ID is assigned for MUST requirements only.
+      </li>
+      <li>STRONGLY RECOMMENDED requirements are marked as [SR] but ID is not assigned.
+      </li>
+      <li>The ID consists of : Device Type ID - Condition ID - Requirement ID (e.g. C-0-1).
+      </li>
+    </ul>
+    <p>
+      Each ID is defined as below:
+    </p>
+    <ul>
+      <li>Device Type ID (see more on <a href="#2_device_types">2. Device Types</a>)
+        <ul>
+          <li>C: Core (Requirements that are applied to any Android device implementations)
+          </li>
+          <li>H: Android Handheld device
+          </li>
+          <li>T: Android Television device
+          </li>
+          <li>A: Android Automotive implementation
+          </li>
+          <li>W: Android Watch implementation
+          </li>
+        </ul>
+      </li>
+      <li>Condition ID
+        <ul>
+          <li>When the requirement is unconditional, this ID is set as 0.
+          </li>
+          <li>When the requirement is conditional, 1 is assinged for the 1st condition and the number increments by 1 within the same section and the same device type.
+          </li>
+        </ul>
+      </li>
+      <li>Requirement ID
+        <ul>
+          <li>This ID starts from 1 and increments by 1 within the same section and the same condition.
+          </li>
+        </ul>
+      </li>
+    </ul>
+    <h2 id="2_device_types">
+      2. Device Types
+    </h2>
+    <p>
+      While the Android Open Source Project provides a software stack that can be used for a variety of device types and form factors, there are a few device types that have a relatively better established application distribution ecosystem.
+    </p>
+    <p>
+      This section describes those device types, and additional requirements and recommendations applicable for each device type.
+    </p>
+    <p>
+      All Android device implementations that do not fit into any of the described device types MUST still meet all requirements in the other sections of this Compatibility Definition.
+    </p>
+    <h3 id="2_1_device_configurations">
+      2.1 Device Configurations
+    </h3>
+    <p>
+      For the major differences in hardware configuration by device type, see the device-specific requirements that follow in this section.
+    </p>
+    <h3 id="2_2_handheld_requirements">
+      2.2. Handheld Requirements
+    </h3>
+    <p>
+      An <strong>Android Handheld device</strong> refers to an Android device implementation that is typically used by holding it in the hand, such as an mp3 player, phone, or tablet.
+    </p>
+    <p>
+      Android device implementations are classified as a Handheld if they meet all the following criteria:
+    </p>
+    <ul>
+      <li>Have a power source that provides mobility, such as a battery.
+      </li>
+      <li>Have a physical diagonal screen size in the range of 2.5 to 8 inches.
+      </li>
+    </ul>
+    <p>
+      The additional requirements in the rest of this section are specific to Android Handheld device implementations.
+    </p>
+    <div class="note">
+      <b>Note:</b> Requirements that do not apply to Android Tablet devices are marked with an *.
+    </div>
+    <h4 id="2_2_1_hardware">
+      2.2.1. Hardware
+    </h4>
+    <p>
+      <strong>Screen Size (Section 7.1.1.1)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>[H-0-1] MUST have a screen at least 2.5 inches in physical diagonal size.<sup>*</sup>
+      </li>
+    </ul>
+    <p>
+      <strong>Screen Density (Section 7.1.1.3)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>[H-SR] Are STRONGLY RECOMMENDED to provide users an affordance to change the display size.
+      </li>
+    </ul>
+    <p>
+      <strong>Legacy Application Compatibility Mode (Section 7.1.5)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>[H-0-1] MUST include support for legacy application compatibility mode as implemented by the upstream Android open source code. That is, device implementations MUST NOT alter the triggers or thresholds at which compatibility mode is activated, and MUST NOT alter the behavior of the compatibility mode itself.
+      </li>
+    </ul>
+    <p>
+      <strong>Keyboard (Section 7.2.1)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>[H-0-1] MUST include support for third-party Input Method Editor (IME) applications.
+      </li>
+    </ul>
+    <p>
+      <strong>Navigation Keys (Section 7.2.3)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [H-0-1] MUST provide the Home, Recents, and Back functions.
+        </p>
+      </li>
+      <li>
+        <p>
+          [H-0-2] MUST send both the normal and long press event of the Back function (<a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BACK"><code>KEYCODE_BACK</code></a>) to the foreground application.
+        </p>
+      </li>
+    </ul>
+    <p>
+      <strong>Touchscreen Input (Section 7.2.4)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>[H-0-1] MUST support touchscreen input.
+      </li>
+    </ul>
+    <p>
+      <strong>Accelerometer (Section 7.3.1)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>[H-SR] Are STRONGLY RECOMMENDED to include a 3-axis accelerometer.
+      </li>
+    </ul>
+    <p>
+      If Handheld device implementations include a 3-axis accelerometer, they:
+    </p>
+    <ul>
+      <li>[H-1-1] MUST be able to report events up to a frequency of at least 100 Hz.
+      </li>
+    </ul>
+    <p>
+      <strong>Gyroscope (Section 7.3.4)</strong>
+    </p>
+    <p>
+      If Handheld device implementations include a gyroscope, they:
+    </p>
+    <ul>
+      <li>[H-1-1] MUST be able to report events up to a frequency of at least 100 Hz.
+      </li>
+    </ul>
+    <p>
+      <strong>Proximity Sensor (Section 7.3.8 )</strong>
+    </p>
+    <p>
+      Handheld device implementations that can make a voice call and indicate any value other than <code>PHONE_TYPE_NONE</code> in <code>getPhoneType</code>:
+    </p>
+    <ul>
+      <li>SHOULD include a proximity sensor.
+      </li>
+    </ul>
+    <p>
+      <strong>Pose Sensor (Section 7.3.12)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>Are RECOMMENDED to support pose sensor with 6 degrees of freedom.
+      </li>
+    </ul>
+    <p>
+      <strong>Bluetooth (Section 7.4.3)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>SHOULD include support for Bluetooth and Bluetooth LE.
+      </li>
+    </ul>
+    <p>
+      <strong>Data Saver (Section 7.4.7)</strong>
+    </p>
+    <p>
+      If Handheld device implementations include a metered connection, they:
+    </p>
+    <ul>
+      <li>[H-1-1] MUST provide the data saver mode.
+      </li>
+    </ul>
+    <p>
+      <strong>Minimum Memory and Storage (Section 7.6.1)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>[H-0-1] MUST have at least 4GB of non-volatile storage available for application private data (a.k.a. "/data" partition)
+      </li>
+      <li>[H-0-2] MUST return “true” for <code>ActivityManager.isLowRamDevice()</code> when there is less than 1GB of memory available to the kernel and userspace.
+      </li>
+    </ul>
+    <p>
+      If Handheld device implementations are 32-bit:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [H-1-1] The memory available to the kernel and userspace MUST be at least 512MB if any of the following densities are used:
+        </p>
+        <ul>
+          <li>280dpi or lower on small/normal screens<sup>*</sup>
+          </li>
+          <li>ldpi or lower on extra large screens
+          </li>
+          <li>mdpi or lower on large screens
+          </li>
+        </ul>
+      </li>
+      <li>
+        <p>
+          [H-2-1] The memory available to the kernel and userspace MUST be at least 608MB if any of the following densities are used:
+        </p>
+        <ul>
+          <li>xhdpi or higher on small/normal screens<sup>*</sup>
+          </li>
+          <li>hdpi or higher on large screens
+          </li>
+          <li>mdpi or higher on extra large screens
+          </li>
+        </ul>
+      </li>
+      <li>
+        <p>
+          [H-3-1] The memory available to the kernel and userspace MUST be at least 896MB if any of the following densities are used:
+        </p>
+        <ul>
+          <li>400dpi or higher on small/normal screens<sup>*</sup>
+          </li>
+          <li>xhdpi or higher on large screens
+          </li>
+          <li>tvdpi or higher on extra large screens
+          </li>
+        </ul>
+      </li>
+      <li>
+        <p>
+          [H-4-1] The memory available to the kernel and userspace MUST be at least 1344MB if any of the following densities are used:
+        </p>
+        <ul>
+          <li>560dpi or higher on small/normal screens<sup>*</sup>
+          </li>
+          <li>400dpi or higher on large screens
+          </li>
+          <li>xhdpi or higher on extra large screens
+          </li>
+        </ul>
+      </li>
+    </ul>
+    <p>
+      If Handheld device implementations are 64-bit:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [H-5-1] The memory available to the kernel and userspace MUST be at least 816MB if any of the following densities are used:
+        </p>
+        <ul>
+          <li>280dpi or lower on small/normal screens<sup>*</sup>
+          </li>
+          <li>ldpi or lower on extra large screens
+          </li>
+          <li>mdpi or lower on large screens
+          </li>
+        </ul>
+      </li>
+      <li>
+        <p>
+          [H-6-1] The memory available to the kernel and userspace MUST be at least 944MB if any of the following densities are used:
+        </p>
+        <ul>
+          <li>xhdpi or higher on small/normal screens<sup>*</sup>
+          </li>
+          <li>hdpi or higher on large screens
+          </li>
+          <li>mdpi or higher on extra large screens
+          </li>
+        </ul>
+      </li>
+      <li>
+        <p>
+          [H-7-1] The memory available to the kernel and userspace MUST be at least 1280MB if any of the following densities are used:
+        </p>
+        <ul>
+          <li>400dpi or higher on small/normal screens<sup>*</sup>
+          </li>
+          <li>xhdpi or higher on large screens
+          </li>
+          <li>tvdpi or higher on extra large screens
+          </li>
+        </ul>
+      </li>
+      <li>
+        <p>
+          [H-8-1] The memory available to the kernel and userspace MUST be at least 1824MB if any of the following densities are used:
+        </p>
+        <ul>
+          <li>560dpi or higher on small/normal screens<sup>*</sup>
+          </li>
+          <li>400dpi or higher on large screens
+          </li>
+          <li>xhdpi or higher on extra large screens
+          </li>
+        </ul>
+      </li>
+    </ul>
+    <p>
+      Note that the "memory available to the kernel and userspace" above refers to the memory space provided in addition to any memory already dedicated to hardware components such as radio, video, and so on that are not under the kernel’s control on device implementations.
+    </p>
+    <p>
+      <strong>Application Shared Storage (Section 7.6.2)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>[H-0-1] MUST NOT provide an application shared storage smaller than 1 GiB.
+      </li>
+    </ul>
+    <p>
+      <strong>USB peripheral mode (Section 7.7.1)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>SHOULD include a USB port supporting peripheral mode.
+      </li>
+    </ul>
+    <p>
+      If handheld device implementations include a USB port supporting peripheral mode, they:
+    </p>
+    <ul>
+      <li>[H-1-1] MUST implement the Android Open Accessory (AOA) API.<sup>*</sup>
+      </li>
+    </ul>
+    <p>
+      <strong>Microphone (Section 7.8.1)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>[H-0-1] MUST include a microphone.
+      </li>
+    </ul>
+    <p>
+      <strong>Audio Output (Section 7.8.2)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>[H-0-1] MUST have an audio output and declare <code>android.hardware.audio.output</code>.
+      </li>
+    </ul>
+    <p>
+      <strong>Virtual Reality Mode (Section 7.9.1)</strong>
+    </p>
+    <p>
+      If Handheld device implementations include support for the VR mode, they:
+    </p>
+    <ul>
+      <li>[H-1-1] MUST declare the <code>android.software.vr.mode</code> feature.<sup>*</sup>
+      </li>
+    </ul>
+    <p>
+      If device implementations declare <code>android.software.vr.mode</code> feature, they:
+    </p>
+    <ul>
+      <li>[H-2-1] MUST include an application implementing <code>android.service.vr.VrListenerService</code> that can be enabled by VR applications via <code>android.app.Activity#setVrModeEnabled</code>.<sup>*</sup>
+      </li>
+    </ul>
+    <p>
+      <strong>Virtual Reality High Performance (Section 7.9.2)</strong>
+    </p>
+    <p>
+      If Handheld device implementations are capable of meeting all the requirements to declare the <code>android.hardware.vr.high_performance</code> feature flag, they:
+    </p>
+    <ul>
+      <li>[H-1-1] MUST declare the <code>android.hardware.vr.high_performance</code> feature flag.<sup>*</sup>
+      </li>
+    </ul>
+    <h4 id="2_2_2_multimedia">
+      2.2.2. Multimedia
+    </h4>
+    <p>
+      <strong>Audio Encoding (Section 5.1.1)</strong>
+    </p>
+    <p>
+      Handheld device implementations MUST support the following audio encoding:
+    </p>
+    <ul>
+      <li>[H-0-1] AMR-NB
+      </li>
+      <li>[H-0-2] AMR-WB
+      </li>
+      <li>[H-0-3] MPEG-4 AAC Profile (AAC LC)
+      </li>
+      <li>[H-0-4] MPEG-4 HE AAC Profile (AAC+)
+      </li>
+      <li>[H-0-5] AAC ELD (enhanced low delay AAC)
+      </li>
+    </ul>
+    <p>
+      <strong>Audio Decoding (Section 5.1.2)</strong>
+    </p>
+    <p>
+      Handheld device implementations MUST support the following audio decoding:
+    </p>
+    <ul>
+      <li>[H-0-1] AMR-NB
+      </li>
+      <li>[H-0-2] AMR-WB
+      </li>
+    </ul>
+    <p>
+      <strong>Video Encoding (Section 5.2)</strong>
+    </p>
+    <p>
+      Handheld device implementations MUST support the following video encoding and make it available to third-party applications:
+    </p>
+    <ul>
+      <li>[H-0-1] H.264 AVC
+      </li>
+      <li>[H-0-2] VP8
+      </li>
+    </ul>
+    <p>
+      <strong>Video Decoding (Section 5.3)</strong>
+    </p>
+    <p>
+      Handheld device implementations MUST support the following video decoding:
+    </p>
+    <ul>
+      <li>[H-0-1] H.264 AVC.
+      </li>
+      <li>[H-0-2] H.265 HEVC.
+      </li>
+      <li>[H-0-3] MPEG-4 SP.
+      </li>
+      <li>[H-0-4] VP8.
+      </li>
+      <li>[H-0-5] VP9.
+      </li>
+    </ul>
+    <h4 id="2_2_3_software">
+      2.2.3. Software
+    </h4>
+    <p>
+      <strong>WebView Compatibility (Section 3.4.1)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>[H-0-1] MUST provide a complete implementation of the <code>android.webkit.Webview</code> API.
+      </li>
+    </ul>
+    <p>
+      <strong>Browser Compatibility (Section 3.4.2)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>[H-0-1] MUST include a standalone Browser application for general user web browsing.
+      </li>
+    </ul>
+    <p>
+      <strong>Launcher (Section 3.8.1)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [H-SR] Are STRONGLY RECOMMENDED to implement a default launcher that supports in-app pinning of shortcuts and widgets.
+        </p>
+      </li>
+      <li>
+        <p>
+          [H-SR] Are STRONGLY RECOMMENDED to implement a default launcher that provides quick access to the additional shortcuts provided by third-party apps through the <a href="https://developer.android.com/reference/android/content/pm/ShortcutManager.html">ShortcutManager</a> API.
+        </p>
+      </li>
+      <li>
+        <p>
+          [H-SR] Are STRONGLY RECOMMENDED to include a default launcher app that shows badges for the app icons.
+        </p>
+      </li>
+    </ul>
+    <p>
+      <strong>Widgets (Section 3.8.2)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>[H-SR] Are STRONGLY RECOMMENDED to support third-party app widgets.
+      </li>
+    </ul>
+    <p>
+      <strong>Notifications (Section 3.8.3)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>[H-0-1] MUST allow third-party apps to notify users of notable events through the <a href="https://developer.android.com/reference/android/app/Notification.html"><code>Notification</code></a> and <a href="https://developer.android.com/reference/android/app/NotificationManager.html"><code>NotificationManager</code></a> API classes.
+      </li>
+      <li>[H-0-2] MUST support rich notifications.
+      </li>
+      <li>[H-0-3] MUST support heads-up notifications.
+      </li>
+      <li>[H-0-4] MUST include a notification shade, providing the user the ability to directly control (e.g. reply, snooze, dismiss, block) the notifications through user affordance such as action buttons or the control panel as implemented in the AOSP.
+      </li>
+    </ul>
+    <p>
+      <strong>Search (Section 3.8.4)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>[H-SR] Are STRONGLY RECOMMENDED to implement an assistant on the device to handle the <a href="http://developer.android.com/reference/android/content/Intent.html#ACTION_ASSIST">Assist action</a>.
+      </li>
+    </ul>
+    <p>
+      <strong>Lock Screen Media Control (Section 3.8.10)</strong>
+    </p>
+    <p>
+      If Android Handheld device implementations support a lock screen,they:
+    </p>
+    <ul>
+      <li>[H-1-1] MUST display the Lock screen Notifications including the Media Notification Template.
+      </li>
+    </ul>
+    <p>
+      <strong>Device administration (Section 3.9)</strong>
+    </p>
+    <p>
+      If Handheld device implementations support a secure lock screen, they:
+    </p>
+    <ul>
+      <li>[H-1-1] MUST implement the full range of <a href="http://developer.android.com/guide/topics/admin/device-admin.html">device administration</a> policies defined in the Android SDK documentation.
+      </li>
+    </ul>
+    <p>
+      <strong>Accessibility (Section 3.10)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [H-SR] MUST support third-party accessibility services.
+        </p>
+      </li>
+      <li>
+        <p>
+          [H-SR] Are STRONGLY RECOMMENDED to preload accessibility services on the device comparable with or exceeding functionality of the Switch Access and TalkBack (for languages supported by the preloaded Text-to-speech engine) accessibility services as provided in the <a href="https://github.com/google/talkback">talkback open source project</a>.
+        </p>
+      </li>
+    </ul>
+    <p>
+      <strong>Text-to-Speech (Section 3.11)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [H-0-1] MUST support installation of third-party TTS engines.
+        </p>
+      </li>
+      <li>
+        <p>
+          [H-SR] Are STRONGLY RECOMMENDED to include a TTS engine supporting the languages available on the device.
+        </p>
+      </li>
+    </ul>
+    <p>
+      <strong>Quick Settings (Section 3.13)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>[H-SR] Are STRONGLY RECOMMENDED to include a Quick Settings UI component.
+      </li>
+    </ul>
+    <p>
+      <strong>Companion Device Pairing (Section 3.15)</strong>
+    </p>
+    <p>
+      If Android handheld device implementations declare <code>FEATURE_BLUETOOTH</code> or <code>FEATURE_WIFI</code> support, they:
+    </p>
+    <ul>
+      <li>[H-1-1] MUST support the companion device pairing feature.
+      </li>
+    </ul>
+    <h4 id="2_2_4_performance_and_power">
+      2.2.4. Performance and Power
+    </h4>
+    <p>
+      <strong>User Experience Consistency (Section 8.1)</strong>
+    </p>
+    <p>
+      For handheld device implementations:
+    </p>
+    <ul>
+      <li>[H-0-1] <strong>Consistent frame latency</strong>. Inconsistent frame latency or a delay to render frames MUST NOT happen more often than 5 frames in a second, and SHOULD be below 1 frames in a second.
+      </li>
+      <li>[H-0-2] <strong>User interface latency</strong>. Device implementations MUST ensure low latency user experience by scrolling a list of 10K list entries as defined by the Android Compatibility Test Suite (CTS) in less than 36 secs.
+      </li>
+      <li>[H-0-3] <strong>Task switching</strong>. When multiple applications have been launched, re-launching an already-running application after it has been launched MUST take less than 1 second.
+      </li>
+    </ul>
+    <p>
+      <strong>File I/O Access Performance (Section 8.2)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>[H-0-1] MUST ensure a sequential write performance of at least 5 MB/s.
+      </li>
+      <li>[H-0-2] MUST ensure a random write performance of at least 0.5 MB/s.
+      </li>
+      <li>[H-0-3] MUST ensure a sequential read performance of at least 15 MB/s.
+      </li>
+      <li>[H-0-4] MUST ensure a random read performance of at least 3.5 MB/s.
+      </li>
+    </ul>
+    <p>
+      <strong>Power-Saving Modes (Section 8.3)</strong>
+    </p>
+    <p>
+      For handheld device implementations:
+    </p>
+    <ul>
+      <li>[H-0-1] All Apps exempted from App Standby and Doze power-saving modes MUST be made visible to the end user.
+      </li>
+      <li>[H-0-2] The triggering, maintenance, wakeup algorithms and the use of global system settings of App Standby and Doze power-saving modes MUST not deviate from the Android Open Source Project.
+      </li>
+    </ul>
+    <p>
+      <strong>Power Consumption Accounting (Sections 8.4)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>[H-0-1] MUST provide a per-component power profile that defines the <a href="http://source.android.com/devices/tech/power/values.html">current consumption value</a> for each hardware component and the approximate battery drain caused by the components over time as documented in the Android Open Source Project site.
+      </li>
+      <li>[H-0-2] MUST report all power consumption values in milliampere hours (mAh).
+      </li>
+      <li>[H-0-3] MUST report CPU power consumption per each process's UID. The Android Open Source Project meets the requirement through the <code>uid_cputime</code> kernel module implementation.
+      </li>
+      <li>[H-0-4] MUST make this power usage available via the <a href="http://source.android.com/devices/tech/power/batterystats.html"><code>adb shell dumpsys batterystats</code></a> shell command to the app developer.
+      </li>
+      <li>SHOULD be attributed to the hardware component itself if unable to attribute hardware component power usage to an application.
+      </li>
+    </ul>
+    <p>
+      If Handheld device implementations include a screen or video output, they:
+    </p>
+    <ul>
+      <li>[H-1-1] MUST honor the <a href="http://developer.android.com/reference/android/content/Intent.html#ACTION_POWER_USAGE_SUMMARY"><code>android.intent.action.POWER_USAGE_SUMMARY</code></a> intent and display a settings menu that shows this power usage.
+      </li>
+    </ul>
+    <h4 id="2_2_5_security_model">
+      2.2.5. Security Model
+    </h4>
+    <p>
+      <strong>Permissions (Sections 9.1)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>[H-0-1] MUST allow third-party apps to access the usage statistics via the <code>android.permission.PACKAGE_USAGE_STATS</code> permission and provide a user-accessible mechanism to grant or revoke access to such apps in response to the <a href="https://developer.android.com/reference/android/provider/Settings.html#ACTION&amp;lowbar;USAGE&amp;lowbar;ACCESS&amp;lowbar;SETTINGS"><code>android.settings.ACTION_USAGE_ACCESS_SETTINGS</code></a> intent.
+      </li>
+    </ul>
+    <h3 id="2_3_television_requirements">
+      2.3. Television Requirements
+    </h3>
+    <p>
+      An <strong>Android Television device</strong> refers to an Android device implementation that is an entertainment interface for consuming digital media, movies, games, apps, and/or live TV for users sitting about ten feet away (a “lean back” or “10-foot user interface”).
+    </p>
+    <p>
+      Android device implementations are classified as a Television if they meet all the following criteria:
+    </p>
+    <ul>
+      <li>Have provided a mechanism to remotely control the rendered user interface on the display that might sit ten feet away from the user.
+      </li>
+      <li>Have an embedded screen display with the diagonal length larger than 24 inches OR include a video output port, such as VGA, HDMI, DisplayPort or a wireless port for display.
+      </li>
+    </ul>
+    <p>
+      The additional requirements in the rest of this section are specific to Android Television device implementations.
+    </p>
+    <h4 id="2_3_1_hardware">
+      2.3.1. Hardware
+    </h4>
+    <p>
+      <strong>Non-touch Navigation (Section 7.2.2)</strong>
+    </p>
+    <p>
+      Television device implementations:
+    </p>
+    <ul>
+      <li>[T-0-1] MUST support <a href="https://developer.android.com/reference/android/content/res/Configuration.html#NAVIGATION_DPAD">D-pad</a>.
+      </li>
+    </ul>
+    <p>
+      <strong>Navigation Keys (Section 7.2.3)</strong>
+    </p>
+    <p>
+      Television device implementations:
+    </p>
+    <ul>
+      <li>[T-0-1] MUST provide the Home and Back functions.
+      </li>
+      <li>[T-0-2] MUST send both the normal and long press event of the Back function (<a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BACK"><code>KEYCODE_BACK</code></a>) to the foreground application.
+      </li>
+    </ul>
+    <p>
+      <strong>Button Mappings (Section 7.2.6.1)</strong>
+    </p>
+    <p>
+      Television device implementations:
+    </p>
+    <ul>
+      <li>[T-0-1] MUST include support for game controllers and declare the <code>android.hardware.gamepad</code> feature flag.
+      </li>
+    </ul>
+    <p>
+      <strong>Remote Control (Section 7.2.7)</strong>
+    </p>
+    <p>
+      Television device implementations:
+    </p>
+    <ul>
+      <li>SHOULD provide a remote control from which users can access <a href="#7_2_2_non-touch_navigation">non-touch navigation</a> and <a href="#7_2_3_navigation_keys">core navigation keys</a> inputs.
+      </li>
+    </ul>
+    <p>
+      <strong>Gyroscope (Section 7.3.4)</strong>
+    </p>
+    <p>
+      If Television device implementations include a gyroscope, they:
+    </p>
+    <ul>
+      <li>[T-1-1] MUST be able to report events up to a frequency of at least 100 Hz.
+      </li>
+    </ul>
+    <p>
+      <strong>Bluetooth (Section 7.4.3)</strong>
+    </p>
+    <p>
+      Television device implementations:
+    </p>
+    <ul>
+      <li>[T-0-1] MUST support Bluetooth and Bluetooth LE.
+      </li>
+    </ul>
+    <p>
+      <strong>Minimum Memory and Storage (Section 7.6.1)</strong>
+    </p>
+    <p>
+      Television device implementations:
+    </p>
+    <ul>
+      <li>[T-0-1] MUST have at least 4GB of non-volatile storage available for application private data (a.k.a. "/data" partition)
+      </li>
+    </ul>
+    <p>
+      <strong>Microphone (Section 7.8.1)</strong>
+    </p>
+    <p>
+      Television device implementations:
+    </p>
+    <ul>
+      <li>SHOULD include a microphone.
+      </li>
+    </ul>
+    <p>
+      <strong>Audio Output (Section 7.8.2)</strong>
+    </p>
+    <p>
+      Television device implementations:
+    </p>
+    <ul>
+      <li>[T-0-1] MUST have an audio output and declare <code>android.hardware.audio.output</code>.
+      </li>
+    </ul>
+    <h4 id="2_3_2_multimedia">
+      2.3.2. Multimedia
+    </h4>
+    <p>
+      <strong>Audio Encoding (Section 5.1)</strong>
+    </p>
+    <p>
+      Television device implementations MUST support the following audio encoding:
+    </p>
+    <ul>
+      <li>[T-0-1] MPEG-4 AAC Profile (AAC LC)
+      </li>
+      <li>[T-0-2] MPEG-4 HE AAC Profile (AAC+)
+      </li>
+      <li>[T-0-3] AAC ELD (enhanced low delay AAC)
+      </li>
+    </ul>
+    <p>
+      <strong>Video Encoding (Section 5.2)</strong>
+    </p>
+    <p>
+      Television device implementations MUST support the following video encoding:
+    </p>
+    <ul>
+      <li>[T-0-1] H.264 AVC
+      </li>
+      <li>[T-0-2] VP8
+      </li>
+    </ul>
+    <p>
+      <strong>H-264 (Section 5.2.2)</strong>
+    </p>
+    <p>
+      Television device implementations are:
+    </p>
+    <ul>
+      <li>[T-SR] STRONGLY RECOMMENDED to support H.264 encoding of 720p and 1080p resolution videos.
+      </li>
+      <li>[T-SR] STRONGLY RECOMMENDED to support H.264 encoding of 1080p resolution video at 30 frame-per-second (fps).
+      </li>
+    </ul>
+    <p>
+      <strong>Video Decoding (Section 5.3)</strong>
+    </p>
+    <p>
+      Television device implementations MUST support the following video decoding:
+    </p>
+    <ul>
+      <li>[T-0-1] H.264 AVC
+      </li>
+      <li>[T-0-2] H.265 HEVC
+      </li>
+      <li>[T-0-3] MPEG-4 SP
+      </li>
+      <li>[T-0-4] VP8
+      </li>
+      <li>[T-0-5] VP9
+      </li>
+    </ul>
+    <p>
+      Television device implementations are STRONGLY RECOMMENDED to support the following video decoding:
+    </p>
+    <ul>
+      <li>[T-SR] MPEG-2
+      </li>
+    </ul>
+    <p>
+      <strong>H.264 (Section 5.3.4)</strong>
+    </p>
+    <p>
+      If Television device implementations support H.264 decoders, they:
+    </p>
+    <ul>
+      <li>[T-1-1] MUST support High Profile Level 4.2 and the HD 1080p (at 60 fps) decoding profile.
+      </li>
+      <li>[T-1-2] MUST be capable of decoding videos with both HD profiles as indicated in the following table and encoded with either the Baseline Profile, Main Profile, or the High Profile Level 4.2
+      </li>
+    </ul>
+    <p>
+      <strong>H.265 (HEVC) (Section 5.3.5)</strong>
+    </p>
+    <p>
+      If Television device implementations support H.265 codec and the HD 1080p decoding profile, they:
+    </p>
+    <ul>
+      <li>[T-1-1] MUST support the Main Profile Level 4.1 Main tier.
+      </li>
+      <li>[T-SR] Are STRONGLY RECOMMENDED to support 60 fps video frame rate for HD 1080p.
+      </li>
+    </ul>
+    <p>
+      If Television device implementations support H.265 codec and the UHD decoding profile, then:
+    </p>
+    <ul>
+      <li>[T-2-1] The codec MUST support Main10 Level 5 Main Tier profile.
+      </li>
+    </ul>
+    <p>
+      <strong>VP8 (Section 5.3.6)</strong>
+    </p>
+    <p>
+      If Television device implementations support VP8 codec, they:
+    </p>
+    <ul>
+      <li>[T-1-1] MUST support the HD 1080p60 decoding profile.
+      </li>
+    </ul>
+    <p>
+      If Television device implementations support VP8 codec and support 720p, they:
+    </p>
+    <ul>
+      <li>[T-2-1] MUST support the HD 720p60 decoding profile.
+      </li>
+    </ul>
+    <p>
+      <strong>VP9 (Section 5.3.7)</strong>
+    </p>
+    <p>
+      If Television device implementations support VP9 codec and the UHD video decoding, they:
+    </p>
+    <ul>
+      <li>[T-1-1] MUST support 8-bit color depth and SHOULD support VP9 Profile 2 (10-bit).
+      </li>
+    </ul>
+    <p>
+      If Television device implementations support VP9 codec, the 1080p profile and VP9 hardware decoding, they:
+    </p>
+    <ul>
+      <li>[T-2-1] MUST support 60 fps for 1080p.
+      </li>
+    </ul>
+    <p>
+      <strong>Secure Media (Section 5.8)</strong>
+    </p>
+    <p>
+      If device implementations are Android Television devices and support 4K resolution, they:
+    </p>
+    <ul>
+      <li>[T-1-1] MUST support HDCP 2.2 for all wired external displays.
+      </li>
+    </ul>
+    <p>
+      If Television device implementations don't support 4K resolution, they:
+    </p>
+    <ul>
+      <li>[T-2-1] MUST support HDCP 1.4 for all wired external displays.
+      </li>
+    </ul>
+    <p>
+      Television device implementations:
+    </p>
+    <ul>
+      <li>[T-SR] Are STRONGLY RECOMMENDED to support simulataneous decoding of secure streams. At minimum, simultaneous decoding of two steams is STRONGLY RECOMMENDED.
+      </li>
+    </ul>
+    <p>
+      <strong>Audio Output Volume (Section 5.5.3)</strong>
+    </p>
+    <p>
+      Television device implementations:
+    </p>
+    <ul>
+      <li>[T-0-1] MUST include support for system Master Volume and digital audio output volume attenuation on supported outputs, except for compressed audio passthrough output (where no audio decoding is done on the device).
+      </li>
+    </ul>
+    <h4 id="2_3_3_software">
+      2.3.3. Software
+    </h4>
+    <p>
+      Television device implementations:
+    </p>
+    <ul>
+      <li>[T-0-1] MUST declare the features <a href="http://developer.android.com/reference/android/content/pm/PackageManager.html#FEATURE_LEANBACK"><code>android.software.leanback</code></a> and <code>android.hardware.type.television</code>.
+      </li>
+    </ul>
+    <p>
+      <strong>WebView compatibility (Section 3.4.1)</strong>
+    </p>
+    <p>
+      Television device implementations:
+    </p>
+    <ul>
+      <li>[T-0-1] MUST provide a complete implementation of the <code>android.webkit.Webview</code> API.
+      </li>
+    </ul>
+    <p>
+      <strong>Lock Screen Media Control (Section 3.8.10)</strong>
+    </p>
+    <p>
+      If Android Television device implementations support a lock screen,they:
+    </p>
+    <ul>
+      <li>[T-1-1] MUST display the Lock screen Notifications including the Media Notification Template.
+      </li>
+    </ul>
+    <p>
+      <strong>Multi-windows (Section 3.8.14)</strong>
+    </p>
+    <p>
+      Television device implementations:
+    </p>
+    <ul>
+      <li>[T-SR] Are STRONGLY RECOMMENDED to support picture-in-picture (PIP) mode multi-window.
+      </li>
+    </ul>
+    <p>
+      <strong>Accessibility (Section 3.10)</strong>
+    </p>
+    <p>
+      Television device implementations:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [T-SR] MUST support third-party accessibility services.
+        </p>
+      </li>
+      <li>
+        <p>
+          [T-SR] Android Television device implementations are STRONGLY RECOMMENDED to preload accessibility services on the device comparable with or exceeding functionality of the Switch Access and TalkBack (for languages supported by the preloaded Text-to-speech engine) accessibility services as provided in the <a href="https://github.com/google/talkback">talkback open source project</a>.
+        </p>
+      </li>
+    </ul>
+    <p>
+      <strong>Text-to-Speech (Section 3.11)</strong>
+    </p>
+    <p>
+      If device implementations report the feature android.hardware.audio.output, they:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [T-SR] STRONGLY RECOMMENDED to include a TTS engine supporting the languages available on the device.
+        </p>
+      </li>
+      <li>
+        <p>
+          [T-0-1] MUST support installation of third-party TTS engines.
+        </p>
+      </li>
+    </ul>
+    <p>
+      <strong>TV Input Framework (Section 3.12)</strong>
+    </p>
+    <p>
+      Television device implementations:
+    </p>
+    <ul>
+      <li>[T-0-1] MUST support TV Input Framework.
+      </li>
+    </ul>
+    <h4 id="2_3_4_performance_and_power">
+      2.3.4. Performance and Power
+    </h4>
+    <p>
+      <strong>User Experience Consistency (Section 8.1)</strong>
+    </p>
+    <p>
+      For Television device implementations:
+    </p>
+    <ul>
+      <li>[T-0-1] <strong>Consistent frame latency</strong>. Inconsistent frame latency or a delay to render frames MUST NOT happen more often than 5 frames in a second, and SHOULD be below 1 frames in a second.
+      </li>
+    </ul>
+    <p>
+      <strong>File I/O Access Performance (Section 8.2)</strong>
+    </p>
+    <p>
+      Television device implementations:
+    </p>
+    <ul>
+      <li>[T-0-1] MUST ensure a sequential write performance of at least 5MB/s.
+      </li>
+      <li>[T-0-2] MUST ensure a random write performance of at least 0.5MB/s.
+      </li>
+      <li>[T-0-3] MUST ensure a sequential read performance of at least 15MB/s.
+      </li>
+      <li>[T-0-4] MUST ensure a random read performance of at least 3.5MB/s.
+      </li>
+    </ul>
+    <p>
+      <strong>Power-Saving Modes (Section 8.3)</strong>
+    </p>
+    <p>
+      For Television device implementations:
+    </p>
+    <ul>
+      <li>[T-0-1] All Apps exempted from App Standby and Doze power-saving modes MUST be made visible to the end user.
+      </li>
+      <li>[T-0-2] The triggering, maintenance, wakeup algorithms and the use of global system settings of App Standby and Doze power-saving modes MUST not deviate from the Android Open Source Project.
+      </li>
+    </ul>
+    <p>
+      <strong>Power Consumption Accounting (Sections 8.4)</strong>
+    </p>
+    <p>
+      Television device implementations:
+    </p>
+    <ul>
+      <li>[T-0-1] MUST provide a per-component power profile that defines the <a href="http://source.android.com/devices/tech/power/values.html">current consumption value</a> for each hardware component and the approximate battery drain caused by the components over time as documented in the Android Open Source Project site.
+      </li>
+      <li>[T-0-2] MUST report all power consumption values in milliampere hours (mAh).
+      </li>
+      <li>[T-0-3] MUST report CPU power consumption per each process's UID. The Android Open Source Project meets the requirement through the <code>uid_cputime</code> kernel module implementation.
+      </li>
+      <li>SHOULD be attributed to the hardware component itself if unable to attribute hardware component power usage to an application.
+      </li>
+      <li>[T-0-4] MUST make this power usage available via the <a href="http://source.android.com/devices/tech/power/batterystats.html"><code>adb shell dumpsys batterystats</code></a> shell command to the app developer.
+      </li>
+    </ul>
+    <h3 id="2_4_watch_requirements">
+      2.4. Watch Requirements
+    </h3>
+    <p>
+      An <strong>Android Watch device</strong> refers to an Android device implementation intended to be worn on the body, perhaps on the wrist.
+    </p>
+    <p>
+      Android device implementations are classified as a Watch if they meet all the following criteria:
+    </p>
+    <ul>
+      <li>Have a screen with the physical diagonal length in the range from 1.1 to 2.5 inches.
+      </li>
+      <li>Have a mechanism provided to be worn on the body.
+      </li>
+    </ul>
+    <p>
+      The additional requirements in the rest of this section are specific to Android Watch device implementations.
+    </p>
+    <h4 id="2_4_1_hardware">
+      2.4.1. Hardware
+    </h4>
+    <p>
+      <strong>Screen Size (Section 7.1.1.1)</strong>
+    </p>
+    <p>
+      Watch device implementations:
+    </p>
+    <ul>
+      <li>[W-0-1] MUST have a screen with the physical diagonal size in the range from 1.1 to 2.5 inches.
+      </li>
+    </ul>
+    <p>
+      <strong>Navigation Keys (Section 7.2.3)</strong>
+    </p>
+    <p>
+      Watch device implementations:
+    </p>
+    <ul>
+      <li>[W-0-1] MUST have the Home function available to the user, and the Back function except for when it is in <code>UI_MODE_TYPE_WATCH</code>.
+      </li>
+    </ul>
+    <p>
+      <strong>Touchscreen Input (Section 7.2.4)</strong>
+    </p>
+    <p>
+      Watch device implementations:
+    </p>
+    <ul>
+      <li>[W-0-2] MUST support touchscreen input.
+      </li>
+    </ul>
+    <p>
+      <strong>Accelerometer (Section 7.3.1)</strong>
+    </p>
+    <p>
+      Watch device implementations:
+    </p>
+    <ul>
+      <li>[W-SR] Are STRONGLY RECOMMENDED to include a 3-axis accelerometer.
+      </li>
+    </ul>
+    <p>
+      <strong>Bluetooth (Section 7.4.3)</strong>
+    </p>
+    <p>
+      Watch device implementations:
+    </p>
+    <ul>
+      <li>[W-0-1] MUST support Bluetooth.
+      </li>
+    </ul>
+    <p>
+      <strong>Minimum Memory and Storage (Section 7.6.1)</strong>
+    </p>
+    <p>
+      Watch device implementations:
+    </p>
+    <ul>
+      <li>[W-0-1] MUST have at least 1GB of non-volatile storage available for application private data (a.k.a. "/data" partition)
+      </li>
+      <li>[W-0-2] MUST have at least 416MB memory available to the kernel and userspace.
+      </li>
+    </ul>
+    <p>
+      <strong>Microphone (Section 7.8.1)</strong>
+    </p>
+    <p>
+      Watch device implementations:
+    </p>
+    <ul>
+      <li>[W-0-1] MUST include a microphone.
+      </li>
+    </ul>
+    <p>
+      <strong>Audio Output (Section 7.8.1)</strong>
+    </p>
+    <p>
+      Watch device implementations:
+    </p>
+    <ul>
+      <li>MAY but SHOULD NOT have audio output.
+      </li>
+    </ul>
+    <h4 id="2_4_2_multimedia">
+      2.4.2. Multimedia
+    </h4>
+    <p>
+      No additional requirements.
+    </p>
+    <h4 id="2_4_3_software">
+      2.4.3. Software
+    </h4>
+    <p>
+      Watch device implementations:
+    </p>
+    <ul>
+      <li>[W-0-1] MUST declare the feature android.hardware.type.watch.
+      </li>
+      <li>[W-0-2] MUST support uiMode = <a href="http://developer.android.com/reference/android/content/res/Configuration.html#UI_MODE_TYPE_WATCH">UI_MODE_TYPE_WATCH</a>.
+      </li>
+    </ul>
+    <p>
+      <strong>Search (Section 3.8.4)</strong>
+    </p>
+    <p>
+      Watch device implementations:
+    </p>
+    <ul>
+      <li>[W-SR] Are STRONGLY RECOMMENDED to implement an assistant on the device to handle the <a href="http://developer.android.com/reference/android/content/Intent.html#ACTION_ASSIST">Assist action</a>.
+      </li>
+    </ul>
+    <p>
+      <strong>Accessibility (Section 3.10)</strong>
+    </p>
+    <p>
+      Watch device implementations that declare the <code>android.hardware.audio.output</code> feature flag:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [W-1-1] MUST support third-party accessibility services.
+        </p>
+      </li>
+      <li>
+        <p>
+          [W-SR] Are STRONGLY RECOMMENDED to preload accessibility services on the device comparable with or exceeding functionality of the Switch Access and TalkBack (for languages supported by the preloaded Text-to-speech engine) accessibility services as provided in the <a href="https://github.com/google/talkback">talkback open source project</a>.
+        </p>
+      </li>
+    </ul>
+    <p>
+      <strong>Text-to-Speech (Section 3.11)</strong>
+    </p>
+    <p>
+      If Watch device implementations report the feature android.hardware.audio.output, they:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [W-SR] Are STRONGLY RECOMMENDED to include a TTS engine supporting the languages available on the device.
+        </p>
+      </li>
+      <li>
+        <p>
+          [W-0-1] MUST support installation of third-party TTS engines.
+        </p>
+      </li>
+    </ul>
+    <h3 id="2_5_automotive_requirements">
+      2.5. Automotive Requirements
+    </h3>
+    <p>
+      <strong>Android Automotive implementation</strong> refers to a vehicle head unit running Android as an operating system for part or all of the system and/or infotainment functionality.
+    </p>
+    <p>
+      Android device implementations are classified as an Automotive if they declare the feature <code>android.hardware.type.automotive</code> or meet all the following criteria.
+    </p>
+    <ul>
+      <li>Are embedded as part of, or pluggable to, an automotive vehicle.
+      </li>
+      <li>Are using a screen in the driver's seat row as the primary display.
+      </li>
+    </ul>
+    <p>
+      The additional requirements in the rest of this section are specific to Android Automotive device implementations.
+    </p>
+    <h4 id="2_5_1_hardware">
+      2.5.1. Hardware
+    </h4>
+    <p>
+      <strong>Screen Size (Section 7.1.1.1)</strong>
+    </p>
+    <p>
+      Automotive device implementations:
+    </p>
+    <ul>
+      <li>[A-0-1] MUST have a screen at least 6 inches in physical diagonal size.
+      </li>
+      <li>[A-0-2] MUST have a screen size layout of at least 750 dp x 480 dp.
+      </li>
+    </ul>
+    <p>
+      <strong>Navigation Keys (Section 7.2.3)</strong>
+    </p>
+    <p>
+      Automotive device implementations:
+    </p>
+    <ul>
+      <li>[A-0-1] MUST provide the Home function and MAY provide Back and Recent functions.
+      </li>
+      <li>[A-0-2] MUST send both the normal and long press event of the Back function (<a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BACK"><code>KEYCODE_BACK</code></a>) to the foreground application.
+      </li>
+    </ul>
+    <p>
+      <strong>Accelerometer (Section 7.3.1)</strong>
+    </p>
+    <p>
+      Automotive device implementations:
+    </p>
+    <ul>
+      <li>[A-SR] Are STRONGLY RECOMMENDED to include a 3-axis accelerometer.
+      </li>
+    </ul>
+    <p>
+      If Automotive device implementations include a 3-axis accelerometer, they:
+    </p>
+    <ul>
+      <li>[A-1-1] MUST be able to report events up to a frequency of at least 100 Hz.
+      </li>
+      <li>[A-1-2] MUST comply with the Android <a href="http://source.android.com/devices/sensors/sensor-types.html#auto_axes">car sensor coordinate system</a>.
+      </li>
+    </ul>
+    <p>
+      <strong>GPS (Section 7.3.3)</strong>
+    </p>
+    <p>
+      If Automotive device implementations include a GPS/GNSS receiver and report the capability to applications through the <code>android.hardware.location.gps</code> feature flag:
+    </p>
+    <ul>
+      <li>[A-1-1] GNSS technology generation MUST be the year "2017" or newer.
+      </li>
+    </ul>
+    <p>
+      <strong>Gyroscope (Section 7.3.4)</strong>
+    </p>
+    <p>
+      If Automotive device implementations include a gyroscope, they:
+    </p>
+    <ul>
+      <li>[A-1-1] MUST be able to report events up to a frequency of at least 100 Hz.
+      </li>
+    </ul>
+    <p>
+      <strong>Android Automotive-only sensors (Section 7.3.11)</strong> <strong>Current Gear (Section 7.3.11.1)</strong>
+    </p>
+    <p>
+      Automotive device implementations:
+    </p>
+    <ul>
+      <li>SHOULD provide current gear as <code>SENSOR_TYPE_GEAR</code>.
+      </li>
+    </ul>
+    <p>
+      <strong>Day Night Mode (Section 7.3.11.2)</strong>
+    </p>
+    <p>
+      Automotive device implementations:
+    </p>
+    <ul>
+      <li>[A-0-1] MUST support day/night mode defined as <code>SENSOR_TYPE_NIGHT</code>.
+      </li>
+      <li>[A-0-2] The value of the <code>SENSOR_TYPE_NIGHT</code> flag MUST be consistent with dashboard day/night mode and SHOULD be based on ambient light sensor input.
+      </li>
+      <li>The underlying ambient light sensor MAY be the same as <a href="#7_3_7_photometer">Photometer</a>.
+      </li>
+    </ul>
+    <p>
+      <strong>Driving Status (Section 7.3.11.3)</strong>
+    </p>
+    <p>
+      Automotive device implementations:
+    </p>
+    <ul>
+      <li>[A-0-1] MUST support driving status defined as <code>SENSOR_TYPE_DRIVING_STATUS</code>, with a default value of <code>DRIVE_STATUS_UNRESTRICTED</code> when the vehicle is fully stopped and parked. It is the responsibility of device manufacturers to configure <code>SENSOR_TYPE_DRIVING_STATUS</code> in compliance with all laws and regulations that apply to markets where the product is shipping.
+      </li>
+    </ul>
+    <p>
+      <strong>Wheel Speed (Section 7.3.11.4)</strong>
+    </p>
+    <p>
+      Automotive device implementations:
+    </p>
+    <ul>
+      <li>[A-0-1] MUST provide vehicle speed defined as <code>SENSOR_TYPE_CAR_SPEED</code>.
+      </li>
+    </ul>
+    <p>
+      <strong>Bluetooth (Section 7.4.3)</strong>
+    </p>
+    <p>
+      Automotive device implementations:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [A-0-1] MUST support Bluetooth and SHOULD support Bluetooth LE.
+        </p>
+      </li>
+      <li>
+        <p>
+          [A-0-2] Android Automotive implementations MUST support the following Bluetooth profiles:
+        </p>
+        <ul>
+          <li>Phone calling over Hands-Free Profile (HFP).
+          </li>
+          <li>Media playback over Audio Distribution Profile (A2DP).
+          </li>
+          <li>Media playback control over Remote Control Profile (AVRCP).
+          </li>
+          <li>Contact sharing using the Phone Book Access Profile (PBAP).
+          </li>
+        </ul>
+      </li>
+      <li>SHOULD support Message Access Profile (MAP).
+      </li>
+    </ul>
+    <p>
+      <strong>Minimum Network Capability (Section 7.4.5)</strong>
+    </p>
+    <p>
+      Automotive device implementations:
+    </p>
+    <ul>
+      <li>SHOULD include support for cellular network based data connectivity.
+      </li>
+    </ul>
+    <p>
+      <strong>Minimum Memory and Storage (Section 7.6.1)</strong>
+    </p>
+    <p>
+      Automotive device implementations:
+    </p>
+    <ul>
+      <li>[A-0-1] MUST have at least 4GB of non-volatile storage available for application private data (a.k.a. "/data" partition)
+      </li>
+    </ul>
+    <p>
+      <strong>USB peripheral mode (Section 7.7.1)</strong>
+    </p>
+    <p>
+      Automotive device implementations:
+    </p>
+    <ul>
+      <li>SHOULD include a USB port supporting peripheral mode.
+      </li>
+    </ul>
+    <p>
+      <strong>Microphone (Section 7.8.1)</strong>
+    </p>
+    <p>
+      Automotive device implementations:
+    </p>
+    <ul>
+      <li>[A-0-1] MUST include a microphone.
+      </li>
+    </ul>
+    <p>
+      <strong>Audio Output (Section 7.8.2)</strong>
+    </p>
+    <p>
+      Automotive device implementations:
+    </p>
+    <ul>
+      <li>[A-0-1] MUST have an audio output and declare <code>android.hardware.audio.output</code>.
+      </li>
+    </ul>
+    <h4 id="2_5_2_multimedia">
+      2.5.2. Multimedia
+    </h4>
+    <p>
+      <strong>Audio Encoding (Section 5.1)</strong>
+    </p>
+    <p>
+      Automotive device implementations MUST support the following audio encoding:
+    </p>
+    <ul>
+      <li>[A-1-1] MPEG-4 AAC Profile (AAC LC)
+      </li>
+      <li>[A-1-2] MPEG-4 HE AAC Profile (AAC+)
+      </li>
+      <li>[A-1-3] AAC ELD (enhanced low delay AAC)
+      </li>
+    </ul>
+    <p>
+      <strong>Video Encoding (Section 5.2)</strong>
+    </p>
+    <p>
+      Automotive device implementations MUST support the following video encoding:
+    </p>
+    <ul>
+      <li>[A-0-1] H.264 AVC
+      </li>
+      <li>[A-0-2] VP8
+      </li>
+    </ul>
+    <p>
+      <strong>Video Decoding (Section 5.3)</strong>
+    </p>
+    <p>
+      Automotive device implementations MUST support the following video decoding:
+    </p>
+    <ul>
+      <li>[A-0-1] H.264 AVC
+      </li>
+      <li>[A-0-2] MPEG-4 SP
+      </li>
+      <li>[A-0-3] VP8
+      </li>
+      <li>[A-0-4] VP9
+      </li>
+    </ul>
+    <p>
+      Automotive device implementations are STRONGLY RECOMMENDED to support the following video decoding:
+    </p>
+    <ul>
+      <li>[A-SR] H.265 HEVC
+      </li>
+    </ul>
+    <h4 id="2_5_3_software">
+      2.5.3. Software
+    </h4>
+    <p>
+      Automotive device implementations:
+    </p>
+    <ul>
+      <li>[A-0-1] MUST declare the feature android.hardware.type.automotive.
+      </li>
+      <li>[A-0-2] MUST support uiMode = <a href="http://developer.android.com/reference/android/content/res/Configuration.html#UI_MODE_TYPE_CAR">UI_MODE_TYPE_CAR</a>.
+      </li>
+      <li>[A-0-3] Android Automotive implementations MUST support all public APIs in the <code>android.car.*</code> namespace.
+      </li>
+    </ul>
+    <p>
+      <strong>WebView Compatibility (Section 3.4.1)</strong>
+    </p>
+    <p>
+      Automotive device implementations:
+    </p>
+    <ul>
+      <li>[A-0-1] MUST provide a complete implementation of the <code>android.webkit.Webview API</code>.
+      </li>
+    </ul>
+    <p>
+      <strong>Notifications (Section 3.8.3)</strong>
+    </p>
+    <p>
+      Android Automotive device implementations:
+    </p>
+    <ul>
+      <li>[A-0-1] MUST display notifications that use the <a href="https://developer.android.com/reference/android/app/Notification.CarExtender.html"><code>Notification.CarExtender</code></a> API when requested by third-party applications.
+      </li>
+    </ul>
+    <p>
+      <strong>Search (Section 3.8.4)</strong>
+    </p>
+    <p>
+      Automotive device implementations:
+    </p>
+    <ul>
+      <li>[A-0-1] MUST implement an assistant on the device to handle the <a href="http://developer.android.com/reference/android/content/Intent.html#ACTION_ASSIST">Assist action</a>.
+      </li>
+    </ul>
+    <p>
+      <strong>Media UI (Section 3.14)</strong>
+    </p>
+    <p>
+      Automotive device implementations:
+    </p>
+    <ul>
+      <li>[A-0-1] MUST include a UI framework to support third-party apps using the media APIs as described in section 3.14.
+      </li>
+    </ul>
+    <h4 id="2_5_4_performance_and_power">
+      2.5.4. Performance and Power
+    </h4>
+    <p>
+      <strong>Power-Saving Modes (Section 8.3)</strong>
+    </p>
+    <p>
+      For Automotive device implementations:
+    </p>
+    <ul>
+      <li>[A-0-1] All Apps exempted from App Standby and Doze power-saving modes MUST be made visible to the end user.
+      </li>
+      <li>[A-0-2] The triggering, maintenance, wakeup algorithms and the use of global system settings of App Standby and Doze power-saving modes MUST not deviate from the Android Open Source Project.
+      </li>
+    </ul>
+    <p>
+      <strong>Power Consumption Accounting (Sections 8.4)</strong>
+    </p>
+    <p>
+      Automotive device implementations:
+    </p>
+    <ul>
+      <li>[A-0-1] MUST provide a per-component power profile that defines the <a href="http://source.android.com/devices/tech/power/values.html">current consumption value</a> for each hardware component and the approximate battery drain caused by the components over time as documented in the Android Open Source Project site.
+      </li>
+      <li>[A-0-2] MUST report all power consumption values in milliampere hours (mAh).
+      </li>
+      <li>[A-0-3] MUST report CPU power consumption per each process's UID. The Android Open Source Project meets the requirement through the <code>uid_cputime</code> kernel module implementation.
+      </li>
+      <li>SHOULD be attributed to the hardware component itself if unable to attribute hardware component power usage to an application.
+      </li>
+      <li>[A-0-4] MUST make this power usage available via the <a href="http://source.android.com/devices/tech/power/batterystats.html"><code>adb shell dumpsys batterystats</code></a> shell command to the app developer.
+      </li>
+    </ul>
+    <h4 id="2_5_5_security_model">
+      2.5.5. Security Model
+    </h4>
+    <p>
+      <strong>Multi-User Support (Section 9.5)</strong>
+    </p>
+    <p>
+      If Automotive device implementations include multiple users, they:
+    </p>
+    <ul>
+      <li>[A-1-1] MUST include a guest account that allows all functions provided by the vehicle system without requiring a user to log in.
+      </li>
+    </ul>
+    <p>
+      <strong>Automotive Vehicle System Isolation (Section 9.14)</strong>
+    </p>
+    <p>
+      Automotive device implementations:
+    </p>
+    <ul>
+      <li>[A-0-1] MUST gatekeep messages from Android framework vehicle subsystems, e.g., whitelisting permitted message types and message sources.
+      </li>
+      <li>[A-0-2] MUST watchdog against denial of service attacks from the Android framework or third-party apps. This guards against malicious software flooding the vehicle network with traffic, which may lead to malfunctioning vehicle subsystems.
+      </li>
+    </ul>
+    <h3 id="2_6_tablet_requirements">
+      2.6. Tablet Requirements
+    </h3>
+    <p>
+      An <strong>Android Tablet device</strong> refers to an Android device implementation that is typically used by holding in both hands and not in a clamshell form-factor.
+    </p>
+    <p>
+      Android device implementations are classified as a Tablet if they meet all the following criteria:
+    </p>
+    <ul>
+      <li>Have a power source that provides mobility, such as a battery.
+      </li>
+      <li>Have a physical diagonal screen size in the range of 7 to 18 inches.
+      </li>
+    </ul>
+    <p>
+      Tablet device implementations have similar requirements to handheld device implementations. The exceptions are in indicated by and * in that section and noted for reference in this section.
+    </p>
+    <h4 id="2_6_1_hardware">
+      2.6.1. Hardware
+    </h4>
+    <p>
+      <strong>Screen Size (Section 7.1.1.1)</strong>
+    </p>
+    <p>
+      Tablet device implementations:
+    </p>
+    <ul>
+      <li>[Ta-0-1] MUST have a screen in the range of 7 to 18 inches.
+      </li>
+    </ul>
+    <p>
+      <strong>Minimum Memory and Storage (Section 7.6.1)</strong>
+    </p>
+    <p>
+      The screen densities listed for small/normal screens in the handheld requirements are not applicable to tablets.
+    </p>
+    <p>
+      <strong>USB peripheral mode (Section 7.7.1)</strong>
+    </p>
+    <p>
+      If handheld device implementations include a USB port supporting peripheral mode, they:
+    </p>
+    <ul>
+      <li>MAY implement the Android Open Accessory (AOA) API.
+      </li>
+    </ul>
+    <p>
+      <strong>Virtual Reality Mode (Section 7.9.1)</strong>
+    </p>
+    <p>
+      <strong>Virtual Reality High Performance (Section 7.9.2)</strong>
+    </p>
+    <p>
+      Virtual reality requirements are not applicable to tablets.
+    </p>
+    <h2 id="3_software">
+      3. Software
+    </h2>
+    <h3 id="3_1_managed_api_compatibility">
+      3.1. Managed API Compatibility
+    </h3>
+    <p>
+      The managed Dalvik bytecode execution environment is the primary vehicle for Android applications. The Android application programming interface (API) is the set of Android platform interfaces exposed to applications running in the managed runtime environment.
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-0-1] Device implementations MUST provide complete implementations, including all documented behaviors, of any documented API exposed by the <a href="http://developer.android.com/reference/packages.html">Android SDK</a> or any API decorated with the “@SystemApi” marker in the upstream Android source code.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-0-2] Device implementations MUST support/preserve all classes, methods, and associated elements marked by the TestApi annotation (@TestApi).
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-0-3] Device implementations MUST NOT omit any managed APIs, alter API interfaces or signatures, deviate from the documented behavior, or include no-ops, except where specifically allowed by this Compatibility Definition.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-0-4] Device implementations MUST still keep the APIs present and behave in a reasonable way, even when some hardware features for which Android includes APIs are omitted. See <a href="#7_hardware_compatibility">section 7</a> for specific requirements for this scenario.
+        </p>
+      </li>
+    </ul>
+    <h3 id="3_1_1_android_extensions">
+      3.1.1. Android Extensions
+    </h3>
+    <p>
+      Android includes the support of extending the managed APIs while keeping the same API level version.
+    </p>
+    <ul>
+      <li>[C-0-1] Android device implementations MUST preload the AOSP implementation of both the shared library <code>ExtShared</code> and services <code>ExtServices</code> with versions higher than or equal to the minimum versions allowed per each API level. For example, Android 7.0 device implementations, running API level 24 MUST include at least version 1.
+      </li>
+    </ul>
+    <h3 id="3_2_soft_api_compatibility">
+      3.2. Soft API Compatibility
+    </h3>
+    <p>
+      In addition to the managed APIs from <a href="#3_1_managed_api_compatibility">section 3.1</a>, Android also includes a significant runtime-only “soft” API, in the form of such things as intents, permissions, and similar aspects of Android applications that cannot be enforced at application compile time.
+    </p>
+    <h4 id="3_2_1_permissions">
+      3.2.1. Permissions
+    </h4>
+    <ul>
+      <li>[C-0-1] Device implementers MUST support and enforce all permission constants as documented by the <a href="http://developer.android.com/reference/android/Manifest.permission.html">Permission reference page</a>. Note that <a href="#9_security_model_compatibility">section 9</a> lists additional requirements related to the Android security model.
+      </li>
+    </ul>
+    <h4 id="3_2_2_build_parameters">
+      3.2.2. Build Parameters
+    </h4>
+    <p>
+      The Android APIs include a number of constants on the <a href="http://developer.android.com/reference/android/os/Build.html">android.os.Build class</a> that are intended to describe the current device.
+    </p>
+    <ul>
+      <li>[C-0-1] To provide consistent, meaningful values across device implementations, the table below includes additional restrictions on the formats of these values to which device implementations MUST conform.
+      </li>
+    </ul>
+    <table>
+      <tr>
+        <th>
+          Parameter
+        </th>
+        <th>
+          Details
+        </th>
+      </tr>
+      <tr>
+        <td>
+          VERSION.RELEASE
+        </td>
+        <td>
+          The version of the currently-executing Android system, in human-readable format. This field MUST have one of the string values defined in <a href="http://source.android.com/compatibility/8.0/versions.html">8.0</a>.
+        </td>
+      </tr>
+      <tr>
+        <td>
+          VERSION.SDK
+        </td>
+        <td>
+          The version of the currently-executing Android system, in a format accessible to third-party application code. For Android 8.0, this field MUST have the integer value 8.0_INT.
+        </td>
+      </tr>
+      <tr>
+        <td>
+          VERSION.SDK_INT
+        </td>
+        <td>
+          The version of the currently-executing Android system, in a format accessible to third-party application code. For Android 8.0, this field MUST have the integer value 8.0_INT.
+        </td>
+      </tr>
+      <tr>
+        <td>
+          VERSION.INCREMENTAL
+        </td>
+        <td>
+          A value chosen by the device implementer designating the specific build of the currently-executing Android system, in human-readable format. This value MUST NOT be reused for different builds made available to end users. A typical use of this field is to indicate which build number or source-control change identifier was used to generate the build. There are no requirements on the specific format of this field, except that it MUST NOT be null or the empty string ("").
+        </td>
+      </tr>
+      <tr>
+        <td>
+          BOARD
+        </td>
+        <td>
+          A value chosen by the device implementer identifying the specific internal hardware used by the device, in human-readable format. A possible use of this field is to indicate the specific revision of the board powering the device. The value of this field MUST be encodable as 7-bit ASCII and match the regular expression “^[a-zA-Z0-9_-]+$”.
+        </td>
+      </tr>
+      <tr>
+        <td>
+          BRAND
+        </td>
+        <td>
+          A value reflecting the brand name associated with the device as known to the end users. MUST be in human-readable format and SHOULD represent the manufacturer of the device or the company brand under which the device is marketed. The value of this field MUST be encodable as 7-bit ASCII and match the regular expression “^[a-zA-Z0-9_-]+$”.
+        </td>
+      </tr>
+      <tr>
+        <td>
+          SUPPORTED_ABIS
+        </td>
+        <td>
+          The name of the instruction set (CPU type + ABI convention) of native code. See <a href="#3_3_native_api_compatibility">section 3.3. Native API Compatibility</a>.
+        </td>
+      </tr>
+      <tr>
+        <td>
+          SUPPORTED_32_BIT_ABIS
+        </td>
+        <td>
+          The name of the instruction set (CPU type + ABI convention) of native code. See <a href="#3_3_native_api_compatibility">section 3.3. Native API Compatibility</a>.
+        </td>
+      </tr>
+      <tr>
+        <td>
+          SUPPORTED_64_BIT_ABIS
+        </td>
+        <td>
+          The name of the second instruction set (CPU type + ABI convention) of native code. See <a href="#3_3_native_api_compatibility">section 3.3. Native API Compatibility</a>.
+        </td>
+      </tr>
+      <tr>
+        <td>
+          CPU_ABI
+        </td>
+        <td>
+          The name of the instruction set (CPU type + ABI convention) of native code. See <a href="#3_3_native_api_compatibility">section 3.3. Native API Compatibility</a>.
+        </td>
+      </tr>
+      <tr>
+        <td>
+          CPU_ABI2
+        </td>
+        <td>
+          The name of the second instruction set (CPU type + ABI convention) of native code. See <a href="#3_3_native_api_compatibility">section 3.3. Native API Compatibility</a>.
+        </td>
+      </tr>
+      <tr>
+        <td>
+          DEVICE
+        </td>
+        <td>
+          A value chosen by the device implementer containing the development name or code name identifying the configuration of the hardware features and industrial design of the device. The value of this field MUST be encodable as 7-bit ASCII and match the regular expression “^[a-zA-Z0-9_-]+$”. This device name MUST NOT change during the lifetime of the product.
+        </td>
+      </tr>
+      <tr>
+        <td>
+          FINGERPRINT
+        </td>
+        <td>
+          A string that uniquely identifies this build. It SHOULD be reasonably human-readable. It MUST follow this template:
+          <p class="small">
+            $(BRAND)/$(PRODUCT)/<br />
+            &nbsp;&nbsp;&nbsp;&nbsp;$(DEVICE):$(VERSION.RELEASE)/$(ID)/$(VERSION.INCREMENTAL):$(TYPE)/$(TAGS)
+          </p>
+          <p>
+            For example:
+          </p>
+          <p class="small">
+            acme/myproduct/<br />
+            &nbsp;&nbsp;&nbsp;&nbsp;mydevice:8.0/LMYXX/3359:userdebug/test-keys
+          </p>
+          <p>
+            The fingerprint MUST NOT include whitespace characters. If other fields included in the template above have whitespace characters, they MUST be replaced in the build fingerprint with another character, such as the underscore ("_") character. The value of this field MUST be encodable as 7-bit ASCII.
+          </p>
+        </td>
+      </tr>
+      <tr>
+        <td>
+          HARDWARE
+        </td>
+        <td>
+          The name of the hardware (from the kernel command line or /proc). It SHOULD be reasonably human-readable. The value of this field MUST be encodable as 7-bit ASCII and match the regular expression “^[a-zA-Z0-9_-]+$”.
+        </td>
+      </tr>
+      <tr>
+        <td>
+          HOST
+        </td>
+        <td>
+          A string that uniquely identifies the host the build was built on, in human-readable format. There are no requirements on the specific format of this field, except that it MUST NOT be null or the empty string ("").
+        </td>
+      </tr>
+      <tr>
+        <td>
+          ID
+        </td>
+        <td>
+          An identifier chosen by the device implementer to refer to a specific release, in human-readable format. This field can be the same as android.os.Build.VERSION.INCREMENTAL, but SHOULD be a value sufficiently meaningful for end users to distinguish between software builds. The value of this field MUST be encodable as 7-bit ASCII and match the regular expression “^[a-zA-Z0-9._-]+$”.
+        </td>
+      </tr>
+      <tr>
+        <td>
+          MANUFACTURER
+        </td>
+        <td>
+          The trade name of the Original Equipment Manufacturer (OEM) of the product. There are no requirements on the specific format of this field, except that it MUST NOT be null or the empty string (""). This field MUST NOT change during the lifetime of the product.
+        </td>
+      </tr>
+      <tr>
+        <td>
+          MODEL
+        </td>
+        <td>
+          A value chosen by the device implementer containing the name of the device as known to the end user. This SHOULD be the same name under which the device is marketed and sold to end users. There are no requirements on the specific format of this field, except that it MUST NOT be null or the empty string (""). This field MUST NOT change during the lifetime of the product.
+        </td>
+      </tr>
+      <tr>
+        <td>
+          PRODUCT
+        </td>
+        <td>
+          A value chosen by the device implementer containing the development name or code name of the specific product (SKU) that MUST be unique within the same brand. MUST be human-readable, but is not necessarily intended for view by end users. The value of this field MUST be encodable as 7-bit ASCII and match the regular expression “^[a-zA-Z0-9_-]+$”. This product name MUST NOT change during the lifetime of the product.
+        </td>
+      </tr>
+      <tr>
+        <td>
+          SERIAL
+        </td>
+        <td>
+          A hardware serial number, which MUST be available and unique across devices with the same MODEL and MANUFACTURER. The value of this field MUST be encodable as 7-bit ASCII and match the regular expression “^([a-zA-Z0-9]{6,20})$”.
+        </td>
+      </tr>
+      <tr>
+        <td>
+          TAGS
+        </td>
+        <td>
+          A comma-separated list of tags chosen by the device implementer that further distinguishes the build. This field MUST have one of the values corresponding to the three typical Android platform signing configurations: release-keys, dev-keys, test-keys.
+        </td>
+      </tr>
+      <tr>
+        <td>
+          TIME
+        </td>
+        <td>
+          A value representing the timestamp of when the build occurred.
+        </td>
+      </tr>
+      <tr>
+        <td>
+          TYPE
+        </td>
+        <td>
+          A value chosen by the device implementer specifying the runtime configuration of the build. This field MUST have one of the values corresponding to the three typical Android runtime configurations: user, userdebug, or eng.
+        </td>
+      </tr>
+      <tr>
+        <td>
+          USER
+        </td>
+        <td>
+          A name or user ID of the user (or automated user) that generated the build. There are no requirements on the specific format of this field, except that it MUST NOT be null or the empty string ("").
+        </td>
+      </tr>
+      <tr>
+        <td>
+          SECURITY_PATCH
+        </td>
+        <td>
+          A value indicating the security patch level of a build. It MUST signify that the build is not in any way vulnerable to any of the issues described up through the designated Android Public Security Bulletin. It MUST be in the format [YYYY-MM-DD], matching a defined string documented in the <a href="source.android.com/security/bulletin">Android Public Security Bulletin</a> or in the <a href="http://source.android.com/security/advisory">Android Security Advisory</a>, for example "2015-11-01".
+        </td>
+      </tr>
+      <tr>
+        <td>
+          BASE_OS
+        </td>
+        <td>
+          A value representing the FINGERPRINT parameter of the build that is otherwise identical to this build except for the patches provided in the Android Public Security Bulletin. It MUST report the correct value and if such a build does not exist, report an empty string ("").
+        </td>
+      </tr>
+      <tr>
+        <td>
+          <a href="https://developer.android.com/reference/android/os/Build.html#BOOTLOADER">BOOTLOADER</a>
+        </td>
+        <td>
+          A value chosen by the device implementer identifying the specific internal bootloader version used in the device, in human-readable format. The value of this field MUST be encodable as 7-bit ASCII and match the regular expression “^[a-zA-Z0-9._-]+$”.
+        </td>
+      </tr>
+      <tr>
+        <td>
+          <a href="https://developer.android.com/reference/android/os/Build.html#getRadioVersion()">getRadioVersion()</a>
+        </td>
+        <td>
+          MUST (be or return) a value chosen by the device implementer identifying the specific internal radio/modem version used in the device, in human-readable format. If a device does not have any internal radio/modem it MUST return NULL. The value of this field MUST be encodable as 7-bit ASCII and match the regular expression “^[a-zA-Z0-9._-,]+$”.
+        </td>
+      </tr>
+    </table>
+    <h4 id="3_2_3_intent_compatibility">
+      3.2.3. Intent Compatibility
+    </h4>
+    <h5 id="3_2_3_1_core_application_intents">
+      3.2.3.1. Core Application Intents
+    </h5>
+    <p>
+      Android intents allow application components to request functionality from other Android components. The Android upstream project includes a list of applications considered core Android applications, which implements several intent patterns to perform common actions.
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-0-1] Device implementations MUST include these application, service components, or at least a handler, for all the public intent filter patterns defined by the following core Android applications in AOSP:
+        </p>
+        <ul>
+          <li>Desk Clock
+          </li>
+          <li>Browser
+          </li>
+          <li>Calendar
+          </li>
+          <li>Contacts
+          </li>
+          <li>Gallery
+          </li>
+          <li>GlobalSearch
+          </li>
+          <li>Launcher
+          </li>
+          <li>Music
+          </li>
+          <li>Settings
+          </li>
+        </ul>
+      </li>
+    </ul>
+    <h5 id="3_2_3_2_intent_resolution">
+      3.2.3.2. Intent Resolution
+    </h5>
+    <ul>
+      <li>[C-0-1] As Android is an extensible platform, device implementations MUST allow each intent pattern referenced in <a href="#3_2_3_1_core_application_intents">section 3.2.3.1</a> to be overridden by third-party applications. The upstream Android open source implementation allows this by default.
+      </li>
+      <li>
+        <p>
+          [C-0-2] Dvice implementers MUST NOT attach special privileges to system applications' use of these intent patterns, or prevent third-party applications from binding to and assuming control of these patterns. This prohibition specifically includes but is not limited to disabling the “Chooser” user interface that allows the user to select between multiple applications that all handle the same intent pattern.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-0-3] Device implementations MUST provide a user interface for users to modify the default activity for intents.
+        </p>
+      </li>
+      <li>
+        <p>
+          However, device implementations MAY provide default activities for specific URI patterns (e.g. http://play.google.com) when the default activity provides a more specific attribute for the data URI. For example, an intent filter pattern specifying the data URI “http://www.android.com” is more specific than the browser's core intent pattern for “http://”.
+        </p>
+      </li>
+    </ul>
+    <p>
+      Android also includes a mechanism for third-party apps to declare an authoritative default <a href="https://developer.android.com/training/app-links">app linking behavior</a> for certain types of web URI intents. When such authoritative declarations are defined in an app's intent filter patterns, device implementations:
+    </p>
+    <ul>
+      <li>[C-0-4] MUST attempt to validate any intent filters by performing the validation steps defined in the <a href="https://developers.google.com/digital-asset-links">Digital Asset Links specification</a> as implemented by the Package Manager in the upstream Android Open Source Project.
+      </li>
+      <li>[C-0-5] MUST attempt validation of the intent filters during the installation of the application and set all successfully validated UIR intent filters as default app handlers for their UIRs.
+      </li>
+      <li>MAY set specific URI intent filters as default app handlers for their URIs, if they are successfully verified but other candidate URI filters fail verification. If a device implementation does this, it MUST provide the user appropriate per-URI pattern overrides in the settings menu.
+      </li>
+      <li>MUST provide the user with per-app App Links controls in Settings as follows:
+        <ul>
+          <li>[C-0-6] The user MUST be able to override holistically the default app links behavior for an app to be: always open, always ask, or never open, which must apply to all candidate URI intent filters equally.
+          </li>
+          <li>[C-0-7] The user MUST be able to see a list of the candidate URI intent filters.
+          </li>
+          <li>The device implementation MAY provide the user with the ability to override specific candidate URI intent filters that were successfully verified, on a per-intent filter basis.
+          </li>
+          <li>[C-0-8] The device implementation MUST provide users with the ability to view and override specific candidate URI intent filters if the device implementation lets some candidate URI intent filters succeed verification while some others can fail.
+          </li>
+        </ul>
+      </li>
+    </ul>
+    <h5 id="3_2_3_3_intent_namespaces">
+      3.2.3.3. Intent Namespaces
+    </h5>
+    <ul>
+      <li>[C-0-1] Device implementations MUST NOT include any Android component that honors any new intent or broadcast intent patterns using an ACTION, CATEGORY, or other key string in the android. <em>or com.android.</em> namespace.
+      </li>
+      <li>[C-0-2] Device implementers MUST NOT include any Android components that honor any new intent or broadcast intent patterns using an ACTION, CATEGORY, or other key string in a package space belonging to another organization.
+      </li>
+      <li>[C-0-3] Device implementers MUST NOT alter or extend any of the intent patterns used by the core apps listed in <a href="#3_2_3_1_core_application_intents">section 3.2.3.1</a>.
+      </li>
+      <li>Device implementations MAY include intent patterns using namespaces clearly and obviously associated with their own organization. This prohibition is analogous to that specified for Java language classes in <a href="#3_6_api_namespaces">section 3.6</a>.
+      </li>
+    </ul>
+    <h5 id="3_2_3_4_broadcast_intents">
+      3.2.3.4. Broadcast Intents
+    </h5>
+    <p>
+      Third-party applications rely on the platform to broadcast certain intents to notify them of changes in the hardware or software environment.
+    </p>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST broadcast the public broadcast intents in response to appropriate system events as described in the SDK documentation. Note that this requirement is not conflicting with section 3.5 as the limitation for background applications are also described in the SDK documentation.
+      </li>
+    </ul>
+    <h5 id="3_2_3_5_default_app_settings">
+      3.2.3.5. Default App Settings
+    </h5>
+    <p>
+      Android includes settings that provide users an easy way to select their default applications, for example for Home screen or SMS.
+    </p>
+    <p>
+      Where it makes sense, device implementations MUST provide a similar settings menu and be compatible with the intent filter pattern and API methods described in the SDK documentation as below.
+    </p>
+    <p>
+      If device implementations report <code>android.software.home_screen</code>, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST honor the <a href="http://developer.android.com/reference/android/provider/Settings.html#ACTION_HOME_SETTINGS">android.settings.HOME_SETTINGS</a> intent to show a default app settings menu for Home Screen.
+      </li>
+    </ul>
+    <p>
+      If device implementations report <code>android.hardware.telephony</code>, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST provide a settings menu that will call the <a href="http://developer.android.com/reference/android/provider/Telephony.Sms.Intents.html">android.provider.Telephony.ACTION_CHANGE_DEFAULT</a> intent to show a dialog to change the default SMS application.
+      </li>
+    </ul>
+    <p>
+      If device implementations report <code>android.hardware.nfc.hce</code>, they:
+    </p>
+    <ul>
+      <li>[C-3-1] MUST honor the <a href="http://developer.android.com/reference/android/provider/Settings.html#ACTION_NFC_PAYMENT_SETTINGS">android.settings.NFC_PAYMENT_SETTINGS</a> intent to show a default app settings menu for Tap and Pay.
+      </li>
+    </ul>
+    <p>
+      If device implementations report <code>android.hardware.telephony</code>, they:
+    </p>
+    <ul>
+      <li>[C-4-1] MUST honor the <a href="https://developer.android.com/reference/android/telecom/TelecomManager.html#ACTION_CHANGE_DEFAULT_DIALER">android.telecom.action.CHANGE_DEFAULT_DIALER</a> intent to show a dialog to allow the user to change the default Phone application.
+      </li>
+    </ul>
+    <p>
+      If device implementations support the VoiceInteractionService, they:
+    </p>
+    <ul>
+      <li>[C-5-1] MUST honor the <a href="https://developer.android.com/reference/android/provider/Settings.html#ACTION_VOICE_INPUT_SETTINGS">android.settings.ACTION_VOICE_INPUT_SETTINGS</a> intent to show a default app settings menu for voice input and assist.
+      </li>
+    </ul>
+    <h4 id="3_2_4_activities_on_secondary_displays">
+      3.2.4. Activities on secondary displays
+    </h4>
+    <p>
+      If device implementations allow launching normal <a href="https://developer.android.com/reference/android/app/Activity.html">Android Activities</a> on secondary displays, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST set the <code>android.software.activities_on_secondary_displays</code> feature flag.
+      </li>
+      <li>[C-1-2] MUST guarantee API compatibility similar to an activity running on the primary display.
+      </li>
+      <li>[C-1-3] MUST land the new activity on the same display as the activity that launched it, when the new activity is launched without specifying a target display via the <a href="https://developer.android.com/reference/android/app/ActivityOptions.html#setLaunchDisplayId%28int%29"><code>ActivityOptions.setLaunchDisplayId()</code></a> API.
+      </li>
+      <li>[C-1-4] MUST destory all activities, when a display with the <a href="http://developer.android.com/reference/android/view/Display.html#FLAG_PRIVATE"><code>Display.FLAG_PRIVATE</code></a> flag is removed.
+      </li>
+      <li>[C-1-5] MUST resize accordingly all activities on a <a href="https://developer.android.com/reference/android/hardware/display/VirtualDisplay.html"><code>VirtualDisplay</code></a> if the display itself is resized.
+      </li>
+      <li>MAY show an IME (input method editor, a user control that enables users to enter text) on the primary display, when a text input field becomes focused on a secondary display.
+      </li>
+      <li>SHOULD implement the input focus on the secondary display independently of the primary display, when touch or key inputs are supported.
+      </li>
+      <li>SHOULD have <a href="https://developer.android.com/reference/android/content/res/Configuration.html"><code>android.content.res.Configuration</code></a> which corresponds to that display in order to be displayed, operate correctly, and maintain compatibility if an activity is launched on secondary display.
+      </li>
+    </ul>
+    <p>
+      If device implementations allow launching normal <a href="https://developer.android.com/reference/android/app/Activity.html">Android Activities</a> on secondary displays and primary and secondary displays have different <a href="https://developer.android.com/reference/android/util/DisplayMetrics.html">android.util.DisplayMetrics</a>:
+    </p>
+    <ul>
+      <li>[C-2-1] Non-resizeable activities (that have <code>resizeableActivity=false</code> in <code>AndroidManifest.xml</code>) and apps targeting API level 23 or lower MUST NOT be allowed on secondary displays.
+      </li>
+    </ul>
+    <p>
+      If device implementations allow launching normal <a href="https://developer.android.com/reference/android/app/Activity.html">Android Activities</a> on secondary displays and a secondary display has the <a href="https://developer.android.com/reference/android/view/Display.html#FLAG_PRIVATE">android.view.Display.FLAG_PRIVATE</a> flag:
+    </p>
+    <ul>
+      <li>[C-3-1] Only the owner of that display, system, and activities that are already on that display MUST be able to launch to it. Everyone can launch to a display that has <a href="https://developer.android.com/reference/android/view/Display.html#FLAG_PUBLIC">android.view.Display.FLAG_PUBLIC</a> flag.
+      </li>
+    </ul>
+    <h3 id="3_3_native_api_compatibility">
+      3.3. Native API Compatibility
+    </h3>
+    <p>
+      Device implementers are:
+    </p>
+    <p>
+      Native code compatibility is challenging. For this reason, device implementers are:
+    </p>
+    <ul>
+      <li>[SR] STRONGLY RECOMMENDED to use the implementations of the libraries listed below from the upstream Android Open Source Project.
+      </li>
+    </ul>
+    <h4 id="3_3_1_application_binary_interfaces">
+      3.3.1. Application Binary Interfaces
+    </h4>
+    <p>
+      Managed Dalvik bytecode can call into native code provided in the application <code>.apk</code> file as an ELF <code>.so</code> file compiled for the appropriate device hardware architecture. As native code is highly dependent on the underlying processor technology, Android defines a number of Application Binary Interfaces (ABIs) in the Android NDK.
+    </p>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST be compatible with one or more defined ABIs and implement compatibility with the Android NDK.
+      </li>
+      <li>[C-0-2] MUST include support for code running in the managed environment to call into native code, using the standard Java Native Interface (JNI) semantics.
+      </li>
+      <li>[C-0-3] MUST be source-compatible (i.e. header-compatible) and binary-compatible (for the ABI) with each required library in the list below.
+      </li>
+      <li>[C-0-4] MUST support the equivalent 32-bit ABI if any 64-bit ABI is supported.
+      </li>
+      <li>[C-0-5] MUST accurately report the native Application Binary Interface (ABI) supported by the device, via the <code>android.os.Build.SUPPORTED_ABIS</code>, <code>android.os.Build.SUPPORTED_32_BIT_ABIS</code>, and <code>android.os.Build.SUPPORTED_64_BIT_ABIS</code> parameters, each a comma separated list of ABIs ordered from the most to the least preferred one.
+      </li>
+      <li>[C-0-6] MUST report, via the above parameters, only those ABIs documented and described in the latest version of the <a href="https://developer.android.com/ndk/guides/abis.html">Android NDK ABI Management documentation</a>, and MUST include support for the <a href="http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0388f/Beijfcja.html">Advanced SIMD</a> (a.k.a. NEON) extension.
+      </li>
+      <li>
+        <p>
+          [C-0-7] MUST make all the following libraries, providing native APIs, available to apps that include native code:
+        </p>
+        <ul>
+          <li>libaaudio.so (AAudio native audio support)
+          </li>
+          <li>libandroid.so (native Android activity support)
+          </li>
+          <li>libc (C library)
+          </li>
+          <li>libcamera2ndk.so
+          </li>
+          <li>libdl (dynamic linker)
+          </li>
+          <li>libEGL.so (native OpenGL surface management)
+          </li>
+          <li>libGLESv1_CM.so (OpenGL ES 1.x)
+          </li>
+          <li>libGLESv2.so (OpenGL ES 2.0)
+          </li>
+          <li>libGLESv3.so (OpenGL ES 3.x)
+          </li>
+          <li>libicui18n.so
+          </li>
+          <li>libicuuc.so
+          </li>
+          <li>libjnigraphics.so
+          </li>
+          <li>liblog (Android logging)
+          </li>
+          <li>libmediandk.so (native media APIs support)
+          </li>
+          <li>libm (math library)
+          </li>
+          <li>libOpenMAXAL.so (OpenMAX AL 1.0.1 support)
+          </li>
+          <li>libOpenSLES.so (OpenSL ES 1.0.1 audio support)
+          </li>
+          <li>libRS.so
+          </li>
+          <li>libstdc++ (Minimal support for C++)
+          </li>
+          <li>libvulkan.so (Vulkan)
+          </li>
+          <li>libz (Zlib compression)
+          </li>
+          <li>JNI interface
+          </li>
+        </ul>
+      </li>
+      <li>
+        <p>
+          [C-0-8] MUST NOT add or remove the public functions for the native libraries listed above.
+        </p>
+      </li>
+      <li>[C-0-9] MUST list additional non-AOSP libraries exposed directly to third-party apps in <code>/vendor/etc/public.libraries.txt</code>.
+      </li>
+      <li>[C-0-10] MUST NOT expose any other native libraries, implemented and provided in AOSP as system libraries, to third-party apps targeting API level 24 or higher as they are reserved.
+      </li>
+      <li>[C-0-11] MUST export all the OpenGL ES 3.1 and <a href="http://developer.android.com/guide/topics/graphics/opengl.html#aep">Android Extension Pack</a> function symbols, as defined in the NDK, through the <code>libGLESv3.so</code> library. Note that while all the symbols MUST be present, section 7.1.4.1 describes in more detail the requirements for when the full implementation of each corresponding functions are expected.
+      </li>
+      <li>[C-0-12] MUST export function symbols for the core Vulkan 1.0 function symobls, as well as the <code>VK_KHR_surface</code>, <code>VK_KHR_android_surface</code>, <code>VK_KHR_swapchain</code>, <code>VK_KHR_maintenance1</code>, and <code>VK_KHR_get_physical_device_properties2</code> extensions through the <code>libvulkan.so</code> library. Note that while all the symbols MUST be present, section 7.1.4.2 describes in more detail the requirements for when the full implementation of each corresponding functions are expected.
+      </li>
+      <li>SHOULD be built using the source code and header files available in the upstream Android Open Source Project
+      </li>
+    </ul>
+    <p>
+      Note that future releases of the Android NDK may introduce support for additional ABIs.
+    </p>
+    <h4 id="3_3_2_32-bit_arm_native_code_compatibility">
+      3.3.2. 32-bit ARM Native Code Compatibility
+    </h4>
+    <p>
+      If device implementations are 64-bit ARM devices, then:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-1-1] Although the ARMv8 architecture deprecates several CPU operations, including some operations used in existing native code, the following deprecated operations MUST remain available to 32-bit native ARM code, either through native CPU support or through software emulation:
+        </p>
+        <ul>
+          <li>SWP and SWPB instructions
+          </li>
+          <li>SETEND instruction
+          </li>
+          <li>CP15ISB, CP15DSB, and CP15DMB barrier operations
+          </li>
+        </ul>
+      </li>
+    </ul>
+    <p>
+      If device implementations include a 32-bit ARM ABI, they:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-2-1] MUST include the following lines in <code>/proc/cpuinfo</code> when it is read by 32-bit ARM applications to ensure compatibility with applications built using legacy versions of Android NDK.
+        </p>
+        <ul>
+          <li>
+            <code>Features:</code>, followed by a list of any optional ARMv7 CPU features supported by the device.
+          </li>
+          <li>
+            <code>CPU architecture:</code>, followed by an integer describing the device's highest supported ARM architecture (e.g., "8" for ARMv8 devices).
+          </li>
+        </ul>
+      </li>
+      <li>
+        <p>
+          SHOULD not alter <code>/proc/cpuinfo</code> when read by 64-bit ARM or non-ARM applications.
+        </p>
+      </li>
+    </ul>
+    <h3 id="3_4_web_compatibility">
+      3.4. Web Compatibility
+    </h3>
+    <h4 id="3_4_1_webview_compatibility">
+      3.4.1. WebView Compatibility
+    </h4>
+    <p>
+      If device implementations provide a complete implementation of the <code>android.webkit.Webview</code> API, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST report <code>android.software.webview</code>.
+      </li>
+      <li>[C-1-2] MUST use the <a href="http://www.chromium.org/">Chromium</a> Project build from the upstream Android Open Source Project on the Android 8.0 branch for the implementation of the <a href="http://developer.android.com/reference/android/webkit/WebView.html"><code>android.webkit.WebView</code></a> API.
+      </li>
+      <li>
+        <p>
+          [C-1-3] The user agent string reported by the WebView MUST be in this format:
+        </p>
+        <p>
+          Mozilla/5.0 (Linux; Android $(VERSION); $(MODEL) Build/$(BUILD); wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 $(CHROMIUM_VER) Mobile Safari/537.36
+        </p>
+        <ul>
+          <li>The value of the $(VERSION) string MUST be the same as the value for android.os.Build.VERSION.RELEASE.
+          </li>
+          <li>The value of the $(MODEL) string MUST be the same as the value for android.os.Build.MODEL.
+          </li>
+          <li>The value of the $(BUILD) string MUST be the same as the value for android.os.Build.ID.
+          </li>
+          <li>The value of the $(CHROMIUM_VER) string MUST be the version of Chromium in the upstream Android Open Source Project.
+          </li>
+          <li>Device implementations MAY omit Mobile in the user agent string.
+          </li>
+        </ul>
+      </li>
+      <li>
+        <p>
+          The WebView component SHOULD include support for as many HTML5 features as possible and if it supports the feature SHOULD conform to the <a href="http://html.spec.whatwg.org/multipage/">HTML5 specification</a>.
+        </p>
+      </li>
+    </ul>
+    <h4 id="3_4_2_browser_compatibility">
+      3.4.2. Browser Compatibility
+    </h4>
+    <p>
+      If device implementations include a standalone Browser application for general web browsing, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support each of these APIs associated with HTML5:
+        <ul>
+          <li>
+            <a href="http://www.w3.org/html/wg/drafts/html/master/browsers.html#offline">application cache/offline operation</a>
+          </li>
+          <li>
+            <a href="http://www.w3.org/html/wg/drafts/html/master/semantics.html#video">&lt;video&gt; tag</a>
+          </li>
+          <li>
+            <a href="http://www.w3.org/TR/geolocation-API/">geolocation</a>
+          </li>
+        </ul>
+      </li>
+      <li>[C-1-2] MUST support the HTML5/W3C <a href="http://www.w3.org/TR/webstorage/">webstorage API</a> and SHOULD support the HTML5/W3C <a href="http://www.w3.org/TR/IndexedDB/">IndexedDB API</a>. Note that as the web development standards bodies are transitioning to favor IndexedDB over webstorage, IndexedDB is expected to become a required component in a future version of Android.
+      </li>
+      <li>MAY ship a custom user agent string in the standalone Browser application.
+      </li>
+      <li>SHOULD implement support for as much of <a href="http://html.spec.whatwg.org/multipage/">HTML5</a> as possible on the standalone Browser application (whether based on the upstream WebKit Browser application or a third-party replacement).
+      </li>
+    </ul>
+    <p>
+      However, If device implementations do not include a standalone Browser application, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST still support the public intent patterns as described in <a href="#3_2_3_1_core_application_intents">section 3.2.3.1</a>.
+      </li>
+    </ul>
+    <h3 id="3_5_api_behavioral_compatibility">
+      3.5. API Behavioral Compatibility
+    </h3>
+    <p>
+      The behaviors of each of the API types (managed, soft, native, and web) must be consistent with the preferred implementation of the upstream <a href="http://source.android.com/">Android Open Source Project</a>. Some specific areas of compatibility are:
+    </p>
+    <ul>
+      <li>[C-0-1] Devices MUST NOT change the behavior or semantics of a standard intent.
+      </li>
+      <li>[C-0-2] Devices MUST NOT alter the lifecycle or lifecycle semantics of a particular type of system component (such as Service, Activity, ContentProvider, etc.).
+      </li>
+      <li>[C-0-3] Devices MUST NOT change the semantics of a standard permission.
+      </li>
+      <li>Devices MUST NOT alter the limitations enforced on background applications. More specifically, for background apps:
+        <ul>
+          <li>[C-0-4] they MUST stop executing callbacks that are registered by the app to receive outputs from the <a href="https://developer.android.com/reference/android/location/GnssMeasurement.html"><code>GnssMeasurement</code></a> and <a href="https://developer.android.com/reference/android/location/GnssNavigationMessage.html"><code>GnssNavigationMessage</code></a>.
+          </li>
+          <li>[C-0-5] they MUST rate-limit the frequency of updates that are provided to the app through the <a href="https://developer.android.com/reference/android/location/LocationManager.html"><code>LocationManager</code></a> API class or the <a href="https://developer.android.com/reference/android/net/wifi/WifiManager.html#startScan%28%29"><code>WifiManager.startScan()</code></a> method.
+          </li>
+          <li>[C-0-6] if the app is targeting API level 25 or higher, they MUST NOT allow to register broadcast receivers for the implicit broadcasts of standard Android intents in the app's manifest, unless the broadcast intent requires a <code>"signature"</code> or <code>"signatureOrSystem"</code> <a href="https://developer.android.com/guide/topics/manifest/permission-element.html#plevel"><code>protectionLevel</code></a> permission or are on the <a href="https://developer.android.com/preview/features/background-broadcasts.html">exemption list</a> .
+          </li>
+          <li>[C-0-7] if the app is targeting API level 25 or higher, they MUST stop the app's background services, just as if the app had called the services'<a href="https://developer.android.com/reference/android/app/Service.html#stopSelf%28%29"><code>stopSelf()</code></a> method, unless the app is placed on a temporary whitelist to handle a task that's visible to the user.
+          </li>
+          <li>[C-0-8] if the app is targeting API level 25 or higher, they MUST release the wakelocks the app holds.
+          </li>
+        </ul>
+      </li>
+    </ul>
+    <p>
+      The above list is not comprehensive. The Compatibility Test Suite (CTS) tests significant portions of the platform for behavioral compatibility, but not all. It is the responsibility of the implementer to ensure behavioral compatibility with the Android Open Source Project. For this reason, device implementers SHOULD use the source code available via the Android Open Source Project where possible, rather than re-implement significant parts of the system.
+    </p>
+    <h3 id="3_6_api_namespaces">
+      3.6. API Namespaces
+    </h3>
+    <p>
+      Android follows the package and class namespace conventions defined by the Java programming language. To ensure compatibility with third-party applications, device implementers MUST NOT make any prohibited modifications (see below) to these package namespaces:
+    </p>
+    <ul>
+      <li>
+        <code>java.*</code>
+      </li>
+      <li>
+        <code>javax.*</code>
+      </li>
+      <li>
+        <code>sun.*</code>
+      </li>
+      <li>
+        <code>android.*</code>
+      </li>
+      <li>
+        <code>com.android.*</code>
+      </li>
+    </ul>
+    <p>
+      That is, they:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST NOT modify the publicly exposed APIs on the Android platform by changing any method or class signatures, or by removing classes or class fields.
+      </li>
+      <li>[C-0-2] MUST NOT add any publicly exposed elements (such as classes or interfaces, or fields or methods to existing classes or interfaces) or Test or System APIs to the APIs in the above namespaces. A “publicly exposed element” is any construct that is not decorated with the “@hide” marker as used in the upstream Android source code.
+      </li>
+    </ul>
+    <p>
+      Device implementers MAY modify the underlying implementation of the APIs, but such modifications:
+    </p>
+    <ul>
+      <li>[C-0-3] MUST NOT impact the stated behavior and Java-language signature of any publicly exposed APIs.
+      </li>
+      <li>[C-0-4] MUST NOT be advertised or otherwise exposed to developers.
+      </li>
+    </ul>
+    <p>
+      However, device implementers MAY add custom APIs outside the standard Android namespace, but the custom APIs:
+    </p>
+    <ul>
+      <li>[C-0-5] MUST NOT be in a namespace owned by or referring to another organization. For instance, device implementers MUST NOT add APIs to the <code>com.google.*</code> or similar namespace: only Google may do so. Similarly, Google MUST NOT add APIs to other companies' namespaces.
+      </li>
+      <li>[C-0-6] MUST be packaged in an Android shared library so that only apps that explicitly use them (via the &lt;uses-library&gt; mechanism) are affected by the increased memory usage of such APIs.
+      </li>
+    </ul>
+    <p>
+      If a device implementer proposes to improve one of the package namespaces above (such as by adding useful new functionality to an existing API, or adding a new API), the implementer SHOULD visit <a href="http://source.android.com/">source.android.com</a> and begin the process for contributing changes and code, according to the information on that site.
+    </p>
+    <p>
+      Note that the restrictions above correspond to standard conventions for naming APIs in the Java programming language; this section simply aims to reinforce those conventions and make them binding through inclusion in this Compatibility Definition.
+    </p>
+    <h3 id="3_7_runtime_compatibility">
+      3.7. Runtime Compatibility
+    </h3>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-0-1] MUST support the full Dalvik Executable (DEX) format and <a href="https://android.googlesource.com/platform/dalvik/">Dalvik bytecode specification and semantics</a>.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-0-2] MUST configure Dalvik runtimes to allocate memory in accordance with the upstream Android platform, and as specified by the following table. (See <a href="#7_1_1_screen_configuration">section 7.1.1</a> for screen size and screen density definitions.)
+        </p>
+      </li>
+      <li>
+        <p>
+          SHOULD use Android RunTime (ART), the reference upstream implementation of the Dalvik Executable Format, and the reference implementation’s package management system.
+        </p>
+      </li>
+      <li>
+        <p>
+          SHOULD run fuzz tests under various modes of execution and target architectures to assure the stability of the runtime. Refer to <a href="https://android.googlesource.com/platform/art/+/master/tools/dexfuzz/">JFuzz</a> and <a href="https://android.googlesource.com/platform/art/+/master/tools/dexfuzz/">DexFuzz</a> in the Android Open Source Project website.
+        </p>
+      </li>
+    </ul>
+    <p>
+      Note that memory values specified below are considered minimum values and device implementations MAY allocate more memory per application.
+    </p>
+    <table>
+      <tr>
+        <th>
+          Screen Layout
+        </th>
+        <th>
+          Screen Density
+        </th>
+        <th>
+          Minimum Application Memory
+        </th>
+      </tr>
+      <tr>
+        <td rowspan="12">
+          Android Watch
+        </td>
+        <td>
+          120 dpi (ldpi)
+        </td>
+        <td rowspan="3">
+          32MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          160 dpi (mdpi)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          213 dpi (tvdpi)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          240 dpi (hdpi)
+        </td>
+        <td rowspan="2">
+          36MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          280 dpi (280dpi)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          320 dpi (xhdpi)
+        </td>
+        <td rowspan="2">
+          48MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          360 dpi (360dpi)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          400 dpi (400dpi)
+        </td>
+        <td>
+          56MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          420 dpi (420dpi)
+        </td>
+        <td>
+          64MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          480 dpi (xxhdpi)
+        </td>
+        <td>
+          88MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          560 dpi (560dpi)
+        </td>
+        <td>
+          112MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          640 dpi (xxxhdpi)
+        </td>
+        <td>
+          154MB
+        </td>
+      </tr>
+      <tr>
+        <td rowspan="12">
+          small/normal
+        </td>
+        <td>
+          120 dpi (ldpi)
+        </td>
+        <td rowspan="2">
+          32MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          160 dpi (mdpi)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          213 dpi (tvdpi)
+        </td>
+        <td rowspan="3">
+          48MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          240 dpi (hdpi)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          280 dpi (280dpi)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          320 dpi (xhdpi)
+        </td>
+        <td rowspan="2">
+          80MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          360 dpi (360dpi)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          400 dpi (400dpi)
+        </td>
+        <td>
+          96MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          420 dpi (420dpi)
+        </td>
+        <td>
+          112MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          480 dpi (xxhdpi)
+        </td>
+        <td>
+          128MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          560 dpi (560dpi)
+        </td>
+        <td>
+          192MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          640 dpi (xxxhdpi)
+        </td>
+        <td>
+          256MB
+        </td>
+      </tr>
+      <tr>
+        <td rowspan="12">
+          large
+        </td>
+        <td>
+          120 dpi (ldpi)
+        </td>
+        <td>
+          32MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          160 dpi (mdpi)
+        </td>
+        <td>
+          48MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          213 dpi (tvdpi)
+        </td>
+        <td rowspan="2">
+          80MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          240 dpi (hdpi)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          280 dpi (280dpi)
+        </td>
+        <td>
+          96MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          320 dpi (xhdpi)
+        </td>
+        <td>
+          128MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          360 dpi (360dpi)
+        </td>
+        <td>
+          160MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          400 dpi (400dpi)
+        </td>
+        <td>
+          192MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          420 dpi (420dpi)
+        </td>
+        <td>
+          228MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          480 dpi (xxhdpi)
+        </td>
+        <td>
+          256MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          560 dpi (560dpi)
+        </td>
+        <td>
+          384MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          640 dpi (xxxhdpi)
+        </td>
+        <td>
+          512MB
+        </td>
+      </tr>
+      <tr>
+        <td rowspan="12">
+          xlarge
+        </td>
+        <td>
+          120 dpi (ldpi)
+        </td>
+        <td>
+          48MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          160 dpi (mdpi)
+        </td>
+        <td>
+          80MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          213 dpi (tvdpi)
+        </td>
+        <td rowspan="2">
+          96MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          240 dpi (hdpi)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          280 dpi (280dpi)
+        </td>
+        <td>
+          144MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          320 dpi (xhdpi)
+        </td>
+        <td>
+          192MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          360 dpi (360dpi)
+        </td>
+        <td>
+          240MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          400 dpi (400dpi)
+        </td>
+        <td>
+          288MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          420 dpi (420dpi)
+        </td>
+        <td>
+          336MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          480 dpi (xxhdpi)
+        </td>
+        <td>
+          384MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          560 dpi (560dpi)
+        </td>
+        <td>
+          576MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          640 dpi (xxxhdpi)
+        </td>
+        <td>
+          768MB
+        </td>
+      </tr>
+    </table>
+    <h3 id="3_8_user_interface_compatibility">
+      3.8. User Interface Compatibility
+    </h3>
+    <h4 id="3_8_1_launcher_(home_screen)">
+      3.8.1. Launcher (Home Screen)
+    </h4>
+    <p>
+      Android includes a launcher application (home screen) and support for third-party applications to replace the device launcher (home screen).
+    </p>
+    <p>
+      If device implementations allow third-party applications to replace the device home screen, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST declare the platform feature <code>android.software.home_screen</code>.
+      </li>
+      <li>[C-1-2] MUST return the <a href="https://developer.android.com/reference/android/graphics/drawable/AdaptiveIconDrawable.html"><code>AdaptiveIconDrawable</code></a> object when the third party application use <code>&lt;adaptive-icon&gt;</code> tag to provide their icon, and the <a href="https://developer.android.com/reference/android/content/pm/PackageManager.html"><code>PackageManager</code></a> methods to retrieve icons are called.
+      </li>
+    </ul>
+    <p>
+      If device implementations include a default launcher that supports in-app pinning of shortcuts and widgets, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST report <code>true</code> for <a href="https://developer.android.com/reference/android/content/pm/ShortcutManager.html#isRequestPinShortcutSupported%28%29"><code>ShortcutManager.isRequestPinShortcutSupported()</code></a> and <a href="https://developer.android.com/reference/android/appwidget/AppWidgetManager.html#isRequestPinAppWidgetSupported%28%29"><code>AppWidgetManager.html.isRequestPinAppWidgetSupported()</code></a>.
+      </li>
+      <li>[C-2-2] MUST have user affordance asking the user before adding a shortcut requested by apps via the <a href="https://developer.android.com/reference/android/content/pm/ShortcutManager.html#requestPinShortcut%28android.content.pm.ShortcutInfo,%20android.content.IntentSender%29"><code>ShortcutManager.requestPinShortcut()</code></a> and the <a href="https://developer.android.com/reference/android/appwidget/AppWidgetManager.html#requestPinAppWidget%28android.content.ComponentName,android.os.Bundle,%20android.app.PendingIntent%29"><code>AppWidgetManager.requestPinAddWidget()</code></a> API method.
+      </li>
+    </ul>
+    <p>
+      Conversely, if device implementations do not support in-app pinning, they:
+    </p>
+    <ul>
+      <li>[C-3-1] MUST report <code>false</code> for <a href="https://developer.android.com/reference/android/content/pm/ShortcutManager.html#isRequestPinShortcutSupported%28%29"><code>ShortcutManager.isRequestPinShortcutSupported()</code></a> and <a href="https://developer.android.com/reference/android/appwidget/AppWidgetManager.html#isRequestPinAppWidgetSupported%28%29"><code>AppWidgetManager.html#isRequestPinAppWidgetSupported()</code></a>.
+      </li>
+    </ul>
+    <p>
+      If device implementations implement a default launcher that provides quick access to the additional shortcuts provided by third-party apps through the <a href="https://developer.android.com/reference/android/content/pm/ShortcutManager.html">ShortcutManager</a> API, they:
+    </p>
+    <ul>
+      <li>[C-4-1] MUST support all documented shortcut features (e.g. static and dynamic shortcuts, pinning shortcuts) and fully implement the APIs of the <a href="https://developer.android.com/reference/android/content/pm/ShortcutManager.html"><code>ShortcutManager</code></a> API class.
+      </li>
+    </ul>
+    <p>
+      If device implementations include a default launcher app that shows badges for the app icons, they:
+    </p>
+    <ul>
+      <li>[C-5-1] MUST respect the <a href="https://developer.android.com/reference/android/app/NotificationChannel.html#setShowBadge%28boolean%29"><code>NotificationChannel.setShowBadge()</code></a> API method. In other words, show a visual affordance associated with the app icon if the value is set as <code>true</code>, and do not show any app icon badging scheme when all of the app's notification channels have set the value as <code>false</code>.
+      </li>
+      <li>MAY override the app icon badges with their proprietary badging scheme when third-party applications indicate support of the proprietary badging scheme through the use of proprietary APIs, but SHOULD use the resources and values provided through the notification badges APIs described in <a href="https://developer.android.com/preview/features/notification-badges.html">the SDK</a> , such as the <a href="http://developer.android.com/reference/android/app/Notification.Builder.html#setNumber%28int%29"><code>Notification.Builder.setNumber()</code></a> and the <a href="http://developer.android.com/reference/android/app/Notification.Builder.html#setBadgeIconType%28int%29"><code>Notification.Builder.setBadgeIconType()</code></a> API.
+      </li>
+    </ul>
+    <h4 id="3_8_2_widgets">
+      3.8.2. Widgets
+    </h4>
+    <p>
+      Android supports third-party app widgets by defining a component type and corresponding API and lifecycle that allows applications to expose an <a href="http://developer.android.com/guide/practices/ui_guidelines/widget_design.html">“AppWidget”</a> to the end user.
+    </p>
+    <p>
+      If device implementations support third-party app widgets, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST declare support for platform feature android.software.app_widgets.
+      </li>
+      <li>[C-1-2] MUST include built-in support for AppWidgets and expose user interface affordances to add, configure, view, and remove AppWidgets directly within the Launcher.
+      </li>
+      <li>[C-1-3] MUST be capable of rendering widgets that are 4 x 4 in the standard grid size. See the <a href="http://developer.android.com/guide/practices/ui_guidelines/widget_design.html">App Widget Design Guidelines</a> in the Android SDK documentation for details.
+      </li>
+      <li>MAY support application widgets on the lock screen.
+      </li>
+    </ul>
+    <h4 id="3_8_3_notifications">
+      3.8.3. Notifications
+    </h4>
+    <p>
+      Android includes <a href="https://developer.android.com/reference/android/app/Notification.html"><code>Notification</code></a> and <a href="https://developer.android.com/reference/android/app/NotificationManager.html"><code>NotificationManager</code></a> APIs that allow third-party app developers to notify users of notable events and attract users' attention using the hardware components (e.g. sound, vibration and light) and software features (e.g. notification shade, system bar) of the device.
+    </p>
+    <h5 id="3_8_3_1_presentation_of_notifications">
+      3.8.3.1. Presentation of Notifications
+    </h5>
+    <p>
+      If device implementations allow third party apps to <a href="http://developer.android.com/guide/topics/ui/notifiers/notifications.html">notify users of notable events</a>, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support notifications that use hardware features, as described in the SDK documentation, and to the extent possible with the device implementation hardware. For instance, if a device implementation includes a vibrator, it MUST correctly implement the vibration APIs. If a device implementation lacks hardware, the corresponding APIs MUST be implemented as no-ops. This behavior is further detailed in <a href="#7_hardware_compatibility">section 7</a>.
+      </li>
+      <li>[C-1-2] MUST correctly render all <a href="https://developer.android.com/guide/topics/resources/available-resources.html">resources</a> (icons, animation files etc.) provided for in the APIs, or in the Status/System Bar <a href="http://developer.android.com/design/style/iconography.html">icon style guide</a>, although they MAY provide an alternative user experience for notifications than that provided by the reference Android Open Source implementation.
+      </li>
+      <li>[C-1-3] MUST honor and implement properly the behaviors described for <a href="https://developer.android.com/guide/topics/ui/notifiers/notifications.html#Managing">the APIs</a> to update, remove and group notifications.
+      </li>
+      <li>[C-1-4] MUST provide the full behavior of the <a href="https://developer.android.com/reference/android/app/NotificationChannel.html">NotificationChannel</a> API documented in the SDK.
+      </li>
+      <li>[C-1-5] MUST provide a user affordance to block and modify a certain third-party app's notification per each channel and app package level.
+      </li>
+      <li>[C-1-6] MUST also provide a user affordance to display deleted notification channels.
+      </li>
+      <li>SHOULD support rich notifications.
+      </li>
+      <li>SHOULD present some higher priority notifications as heads-up notifications.
+      </li>
+      <li>SHOULD have user affordance to snooze notifications.
+      </li>
+      <li>MAY only manage the visibility and timing of when third-party apps can notify users of notable events to mitigate safety issues such as driver distraction.
+      </li>
+    </ul>
+    <p>
+      If device implementations support rich notifications, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST use the exact resources as provided through the <a href="https://developer.android.com/reference/android/app/Notification.Style.html"><code>Notification.Style</code></a> API class and its subclasses for the presented resource elements.
+      </li>
+      <li>SHOULD present each and every resource element (e.g. icon, title and summary text) defined in the <a href="https://developer.android.com/reference/android/app/Notification.Style.html"><code>Notification.Style</code></a> API class and its subclasses.
+      </li>
+    </ul>
+    <p>
+      If device impelementations support heads-up notifications: they:
+    </p>
+    <ul>
+      <li>[C-3-1] MUST use the heads-up notification view and resources as described in the <a href="https://developer.android.com/reference/android/app/Notification.Builder.html"><code>Notification.Builder</code></a> API class when heads-up notifications are presented.
+      </li>
+    </ul>
+    <h5 id="3_8_3_2_notification_listener_service">
+      3.8.3.2. Notification Listener Service
+    </h5>
+    <p>
+      Android includes the <a href="https://developer.android.com/reference/android/service/notification/NotificationListenerService.html"><code>NotificationListenerService</code></a> APIs that allow apps (once explicitly enabled by the user) to receive a copy of all notifications as they are posted or updated.
+    </p>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST correctly and promptly update notifications in their entirety to all such installed and user-enabled listener services, including any and all metadata attached to the Notification object.
+      </li>
+      <li>[C-0-2] MUST respect the <a href="https://developer.android.com/reference/android/service/notification/NotificationListenerService.html#snoozeNotification%28java.lang.String,%20long%29"><code>snoozeNotification()</code></a> API call, and dismiss the notification and make a callback after the snooze duration that is set in the API call.
+      </li>
+    </ul>
+    <p>
+      If device implementations have a user affordance to snooze notifications, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST reflect the snoozed notification status properly through the standard APIs such as <a href="https://developer.android.com/reference/android/service/notification/NotificationListenerService.html#getSnoozedNotifications%28%29"><code>NotificationListenerService.getSnoozedNotifications()</code></a>.
+      </li>
+      <li>[C-1-2] MUST make this user affordance available to snooze notifications from each installed third-party app's, unless they are from persistent/foreground services.
+      </li>
+    </ul>
+    <h5 id="3_8_3_3_dnd_(do_not_disturb)">
+      3.8.3.3. DND (Do not Disturb)
+    </h5>
+    <p>
+      If device implementations support the DND feature, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST implement an activity that would respond to the intent <a href="https://developer.android.com/reference/android/provider/Settings.html#ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS">ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS</a>, which for implementations with UI_MODE_TYPE_NORMAL it MUST be an activity where the user can grant or deny the app access to DND policy configurations.
+      </li>
+      <li>[C-1-2] MUST, for when the device implementation has provided a means for the user to grant or deny third-party apps to access the DND policy configuration, display <a href="https://developer.android.com/reference/android/app/NotificationManager.html#addAutomaticZenRule%28android.app.AutomaticZenRule%29">Automatic DND rules</a> created by applications alongside the user-created and pre-defined rules.
+      </li>
+      <li>[C-1-3] MUST honor the <a href="https://developer.android.com/reference/android/app/NotificationManager.Policy.html#suppressedVisualEffects"><code>suppressedVisualEffects</code></a> values passed along the <a href="https://developer.android.com/reference/android/app/NotificationManager.Policy.html#NotificationManager.Policy%28int,%20int,%20int,%20int%29"><code>NotificationManager.Policy</code></a> and if an app has set any of the SUPPRESSED_EFFECT_SCREEN_OFF or SUPPRESSED_EFFECT_SCREEN_ON flags, it SHOULD indicate to the user that the visual effects are suppressed in the DND settings menu.
+      </li>
+    </ul>
+    <h4 id="3_8_4_search">
+      3.8.4. Search
+    </h4>
+    <p>
+      Android includes APIs that allow developers to <a href="http://developer.android.com/reference/android/app/SearchManager.html">incorporate search</a> into their applications and expose their application’s data into the global system search. Generally speaking, this functionality consists of a single, system-wide user interface that allows users to enter queries, displays suggestions as users type, and displays results. The Android APIs allow developers to reuse this interface to provide search within their own apps and allow developers to supply results to the common global search user interface.
+    </p>
+    <ul>
+      <li>Android device implementations SHOULD include global search, a single, shared, system-wide search user interface capable of real-time suggestions in response to user input.
+      </li>
+    </ul>
+    <p>
+      If device implementations implement the global search interface, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST implement the APIs that allow third-party applications to add suggestions to the search box when it is run in global search mode.
+      </li>
+    </ul>
+    <p>
+      If no third-party applications are installed that make use of the global search:
+    </p>
+    <ul>
+      <li>The default behavior SHOULD be to display web search engine results and suggestions.
+      </li>
+    </ul>
+    <p>
+      Android also includes the <a href="https://developer.android.com/reference/android/app/assist/package-summary.html">Assist APIs</a> to allow applications to elect how much information of the current context is shared with the assistant on the device.
+    </p>
+    <p>
+      If device implementations support the Assist action, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST indicate clearly to the end user when the context is shared, by either:
+        <ul>
+          <li>Each time the assist app accesses the context, displaying a white light around the edges of the screen that meet or exceed the duration and brightness of the Android Open Source Project implementation.
+          </li>
+          <li>For the preinstalled assist app, providing a user affordance less than two navigations away from <a href="#3_2_3_5_default_app_settings">the default voice input and assistant app settings menu</a>, and only sharing the context when the assist app is explicitly invoked by the user through a hotword or assist navigation key input.
+          </li>
+        </ul>
+      </li>
+      <li>[C-2-2] The designated interaction to launch the assist app as described in <a href="#7_2_3_navigation_keys">section 7.2.3</a> MUST launch the user-selected assist app, in other words the app that implements <code>VoiceInteractionService</code>, or an activity handling the <code>ACTION_ASSIST</code> intent.
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to use long press on <code>HOME</code> key as this designated interaction.
+      </li>
+    </ul>
+    <h4 id="3_8_5_alerts_and_toasts">
+      3.8.5. Alerts and Toasts
+    </h4>
+    <p>
+      Applications can use the <a href="http://developer.android.com/reference/android/widget/Toast.html"><code>Toast</code></a> API to display short non-modal strings to the end user that disappear after a brief period of time, and use the <a href="http://developer.android.com/reference/android/view/WindowManager.LayoutParams.html#TYPE_APPLICATION_OVERLAY"><code>TYPE_APPLICATION_OVERLAY</code></a> window type API to display alert windows as an overlay over other apps.
+    </p>
+    <p>
+      If device implementations include a screen or video output, they:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-1-1] MUST provide a user affordance to block an app from displaying alert windows that use the <a href="http://developer.android.com/reference/android/view/WindowManager.LayoutParams.html#TYPE_APPLICATION_OVERLAY"><code>TYPE_APPLICATION_OVERLAY</code></a> . The AOSP implementation meets this requirement by having controls in the notification shade.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-1-2] MUST honor the Toast API and display Toasts from applications to end users in some highly visible manner.
+        </p>
+      </li>
+    </ul>
+    <h4 id="3_8_6_themes">
+      3.8.6. Themes
+    </h4>
+    <p>
+      Android provides “themes” as a mechanism for applications to apply styles across an entire Activity or application.
+    </p>
+    <p>
+      Android includes a “Holo” and "Material" theme family as a set of defined styles for application developers to use if they want to match the <a href="http://developer.android.com/guide/topics/ui/themes.html">Holo theme look and feel</a> as defined by the Android SDK.
+    </p>
+    <p>
+      If device implementations include a screen or video output, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST NOT alter any of the <a href="http://developer.android.com/reference/android/R.style.html">Holo theme attributes</a> exposed to applications.
+      </li>
+      <li>[C-1-2] MUST support the “Material” theme family and MUST NOT alter any of the <a href="http://developer.android.com/reference/android/R.style.html#Theme_Material">Material theme attributes</a> or their assets exposed to applications.
+      </li>
+    </ul>
+    <p>
+      Android also includes a “Device Default” theme family as a set of defined styles for application developers to use if they want to match the look and feel of the device theme as defined by the device implementer.
+    </p>
+    <ul>
+      <li>Device implementations MAY modify the <a href="http://developer.android.com/reference/android/R.style.html">Device Default theme attributes</a> exposed to applications.
+      </li>
+    </ul>
+    <p>
+      Android supports a variant theme with translucent system bars, which allows application developers to fill the area behind the status and navigation bar with their app content. To enable a consistent developer experience in this configuration, it is important the status bar icon style is maintained across different device implementations.
+    </p>
+    <p>
+      If device implementations include a system status bar, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST use white for system status icons (such as signal strength and battery level) and notifications issued by the system, unless the icon is indicating a problematic status or an app requests a light status bar using the SYSTEM_UI_FLAG_LIGHT_STATUS_BAR flag.
+      </li>
+      <li>[C-2-2] Android device implementations MUST change the color of the system status icons to black (for details, refer to <a href="http://developer.android.com/reference/android/R.style.html">R.style</a>) when an app requests a light status bar.
+      </li>
+    </ul>
+    <h4 id="3_8_7_live_wallpapers">
+      3.8.7. Live Wallpapers
+    </h4>
+    <p>
+      Android defines a component type and corresponding API and lifecycle that allows applications to expose one or more <a href="http://developer.android.com/reference/android/service/wallpaper/WallpaperService.html">“Live Wallpapers”</a> to the end user. Live wallpapers are animations, patterns, or similar images with limited input capabilities that display as a wallpaper, behind other applications.
+    </p>
+    <p>
+      Hardware is considered capable of reliably running live wallpapers if it can run all live wallpapers, with no limitations on functionality, at a reasonable frame rate with no adverse effects on other applications. If limitations in the hardware cause wallpapers and/or applications to crash, malfunction, consume excessive CPU or battery power, or run at unacceptably low frame rates, the hardware is considered incapable of running live wallpaper. As an example, some live wallpapers may use an OpenGL 2.0 or 3.x context to render their content. Live wallpaper will not run reliably on hardware that does not support multiple OpenGL contexts because the live wallpaper use of an OpenGL context may conflict with other applications that also use an OpenGL context.
+    </p>
+    <ul>
+      <li>Device implementations capable of running live wallpapers reliably as described above SHOULD implement live wallpapers.
+      </li>
+    </ul>
+    <p>
+      If device implementations implement live wallpapers, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST report the platform feature flag android.software.live_wallpaper.
+      </li>
+    </ul>
+    <h4 id="3_8_8_activity_switching">
+      3.8.8. Activity Switching
+    </h4>
+    <p>
+      The upstream Android source code includes the <a href="https://developer.android.com/guide/components/activities/recents.html">overview screen</a>, a system-level user interface for task switching and displaying recently accessed activities and tasks using a thumbnail image of the application’s graphical state at the moment the user last left the application.
+    </p>
+    <p>
+      Device implementations including the recents function navigation key as detailed in <a href="#7_2_3_navigation_keys">section 7.2.3</a> MAY alter the interface.
+    </p>
+    <p>
+      If device implementations including the recents function navigation key as detailed in <a href="#7_2_3_navigation_keys">section 7.2.3</a> alter the interface, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support at least up to 20 displayed activities.
+      </li>
+      <li>SHOULD at least display the title of 4 activities at a time.
+      </li>
+      <li>[C-1-2] MUST implement the <a href="http://developer.android.com/about/versions/android-5.0.html#ScreenPinning">screen pinning behavior</a> and provide the user with a settings menu to toggle the feature.
+      </li>
+      <li>SHOULD display highlight color, icon, screen title in recents.
+      </li>
+      <li>SHOULD display a closing affordance ("x") but MAY delay this until user interacts with screens.
+      </li>
+      <li>SHOULD implement a shortcut to switch easily to the previous activity
+      </li>
+      <li>SHOULD trigger the fast-switch action between the two most recently used apps, when the recents function key is tapped twice.
+      </li>
+      <li>SHOULD trigger the split-screen multiwindow-mode, if supported, when the recents functions key is long pressed.
+      </li>
+      <li>
+        <p>
+          MAY display affiliated recents as a group that moves together.
+        </p>
+      </li>
+      <li>
+        <p>
+          [SR] Device implementations are STRONGLY RECOMMENDED to use the upstream Android user interface (or a similar thumbnail-based interface) for the overview screen.
+        </p>
+      </li>
+    </ul>
+    <h4 id="3_8_9_input_management">
+      3.8.9. Input Management
+    </h4>
+    <p>
+      Android includes support for <a href="http://developer.android.com/guide/topics/text/creating-input-method.html">Input Management</a> and support for third-party input method editors.
+    </p>
+    <p>
+      If device implementations allow users to use third-party input methods on the device, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST declare the platform feature android.software.input_methods and support IME APIs as defined in the Android SDK documentation.
+      </li>
+      <li>[C-1-2] MUST provide a user-accessible mechanism to add and configure third-party input methods in response to the android.settings.INPUT_METHOD_SETTINGS intent.
+      </li>
+    </ul>
+    <p>
+      If device implementations declare the <a href="https://developer.android.com/reference/android/content/pm/PackageManager.html#FEATURE_AUTOFILL"><code>android.software.autofill</code></a> feature flag, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST fully implement the <a href="https://developer.android.com/reference/android/service/autofill/AutofillService.html"><code>AutofillService</code></a> and <a href="https://developer.android.com/reference/android/view/autofill/AutofillManager.html"><code>AutofillManager</code></a> APIs and honor the <a href="https://developer.android.com/reference/android/provider/Settings.html#ACTION_REQUEST_SET_AUTOFILL_SERVICE"><code>android.settings.REQUEST_SET_AUTOFILL_SERVICE</code></a> intent to show a default app settings menu to enable and disable autofill and change the default autofill service for the user.
+      </li>
+    </ul>
+    <h4 id="3_8_10_lock_screen_media_control">
+      3.8.10. Lock Screen Media Control
+    </h4>
+    <p>
+      The Remote Control Client API is deprecated from Android 5.0 in favor of the <a href="http://developer.android.com/reference/android/app/Notification.MediaStyle.html">Media Notification Template</a> that allows media applications to integrate with playback controls that are displayed on the lock screen.
+    </p>
+    <h4 id="3_8_11_screen_savers_(previously_dreams)">
+      3.8.11. Screen savers (previously Dreams)
+    </h4>
+    <p>
+      Android includes support for <a href="http://developer.android.com/reference/android/service/dreams/DreamService.html">interactivescreensavers</a>, previously referred to as Dreams. Screen savers allow users to interact with applications when a device connected to a power source is idle or docked in a desk dock. Android Watch devices MAY implement screen savers, but other types of device implementations SHOULD include support for screen savers and provide a settings option for users toconfigure screen savers in response to the <code>android.settings.DREAM_SETTINGS</code> intent.
+    </p>
+    <h4 id="3_8_12_location">
+      3.8.12. Location
+    </h4>
+    <p>
+      If device implementations include a hardware sensor (e.g. GPS) that is capable of providing the location coordinates:
+    </p>
+    <ul>
+      <li>[C-1-1] <a href="http://developer.android.com/reference/android/provider/Settings.Secure.html#LOCATION_MODE">location modes</a> MUST be displayed in the Location menu within Settings.
+      </li>
+    </ul>
+    <h4 id="3_8_13_unicode_and_font">
+      3.8.13. Unicode and Font
+    </h4>
+    <p>
+      Android includes support for the emoji characters defined in <a href="http://www.unicode.org/versions/Unicode10.0.0/">Unicode 10.0</a>.
+    </p>
+    <p>
+      If device implementations include a screen or video output, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST be capable of rendering these emoji characters in color glyph.
+      </li>
+      <li>[C-1-2] MUST include support for:
+      </li>
+      <li>Roboto 2 font with different weights—sans-serif-thin, sans-serif-light, sans-serif-medium, sans-serif-black, sans-serif-condensed, sans-serif-condensed-light for the languages available on the device.
+      </li>
+      <li>Full Unicode 7.0 coverage of Latin, Greek, and Cyrillic, including the Latin Extended A, B, C, and D ranges, and all glyphs in the currency symbols block of Unicode 7.0.
+      </li>
+      <li>SHOULD support the skin tone and diverse family emojis as specified in the <a href="http://unicode.org/reports/tr51">Unicode Technical Report #51</a>.
+      </li>
+    </ul>
+    <p>
+      If device implementations include an IME, they:
+    </p>
+    <ul>
+      <li>SHOULD provide an input method to the user for these emoji characters.
+      </li>
+    </ul>
+    <h4 id="3_8_14_multi-windows">
+      3.8.14. Multi-windows
+    </h4>
+    <p>
+      If device implementations have the capability to display multiple activities at the same time, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST implement such multi-window mode(s) in accordance with the application behaviors and APIs described in the Android SDK <a href="https://developer.android.com/guide/topics/ui/multi-window.html">multi-window mode support documentation</a> and meet the following requirements:
+      </li>
+      <li>[C-1-2] Applications can indicate whether they are capable of operating in multi-window mode in the <code>AndroidManifest.xml</code> file, either explicitly via setting the <a href="https://developer.android.com/reference/android/R.attr.html#resizeableActivity"><code>android:resizeableActivity</code></a> attribute to <code>true</code> or implicitly by having the targetSdkVersion &gt; 24. Apps that explicitly set this attribute to <code>false</code> in their manifest MUST NOT be launched in multi-window mode. Older apps with targetSdkVersion &lt; 24 that did not set this <code>android:resizeableActivity</code> attribute MAY be launched in multi-window mode, but the system MUST provide warning that the app may not work as expected in multi-window mode.
+      </li>
+      <li>[C-1-3] MUST NOT offer split-screen or freeform mode if the screen height &lt; 440 dp and the screen width &lt; 440 dp.
+      </li>
+      <li>Device implementations with screen size <code>xlarge</code> SHOULD support freeform mode.
+      </li>
+    </ul>
+    <p>
+      If device implementations support multi-window mode(s), and the split screen mode, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST preload a <a href="https://developer.android.com/guide/topics/ui/multi-window.html#configuring">resizeable</a> launcher as the default.
+      </li>
+      <li>[C-2-2] MUST crop the docked activity of a split-screen multi-window but SHOULD show some content of it, if the Launcher app is the focused window.
+      </li>
+      <li>[C-2-3] MUST honor the declared <a href="https://developer.android.com/reference/android/R.styleable.html#AndroidManifestLayout_minWidth"><code>AndroidManifestLayout_minWidth</code></a> and <a href="https://developer.android.com/reference/android/R.styleable.html#AndroidManifestLayout_minHeight"><code>AndroidManifestLayout_minHeight</code></a> values of the third-party launcher application and not override these values in the course of showing some content of the docked activity.
+      </li>
+    </ul>
+    <p>
+      If device implementations support multi-window mode(s) and Picture-in-Picture multi-window mode, they:
+    </p>
+    <ul>
+      <li>[C-3-1] MUST launch activities in picture-in-picture multi-window mode when the app is: * Targeting API level 26 or higher and declares <a href="https://developer.android.com/reference/android/R.attr.html#supportsPictureInPicture"><code>android:supportsPictureInPicture</code></a> * Targeting API level 25 or lower and declares both <a href="https://developer.android.com/reference/android/R.attr.html#resizeableActivity"><code>android:resizeableActivity</code></a> and <a href="https://developer.android.com/reference/android/R.attr.html#supportsPictureInPicture"><code>android:supportsPictureInPicture</code></a>.
+      </li>
+      <li>[C-3-2] MUST expose the actions in their SystemUI as specified by the current PIP activity through the <a href="https://developer.android.com/reference/android/app/PictureInPictureParams.Builder.html#setActions%28java.util.List%3Candroid.app.RemoteAction%3E%29"><code>setActions()</code></a> API.
+      </li>
+      <li>[C-3-3] MUST support aspect ratios greater than or equal to 1:2.39 and less than or equal to 2.39:1, as specified by the PIP activity through the <a href="https://developer.android.com/reference/android/app/PictureInPictureParams.Builder.html#setAspectRatio%28android.util.Rational%29"><code>setAspectRatio()</code></a> API.
+      </li>
+      <li>[C-3-4] MUST use <a href="https://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_WINDOW"><code>KeyEvent.KEYCODE_WINDOW</code></a> to control the PIP window; if PIP mode is not implemented, the key MUST be available to the foreground activity.
+      </li>
+      <li>[C-3-5] MUST provide a user affordance to block an app from displaying in PIP mode; the AOSP implementation meets this requirement by having controls in the notification shade.
+      </li>
+      <li>[C-3-6] MUST allocate minimum width and height of 108 dp for the PIP window and minimum width of 240 dp and height of 135 dp for the PIP window when the <code>Configuration.uiMode</code> is configured as <a href="https://developer.android.com/reference/android/content/res/Configuration.html#UI_MODE_TYPE_TELEVISION"><code>UI_MODE_TYPE_TELEVISION</code></a>
+      </li>
+    </ul>
+    <h3 id="3_9_device_administration">
+      3.9. Device Administration
+    </h3>
+    <p>
+      Android includes features that allow security-aware applications to perform device administration functions at the system level, such as enforcing password policies or performing remote wipe, through the <a href="http://developer.android.com/guide/topics/admin/device-admin.html">Android Device Administration API</a>].
+    </p>
+    <p>
+      If device implementations implement the full range of <a href="http://developer.android.com/guide/topics/admin/device-admin.html">device administration</a> policies defined in the Android SDK documentation, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST declare <code>android.software.device_admin</code>.
+      </li>
+      <li>[C-1-2] MUST support device owner provisioning as described in <a href="#3_9_1_device_provisioning">section 3.9.1</a> and <a href="#3_9_1_1_device_owner_provisioning">section 3.9.1.1</a>.
+      </li>
+      <li>[C-1-3] MUST declare the support of manged profiles via the <code>android.software.managed_users</code> feature flag, except for when the device is configured so that it would <a href="http://developer.android.com/reference/android/app/ActivityManager.html#isLowRamDevice%28%29">report</a> itself as a low RAM device or so that it allocate internal (non-removable) storage as shared storage.
+      </li>
+    </ul>
+    <h4 id="3_9_1_device_provisioning">
+      3.9.1 Device Provisioning
+    </h4>
+    <h5 id="3_9_1_1_device_owner_provisioning">
+      3.9.1.1 Device owner provisioning
+    </h5>
+    <p>
+      If device implementations declare <code>android.software.device_admin</code>, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support enrolling a Device Policy Client (DPC) as a <a href="http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#isDeviceOwnerApp%28java.lang.String%29">Device Owner app</a> as described below:.
+        <ul>
+          <li>when the device implementation has no user data is configured yet, it:
+            <ul>
+              <li>[C-1-3] MUST report <code>true</code> for <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#isProvisioningAllowed(java.lang.String)"><code>DevicePolicyManager.isProvisioningAllowed(ACTION_PROVISION_MANAGED_DEVICE)</code></a>.
+              </li>
+              <li>[C-1-4] MUST enroll the DPC application as the Device Owner app in response to the intent action <a href="http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#ACTION_PROVISION_MANAGED_DEVICE"><code>android.app.action.PROVISION_MANAGED_DEVICE</code></a>.
+              </li>
+              <li>[C-1-5] MUST enroll the DPC application as the Device Owner app if the device declares Near-Field Communications (NFC) support via the feature flag <code>android.hardware.nfc</code> and receives an NFC message containing a record with MIME type <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#MIME_TYPE_PROVISIONING_NFC"><code>MIME_TYPE_PROVISIONING_NFC</code></a>.
+              </li>
+            </ul>
+          </li>
+          <li>When the device implementation has user data, it:
+            <ul>
+              <li>[C-1-6] MUST report <code>false</code> for the <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#isProvisioningAllowed(java.lang.String)"><code>DevicePolicyManager.isProvisioningAllowed(ACTION_PROVISION_MANAGED_DEVICE)</code></a>.
+              </li>
+              <li>[C-1-7] MUST not enroll any DPC application as the Device Owner App any more.
+              </li>
+            </ul>
+          </li>
+        </ul>
+      </li>
+      <li>[C-1-2] MUST NOT set an application (including pre-installed app) as the Device Owner app without explicit consent or action from the user or the administrator of the device.
+      </li>
+    </ul>
+    <p>
+      If device implementations declare <code>android.software.device_admin</code>, but also include a proprietary Device Owner management solution and provide a mechanism to promote an application configured in their solution as a "Device Owner equivalent" to the standard "Device Owner" as recognized by the standard Android <a href="http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html">DevicePolicyManager</a> APIs, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST have a process in place to verify that the specific app being promoted belongs to a legitimate enterprise device management solution and it has been already configured in the proprietary solution to have the rights equivalent as a "Device Owner".
+      </li>
+      <li>[C-2-2] MUST show the same AOSP Device Owner consent disclosure as the flow initiated by <a href="http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#ACTION_PROVISION_MANAGED_DEVICE"><code>android.app.action.PROVISION_MANAGED_DEVICE</code></a> prior to enrolling the DPC application as "Device Owner".
+      </li>
+      <li>MAY have user data on the device prior to enrolling the DPC application as "Device Owner".
+      </li>
+    </ul>
+    <h5 id="3_9_1_2_managed_profile_provisioning">
+      3.9.1.2 Managed profile provisioning
+    </h5>
+    <p>
+      If device implementations declare <code>android.software.managed_users</code>, they:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-1-1] MUST implement the <a href="http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#ACTION_PROVISION_MANAGED_PROFILE">APIs</a> allowing a Device Policy Controller (DPC) application to become the <a href="http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#isProfileOwnerApp%28java.lang.String%29">owner of a new Managed Profile</a>.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-1-2] The managed profile provisioning process (the flow initiated by <a href="http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#ACTION_PROVISION_MANAGED_PROFILE">android.app.action.PROVISION_MANAGED_PROFILE</a>) users experience MUST align with the AOSP implementation.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-1-3] MUST provide the following user affordances within the Settings to indicate to the user when a particular system function has been disabled by the Device Policy Controller (DPC):
+        </p>
+        <ul>
+          <li>A consistent icon or other user affordance (for example the upstream AOSP info icon) to represent when a particular setting is restricted by a Device Admin.
+          </li>
+          <li>A short explanation message, as provided by the Device Admin via the <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#setShortSupportMessage%28android.content.ComponentName,%20java.lang.CharSequence%29"><code>setShortSupportMessage</code></a>.
+          </li>
+          <li>The DPC application’s icon.
+          </li>
+        </ul>
+      </li>
+    </ul>
+    <h3 id="3_9_2_managed_profile_support">
+      3.9.2 Managed Profile Support
+    </h3>
+    <p>
+      If device implementations declare <code>android.software.managed_users</code>, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support managed profiles via the <code>android.app.admin.DevicePolicyManager</code> APIs.
+      </li>
+      <li>[C-1-2] MUST allow one and only <a href="http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#ACTION_PROVISION_MANAGED_PROFILE">one managed profile to be created</a>.
+      </li>
+      <li>[C-1-3] MUST use an icon badge (similar to the AOSP upstream work badge) to represent the managed applications and widgets and other badged UI elements like Recents &amp; Notifications.
+      </li>
+      <li>[C-1-4] MUST display a notification icon (similar to the AOSP upstream work badge) to indicate when user is within a managed profile application.
+      </li>
+      <li>[C-1-5] MUST display a toast indicating that the user is in the managed profile if and when the device wakes up (ACTION_USER_PRESENT) and the foreground application is within the managed profile.
+      </li>
+      <li>[C-1-6] Where a managed profile exists, MUST show a visual affordance in the Intent 'Chooser' to allow the user to forward the intent from the managed profile to the primary user or vice versa, if enabled by the Device Policy Controller.
+      </li>
+      <li>[C-1-7] Where a managed profile exists, MUST expose the following user affordances for both the primary user and the managed profile:
+        <ul>
+          <li>Separate accounting for battery, location, mobile data and storage usage for the primary user and managed profile.
+          </li>
+          <li>Independent management of VPN Applications installed within the primary user or managed profile.
+          </li>
+          <li>Independent management of applications installed within the primary user or managed profile.
+          </li>
+          <li>Independent management of accounts within the primary user or managed profile.
+          </li>
+        </ul>
+      </li>
+      <li>[C-1-8] MUST ensure the preinstalled dialer, contacts and messaging applications can search for and look up caller information from the managed profile (if one exists) alongside those from the primary profile, if the Device Policy Controller permits it.
+      </li>
+      <li>[C-1-9] MUST ensure that it satisfies all the security requirements applicable for a device with multiple users enabled (see<a href="#9_5_multi-user_support">section 9.5</a>), even though the managed profile is not counted as another user in addition to the primary user.
+      </li>
+      <li>[C-1-10] MUST support the ability to specify a separate lock screen meeting the following requirements to grant access to apps running in a managed profile.
+        <ul>
+          <li>Device implementations MUST honor the <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#ACTION_SET_NEW_PASSWORD"><code>DevicePolicyManager.ACTION_SET_NEW_PASSWORD</code></a> intent and show an interface to configure a separate lock screen credential for the managed profile.
+          </li>
+          <li>The lock screen credentials of the managed profile MUST use the same credential storage and management mechanisms as the parent profile, as documented on the <a href="http://source.android.com/security/authentication/index.html">Android Open Source Project Site</a>
+          </li>
+          <li>The DPC <a href="https://developer.android.com/guide/topics/admin/device-admin.html#pwd">password policies</a> MUST apply to only the managed profile's lock screen credentials unless called upon the <code>DevicePolicyManager</code> instance returned by <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#getParentProfileInstance%28android.content.ComponentName%29">getParentProfileInstance</a>.
+          </li>
+        </ul>
+      </li>
+      <li>When contacts from the managed profile are displayed in the preinstalled call log, in-call UI, in-progress and missed-call notifications, contacts and messaging apps they SHOULD be badged with the same badge used to indicate managed profile applications.
+      </li>
+    </ul>
+    <h3 id="3_10_accessibility">
+      3.10. Accessibility
+    </h3>
+    <p>
+      Android provides an accessibility layer that helps users with disabilities to navigate their devices more easily. In addition, Android provides platform APIs that enable accessibility service implementations to receive callbacks for user and system events and generate alternate feedback mechanisms, such as text-to-speech, haptic feedback, and trackball/d-pad navigation.
+    </p>
+    <p>
+      If device implementations support third-party accessibility services, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST provide an implementation of the Android accessibility framework as described in the <a href="http://developer.android.com/reference/android/view/accessibility/package-summary.html">accessibility APIs</a> SDK documentation.
+      </li>
+      <li>[C-1-2] MUST generate accessibility events and deliver the appropriate <code>AccessibilityEvent</code> to all registered <a href="http://developer.android.com/reference/android/accessibilityservice/AccessibilityService.html"><code>AccessibilityService</code></a> implementations as documented in the SDK.
+      </li>
+      <li>[C-1-3] MUST honor the <code>android.settings.ACCESSIBILITY_SETTINGS</code> intent to provide a user-accessible mechanism to enable and disable the third-party accessibility services alongside the preloaded accessibility services.
+      </li>
+      <li>[C-1-4] MUST add a button in the system's navigation bar allowing the user to control the accessibility service when the enabled accessibility services declare the <a href="https://developer.android.com/reference/android/accessibilityservice/AccessibilityServiceInfo.html#FLAG%5FREQUEST%5FACCESSIBILITY%5FBUTTON"><code>AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON</code></a> . Note that for device implementations with no system navigation bar, this requirement is not applicable, but device implementations SHOULD provide a user affordance to control these accessibility services.
+      </li>
+    </ul>
+    <p>
+      If device implementations include preloaded accessibility services, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST implement these preloaded accessibility services as [Direct Boot aware] (https://developer.android.com/reference/android/content/pm/ComponentInfo.html#directBootAware) apps when the data storage is encrypted with File Based Encryption (FBE).
+      </li>
+      <li>SHOULD provide a mechanism in the out-of-box setup flow for users to enable relevant accessibility services, as well as options to adjust the font size, display size and magnification gestures.
+      </li>
+    </ul>
+    <h3 id="3_11_text-to-speech">
+      3.11. Text-to-Speech
+    </h3>
+    <p>
+      Android includes APIs that allow applications to make use of text-to-speech (TTS) services and allows service providers to provide implementations of TTS services.
+    </p>
+    <p>
+      If device implementations reporting the feature android.hardware.audio.output, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support the <a href="http://developer.android.com/reference/android/speech/tts/package-summary.html">Android TTS framework</a> APIs.
+      </li>
+    </ul>
+    <p>
+      If device implementations support installation of third-party TTS engines, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST provide user affordance to allow the user to select a TTS engine for use at system level.
+      </li>
+    </ul>
+    <h3 id="3_12_tv_input_framework">
+      3.12. TV Input Framework
+    </h3>
+    <p>
+      The <a href="http://source.android.com/devices/tv/index.html">Android Television Input Framework (TIF)</a> simplifies the delivery of live content to Android Television devices. TIF provides a standard API to create input modules that control Android Television devices.
+    </p>
+    <p>
+      If device implementations support TIF, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST declare the platform feature <code>android.software.live_tv</code>.
+      </li>
+      <li>[C-1-2] MUST preload a TV application (TV App) and meet all requirements described in <a href="#3_12_tv-input-framework">section 3.12.1</a>.
+      </li>
+    </ul>
+    <h4 id="3_12_1_tv_app">
+      3.12.1. TV App
+    </h4>
+    <p>
+      If device implementations support TIF:
+    </p>
+    <ul>
+      <li>[C-1-1] The TV App MUST provide facilities to install and use <a href="http://developer.android.com/reference/android/media/tv/TvContract.Channels.html">TV Channels</a> and meet the following requirements:
+      </li>
+    </ul>
+    <p>
+      The TV app that is required for Android device implementations declaring the <code>android.software.live_tv</code> feature flag, MUST meet the following requirements:
+    </p>
+    <ul>
+      <li>Device implementations SHOULD allow third-party TIF-based inputs (<a href="https://source.android.com/devices/tv/index.html#third-party_input_example">third-party inputs</a>) to be installed and managed.
+      </li>
+      <li>Device implementations MAY provide visual separation between pre-installed <a href="https://source.android.com/devices/tv/index.html#tv_inputs">TIF-based inputs</a> (installed inputs) and third-party inputs.
+      </li>
+      <li>Device implementations SHOULD NOT display the third-party inputs more than a single navigation action away from the TV App (i.e. expanding a list of third-party inputs from the TV App).
+      </li>
+    </ul>
+    <p>
+      The Android Open Source Project provides an implementation of the TV App that meets the above requirements.
+    </p>
+    <h5 id="3_12_1_1_electronic_program_guide">
+      3.12.1.1. Electronic Program Guide
+    </h5>
+    <p>
+      If device implementations support TIF, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST show an informational and interactive overlay, which MUST include an electronic program guide (EPG) generated from the values in the <a href="https://developer.android.com/reference/android/media/tv/TvContract.Programs.html">TvContract.Programs</a> fields.
+      </li>
+      <li>[C-1-2] On channel change, device implementations MUST display EPG data for the currently playing program.
+      </li>
+      <li>[SR] The EPG is STRONGLY RECOMMENDED to display installed inputs and third-party inputs with equal prominence. The EPG SHOULD NOT display the third-party inputs more than a single navigation action away from the installed inputs on the EPG.
+      </li>
+      <li>The EPG SHOULD display information from all installed inputs and third-party inputs.
+      </li>
+      <li>The EPG MAY provide visual separation between the installed inputs and third-party inputs.
+      </li>
+    </ul>
+    <h5 id="3_12_1_2_navigation">
+      3.12.1.2. Navigation
+    </h5>
+    <p>
+      If device implementations support TIF, they:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-1-1] MUST allow navigation for the following functions via the D-pad, Back, and Home keys on the Android Television device’s input device(s) (i.e. remote control, remote control application, or game controller):
+        </p>
+        <ul>
+          <li>Changing TV channels
+          </li>
+          <li>Opening EPG
+          </li>
+          <li>Configuring and tuning to third-party TIF-based inputs
+          </li>
+          <li>Opening Settings menu
+          </li>
+        </ul>
+      </li>
+      <li>
+        <p>
+          SHOULD pass key events to HDMI inputs through CEC.
+        </p>
+      </li>
+    </ul>
+    <h5 id="3_12_1_3_tv_input_app_linking">
+      3.12.1.3. TV input app linking
+    </h5>
+    <p>
+      If device implementations support TIF, they:
+    </p>
+    <ul>
+      <li>[C-1-1] Android Television device implementations MUST support <a href="http://developer.android.com/reference/android/media/tv/TvContract.Channels.html#COLUMN_APP_LINK_INTENT_URI">TV input app linking</a>, which allows all inputs to provide activity links from the current activity to another activity (i.e. a link from live programming to related content).
+      </li>
+      <li>[C-1-2] The TV App MUST show TV input app linking when it is provided.
+      </li>
+    </ul>
+    <h5 id="3_12_1_4_time_shifting">
+      3.12.1.4. Time shifting
+    </h5>
+    <p>
+      If device implementations support TIF, they:
+    </p>
+    <ul>
+      <li>[SR] STRONGLY RECOMMENDED to support time shifting, which allows the user to pause and resume live content.
+      </li>
+      <li>SHOULD provide the user a way to pause and resume the currently playing program, if time shifting for that program <a href="https://developer.android.com/reference/android/media/tv/TvInputManager.html#TIME_SHIFT_STATUS_AVAILABLE">is available</a>.
+      </li>
+    </ul>
+    <h5 id="3_12_1_5_tv_recording">
+      3.12.1.5. TV recording
+    </h5>
+    <p>
+      If device implementations support TIF, they:
+    </p>
+    <ul>
+      <li>[SR] STRONGLY RECOMMENDED to support TV recording.
+      </li>
+      <li>
+        <p>
+          If the TV input supports recording and the recording of a program is not <a href="https://developer.android.com/reference/android/media/tv/TvContract.Programs.html#COLUMN_RECORDING_PROHIBITED">prohibited</a>, the EPG MAY provide a way to <a href="https://developer.android.com/reference/android/media/tv/TvInputInfo.html#canRecord%28%29">record a program</a>.
+        </p>
+      </li>
+      <li>
+        <p>
+          SHOULD provide a user interface to play recorded programs.
+        </p>
+      </li>
+    </ul>
+    <h3 id="3_13_quick_settings">
+      3.13. Quick Settings
+    </h3>
+    <p>
+      Android provides a Quick Settings UI component that allows quick access to frequently used or urgently needed actions.
+    </p>
+    <p>
+      If device implementations include a Quick Settings UI component, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST allow the user to add or remove the tiles provided through the <a href="https://developer.android.com/reference/android/service/quicksettings/package-summary.html"><code>quicksettings</code></a> APIs from a third-party app.
+      </li>
+      <li>[C-1-2] MUST NOT automatically add a tile from a third-party app directly to the Quick Settings.
+      </li>
+      <li>[C-1-3] MUST display all the user-added tiles from third-party apps alongside the system-provided quick setting tiles.
+      </li>
+    </ul>
+    <h3 id="3_14_media_ui">
+      3.14. Media UI
+    </h3>
+    <p>
+      If device implementations include the UI framework that supports third-party apps that depend on <a href="http://developer.android.com/reference/android/media/browse/MediaBrowser.html"><code>MediaBrowser</code></a> and <a href="http://developer.android.com/reference/android/media/session/MediaSession.html"><code>MediaSession</code></a> , they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST display <a href="http://developer.android.com/reference/android/media/browse/MediaBrowser.MediaItem.html">MediaItem</a> icons and notification icons unaltered.
+      </li>
+      <li>[C-1-2] MUST display those items as described by MediaSession, e.g., metadata, icons, imagery.
+      </li>
+      <li>[C-1-3] MUST show app title.
+      </li>
+      <li>[C-1-4] MUST have drawer to present <a href="http://developer.android.com/reference/android/media/browse/MediaBrowser.html">MediaBrowser</a> hierarchy.
+      </li>
+    </ul>
+    <h3 id="3_15_instant_apps">
+      3.15. Instant Apps
+    </h3>
+    <p>
+      Device implementations MUST satisfy the following requirements:
+    </p>
+    <ul>
+      <li>[C-0-1] Instant Apps MUST only be granted permissions that have the <a href="https://developer.android.com/guide/topics/manifest/permission-element.html#plevel"><code>android:protectionLevel</code></a> set to <code>"ephemeral"</code>.
+      </li>
+      <li>[C-0-2] Instant Apps MUST NOT interact with installed apps via <a href="https://developer.android.com/reference/android/content/Intent.html">implicit intents</a> unless one of the following is true:
+        <ul>
+          <li>The component's intent pattern filter is exposed and has CATEGORY_BROWSABLE
+          </li>
+          <li>The action is one of ACTION_SEND, ACTION_SENDTO, ACTION_SEND_MULTIPLE
+          </li>
+          <li>The target is explicitly exposed with <a href="https://developer.android.com/reference/android/R.attr.html#visibleToInstantApps">android:visibleToInstantApps</a>
+          </li>
+        </ul>
+      </li>
+      <li>[C-0-3] Instant Apps MUST NOT interact explicitly with installed apps unless the component is exposed via android:visibleToInstantApps.
+      </li>
+      <li>[C-0-4] IInstalled Apps MUST NOT see details about Instant Apps on the device unless the Instant App explicitly connects to the installed application.
+      </li>
+    </ul>
+    <h3 id="3_16_companion_device_pairing">
+      3.16. Companion Device Pairing
+    </h3>
+    <p>
+      Android includes support for companion device pairing to more effectively manage association with companion devices and provides the <a href="https://developer.android.com/reference/android/companion/CompanionDeviceManager.html"><code>CompanionDeviceManager</code></a> API for apps to access this feature.
+    </p>
+    <p>
+      If device implementations support the companion device pairing feature, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST declare the feature flag <a href="https://developer.android.com/reference/android/content/pm/PackageManager.html?#FEATURE_COMPANION_DEVICE_SETUP"><code>FEATURE_COMPANION_DEVICE_SETUP</code></a> .
+      </li>
+      <li>[C-1-2] MUST ensure the APIs in the <a href="https://developer.android.com/reference/android/companion/package-summary.html"><code>android.companion</code></a> package is fully implemented.
+      </li>
+      <li>[C-1-3] MUST provide user affordances for the user to select/confirm a companion device is present and operational.
+      </li>
+    </ul>
+    <h2 id="4_application_packaging_compatibility">
+      4. Application Packaging Compatibility
+    </h2>
+    <p>
+      Devices implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST be capable of installing and running Android “.apk” files as generated by the “aapt” tool included in the <a href="http://developer.android.com/tools/help/index.html">official Android SDK</a>.
+      </li>
+      <li>As the above requirement may be challenging, device implementations are RECOMMENDED to use the AOSP reference implementation's package management systemDevice implementations.
+      </li>
+      <li>[C-0-2] MUST support verifying “.apk” files using the <a href="https://source.android.com/security/apksigning/v2.html">APK Signature Scheme v2</a> and <a href="https://source.android.com/security/apksigning/v2.html#v1-verification">JAR signing</a>.
+      </li>
+      <li>[C-0-3] MUST NOT extend either the <a href="http://developer.android.com/guide/components/fundamentals.html">.apk</a>, <a href="http://developer.android.com/guide/topics/manifest/manifest-intro.html">Android Manifest</a>, <a href="https://android.googlesource.com/platform/dalvik/">Dalvik bytecode</a>, or RenderScript bytecode formats in such a way that would prevent those files from installing and running correctly on other compatible devices.
+      </li>
+      <li>[C-0-4] MUST NOT allow apps other than the current "installer of record" for the package to silently uninstall the app without any prompt, as documented in the SDK for the <a href="https://developer.android.com/reference/android/Manifest.permission.html#DELETE_PACKAGES"><code>DELETE_PACKAGE</code></a> permission. The only exceptions are the system package verifier app handling <a href="https://developer.android.com/reference/android/content/Intent.html#ACTION_PACKAGE_NEEDS_VERIFICATION">PACKAGE_NEEDS_VERIFICATION</a> intent and the storage manager app handling <a href="https://developer.android.com/reference/android/os/storage/StorageManager.html#ACTION_MANAGE_STORAGE">ACTION_MANAGE_STORAGE</a> intent.
+      </li>
+    </ul>
+    <p>
+      Device implementations MUST NOT install application packages from unknown sources, unless the app that <a href="https://developer.android.com/reference/android/content/Intent.html#ACTION_INSTALL_PACKAGE">requests the installation</a> meets all the following requirements:
+    </p>
+    <ul>
+      <li>It MUST declare the <a href="http://developer.android.com/reference/android/Manifest.permission.html#REQUEST_INSTALL_PACKAGES"><code>REQUEST_INSTALL_PACKAGES</code></a> permission or have the <code>android:targetSdkVersion</code> set at 24 or lower.
+      </li>
+      <li>It MUST have been granted permission by the user to install apps from unknown sources.
+      </li>
+    </ul>
+    <p>
+      Device implementations MUST have an activity that handles the <a href="http://developer.android.com/reference/android/provider/Settings.html#ACTION_MANAGE_UNKNOWN_APP_SOURCES"><code>android.settings.MANAGE_UNKNOWN_APP_SOURCES</code></a> intent. They SHOULD provide a user affordance to grant/revoke the permission to install apps from unknown sources per application, but MAY choose to implement this as a no-op and return <code>RESULT_CANCELED</code> for <a href="http://developer.android.com/reference/android/app/Activity.html#startActivityForResult%28android.content.Intent,%20int%29"><code>startActivityForResult()</code></a>, if the device implementation does not want to allow users to have this choice. However even in such cases, they SHOULD indicate to the user why there is no such choice presented.
+    </p>
+    <h2 id="5_multimedia_compatibility">
+      5. Multimedia Compatibility
+    </h2>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST support the media formats, encoders, decoders, file types, and container formats defined in <a href="#5_1_media-codecs.md">section 5.1</a> for each and every codec declared by <code>MediaCodecList</code>.
+      </li>
+      <li>[C-0-2] MUST declare and report support of the encoders, decoders available to third-party applications via <a href="http://developer.android.com/reference/android/media/MediaCodecList.html"><code>MediaCodecList</code></a>.
+      </li>
+      <li>[C-0-3] MUST be able to decode and make available to third-party apps all the formats it can encode. This includes all bitstreams that its encoders generate and the profiles reported in its <a href="http://developer.android.com/reference/android/media/CamcorderProfile.html"><code>CamcorderProfile</code></a>.
+      </li>
+    </ul>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>SHOULD aim for minimum codec latency, in others words, they
+        <ul>
+          <li>SHOULD NOT consume and store input buffers and return input buffers only once processed.
+          </li>
+          <li>SHOULD NOT hold onto decoded buffers for longer than as specified by the standard (e.g. SPS).
+          </li>
+          <li>SHOULD NOT hold onto encoded buffers longer than required by the GOP structure.
+          </li>
+        </ul>
+      </li>
+    </ul>
+    <p>
+      All of the codecs listed in the section below are provided as software implementations in the preferred Android implementation from the Android Open Source Project.
+    </p>
+    <p>
+      Please note that neither Google nor the Open Handset Alliance make any representation that these codecs are free from third-party patents. Those intending to use this source code in hardware or software products are advised that implementations of this code, including in open source software or shareware, may require patent licenses from the relevant patent holders.
+    </p>
+    <h3 id="5_1_media_codecs">
+      5.1. Media Codecs
+    </h3>
+    <h4 id="5_1_1_audio_encoding">
+      5.1.1. Audio Encoding
+    </h4>
+    <p>
+      See more details in <a href="#5_1_3_audio_codecs_details">5.1.3. Audio Codecs Details</a>.
+    </p>
+    <p>
+      If device implementations declare <code>android.hardware.microphone</code>, they MUST support the following audio encoding:
+    </p>
+    <ul>
+      <li>[C-1-1] PCM/WAVE
+      </li>
+    </ul>
+    <h4 id="5_1_2_audio_decoding">
+      5.1.2. Audio Decoding
+    </h4>
+    <p>
+      See more details in <a href="#5_1_3_audio_codecs_details">5.1.3. Audio Codecs Details</a>.
+    </p>
+    <p>
+      If device implementations declare support for the <code>android.hardware.audio.output</code> feature, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MPEG-4 AAC Profile (AAC LC)
+      </li>
+      <li>[C-1-2] MPEG-4 HE AAC Profile (AAC+)
+      </li>
+      <li>[C-1-3] MPEG-4 HE AACv2 Profile (enhanced AAC+)
+      </li>
+      <li>[C-1-4] AAC ELD (enhanced low delay AAC)
+      </li>
+      <li>[C-1-5] FLAC
+      </li>
+      <li>[C-1-6] MP3
+      </li>
+      <li>[C-1-7] MIDI
+      </li>
+      <li>[C-1-8] Vorbis
+      </li>
+      <li>[C-1-9] PCM/WAVE
+      </li>
+      <li>[C-1-10] Opus
+      </li>
+    </ul>
+    <p>
+      If device implementations support the decoding of AAC input buffers of multichannel streams (i.e. more than two channels) to PCM through the default AAC audio decoder in the <code>android.media.MediaCodec</code> API, the following MUST be supported:
+    </p>
+    <ul>
+      <li>[C-2-1] Decoding MUST be performed without downmixing (e.g. a 5.0 AAC stream must be decoded to five channels of PCM, a 5.1 AAC stream must be decoded to six channels of PCM).
+      </li>
+      <li>[C-2-2] Dynamic range metadata MUST be as defined in "Dynamic Range Control (DRC)" in ISO/IEC 14496-3, and the <code>android.media.MediaFormat</code> DRC keys to configure the dynamic range-related behaviors of the audio decoder. The AAC DRC keys were introduced in API 21,and are: KEY_AAC_DRC_ATTENUATION_FACTOR, KEY_AAC_DRC_BOOST_FACTOR, KEY_AAC_DRC_HEAVY_COMPRESSION, KEY_AAC_DRC_TARGET_REFERENCE_LEVEL and KEY_AAC_ENCODED_TARGET_LEVEL
+      </li>
+    </ul>
+    <h4 id="5_1_3_audio_codecs_details">
+      5.1.3. Audio Codecs Details
+    </h4>
+    <table>
+      <tr>
+        <th>
+          Format/Codec
+        </th>
+        <th>
+          Details
+        </th>
+        <th>
+          Supported File Types/Container Formats
+        </th>
+      </tr>
+      <tr>
+        <td>
+          MPEG-4 AAC Profile<br />
+          (AAC LC)
+        </td>
+        <td>
+          Support for mono/stereo/5.0/5.1 content with standard sampling rates from 8 to 48 kHz.
+        </td>
+        <td>
+          <ul>
+            <li class="table_list">3GPP (.3gp)
+            </li>
+            <li class="table_list">MPEG-4 (.mp4, .m4a)
+            </li>
+            <li class="table_list">ADTS raw AAC (.aac, ADIF not supported)
+            </li>
+            <li class="table_list">MPEG-TS (.ts, not seekable)
+            </li>
+          </ul>
+        </td>
+      </tr>
+      <tr>
+        <td>
+          MPEG-4 HE AAC Profile (AAC+)
+        </td>
+        <td>
+          Support for mono/stereo/5.0/5.1 content with standard sampling rates from 16 to 48 kHz.
+        </td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>
+          MPEG-4 HE AACv2<br />
+          Profile (enhanced AAC+)
+        </td>
+        <td>
+          Support for mono/stereo/5.0/5.1 content with standard sampling rates from 16 to 48 kHz.
+        </td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>
+          AAC ELD (enhanced low delay AAC)
+        </td>
+        <td>
+          Support for mono/stereo content with standard sampling rates from 16 to 48 kHz.
+        </td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>
+          AMR-NB
+        </td>
+        <td>
+          4.75 to 12.2 kbps sampled @ 8 kHz
+        </td>
+        <td>
+          3GPP (.3gp)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          AMR-WB
+        </td>
+        <td>
+          9 rates from 6.60 kbit/s to 23.85 kbit/s sampled @ 16 kHz
+        </td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>
+          FLAC
+        </td>
+        <td>
+          Mono/Stereo (no multichannel). Sample rates up to 48 kHz (but up to 44.1 kHz is RECOMMENDED on devices with 44.1 kHz output, as the 48 to 44.1 kHz downsampler does not include a low-pass filter). 16-bit RECOMMENDED; no dither applied for 24-bit.
+        </td>
+        <td>
+          FLAC (.flac) only
+        </td>
+      </tr>
+      <tr>
+        <td>
+          MP3
+        </td>
+        <td>
+          Mono/Stereo 8-320Kbps constant (CBR) or variable bitrate (VBR)
+        </td>
+        <td>
+          MP3 (.mp3)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          MIDI
+        </td>
+        <td>
+          MIDI Type 0 and 1. DLS Version 1 and 2. XMF and Mobile XMF. Support for ringtone formats RTTTL/RTX, OTA, and iMelody
+        </td>
+        <td>
+          <ul>
+            <li class="table_list">Type 0 and 1 (.mid, .xmf, .mxmf)
+            </li>
+            <li class="table_list">RTTTL/RTX (.rtttl, .rtx)
+            </li>
+            <li class="table_list">OTA (.ota)
+            </li>
+            <li class="table_list">iMelody (.imy)
+            </li>
+          </ul>
+        </td>
+      </tr>
+      <tr>
+        <td>
+          Vorbis
+        </td>
+        <td></td>
+        <td>
+          <ul>
+            <li class="table_list">Ogg (.ogg)
+            </li>
+            <li class="table_list">Matroska (.mkv, Android 4.0+)
+            </li>
+          </ul>
+        </td>
+      </tr>
+      <tr>
+        <td>
+          PCM/WAVE
+        </td>
+        <td>
+          16-bit linear PCM (rates up to limit of hardware). Devices MUST support sampling rates for raw PCM recording at 8000, 11025, 16000, and 44100 Hz frequencies.
+        </td>
+        <td>
+          WAVE (.wav)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          Opus
+        </td>
+        <td></td>
+        <td>
+          Matroska (.mkv), Ogg(.ogg)
+        </td>
+      </tr>
+    </table>
+    <h4 id="5_1_4_image_encoding">
+      5.1.4. Image Encoding
+    </h4>
+    <p>
+      See more details in <a href="#5_1_6_image_codecs_details">5.1.6. Image Codecs Details</a>.
+    </p>
+    <p>
+      Device implementations MUST support encoding the following image encoding:
+    </p>
+    <ul>
+      <li>[C-0-1] JPEG
+      </li>
+      <li>[C-0-2] PNG
+      </li>
+      <li>[C-0-3] WebP
+      </li>
+    </ul>
+    <h4 id="5_1_5_image_decoding">
+      5.1.5. Image Decoding
+    </h4>
+    <p>
+      See more details in <a href="#5_1_6_image_codecs_details">5.1.6. Image Codecs Details</a>.
+    </p>
+    <p>
+      Device impelementations MUST support encoding the following image decoding:
+    </p>
+    <ul>
+      <li>[C-0-1] JPEG
+      </li>
+      <li>[C-0-2] GIF
+      </li>
+      <li>[C-0-3] PNG
+      </li>
+      <li>[C-0-4] BMP
+      </li>
+      <li>[C-0-5] WebP
+      </li>
+      <li>[C-0-6] Raw
+      </li>
+    </ul>
+    <h4 id="5_1_6_image_codecs_details">
+      5.1.6. Image Codecs Details
+    </h4>
+    <table>
+      <tr>
+        <th>
+          Format/Codec
+        </th>
+        <th>
+          Details
+        </th>
+        <th>
+          Supported File Types/Container Formats
+        </th>
+      </tr>
+      <tr>
+        <td>
+          JPEG
+        </td>
+        <td>
+          Base+progressive
+        </td>
+        <td>
+          JPEG (.jpg)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          GIF
+        </td>
+        <td></td>
+        <td>
+          GIF (.gif)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          PNG
+        </td>
+        <td></td>
+        <td>
+          PNG (.png)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          BMP
+        </td>
+        <td></td>
+        <td>
+          BMP (.bmp)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          WebP
+        </td>
+        <td></td>
+        <td>
+          WebP (.webp)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          Raw
+        </td>
+        <td></td>
+        <td>
+          ARW (.arw), CR2 (.cr2), DNG (.dng), NEF (.nef), NRW (.nrw), ORF (.orf), PEF (.pef), RAF (.raf), RW2 (.rw2), SRW (.srw)
+        </td>
+      </tr>
+    </table>
+    <h4 id="5_1_7_video_codecs">
+      5.1.7. Video Codecs
+    </h4>
+    <ul>
+      <li>For acceptable quality of web video streaming and video-conference services, device implementations SHOULD use a hardware VP8 codec that meets the <a href="http://www.webmproject.org/hardware/rtc-coding-requirements/">requirements</a>.
+      </li>
+    </ul>
+    <p>
+      If device implementations include a video decoder or encoder:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-1-1] Video codecs MUST support output and input bytebuffer sizes that accommodate the largest feasible compressed and uncompressed frame as dictated by the standard and configuration but also not overallocate.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-1-2] Video encoders and decoders MUST support YUV420 flexible color format (COLOR_FormatYUV420Flexible).
+        </p>
+      </li>
+    </ul>
+    <p>
+      If device implementations advertise HDR profile support through <a href="https://developer.android.com/reference/android/view/Display.HdrCapabilities.html"><code>Display.HdrCapabilities</code></a>, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST support HDR static metadata parsing and handling.
+      </li>
+    </ul>
+    <p>
+      If device implementations advertise intra refresh support through <code>FEATURE_IntraRefresh</code> in the <a href="https://developer.android.com/reference/android/media/MediaCodecInfo.CodecCapabilities.html#FEATURE_IntraRefresh"><code>MediaCodecInfo.CodecCapabilities</code></a> class, they:
+    </p>
+    <ul>
+      <li>[C-3-1]MUST support the refresh periods in the range of 10 - 60 frames and accurately operate within 20% of configured refresh period.
+      </li>
+    </ul>
+    <h4 id="5_1_8_video_codecs_list">
+      5.1.8. Video Codecs List
+    </h4>
+    <table>
+      <tr>
+        <th>
+          Format/Codec
+        </th>
+        <th>
+          Details
+        </th>
+        <th>
+          Supported File Types/<br />
+          Container Formats
+        </th>
+      </tr>
+      <tr>
+        <td>
+          H.263
+        </td>
+        <td></td>
+        <td>
+          <ul>
+            <li class="table_list">3GPP (.3gp)
+            </li>
+            <li class="table_list">MPEG-4 (.mp4)
+            </li>
+          </ul>
+        </td>
+      </tr>
+      <tr>
+        <td>
+          H.264 AVC
+        </td>
+        <td>
+          See <a href="#5_2_video_encoding">section 5.2</a> and <a href="#5_3_video_decoding">5.3</a> for details
+        </td>
+        <td>
+          <ul>
+            <li class="table_list">3GPP (.3gp)
+            </li>
+            <li class="table_list">MPEG-4 (.mp4)
+            </li>
+            <li class="table_list">MPEG-2 TS (.ts, AAC audio only, not seekable, Android 3.0+)
+            </li>
+          </ul>
+        </td>
+      </tr>
+      <tr>
+        <td>
+          H.265 HEVC
+        </td>
+        <td>
+          See <a href="#5_3_video_decoding">section 5.3</a> for details
+        </td>
+        <td>
+          MPEG-4 (.mp4)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          MPEG-2
+        </td>
+        <td>
+          Main Profile
+        </td>
+        <td>
+          MPEG2-TS
+        </td>
+      </tr>
+      <tr>
+        <td>
+          MPEG-4 SP
+        </td>
+        <td></td>
+        <td>
+          3GPP (.3gp)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          VP8
+        </td>
+        <td>
+          See <a href="#5_2_video_encoding">section 5.2</a> and <a href="#5_3_video_decoding">5.3</a> for details
+        </td>
+        <td>
+          <ul>
+            <li class="table_list">
+              <a href="http://www.webmproject.org/">WebM (.webm)</a>
+            </li>
+            <li class="table_list">Matroska (.mkv)
+            </li>
+          </ul>
+        </td>
+      </tr>
+      <tr>
+        <td>
+          VP9
+        </td>
+        <td>
+          See <a href="#5_3_video_decoding">section 5.3</a> for details
+        </td>
+        <td>
+          <ul>
+            <li class="table_list">
+              <a href="http://www.webmproject.org/">WebM (.webm)</a>
+            </li>
+            <li class="table_list">Matroska (.mkv)
+            </li>
+          </ul>
+        </td>
+      </tr>
+    </table>
+    <h3 id="5_2_video_encoding">
+      5.2. Video Encoding
+    </h3>
+    <p>
+      If device implementations support any video encoder and make it available to third-party apps, they:
+    </p>
+    <ul>
+      <li>SHOULD NOT be, over two sliding windows, more than ~15% over the bitrate between intraframe (I-frame) intervals.
+      </li>
+      <li>SHOULD NOT be more than ~100% over the bitrate over a sliding window of 1 second.
+      </li>
+    </ul>
+    <p>
+      If device implementations include an embedded screen display with the diagonal length of at least 2.5 inches or include a video output port or declare the support of a camera via the <code>android.hardware.camera.any</code> feature flag, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST include the support of at least one of the VP8 or H.264 video encoders, and make it available for third-party applications.
+      </li>
+      <li>SHOULD support both VP8 and H.264 video encoders, and make it available for third-party applications.
+      </li>
+    </ul>
+    <p>
+      If device implementations support any of the H.264, VP8, VP9 or HEVC video encoders and make it available to third-party applications, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST support dynamically configurable bitrates.
+      </li>
+      <li>SHOULD support variable frame rates, where video encoder SHOULD determine instantaneous frame duration based on the timestamps of input buffers, and allocate its bit bucket based on that frame duration.
+      </li>
+    </ul>
+    <p>
+      If device implementations support the MPEG-4 SP video encoder and make it available to third-party apps, they:
+    </p>
+    <ul>
+      <li>SHOULD support dynamically configurable bitrates for the supported encoder.
+      </li>
+    </ul>
+    <h4 id="5_2_1_h_263">
+      5.2.1. H.263
+    </h4>
+    <p>
+      If device implementations support H.263 encoders and make it available to third-party apps, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support Baseline Profile Level 45.
+      </li>
+      <li>SHOULD support dynamically configurable bitrates for the supported encoder.
+      </li>
+    </ul>
+    <h4 id="5_2_2_h-264">
+      5.2.2. H-264
+    </h4>
+    <p>
+      If device implementations support H.264 codec, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support Baseline Profile Level 3. However, support for ASO (Arbitrary Slice Ordering), FMO (Flexible Macroblock Ordering) and RS (Redundant Slices) is OPTIONAL. Moreover, to maintain compatibility with other Android devices, it is RECOMMENDED that ASO, FMO and RS are not used for Baseline Profile by encoders.
+      </li>
+      <li>[C-1-2] MUST support the SD (Standard Definition) video encoding profiles in the following table.
+      </li>
+      <li>SHOULD support Main Profile Level 4.
+      </li>
+      <li>SHOULD support the HD (High Definition) video encoding profiles as indicated in the following table.
+      </li>
+    </ul>
+    <p>
+      If device implementations report support of H.264 encoding for 720p or 1080p resolution videos through the media APIs, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST support the encoding profiles in the following table.
+      </li>
+    </ul>
+    <table>
+      <tr>
+        <th></th>
+        <th>
+          SD (Low quality)
+        </th>
+        <th>
+          SD (High quality)
+        </th>
+        <th>
+          HD 720p
+        </th>
+        <th>
+          HD 1080p
+        </th>
+      </tr>
+      <tr>
+        <th>
+          Video resolution
+        </th>
+        <td>
+          320 x 240 px
+        </td>
+        <td>
+          720 x 480 px
+        </td>
+        <td>
+          1280 x 720 px
+        </td>
+        <td>
+          1920 x 1080 px
+        </td>
+      </tr>
+      <tr>
+        <th>
+          Video frame rate
+        </th>
+        <td>
+          20 fps
+        </td>
+        <td>
+          30 fps
+        </td>
+        <td>
+          30 fps
+        </td>
+        <td>
+          30 fps
+        </td>
+      </tr>
+      <tr>
+        <th>
+          Video bitrate
+        </th>
+        <td>
+          384 Kbps
+        </td>
+        <td>
+          2 Mbps
+        </td>
+        <td>
+          4 Mbps
+        </td>
+        <td>
+          10 Mbps
+        </td>
+      </tr>
+    </table>
+    <h4 id="5_2_3_vp8">
+      5.2.3. VP8
+    </h4>
+    <p>
+      If device implementations support VP8 codec, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support the SD video encoding profiles.
+      </li>
+      <li>SHOULD support the following HD (High Definition) video encoding profiles.
+      </li>
+      <li>SHOULD support writing Matroska WebM files.
+      </li>
+      <li>SHOULD use a hardware VP8 codec that meets the <a href="http://www.webmproject.org/hardware/rtc-coding-requirements">WebM project RTC hardware coding requirements</a>, to ensure acceptable quality of web video streaming and video-conference services.
+      </li>
+    </ul>
+    <p>
+      If device implementations report support of VP8 encoding for 720p or 1080p resolution videos through the media APIs, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST support the encoding profiles in the following table.
+      </li>
+    </ul>
+    <table>
+      <tr>
+        <th></th>
+        <th>
+          SD (Low quality)
+        </th>
+        <th>
+          SD (High quality)
+        </th>
+        <th>
+          HD 720p
+        </th>
+        <th>
+          HD 1080p
+        </th>
+      </tr>
+      <tr>
+        <th>
+          Video resolution
+        </th>
+        <td>
+          320 x 180 px
+        </td>
+        <td>
+          640 x 360 px
+        </td>
+        <td>
+          1280 x 720 px
+        </td>
+        <td>
+          1920 x 1080 px
+        </td>
+      </tr>
+      <tr>
+        <th>
+          Video frame rate
+        </th>
+        <td>
+          30 fps
+        </td>
+        <td>
+          30 fps
+        </td>
+        <td>
+          30 fps
+        </td>
+        <td>
+          30 fps
+        </td>
+      </tr>
+      <tr>
+        <th>
+          Video bitrate
+        </th>
+        <td>
+          800 Kbps
+        </td>
+        <td>
+          2 Mbps
+        </td>
+        <td>
+          4 Mbps
+        </td>
+        <td>
+          10 Mbps
+        </td>
+      </tr>
+    </table>
+    <h4 id="5_2_4_vp9">
+      5.2.4. VP9
+    </h4>
+    <p>
+      If device implementations support VP9 codec, they:
+    </p>
+    <ul>
+      <li>SHOULD support writing Matroska WebM files.
+      </li>
+    </ul>
+    <h3 id="5_3_video_decoding">
+      5.3. Video Decoding
+    </h3>
+    <p>
+      If device implementations support VP8, VP9, H.264, or H.265 codecs, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support dynamic video resolution and frame rate switching through the standard Android APIs within the same stream for all VP8, VP9, H.264, and H.265 codecs in real time and up to the maximum resolution supported by each codec on the device.
+      </li>
+    </ul>
+    <p>
+      If device implementations declare support for the Dolby Vision decoder through <a href="https://developer.android.com/reference/android/view/Display.HdrCapabilities.html#HDR_TYPE_DOLBY_VISION"><code>HDR_TYPE_DOLBY_VISION</code></a> , they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST provide a Dolby Vision-capable extractor.
+      </li>
+      <li>[C-2-2] MUST properly display Dolby Vision content on the device screen or on a standard video output port (e.g., HDMI).
+      </li>
+      <li>[C-2-3] MUST set the track index of backward-compatible base-layer(s) (if present) to be the same as the combined Dolby Vision layer's track index.
+      </li>
+    </ul>
+    <h4 id="5_3_1_mpeg-2">
+      5.3.1. MPEG-2
+    </h4>
+    <p>
+      If device implementations support MPEG-2 decoders, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support the Main Profile High Level.
+      </li>
+    </ul>
+    <h4 id="5_3_2_h_263">
+      5.3.2. H.263
+    </h4>
+    <p>
+      If device implementations support H.263 decoders, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support Baseline Profile Level 30 and Level 45.
+      </li>
+    </ul>
+    <h4 id="5_3_3_mpeg-4">
+      5.3.3. MPEG-4
+    </h4>
+    <p>
+      If device implementations with MPEG-4 decoders, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support Simple Profile Level 3.
+      </li>
+    </ul>
+    <h4 id="5_3_4_h_264">
+      5.3.4. H.264
+    </h4>
+    <p>
+      If device implementations support H.264 decoders, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support Main Profile Level 3.1 and Baseline Profile. Support for ASO (Arbitrary Slice Ordering), FMO (Flexible Macroblock Ordering) and RS (Redundant Slices) is OPTIONAL.
+      </li>
+      <li>[C-1-2] MUST be capable of decoding videos with the SD (Standard Definition) profiles listed in the following table and encoded with the Baseline Profile and Main Profile Level 3.1 (including 720p30).
+      </li>
+      <li>SHOULD be capable of decoding videos with the HD (High Definition) profiles as indicated in the following table.
+      </li>
+    </ul>
+    <p>
+      If the height that is reported by the <code>Display.getSupportedModes()</code> method is equal or greater than the video resolution, device implementations:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST support the HD 720p video encoding profiles in the following table.
+      </li>
+      <li>[C-2-2] MUST support the HD 1080p video encoding profiles in the following table.
+      </li>
+    </ul>
+    <table>
+      <tr>
+        <th></th>
+        <th>
+          SD (Low quality)
+        </th>
+        <th>
+          SD (High quality)
+        </th>
+        <th>
+          HD 720p
+        </th>
+        <th>
+          HD 1080p
+        </th>
+      </tr>
+      <tr>
+        <th>
+          Video resolution
+        </th>
+        <td>
+          320 x 240 px
+        </td>
+        <td>
+          720 x 480 px
+        </td>
+        <td>
+          1280 x 720 px
+        </td>
+        <td>
+          1920 x 1080 px
+        </td>
+      </tr>
+      <tr>
+        <th>
+          Video frame rate
+        </th>
+        <td>
+          30 fps
+        </td>
+        <td>
+          30 fps
+        </td>
+        <td>
+          60 fps
+        </td>
+        <td>
+          30 fps (60 fps<sup>Television</sup>)
+        </td>
+      </tr>
+      <tr>
+        <th>
+          Video bitrate
+        </th>
+        <td>
+          800 Kbps
+        </td>
+        <td>
+          2 Mbps
+        </td>
+        <td>
+          8 Mbps
+        </td>
+        <td>
+          20 Mbps
+        </td>
+      </tr>
+    </table>
+    <h4 id="5_3_5_h_265_(hevc)">
+      5.3.5. H.265 (HEVC)
+    </h4>
+    <p>
+      If device implementations support H.265 codec, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support the Main Profile Level 3 Main tier and the SD video decoding profiles as indicated in the following table.
+      </li>
+      <li>SHOULD support the HD decoding profiles as indicated in the following table.
+      </li>
+      <li>[C-1-2] MUST support the HD decoding profiles as indicated in the following table if there is a hardware decoder.
+      </li>
+    </ul>
+    <p>
+      If the height that is reported by the <code>Display.getSupportedModes()</code> method is equal to or greater than the video resolution, then:
+    </p>
+    <ul>
+      <li>[C-2-1] Device implementations MUST support at least one of H.265 or VP9 decoding of 720, 1080 and UHD profiles.
+      </li>
+    </ul>
+    <table>
+      <tr>
+        <th></th>
+        <th>
+          SD (Low quality)
+        </th>
+        <th>
+          SD (High quality)
+        </th>
+        <th>
+          HD 720p
+        </th>
+        <th>
+          HD 1080p
+        </th>
+        <th>
+          UHD
+        </th>
+      </tr>
+      <tr>
+        <th>
+          Video resolution
+        </th>
+        <td>
+          352 x 288 px
+        </td>
+        <td>
+          720 x 480 px
+        </td>
+        <td>
+          1280 x 720 px
+        </td>
+        <td>
+          1920 x 1080 px
+        </td>
+        <td>
+          3840 x 2160 px
+        </td>
+      </tr>
+      <tr>
+        <th>
+          Video frame rate
+        </th>
+        <td>
+          30 fps
+        </td>
+        <td>
+          30 fps
+        </td>
+        <td>
+          30 fps
+        </td>
+        <td>
+          30/60 fps (60 fps<sup>Television with H.265 hardware decoding</sup>)
+        </td>
+        <td>
+          60 fps
+        </td>
+      </tr>
+      <tr>
+        <th>
+          Video bitrate
+        </th>
+        <td>
+          600 Kbps
+        </td>
+        <td>
+          1.6 Mbps
+        </td>
+        <td>
+          4 Mbps
+        </td>
+        <td>
+          5 Mbps
+        </td>
+        <td>
+          20 Mbps
+        </td>
+      </tr>
+    </table>
+    <h4 id="5_3_6_vp8">
+      5.3.6. VP8
+    </h4>
+    <p>
+      If device implementations support VP8 codec, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support the SD decoding profiles in the following table.
+      </li>
+      <li>SHOULD use a hardware VP8 codec that meets the <a href="" title="http://www.webmproject.org/hardware/rtc-coding-requirements/">requirements</a>.
+      </li>
+      <li>SHOULD support the HD decoding profiles in the following table.
+      </li>
+    </ul>
+    <p>
+      If the height as reported by the <code>Display.getSupportedModes()</code> method is equal or greater than the video resolution, then:
+    </p>
+    <ul>
+      <li>[C-2-1] Device implementations MUST support 720p profiles in the following table.
+      </li>
+      <li>[C-2-2] Device implementations MUST support 1080p profiles in the following table.
+      </li>
+    </ul>
+    <table>
+      <tr>
+        <th></th>
+        <th>
+          SD (Low quality)
+        </th>
+        <th>
+          SD (High quality)
+        </th>
+        <th>
+          HD 720p
+        </th>
+        <th>
+          HD 1080p
+        </th>
+      </tr>
+      <tr>
+        <th>
+          Video resolution
+        </th>
+        <td>
+          320 x 180 px
+        </td>
+        <td>
+          640 x 360 px
+        </td>
+        <td>
+          1280 x 720 px
+        </td>
+        <td>
+          1920 x 1080 px
+        </td>
+      </tr>
+      <tr>
+        <th>
+          Video frame rate
+        </th>
+        <td>
+          30 fps
+        </td>
+        <td>
+          30 fps
+        </td>
+        <td>
+          30 fps (60 fps<sup>Television</sup>)
+        </td>
+        <td>
+          30 (60 fps<sup>Television</sup>)
+        </td>
+      </tr>
+      <tr>
+        <th>
+          Video bitrate
+        </th>
+        <td>
+          800 Kbps
+        </td>
+        <td>
+          2 Mbps
+        </td>
+        <td>
+          8 Mbps
+        </td>
+        <td>
+          20 Mbps
+        </td>
+      </tr>
+    </table>
+    <h4 id="5_3_7_vp9">
+      5.3.7. VP9
+    </h4>
+    <p>
+      If device implementations support VP9 codec, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support the SD video decoding profiles as indicated in the following table.
+      </li>
+      <li>SHOULD support the HD decoding profiles as indicated in the following table.
+      </li>
+    </ul>
+    <p>
+      If device implementations support VP9 codec and a hardware decoder:
+    </p>
+    <ul>
+      <li>[C-2-2] MUST support the HD decoding profiles as indicated in the following table.
+      </li>
+    </ul>
+    <p>
+      If the height that is reported by the <code>Display.getSupportedModes()</code> method is equal to or greater than the video resolution, then:
+    </p>
+    <ul>
+      <li>[C-3-1] Device implementations MUST support at least one of VP9 or H.265 decoding of the 720, 1080 and UHD profiles.
+      </li>
+    </ul>
+    <table>
+      <tr>
+        <th></th>
+        <th>
+          SD (Low quality)
+        </th>
+        <th>
+          SD (High quality)
+        </th>
+        <th>
+          HD 720p
+        </th>
+        <th>
+          HD 1080p
+        </th>
+        <th>
+          UHD
+        </th>
+      </tr>
+      <tr>
+        <th>
+          Video resolution
+        </th>
+        <td>
+          320 x 180 px
+        </td>
+        <td>
+          640 x 360 px
+        </td>
+        <td>
+          1280 x 720 px
+        </td>
+        <td>
+          1920 x 1080 px
+        </td>
+        <td>
+          3840 x 2160 px
+        </td>
+      </tr>
+      <tr>
+        <th>
+          Video frame rate
+        </th>
+        <td>
+          30 fps
+        </td>
+        <td>
+          30 fps
+        </td>
+        <td>
+          30 fps
+        </td>
+        <td>
+          30 fps (60 fps<sup>Television with VP9 hardware decoding</sup>)
+        </td>
+        <td>
+          60 fps
+        </td>
+      </tr>
+      <tr>
+        <th>
+          Video bitrate
+        </th>
+        <td>
+          600 Kbps
+        </td>
+        <td>
+          1.6 Mbps
+        </td>
+        <td>
+          4 Mbps
+        </td>
+        <td>
+          5 Mbps
+        </td>
+        <td>
+          20 Mbps
+        </td>
+      </tr>
+    </table>
+    <h3 id="5_4_audio_recording">
+      5.4. Audio Recording
+    </h3>
+    <p>
+      While some of the requirements outlined in this section are listed as SHOULD since Android 4.3, the Compatibility Definition for future versions are planned to change these to MUST. Existing and new Android devices are <strong>STRONGLY RECOMMENDED</strong> to meet these requirements that are listed as SHOULD, or they will not be able to attain Android compatibility when upgraded to the future version.
+    </p>
+    <h4 id="5_4_1_raw_audio_capture">
+      5.4.1. Raw Audio Capture
+    </h4>
+    <p>
+      If device implementations declare <code>android.hardware.microphone</code>, they:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-1-1] MUST allow capture of raw audio content with the following characteristics:
+        </p>
+      </li>
+      <li>
+        <p>
+          <strong>Format</strong>: Linear PCM, 16-bit
+        </p>
+      </li>
+      <li>
+        <strong>Sampling rates</strong>: 8000, 11025, 16000, 44100 Hz
+      </li>
+      <li>
+        <p>
+          <strong>Channels</strong>: Mono
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-1-2] MUST capture at above sample rates without up-sampling.
+        </p>
+      </li>
+      <li>[C-1-3] MUST include an appropriate anti-aliasing filter when the sample rates given above are captured with down-sampling.
+      </li>
+      <li>
+        <p>
+          SHOULD allow AM radio and DVD quality capture of raw audio content, which means the following characteristics:
+        </p>
+      </li>
+      <li>
+        <p>
+          <strong>Format</strong>: Linear PCM, 16-bit
+        </p>
+      </li>
+      <li>
+        <strong>Sampling rates</strong>: 22050, 48000 Hz
+      </li>
+      <li>
+        <strong>Channels</strong>: Stereo
+      </li>
+    </ul>
+    <p>
+      If device implementations allow AM radio and DVD quality capture of raw audio content, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST capture without up-sampling at any ratio higher than 16000:22050 or 44100:48000.
+      </li>
+      <li>[C-2-2] MUST include an appropriate anti-aliasing filter for any up-sampling or down-sampling.
+      </li>
+    </ul>
+    <h4 id="5_4_2_capture_for_voice_recognition">
+      5.4.2. Capture for Voice Recognition
+    </h4>
+    <p>
+      If device implementations declare <code>android.hardware.microphone</code>, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST capture <code>android.media.MediaRecorder.AudioSource.VOICE_RECOGNITION</code> audio source at one of the sampling rates, 44100 and 48000.
+      </li>
+      <li>[C-1-2] MUST, by default, disable any noise reduction audio processing when recording an audio stream from the <code>AudioSource.VOICE_RECOGNITION</code> audio source.
+      </li>
+      <li>[C-1-3] MUST, by default, disable any automatic gain control when recording an audio stream from the <code>AudioSource.VOICE_RECOGNITION</code> audio source.
+      </li>
+      <li>SHOULD record the voice recognition audio stream with approximately flat amplitude versus frequency characteristics: specifically, ±3 dB, from 100 Hz to 4000 Hz.
+      </li>
+      <li>SHOULD record the voice recognition audio stream with input sensitivity set such that a 90 dB sound power level (SPL) source at 1000 Hz yields RMS of 2500 for 16-bit samples.
+      </li>
+      <li>SHOULD record the voice recognition audio stream so that the PCM amplitude levels linearly track input SPL changes over at least a 30 dB range from -18 dB to +12 dB re 90 dB SPL at the microphone.
+      </li>
+      <li>SHOULD record the voice recognition audio stream with total harmonic distortion (THD) less than 1% for 1 kHz at 90 dB SPL input level at the microphone.
+      </li>
+    </ul>
+    <p>
+      If device impelementations declare <code>android.hardware.microphone</code> and noise suppression (reduction) technologies tuned for speech recognition, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST allow this audio affect to be controllable with the <code>android.media.audiofx.NoiseSuppressor</code> API.
+      </li>
+      <li>[C-2-2] MUST uniquely identfiy each noise suppression technology implementation via the <code>AudioEffect.Descriptor.uuid</code> field.
+      </li>
+    </ul>
+    <h4 id="5_4_3_capture_for_rerouting_of_playback">
+      5.4.3. Capture for Rerouting of Playback
+    </h4>
+    <p>
+      The <code>android.media.MediaRecorder.AudioSource</code> class includes the <code>REMOTE_SUBMIX</code> audio source.
+    </p>
+    <p>
+      If device implementations declare both <code>android.hardware.audio.output</code> and <code>android.hardware.microphone</code>, they:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-1-1] MUST properly implement the <code>REMOTE_SUBMIX</code> audio source so that when an application uses the <code>android.media.AudioRecord</code> API to record from this audio source, it captures a mix of all audio streams except for the following:
+        </p>
+        <ul>
+          <li>
+            <code>AudioManager.STREAM_RING</code>
+          </li>
+          <li>
+            <code>AudioManager.STREAM_ALARM</code>
+          </li>
+          <li>
+            <code>AudioManager.STREAM_NOTIFICATION</code>
+          </li>
+        </ul>
+      </li>
+    </ul>
+    <h3 id="5_5_audio_playback">
+      5.5. Audio Playback
+    </h3>
+    <p>
+      Android includes the support to allow apps to playback audio through the audio output peripheral as defined in section 7.8.2.
+    </p>
+    <h4 id="5_5_1_raw_audio_playback">
+      5.5.1. Raw Audio Playback
+    </h4>
+    <p>
+      If device implementations declare <code>android.hardware.audio.output</code>, they:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-1-1] MUST allow playback of raw audio content with the following characteristics:
+        </p>
+        <ul>
+          <li>
+            <strong>Format</strong>: Linear PCM, 16-bit
+          </li>
+          <li>
+            <strong>Sampling rates</strong>: 8000, 11025, 16000, 22050, 32000, 44100
+          </li>
+          <li>
+            <strong>Channels</strong>: Mono, Stereo
+          </li>
+        </ul>
+      </li>
+      <li>
+        <p>
+          SHOULD allow playback of raw audio content with the following characteristics:
+        </p>
+        <ul>
+          <li>
+            <strong>Sampling rates</strong>: 24000, 48000
+          </li>
+        </ul>
+      </li>
+    </ul>
+    <h4 id="5_5_2_audio_effects">
+      5.5.2. Audio Effects
+    </h4>
+    <p>
+      Android provides an <a href="http://developer.android.com/reference/android/media/audiofx/AudioEffect.html">API for audio effects</a> for device implementations.
+    </p>
+    <p>
+      If device implementations declare the feature <code>android.hardware.audio.output</code>, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support the <code>EFFECT_TYPE_EQUALIZER</code> and <code>EFFECT_TYPE_LOUDNESS_ENHANCER</code> implementations controllable through the AudioEffect subclasses <code>Equalizer</code>, <code>LoudnessEnhancer</code>.
+      </li>
+      <li>[C-1-2] MUST support the visualizer API implementation, controllable through the <code>Visualizer</code> class.
+      </li>
+      <li>SHOULD support the <code>EFFECT_TYPE_BASS_BOOST</code>, <code>EFFECT_TYPE_ENV_REVERB</code>, <code>EFFECT_TYPE_PRESET_REVERB</code>, and <code>EFFECT_TYPE_VIRTUALIZER</code> implementations controllable through the <code>AudioEffect</code> sub-classes <code>BassBoost</code>, <code>EnvironmentalReverb</code>, <code>PresetReverb</code>, and <code>Virtualizer</code>.
+      </li>
+    </ul>
+    <h4 id="5_5_3_audio_output_volume">
+      5.5.3. Audio Output Volume
+    </h4>
+    <p>
+      Automotive device implementations:
+    </p>
+    <ul>
+      <li>SHOULD allow adjusting audio volume separately per each audio stream using the content type or usage as defined by <a href="" title="http://developer.android.com/reference/android/media/AudioAttributes.html">AudioAttributes</a> and car audio usage as publicly defined in <code>android.car.CarAudioManager</code>.
+      </li>
+    </ul>
+    <h3 id="5_6_audio_latency">
+      5.6. Audio Latency
+    </h3>
+    <p>
+      Audio latency is the time delay as an audio signal passes through a system. Many classes of applications rely on short latencies, to achieve real-time sound effects.
+    </p>
+    <p>
+      For the purposes of this section, use the following definitions:
+    </p>
+    <ul>
+      <li>
+        <strong>output latency</strong>. The interval between when an application writes a frame of PCM-coded data and when the corresponding sound is presented to environment at an on-device transducer or signal leaves the device via a port and can be observed externally.
+      </li>
+      <li>
+        <strong>cold output latency</strong>. The output latency for the first frame, when the audio output system has been idle and powered down prior to the request.
+      </li>
+      <li>
+        <strong>continuous output latency</strong>. The output latency for subsequent frames, after the device is playing audio.
+      </li>
+      <li>
+        <strong>input latency</strong>. The interval between when a sound is presented by environment to device at an on-device transducer or signal enters the device via a port and when an application reads the corresponding frame of PCM-coded data.
+      </li>
+      <li>
+        <strong>lost input</strong>. The initial portion of an input signal that is unusable or unavailable.
+      </li>
+      <li>
+        <strong>cold input latency</strong>. The sum of lost input time and the input latency for the first frame, when the audio input system has been idle and powered down prior to the request.
+      </li>
+      <li>
+        <strong>continuous input latency</strong>. The input latency for subsequent frames, while the device is capturing audio.
+      </li>
+      <li>
+        <strong>cold output jitter</strong>. The variability among separate measurements of cold output latency values.
+      </li>
+      <li>
+        <strong>cold input jitter</strong>. The variability among separate measurements of cold input latency values.
+      </li>
+      <li>
+        <strong>continuous round-trip latency</strong>. The sum of continuous input latency plus continuous output latency plus one buffer period. The buffer period allows time for the app to process the signal and time for the app to mitigate phase difference between input and output streams.
+      </li>
+      <li>
+        <strong>OpenSL ES PCM buffer queue API</strong>. The set of PCM-related <a href="https://developer.android.com/ndk/guides/audio/opensl/index.html">OpenSL ES</a> APIs within <a href="https://developer.android.com/ndk/index.html">Android NDK</a>.
+      </li>
+      <li>
+        <strong>AAudio native audio API</strong>. The set of <a href="https://developer.android.com/ndk/guides/audio/aaudio/aaudio.html">AAudio</a> APIs within <a href="https://developer.android.com/ndk/index.html">Android NDK</a>.
+      </li>
+    </ul>
+    <p>
+      If device implementations declare <code>android.hardware.audio.output</code> they are STRONGLY RECOMMENDED to meet or exceed the following requirements:
+    </p>
+    <ul>
+      <li>[SR] Cold output latency of 100 milliseconds or less
+      </li>
+      <li>[SR] Continuous output latency of 45 milliseconds or less
+      </li>
+      <li>[SR] Minimize the cold output jitter
+      </li>
+    </ul>
+    <p>
+      If device implementations meet the above requirements after any initial calibration when using the OpenSL ES PCM buffer queue API, for continuous output latency and cold output latency over at least one supported audio output device, they are:
+    </p>
+    <ul>
+      <li>[SR] STRONGLY RECOMMENDED to report low latency audio by declaring <code>android.hardware.audio.low_latency</code> feature flag.
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to also meet the requirements for low-latency audio via the AAudio API.
+      </li>
+    </ul>
+    <p>
+      If device implementations do not meet the requirements for low-latency audio via the OpenSL ES PCM buffer queue API, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST NOT report support for low-latency audio.
+      </li>
+    </ul>
+    <p>
+      If device implementations include <code>android.hardware.microphone</code>, they are STRONGLY RECOMMENDED to meet these input audio requirements:
+    </p>
+    <ul>
+      <li>[SR] Cold input latency of 100 milliseconds or less
+      </li>
+      <li>[SR] Continuous input latency of 30 milliseconds or less
+      </li>
+      <li>[SR] Continuous round-trip latency of 50 milliseconds or less
+      </li>
+      <li>[SR] Minimize the cold input jitter
+      </li>
+    </ul>
+    <h3 id="5_7_network_protocols">
+      5.7. Network Protocols
+    </h3>
+    <p>
+      Device implementations MUST support the <a href="http://developer.android.com/guide/appendix/media-formats.html">media network protocols</a> for audio and video playback as specified in the Android SDK documentation.
+    </p>
+    <p>
+      If device implementations include an audio or a video decoder, they:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-1-1] MUST support all required codecs and container formats in <a href="#5_1_media_codecs">section 5.1</a> over HTTP(S).
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-1-2] MUST support the media segment formats shown in the Media Segmant Formats table below over <a href="http://tools.ietf.org/html/draft-pantos-http-live-streaming-07">HTTP Live Streaming draft protocol, Version 7</a>.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-1-3] MUST support the following RTP audio video profile and related codecs in the RTSP table below. For exceptions please see the table footnotes in <a href="#5_1_media_codecs">section 5.1</a>.
+        </p>
+      </li>
+    </ul>
+    <p>
+      Media Segment Formats
+    </p>
+    <table>
+      <tr>
+        <th>
+          Segment formats
+        </th>
+        <th>
+          Reference(s)
+        </th>
+        <th>
+          Required codec support
+        </th>
+      </tr>
+      <tr id="mp2t">
+        <td>
+          MPEG-2 Transport Stream
+        </td>
+        <td>
+          <a href="http://www.iso.org/iso/catalogue_detail?csnumber=44169">ISO 13818</a>
+        </td>
+        <td>
+          Video codecs:
+          <ul>
+            <li class="table_list">H264 AVC
+            </li>
+            <li class="table_list">MPEG-4 SP
+            </li>
+            <li class="table_list">MPEG-2
+            </li>
+          </ul>See <a href="#5_1_3_video_codecs">section 5.1.3</a> for details on H264 AVC, MPEG2-4 SP,<br />
+          and MPEG-2.
+          <p>
+            Audio codecs:
+          </p>
+          <ul>
+            <li class="table_list">AAC
+            </li>
+          </ul>See <a href="#5_1_1_audio_codecs">section 5.1.1</a> for details on AAC and its variants.
+        </td>
+      </tr>
+      <tr>
+        <td>
+          AAC with ADTS framing and ID3 tags
+        </td>
+        <td>
+          <a href="http://www.iso.org/iso/home/store/catalogue_tc/catalogue_detail.htm?csnumber=43345">ISO 13818-7</a>
+        </td>
+        <td>
+          See <a href="#5_1_1_audio_codecs">section 5.1.1</a> for details on AAC and its variants
+        </td>
+      </tr>
+      <tr>
+        <td>
+          WebVTT
+        </td>
+        <td>
+          <a href="http://dev.w3.org/html5/webvtt/">WebVTT</a>
+        </td>
+        <td></td>
+      </tr>
+    </table>
+    <p>
+      RTSP (RTP, SDP)
+    </p>
+    <table>
+      <tr>
+        <th>
+          Profile name
+        </th>
+        <th>
+          Reference(s)
+        </th>
+        <th>
+          Required codec support
+        </th>
+      </tr>
+      <tr>
+        <td>
+          H264 AVC
+        </td>
+        <td>
+          <a href="https://tools.ietf.org/html/rfc6184">RFC 6184</a>
+        </td>
+        <td>
+          See <a href="#5_1_3_video_codecs">section 5.1.3</a> for details on H264 AVC
+        </td>
+      </tr>
+      <tr>
+        <td>
+          MP4A-LATM
+        </td>
+        <td>
+          <a href="https://tools.ietf.org/html/rfc6416">RFC 6416</a>
+        </td>
+        <td>
+          See <a href="#5_1_1_audio_codecs">section 5.1.1</a> for details on AAC and its variants
+        </td>
+      </tr>
+      <tr>
+        <td>
+          H263-1998
+        </td>
+        <td>
+          <a href="https://tools.ietf.org/html/rfc3551">RFC 3551</a><br />
+          <a href="https://tools.ietf.org/html/rfc4629">RFC 4629</a><br />
+          <a href="https://tools.ietf.org/html/rfc2190">RFC 2190</a>
+        </td>
+        <td>
+          See <a href="#5_1_3_video_codecs">section 5.1.3</a> for details on H263
+        </td>
+      </tr>
+      <tr>
+        <td>
+          H263-2000
+        </td>
+        <td>
+          <a href="https://tools.ietf.org/html/rfc4629">RFC 4629</a>
+        </td>
+        <td>
+          See <a href="#5_1_3_video_codecs">section 5.1.3</a> for details on H263
+        </td>
+      </tr>
+      <tr>
+        <td>
+          AMR
+        </td>
+        <td>
+          <a href="https://tools.ietf.org/html/rfc4867">RFC 4867</a>
+        </td>
+        <td>
+          See <a href="#5_1_1_audio_codecs">section 5.1.1</a> for details on AMR-NB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          AMR-WB
+        </td>
+        <td>
+          <a href="https://tools.ietf.org/html/rfc4867">RFC 4867</a>
+        </td>
+        <td>
+          See <a href="#5_1_1_audio_codecs">section 5.1.1</a> for details on AMR-WB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          MP4V-ES
+        </td>
+        <td>
+          <a href="https://tools.ietf.org/html/rfc6416">RFC 6416</a>
+        </td>
+        <td>
+          See <a href="#5_1_3_video_codecs">section 5.1.3</a> for details on MPEG-4 SP
+        </td>
+      </tr>
+      <tr>
+        <td>
+          mpeg4-generic
+        </td>
+        <td>
+          <a href="https://tools.ietf.org/html/rfc3640">RFC 3640</a>
+        </td>
+        <td>
+          See <a href="#5_1_1_audio_codecs">section 5.1.1</a> for details on AAC and its variants
+        </td>
+      </tr>
+      <tr>
+        <td>
+          MP2T
+        </td>
+        <td>
+          <a href="https://tools.ietf.org/html/rfc2250">RFC 2250</a>
+        </td>
+        <td>
+          See <a href="#mp2t">MPEG-2 Transport Stream</a> underneath HTTP Live Streaming for details
+        </td>
+      </tr>
+    </table>
+    <h3 id="5_8_secure_media">
+      5.8. Secure Media
+    </h3>
+    <p>
+      If device implementations support secure video output and are capable of supporting secure surfaces, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST declare support for <code>Display.FLAG_SECURE</code>.
+      </li>
+    </ul>
+    <p>
+      If device implementations declare support for <code>Display.FLAG_SECURE</code> and support wireless display protocol, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST secure the link with a cryptographically strong mechanism such as HDCP 2.x or higher for the displays connected through wireless protocols such as Miracast.
+      </li>
+    </ul>
+    <p>
+      If device implementations declare support for <code>Display.FLAG_SECURE</code> and support wired external display, they:
+    </p>
+    <ul>
+      <li>[C-3-1] MUST support HDCP 1.2 or higher for all wired external displays.
+      </li>
+    </ul>
+    <h3 id="5_9_musical_instrument_digital_interface_(midi)">
+      5.9. Musical Instrument Digital Interface (MIDI)
+    </h3>
+    <p>
+      If a device implementation supports the inter-app MIDI software transport (virtual MIDI devices), and it supports MIDI over <em>all</em> of the following MIDI-capable hardware transports for which it provides generic non-MIDI connectivity, it is:
+    </p>
+    <ul>
+      <li>[SR] STRONGLY RECOMMENDED to report support for feature android.software.midi via the <a href="http://developer.android.com/reference/android/content/pm/PackageManager.html">android.content.pm.PackageManager</a> class.
+      </li>
+    </ul>
+    <p>
+      The MIDI-capable hardware transports are:
+    </p>
+    <ul>
+      <li>USB host mode (section 7.7 USB)
+      </li>
+      <li>USB peripheral mode (section 7.7 USB)
+      </li>
+      <li>MIDI over Bluetooth LE acting in central role (section 7.4.3 Bluetooth)
+      </li>
+    </ul>
+    <p>
+      If the device implementation provides generic non-MIDI connectivity over a particular MIDI-capable hardware transport listed above, but does not support MIDI over that hardware transport, it:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST NOT report support for feature android.software.midi.
+      </li>
+    </ul>
+    <h3 id="5_10_professional_audio">
+      5.10. Professional Audio
+    </h3>
+    <p>
+      If device implementations report support for feature <code>android.hardware.audio.pro</code> via the <a href="http://developer.android.com/reference/android/content/pm/PackageManager.html">android.content.pm.PackageManager</a> class, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST report support for feature <code>android.hardware.audio.low_latency</code>.
+      </li>
+      <li>[C-1-2] MUST have the continuous round-trip audio latency, as defined in <a href="#5_6_audio_latency">section 5.6 Audio Latency</a>, MUST be 20 milliseconds or less and SHOULD be 10 milliseconds or less over at least one supported path.
+      </li>
+      <li>[C-1-3] MUST include a USB port(s) supporting USB host mode and USB peripheral mode.
+      </li>
+      <li>[C-1-4] MUST report support for feature <code>android.software.midi</code>.
+      </li>
+      <li>[C-1-5] MUST meet latencies and USB audio requirements using the <a href="https://developer.android.com/ndk/guides/audio/opensl-for-android.html">OpenSL ES</a> PCM buffer queue API.
+      </li>
+      <li>SHOULD provide a sustainable level of CPU performance while audio is active.
+      </li>
+      <li>SHOULD minimize audio clock inaccuracy and drift relative to standard time.
+      </li>
+      <li>SHOULD minimize audio clock drift relative to the CPU <code>CLOCK_MONOTONIC</code> when both are active.
+      </li>
+      <li>SHOULD minimize audio latency over on-device transducers.
+      </li>
+      <li>SHOULD minimize audio latency over USB digital audio.
+      </li>
+      <li>SHOULD document audio latency measurements over all paths.
+      </li>
+      <li>SHOULD minimize jitter in audio buffer completion callback entry times, as this affects usable percentage of full CPU bandwidth by the callback.
+      </li>
+      <li>SHOULD provide zero audio underruns (output) or overruns (input) under normal use at reported latency.
+      </li>
+      <li>SHOULD provide zero inter-channel latency difference.
+      </li>
+      <li>SHOULD minimize MIDI mean latency over all transports.
+      </li>
+      <li>SHOULD minimize MIDI latency variability under load (jitter) over all transports.
+      </li>
+      <li>SHOULD provide accurate MIDI timestamps over all transports.
+      </li>
+      <li>SHOULD minimize audio signal noise over on-device transducers, including the period immediately after cold start.
+      </li>
+      <li>SHOULD provide zero audio clock difference between the input and output sides of corresponding end-points, when both are active. Examples of corresponding end-points include the on-device microphone and speaker, or the audio jack input and output.
+      </li>
+      <li>SHOULD handle audio buffer completion callbacks for the input and output sides of corresponding end-points on the same thread when both are active, and enter the output callback immediately after the return from the input callback. Or if it is not feasible to handle the callbacks on the same thread, then enter the output callback shortly after entering the input callback to permit the application to have a consistent timing of the input and output sides.
+      </li>
+      <li>SHOULD minimize the phase difference between HAL audio buffering for the input and output sides of corresponding end-points.
+      </li>
+      <li>SHOULD minimize touch latency.
+      </li>
+      <li>SHOULD minimize touch latency variability under load (jitter).
+      </li>
+    </ul>
+    <p>
+      If device implementations meet all of the above requirements, they:
+    </p>
+    <ul>
+      <li>[SR] STRONGLY RECOMMENDED to report support for feature <code>android.hardware.audio.pro</code> via the <a href="http://developer.android.com/reference/android/content/pm/PackageManager.html"><code>android.content.pm.PackageManager</code></a> class.
+      </li>
+    </ul>
+    <p>
+      If device implementations meet the requirements via the OpenSL ES PCM buffer queue API, they:
+    </p>
+    <ul>
+      <li>[SR] STRONGLY RECOMMENDED to also meet the same requirements via the <a href="https://developer.android.com/ndk/guides/audio/aaudio/aaudio.html">AAudio</a> API.
+      </li>
+    </ul>
+    <p>
+      If device implementations include a 4 conductor 3.5mm audio jack, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST have the continuous round-trip audio latency to be 20 milliseconds or less over the audio jack path.
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to comply with section <a href="https://source.android.com/devices/accessories/headset/jack-headset-spec">Mobile device (jack) specifications</a> of the <a href="https://source.android.com/devices/accessories/headset/plug-headset-spec">Wired Audio Headset Specification (v1.1)</a>.
+      </li>
+      <li>The continuous round-trip audio latency SHOULD be 10 milliseconds or less over the audio jack path.
+      </li>
+    </ul>
+    <p>
+      If device implementations omit a 4 conductor 3.5mm audio jack, they:
+    </p>
+    <ul>
+      <li>[C-3-1] MUST have a continuous round-trip audio latency of 20 milliseconds or less.
+      </li>
+      <li>The continuous round-trip audio latency SHOULD be 10 milliseconds or less over the USB host mode port using USB audio class.
+      </li>
+    </ul>
+    <p>
+      If device implementations include a USB port(s) supporting USB host mode, they:
+    </p>
+    <ul>
+      <li>[C-4-1] MUST implement the USB audio class.
+      </li>
+    </ul>
+    <p>
+      If device implementations include an HDMI port, they:
+    </p>
+    <ul>
+      <li>[C-5-1] MUST support output in stereo and eight channels at 20-bit or 24-bit depth and 192 kHz without bit-depth loss or resampling.
+      </li>
+    </ul>
+    <h3 id="5_11_capture_for_unprocessed">
+      5.11. Capture for Unprocessed
+    </h3>
+    <p>
+      Android includes support for recording of unprocessed audio via the <code>android.media.MediaRecorder.AudioSource.UNPROCESSED</code> audio source. In OpenSL ES, it can be accessed with the record preset <code>SL_ANDROID_RECORDING_PRESET_UNPROCESSED</code>.
+    </p>
+    <p>
+      If device implementations intent to support unprocessed audio source and make it available to third-party apps, they:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-1-1] MUST report the support through the <code>android.media.AudioManager</code> property <a href="http://developer.android.com/reference/android/media/AudioManager.html#PROPERTY_SUPPORT_AUDIO_SOURCE_UNPROCESSED">PROPERTY_SUPPORT_AUDIO_SOURCE_UNPROCESSED</a>.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-1-2] MUST exhibit approximately flat amplitude-versus-frequency characteristics in the mid-frequency range: specifically ±10dB from 100 Hz to 7000 Hz for each and every microphone used to record the unprocessed audio source.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-1-3] MUST exhibit amplitude levels in the low frequency range: specifically from ±20 dB from 5 Hz to 100 Hz compared to the mid-frequency range for each and every microphone used to record the unprocessed audio source.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-1-4] MUST exhibit amplitude levels in the high frequency range: specifically from ±30 dB from 7000 Hz to 22 KHz compared to the mid-frequency range for each and every microphone used to record the unprocessed audio source.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-1-5] MUST set audio input sensitivity such that a 1000 Hz sinusoidal tone source played at 94 dB Sound Pressure Level (SPL) yields a response with RMS of 520 for 16 bit-samples (or -36 dB Full Scale for floating point/double precision samples) for each and every microphone used to record the unprocessed audio source.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-1-6] MUST have a signal-to-noise ratio (SNR) at 60 dB or higher for each and every microphone used to record the unprocessed audio source. (whereas the SNR is measured as the difference between 94 dB SPL and equivalent SPL of self noise, A-weighted).
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-1-7] MUST have a total harmonic distortion (THD) less than be less than 1% for 1 kHZ at 90 dB SPL input level at each and every microphone used to record the unprocessed audio source.
+        </p>
+      </li>
+      <li>
+        <p>
+          MUST not have any other signal processing (e.g. Automatic Gain Control, High Pass Filter, or Echo cancellation) in the path other than a level multiplier to bring the level to desired range. In other words:
+        </p>
+      </li>
+      <li>[C-1-8] If any signal processing is present in the architecture for any reason, it MUST be disabled and effectively introduce zero delay or extra latency to the signal path.
+      </li>
+      <li>[C-1-9] The level multiplier, while allowed to be on the path, MUST NOT introduce delay or latency to the signal path.
+      </li>
+    </ul>
+    <p>
+      All SPL measurements are made directly next to the microphone under test. For multiple microphone configurations, these requirements apply to each microphone.
+    </p>
+    <p>
+      If device implementations declare <code>android.hardware.microphone</code> but do not support unprocessed audio source, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST return <code>null</code> for the <code>AudioManager.getProperty(PROPERTY_SUPPORT_AUDIO_SOURCE_UNPROCESSED)</code> API method, to properly indicate the lack of support.
+      </li>
+      <li>[SR] are still STRONGLY RECOMMENDED to satisfy as many of the requirements for the signal path for the unprocessed recording source.
+      </li>
+    </ul>
+    <h2 id="6_developer_tools_and_options_compatibility">
+      6. Developer Tools and Options Compatibility
+    </h2>
+    <h3 id="6_1_developer_tools">
+      6.1. Developer Tools
+    </h3>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST support the Android Developer Tools provided in the Android SDK.
+      </li>
+      <li>
+        <p>
+          <a href="http://developer.android.com/tools/help/adb.html"><strong>Android Debug Bridge (adb)</strong></a>
+        </p>
+        <ul>
+          <li>[C-0-2] MUST support all adb functions as documented in the Android SDK including <a href="https://source.android.com/devices/input/diagnostics.html">dumpsys</a>.
+          </li>
+          <li>[C-0-3] MUST NOT alter the format or the contents of device system events (batterystats , diskstats, fingerprint, graphicsstats, netstats, notification, procstats) logged via dumpsys.
+          </li>
+          <li>[C-0-4] MUST have the device-side adb daemon be inactive by default and there MUST be a user-accessible mechanism to turn on the Android Debug Bridge.
+          </li>
+          <li>[C-0-5] MUST support secure adb. Android includes support for secure adb. Secure adb enables adb on known authenticated hosts.
+          </li>
+          <li>
+            <p>
+              [C-0-6] MUST provide a mechanism allowing adb to be connected from a host machine. For example:
+            </p>
+            <ul>
+              <li>Device implementations without a USB port supporting peripheral mode MUST implement adb via local-area network (such as Ethernet or Wi-Fi).
+              </li>
+              <li>MUST provide drivers for Windows 7, 9 and 10, allowing developers to connect to the device using the adb protocol.
+              </li>
+            </ul>
+          </li>
+        </ul>
+      </li>
+      <li>
+        <p>
+          <a href="http://developer.android.com/tools/debugging/ddms.html"><strong>Dalvik Debug Monitor Service (ddms)</strong></a>
+        </p>
+        <ul>
+          <li>[C-0-7] MUST support all ddms features as documented in the Android SDK. As ddms uses adb, support for ddms SHOULD be inactive by default, but MUST be supported whenever the user has activated the Android Debug Bridge, as above.
+          </li>
+        </ul>
+      </li>
+      <li>
+        <a href="http://developer.android.com/tools/help/monkey.html"><strong>Monkey</strong></a>
+        <ul>
+          <li>[C-0-8] MUST include the Monkey framework and make it available for applications to use.
+          </li>
+        </ul>
+      </li>
+      <li>
+        <a href="http://developer.android.com/tools/help/systrace.html"><strong>SysTrace</strong></a>
+        <ul>
+          <li>[C-0-9] MUST support systrace tool as documented in the Android SDK. Systrace must be inactive by default and there MUST be a user-accessible mechanism to turn on Systrace.
+          </li>
+        </ul>
+      </li>
+    </ul>
+    <h3 id="6_2_developer_options">
+      6.2. Developer Options
+    </h3>
+    <p>
+      Android includes support for developers to configure application development-related settings.
+    </p>
+    <p>
+      Device implementations MUST provide a consistent experience for Developer Options, they:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST honor the <a href="http://developer.android.com/reference/android/provider/Settings.html#ACTION_APPLICATION_DEVELOPMENT_SETTINGS">android.settings.APPLICATION_DEVELOPMENT_SETTINGS</a> intent to show application development-related settings. The upstream Android implementation hides the Developer Options menu by default and enables users to launch Developer Options after pressing seven (7) times on the <strong>Settings</strong> &gt; <strong>About Device</strong> &gt; <strong>Build Number</strong> menu item.
+      </li>
+      <li>[C-0-2] MUST hide Developer Options by default and MUST provide a mechanism to enable Developer Options without the need for any special whitelisting.
+      </li>
+      <li>MAY temporarily limit access to the Developer Options menu, by visually hiding or disabling the menu, to prevent distraction for scenarios where the safety of the user is of concern.
+      </li>
+    </ul>
+    <h2 id="7_hardware_compatibility">
+      7. Hardware Compatibility
+    </h2>
+    <p>
+      If a device includes a particular hardware component that has a corresponding API for third-party developers:
+    </p>
+    <ul>
+      <li>[C-0-1] The device implementation MUST implement that API as described in the Android SDK documentation.
+      </li>
+    </ul>
+    <p>
+      If an API in the SDK interacts with a hardware component that is stated to be optional and the device implementation does not possess that component:
+    </p>
+    <ul>
+      <li>[C-0-2] Complete class definitions (as documented by the SDK) for the component APIs MUST still be presented.
+      </li>
+      <li>[C-0-3] The API’s behaviors MUST be implemented as no-ops in some reasonable fashion.
+      </li>
+      <li>[C-0-4] API methods MUST return null values where permitted by the SDK documentation.
+      </li>
+      <li>[C-0-5] API methods MUST return no-op implementations of classes where null values are not permitted by the SDK documentation.
+      </li>
+      <li>[C-0-6] API methods MUST NOT throw exceptions not documented by the SDK documentation.
+      </li>
+      <li>[C-0-7] Device implementations MUST consistently report accurate hardware configuration information via the <code>getSystemAvailableFeatures()</code> and <code>hasSystemFeature(String)</code> methods on the <a href="http://developer.android.com/reference/android/content/pm/PackageManager.html">android.content.pm.PackageManager</a> class for the same build fingerprint.
+      </li>
+    </ul>
+    <p>
+      A typical example of a scenario where these requirements apply is the telephony API: Even on non-phone devices, these APIs must be implemented as reasonable no-ops.
+    </p>
+    <h3 id="7_1_display_and_graphics">
+      7.1. Display and Graphics
+    </h3>
+    <p>
+      Android includes facilities that automatically adjust application assets and UI layouts appropriately for the device to ensure that third-party applications run well on a <a href="http://developer.android.com/guide/practices/screens_support.html">variety of hardware configurations</a>. Devices MUST properly implement these APIs and behaviors, as detailed in this section.
+    </p>
+    <p>
+      The units referenced by the requirements in this section are defined as follows:
+    </p>
+    <ul>
+      <li>
+        <strong>physical diagonal size</strong>. The distance in inches between two opposing corners of the illuminated portion of the display.
+      </li>
+      <li>
+        <strong>dots per inch (dpi)</strong>. The number of pixels encompassed by a linear horizontal or vertical span of 1”. Where dpi values are listed, both horizontal and vertical dpi must fall within the range.
+      </li>
+      <li>
+        <strong>aspect ratio</strong>. The ratio of the pixels of the longer dimension to the shorter dimension of the screen. For example, a display of 480x854 pixels would be 854/480 = 1.779, or roughly “16:9”.
+      </li>
+      <li>
+        <strong>density-independent pixel (dp)</strong>. The virtual pixel unit normalized to a 160 dpi screen, calculated as: pixels = dps * (density/160).
+      </li>
+    </ul>
+    <h4 id="7_1_1_screen_configuration">
+      7.1.1. Screen Configuration
+    </h4>
+    <h5 id="7_1_1_1_screen_size">
+      7.1.1.1. Screen Size
+    </h5>
+    <p>
+      The Android UI framework supports a variety of different logical screen layout sizes, and allows applications to query the current configuration's screen layout size via <code>Configuration.screenLayout</code> with the <code>SCREENLAYOUT_SIZE_MASK</code> and <code>Configuration.smallestScreenWidthDp</code>.
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-0-1] Device implementations MUST report the correct layout size for the <code>Configuration.screenLayout</code> as defined in the Android SDK documentation. Specifically, device implementations MUST report the correct logical density-independent pixel (dp) screen dimensions as below:
+        </p>
+        <ul>
+          <li>Devices with the <code>Configuration.uiMode</code> set as any value other than UI_MODE_TYPE_WATCH, and reporting a <code>small</code> size for the <code>Configuration.screenLayout</code>, MUST have at least 426 dp x 320 dp.
+          </li>
+          <li>Devices reporting a <code>normal</code> size for the <code>Configuration.screenLayout</code>, MUST have at least 480 dp x 320 dp.
+          </li>
+          <li>Devices reporting a <code>large</code> size for the <code>Configuration.screenLayout</code>, MUST have at least 640 dp x 480 dp.
+          </li>
+          <li>Devices reporting a <code>xlarge</code> size for the <code>Configuration.screenLayout</code>, MUST have at least 960 dp x 720 dp.
+          </li>
+        </ul>
+      </li>
+      <li>
+        <p>
+          [C-0-2] Device implementations MUST correctly honor applications' stated support for screen sizes through the <a href="https://developer.android.com/guide/topics/manifest/supports-screens-element.html">&lt;<code>supports-screens</code>&gt;</a> attribute in the AndroidManifest.xml, as described in the Android SDK documentation.
+        </p>
+      </li>
+    </ul>
+    <h5 id="7_1_1_2_screen_aspect_ratio">
+      7.1.1.2. Screen Aspect Ratio
+    </h5>
+    <p>
+      While there is no restriction to the screen aspect ratio value of the physical screen display, the screen aspect ratio of the logical display that third-party apps are rendered within, as can be derived from the height and width values reported through the <a href="https://developer.android.com/reference/android/view/Display.html"><code>view.Display</code></a> APIs and <a href="https://developer.android.com/reference/android/content/res/Configuration.html">Configuration</a> API, MUST meet the following requirements:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-0-1] Device implementations with the <code>Configuration.uiMode</code> set as <code>UI_MODE_TYPE_NORMAL</code> MUST have an aspect ratio value between 1.3333 (4:3) and 1.86 (roughly 16:9), unless the app can be deemed as ready to be stretched longer by meeting one of the following conditions:
+        </p>
+        <ul>
+          <li>The app has declared that it supports a larger screen aspect ratio through the <a href="https://developer.android.com/guide/practices/screens&amp;lowbar;support.html#MaxAspectRatio"><code>android.max_aspect</code></a> metadata value.
+          </li>
+          <li>The app declares it is resizeable via the <a href="https://developer.android.com/guide/topics/ui/multi-window.html#configuring">android:resizeableActivity</a> attribute.
+          </li>
+          <li>The app is targeting API level 26 or higher and does not declare a <a href="https://developer.android.com/reference/android/R.attr.html#maxAspectRatio"><code>android:MaxAspectRatio</code></a> that would restrict the allowed aspect ratio.
+          </li>
+        </ul>
+      </li>
+      <li>
+        <p>
+          [C-0-2] Device implementations with the <code>Configuration.uiMode</code> set as <code>UI_MODE_TYPE_WATCH</code> MUST have an aspect ratio value set as 1.0 (1:1).
+        </p>
+      </li>
+    </ul>
+    <h5 id="7_1_1_3_screen_density">
+      7.1.1.3. Screen Density
+    </h5>
+    <p>
+      The Android UI framework defines a set of standard logical densities to help application developers target application resources.
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-0-1] By default, device implementations MUST report only one of the following logical Android framework densities through the <a href="https://developer.android.com/reference/android/util/DisplayMetrics.html#DENSITY_DEVICE_STABLE">DENSITY_DEVICE_STABLE</a> API and this value MUST NOT change at any time; however, the device MAY report a different arbitrary density according to the display configuration changes made by the user (for example, display size) set after initial boot.
+        </p>
+        <ul>
+          <li>120 dpi (ldpi)
+          </li>
+          <li>160 dpi (mdpi)
+          </li>
+          <li>213 dpi (tvdpi)
+          </li>
+          <li>240 dpi (hdpi)
+          </li>
+          <li>260 dpi (260dpi)
+          </li>
+          <li>280 dpi (280dpi)
+          </li>
+          <li>300 dpi (300dpi)
+          </li>
+          <li>320 dpi (xhdpi)
+          </li>
+          <li>340 dpi (340dpi)
+          </li>
+          <li>360 dpi (360dpi)
+          </li>
+          <li>400 dpi (400dpi)
+          </li>
+          <li>420 dpi (420dpi)
+          </li>
+          <li>480 dpi (xxhdpi)
+          </li>
+          <li>560 dpi (560dpi)
+          </li>
+          <li>640 dpi (xxxhdpi)
+          </li>
+        </ul>
+      </li>
+      <li>
+        <p>
+          Device implementations SHOULD define the standard Android framework density that is numerically closest to the physical density of the screen, unless that logical density pushes the reported screen size below the minimum supported. If the standard Android framework density that is numerically closest to the physical density results in a screen size that is smaller than the smallest supported compatible screen size (320 dp width), device implementations SHOULD report the next lowest standard Android framework density.
+        </p>
+      </li>
+    </ul>
+    <p>
+      If there is an affordance to change the display size of the device:
+    </p>
+    <ul>
+      <li>[C-1-1] The display size MUST NOT be scaled any larger than 1.5 times the native density or produce an effective minimum screen dimension smaller than 320dp (equivalent to resource qualifier sw320dp), whichever comes first.
+      </li>
+      <li>[C-1-2] Display size MUST NOT be scaled any smaller than 0.85 times the native density.
+      </li>
+      <li>To ensure good usability and consistent font sizes, it is RECOMMENDED that the following scaling of Native Display options be provided (while complying with the limits specified above)
+      </li>
+      <li>Small: 0.85x
+      </li>
+      <li>Default: 1x (Native display scale)
+      </li>
+      <li>Large: 1.15x
+      </li>
+      <li>Larger: 1.3x
+      </li>
+      <li>Largest 1.45x
+      </li>
+    </ul>
+    <h4 id="7_1_2_display_metrics">
+      7.1.2. Display Metrics
+    </h4>
+    <p>
+      If device implementations include a screen or video output, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST report correct values for all display metrics defined in the <a href="https://developer.android.com/reference/android/util/DisplayMetrics.html"><code>android.util.DisplayMetrics</code></a> API.
+      </li>
+    </ul>
+    <p>
+      If device implementations does not include an embedded screen or video output, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST report reasonable values for all display metrics defined in the <a href="https://developer.android.com/reference/android/util/DisplayMetrics.html"><code>android.util.DisplayMetrics</code></a> API for the emulated default <code>view.Display</code>.
+      </li>
+    </ul>
+    <h4 id="7_1_3_screen_orientation">
+      7.1.3. Screen Orientation
+    </h4>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST report which screen orientations they support (<code>android.hardware.screen.portrait</code> and/or <code>android.hardware.screen.landscape</code>) and MUST report at least one supported orientation. For example, a device with a fixed orientation landscape screen, such as a television or laptop, SHOULD only report <code>android.hardware.screen.landscape</code>.
+      </li>
+      <li>[C-0-2] MUST report the correct value for the device’s current orientation, whenever queried via the <code>android.content.res.Configuration.orientation</code>, <code>android.view.Display.getOrientation()</code>, or other APIs.
+      </li>
+    </ul>
+    <p>
+      If device implementations support both screen orientations, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support dynamic orientation by applications to either portrait or landscape screen orientation. That is, the device must respect the application’s request for a specific screen orientation.
+      </li>
+      <li>[C-1-2] MUST NOT change the reported screen size or density when changing orientation.
+      </li>
+      <li>MAY select either portrait or landscape orientation as the default.
+      </li>
+    </ul>
+    <h4 id="7_1_4_2d_and_3d_graphics_acceleration">
+      7.1.4. 2D and 3D Graphics Acceleration
+    </h4>
+    <h5 id="7_1_4_1_opengl_es">
+      7.1.4.1 OpenGL ES
+    </h5>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST correctly identify the supported OpenGL ES versions (1.1, 2.0, 3.0, 3.1, 3.2) through the managed APIs (such as via the <code>GLES10.getString()</code> method) and the native APIs.
+      </li>
+      <li>[C-0-2] MUST include the support for all the corresponding managed APIs and native APIs for every OpenGL ES versions they identified to support.
+      </li>
+    </ul>
+    <p>
+      If device implementations include a screen or video output, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support both OpenGL ES 1.0 and 2.0, as embodied and detailed in the <a href="https://developer.android.com/guide/topics/graphics/opengl.html">Android SDK documentation</a>.
+      </li>
+      <li>[SR] are STRONGLY RECOMMENDED to support OpenGL ES 3.0.
+      </li>
+      <li>SHOULD support OpenGL ES 3.1 or 3.2.
+      </li>
+    </ul>
+    <p>
+      If device implementations support any of the OpenGL ES versions, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST report via the OpenGL ES managed APIs and native APIs any other OpenGL ES extensions they have implemented, and conversely MUST NOT report extension strings that they do not support.
+      </li>
+      <li>[C-2-2] MUST support the <code>EGL_KHR_image</code>, <code>EGL_KHR_image_base</code>, <code>EGL_ANDROID_image_native_buffer</code>, <code>EGL_ANDROID_get_native_client_buffer</code>, <code>EGL_KHR_wait_sync</code>, <code>EGL_KHR_get_all_proc_addresses</code>, <code>EGL_ANDROID_presentation_time</code>, <code>EGL_KHR_swap_buffers_with_damage</code> and <code>EGL_ANDROID_recordable</code> extensions.
+      </li>
+      <li>[SR] are STRONGLY RECOMMENDED to support EGL_KHR_partial_update.
+      </li>
+      <li>SHOULD accurately report via the <code>getString()</code> method, any texture compression format that they support, which is typically vendor-specific.
+      </li>
+    </ul>
+    <p>
+      If device implementations declare support for OpenGL ES 3.0, 3.1, or 3.2, they:
+    </p>
+    <ul>
+      <li>[C-3-1] MUST export the corresponding function symbols for these version in addition to the OpenGL ES 2.0 function symbols in the libGLESv2.so library.
+      </li>
+    </ul>
+    <p>
+      If device implementations support OpenGL ES 3.2, they:
+    </p>
+    <ul>
+      <li>[C-4-1] MUST support the OpenGL ES Android Extension Pack in its entirety.
+      </li>
+    </ul>
+    <p>
+      If device implementations support the OpenGL ES <a href="https://developer.android.com/reference/android/opengl/GLES31Ext.html">Android Extension Pack</a> in its entirety, they:
+    </p>
+    <ul>
+      <li>[C-5-1] MUST identify the support through the <code>android.hardware.opengles.aep</code> feature flag.
+      </li>
+    </ul>
+    <p>
+      If device implementations expose support for the <code>EGL_KHR_mutable_render_buffer</code> extension, they:
+    </p>
+    <ul>
+      <li>[C-6-1] MUST also support the <code>EGL_ANDROID_front_buffer_auto_refresh</code> extension.
+      </li>
+    </ul>
+    <h5 id="7_1_4_2_vulkan">
+      7.1.4.2 Vulkan
+    </h5>
+    <p>
+      Android includes support for <a href="https://www.khronos.org/registry/vulkan/specs/1.0-wsi&amp;lowbarextensions/xhtml/vkspec.html">Vulkan</a> , a low-overhead, cross-platform API for high-performance 3D graphics.
+    </p>
+    <p>
+      If device implementations support OpenGL ES 3.0 or 3.1, they:
+    </p>
+    <ul>
+      <li>[SR] Are STRONGLY RECOMMENDED to include support for Vulkan 1.0 .
+      </li>
+    </ul>
+    <p>
+      If device implementations include a screen or video output, they:
+    </p>
+    <ul>
+      <li>SHOULD include support for Vulkan 1.0.
+      </li>
+    </ul>
+    <p>
+      Device implementations, if including support for Vulkan 1.0:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST report the correct integer value with the <code>android.hardware.vulkan.level</code> and <code>android.hardware.vulkan.version</code> feature flags.
+      </li>
+      <li>[C-1-2] MUST enumarate, at least one <code>VkPhysicalDevice</code> for the Vulkan native API <a href="https://www.khronos.org/registry/vulkan/specs/1.0/man/html/vkEnumeratePhysicalDevices.html"><code>vkEnumeratePhysicalDevices()</code></a> .
+      </li>
+      <li>[C-1-3] MUST fully implement the Vulkan 1.0 APIs for each enumerated <code>VkPhysicalDevice</code>.
+      </li>
+      <li>[C-1-4] MUST enumerate layers, contained in native libraries named as <code>libVkLayer*.so</code> in the application package’s native library directory, through the Vulkan native APIs <a href="https://www.khronos.org/registry/vulkan/specs/1.0/man/html/vkEnumerateInstanceLayerProperties.html"><code>vkEnumerateInstanceLayerProperties()</code></a> and <a href="https://www.khronos.org/registry/vulkan/specs/1.0/man/html/vkEnumerateDeviceLayerProperties.html"><code>vkEnumerateDeviceLayerProperties()</code></a> .
+      </li>
+      <li>[C-1-5] MUST NOT enumerate layers provided by libraries outside of the application package, or provide other ways of tracing or intercepting the Vulkan API, unless the application has the <code>android:debuggable</code> attribute set as <code>true</code>.
+      </li>
+      <li>[C-1-6] MUST report all extension strings that they do support via the Vulkan native APIs , and conversely MUST NOT report extension strings that they do not correctly support.
+      </li>
+    </ul>
+    <p>
+      Device implementations, if not including support for Vulkan 1.0:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST NOT declare any of the Vulkan feature flags (e.g. <code>android.hardware.vulkan.level</code>, <code>android.hardware.vulkan.version</code>).
+      </li>
+      <li>[C-2-2] MUST NOT enumarate any <code>VkPhysicalDevice</code> for the Vulkan native API <code>vkEnumeratePhysicalDevices()</code>.
+      </li>
+    </ul>
+    <h5 id="7_1_4_3_renderscript">
+      7.1.4.3 RenderScript
+    </h5>
+    <ul>
+      <li>[C-0-1] Device implementations MUST support <a href="http://developer.android.com/guide/topics/renderscript/">Android RenderScript</a>, as detailed in the Android SDK documentation.
+      </li>
+    </ul>
+    <h5 id="7_1_4_4_2d_graphics_acceleration">
+      7.1.4.4 2D Graphics Acceleration
+    </h5>
+    <p>
+      Android includes a mechanism for applications to declare that they want to enable hardware acceleration for 2D graphics at the Application, Activity, Window, or View level through the use of a manifest tag <a href="http://developer.android.com/guide/topics/graphics/hardware-accel.html">android:hardwareAccelerated</a> or direct API calls.
+    </p>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST enable hardware acceleration by default, and MUST disable hardware acceleration if the developer so requests by setting android:hardwareAccelerated="false” or disabling hardware acceleration directly through the Android View APIs.
+      </li>
+      <li>[C-0-2] MUST exhibit behavior consistent with the Android SDK documentation on <a href="http://developer.android.com/guide/topics/graphics/hardware-accel.html">hardware acceleration</a>.
+      </li>
+    </ul>
+    <p>
+      Android includes a TextureView object that lets developers directly integrate hardware-accelerated OpenGL ES textures as rendering targets in a UI hierarchy.
+    </p>
+    <ul>
+      <li>[C-0-3] MUST support the TextureView API, and MUST exhibit consistent behavior with the upstream Android implementation.
+      </li>
+    </ul>
+    <h5 id="7_1_4_5_wide-gamut_displays">
+      7.1.4.5 Wide-gamut Displays
+    </h5>
+    <p>
+      If device implementations claim support for wide-gamut displays through <a href="https://developer.android.com/reference/android/view/Display.html#isWideColorGamut%28%29"><code>Display.isWideColorGamut()</code></a> , they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST have a color-calibrated display.
+      </li>
+      <li>[C-1-2] MUST have a display whose gamut covers the sRGB color gamut entirely in CIE 1931 xyY space.
+      </li>
+      <li>[C-1-3] MUST have a display whose gamut has an area of at least 90% of NTSC 1953 in CIE 1931 xyY space.
+      </li>
+      <li>[C-1-4] MUST support OpenGL ES 3.0, 3.1, or 3.2 and report it properly.
+      </li>
+      <li>[C-1-5] MUST advertise support for the <code>EGL_KHR_no_config_context</code>, <code>EGL_EXT_pixel_format_float</code>,<code>EGL_KHR_gl_colorspace</code>, <code>EGL_EXT_colorspace_scrgb_linear</code>, and <code>EGL_GL_colorspace_display_p3</code> extensions.
+      </li>
+      <li>[SR] Are STRONGLY RECOMMENDED to support <code>GL_EXT_sRGB</code>.
+      </li>
+    </ul>
+    <p>
+      Conversely, if device implementations do not support wide-gamut displays, they:
+    </p>
+    <ul>
+      <li>[C-2-1] SHOULD cover 100% or more of sRGB in CIE 1931 xyY space, although the screen color gamut is undefined.
+      </li>
+    </ul>
+    <h4 id="7_1_5_legacy_application_compatibility_mode">
+      7.1.5. Legacy Application Compatibility Mode
+    </h4>
+    <p>
+      Android specifies a “compatibility mode” in which the framework operates in a 'normal' screen size equivalent (320dp width) mode for the benefit of legacy applications not developed for old versions of Android that pre-date screen-size independence.
+    </p>
+    <h4 id="7_1_6_screen_technology">
+      7.1.6. Screen Technology
+    </h4>
+    <p>
+      The Android platform includes APIs that allow applications to render rich graphics to the display. Devices MUST support all of these APIs as defined by the Android SDK unless specifically allowed in this document.
+    </p>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST support displays capable of rendering 16-bit color graphics.
+      </li>
+      <li>SHOULD support displays capable of 24-bit color graphics.
+      </li>
+      <li>[C-0-2] MUST support displays capable of rendering animations.
+      </li>
+      <li>[C-0-3] MUST use the display technology that have a pixel aspect ratio (PAR) between 0.9 and 1.15. That is, the pixel aspect ratio MUST be near square (1.0) with a 10 ~ 15% tolerance.
+      </li>
+    </ul>
+    <h4 id="7_1_7_secondary_displays">
+      7.1.7. Secondary Displays
+    </h4>
+    <p>
+      Android includes support for secondary display to enable media sharing capabilities and developer APIs for accessing external displays.
+    </p>
+    <p>
+      If device implementations support an external display either via a wired, wireless, or an embedded additional display connection, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST implement the <a href="https://developer.android.com/reference/android/hardware/display/DisplayManager.html"><code>DisplayManager</code></a> system service and API as described in the Android SDK documentation.
+      </li>
+    </ul>
+    <h3 id="7_2_input_devices">
+      7.2. Input Devices
+    </h3>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST include an input mechanism, such as a <a href="#7_2_4_touchScreen_input">touchscreen</a> or <a href="#7_2_2_non-touch_navigation">non-touch navigation</a>, to navigate between the UI elements.
+      </li>
+    </ul>
+    <h4 id="7_2_1_keyboard">
+      7.2.1. Keyboard
+    </h4>
+    <p>
+      If device implementations include support for third-party Input Method Editor (IME) applications, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST declare the <a href="https://developer.android.com/reference/android/content/pm/PackageManager.html#FEATURE_INPUT_METHODS"><code>android.software.input_methods</code></a> feature flag.
+      </li>
+      <li>[C-1-2] MUST implement fully <a href="https://developer.android.com/reference/android/view/inputmethod/InputMethodManager.html"><code>Input Management Framework</code></a>
+      </li>
+      <li>[C-1-3] MUST have a preloaded software keyboard.
+      </li>
+    </ul>
+    <p>
+      Device implementations: <em>[C-0-1] MUST NOT include a hardware keyboard that does not match one of the formats specified in <a href="http://developer.android.com/reference/android/content/res/Configuration.html">android.content.res.Configuration.keyboard</a> (QWERTY or 12-key).</em> SHOULD include additional soft keyboard implementations. * MAY include a hardware keyboard.
+    </p>
+    <h4 id="7_2_2_non-touch_navigation">
+      7.2.2. Non-touch Navigation
+    </h4>
+    <p>
+      Android includes support for d-pad, trackball, and wheel as mechanisms for non-touch navigation.
+    </p>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST report the correct value for <a href="https://developer.android.com/reference/android/content/res/Configuration.html#navigation">android.content.res.Configuration.navigation</a>.
+      </li>
+    </ul>
+    <p>
+      If device implementations lack non-touch navigations, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST provide a reasonable alternative user interface mechanism for the selection and editing of text, compatible with Input Management Engines. The upstream Android open source implementation includes a selection mechanism suitable for use with devices that lack non-touch navigation inputs.
+      </li>
+    </ul>
+    <h4 id="7_2_3_navigation_keys">
+      7.2.3. Navigation Keys
+    </h4>
+    <p>
+      The <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_HOME">Home</a>, <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_APP_SWITCH">Recents</a>, and <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BACK">Back</a> functions typically provided via an interaction with a dedicated physical button or a distinct portion of the touch screen, are essential to the Android navigation paradigm and therefore:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST provide the Home function.
+      </li>
+      <li>SHOULD provide buttons for the Recents and Back function.
+      </li>
+    </ul>
+    <p>
+      If the Home, Recents, or Back functions are provided, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST be accessible with a single action (e.g. tap, double-click or gesture) when any of them are accessible.
+      </li>
+      <li>[C-1-2] MUST provide a clear indication of which single action would trigger each function. Having a visible icon imprinted on the button, showing a software icon on the navigation bar portion of the screen, or walking the user through a guided step-by-step demo flow during the out-of-box setup experience are examples of such an indication.
+      </li>
+    </ul>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>[SR] are STRONGLY RECOMMENDED to not provide the input mechanism for the <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BACK">Menu function</a> as it is deprecated in favor of action bar since Android 4.0.
+      </li>
+    </ul>
+    <p>
+      If device implementations provide the Menu function, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST display the action overflow button whenever the action overflow menu popup is not empty and the action bar is visible.
+      </li>
+      <li>[C-2-2] MUST NOT modify the position of the action overflow popup displayed by selecting the overflow button in the action bar, but MAY render the action overflow popup at a modified position on the screen when it is displayed by selecting the Menu function.
+      </li>
+    </ul>
+    <p>
+      If device implementations do not provide the Menu function, for backwards compatibility, they:
+    </p>
+    <ul>
+      <li>[C-3-1] MUST make the Menu function available to applications when <code>targetSdkVersion</code> is less than 10, either by a physical button, a software key, or gestures. This Menu function should be accessible unless hidden together with other navigation functions.
+      </li>
+    </ul>
+    <p>
+      If device implementations provide the <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_ASSIST">Assist function</a>, they:
+    </p>
+    <ul>
+      <li>[C-4-1] MUST make the Assist function accessible with a single action (e.g. tap, double-click or gesture) when other navigation keys are accessible.
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to use long press on HOME function as this designated interaction.
+      </li>
+    </ul>
+    <p>
+      If device implementations use a distinct portion of the screen to display the navigation keys, they:
+    </p>
+    <ul>
+      <li>[C-5-1] Navigation keys MUST use a distinct portion of the screen, not available to applications, and MUST NOT obscure or otherwise interfere with the portion of the screen available to applications.
+      </li>
+      <li>[C-5-2] MUST make available a portion of the display to applications that meets the requirements defined in <a href="#7_1_1_screen_configuration">section 7.1.1</a>.
+      </li>
+      <li>[C-5-3] MUST honor the flags set by the app through the <a href="https://developer.android.com/reference/android/view/View.html#setSystemUiVisibility%28int%29"><code>View.setSystemUiVisibility()</code></a> API method, so that this distinct portion of the screen (a.k.a. the navigation bar) is properly hidden away as documented in the SDK.
+      </li>
+    </ul>
+    <h4 id="7_2_4_touchscreen_input">
+      7.2.4. Touchscreen Input
+    </h4>
+    <p>
+      Android includes support for a variety of pointer input systems, such as touchscreens, touch pads, and fake touch input devices. <a href="http://source.android.com/devices/tech/input/touch-devices.html">Touchscreen-based device implementations</a> are associated with a display such that the user has the impression of directly manipulating items on screen. Since the user is directly touching the screen, the system does not require any additional affordances to indicate the objects being manipulated.
+    </p>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>SHOULD have a pointer input system of some kind (either mouse-like or touch).
+      </li>
+      <li>SHOULD support fully independently tracked pointers.
+      </li>
+    </ul>
+    <p>
+      If device implementations include a touchscreen (single-touch or better), they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST report <code>TOUCHSCREEN_FINGER</code> for the <a href="https://developer.android.com/reference/android/content/res/Configuration.html#touchscreen"><code>Configuration.touchscreen</code></a> API field.
+      </li>
+      <li>[C-1-2] MUST report the <code>android.hardware.touchscreen</code> and <code>android.hardware.faketouch</code> feature flags
+      </li>
+    </ul>
+    <p>
+      If device implementations include a touchscreen that can track more than a single touch, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST report the appropriate feature flags <code>android.hardware.touchscreen.multitouch</code>, <code>android.hardware.touchscreen.multitouch.distinct</code>, <code>android.hardware.touchscreen.multitouch.jazzhand</code> corresponding to the type of the specific touchscreen on the device.
+      </li>
+    </ul>
+    <p>
+      If device implementations do not include a touchscreen (and rely on a pointer device only) and meet the fake touch requirements in <a href="#7_2_5_fake_touch_input">section 7.2.5</a>, they:
+    </p>
+    <ul>
+      <li>[C-3-1] MUST NOT report any feature flag starting with <code>android.hardware.touchscreen</code> and MUST report only <code>android.hardware.faketouch</code>.
+      </li>
+    </ul>
+    <h4 id="7_2_5_fake_touch_input">
+      7.2.5. Fake Touch Input
+    </h4>
+    <p>
+      Fake touch interface provides a user input system that approximates a subset of touchscreen capabilities. For example, a mouse or remote control that drives an on-screen cursor approximates touch, but requires the user to first point or focus then click. Numerous input devices like the mouse, trackpad, gyro-based air mouse, gyro-pointer, joystick, and multi-touch trackpad can support fake touch interactions. Android includes the feature constant android.hardware.faketouch, which corresponds to a high-fidelity non-touch (pointer-based) input device such as a mouse or trackpad that can adequately emulate touch-based input (including basic gesture support), and indicates that the device supports an emulated subset of touchscreen functionality.
+    </p>
+    <p>
+      If device implementations do not include a touchscreen but include another pointer input system which they want to make available, they:
+    </p>
+    <ul>
+      <li>SHOULD declare support for the <code>android.hardware.faketouch</code> feature flag.
+      </li>
+    </ul>
+    <p>
+      If device implementations declare support for <code>android.hardware.faketouch</code>, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST report the <a href="http://developer.android.com/reference/android/view/MotionEvent.html">absolute X and Y screen positions</a> of the pointer location and display a visual pointer on the screen.
+      </li>
+      <li>[C-1-2] MUST report touch event with the action code that specifies the state change that occurs on the pointer <a href="http://developer.android.com/reference/android/view/MotionEvent.html">going down or up on the screen</a>.
+      </li>
+      <li>[C-1-3] MUST support pointer down and up on an object on the screen, which allows users to emulate tap on an object on the screen.
+      </li>
+      <li>[C-1-4] MUST support pointer down, pointer up, pointer down then pointer up in the same place on an object on the screen within a time threshold, which allows users to <a href="http://developer.android.com/reference/android/view/MotionEvent.html">emulate double tap</a> on an object on the screen.
+      </li>
+      <li>[C-1-5] MUST support pointer down on an arbitrary point on the screen, pointer move to any other arbitrary point on the screen, followed by a pointer up, which allows users to emulate a touch drag.
+      </li>
+      <li>[C-1-6] MUST support pointer down then allow users to quickly move the object to a different position on the screen and then pointer up on the screen, which allows users to fling an object on the screen.
+      </li>
+      <li>[C-1-7] MUST report <code>TOUCHSCREEN_NOTOUCH</code> for the <a href="https://developer.android.com/reference/android/content/res/Configuration.html#touchscreen"><code>Configuration.touchscreen</code></a> API field.
+      </li>
+    </ul>
+    <p>
+      If device implementations declare support for <code>android.hardware.faketouch.multitouch.distinct</code>, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST declare support for <code>android.hardware.faketouch</code>.
+      </li>
+      <li>[C-2-2] MUST support distinct tracking of two or more independent pointer inputs.
+      </li>
+    </ul>
+    <p>
+      If device implementations declare support for <code>android.hardware.faketouch.multitouch.jazzhand</code>, they:
+    </p>
+    <ul>
+      <li>[C-3-1] MUST declare support for <code>android.hardware.faketouch</code>.
+      </li>
+      <li>[C-3-2] MUST support distinct tracking of 5 (tracking a hand of fingers) or more pointer inputs fully independently.
+      </li>
+    </ul>
+    <h4 id="7_2_6_game_controller_support">
+      7.2.6. Game Controller Support
+    </h4>
+    <h5 id="7_2_6_1_button_mappings">
+      7.2.6.1. Button Mappings
+    </h5>
+    <p>
+      If device implementations declare the <code>android.hardware.gamepad</code> feature flag, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST have embed a controller or ship with a separate controller in the box, that would provide means to input all the events listed in the below tables.
+      </li>
+      <li>[C-1-2] MUST be capable to map HID events to it's associated Android <code>view.InputEvent</code> constants as listed in the below tables. The upstream Android implementation includes implementation for game controllers that satisfies this requirement.
+      </li>
+    </ul>
+    <table>
+      <tr>
+        <th>
+          Button
+        </th>
+        <th>
+          HID Usage<sup>2</sup>
+        </th>
+        <th>
+          Android Button
+        </th>
+      </tr>
+      <tr>
+        <td>
+          <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BUTTON_A">A</a><sup>1</sup>
+        </td>
+        <td>
+          0x09 0x0001
+        </td>
+        <td>
+          KEYCODE_BUTTON_A (96)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BUTTON_B">B</a><sup>1</sup>
+        </td>
+        <td>
+          0x09 0x0002
+        </td>
+        <td>
+          KEYCODE_BUTTON_B (97)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BUTTON_X">X</a><sup>1</sup>
+        </td>
+        <td>
+          0x09 0x0004
+        </td>
+        <td>
+          KEYCODE_BUTTON_X (99)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BUTTON_Y">Y</a><sup>1</sup>
+        </td>
+        <td>
+          0x09 0x0005
+        </td>
+        <td>
+          KEYCODE_BUTTON_Y (100)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_DPAD_UP">D-pad up</a><sup>1</sup><br />
+          <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_DPAD_DOWN">D-pad down</a><sup>1</sup>
+        </td>
+        <td>
+          0x01 0x0039<sup>3</sup>
+        </td>
+        <td>
+          <a href="http://developer.android.com/reference/android/view/MotionEvent.html#AXIS_HAT_Y">AXIS_HAT_Y</a><sup>4</sup>
+        </td>
+      </tr>
+      <tr>
+        <td>
+          <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_DPAD_LEFT">D-pad left</a>1<br />
+          <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_DPAD_RIGHT">D-pad right</a><sup>1</sup>
+        </td>
+        <td>
+          0x01 0x0039<sup>3</sup>
+        </td>
+        <td>
+          <a href="http://developer.android.com/reference/android/view/MotionEvent.html#AXIS_HAT_X">AXIS_HAT_X</a><sup>4</sup>
+        </td>
+      </tr>
+      <tr>
+        <td>
+          <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BUTTON_L1">Left shoulder button</a><sup>1</sup>
+        </td>
+        <td>
+          0x09 0x0007
+        </td>
+        <td>
+          KEYCODE_BUTTON_L1 (102)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BUTTON_R1">Right shoulder button</a><sup>1</sup>
+        </td>
+        <td>
+          0x09 0x0008
+        </td>
+        <td>
+          KEYCODE_BUTTON_R1 (103)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BUTTON_THUMBL">Left stick click</a><sup>1</sup>
+        </td>
+        <td>
+          0x09 0x000E
+        </td>
+        <td>
+          KEYCODE_BUTTON_THUMBL (106)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BUTTON_THUMBR">Right stick click</a><sup>1</sup>
+        </td>
+        <td>
+          0x09 0x000F
+        </td>
+        <td>
+          KEYCODE_BUTTON_THUMBR (107)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_HOME">Home</a><sup>1</sup>
+        </td>
+        <td>
+          0x0c 0x0223
+        </td>
+        <td>
+          KEYCODE_HOME (3)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BACK">Back</a><sup>1</sup>
+        </td>
+        <td>
+          0x0c 0x0224
+        </td>
+        <td>
+          KEYCODE_BACK (4)
+        </td>
+      </tr>
+    </table>
+    <p class="table_footnote">
+      1 <a href="http://developer.android.com/reference/android/view/KeyEvent.html">KeyEvent</a>
+    </p>
+    <p class="table_footnote">
+      2 The above HID usages must be declared within a Game pad CA (0x01 0x0005).
+    </p>
+    <p class="table_footnote">
+      3 This usage must have a Logical Minimum of 0, a Logical Maximum of 7, a Physical Minimum of 0, a Physical Maximum of 315, Units in Degrees, and a Report Size of 4. The logical value is defined to be the clockwise rotation away from the vertical axis; for example, a logical value of 0 represents no rotation and the up button being pressed, while a logical value of 1 represents a rotation of 45 degrees and both the up and left keys being pressed.
+    </p>
+    <p class="table_footnote">
+      4 <a href="http://developer.android.com/reference/android/view/MotionEvent.html">MotionEvent</a>
+    </p>
+    <table>
+      <tr>
+        <th>
+          Analog Controls<sup>1</sup>
+        </th>
+        <th>
+          HID Usage
+        </th>
+        <th>
+          Android Button
+        </th>
+      </tr>
+      <tr>
+        <td>
+          <a href="http://developer.android.com/reference/android/view/MotionEvent.html#AXIS_LTRIGGER">Left Trigger</a>
+        </td>
+        <td>
+          0x02 0x00C5
+        </td>
+        <td>
+          AXIS_LTRIGGER
+        </td>
+      </tr>
+      <tr>
+        <td>
+          <a href="http://developer.android.com/reference/android/view/MotionEvent.html#AXIS_THROTTLE">Right Trigger</a>
+        </td>
+        <td>
+          0x02 0x00C4
+        </td>
+        <td>
+          AXIS_RTRIGGER
+        </td>
+      </tr>
+      <tr>
+        <td>
+          <a href="http://developer.android.com/reference/android/view/MotionEvent.html#AXIS_Y">Left Joystick</a>
+        </td>
+        <td>
+          0x01 0x0030<br />
+          0x01 0x0031
+        </td>
+        <td>
+          AXIS_X<br />
+          AXIS_Y
+        </td>
+      </tr>
+      <tr>
+        <td>
+          <a href="http://developer.android.com/reference/android/view/MotionEvent.html#AXIS_Z">Right Joystick</a>
+        </td>
+        <td>
+          0x01 0x0032<br />
+          0x01 0x0035
+        </td>
+        <td>
+          AXIS_Z<br />
+          AXIS_RZ
+        </td>
+      </tr>
+    </table>
+    <p class="table_footnote">
+      1 <a href="http://developer.android.com/reference/android/view/MotionEvent.html">MotionEvent</a>
+    </p>
+    <h4 id="7_2_7_remote_control">
+      7.2.7. Remote Control
+    </h4>
+    <p>
+      See <a href="#2_3_1_hardware">Section 2.3.1</a> for device-specific requirements.
+    </p>
+    <h3 id="7_3_sensors">
+      7.3. Sensors
+    </h3>
+    <p>
+      If device implementations include a particular sensor type that has a corresponding API for third-party developers, the device implementation MUST implement that API as described in the Android SDK documentation and the Android Open Source documentation on <a href="http://source.android.com/devices/sensors/">sensors</a>.
+    </p>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST accurately report the presence or absence of sensors per the <a href="http://developer.android.com/reference/android/content/pm/PackageManager.html"><code>android.content.pm.PackageManager</code></a> class.
+      </li>
+      <li>[C-0-2] MUST return an accurate list of supported sensors via the <code>SensorManager.getSensorList()</code> and similar methods.
+      </li>
+      <li>[C-0-3] MUST behave reasonably for all other sensor APIs (for example, by returning <code>true</code> or <code>false</code> as appropriate when applications attempt to register listeners, not calling sensor listeners when the corresponding sensors are not present; etc.).
+      </li>
+    </ul>
+    <p>
+      If device implementations include a particular sensor type that has a corresponding API for third-party developers, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST <a href="http://developer.android.com/reference/android/hardware/SensorEvent.html">report all sensor measurements</a> using the relevant International System of Units (metric) values for each sensor type as defined in the Android SDK documentation.
+      </li>
+      <li>[C-1-2] MUST report sensor data with a maximum latency of 100 milliseconds
+      </li>
+      <li>2 * sample_time for the case of a sensor streamed with a minimum required latency of 5 ms + 2 * sample_time when the application processor is active. This delay does not include any filtering delays.
+      </li>
+      <li>[C-1-3] MUST report the first sensor sample within 400 milliseconds + 2 * sample_time of the sensor being activated. It is acceptable for this sample to have an accuracy of 0.
+      </li>
+      <li>
+        <p>
+          [SR] SHOULD <a href="http://developer.android.com/reference/android/hardware/SensorEvent.html#timestamp">report the event time</a> in nanoseconds as defined in the Android SDK documentation, representing the time the event happened and synchronized with the SystemClock.elapsedRealtimeNano() clock. Existing and new Android devices are <strong>STRONGLY RECOMMENDED</strong> to meet these requirements so they will be able to upgrade to the future platform releases where this might become a REQUIRED component. The synchronization error SHOULD be below 100 milliseconds.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-1-7] For any API indicated by the Android SDK documentation to be a <a href="https://source.android.com/devices/sensors/report-modes.html#continuous">continuous sensor</a>, device implementations MUST continuously provide periodic data samples that SHOULD have a jitter below 3%, where jitter is defined as the standard deviation of the difference of the reported timestamp values between consecutive events.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-1-8] MUST ensure that the sensor event stream MUST NOT prevent the device CPU from entering a suspend state or waking up from a suspend state.
+        </p>
+      </li>
+      <li>When several sensors are activated, the power consumption SHOULD NOT exceed the sum of the individual sensor’s reported power consumption.
+      </li>
+    </ul>
+    <p>
+      The list above is not comprehensive; the documented behavior of the Android SDK and the Android Open Source Documentations on <a href="http://source.android.com/devices/sensors/">sensors</a> is to be considered authoritative.
+    </p>
+    <p>
+      Some sensor types are composite, meaning they can be derived from data provided by one or more other sensors. (Examples include the orientation sensor and the linear acceleration sensor.)
+    </p>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>SHOULD implement these sensor types, when they include the prerequisite physical sensors as described in <a href="https://source.android.com/devices/sensors/sensor-types.html">sensor types</a>.
+      </li>
+    </ul>
+    <p>
+      If device implementations include a composite sensor, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST implement the sensor as described in the Android Open Source documentation on <a href="https://source.android.com/devices/sensors/sensor-types.html#composite_sensor_type_summary">composite sensors</a>.
+      </li>
+    </ul>
+    <h4 id="7_3_1_accelerometer">
+      7.3.1. Accelerometer
+    </h4>
+    <ul>
+      <li>Device implementations SHOULD include a 3-axis accelerometer.
+      </li>
+    </ul>
+    <p>
+      If device implementations include a 3-axis accelerometer, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST be able to report events up to a frequency of at least 50 Hz.
+      </li>
+      <li>[C-1-2] MUST implement and report <a href="http://developer.android.com/reference/android/hardware/Sensor.html#TYPE_ACCELEROMETER"><code>TYPE_ACCELEROMETER</code></a> sensor.
+      </li>
+      <li>[C-1-3] MUST comply with the <a href="http://developer.android.com/reference/android/hardware/SensorEvent.html">Android sensor coordinate system</a> as detailed in the Android APIs.
+      </li>
+      <li>[C-1-4] MUST be capable of measuring from freefall up to four times the gravity(4g) or more on any axis.
+      </li>
+      <li>[C-1-5] MUST have a resolution of at least 12-bits.
+      </li>
+      <li>[C-1-6] MUST have a standard deviation no greater than 0.05 m/s^, where the standard deviation should be calculated on a per axis basis on samples collected over a period of at least 3 seconds at the fastest sampling rate.
+      </li>
+      <li>[SR] are <strong>STRONGLY RECOMMENDED</strong> to implement the <code>TYPE_SIGNIFICANT_MOTION</code> composite sensor.
+      </li>
+      <li>[SR] are STRONGLY RECOMMENDED to implement the <code>TYPE_ACCELEROMETER_UNCALIBRATED</code> sensor if online accelerometer calibration is available.
+      </li>
+      <li>SHOULD implement the <code>TYPE_SIGNIFICANT_MOTION</code>, <code>TYPE_TILT_DETECTOR</code>, <code>TYPE_STEP_DETECTOR</code>, <code>TYPE_STEP_COUNTER</code> composite sensors as described in the Android SDK document.
+      </li>
+      <li>SHOULD report events up to at least 200 Hz.
+      </li>
+      <li>SHOULD have a resolution of at least 16-bits.
+      </li>
+      <li>SHOULD be calibrated while in use if the characteristics changes over the life cycle and compensated, and preserve the compensation parameters between device reboots.
+      </li>
+      <li>SHOULD be temperature compensated.
+      </li>
+      <li>SHOULD also implement <a href="https://developer.android.com/reference/android/hardware/Sensor.html#STRING_TYPE_ACCELEROMETER_UNCALIBRATED"><code>TYPE_ACCELEROMETER_UNCALIBRATED</code></a> sensor.
+      </li>
+    </ul>
+    <p>
+      If device implementations include a 3-axis accelerometer and any of the <code>TYPE_SIGNIFICANT_MOTION</code>, <code>TYPE_TILT_DETECTOR</code>, <code>TYPE_STEP_DETECTOR</code>, <code>TYPE_STEP_COUNTER</code> composite sensors are implemented:
+    </p>
+    <ul>
+      <li>[C-2-1] The sum of their power consumption MUST always be less than 4 mW.
+      </li>
+      <li>SHOULD each be below 2 mW and 0.5 mW for when the device is in a dynamic or static condition.
+      </li>
+    </ul>
+    <p>
+      If device implementations include a 3-axis accelerometer and a gyroscope sensor, they:
+    </p>
+    <ul>
+      <li>[C-3-1] MUST implement the <code>TYPE_GRAVITY</code> and <code>TYPE_LINEAR_ACCELERATION</code> composite sensors.
+      </li>
+      <li>SHOULD implement the <code>TYPE_GAME_ROTATION_VECTOR</code> composite sensor.
+      </li>
+      <li>[SR] Existing and new Android devices are STRONGLY RECOMMENDED to implement the <code>TYPE_GAME_ROTATION_VECTOR</code> sensor.
+      </li>
+    </ul>
+    <p>
+      If device implementations include a 3-axis accelerometer, a gyroscope sensor and a magnetometer sensor, they:
+    </p>
+    <ul>
+      <li>[C-4-1] MUST implement a <code>TYPE_ROTATION_VECTOR</code> composite sensor.
+      </li>
+    </ul>
+    <h4 id="7_3_2_magnetometer">
+      7.3.2. Magnetometer
+    </h4>
+    <ul>
+      <li>Device implementations SHOULD include a 3-axis magnetometer (compass).
+      </li>
+    </ul>
+    <p>
+      If device impelementations include a 3-axis magnetometer, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST implement the <code>TYPE_MAGNETIC_FIELD</code> sensor.
+      </li>
+      <li>[C-1-2] MUST be able to report events up to a frequency of at least 10 Hz and SHOULD report events up to at least 50 Hz.
+      </li>
+      <li>[C-1-3] MUST comply with the <a href="http://developer.android.com/reference/android/hardware/SensorEvent.html">Android sensor coordinate system</a> as detailed in the Android APIs.
+      </li>
+      <li>[C-1-4] MUST be capable of measuring between -900 µT and +900 µT on each axis before saturating.
+      </li>
+      <li>[C-1-5] MUST have a hard iron offset value less than 700 µT and SHOULD have a value below 200 µT, by placing the magnetometer far from dynamic (current-induced) and static (magnet-induced) magnetic fields.
+      </li>
+      <li>[C-1-6] MUST have a resolution equal or denser than 0.6 µT.
+      </li>
+      <li>[C-1-7] MUST support online calibration and compensation of the hard iron bias, and preserve the compensation parameters between device reboots.
+      </li>
+      <li>[C-1-8] MUST have the soft iron compensation applied—the calibration can be done either while in use or during the production of the device.
+      </li>
+      <li>[C-1-9] MUST have a standard deviation, calculated on a per axis basis on samples collected over a period of at least 3 seconds at the fastest sampling rate, no greater than 1.5 µT; SHOULD have a standard deviation no greater than 0.5 µT.
+      </li>
+      <li>SHOULD implement <code>TYPE_MAGNETIC_FIELD_UNCALIBRATED</code> sensor.
+      </li>
+      <li>[SR] Existing and new Android devices are STRONGLY RECOMMENDED to implement the <code>TYPE_MAGNETIC_FIELD_UNCALIBRATED</code> sensor.
+      </li>
+    </ul>
+    <p>
+      If device impelementations include a 3-axis magnetometer, an accelerometer sensor and a gyroscope sensor, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST implement a <code>TYPE_ROTATION_VECTOR</code> composite sensor.
+      </li>
+    </ul>
+    <p>
+      If device impelementations include a 3-axis magnetometer, an accelerometer, they:
+    </p>
+    <ul>
+      <li>MAY implement the <code>TYPE_GEOMAGNETIC_ROTATION_VECTOR</code> sensor.
+      </li>
+    </ul>
+    <p>
+      If device impelementations include a 3-axis magnetometer, an accelerometer and <code>TYPE_GEOMAGNETIC_ROTATION_VECTOR</code> sensor, they:
+    </p>
+    <ul>
+      <li>[C-3-1] MUST consume less than 10 mW.
+      </li>
+      <li>SHOULD consume less than 3 mW when the sensor is registered for batch mode at 10 Hz.
+      </li>
+    </ul>
+    <h4 id="7_3_3_gps">
+      7.3.3. GPS
+    </h4>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>SHOULD include a GPS/GNSS receiver.
+      </li>
+    </ul>
+    <p>
+      If device implementations include a GPS/GNSS receiver and report the capability to applications through the <code>android.hardware.location.gps</code> feature flag, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support location outputs at a rate of at least 1 Hz when requested via <code>LocationManager#requestLocationUpdate</code>.
+      </li>
+      <li>[C-1-2] MUST be able to determine the location in open-sky conditions (strong signals, negligible multipath, HDOP &lt; 2) within 10 seconds (fast time to first fix), when connected to a 0.5 Mbps or faster data speed internet connection. This requirement is typically met by the use of some form of Assisted or Predicted GPS/GNSS technique to minimize GPS/GNSS lock-on time (Assistance data includes Reference Time, Reference Location and Satellite Ephemeris/Clock).
+        <ul>
+          <li>[SR] After making such a location calculation, it is STRONGLY RECOMMENDED for the device to be able to determine its location, in open sky, within 10 seconds, when location requests are restarted, up to an hour after the initial location calculation, even when the subsequent request is made without a data connection, and/or after a power cycle.
+          </li>
+        </ul>
+      </li>
+      <li>
+        <p>
+          In open sky conditions after determining the location, while stationary or moving with less than 1 meter per second squared of acceleration:
+        </p>
+        <ul>
+          <li>[C-1-3] MUST be able to determine location within 20 meters, and speed within 0.5 meters per second, at least 95% of the time.
+          </li>
+          <li>[C-1-4] MUST simultaneously track and report via <a href="https://developer.android.com/reference/android/location/GnssStatus.Callback.html#GnssStatus.Callback()'"><code>GnssStatus.Callback</code></a> at least 8 satellites from one constellation.
+          </li>
+          <li>SHOULD be able to simultaneously track at least 24 satellites, from multiple constellations (e.g. GPS + at least one of Glonass, Beidou, Galileo).
+          </li>
+          <li>[C-1-5] MUST report the GNSS technology generation through the test API ‘getGnssYearOfHardware’.
+          </li>
+          <li>[SR] Continue to deliver normal GPS/GNSS location outputs during an emergency phone call.
+          </li>
+          <li>[SR] Report GNSS measurements from all constellations tracked (as reported in GnssStatus messages), with the exception of SBAS.
+          </li>
+          <li>[SR] Report AGC, and Frequency of GNSS measurement.
+          </li>
+          <li>[SR] Report all accuracy estimates (including Bearing, Speed, and Vertical) as part of each GPS Location.
+          </li>
+          <li>[SR] are STRONGLY RECOMMENDED to meet as many as possible from the additional mandatory requirements for devices reporting the year "2016" or "2017" through the Test API <code>LocationManager.getGnssYearOfHardware()</code>.
+          </li>
+        </ul>
+      </li>
+    </ul>
+    <p>
+      If device implementations include a GPS/GNSS receiver and report the capability to applications through the <code>android.hardware.location.gps</code> feature flag and the <code>LocationManager.getGnssYearOfHardware()</code> Test API reports the year "2016" or newer, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST report GPS measurements, as soon as they are found, even if a location calculated from GPS/GNSS is not yet reported.
+      </li>
+      <li>[C-2-2] MUST report GPS pseudoranges and pseudorange rates, that, in open-sky conditions after determining the location, while stationary or moving with less than 0.2 meter per second squared of acceleration, are sufficient to calculate position within 20 meters, and speed within 0.2 meters per second, at least 95% of the time.
+      </li>
+    </ul>
+    <p>
+      If device implementations include a GPS/GNSS receiver and report the capability to applications through the <code>android.hardware.location.gps</code> feature flag and the <code>LocationManager.getGnssYearOfHardware()</code> Test API reports the year "2017" or newer, they:
+    </p>
+    <ul>
+      <li>[C-3-1] MUST continue to deliver normal GPS/GNSS location outputs during an emergency phone call.
+      </li>
+      <li>[C-3-2] MUST report GNSS measurements from all constellations tracked (as reported in GnssStatus messages), with the exception of SBAS.
+      </li>
+      <li>[C-3-3] MUST report AGC, and Frequency of GNSS measurement.
+      </li>
+      <li>[C-3-4] MUST report all accuracy estimates (including Bearing, Speed, and Vertical) as part of each GPS Location.
+      </li>
+    </ul>
+    <h4 id="7_3_4_gyroscope">
+      7.3.4. Gyroscope
+    </h4>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>SHOULD include a gyroscope (angular change sensor).
+      </li>
+      <li>SHOULD NOT include a gyroscope sensor unless a 3-axis accelerometer is also included.
+      </li>
+    </ul>
+    <p>
+      If device implementations include a gyroscope, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST be able to report events up to a frequency of at least 50 Hz.
+      </li>
+      <li>[C-1-2] MUST implement the <code>TYPE_GYROSCOPE</code> sensor and SHOULD also implement <code>TYPE_GYROSCOPE_UNCALIBRATED</code> sensor.
+      </li>
+      <li>[C-1-3] MUST be capable of measuring orientation changes up to 1,000 degrees per second.
+      </li>
+      <li>[C-1-4] MUST have a resolution of 12-bits or more and SHOULD have a resolution of 16-bits or more.
+      </li>
+      <li>[C-1-5] MUST be temperature compensated.
+      </li>
+      <li>[C-1-6] MUST be calibrated and compensated while in use, and preserve the compensation parameters between device reboots.
+      </li>
+      <li>[C-1-7] MUST have a variance no greater than 1e-7 rad^2 / s^2 per Hz (variance per Hz, or rad^2 / s). The variance is allowed to vary with the sampling rate, but MUST be constrained by this value. In other words, if you measure the variance of the gyro at 1 Hz sampling rate it SHOULD be no greater than 1e-7 rad^2/s^2.
+      </li>
+      <li>[SR] Existing and new Android devices are STRONGLY RECOMMENDED to implement the <code>SENSOR_TYPE_GYROSCOPE_UNCALIBRATED</code> sensor.
+      </li>
+      <li>[SR] Calibration error is STRONGLY RECOMMENDED to be less than 0.01 rad/s when device is stationary at room temperature.
+      </li>
+      <li>SHOULD report events up to at least 200 Hz.
+      </li>
+    </ul>
+    <p>
+      If device implementations include a gyroscope, an accelerometer sensor and a magnetometer sensor, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST implement a <code>TYPE_ROTATION_VECTOR</code> composite sensor.
+      </li>
+    </ul>
+    <p>
+      If device implementations include a gyroscope and a accelerometer sensor, they:
+    </p>
+    <ul>
+      <li>[C-3-1] MUST implement the <code>TYPE_GRAVITY</code> and <code>TYPE_LINEAR_ACCELERATION</code> composite sensors.
+      </li>
+      <li>[SR] Existing and new Android devices are STRONGLY RECOMMENDED to implement the <code>TYPE_GAME_ROTATION_VECTOR</code> sensor.
+      </li>
+      <li>SHOULD implement the <code>TYPE_GAME_ROTATION_VECTOR</code> composite sensor.
+      </li>
+    </ul>
+    <h4 id="7_3_5_barometer">
+      7.3.5. Barometer
+    </h4>
+    <ul>
+      <li>Device implementations SHOULD include a barometer (ambient air pressure sensor).
+      </li>
+    </ul>
+    <p>
+      If device implementations include a barometer, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST implement and report <code>TYPE_PRESSURE</code> sensor.
+      </li>
+      <li>[C-1-2] MUST be able to deliver events at 5 Hz or greater.
+      </li>
+      <li>[C-1-3] MUST be temperature compensated.
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to be able to report pressure measurements in the range 300hPa to 1100hPa.
+      </li>
+      <li>SHOULD have an absolute accuracy of 1hPa.
+      </li>
+      <li>SHOULD have a relative accuracy of 0.12hPa over 20hPa range (equivalent to ~1m accuracy over ~200m change at sea level).
+      </li>
+    </ul>
+    <h4 id="7_3_6_thermometer">
+      7.3.6. Thermometer
+    </h4>
+    <p>
+      Device implementations: <em>MAY include an ambient thermometer (temperature sensor).</em> MAY but SHOULD NOT include a CPU temperature sensor.
+    </p>
+    <p>
+      If device implementations include an ambient thermometer (temperature sensor), they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST be defined as <code>SENSOR_TYPE_AMBIENT_TEMPERATURE</code> and MUST measure the ambient (room/vehicle cabin) temperature from where the user is interacting with the device in degrees Celsius.
+      </li>
+      <li>[C-1-2] MUST be defined as <code>SENSOR_TYPE_TEMPERATURE</code>.
+      </li>
+      <li>[C-1-3] MUST measure the temperature of the device CPU.
+      </li>
+      <li>[C-1-4] MUST NOT measure any other temperature.
+      </li>
+    </ul>
+    <p>
+      Note the <code>SENSOR_TYPE_TEMPERATURE</code> sensor type was deprecated in Android 4.0.
+    </p>
+    <h4 id="7_3_7_photometer">
+      7.3.7. Photometer
+    </h4>
+    <ul>
+      <li>Device implementations MAY include a photometer (ambient light sensor).
+      </li>
+    </ul>
+    <h4 id="7_3_8_proximity_sensor">
+      7.3.8. Proximity Sensor
+    </h4>
+    <ul>
+      <li>Device implementations MAY include a proximity sensor.
+      </li>
+    </ul>
+    <p>
+      If device implementations include a proximity sensor, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST measure the proximity of an object in the same direction as the screen. That is, the proximity sensor MUST be oriented to detect objects close to the screen, as the primary intent of this sensor type is to detect a phone in use by the user. If device implementations include a proximity sensor with any other orientation, it MUST NOT be accessible through this API.
+      </li>
+      <li>[C-1-2] MUST have 1-bit of accuracy or more.
+      </li>
+    </ul>
+    <h4 id="7_3_9_high_fidelity_sensors">
+      7.3.9. High Fidelity Sensors
+    </h4>
+    <p>
+      If device implementations include a set of higher quality sensors as defined in this section, and make available them to third-party apps, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST identify the capability through the <code>android.hardware.sensor.hifi_sensors</code> feature flag.
+      </li>
+    </ul>
+    <p>
+      If device implementations declare <code>android.hardware.sensor.hifi_sensors</code>, they:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-2-1] MUST have a <code>TYPE_ACCELEROMETER</code> sensor which:
+        </p>
+        <ul>
+          <li>MUST have a measurement range between at least -8g and +8g.
+          </li>
+          <li>MUST have a measurement resolution of at least 1024 LSB/G.
+          </li>
+          <li>MUST have a minimum measurement frequency of 12.5 Hz or lower.
+          </li>
+          <li>MUST have a maximum measurement frequency of 400 Hz or higher.
+          </li>
+          <li>MUST have a measurement noise not above 400 uG/√Hz.
+          </li>
+          <li>MUST implement a non-wake-up form of this sensor with a buffering capability of at least 3000 sensor events.
+          </li>
+          <li>MUST have a batching power consumption not worse than 3 mW.
+          </li>
+          <li>SHOULD have a stationary noise bias stability of \&lt;15 μg √Hz from 24hr static dataset.
+          </li>
+          <li>SHOULD have a bias change vs. temperature of ≤ +/- 1mg / °C.
+          </li>
+          <li>SHOULD have a best-fit line non-linearity of ≤ 0.5%, and sensitivity change vs. temperature of ≤ 0.03%/C°.
+          </li>
+          <li>SHOULD have white noise spectrum to ensure adequate qualification of sensor’s noise integrity.
+          </li>
+        </ul>
+      </li>
+      <li>
+        <p>
+          [C-2-2] MUST have a <code>TYPE_ACCELEROMETER_UNCALIBRATED</code> with the same quality requirements as <code>TYPE_ACCELEROMETER</code>.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-2-3] MUST have a <code>TYPE_GYROSCOPE</code> sensor which:
+        </p>
+        <ul>
+          <li>MUST have a measurement range between at least -1000 and +1000 dps.
+          </li>
+          <li>MUST have a measurement resolution of at least 16 LSB/dps.
+          </li>
+          <li>MUST have a minimum measurement frequency of 12.5 Hz or lower.
+          </li>
+          <li>MUST have a maximum measurement frequency of 400 Hz or higher.
+          </li>
+          <li>MUST have a measurement noise not above 0.014°/s/√Hz.
+          </li>
+          <li>SHOULD have a stationary bias stability of &lt; 0.0002 °/s √Hz from 24-hour static dataset.
+          </li>
+          <li>SHOULD have a bias change vs. temperature of ≤ +/- 0.05 °/ s / °C.
+          </li>
+          <li>SHOULD have a sensitivity change vs. temperature of ≤ 0.02% / °C.
+          </li>
+          <li>SHOULD have a best-fit line non-linearity of ≤ 0.2%.
+          </li>
+          <li>SHOULD have a noise density of ≤ 0.007 °/s/√Hz.
+          </li>
+          <li>SHOULD have white noise spectrum to ensure adequate qualification of sensor’s noise integrity.
+          </li>
+          <li>SHOULD have calibration error less than 0.002 rad/s in temperature range 10 ~ 40 ℃ when device is stationary.
+          </li>
+        </ul>
+      </li>
+      <li>
+        <p>
+          [C-2-4] MUST have a <code>TYPE_GYROSCOPE_UNCALIBRATED</code> with the same quality requirements as <code>TYPE_GYROSCOPE</code>.
+        </p>
+      </li>
+      <li>[C-2-5] MUST have a <code>TYPE_GEOMAGNETIC_FIELD</code> sensor which:
+        <ul>
+          <li>MUST have a measurement range between at least -900 and +900 uT.
+          </li>
+          <li>MUST have a measurement resolution of at least 5 LSB/uT.
+          </li>
+          <li>MUST have a minimum measurement frequency of 5 Hz or lower.
+          </li>
+          <li>MUST have a maximum measurement frequency of 50 Hz or higher.
+          </li>
+          <li>MUST have a measurement noise not above 0.5 uT.
+          </li>
+        </ul>
+      </li>
+      <li>[C-2-6] MUST have a <code>TYPE_MAGNETIC_FIELD_UNCALIBRATED</code> with the same quality requirements as <code>TYPE_GEOMAGNETIC_FIELD</code> and in addition:
+        <ul>
+          <li>MUST implement a non-wake-up form of this sensor with a buffering capability of at least 600 sensor events.
+          </li>
+          <li>SHOULD have white noise spectrum to ensure adequate qualification of sensor’s noise integrity.
+          </li>
+        </ul>
+      </li>
+      <li>[C-2-7] MUST have a <code>TYPE_PRESSURE</code> sensor which:
+        <ul>
+          <li>MUST have a measurement range between at least 300 and 1100 hPa.
+          </li>
+          <li>MUST have a measurement resolution of at least 80 LSB/hPa.
+          </li>
+          <li>MUST have a minimum measurement frequency of 1 Hz or lower.
+          </li>
+          <li>MUST have a maximum measurement frequency of 10 Hz or higher.
+          </li>
+          <li>MUST have a measurement noise not above 2 Pa/√Hz.
+          </li>
+          <li>MUST implement a non-wake-up form of this sensor with a buffering capability of at least 300 sensor events.
+          </li>
+          <li>MUST have a batching power consumption not worse than 2 mW.
+          </li>
+        </ul>
+      </li>
+      <li>[C-2-8] MUST have a <code>TYPE_GAME_ROTATION_VECTOR</code> sensor which:
+        <ul>
+          <li>MUST implement a non-wake-up form of this sensor with a buffering capability of at least 300 sensor events.
+          </li>
+          <li>MUST have a batching power consumption not worse than 4 mW.
+          </li>
+        </ul>
+      </li>
+      <li>[C-2-9] MUST have a <code>TYPE_SIGNIFICANT_MOTION</code> sensor which:
+        <ul>
+          <li>MUST have a power consumption not worse than 0.5 mW when device is static and 1.5 mW when device is moving.
+          </li>
+        </ul>
+      </li>
+      <li>[C-2-10] MUST have a <code>TYPE_STEP_DETECTOR</code> sensor which:
+        <ul>
+          <li>MUST implement a non-wake-up form of this sensor with a buffering capability of at least 100 sensor events.
+          </li>
+          <li>MUST have a power consumption not worse than 0.5 mW when device is static and 1.5 mW when device is moving.
+          </li>
+          <li>MUST have a batching power consumption not worse than 4 mW.
+          </li>
+        </ul>
+      </li>
+      <li>[C-2-11] MUST have a <code>TYPE_STEP_COUNTER</code> sensor which:
+        <ul>
+          <li>MUST have a power consumption not worse than 0.5 mW when device is static and 1.5 mW when device is moving.
+          </li>
+        </ul>
+      </li>
+      <li>[C-2-12] MUST have a <code>TILT_DETECTOR</code> sensor which:
+        <ul>
+          <li>MUST have a power consumption not worse than 0.5 mW when device is static and 1.5 mW when device is moving.
+          </li>
+        </ul>
+      </li>
+      <li>[C-2-13] The event timestamp of the same physical event reported by the Accelerometer, Gyroscope sensor and Magnetometer MUST be within 2.5 milliseconds of each other.
+      </li>
+      <li>[C-2-14] MUST have Gyroscope sensor event timestamps on the same time base as the camera subsystem and within 1 milliseconds of error.
+      </li>
+      <li>[C-2-15] MUST deliver samples to applications within 5 milliseconds from the time when the data is available on any of the above physical sensors to the application.
+      </li>
+      <li>[C-2-16] MUST not have a power consumption higher than 0.5 mW when device is static and 2.0 mW when device is moving when any combination of the following sensors are enabled:
+        <ul>
+          <li>
+            <code>SENSOR_TYPE_SIGNIFICANT_MOTION</code>
+          </li>
+          <li>
+            <code>SENSOR_TYPE_STEP_DETECTOR</code>
+          </li>
+          <li>
+            <code>SENSOR_TYPE_STEP_COUNTER</code>
+          </li>
+          <li>
+            <code>SENSOR_TILT_DETECTORS</code>
+          </li>
+        </ul>
+      </li>
+      <li>[C-2-17] MAY have a <code>TYPE_PROXIMITY</code> sensor, but if present MUST have a minimum buffer capability of 100 sensor events.
+      </li>
+    </ul>
+    <p>
+      Note that all power consumption requirements in this section do not include the power consumption of the Application Processor. It is inclusive of the power drawn by the entire sensor chain—the sensor, any supporting circuitry, any dedicated sensor processing system, etc.
+    </p>
+    <p>
+      If device implementations include direct sensor support, they:
+    </p>
+    <ul>
+      <li>[C-3-1] MUST correctly declare support of direct channel types and direct report rates level through the <a href="https://developer.android.com/reference/android/hardware/Sensor.html#isDirectChannelTypeSupported%28int%29"><code>isDirectChannelTypeSupported</code></a> and <a href="https://developer.android.com/reference/android/hardware/Sensor.html#getHighestDirectReportRateLevel%28%29"><code>getHighestDirectReportRateLevel</code></a> API.
+      </li>
+      <li>[C-3-2] MUST support at least one of the two sensor direct channel types for all sensors that declare support for sensor direct channel:
+        <ul>
+          <li>
+            <a href="https://developer.android.com/reference/android/hardware/SensorDirectChannel.html#TYPE_HARDWARE_BUFFER"><code>TYPE_HARDWARE_BUFFER</code></a>
+          </li>
+          <li>
+            <a href="https://developer.android.com/reference/android/hardware/SensorDirectChannel.html#TYPE_MEMORY_FILE"><code>TYPE_MEMORY_FILE</code></a>
+          </li>
+        </ul>
+      </li>
+      <li>SHOULD support event reporting through sensor direct channel for primary sensor (non-wakeup variant) of the following types:
+        <ul>
+          <li>
+            <code>TYPE_ACCELEROMETER</code>
+          </li>
+          <li>
+            <code>TYPE_ACCELEROMETER_UNCALIBRATED</code>
+          </li>
+          <li>
+            <code>TYPE_GYROSCOPE</code>
+          </li>
+          <li>
+            <code>TYPE_GYROSCOPE_UNCALIBRATED</code>
+          </li>
+          <li>
+            <code>TYPE_MAGNETIC_FIELD</code>
+          </li>
+          <li>
+            <code>TYPE_MAGNETIC_FIELD_UNCALIBRATED</code>
+          </li>
+        </ul>
+      </li>
+    </ul>
+    <h4 id="7_3_10_fingerprint_sensor">
+      7.3.10. Fingerprint Sensor
+    </h4>
+    <p>
+      If device implementations include a secure lock screen, they:
+    </p>
+    <ul>
+      <li>SHOULD include a fingerprint sensor.
+      </li>
+    </ul>
+    <p>
+      If device implementations include a fingerprint sensor and make the sensor available to third-party apps, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST declare support for the <code>android.hardware.fingerprint</code> feature.
+      </li>
+      <li>[C-1-2] MUST fully implement the <a href="https://developer.android.com/reference/android/hardware/fingerprint/package-summary.html">corresponding API</a> as described in the Android SDK documentation.
+      </li>
+      <li>[C-1-3] MUST have a false acceptance rate not higher than 0.002%.
+      </li>
+      <li>[C-1-4] MUST rate limit attempts for at least 30 seconds after five false trials for fingerprint verification.
+      </li>
+      <li>[C-1-5] MUST have a hardware-backed keystore implementation, and perform the fingerprint matching in a Trusted Execution Environment (TEE) or on a chip with a secure channel to the TEE.
+      </li>
+      <li>[C-1-6] MUST have all identifiable fingerprint data encrypted and cryptographically authenticated such that they cannot be acquired, read or altered outside of the Trusted Execution Environment (TEE) as documented in the <a href="https://source.android.com/devices/tech/security/authentication/fingerprint-hal.html">implementation guidelines</a> on the Android Open Source Project site.
+      </li>
+      <li>[C-1-7] MUST prevent adding a fingerprint without first establishing a chain of trust by having the user confirm existing or add a new device credential (PIN/pattern/password) that's secured by TEE; the Android Open Source Project implementation provides the mechanism in the framework to do so.
+      </li>
+      <li>[C-1-8] MUST NOT enable 3rd-party applications to distinguish between individual fingerprints.
+      </li>
+      <li>[C-1-9] MUST honor the DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT flag.
+      </li>
+      <li>[C-1-10] MUST, when upgraded from a version earlier than Android 6.0, have the fingerprint data securely migrated to meet the above requirements or removed.
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to have a false rejection rate of less than 10%, as measured on the device.
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to have a latency below 1 second, measured from when the fingerprint sensor is touched until the screen is unlocked, for one enrolled finger.
+      </li>
+      <li>SHOULD use the Android Fingerprint icon provided in the Android Open Source Project.
+      </li>
+    </ul>
+    <h4 id="7_3_11_android_automotive-only_sensors">
+      7.3.11. Android Automotive-only sensors
+    </h4>
+    <p>
+      Automotive-specific sensors are defined in the <code>android.car.CarSensorManager API</code>.
+    </p>
+    <h5 id="7_3_11_1_current_gear">
+      7.3.11.1. Current Gear
+    </h5>
+    <p>
+      See <a href="#2_5_1_hardware">Section 2.5.1</a> for device-specific requirements.
+    </p>
+    <h5 id="7_3_11_2_day_night_mode">
+      7.3.11.2. Day Night Mode
+    </h5>
+    <p>
+      See <a href="#2_5_1_hardware">Section 2.5.1</a> for device-specific requirements.
+    </p>
+    <h5 id="7_3_11_3_driving_status">
+      7.3.11.3. Driving Status
+    </h5>
+    <p>
+      See <a href="#2_5_1_hardware">Section 2.5.1</a> for device-specific requirements.
+    </p>
+    <h5 id="7_3_11_4_wheel_speed">
+      7.3.11.4. Wheel Speed
+    </h5>
+    <p>
+      See <a href="#2_5_1_hardware">Section 2.5.1</a> for device-specific requirements.
+    </p>
+    <h3 id="7_3_12_pose_sensor">
+      7.3.12. Pose Sensor
+    </h3>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>MAY support pose sensor with 6 degrees of freedom.
+      </li>
+    </ul>
+    <p>
+      If device implementations support pose sensor with 6 degrees of freedom, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST implement and report <a href="https://developer.android.com/reference/android/hardware/Sensor.html#TYPE_POSE_6DOF"><code>TYPE_POSE_6DOF</code></a> sensor.
+      </li>
+      <li>[C-1-2] MUST be more accurate than the rotation vector alone.
+      </li>
+    </ul>
+    <h3 id="7_4_data_connectivity">
+      7.4. Data Connectivity
+    </h3>
+    <h4 id="7_4_1_telephony">
+      7.4.1. Telephony
+    </h4>
+    <p>
+      “Telephony” as used by the Android APIs and this document refers specifically to hardware related to placing voice calls and sending SMS messages via a GSM or CDMA network. While these voice calls may or may not be packet-switched, they are for the purposes of Android considered independent of any data connectivity that may be implemented using the same network. In other words, the Android “telephony” functionality and APIs refer specifically to voice calls and SMS. For instance, device implementations that cannot place calls or send/receive SMS messages are not considered a telephony device, regardless of whether they use a cellular network for data connectivity.
+    </p>
+    <ul>
+      <li>Android MAY be used on devices that do not include telephony hardware. That is, Android is compatible with devices that are not phones.
+      </li>
+    </ul>
+    <p>
+      If device implementations include GSM or CDMA telephony, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST declare the <code>android.hardware.telephony</code> feature flag and other sub-feature flags according to the technology.
+      </li>
+      <li>[C-1-2] MUST implement full support for the API for that technology.
+      </li>
+    </ul>
+    <p>
+      If device implementations do not include telephony hardware, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST implement the full APIs as no-ops.
+      </li>
+    </ul>
+    <h5 id="7_4_1_1_number_blocking_compatibility">
+      7.4.1.1. Number Blocking Compatibility
+    </h5>
+    <p>
+      If device implementations report the <code>android.hardware.telephony feature</code>, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST include number blocking support
+      </li>
+      <li>[C-1-2] MUST fully implement <a href="http://developer.android.com/reference/android/provider/BlockedNumberContract.html"><code>BlockedNumberContract</code></a> and the corresponding API as described in the SDK documentation.
+      </li>
+      <li>[C-1-3] MUST block all calls and messages from a phone number in 'BlockedNumberProvider' without any interaction with apps. The only exception is when number blocking is temporarily lifted as described in the SDK documentation.
+      </li>
+      <li>[C-1-4] MUST NOT write to the <a href="http://developer.android.com/reference/android/provider/CallLog.html">platform call log provider</a> for a blocked call.
+      </li>
+      <li>[C-1-5] MUST NOT write to the <a href="http://developer.android.com/reference/android/provider/Telephony.html">Telephony provider</a> for a blocked message.
+      </li>
+      <li>[C-1-6] MUST implement a blocked numbers management UI, which is opened with the intent returned by <code>TelecomManager.createManageBlockedNumbersIntent()</code> method.
+      </li>
+      <li>[C-1-7] MUST NOT allow secondary users to view or edit the blocked numbers on the device as the Android platform assumes the primary user to have full control of the telephony services, a single instance, on the device. All blocking related UI MUST be hidden for secondary users and the blocked list MUST still be respected.
+      </li>
+      <li>SHOULD migrate the blocked numbers into the provider when a device updates to Android 7.0.
+      </li>
+    </ul>
+    <h4 id="7_4_2_ieee_802_11_(wi-fi)">
+      7.4.2. IEEE 802.11 (Wi-Fi)
+    </h4>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>SHOULD include support for one or more forms of 802.11.
+      </li>
+    </ul>
+    <p>
+      If device implementations include support for 802.11 and expose the functionality to a third-party application, they
+    </p>
+    <ul>
+      <li>[C-1-1] MUST implement the corresponding Android API.
+      </li>
+      <li>[C-1-2] MUST report the hardware feature flag <code>android.hardware.wifi</code>.
+      </li>
+      <li>[C-1-3] MUST implement the <a href="http://developer.android.com/reference/android/net/wifi/WifiManager.MulticastLock.html">multicast API</a> as described in the SDK documentation.
+      </li>
+      <li>[C-1-4] MUST support multicast DNS (mDNS) and MUST NOT filter mDNS packets (224.0.0.251) at any time of operation including:
+        <ul>
+          <li>Even when the screen is not in an active state.
+          </li>
+          <li>For Android Television device implementations, even when in standby power states.
+          </li>
+        </ul>
+      </li>
+      <li>SHOULD randomize the source MAC address and sequence number of probe request frames, once at the beginning of each scan, while STA is disconnected.
+        <ul>
+          <li>Each group of probe request frames comprising one scan should use one consistent MAC address (SHOULD NOT randomize MAC address halfway through a scan).
+          </li>
+          <li>Probe request sequence number should iterate as normal (sequentially) between the probe requests in a scan
+          </li>
+          <li>Probe request sequence number should randomize between the last probe request of a scan and the first probe request of the next scan
+          </li>
+        </ul>
+      </li>
+      <li>SHOULD only allow the following information elements in probe request frames, while STA is disconnected:
+        <ul>
+          <li>SSID Parameter Set (0)
+          </li>
+          <li>DS Parameter Set (3)
+          </li>
+        </ul>
+      </li>
+    </ul>
+    <h5 id="7_4_2_1_wi-fi_direct">
+      7.4.2.1. Wi-Fi Direct
+    </h5>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>SHOULD include support for Wi-Fi Direct (Wi-Fi peer-to-peer).
+      </li>
+    </ul>
+    <p>
+      If device implementations include support for Wi-Fi Direct, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST implement the <a href="http://developer.android.com/reference/android/net/wifi/p2p/WifiP2pManager.html">corresponding Android API</a> as described in the SDK documentation.
+      </li>
+      <li>[C-1-2] MUST report the hardware feature <code>android.hardware.wifi.direct</code>.
+      </li>
+      <li>[C-1-3] MUST support regular Wi-Fi operation.
+      </li>
+      <li>SHOULD support Wi-Fi and Wi-Fi Direct operations concurrently.
+      </li>
+    </ul>
+    <h5 id="7_4_2_2_wi-fi_tunneled_direct_link_setup">
+      7.4.2.2. Wi-Fi Tunneled Direct Link Setup
+    </h5>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>SHOULD include support for <a href="http://developer.android.com/reference/android/net/wifi/WifiManager.html">Wi-Fi Tunneled Direct Link Setup (TDLS)</a> as described in the Android SDK Documentation.
+      </li>
+    </ul>
+    <p>
+      If device implementations include support for TDLS and TDLS is enabled by the WiFiManager API, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST declare support for TDLS through [<code>WifiManager.isTdlsSupported</code>] (https://developer.android.com/reference/android/net/wifi/WifiManager.html#isTdlsSupported%28%29).
+      </li>
+      <li>SHOULD use TDLS only when it is possible AND beneficial.
+      </li>
+      <li>SHOULD have some heuristic and NOT use TDLS when its performance might be worse than going through the Wi-Fi access point.
+      </li>
+    </ul>
+    <h5 id="7_4_2_3_wi-fi_aware">
+      7.4.2.3. Wi-Fi Aware
+    </h5>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>SHOULD include support for <a href="http://www.wi-fi.org/discover-wi-fi/wi-fi-aware">Wi-Fi Aware</a>.
+      </li>
+    </ul>
+    <p>
+      If device implementations include support for Wi-Fi Aware and expose the functionality to third-party apps, then they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST implement the <code>WifiAwareManager</code> APIs as described in the <a href="http://developer.android.com/reference/android/net/wifi/aware/WifiAwareManager.html">SDK documentation</a>.
+      </li>
+      <li>[C-1-2] MUST declare the <code>android.hardware.wifi.aware</code> feature flag.
+      </li>
+      <li>[C-1-3] MUST support Wi-Fi and Wi-Fi Aware operations concurrently.
+      </li>
+      <li>[C-1-4] MUST randomize the Wi-Fi Aware management interface address at intervals no longer then 30 minutes and whenever Wi-Fi Aware is enabled.
+      </li>
+    </ul>
+    <h5 id="7_4_2_4_wi-fi_passpoint">
+      7.4.2.4. Wi-Fi Passpoint
+    </h5>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>SHOULD include support for <a href="http://www.wi-fi.org/discover-wi-fi/wi-fi-certified-passpoint">Wi-Fi Passpoint</a>.
+      </li>
+    </ul>
+    <p>
+      If device implementations include support for Wi-Fi Passpoint, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST implement the Passpoint related <code>WifiManager</code> APIs as described in the <a href="http://developer.android.com/reference/android/net/wifi/WifiManager.html">SDK documentation</a>.
+      </li>
+      <li>[C-1-2] MUST support IEEE 802.11u standard, specifically related to Network Discovery and Selection, such as Generic Advertisement Service (GAS) and Access Network Query Protocol (ANQP).
+      </li>
+    </ul>
+    <p>
+      Conversely if device implementations do not include support for Wi-Fi Passpoint:
+    </p>
+    <ul>
+      <li>[C-2-1] The implementation of the Passpoint related <code>WifiManager</code> APIs MUST throw an <code>UnsupportedOperationException</code>.
+      </li>
+    </ul>
+    <h4 id="7_4_3_bluetooth">
+      7.4.3. Bluetooth
+    </h4>
+    <p>
+      If device implementations support Bluetooth Audio profile, they:
+    </p>
+    <ul>
+      <li>SHOULD support Advanced Audio Codecs and Bluetooth Audio Codecs (e.g. LDAC).
+      </li>
+    </ul>
+    <p>
+      If device implementations declare <code>android.hardware.vr.high_performance</code> feature, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support Bluetooth 4.2 and Bluetooth LE Data Length Extension.
+      </li>
+    </ul>
+    <p>
+      Android includes support for <a href="http://developer.android.com/reference/android/bluetooth/package-summary.html">Bluetooth and Bluetooth Low Energy</a>.
+    </p>
+    <p>
+      If device implementations include support for Bluetooth and Bluetooth Low Energy, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST declare the relevant platform features (<code>android.hardware.bluetooth</code> and <code>android.hardware.bluetooth_le</code> respectively) and implement the platform APIs.
+      </li>
+      <li>SHOULD implement relevant Bluetooth profiles such as A2DP, AVCP, OBEX, etc. as appropriate for the device.
+      </li>
+    </ul>
+    <p>
+      If device implementations include support for Bluetooth Low Energy, they:
+    </p>
+    <ul>
+      <li>[C-3-1] MUST declare the hardware feature <code>android.hardware.bluetooth_le</code>.
+      </li>
+      <li>[C-3-2] MUST enable the GATT (generic attribute profile) based Bluetooth APIs as described in the SDK documentation and <a href="http://developer.android.com/reference/android/bluetooth/package-summary.html">android.bluetooth</a>.
+      </li>
+      <li>[C-3-3] MUST report the correct value for <code>BluetoothAdapter.isOffloadedFilteringSupported()</code> to indicate whether the filtering logic for the <a href="https://developer.android.com/reference/android/bluetooth/le/ScanFilter.html">ScanFilter</a> API classes is implemented.
+      </li>
+      <li>[C-3-4] MUST report the correct value for <code>BluetoothAdapter.isMultipleAdvertisementSupported()</code> to indicate whether Low Energy Advertising is supported.
+      </li>
+      <li>SHOULD support offloading of the filtering logic to the bluetooth chipset when implementing the <a href="https://developer.android.com/reference/android/bluetooth/le/ScanFilter.html">ScanFilter API</a>.
+      </li>
+      <li>SHOULD support offloading of the batched scanning to the bluetooth chipset.
+      </li>
+      <li>
+        <p>
+          SHOULD support multi advertisement with at least 4 slots.
+        </p>
+      </li>
+      <li>
+        <p>
+          [SR] STRONGLY RECOMMENDED to implement a Resolvable Private Address (RPA) timeout no longer than 15 minutes and rotate the address at timeout to protect user privacy.
+        </p>
+      </li>
+    </ul>
+    <h4 id="7_4_4_near-field_communications">
+      7.4.4. Near-Field Communications
+    </h4>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>SHOULD include a transceiver and related hardware for Near-Field Communications (NFC).
+      </li>
+      <li>[C-0-1] MUST implement <code>android.nfc.NdefMessage</code> and <code>android.nfc.NdefRecord</code> APIs even if they do not include support for NFC or declare the <code>android.hardware.nfc</code> feature as the classes represent a protocol-independent data representation format.
+      </li>
+    </ul>
+    <p>
+      If device implementations include NFC hardware and plan to make it available to third-party apps, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST report the <code>android.hardware.nfc</code> feature from the <a href="http://developer.android.com/reference/android/content/pm/PackageManager.html"><code>android.content.pm.PackageManager.hasSystemFeature()</code> method</a>.
+      </li>
+      <li>MUST be capable of reading and writing NDEF messages via the following NFC standards as below:
+      </li>
+      <li>[C-1-2] MUST be capable of acting as an NFC Forum reader/writer (as defined by the NFC Forum technical specification NFCForum-TS-DigitalProtocol-1.0) via the following NFC standards:
+      </li>
+      <li>NfcA (ISO14443-3A)
+      </li>
+      <li>NfcB (ISO14443-3B)
+      </li>
+      <li>NfcF (JIS X 6319-4)
+      </li>
+      <li>IsoDep (ISO 14443-4)
+      </li>
+      <li>NFC Forum Tag Types 1, 2, 3, 4, 5 (defined by the NFC Forum)
+      </li>
+      <li>
+        <p>
+          [SR] STRONGLY RECOMMENDED to be capable of reading and writing NDEF messages as well as raw data via the following NFC standards. Note that while the NFC standards are stated as STRONGLY RECOMMENDED, the Compatibility Definition for a future version is planned to change these to MUST. These standards are optional in this version but will be required in future versions. Existing and new devices that run this version of Android are very strongly encouraged to meet these requirements now so they will be able to upgrade to the future platform releases.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-1-3] MUST be capable of transmitting and receiving data via the following peer-to-peer standards and protocols:
+        </p>
+      </li>
+      <li>ISO 18092
+      </li>
+      <li>LLCP 1.2 (defined by the NFC Forum)
+      </li>
+      <li>SDP 1.0 (defined by the NFC Forum)
+      </li>
+      <li>
+        <a href="http://static.googleusercontent.com/media/source.android.com/en/us/compatibility/ndef-push-protocol.pdf">NDEF Push Protocol</a>
+      </li>
+      <li>SNEP 1.0 (defined by the NFC Forum)
+      </li>
+      <li>[C-1-4] MUST include support for <a href="http://developer.android.com/guide/topics/connectivity/nfc/nfc.html">Android Beam</a> and SHOULD enable Android Beam by default.
+      </li>
+      <li>[C-1-5] MUST be able to send and receive using Android Beam, when Android Beam is enabled or another proprietary NFC P2p mode is turned on.
+      </li>
+      <li>[C-1-6] MUST implement the SNEP default server. Valid NDEF messages received by the default SNEP server MUST be dispatched to applications using the <code>android.nfc.ACTION_NDEF_DISCOVERED</code> intent. Disabling Android Beam in settings MUST NOT disable dispatch of incoming NDEF message.
+      </li>
+      <li>[C-1-7] MUST honor the <code>android.settings.NFCSHARING_SETTINGS</code> intent to show <a href="http://developer.android.com/reference/android/provider/Settings.html#ACTION_NFCSHARING_SETTINGS">NFC sharing settings</a>.
+      </li>
+      <li>[C-1-8] MUST implement the NPP server. Messages received by the NPP server MUST be processed the same way as the SNEP default server.
+      </li>
+      <li>[C-1-9] MUST implement a SNEP client and attempt to send outbound P2P NDEF to the default SNEP server when Android Beam is enabled. If no default SNEP server is found then the client MUST attempt to send to an NPP server.
+      </li>
+      <li>[C-1-10] MUST allow foreground activities to set the outbound P2P NDEF message using <code>android.nfc.NfcAdapter.setNdefPushMessage</code>, and <code>android.nfc.NfcAdapter.setNdefPushMessageCallback</code>, and <code>android.nfc.NfcAdapter.enableForegroundNdefPush</code>.
+      </li>
+      <li>SHOULD use a gesture or on-screen confirmation, such as 'Touch to Beam', before sending outbound P2P NDEF messages.
+      </li>
+      <li>[C-1-11] MUST support NFC Connection handover to Bluetooth when the device supports Bluetooth Object Push Profile.
+      </li>
+      <li>[C-1-12] MUST support connection handover to Bluetooth when using <code>android.nfc.NfcAdapter.setBeamPushUris</code>, by implementing the “<a href="http://members.nfc-forum.org/specs/spec_list/#conn_handover">Connection Handover version 1.2</a>” and “<a href="http://members.nfc-forum.org/apps/group_public/download.php/18688/NFCForum-AD-BTSSP_1_1.pdf">Bluetooth Secure Simple Pairing Using NFC version 1.0</a>” specs from the NFC Forum. Such an implementation MUST implement the handover LLCP service with service name “urn:nfc:sn:handover” for exchanging the handover request/select records over NFC, and it MUST use the Bluetooth Object Push Profile for the actual Bluetooth data transfer. For legacy reasons (to remain compatible with Android 4.1 devices), the implementation SHOULD still accept SNEP GET requests for exchanging the handover request/select records over NFC. However an implementation itself SHOULD NOT send SNEP GET requests for performing connection handover.
+      </li>
+      <li>[C-1-13] MUST poll for all supported technologies while in NFC discovery mode.
+      </li>
+      <li>SHOULD be in NFC discovery mode while the device is awake with the screen active and the lock-screen unlocked.
+      </li>
+      <li>SHOULD be capable of reading the barcode and URL (if encoded) of <a href="http://developer.android.com/reference/android/nfc/tech/NfcBarcode.html">Thinfilm NFC Barcode</a> products.
+      </li>
+    </ul>
+    <p>
+      (Note that publicly available links are not available for the JIS, ISO, and NFC Forum specifications cited above.)
+    </p>
+    <p>
+      Android includes support for NFC Host Card Emulation (HCE) mode.
+    </p>
+    <p>
+      If device implementations include an NFC controller chipset capable of HCE (for NfcA and/or NfcB) and support Application ID (AID) routing, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST report the <code>android.hardware.nfc.hce</code> feature constant.
+      </li>
+      <li>[C-2-2] MUST support <a href="http://developer.android.com/guide/topics/connectivity/nfc/hce.html">NFC HCE APIs</a> as defined in the Android SDK.
+      </li>
+    </ul>
+    <p>
+      If device implementations include an NFC controller chipset capable of HCE for NfcF, and implement the feature for third-party applications, they:
+    </p>
+    <ul>
+      <li>[C-3-1] MUST report the <code>android.hardware.nfc.hcef</code> feature constant.
+      </li>
+      <li>[C-3-2] MUST implement the [NfcF Card Emulation APIs] (https://developer.android.com/reference/android/nfc/cardemulation/NfcFCardEmulation.html) as defined in the Android SDK.
+      </li>
+    </ul>
+    <p>
+      If device implementations include general NFC support as described in this section and support MIFARE technologies (MIFARE Classic, MIFARE Ultralight, NDEF on MIFARE Classic) in the reader/writer role, they:
+    </p>
+    <ul>
+      <li>[C-4-1] MUST implement the corresponding Android APIs as documented by the Android SDK.
+      </li>
+      <li>[C-4-2] MUST report the feature <code>com.nxp.mifare</code> from the <a href="http://developer.android.com/reference/android/content/pm/PackageManager.html"><code>android.content.pm.PackageManager.hasSystemFeature</code>()</a> method. Note that this is not a standard Android feature and as such does not appear as a constant in the <code>android.content.pm.PackageManager</code> class.
+      </li>
+    </ul>
+    <h4 id="7_4_5_minimum_network_capability">
+      7.4.5. Minimum Network Capability
+    </h4>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST include support for one or more forms of data networking. Specifically, device implementations MUST include support for at least one data standard capable of 200Kbit/sec or greater. Examples of technologies that satisfy this requirement include EDGE, HSPA, EV-DO, 802.11g, Ethernet, Bluetooth PAN, etc.
+      </li>
+      <li>[C-0-2] MUST include an IPv6 networking stack and support IPv6 communication using the managed APIs, such as <code>java.net.Socket</code> and <code>java.net.URLConnection</code>, as well as the native APIs, such as <code>AF_INET6</code> sockets.
+      </li>
+      <li>[C-0-3] MUST enable IPv6 by default.
+      </li>
+      <li>MUST ensure that IPv6 communication is as reliable as IPv4, for example.
+      </li>
+      <li>[C-0-4] MUST maintain IPv6 connectivity in doze mode.
+      </li>
+      <li>[C-0-5] Rate-limiting MUST NOT cause the device to lose IPv6 connectivity on any IPv6-compliant network that uses RA lifetimes of at least 180 seconds.
+      </li>
+      <li>SHOULD also include support for at least one common wireless data standard, such as 802.11 (Wi-Fi) when a physical networking standard (such as Ethernet) is the primary data connection
+      </li>
+      <li>MAY implement more than one form of data connectivity.
+      </li>
+    </ul>
+    <p>
+      The required level of IPv6 support depends on the network type, as follows:
+    </p>
+    <p>
+      If devices implementations support Wi-Fi networks, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support dual-stack and IPv6-only operation on Wi-Fi.
+      </li>
+    </ul>
+    <p>
+      If device impelementations support Ethernet networks, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST support dual-stack operation on Ethernet.
+      </li>
+    </ul>
+    <p>
+      If device implementations support cellular data, they:
+    </p>
+    <ul>
+      <li>[C-3-1] MUST simultaneously meet these requirements on each network to which it is connected when a device is simultaneously connected to more than one network (e.g., Wi-Fi and cellular data), .
+      </li>
+      <li>SHOULD support IPv6 operation (IPv6-only and possibly dual-stack) on cellular data.
+      </li>
+    </ul>
+    <h4 id="7_4_6_sync_settings">
+      7.4.6. Sync Settings
+    </h4>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST have the master auto-sync setting on by default so that the method <a href="http://developer.android.com/reference/android/content/ContentResolver.html"><code>getMasterSyncAutomatically()</code></a> returns “true”.
+      </li>
+    </ul>
+    <h4 id="7_4_7_data_saver">
+      7.4.7. Data Saver
+    </h4>
+    <p>
+      If device implementations include a metered connection, they are:
+    </p>
+    <ul>
+      <li>[SR] STRONGLY RECOMMENDED to provide the data saver mode.
+      </li>
+    </ul>
+    <p>
+      If device implementations provide the data saver mode, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support all the APIs in the <code>ConnectivityManager</code> class as described in the <a href="https://developer.android.com/training/basics/network-ops/data-saver.html">SDK documentation</a>
+      </li>
+      <li>[C-1-2] MUST provide a user interface in the settings, that handles the <a href="https://developer.android.com/reference/android/provider/Settings.html#ACTION_IGNORE_BACKGROUND_DATA_RESTRICTIONS_SETTINGS"><code>Settings.ACTION_IGNORE_BACKGROUND_DATA_RESTRICTIONS_SETTINGS</code></a> intent, allowing users to add applications to or remove applications from the whitelist.
+      </li>
+    </ul>
+    <p>
+      If device implementations do not provide the data saver mode, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST return the value <code>RESTRICT_BACKGROUND_STATUS_DISABLED</code> for <a href="https://developer.android.com/reference/android/net/ConnectivityManager.html#getRestrictBackgroundStatus%28%29"><code>ConnectivityManager.getRestrictBackgroundStatus()</code></a>
+      </li>
+      <li>[C-2-2] MUST NOT broadcast <code>ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED</code>.
+      </li>
+      <li>[C-2-3] MUST have an activity that handles the <code>Settings.ACTION_IGNORE_BACKGROUND_DATA_RESTRICTIONS_SETTINGS</code> intent but MAY implement it as a no-op.
+      </li>
+    </ul>
+    <h3 id="7_5_cameras">
+      7.5. Cameras
+    </h3>
+    <p>
+      If device implementations include at least one camera, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST declare the <code>android.hardware.camera.any</code> feature flag.
+      </li>
+      <li>[C-1-2] MUST be possible for an application to simultaneously allocate 3 RGBA_8888 bitmaps equal to the size of the images produced by the largest-resolution camera sensor on the device, while camera is open for the purpose of basic preview and still capture.
+      </li>
+    </ul>
+    <h4 id="7_5_1_rear-facing_camera">
+      7.5.1. Rear-Facing Camera
+    </h4>
+    <p>
+      A rear-facing camera is a camera located on the side of the device opposite the display; that is, it images scenes on the far side of the device, like a traditional camera.
+    </p>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>SHOULD include a rear-facing camera.
+      </li>
+    </ul>
+    <p>
+      If device implementations include at least one rear-facing camera, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST report the feature flag <code>android.hardware.camera</code> and <code>android.hardware.camera.any</code>.
+      </li>
+      <li>[C-1-2] MUST have a resolution of at least 2 megapixels.
+      </li>
+      <li>SHOULD have either hardware auto-focus or software auto-focus implemented in the camera driver (transparent to application software).
+      </li>
+      <li>MAY have fixed-focus or EDOF (extended depth of field) hardware.
+      </li>
+      <li>MAY include a flash.
+      </li>
+    </ul>
+    <p>
+      If the Camera includes a flash:
+    </p>
+    <ul>
+      <li>[C-2-1] the flash lamp MUST NOT be lit while an <code>android.hardware.Camera.PreviewCallback</code> instance has been registered on a Camera preview surface, unless the application has explicitly enabled the flash by enabling the <code>FLASH_MODE_AUTO</code> or <code>FLASH_MODE_ON</code> attributes of a <code>Camera.Parameters</code> object. Note that this constraint does not apply to the device’s built-in system camera application, but only to third-party applications using <code>Camera.PreviewCallback</code>.
+      </li>
+    </ul>
+    <h4 id="7_5_2_front-facing_camera">
+      7.5.2. Front-Facing Camera
+    </h4>
+    <p>
+      A front-facing camera is a camera located on the same side of the device as the display; that is, a camera typically used to image the user, such as for video conferencing and similar applications.
+    </p>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>MAY include a front-facing camera
+      </li>
+    </ul>
+    <p>
+      If device implementations include at least one front-facing camera, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST report the feature flag <code>android.hardware.camera.any</code> and <code>android.hardware.camera.front</code>.
+      </li>
+      <li>[C-1-2] MUST have a resolution of at least VGA (640x480 pixels).
+      </li>
+      <li>[C-1-3] MUST NOT use a front-facing camera as the default for the Camera API and MUST NOT configure the API to treat a front-facing camera as the default rear-facing camera, even if it is the only camera on the device.
+      </li>
+      <li>[C-1-5] The camera preview MUST be mirrored horizontally relative to the orientation specified by the application when the current application has explicitly requested that the Camera display be rotated via a call to the <a href="http://developer.android.com/reference/android/hardware/Camera.html#setDisplayOrientation(int)"><code>android.hardware.Camera.setDisplayOrientation()</code></a> method. Conversely, the preview MUST be mirrored along the device’s default horizontal axis when the current application does not explicitly request that the Camera display be rotated via a call to the <a href="http://developer.android.com/reference/android/hardware/Camera.html#setDisplayOrientation(int)"><code>android.hardware.Camera.setDisplayOrientation()</code></a> method.
+      </li>
+      <li>[C-1-6] MUST NOT mirror the final captured still image or video streams returned to application callbacks or committed to media storage.
+      </li>
+      <li>[C-1-7] MUST mirror the image displayed by the postview in the same manner as the camera preview image stream.
+      </li>
+      <li>MAY include features (such as auto-focus, flash, etc.) available to rear-facing cameras as described in <a href="#7_5_1_rear-facing_camera">section 7.5.1</a>.
+      </li>
+    </ul>
+    <p>
+      If device implementations are capable of being rotated by user (such as automatically via an accelerometer or manually via user input):
+    </p>
+    <ul>
+      <li>[C-2-1] The camera preview MUST be mirrored horizontally relative to the device’s current orientation.
+      </li>
+    </ul>
+    <h4 id="7_5_3_external_camera">
+      7.5.3. External Camera
+    </h4>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>MAY include support for an external camera that is not necessarily always connected.
+      </li>
+    </ul>
+    <p>
+      If device impelmentations include support for an external camera, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST declare the platform feature flag <code>android.hardware.camera.external</code> and <code>android.hardware camera.any</code>.
+      </li>
+      <li>[C-1-2] MUST support USB Video Class (UVC 1.0 or higher) if the external camera connects through the USB port.
+      </li>
+      <li>SHOULD support video compressions such as MJPEG to enable transfer of high-quality unencoded streams (i.e. raw or independently compressed picture streams).
+      </li>
+      <li>MAY support multiple cameras.
+      </li>
+      <li>MAY support camera-based video encoding. If supported, a simultaneous unencoded / MJPEG stream (QVGA or greater resolution) MUST be accessible to the device implementation.
+      </li>
+    </ul>
+    <h4 id="7_5_4_camera_api_behavior">
+      7.5.4. Camera API Behavior
+    </h4>
+    <p>
+      Android includes two API packages to access the camera, the newer android.hardware.camera2 API expose lower-level camera control to the app, including efficient zero-copy burst/streaming flows and per-frame controls of exposure, gain, white balance gains, color conversion, denoising, sharpening, and more.
+    </p>
+    <p>
+      The older API package, <code>android.hardware.Camera</code>, is marked as deprecated in Android 5.0 but as it should still be available for apps to use. Android device implementations MUST ensure the continued support of the API as described in this section and in the Android SDK.
+    </p>
+    <p>
+      Device implementations MUST implement the following behaviors for the camera-related APIs, for all available cameras. Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST use <code>android.hardware.PixelFormat.YCbCr_420_SP</code> for preview data provided to application callbacks when an application has never called <code>android.hardware.Camera.Parameters.setPreviewFormat(int)</code>.
+      </li>
+      <li>[C-0-2] MUST further be in the NV21 encoding format when an application registers an <code>android.hardware.Camera.PreviewCallback</code> instance and the system calls the <code>onPreviewFrame()</code> method and the preview format is YCbCr_420_SP, the data in the byte[] passed into <code>onPreviewFrame()</code>. That is, NV21 MUST be the default.
+      </li>
+      <li>[C-0-3] MUST support the YV12 format (as denoted by the <code>android.graphics.ImageFormat.YV12</code> constant) for camera previews for both front- and rear-facing cameras for <code>android.hardware.Camera</code>. (The hardware video encoder and camera may use any native pixel format, but the device implementation MUST support conversion to YV12.)
+      </li>
+      <li>[C-0-4] MUST support the <code>android.hardware.ImageFormat.YUV_420_888</code> and <code>android.hardware.ImageFormat.JPEG</code> formats as outputs through the <code>android.media.ImageReader</code> API for <code>android.hardware.camera2</code>.
+      </li>
+      <li>[C-0-5] MUST still implement the full <a href="http://developer.android.com/reference/android/hardware/Camera.html">Camera API</a> included in the Android SDK documentation, regardless of whether the device includes hardware autofocus or other capabilities. For instance, cameras that lack autofocus MUST still call any registered <code>android.hardware.Camera.AutoFocusCallback</code> instances (even though this has no relevance to a non-autofocus camera.) Note that this does apply to front-facing cameras; for instance, even though most front-facing cameras do not support autofocus, the API callbacks must still be “faked” as described.
+      </li>
+      <li>[C-0-6] MUST recognize and honor each parameter name defined as a constant on the <a href="http://developer.android.com/reference/android/hardware/Camera.Parameters.html"><code>android.hardware.Camera.Parameters</code></a> class. Conversely, device implementations MUST NOT honor or recognize string constants passed to the <code>android.hardware.Camera.setParameters()</code> method other than those documented as constants on the <code>android.hardware.Camera.Parameters</code>. That is, device implementations MUST support all standard Camera parameters if the hardware allows, and MUST NOT support custom Camera parameter types. For instance, device implementations that support image capture using high dynamic range (HDR) imaging techniques MUST support camera parameter <code>Camera.SCENE_MODE_HDR</code>.
+      </li>
+      <li>[C-0-7] MUST report the proper level of support with the <a href="https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics.html#INFO_SUPPORTED_HARDWARE_LEVEL"><code>android.info.supportedHardwareLevel</code></a> property as described in the Android SDK and report the appropriate <a href="http://source.android.com/devices/camera/versioning.html">framework feature flags</a>.
+      </li>
+      <li>[C-0-8] MUST also declare its individual camera capabilities of <code>android.hardware.camera2</code> via the <code>android.request.availableCapabilities</code> property and declare the appropriate <a href="http://source.android.com/devices/camera/versioning.html">feature flags</a>; MUST define the feature flag if any of its attached camera devices supports the feature.
+      </li>
+      <li>[C-0-9] MUST broadcast the <code>Camera.ACTION_NEW_PICTURE</code> intent whenever a new picture is taken by the camera and the entry of the picture has been added to the media store.
+      </li>
+      <li>[C-0-10] MUST broadcast the <code>Camera.ACTION_NEW_VIDEO</code> intent whenever a new video is recorded by the camera and the entry of the picture has been added to the media store.
+      </li>
+    </ul>
+    <h4 id="7_5_5_camera_orientation">
+      7.5.5. Camera Orientation
+    </h4>
+    <p>
+      If device implementations have a front- or a rear-facing camera, such camera(s):
+    </p>
+    <ul>
+      <li>[C-1-1] MUST be oriented so that the long dimension of the camera aligns with the screen’s long dimension. That is, when the device is held in the landscape orientation, cameras MUST capture images in the landscape orientation. This applies regardless of the device’s natural orientation; that is, it applies to landscape-primary devices as well as portrait-primary devices.
+      </li>
+    </ul>
+    <h3 id="7_6_memory_and_storage">
+      7.6. Memory and Storage
+    </h3>
+    <h4 id="7_6_1_minimum_memory_and_storage">
+      7.6.1. Minimum Memory and Storage
+    </h4>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST include a <a href="http://developer.android.com/reference/android/app/DownloadManager.html">Download Manager</a> that applications MAY use to download data files and they MUST be capable of downloading individual files of at least 100MB in size to the default “cache” location.
+      </li>
+    </ul>
+    <h4 id="7_6_2_application_shared_storage">
+      7.6.2. Application Shared Storage
+    </h4>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST offer storage to be shared by applications, also often referred as “shared external storage”, "application shared storage" or by the Linux path "/sdcard" it is mounted on.
+      </li>
+      <li>[C-0-2] MUST be configured with shared storage mounted by default, in other words “out of the box”, regardless of whether the storage is implemented on an internal storage component or a removable storage medium (e.g. Secure Digital card slot).
+      </li>
+      <li>[C-0-3] MUST mount the application shared storage directly on the Linux path <code>sdcard</code> or include a Linux symbolic link from <code>sdcard</code> to the actual mount point.
+      </li>
+      <li>[C-0-4] MUST enforce the <code>android.permission.WRITE_EXTERNAL_STORAGE</code> permission on this shared storage as documented in the SDK. Shared storage MUST otherwise be writable by any application that obtains that permission.
+      </li>
+    </ul>
+    <p>
+      Device implementations MAY meet the above requirements using either:
+    </p>
+    <ul>
+      <li>a user-accessible removable storage, such as a Secure Digital (SD) card slot.
+      </li>
+      <li>a portion of the internal (non-removable) storage as implemented in the Android Open Source Project (AOSP).
+      </li>
+    </ul>
+    <p>
+      If device implementations use removable storage to satisfy the above requirements, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST implement a toast or pop-up user interface warning the user when there is no storage medium inserted in the slot.
+      </li>
+      <li>[C-1-2] MUST include a FAT-formatted storage medium (e.g. SD card) or show on the box and other material available at time of purchase that the storage medium has to be purchased separately.
+      </li>
+    </ul>
+    <p>
+      If device implementations use a protion of the non-removable storage to satisfy the above requirements, they:
+    </p>
+    <ul>
+      <li>SHOULD use the AOSP implementation of the internal application shared storage.
+      </li>
+      <li>MAY share the storage space with the application private data.
+      </li>
+    </ul>
+    <p>
+      If device implementations include multiple shared storage paths (such as both an SD card slot and shared internal storage), they:
+    </p>
+    <ul>
+      <li>[C-3-1] MUST allow only pre-installed and privileged Android applications with the <code>WRITE_EXTERNAL_STORAGE</code> permission to write to the secondary external storage, except when writing to their package-specific directories or within the <code>URI</code> returned by firing the <code>ACTION_OPEN_DOCUMENT_TREE</code> intent.
+      </li>
+    </ul>
+    <p>
+      If device implementations have a USB port with USB peripheral mode support, they:
+    </p>
+    <ul>
+      <li>[C-3-1] MUST provide a mechanism to access the data on the application shared storage from a host computer.
+      </li>
+      <li>SHOULD expose content from both storage paths transparently through Android’s media scanner service and <code>android.provider.MediaStore</code>.
+      </li>
+      <li>MAY use USB mass storage, but SHOULD use Media Transfer Protocol to satisfy this requirement.
+      </li>
+    </ul>
+    <p>
+      If device implementations have a USB port with USB peripheral mode and support Media Transfer Protocol, they:
+    </p>
+    <ul>
+      <li>SHOULD be compatible with the reference Android MTP host, <a href="http://www.android.com/filetransfer">Android File Transfer</a>.
+      </li>
+      <li>SHOULD report a USB device class of 0x00.
+      </li>
+      <li>SHOULD report a USB interface name of 'MTP'.
+      </li>
+    </ul>
+    <h4 id="7_6_3_adoptable_storage">
+      7.6.3. Adoptable Storage
+    </h4>
+    <p>
+      If the device is expected to be mobile in nature unlike Television, device implementations are:
+    </p>
+    <ul>
+      <li>[SR] STRONGLY RECOMMENDED to implement the adoptable storage in a long-term stable location, since accidentally disconnecting them can cause data loss/corruption.
+      </li>
+    </ul>
+    <p>
+      If the removable storage device port is in a long-term stable location, such as within the battery compartment or other protective cover, device implementations are:
+    </p>
+    <ul>
+      <li>[SR] STRONGLY RECOMMENDED to implement <a href="http://source.android.com/devices/storage/adoptable.html">adoptable storage</a>.
+      </li>
+    </ul>
+    <h3 id="7_7_usb">
+      7.7. USB
+    </h3>
+    <p>
+      If device implementations have a USB port, they:
+    </p>
+    <ul>
+      <li>SHOULD support USB peripheral mode and SHOULD support USB host mode.
+      </li>
+    </ul>
+    <h4 id="7_7_1_usb_peripheral_mode">
+      7.7.1. USB peripheral mode
+    </h4>
+    <p>
+      If device implementations include a USB port supporting peripheral mode:
+    </p>
+    <ul>
+      <li>[C-1-1] The port MUST be connectable to a USB host that has a standard type-A or type-C USB port.
+      </li>
+      <li>[C-1-2] MUST report the correct value of <code>iSerialNumber</code> in USB standard device descriptor through <code>android.os.Build.SERIAL</code>.
+      </li>
+      <li>[C-1-3] MUST detect 1.5A and 3.0A chargers per the Type-C resistor standard and MUST detect changes in the advertisement if they support Type-C USB.
+      </li>
+      <li>[SR] The port SHOULD use micro-B, micro-AB or Type-C USB form factor. Existing and new Android devices are <strong>STRONGLY RECOMMENDED to meet these requirements</strong> so they will be able to upgrade to the future platform releases.
+      </li>
+      <li>[SR] The port SHOULD be located on the bottom of the device (according to natural orientation) or enable software screen rotation for all apps (including home screen), so that the display draws correctly when the device is oriented with the port at bottom. Existing and new Android devices are <strong>STRONGLY RECOMMENDED to meet these requirements</strong> so they will be able to upgrade to future platform releases.
+      </li>
+      <li>[SR] SHOULD implement support to draw 1.5 A current during HS chirp and traffic as specified in the <a href="http://www.usb.org/developers/docs/devclass_docs/BCv1.2_070312.zip">USB Battery Charging specification, revision 1.2</a>. Existing and new Android devices are <strong>STRONGLY RECOMMENDED to meet these requirements</strong> so they will be able to upgrade to the future platform releases.
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to not support proprietary charging methods that modify Vbus voltage beyond default levels, or alter sink/source roles as such may result in interoperability issues with the chargers or devices that support the standard USB Power Delivery methods. While this is called out as "STRONGLY RECOMMENDED", in future Android versions we might REQUIRE all type-C devices to support full interoperability with standard type-C chargers.
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to support Power Delivery for data and power role swapping when they support Type-C USB and USB host mode.
+      </li>
+      <li>SHOULD support Power Delivery for high-voltage charging and support for Alternate Modes such as display out.
+      </li>
+      <li>SHOULD implement the Android Open Accessory (AOA) API and specification as documented in the Android SDK documentation.
+      </li>
+    </ul>
+    <p>
+      If device implementations including a USB port, implement the AOA specification, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST declare support for the hardware feature <a href="http://developer.android.com/guide/topics/connectivity/usb/accessory.html"><code>android.hardware.usb.accessory</code></a>.
+      </li>
+      <li>[C-2-2] The USB mass storage class MUST include the string "android" at the end of the interface description <code>iInterface</code> string of the USB mass storage
+      </li>
+      <li>SHOULD NOT implement <a href="https://source.android.com/devices/accessories/aoa2#audio-support">AOAv2 audio</a> documented in the Android Open Accessory Protocol 2.0 documentation. AOAv2 audio is deprecated as of Android version 8.0 (API level 26).
+      </li>
+    </ul>
+    <h4 id="7_7_2_usb_host_mode">
+      7.7.2. USB host mode
+    </h4>
+    <p>
+      If device implementations include a USB port supporting host mode, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST implement the Android USB host API as documented in the Android SDK and MUST declare support for the hardware feature <a href="http://developer.android.com/guide/topics/connectivity/usb/host.html"><code>android.hardware.usb.host</code></a>.
+      </li>
+      <li>[C-1-2] MUST implement support to connect standard USB peripherals, in other words, they MUST either:
+        <ul>
+          <li>Have an on-device type C port or ship with cable(s) adapting an on-device proprietary port to a standard USB type-C port (USB Type-C device).
+          </li>
+          <li>Have an on-device type A or ship with cable(s) adapting an on-device proprietary port to a standard USB type-A port.
+          </li>
+          <li>Have an on-device micro-AB port, which SHOULD ship with a cable adapting to a standard type-A port.
+          </li>
+        </ul>
+      </li>
+      <li>[C-1-3] MUST NOT ship with an adapter converting from USB type A or micro-AB ports to a type-C port (receptacle).
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to implement the <a href="http://developer.android.com/reference/android/hardware/usb/UsbConstants.html#USB_CLASS_AUDIO">USB audio class</a> as documented in the Android SDK documentation.
+      </li>
+      <li>SHOULD support charging the connected USB peripheral device while in host mode; advertising a source current of at least 1.5A as specified in the Termination Parameters section of the <a href="http://www.usb.org/developers/docs/usb_31_021517.zip">USB Type-C Cable and Connector Specification Revision 1.2</a> for USB Type-C connectors or using Charging Downstream Port(CDP) output current range as specified in the <a href="http://www.usb.org/developers/docs/devclass_docs/BCv1.2_070312.zip">USB Battery Charging specifications, revision 1.2</a> for Micro-AB connectors.
+      </li>
+      <li>SHOULD implement and support USB Type-C standards.
+      </li>
+    </ul>
+    <p>
+      If device implementations include a USB port supporting host mode and the USB audio class, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST support the <a href="https://developer.android.com/reference/android/hardware/usb/UsbConstants.html#USB_CLASS_HID">USB HID class</a>
+      </li>
+      <li>[C-2-2] MUST support the detection and mapping of the following HID data fields specified in the <a href="http://www.usb.org/developers/hidpage/Hut1_12v2.pdf">USB HID Usage Tables</a> and the <a href="http://www.usb.org/developers/hidpage/Voice_Command_Usage.pdf">Voice Command Usage Request</a> to the <a href="https://developer.android.com/reference/android/view/KeyEvent.html"><code>KeyEvent</code></a> constants as below:
+        <ul>
+          <li>Usage Page (0xC) Usage ID (0x0CD): <code>KEYCODE_MEDIA_PLAY_PAUSE</code>
+          </li>
+          <li>Usage Page (0xC) Usage ID (0x0E9): <code>KEYCODE_VOLUME_UP</code>
+          </li>
+          <li>Usage Page (0xC) Usage ID (0x0EA): <code>KEYCODE_VOLUME_DOWN</code>
+          </li>
+          <li>Usage Page (0xC) Usage ID (0x0CF): <code>KEYCODE_VOICE_ASSIST</code>
+          </li>
+        </ul>
+      </li>
+    </ul>
+    <p>
+      If device implementations include a USB port supporting host mode and the Storage Access Framework (SAF), they:
+    </p>
+    <ul>
+      <li>[C-3-1] MUST recognize any remotely connected MTP (Media Transfer Protocol) devices and make their contents accessible through the <code>ACTION_GET_CONTENT</code>, <code>ACTION_OPEN_DOCUMENT</code>, and <code>ACTION_CREATE_DOCUMENT</code> intents. .
+      </li>
+    </ul>
+    <p>
+      If device implementations include a USB port supporting host mode and USB Type-C, they:
+    </p>
+    <ul>
+      <li>[C-4-1] MUST implement Dual Role Port functionality as defined by the USB Type-C specification (section 4.5.1.3.3).
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to support DisplayPort, SHOULD support USB SuperSpeed Data Rates, and are STRONGLY RECOMMENDED to support Power Delivery for data and power role swapping.
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to NOT support Audio Adapter Accessory Mode as described in the Appendix A of the <a href="http://www.usb.org/developers/docs/">USB Type-C Cable and Connector Specification Revision 1.2</a>.
+      </li>
+      <li>SHOULD implement the Try.* model that is most appropriate for the device form factor. For example a handheld device SHOULD implement the Try.SNK model.
+      </li>
+    </ul>
+    <h3 id="7_8_audio">
+      7.8. Audio
+    </h3>
+    <h4 id="7_8_1_microphone">
+      7.8.1. Microphone
+    </h4>
+    <p>
+      If device implementations include a microphone, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST report the <code>android.hardware.microphone</code> feature constant.
+      </li>
+      <li>[C-1-2] MUST meet the audio recording requirements in <a href="#5_4_audio_recording">section 5.4</a>.
+      </li>
+      <li>[C-1-3] MUST meet the audio latency requirements in <a href="#5_6_audio_latency">section 5.6</a>.
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to support near-ultrasound recording as described in <a href="#7_8_3_near_ultrasound">section 7.8.3</a>.
+      </li>
+    </ul>
+    <p>
+      If device implementations omit a microphone, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST NOT report the <code>android.hardware.microphone</code> feature constant.
+      </li>
+      <li>[C-2-2] MUST implement the audio recording API at least as no-ops, per <a href="#7_hardware_compatibility">section 7</a>.
+      </li>
+    </ul>
+    <h4 id="7_8_2_audio_output">
+      7.8.2. Audio Output
+    </h4>
+    <p>
+      If device implementations include a speaker or an audio/multimedia output port for an audio output peripheral such as a 4 conductor 3.5mm audio jack or USB host mode port using <a href="https://source.android.com/devices/audio/usb#audioClass">USB audio class</a>, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST report the <code>android.hardware.audio.output</code> feature constant.
+      </li>
+      <li>[C-1-2] MUST meet the audio playback requirements in <a href="#5_5_audio_playback">section 5.5</a>.
+      </li>
+      <li>[C-1-3] MUST meet the audio latency requirements in <a href="#5_6_audio_latency">section 5.6</a>.
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to support near-ultrasound playback as described in <a href="#7_8_3_near_ultrasound">section 7.8.3</a>.
+      </li>
+    </ul>
+    <p>
+      If device implementations do not include a speaker or audio output port, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST NOT report the <code>android.hardware.audio output</code> feature.
+      </li>
+      <li>[C-2-2] MUST implement the Audio Output related APIs as no-ops at least.
+      </li>
+    </ul>
+    <p>
+      For the purposes of this section, an "output port" is a <a href="https://en.wikipedia.org/wiki/Computer_port_%28hardware%29">physical interface</a> such as a 3.5mm audio jack, HDMI, or USB host mode port with USB audio class. Support for audio output over radio-based protocols such as Bluetooth, WiFi, or cellular network does not qualify as including an "output port".
+    </p>
+    <h5 id="7_8_2_1_analog_audio_ports">
+      7.8.2.1. Analog Audio Ports
+    </h5>
+    <p>
+      In order to be compatible with the <a href="http://source.android.com/accessories/headset-spec.html">headsets and other audio accessories</a> using the 3.5mm audio plug across the Android ecosystem, if a device implementation includes one or more analog audio ports, at least one of the audio port(s) SHOULD be a 4 conductor 3.5mm audio jack.
+    </p>
+    <p>
+      If device implementations have a 4 conductor 3.5mm audio jack, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support audio playback to stereo headphones and stereo headsets with a microphone.
+      </li>
+      <li>[C-1-2] MUST support TRRS audio plugs with the CTIA pin-out order.
+      </li>
+      <li>[C-1-3] MUST support the detection and mapping to the keycodes for the following 3 ranges of equivalent impedance between the microphone and ground conductors on the audio plug:
+        <ul>
+          <li>
+            <strong>70 ohm or less</strong>: <code>KEYCODE_HEADSETHOOK</code>
+          </li>
+          <li>
+            <strong>210-290 ohm</strong>: <code>KEYCODE_VOLUME_UP</code>
+          </li>
+          <li>
+            <strong>360-680 ohm</strong>: <code>KEYCODE_VOLUME_DOWN</code>
+          </li>
+        </ul>
+      </li>
+      <li>[C-1-4] MUST trigger <code>ACTION_HEADSET_PLUG</code> upon a plug insert, but only after all contacts on plug are touching their relevant segments on the jack.
+      </li>
+      <li>[C-1-5] MUST be capable of driving at least 150mV ± 10% of output voltage on a 32 ohm speaker impedance.
+      </li>
+      <li>[C-1-6] MUST have a microphone bias voltage between 1.8V ~ 2.9V.
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to detect and map to the keycode for the following range of equivalent impedance between the microphone and ground conductors on the audio plug:
+        <ul>
+          <li>
+            <strong>110-180 ohm:</strong> <code>KEYCODE_VOICE_ASSIST</code>
+          </li>
+        </ul>
+      </li>
+      <li>SHOULD support audio plugs with the OMTP pin-out order.
+      </li>
+      <li>SHOULD support audio recording from stereo headsets with a microphone.
+      </li>
+    </ul>
+    <p>
+      If device implementations have a 4 conductor 3.5mm audio jack and support a microphone, and broadcast the <code>android.intent.action.HEADSET_PLUG</code> with the extra value microphone set as 1, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST support the detection of microphone on the plugged in audio accessory.
+      </li>
+    </ul>
+    <h4 id="7_8_3_near-ultrasound">
+      7.8.3. Near-Ultrasound
+    </h4>
+    <p>
+      Near-Ultrasound audio is the 18.5 kHz to 20 kHz band.
+    </p>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>MUST correctly report the support of near-ultrasound audio capability via the <a href="http://developer.android.com/reference/android/media/AudioManager.html#getProperty%28java.lang.String%29">AudioManager.getProperty</a> API as follows:
+      </li>
+    </ul>
+    <p>
+      If <a href="http://developer.android.com/reference/android/media/AudioManager.html#PROPERTY_SUPPORT_MIC_NEAR_ULTRASOUND"><code>PROPERTY_SUPPORT_MIC_NEAR_ULTRASOUND</code></a> is "true", the following requirements MUST be met by the <code>VOICE_RECOGNITION</code> and <code>UNPROCESSED</code> audio sources:
+    </p>
+    <ul>
+      <li>[C-1-1] The microphone's mean power response in the 18.5 kHz to 20 kHz band MUST be no more than 15 dB below the response at 2 kHz.
+      </li>
+      <li>[C-1-2] The microphone's unweighted signal to noise ratio over 18.5 kHz to 20 kHz for a 19 kHz tone at -26 dBFS MUST be no lower than 50 dB.
+      </li>
+    </ul>
+    <p>
+      If <a href="http://developer.android.com/reference/android/media/AudioManager.html#PROPERTY_SUPPORT_SPEAKER_NEAR_ULTRASOUND"><code>PROPERTY_SUPPORT_SPEAKER_NEAR_ULTRASOUND</code></a> is "true":
+    </p>
+    <ul>
+      <li>[C-2-1] The speaker's mean response in 18.5 kHz - 20 kHz MUST be no lower than 40 dB below the response at 2 kHz.
+      </li>
+    </ul>
+    <h3 id="7_9_virtual_reality">
+      7.9. Virtual Reality
+    </h3>
+    <p>
+      Android includes APIs and facilities to build "Virtual Reality" (VR) applications including high quality mobile VR experiences. Device implementations MUST properly implement these APIs and behaviors, as detailed in this section.
+    </p>
+    <h4 id="7_9_1_virtual_reality_mode">
+      7.9.1. Virtual Reality Mode
+    </h4>
+    <p>
+      Android includes support for <a href="https://developer.android.com/reference/android/app/Activity.html#setVrModeEnabled%28boolean,%20android.content.ComponentName%29">VR Mode</a>, a feature which handles stereoscopic rendering of notifications and disables monocular system UI components while a VR application has user focus.
+    </p>
+    <h4 id="7_9_2_virtual_reality_high_performance">
+      7.9.2. Virtual Reality High Performance
+    </h4>
+    <p>
+      If device implementations identify the support of high performance VR for longer user periods through the <code>android.hardware.vr.high_performance</code> feature flag, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST have at least 2 physical cores.
+      </li>
+      <li>[C-1-2] MUST declare <code>android.software.vr.mode feature</code>.
+      </li>
+      <li>[C-1-3] MUST support sustained performance mode.
+      </li>
+      <li>[C-1-4] MUST support OpenGL ES 3.2.
+      </li>
+      <li>[C-1-5] MUST support Vulkan Hardware Level 0 and SHOULD support Vulkan Hardware Level 1.
+      </li>
+      <li>[C-1-6] MUST implement <a href="https://www.khronos.org/registry/EGL/extensions/KHR/EGL_KHR_mutable_render_buffer.txt"><code>EGL_KHR_mutable_render_buffer</code></a>, <a href="https://www.khronos.org/registry/EGL/extensions/ANDROID/EGL_ANDROID_front_buffer_auto_refresh.txt"><code>EGL_ANDROID_front_buffer_auto_refresh</code></a>, <a href="https://www.khronos.org/registry/EGL/extensions/ANDROID/EGL_ANDROID_get_native_client_buffer.txt"><code>EGL_ANDROID_get_native_client_buffer</code></a>, <a href="https://www.khronos.org/registry/EGL/extensions/KHR/EGL_KHR_fence_sync.txt"><code>EGL_KHR_fence_sync</code></a>, <a href="https://www.khronos.org/registry/EGL/extensions/KHR/EGL_KHR_wait_sync.txt"><code>EGL_KHR_wait_sync</code></a>, <a href="https://www.khronos.org/registry/EGL/extensions/IMG/EGL_IMG_context_priority.txt"><code>EGL_IMG_context_priority</code></a>, <a href="https://www.khronos.org/registry/EGL/extensions/EXT/EGL_EXT_protected_content.txt"><code>EGL_EXT_protected_content</code></a>, and expose the extensions in the list of available EGL extensions.
+      </li>
+      <li>[C-1-7] The GPU and display MUST be able to synchronize access to the shared front buffer such that alternating-eye rendering of VR content at 60fps with two render contexts will be displayed with no visible tearing artifacts.
+      </li>
+      <li>[C-1-8] MUST implement <a href="https://www.khronos.org/registry/OpenGL/extensions/EXT/EXT_multisampled_render_to_texture.txt"><code>GL_EXT_multisampled_render_to_texture</code></a>, <a href="https://www.khronos.org/registry/OpenGL/extensions/OVR/OVR_multiview.txt"><code>GL_OVR_multiview</code></a>, <a href="https://www.khronos.org/registry/OpenGL/extensions/OVR/OVR_multiview2.txt"><code>GL_OVR_multiview2</code></a>, <a href="https://www.khronos.org/registry/OpenGL/extensions/OVR/OVR_multiview_multisampled_render_to_texture.txt"><code>GL_OVR_multiview_multisampled_render_to_texture</code></a>, <a href="https://www.khronos.org/registry/OpenGL/extensions/EXT/EXT_protected_textures.txt"><code>GL_EXT_protected_textures</code></a>, and expose the extensions in the list of available GL extensions.
+      </li>
+      <li>[C-1-9] MUST implement support for <a href="https://developer.android.com/ndk/reference/hardware__buffer_8h.html"><code>AHardwareBuffer</code></a> flags <code>AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER</code> and <code>AHARDWAREBUFFER_USAGE_SENSOR_DIRECT_DATA</code> as described in the NDK.
+      </li>
+      <li>[C-1-10] MUST implement support for <code>AHardwareBuffers</code> with more than one layer.
+      </li>
+      <li>[C-1-11] MUST support H.264 decoding at least 3840x2160@30fps-40Mbps (equivalent to 4 instances of 1920x1080@30fps-10Mbps or 2 instances of 1920x1080@60fps-20Mbps).
+      </li>
+      <li>[C-1-12] MUST support HEVC and VP9, MUST be capable to decode at least 1920x1080@30fps-10Mbps and SHOULD be capable to decode 3840x2160@30fps-20Mbps (equivalent to 4 instances of 1920x1080@30fps-5Mbps).
+      </li>
+      <li>[C-1-13] MUST support <code>HardwarePropertiesManager.getDeviceTemperatures</code> API and return accurate values for skin temperature.
+      </li>
+      <li>[C-1-14] MUST have an embedded screen, and its resolution MUST be at least be FullHD(1080p) and STRONGLY RECOMMENDED TO BE be QuadHD (1440p) or higher.
+      </li>
+      <li>[C-1-15] The display MUST measure between 4.7" and 6.3" diagonal.
+      </li>
+      <li>[C-1-16] The display MUST update at least 60 Hz while in VR Mode.
+      </li>
+      <li>[C-1-17] The display latency on Gray-to-Gray, White-to-Black, and Black-to-White switching time MUST be ≤ 3 ms.
+      </li>
+      <li>[C-1-18] The display MUST support a low-persistence mode with ≤5 ms persistence, persistence being defined as the amount of time for which a pixel is emitting light.
+      </li>
+      <li>[C-1-19] MUST support Bluetooth 4.2 and Bluetooth LE Data Length Extension <a href="#7_4_3_bluetooth">section 7.4.3</a>.
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to support <code>android.hardware.sensor.hifi_sensors</code> feature and MUST meet the gyroscope, accelerometer, and magnetometer related requirements for <code>android.hardware.hifi_sensors</code>.
+      </li>
+      <li>MAY provide an exclusive core to the foreground application and MAY support the <code>Process.getExclusiveCores</code> API to return the numbers of the cpu cores that are exclusive to the top foreground application. If exclusive core is supported then the core MUST not allow any other userspace processes to run on it (except device drivers used by the application), but MAY allow some kernel processes to run as necessary.
+      </li>
+    </ul>
+    <h2 id="8_performance_and_power">
+      8. Performance and Power
+    </h2>
+    <p>
+      Some minimum performance and power criteria are critical to the user experience and impact the baseline assumptions developers would have when developing an app.
+    </p>
+    <h3 id="8_1_user_experience_consistency">
+      8.1. User Experience Consistency
+    </h3>
+    <p>
+      A smooth user interface can be provided to the end user if there are certain minimum requirements to ensure a consistent frame rate and response times for applications and games. Device implementations, depending on the device type, MAY have measurable requirements for the user interface latency and task switching as described in <a href="#2_device-types">section 2</a>.
+    </p>
+    <h3 id="8_2_file_i/o_access_performance">
+      8.2. File I/O Access Performance
+    </h3>
+    <p>
+      Providing a common baseline for a consistent file access performance on the application private data storage (<code>/data</code> partition) allows app developers to set a proper expectation that would help their software design. Device implementations, depending on the device type, MAY have certain requirements described in <a href="#2_device-type">section 2</a> for the following read and write operations:
+    </p>
+    <ul>
+      <li>
+        <strong>Sequential write performance</strong>. Measured by writing a 256MB file using 10MB write buffer.
+      </li>
+      <li>
+        <strong>Random write performance</strong>. Measured by writing a 256MB file using 4KB write buffer.
+      </li>
+      <li>
+        <strong>Sequential read performance</strong>. Measured by reading a 256MB file using 10MB write buffer.
+      </li>
+      <li>
+        <strong>Random read performance</strong>. Measured by reading a 256MB file using 4KB write buffer.
+      </li>
+    </ul>
+    <h3 id="8_3_power-saving_modes">
+      8.3. Power-Saving Modes
+    </h3>
+    <p>
+      Android includes App Standby and Doze power-saving modes to optimize battery usage. <em>[SR] All Apps exempted from these modes are STRONGLY RECOMMENDED to be made visible to the end user.</em> [SR] The triggering, maintenance, wakeup algorithms and the use of global system settings of these power-saving modes are STRONGLY RECOMMENDED NOT to deviate from the Android Open Source Project.
+    </p>
+    <p>
+      In addition to the power-saving modes, Android device implementations MAY implement any or all of the 4 sleeping power states as defined by the Advanced Configuration and Power Interface (ACPI).
+    </p>
+    <p>
+      If device implementations implements S3 and S4 power states as defined by the ACPI, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST only enter these states when closing a lid that is physically part of the device.
+      </li>
+    </ul>
+    <h3 id="8_4_power_consumption_accounting">
+      8.4. Power Consumption Accounting
+    </h3>
+    <p>
+      A more accurate accounting and reporting of the power consumption provides the app developer both the incentives and the tools to optimize the power usage pattern of the application.
+    </p>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>[SR] STRONGLY RECOMMENDED to provide a per-component power profile that defines the <a href="http://source.android.com/devices/tech/power/values.html">current consumption value</a> for each hardware component and the approximate battery drain caused by the components over time as documented in the Android Open Source Project site.
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to report all power consumption values in milliampere hours (mAh).
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to report CPU power consumption per each process's UID. The Android Open Source Project meets the requirement through the <code>uid_cputime</code> kernel module implementation.
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to make this power usage available via the <a href="http://source.android.com/devices/tech/power/batterystats.html"><code>adb shell dumpsys batterystats</code></a> shell command to the app developer.
+      </li>
+      <li>SHOULD be attributed to the hardware component itself if unable to attribute hardware component power usage to an application.
+      </li>
+    </ul>
+    <h3 id="8_5_consistent_performance">
+      8.5. Consistent Performance
+    </h3>
+    <p>
+      Performance can fluctuate dramatically for high-performance long-running apps, either because of the other apps running in the background or the CPU throttling due to temperature limits. Android includes programmatic interfaces so that when the device is capable, the top foreground application can request that the system optimize the allocation of the resources to address such fluctuations.
+    </p>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-0-1] MUST report the support of Sustained Performance Mode accurately through the <a href="https://developer.android.com/reference/android/os/PowerManager.html#isSustainedPerformanceModeSupported%28%29"><code>PowerManager.isSustainedPerformanceModeSupported()</code></a> API method.
+        </p>
+      </li>
+      <li>
+        <p>
+          SHOULD support Sustained Performance Mode.
+        </p>
+      </li>
+    </ul>
+    <p>
+      If device implementations report support of Sustained Performance Mode, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST provide the top foreground application a consistent level of performance for at least 30 minutes, when the app requests it.
+      </li>
+      <li>[C-1-2] MUST honor the <a href="https://developer.android.com/reference/android/view/Window.html#setSustainedPerformanceMode%28boolean%29"><code>Window.setSustainedPerformanceMode()</code></a> API and other related APIs.
+      </li>
+    </ul>
+    <p>
+      If device implementations include two or more CPU cores, they:
+    </p>
+    <ul>
+      <li>SHOULD provide at least one exclusive core that can be reserved by the top foreground application.
+      </li>
+    </ul>
+    <p>
+      If device implementations support reserving one exclusive core for the top foreground application, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST report through the <a href="https://developer.android.com/reference/android/os/Process.html#getExclusiveCores%28%29"><code>Process.getExclusiveCores()</code></a> API method the ID numbers of the exclusive cores that can be reserved by the top foreground application.
+      </li>
+      <li>[C-2-2] MUST not allow any user space processes except the device drivers used by the application to run on the exclusive cores, but MAY allow some kernel processes to run as necessary.
+      </li>
+    </ul>
+    <p>
+      If device implementations do not support an exclusive core, they:
+    </p>
+    <ul>
+      <li>[C-3-1] MUST return an empty list through the <a href="https://developer.android.com/reference/android/os/Process.html#getExclusiveCores%28%29"><code>Process.getExclusiveCores()</code></a> API method.
+      </li>
+    </ul>
+    <h2 id="9_security_model_compatibility">
+      9. Security Model Compatibility
+    </h2>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-0-1] MUST implement a security model consistent with the Android platform security model as defined in <a href="http://developer.android.com/guide/topics/security/permissions.html">Security and Permissions reference document</a> in the APIs in the Android developer documentation.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-0-2] MUST support installation of self-signed applications without requiring any additional permissions/certificates from any third parties/authorities. Specifically, compatible devices MUST support the security mechanisms described in the follow subsections.
+        </p>
+      </li>
+    </ul>
+    <h3 id="9_1_permissions">
+      9.1. Permissions
+    </h3>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-0-1] MUST support the <a href="http://developer.android.com/guide/topics/security/permissions.html">Android permissions model</a> as defined in the Android developer documentation. Specifically, they MUST enforce each permission defined as described in the SDK documentation; no permissions may be omitted, altered, or ignored.
+        </p>
+      </li>
+      <li>
+        <p>
+          MAY add additional permissions, provided the new permission ID strings are not in the <code>android.\*</code> namespace.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-0-2] Permissions with a <code>protectionLevel</code> of <a href="https://developer.android.com/reference/android/content/pm/PermissionInfo.html#PROTECTION&amp;lowbar;FLAG&amp;lowbar;PRIVILEGED"><code>PROTECTION_FLAG_PRIVILEGED</code></a> MUST only be granted to apps preloaded in the privileged path(s) of the system image and within the subset of the explicitly whitelisted permissions for each app. The AOSP implementation meets this requirement by reading and honoring the whitelisted permissions for each app from the files in the <code>etc/permissions/</code> path and using the <code>system/priv-app</code> path as the privileged path.
+        </p>
+      </li>
+    </ul>
+    <p>
+      Permissions with a protection level of dangerous are runtime permissions. Applications with <code>targetSdkVersion</code> &gt; 22 request them at runtime.
+    </p>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-3] MUST show a dedicated interface for the user to decide whether to grant the requested runtime permissions and also provide an interface for the user to manage runtime permissions.
+      </li>
+      <li>[C-0-4] MUST have one and only one implementation of both user interfaces.
+      </li>
+      <li>[C-0-5] MUST NOT grant any runtime permissions to preinstalled apps unless:
+      </li>
+      <li>the user's consent can be obtained before the application uses it
+      </li>
+      <li>the runtime permissions are associated with an intent pattern for which the preinstalled application is set as the default handler
+      </li>
+    </ul>
+    <p>
+      If device implementations include a pre-installed app or wish to allow third-party apps to access the usage statistics, they:
+    </p>
+    <ul>
+      <li>[C-1-1] are STRONGLY RECOMMENDED provide user-accessible mechanism to grant or revoke access to the usage stats in response to the <a href="https://developer.android.com/reference/android/provider/Settings.html#ACTION&amp;lowbar;USAGE&amp;lowbar;ACCESS&amp;lowbar;SETTINGS"><code>android.settings.ACTION_USAGE_ACCESS_SETTINGS</code></a> intent for apps that declare the <code>android.permission.PACKAGE_USAGE_STATS</code> permission.
+      </li>
+    </ul>
+    <p>
+      If device implementations intend to disallow any apps, including pre-installed apps, from accessing the usage statistics, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST still have an activity that handles the <a href="https://developer.android.com/reference/android/provider/Settings.html#ACTION&amp;lowbar;USAGE&amp;lowbar;ACCESS&amp;lowbar;SETTINGS"><code>android.settings.ACTION_USAGE_ACCESS_SETTINGS</code></a> intent pattern but MUST implement it as a no-op, that is to have an equivalent behavior as when the user is declined for access.
+      </li>
+    </ul>
+    <h3 id="9_2_uid_and_process_isolation">
+      9.2. UID and Process Isolation
+    </h3>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST support the Android application sandbox model, in which each application runs as a unique Unixstyle UID and in a separate process.
+      </li>
+      <li>[C-0-2] MUST support running multiple applications as the same Linux user ID, provided that the applications are properly signed and constructed, as defined in the <a href="http://developer.android.com/guide/topics/security/permissions.html">Security and Permissions reference</a>.
+      </li>
+    </ul>
+    <h3 id="9_3_filesystem_permissions">
+      9.3. Filesystem Permissions
+    </h3>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST support the Android file access permissions model as defined in the <a href="http://developer.android.com/guide/topics/security/permissions.html">Security and Permissions reference</a>.
+      </li>
+    </ul>
+    <h3 id="9_4_alternate_execution_environments">
+      9.4. Alternate Execution Environments
+    </h3>
+    <p>
+      Device implementations MUST keep consistency of the Android security and permission model, even if they include runtime environments that execute applications using some other software or technology than the Dalvik Executable Format or native code. In other words:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-0-1] Alternate runtimes MUST themselves be Android applications, and abide by the standard Android security model, as described elsewhere in <a href="#9_security_model_compatibility">section 9</a>.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-0-2] Alternate runtimes MUST NOT be granted access to resources protected by permissions not requested in the runtime’s <code>AndroidManifest.xml</code> file via the &lt;<code>uses-permission</code>&gt; mechanism.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-0-3] Alternate runtimes MUST NOT permit applications to make use of features protected by Android permissions restricted to system applications.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-0-4] Alternate runtimes MUST abide by the Android sandbox model and installed applications using an alternate runtime MUST NOT reuse the sandbox of any other app installed on the device, except through the standard Android mechanisms of shared user ID and signing certificate.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-0-5] Alternate runtimes MUST NOT launch with, grant, or be granted access to the sandboxes corresponding to other Android applications.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-0-6] Alternate runtimes MUST NOT be launched with, be granted, or grant to other applications any privileges of the superuser (root), or of any other user ID.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-0-7] When the <code>.apk</code> files of alternate runtimes are included in the system image of device implementations, it MUST be signed with a key distinct from the key used to sign other applications included with the device implementations.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-0-8] When installing applications, alternate runtimes MUST obtain user consent for the Android permissions used by the application.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-0-9] When an application needs to make use of a device resource for which there is a corresponding Android permission (such as Camera, GPS, etc.), the alternate runtime MUST inform the user that the application will be able to access that resource.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-0-10] When the runtime environment does not record application capabilities in this manner, the runtime environment MUST list all permissions held by the runtime itself when installing any application using that runtime.
+        </p>
+      </li>
+      <li>
+        <p>
+          Alternate runtimes SHOULD install apps via the <code>PackageManager</code> into separate Android sandboxes (Linux user IDs, etc.).
+        </p>
+      </li>
+      <li>
+        <p>
+          Alternate runtimes MAY provide a single Android sandbox shared by all applications using the alternate runtime.
+        </p>
+      </li>
+    </ul>
+    <h3 id="9_5_multi-user_support">
+      9.5. Multi-User Support
+    </h3>
+    <p>
+      Android includes <a href="http://developer.android.com/reference/android/os/UserManager.html">support for multiple users</a> and provides support for full user isolation.
+    </p>
+    <ul>
+      <li>Device implementations MAY but SHOULD NOT enable multi-user if they use <a href="http://developer.android.com/reference/android/os/Environment.html">removable media</a> for primary external storage.
+      </li>
+    </ul>
+    <p>
+      If device implementations include multiple users, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST meet the following requirements related to <a href="http://source.android.com/devices/storage/traditional.html">multi-user support</a>.
+      </li>
+      <li>[C-1-2] MUST, for each user, implement a security model consistent with the Android platform security model as defined in <a href="http://developer.android.com/guide/topics/security/permissions.html">Security and Permissions reference document</a> in the APIs.
+      </li>
+      <li>[C-1-3] MUST have separate and isolated shared application storage (a.k.a. <code>/sdcard</code>) directories for each user instance.
+      </li>
+      <li>[C-1-4] MUST ensure that applications owned by and running on behalf a given user cannot list, read, or write to the files owned by any other user, even if the data of both users are stored on the same volume or filesystem.
+      </li>
+      <li>[C-1-5] MUST encrypt the contents of the SD card when multiuser is enabled using a key stored only on non-removable media accessible only to the system if device implementations use removable media for the external storage APIs. As this will make the media unreadable by a host PC, device implementations will be required to switch to MTP or a similar system to provide host PCs with access to the current user’s data.
+      </li>
+    </ul>
+    <p>
+      If device implementations include multiple users and do not declare the <code>android.hardware.telephony</code> feature flag, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST support restricted profiles, a feature that allows device owners to manage additional users and their capabilities on the device. With restricted profiles, device owners can quickly set up separate environments for additional users to work in, with the ability to manage finer-grained restrictions in the apps that are available in those environments.
+      </li>
+    </ul>
+    <p>
+      If device implementations include multiple users and declare the <code>android.hardware.telephony</code> feature flag, they:
+    </p>
+    <ul>
+      <li>[C-3-1] MUST NOT support restricted profiles but MUST align with the AOSP implementation of controls to enable /disable other users from accessing the voice calls and SMS.
+      </li>
+    </ul>
+    <h3 id="9_6_premium_sms_warning">
+      9.6. Premium SMS Warning
+    </h3>
+    <p>
+      Android includes support for warning users of any outgoing <a href="http://en.wikipedia.org/wiki/Short_code">premium SMS message</a>. Premium SMS messages are text messages sent to a service registered with a carrier that may incur a charge to the user.
+    </p>
+    <p>
+      If device implementations declare support for <code>android.hardware.telephony</code>, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST warn users before sending a SMS message to numbers identified by regular expressions defined in <code>/data/misc/sms/codes.xml</code> file in the device. The upstream Android Open Source Project provides an implementation that satisfies this requirement.
+      </li>
+    </ul>
+    <h3 id="9_7_kernel_security_features">
+      9.7. Kernel Security Features
+    </h3>
+    <p>
+      The Android Sandbox includes features that use the Security-Enhanced Linux (SELinux) mandatory access control (MAC) system, seccomp sandboxing, and other security features in the Linux kernel. Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST maintain compatibility with existing applications, even when SELinux or any other security features are implemented below the Android framework.
+      </li>
+      <li>[C-0-2] MUST NOT have a visible user interface when a security violation is detected and successfully blocked by the security feature implemented below the Android framework, but MAY have a visible user interface when an unblocked security violation occurs resulting in a successful exploit.
+      </li>
+      <li>[C-0-3] MUST NOT make SELinux or any other security features implemented below the Android framework configurable to the user or app developer.
+      </li>
+      <li>[C-0-4] MUST NOT allow an application that can affect another application through an API (such as a Device Administration API) to configure a policy that breaks compatibility.
+      </li>
+      <li>[C-0-5] MUST split the media framework into multiple processes so that it is possible to more narrowly grant access for each process as <a href="https://source.android.com/devices/media/framework-hardening.html#arch_changes">described</a> in the Android Open Source Project site.
+      </li>
+      <li>[C-0-6] MUST implement a kernel application sandboxing mechanism which allows filtering of system calls using a configurable policy from multithreaded programs. The upstream Android Open Source Project meets this requirement through enabling the seccomp-BPF with threadgroup synchronization (TSYNC) as described <a href="http://source.android.com/devices/tech/config/kernel.html#Seccomp-BPF-TSYNC">in the Kernel Configuration section of source.android.com</a>.
+      </li>
+    </ul>
+    <p>
+      Kernel integrity and self-protection features are integral to Android security. Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-7] MUST implement kernel stack buffer overflow protections (e.g. <code>CONFIG_CC_STACKPROTECTOR_STRONG</code>).
+      </li>
+      <li>[C-0-8] MUST implement strict kernel memory protections where executable code is read-only, read-only data is non-executable and non-writable, and writable data is non-executable (e.g. <code>CONFIG_DEBUG_RODATA</code> or <code>CONFIG_STRICT_KERNEL_RWX</code>).
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to keep kernel data which is written only during initialization marked read-only after initialization (e.g. <code>__ro_after_init</code>).
+      </li>
+      <li>[SR} STRONGLY RECOMMENDED to implement static and dynamic object size bounds checking of copies between user-space and kernel-space (e.g. <code>CONFIG_HARDENED_USERCOPY</code>).
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to never execute user-space memory when running in the kernel (e.g. hardware PXN, or emulated via <code>CONFIG_CPU_SW_DOMAIN_PAN</code> or <code>CONFIG_ARM64_SW_TTBR0_PAN</code>).
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to never read or write user-space memory in the kernel outside of normal usercopy access APIs (e.g. hardware PAN, or emulated via <code>CONFIG_CPU_SW_DOMAIN_PAN</code> or <code>CONFIG_ARM64_SW_TTBR0_PAN</code>).
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to randomize the layout of the kernel code and memory, and to avoid exposures that would compromise the randomization (e.g. <code>CONFIG_RANDOMIZE_BASE</code> with bootloader entropy via the <a href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/chosen.txt"><code>/chosen/kaslr-seed Device Tree node</code></a> or <a href="https://docs.microsoft.com/en-us/windows-hardware/drivers/bringup/efi-rng-protocol"><code>EFI_RNG_PROTOCOL</code></a>).
+      </li>
+    </ul>
+    <p>
+      If device implementations use a Linux kernel, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST implement SELinux.
+      </li>
+      <li>[C-1-2] MUST set SELinux to global enforcing mode.
+      </li>
+      <li>[C-1-3] MUST configure all domains in enforcing mode. No permissive mode domains are allowed, including domains specific to a device/vendor.
+      </li>
+      <li>[C-1-4] MUST NOT modify, omit, or replace the neverallow rules present within the system/sepolicy folder provided in the upstream Android Open Source Project (AOSP) and the policy MUST compile with all neverallow rules present, for both AOSP SELinux domains as well as device/vendor specific domains.
+      </li>
+      <li>SHOULD retain the default SELinux policy provided in the system/sepolicy folder of the upstream Android Open Source Project and only further add to this policy for their own device-specific configuration.
+      </li>
+    </ul>
+    <p>
+      If device implementations use kernel other than Linux, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST use an mandatory access control system that is equivalent to SELinux.
+      </li>
+    </ul>
+    <h3 id="9_8_privacy">
+      9.8. Privacy
+    </h3>
+    <h4 id="9_8_1_usage_history">
+      9.8.1. Usage History
+    </h4>
+    <p>
+      Android stores the history of the user's choices and manages such history by <a href="https://developer.android.com/reference/android/app/usage/UsageStatsManager.html">UsageStatsManager</a>.
+    </p>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST keep a reasonable retention period of such user history.
+      </li>
+      <li>[SR] Are STRONGLY RECOMMENDED to keep the 14 days retention period as configured by default in the AOSP implementation.
+      </li>
+    </ul>
+    <h4 id="9_8_2_recording">
+      9.8.2. Recording
+    </h4>
+    <p>
+      If device implementations include functionality in the system that captures the contents displayed on the screen and/or records the audio stream played on the device, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST have an ongoing notification to the user whenever this functionality is enabled and actively capturing/recording.
+      </li>
+    </ul>
+    <p>
+      If device implementations include a component enabled out-of-box, capable of recording ambient audio to infer useful information about user’s context, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST NOT store in persistent on-device storage or transmit off the device the recorded raw audio or any format that can be converted back into the original audio or a near facsimile, except with explicit user consent.
+      </li>
+    </ul>
+    <h4 id="9_8_3_connectivity">
+      9.8.3. Connectivity
+    </h4>
+    <p>
+      If device implementations have a USB port with USB peripheral mode support, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST present a user interface asking for the user's consent before allowing access to the contents of the shared storage over the USB port.
+      </li>
+    </ul>
+    <h4 id="9_8_4_network_traffic">
+      9.8.4. Network Traffic
+    </h4>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST preinstall the same root certificates for the system-trusted Certificate Authority (CA) store as <a href="https://source.android.com/security/overview/app-security.html#certificate-authorities">provided</a> in the upstream Android Open Source Project.
+      </li>
+      <li>[C-0-2] MUST ship with an empty user root CA store.
+      </li>
+      <li>[C-0-3] MUST display a warning to the user indicating the network traffic may be monitored, when a user root CA is added.
+      </li>
+    </ul>
+    <p>
+      If device traffic is routed through a VPN, device implementations:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST display a warning to the user indicating either:
+        <ul>
+          <li>That network traffic may be monitored.
+          </li>
+          <li>That network traffic is being routed through the specific VPN application providing the VPN.
+          </li>
+        </ul>
+      </li>
+    </ul>
+    <p>
+      If device implementations have a mechanism, enabled out-of-box by default, that routes network data traffic through a proxy server or VPN gateway (for example, preloading a VPN service with <code>android.permission.CONTROL_VPN</code> granted), they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST ask for the user's consent before enabling that mechanism, unless that VPN is enabled by the Device Policy Controller via the <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#setAlwaysOnVpnPackage%28android.content.ComponentName,%20java.lang.String,%20boolean%29"><code>DevicePolicyManager.setAlwaysOnVpnPackage()</code></a> , in which case the user does not need to provide a separate consent, but MUST only be notified.
+      </li>
+    </ul>
+    <h3 id="9_9_data_storage_encryption">
+      9.9. Data Storage Encryption
+    </h3>
+    <p>
+      If device implementations support a secure lock screen as described in <a href="#9_11_1_secure_lock_screen">section 9.11.1</a>, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support data storage encryption of the application private data (<code>/data partition</code>), as well as the application shared storage partition (<code>/sdcard partition</code>) if it is a permanent, non-removable part of the device.
+      </li>
+    </ul>
+    <p>
+      If device implementations support a secure lock screen as described in <a href="#9_11_1_secure_lock_screen">section 9.11.1</a> and support data storage encryption with Advanced Encryption Standard (AES) crypto performance above 50MiB/sec, they:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-2-1] MUST enable the data storage encryption by default at the time the user has completed the out-of-box setup experience. If device implementations are already launched on an earlier Android version with encryption disabled by default, such a device cannot meet the requirement through a system software update and thus MAY be exempted.
+        </p>
+      </li>
+      <li>
+        <p>
+          SHOULD meet the above data storage encryption requirement via implementing <a href="https://source.android.com/security/encryption/file-based.html">File Based Encryption</a> (FBE).
+        </p>
+      </li>
+    </ul>
+    <h4 id="9_9_1_direct_boot">
+      9.9.1. Direct Boot
+    </h4>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-0-1] MUST implement the <a href="http://developer.android.com/preview/features/direct-boot.html">Direct Boot mode</a> APIs even if they do not support Storage Encryption.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-0-2] The <a href="https://developer.android.com/reference/android/content/Intent.html#ACTION_LOCKED_BOOT_COMPLETED"><code>ACTION_LOCKED_BOOT_COMPLETED</code></a> and <a href="https://developer.android.com/reference/android/content/Intent.html#ACTION_USER_UNLOCKED"><code>ACTION_USER_UNLOCKED</code></a> Intents MUST still be broadcast to signal Direct Boot aware applications that Device Encrypted (DE) and Credential Encrypted (CE) storage locations are available for user.
+        </p>
+      </li>
+    </ul>
+    <h4 id="9_9_2_file_based_encryption">
+      9.9.2. File Based Encryption
+    </h4>
+    <p>
+      If device implementations support FBE, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST boot up without challenging the user for credentials and allow Direct Boot aware apps to access to the Device Encrypted (DE) storage after the <code>ACTION_LOCKED_BOOT_COMPLETED</code> message is broadcasted.
+      </li>
+      <li>[C-1-2] MUST only allow access to Credential Encrypted (CE) storage after the user has unlocked the device by supplying their credentials (eg. passcode, pin, pattern or fingerprint) and the <code>ACTION_USER_UNLOCKED</code> message is broadcasted.
+      </li>
+      <li>[C-1-3] MUST NOT offer any method to unlock the CE protected storage without the user-supplied credentials.
+      </li>
+      <li>[C-1-4] MUST support Verified Boot and ensure that DE keys are cryptographically bound to the device's hardware root of trust.
+      </li>
+      <li>[C-1-5] MUST support encrypting file contents using AES with a key length of 256-bits in XTS mode.
+      </li>
+      <li>
+        <p>
+          [C-1-6] MUST support encrypting file name using AES with a key length of 256-bits in CBC-CTS mode.
+        </p>
+      </li>
+      <li>
+        <p>
+          The keys protecting CE and DE storage areas:
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-1-7] MUST be cryptographically bound to a hardware-backed Keystore.
+        </p>
+      </li>
+      <li>[C-1-8] CE keys MUST be bound to a user's lock screen credentials.
+      </li>
+      <li>[C-1-9] CE keys MUST be bound to a default passcode when the user has not specified lock screen credentials.
+      </li>
+      <li>
+        <p>
+          [C-1-10] MUST be unique and distinct, in other words no user's CE or DE key matches any other user's CE or DE keys.
+        </p>
+      </li>
+      <li>
+        <p>
+          SHOULD make preloaded essential apps (e.g. Alarm, Phone, Messenger) Direct Boot aware.
+        </p>
+      </li>
+      <li>MAY support alternative ciphers, key lengths and modes for file content and file name encryption, but MUST use the mandatorily supported ciphers, key lengths and modes by default.
+      </li>
+    </ul>
+    <p>
+      The upstream Android Open Source project provides a preferred implementation of this feature based on the Linux kernel ext4 encryption feature.
+    </p>
+    <h4 id="9_9_3_full_disk_encryption">
+      9.9.3. Full Disk Encryption
+    </h4>
+    <p>
+      If device implementations support <a href="http://source.android.com/devices/tech/security/encryption/index.html">full disk encryption</a> (FDE), they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST use AES with a key of 128-bits (or greater) and a mode designed for storage (for example, AES-XTS, AES-CBC-ESSIV).
+      </li>
+      <li>[C-1-2] MUST use a default passcode to wrap the encryption key and MUST NOT write the encryption key to storage at any time without being encrypted.
+      </li>
+      <li>[C-1-3] MUST provide the user the possibility to AES encrypt the encryption key, except when it is in active use, with the lock screen credentials stretched using a slow stretching algorithm (e.g. PBKDF2 or scrypt).
+      </li>
+      <li>[C-1-4] The above default password stretching algorithm MUST be cryptographically bound to that keystore when the user has not specified a lock screen credentials or has disabled use of the passcode for encryption and the device provides a hardware-backed keystore.
+      </li>
+      <li>[C-1-5] MUST NOT send encryption key off the device (even when wrapped with the user passcode and/or hardware bound key).
+      </li>
+    </ul>
+    <p>
+      The upstream Android Open Source project provides a preferred implementation of this feature, based on the Linux kernel feature dm-crypt.
+    </p>
+    <h3 id="9_10_device_integrity">
+      9.10. Device Integrity
+    </h3>
+    <p>
+      The following requirements ensures there is transparancy to the status of the device integrity. Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST correctly report through the System API method <code>PersistentDataBlockManager.getFlashLockState()</code> whether their bootloader state permits flashing of the system image. The <code>FLASH_LOCK_UNKNOWN</code> state is reserved for device implementations upgrading from an earlier version of Android where this new system API method did not exist.
+      </li>
+    </ul>
+    <p>
+      Verified boot is a feature that guarantees the integrity of the device software. If a device implementation supports the feature, it:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST declare the platform feature flag <code>android.software.verified_boot</code>.
+      </li>
+      <li>[C-2-1] MUST perform verification on every boot sequence.
+      </li>
+      <li>[C-3-1] MUST start verification from an immutable hardware key that is the root of trust and go all the way up to the system partition.
+      </li>
+      <li>[C-4-1] MUST implement each stage of verification to check the integrity and authenticity of all the bytes in the next stage before executing the code in the next stage.
+      </li>
+      <li>[C-5-1] MUST use verification algorithms as strong as current recommendations from NIST for hashing algorithms (SHA-256) and public key sizes (RSA-2048).
+      </li>
+      <li>[C-6-1] MUST NOT allow boot to complete when system verification fails, unless the user consents to attempt booting anyway, in which case the data from any non-verified storage blocks MUST not be used.
+      </li>
+      <li>[C-7-1] MUST NOT allow verified partitions on the device to be modified unless the user has explicitly unlocked the boot loader.
+      </li>
+      <li>[SR] If there are multiple discrete chips in the device (e.g. radio, specialized image processor), the boot process of each of those chips is STRONGLY RECOMMENDED to verify every stage upon booting.
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to use tamper-evident storage: for when the bootloader is unlocked. Tamper-evident storage means that the boot loader can detect if the storage has been tampered with from inside the HLOS (High Level Operating System).
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to prompt the user, while using the device, and require physical confirmation before allowing a transition from boot loader locked mode to boot loader unlocked mode.
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to implement rollback protection for the HLOS (e.g. boot, system partitions) and to use tamper-evident storage for storing the metadata used for determining the minimum allowable OS version.
+      </li>
+      <li>SHOULD implement rollback protection for any component with persistent firmware (e.g. modem, camera) and SHOULD use tamper-evident storage for storing the metadata used for determining the minimum allowable version.
+      </li>
+    </ul>
+    <p>
+      The upstream Android Open Source Project provides a preferred implementation of this feature in the <a href="http://android.googlesource.com/platform/external/avb/"><code>external/avb/</code></a> repository, which can be integrated into the boot loader used for loading Android.
+    </p>
+    <p>
+      Device implementations with Advanced Encryption Standard (AES) crypto performance above 50 MiB/seconds:
+    </p>
+    <ul>
+      <li>[C-8-1] MUST support verified boot for device integrity.
+      </li>
+    </ul>
+    <p>
+      If a device implementation is already launched without supporting verified boot on an earlier version of Android, such a device can not add support for this feature with a system software update and thus are exempted from the requirement.
+    </p>
+    <h3 id="9_11_keys_and_credentials">
+      9.11. Keys and Credentials
+    </h3>
+    <p>
+      The <a href="https://developer.android.com/training/articles/keystore.html">Android Keystore System</a> allows app developers to store cryptographic keys in a container and use them in cryptographic operations through the <a href="https://developer.android.com/reference/android/security/KeyChain.html">KeyChain API</a> or the <a href="https://developer.android.com/reference/java/security/KeyStore.html">Keystore API</a>. Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST at least allow more than 8,192 keys to be imported.
+      </li>
+      <li>[C-0-2] The lock screen authentication MUST rate-limit attempts and MUST have an exponential backoff algorithm. Beyond 150 failed attempts, the delay MUST be at least 24 hours per attempt.
+      </li>
+      <li>SHOULD not limit the number of keys that can be generated
+      </li>
+    </ul>
+    <p>
+      When the device implementation supports a secure lock screen, it:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST back up the keystore implementation with secure hardware.
+      </li>
+      <li>[C-1-2] MUST have implementations of RSA, AES, ECDSA and HMAC cryptographic algorithms and MD5, SHA1, and SHA-2 family hash functions to properly support the Android Keystore system's supported algorithms in an area that is securely isolated from the code running on the kernel and above. Secure isolation MUST block all potential mechanisms by which kernel or userspace code might access the internal state of the isolated environment, including DMA. The upstream Android Open Source Project (AOSP) meets this requirement by using the <a href="https://source.android.com/security/trusty/">Trusty</a> implementation, but another ARM TrustZone-based solution or a third-party reviewed secure implementation of a proper hypervisor-based isolation are alternative options.
+      </li>
+      <li>[C-1-3] MUST perform the lock screen authentication in the isolated execution environment and only when successful, allow the authentication-bound keys to be used. The upstream Android Open Source Project provides the <a href="http://source.android.com/devices/tech/security/authentication/gatekeeper.html">Gatekeeper Hardware Abstraction Layer (HAL)</a> and Trusty, which can be used to satisfy this requirement.
+      </li>
+      <li>[C-1-4] MUST support key attestation where the attestation signing key is protected by secure hardware and signing is performed in secure hardware. The attestation signing keys MUST be shared across large enough number of devices to prevent the keys from being used as device identifiers. One way of meeting this requirement is to share the same attestation key unless at least 100,000 units of a given SKU are produced. If more than 100,000 units of an SKU are produced, a different key MAY be used for each 100,000 units.
+      </li>
+    </ul>
+    <p>
+      Note that if a device implementation is already launched on an earlier Android version, such a device is exempted from the requirement to have a hardware-backed keystore, unless it declares the <code>android.hardware.fingerprint</code> feature which requires a hardware-backed keystore.
+    </p>
+    <h4 id="9_11_1_secure_lock_screen">
+      9.11.1. Secure Lock Screen
+    </h4>
+    <p>
+      If device implementations have a secure lock screen and include one or more trust agent, which implements the <code>TrustAgentService</code> System API, then they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST indicate the user in the Settings and Lock screen user interface of situations where either the screen auto-lock is deferred or the screen lock can be unlocked by the trust agent. The AOSP meets the requirement by showing a text description for the "Automatically lock setting" and "Power button instantly locks setting" menus and a distinguishable icon on the lock screen.
+      </li>
+      <li>[C-1-2] MUST respect and fully implement all trust agent APIs in the <code>DevicePolicyManager</code> class, such as the <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#KEYGUARD&amp;lowbarDISABLE&amp;lowbarTRUST&amp;lowbarAGENTS"><code>KEYGUARD_DISABLE_TRUST_AGENTS</code></a> constant.
+      </li>
+      <li>[C-1-3] MUST NOT fully implement the <code>TrustAgentService.addEscrowToken()</code> function on a device that is used as the primary personal device (e.g. handheld) but MAY fully implement the function on device implementations typically shared.
+      </li>
+      <li>[C-1-4] MUST encrypt the tokens added by <code>TrustAgentService.addEscrowToken()</code> before storing them on the device.
+      </li>
+      <li>[C-1-5] MUST NOT store the encryption key on the device.
+      </li>
+      <li>[C-1-6] MUST inform the user about the security implications before enabling the escrow token to decrypt the data storage.
+      </li>
+    </ul>
+    <p>
+      If device implementations add or modify the authentication methods to unlock the lock screen, then for such an authentication method to be treated as a secure way to lock the screen, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST be the user authentication method as described in <a href="https://developer.android.com/training/articles/keystore.html#UserAuthentication">Requiring User Authentication For Key Use</a>.
+      </li>
+      <li>[C-2-2] MUST unlock all keys for a third-party developer app to use when the user unlocks the secure lock screen. For example, all keys MUST be available for a third-party developer app through relevant APIs, such as <a href="https://developer.android.com/reference/android/app/KeyguardManager.html#createConfirmDeviceCredentialIntent%28java.lang.CharSequence,%20java.lang.CharSequence%29"><code>createConfirmDeviceCredentialIntent</code></a> and <a href="https://developer.android.com/reference/android/security/keystore/KeyGenParameterSpec.Builder.html#setUserAuthenticationRequired%28boolean%29"><code>setUserAuthenticationRequired</code></a>.
+      </li>
+    </ul>
+    <p>
+      If device implementations add or modify the authentication methods to unlock the lock screen if based on a known secret then for such an authentication method to be treated as a secure way to lock the screen, they:
+    </p>
+    <ul>
+      <li>[C-3-1] The entropy of the shortest allowed length of inputs MUST be greater than 10 bits.
+      </li>
+      <li>[C-3-2] The maximum entropy of all possible inputs MUST be greater than 18 bits.
+      </li>
+      <li>[C-3-3] MUST not replace any of the existing authentication methods (PIN,pattern, password) implemented and provided in AOSP.
+      </li>
+      <li>[C-3-4] MUST be disabled when the Device Policy Controller (DPC) application has set the password quality policy via the <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#setPasswordQuality%28android.content.ComponentName,%20int%29"><code>DevicePolicyManager.setPasswordQuality()</code></a> method with a more restrictive quality constant than <code>PASSWORD_QUALITY_SOMETHING</code>.
+      </li>
+    </ul>
+    <p>
+      If device implementations add or modify the authentication methods to unlock the lock screen if based on a physical token or the location, then for such an authentication method to be treated as a secure way to lock the screen, they:
+    </p>
+    <ul>
+      <li>[C-4-1] MUST have a fall-back mechanism to use one of the primary authentication methods which is based on a known secret and meets the requirements to be treated as a secure lock screen.
+      </li>
+      <li>[C-4-2] MUST be disabled and only allow the primary authentication to unlock the screen when the Device Policy Controller (DPC) application has set the policy with either the <a href="http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#setKeyguardDisabledFeatures%28android.content.ComponentName,%20int%29"><code>DevicePolicyManager.setKeyguardDisabledFeatures(KEYGUARD_DISABLE_TRUST_AGENTS)</code></a> method or the <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#setPasswordQuality%28android.content.ComponentName,%20int%29"><code>DevicePolicyManager.setPasswordQuality()</code></a> method with a more restrictive quality constant than <code>PASSWORD_QUALITY_UNSPECIFIED</code>.
+      </li>
+      <li>[C-4-3] The user MUST be challenged for the primary authentication (e.g.PIN, pattern, password) at least once every 72 hours or less.
+      </li>
+    </ul>
+    <p>
+      If device implementations add or modify the authentication methods to unlock the lock screen based on biometrics, then for such an authentication method to be treated as a secure way to lock the screen, they:
+    </p>
+    <ul>
+      <li>[C-5-1] MUST have a fall-back mechanism to use one of the primary authentication methods which is based on a known secret and meets the requirements to be treated as a secure lock screen.
+      </li>
+      <li>[C-5-2] MUST be disabled and only allow the primary authentication to unlock the screen when the Device Policy Controller (DPC) application has set the keguard feature policy by calling the method <a href="http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#setKeyguardDisabledFeatures%28android.content.ComponentName,%20int%29"><code>DevicePolicyManager.setKeyguardDisabledFeatures(KEYGUARD_DISABLE_FINGERPRINT)</code></a>.
+      </li>
+      <li>[C-5-3] MUST have a false acceptance rate that is equal or stronger than what is required for a fingerprint sensor as described in section 7.3.10, or otherwise MUST be disabled and only allow the primary authentication to unlock the screen when the Device Policy Controller (DPC) application has set the password quality policy via the <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#setPasswordQuality%28android.content.ComponentName,%20int%29"><code>DevicePolicyManager.setPasswordQuality()</code></a> method with a more restrictive quality constant than <code>PASSWORD_QUALITY_BIOMETRIC_WEAK</code>.
+      </li>
+      <li>[C-5-4] The user MUST be challenged for the primary authentication (e.g.PIN, pattern, password) at least once every 72 hours or less.
+      </li>
+    </ul>
+    <p>
+      If device implementations add or modify the authentication methods to unlock the lock screen and if such an authentication method will be used to unlock the keyguard, but will not be treated as a secure lock screen, then they:
+    </p>
+    <ul>
+      <li>[C-6-1] MUST return <code>false</code> for both the <a href="http://developer.android.com/reference/android/app/KeyguardManager.html#isKeyguardSecure%28%29"><code>KeyguardManager.isKeyguardSecure()</code></a> and the <a href="https://developer.android.com/reference/android/app/KeyguardManager.html#isDeviceSecure%28%29"><code>KeyguardManager.isDeviceSecure()</code></a> methods.
+      </li>
+      <li>[C-6-2] MUST be disabled when the Device Policy Controller (DPC) application has set the password quality policy via the <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#setPasswordQuality%28android.content.ComponentName,%20int%29"><code>DevicePolicyManager.setPasswordQuality()</code></a> method with a more restrictive quality constant than <code>PASSWORD_QUALITY_UNSPECIFIED</code>.
+      </li>
+      <li>[C-6-3] MUST NOT reset the password expiration timers set by <a href="http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#setPasswordExpirationTimeout%28android.content.ComponentName,%20long%29"><code>DevicePolicyManager.setPasswordExpirationTimeout()</code></a>.
+      </li>
+      <li>[C-6-4] MUST NOT authenticate access to keystores if the application has called <a href="https://developer.android.com/reference/android/security/keystore/KeyGenParameterSpec.Builder.html#setUserAuthenticationRequired%28boolean%29"><code>KeyGenParameterSpec.Builder.setUserAuthenticationRequired(true)</code></a>).
+      </li>
+    </ul>
+    <h3 id="9_12_data_deletion">
+      9.12. Data Deletion
+    </h3>
+    <p>
+      All device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST provide users a mechanism to perform a "Factory Data Reset".
+      </li>
+      <li>[C-0-2] MUST delete all user-generated data. That is, all data except for the following:
+        <ul>
+          <li>The system image
+          </li>
+          <li>Any operating system files required by the system image
+          </li>
+        </ul>
+      </li>
+      <li>[C-0-3] MUST delete the data in such a way that will satisfy relevant industry standards such as NIST SP800-88.
+      </li>
+      <li>[C-0-4] MUST trigger the above "Factory Data Reset" process when the <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#wipeData%28int%29"><code>DevicePolicyManager.wipeData()</code></a> API is called by the primary user's Device Policy Controller app.
+      </li>
+      <li>MAY provide a fast data wipe option that conducts only a logical data erase.
+      </li>
+    </ul>
+    <h3 id="9_13_safe_boot_mode">
+      9.13. Safe Boot Mode
+    </h3>
+    <p>
+      Android provides Safe Boot Mode, which allows users to boot up into a mode where only preinstalled system apps are allowed to run and all third-party apps are disabled. This mode, known as "Safe Boot Mode", provides the user the capability to uninstall potentially harmful third-party apps.
+    </p>
+    <p>
+      Device implementations are:
+    </p>
+    <ul>
+      <li>[SR] STRONGLY RECOMMENDED to implement Safe Boot Mode.
+      </li>
+    </ul>
+    <p>
+      If device implementations implement Safe Boot Mode, they:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-1-1] MUST provide the user an option to enter Safe Boot Mode in such a way that is uninterruptible from third-party apps installed on the device, except when the third-party app is a Device Policy Controller and has set the <a href="https://developer.android.com/reference/android/os/UserManager.html#DISALLOW_SAFE_BOOT"><code>UserManager.DISALLOW_SAFE_BOOT</code></a> flag as true.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-1-2] MUST provide the user the capability to uninstall any third-party apps within Safe Mode.
+        </p>
+      </li>
+      <li>
+        <p>
+          SHOULD provide the user an option to enter Safe Boot Mode from the boot menu using a workflow that is different from that of a normal boot.
+        </p>
+      </li>
+    </ul>
+    <h3 id="9_14_automotive_vehicle_system_isolation">
+      9.14. Automotive Vehicle System Isolation
+    </h3>
+    <p>
+      Android Automotive devices are expected to exchange data with critical vehicle subsystems by using the <a href="http://source.android.com/devices/automotive.html">vehicle HAL</a> to send and receive messages over vehicle networks such as CAN bus.
+    </p>
+    <p>
+      The data exchange can be secured by implementing security features below the Android framework layers to prevent malicious or unintentional interaction with these subsystems.
+    </p>
+    <h2 id="10_software_compatibility_testing">
+      10. Software Compatibility Testing
+    </h2>
+    <p>
+      Device implementations MUST pass all tests described in this section.
+    </p>
+    <p>
+      However, note that no software test package is fully comprehensive. For this reason, device implementers are <strong>STRONGLY RECOMMENDED</strong> to make the minimum number of changes as possible to the reference and preferred implementation of Android available from the Android Open Source Project. This will minimize the risk of introducing bugs that create incompatibilities requiring rework and potential device updates.
+    </p>
+    <h3 id="10_1_compatibility_test_suite">
+      10.1. Compatibility Test Suite
+    </h3>
+    <p>
+      Device implementations MUST pass the <a href="http://source.android.com/compatibility/index.html">Android Compatibility Test Suite (CTS)</a> available from the Android Open Source Project, using the final shipping software on the device. Additionally, device implementers SHOULD use the reference implementation in the Android Open Source tree as much as possible, and MUST ensure compatibility in cases of ambiguity in CTS and for any reimplementations of parts of the reference source code.
+    </p>
+    <p>
+      The CTS is designed to be run on an actual device. Like any software, the CTS may itself contain bugs. The CTS will be versioned independently of this Compatibility Definition, and multiple revisions of the CTS may be released for Android 8.0. Device implementations MUST pass the latest CTS version available at the time the device software is completed.
+    </p>
+    <h3 id="10_2_cts_verifier">
+      10.2. CTS Verifier
+    </h3>
+    <p>
+      Device implementations MUST correctly execute all applicable cases in the CTS Verifier. The CTS Verifier is included with the Compatibility Test Suite, and is intended to be run by a human operator to test functionality that cannot be tested by an automated system, such as correct functioning of a camera and sensors.
+    </p>
+    <p>
+      The CTS Verifier has tests for many kinds of hardware, including some hardware that is optional. Device implementations MUST pass all tests for hardware that they possess; for instance, if a device possesses an accelerometer, it MUST correctly execute the Accelerometer test case in the CTS Verifier. Test cases for features noted as optional by this Compatibility Definition Document MAY be skipped or omitted.
+    </p>
+    <p>
+      Every device and every build MUST correctly run the CTS Verifier, as noted above. However, since many builds are very similar, device implementers are not expected to explicitly run the CTS Verifier on builds that differ only in trivial ways. Specifically, device implementations that differ from an implementation that has passed the CTS Verifier only by the set of included locales, branding, etc. MAY omit the CTS Verifier test.
+    </p>
+    <h2 id="11_updatable_software">
+      11. Updatable Software
+    </h2>
+    <p>
+      Device implementations MUST include a mechanism to replace the entirety of the system software. The mechanism need not perform “live” upgrades—that is, a device restart MAY be required.
+    </p>
+    <p>
+      Any method can be used, provided that it can replace the entirety of the software preinstalled on the device. For instance, any of the following approaches will satisfy this requirement:
+    </p>
+    <ul>
+      <li>“Over-the-air (OTA)” downloads with offline update via reboot.
+      </li>
+      <li>“Tethered” updates over USB from a host PC.
+      </li>
+      <li>“Offline” updates via a reboot and update from a file on removable storage.
+      </li>
+    </ul>
+    <p>
+      However, if the device implementation includes support for an unmetered data connection such as 802.11 or Bluetooth PAN (Personal Area Network) profile, it MUST support OTA downloads with offline update via reboot.
+    </p>
+    <p>
+      The update mechanism used MUST support updates without wiping user data. That is, the update mechanism MUST preserve application private data and application shared data. Note that the upstream Android software includes an update mechanism that satisfies this requirement.
+    </p>
+    <p>
+      For device implementations that are launching with Android 6.0 and later, the update mechanism SHOULD support verifying that the system image is binary identical to expected result following an OTA. The block-based OTA implementation in the upstream Android Open Source Project, added since Android 5.1, satisfies this requirement.
+    </p>
+    <p>
+      Also, device implementations SHOULD support <a href="https://source.android.com/devices/tech/ota/ab_updates.html">A/B system updates</a>. The AOSP implements this feature using the boot control HAL.
+    </p>
+    <p>
+      If an error is found in a device implementation after it has been released but within its reasonable product lifetime that is determined in consultation with the Android Compatibility Team to affect the compatibility of third-party applications, the device implementer MUST correct the error via a software update available that can be applied per the mechanism just described.
+    </p>
+    <p>
+      Android includes features that allow the Device Owner app (if present) to control the installation of system updates. To facilitate this, the system update subsystem for devices that report android.software.device_admin MUST implement the behavior described in the <a href="http://developer.android.com/reference/android/app/admin/SystemUpdatePolicy.html">SystemUpdatePolicy</a> class.
+    </p>
+    <h2 id="12_document_changelog">
+      12. Document Changelog
+    </h2>
+    <p>
+      For a summary of changes to the Compatibility Definition in this release:
+    </p>
+    <ul>
+      <li>
+        <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/oreo-dev/?pretty=full&amp;no-merges">Document changelog</a>
+      </li>
+    </ul>
+    <p>
+      For a summary of changes to individuals sections:
+    </p>
+    <ol>
+      <li>
+        <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/oreo-dev/1_introduction?pretty=full&amp;no-merges">Introduction</a>
+      </li>
+      <li>
+        <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/oreo-dev/2_device_types?pretty=full&amp;no-merges">Device Types</a>
+      </li>
+      <li>
+        <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/oreo-dev/3_software?pretty=full&amp;no-merges">Software</a>
+      </li>
+      <li>
+        <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/oreo-dev/4_application-packaging?pretty=full&amp;no-merges">Application Packaging</a>
+      </li>
+      <li>
+        <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/oreo-dev/5_multimedia?pretty=full&amp;no-merges">Multimedia</a>
+      </li>
+      <li>
+        <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/oreo-dev/6_dev-tools-and-options?pretty=full&amp;no-merges">Developer Tools and Options</a>
+      </li>
+      <li>
+        <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/oreo-dev/7_hardware-compatibility?pretty=full&amp;no-merges">Hardware Compatibility</a>
+      </li>
+      <li>
+        <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/oreo-dev/8_performance-and-power?pretty=full&amp;no-merges">Performance and Power</a>
+      </li>
+      <li>
+        <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/oreo-dev/9_security-model?pretty=full&amp;no-merges">Security Model</a>
+      </li>
+      <li>
+        <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/oreo-dev/10_software-compatibility-testing?pretty=full&amp;no-merges">Software Compatibility Testing</a>
+      </li>
+      <li>
+        <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/oreo-dev/11_updatable-software?pretty=full&amp;no-merges">Updatable Software</a>
+      </li>
+      <li>
+        <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/oreo-dev/12_document-changelog?pretty=full&amp;no-merges">Document Changelog</a>
+      </li>
+      <li>
+        <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/oreo-dev/13_contact-us?pretty=full&amp;no-merges">Contact Us</a>
+      </li>
+    </ol>
+    <h3 id="12_1_changelog_viewing_tips">
+      12.1. Changelog Viewing Tips
+    </h3>
+    <p>
+      Changes are marked as follows:
+    </p>
+    <ul>
+      <li>
+        <p>
+          <strong>CDD</strong><br />
+          Substantive changes to the compatibility requirements.
+        </p>
+      </li>
+      <li>
+        <p>
+          <strong>Docs</strong><br />
+          Cosmetic or build related changes.
+        </p>
+      </li>
+    </ul>
+    <p>
+      For best viewing, append the <code>pretty=full</code> and <code>no-merges</code> URL parameters to your changelog URLs.
+    </p>
+    <h2 id="13_contact_us">
+      13. Contact Us
+    </h2>
+    <p>
+      You can join the <a href="https://groups.google.com/forum/#!forum/android-compatibility">android-compatibility forum</a> and ask for clarifications or bring up any issues that you think the document does not cover.
+    </p>
+  </body>
+</html>
diff --git a/en/compatibility/8.0/versions.html b/en/compatibility/8.0/versions.html
new file mode 100644
index 0000000..612d2f9
--- /dev/null
+++ b/en/compatibility/8.0/versions.html
@@ -0,0 +1,43 @@
+<html devsite>
+  <head>
+    <title>Permitted Version Strings for Android 8.0</title>
+    <meta name="project_path" value="/_project.yaml" />
+    <meta name="book_path" value="/_book.yaml" />
+  </head>
+  <body>
+  <!--
+      Copyright 2017 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>As described in Section 3.2.2 of the <a
+href="android-8.0-cdd.pdf">Android 8.0 Compatibility Definition</a>,
+only certain strings are allowable for the system property
+<code>android.os.Build.VERSION.RELEASE</code>. The reason for this is that
+applications and web sites may rely on predictable values for this string, and
+so that end users can easily and reliably identify the version of Android
+running on their devices.</p>
+<p>Because subsequent releases of the Android software may revise this string,
+but not change any API behavior, such releases may not be accompanied by a new
+Compatibility Definition Document. This page lists the versions that are
+allowable by an Android 8.0-based system. The only permitted values for
+<code>android.os.Build.VERSION.RELEASE</code> for Android 8.0 are:</p>
+<ul>
+<li>8.0</li>
+</ul>
+
+  </body>
+</html>
diff --git a/en/compatibility/android-7.1-cdd.html b/en/compatibility/android-7.1-cdd.html
deleted file mode 100644
index 91aef4f..0000000
--- a/en/compatibility/android-7.1-cdd.html
+++ /dev/null
@@ -1,7086 +0,0 @@
-<html xmlns="http://www.w3.org/1999/xhtml">
-  <head>
-    <title>
-      Android 7.0, (N) Compatibility Definition
-    </title>
-    <link href="source/android-cdd.css" rel="stylesheet" type="text/css" />
-    <meta charset="utf-8" />
-  </head>
-  <body>
-    <h6>
-      Table of Contents
-    </h6>
-    <div id="toc">
-      <div id="toc_left">
-        <p class="toc_h1">
-          <a href="#1_introduction">1. Introduction</a>
-        </p>
-        <p class="toc_h1">
-          <a href="#2_device_types">2. Device Types</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#2_1_device_configurations">2.1 Device Configurations</a>
-        </p>
-        <p class="toc_h1">
-          <a href="#3_software">3. Software</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#3_1_managed_api_compatibility">3.1. Managed API Compatibility</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#3_1_1_android_extensions">3.1.1. Android Extensions</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#3_2_soft_api_compatibility">3.2. Soft API Compatibility</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#3_2_1_permissions">3.2.1. Permissions</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#3_2_2_build_parameters">3.2.2. Build Parameters</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#3_2_3_intent_compatibility">3.2.3. Intent Compatibility</a>
-        </p>
-        <p class="toc_h4">
-          <a href="#3_2_3_1_core_application_intents">3.2.3.1. Core Application Intents</a>
-        </p>
-        <p class="toc_h4">
-          <a href="#3_2_3_2_intent_resolution">3.2.3.2. Intent Resolution</a>
-        </p>
-        <p class="toc_h4">
-          <a href="#3_2_3_3_intent_namespaces">3.2.3.3. Intent Namespaces</a>
-        </p>
-        <p class="toc_h4">
-          <a href="#3_2_3_4_broadcast_intents">3.2.3.4. Broadcast Intents</a>
-        </p>
-        <p class="toc_h4">
-          <a href="#3_2_3_5_default_app_settings">3.2.3.5. Default App Settings</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#3_3_native_api_compatibility">3.3. Native API Compatibility</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#3_3_1_application_binary_interfaces">3.3.1. Application Binary Interfaces</a>
-        </p>
-        <p class="toc_h4">
-          <a href="#3_3_1_1_graphic_libraries">3.3.1.1. Graphic Libraries</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#3_3_2_32-bit_arm_native_code_compatibility">3.3.2. 32-bit ARM Native Code Compatibility</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#3_4_web_compatibility">3.4. Web Compatibility</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#3_4_1_webview_compatibility">3.4.1. WebView Compatibility</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#3_4_2_browser_compatibility">3.4.2. Browser Compatibility</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#3_5_api_behavioral_compatibility">3.5. API Behavioral Compatibility</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#3_6_api_namespaces">3.6. API Namespaces</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#3_7_runtime_compatibility">3.7. Runtime Compatibility</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#3_8_user_interface_compatibility">3.8. User Interface Compatibility</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#3_8_1_launcher_(home_screen)">3.8.1. Launcher (Home Screen)</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#3_8_2_widgets">3.8.2. Widgets</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#3_8_3_notifications">3.8.3. Notifications</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#3_8_4_search">3.8.4. Search</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#3_8_5_toasts">3.8.5. Toasts</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#3_8_6_themes">3.8.6. Themes</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#3_8_7_live_wallpapers">3.8.7. Live Wallpapers</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#3_8_8_activity_switching">3.8.8. Activity Switching</a>
-        </p>
-      </div>
-      <div id="toc_right">
-        <p class="toc_h3">
-          <a href="#3_8_9_input_management">3.8.9. Input Management</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#3_8_10_lock_screen_media_control">3.8.10. Lock Screen Media Control</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#3_8_11_screen_savers_(previously_dreams)">3.8.11. Screen savers (previously Dreams)</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#3_8_12_location">3.8.12. Location</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#3_8_13_unicode_and_font">3.8.13. Unicode and Font</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#3_8_14_multi-windows">3.8.14. Multi-windows</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#3_9_device_administration">3.9. Device Administration</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#3_9_1_device_provisioning">3.9.1 Device Provisioning</a>
-        </p>
-        <p class="toc_h4">
-          <a href="#3_9_1_1_device_owner_provisioning">3.9.1.1 Device owner provisioning</a>
-        </p>
-        <p class="toc_h4">
-          <a href="#3_9_1_2_managed_profile_provisioning">3.9.1.2 Managed profile provisioning</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#3_9_2_managed_profile_support">3.9.2 Managed Profile Support</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#3_10_accessibility">3.10. Accessibility</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#3_11_text-to-speech">3.11. Text-to-Speech</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#3_12_tv_input_framework">3.12. TV Input Framework</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#3_12_1_tv_app">3.12.1. TV App</a>
-        </p>
-        <p class="toc_h4">
-          <a href="#3_12_1_1_electronic_program_guide">3.12.1.1. Electronic Program Guide</a>
-        </p>
-        <p class="toc_h4">
-          <a href="#3_12_1_2_navigation">3.12.1.2. Navigation</a>
-        </p>
-        <p class="toc_h4">
-          <a href="#3_12_1_3_tv_input_app_linking">3.12.1.3. TV input app linking</a>
-        </p>
-        <p class="toc_h4">
-          <a href="#3_12_1_4_time_shifting">3.12.1.4. Time shifting</a>
-        </p>
-        <p class="toc_h4">
-          <a href="#3_12_1_5_tv_recording">3.12.1.5. TV recording</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#3_13_quick_settings">3.13. Quick Settings</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#3_14_vehicle_ui_apis">3.14. Vehicle UI APIs</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#3_14_1__vehicle_media_ui">3.14.1. Vehicle Media UI</a>
-        </p>
-        <p class="toc_h1">
-          <a href="#4_application_packaging_compatibility">4. Application Packaging Compatibility</a>
-        </p>
-        <p class="toc_h1">
-          <a href="#5_multimedia_compatibility">5. Multimedia Compatibility</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#5_1_media_codecs">5.1. Media Codecs</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#5_1_1_audio_codecs">5.1.1. Audio Codecs</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#5_1_2_image_codecs">5.1.2. Image Codecs</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#5_1_3_video_codecs">5.1.3. Video Codecs</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#5_2_video_encoding">5.2. Video Encoding</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#5_2_1_h_263">5.2.1. H.263</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#5_2_2_h-264">5.2.2. H-264</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#5_2_3_vp8">5.2.3. VP8</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#5_3_video_decoding">5.3. Video Decoding</a>
-        </p>
-      </div>
-      <div style="clear: both; page-break-after:always; height:1px"></div>
-      <div id="toc_left">
-        <p class="toc_h3">
-          <a href="#5_3_1_mpeg-2">5.3.1. MPEG-2</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#5_3_2_h_263">5.3.2. H.263</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#5_3_3_mpeg-4">5.3.3. MPEG-4</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#5_3_4_h_264">5.3.4. H.264</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#5_3_5_h_265_(hevc)">5.3.5. H.265 (HEVC)</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#5_3_6_vp8">5.3.6. VP8</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#5_3_7_vp9">5.3.7. VP9</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#5_4_audio_recording">5.4. Audio Recording</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#5_4_1_raw_audio_capture">5.4.1. Raw Audio Capture</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#5_4_2_capture_for_voice_recognition">5.4.2. Capture for Voice Recognition</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#5_4_3_capture_for_rerouting_of_playback">5.4.3. Capture for Rerouting of Playback</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#5_5_audio_playback">5.5. Audio Playback</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#5_5_1_raw_audio_playback">5.5.1. Raw Audio Playback</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#5_5_2_audio_effects">5.5.2. Audio Effects</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#5_5_3_audio_output_volume">5.5.3. Audio Output Volume</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#5_6_audio_latency">5.6. Audio Latency</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#5_7_network_protocols">5.7. Network Protocols</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#5_8_secure_media">5.8. Secure Media</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#5_9_musical_instrument_digital_interface_(midi)">5.9. Musical Instrument Digital Interface (MIDI)</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#5_10_professional_audio">5.10. Professional Audio</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#5_11_capture_for_unprocessed">5.11. Capture for Unprocessed</a>
-        </p>
-        <p class="toc_h1">
-          <a href="#6_developer_tools_and_options_compatibility">6. Developer Tools and Options Compatibility</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#6_1_developer_tools">6.1. Developer Tools</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#6_2_developer_options">6.2. Developer Options</a>
-        </p>
-        <p class="toc_h1">
-          <a href="#7_hardware_compatibility">7. Hardware Compatibility</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#7_1_display_and_graphics">7.1. Display and Graphics</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#7_1_1_screen_configuration">7.1.1. Screen Configuration</a>
-        </p>
-        <p class="toc_h4">
-          <a href="#7_1_1_1_screen_size">7.1.1.1. Screen Size</a>
-        </p>
-        <p class="toc_h4">
-          <a href="#7_1_1_2_screen_aspect_ratio">7.1.1.2. Screen Aspect Ratio</a>
-        </p>
-        <p class="toc_h4">
-          <a href="#7_1_1_3_screen_density">7.1.1.3. Screen Density</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#7_1_2_display_metrics">7.1.2. Display Metrics</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#7_1_3_screen_orientation">7.1.3. Screen Orientation</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#7_1_4_2d_and_3d_graphics_acceleration">7.1.4. 2D and 3D Graphics Acceleration</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#7_1_5_legacy_application_compatibility_mode">7.1.5. Legacy Application Compatibility Mode</a>
-        </p>
-      </div>
-      <div id="toc_right">
-        <p class="toc_h3">
-          <a href="#7_1_6_screen_technology">7.1.6. Screen Technology</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#7_1_7_secondary_displays">7.1.7. Secondary Displays</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#7_2_input_devices">7.2. Input Devices</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#7_2_1_keyboard">7.2.1. Keyboard</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#7_2_2_non-touch_navigation">7.2.2. Non-touch Navigation</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#7_2_3_navigation_keys">7.2.3. Navigation Keys</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#7_2_4_touchscreen_input">7.2.4. Touchscreen Input</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#7_2_5_fake_touch_input">7.2.5. Fake Touch Input</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#7_2_6_game_controller_support">7.2.6. Game Controller Support</a>
-        </p>
-        <p class="toc_h4">
-          <a href="#7_2_6_1_button_mappings">7.2.6.1. Button Mappings</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#7_2_7_remote_control">7.2.7. Remote Control</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#7_3_sensors">7.3. Sensors</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#7_3_1_accelerometer">7.3.1. Accelerometer</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#7_3_2_magnetometer">7.3.2. Magnetometer</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#7_3_3_gps">7.3.3. GPS</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#7_3_4_gyroscope">7.3.4. Gyroscope</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#7_3_5_barometer">7.3.5. Barometer</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#7_3_6_thermometer">7.3.6. Thermometer</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#7_3_7_photometer">7.3.7. Photometer</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#7_3_8_proximity_sensor">7.3.8. Proximity Sensor</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#7_3_9_high_fidelity_sensors">7.3.9. High Fidelity Sensors</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#7_3_10_fingerprint_sensor">7.3.10. Fingerprint Sensor</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#7_3_11_android_automotive-only_sensors">7.3.11. Android Automotive-only sensors</a>
-        </p>
-        <p class="toc_h4">
-          <a href="#7_3_11_1_current_gear">7.3.11.1. Current Gear</a>
-        </p>
-        <p class="toc_h4">
-          <a href="#7_3_11_2_day_night_mode">7.3.11.2. Day Night Mode</a>
-        </p>
-        <p class="toc_h4">
-          <a href="#7_3_11_3_driving_status">7.3.11.3. Driving Status</a>
-        </p>
-        <p class="toc_h4">
-          <a href="#7_3_11_4_wheel_speed">7.3.11.4. Wheel Speed</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#7_3_12_pose_sensor">7.3.12. Pose Sensor</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#7_4_data_connectivity">7.4. Data Connectivity</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#7_4_1_telephony">7.4.1. Telephony</a>
-        </p>
-        <p class="toc_h4">
-          <a href="#7_4_1_1_number_blocking_compatibility">7.4.1.1. Number Blocking Compatibility</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#7_4_2_ieee_802_11_(wi-fi)">7.4.2. IEEE 802.11 (Wi-Fi)</a>
-        </p>
-        <p class="toc_h4">
-          <a href="#7_4_2_1_wi-fi_direct">7.4.2.1. Wi-Fi Direct</a>
-        </p>
-        <p class="toc_h4">
-          <a href="#7_4_2_2_wi-fi_tunneled_direct_link_setup">7.4.2.2. Wi-Fi Tunneled Direct Link Setup</a>
-        </p>
-      </div>
-      <div style="clear: both; page-break-after:always; height:1px"></div>
-      <div id="toc_left">
-        <p class="toc_h3">
-          <a href="#7_4_3_bluetooth">7.4.3. Bluetooth</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#7_4_4_near-field_communications">7.4.4. Near-Field Communications</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#7_4_5_minimum_network_capability">7.4.5. Minimum Network Capability</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#7_4_6_sync_settings">7.4.6. Sync Settings</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#7_4_7_data_saver">7.4.7. Data Saver</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#7_5_cameras">7.5. Cameras</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#7_5_1_rear-facing_camera">7.5.1. Rear-Facing Camera</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#7_5_2_front-facing_camera">7.5.2. Front-Facing Camera</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#7_5_3_external_camera">7.5.3. External Camera</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#7_5_4_camera_api_behavior">7.5.4. Camera API Behavior</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#7_5_5_camera_orientation">7.5.5. Camera Orientation</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#7_6_memory_and_storage">7.6. Memory and Storage</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#7_6_1_minimum_memory_and_storage">7.6.1. Minimum Memory and Storage</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#7_6_2_application_shared_storage">7.6.2. Application Shared Storage</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#7_6_3_adoptable_storage">7.6.3. Adoptable Storage</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#7_7_usb">7.7. USB</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#7_7_1_usb_peripheral_mode">7.7.1. USB peripheral mode</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#7_7_2_usb_host_mode">7.7.2. USB host mode</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#7_8_audio">7.8. Audio</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#7_8_1_microphone">7.8.1. Microphone</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#7_8_2_audio_output">7.8.2. Audio Output</a>
-        </p>
-        <p class="toc_h4">
-          <a href="#7_8_2_1_analog_audio_ports">7.8.2.1. Analog Audio Ports</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#7_8_3_near-ultrasound">7.8.3. Near-Ultrasound</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#7_9_virtual_reality">7.9. Virtual Reality</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#7_9_1_virtual_reality_mode">7.9.1. Virtual Reality Mode</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#7_9_2_virtual_reality_high_performance">7.9.2. Virtual Reality High Performance</a>
-        </p>
-        <p class="toc_h1">
-          <a href="#8_performance_and_power">8. Performance and Power</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#8_1_user_experience_consistency">8.1. User Experience Consistency</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#8_2_file_i/o_access_performance">8.2. File I/O Access Performance</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#8_3_power-saving_modes">8.3. Power-Saving Modes</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#8_4_power_consumption_accounting">8.4. Power Consumption Accounting</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#8_5_consistent_performance">8.5. Consistent Performance</a>
-        </p>
-        <p class="toc_h1">
-          <a href="#9_security_model_compatibility">9. Security Model Compatibility</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#9_1_permissions">9.1. Permissions</a>
-        </p>
-      </div>
-      <div id="toc_right">
-        <p class="toc_h2">
-          <a href="#9_2_uid_and_process_isolation">9.2. UID and Process Isolation</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#9_3_filesystem_permissions">9.3. Filesystem Permissions</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#9_4_alternate_execution_environments">9.4. Alternate Execution Environments</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#9_5_multi-user_support">9.5. Multi-User Support</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#9_6_premium_sms_warning">9.6. Premium SMS Warning</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#9_7_kernel_security_features">9.7. Kernel Security Features</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#9_8_privacy">9.8. Privacy</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#9_9_data_storage_encryption">9.9. Data Storage Encryption</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#9_9_1_direct_boot">9.9.1. Direct Boot</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#9_9_2_file_based_encryption">9.9.2. File Based Encryption</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#9_9_3_full_disk_encryption">9.9.3. Full Disk Encryption</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#9_10_device_integrity">9.10. Device Integrity</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#9_11_keys_and_credentials">9.11. Keys and Credentials</a>
-        </p>
-        <p class="toc_h3">
-          <a href="#9_11_1_secure_lock_screen">9.11.1. Secure Lock Screen</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#9_12_data_deletion">9.12. Data Deletion</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#9_13_safe_boot_mode">9.13. Safe Boot Mode</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#9_14_automotive_vehicle_system_isolation">9.14. Automotive Vehicle System Isolation</a>
-        </p>
-        <p class="toc_h1">
-          <a href="#10_software_compatibility_testing">10. Software Compatibility Testing</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#10_1_compatibility_test_suite">10.1. Compatibility Test Suite</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#10_2_cts_verifier">10.2. CTS Verifier</a>
-        </p>
-        <p class="toc_h1">
-          <a href="#11_updatable_software">11. Updatable Software</a>
-        </p>
-        <p class="toc_h1">
-          <a href="#12_document_changelog">12. Document Changelog</a>
-        </p>
-        <p class="toc_h2">
-          <a href="#12_1_changelog_viewing_tips">12.1. Changelog Viewing Tips</a>
-        </p>
-        <p class="toc_h1">
-          <a href="#13_contact_us">13. Contact Us</a>
-        </p>
-      </div>
-      <div style="clear: both; page-break-after:always; height:1px"></div>
-      <div style="clear: both"></div>
-    </div>
-    <div id="main">
-      <h1 id="1_introduction">
-        1. Introduction
-      </h1>
-      <p>
-        This document enumerates the requirements that must be met in order for devices to be compatible with Android 7.1.
-      </p>
-      <p>
-        The use of “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” is per the IETF standard defined in <a href="http://www.ietf.org/rfc/rfc2119.txt">RFC2119</a> .
-      </p>
-      <p>
-        As used in this document, a “device implementer” or “implementer” is a person or organization developing a hardware/software solution running Android 7.1. A “device implementation” or “implementation is the hardware/software solution so developed.
-      </p>
-      <p>
-        To be considered compatible with Android 7.1, device implementations MUST meet the requirements presented in this Compatibility Definition, including any documents incorporated via reference.
-      </p>
-      <p>
-        Where this definition or the software tests described in <a href="#10_software_compatibility_testing">section 10</a> is silent, ambiguous, or incomplete, it is the responsibility of the device implementer to ensure compatibility with existing implementations.
-      </p>
-      <p>
-        For this reason, the <a href="http://source.android.com/">Android Open Source Project</a> is both the reference and preferred implementation of Android. Device implementers are STRONGLY RECOMMENDED to base their implementations to the greatest extent possible on the “upstream” source code available from the Android Open Source Project. While some components can hypothetically be replaced with alternate implementations, it is STRONGLY RECOMMENDED to not follow this practice, as passing the software tests will become substantially more difficult. It is the implementer’s responsibility to ensure full behavioral compatibility with the standard Android implementation, including and beyond the Compatibility Test Suite. Finally, note that certain component substitutions and modifications are explicitly forbidden by this document.
-      </p>
-      <p>
-        Many of the resources linked to in this document are derived directly or indirectly from the Android SDK and will be functionally identical to the information in that SDK’s documentation. In any cases where this Compatibility Definition or the Compatibility Test Suite disagrees with the SDK documentation, the SDK documentation is considered authoritative. Any technical details provided in the linked resources throughout this document are considered by inclusion to be part of this Compatibility Definition.
-      </p>
-      <h1 id="2_device_types">
-        2. Device Types
-      </h1>
-      <p>
-        While the Android Open Source Project has been used in the implementation of a variety of device types and form factors, many aspects of the architecture and compatibility requirements were optimized for handheld devices. Starting from Android 5.0, the Android Open Source Project aims to embrace a wider variety of device types as described in this section.
-      </p>
-      <p>
-        <strong>Android Handheld device</strong> refers to an Android device implementation that is typically used by holding it in the hand, such as mp3 players, phones, and tablets. Android Handheld device implementations:
-      </p>
-      <ul>
-        <li>MUST have a touchscreen embedded in the device.
-        </li>
-        <li>MUST have a power source that provides mobility, such as a battery.
-        </li>
-      </ul>
-      <p>
-        <strong>Android Television device</strong> refers to an Android device implementation that is an entertainment interface for consuming digital media, movies, games, apps, and/or live TV for users sitting about ten feet away (a “lean back” or “10-foot user interface”). Android Television devices:
-      </p>
-      <ul>
-        <li>MUST have an embedded screen OR include a video output port, such as VGA, HDMI, or a wireless port for display.
-        </li>
-        <li>MUST declare the features <a href="http://developer.android.com/reference/android/content/pm/PackageManager.html#FEATURE_LEANBACK">android.software.leanback</a> and android.hardware.type.television.
-        </li>
-      </ul>
-      <p>
-        <strong>Android Watch device</strong> refers to an Android device implementation intended to be worn on the body, perhaps on the wrist, and:
-      </p>
-      <ul>
-        <li>MUST have a screen with the physical diagonal length in the range from 1.1 to 2.5 inches.
-        </li>
-        <li>MUST declare the feature android.hardware.type.watch.
-        </li>
-        <li>MUST support uiMode = <a href="http://developer.android.com/reference/android/content/res/Configuration.html#UI_MODE_TYPE_WATCH">UI_MODE_TYPE_WATCH</a> .
-        </li>
-      </ul>
-      <p>
-        <strong>Android Automotive implementation</strong> refers to a vehicle head unit running Android as an operating system for part or all of the system and/or infotainment functionality. Android Automotive implementations:
-      </p>
-      <ul>
-        <li>MUST have a screen with the physical diagonal length equal to or greater than 6 inches.
-        </li>
-        <li>MUST declare the feature android.hardware.type.automotive.
-        </li>
-        <li>MUST support uiMode = <a href="http://developer.android.com/reference/android/content/res/Configuration.html#UI_MODE_TYPE_CAR">UI_MODE_TYPE_CAR</a> .
-        </li>
-        <li>Android Automotive implementations MUST support all public APIs in the <code>android.car.*</code> namespace.
-        </li>
-      </ul>
-      <p>
-        All Android device implementations that do not fit into any of the above device types still MUST meet all requirements in this document to be Android 7.1 compatible, unless the requirement is explicitly described to be only applicable to a specific Android device type from above.
-      </p>
-      <h2 id="2_1_device_configurations">
-        2.1 Device Configurations
-      </h2>
-      <p>
-        This is a summary of major differences in hardware configuration by device type. (Empty cells denote a “MAY”). Not all configurations are covered in this table; see relevant hardware sections for more detail.
-      </p>
-      <table>
-        <tr>
-          <th>
-            Category
-          </th>
-          <th>
-            Feature
-          </th>
-          <th>
-            Section
-          </th>
-          <th>
-            Handheld
-          </th>
-          <th>
-            Television
-          </th>
-          <th>
-            Watch
-          </th>
-          <th>
-            Automotive
-          </th>
-          <th>
-            Other
-          </th>
-        </tr>
-        <tr>
-          <td rowspan="3">
-            Input
-          </td>
-          <td>
-            D-pad
-          </td>
-          <td>
-            <a href="#7_2_2_non-touch-navigation">7.2.2. Non-touch Navigation</a>
-          </td>
-          <td></td>
-          <td>
-            MUST
-          </td>
-          <td></td>
-          <td></td>
-          <td></td>
-        </tr>
-        <tr>
-          <td>
-            Touchscreen
-          </td>
-          <td>
-            <a href="#7_2_4_touchscreen_input">7.2.4. Touchscreen input</a>
-          </td>
-          <td>
-            MUST
-          </td>
-          <td></td>
-          <td>
-            MUST
-          </td>
-          <td></td>
-          <td>
-            SHOULD
-          </td>
-        </tr>
-        <tr>
-          <td>
-            Microphone
-          </td>
-          <td>
-            <a href="#7_8_1_microphone">7.8.1. Microphone</a>
-          </td>
-          <td>
-            MUST
-          </td>
-          <td>
-            SHOULD
-          </td>
-          <td>
-            MUST
-          </td>
-          <td>
-            MUST
-          </td>
-          <td>
-            SHOULD
-          </td>
-        </tr>
-        <tr>
-          <td rowspan="2">
-            Sensors
-          </td>
-          <td>
-            Accelerometer
-          </td>
-          <td>
-            <a href="#7_3_1_accelerometer">7.3.1 Accelerometer</a>
-          </td>
-          <td>
-            SHOULD
-          </td>
-          <td></td>
-          <td>
-            SHOULD
-          </td>
-          <td></td>
-          <td>
-            SHOULD
-          </td>
-        </tr>
-        <tr>
-          <td>
-            GPS
-          </td>
-          <td>
-            <a href="#7_3_3_gps">7.3.3. GPS</a>
-          </td>
-          <td>
-            SHOULD
-          </td>
-          <td></td>
-          <td></td>
-          <td>
-            SHOULD
-          </td>
-          <td></td>
-        </tr>
-        <tr>
-          <td rowspan="6">
-            Connectivity
-          </td>
-          <td>
-            Wi-Fi
-          </td>
-          <td>
-            <a href="#7_4_2_ieee_802.11">7.4.2. IEEE 802.11</a>
-          </td>
-          <td>
-            SHOULD
-          </td>
-          <td>
-            SHOULD
-          </td>
-          <td></td>
-          <td>
-            SHOULD
-          </td>
-          <td>
-            SHOULD
-          </td>
-        </tr>
-        <tr>
-          <td>
-            Wi-Fi Direct
-          </td>
-          <td>
-            <a href="#7_4_2_1_wi-fi-direct">7.4.2.1. Wi-Fi Direct</a>
-          </td>
-          <td>
-            SHOULD
-          </td>
-          <td>
-            SHOULD
-          </td>
-          <td></td>
-          <td></td>
-          <td>
-            SHOULD
-          </td>
-        </tr>
-        <tr>
-          <td>
-            Bluetooth
-          </td>
-          <td>
-            <a href="#7_4_3_bluetooth">7.4.3. Bluetooth</a>
-          </td>
-          <td>
-            SHOULD
-          </td>
-          <td>
-            MUST
-          </td>
-          <td>
-            MUST
-          </td>
-          <td>
-            MUST
-          </td>
-          <td>
-            SHOULD
-          </td>
-        </tr>
-        <tr>
-          <td>
-            Bluetooth Low Energy
-          </td>
-          <td>
-            <a href="#7_4_3_bluetooth">7.4.3. Bluetooth</a>
-          </td>
-          <td>
-            SHOULD
-          </td>
-          <td>
-            MUST
-          </td>
-          <td>
-            SHOULD
-          </td>
-          <td>
-            SHOULD
-          </td>
-          <td>
-            SHOULD
-          </td>
-        </tr>
-        <tr>
-          <td>
-            Cellular radio
-          </td>
-          <td>
-            <a href="#7_4_5_minimum_network_capability">7.4.5. Minimum Network Capability</a>
-          </td>
-          <td></td>
-          <td></td>
-          <td></td>
-          <td>
-            SHOULD
-          </td>
-          <td></td>
-        </tr>
-        <tr>
-          <td>
-            USB peripheral/host mode
-          </td>
-          <td>
-            <a href="#7_7_usb">7.7. USB</a>
-          </td>
-          <td>
-            SHOULD
-          </td>
-          <td></td>
-          <td></td>
-          <td>
-            SHOULD
-          </td>
-          <td>
-            SHOULD
-          </td>
-        </tr>
-        <tr>
-          <td>
-            Output
-          </td>
-          <td>
-            Speaker and/or Audio output ports
-          </td>
-          <td>
-            <a href="#7_8_2_audio_output">7.8.2. Audio Output</a>
-          </td>
-          <td>
-            MUST
-          </td>
-          <td>
-            MUST
-          </td>
-          <td></td>
-          <td>
-            MUST
-          </td>
-          <td>
-            MUST
-          </td>
-        </tr>
-      </table>
-      <h1 id="3_software">
-        3. Software
-      </h1>
-      <h2 id="3_1_managed_api_compatibility">
-        3.1. Managed API Compatibility
-      </h2>
-      <p>
-        The managed Dalvik bytecode execution environment is the primary vehicle for Android applications. The Android application programming interface (API) is the set of Android platform interfaces exposed to applications running in the managed runtime environment. Device implementations MUST provide complete implementations, including all documented behaviors, of any documented API exposed by the <a href="http://developer.android.com/reference/packages.html">Android SDK</a> or any API decorated with the “@SystemApi” marker in the upstream Android source code.
-      </p>
-      <p>
-        Device implementations MUST support/preserve all classes, methods, and associated elements marked by the TestApi annotation (@TestApi).
-      </p>
-      <p>
-        Device implementations MUST NOT omit any managed APIs, alter API interfaces or signatures, deviate from the documented behavior, or include no-ops, except where specifically allowed by this Compatibility Definition.
-      </p>
-      <p>
-        This Compatibility Definition permits some types of hardware for which Android includes APIs to be omitted by device implementations. In such cases, the APIs MUST still be present and behave in a reasonable way. See <a href="#7_hardware_compatibility">section 7</a> for specific requirements for this scenario.
-      </p>
-      <h2 id="3_1_1_android_extensions">
-        3.1.1. Android Extensions
-      </h2>
-      <p>
-        Android includes the support of extending the managed APIs while keeping the same API level version. Android device implementations MUST preload the AOSP implementation of both the shared library <code>ExtShared</code> and services <code>ExtServices</code> with versions higher than or equal to the minimum versions allowed per each API level. For example, Android 7.0 device implementations, running API level 24 MUST include at least version 1.
-      </p>
-      <h2 id="3_2_soft_api_compatibility">
-        3.2. Soft API Compatibility
-      </h2>
-      <p>
-        In addition to the managed APIs from <a href="#3_1_managed_api_compatibility">section 3.1</a> , Android also includes a significant runtime-only “soft” API, in the form of such things as intents, permissions, and similar aspects of Android applications that cannot be enforced at application compile time.
-      </p>
-      <h3 id="3_2_1_permissions">
-        3.2.1. Permissions
-      </h3>
-      <p>
-        Device implementers MUST support and enforce all permission constants as documented by the <a href="http://developer.android.com/reference/android/Manifest.permission.html">Permission reference page</a> . Note that <a href="#9_security_model_compatibility">section 9</a> lists additional requirements related to the Android security model.
-      </p>
-      <h3 id="3_2_2_build_parameters">
-        3.2.2. Build Parameters
-      </h3>
-      <p>
-        The Android APIs include a number of constants on the <a href="http://developer.android.com/reference/android/os/Build.html">android.os.Build class</a> that are intended to describe the current device. To provide consistent, meaningful values across device implementations, the table below includes additional restrictions on the formats of these values to which device implementations MUST conform.
-      </p>
-      <table>
-        <tr>
-          <th>
-            Parameter
-          </th>
-          <th>
-            Details
-          </th>
-        </tr>
-        <tr>
-          <td>
-            VERSION.RELEASE
-          </td>
-          <td>
-            The version of the currently-executing Android system, in human-readable format. This field MUST have one of the string values defined in <a href="http://source.android.com/compatibility/7.1/versions.html">7.1</a> .
-          </td>
-        </tr>
-        <tr>
-          <td>
-            VERSION.SDK
-          </td>
-          <td>
-            The version of the currently-executing Android system, in a format accessible to third-party application code. For Android 7.1, this field MUST have the integer value 7.1_INT.
-          </td>
-        </tr>
-        <tr>
-          <td>
-            VERSION.SDK_INT
-          </td>
-          <td>
-            The version of the currently-executing Android system, in a format accessible to third-party application code. For Android 7.1, this field MUST have the integer value 7.1_INT.
-          </td>
-        </tr>
-        <tr>
-          <td>
-            VERSION.INCREMENTAL
-          </td>
-          <td>
-            A value chosen by the device implementer designating the specific build of the currently-executing Android system, in human-readable format. This value MUST NOT be reused for different builds made available to end users. A typical use of this field is to indicate which build number or source-control change identifier was used to generate the build. There are no requirements on the specific format of this field, except that it MUST NOT be null or the empty string ("").
-          </td>
-        </tr>
-        <tr>
-          <td>
-            BOARD
-          </td>
-          <td>
-            A value chosen by the device implementer identifying the specific internal hardware used by the device, in human-readable format. A possible use of this field is to indicate the specific revision of the board powering the device. The value of this field MUST be encodable as 7-bit ASCII and match the regular expression “^[a-zA-Z0-9_-]+$”.
-          </td>
-        </tr>
-        <tr>
-          <td>
-            BRAND
-          </td>
-          <td>
-            A value reflecting the brand name associated with the device as known to the end users. MUST be in human-readable format and SHOULD represent the manufacturer of the device or the company brand under which the device is marketed. The value of this field MUST be encodable as 7-bit ASCII and match the regular expression “^[a-zA-Z0-9_-]+$”.
-          </td>
-        </tr>
-        <tr>
-          <td>
-            SUPPORTED_ABIS
-          </td>
-          <td>
-            The name of the instruction set (CPU type + ABI convention) of native code. See <a href="#3_3_native_api_compatibility">section 3.3. Native API Compatibility</a> .
-          </td>
-        </tr>
-        <tr>
-          <td>
-            SUPPORTED_32_BIT_ABIS
-          </td>
-          <td>
-            The name of the instruction set (CPU type + ABI convention) of native code. See <a href="#3_3_native_api_compatibility">section 3.3. Native API Compatibility</a> .
-          </td>
-        </tr>
-        <tr>
-          <td>
-            SUPPORTED_64_BIT_ABIS
-          </td>
-          <td>
-            The name of the second instruction set (CPU type + ABI convention) of native code. See <a href="#3_3_native_api_compatibility">section 3.3. Native API Compatibility</a> .
-          </td>
-        </tr>
-        <tr>
-          <td>
-            CPU_ABI
-          </td>
-          <td>
-            The name of the instruction set (CPU type + ABI convention) of native code. See <a href="#3_3_native_api_compatibility">section 3.3. Native API Compatibility</a> .
-          </td>
-        </tr>
-        <tr>
-          <td>
-            CPU_ABI2
-          </td>
-          <td>
-            The name of the second instruction set (CPU type + ABI convention) of native code. See <a href="#3_3_native_api_compatibility">section 3.3. Native API Compatibility</a> .
-          </td>
-        </tr>
-        <tr>
-          <td>
-            DEVICE
-          </td>
-          <td>
-            A value chosen by the device implementer containing the development name or code name identifying the configuration of the hardware features and industrial design of the device. The value of this field MUST be encodable as 7-bit ASCII and match the regular expression “^[a-zA-Z0-9_-]+$”. This device name MUST NOT change during the lifetime of the product.
-          </td>
-        </tr>
-        <tr>
-          <td>
-            FINGERPRINT
-          </td>
-          <td>
-            A string that uniquely identifies this build. It SHOULD be reasonably human-readable. It MUST follow this template:
-            <p class="small">
-              $(BRAND)/$(PRODUCT)/<br />
-              &nbsp;&nbsp;&nbsp;&nbsp;$(DEVICE):$(VERSION.RELEASE)/$(ID)/$(VERSION.INCREMENTAL):$(TYPE)/$(TAGS)
-            </p>
-            <p>
-              For example:
-            </p>
-            <p class="small">
-              acme/myproduct/<br />
-              &nbsp;&nbsp;&nbsp;&nbsp;mydevice:7.1/LMYXX/3359:userdebug/test-keys
-            </p>
-            <p>
-              The fingerprint MUST NOT include whitespace characters. If other fields included in the template above have whitespace characters, they MUST be replaced in the build fingerprint with another character, such as the underscore ("_") character. The value of this field MUST be encodable as 7-bit ASCII.
-            </p>
-          </td>
-        </tr>
-        <tr>
-          <td>
-            HARDWARE
-          </td>
-          <td>
-            The name of the hardware (from the kernel command line or /proc). It SHOULD be reasonably human-readable. The value of this field MUST be encodable as 7-bit ASCII and match the regular expression “^[a-zA-Z0-9_-]+$”.
-          </td>
-        </tr>
-        <tr>
-          <td>
-            HOST
-          </td>
-          <td>
-            A string that uniquely identifies the host the build was built on, in human-readable format. There are no requirements on the specific format of this field, except that it MUST NOT be null or the empty string ("").
-          </td>
-        </tr>
-        <tr>
-          <td>
-            ID
-          </td>
-          <td>
-            An identifier chosen by the device implementer to refer to a specific release, in human-readable format. This field can be the same as android.os.Build.VERSION.INCREMENTAL, but SHOULD be a value sufficiently meaningful for end users to distinguish between software builds. The value of this field MUST be encodable as 7-bit ASCII and match the regular expression “^[a-zA-Z0-9._-]+$”.
-          </td>
-        </tr>
-        <tr>
-          <td>
-            MANUFACTURER
-          </td>
-          <td>
-            The trade name of the Original Equipment Manufacturer (OEM) of the product. There are no requirements on the specific format of this field, except that it MUST NOT be null or the empty string ("").
-          </td>
-        </tr>
-        <tr>
-          <td>
-            MODEL
-          </td>
-          <td>
-            A value chosen by the device implementer containing the name of the device as known to the end user. This SHOULD be the same name under which the device is marketed and sold to end users. There are no requirements on the specific format of this field, except that it MUST NOT be null or the empty string ("").
-          </td>
-        </tr>
-        <tr>
-          <td>
-            PRODUCT
-          </td>
-          <td>
-            A value chosen by the device implementer containing the development name or code name of the specific product (SKU) that MUST be unique within the same brand. MUST be human-readable, but is not necessarily intended for view by end users. The value of this field MUST be encodable as 7-bit ASCII and match the regular expression “^[a-zA-Z0-9_-]+$”. This product name MUST NOT change during the lifetime of the product.
-          </td>
-        </tr>
-        <tr>
-          <td>
-            SERIAL
-          </td>
-          <td>
-            A hardware serial number, which MUST be available and unique across devices with the same MODEL and MANUFACTURER. The value of this field MUST be encodable as 7-bit ASCII and match the regular expression “^([a-zA-Z0-9]{6,20})$”.
-          </td>
-        </tr>
-        <tr>
-          <td>
-            TAGS
-          </td>
-          <td>
-            A comma-separated list of tags chosen by the device implementer that further distinguishes the build. This field MUST have one of the values corresponding to the three typical Android platform signing configurations: release-keys, dev-keys, test-keys.
-          </td>
-        </tr>
-        <tr>
-          <td>
-            TIME
-          </td>
-          <td>
-            A value representing the timestamp of when the build occurred.
-          </td>
-        </tr>
-        <tr>
-          <td>
-            TYPE
-          </td>
-          <td>
-            A value chosen by the device implementer specifying the runtime configuration of the build. This field MUST have one of the values corresponding to the three typical Android runtime configurations: user, userdebug, or eng.
-          </td>
-        </tr>
-        <tr>
-          <td>
-            USER
-          </td>
-          <td>
-            A name or user ID of the user (or automated user) that generated the build. There are no requirements on the specific format of this field, except that it MUST NOT be null or the empty string ("").
-          </td>
-        </tr>
-        <tr>
-          <td>
-            SECURITY_PATCH
-          </td>
-          <td>
-            A value indicating the security patch level of a build. It MUST signify that the build is not in any way vulnerable to any of the issues described up through the designated Android Public Security Bulletin. It MUST be in the format [YYYY-MM-DD], matching a defined string documented in the <a href="source.android.com/security/bulletin">Android Public Security Bulletin</a> or in the <a href="http://source.android.com/security/advisory">Android Security Advisory</a> , for example "2015-11-01".
-          </td>
-        </tr>
-        <tr>
-          <td>
-            BASE_OS
-          </td>
-          <td>
-            A value representing the FINGERPRINT parameter of the build that is otherwise identical to this build except for the patches provided in the Android Public Security Bulletin. It MUST report the correct value and if such a build does not exist, report an empty string ("").
-          </td>
-        </tr>
-      </table>
-      <h3 id="3_2_3_intent_compatibility">
-        3.2.3. Intent Compatibility
-      </h3>
-      <h4 id="3_2_3_1_core_application_intents">
-        3.2.3.1. Core Application Intents
-      </h4>
-      <p>
-        Android intents allow application components to request functionality from other Android components. The Android upstream project includes a list of applications considered core Android applications, which implements several intent patterns to perform common actions. The core Android applications are:
-      </p>
-      <ul>
-        <li>Desk Clock
-        </li>
-        <li>Browser
-        </li>
-        <li>Calendar
-        </li>
-        <li>Contacts
-        </li>
-        <li>Gallery
-        </li>
-        <li>GlobalSearch
-        </li>
-        <li>Launcher
-        </li>
-        <li>Music
-        </li>
-        <li>Settings
-        </li>
-      </ul>
-      <p>
-        Device implementations MUST include the core Android applications as appropriate or a component implementing the same intent patterns defined by all the Activity or Service components of these core Android applications exposed to other applications, implicitly or explicitly, through the <code>android:exported</code> attribute.
-      </p>
-      <h4 id="3_2_3_2_intent_resolution">
-        3.2.3.2. Intent Resolution
-      </h4>
-      <p>
-        As Android is an extensible platform, device implementations MUST allow each intent pattern referenced in <a href="#3_2_3_1_core_application_intents">section 3.2.3.1</a> to be overridden by third-party applications. The upstream Android open source implementation allows this by default; device implementers MUST NOT attach special privileges to system applications' use of these intent patterns, or prevent third-party applications from binding to and assuming control of these patterns. This prohibition specifically includes but is not limited to disabling the “Chooser” user interface that allows the user to select between multiple applications that all handle the same intent pattern.
-      </p>
-      <p>
-        Device implementations MUST provide a user interface for users to modify the default activity for intents.
-      </p>
-      <p>
-        However, device implementations MAY provide default activities for specific URI patterns (e.g. http://play.google.com) when the default activity provides a more specific attribute for the data URI. For example, an intent filter pattern specifying the data URI “http://www.android.com” is more specific than the browser's core intent pattern for “http://”.
-      </p>
-      <p>
-        Android also includes a mechanism for third-party apps to declare an authoritative default <a href="https://developer.android.com/training/app-links">app linking behavior</a> for certain types of web URI intents. When such authoritative declarations are defined in an app's intent filter patterns, device implementations:
-      </p>
-      <ul>
-        <li>MUST attempt to validate any intent filters by performing the validation steps defined in the <a href="https://developers.google.com/digital-asset-links">Digital Asset Links specification</a> as implemented by the Package Manager in the upstream Android Open Source Project.
-        </li>
-        <li>MUST attempt validation of the intent filters during the installation of the application and set all successfully validated UIR intent filters as default app handlers for their UIRs.
-        </li>
-        <li>MAY set specific URI intent filters as default app handlers for their URIs, if they are successfully verified but other candidate URI filters fail verification. If a device implementation does this, it MUST provide the user appropriate per-URI pattern overrides in the settings menu.
-        </li>
-        <li>MUST provide the user with per-app App Links controls in Settings as follows:
-          <ul>
-            <li>The user MUST be able to override holistically the default app links behavior for an app to be: always open, always ask, or never open, which must apply to all candidate URI intent filters equally.
-            </li>
-            <li>The user MUST be able to see a list of the candidate URI intent filters.
-            </li>
-            <li>The device implementation MAY provide the user with the ability to override specific candidate URI intent filters that were successfully verified, on a per-intent filter basis.
-            </li>
-            <li>The device implementation MUST provide users with the ability to view and override specific candidate URI intent filters if the device implementation lets some candidate URI intent filters succeed verification while some others can fail.
-            </li>
-          </ul>
-        </li>
-      </ul>
-      <h4 id="3_2_3_3_intent_namespaces">
-        3.2.3.3. Intent Namespaces
-      </h4>
-      <p>
-        Device implementations MUST NOT include any Android component that honors any new intent or broadcast intent patterns using an ACTION, CATEGORY, or other key string in the android. <em>or com.android.</em> namespace. Device implementers MUST NOT include any Android components that honor any new intent or broadcast intent patterns using an ACTION, CATEGORY, or other key string in a package space belonging to another organization. Device implementers MUST NOT alter or extend any of the intent patterns used by the core apps listed in <a href="#3_2_3_1_core_application_intents">section 3.2.3.1</a> . Device implementations MAY include intent patterns using namespaces clearly and obviously associated with their own organization. This prohibition is analogous to that specified for Java language classes in <a href="#3_6_api_namespaces">section 3.6</a> .
-      </p>
-      <h4 id="3_2_3_4_broadcast_intents">
-        3.2.3.4. Broadcast Intents
-      </h4>
-      <p>
-        Third-party applications rely on the platform to broadcast certain intents to notify them of changes in the hardware or software environment. Android-compatible devices MUST broadcast the public broadcast intents in response to appropriate system events. Broadcast intents are described in the SDK documentation.
-      </p>
-      <h4 id="3_2_3_5_default_app_settings">
-        3.2.3.5. Default App Settings
-      </h4>
-      <p>
-        Android includes settings that provide users an easy way to select their default applications, for example for Home screen or SMS. Where it makes sense, device implementations MUST provide a similar settings menu and be compatible with the intent filter pattern and API methods described in the SDK documentation as below.
-      </p>
-      <p>
-        Device implementations:
-      </p>
-      <ul>
-        <li>MUST honor the <a href="http://developer.android.com/reference/android/provider/Settings.html#ACTION_HOME_SETTINGS">android.settings.HOME_SETTINGS</a> intent to show a default app settings menu for Home Screen, if the device implementation reports android.software.home_screen.
-        </li>
-        <li>MUST provide a settings menu that will call the <a href="http://developer.android.com/reference/android/provider/Telephony.Sms.Intents.html">android.provider.Telephony.ACTION_CHANGE_DEFAULT</a> intent to show a dialog to change the default SMS application, if the device implementation reports android.hardware.telephony.
-        </li>
-        <li>MUST honor the <a href="http://developer.android.com/reference/android/provider/Settings.html#ACTION_NFC_PAYMENT_SETTINGS">android.settings.NFC_PAYMENT_SETTINGS</a> intent to show a default app settings menu for Tap and Pay, if the device implementation reports android.hardware.nfc.hce.
-        </li>
-        <li>MUST honor the <a href="https://developer.android.com/reference/android/telecom/TelecomManager.html#ACTION_CHANGE_DEFAULT_DIALER">android.telecom.action.CHANGE_DEFAULT_DIALER</a> intent to show a dialog to allow the user to change the default Phone application, if the device implementation reports <code>android.hardware.telephony</code> .
-        </li>
-        <li>MUST honor the <a href="https://developer.android.com/reference/android/provider/Settings.html#ACTION_VOICE_INPUT_SETTINGS">android.settings.ACTION_VOICE_INPUT_SETTINGS</a> intent when the device supports the VoiceInteractionService and show a default app settings menu for voice input and assist.
-        </li>
-      </ul>
-      <h2 id="3_3_native_api_compatibility">
-        3.3. Native API Compatibility
-      </h2>
-      <p>
-        Native code compatibility is challenging. For this reason, device implementers are <strong>STRONGLY RECOMMENDED</strong> to use the implementations of the libraries listed below from the upstream Android Open Source Project.
-      </p>
-      <h3 id="3_3_1_application_binary_interfaces">
-        3.3.1. Application Binary Interfaces
-      </h3>
-      <p>
-        Managed Dalvik bytecode can call into native code provided in the application .apk file as an ELF .so file compiled for the appropriate device hardware architecture. As native code is highly dependent on the underlying processor technology, Android defines a number of Application Binary Interfaces (ABIs) in the Android NDK. Device implementations MUST be compatible with one or more defined ABIs, and MUST implement compatibility with the Android NDK, as below.
-      </p>
-      <p>
-        If a device implementation includes support for an Android ABI, it:
-      </p>
-      <ul>
-        <li>MUST include support for code running in the managed environment to call into native code, using the standard Java Native Interface (JNI) semantics.
-        </li>
-        <li>MUST be source-compatible (i.e. header compatible) and binary-compatible (for the ABI) with each required library in the list below.
-        </li>
-        <li>MUST support the equivalent 32-bit ABI if any 64-bit ABI is supported.
-        </li>
-        <li>MUST accurately report the native Application Binary Interface (ABI) supported by the device, via the android.os.Build.SUPPORTED_ABIS, android.os.Build.SUPPORTED_32_BIT_ABIS, and android.os.Build.SUPPORTED_64_BIT_ABIS parameters, each a comma separated list of ABIs ordered from the most to the least preferred one.
-        </li>
-        <li>MUST report, via the above parameters, only those ABIs documented and described in the latest version of the <a href="https://developer.android.com/ndk/guides/abis.html">Android NDK ABI Management documentation</a> , and MUST include support for the <a href="http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0388f/Beijfcja.html">Advanced SIMD</a> (a.k.a. NEON) extension.
-        </li>
-        <li>SHOULD be built using the source code and header files available in the upstream Android Open Source Project
-        </li>
-      </ul>
-      <p>
-        Note that future releases of the Android NDK may introduce support for additional ABIs. If a device implementation is not compatible with an existing predefined ABI, it MUST NOT report support for any ABIs at all.
-      </p>
-      <p>
-        The following native code APIs MUST be available to apps that include native code:
-      </p>
-      <ul>
-        <li>libandroid.so (native Android activity support)
-        </li>
-        <li>libc (C library)
-        </li>
-        <li>libcamera2ndk.so
-        </li>
-        <li>libdl (dynamic linker)
-        </li>
-        <li>libEGL.so (native OpenGL surface management)
-        </li>
-        <li>libGLESv1_CM.so (OpenGL ES 1.x)
-        </li>
-        <li>libGLESv2.so (OpenGL ES 2.0)
-        </li>
-        <li>libGLESv3.so (OpenGL ES 3.x)
-        </li>
-        <li>libicui18n.so
-        </li>
-        <li>libicuuc.so
-        </li>
-        <li>libjnigraphics.so
-        </li>
-        <li>liblog (Android logging)
-        </li>
-        <li>libmediandk.so (native media APIs support)
-        </li>
-        <li>libm (math library)
-        </li>
-        <li>libOpenMAXAL.so (OpenMAX AL 1.0.1 support)
-        </li>
-        <li>libOpenSLES.so (OpenSL ES 1.0.1 audio support)
-        </li>
-        <li>libRS.so
-        </li>
-        <li>libstdc++ (Minimal support for C++)
-        </li>
-        <li>libvulkan.so (Vulkan)
-        </li>
-        <li>libz (Zlib compression)
-        </li>
-        <li>JNI interface
-        </li>
-        <li>Support for OpenGL, as described below
-        </li>
-      </ul>
-      <p>
-        For the native libraries listed above, the device implementation MUST NOT add or remove the public functions.
-      </p>
-      <p>
-        Native libraries not listed above but implemented and provided in AOSP as system libraries are reserved and MUST NOT be exposed to third-party apps targeting API level 24 or higher.
-      </p>
-      <p>
-        Device implementations MAY add non-AOSP libraries and expose them directly as an API to third-party apps but the additional libraries SHOULD be in <code>/vendor/lib</code> or <code>/vendor/lib64</code> and MUST be listed in <code>/vendor/etc/public.libraries.txt</code> .
-      </p>
-      <p>
-        Note that device implementations MUST include libGLESv3.so and in turn, MUST export all the OpenGL ES 3.1 and <a href="http://developer.android.com/guide/topics/graphics/opengl.html#aep">Android Extension Pack</a> function symbols as defined in the NDK release android-24. Although all the symbols must be present, only the corresponding functions for OpenGL ES versions and extensions actually supported by the device must be fully implemented.
-      </p>
-      <h4 id="3_3_1_1_graphic_libraries">
-        3.3.1.1. Graphic Libraries
-      </h4>
-      <p>
-        <a href="https://www.khronos.org/registry/vulkan/specs/1.0-wsi_extensions/xhtml/vkspec.html">Vulkan</a> is a low-overhead, cross-platform API for high-performance 3D graphics. Device implementations, even if not including support of the Vulkan APIs, MUST satisfy the following requirements:
-      </p>
-      <ul>
-        <li>It MUST always provide a native library named <code>libvulkan.so</code> which exports function symbols for the core Vulkan 1.0 API as well as the <code>VK_KHR_surface</code> , <code>VK_KHR_android_surface</code> , and <code>VK_KHR_swapchain</code> extensions.
-        </li>
-      </ul>
-      <p>
-        Device implementations, if including support of the Vulkan APIs:
-      </p>
-      <ul>
-        <li>MUST report, one or more <code>VkPhysicalDevices</code> through the <code>vkEnumeratePhysicalDevices</code> call.
-        </li>
-        <li>Each enumerated <code>VkPhysicalDevices</code> MUST fully implement the Vulkan 1.0 API.
-        </li>
-        <li>MUST report the correct <a href="https://developer.android.com/reference/android/content/pm/PackageManager.html#FEATURE_VULKAN_HARDWARE_LEVEL"><code>PackageManager#FEATURE_VULKAN_HARDWARE_LEVEL</code></a> and <a href="https://developer.android.com/reference/android/content/pm/PackageManager.html#FEATURE_VULKAN_HARDWARE_VERSION"><code>PackageManager#FEATURE_VULKAN_HARDWARE_VERSION</code></a> feature flags.
-        </li>
-        <li>MUST enumerate layers, contained in native libraries named <code>libVkLayer*.so</code> in the application package’s native library directory, through the <code>vkEnumerateInstanceLayerProperties</code> and <code>vkEnumerateDeviceLayerProperties</code> functions in <code>libvulkan.so</code>
-        </li>
-        <li>MUST NOT enumerate layers provided by libraries outside of the application package, or provide other ways of tracing or intercepting the Vulkan API, unless the application has the <code>android:debuggable=”true”</code> attribute.
-        </li>
-      </ul>
-      <p>
-        Device implementations, if not including support of the Vulkan APIs:
-      </p>
-      <ul>
-        <li>MUST report 0 <code>VkPhysicalDevices</code> through the <code>vkEnumeratePhysicalDevices</code> call.
-        </li>
-        <li>MUST NOT declare any of the Vulkan feature flags <a href="https://developer.android.com/reference/android/content/pm/PackageManager.html#FEATURE_VULKAN_HARDWARE_LEVEL"><code>PackageManager#FEATURE_VULKAN_HARDWARE_LEVEL</code></a> and <a href="https://developer.android.com/reference/android/content/pm/PackageManager.html#FEATURE_VULKAN_HARDWARE_VERSION"><code>PackageManager#FEATURE_VULKAN_HARDWARE_VERSION</code></a> .
-        </li>
-      </ul>
-      <h3 id="3_3_2_32-bit_arm_native_code_compatibility">
-        3.3.2. 32-bit ARM Native Code Compatibility
-      </h3>
-      <p>
-        The ARMv8 architecture deprecates several CPU operations, including some operations used in existing native code. On 64-bit ARM devices, the following deprecated operations MUST remain available to 32-bit native ARM code, either through native CPU support or through software emulation:
-      </p>
-      <ul>
-        <li>SWP and SWPB instructions
-        </li>
-        <li>SETEND instruction
-        </li>
-        <li>CP15ISB, CP15DSB, and CP15DMB barrier operations
-        </li>
-      </ul>
-      <p>
-        Legacy versions of the Android NDK used /proc/cpuinfo to discover CPU features from 32-bit ARM native code. For compatibility with applications built using this NDK, devices MUST include the following lines in /proc/cpuinfo when it is read by 32-bit ARM applications:
-      </p>
-      <ul>
-        <li>"Features: ", followed by a list of any optional ARMv7 CPU features supported by the device.
-        </li>
-        <li>"CPU architecture: ", followed by an integer describing the device's highest supported ARM architecture (e.g., "8" for ARMv8 devices).
-        </li>
-      </ul>
-      <p>
-        These requirements only apply when /proc/cpuinfo is read by 32-bit ARM applications. Devices SHOULD not alter /proc/cpuinfo when read by 64-bit ARM or non-ARM applications.
-      </p>
-      <h2 id="3_4_web_compatibility">
-        3.4. Web Compatibility
-      </h2>
-      <h3 id="3_4_1_webview_compatibility">
-        3.4.1. WebView Compatibility
-      </h3>
-      <div class="note">
-        Android Watch devices MAY, but all other device implementations MUST provide a complete implementation of the android.webkit.Webview API.
-      </div>
-      <p>
-        The platform feature android.software.webview MUST be reported on any device that provides a complete implementation of the android.webkit.WebView API, and MUST NOT be reported on devices without a complete implementation of the API. The Android Open Source implementation uses code from the Chromium Project to implement the <a href="http://developer.android.com/reference/android/webkit/WebView.html">android.webkit.WebView</a> . Because it is not feasible to develop a comprehensive test suite for a web rendering system, device implementers MUST use the specific upstream build of Chromium in the WebView implementation. Specifically:
-      </p>
-      <ul>
-        <li>Device android.webkit.WebView implementations MUST be based on the <a href="http://www.chromium.org/">Chromium</a> build from the upstream Android Open Source Project for Android 7.1. This build includes a specific set of functionality and security fixes for the WebView.
-        </li>
-        <li>
-          <p>
-            The user agent string reported by the WebView MUST be in this format:
-          </p>
-          <p>
-            Mozilla/5.0 (Linux; Android $(VERSION); $(MODEL) Build/$(BUILD); wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 $(CHROMIUM_VER) Mobile Safari/537.36
-          </p>
-          <ul>
-            <li>The value of the $(VERSION) string MUST be the same as the value for android.os.Build.VERSION.RELEASE.
-            </li>
-            <li>The value of the $(MODEL) string MUST be the same as the value for android.os.Build.MODEL.
-            </li>
-            <li>The value of the $(BUILD) string MUST be the same as the value for android.os.Build.ID.
-            </li>
-            <li>The value of the $(CHROMIUM_VER) string MUST be the version of Chromium in the upstream Android Open Source Project.
-            </li>
-            <li>Device implementations MAY omit Mobile in the user agent string.
-            </li>
-          </ul>
-        </li>
-      </ul>
-      <p>
-        The WebView component SHOULD include support for as many HTML5 features as possible and if it supports the feature SHOULD conform to the <a href="http://html.spec.whatwg.org/multipage/">HTML5 specification</a> .
-      </p>
-      <h3 id="3_4_2_browser_compatibility">
-        3.4.2. Browser Compatibility
-      </h3>
-      <div class="note">
-        Android Television, Watch, and Android Automotive implementations MAY omit a browser application, but MUST support the public intent patterns as described in <a href="#3_2_3_1_core_application_intents">section 3.2.3.1</a> . All other types of device implementations MUST include a standalone Browser application for general user web browsing.
-      </div>
-      <p>
-        The standalone Browser MAY be based on a browser technology other than WebKit. However, even if an alternate Browser application is used, the android.webkit.WebView component provided to third-party applications MUST be based on WebKit, as described in <a href="#3_4_1_webview_compatibility">section 3.4.1</a> .
-      </p>
-      <p>
-        Implementations MAY ship a custom user agent string in the standalone Browser application.
-      </p>
-      <p>
-        The standalone Browser application (whether based on the upstream WebKit Browser application or a third-party replacement) SHOULD include support for as much of <a href="http://html.spec.whatwg.org/multipage/">HTML5</a> as possible. Minimally, device implementations MUST support each of these APIs associated with HTML5:
-      </p>
-      <ul>
-        <li>
-          <a href="http://www.w3.org/html/wg/drafts/html/master/browsers.html#offline">application cache/offline operation</a>
-        </li>
-        <li>
-          <a href="http://www.w3.org/html/wg/drafts/html/master/semantics.html#video">&lt;video&gt; tag</a>
-        </li>
-        <li>
-          <a href="http://www.w3.org/TR/geolocation-API/">geolocation</a>
-        </li>
-      </ul>
-      <p>
-        Additionally, device implementations MUST support the HTML5/W3C <a href="http://www.w3.org/TR/webstorage/">webstorage API</a> and SHOULD support the HTML5/W3C <a href="http://www.w3.org/TR/IndexedDB/">IndexedDB API</a> . Note that as the web development standards bodies are transitioning to favor IndexedDB over webstorage, IndexedDB is expected to become a required component in a future version of Android.
-      </p>
-      <h2 id="3_5_api_behavioral_compatibility">
-        3.5. API Behavioral Compatibility
-      </h2>
-      <p>
-        The behaviors of each of the API types (managed, soft, native, and web) must be consistent with the preferred implementation of the upstream <a href="http://source.android.com/">Android Open Source Project</a> . Some specific areas of compatibility are:
-      </p>
-      <ul>
-        <li>Devices MUST NOT change the behavior or semantics of a standard intent.
-        </li>
-        <li>Devices MUST NOT alter the lifecycle or lifecycle semantics of a particular type of system component (such as Service, Activity, ContentProvider, etc.).
-        </li>
-        <li>Devices MUST NOT change the semantics of a standard permission.
-        </li>
-      </ul>
-      <p>
-        The above list is not comprehensive. The Compatibility Test Suite (CTS) tests significant portions of the platform for behavioral compatibility, but not all. It is the responsibility of the implementer to ensure behavioral compatibility with the Android Open Source Project. For this reason, device implementers SHOULD use the source code available via the Android Open Source Project where possible, rather than re-implement significant parts of the system.
-      </p>
-      <h2 id="3_6_api_namespaces">
-        3.6. API Namespaces
-      </h2>
-      <p>
-        Android follows the package and class namespace conventions defined by the Java programming language. To ensure compatibility with third-party applications, device implementers MUST NOT make any prohibited modifications (see below) to these package namespaces:
-      </p>
-      <ul>
-        <li>java.*
-        </li>
-        <li>javax.*
-        </li>
-        <li>sun.*
-        </li>
-        <li>android.*
-        </li>
-        <li>com.android.*
-        </li>
-      </ul>
-      <p>
-        <strong>Prohibited modifications include</strong> :
-      </p>
-      <ul>
-        <li>Device implementations MUST NOT modify the publicly exposed APIs on the Android platform by changing any method or class signatures, or by removing classes or class fields.
-        </li>
-        <li>Device implementers MAY modify the underlying implementation of the APIs, but such modifications MUST NOT impact the stated behavior and Java-language signature of any publicly exposed APIs.
-        </li>
-        <li>Device implementers MUST NOT add any publicly exposed elements (such as classes or interfaces, or fields or methods to existing classes or interfaces) to the APIs above.
-        </li>
-      </ul>
-      <p>
-        A “publicly exposed element” is any construct that is not decorated with the“@hide” marker as used in the upstream Android source code. In other words, device implementers MUST NOT expose new APIs or alter existing APIs in the namespaces noted above. Device implementers MAY make internal-only modifications, but those modifications MUST NOT be advertised or otherwise exposed to developers.
-      </p>
-      <p>
-        Device implementers MAY add custom APIs, but any such APIs MUST NOT be in a namespace owned by or referring to another organization. For instance, device implementers MUST NOT add APIs to the com.google.* or similar namespace: only Google may do so. Similarly, Google MUST NOT add APIs to other companies' namespaces. Additionally, if a device implementation includes custom APIs outside the standard Android namespace, those APIs MUST be packaged in an Android shared library so that only apps that explicitly use them (via the &lt;uses-library&gt; mechanism) are affected by the increased memory usage of such APIs.
-      </p>
-      <p>
-        If a device implementer proposes to improve one of the package namespaces above (such as by adding useful new functionality to an existing API, or adding a new API), the implementer SHOULD visit <a href="http://source.android.com/">source.android.com</a> and begin the process for contributing changes and code, according to the information on that site.
-      </p>
-      <p>
-        Note that the restrictions above correspond to standard conventions for naming APIs in the Java programming language; this section simply aims to reinforce those conventions and make them binding through inclusion in this Compatibility Definition.
-      </p>
-      <h2 id="3_7_runtime_compatibility">
-        3.7. Runtime Compatibility
-      </h2>
-      <p>
-        Device implementations MUST support the full Dalvik Executable (DEX) format and <a href="https://android.googlesource.com/platform/dalvik/">Dalvik bytecode specification and semantics</a> . Device implementers SHOULD use ART, the reference upstream implementation of the Dalvik Executable Format, and the reference implementation’s package management system.
-      </p>
-      <p>
-        Device implementations MUST configure Dalvik runtimes to allocate memory in accordance with the upstream Android platform, and as specified by the following table. (See <a href="#7_1_1_screen_configuration">section 7.1.1</a> for screen size and screen density definitions.) Note that memory values specified below are considered minimum values and device implementations MAY allocate more memory per application.
-      </p>
-      <table>
-        <tr>
-          <th>
-            Screen Layout
-          </th>
-          <th>
-            Screen Density
-          </th>
-          <th>
-            Minimum Application Memory
-          </th>
-        </tr>
-        <tr>
-          <td rowspan="12">
-            Android Watch
-          </td>
-          <td>
-            120 dpi (ldpi)
-          </td>
-          <td rowspan="3">
-            32MB
-          </td>
-        </tr>
-        <tr>
-          <td>
-            160 dpi (mdpi)
-          </td>
-        </tr>
-        <tr>
-          <td>
-            213 dpi (tvdpi)
-          </td>
-        </tr>
-        <tr>
-          <td>
-            240 dpi (hdpi)
-          </td>
-          <td rowspan="2">
-            36MB
-          </td>
-        </tr>
-        <tr>
-          <td>
-            280 dpi (280dpi)
-          </td>
-        </tr>
-        <tr>
-          <td>
-            320 dpi (xhdpi)
-          </td>
-          <td rowspan="2">
-            48MB
-          </td>
-        </tr>
-        <tr>
-          <td>
-            360 dpi (360dpi)
-          </td>
-        </tr>
-        <tr>
-          <td>
-            400 dpi (400dpi)
-          </td>
-          <td>
-            56MB
-          </td>
-        </tr>
-        <tr>
-          <td>
-            420 dpi (420dpi)
-          </td>
-          <td>
-            64MB
-          </td>
-        </tr>
-        <tr>
-          <td>
-            480 dpi (xxhdpi)
-          </td>
-          <td>
-            88MB
-          </td>
-        </tr>
-        <tr>
-          <td>
-            560 dpi (560dpi)
-          </td>
-          <td>
-            112MB
-          </td>
-        </tr>
-        <tr>
-          <td>
-            640 dpi (xxxhdpi)
-          </td>
-          <td>
-            154MB
-          </td>
-        </tr>
-        <tr>
-          <td rowspan="12">
-            small/normal
-          </td>
-          <td>
-            120 dpi (ldpi)
-          </td>
-          <td rowspan="2">
-            32MB
-          </td>
-        </tr>
-        <tr>
-          <td>
-            160 dpi (mdpi)
-          </td>
-        </tr>
-        <tr>
-          <td>
-            213 dpi (tvdpi)
-          </td>
-          <td rowspan="3">
-            48MB
-          </td>
-        </tr>
-        <tr>
-          <td>
-            240 dpi (hdpi)
-          </td>
-        </tr>
-        <tr>
-          <td>
-            280 dpi (280dpi)
-          </td>
-        </tr>
-        <tr>
-          <td>
-            320 dpi (xhdpi)
-          </td>
-          <td rowspan="2">
-            80MB
-          </td>
-        </tr>
-        <tr>
-          <td>
-            360 dpi (360dpi)
-          </td>
-        </tr>
-        <tr>
-          <td>
-            400 dpi (400dpi)
-          </td>
-          <td>
-            96MB
-          </td>
-        </tr>
-        <tr>
-          <td>
-            420 dpi (420dpi)
-          </td>
-          <td>
-            112MB
-          </td>
-        </tr>
-        <tr>
-          <td>
-            480 dpi (xxhdpi)
-          </td>
-          <td>
-            128MB
-          </td>
-        </tr>
-        <tr>
-          <td>
-            560 dpi (560dpi)
-          </td>
-          <td>
-            192MB
-          </td>
-        </tr>
-        <tr>
-          <td>
-            640 dpi (xxxhdpi)
-          </td>
-          <td>
-            256MB
-          </td>
-        </tr>
-        <tr>
-          <td rowspan="12">
-            large
-          </td>
-          <td>
-            120 dpi (ldpi)
-          </td>
-          <td>
-            32MB
-          </td>
-        </tr>
-        <tr>
-          <td>
-            160 dpi (mdpi)
-          </td>
-          <td>
-            48MB
-          </td>
-        </tr>
-        <tr>
-          <td>
-            213 dpi (tvdpi)
-          </td>
-          <td rowspan="2">
-            80MB
-          </td>
-        </tr>
-        <tr>
-          <td>
-            240 dpi (hdpi)
-          </td>
-        </tr>
-        <tr>
-          <td>
-            280 dpi (280dpi)
-          </td>
-          <td>
-            96MB
-          </td>
-        </tr>
-        <tr>
-          <td>
-            320 dpi (xhdpi)
-          </td>
-          <td>
-            128MB
-          </td>
-        </tr>
-        <tr>
-          <td>
-            360 dpi (360dpi)
-          </td>
-          <td>
-            160MB
-          </td>
-        </tr>
-        <tr>
-          <td>
-            400 dpi (400dpi)
-          </td>
-          <td>
-            192MB
-          </td>
-        </tr>
-        <tr>
-          <td>
-            420 dpi (420dpi)
-          </td>
-          <td>
-            228MB
-          </td>
-        </tr>
-        <tr>
-          <td>
-            480 dpi (xxhdpi)
-          </td>
-          <td>
-            256MB
-          </td>
-        </tr>
-        <tr>
-          <td>
-            560 dpi (560dpi)
-          </td>
-          <td>
-            384MB
-          </td>
-        </tr>
-        <tr>
-          <td>
-            640 dpi (xxxhdpi)
-          </td>
-          <td>
-            512MB
-          </td>
-        </tr>
-        <tr>
-          <td rowspan="12">
-            xlarge
-          </td>
-          <td>
-            120 dpi (ldpi)
-          </td>
-          <td>
-            48MB
-          </td>
-        </tr>
-        <tr>
-          <td>
-            160 dpi (mdpi)
-          </td>
-          <td>
-            80MB
-          </td>
-        </tr>
-        <tr>
-          <td>
-            213 dpi (tvdpi)
-          </td>
-          <td rowspan="2">
-            96MB
-          </td>
-        </tr>
-        <tr>
-          <td>
-            240 dpi (hdpi)
-          </td>
-        </tr>
-        <tr>
-          <td>
-            280 dpi (280dpi)
-          </td>
-          <td>
-            144MB
-          </td>
-        </tr>
-        <tr>
-          <td>
-            320 dpi (xhdpi)
-          </td>
-          <td>
-            192MB
-          </td>
-        </tr>
-        <tr>
-          <td>
-            360 dpi (360dpi)
-          </td>
-          <td>
-            240MB
-          </td>
-        </tr>
-        <tr>
-          <td>
-            400 dpi (400dpi)
-          </td>
-          <td>
-            288MB
-          </td>
-        </tr>
-        <tr>
-          <td>
-            420 dpi (420dpi)
-          </td>
-          <td>
-            336MB
-          </td>
-        </tr>
-        <tr>
-          <td>
-            480 dpi (xxhdpi)
-          </td>
-          <td>
-            384MB
-          </td>
-        </tr>
-        <tr>
-          <td>
-            560 dpi (560dpi)
-          </td>
-          <td>
-            576MB
-          </td>
-        </tr>
-        <tr>
-          <td>
-            640 dpi (xxxhdpi)
-          </td>
-          <td>
-            768MB
-          </td>
-        </tr>
-      </table>
-      <h2 id="3_8_user_interface_compatibility">
-        3.8. User Interface Compatibility
-      </h2>
-      <h3 id="3_8_1_launcher_(home_screen)">
-        3.8.1. Launcher (Home Screen)
-      </h3>
-      <p>
-        Android includes a launcher application (home screen) and support for third-party applications to replace the device launcher (home screen). Device implementations that allow third-party applications to replace the device home screen MUST declare the platform feature android.software.home_screen.
-      </p>
-      <h3 id="3_8_2_widgets">
-        3.8.2. Widgets
-      </h3>
-      <div class="note">
-        Widgets are optional for all Android device implementations, but SHOULD be supported on Android Handheld devices.
-      </div>
-      <p>
-        Android defines a component type and corresponding API and lifecycle that allows applications to expose an <a href="http://developer.android.com/guide/practices/ui_guidelines/widget_design.html">“AppWidget”</a> to the end user, a feature that is STRONGLY RECOMMENDED to be supported on Handheld Device implementations. Device implementations that support embedding widgets on the home screen MUST meet the following requirements and declare support for platform feature android.software.app_widgets.
-      </p>
-      <ul>
-        <li>Device launchers MUST include built-in support for AppWidgets and expose user interface affordances to add, configure, view, and remove AppWidgets directly within the Launcher.
-        </li>
-        <li>Device implementations MUST be capable of rendering widgets that are 4 x 4 in the standard grid size. See the <a href="http://developer.android.com/guide/practices/ui_guidelines/widget_design.html">App Widget Design Guidelines</a> in the Android SDK documentation for details.
-        </li>
-        <li>Device implementations that include support for lock screen MAY support application widgets on the lock screen.
-        </li>
-      </ul>
-      <h3 id="3_8_3_notifications">
-        3.8.3. Notifications
-      </h3>
-      <p>
-        Android includes APIs that allow developers to <a href="http://developer.android.com/guide/topics/ui/notifiers/notifications.html">notify users of notable events</a> using hardware and software features of the device.
-      </p>
-      <p>
-        Some APIs allow applications to perform notifications or attract attention using hardware—specifically sound, vibration, and light. Device implementations MUST support notifications that use hardware features, as described in the SDK documentation, and to the extent possible with the device implementation hardware. For instance, if a device implementation includes a vibrator, it MUST correctly implement the vibration APIs. If a device implementation lacks hardware, the corresponding APIs MUST be implemented as no-ops. This behavior is further detailed in <a href="#7_hardware_compatibility">section 7</a> .
-      </p>
-      <p>
-        Additionally, the implementation MUST correctly render all <a href="https://developer.android.com/guide/topics/resources/available-resources.html">resources</a> (icons, animation files etc.) provided for in the APIs, or in the Status/System Bar <a href="http://developer.android.com/design/style/iconography.html">icon style guide</a> , which in the case of an Android Television device includes the possibility to not display the notifications. Device implementers MAY provide an alternative user experience for notifications than that provided by the reference Android Open Source implementation; however, such alternative notification systems MUST support existing notification resources, as above.
-      </p>
-      <div class="note">
-        Android Automotive implementations MAY manage the visibility and timing of notifications to mitigate driver distraction, but MUST display notifications that use <a href="https://developer.android.com/reference/android/app/Notification.CarExtender.html">CarExtender</a> when requested by applications.
-      </div>
-      <p>
-        Android includes support for various notifications, such as:
-      </p>
-      <ul>
-        <li>
-          <strong>Rich notifications</strong> . Interactive Views for ongoing notifications.
-        </li>
-        <li>
-          <strong>Heads-up notifications</strong> . Interactive Views users can act on or dismiss without leaving the current app.
-        </li>
-        <li>
-          <strong>Lock screen notifications</strong> . Notifications shown over a lock screen with granular control on visibility.
-        </li>
-      </ul>
-      <p>
-        Android device implementations, when such notifications are made visible, MUST properly execute Rich and Heads-up notifications and include the title/name, icon, text as <a href="https://developer.android.com/design/patterns/notifications.html">documented in the Android APIs</a> .
-      </p>
-      <p>
-        Android includes Notification Listener Service APIs that allow apps (once explicitly enabled by the user) to receive a copy of all notifications as they are posted or updated. Device implementations MUST correctly and promptly send notifications in their entirety to all such installed and user-enabled listener services, including any and all metadata attached to the Notification object.
-      </p>
-      <p>
-        Handheld device implementations MUST support the behaviors of updating, removing, replying to, and bundling notifications as described in this <a href="https://developer.android.com/guide/topics/ui/notifiers/notifications.html#Managing">section</a> .
-      </p>
-      <p>
-        Also, handheld device implementations MUST provide:
-      </p>
-      <ul>
-        <li>The ability to control notifications directly in the notification shade.
-        </li>
-        <li>The visual affordance to trigger the control panel in the notification shade.
-        </li>
-        <li>The ability to BLOCK, MUTE and RESET notification preference from a package, both in the inline control panel as well as in the settings app.
-        </li>
-      </ul>
-      <p>
-        All 6 direct subclasses of the <code>Notification.Style class</code> MUST be supported as described in the <a href="https://developer.android.com/reference/android/app/Notification.Style.html">SDK documents</a> .
-      </p>
-      <p>
-        Device implementations that support the DND (Do not Disturb) feature MUST meet the following requirements:
-      </p>
-      <ul>
-        <li>MUST implement an activity that would respond to the intent <a href="https://developer.android.com/reference/android/provider/Settings.html#ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS">ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS</a> , which for implementations with UI_MODE_TYPE_NORMAL it MUST be an activity where the user can grant or deny the app access to DND policy configurations.
-        </li>
-        <li>MUST, for when the device implementation has provided a means for the user to grant or deny third-party apps to access the DND policy configuration, display <a href="https://developer.android.com/reference/android/app/NotificationManager.html#addAutomaticZenRule%28android.app.AutomaticZenRule%29">Automatic DND rules</a> created by applications alongside the user-created and pre-defined rules.
-        </li>
-        <li>MUST honor the <a href="https://developer.android.com/reference/android/app/NotificationManager.Policy.html#suppressedVisualEffects"><code>suppressedVisualEffects</code></a> values passed along the <a href="https://developer.android.com/reference/android/app/NotificationManager.Policy.html#NotificationManager.Policy%28int,%20int,%20int,%20int%29"><code>NotificationManager.Policy</code></a> and if an app has set any of the SUPPRESSED_EFFECT_SCREEN_OFF or SUPPRESSED_EFFECT_SCREEN_ON flags, it SHOULD indicate to the user that the visual effects are suppressed in the DND settings menu.
-        </li>
-      </ul>
-      <h3 id="3_8_4_search">
-        3.8.4. Search
-      </h3>
-      <p>
-        Android includes APIs that allow developers to <a href="http://developer.android.com/reference/android/app/SearchManager.html">incorporate search</a> into their applications and expose their application’s data into the global system search. Generally speaking, this functionality consists of a single, system-wide user interface that allows users to enter queries, displays suggestions as users type, and displays results. The Android APIs allow developers to reuse this interface to provide search within their own apps and allow developers to supply results to the common global search user interface.
-      </p>
-      <p>
-        Android device implementations SHOULD include global search, a single, shared, system-wide search user interface capable of real-time suggestions in response to user input. Device implementations SHOULD implement the APIs that allow developers to reuse this user interface to provide search within their own applications. Device implementations that implement the global search interface MUST implement the APIs that allow third-party applications to add suggestions to the search box when it is run in global search mode. If no third-party applications are installed that make use of this functionality, the default behavior SHOULD be to display web search engine results and suggestions.
-      </p>
-      <p>
-        Android device implementations SHOULD, and Android Automotive implementations MUST, implement an assistant on the device to handle the <a href="http://developer.android.com/reference/android/content/Intent.html#ACTION_ASSIST">Assist action</a> .
-      </p>
-      <p>
-        Android also includes the <a href="https://developer.android.com/reference/android/app/assist/package-summary.html">Assist APIs</a> to allow applications to elect how much information of the current context is shared with the assistant on the device. Device implementations supporting the Assist action MUST indicate clearly to the end user when the context is shared by displaying a white light around the edges of the screen. To ensure clear visibility to the end user, the indication MUST meet or exceed the duration and brightness of the Android Open Source Project implementation.
-      </p>
-      <p>
-        This indication MAY be disabled by default for preinstalled apps using the Assist and VoiceInteractionService API, if all following requirements are met:
-      </p>
-      <ul>
-        <li>
-          <p>
-            The preinstalled app MUST request the context to be shared only when the user invoked the app by one of the following means, and the app is running in the foreground:
-          </p>
-          <ul>
-            <li>hotword invocation
-            </li>
-            <li>input of the ASSIST navigation key/button/gesture
-            </li>
-          </ul>
-        </li>
-        <li>
-          <p>
-            The device implementation MUST provide an affordance to enable the indication, less than two navigations away from (the default voice input and assistant app settings menu) <a href="#3_2_3_5_default_app_settings">section 3.2.3.5</a> .
-          </p>
-        </li>
-      </ul>
-      <h3 id="3_8_5_toasts">
-        3.8.5. Toasts
-      </h3>
-      <p>
-        Applications can use the <a href="http://developer.android.com/reference/android/widget/Toast.html">“Toast” API</a> to display short non-modal strings to the end user that disappear after a brief period of time. Device implementations MUST display Toasts from applications to end users in some high-visibility manner.
-      </p>
-      <h3 id="3_8_6_themes">
-        3.8.6. Themes
-      </h3>
-      <p>
-        Android provides “themes” as a mechanism for applications to apply styles across an entire Activity or application.
-      </p>
-      <p>
-        Android includes a “Holo” theme family as a set of defined styles for application developers to use if they want to match the <a href="http://developer.android.com/guide/topics/ui/themes.html">Holo theme look and feel</a> as defined by the Android SDK. Device implementations MUST NOT alter any of the <a href="http://developer.android.com/reference/android/R.style.html">Holo theme attributes</a> exposed to applications.
-      </p>
-      <p>
-        Android includes a “Material” theme family as a set of defined styles for application developers to use if they want to match the design theme’s look and feel across the wide variety of different Android device types. Device implementations MUST support the “Material” theme family and MUST NOT alter any of the <a href="http://developer.android.com/reference/android/R.style.html#Theme_Material">Material theme attributes</a> or their assets exposed to applications.
-      </p>
-      <p>
-        Android also includes a “Device Default” theme family as a set of defined styles for application developers to use if they want to match the look and feel of the device theme as defined by the device implementer. Device implementations MAY modify the <a href="http://developer.android.com/reference/android/R.style.html">Device Default theme attributes</a> exposed to applications.
-      </p>
-      <p>
-        Android supports a variant theme with translucent system bars, which allows application developers to fill the area behind the status and navigation bar with their app content. To enable a consistent developer experience in this configuration, it is important the status bar icon style is maintained across different device implementations. Therefore, Android device implementations MUST use white for system status icons (such as signal strength and battery level) and notifications issued by the system, unless the icon is indicating a problematic status or an app requests a light status bar using the SYSTEM_UI_FLAG_LIGHT_STATUS_BAR flag. When an app requests a light status bar, Android device implementations MUST change the color of the system status icons to black (for details, refer to <a href="http://developer.android.com/reference/android/R.style.html">R.style</a> ).
-      </p>
-      <h3 id="3_8_7_live_wallpapers">
-        3.8.7. Live Wallpapers
-      </h3>
-      <p>
-        Android defines a component type and corresponding API and lifecycle that allows applications to expose one or more <a href="http://developer.android.com/reference/android/service/wallpaper/WallpaperService.html">“Live Wallpapers”</a> to the end user. Live wallpapers are animations, patterns, or similar images with limited input capabilities that display as a wallpaper, behind other applications.
-      </p>
-      <p>
-        Hardware is considered capable of reliably running live wallpapers if it can run all live wallpapers, with no limitations on functionality, at a reasonable frame rate with no adverse effects on other applications. If limitations in the hardware cause wallpapers and/or applications to crash, malfunction, consume excessive CPU or battery power, or run at unacceptably low frame rates, the hardware is considered incapable of running live wallpaper. As an example, some live wallpapers may use an OpenGL 2.0 or 3.x context to render their content. Live wallpaper will not run reliably on hardware that does not support multiple OpenGL contexts because the live wallpaper use of an OpenGL context may conflict with other applications that also use an OpenGL context.
-      </p>
-      <p>
-        Device implementations capable of running live wallpapers reliably as described above SHOULD implement live wallpapers, and when implemented MUST report the platform feature flag android.software.live_wallpaper.
-      </p>
-      <h3 id="3_8_8_activity_switching">
-        3.8.8. Activity Switching
-      </h3>
-      <div class="note">
-        As the Recent function navigation key is OPTIONAL, the requirement to implement the overview screen is OPTIONAL for Android Watch and Android Automotive implementations, and RECOMMENDED for Android Television devices. There SHOULD still be a method to switch between activities on Android Automotive implementations.
-      </div>
-      <p>
-        The upstream Android source code includes the <a href="http://developer.android.com/guide/components/recents.html">overview screen</a> , a system-level user interface for task switching and displaying recently accessed activities and tasks using a thumbnail image of the application’s graphical state at the moment the user last left the application. Device implementations including the recents function navigation key as detailed in <a href="#7_2_3_navigation_keys">section 7.2.3</a> MAY alter the interface but MUST meet the following requirements:
-      </p>
-      <ul>
-        <li>MUST support at least up to 20 displayed activities.
-        </li>
-        <li>SHOULD at least display the title of 4 activities at a time.
-        </li>
-        <li>MUST implement the <a href="http://developer.android.com/about/versions/android-5.0.html#ScreenPinning">screen pinning behavior</a> and provide the user with a settings menu to toggle the feature.
-        </li>
-        <li>SHOULD display highlight color, icon, screen title in recents.
-        </li>
-        <li>SHOULD display a closing affordance ("x") but MAY delay this until user interacts with screens.
-        </li>
-        <li>SHOULD implement a shortcut to switch easily to the previous activity
-        </li>
-        <li>MAY display affiliated recents as a group that moves together.
-        </li>
-        <li>SHOULD trigger the fast-switch action between the two most recently used apps, when the recents function key is tapped twice.
-        </li>
-        <li>SHOULD trigger the split-screen multiwindow-mode, if supported, when the recents functions key is long pressed.
-        </li>
-      </ul>
-      <p>
-        Device implementations are STRONGLY RECOMMENDED to use the upstream Android user interface (or a similar thumbnail-based interface) for the overview screen.
-      </p>
-      <h3 id="3_8_9_input_management">
-        3.8.9. Input Management
-      </h3>
-      <p>
-        Android includes support for <a href="http://developer.android.com/guide/topics/text/creating-input-method.html">Input Management</a> and support for third-party input method editors. Device implementations that allow users to use third-party input methods on the device MUST declare the platform feature android.software.input_methods and support IME APIs as defined in the Android SDK documentation.
-      </p>
-      <p>
-        Device implementations that declare the android.software.input_methods feature MUST provide a user-accessible mechanism to add and configure third-party input methods. Device implementations MUST display the settings interface in response to the android.settings.INPUT_METHOD_SETTINGS intent.
-      </p>
-      <h3 id="3_8_10_lock_screen_media_control">
-        3.8.10. Lock Screen Media Control
-      </h3>
-      <p>
-        The Remote Control Client API is deprecated from Android 5.0 in favor of the <a href="http://developer.android.com/reference/android/app/Notification.MediaStyle.html">Media Notification Template</a> that allows media applications to integrate with playback controls that are displayed on the lock screen. Device implementations that support a lock screen, unless an Android Automotive or Watch implementation, MUST display the Lock screen Notifications including the Media Notification Template.
-      </p>
-      <h3 id="3_8_11_screen_savers_(previously_dreams)">
-        3.8.11. Screen savers (previously Dreams)
-      </h3>
-      <p>
-        Android includes support for <a href="http://developer.android.com/reference/android/service/dreams/DreamService.html">interactivescreensavers</a> , previously referred to as Dreams. Screen savers allow users to interact with applications when a device connected to a power source is idle or docked in a desk dock. Android Watch devices MAY implement screen savers, but other types of device implementations SHOULD include support for screen savers and provide a settings option for users toconfigure screen savers in response to the <code>android.settings.DREAM_SETTINGS</code> intent.
-      </p>
-      <h3 id="3_8_12_location">
-        3.8.12. Location
-      </h3>
-      <p>
-        When a device has a hardware sensor (e.g. GPS) that is capable of providing the location coordinates, <a href="http://developer.android.com/reference/android/provider/Settings.Secure.html#LOCATION_MODE">location modes</a> MUST be displayed in the Location menu within Settings.
-      </p>
-      <h3 id="3_8_13_unicode_and_font">
-        3.8.13. Unicode and Font
-      </h3>
-      <p>
-        Android includes support for the emoji characters defined in <a href="http://www.unicode.org/versions/Unicode9.0.0/">Unicode 9.0</a> . All device implementations MUST be capable of rendering these emoji characters in color glyph and when Android device implementations include an IME, it SHOULD provide an input method to the user for these emoji characters.
-      </p>
-      <p>
-        Android handheld devices SHOULD support the skin tone and diverse family emojis as specified in the <a href="http://unicode.org/reports/tr51">Unicode Technical Report #51</a> .
-      </p>
-      <p>
-        Android includes support for Roboto 2 font with different weights—sans-serif-thin, sans-serif-light, sans-serif-medium, sans-serif-black, sans-serif-condensed, sans-serif-condensed-light—which MUST all be included for the languages available on the device and full Unicode 7.0 coverage of Latin, Greek, and Cyrillic, including the Latin Extended A, B, C, and D ranges, and all glyphs in the currency symbols block of Unicode 7.0.
-      </p>
-      <h3 id="3_8_14_multi-windows">
-        3.8.14. Multi-windows
-      </h3>
-      <p>
-        A device implementation MAY choose not to implement any multi-window modes, but if it has the capability to display multiple activities at the same time it MUST implement such multi-window mode(s) in accordance with the application behaviors and APIs described in the Android SDK <a href="https://developer.android.com/preview/features/multi-window.html">multi-window mode support documentation</a> and meet the following requirements:
-      </p>
-      <ul>
-        <li>Applications can indicate whether they are capable of operating in multi-window mode in the AndroidManifest.xml file, either explicitly via the <a href="https://developer.android.com/reference/android/R.attr.html#resizeableActivity"><code>android:resizeableActivity</code></a> attribute or implicitly by having the targetSdkVersion &gt; 24. Apps that explicitly set this attribute to false in their manifest MUST not be launched in multi-window mode. Apps that don't set the attribute in their manifest file (targetSdkVersion &lt; 24) can be launched in multi-window mode, but the system MUST provide warning that the app may not work as expected in multi-window mode.
-        </li>
-        <li>Device implementations MUST NOT offer split-screen or freeform mode if both the screen height and width is less than 440 dp.
-        </li>
-        <li>Device implementations with screen size <code>xlarge</code> SHOULD support freeform mode.
-        </li>
-        <li>Android Television device implementations MUST support picture-in-picture (PIP) mode multi-window and place the PIP multi-window in the top right corner when PIP is ON.
-        </li>
-        <li>Device implementations with PIP mode multi-window support MUST allocate at least 240x135 dp for the PIP window.
-        </li>
-        <li>If the PIP multi-window mode is supported the <a href="https://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_WINDOW"><code>KeyEvent.KEYCODE_WINDOW</code></a> key MUST be used to control the PIP window; otherwise, the key MUST be available to the foreground activity.
-        </li>
-      </ul>
-      <h2 id="3_9_device_administration">
-        3.9. Device Administration
-      </h2>
-      <p>
-        Android includes features that allow security-aware applications to perform device administration functions at the system level, such as enforcing password policies or performing remote wipe, through the <a href="http://developer.android.com/guide/topics/admin/device-admin.html">Android Device Administration API</a> ]. Device implementations MUST provide an implementation of the <a href="http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html">DevicePolicyManager</a> class. Device implementations that supports a secure lock screen MUST implement the full range of <a href="http://developer.android.com/guide/topics/admin/device-admin.html">device administration</a> policies defined in the Android SDK documentation and report the platform feature android.software.device_admin.
-      </p>
-      <h3 id="3_9_1_device_provisioning">
-        3.9.1 Device Provisioning
-      </h3>
-      <h4 id="3_9_1_1_device_owner_provisioning">
-        3.9.1.1 Device owner provisioning
-      </h4>
-      <p>
-        If a device implementation declares the <code>android.software.device_admin</code> feature then it MUST implement the provisioning of the <a href="http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#isDeviceOwnerApp(java.lang.String)">Device Owner app</a> of a Device Policy Client (DPC) application as indicated below:
-      </p>
-      <ul>
-        <li>When the device implementation has no user data configured yet, it:
-          <ul>
-            <li>MUST report <code>true</code> for <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#isProvisioningAllowed(java.lang.String)"><code>DevicePolicyManager.isProvisioningAllowed(ACTION_PROVISION_MANAGED_DEVICE)</code></a> .
-            </li>
-            <li>MUST enroll the DPC application as the Device Owner app in response to the intent action <a href="http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#ACTION_PROVISION_MANAGED_DEVICE"><code>android.app.action.PROVISION_MANAGED_DEVICE</code></a> .
-            </li>
-            <li>MUST enroll the DPC application as the Device Owner app if the device declares Near-Field Communications (NFC) support via the feature flag <code>android.hardware.nfc</code> and receives an NFC message containing a record with MIME type <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#MIME_TYPE_PROVISIONING_NFC"><code>MIME_TYPE_PROVISIONING_NFC</code></a> .
-            </li>
-          </ul>
-        </li>
-        <li>When the device implementation has user data, it:
-          <ul>
-            <li>MUST report <code>false</code> for the <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#isProvisioningAllowed(java.lang.String)"><code>DevicePolicyManager.isProvisioningAllowed(ACTION_PROVISION_MANAGED_DEVICE)</code></a> .
-            </li>
-            <li>MUST not enroll any DPC application as the Device Owner App any more.
-            </li>
-          </ul>
-        </li>
-      </ul>
-      <p>
-        Device implementations MAY have a preinstalled application performing device administration functions but this application MUST NOT be set as the Device Owner app without explicit consent or action from the user or the administrator of the device.
-      </p>
-      <h4 id="3_9_1_2_managed_profile_provisioning">
-        3.9.1.2 Managed profile provisioning
-      </h4>
-      <p>
-        If a device implementation declares the android.software.managed_users, it MUST be possible to enroll a Device Policy Controller (DPC) application as the <a href="http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#isProfileOwnerApp(java.lang.String)">owner of a new Managed Profile</a> .
-      </p>
-      <p>
-        The managed profile provisioning process (the flow initiated by <a href="http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#ACTION_PROVISION_MANAGED_PROFILE">android.app.action.PROVISION_MANAGED_PROFILE</a> ) user experience MUST align with the AOSP implementation.
-      </p>
-      <p>
-        Device implementations MUST provide the following user affordances within the Settings user interface to indicate to the user when a particular system function has been disabled by the Device Policy Controller (DPC):
-      </p>
-      <ul>
-        <li>A consistent icon or other user affordance (for example the upstream AOSP info icon) to represent when a particular setting is restricted by a Device Admin.
-        </li>
-        <li>A short explanation message, as provided by the Device Admin via the <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#setShortSupportMessage%28android.content.ComponentName,%20java.lang.CharSequence%29"><code>setShortSupportMessage</code></a> .
-        </li>
-        <li>The DPC application’s icon.
-        </li>
-      </ul>
-      <h2 id="3_9_2_managed_profile_support">
-        3.9.2 Managed Profile Support
-      </h2>
-      <p>
-        Managed profile capable devices are those devices that:
-      </p>
-      <ul>
-        <li>Declare android.software.device_admin (see <a href="#3_9_device_administration">section 3.9 Device Administration</a> ).
-        </li>
-        <li>Are not low RAM devices (see <a href="#7_6_1_minimum_memory_and_storage">section 7.6.1</a> ).
-        </li>
-        <li>Allocate internal (non-removable) storage as shared storage (see <a href="#7_6_2_application_shared_storage">section 7.6.2</a> ).
-        </li>
-      </ul>
-      <p>
-        Managed profile capable devices MUST:
-      </p>
-      <ul>
-        <li>Declare the platform feature flag <code>android.software.managed_users</code> .
-        </li>
-        <li>Support managed profiles via the <code>android.app.admin.DevicePolicyManager</code> APIs.
-        </li>
-        <li>Allow one and only <a href="http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#ACTION_PROVISION_MANAGED_PROFILE">one managed profile to be created</a> .
-        </li>
-        <li>Use an icon badge (similar to the AOSP upstream work badge) to represent the managed applications and widgets and other badged UI elements like Recents &amp; Notifications.
-        </li>
-        <li>Display a notification icon (similar to the AOSP upstream work badge) to indicate when user is within a managed profile application.
-        </li>
-        <li>Display a toast indicating that the user is in the managed profile if and when the device wakes up (ACTION_USER_PRESENT) and the foreground application is within the managed profile.
-        </li>
-        <li>Where a managed profile exists, show a visual affordance in the Intent 'Chooser' to allow the user to forward the intent from the managed profile to the primary user or vice versa, if enabled by the Device Policy Controller.
-        </li>
-        <li>Where a managed profile exists, expose the following user affordances for both the primary user and the managed profile:
-          <ul>
-            <li>Separate accounting for battery, location, mobile data and storage usage for the primary user and managed profile.
-            </li>
-            <li>Independent management of VPN Applications installed within the primary user or managed profile.
-            </li>
-            <li>Independent management of applications installed within the primary user or managed profile.
-            </li>
-            <li>Independent management of accounts within the primary user or managed profile.
-            </li>
-          </ul>
-        </li>
-        <li>Ensure the preinstalled dialer, contacts and messaging applications can search for and look up caller information from the managed profile (if one exists) alongside those from the primary profile, if the Device Policy Controller permits it. When contacts from the managed profile are displayed in the preinstalled call log, in-call UI, in-progress and missed-call notifications, contacts and messaging apps they SHOULD be badged with the same badge used to indicate managed profile applications.
-        </li>
-        <li>MUST ensure that it satisfies all the security requirements applicable for a device with multiple users enabled (see <a href="#9_5_multi-user_support">section 9.5</a> ), even though the managed profile is not counted as another user in addition to the primary user.
-        </li>
-        <li>Support the ability to specify a separate lock screen meeting the following requirements to grant access to apps running in a managed profile.
-          <ul>
-            <li>Device implementations MUST honor the <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#ACTION_SET_NEW_PASSWORD"><code>DevicePolicyManager.ACTION_SET_NEW_PASSWORD</code></a> intent and show an interface to configure a separate lock screen credential for the managed profile.
-            </li>
-            <li>The lock screen credentials of the managed profile MUST use the same credential storage and management mechanisms as the parent profile, as documented on the <a href="http://source.android.com/security/authentication/index.html">Android Open Source Project Site</a>
-            </li>
-            <li>The DPC <a href="https://developer.android.com/guide/topics/admin/device-admin.html#pwd">password policies</a> MUST apply to only the managed profile's lock screen credentials unless called upon the <code>DevicePolicyManager</code> instance returned by <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#getParentProfileInstance%28android.content.ComponentName%29">getParentProfileInstance</a> .
-            </li>
-          </ul>
-        </li>
-      </ul>
-      <h2 id="3_10_accessibility">
-        3.10. Accessibility
-      </h2>
-      <p>
-        Android provides an accessibility layer that helps users with disabilities to navigate their devices more easily. In addition, Android provides platform APIs that enable <a href="http://developer.android.com/reference/android/accessibilityservice/AccessibilityService.html">accessibility service implementations</a> to receive callbacks for user and system events and generate alternate feedback mechanisms, such as text-to-speech, haptic feedback, and trackball/d-pad navigation.
-      </p>
-      <p>
-        Device implementations include the following requirements:
-      </p>
-      <ul>
-        <li>Android Automotive implementations SHOULD provide an implementation of the Android accessibility framework consistent with the default Android implementation.
-        </li>
-        <li>Device implementations (Android Automotive excluded) MUST provide an implementation of the Android accessibility framework consistent with the default Android implementation.
-        </li>
-        <li>Device implementations (Android Automotive excluded) MUST support third-party accessibility service implementations through the <a href="http://developer.android.com/reference/android/view/accessibility/package-summary.html">android.accessibilityservice APIs</a> .
-        </li>
-        <li>Device implementations (Android Automotive excluded) MUST generate AccessibilityEvents and deliver these events to all registered AccessibilityService implementations in a manner consistent with the default Android implementation
-        </li>
-        <li>
-          <p>
-            Device implementations (Android Automotive and Android Watch devices with no audio output excluded), MUST provide a user-accessible mechanism to enable and disable accessibility services, and MUST display this interface in response to the android.provider.Settings.ACTION_ACCESSIBILITY_SETTINGS intent.
-          </p>
-        </li>
-        <li>
-          <p>
-            Android device implementations with audio output are STRONGLY RECOMMENDED to provide implementations of accessibility services on the device comparable in or exceeding functionality of the TalkBack** and Switch Access accessibility services (https://github.com/google/talkback).
-          </p>
-        </li>
-        <li>Android Watch devices with audio output SHOULD provide implementations of an accessibility service on the device comparable in or exceeding functionality of the TalkBack accessibility service (https://github.com/google/talkback).
-        </li>
-        <li>Device implementations SHOULD provide a mechanism in the out-of-box setup flow for users to enable relevant accessibility services, as well as options to adjust the font size, display size and magnification gestures.
-        </li>
-      </ul>
-      <p>
-        ** For languages supported by Text-to-speech.
-      </p>
-      <p>
-        Also, note that if there is a preloaded accessibility service, it MUST be a Direct Boot aware {directBootAware} app if the device has encrypted storage using File Based Encryption (FBE).
-      </p>
-      <h2 id="3_11_text-to-speech">
-        3.11. Text-to-Speech
-      </h2>
-      <p>
-        Android includes APIs that allow applications to make use of text-to-speech (TTS) services and allows service providers to provide implementations of TTS services. Device implementations reporting the feature android.hardware.audio.output MUST meet these requirements related to the <a href="http://developer.android.com/reference/android/speech/tts/package-summary.html">Android TTS framework</a> .
-      </p>
-      <p>
-        Android Automotive implementations:
-      </p>
-      <ul>
-        <li>MUST support the Android TTS framework APIs.
-        </li>
-        <li>MAY support installation of third-party TTS engines. If supported, partners MUST provide a user-accessible interface that allows the user to select a TTS engine for use at system level.
-        </li>
-      </ul>
-      <p>
-        All other device implementations:
-      </p>
-      <ul>
-        <li>MUST support the Android TTS framework APIs and SHOULD include a TTS engine supporting the languages available on the device. Note that the upstream Android open source software includes a full-featured TTS engine implementation.
-        </li>
-        <li>MUST support installation of third-party TTS engines.
-        </li>
-        <li>MUST provide a user-accessible interface that allows users to select a TTS engine for use at the system level.
-        </li>
-      </ul>
-      <h2 id="3_12_tv_input_framework">
-        3.12. TV Input Framework
-      </h2>
-      <p>
-        The <a href="http://source.android.com/devices/tv/index.html">Android Television Input Framework (TIF)</a> simplifies the delivery of live content to Android Television devices. TIF provides a standard API to create input modules that control Android Television devices. Android Television device implementations MUST support TV Input Framework.
-      </p>
-      <p>
-        Device implementations that support TIF MUST declare the platform feature android.software.live_tv.
-      </p>
-      <h3 id="3_12_1_tv_app">
-        3.12.1. TV App
-      </h3>
-      <p>
-        Any device implementation that declares support for Live TV MUST have an installed TV application (TV App). The Android Open Source Project provides an implementation of the TV App.
-      </p>
-      <p>
-        The TV App MUST provide facilities to install and use <a href="http://developer.android.com/reference/android/media/tv/TvContract.Channels.html">TV Channels</a> and meet the following requirements:
-      </p>
-      <ul>
-        <li>Device implementations MUST allow third-party TIF-based inputs ( <a href="https://source.android.com/devices/tv/index.html#third-party_input_example">third-party inputs</a> ) to be installed and managed.
-        </li>
-        <li>Device implementations MAY provide visual separation between pre-installed <a href="https://source.android.com/devices/tv/index.html#tv_inputs">TIF-based inputs</a> (installed inputs) and third-party inputs.
-        </li>
-        <li>Device implementations MUST NOT display the third-party inputs more than a single navigation action away from the TV App (i.e. expanding a list of third-party inputs from the TV App).
-        </li>
-      </ul>
-      <h4 id="3_12_1_1_electronic_program_guide">
-        3.12.1.1. Electronic Program Guide
-      </h4>
-      <p>
-        Android Television device implementations MUST show an informational and interactive overlay, which MUST include an electronic program guide (EPG) generated from the values in the <a href="https://developer.android.com/reference/android/media/tv/TvContract.Programs.html">TvContract.Programs</a> fields. The EPG MUST meet the following requirements:
-      </p>
-      <ul>
-        <li>The EPG MUST display information from all installed inputs and third-party inputs.
-        </li>
-        <li>The EPG MAY provide visual separation between the installed inputs and third-party inputs.
-        </li>
-        <li>The EPG is STRONGLY RECOMMENDED to display installed inputs and third-party inputs with equal prominence. The EPG MUST NOT display the third-party inputs more than a single navigation action away from the installed inputs on the EPG.
-        </li>
-        <li>On channel change, device implementations MUST display EPG data for the currently playing program.
-        </li>
-      </ul>
-      <h4 id="3_12_1_2_navigation">
-        3.12.1.2. Navigation
-      </h4>
-      <p>
-        The TV App MUST allow navigation for the following functions via the D-pad, Back, and Home keys on the Android Television device’s input device(s) (i.e. remote control, remote control application, or game controller):
-      </p>
-      <ul>
-        <li>Changing TV channels
-        </li>
-        <li>Opening EPG
-        </li>
-        <li>Configuring and tuning to third-party TIF-based inputs
-        </li>
-        <li>Opening Settings menu
-        </li>
-      </ul>
-      <p>
-        The TV App SHOULD pass key events to HDMI inputs through CEC.
-      </p>
-      <h4 id="3_12_1_3_tv_input_app_linking">
-        3.12.1.3. TV input app linking
-      </h4>
-      <p>
-        Android Television device implementations MUST support <a href="http://developer.android.com/reference/android/media/tv/TvContract.Channels.html#COLUMN_APP_LINK_INTENT_URI">TV input app linking</a> , which allows all inputs to provide activity links from the current activity to another activity (i.e. a link from live programming to related content). The TV App MUST show TV input app linking when it is provided.
-      </p>
-      <h4 id="3_12_1_4_time_shifting">
-        3.12.1.4. Time shifting
-      </h4>
-      <p>
-        Android Television device implementations MUST support time shifting, which allows the user to pause and resume live content. Device implementations MUST provide the user a way to pause and resume the currently playing program, if time shifting for that program <a href="https://developer.android.com/reference/android/media/tv/TvInputManager.html#TIME_SHIFT_STATUS_AVAILABLE">is available</a> .
-      </p>
-      <h4 id="3_12_1_5_tv_recording">
-        3.12.1.5. TV recording
-      </h4>
-      <p>
-        Android Television device implementations are STRONGLY RECOMMENDED to support TV recording. If the TV input supports recording, the EPG MAY provide a way to <a href="https://developer.android.com/reference/android/media/tv/TvInputInfo.html#canRecord%28%29">record a program</a> if the recording of such a program is not <a href="https://developer.android.com/reference/android/media/tv/TvContract.Programs.html#COLUMN_RECORDING_PROHIBITED">prohibited</a> . Device implementations SHOULD provide a user interface to play recorded programs.
-      </p>
-      <h2 id="3_13_quick_settings">
-        3.13. Quick Settings
-      </h2>
-      <p>
-        Android device implementations SHOULD include a Quick Settings UI component that allow quick access to frequently used or urgently needed actions.
-      </p>
-      <p>
-        Android includes the <a href="https://developer.android.com/reference/android/service/quicksettings/package-summary.html"><code>quicksettings</code></a> API allowing third party apps to implement tiles that can be added by the user alongside the system-provided tiles in the Quick Settings UI component. If a device implementation has a Quick Settings UI component, it:
-      </p>
-      <ul>
-        <li>MUST allow the user to add or remove tiles from a third-party app to Quick Settings.
-        </li>
-        <li>MUST NOT automatically add a tile from a third-party app directly to Quick Settings.
-        </li>
-        <li>MUST display all the user-added tiles from third-party apps alongside the system-provided quick setting tiles.
-        </li>
-      </ul>
-      <h2 id="3_14_vehicle_ui_apis">
-        3.14. Vehicle UI APIs
-      </h2>
-      <h3 id="3_14_1__vehicle_media_ui">
-        3.14.1. Vehicle Media UI
-      </h3>
-      <p>
-        Any device implementation that <a href="https://developer.android.com/reference/android/content/pm/PackageManager.html?#FEATURE_AUTOMOTIVE?">declares automotive support</a> MUST include a UI framework to support third-party apps consuming the <a href="http://developer.android.com/reference/android/media/browse/MediaBrowser.html">MediaBrowser</a> and <a href="http://developer.android.com/reference/android/media/session/MediaSession.html">MediaSession</a> APIs.
-      </p>
-      <p>
-        The UI framework supporting third-party apps that depend on MediaBrowser and MediaSession has the following visual requirements:
-      </p>
-      <ul>
-        <li>MUST display <a href="http://developer.android.com/reference/android/media/browse/MediaBrowser.MediaItem.html">MediaItem</a> icons and notification icons unaltered.
-        </li>
-        <li>MUST display those items as described by MediaSession, e.g., metadata, icons, imagery.
-        </li>
-        <li>MUST show app title.
-        </li>
-        <li>MUST have drawer to present <a href="http://developer.android.com/reference/android/media/browse/MediaBrowser.html">MediaBrowser</a> hierarchy.
-        </li>
-      </ul>
-      <h1 id="4_application_packaging_compatibility">
-        4. Application Packaging Compatibility
-      </h1>
-      <p>
-        Device implementations MUST install and run Android “.apk” files as generated by the “aapt” tool included in the <a href="http://developer.android.com/tools/help/index.html">official Android SDK</a> . For this reason device implementations SHOULD use the reference implementation’s package management system.
-      </p>
-      <p>
-        The package manager MUST support verifying “.apk” files using the <a href="https://source.android.com/security/apksigning/v2.html">APK Signature Scheme v2</a> and <a href="https://source.android.com/security/apksigning/v2.html#v1-verification">JAR signing</a> .
-      </p>
-      <p>
-        Devices implementations MUST NOT extend either the <a href="http://developer.android.com/guide/components/fundamentals.html">.apk</a> , <a href="http://developer.android.com/guide/topics/manifest/manifest-intro.html">Android Manifest</a> , <a href="https://android.googlesource.com/platform/dalvik/">Dalvik bytecode</a> , or RenderScript bytecode formats in such a way that would prevent those files from installing and running correctly on other compatible devices.
-      </p>
-      <p>
-        Device implementations MUST NOT allow apps other than the current "installer of record" for the package to silently uninstall the app without any prompt, as documented in the SDK for the <a href="https://developer.android.com/reference/android/Manifest.permission.html#DELETE_PACKAGES"><code>DELETE_PACKAGE</code></a> permission. The only exceptions are the system package verifier app handling <a href="https://developer.android.com/reference/android/content/Intent.html#ACTION_PACKAGE_NEEDS_VERIFICATION">PACKAGE_NEEDS_VERIFICATION</a> intent and the storage manager app handling <a href="https://developer.android.com/reference/android/os/storage/StorageManager.html#ACTION_MANAGE_STORAGE">ACTION_MANAGE_STORAGE</a> intent.
-      </p>
-      <h1 id="5_multimedia_compatibility">
-        5. Multimedia Compatibility
-      </h1>
-      <h2 id="5_1_media_codecs">
-        5.1. Media Codecs
-      </h2>
-      <p>
-        Device implementations—
-      </p>
-      <ul>
-        <li>
-          <p>
-            MUST support the <a href="http://developer.android.com/guide/appendix/media-formats.html">core media formats</a> specified in the Android SDK documentation, except where explicitly permitted in this document.
-          </p>
-        </li>
-        <li>
-          <p>
-            MUST support the media formats, encoders, decoders, file types, and container formats defined in the tables below and reported via <a href="http://developer.android.com/reference/android/media/MediaCodecList.html">MediaCodecList</a> .
-          </p>
-        </li>
-        <li>
-          <p>
-            MUST also be able to decode all profiles reported in its <a href="http://developer.android.com/reference/android/media/CamcorderProfile.html">CamcorderProfile</a>
-          </p>
-        </li>
-        <li>
-          <p>
-            MUST be able to decode all formats it can encode. This includes all bitstreams that its encoders generate.
-          </p>
-        </li>
-      </ul>
-      <p>
-        Codecs SHOULD aim for minimum codec latency, in other words, codecs—
-      </p>
-      <ul>
-        <li>SHOULD NOT consume and store input buffers and return input buffers only once processed
-        </li>
-        <li>SHOULD NOT hold onto decoded buffers for longer than as specified by the standard (e.g. SPS).
-        </li>
-        <li>SHOULD NOT hold onto encoded buffers longer than required by the GOP structure.
-        </li>
-      </ul>
-      <p>
-        All of the codecs listed in the table below are provided as software implementations in the preferred Android implementation from the Android Open Source Project.
-      </p>
-      <p>
-        Please note that neither Google nor the Open Handset Alliance make any representation that these codecs are free from third-party patents. Those intending to use this source code in hardware or software products are advised that implementations of this code, including in open source software or shareware, may require patent licenses from the relevant patent holders.
-      </p>
-      <h3 id="5_1_1_audio_codecs">
-        5.1.1. Audio Codecs
-      </h3>
-      <table>
-        <tr>
-          <th>
-            Format/Codec
-          </th>
-          <th>
-            Encoder
-          </th>
-          <th>
-            Decoder
-          </th>
-          <th>
-            Details
-          </th>
-          <th>
-            Supported File Types/Container Formats
-          </th>
-        </tr>
-        <tr>
-          <td>
-            MPEG-4 AAC Profile<br />
-            (AAC LC)
-          </td>
-          <td>
-            REQUIRED <sup>1</sup>
-          </td>
-          <td>
-            REQUIRED
-          </td>
-          <td>
-            Support for mono/stereo/5.0/5.1 <sup>2</sup> content with standard sampling rates from 8 to 48 kHz.
-          </td>
-          <td>
-            <ul>
-              <li class="table_list">3GPP (.3gp)
-              </li>
-              <li class="table_list">MPEG-4 (.mp4, .m4a)
-              </li>
-              <li class="table_list">ADTS raw AAC (.aac, decode in Android 3.1+, encode in Android 4.0+, ADIF not supported)
-              </li>
-              <li class="table_list">MPEG-TS (.ts, not seekable, Android 3.0+)
-              </li>
-            </ul>
-          </td>
-        </tr>
-        <tr>
-          <td>
-            MPEG-4 HE AAC Profile (AAC+)
-          </td>
-          <td>
-            REQUIRED <sup>1</sup><br />
-            (Android 4.1+)
-          </td>
-          <td>
-            REQUIRED
-          </td>
-          <td>
-            Support for mono/stereo/5.0/5.1 <sup>2</sup> content with standard sampling rates from 16 to 48 kHz.
-          </td>
-          <td></td>
-        </tr>
-        <tr>
-          <td>
-            MPEG-4 HE AACv2<br />
-            Profile (enhanced AAC+)
-          </td>
-          <td></td>
-          <td>
-            REQUIRED
-          </td>
-          <td>
-            Support for mono/stereo/5.0/5.1 <sup>2</sup> content with standard sampling rates from 16 to 48 kHz.
-          </td>
-          <td></td>
-        </tr>
-        <tr>
-          <td>
-            AAC ELD (enhanced low delay AAC)
-          </td>
-          <td>
-            REQUIRED <sup>1</sup><br />
-            (Android 4.1+)
-          </td>
-          <td>
-            REQUIRED<br />
-            (Android 4.1+)
-          </td>
-          <td>
-            Support for mono/stereo content with standard sampling rates from 16 to 48 kHz.
-          </td>
-          <td></td>
-        </tr>
-        <tr>
-          <td>
-            AMR-NB
-          </td>
-          <td>
-            REQUIRED <sup>3</sup>
-          </td>
-          <td>
-            REQUIRED <sup>3</sup>
-          </td>
-          <td>
-            4.75 to 12.2 kbps sampled @ 8 kHz
-          </td>
-          <td>
-            3GPP (.3gp)
-          </td>
-        </tr>
-        <tr>
-          <td>
-            AMR-WB
-          </td>
-          <td>
-            REQUIRED <sup>3</sup>
-          </td>
-          <td>
-            REQUIRED <sup>3</sup>
-          </td>
-          <td>
-            9 rates from 6.60 kbit/s to 23.85 kbit/s sampled @ 16 kHz
-          </td>
-          <td></td>
-        </tr>
-        <tr>
-          <td>
-            FLAC
-          </td>
-          <td></td>
-          <td>
-            REQUIRED<br />
-            (Android 3.1+)
-          </td>
-          <td>
-            Mono/Stereo (no multichannel). Sample rates up to 48 kHz (but up to 44.1 kHz is RECOMMENDED on devices with 44.1 kHz output, as the 48 to 44.1 kHz downsampler does not include a low-pass filter). 16-bit RECOMMENDED; no dither applied for 24-bit.
-          </td>
-          <td>
-            FLAC (.flac) only
-          </td>
-        </tr>
-        <tr>
-          <td>
-            MP3
-          </td>
-          <td></td>
-          <td>
-            REQUIRED
-          </td>
-          <td>
-            Mono/Stereo 8-320Kbps constant (CBR) or variable bitrate (VBR)
-          </td>
-          <td>
-            MP3 (.mp3)
-          </td>
-        </tr>
-        <tr>
-          <td>
-            MIDI
-          </td>
-          <td></td>
-          <td>
-            REQUIRED
-          </td>
-          <td>
-            MIDI Type 0 and 1. DLS Version 1 and 2. XMF and Mobile XMF. Support for ringtone formats RTTTL/RTX, OTA, and iMelody
-          </td>
-          <td>
-            <ul>
-              <li class="table_list">Type 0 and 1 (.mid, .xmf, .mxmf)
-              </li>
-              <li class="table_list">RTTTL/RTX (.rtttl, .rtx)
-              </li>
-              <li class="table_list">OTA (.ota)
-              </li>
-              <li class="table_list">iMelody (.imy)
-              </li>
-            </ul>
-          </td>
-        </tr>
-        <tr>
-          <td>
-            Vorbis
-          </td>
-          <td></td>
-          <td>
-            REQUIRED
-          </td>
-          <td></td>
-          <td>
-            <ul>
-              <li class="table_list">Ogg (.ogg)
-              </li>
-              <li class="table_list">Matroska (.mkv, Android 4.0+)
-              </li>
-            </ul>
-          </td>
-        </tr>
-        <tr>
-          <td>
-            PCM/WAVE
-          </td>
-          <td>
-            REQUIRED <sup>4</sup><br />
-            (Android 4.1+)
-          </td>
-          <td>
-            REQUIRED
-          </td>
-          <td>
-            16-bit linear PCM (rates up to limit of hardware). Devices MUST support sampling rates for raw PCM recording at 8000, 11025, 16000, and 44100 Hz frequencies.
-          </td>
-          <td>
-            WAVE (.wav)
-          </td>
-        </tr>
-        <tr>
-          <td>
-            Opus
-          </td>
-          <td></td>
-          <td>
-            REQUIRED<br />
-            (Android 5.0+)
-          </td>
-          <td></td>
-          <td>
-            Matroska (.mkv), Ogg(.ogg)
-          </td>
-        </tr>
-      </table>
-      <p class="table_footnote">
-        1 Required for device implementations that define android.hardware.microphone but optional for Android Watch device implementations.
-      </p>
-      <p class="table_footnote">
-        2 Recording or playback MAY be performed in mono or stereo, but the decoding of AAC input buffers of multichannel streams (i.e. more than two channels) to PCM through the default AAC audio decoder in the android.media.MediaCodec API, the following MUST be supported:
-      </p>
-      <ul>
-        <li>decoding is performed without downmixing (e.g. a 5.0 AAC stream must be decoded to five channels of PCM, a 5.1 AAC stream must be decoded to six channels of PCM),
-        </li>
-        <li>dynamic range metadata, as defined in "Dynamic Range Control (DRC)" in ISO/IEC 14496-3, and the android.media.MediaFormat DRC keys to configure the dynamic range-related behaviors of the audio decoder. The AAC DRC keys were introduced in API 21,and are: KEY_AAC_DRC_ATTENUATION_FACTOR, KEY_AAC_DRC_BOOST_FACTOR, KEY_AAC_DRC_HEAVY_COMPRESSION, KEY_AAC_DRC_TARGET_REFERENCE_LEVEL and KEY_AAC_ENCODED_TARGET_LEVEL
-        </li>
-      </ul>
-      <p class="table_footnote">
-        3 Required for Android Handheld device implementations.
-      </p>
-      <p class="table_footnote">
-        4 Required for device implementations that define android.hardware.microphone, including Android Watch device implementations.
-      </p>
-      <h3 id="5_1_2_image_codecs">
-        5.1.2. Image Codecs
-      </h3>
-      <table>
-        <tr>
-          <th>
-            Format/Codec
-          </th>
-          <th>
-            Encoder
-          </th>
-          <th>
-            Decoder
-          </th>
-          <th>
-            Details
-          </th>
-          <th>
-            Supported File Types/Container Formats
-          </th>
-        </tr>
-        <tr>
-          <td>
-            JPEG
-          </td>
-          <td>
-            REQUIRED
-          </td>
-          <td>
-            REQUIRED
-          </td>
-          <td>
-            Base+progressive
-          </td>
-          <td>
-            JPEG (.jpg)
-          </td>
-        </tr>
-        <tr>
-          <td>
-            GIF
-          </td>
-          <td></td>
-          <td>
-            REQUIRED
-          </td>
-          <td></td>
-          <td>
-            GIF (.gif)
-          </td>
-        </tr>
-        <tr>
-          <td>
-            PNG
-          </td>
-          <td>
-            REQUIRED
-          </td>
-          <td>
-            REQUIRED
-          </td>
-          <td></td>
-          <td>
-            PNG (.png)
-          </td>
-        </tr>
-        <tr>
-          <td>
-            BMP
-          </td>
-          <td></td>
-          <td>
-            REQUIRED
-          </td>
-          <td></td>
-          <td>
-            BMP (.bmp)
-          </td>
-        </tr>
-        <tr>
-          <td>
-            WebP
-          </td>
-          <td>
-            REQUIRED
-          </td>
-          <td>
-            REQUIRED
-          </td>
-          <td></td>
-          <td>
-            WebP (.webp)
-          </td>
-        </tr>
-        <tr>
-          <td>
-            Raw
-          </td>
-          <td></td>
-          <td>
-            REQUIRED
-          </td>
-          <td></td>
-          <td>
-            ARW (.arw), CR2 (.cr2), DNG (.dng), NEF (.nef), NRW (.nrw), ORF (.orf), PEF (.pef), RAF (.raf), RW2 (.rw2), SRW (.srw)
-          </td>
-        </tr>
-      </table>
-      <h3 id="5_1_3_video_codecs">
-        5.1.3. Video Codecs
-      </h3>
-      <ul>
-        <li>
-          <p>
-            Codecs advertising HDR profile support MUST support HDR static metadata parsing and handling.
-          </p>
-        </li>
-        <li>
-          <p>
-            If a media codec advertises intra refresh support, then it MUST support the refresh periods in the range of 10 - 60 frames and accurately operate within 20% of configured refresh period.
-          </p>
-        </li>
-        <li>
-          <p>
-            Video codecs MUST support output and input bytebuffer sizes that accommodate the largest feasible compressed and uncompressed frame as dictated by the standard and configuration but also not overallocate.
-          </p>
-        </li>
-        <li>
-          <p>
-            Video encoders and decoders MUST support YUV420 flexible color format (COLOR_FormatYUV420Flexible).
-          </p>
-        </li>
-      </ul>
-      <table>
-        <tr>
-          <th>
-            Format/Codec
-          </th>
-          <th>
-            Encoder
-          </th>
-          <th>
-            Decoder
-          </th>
-          <th>
-            Details
-          </th>
-          <th>
-            Supported File Types/<br />
-            Container Formats
-          </th>
-        </tr>
-        <tr>
-          <td>
-            H.263
-          </td>
-          <td>
-            MAY
-          </td>
-          <td>
-            MAY
-          </td>
-          <td></td>
-          <td>
-            <ul>
-              <li class="table_list">3GPP (.3gp)
-              </li>
-              <li class="table_list">MPEG-4 (.mp4)
-              </li>
-            </ul>
-          </td>
-        </tr>
-        <tr>
-          <td>
-            H.264 AVC
-          </td>
-          <td>
-            REQUIRED <sup>2</sup>
-          </td>
-          <td>
-            REQUIRED <sup>2</sup>
-          </td>
-          <td>
-            See <a href="#5_2_video_encoding">section 5.2</a> and <a href="#5_3_video_decoding">5.3</a> for details
-          </td>
-          <td>
-            <ul>
-              <li class="table_list">3GPP (.3gp)
-              </li>
-              <li class="table_list">MPEG-4 (.mp4)
-              </li>
-              <li class="table_list">MPEG-2 TS (.ts, AAC audio only, not seekable, Android 3.0+)
-              </li>
-            </ul>
-          </td>
-        </tr>
-        <tr>
-          <td>
-            H.265 HEVC
-          </td>
-          <td></td>
-          <td>
-            REQUIRED <sup>5</sup>
-          </td>
-          <td>
-            See <a href="#5_3_video_decoding">section 5.3</a> for details
-          </td>
-          <td>
-            MPEG-4 (.mp4)
-          </td>
-        </tr>
-        <tr>
-          <td>
-            MPEG-2
-          </td>
-          <td></td>
-          <td>
-            STRONGLY RECOMMENDED <sup>6</sup>
-          </td>
-          <td>
-            Main Profile
-          </td>
-          <td>
-            MPEG2-TS
-          </td>
-        </tr>
-        <tr>
-          <td>
-            MPEG-4 SP
-          </td>
-          <td></td>
-          <td>
-            REQUIRED <sup>2</sup>
-          </td>
-          <td></td>
-          <td>
-            3GPP (.3gp)
-          </td>
-        </tr>
-        <tr>
-          <td>
-            VP8 <sup>3</sup>
-          </td>
-          <td>
-            REQUIRED <sup>2</sup><br />
-            (Android 4.3+)
-          </td>
-          <td>
-            REQUIRED <sup>2</sup><br />
-            (Android 2.3.3+)
-          </td>
-          <td>
-            See <a href="#5_2_video_encoding">section 5.2</a> and <a href="#5_3_video_decoding">5.3</a> for details
-          </td>
-          <td>
-            <ul>
-              <li class="table_list">
-                <a href="http://www.webmproject.org/">WebM (.webm)</a>
-              </li>
-              <li class="table_list">Matroska (.mkv, Android 4.0+) <sup>4</sup>
-              </li>
-            </ul>
-          </td>
-        </tr>
-        <tr>
-          <td>
-            VP9
-          </td>
-          <td></td>
-          <td>
-            REQUIRED <sup>2</sup><br />
-            (Android 4.4+)
-          </td>
-          <td>
-            See <a href="#5_3_video_decoding">section 5.3</a> for details
-          </td>
-          <td>
-            <ul>
-              <li class="table_list">
-                <a href="http://www.webmproject.org/">WebM (.webm)</a>
-              </li>
-              <li class="table_list">Matroska (.mkv, Android 4.0+) <sup>4</sup>
-              </li>
-            </ul>
-          </td>
-        </tr>
-      </table>
-      <p class="table_footnote">
-        1 Required for device implementations that include camera hardware and define android.hardware.camera or android.hardware.camera.front.
-      </p>
-      <p class="table_footnote">
-        2 Required for device implementations except Android Watch devices.
-      </p>
-      <p class="table_footnote">
-        3 For acceptable quality of web video streaming and video-conference services, device implementations SHOULD use a hardware VP8 codec that meets the <a href="http://www.webmproject.org/hardware/rtc-coding-requirements/">requirements</a> .
-      </p>
-      <p class="table_footnote">
-        4 Device implementations SHOULD support writing Matroska WebM files.
-      </p>
-      <p class="table_footnote">
-        5 STRONGLY RECOMMENDED for Android Automotive, optional for Android Watch, and required for all other device types.
-      </p>
-      <p class="table_footnote">
-        6 Applies only to Android Television device implementations.
-      </p>
-      <h2 id="5_2_video_encoding">
-        5.2. Video Encoding
-      </h2>
-      <div class="note">
-        Video codecs are optional for Android Watch device implementations.
-      </div>
-      <p>
-        H.264, VP8, VP9 and HEVC video encoders—
-      </p>
-      <ul>
-        <li>MUST support dynamically configurable bitrates.
-        </li>
-        <li>SHOULD support variable frame rates, where video encoder SHOULD determine instantaneous frame duration based on the timestamps of input buffers, and allocate its bit bucket based on that frame duration.
-        </li>
-      </ul>
-      <p>
-        H.263 and MPEG-4 video encoder SHOULD support dynamically configurable bitrates.
-      </p>
-      <p>
-        All video encoders SHOULD meet the following bitrate targets over two sliding windows:
-      </p>
-      <ul>
-        <li>It SHOULD be not more than ~15% over the bitrate between intraframe (I-frame) intervals.
-        </li>
-        <li>It SHOULD be not more than ~100% over the bitrate over a sliding window of 1 second.
-        </li>
-      </ul>
-      <h3 id="5_2_1_h_263">
-        5.2.1. H.263
-      </h3>
-      <p>
-        Android device implementations with H.263 encoders MUST support Baseline Profile Level 45.
-      </p>
-      <h3 id="5_2_2_h-264">
-        5.2.2. H-264
-      </h3>
-      <p>
-        Android device implementations with H.264 codec support:
-      </p>
-      <ul>
-        <li>MUST support Baseline Profile Level 3.<br />
-          However, support for ASO (Arbitrary Slice Ordering), FMO (Flexible Macroblock Ordering) and RS (Redundant Slices) is OPTIONAL. Moreover, to maintain compatibility with other Android devices, it is RECOMMENDED that ASO, FMO and RS are not used for Baseline Profile by encoders.
-        </li>
-        <li>MUST support the SD (Standard Definition) video encoding profiles in the following table.
-        </li>
-        <li>SHOULD support Main Profile Level 4.
-        </li>
-        <li>SHOULD support the HD (High Definition) video encoding profiles as indicated in the following table.
-        </li>
-        <li>In addition, Android Television devices are STRONGLY RECOMMENDED to encode HD 1080p video at 30 fps.
-        </li>
-      </ul>
-      <table>
-        <tr>
-          <th></th>
-          <th>
-            SD (Low quality)
-          </th>
-          <th>
-            SD (High quality)
-          </th>
-          <th>
-            HD 720p <sup>1</sup>
-          </th>
-          <th>
-            HD 1080p <sup>1</sup>
-          </th>
-        </tr>
-        <tr>
-          <th>
-            Video resolution
-          </th>
-          <td>
-            320 x 240 px
-          </td>
-          <td>
-            720 x 480 px
-          </td>
-          <td>
-            1280 x 720 px
-          </td>
-          <td>
-            1920 x 1080 px
-          </td>
-        </tr>
-        <tr>
-          <th>
-            Video frame rate
-          </th>
-          <td>
-            20 fps
-          </td>
-          <td>
-            30 fps
-          </td>
-          <td>
-            30 fps
-          </td>
-          <td>
-            30 fps
-          </td>
-        </tr>
-        <tr>
-          <th>
-            Video bitrate
-          </th>
-          <td>
-            384 Kbps
-          </td>
-          <td>
-            2 Mbps
-          </td>
-          <td>
-            4 Mbps
-          </td>
-          <td>
-            10 Mbps
-          </td>
-        </tr>
-      </table>
-      <p class="table_footnote">
-        1 When supported by hardware, but STRONGLY RECOMMENDED for Android Television devices.
-      </p>
-      <h3 id="5_2_3_vp8">
-        5.2.3. VP8
-      </h3>
-      <p>
-        Android device implementations with VP8 codec support MUST support the SD video encoding profiles and SHOULD support the following HD (High Definition) video encoding profiles.
-      </p>
-      <table>
-        <tr>
-          <th></th>
-          <th>
-            SD (Low quality)
-          </th>
-          <th>
-            SD (High quality)
-          </th>
-          <th>
-            HD 720p <sup>1</sup>
-          </th>
-          <th>
-            HD 1080p <sup>1</sup>
-          </th>
-        </tr>
-        <tr>
-          <th>
-            Video resolution
-          </th>
-          <td>
-            320 x 180 px
-          </td>
-          <td>
-            640 x 360 px
-          </td>
-          <td>
-            1280 x 720 px
-          </td>
-          <td>
-            1920 x 1080 px
-          </td>
-        </tr>
-        <tr>
-          <th>
-            Video frame rate
-          </th>
-          <td>
-            30 fps
-          </td>
-          <td>
-            30 fps
-          </td>
-          <td>
-            30 fps
-          </td>
-          <td>
-            30 fps
-          </td>
-        </tr>
-        <tr>
-          <th>
-            Video bitrate
-          </th>
-          <td>
-            800 Kbps
-          </td>
-          <td>
-            2 Mbps
-          </td>
-          <td>
-            4 Mbps
-          </td>
-          <td>
-            10 Mbps
-          </td>
-        </tr>
-      </table>
-      <p class="table_footnote">
-        1 When supported by hardware.
-      </p>
-      <h2 id="5_3_video_decoding">
-        5.3. Video Decoding
-      </h2>
-      <div class="note">
-        Video codecs are optional for Android Watch device implementations.
-      </div>
-      <p>
-        Device implementations—
-      </p>
-      <ul>
-        <li>
-          <p>
-            MUST support dynamic video resolution and frame rate switching through the standard Android APIs within the same stream for all VP8, VP9, H.264, and H.265 codecs in real time and up to the maximum resolution supported by each codec on the device.
-          </p>
-        </li>
-        <li>
-          <p>
-            Implementations that support the Dolby Vision decoder—
-          </p>
-        </li>
-        <li>MUST provide a Dolby Vision-capable extractor.
-        </li>
-        <li>
-          <p>
-            MUST properly display Dolby Vision content on the device screen or on a standard video output port (e.g., HDMI).
-          </p>
-        </li>
-        <li>
-          <p>
-            Implementations that provide a Dolby Vision-capable extractor MUST set the track index of backward-compatible base-layer(s) (if present) to be the same as the combined Dolby Vision layer's track index.
-          </p>
-        </li>
-      </ul>
-      <h3 id="5_3_1_mpeg-2">
-        5.3.1. MPEG-2
-      </h3>
-      <p>
-        Android device implementations with MPEG-2 decoders must support the Main Profile High Level.
-      </p>
-      <h3 id="5_3_2_h_263">
-        5.3.2. H.263
-      </h3>
-      <p>
-        Android device implementations with H.263 decoders MUST support Baseline Profile Level 30 and Level 45.
-      </p>
-      <h3 id="5_3_3_mpeg-4">
-        5.3.3. MPEG-4
-      </h3>
-      <p>
-        Android device implementations with MPEG-4 decoders MUST support Simple Profile Level 3.
-      </p>
-      <h3 id="5_3_4_h_264">
-        5.3.4. H.264
-      </h3>
-      <p>
-        Android device implementations with H.264 decoders:
-      </p>
-      <ul>
-        <li>MUST support Main Profile Level 3.1 and Baseline Profile.<br />
-          Support for ASO (Arbitrary Slice Ordering), FMO (Flexible Macroblock Ordering) and RS (Redundant Slices) is OPTIONAL.
-        </li>
-        <li>MUST be capable of decoding videos with the SD (Standard Definition) profiles listed in the following table and encoded with the Baseline Profile and Main Profile Level 3.1 (including 720p30).
-        </li>
-        <li>SHOULD be capable of decoding videos with the HD (High Definition) profiles as indicated in the following table.
-        </li>
-        <li>In addition, Android Television devices—
-          <ul>
-            <li>MUST support High Profile Level 4.2 and the HD 1080p60 decoding profile.
-            </li>
-            <li>MUST be capable of decoding videos with both HD profiles as indicated in the following table and encoded with either the Baseline Profile, Main Profile, or the High Profile Level 4.2
-            </li>
-          </ul>
-        </li>
-      </ul>
-      <table>
-        <tr>
-          <th></th>
-          <th>
-            SD (Low quality)
-          </th>
-          <th>
-            SD (High quality)
-          </th>
-          <th>
-            HD 720p <sup>1</sup>
-          </th>
-          <th>
-            HD 1080p <sup>1</sup>
-          </th>
-        </tr>
-        <tr>
-          <th>
-            Video resolution
-          </th>
-          <td>
-            320 x 240 px
-          </td>
-          <td>
-            720 x 480 px
-          </td>
-          <td>
-            1280 x 720 px
-          </td>
-          <td>
-            1920 x 1080 px
-          </td>
-        </tr>
-        <tr>
-          <th>
-            Video frame rate
-          </th>
-          <td>
-            30 fps
-          </td>
-          <td>
-            30 fps
-          </td>
-          <td>
-            60 fps
-          </td>
-          <td>
-            30 fps (60 fps <sup>2</sup> )
-          </td>
-        </tr>
-        <tr>
-          <th>
-            Video bitrate
-          </th>
-          <td>
-            800 Kbps
-          </td>
-          <td>
-            2 Mbps
-          </td>
-          <td>
-            8 Mbps
-          </td>
-          <td>
-            20 Mbps
-          </td>
-        </tr>
-      </table>
-      <p class="table_footnote">
-        1 REQUIRED for when the height as reported by the Display.getSupportedModes() method is equal or greater than the video resolution.
-      </p>
-      <p class="table_footnote">
-        2 REQUIRED for Android Television device implementations.
-      </p>
-      <h3 id="5_3_5_h_265_(hevc)">
-        5.3.5. H.265 (HEVC)
-      </h3>
-      <p>
-        Android device implementations, when supporting H.265 codec as described in <a href="#5_1_3_video_codecs">section 5.1.3</a> :
-      </p>
-      <ul>
-        <li>MUST support the Main Profile Level 3 Main tier and the SD video decoding profiles as indicated in the following table.
-        </li>
-        <li>SHOULD support the HD decoding profiles as indicated in the following table.
-        </li>
-        <li>MUST support the HD decoding profiles as indicated in the following table if there is a hardware decoder.
-        </li>
-        <li>In addition, Android Television devices:
-        </li>
-        <li>MUST support the HD 720p decoding profile.
-        </li>
-        <li>STRONGLY RECOMMENDED to support the HD 1080p decoding profile. If the HD 1080p decoding profile is supported, it MUST support the Main Profile Level 4.1 Main tier.
-        </li>
-        <li>SHOULD support the UHD decoding profile. If the UHD decoding profile is supported the codec MUST support Main10 Level 5 Main Tier profile.
-        </li>
-      </ul>
-      <table>
-        <tr>
-          <th></th>
-          <th>
-            SD (Low quality)
-          </th>
-          <th>
-            SD (High quality)
-          </th>
-          <th>
-            HD 720p
-          </th>
-          <th>
-            HD 1080p
-          </th>
-          <th>
-            UHD
-          </th>
-        </tr>
-        <tr>
-          <th>
-            Video resolution
-          </th>
-          <td>
-            352 x 288 px
-          </td>
-          <td>
-            720 x 480 px
-          </td>
-          <td>
-            1280 x 720 px
-          </td>
-          <td>
-            1920 x 1080 px
-          </td>
-          <td>
-            3840 x 2160 px
-          </td>
-        </tr>
-        <tr>
-          <th>
-            Video frame rate
-          </th>
-          <td>
-            30 fps
-          </td>
-          <td>
-            30 fps
-          </td>
-          <td>
-            30 fps
-          </td>
-          <td>
-            30 fps (60 fps <sup>1</sup> )
-          </td>
-          <td>
-            60 fps
-          </td>
-        </tr>
-        <tr>
-          <th>
-            Video bitrate
-          </th>
-          <td>
-            600 Kbps
-          </td>
-          <td>
-            1.6 Mbps
-          </td>
-          <td>
-            4 Mbps
-          </td>
-          <td>
-            5 Mbps
-          </td>
-          <td>
-            20 Mbps
-          </td>
-        </tr>
-      </table>
-      <p class="table_footnote">
-        1 REQUIRED for Android Television device implementations with H.265 hardware decoding.
-      </p>
-      <h3 id="5_3_6_vp8">
-        5.3.6. VP8
-      </h3>
-      <p>
-        Android device implementations, when supporting VP8 codec as described in <a href="https://source.android.com/compatibility/android-cdd.html#5_1_3_video_codecs">section 5.1.3</a> :
-      </p>
-      <ul>
-        <li>MUST support the SD decoding profiles in the following table.
-        </li>
-        <li>SHOULD support the HD decoding profiles in the following table.
-        </li>
-        <li>Android Television devices MUST support the HD 1080p60 decoding profile.
-        </li>
-      </ul>
-      <table>
-        <tr>
-          <th></th>
-          <th>
-            SD (Low quality)
-          </th>
-          <th>
-            SD (High quality)
-          </th>
-          <th>
-            HD 720p <sup>1</sup>
-          </th>
-          <th>
-            HD 1080p <sup>1</sup>
-          </th>
-        </tr>
-        <tr>
-          <th>
-            Video resolution
-          </th>
-          <td>
-            320 x 180 px
-          </td>
-          <td>
-            640 x 360 px
-          </td>
-          <td>
-            1280 x 720 px
-          </td>
-          <td>
-            1920 x 1080 px
-          </td>
-        </tr>
-        <tr>
-          <th>
-            Video frame rate
-          </th>
-          <td>
-            30 fps
-          </td>
-          <td>
-            30 fps
-          </td>
-          <td>
-            30 fps (60 fps <sup>2</sup> )
-          </td>
-          <td>
-            30 (60 fps <sup>2</sup> )
-          </td>
-        </tr>
-        <tr>
-          <th>
-            Video bitrate
-          </th>
-          <td>
-            800 Kbps
-          </td>
-          <td>
-            2 Mbps
-          </td>
-          <td>
-            8 Mbps
-          </td>
-          <td>
-            20 Mbps
-          </td>
-        </tr>
-      </table>
-      <p class="table_footnote">
-        1 REQUIRED for when the height as reported by the Display.getSupportedModes() method is equal or greater than the video resolution.
-      </p>
-      <p class="table_footnote">
-        2 REQUIRED for Android Television device implementations.
-      </p>
-      <h3 id="5_3_7_vp9">
-        5.3.7. VP9
-      </h3>
-      <p>
-        Android device implementations, when supporting VP9 codec as described in <a href="https://source.android.com/compatibility/android-cdd.html#5_1_3_video_codecs">section 5.1.3</a> :
-      </p>
-      <ul>
-        <li>MUST support the SD video decoding profiles as indicated in the following table.
-        </li>
-        <li>SHOULD support the HD decoding profiles as indicated in the following table.
-        </li>
-        <li>MUST support the HD decoding profiles as indicated in the following table, if there is a hardware decoder.
-        </li>
-        <li>
-          <p>
-            In addition, Android Television devices:
-          </p>
-          <ul>
-            <li>MUST support the HD 720p decoding profile.
-            </li>
-            <li>STRONGLY RECOMMENDED to support the HD 1080p decoding profile.
-            </li>
-            <li>SHOULD support the UHD decoding profile. If the UHD video decoding profile is supported, it MUST support 8-bit color depth and SHOULD support VP9 Profile 2 (10-bit).
-            </li>
-          </ul>
-        </li>
-      </ul>
-      <table>
-        <tr>
-          <th></th>
-          <th>
-            SD (Low quality)
-          </th>
-          <th>
-            SD (High quality)
-          </th>
-          <th>
-            HD 720p
-          </th>
-          <th>
-            HD 1080p
-          </th>
-          <th>
-            UHD
-          </th>
-        </tr>
-        <tr>
-          <th>
-            Video resolution
-          </th>
-          <td>
-            320 x 180 px
-          </td>
-          <td>
-            640 x 360 px
-          </td>
-          <td>
-            1280 x 720 px
-          </td>
-          <td>
-            1920 x 1080 px
-          </td>
-          <td>
-            3840 x 2160 px
-          </td>
-        </tr>
-        <tr>
-          <th>
-            Video frame rate
-          </th>
-          <td>
-            30 fps
-          </td>
-          <td>
-            30 fps
-          </td>
-          <td>
-            30 fps
-          </td>
-          <td>
-            30 fps (60 fps <sup>1</sup> )
-          </td>
-          <td>
-            60 fps
-          </td>
-        </tr>
-        <tr>
-          <th>
-            Video bitrate
-          </th>
-          <td>
-            600 Kbps
-          </td>
-          <td>
-            1.6 Mbps
-          </td>
-          <td>
-            4 Mbps
-          </td>
-          <td>
-            5 Mbps
-          </td>
-          <td>
-            20 Mbps
-          </td>
-        </tr>
-      </table>
-      <p class="table_footnote">
-        1 REQUIRED for Android Television device implementations with VP9 hardware decoding.
-      </p>
-      <h2 id="5_4_audio_recording">
-        5.4. Audio Recording
-      </h2>
-      <p>
-        While some of the requirements outlined in this section are stated as SHOULD since Android 4.3, the Compatibility Definition for a future version is planned to change these to MUST. Existing and new Android devices are <strong>STRONGLY RECOMMENDED</strong> to meet these requirements that are stated as SHOULD, or they will not be able to attain Android compatibility when upgraded to the future version.
-      </p>
-      <h3 id="5_4_1_raw_audio_capture">
-        5.4.1. Raw Audio Capture
-      </h3>
-      <p>
-        Device implementations that declare android.hardware.microphone MUST allow capture of raw audio content with the following characteristics:
-      </p>
-      <ul>
-        <li>
-          <strong>Format</strong> : Linear PCM, 16-bit
-        </li>
-        <li>
-          <strong>Sampling rates</strong> : 8000, 11025, 16000, 44100
-        </li>
-        <li>
-          <strong>Channels</strong> : Mono
-        </li>
-      </ul>
-      <p>
-        The capture for the above sample rates MUST be done without up-sampling, and any down-sampling MUST include an appropriate anti-aliasing filter.
-      </p>
-      <p>
-        Device implementations that declare android.hardware.microphone SHOULD allow capture of raw audio content with the following characteristics:
-      </p>
-      <ul>
-        <li>
-          <strong>Format</strong> : Linear PCM, 16-bit
-        </li>
-        <li>
-          <strong>Sampling rates</strong> : 22050, 48000
-        </li>
-        <li>
-          <strong>Channels</strong> : Stereo
-        </li>
-      </ul>
-      <p>
-        If capture for the above sample rates is supported, then the capture MUST be done without up-sampling at any ratio higher than 16000:22050 or 44100:48000. Any up-sampling or down-sampling MUST include an appropriate anti-aliasing filter.
-      </p>
-      <h3 id="5_4_2_capture_for_voice_recognition">
-        5.4.2. Capture for Voice Recognition
-      </h3>
-      <p>
-        The android.media.MediaRecorder.AudioSource.VOICE_RECOGNITION audio source MUST support capture at one of the sampling rates, 44100 and 48000.
-      </p>
-      <p>
-        In addition to the above recording specifications, when an application has started recording an audio stream using the android.media.MediaRecorder.AudioSource.VOICE_RECOGNITION audio source:
-      </p>
-      <ul>
-        <li>The device SHOULD exhibit approximately flat amplitude versus frequency characteristics: specifically, ±3 dB, from 100 Hz to 4000 Hz.
-        </li>
-        <li>Audio input sensitivity SHOULD be set such that a 90 dB sound power level (SPL) source at 1000 Hz yields RMS of 2500 for 16-bit samples.
-        </li>
-        <li>PCM amplitude levels SHOULD linearly track input SPL changes over at least a 30 dB range from -18 dB to +12 dB re 90 dB SPL at the microphone.
-        </li>
-        <li>Total harmonic distortion SHOULD be less than 1% for 1 kHz at 90 dB SPL input level at the microphone.
-        </li>
-        <li>Noise reduction processing, if present, MUST be disabled.
-        </li>
-        <li>Automatic gain control, if present, MUST be disabled.
-        </li>
-      </ul>
-      <p>
-        If the platform supports noise suppression technologies tuned for speech recognition, the effect MUST be controllable from the android.media.audiofx.NoiseSuppressor API. Moreover, the UUID field for the noise suppressor’s effect descriptor MUST uniquely identify each implementation of the noise suppression technology.
-      </p>
-      <h3 id="5_4_3_capture_for_rerouting_of_playback">
-        5.4.3. Capture for Rerouting of Playback
-      </h3>
-      <p>
-        The android.media.MediaRecorder.AudioSource class includes the REMOTE_SUBMIX audio source. Devices that declare android.hardware.audio.output MUST properly implement the REMOTE_SUBMIX audio source so that when an application uses the android.media.AudioRecord API to record from this audio source, it can capture a mix of all audio streams except for the following:
-      </p>
-      <ul>
-        <li>STREAM_RING
-        </li>
-        <li>STREAM_ALARM
-        </li>
-        <li>STREAM_NOTIFICATION
-        </li>
-      </ul>
-      <h2 id="5_5_audio_playback">
-        5.5. Audio Playback
-      </h2>
-      <p>
-        Device implementations that declare android.hardware.audio.output MUST conform to the requirements in this section.
-      </p>
-      <h3 id="5_5_1_raw_audio_playback">
-        5.5.1. Raw Audio Playback
-      </h3>
-      <p>
-        The device MUST allow playback of raw audio content with the following characteristics:
-      </p>
-      <ul>
-        <li>
-          <strong>Format</strong> : Linear PCM, 16-bit
-        </li>
-        <li>
-          <strong>Sampling rates</strong> : 8000, 11025, 16000, 22050, 32000, 44100
-        </li>
-        <li>
-          <strong>Channels</strong> : Mono, Stereo
-        </li>
-      </ul>
-      <p>
-        The device SHOULD allow playback of raw audio content with the following characteristics:
-      </p>
-      <ul>
-        <li>
-          <strong>Sampling rates</strong> : 24000, 48000
-        </li>
-      </ul>
-      <h3 id="5_5_2_audio_effects">
-        5.5.2. Audio Effects
-      </h3>
-      <p>
-        Android provides an <a href="http://developer.android.com/reference/android/media/audiofx/AudioEffect.html">API for audio effects</a> for device implementations. Device implementations that declare the feature android.hardware.audio.output:
-      </p>
-      <ul>
-        <li>MUST support the EFFECT_TYPE_EQUALIZER and EFFECT_TYPE_LOUDNESS_ENHANCER implementations controllable through the AudioEffect subclasses Equalizer, LoudnessEnhancer.
-        </li>
-        <li>MUST support the visualizer API implementation, controllable through the Visualizer class.
-        </li>
-        <li>SHOULD support the EFFECT_TYPE_BASS_BOOST, EFFECT_TYPE_ENV_REVERB, EFFECT_TYPE_PRESET_REVERB, and EFFECT_TYPE_VIRTUALIZER implementations controllable through the AudioEffect sub-classes BassBoost, EnvironmentalReverb, PresetReverb, and Virtualizer.
-        </li>
-      </ul>
-      <h3 id="5_5_3_audio_output_volume">
-        5.5.3. Audio Output Volume
-      </h3>
-      <p>
-        Android Television device implementations MUST include support for system Master Volume and digital audio output volume attenuation on supported outputs, except for compressed audio passthrough output (where no audio decoding is done on the device).
-      </p>
-      <p>
-        Android Automotive device implementations SHOULD allow adjusting audio volume separately per each audio stream using the content type or usage as defined by <a href="" title="http://developer.android.com/reference/android/media/AudioAttributes.html">AudioAttributes</a> and car audio usage as publicly defined in <code>android.car.CarAudioManager</code> .
-      </p>
-      <h2 id="5_6_audio_latency">
-        5.6. Audio Latency
-      </h2>
-      <p>
-        Audio latency is the time delay as an audio signal passes through a system. Many classes of applications rely on short latencies, to achieve real-time sound effects.
-      </p>
-      <p>
-        For the purposes of this section, use the following definitions:
-      </p>
-      <ul>
-        <li>
-          <strong>output latency</strong> . The interval between when an application writes a frame of PCM-coded data and when the corresponding sound is presented to environment at an on-device transducer or signal leaves the device via a port and can be observed externally.
-        </li>
-        <li>
-          <strong>cold output latency</strong> . The output latency for the first frame, when the audio output system has been idle and powered down prior to the request.
-        </li>
-        <li>
-          <strong>continuous output latency</strong> . The output latency for subsequent frames, after the device is playing audio.
-        </li>
-        <li>
-          <strong>input latency</strong> . The interval between when a sound is presented by environment to device at an on-device transducer or signal enters the device via a port and when an application reads the corresponding frame of PCM-coded data.
-        </li>
-        <li>
-          <strong>lost input</strong> . The initial portion of an input signal that is unusable or unavailable.
-        </li>
-        <li>
-          <strong>cold input latency</strong> . The sum of lost input time and the input latency for the first frame, when the audio input system has been idle and powered down prior to the request.
-        </li>
-        <li>
-          <strong>continuous input latency</strong> . The input latency for subsequent frames, while the device is capturing audio.
-        </li>
-        <li>
-          <strong>cold output jitter</strong> . The variability among separate measurements of cold output latency values.
-        </li>
-        <li>
-          <strong>cold input jitter</strong> . The variability among separate measurements of cold input latency values.
-        </li>
-        <li>
-          <strong>continuous round-trip latency</strong> . The sum of continuous input latency plus continuous output latency plus one buffer period. The buffer period allows time for the app to process the signal and time for the app to mitigate phase difference between input and output streams.
-        </li>
-        <li>
-          <strong>OpenSL ES PCM buffer queue API</strong> . The set of PCM-related OpenSL ES APIs within <a href="https://developer.android.com/ndk/index.html">Android NDK</a> .
-        </li>
-      </ul>
-      <p>
-        Device implementations that declare android.hardware.audio.output are STRONGLY RECOMMENDED to meet or exceed these audio output requirements:
-      </p>
-      <ul>
-        <li>cold output latency of 100 milliseconds or less
-        </li>
-        <li>continuous output latency of 45 milliseconds or less
-        </li>
-        <li>minimize the cold output jitter
-        </li>
-      </ul>
-      <p>
-        If a device implementation meets the requirements of this section after any initial calibration when using the OpenSL ES PCM buffer queue API, for continuous output latency and cold output latency over at least one supported audio output device, it is STRONGLY RECOMMENDED to report support for low-latency audio, by reporting the feature android.hardware.audio.low_latency via the <a href="http://developer.android.com/reference/android/content/pm/PackageManager.html">android.content.pm.PackageManager</a> class. Conversely, if the device implementation does not meet these requirements it MUST NOT report support for low-latency audio.
-      </p>
-      <p>
-        Device implementations that include android.hardware.microphone are STRONGLY RECOMMENDED to meet these input audio requirements:
-      </p>
-      <ul>
-        <li>cold input latency of 100 milliseconds or less
-        </li>
-        <li>continuous input latency of 30 milliseconds or less
-        </li>
-        <li>continuous round-trip latency of 50 milliseconds or less
-        </li>
-        <li>minimize the cold input jitter
-        </li>
-      </ul>
-      <h2 id="5_7_network_protocols">
-        5.7. Network Protocols
-      </h2>
-      <p>
-        Devices MUST support the <a href="http://developer.android.com/guide/appendix/media-formats.html">media network protocols</a> for audio and video playback as specified in the Android SDK documentation. Specifically, devices MUST support the following media network protocols:
-      </p>
-      <ul>
-        <li>
-          <p>
-            HTTP(S) progressive streaming<br />
-            All required codecs and container formats in <a href="#5_1_media_codecs">section 5.1</a> MUST be supported over HTTP(S)
-          </p>
-        </li>
-        <li>
-          <p>
-            <a href="http://tools.ietf.org/html/draft-pantos-http-live-streaming-07">HTTP Live Streaming draft protocol, Version 7</a><br />
-            The following media segment formats MUST be supported:
-          </p>
-        </li>
-      </ul>
-      <table>
-        <tr>
-          <th>
-            Segment formats
-          </th>
-          <th>
-            Reference(s)
-          </th>
-          <th>
-            Required codec support
-          </th>
-        </tr>
-        <tr id="mp2t">
-          <td>
-            MPEG-2 Transport Stream
-          </td>
-          <td>
-            <a href="http://www.iso.org/iso/catalogue_detail?csnumber=44169">ISO 13818</a>
-          </td>
-          <td>
-            Video codecs:
-            <ul>
-              <li class="table_list">H264 AVC
-              </li>
-              <li class="table_list">MPEG-4 SP
-              </li>
-              <li class="table_list">MPEG-2
-              </li>
-            </ul>See <a href="#5_1_3_video_codecs">section 5.1.3</a> for details on H264 AVC, MPEG2-4 SP,<br />
-            and MPEG-2.
-            <p>
-              Audio codecs:
-            </p>
-            <ul>
-              <li class="table_list">AAC
-              </li>
-            </ul>See <a href="#5_1_1_audio_codecs">section 5.1.1</a> for details on AAC and its variants.
-          </td>
-        </tr>
-        <tr>
-          <td>
-            AAC with ADTS framing and ID3 tags
-          </td>
-          <td>
-            <a href="http://www.iso.org/iso/home/store/catalogue_tc/catalogue_detail.htm?csnumber=43345">ISO 13818-7</a>
-          </td>
-          <td>
-            See <a href="#5_1_1_audio_codecs">section 5.1.1</a> for details on AAC and its variants
-          </td>
-        </tr>
-        <tr>
-          <td>
-            WebVTT
-          </td>
-          <td>
-            <a href="http://dev.w3.org/html5/webvtt/">WebVTT</a>
-          </td>
-          <td></td>
-        </tr>
-      </table>
-      <ul>
-        <li>
-          <p>
-            RTSP (RTP, SDP)
-          </p>
-          <p>
-            The following RTP audio video profile and related codecs MUST be supported. For exceptions please see the table footnotes in <a href="#5_1_media_codecs">section 5.1</a> .
-          </p>
-        </li>
-      </ul>
-      <table>
-        <tr>
-          <th>
-            Profile name
-          </th>
-          <th>
-            Reference(s)
-          </th>
-          <th>
-            Required codec support
-          </th>
-        </tr>
-        <tr>
-          <td>
-            H264 AVC
-          </td>
-          <td>
-            <a href="https://tools.ietf.org/html/rfc6184">RFC 6184</a>
-          </td>
-          <td>
-            See <a href="#5_1_3_video_codecs">section 5.1.3</a> for details on H264 AVC
-          </td>
-        </tr>
-        <tr>
-          <td>
-            MP4A-LATM
-          </td>
-          <td>
-            <a href="https://tools.ietf.org/html/rfc6416">RFC 6416</a>
-          </td>
-          <td>
-            See <a href="#5_1_1_audio_codecs">section 5.1.1</a> for details on AAC and its variants
-          </td>
-        </tr>
-        <tr>
-          <td>
-            H263-1998
-          </td>
-          <td>
-            <a href="https://tools.ietf.org/html/rfc3551">RFC 3551</a><br />
-            <a href="https://tools.ietf.org/html/rfc4629">RFC 4629</a><br />
-            <a href="https://tools.ietf.org/html/rfc2190">RFC 2190</a>
-          </td>
-          <td>
-            See <a href="#5_1_3_video_codecs">section 5.1.3</a> for details on H263
-          </td>
-        </tr>
-        <tr>
-          <td>
-            H263-2000
-          </td>
-          <td>
-            <a href="https://tools.ietf.org/html/rfc4629">RFC 4629</a>
-          </td>
-          <td>
-            See <a href="#5_1_3_video_codecs">section 5.1.3</a> for details on H263
-          </td>
-        </tr>
-        <tr>
-          <td>
-            AMR
-          </td>
-          <td>
-            <a href="https://tools.ietf.org/html/rfc4867">RFC 4867</a>
-          </td>
-          <td>
-            See <a href="#5_1_1_audio_codecs">section 5.1.1</a> for details on AMR-NB
-          </td>
-        </tr>
-        <tr>
-          <td>
-            AMR-WB
-          </td>
-          <td>
-            <a href="https://tools.ietf.org/html/rfc4867">RFC 4867</a>
-          </td>
-          <td>
-            See <a href="#5_1_1_audio_codecs">section 5.1.1</a> for details on AMR-WB
-          </td>
-        </tr>
-        <tr>
-          <td>
-            MP4V-ES
-          </td>
-          <td>
-            <a href="https://tools.ietf.org/html/rfc6416">RFC 6416</a>
-          </td>
-          <td>
-            See <a href="#5_1_3_video_codecs">section 5.1.3</a> for details on MPEG-4 SP
-          </td>
-        </tr>
-        <tr>
-          <td>
-            mpeg4-generic
-          </td>
-          <td>
-            <a href="https://tools.ietf.org/html/rfc3640">RFC 3640</a>
-          </td>
-          <td>
-            See <a href="#5_1_1_audio_codecs">section 5.1.1</a> for details on AAC and its variants
-          </td>
-        </tr>
-        <tr>
-          <td>
-            MP2T
-          </td>
-          <td>
-            <a href="https://tools.ietf.org/html/rfc2250">RFC 2250</a>
-          </td>
-          <td>
-            See <a href="#mp2t">MPEG-2 Transport Stream</a> underneath HTTP Live Streaming for details
-          </td>
-        </tr>
-      </table>
-      <h2 id="5_8_secure_media">
-        5.8. Secure Media
-      </h2>
-      <p>
-        Device implementations that support secure video output and are capable of supporting secure surfaces MUST declare support for Display.FLAG_SECURE. Device implementations that declare support for Display.FLAG_SECURE, if they support a wireless display protocol, MUST secure the link with a cryptographically strong mechanism such as HDCP 2.x or higher for Miracast wireless displays. Similarly if they support a wired external display, the device implementations MUST support HDCP 1.2 or higher. Android Television device implementations MUST support HDCP 2.2 for devices supporting 4K resolution and HDCP 1.4 or above for lower resolutions. The upstream Android open source implementation includes support for wireless (Miracast) and wired (HDMI) displays that satisfies this requirement.
-      </p>
-      <h2 id="5_9_musical_instrument_digital_interface_(midi)">
-        5.9. Musical Instrument Digital Interface (MIDI)
-      </h2>
-      <p>
-        If a device implementation supports the inter-app MIDI software transport (virtual MIDI devices), and it supports MIDI over <em>all</em> of the following MIDI-capable hardware transports for which it provides generic non-MIDI connectivity, it is STRONGLY RECOMMENDED to report support for feature android.software.midi via the <a href="http://developer.android.com/reference/android/content/pm/PackageManager.html">android.content.pm.PackageManager</a> class.
-      </p>
-      <p>
-        The MIDI-capable hardware transports are:
-      </p>
-      <ul>
-        <li>USB host mode (section 7.7 USB)
-        </li>
-        <li>USB peripheral mode (section 7.7 USB)
-        </li>
-        <li>MIDI over Bluetooth LE acting in central role (section 7.4.3 Bluetooth)
-        </li>
-      </ul>
-      <p>
-        Conversely, if the device implementation provides generic non-MIDI connectivity over a particular MIDI-capable hardware transport listed above, but does not support MIDI over that hardware transport, it MUST NOT report support for feature android.software.midi.
-      </p>
-      <h2 id="5_10_professional_audio">
-        5.10. Professional Audio
-      </h2>
-      <p>
-        If a device implementation meets <em>all</em> of the following requirements, it is STRONGLY RECOMMENDED to report support for feature android.hardware.audio.pro via the <a href="http://developer.android.com/reference/android/content/pm/PackageManager.html">android.content.pm.PackageManager</a> class.
-      </p>
-      <ul>
-        <li>The device implementation MUST report support for feature android.hardware.audio.low_latency.
-        </li>
-        <li>The continuous round-trip audio latency, as defined in section 5.6 Audio Latency, MUST be 20 milliseconds or less and SHOULD be 10 milliseconds or less over at least one supported path.
-        </li>
-        <li>If the device includes a 4 conductor 3.5mm audio jack, the continuous round-trip audio latency MUST be 20 milliseconds or less over the audio jack path, and SHOULD be 10 milliseconds or less over at the audio jack path.
-        </li>
-        <li>The device implementation MUST include a USB port(s) supporting USB host mode and USB peripheral mode.
-        </li>
-        <li>The USB host mode MUST implement the USB audio class.
-        </li>
-        <li>If the device includes an HDMI port, the device implementation MUST support output in stereo and eight channels at 20-bit or 24-bit depth and 192 kHz without bit-depth loss or resampling.
-        </li>
-        <li>The device implementation MUST report support for feature android.software.midi.
-        </li>
-        <li>If the device includes a 4 conductor 3.5mm audio jack, the device implementation is STRONGLY RECOMMENDED to comply with section <a href="https://source.android.com/accessories/headset/specification.html#mobile_device_jack_specifications">Mobile device (jack) specifications</a> of the <a href="https://source.android.com/accessories/headset/specification.html">Wired Audio Headset Specification (v1.1)</a> .
-        </li>
-      </ul>
-      <p>
-        Latencies and USB audio requirements MUST be met using the <a href="https://developer.android.com/ndk/guides/audio/opensl-for-android.html">OpenSL ES</a> PCM buffer queue API.
-      </p>
-      <p>
-        In addition, a device implementation that reports support for this feature SHOULD:
-      </p>
-      <ul>
-        <li>Provide a sustainable level of CPU performance while audio is active.
-        </li>
-        <li>Minimize audio clock inaccuracy and drift relative to standard time.
-        </li>
-        <li>Minimize audio clock drift relative to the CPU <code>CLOCK_MONOTONIC</code> when both are active.
-        </li>
-        <li>Minimize audio latency over on-device transducers.
-        </li>
-        <li>Minimize audio latency over USB digital audio.
-        </li>
-        <li>Document audio latency measurements over all paths.
-        </li>
-        <li>Minimize jitter in audio buffer completion callback entry times, as this affects usable percentage of full CPU bandwidth by the callback.
-        </li>
-        <li>Provide zero audio underruns (output) or overruns (input) under normal use at reported latency.
-        </li>
-        <li>Provide zero inter-channel latency difference.
-        </li>
-        <li>Minimize MIDI mean latency over all transports.
-        </li>
-        <li>Minimize MIDI latency variability under load (jitter) over all transports.
-        </li>
-        <li>Provide accurate MIDI timestamps over all transports.
-        </li>
-        <li>Minimize audio signal noise over on-device transducers, including the period immediately after cold start.
-        </li>
-        <li>Provide zero audio clock difference between the input and output sides of corresponding end-points, when both are active. Examples of corresponding end-points include the on-device microphone and speaker, or the audio jack input and output.
-        </li>
-        <li>Handle audio buffer completion callbacks for the input and output sides of corresponding end-points on the same thread when both are active, and enter the output callback immediately after the return from the input callback. Or if it is not feasible to handle the callbacks on the same thread, then enter the output callback shortly after entering the input callback to permit the application to have a consistent timing of the input and output sides.
-        </li>
-        <li>Minimize the phase difference between HAL audio buffering for the input and output sides of corresponding end-points.
-        </li>
-        <li>Minimize touch latency.
-        </li>
-        <li>Minimize touch latency variability under load (jitter).
-        </li>
-      </ul>
-      <h2 id="5_11_capture_for_unprocessed">
-        5.11. Capture for Unprocessed
-      </h2>
-      <p>
-        Starting from Android 7.0, a new recording source has been added. It can be accessed using the <code>android.media.MediaRecorder.AudioSource.UNPROCESSED</code> audio source. In OpenSL ES, it can be accessed with the record preset <code>SL_ANDROID_RECORDING_PRESET_UNPROCESSED</code> .
-      </p>
-      <p>
-        A device MUST satisfy all of the following requirements to report support of the unprocessed audio source via the <code>android.media.AudioManager</code> property <a href="http://developer.android.com/reference/android/media/AudioManager.html#PROPERTY_SUPPORT_AUDIO_SOURCE_UNPROCESSED">PROPERTY_SUPPORT_AUDIO_SOURCE_UNPROCESSED</a> :
-      </p>
-      <ul>
-        <li>
-          <p>
-            The device MUST exhibit approximately flat amplitude-versus-frequency characteristics in the mid-frequency range: specifically ±10dB from 100 Hz to 7000 Hz.
-          </p>
-        </li>
-        <li>
-          <p>
-            The device MUST exhibit amplitude levels in the low frequency range: specifically from ±20 dB from 5 Hz to 100 Hz compared to the mid-frequency range.
-          </p>
-        </li>
-        <li>
-          <p>
-            The device MUST exhibit amplitude levels in the high frequency range: specifically from ±30 dB from 7000 Hz to 22 KHz compared to the mid-frequency range.
-          </p>
-        </li>
-        <li>
-          <p>
-            Audio input sensitivity MUST be set such that a 1000 Hz sinusoidal tone source played at 94 dB Sound Pressure Level (SPL) yields a response with RMS of 520 for 16 bit-samples (or -36 dB Full Scale for floating point/double precision samples).
-          </p>
-        </li>
-        <li>
-          <p>
-            SNR &gt; 60 dB (difference between 94 dB SPL and equivalent SPL of self noise, A-weighted).
-          </p>
-        </li>
-        <li>
-          <p>
-            Total harmonic distortion MUST be less than 1% for 1 kHZ at 90 dB SPL input level at the microphone.
-          </p>
-        </li>
-        <li>
-          <p>
-            The only signal processing allowed in the path is a level multiplier to bring the level to desired range. This level multiplier MUST NOT introduce delay or latency to the signal path.
-          </p>
-        </li>
-        <li>
-          <p>
-            No other signal processing is allowed in the path, such as Automatic Gain Control, High Pass Filter, or Echo Cancellation. If any signal processing is present in the architecture for any reason, it MUST be disabled and effectively introduce zero delay or extra latency to the signal path.
-          </p>
-        </li>
-      </ul>
-      <p>
-        All SPL measurements are made directly next to the microphone under test.
-      </p>
-      <p>
-        For multiple microphone configurations, these requirements apply to each microphone.
-      </p>
-      <p>
-        It is STRONGLY RECOMMENDED that a device satisfy as many of the requirements for the signal path for the unprocessed recording source; however, a device must satisfy <em>all</em> of these requirements, listed above, if it claims to support the unprocessed audio source.
-      </p>
-      <h1 id="6_developer_tools_and_options_compatibility">
-        6. Developer Tools and Options Compatibility
-      </h1>
-      <h2 id="6_1_developer_tools">
-        6.1. Developer Tools
-      </h2>
-      <p>
-        Device implementations MUST support the Android Developer Tools provided in the Android SDK. Android compatible devices MUST be compatible with:
-      </p>
-      <ul>
-        <li>
-          <a href="http://developer.android.com/tools/help/adb.html"><strong>Android Debug Bridge (adb)</strong></a>
-          <ul>
-            <li>Device implementations MUST support all adb functions as documented in the Android SDK including <a href="https://source.android.com/devices/input/diagnostics.html">dumpsys</a> .
-            </li>
-            <li>The device-side adb daemon MUST be inactive by default and there MUST be a user-accessible mechanism to turn on the Android Debug Bridge. If a device implementation omits USB peripheral mode, it MUST implement the Android Debug Bridge via local-area network (such as Ethernet or 802.11).
-            </li>
-            <li>Android includes support for secure adb. Secure adb enables adb on known authenticated hosts. Device implementations MUST support secure adb.
-            </li>
-          </ul>
-        </li>
-        <li>
-          <a href="http://developer.android.com/tools/debugging/ddms.html"><strong>Dalvik Debug Monitor Service (ddms)</strong></a>
-          <ul>
-            <li>Device implementations MUST support all ddms features as documented in the Android SDK.
-            </li>
-            <li>As ddms uses adb, support for ddms SHOULD be inactive by default, but MUST be supported whenever the user has activated the Android Debug Bridge, as above.
-            </li>
-          </ul>
-        </li>
-        <li>
-          <a href="http://developer.android.com/tools/help/monkey.html"><strong>Monkey</strong></a> Device implementations MUST include the Monkey framework, and make it available for applications to use.
-        </li>
-        <li>
-          <a href="http://developer.android.com/tools/help/systrace.html"><strong>SysTrace</strong></a>
-          <ul>
-            <li>Device implementations MUST support systrace tool as documented in the Android SDK. Systrace must be inactive by default, and there MUST be a user-accessible mechanism to turn on Systrace.
-            </li>
-            <li>Most Linux-based systems and Apple Macintosh systems recognize Android devices using the standard Android SDK tools, without additional support; however Microsoft Windows systems typically require a driver for new Android devices. (For instance, new vendor IDs and sometimes new device IDs require custom USB drivers for Windows systems.)
-            </li>
-            <li>If a device implementation is unrecognized by the adb tool as provided in the standard Android SDK, device implementers MUST provide Windows drivers allowing developers to connect to the device using the adb protocol. These drivers MUST be provided for Windows XP, Windows Vista, Windows 7, Windows 8, and Windows 10 in both 32-bit and 64-bit versions.
-            </li>
-          </ul>
-        </li>
-      </ul>
-      <h2 id="6_2_developer_options">
-        6.2. Developer Options
-      </h2>
-      <p>
-        Android includes support for developers to configure application development-related settings. Device implementations MUST honor the <a href="http://developer.android.com/reference/android/provider/Settings.html#ACTION_APPLICATION_DEVELOPMENT_SETTINGS">android.settings.APPLICATION_DEVELOPMENT_SETTINGS</a> intent to show application development-related settings The upstream Android implementation hides the Developer Options menu by default and enables users to launch Developer Options after pressing seven (7) times on the <strong>Settings</strong> &gt; <strong>About Device</strong> &gt; <strong>Build Number</strong> menu item. Device implementations MUST provide a consistent experience for Developer Options. Specifically, device implementations MUST hide Developer Options by default and MUST provide a mechanism to enable Developer Options that is consistent with the upstream Android implementation.
-      </p>
-      <div class="note">
-        Android Automotive implementations MAY limit access to the Developer Options menu by visually hiding or disabling the menu when the vehicle is in motion.
-      </div>
-      <h1 id="7_hardware_compatibility">
-        7. Hardware Compatibility
-      </h1>
-      <p>
-        If a device includes a particular hardware component that has a corresponding API for third-party developers, the device implementation MUST implement that API as described in the Android SDK documentation. If an API in the SDK interacts with a hardware component that is stated to be optional and the device implementation does not possess that component:
-      </p>
-      <ul>
-        <li>Complete class definitions (as documented by the SDK) for the component APIs MUST still be presented.
-        </li>
-        <li>The API’s behaviors MUST be implemented as no-ops in some reasonable fashion.
-        </li>
-        <li>API methods MUST return null values where permitted by the SDK documentation.
-        </li>
-        <li>API methods MUST return no-op implementations of classes where null values are not permitted by the SDK documentation.
-        </li>
-        <li>API methods MUST NOT throw exceptions not documented by the SDK documentation.
-        </li>
-      </ul>
-      <p>
-        A typical example of a scenario where these requirements apply is the telephony API: Even on non-phone devices, these APIs must be implemented as reasonable no-ops.
-      </p>
-      <p>
-        Device implementations MUST consistently report accurate hardware configuration information via the getSystemAvailableFeatures() and hasSystemFeature(String) methods on the <a href="http://developer.android.com/reference/android/content/pm/PackageManager.html">android.content.pm.PackageManager</a> class for the same build fingerprint.
-      </p>
-      <h2 id="7_1_display_and_graphics">
-        7.1. Display and Graphics
-      </h2>
-      <p>
-        Android includes facilities that automatically adjust application assets and UI layouts appropriately for the device to ensure that third-party applications run well on a <a href="http://developer.android.com/guide/practices/screens_support.html">variety of hardware configurations</a> . Devices MUST properly implement these APIs and behaviors, as detailed in this section.
-      </p>
-      <p>
-        The units referenced by the requirements in this section are defined as follows:
-      </p>
-      <ul>
-        <li>
-          <strong>physical diagonal size</strong> . The distance in inches between two opposing corners of the illuminated portion of the display.
-        </li>
-        <li>
-          <strong>dots per inch (dpi)</strong> . The number of pixels encompassed by a linear horizontal or vertical span of 1”. Where dpi values are listed, both horizontal and vertical dpi must fall within the range.
-        </li>
-        <li>
-          <strong>aspect ratio</strong> . The ratio of the pixels of the longer dimension to the shorter dimension of the screen. For example, a display of 480x854 pixels would be 854/480 = 1.779, or roughly “16:9”.
-        </li>
-        <li>
-          <strong>density-independent pixel (dp)</strong> . The virtual pixel unit normalized to a 160 dpi screen, calculated as: pixels = dps * (density/160).
-        </li>
-      </ul>
-      <h3 id="7_1_1_screen_configuration">
-        7.1.1. Screen Configuration
-      </h3>
-      <h4 id="7_1_1_1_screen_size">
-        7.1.1.1. Screen Size
-      </h4>
-      <div class="note">
-        Android Watch devices (detailed in <a href="#2_device_types">section 2</a> ) MAY have smaller screen sizes as described in this section.
-      </div>
-      <p>
-        The Android UI framework supports a variety of different screen sizes, and allows applications to query the device screen size (aka “screen layout") via android.content.res.Configuration.screenLayout with the SCREENLAYOUT_SIZE_MASK. Device implementations MUST report the correct <a href="http://developer.android.com/guide/practices/screens_support.html">screen size</a> as defined in the Android SDK documentation and determined by the upstream Android platform. Specifically, device implementations MUST report the correct screen size according to the following logical density-independent pixel (dp) screen dimensions.
-      </p>
-      <ul>
-        <li>Devices MUST have screen sizes of at least 426 dp x 320 dp (‘small’), unless it is an Android Watch device.
-        </li>
-        <li>Devices that report screen size ‘normal’ MUST have screen sizes of at least 480 dp x 320 dp.
-        </li>
-        <li>Devices that report screen size ‘large’ MUST have screen sizes of at least 640 dp x 480 dp.
-        </li>
-        <li>Devices that report screen size ‘xlarge’ MUST have screen sizes of at least 960 dp x 720 dp.
-        </li>
-      </ul>
-      <p>
-        In addition:
-      </p>
-      <ul>
-        <li>Android Watch devices MUST have a screen with the physical diagonal size in the range from 1.1 to 2.5 inches.
-        </li>
-        <li>Android Automotive devices MUST have a screen with the physical diagonal size greater than or equal to 6 inches.
-        </li>
-        <li>Android Automotive devices MUST have a screen size of at least 750 dp x 480 dp.
-        </li>
-        <li>Other types of Android device implementations, with a physically integrated screen, MUST have a screen at least 2.5 inches in physical diagonal size.
-        </li>
-      </ul>
-      <p>
-        Devices MUST NOT change their reported screen size at any time.
-      </p>
-      <p>
-        Applications optionally indicate which screen sizes they support via the &lt;supports-screens&gt; attribute in the AndroidManifest.xml file. Device implementations MUST correctly honor applications' stated support for small, normal, large, and xlarge screens, as described in the Android SDK documentation.
-      </p>
-      <h4 id="7_1_1_2_screen_aspect_ratio">
-        7.1.1.2. Screen Aspect Ratio
-      </h4>
-      <p>
-        While there is no restriction to the screen aspect ratio value of the physical screen display, the screen aspect ratio of the surface that third-party apps are rendered on and which can be derived from the values reported via the <a href="https://developer.android.com/reference/android/util/DisplayMetrics.html">DisplayMetrics</a> MUST meet the following requirements:
-      </p>
-      <ul>
-        <li>If the <a href="https://developer.android.com/reference/android/content/res/Configuration.html#uiMode">uiMode</a> is configured as UI_MODE_TYPE_WATCH, the aspect ratio value MAY be set as 1.0 (1:1).
-        </li>
-        <li>If the third-party app indicates that it is resizeable via the <a href="https://developer.android.com/guide/topics/ui/multi-window.html#configuring">android:resizeableActivity</a> attribute, there are no restrictions to the aspect ratio value.
-        </li>
-        <li>For all other cases, the aspect ratio MUST be a value between 1.3333 (4:3) and 1.86 (roughly 16:9) unless the app has indicated explicitly that it supports a higher screen aspect ratio through the <a href="https://developer.android.com/guide/practices/screens_support.html#MaxAspectRatio">maxAspectRatio</a> metadata value.
-        </li>
-      </ul>
-      <h4 id="7_1_1_3_screen_density">
-        7.1.1.3. Screen Density
-      </h4>
-      <p>
-        The Android UI framework defines a set of standard logical densities to help application developers target application resources. By default, device implementations MUST report only one of the following logical Android framework densities through the <a href="https://developer.android.com/reference/android/util/DisplayMetrics.html#DENSITY_DEVICE_STABLE">DENSITY_DEVICE_STABLE</a> API and this value MUST NOT change at any time; however, the device MAY report a different arbitrary density according to the display configuration changes made by the user (for example, display size) set after initial boot.
-      </p>
-      <ul>
-        <li>120 dpi (ldpi)
-        </li>
-        <li>160 dpi (mdpi)
-        </li>
-        <li>213 dpi (tvdpi)
-        </li>
-        <li>240 dpi (hdpi)
-        </li>
-        <li>260 dpi (260dpi)
-        </li>
-        <li>280 dpi (280dpi)
-        </li>
-        <li>300 dpi (300dpi)
-        </li>
-        <li>320 dpi (xhdpi)
-        </li>
-        <li>340 dpi (340dpi)
-        </li>
-        <li>360 dpi (360dpi)
-        </li>
-        <li>400 dpi (400dpi)
-        </li>
-        <li>420 dpi (420dpi)
-        </li>
-        <li>480 dpi (xxhdpi)
-        </li>
-        <li>560 dpi (560dpi)
-        </li>
-        <li>640 dpi (xxxhdpi)
-        </li>
-      </ul>
-      <p>
-        Device implementations SHOULD define the standard Android framework density that is numerically closest to the physical density of the screen, unless that logical density pushes the reported screen size below the minimum supported. If the standard Android framework density that is numerically closest to the physical density results in a screen size that is smaller than the smallest supported compatible screen size (320 dp width), device implementations SHOULD report the next lowest standard Android framework density.
-      </p>
-      <p>
-        Device implementations are STRONGLY RECOMMENDED to provide users a setting to change the display size. If there is an implementation to change the display size of the device, it MUST align with the AOSP implementation as indicated below:
-      </p>
-      <ul>
-        <li>The display size MUST NOT be scaled any larger than 1.5 times the native density or produce an effective minimum screen dimension smaller than 320dp (equivalent to resource qualifier sw320dp), whichever comes first.
-        </li>
-        <li>Display size MUST NOT be scaled any smaller than 0.85 times the native density.
-        </li>
-        <li>To ensure good usability and consistent font sizes, it is RECOMMENDED that the following scaling of Native Display options be provided (while complying with the limits specified above)
-        </li>
-        <li>Small: 0.85x
-        </li>
-        <li>Default: 1x (Native display scale)
-        </li>
-        <li>Large: 1.15x
-        </li>
-        <li>Larger: 1.3x
-        </li>
-        <li>Largest 1.45x
-        </li>
-      </ul>
-      <h3 id="7_1_2_display_metrics">
-        7.1.2. Display Metrics
-      </h3>
-      <p>
-        Device implementations MUST report correct values for all display metrics defined in <a href="http://developer.android.com/reference/android/util/DisplayMetrics.html">android.util.DisplayMetrics</a> and MUST report the same values regardless of whether the embedded or external screen is used as the default display.
-      </p>
-      <h3 id="7_1_3_screen_orientation">
-        7.1.3. Screen Orientation
-      </h3>
-      <p>
-        Devices MUST report which screen orientations they support (android.hardware.screen.portrait and/or android.hardware.screen.landscape) and MUST report at least one supported orientation. For example, a device with a fixed orientation landscape screen, such as a television or laptop, SHOULD only report android.hardware.screen.landscape.
-      </p>
-      <p>
-        Devices that report both screen orientations MUST support dynamic orientation by applications to either portrait or landscape screen orientation. That is, the device must respect the application’s request for a specific screen orientation. Device implementations MAY select either portrait or landscape orientation as the default.
-      </p>
-      <p>
-        Devices MUST report the correct value for the device’s current orientation, whenever queried via the android.content.res.Configuration.orientation, android.view.Display.getOrientation(), or other APIs.
-      </p>
-      <p>
-        Devices MUST NOT change the reported screen size or density when changing orientation.
-      </p>
-      <h3 id="7_1_4_2d_and_3d_graphics_acceleration">
-        7.1.4. 2D and 3D Graphics Acceleration
-      </h3>
-      <p>
-        Device implementations MUST support both OpenGL ES 1.0 and 2.0, as embodied and detailed in the Android SDK documentations. Device implementations SHOULD support OpenGL ES 3.0, 3.1, or 3.2 on devices capable of supporting it. Device implementations MUST also support <a href="http://developer.android.com/guide/topics/renderscript/">Android RenderScript</a> , as detailed in the Android SDK documentation.
-      </p>
-      <p>
-        Device implementations MUST also correctly identify themselves as supporting OpenGL ES 1.0, OpenGL ES 2.0, OpenGL ES 3.0, OpenGL 3.1, or OpenGL 3.2. That is:
-      </p>
-      <ul>
-        <li>The managed APIs (such as via the GLES10.getString() method) MUST report support for OpenGL ES 1.0 and OpenGL ES 2.0.
-        </li>
-        <li>The native C/C++ OpenGL APIs (APIs available to apps via libGLES_v1CM.so, libGLES_v2.so, or libEGL.so) MUST report support for OpenGL ES 1.0 and OpenGL ES 2.0.
-        </li>
-        <li>Device implementations that declare support for OpenGL ES 3.0, 3.1, or 3.2 MUST support the corresponding managed APIs and include support for native C/C++ APIs. On device implementations that declare support for OpenGL ES 3.0, 3.1, or 3.2 libGLESv2.so MUST export the corresponding function symbols in addition to the OpenGL ES 2.0 function symbols.
-        </li>
-      </ul>
-      <p>
-        Android provides an OpenGL ES <a href="https://developer.android.com/reference/android/opengl/GLES31Ext.html">extension pack</a> with Java interfaces and native support for advanced graphics functionality such as tessellation and the ASTC texture compression format. Android device implementations MUST support the extension pack if the device supports OpenGL ES 3.2 and MAY support it otherwise. If the extension pack is supported in its entirety, the device MUST identify the support through the <code>android.hardware.opengles.aep</code> feature flag.
-      </p>
-      <p>
-        Also, device implementations MAY implement any desired OpenGL ES extensions. However, device implementations MUST report via the OpenGL ES managed and native APIs all extension strings that they do support, and conversely MUST NOT report extension strings that they do not support.
-      </p>
-      <p>
-        Note that Android includes support for applications to optionally specify that they require specific OpenGL texture compression formats. These formats are typically vendor-specific. Device implementations are not required by Android to implement any specific texture compression format. However, they SHOULD accurately report any texture compression formats that they do support, via the getString() method in the OpenGL API.
-      </p>
-      <p>
-        Android includes a mechanism for applications to declare that they want to enable hardware acceleration for 2D graphics at the Application, Activity, Window, or View level through the use of a manifest tag <a href="http://developer.android.com/guide/topics/graphics/hardware-accel.html">android:hardwareAccelerated</a> or direct API calls.
-      </p>
-      <p>
-        Device implementations MUST enable hardware acceleration by default, and MUST disable hardware acceleration if the developer so requests by setting android:hardwareAccelerated="false” or disabling hardware acceleration directly through the Android View APIs.
-      </p>
-      <p>
-        In addition, device implementations MUST exhibit behavior consistent with the Android SDK documentation on <a href="http://developer.android.com/guide/topics/graphics/hardware-accel.html">hardware acceleration</a> .
-      </p>
-      <p>
-        Android includes a TextureView object that lets developers directly integrate hardware-accelerated OpenGL ES textures as rendering targets in a UI hierarchy. Device implementations MUST support the TextureView API, and MUST exhibit consistent behavior with the upstream Android implementation.
-      </p>
-      <p>
-        Android includes support for EGL_ANDROID_RECORDABLE, an EGLConfig attribute that indicates whether the EGLConfig supports rendering to an ANativeWindow that records images to a video. Device implementations MUST support <a href="https://www.khronos.org/registry/egl/extensions/ANDROID/EGL_ANDROID_recordable.txt">EGL_ANDROID_RECORDABLE</a> extension.
-      </p>
-      <h3 id="7_1_5_legacy_application_compatibility_mode">
-        7.1.5. Legacy Application Compatibility Mode
-      </h3>
-      <p>
-        Android specifies a “compatibility mode” in which the framework operates in a 'normal' screen size equivalent (320dp width) mode for the benefit of legacy applications not developed for old versions of Android that pre-date screen-size independence.
-      </p>
-      <ul>
-        <li>Android Automotive does not support legacy compatibility mode.
-        </li>
-        <li>All other device implementations MUST include support for legacy application compatibility mode as implemented by the upstream Android open source code. That is, device implementations MUST NOT alter the triggers or thresholds at which compatibility mode is activated, and MUST NOT alter the behavior of the compatibility mode itself.
-        </li>
-      </ul>
-      <h3 id="7_1_6_screen_technology">
-        7.1.6. Screen Technology
-      </h3>
-      <p>
-        The Android platform includes APIs that allow applications to render rich graphics to the display. Devices MUST support all of these APIs as defined by the Android SDK unless specifically allowed in this document.
-      </p>
-      <ul>
-        <li>Devices MUST support displays capable of rendering 16-bit color graphics and SHOULD support displays capable of 24-bit color graphics.
-        </li>
-        <li>Devices MUST support displays capable of rendering animations.
-        </li>
-        <li>The display technology used MUST have a pixel aspect ratio (PAR) between 0.9 and 1.15. That is, the pixel aspect ratio MUST be near square (1.0) with a 10 ~ 15% tolerance.
-        </li>
-      </ul>
-      <h3 id="7_1_7_secondary_displays">
-        7.1.7. Secondary Displays
-      </h3>
-      <p>
-        Android includes support for secondary display to enable media sharing capabilities and developer APIs for accessing external displays. If a device supports an external display either via a wired, wireless, or an embedded additional display connection then the device implementation MUST implement the <a href="http://developer.android.com/reference/android/hardware/display/DisplayManager.html">display manager API</a> as described in the Android SDK documentation.
-      </p>
-      <h2 id="7_2_input_devices">
-        7.2. Input Devices
-      </h2>
-      <p>
-        Devices MUST support a touchscreen or meet the requirements listed in 7.2.2 for non-touch navigation.
-      </p>
-      <h3 id="7_2_1_keyboard">
-        7.2.1. Keyboard
-      </h3>
-      <div class="note">
-        Android Watch and Android Automotive implementations MAY implement a soft keyboard. All other device implementations MUST implement a soft keyboard and:
-      </div>
-      <p>
-        Device implementations:
-      </p>
-      <ul>
-        <li>MUST include support for the Input Management Framework (which allows third-party developers to create Input Method Editors—i.e. soft keyboard) as detailed at <a href="http://developer.android.com">http://developer.android.com</a> .
-        </li>
-        <li>MUST provide at least one soft keyboard implementation (regardless of whether a hard keyboard is present) except for Android Watch devices where the screen size makes it less reasonable to have a soft keyboard.
-        </li>
-        <li>MAY include additional soft keyboard implementations.
-        </li>
-        <li>MAY include a hardware keyboard.
-        </li>
-        <li>MUST NOT include a hardware keyboard that does not match one of the formats specified in <a href="http://developer.android.com/reference/android/content/res/Configuration.html">android.content.res.Configuration.keyboard</a> (QWERTY or 12-key).
-        </li>
-      </ul>
-      <h3 id="7_2_2_non-touch_navigation">
-        7.2.2. Non-touch Navigation
-      </h3>
-      <div class="note">
-        Android Television devices MUST support D-pad.
-      </div>
-      <p>
-        Device implementations:
-      </p>
-      <ul>
-        <li>MAY omit a non-touch navigation option (trackball, d-pad, or wheel) if the device implementation is not an Android Television device.
-        </li>
-        <li>MUST report the correct value for <a href="http://developer.android.com/reference/android/content/res/Configuration.html">android.content.res.Configuration.navigation</a> .
-        </li>
-        <li>MUST provide a reasonable alternative user interface mechanism for the selection and editing of text, compatible with Input Management Engines. The upstream Android open source implementation includes a selection mechanism suitable for use with devices that lack non-touch navigation inputs.
-        </li>
-      </ul>
-      <h3 id="7_2_3_navigation_keys">
-        7.2.3. Navigation Keys
-      </h3>
-      <div class="note">
-        The availability and visibility requirement of the Home, Recents, and Back functions differ between device types as described in this section.
-      </div>
-      <p>
-        The Home, Recents, and Back functions (mapped to the key events KEYCODE_HOME, KEYCODE_APP_SWITCH, KEYCODE_BACK, respectively) are essential to the Android navigation paradigm and therefore:
-      </p>
-      <ul>
-        <li>Android Handheld device implementations MUST provide the Home, Recents, and Back functions.
-        </li>
-        <li>Android Television device implementations MUST provide the Home and Back functions.
-        </li>
-        <li>Android Watch device implementations MUST have the Home function available to the user, and the Back function except for when it is in <code>UI_MODE_TYPE_WATCH</code> .
-        </li>
-        <li>Android Watch device implementations, and no other Android device types, MAY consume the long press event on the key event <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BACK"><code>KEYCODE_BACK</code></a> and omit it from being sent to the foreground application.
-        </li>
-        <li>Android Automotive implementations MUST provide the Home function and MAY provide Back and Recent functions.
-        </li>
-        <li>All other types of device implementations MUST provide the Home and Back functions.
-        </li>
-      </ul>
-      <p>
-        These functions MAY be implemented via dedicated physical buttons (such as mechanical or capacitive touch buttons), or MAY be implemented using dedicated software keys on a distinct portion of the screen, gestures, touch panel, etc. Android supports both implementations. All of these functions MUST be accessible with a single action (e.g. tap, double-click or gesture) when visible.
-      </p>
-      <p>
-        Recents function, if provided, MUST have a visible button or icon unless hidden together with other navigation functions in full-screen mode. This does not apply to devices upgrading from earlier Android versions that have physical buttons for navigation and no recents key.
-      </p>
-      <p>
-        The Home and Back functions, if provided, MUST each have a visible button or icon unless hidden together with other navigation functions in full-screen mode or when the uiMode UI_MODE_TYPE_MASK is set to UI_MODE_TYPE_WATCH.
-      </p>
-      <p>
-        The Menu function is deprecated in favor of action bar since Android 4.0. Therefore the new device implementations shipping with Android 7.1 and later MUST NOT implement a dedicated physical button for the Menu function. Older device implementations SHOULD NOT implement a dedicated physical button for the Menu function, but if the physical Menu button is implemented and the device is running applications with targetSdkVersion &gt; 10, the device implementation:
-      </p>
-      <ul>
-        <li>MUST display the action overflow button on the action bar when it is visible and the resulting action overflow menu popup is not empty. For a device implementation launched before Android 4.4 but upgrading to Android 7.1, this is RECOMMENDED.
-        </li>
-        <li>MUST NOT modify the position of the action overflow popup displayed by selecting the overflow button in the action bar.
-        </li>
-        <li>MAY render the action overflow popup at a modified position on the screen when it is displayed by selecting the physical menu button.
-        </li>
-      </ul>
-      <p>
-        For backwards compatibility, device implementations MUST make the Menu function available to applications when targetSdkVersion is less than 10, either by a physical button, a software key, or gestures. This Menu function should be presented unless hidden together with other navigation functions.
-      </p>
-      <p>
-        Android device implementations supporting the <a href="http://developer.android.com/reference/android/content/Intent.html#ACTION_ASSIST">Assist action</a> and/or <a href="https://developer.android.com/reference/android/service/voice/VoiceInteractionService.html"><code>VoiceInteractionService</code></a> MUST be able to launch an assist app with a single interaction (e.g. tap, double-click, or gesture) when other navigation keys are visible. It is STRONGLY RECOMMENDED to use long press on home as this interaction. The designated interaction MUST launch the user-selected assist app, in other words the app that implements a VoiceInteractionService, or an activity handling the ACTION_ASSIST intent.
-      </p>
-      <p>
-        Device implementations MAY use a distinct portion of the screen to display the navigation keys, but if so, MUST meet these requirements:
-      </p>
-      <ul>
-        <li>Device implementation navigation keys MUST use a distinct portion of the screen, not available to applications, and MUST NOT obscure or otherwise interfere with the portion of the screen available to applications.
-        </li>
-        <li>Device implementations MUST make available a portion of the display to applications that meets the requirements defined in <a href="#7_1_1_screen_configuration">section 7.1.1</a> .
-        </li>
-        <li>Device implementations MUST display the navigation keys when applications do not specify a system UI mode, or specify SYSTEM_UI_FLAG_VISIBLE.
-        </li>
-        <li>Device implementations MUST present the navigation keys in an unobtrusive “low profile” (eg. dimmed) mode when applications specify SYSTEM_UI_FLAG_LOW_PROFILE.
-        </li>
-        <li>Device implementations MUST hide the navigation keys when applications specify SYSTEM_UI_FLAG_HIDE_NAVIGATION.
-        </li>
-      </ul>
-      <h3 id="7_2_4_touchscreen_input">
-        7.2.4. Touchscreen Input
-      </h3>
-      <div class="note">
-        Android Handhelds and Watch Devices MUST support touchscreen input.
-      </div>
-      <p>
-        Device implementations SHOULD have a pointer input system of some kind (either mouse-like or touch). However, if a device implementation does not support a pointer input system, it MUST NOT report the android.hardware.touchscreen or android.hardware.faketouch feature constant. Device implementations that do include a pointer input system:
-      </p>
-      <ul>
-        <li>SHOULD support fully independently tracked pointers, if the device input system supports multiple pointers.
-        </li>
-        <li>MUST report the value of <a href="http://developer.android.com/reference/android/content/res/Configuration.html">android.content.res.Configuration.touchscreen</a> corresponding to the type of the specific touchscreen on the device.
-        </li>
-      </ul>
-      <p>
-        Android includes support for a variety of touchscreens, touch pads, and fake touch input devices. <a href="http://source.android.com/devices/tech/input/touch-devices.html">Touchscreen-based device implementations</a> are associated with a display such that the user has the impression of directly manipulating items on screen. Since the user is directly touching the screen, the system does not require any additional affordances to indicate the objects being manipulated. In contrast, a fake touch interface provides a user input system that approximates a subset of touchscreen capabilities. For example, a mouse or remote control that drives an on-screen cursor approximates touch, but requires the user to first point or focus then click. Numerous input devices like the mouse, trackpad, gyro-based air mouse, gyro-pointer, joystick, and multi-touch trackpad can support fake touch interactions. Android includes the feature constant android.hardware.faketouch, which corresponds to a high-fidelity non-touch (pointer-based) input device such as a mouse or trackpad that can adequately emulate touch-based input (including basic gesture support), and indicates that the device supports an emulated subset of touchscreen functionality. Device implementations that declare the fake touch feature MUST meet the fake touch requirements in <a href="#7_2_5_fake_touch_input">section 7.2.5</a> .
-      </p>
-      <p>
-        Device implementations MUST report the correct feature corresponding to the type of input used. Device implementations that include a touchscreen (single-touch or better) MUST report the platform feature constant android.hardware.touchscreen. Device implementations that report the platform feature constant android.hardware.touchscreen MUST also report the platform feature constant android.hardware.faketouch. Device implementations that do not include a touchscreen (and rely on a pointer device only) MUST NOT report any touchscreen feature, and MUST report only android.hardware.faketouch if they meet the fake touch requirements in <a href="#7_2_5_fake_touch_input">section 7.2.5</a> .
-      </p>
-      <h3 id="7_2_5_fake_touch_input">
-        7.2.5. Fake Touch Input
-      </h3>
-      <p>
-        Device implementations that declare support for android.hardware.faketouch:
-      </p>
-      <ul>
-        <li>MUST report the <a href="http://developer.android.com/reference/android/view/MotionEvent.html">absolute X and Y screen positions</a> of the pointer location and display a visual pointer on the screen.
-        </li>
-        <li>MUST report touch event with the action code that specifies the state change that occurs on the pointer <a href="http://developer.android.com/reference/android/view/MotionEvent.html">going down or up on the screen</a> .
-        </li>
-        <li>MUST support pointer down and up on an object on the screen, which allows users to emulate tap on an object on the screen.
-        </li>
-        <li>MUST support pointer down, pointer up, pointer down then pointer up in the same place on an object on the screen within a time threshold, which allows users to <a href="http://developer.android.com/reference/android/view/MotionEvent.html">emulate double tap</a> on an object on the screen.
-        </li>
-        <li>MUST support pointer down on an arbitrary point on the screen, pointer move to any other arbitrary point on the screen, followed by a pointer up, which allows users to emulate a touch drag.
-        </li>
-        <li>MUST support pointer down then allow users to quickly move the object to a different position on the screen and then pointer up on the screen, which allows users to fling an object on the screen.
-        </li>
-      </ul>
-      <p>
-        Devices that declare support for android.hardware.faketouch.multitouch.distinct MUST meet the requirements for faketouch above, and MUST also support distinct tracking of two or more independent pointer inputs.
-      </p>
-      <h3 id="7_2_6_game_controller_support">
-        7.2.6. Game Controller Support
-      </h3>
-      <p>
-        Android Television device implementations MUST support button mappings for game controllers as listed below. The upstream Android implementation includes implementation for game controllers that satisfies this requirement.
-      </p>
-      <h4 id="7_2_6_1_button_mappings">
-        7.2.6.1. Button Mappings
-      </h4>
-      <p>
-        Android Television device implementations MUST support the following key mappings:
-      </p>
-      <table>
-        <tr>
-          <th>
-            Button
-          </th>
-          <th>
-            HID Usage <sup>2</sup>
-          </th>
-          <th>
-            Android Button
-          </th>
-        </tr>
-        <tr>
-          <td>
-            <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BUTTON_A">A</a> <sup>1</sup>
-          </td>
-          <td>
-            0x09 0x0001
-          </td>
-          <td>
-            KEYCODE_BUTTON_A (96)
-          </td>
-        </tr>
-        <tr>
-          <td>
-            <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BUTTON_B">B</a> <sup>1</sup>
-          </td>
-          <td>
-            0x09 0x0002
-          </td>
-          <td>
-            KEYCODE_BUTTON_B (97)
-          </td>
-        </tr>
-        <tr>
-          <td>
-            <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BUTTON_X">X</a> <sup>1</sup>
-          </td>
-          <td>
-            0x09 0x0004
-          </td>
-          <td>
-            KEYCODE_BUTTON_X (99)
-          </td>
-        </tr>
-        <tr>
-          <td>
-            <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BUTTON_Y">Y</a> <sup>1</sup>
-          </td>
-          <td>
-            0x09 0x0005
-          </td>
-          <td>
-            KEYCODE_BUTTON_Y (100)
-          </td>
-        </tr>
-        <tr>
-          <td>
-            <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_DPAD_UP">D-pad up</a> <sup>1</sup><br />
-            <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_DPAD_DOWN">D-pad down</a> <sup>1</sup>
-          </td>
-          <td>
-            0x01 0x0039 <sup>3</sup>
-          </td>
-          <td>
-            <a href="http://developer.android.com/reference/android/view/MotionEvent.html#AXIS_HAT_Y">AXIS_HAT_Y</a> <sup>4</sup>
-          </td>
-        </tr>
-        <tr>
-          <td>
-            <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_DPAD_LEFT">D-pad left</a> 1<br />
-            <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_DPAD_RIGHT">D-pad right</a> <sup>1</sup>
-          </td>
-          <td>
-            0x01 0x0039 <sup>3</sup>
-          </td>
-          <td>
-            <a href="http://developer.android.com/reference/android/view/MotionEvent.html#AXIS_HAT_X">AXIS_HAT_X</a> <sup>4</sup>
-          </td>
-        </tr>
-        <tr>
-          <td>
-            <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BUTTON_L1">Left shoulder button</a> <sup>1</sup>
-          </td>
-          <td>
-            0x09 0x0007
-          </td>
-          <td>
-            KEYCODE_BUTTON_L1 (102)
-          </td>
-        </tr>
-        <tr>
-          <td>
-            <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BUTTON_R1">Right shoulder button</a> <sup>1</sup>
-          </td>
-          <td>
-            0x09 0x0008
-          </td>
-          <td>
-            KEYCODE_BUTTON_R1 (103)
-          </td>
-        </tr>
-        <tr>
-          <td>
-            <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BUTTON_THUMBL">Left stick click</a> <sup>1</sup>
-          </td>
-          <td>
-            0x09 0x000E
-          </td>
-          <td>
-            KEYCODE_BUTTON_THUMBL (106)
-          </td>
-        </tr>
-        <tr>
-          <td>
-            <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BUTTON_THUMBR">Right stick click</a> <sup>1</sup>
-          </td>
-          <td>
-            0x09 0x000F
-          </td>
-          <td>
-            KEYCODE_BUTTON_THUMBR (107)
-          </td>
-        </tr>
-        <tr>
-          <td>
-            <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_HOME">Home</a> <sup>1</sup>
-          </td>
-          <td>
-            0x0c 0x0223
-          </td>
-          <td>
-            KEYCODE_HOME (3)
-          </td>
-        </tr>
-        <tr>
-          <td>
-            <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BACK">Back</a> <sup>1</sup>
-          </td>
-          <td>
-            0x0c 0x0224
-          </td>
-          <td>
-            KEYCODE_BACK (4)
-          </td>
-        </tr>
-      </table>
-      <p class="table_footnote">
-        1 <a href="http://developer.android.com/reference/android/view/KeyEvent.html">KeyEvent</a>
-      </p>
-      <p class="table_footnote">
-        2 The above HID usages must be declared within a Game pad CA (0x01 0x0005).
-      </p>
-      <p class="table_footnote">
-        3 This usage must have a Logical Minimum of 0, a Logical Maximum of 7, a Physical Minimum of 0, a Physical Maximum of 315, Units in Degrees, and a Report Size of 4. The logical value is defined to be the clockwise rotation away from the vertical axis; for example, a logical value of 0 represents no rotation and the up button being pressed, while a logical value of 1 represents a rotation of 45 degrees and both the up and left keys being pressed.
-      </p>
-      <p class="table_footnote">
-        4 <a href="http://developer.android.com/reference/android/view/MotionEvent.html">MotionEvent</a>
-      </p>
-      <table>
-        <tr>
-          <th>
-            Analog Controls <sup>1</sup>
-          </th>
-          <th>
-            HID Usage
-          </th>
-          <th>
-            Android Button
-          </th>
-        </tr>
-        <tr>
-          <td>
-            <a href="http://developer.android.com/reference/android/view/MotionEvent.html#AXIS_LTRIGGER">Left Trigger</a>
-          </td>
-          <td>
-            0x02 0x00C5
-          </td>
-          <td>
-            AXIS_LTRIGGER
-          </td>
-        </tr>
-        <tr>
-          <td>
-            <a href="http://developer.android.com/reference/android/view/MotionEvent.html#AXIS_THROTTLE">Right Trigger</a>
-          </td>
-          <td>
-            0x02 0x00C4
-          </td>
-          <td>
-            AXIS_RTRIGGER
-          </td>
-        </tr>
-        <tr>
-          <td>
-            <a href="http://developer.android.com/reference/android/view/MotionEvent.html#AXIS_Y">Left Joystick</a>
-          </td>
-          <td>
-            0x01 0x0030<br />
-            0x01 0x0031
-          </td>
-          <td>
-            AXIS_X<br />
-            AXIS_Y
-          </td>
-        </tr>
-        <tr>
-          <td>
-            <a href="http://developer.android.com/reference/android/view/MotionEvent.html#AXIS_Z">Right Joystick</a>
-          </td>
-          <td>
-            0x01 0x0032<br />
-            0x01 0x0035
-          </td>
-          <td>
-            AXIS_Z<br />
-            AXIS_RZ
-          </td>
-        </tr>
-      </table>
-      <p class="table_footnote">
-        1 <a href="http://developer.android.com/reference/android/view/MotionEvent.html">MotionEvent</a>
-      </p>
-      <h3 id="7_2_7_remote_control">
-        7.2.7. Remote Control
-      </h3>
-      <p>
-        Android Television device implementations SHOULD provide a remote control to allow users to access the TV interface. The remote control MAY be a physical remote or can be a software-based remote that is accessible from a mobile phone or tablet. The remote control MUST meet the requirements defined below.
-      </p>
-      <ul>
-        <li>
-          <strong>Search affordance</strong> . Device implementations MUST fire KEYCODE_SEARCH (or KEYCODE_ASSIST if the device supports an assistant) when the user invokes voice search on either the physical or software-based remote.
-        </li>
-        <li>
-          <strong>Navigation</strong> . All Android Television remotes MUST include <a href="http://developer.android.com/reference/android/view/KeyEvent.html">Back, Home, and Select buttons and support for D-pad events</a> .
-        </li>
-      </ul>
-      <h2 id="7_3_sensors">
-        7.3. Sensors
-      </h2>
-      <p>
-        Android includes APIs for accessing a variety of sensor types. Devices implementations generally MAY omit these sensors, as provided for in the following subsections. If a device includes a particular sensor type that has a corresponding API for third-party developers, the device implementation MUST implement that API as described in the Android SDK documentation and the Android Open Source documentation on <a href="http://source.android.com/devices/sensors/">sensors</a> . For example, device implementations:
-      </p>
-      <ul>
-        <li>MUST accurately report the presence or absence of sensors per the <a href="http://developer.android.com/reference/android/content/pm/PackageManager.html">android.content.pm.PackageManager</a> class.
-        </li>
-        <li>MUST return an accurate list of supported sensors via the SensorManager.getSensorList() and similar methods.
-        </li>
-        <li>MUST behave reasonably for all other sensor APIs (for example, by returning true or false as appropriate when applications attempt to register listeners, not calling sensor listeners when the corresponding sensors are not present; etc.).
-        </li>
-        <li>MUST <a href="http://developer.android.com/reference/android/hardware/SensorEvent.html">report all sensor measurements</a> using the relevant International System of Units (metric) values for each sensor type as defined in the Android SDK documentation.
-        </li>
-        <li>SHOULD <a href="http://developer.android.com/reference/android/hardware/SensorEvent.html#timestamp">report the event time</a> in nanoseconds as defined in the Android SDK documentation, representing the time the event happened and synchronized with the SystemClock.elapsedRealtimeNano() clock. Existing and new Android devices are <strong>STRONGLY RECOMMENDED</strong> to meet these requirements so they will be able to upgrade to the future platform releases where this might become a REQUIRED component. The synchronization error SHOULD be below 100 milliseconds.
-        </li>
-        <li>MUST report sensor data with a maximum latency of 100 milliseconds + 2 * sample_time for the case of a sensor streamed with a minimum required latency of 5 ms + 2 * sample_time when the application processor is active. This delay does not include any filtering delays.
-        </li>
-        <li>MUST report the first sensor sample within 400 milliseconds + 2 * sample_time of the sensor being activated. It is acceptable for this sample to have an accuracy of 0.
-        </li>
-      </ul>
-      <p>
-        The list above is not comprehensive; the documented behavior of the Android SDK and the Android Open Source Documentations on <a href="http://source.android.com/devices/sensors/">sensors</a> is to be considered authoritative.
-      </p>
-      <p>
-        Some sensor types are composite, meaning they can be derived from data provided by one or more other sensors. (Examples include the orientation sensor and the linear acceleration sensor.) Device implementations SHOULD implement these sensor types, when they include the prerequisite physical sensors as described in <a href="https://source.android.com/devices/sensors/sensor-types.html">sensor types</a> . If a device implementation includes a composite sensor it MUST implement the sensor as described in the Android Open Source documentation on <a href="https://source.android.com/devices/sensors/sensor-types.html#composite_sensor_type_summary">composite sensors</a> .
-      </p>
-      <p>
-        Some Android sensors support a <a href="https://source.android.com/devices/sensors/report-modes.html#continuous">“continuous” trigger mode</a> , which returns data continuously. For any API indicated by the Android SDK documentation to be a continuous sensor, device implementations MUST continuously provide periodic data samples that SHOULD have a jitter below 3%, where jitter is defined as the standard deviation of the difference of the reported timestamp values between consecutive events.
-      </p>
-      <p>
-        Note that the device implementations MUST ensure that the sensor event stream MUST NOT prevent the device CPU from entering a suspend state or waking up from a suspend state.
-      </p>
-      <p>
-        Finally, when several sensors are activated, the power consumption SHOULD NOT exceed the sum of the individual sensor’s reported power consumption.
-      </p>
-      <h3 id="7_3_1_accelerometer">
-        7.3.1. Accelerometer
-      </h3>
-      <p>
-        Device implementations SHOULD include a 3-axis accelerometer. Android Handheld devices, Android Automotive implementations, and Android Watch devices are STRONGLY RECOMMENDED to include this sensor. If a device implementation does include a 3-axis accelerometer, it:
-      </p>
-      <ul>
-        <li>MUST implement and report <a href="http://developer.android.com/reference/android/hardware/Sensor.html#TYPE_ACCELEROMETER">TYPE_ACCELEROMETER sensor</a> .
-        </li>
-        <li>MUST be able to report events up to a frequency of at least 50 Hz for Android Watch devices as such devices have a stricter power constraint and 100 Hz for all other device types.
-        </li>
-        <li>SHOULD report events up to at least 200 Hz.
-        </li>
-        <li>MUST comply with the <a href="http://developer.android.com/reference/android/hardware/SensorEvent.html">Android sensor coordinate system</a> as detailed in the Android APIs. Android Automotive implementations MUST comply with the Android <a href="http://source.android.com/devices/sensors/sensor-types.html#auto_axes">car sensor coordinate system</a> .
-        </li>
-        <li>MUST be capable of measuring from freefall up to four times the gravity (4g) or more on any axis.
-        </li>
-        <li>MUST have a resolution of at least 12-bits and SHOULD have a resolution of at least 16-bits.
-        </li>
-        <li>SHOULD be calibrated while in use if the characteristics changes over the life cycle and compensated, and preserve the compensation parameters between device reboots.
-        </li>
-        <li>SHOULD be temperature compensated.
-        </li>
-        <li>MUST have a standard deviation no greater than 0.05 m/s^, where the standard deviation should be calculated on a per axis basis on samples collected over a period of at least 3 seconds at the fastest sampling rate.
-        </li>
-        <li>SHOULD implement the TYPE_SIGNIFICANT_MOTION, TYPE_TILT_DETECTOR, TYPE_STEP_DETECTOR, TYPE_STEP_COUNTER composite sensors as described in the Android SDK document. Existing and new Android devices are <strong>STRONGLY RECOMMENDED</strong> to implement the TYPE_SIGNIFICANT_MOTION composite sensor. If any of these sensors are implemented, the sum of their power consumption MUST always be less than 4 mW and SHOULD each be below 2 mW and 0.5 mW for when the device is in a dynamic or static condition.
-        </li>
-        <li>If a gyroscope sensor is included, MUST implement the TYPE_GRAVITY and TYPE_LINEAR_ACCELERATION composite sensors and SHOULD implement the TYPE_GAME_ROTATION_VECTOR composite sensor. Existing and new Android devices are STRONGLY RECOMMENDED to implement the TYPE_GAME_ROTATION_VECTOR sensor.
-        </li>
-        <li>MUST implement a TYPE_ROTATION_VECTOR composite sensor, if a gyroscope sensor and a magnetometer sensor is also included.
-        </li>
-      </ul>
-      <h3 id="7_3_2_magnetometer">
-        7.3.2. Magnetometer
-      </h3>
-      <p>
-        Device implementations SHOULD include a 3-axis magnetometer (compass). If a device does include a 3-axis magnetometer, it:
-      </p>
-      <ul>
-        <li>MUST implement the TYPE_MAGNETIC_FIELD sensor and SHOULD also implement TYPE_MAGNETIC_FIELD_UNCALIBRATED sensor. Existing and new Android devices are STRONGLY RECOMMENDED to implement the TYPE_MAGNETIC_FIELD_UNCALIBRATED sensor.
-        </li>
-        <li>MUST be able to report events up to a frequency of at least 10 Hz and SHOULD report events up to at least 50 Hz.
-        </li>
-        <li>MUST comply with the <a href="http://developer.android.com/reference/android/hardware/SensorEvent.html">Android sensor coordinate system</a> as detailed in the Android APIs.
-        </li>
-        <li>MUST be capable of measuring between -900 µT and +900 µT on each axis before saturating.
-        </li>
-        <li>MUST have a hard iron offset value less than 700 µT and SHOULD have a value below 200 µT, by placing the magnetometer far from dynamic (current-induced) and static (magnet-induced) magnetic fields.
-        </li>
-        <li>MUST have a resolution equal or denser than 0.6 µT and SHOULD have a resolution equal or denser than 0.2 µT.
-        </li>
-        <li>SHOULD be temperature compensated.
-        </li>
-        <li>MUST support online calibration and compensation of the hard iron bias, and preserve the compensation parameters between device reboots.
-        </li>
-        <li>MUST have the soft iron compensation applied—the calibration can be done either while in use or during the production of the device.
-        </li>
-        <li>SHOULD have a standard deviation, calculated on a per axis basis on samples collected over a period of at least 3 seconds at the fastest sampling rate, no greater than 0.5 µT.
-        </li>
-        <li>MUST implement a TYPE_ROTATION_VECTOR composite sensor, if an accelerometer sensor and a gyroscope sensor is also included.
-        </li>
-        <li>MAY implement the TYPE_GEOMAGNETIC_ROTATION_VECTOR sensor if an accelerometer sensor is also implemented. However if implemented, it MUST consume less than 10 mW and SHOULD consume less than 3 mW when the sensor is registered for batch mode at 10 Hz.
-        </li>
-      </ul>
-      <h3 id="7_3_3_gps">
-        7.3.3. GPS
-      </h3>
-      <p>
-        Device implementations SHOULD include a GPS/GNSS receiver. If a device implementation does include a GPS/GNSS receiver and reports the capability to applications through the <code>android.hardware.location.gps</code> feature flag:
-      </p>
-      <ul>
-        <li>It is STRONGLY RECOMMENDED that the device continue to deliver normal GPS/GNSS outputs to applications during an emergency phone call and that location output not be blocked during an emergency phone call.
-        </li>
-        <li>It MUST support location outputs at a rate of at least 1 Hz when requested via <code>LocationManager#requestLocationUpdate</code> .
-        </li>
-        <li>It MUST be able to determine the location in open-sky conditions (strong signals, negligible multipath, HDOP &lt; 2) within 10 seconds (fast time to first fix), when connected to a 0.5 Mbps or faster data speed internet connection. This requirement is typically met by the use of some form of Assisted or Predicted GPS/GNSS technique to minimize GPS/GNSS lock-on time (Assistance data includes Reference Time, Reference Location and Satellite Ephemeris/Clock).
-          <ul>
-            <li>After making such a location calculation, it is STRONGLY RECOMMENDED for the device to be able to determine its location, in open sky, within 10 seconds, when location requests are restarted, up to an hour after the initial location calculation, even when the subsequent request is made without a data connection, and/or after a power cycle.
-            </li>
-          </ul>
-        </li>
-        <li>In open sky conditions after determining the location, while stationary or moving with less than 1 meter per second squared of acceleration:
-          <ul>
-            <li>It MUST be able to determine location within 20 meters, and speed within 0.5 meters per second, at least 95% of the time.
-            </li>
-            <li>It MUST simultaneously track and report via <a href="https://developer.android.com/reference/android/location/GnssStatus.Callback.html#GnssStatus.Callback()'">GnssStatus.Callback</a> at least 8 satellites from one constellation.
-            </li>
-            <li>It SHOULD be able to simultaneously track at least 24 satellites, from multiple constellations (e.g. GPS + at least one of Glonass, Beidou, Galileo).
-            </li>
-          </ul>
-        </li>
-        <li>It MUST report the GNSS technology generation through the test API ‘getGnssYearOfHardware’.
-        </li>
-        <li>It is STRONGLY RECOMMENDED to meet and MUST meet all requirements below if the GNSS technology generation is reported as the year "2016" or newer.
-          <ul>
-            <li>It MUST report GPS measurements, as soon as they are found, even if a location calculated from GPS/GNSS is not yet reported.
-            </li>
-            <li>It MUST report GPS pseudoranges and pseudorange rates, that, in open-sky conditions after determining the location, while stationary or moving with less than 0.2 meter per second squared of acceleration, are sufficient to calculate position within 20 meters, and speed within 0.2 meters per second, at least 95% of the time.
-            </li>
-          </ul>
-        </li>
-      </ul>
-      <p>
-        Note that while some of the GPS requirements above are stated as STRONGLY RECOMMENDED, the Compatibility Definition for the next major version is expected to change these to a MUST.
-      </p>
-      <h3 id="7_3_4_gyroscope">
-        7.3.4. Gyroscope
-      </h3>
-      <p>
-        Device implementations SHOULD include a gyroscope (angular change sensor). Devices SHOULD NOT include a gyroscope sensor unless a 3-axis accelerometer is also included. If a device implementation includes a gyroscope, it:
-      </p>
-      <ul>
-        <li>MUST implement the TYPE_GYROSCOPE sensor and SHOULD also implement TYPE_GYROSCOPE_UNCALIBRATED sensor. Existing and new Android devices are STRONGLY RECOMMENDED to implement the SENSOR_TYPE_GYROSCOPE_UNCALIBRATED sensor.
-        </li>
-        <li>MUST be capable of measuring orientation changes up to 1,000 degrees per second.
-        </li>
-        <li>MUST be able to report events up to a frequency of at least 50 Hz for Android Watch devices as such devices have a stricter power constraint and 100 Hz for all other device types.
-        </li>
-        <li>SHOULD report events up to at least 200 Hz.
-        </li>
-        <li>MUST have a resolution of 12-bits or more and SHOULD have a resolution of 16-bits or more.
-        </li>
-        <li>MUST be temperature compensated.
-        </li>
-        <li>MUST be calibrated and compensated while in use, and preserve the compensation parameters between device reboots.
-        </li>
-        <li>MUST have a variance no greater than 1e-7 rad^2 / s^2 per Hz (variance per Hz, or rad^2 / s). The variance is allowed to vary with the sampling rate, but must be constrained by this value. In other words, if you measure the variance of the gyro at 1 Hz sampling rate it should be no greater than 1e-7 rad^2/s^2.
-        </li>
-        <li>MUST implement a TYPE_ROTATION_VECTOR composite sensor, if an accelerometer sensor and a magnetometer sensor is also included.
-        </li>
-        <li>If an accelerometer sensor is included, MUST implement the TYPE_GRAVITY and TYPE_LINEAR_ACCELERATION composite sensors and SHOULD implement the TYPE_GAME_ROTATION_VECTOR composite sensor. Existing and new Android devices are STRONGLY RECOMMENDED to implement the TYPE_GAME_ROTATION_VECTOR sensor.
-        </li>
-      </ul>
-      <h3 id="7_3_5_barometer">
-        7.3.5. Barometer
-      </h3>
-      <p>
-        Device implementations SHOULD include a barometer (ambient air pressure sensor). If a device implementation includes a barometer, it:
-      </p>
-      <ul>
-        <li>MUST implement and report TYPE_PRESSURE sensor.
-        </li>
-        <li>MUST be able to deliver events at 5 Hz or greater.
-        </li>
-        <li>MUST have adequate precision to enable estimating altitude.
-        </li>
-        <li>MUST be temperature compensated.
-        </li>
-      </ul>
-      <h3 id="7_3_6_thermometer">
-        7.3.6. Thermometer
-      </h3>
-      <p>
-        Device implementations MAY include an ambient thermometer (temperature sensor). If present, it MUST be defined as SENSOR_TYPE_AMBIENT_TEMPERATURE and it MUST measure the ambient (room) temperature in degrees Celsius.
-      </p>
-      <p>
-        Device implementations MAY but SHOULD NOT include a CPU temperature sensor. If present, it MUST be defined as SENSOR_TYPE_TEMPERATURE, it MUST measure the temperature of the device CPU, and it MUST NOT measure any other temperature. Note the SENSOR_TYPE_TEMPERATURE sensor type was deprecated in Android 4.0.
-      </p>
-      <div class="note">
-        For Android Automotive implementations, SENSOR_TYPE_AMBIENT_TEMPERATURE MUST measure the temperature inside the vehicle cabin.
-      </div>
-      <h3 id="7_3_7_photometer">
-        7.3.7. Photometer
-      </h3>
-      <p>
-        Device implementations MAY include a photometer (ambient light sensor).
-      </p>
-      <h3 id="7_3_8_proximity_sensor">
-        7.3.8. Proximity Sensor
-      </h3>
-      <p>
-        Device implementations MAY include a proximity sensor. Devices that can make a voice call and indicate any value other than PHONE_TYPE_NONE in getPhoneType SHOULD include a proximity sensor. If a device implementation does include a proximity sensor, it:
-      </p>
-      <ul>
-        <li>MUST measure the proximity of an object in the same direction as the screen. That is, the proximity sensor MUST be oriented to detect objects close to the screen, as the primary intent of this sensor type is to detect a phone in use by the user. If a device implementation includes a proximity sensor with any other orientation, it MUST NOT be accessible through this API.
-        </li>
-        <li>MUST have 1-bit of accuracy or more.
-        </li>
-      </ul>
-      <h3 id="7_3_9_high_fidelity_sensors">
-        7.3.9. High Fidelity Sensors
-      </h3>
-      <p>
-        Device implementations supporting a set of higher quality sensors that can meet all the requirements listed in this section MUST identify the support through the <code>android.hardware.sensor.hifi_sensors</code> feature flag.
-      </p>
-      <p>
-        A device declaring android.hardware.sensor.hifi_sensors MUST support all of the following sensor types meeting the quality requirements as below:
-      </p>
-      <ul>
-        <li>SENSOR_TYPE_ACCELEROMETER
-          <ul>
-            <li>MUST have a measurement range between at least -8g and +8g.
-            </li>
-            <li>MUST have a measurement resolution of at least 1024 LSB/G.
-            </li>
-            <li>MUST have a minimum measurement frequency of 12.5 Hz or lower.
-            </li>
-            <li>MUST have a maximum measurement frequency of 400 Hz or higher.
-            </li>
-            <li>MUST have a measurement noise not above 400 uG/√Hz.
-            </li>
-            <li>MUST implement a non-wake-up form of this sensor with a buffering capability of at least 3000 sensor events.
-            </li>
-            <li>MUST have a batching power consumption not worse than 3 mW.
-            </li>
-            <li>SHOULD have a stationary noise bias stability of \&lt;15 μg √Hz from 24hr static dataset.
-            </li>
-            <li>SHOULD have a bias change vs. temperature of ≤ +/- 1mg / °C.
-            </li>
-            <li>SHOULD have a best-fit line non-linearity of ≤ 0.5%, and sensitivity change vs. temperature of ≤ 0.03%/C°.
-            </li>
-          </ul>
-        </li>
-        <li>
-          <p>
-            SENSOR_TYPE_GYROSCOPE
-          </p>
-          <ul>
-            <li>MUST have a measurement range between at least -1000 and +1000 dps.
-            </li>
-            <li>MUST have a measurement resolution of at least 16 LSB/dps.
-            </li>
-            <li>MUST have a minimum measurement frequency of 12.5 Hz or lower.
-            </li>
-            <li>MUST have a maximum measurement frequency of 400 Hz or higher.
-            </li>
-            <li>MUST have a measurement noise not above 0.014°/s/√Hz.
-            </li>
-            <li>SHOULD have a stationary bias stability of &lt; 0.0002 °/s √Hz from 24-hour static dataset.
-            </li>
-            <li>SHOULD have a bias change vs. temperature of ≤ +/- 0.05 °/ s / °C.
-            </li>
-            <li>SHOULD have a sensitivity change vs. temperature of ≤ 0.02% / °C.
-            </li>
-            <li>SHOULD have a best-fit line non-linearity of ≤ 0.2%.
-            </li>
-            <li>SHOULD have a noise density of ≤ 0.007 °/s/√Hz.
-            </li>
-          </ul>
-        </li>
-        <li>
-          <p>
-            SENSOR_TYPE_GYROSCOPE_UNCALIBRATED with the same quality requirements as SENSOR_TYPE_GYROSCOPE.
-          </p>
-        </li>
-        <li>SENSOR_TYPE_GEOMAGNETIC_FIELD
-          <ul>
-            <li>MUST have a measurement range between at least -900 and +900 uT.
-            </li>
-            <li>MUST have a measurement resolution of at least 5 LSB/uT.
-            </li>
-            <li>MUST have a minimum measurement frequency of 5 Hz or lower.
-            </li>
-            <li>MUST have a maximum measurement frequency of 50 Hz or higher.
-            </li>
-            <li>MUST have a measurement noise not above 0.5 uT.
-            </li>
-          </ul>
-        </li>
-        <li>SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED with the same quality requirements as SENSOR_TYPE_GEOMAGNETIC_FIELD and in addition:
-          <ul>
-            <li>MUST implement a non-wake-up form of this sensor with a buffering capability of at least 600 sensor events.
-            </li>
-          </ul>
-        </li>
-        <li>SENSOR_TYPE_PRESSURE
-          <ul>
-            <li>MUST have a measurement range between at least 300 and 1100 hPa.
-            </li>
-            <li>MUST have a measurement resolution of at least 80 LSB/hPa.
-            </li>
-            <li>MUST have a minimum measurement frequency of 1 Hz or lower.
-            </li>
-            <li>MUST have a maximum measurement frequency of 10 Hz or higher.
-            </li>
-            <li>MUST have a measurement noise not above 2 Pa/√Hz.
-            </li>
-            <li>MUST implement a non-wake-up form of this sensor with a buffering capability of at least 300 sensor events.
-            </li>
-            <li>MUST have a batching power consumption not worse than 2 mW.
-            </li>
-          </ul>
-        </li>
-        <li>SENSOR_TYPE_GAME_ROTATION_VECTOR
-          <ul>
-            <li>MUST implement a non-wake-up form of this sensor with a buffering capability of at least 300 sensor events.
-            </li>
-            <li>MUST have a batching power consumption not worse than 4 mW.
-            </li>
-          </ul>
-        </li>
-        <li>SENSOR_TYPE_SIGNIFICANT_MOTION
-          <ul>
-            <li>MUST have a power consumption not worse than 0.5 mW when device is static and 1.5 mW when device is moving.
-            </li>
-          </ul>
-        </li>
-        <li>SENSOR_TYPE_STEP_DETECTOR
-          <ul>
-            <li>MUST implement a non-wake-up form of this sensor with a buffering capability of at least 100 sensor events.
-            </li>
-            <li>MUST have a power consumption not worse than 0.5 mW when device is static and 1.5 mW when device is moving.
-            </li>
-            <li>MUST have a batching power consumption not worse than 4 mW.
-            </li>
-          </ul>
-        </li>
-        <li>SENSOR_TYPE_STEP_COUNTER
-          <ul>
-            <li>MUST have a power consumption not worse than 0.5 mW when device is static and 1.5 mW when device is moving.
-            </li>
-          </ul>
-        </li>
-        <li>SENSOR_TILT_DETECTOR
-          <ul>
-            <li>MUST have a power consumption not worse than 0.5 mW when device is static and 1.5 mW when device is moving.
-            </li>
-          </ul>
-        </li>
-      </ul>
-      <p>
-        Also such a device MUST meet the following sensor subsystem requirements:
-      </p>
-      <ul>
-        <li>The event timestamp of the same physical event reported by the Accelerometer, Gyroscope sensor and Magnetometer MUST be within 2.5 milliseconds of each other.
-        </li>
-        <li>The Gyroscope sensor event timestamps MUST be on the same time base as the camera subsystem and within 1 milliseconds of error.
-        </li>
-        <li>High Fidelity sensors MUST deliver samples to applications within 5 milliseconds from the time when the data is available on the physical sensor to the application.
-        </li>
-        <li>The power consumption MUST not be higher than 0.5 mW when device is static and 2.0 mW when device is moving when any combination of the following sensors are enabled:
-          <ul>
-            <li>SENSOR_TYPE_SIGNIFICANT_MOTION
-            </li>
-            <li>SENSOR_TYPE_STEP_DETECTOR
-            </li>
-            <li>SENSOR_TYPE_STEP_COUNTER
-            </li>
-            <li>SENSOR_TILT_DETECTORS
-            </li>
-          </ul>
-        </li>
-      </ul>
-      <p>
-        Note that all power consumption requirements in this section do not include the power consumption of the Application Processor. It is inclusive of the power drawn by the entire sensor chain—the sensor, any supporting circuitry, any dedicated sensor processing system, etc.
-      </p>
-      <p>
-        The following sensor types MAY also be supported on a device implementation declaring android.hardware.sensor.hifi_sensors, but if these sensor types are present they MUST meet the following minimum buffering capability requirement:
-      </p>
-      <ul>
-        <li>SENSOR_TYPE_PROXIMITY: 100 sensor events
-        </li>
-      </ul>
-      <h3 id="7_3_10_fingerprint_sensor">
-        7.3.10. Fingerprint Sensor
-      </h3>
-      <p>
-        Device implementations with a secure lock screen SHOULD include a fingerprint sensor. If a device implementation includes a fingerprint sensor and has a corresponding API for third-party developers, it:
-      </p>
-      <ul>
-        <li>MUST declare support for the android.hardware.fingerprint feature.
-        </li>
-        <li>MUST fully implement the <a href="https://developer.android.com/reference/android/hardware/fingerprint/package-summary.html">corresponding API</a> as described in the Android SDK documentation.
-        </li>
-        <li>MUST have a false acceptance rate not higher than 0.002%.
-        </li>
-        <li>Is STRONGLY RECOMMENDED to have a false rejection rate of less than 10%, as measured on the device
-        </li>
-        <li>Is STRONGLY RECOMMENDED to have a latency below 1 second, measured from when the fingerprint sensor is touched until the screen is unlocked, for one enrolled finger.
-        </li>
-        <li>MUST rate limit attempts for at least 30 seconds after five false trials for fingerprint verification.
-        </li>
-        <li>MUST have a hardware-backed keystore implementation, and perform the fingerprint matching in a Trusted Execution Environment (TEE) or on a chip with a secure channel to the TEE.
-        </li>
-        <li>MUST have all identifiable fingerprint data encrypted and cryptographically authenticated such that they cannot be acquired, read or altered outside of the Trusted Execution Environment (TEE) as documented in the <a href="https://source.android.com/devices/tech/security/authentication/fingerprint-hal.html">implementation guidelines</a> on the Android Open Source Project site.
-        </li>
-        <li>MUST prevent adding a fingerprint without first establishing a chain of trust by having the user confirm existing or add a new device credential (PIN/pattern/password) that's secured by TEE; the Android Open Source Project implementation provides the mechanism in the framework to do so.
-        </li>
-        <li>MUST NOT enable 3rd-party applications to distinguish between individual fingerprints.
-        </li>
-        <li>MUST honor the DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT flag.
-        </li>
-        <li>MUST, when upgraded from a version earlier than Android 6.0, have the fingerprint data securely migrated to meet the above requirements or removed.
-        </li>
-        <li>SHOULD use the Android Fingerprint icon provided in the Android Open Source Project.
-        </li>
-      </ul>
-      <h3 id="7_3_11_android_automotive-only_sensors">
-        7.3.11. Android Automotive-only sensors
-      </h3>
-      <p>
-        Automotive-specific sensors are defined in the <code>android.car.CarSensorManager API</code> .
-      </p>
-      <h4 id="7_3_11_1_current_gear">
-        7.3.11.1. Current Gear
-      </h4>
-      <p>
-        Android Automotive implementations SHOULD provide current gear as SENSOR_TYPE_GEAR.
-      </p>
-      <h4 id="7_3_11_2_day_night_mode">
-        7.3.11.2. Day Night Mode
-      </h4>
-      <p>
-        Android Automotive implementations MUST support day/night mode defined as SENSOR_TYPE_NIGHT. The value of this flag MUST be consistent with dashboard day/night mode and SHOULD be based on ambient light sensor input. The underlying ambient light sensor MAY be the same as <a href="#7_3_7_photometer">Photometer</a> .
-      </p>
-      <h4 id="7_3_11_3_driving_status">
-        7.3.11.3. Driving Status
-      </h4>
-      <p>
-        Android Automotive implementations MUST support driving status defined as SENSOR_TYPE_DRIVING_STATUS, with a default value of DRIVE_STATUS_UNRESTRICTED when the vehicle is fully stopped and parked. It is the responsibility of device manufacturers to configure SENSOR_TYPE_DRIVING_STATUS in compliance with all laws and regulations that apply to markets where the product is shipping.
-      </p>
-      <h4 id="7_3_11_4_wheel_speed">
-        7.3.11.4. Wheel Speed
-      </h4>
-      <p>
-        Android Automotive implementations MUST provide vehicle speed defined as SENSOR_TYPE_CAR_SPEED.
-      </p>
-      <h2 id="7_3_12_pose_sensor">
-        7.3.12. Pose Sensor
-      </h2>
-      <p>
-        Device implementations MAY support pose sensor with 6 degrees of freedom. Android Handheld devices are RECOMMENDED to support this sensor. If a device implementation does support pose sensor with 6 degrees of freedom, it:
-      </p>
-      <ul>
-        <li>MUST implement and report <a href="https://developer.android.com/reference/android/hardware/Sensor.html#TYPE_POSE_6DOF"><code>TYPE_POSE_6DOF</code></a> sensor.
-        </li>
-        <li>MUST be more accurate than the rotation vector alone.
-        </li>
-      </ul>
-      <h2 id="7_4_data_connectivity">
-        7.4. Data Connectivity
-      </h2>
-      <h3 id="7_4_1_telephony">
-        7.4.1. Telephony
-      </h3>
-      <p>
-        “Telephony” as used by the Android APIs and this document refers specifically to hardware related to placing voice calls and sending SMS messages via a GSM or CDMA network. While these voice calls may or may not be packet-switched, they are for the purposes of Android considered independent of any data connectivity that may be implemented using the same network. In other words, the Android “telephony” functionality and APIs refer specifically to voice calls and SMS. For instance, device implementations that cannot place calls or send/receive SMS messages MUST NOT report the android.hardware.telephony feature or any subfeatures, regardless of whether they use a cellular network for data connectivity.
-      </p>
-      <p>
-        Android MAY be used on devices that do not include telephony hardware. That is, Android is compatible with devices that are not phones. However, if a device implementation does include GSM or CDMA telephony, it MUST implement full support for the API for that technology. Device implementations that do not include telephony hardware MUST implement the full APIs as no-ops.
-      </p>
-      <h4 id="7_4_1_1_number_blocking_compatibility">
-        7.4.1.1. Number Blocking Compatibility
-      </h4>
-      <p>
-        Android Telephony device implementations MUST include number blocking support and:
-      </p>
-      <ul>
-        <li>MUST fully implement <a href="http://developer.android.com/reference/android/provider/BlockedNumberContract.html">BlockedNumberContract</a> and the corresponding API as described in the SDK documentation.
-        </li>
-        <li>MUST block all calls and messages from a phone number in 'BlockedNumberProvider' without any interaction with apps. The only exception is when number blocking is temporarily lifted as described in the SDK documentation.
-        </li>
-        <li>MUST NOT write to the <a href="http://developer.android.com/reference/android/provider/CallLog.html">platform call log provider</a> for a blocked call.
-        </li>
-        <li>MUST NOT write to the <a href="http://developer.android.com/reference/android/provider/Telephony.html">Telephony provider</a> for a blocked message.
-        </li>
-        <li>MUST implement a blocked numbers management UI, which is opened with the intent returned by TelecomManager.createManageBlockedNumbersIntent() method.
-        </li>
-        <li>MUST NOT allow secondary users to view or edit the blocked numbers on the device as the Android platform assumes the primary user to have full control of the telephony services, a single instance, on the device. All blocking related UI MUST be hidden for secondary users and the blocked list MUST still be respected.
-        </li>
-        <li>SHOULD migrate the blocked numbers into the provider when a device updates to Android 7.0.
-        </li>
-      </ul>
-      <h3 id="7_4_2_ieee_802_11_(wi-fi)">
-        7.4.2. IEEE 802.11 (Wi-Fi)
-      </h3>
-      <p>
-        All Android device implementations SHOULD include support for one or more forms of 802.11. If a device implementation does include support for 802.11 and exposes the functionality to a third-party application, it MUST implement the corresponding Android API and:
-      </p>
-      <ul>
-        <li>MUST report the hardware feature flag android.hardware.wifi.
-        </li>
-        <li>MUST implement the <a href="http://developer.android.com/reference/android/net/wifi/WifiManager.MulticastLock.html">multicast API</a> as described in the SDK documentation.
-        </li>
-        <li>MUST support multicast DNS (mDNS) and MUST NOT filter mDNS packets (224.0.0.251) at any time of operation including:
-          <ul>
-            <li>Even when the screen is not in an active state.
-            </li>
-            <li>For Android Television device implementations, even when in standby power states.
-            </li>
-          </ul>
-        </li>
-      </ul>
-      <h4 id="7_4_2_1_wi-fi_direct">
-        7.4.2.1. Wi-Fi Direct
-      </h4>
-      <p>
-        Device implementations SHOULD include support for Wi-Fi Direct (Wi-Fi peer-to-peer). If a device implementation does include support for Wi-Fi Direct, it MUST implement the <a href="http://developer.android.com/reference/android/net/wifi/p2p/WifiP2pManager.html">corresponding Android API</a> as described in the SDK documentation. If a device implementation includes support for Wi-Fi Direct, then it:
-      </p>
-      <ul>
-        <li>MUST report the hardware feature android.hardware.wifi.direct.
-        </li>
-        <li>MUST support regular Wi-Fi operation.
-        </li>
-        <li>SHOULD support concurrent Wi-Fi and Wi-Fi Direct operation.
-        </li>
-      </ul>
-      <h4 id="7_4_2_2_wi-fi_tunneled_direct_link_setup">
-        7.4.2.2. Wi-Fi Tunneled Direct Link Setup
-      </h4>
-      <p>
-        Device implementations SHOULD include support for <a href="http://developer.android.com/reference/android/net/wifi/WifiManager.html">Wi-Fi Tunneled Direct Link Setup (TDLS)</a> as described in the Android SDK Documentation. If a device implementation does include support for TDLS and TDLS is enabled by the WiFiManager API, the device:
-      </p>
-      <ul>
-        <li>SHOULD use TDLS only when it is possible AND beneficial.
-        </li>
-        <li>SHOULD have some heuristic and NOT use TDLS when its performance might be worse than going through the Wi-Fi access point.
-        </li>
-      </ul>
-      <h3 id="7_4_3_bluetooth">
-        7.4.3. Bluetooth
-      </h3>
-      <div class="note">
-        Android Watch implementations MUST support Bluetooth. Android Television implementations MUST support Bluetooth and Bluetooth LE. Android Automotive implementations MUST support Bluetooth and SHOULD support Bluetooth LE.
-      </div>
-      <p>
-        Device implementations that support <code>android.hardware.vr.high_performance</code> feature MUST support Bluetooth 4.2 and Bluetooth LE Data Length Extension.
-      </p>
-      <p>
-        Android includes support for <a href="http://developer.android.com/reference/android/bluetooth/package-summary.html">Bluetooth and Bluetooth Low Energy</a> . Device implementations that include support for Bluetooth and Bluetooth Low Energy MUST declare the relevant platform features (android.hardware.bluetooth and android.hardware.bluetooth_le respectively) and implement the platform APIs. Device implementations SHOULD implement relevant Bluetooth profiles such as A2DP, AVCP, OBEX, etc. as appropriate for the device.
-      </p>
-      <p>
-        Android Automotive implementations SHOULD support Message Access Profile (MAP). Android Automotive implementations MUST support the following Bluetooth profiles:
-      </p>
-      <ul>
-        <li>Phone calling over Hands-Free Profile (HFP).
-        </li>
-        <li>Media playback over Audio Distribution Profile (A2DP).
-        </li>
-        <li>Media playback control over Remote Control Profile (AVRCP).
-        </li>
-        <li>Contact sharing using the Phone Book Access Profile (PBAP).
-        </li>
-      </ul>
-      <p>
-        Device implementations including support for Bluetooth Low Energy:
-      </p>
-      <ul>
-        <li>MUST declare the hardware feature android.hardware.bluetooth_le.
-        </li>
-        <li>MUST enable the GATT (generic attribute profile) based Bluetooth APIs as described in the SDK documentation and <a href="http://developer.android.com/reference/android/bluetooth/package-summary.html">android.bluetooth</a> .
-        </li>
-        <li>are STRONGLY RECOMMENDED to implement a Resolvable Private Address (RPA) timeout no longer than 15 minutes and rotate the address at timeout to protect user privacy.
-        </li>
-        <li>SHOULD support offloading of the filtering logic to the bluetooth chipset when implementing the <a href="https://developer.android.com/reference/android/bluetooth/le/ScanFilter.html">ScanFilter API</a> , and MUST report the correct value of where the filtering logic is implemented whenever queried via the android.bluetooth.BluetoothAdapter.isOffloadedFilteringSupported() method.
-        </li>
-        <li>SHOULD support offloading of the batched scanning to the bluetooth chipset, but if not supported, MUST report ‘false’ whenever queried via the android.bluetooth.BluetoothAdapter.isOffloadedScanBatchingSupported() method.
-        </li>
-        <li>SHOULD support multi advertisement with at least 4 slots, but if not supported, MUST report ‘false’ whenever queried via the android.bluetooth.BluetoothAdapter.isMultipleAdvertisementSupported() method.
-        </li>
-      </ul>
-      <h3 id="7_4_4_near-field_communications">
-        7.4.4. Near-Field Communications
-      </h3>
-      <p>
-        Device implementations SHOULD include a transceiver and related hardware for Near-Field Communications (NFC). If a device implementation does include NFC hardware and plans to make it available to third-party apps, then it:
-      </p>
-      <ul>
-        <li>MUST report the android.hardware.nfc feature from the <a href="http://developer.android.com/reference/android/content/pm/PackageManager.html">android.content.pm.PackageManager.hasSystemFeature() method</a> .
-        </li>
-        <li>MUST be capable of reading and writing NDEF messages via the following NFC standards:
-          <ul>
-            <li>MUST be capable of acting as an NFC Forum reader/writer (as defined by the NFC Forum technical specification NFCForum-TS-DigitalProtocol-1.0) via the following NFC standards:
-              <ul>
-                <li>NfcA (ISO14443-3A)
-                </li>
-                <li>NfcB (ISO14443-3B)
-                </li>
-                <li>NfcF (JIS X 6319-4)
-                </li>
-                <li>IsoDep (ISO 14443-4)
-                </li>
-                <li>NFC Forum Tag Types 1, 2, 3, 4 (defined by the NFC Forum)
-                </li>
-              </ul>
-            </li>
-            <li>STRONGLY RECOMMENDED to be capable of reading and writing NDEF messages as well as raw data via the following NFC standards. Note that while the NFC standards below are stated as STRONGLY RECOMMENDED, the Compatibility Definition for a future version is planned to change these to MUST. These standards are optional in this version but will be required in future versions. Existing and new devices that run this version of Android are very strongly encouraged to meet these requirements now so they will be able to upgrade to the future platform releases.
-              <ul>
-                <li>NfcV (ISO 15693)
-                </li>
-              </ul>
-            </li>
-            <li>SHOULD be capable of reading the barcode and URL (if encoded) of <a href="http://developer.android.com/reference/android/nfc/tech/NfcBarcode.html">Thinfilm NFC Barcode</a> products.
-            </li>
-            <li>MUST be capable of transmitting and receiving data via the following peer-to-peer standards and protocols:
-              <ul>
-                <li>ISO 18092
-                </li>
-                <li>LLCP 1.2 (defined by the NFC Forum)
-                </li>
-                <li>SDP 1.0 (defined by the NFC Forum)
-                </li>
-                <li>
-                  <a href="http://static.googleusercontent.com/media/source.android.com/en/us/compatibility/ndef-push-protocol.pdf">NDEF Push Protocol</a>
-                </li>
-                <li>SNEP 1.0 (defined by the NFC Forum)
-                </li>
-              </ul>
-            </li>
-            <li>MUST include support for <a href="http://developer.android.com/guide/topics/connectivity/nfc/nfc.html">Android Beam</a> .
-            </li>
-            <li>MUST implement the SNEP default server. Valid NDEF messages received by the default SNEP server MUST be dispatched to applications using the android.nfc.ACTION_NDEF_DISCOVERED intent. Disabling Android Beam in settings MUST NOT disable dispatch of incoming NDEF message.
-            </li>
-            <li>MUST honor the android.settings.NFCSHARING_SETTINGS intent to show <a href="http://developer.android.com/reference/android/provider/Settings.html#ACTION_NFCSHARING_SETTINGS">NFC sharing settings</a> .
-            </li>
-            <li>MUST implement the NPP server. Messages received by the NPP server MUST be processed the same way as the SNEP default server.
-            </li>
-            <li>MUST implement a SNEP client and attempt to send outbound P2P NDEF to the default SNEP server when Android Beam is enabled. If no default SNEP server is found then the client MUST attempt to send to an NPP server.
-            </li>
-            <li>MUST allow foreground activities to set the outbound P2P NDEF message using android.nfc.NfcAdapter.setNdefPushMessage, and android.nfc.NfcAdapter.setNdefPushMessageCallback, and android.nfc.NfcAdapter.enableForegroundNdefPush.
-            </li>
-            <li>SHOULD use a gesture or on-screen confirmation, such as 'Touch to Beam', before sending outbound P2P NDEF messages.
-            </li>
-            <li>SHOULD enable Android Beam by default and MUST be able to send and receive using Android Beam, even when another proprietary NFC P2p mode is turned on.
-            </li>
-            <li>MUST support NFC Connection handover to Bluetooth when the device supports Bluetooth Object Push Profile. Device implementations MUST support connection handover to Bluetooth when using android.nfc.NfcAdapter.setBeamPushUris, by implementing the “ <a href="http://members.nfc-forum.org/specs/spec_list/#conn_handover">Connection Handover version 1.2</a> ” and “ <a href="http://members.nfc-forum.org/apps/group_public/download.php/18688/NFCForum-AD-BTSSP_1_1.pdf">Bluetooth Secure Simple Pairing Using NFC version 1.0</a> ” specs from the NFC Forum. Such an implementation MUST implement the handover LLCP service with service name “urn:nfc:sn:handover” for exchanging the handover request/select records over NFC, and it MUST use the Bluetooth Object Push Profile for the actual Bluetooth data transfer. For legacy reasons (to remain compatible with Android 4.1 devices), the implementation SHOULD still accept SNEP GET requests for exchanging the handover request/select records over NFC. However an implementation itself SHOULD NOT send SNEP GET requests for performing connection handover.
-            </li>
-            <li>MUST poll for all supported technologies while in NFC discovery mode.
-            </li>
-            <li>SHOULD be in NFC discovery mode while the device is awake with the screen active and the lock-screen unlocked.
-            </li>
-          </ul>
-        </li>
-      </ul>
-      <p>
-        (Note that publicly available links are not available for the JIS, ISO, and NFC Forum specifications cited above.)
-      </p>
-      <p>
-        Android includes support for NFC Host Card Emulation (HCE) mode. If a device implementation does include an NFC controller chipset capable of HCE (for NfcA and/or NfcB) and it supports Application ID (AID) routing, then it:
-      </p>
-      <ul>
-        <li>MUST report the android.hardware.nfc.hce feature constant.
-        </li>
-        <li>MUST support <a href="http://developer.android.com/guide/topics/connectivity/nfc/hce.html">NFC HCE APIs</a> as defined in the Android SDK.
-        </li>
-      </ul>
-      <p>
-        If a device implementation does include an NFC controller chipset capable of HCE for NfcF, and it implements the feature for third-party applications, then it:
-      </p>
-      <ul>
-        <li>MUST report the android.hardware.nfc.hcef feature constant.
-        </li>
-        <li>MUST implement the [NfcF Card Emulation APIs] (https://developer.android.com/reference/android/nfc/cardemulation/NfcFCardEmulation.html) as defined in the Android SDK.
-        </li>
-      </ul>
-      <p>
-        Additionally, device implementations MAY include reader/writer support for the following MIFARE technologies.
-      </p>
-      <ul>
-        <li>MIFARE Classic
-        </li>
-        <li>MIFARE Ultralight
-        </li>
-        <li>NDEF on MIFARE Classic
-        </li>
-      </ul>
-      <p>
-        Note that Android includes APIs for these MIFARE types. If a device implementation supports MIFARE in the reader/writer role, it:
-      </p>
-      <ul>
-        <li>MUST implement the corresponding Android APIs as documented by the Android SDK.
-        </li>
-        <li>MUST report the feature com.nxp.mifare from the <a href="http://developer.android.com/reference/android/content/pm/PackageManager.html">android.content.pm.PackageManager.hasSystemFeature()</a> method. Note that this is not a standard Android feature and as such does not appear as a constant in the android.content.pm.PackageManager class.
-        </li>
-        <li>MUST NOT implement the corresponding Android APIs nor report the com.nxp.mifare feature unless it also implements general NFC support as described in this section.
-        </li>
-      </ul>
-      <p>
-        If a device implementation does not include NFC hardware, it MUST NOT declare the android.hardware.nfc feature from the <a href="http://developer.android.com/reference/android/content/pm/PackageManager.html">android.content.pm.PackageManager.hasSystemFeature()</a> method, and MUST implement the Android NFC API as a no-op.
-      </p>
-      <p>
-        As the classes android.nfc.NdefMessage and android.nfc.NdefRecord represent a protocol-independent data representation format, device implementations MUST implement these APIs even if they do not include support for NFC or declare the android.hardware.nfc feature.
-      </p>
-      <h3 id="7_4_5_minimum_network_capability">
-        7.4.5. Minimum Network Capability
-      </h3>
-      <p>
-        Device implementations MUST include support for one or more forms of data networking. Specifically, device implementations MUST include support for at least one data standard capable of 200Kbit/sec or greater. Examples of technologies that satisfy this requirement include EDGE, HSPA, EV-DO, 802.11g, Ethernet, Bluetooth PAN, etc.
-      </p>
-      <p>
-        Device implementations where a physical networking standard (such as Ethernet) is the primary data connection SHOULD also include support for at least one common wireless data standard, such as 802.11 (Wi-Fi).
-      </p>
-      <p>
-        Devices MAY implement more than one form of data connectivity.
-      </p>
-      <p>
-        Devices MUST include an IPv6 networking stack and support IPv6 communication using the managed APIs, such as <code>java.net.Socket</code> and <code>java.net.URLConnection</code> , as well as the native APIs, such as <code>AF_INET6</code> sockets. The required level of IPv6 support depends on the network type, as follows:
-      </p>
-      <ul>
-        <li>Devices that support Wi-Fi networks MUST support dual-stack and IPv6-only operation on Wi-Fi.
-        </li>
-        <li>Devices that support Ethernet networks MUST support dual-stack operation on Ethernet.
-        </li>
-        <li>Devices that support cellular data SHOULD support IPv6 operation (IPv6-only and possibly dual-stack) on cellular data.
-        </li>
-        <li>When a device is simultaneously connected to more than one network (e.g., Wi-Fi and cellular data), it MUST simultaneously meet these requirements on each network to which it is connected.
-        </li>
-      </ul>
-      <p>
-        IPv6 MUST be enabled by default.
-      </p>
-      <p>
-        In order to ensure that IPv6 communication is as reliable as IPv4, unicast IPv6 packets sent to the device MUST NOT be dropped, even when the screen is not in an active state. Redundant multicast IPv6 packets, such as repeated identical Router Advertisements, MAY be rate-limited in hardware or firmware if doing so is necessary to save power. In such cases, rate-limiting MUST NOT cause the device to lose IPv6 connectivity on any IPv6-compliant network that uses RA lifetimes of at least 180 seconds.
-      </p>
-      <p>
-        IPv6 connectivity MUST be maintained in doze mode.
-      </p>
-      <h3 id="7_4_6_sync_settings">
-        7.4.6. Sync Settings
-      </h3>
-      <p>
-        Device implementations MUST have the master auto-sync setting on by default so that the method <a href="http://developer.android.com/reference/android/content/ContentResolver.html">getMasterSyncAutomatically()</a> returns “true”.
-      </p>
-      <h3 id="7_4_7_data_saver">
-        7.4.7. Data Saver
-      </h3>
-      <p>
-        Device implementations with a metered connection are STRONGLY RECOMMENDED to provide the data saver mode.
-      </p>
-      <p>
-        If a device implementation provides the data saver mode, it:
-      </p>
-      <ul>
-        <li>
-          <p>
-            MUST support all the APIs in the <code>ConnectivityManager</code> class as described in the <a href="https://developer.android.com/training/basics/network-ops/data-saver.html">SDK documentation</a>
-          </p>
-        </li>
-        <li>
-          <p>
-            MUST provide a user interface in the settings, allowing users to add applications to or remove applications from the whitelist.
-          </p>
-        </li>
-      </ul>
-      <p>
-        Conversely if a device implementation does not provide the data saver mode, it:
-      </p>
-      <ul>
-        <li>
-          <p>
-            MUST return the value <code>RESTRICT_BACKGROUND_STATUS_DISABLED</code> for <a href="https://developer.android.com/reference/android/net/ConnectivityManager.html#getRestrictBackgroundStatus%28%29"><code>ConnectivityManager.getRestrictBackgroundStatus()</code></a>
-          </p>
-        </li>
-        <li>
-          <p>
-            MUST not broadcast <code>ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED</code>
-          </p>
-        </li>
-        <li>
-          <p>
-            MUST have an activity that handles the <code>Settings.ACTION_IGNORE_BACKGROUND_DATA_RESTRICTIONS_SETTINGS</code> intent but MAY implement it as a no-op.
-          </p>
-        </li>
-      </ul>
-      <h2 id="7_5_cameras">
-        7.5. Cameras
-      </h2>
-      <p>
-        Device implementations SHOULD include a rear-facing camera and MAY include a front-facing camera. A rear-facing camera is a camera located on the side of the device opposite the display; that is, it images scenes on the far side of the device, like a traditional camera. A front-facing camera is a camera located on the same side of the device as the display; that is, a camera typically used to image the user, such as for video conferencing and similar applications.
-      </p>
-      <p>
-        If a device implementation includes at least one camera, it MUST be possible for an application to simultaneously allocate 3 RGBA_8888 bitmaps equal to the size of the images produced by the largest-resolution camera sensor on the device, while camera is open for the purpose of basic preview and still capture.
-      </p>
-      <h3 id="7_5_1_rear-facing_camera">
-        7.5.1. Rear-Facing Camera
-      </h3>
-      <p>
-        Device implementations SHOULD include a rear-facing camera. If a device implementation includes at least one rear-facing camera, it:
-      </p>
-      <ul>
-        <li>MUST report the feature flag android.hardware.camera and android.hardware.camera.any.
-        </li>
-        <li>MUST have a resolution of at least 2 megapixels.
-        </li>
-        <li>SHOULD have either hardware auto-focus or software auto-focus implemented in the camera driver (transparent to application software).
-        </li>
-        <li>MAY have fixed-focus or EDOF (extended depth of field) hardware.
-        </li>
-        <li>MAY include a flash. If the Camera includes a flash, the flash lamp MUST NOT be lit while an android.hardware.Camera.PreviewCallback instance has been registered on a Camera preview surface, unless the application has explicitly enabled the flash by enabling the FLASH_MODE_AUTO or FLASH_MODE_ON attributes of a Camera.Parameters object. Note that this constraint does not apply to the device’s built-in system camera application, but only to third-party applications using Camera.PreviewCallback.
-        </li>
-      </ul>
-      <h3 id="7_5_2_front-facing_camera">
-        7.5.2. Front-Facing Camera
-      </h3>
-      <p>
-        Device implementations MAY include a front-facing camera. If a device implementation includes at least one front-facing camera, it:
-      </p>
-      <ul>
-        <li>MUST report the feature flag android.hardware.camera.any and android.hardware.camera.front.
-        </li>
-        <li>MUST have a resolution of at least VGA (640x480 pixels).
-        </li>
-        <li>MUST NOT use a front-facing camera as the default for the Camera API. The camera API in Android has specific support for front-facing cameras and device implementations MUST NOT configure the API to to treat a front-facing camera as the default rear-facing camera, even if it is the only camera on the device.
-        </li>
-        <li>MAY include features (such as auto-focus, flash, etc.) available to rear-facing cameras as described in <a href="#7_5_1_rear-facing_camera">section 7.5.1</a> .
-        </li>
-        <li>MUST horizontally reflect (i.e. mirror) the stream displayed by an app in a CameraPreview, as follows:
-          <ul>
-            <li>If the device implementation is capable of being rotated by user (such as automatically via an accelerometer or manually via user input), the camera preview MUST be mirrored horizontally relative to the device’s current orientation.
-            </li>
-            <li>If the current application has explicitly requested that the Camera display be rotated via a call to the <a href="http://developer.android.com/reference/android/hardware/Camera.html#setDisplayOrientation(int)">android.hardware.Camera.setDisplayOrientation()</a> method, the camera preview MUST be mirrored horizontally relative to the orientation specified by the application.
-            </li>
-            <li>Otherwise, the preview MUST be mirrored along the device’s default horizontal axis.
-            </li>
-          </ul>
-        </li>
-        <li>MUST mirror the image displayed by the postview in the same manner as the camera preview image stream. If the device implementation does not support postview, this requirement obviously does not apply.
-        </li>
-        <li>MUST NOT mirror the final captured still image or video streams returned to application callbacks or committed to media storage.
-        </li>
-      </ul>
-      <h3 id="7_5_3_external_camera">
-        7.5.3. External Camera
-      </h3>
-      <p>
-        Device implementations MAY include support for an external camera that is not necessarily always connected. If a device includes support for an external camera, it:
-      </p>
-      <ul>
-        <li>MUST declare the platform feature flag <code>android.hardware.camera.external</code> and <code>android.hardware camera.any</code> .
-        </li>
-        <li>MAY support multiple cameras.
-        </li>
-        <li>MUST support USB Video Class (UVC 1.0 or higher) if the external camera connects through the USB port.
-        </li>
-        <li>SHOULD support video compressions such as MJPEG to enable transfer of high-quality unencoded streams (i.e. raw or independently compressed picture streams).
-        </li>
-        <li>MAY support camera-based video encoding. If supported, a simultaneous unencoded / MJPEG stream (QVGA or greater resolution) MUST be accessible to the device implementation.
-        </li>
-      </ul>
-      <h3 id="7_5_4_camera_api_behavior">
-        7.5.4. Camera API Behavior
-      </h3>
-      <p>
-        Android includes two API packages to access the camera, the newer android.hardware.camera2 API expose lower-level camera control to the app, including efficient zero-copy burst/streaming flows and per-frame controls of exposure, gain, white balance gains, color conversion, denoising, sharpening, and more.
-      </p>
-      <p>
-        The older API package, android.hardware.Camera, is marked as deprecated in Android 5.0 but as it should still be available for apps to use Android device implementations MUST ensure the continued support of the API as described in this section and in the Android SDK.
-      </p>
-      <p>
-        Device implementations MUST implement the following behaviors for the camera-related APIs, for all available cameras:
-      </p>
-      <ul>
-        <li>If an application has never called android.hardware.Camera.Parameters.setPreviewFormat(int), then the device MUST use android.hardware.PixelFormat.YCbCr_420_SP for preview data provided to application callbacks.
-        </li>
-        <li>If an application registers an android.hardware.Camera.PreviewCallback instance and the system calls the onPreviewFrame() method when the preview format is YCbCr_420_SP, the data in the byte[] passed into onPreviewFrame() must further be in the NV21 encoding format. That is, NV21 MUST be the default.
-        </li>
-        <li>For android.hardware.Camera, device implementations MUST support the YV12 format (as denoted by the android.graphics.ImageFormat.YV12 constant) for camera previews for both front- and rear-facing cameras. (The hardware video encoder and camera may use any native pixel format, but the device implementation MUST support conversion to YV12.)
-        </li>
-        <li>For android.hardware.camera2, device implementations must support the android.hardware.ImageFormat.YUV_420_888 and android.hardware.ImageFormat.JPEG formats as outputs through the android.media.ImageReader API.
-        </li>
-      </ul>
-      <p>
-        Device implementations MUST still implement the full <a href="http://developer.android.com/reference/android/hardware/Camera.html">Camera API</a> included in the Android SDK documentation, regardless of whether the device includes hardware autofocus or other capabilities. For instance, cameras that lack autofocus MUST still call any registered android.hardware.Camera.AutoFocusCallback instances (even though this has no relevance to a non-autofocus camera.) Note that this does apply to front-facing cameras; for instance, even though most front-facing cameras do not support autofocus, the API callbacks must still be “faked” as described.
-      </p>
-      <p>
-        Device implementations MUST recognize and honor each parameter name defined as a constant on the <a href="http://developer.android.com/reference/android/hardware/Camera.Parameters.html">android.hardware.Camera.Parameters</a> class, if the underlying hardware supports the feature. If the device hardware does not support a feature, the API must behave as documented. Conversely, device implementations MUST NOT honor or recognize string constants passed to the android.hardware.Camera.setParameters() method other than those documented as constants on the android.hardware.Camera.Parameters. That is, device implementations MUST support all standard Camera parameters if the hardware allows, and MUST NOT support custom Camera parameter types. For instance, device implementations that support image capture using high dynamic range (HDR) imaging techniques MUST support camera parameter Camera.SCENE_MODE_HDR.
-      </p>
-      <p>
-        Because not all device implementations can fully support all the features of the android.hardware.camera2 API, device implementations MUST report the proper level of support with the <a href="https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics.html#INFO_SUPPORTED_HARDWARE_LEVEL">android.info.supportedHardwareLevel</a> property as described in the Android SDK and report the appropriate <a href="http://source.android.com/devices/camera/versioning.html">framework feature flags</a> .
-      </p>
-      <p>
-        Device implementations MUST also declare its Individual camera capabilities of android.hardware.camera2 via the android.request.availableCapabilities property and declare the appropriate <a href="http://source.android.com/devices/camera/versioning.html">feature flags</a> ; a device must define the feature flag if any of its attached camera devices supports the feature.
-      </p>
-      <p>
-        Device implementations MUST broadcast the Camera.ACTION_NEW_PICTURE intent whenever a new picture is taken by the camera and the entry of the picture has been added to the media store.
-      </p>
-      <p>
-        Device implementations MUST broadcast the Camera.ACTION_NEW_VIDEO intent whenever a new video is recorded by the camera and the entry of the picture has been added to the media store.
-      </p>
-      <h3 id="7_5_5_camera_orientation">
-        7.5.5. Camera Orientation
-      </h3>
-      <p>
-        Both front- and rear-facing cameras, if present, MUST be oriented so that the long dimension of the camera aligns with the screen’s long dimension. That is, when the device is held in the landscape orientation, cameras MUST capture images in the landscape orientation. This applies regardless of the device’s natural orientation; that is, it applies to landscape-primary devices as well as portrait-primary devices.
-      </p>
-      <h2 id="7_6_memory_and_storage">
-        7.6. Memory and Storage
-      </h2>
-      <h3 id="7_6_1_minimum_memory_and_storage">
-        7.6.1. Minimum Memory and Storage
-      </h3>
-      <div class="note">
-        Android Television devices MUST have at least 4GB of non-volatile storage available for application private data.
-      </div>
-      <p>
-        The memory available to the kernel and userspace on device implementations MUST be at least equal or larger than the minimum values specified by the following table. (See <a href="#7_1_1_screen_configuration">section 7.1.1</a> for screen size and density definitions.)
-      </p>
-      <table>
-        <tr>
-          <th>
-            Density and screen size
-          </th>
-          <th>
-            32-bit device
-          </th>
-          <th>
-            64-bit device
-          </th>
-        </tr>
-        <tr>
-          <td>
-            Android Watch devices (due to smaller screens)
-          </td>
-          <td>
-            416MB
-          </td>
-          <td>
-            Not applicable
-          </td>
-        </tr>
-        <tr>
-          <td>
-            <ul>
-              <li class="table_list">280dpi or lower on small/normal screens
-              </li>
-              <li class="table_list">mdpi or lower on large screens
-              </li>
-              <li class="table_list">ldpi or lower on extra large screens
-              </li>
-            </ul>
-          </td>
-          <td>
-            512MB
-          </td>
-          <td>
-            816MB
-          </td>
-        </tr>
-        <tr>
-          <td>
-            <ul>
-              <li class="table_list">xhdpi or higher on small/normal screens
-              </li>
-              <li class="table_list">hdpi or higher on large screens
-              </li>
-              <li class="table_list">mdpi or higher on extra large screens
-              </li>
-            </ul>
-          </td>
-          <td>
-            608MB
-          </td>
-          <td>
-            944MB
-          </td>
-        </tr>
-        <tr>
-          <td>
-            <ul>
-              <li class="table_list">400dpi or higher on small/normal screens
-              </li>
-              <li class="table_list">xhdpi or higher on large screens
-              </li>
-              <li class="table_list">tvdpi or higher on extra large screens
-              </li>
-            </ul>
-          </td>
-          <td>
-            896MB
-          </td>
-          <td>
-            1280MB
-          </td>
-        </tr>
-        <tr>
-          <td>
-            <ul>
-              <li class="table_list">560dpi or higher on small/normal screens
-              </li>
-              <li class="table_list">400dpi or higher on large screens
-              </li>
-              <li class="table_list">xhdpi or higher on extra large screens
-              </li>
-            </ul>
-          </td>
-          <td>
-            1344MB
-          </td>
-          <td>
-            1824MB
-          </td>
-        </tr>
-      </table>
-      <p>
-        The minimum memory values MUST be in addition to any memory space already dedicated to hardware components such as radio, video, and so on that is not under the kernel’s control.
-      </p>
-      <p>
-        Device implementations with less than 512MB of memory available to the kernel and userspace, unless an Android Watch, MUST return the value "true" for ActivityManager.isLowRamDevice().
-      </p>
-      <p>
-        Android Television devices MUST have at least 4GB and other device implementations MUST have at least 3GB of non-volatile storage available for application private data. That is, the /data partition MUST be at least 4GB for Android Television devices and at least 3GB for other device implementations. Device implementations that run Android are <strong>STRONGLY RECOMMENDED</strong> to have at least 4GB of non-volatile storage for application private data so they will be able to upgrade to the future platform releases.
-      </p>
-      <p>
-        The Android APIs include a <a href="http://developer.android.com/reference/android/app/DownloadManager.html">Download Manager</a> that applications MAY use to download data files. The device implementation of the Download Manager MUST be capable of downloading individual files of at least 100MB in size to the default “cache” location.
-      </p>
-      <h3 id="7_6_2_application_shared_storage">
-        7.6.2. Application Shared Storage
-      </h3>
-      <p>
-        Device implementations MUST offer shared storage for applications also often referred as “shared external storage”.
-      </p>
-      <p>
-        Device implementations MUST be configured with shared storage mounted by default, “out of the box”. If the shared storage is not mounted on the Linuxpath /sdcard, then the device MUST include a Linux symbolic link from /sdcard to the actual mount point.
-      </p>
-      <p>
-        Device implementations MAY have hardware for user-accessible removable storage, such as a Secure Digital (SD) card slot. If this slot is used to satisfy the shared storage requirement, the device implementation:
-      </p>
-      <ul>
-        <li>MUST implement a toast or pop-up user interface warning the user when there is no SD card.
-        </li>
-        <li>MUST include a FAT-formatted SD card 1GB in size or larger OR show on the box and other material available at time of purchase that the SD card has to be separately purchased.
-        </li>
-        <li>MUST mount the SD card by default.
-        </li>
-      </ul>
-      <p>
-        Alternatively, device implementations MAY allocate internal (non-removable) storage as shared storage for apps as included in the upstream Android Open Source Project; device implementations SHOULD use this configuration and software implementation. If a device implementation uses internal (non-removable) storage to satisfy the shared storage requirement, while that storage MAY share space with the application private data, it MUST be at least 1GB in size and mounted on /sdcard (or /sdcard MUST be a symbolic link to the physical location if it is mounted elsewhere).
-      </p>
-      <p>
-        Device implementations MUST enforce as documented the android.permission.WRITE_EXTERNAL_STORAGE permission on this shared storage. Shared storage MUST otherwise be writable by any application that obtains that permission.
-      </p>
-      <p>
-        Device implementations that include multiple shared storage paths (such as both an SD card slot and shared internal storage) MUST allow only pre-installed &amp; privileged Android applications with the WRITE_EXTERNAL_STORAGE permission to write to the secondary external storage, except when writing to their package-specific directories or within the <code>URI</code> returned by firing the <code>ACTION_OPEN_DOCUMENT_TREE</code> intent.
-      </p>
-      <p>
-        However, device implementations SHOULD expose content from both storage paths transparently through Android’s media scanner service and android.provider.MediaStore.
-      </p>
-      <p>
-        Regardless of the form of shared storage used, if the device implementation has a USB port with USB peripheral mode support, it MUST provide some mechanism to access the contents of shared storage from a host computer. Device implementations MAY use USB mass storage, but SHOULD use Media Transfer Protocol to satisfy this requirement. If the device implementation supports Media Transfer Protocol, it:
-      </p>
-      <ul>
-        <li>SHOULD be compatible with the reference Android MTP host, <a href="http://www.android.com/filetransfer">Android File Transfer</a> .
-        </li>
-        <li>SHOULD report a USB device class of 0x00.
-        </li>
-        <li>SHOULD report a USB interface name of 'MTP'.
-        </li>
-      </ul>
-      <h3 id="7_6_3_adoptable_storage">
-        7.6.3. Adoptable Storage
-      </h3>
-      <p>
-        Device implementations are STRONGLY RECOMMENDED to implement <a href="http://source.android.com/devices/storage/adoptable.html">adoptable storage</a> if the removable storage device port is in a long-term stable location, such as within the battery compartment or other protective cover.
-      </p>
-      <p>
-        Device implementations such as a television, MAY enable adoption through USB ports as the device is expected to be static and not mobile. But for other device implementations that are mobile in nature, it is STRONGLY RECOMMENDED to implement the adoptable storage in a long-term stable location, since accidentally disconnecting them can cause data loss/corruption.
-      </p>
-      <h2 id="7_7_usb">
-        7.7. USB
-      </h2>
-      <p>
-        Device implementations SHOULD support USB peripheral mode and SHOULD support USB host mode.
-      </p>
-      <h3 id="7_7_1_usb_peripheral_mode">
-        7.7.1. USB peripheral mode
-      </h3>
-      <p>
-        If a device implementation includes a USB port supporting peripheral mode:
-      </p>
-      <ul>
-        <li>The port MUST be connectable to a USB host that has a standard type-A or type-C USB port.
-        </li>
-        <li>The port SHOULD use micro-B, micro-AB or Type-C USB form factor. Existing and new Android devices are <strong>STRONGLY RECOMMENDED to meet these requirements</strong> so they will be able to upgrade to the future platform releases.
-        </li>
-        <li>The port SHOULD be located on the bottom of the device (according to natural orientation) or enable software screen rotation for all apps (including home screen), so that the display draws correctly when the device is oriented with the port at bottom. Existing and new Android devices are <strong>STRONGLY RECOMMENDED to meet these requirements</strong> so they will be able to upgrade to future platform releases.
-        </li>
-        <li>It MUST allow a USB host connected with the Android device to access the contents of the shared storage volume using either USB mass storage or Media Transfer Protocol.
-        </li>
-        <li>It SHOULD implement the Android Open Accessory (AOA) API and specification as documented in the Android SDK documentation, and if it is an Android Handheld device it MUST implement the AOA API. Device implementations implementing the AOA specification:
-          <ul>
-            <li>MUST declare support for the hardware feature <a href="http://developer.android.com/guide/topics/connectivity/usb/accessory.html">android.hardware.usb.accessory</a> .
-            </li>
-            <li>MUST implement the <a href="http://developer.android.com/reference/android/hardware/usb/UsbConstants.html#USB_CLASS_AUDIO">USB audio class</a> as documented in the Android SDK documentation.
-            </li>
-            <li>The USB mass storage class MUST include the string "android" at the end of the interface description <code>iInterface</code> string of the USB mass storage
-            </li>
-          </ul>
-        </li>
-        <li>It SHOULD implement support to draw 1.5 A current during HS chirp and traffic as specified in the <a href="http://www.usb.org/developers/docs/devclass_docs/BCv1.2_070312.zip">USB Battery Charging specification, revision 1.2</a> . Existing and new Android devices are <strong>STRONGLY RECOMMENDED to meet these requirements</strong> so they will be able to upgrade to the future platform releases.
-        </li>
-        <li>Type-C devices MUST detect 1.5A and 3.0A chargers per the Type-C resistor standard and it must detect changes in the advertisement.
-        </li>
-        <li>Type-C devices also supporting USB host mode are STRONGLY RECOMMENDED to support Power Delivery for data and power role swapping.
-        </li>
-        <li>Type-C devices SHOULD support Power Delivery for high-voltage charging and support for Alternate Modes such as display out.
-        </li>
-        <li>The value of iSerialNumber in USB standard device descriptor MUST be equal to the value of android.os.Build.SERIAL.
-        </li>
-        <li>Type-C devices are STRONGLY RECOMMENDED to not support proprietary charging methods that modify Vbus voltage beyond default levels, or alter sink/source roles as such may result in interoperability issues with the chargers or devices that support the standard USB Power Delivery methods. While this is called out as "STRONGLY RECOMMENDED", in future Android versions we might REQUIRE all type-C devices to support full interoperability with standard type-C chargers.
-        </li>
-      </ul>
-      <h3 id="7_7_2_usb_host_mode">
-        7.7.2. USB host mode
-      </h3>
-      <p>
-        If a device implementation includes a USB port supporting host mode, it:
-      </p>
-      <ul>
-        <li>SHOULD use a type-C USB port, if the device implementation supports USB 3.1.
-        </li>
-        <li>MAY use a non-standard port form factor, but if so MUST ship with a cable or cables adapting the port to a standard type-A or type-C USB port.
-        </li>
-        <li>MAY use a micro-AB USB port, but if so SHOULD ship with a cable or cables adapting the port to a standard type-A or type-C USB port.
-        </li>
-        <li>is <strong>STRONGLY RECOMMENDED</strong> to implement the <a href="http://developer.android.com/reference/android/hardware/usb/UsbConstants.html#USB_CLASS_AUDIO">USB audio class</a> as documented in the Android SDK documentation.
-        </li>
-        <li>MUST implement the Android USB host API as documented in the Android SDK, and MUST declare support for the hardware feature <a href="http://developer.android.com/guide/topics/connectivity/usb/host.html">android.hardware.usb.host</a> .
-        </li>
-        <li>SHOULD support device charging while in host mode; advertising a source current of at least 1.5A as specified in the Termination Parameters section of the [USB Type-C Cable and Connector Specification Revision 1.2] (http://www.usb.org/developers/docs/usb_31_021517.zip) for USB Type-C connectors or using Charging Downstream Port(CDP) output current range as specified in the <a href="http://www.usb.org/developers/docs/devclass_docs/BCv1.2_070312.zip">USB Battery Charging specifications, revision 1.2</a> for Micro-AB connectors.
-        </li>
-        <li>USB Type-C devices are STRONGLY RECOMMENDED to support DisplayPort, SHOULD support USB SuperSpeed Data Rates, and are STRONGLY RECOMMENDED to support Power Delivery for data and power role swapping.
-        </li>
-        <li>Devices with any type-A or type-AB ports MUST NOT ship with an adapter converting from this port to a type-C receptacle.
-        </li>
-        <li>MUST recognize any remotely connected MTP (Media Transfer Protocol) devices and make their contents accessible through the <code>ACTION_GET_CONTENT</code> , <code>ACTION_OPEN_DOCUMENT</code> , and <code>ACTION_CREATE_DOCUMENT</code> intents, if the Storage Access Framework (SAF) is supported.
-        </li>
-        <li>MUST, if using a Type-C USB port and including support for peripheral mode, implement Dual Role Port functionality as defined by the USB Type-C specification (section 4.5.1.3.3).
-        </li>
-        <li>SHOULD, if the Dual Role Port functionality is supported, implement the Try.* model that is most appropriate for the device form factor. For example a handheld device SHOULD implement the Try.SNK model.
-        </li>
-      </ul>
-      <h2 id="7_8_audio">
-        7.8. Audio
-      </h2>
-      <h3 id="7_8_1_microphone">
-        7.8.1. Microphone
-      </h3>
-      <div class="note">
-        Android Handheld, Watch, and Automotive implementations MUST include a microphone.
-      </div>
-      <p>
-        Device implementations MAY omit a microphone. However, if a device implementation omits a microphone, it MUST NOT report the android.hardware.microphone feature constant, and MUST implement the audio recording API at least as no-ops, per <a href="#7_hardware_compatibility">section 7</a> . Conversely, device implementations that do possess a microphone:
-      </p>
-      <ul>
-        <li>MUST report the android.hardware.microphone feature constant.
-        </li>
-        <li>MUST meet the audio recording requirements in <a href="#5_4_audio_recording">section 5.4</a> .
-        </li>
-        <li>MUST meet the audio latency requirements in <a href="#5_6_audio_latency">section 5.6</a> .
-        </li>
-        <li>STRONGLY RECOMMENDED to support near-ultrasound recording as described in <a href="#7_8_3_near_ultrasound">section 7.8.3</a> .
-        </li>
-      </ul>
-      <h3 id="7_8_2_audio_output">
-        7.8.2. Audio Output
-      </h3>
-      <div class="note">
-        Android Watch devices MAY include an audio output.
-      </div>
-      <p>
-        Device implementations including a speaker or with an audio/multimedia output port for an audio output peripheral as a headset or an external speaker:
-      </p>
-      <ul>
-        <li>MUST report the android.hardware.audio.output feature constant.
-        </li>
-        <li>MUST meet the audio playback requirements in <a href="#5_5_audio_playback">section 5.5</a> .
-        </li>
-        <li>MUST meet the audio latency requirements in <a href="#5_6_audio_latency">section 5.6</a> .
-        </li>
-        <li>STRONGLY RECOMMENDED to support near-ultrasound playback as described in <a href="#7_8_3_near_ultrasound">section 7.8.3</a> .
-        </li>
-      </ul>
-      <p>
-        Conversely, if a device implementation does not include a speaker or audio output port, it MUST NOT report the android.hardware.audio output feature, and MUST implement the Audio Output related APIs as no-ops at least.
-      </p>
-      <p>
-        Android Watch device implementation MAY but SHOULD NOT have audio output, but other types of Android device implementations MUST have an audio output and declare android.hardware.audio.output.
-      </p>
-      <h4 id="7_8_2_1_analog_audio_ports">
-        7.8.2.1. Analog Audio Ports
-      </h4>
-      <p>
-        In order to be compatible with the <a href="http://source.android.com/accessories/headset-spec.html">headsets and other audio accessories</a> using the 3.5mm audio plug across the Android ecosystem, if a device implementation includes one or more analog audio ports, at least one of the audio port(s) SHOULD be a 4 conductor 3.5mm audio jack. If a device implementation has a 4 conductor 3.5mm audio jack, it:
-      </p>
-      <ul>
-        <li>MUST support audio playback to stereo headphones and stereo headsets with a microphone, and SHOULD support audio recording from stereo headsets with a microphone.
-        </li>
-        <li>MUST support TRRS audio plugs with the CTIA pin-out order, and SHOULD support audio plugs with the OMTP pin-out order.
-        </li>
-        <li>MUST support the detection of microphone on the plugged in audio accessory, if the device implementation supports a microphone, and broadcast the android.intent.action.HEADSET_PLUG with the extra value microphone set as 1.
-        </li>
-        <li>MUST support the detection and mapping to the keycodes for the following 3 ranges of equivalent impedance between the microphone and ground conductors on the audio plug:
-          <ul>
-            <li>
-              <strong>70 ohm or less</strong> : KEYCODE_HEADSETHOOK
-            </li>
-            <li>
-              <strong>210-290 Ohm</strong> : KEYCODE_VOLUME_UP
-            </li>
-            <li>
-              <strong>360-680 Ohm</strong> : KEYCODE_VOLUME_DOWN
-            </li>
-          </ul>
-        </li>
-        <li>STRONGLY RECOMMENDED to detect and map to the keycode for the following range of equivalent impedance between the microphone and ground conductors on the audio plug:
-          <ul>
-            <li>
-              <strong>110-180 Ohm:</strong> KEYCODE_VOICE_ASSIST
-            </li>
-          </ul>
-        </li>
-        <li>MUST trigger ACTION_HEADSET_PLUG upon a plug insert, but only after all contacts on plug are touching their relevant segments on the jack.
-        </li>
-        <li>MUST be capable of driving at least 150mV ± 10% of output voltage on a 32 Ohm speaker impedance.
-        </li>
-        <li>MUST have a microphone bias voltage between 1.8V ~ 2.9V.
-        </li>
-      </ul>
-      <h3 id="7_8_3_near-ultrasound">
-        7.8.3. Near-Ultrasound
-      </h3>
-      <p>
-        Near-Ultrasound audio is the 18.5 kHz to 20 kHz band. Device implementations MUST correctly report the support of near-ultrasound audio capability via the <a href="http://developer.android.com/reference/android/media/AudioManager.html#getProperty%28java.lang.String%29">AudioManager.getProperty</a> API as follows:
-      </p>
-      <ul>
-        <li>If <a href="http://developer.android.com/reference/android/media/AudioManager.html#PROPERTY_SUPPORT_MIC_NEAR_ULTRASOUND">PROPERTY_SUPPORT_MIC_NEAR_ULTRASOUND</a> is "true", then the following requirements must be met by the VOICE_RECOGNITION and UNPROCESSED audio sources:
-          <ul>
-            <li>The microphone's mean power response in the 18.5 kHz to 20 kHz band MUST be no more than 15 dB below the response at 2 kHz.
-            </li>
-            <li>The microphone's unweighted signal to noise ratio over 18.5 kHz to 20 kHz for a 19 kHz tone at -26 dBFS MUST be no lower than 50 dB.
-            </li>
-          </ul>
-        </li>
-        <li>If <a href="http://developer.android.com/reference/android/media/AudioManager.html#PROPERTY_SUPPORT_SPEAKER_NEAR_ULTRASOUND">PROPERTY_SUPPORT_SPEAKER_NEAR_ULTRASOUND</a> is "true", then the speaker's mean response in 18.5 kHz - 20 kHz MUST be no lower than 40 dB below the response at 2 kHz.
-        </li>
-      </ul>
-      <h2 id="7_9_virtual_reality">
-        7.9. Virtual Reality
-      </h2>
-      <p>
-        Android includes APIs and facilities to build "Virtual Reality" (VR) applications including high quality mobile VR experiences. Device implementations MUST properly implement these APIs and behaviors, as detailed in this section.
-      </p>
-      <h3 id="7_9_1_virtual_reality_mode">
-        7.9.1. Virtual Reality Mode
-      </h3>
-      <p>
-        Android handheld device implementations that support a mode for VR applications that handles stereoscopic rendering of notifications and disable monocular system UI components while a VR application has user focus MUST declare <code>android.software.vr.mode</code> feature. Devices declaring this feature MUST include an application implementing <code>android.service.vr.VrListenerService</code> that can be enabled by VR applications via <code>android.app.Activity#setVrModeEnabled</code> .
-      </p>
-      <h3 id="7_9_2_virtual_reality_high_performance">
-        7.9.2. Virtual Reality High Performance
-      </h3>
-      <p>
-        Android handheld device implementations MUST identify the support of high performance virtual reality for longer user periods through the <code>android.hardware.vr.high_performance</code> feature flag and meet the following requirements.
-      </p>
-      <ul>
-        <li>Device implementations MUST have at least 2 physical cores.
-        </li>
-        <li>Device implementations MUST declare android.software.vr.mode feature.
-        </li>
-        <li>Device implementations MAY provide an exclusive core to the foreground application and MAY support the Process.getExclusiveCores API to return the numbers of the cpu cores that are exclusive to the top foreground application. If exclusive core is supported then the core MUST not allow any other userspace processes to run on it (except device drivers used by the application), but MAY allow some kernel processes to run as necessary.
-        </li>
-        <li>Device implementations MUST support sustained performance mode.
-        </li>
-        <li>Device implementations MUST support OpenGL ES 3.2.
-        </li>
-        <li>Device implementations MUST support Vulkan Hardware Level 0 and SHOULD support Vulkan Hardware Level 1.
-        </li>
-        <li>Device implementations MUST implement EGL_KHR_mutable_render_buffer and EGL_ANDROID_front_buffer_auto_refresh, EGL_ANDROID_create_native_client_buffer, EGL_KHR_fence_sync and EGL_KHR_wait_sync so that they may be used for Shared Buffer Mode, and expose the extensions in the list of available EGL extensions.
-        </li>
-        <li>The GPU and display MUST be able to synchronize access to the shared front buffer such that alternating-eye rendering of VR content at 60fps with two render contexts will be displayed with no visible tearing artifacts.
-        </li>
-        <li>Device implementations MUST implement EGL_IMG_context_priority, and expose the extension in the list of available EGL extensions.
-        </li>
-        <li>Device implementations MUST implement GL_EXT_multisampled_render_to_texture, GL_OVR_multiview, GL_OVR_multiview2 and GL_OVR_multiview_multisampled_render_to_texture, and expose the extensions in the list of available GL extensions.
-        </li>
-        <li>Device implementations MUST implement EGL_EXT_protected_content and GL_EXT_protected_textures so that it may be used for Secure Texture Video Playback, and expose the extensions in the list of available EGL and GL extensions.
-        </li>
-        <li>Device implementations MUST support H.264 decoding at least 3840x2160@30fps-40Mbps (equivalent to 4 instances of 1920x1080@30fps-10Mbps or 2 instances of 1920x1080@60fps-20Mbps).
-        </li>
-        <li>Device implementations MUST support HEVC and VP9, MUST be capable to decode at least 1920x1080@30fps-10Mbps and SHOULD be capable to decode 3840x2160@30fps-20Mbps (equivalent to 4 instances of 1920x1080@30fps-5Mbps).
-        </li>
-        <li>The device implementations are STRONGLY RECOMMENDED to support android.hardware.sensor.hifi_sensors feature and MUST meet the gyroscope, accelerometer, and magnetometer related requirements for android.hardware.hifi_sensors.
-        </li>
-        <li>Device implementations MUST support HardwarePropertiesManager.getDeviceTemperatures API and return accurate values for skin temperature.
-        </li>
-        <li>The device implementation MUST have an embedded screen, and its resolution MUST be at least be FullHD(1080p) and STRONGLY RECOMMENDED TO BE be QuadHD (1440p) or higher.
-        </li>
-        <li>The display MUST measure between 4.7" and 6" diagonal.
-        </li>
-        <li>The display MUST update at least 60 Hz while in VR Mode.
-        </li>
-        <li>The display latency on Gray-to-Gray, White-to-Black, and Black-to-White switching time MUST be ≤ 3 ms.
-        </li>
-        <li>The display MUST support a low-persistence mode with ≤5 ms persistence,persistence being defined as the amount of time for which a pixel is emitting light.
-        </li>
-        <li>Device implementations MUST support Bluetooth 4.2 and Bluetooth LE Data Length Extension <a href="#7_4_3_bluetooth">section 7.4.3</a> .
-        </li>
-      </ul>
-      <h1 id="8_performance_and_power">
-        8. Performance and Power
-      </h1>
-      <p>
-        Some minimum performance and power criteria are critical to the user experience and impact the baseline assumptions developers would have when developing an app. Android Watch devices SHOULD and other type of device implementations MUST meet the following criteria.
-      </p>
-      <h2 id="8_1_user_experience_consistency">
-        8.1. User Experience Consistency
-      </h2>
-      <p>
-        Device implementations MUST provide a smooth user interface by ensuring a consistent frame rate and response times for applications and games. Device implementations MUST meet the following requirements:
-      </p>
-      <ul>
-        <li>
-          <strong>Consistent frame latency</strong> . Inconsistent frame latency or a delay to render frames MUST NOT happen more often than 5 frames in a second, and SHOULD be below 1 frames in a second.
-        </li>
-        <li>
-          <strong>User interface latency</strong> . Device implementations MUST ensure low latency user experience by scrolling a list of 10K list entries as defined by the Android Compatibility Test Suite (CTS) in less than 36 secs.
-        </li>
-        <li>
-          <strong>Task switching</strong> . When multiple applications have been launched, re-launching an already-running application after it has been launched MUST take less than 1 second.
-        </li>
-      </ul>
-      <h2 id="8_2_file_i/o_access_performance">
-        8.2. File I/O Access Performance
-      </h2>
-      <p>
-        Device implementations MUST ensure internal storage file access performance consistency for read and write operations.
-      </p>
-      <ul>
-        <li>
-          <strong>Sequential write</strong> . Device implementations MUST ensure a sequential write performance of at least 5MB/s for a 256MB file using 10MB write buffer.
-        </li>
-        <li>
-          <strong>Random write</strong> . Device implementations MUST ensure a random write performance of at least 0.5MB/s for a 256MB file using 4KB write buffer.
-        </li>
-        <li>
-          <strong>Sequential read</strong> . Device implementations MUST ensure a sequential read performance of at least 15MB/s for a 256MB file using 10MB write buffer.
-        </li>
-        <li>
-          <strong>Random read</strong> . Device implementations MUST ensure a random read performance of at least 3.5MB/s for a 256MB file using 4KB write buffer.
-        </li>
-      </ul>
-      <h2 id="8_3_power-saving_modes">
-        8.3. Power-Saving Modes
-      </h2>
-      <p>
-        Android 6.0 introduced App Standby and Doze power-saving modes to optimize battery usage. All Apps exempted from these modes MUST be made visible to the end user. Further, the triggering, maintenance, wakeup algorithms and the use of global system settings of these power-saving modes MUST not deviate from the Android Open Source Project.
-      </p>
-      <p>
-        In addition to the power-saving modes, Android device implementations MAY implement any or all of the 4 sleeping power states as defined by the Advanced Configuration and Power Interface (ACPI), but if it implements S3 and S4 power states, it can only enter these states when closing a lid that is physically part of the device.
-      </p>
-      <h2 id="8_4_power_consumption_accounting">
-        8.4. Power Consumption Accounting
-      </h2>
-      <p>
-        A more accurate accounting and reporting of the power consumption provides the app developer both the incentives and the tools to optimize the power usage pattern of the application. Therefore, device implementations:
-      </p>
-      <ul>
-        <li>MUST be able to track hardware component power usage and attribute that power usage to specific applications. Specifically, implementations:
-          <ul>
-            <li>MUST provide a per-component power profile that defines the <a href="http://source.android.com/devices/tech/power/values.html">current consumption value</a> for each hardware component and the approximate battery drain caused by the components over time as documented in the Android Open Source Project site.
-            </li>
-            <li>MUST report all power consumption values in milliampere hours (mAh).
-            </li>
-            <li>SHOULD be attributed to the hardware component itself if unable to attribute hardware component power usage to an application.
-            </li>
-            <li>MUST report CPU power consumption per each process's UID. The Android Open Source Project meets the requirement through the <code>uid_cputime</code> kernel module implementation.
-            </li>
-          </ul>
-        </li>
-        <li>MUST make this power usage available via the <a href="http://source.android.com/devices/tech/power/batterystats.html"><code>adb shell dumpsys batterystats</code></a> shell command to the app developer.
-        </li>
-        <li>MUST honor the <a href="http://developer.android.com/reference/android/content/Intent.html#ACTION_POWER_USAGE_SUMMARY">android.intent.action.POWER_USAGE_SUMMARY</a> intent and display a settings menu that shows this power usage.
-        </li>
-      </ul>
-      <h2 id="8_5_consistent_performance">
-        8.5. Consistent Performance
-      </h2>
-      <p>
-        Performance can fluctuate dramatically for high-performance long-running apps, either because of the other apps running in the background or the CPU throttling due to temperature limits. Android includes programmatic interfaces so that when the device is capable, the top foreground application can request that the system optimize the allocation of the resources to address such fluctuations.
-      </p>
-      <p>
-        Device implementations SHOULD support Sustained Performance Mode which can provide the top foreground application a consistent level of performance for a prolonged amount of time when requested through the <a href="https://developer.android.com/reference/android/view/Window.html#setSustainedPerformanceMode%28boolean%29"><code>Window.setSustainedPerformanceMode()</code></a> API method. A Device implementation MUST report the support of Sustained Performance Mode accurately through the <a href="https://developer.android.com/reference/android/os/PowerManager.html#isSustainedPerformanceModeSupported%28%29"><code>PowerManager.isSustainedPerformanceModeSupported()</code></a> API method.
-      </p>
-      <p>
-        Device implementations with two or more CPU cores SHOULD provide at least one exclusive core that can be reserved by the top foreground application. If provided, implementations MUST meet the following requirements:
-      </p>
-      <ul>
-        <li>Implementations MUST report through the <a href="https://developer.android.com/reference/android/os/Process.html#getExclusiveCores%28%29"><code>Process.getExclusiveCores()</code></a> API method the id numbers of the exclusive cores that can be reserved by the top foreground application.
-        </li>
-        <li>Device implementations MUST not allow any user space processes except the device drivers used by the application to run on the exclusive cores, but MAY allow some kernel processes to run as necessary.
-        </li>
-      </ul>
-      <p>
-        If a device implementation does not support an exclusive core, it MUST return an empty list through the <a href="https://developer.android.com/reference/android/os/Process.html#getExclusiveCores%28%29"><code>Process.getExclusiveCores()</code></a> API method.
-      </p>
-      <h1 id="9_security_model_compatibility">
-        9. Security Model Compatibility
-      </h1>
-      <p>
-        Device implementations MUST implement a security model consistent with the Android platform security model as defined in <a href="http://developer.android.com/guide/topics/security/permissions.html">Security and Permissions reference document</a> in the APIs in the Android developer documentation. Device implementations MUST support installation of self-signed applications without requiring any additional permissions/certificates from any third parties/authorities. Specifically, compatible devices MUST support the security mechanisms described in the follow subsections.
-      </p>
-      <h2 id="9_1_permissions">
-        9.1. Permissions
-      </h2>
-      <p>
-        Device implementations MUST support the <a href="http://developer.android.com/guide/topics/security/permissions.html">Android permissions model</a> as defined in the Android developer documentation. Specifically, implementations MUST enforce each permission defined as described in the SDK documentation; no permissions may be omitted, altered, or ignored. Implementations MAY add additional permissions, provided the new permission ID strings are not in the android.* namespace.
-      </p>
-      <p>
-        Permissions with a <code>protectionLevel</code> of <a href="https://developer.android.com/reference/android/content/pm/PermissionInfo.html#PROTECTION_FLAG_PRIVILEGED">'PROTECTION_FLAG_PRIVILEGED'</a> MUST only be granted to apps preloaded in the whitelisted privileged path(s) of the system image, such as the <code>system/priv-app</code> path in the AOSP implementation.
-      </p>
-      <p>
-        Permissions with a protection level of dangerous are runtime permissions. Applications with targetSdkVersion &gt; 22 request them at runtime. Device implementations:
-      </p>
-      <ul>
-        <li>MUST show a dedicated interface for the user to decide whether to grant the requested runtime permissions and also provide an interface for the user to manage runtime permissions.
-        </li>
-        <li>MUST have one and only one implementation of both user interfaces.
-        </li>
-        <li>MUST NOT grant any runtime permissions to preinstalled apps unless:
-          <ul>
-            <li>the user's consent can be obtained before the application uses it
-            </li>
-            <li>the runtime permissions are associated with an intent pattern for which the preinstalled application is set as the default handler
-            </li>
-          </ul>
-        </li>
-      </ul>
-      <h2 id="9_2_uid_and_process_isolation">
-        9.2. UID and Process Isolation
-      </h2>
-      <p>
-        Device implementations MUST support the Android application sandbox model, in which each application runs as a unique Unixstyle UID and in a separate process. Device implementations MUST support running multiple applications as the same Linux user ID, provided that the applications are properly signed and constructed, as defined in the <a href="http://developer.android.com/guide/topics/security/permissions.html">Security and Permissions reference</a> .
-      </p>
-      <h2 id="9_3_filesystem_permissions">
-        9.3. Filesystem Permissions
-      </h2>
-      <p>
-        Device implementations MUST support the Android file access permissions model as defined in the <a href="http://developer.android.com/guide/topics/security/permissions.html">Security and Permissions reference</a> .
-      </p>
-      <h2 id="9_4_alternate_execution_environments">
-        9.4. Alternate Execution Environments
-      </h2>
-      <p>
-        Device implementations MAY include runtime environments that execute applications using some other software or technology than the Dalvik Executable Format or native code. However, such alternate execution environments MUST NOT compromise the Android security model or the security of installed Android applications, as described in this section.
-      </p>
-      <p>
-        Alternate runtimes MUST themselves be Android applications, and abide by the standard Android security model, as described elsewhere in <a href="#9_security_model_compatibility">section 9</a> .
-      </p>
-      <p>
-        Alternate runtimes MUST NOT be granted access to resources protected by permissions not requested in the runtime’s AndroidManifest.xml file via the &lt;uses-permission&gt; mechanism.
-      </p>
-      <p>
-        Alternate runtimes MUST NOT permit applications to make use of features protected by Android permissions restricted to system applications.
-      </p>
-      <p>
-        Alternate runtimes MUST abide by the Android sandbox model. Specifically, alternate runtimes:
-      </p>
-      <ul>
-        <li>SHOULD install apps via the PackageManager into separate Android sandboxes (Linux user IDs, etc.).
-        </li>
-        <li>MAY provide a single Android sandbox shared by all applications using the alternate runtime.
-        </li>
-        <li>Installed applications using an alternate runtime MUST NOT reuse the sandbox of any other app installed on the device, except through the standard Android mechanisms of shared user ID and signing certificate.
-        </li>
-        <li>MUST NOT launch with, grant, or be granted access to the sandboxes corresponding to other Android applications.
-        </li>
-        <li>MUST NOT be launched with, be granted, or grant to other applications any privileges of the superuser (root), or of any other user ID.
-        </li>
-      </ul>
-      <p>
-        The .apk files of alternate runtimes MAY be included in the system image of a device implementation, but MUST be signed with a key distinct from the key used to sign other applications included with the device implementation.
-      </p>
-      <p>
-        When installing applications, alternate runtimes MUST obtain user consent for the Android permissions used by the application. If an application needs to make use of a device resource for which there is a corresponding Android permission (such as Camera, GPS, etc.), the alternate runtime MUST inform the user that the application will be able to access that resource. If the runtime environment does not record application capabilities in this manner, the runtime environment MUST list all permissions held by the runtime itself when installing any application using that runtime.
-      </p>
-      <h2 id="9_5_multi-user_support">
-        9.5. Multi-User Support
-      </h2>
-      <div class="note">
-        This feature is optional for all device types.
-      </div>
-      <p>
-        Android includes <a href="http://developer.android.com/reference/android/os/UserManager.html">support for multiple users</a> and provides support for full user isolation. Device implementations MAY enable multiple users, but when enabled MUST meet the following requirements related to <a href="http://source.android.com/devices/storage/traditional.html">multi-user support</a> :
-      </p>
-      <ul>
-        <li>Android Automotive device implementations with multi-user support enabled MUST include a guest account that allows all functions provided by the vehicle system without requiring a user to log in.
-        </li>
-        <li>Device implementations that do not declare the android.hardware.telephony feature flag MUST support restricted profiles, a feature that allows device owners to manage additional users and their capabilities on the device. With restricted profiles, device owners can quickly set up separate environments for additional users to work in, with the ability to manage finer-grained restrictions in the apps that are available in those environments.
-        </li>
-        <li>Conversely device implementations that declare the android.hardware.telephony feature flag MUST NOT support restricted profiles but MUST align with the AOSP implementation of controls to enable /disable other users from accessing the voice calls and SMS.
-        </li>
-        <li>Device implementations MUST, for each user, implement a security model consistent with the Android platform security model as defined in <a href="http://developer.android.com/guide/topics/security/permissions.html">Security and Permissions reference document</a> in the APIs.
-        </li>
-        <li>Each user instance on an Android device MUST have separate and isolated external storage directories. Device implementations MAY store multiple users' data on the same volume or filesystem. However, the device implementation MUST ensure that applications owned by and running on behalf a given user cannot list, read, or write to data owned by any other user. Note that removable media, such as SD card slots, can allow one user to access another’s data by means of a host PC. For this reason, device implementations that use removable media for the external storage APIs MUST encrypt the contents of the SD card if multiuser is enabled using a key stored only on non-removable media accessible only to the system. As this will make the media unreadable by a host PC, device implementations will be required to switch to MTP or a similar system to provide host PCs with access to the current user’s data. Accordingly, device implementations MAY but SHOULD NOT enable multi-user if they use <a href="http://developer.android.com/reference/android/os/Environment.html">removable media</a> for primary external storage.
-        </li>
-      </ul>
-      <h2 id="9_6_premium_sms_warning">
-        9.6. Premium SMS Warning
-      </h2>
-      <p>
-        Android includes support for warning users of any outgoing <a href="http://en.wikipedia.org/wiki/Short_code">premium SMS message</a> . Premium SMS messages are text messages sent to a service registered with a carrier that may incur a charge to the user. Device implementations that declare support for android.hardware.telephony MUST warn users before sending a SMS message to numbers identified by regular expressions defined in /data/misc/sms/codes.xml file in the device. The upstream Android Open Source Project provides an implementation that satisfies this requirement.
-      </p>
-      <h2 id="9_7_kernel_security_features">
-        9.7. Kernel Security Features
-      </h2>
-      <p>
-        The Android Sandbox includes features that use the Security-Enhanced Linux (SELinux) mandatory access control (MAC) system, seccomp sandboxing, and other security features in the Linux kernel. SELinux or any other security features implemented below the Android framework:
-      </p>
-      <ul>
-        <li>MUST maintain compatibility with existing applications.
-        </li>
-        <li>MUST NOT have a visible user interface when a security violation is detected and successfully blocked, but MAY have a visible user interface when an unblocked security violation occurs resulting in a successful exploit.
-        </li>
-        <li>SHOULD NOT be user or developer configurable.
-        </li>
-      </ul>
-      <p>
-        If any API for configuration of policy is exposed to an application that can affect another application (such as a Device Administration API), the API MUST NOT allow configurations that break compatibility.
-      </p>
-      <p>
-        Devices MUST implement SELinux or, if using a kernel other than Linux, an equivalent mandatory access control system. Devices MUST also meet the following requirements, which are satisfied by the reference implementation in the upstream Android Open Source Project.
-      </p>
-      <p>
-        Device implementations:
-      </p>
-      <ul>
-        <li>MUST set SELinux to global enforcing mode.
-        </li>
-        <li>MUST configure all domains in enforcing mode. No permissive mode domains are allowed, including domains specific to a device/vendor.
-        </li>
-        <li>MUST NOT modify, omit, or replace the neverallow rules present within the system/sepolicy folder provided in the upstream Android Open Source Project (AOSP) and the policy MUST compile with all neverallow rules present, for both AOSP SELinux domains as well as device/vendor specific domains.
-        </li>
-        <li>MUST split the media framework into multiple processes so that it is possible to more narrowly grant access for each process as <a href="https://source.android.com/devices/media/framework-hardening.html#arch_changes">described</a> in the Android Open Source Project site.
-        </li>
-      </ul>
-      <p>
-        Device implementations SHOULD retain the default SELinux policy provided in the system/sepolicy folder of the upstream Android Open Source Project and only further add to this policy for their own device-specific configuration. Device implementations MUST be compatible with the upstream Android Open Source Project.
-      </p>
-      <p>
-        Devices MUST implement a kernel application sandboxing mechanism which allows filtering of system calls using a configurable policy from multithreaded programs. The upstream Android Open Source Project meets this requirement through enabling the seccomp-BPF with threadgroup synchronization (TSYNC) as described <a href="http://source.android.com/devices/tech/config/kernel.html#Seccomp-BPF-TSYNC">in the Kernel Configuration section of source.android.com</a> .
-      </p>
-      <h2 id="9_8_privacy">
-        9.8. Privacy
-      </h2>
-      <p>
-        If the device implements functionality in the system that captures the contents displayed on the screen and/or records the audio stream played on the device, it MUST continuously notify the user whenever this functionality is enabled and actively capturing/recording.
-      </p>
-      <p>
-        If a device implementation has a mechanism that routes network data traffic through a proxy server or VPN gateway by default (for example, preloading a VPN service with android.permission.CONTROL_VPN granted), the device implementation MUST ask for the user's consent before enabling that mechanism, unless that VPN is enabled by the Device Policy Controller via the <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#setAlwaysOnVpnPackage(android.content.ComponentName,%20java.lang.String,%20boolean)"><code>DevicePolicyManager.setAlwaysOnVpnPackage()</code></a> , in which case the user does not need to provide a separate consent, but MUST only be notified.
-      </p>
-      <p>
-        Device implementations MUST ship with an empty user-added Certificate Authority (CA) store, and MUST preinstall the same root certificates for the system-trusted CA store as <a href="https://source.android.com/security/overview/app-security.html#certificate-authorities">provided</a> in the upstream Android Open Source Project.
-      </p>
-      <p>
-        When devices are routed through a VPN, or a user root CA is installed, the implementation MUST display a warning indicating the network traffic may be monitored to the user.
-      </p>
-      <p>
-        If a device implementation has a USB port with USB peripheral mode support, it MUST present a user interface asking for the user's consent before allowing access to the contents of the shared storage over the USB port.
-      </p>
-      <h2 id="9_9_data_storage_encryption">
-        9.9. Data Storage Encryption
-      </h2>
-      <div class="note">
-        Optional for Android device implementations without a secure lock screen.
-      </div>
-      <p>
-        If the device implementation supports a secure lock screen as described in section 9.11.1, then the device MUST support data storage encryption of the application private data (/data partition), as well as the application shared storage partition (/sdcard partition) if it is a permanent, non-removable part of the device.
-      </p>
-      <p>
-        For device implementations supporting data storage encryption and with Advanced Encryption Standard (AES) crypto performance above 50MiB/sec, the data storage encryption MUST be enabled by default at the time the user has completed the out-of-box setup experience. If a device implementation is already launched on an earlier Android version with encryption disabled by default, such a device cannot meet the requirement through a system software update and thus MAY be exempted.
-      </p>
-      <p>
-        Device implementations SHOULD meet the above data storage encryption requirement via implementing <a href="https://source.android.com/security/encryption/file-based.html">File Based Encryption</a> (FBE).
-      </p>
-      <h3 id="9_9_1_direct_boot">
-        9.9.1. Direct Boot
-      </h3>
-      <p>
-        All devices MUST implement the <a href="http://developer.android.com/preview/features/direct-boot.html">Direct Boot mode</a> APIs even if they do not support Storage Encryption. In particular, the <a href="https://developer.android.com/reference/android/content/Intent.html#LOCKED_BOOT_COMPLETED">LOCKED_BOOT_COMPLETED</a> and <a href="https://developer.android.com/reference/android/content/Intent.html#ACTION_USER_UNLOCKED">ACTION_USER_UNLOCKED</a> Intents must still be broadcast to signal Direct Boot aware applications that Device Encrypted (DE) and Credential Encrypted (CE) storage locations are available for user.
-      </p>
-      <h3 id="9_9_2_file_based_encryption">
-        9.9.2. File Based Encryption
-      </h3>
-      <p>
-        Device implementations supporting FBE:
-      </p>
-      <ul>
-        <li>MUST boot up without challenging the user for credentials and allow Direct Boot aware apps to access to the Device Encrypted (DE) storage after the LOCKED_BOOT_COMPLETED message is broadcasted.
-        </li>
-        <li>MUST only allow access to Credential Encrypted (CE) storage after the user has unlocked the device by supplying their credentials (eg. passcode, pin, pattern or fingerprint) and the ACTION_USER_UNLOCKED message is broadcasted. Device implementations MUST NOT offer any method to unlock the CE protected storage without the user supplied credentials.
-        </li>
-        <li>MUST support Verified Boot and ensure that DE keys are cryptographically bound to the device's hardware root of trust.
-        </li>
-        <li>MUST support encrypting file contents using AES with a key length of 256-bits in XTS mode.
-        </li>
-        <li>MUST support encrypting file name using AES with a key length of 256-bits in CBC-CTS mode.
-        </li>
-        <li>MAY support alternative ciphers, key lengths and modes for file content and file name encryption, but MUST use the mandatorily supported ciphers, key lengths and modes by default.
-        </li>
-        <li>SHOULD make preloaded essential apps (e.g. Alarm, Phone, Messenger) Direct Boot aware.
-        </li>
-      </ul>
-      <p>
-        The keys protecting CE and DE storage areas:
-      </p>
-      <ul>
-        <li>MUST be cryptographically bound to a hardware-backed Keystore. CE keys must be bound to a user's lock screen credentials. If the user has specified no lock screen credentials then the CE keys MUST be bound to a default passcode.
-        </li>
-        <li>MUST be unique and distinct, in other words no user's CE or DE key may match any other user's CE or DE keys.
-        </li>
-      </ul>
-      <p>
-        The upstream Android Open Source project provides a preferred implementation of this feature based on the Linux kernel ext4 encryption feature.
-      </p>
-      <h3 id="9_9_3_full_disk_encryption">
-        9.9.3. Full Disk Encryption
-      </h3>
-      <p>
-        Device implementations supporting <a href="http://source.android.com/devices/tech/security/encryption/index.html">full disk encryption</a> (FDE). MUST use AES with a key of 128-bits (or greater) and a mode designed for storage (for example, AES-XTS, AES-CBC-ESSIV). The encryption key MUST NOT be written to storage at any time without being encrypted. The user MUST be provided with the possibility to AES encrypt the encryption key, except when it is in active use, with the lock screen credentials stretched using a slow stretching algorithm (e.g. PBKDF2 or scrypt). If the user has not specified a lock screen credentials or has disabled use of the passcode for encryption, the system SHOULD use a default passcode to wrap the encryption key. If the device provides a hardware-backed keystore, the password stretching algorithm MUST be cryptographically bound to that keystore. The encryption key MUST NOT be sent off the device (even when wrapped with the user passcode and/or hardware bound key). The upstream Android Open Source project provides a preferred implementation of this feature based on the Linux kernel feature dm-crypt.
-      </p>
-      <h2 id="9_10_device_integrity">
-        9.10. Device Integrity
-      </h2>
-      <p>
-        The following requirements ensures there is transparancy to the status of the device integrity.
-      </p>
-      <p>
-        Device implementations MUST correctly report through the System API method PersistentDataBlockManager.getFlashLockState() whether their bootloader state permits flashing of the system image. The <code>FLASH_LOCK_UNKNOWN</code> state is reserved for device implementations upgrading from an earlier version of Android where this new system API method did not exist.
-      </p>
-      <p>
-        Verified boot is a feature that guarantees the integrity of the device software. If a device implementation supports the feature, it MUST:
-      </p>
-      <ul>
-        <li>Declare the platform feature flag android.software.verified_boot.
-        </li>
-        <li>Perform verification on every boot sequence.
-        </li>
-        <li>Start verification from an immutable hardware key that is the root of trust and go all the way up to the system partition.
-        </li>
-        <li>Implement each stage of verification to check the integrity and authenticity of all the bytes in the next stage before executing the code in the next stage.
-        </li>
-        <li>Use verification algorithms as strong as current recommendations from NIST for hashing algorithms (SHA-256) and public key sizes (RSA-2048).
-        </li>
-        <li>MUST NOT allow boot to complete when system verification fails, unless the user consents to attempt booting anyway, in which case the data from any non-verified storage blocks MUST not be used.
-        </li>
-        <li>MUST NOT allow verified partitions on the device to be modified unless the user has explicitly unlocked the boot loader.
-        </li>
-      </ul>
-      <p>
-        The upstream Android Open Source Project provides a preferred implementation of this feature based on the Linux kernel feature dm-verity.
-      </p>
-      <p>
-        Starting from Android 6.0, device implementations with Advanced Encryption Standard (AES) crypto performance above 50 MiB/seconds MUST support verified boot for device integrity.
-      </p>
-      <p>
-        If a device implementation is already launched without supporting verified boot on an earlier version of Android, such a device can not add support for this feature with a system software update and thus are exempted from the requirement.
-      </p>
-      <h2 id="9_11_keys_and_credentials">
-        9.11. Keys and Credentials
-      </h2>
-      <p>
-        The <a href="https://developer.android.com/training/articles/keystore.html">Android Keystore System</a> allows app developers to store cryptographic keys in a container and use them in cryptographic operations through the <a href="https://developer.android.com/reference/android/security/KeyChain.html">KeyChain API</a> or the <a href="https://developer.android.com/reference/java/security/KeyStore.html">Keystore API</a> .
-      </p>
-      <p>
-        All Android device implementations MUST meet the following requirements:
-      </p>
-      <ul>
-        <li>SHOULD not limit the number of keys that can be generated, and MUST at least allow more than 8,192 keys to be imported.
-        </li>
-        <li>The lock screen authentication MUST rate limit attempts and MUST have an exponential backoff algorithm. Beyond 150 failed attempts, the delay MUST be at least 24 hours per attempt.
-        </li>
-        <li>When the device implementation supports a secure lock screen it MUST back up the keystore implementation with secure hardware and meet following requirements:
-          <ul>
-            <li>MUST have implementations of RSA, AES, ECDSA and HMAC cryptographic algorithms and MD5, SHA1, and SHA-2 family hash functions to properly support the Android Keystore system's supported algorithms in an area that is securely isolated from the code running on the kernel and above. Secure isolation MUST block all potential mechanisms by which kernel or userspace code might access the internal state of the isolated environment, including DMA. The upstream Android Open Source Project (AOSP) meets this requirement by using the <a href="https://source.android.com/security/trusty/">Trusty</a> implementation, but another ARM TrustZone-based solution or a third-party reviewed secure implementation of a proper hypervisor-based isolation are alternative options.
-            </li>
-            <li>MUST perform the lock screen authentication in the isolated execution environment and only when successful, allow the authentication-bound keys to be used. The upstream Android Open Source Project provides the <a href="http://source.android.com/devices/tech/security/authentication/gatekeeper.html">Gatekeeper Hardware Abstraction Layer (HAL)</a> and Trusty, which can be used to satisfy this requirement.
-            </li>
-          </ul>
-        </li>
-      </ul>
-      <p>
-        Note that if a device implementation is already launched on an earlier Android version, such a device is exempted from the requirement to have a hardware-backed keystore, unless it declares the <code>android.hardware.fingerprint</code> feature which requires a hardware-backed keystore.
-      </p>
-      <h3 id="9_11_1_secure_lock_screen">
-        9.11.1. Secure Lock Screen
-      </h3>
-      <p>
-        Device implementations MAY add or modify the authentication methods to unlock the lock screen, but MUST still meet the following requirements:
-      </p>
-      <ul>
-        <li>The authentication method, if based on a known secret, MUST NOT be treated as a secure lock screen unless it meets all following requirements:
-          <ul>
-            <li>The entropy of the shortest allowed length of inputs MUST be greater than 10 bits.
-            </li>
-            <li>The maximum entropy of all possible inputs MUST be greater than 18 bits.
-            </li>
-            <li>MUST not replace any of the existing authentication methods (PIN, pattern, password) implemented and provided in AOSP.
-            </li>
-            <li>MUST be disabled when the Device Policy Controller (DPC) application has set the password quality policy via the <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#setPasswordQuality%28android.content.ComponentName,%20int%29"><code>DevicePolicyManager.setPasswordQuality()</code></a> method with a more restrictive quality constant than <code>PASSWORD_QUALITY_SOMETHING</code> .
-            </li>
-          </ul>
-        </li>
-        <li>The authenticaion method, if based on a physical token or the location, MUST NOT be treated as a secure lock screen unless it meets all following requirements:
-          <ul>
-            <li>It MUST have a fall-back mechanism to use one of the primary authentication methods which is based on a known secret and meets the requirements to be treated as a secure lock screen.
-            </li>
-            <li>It MUST be disabled and only allow the primary authentication to unlock the screen when the Device Policy Controller (DPC) application has set the policy with either the <a href="http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#setKeyguardDisabledFeatures%28android.content.ComponentName,%20int%29"><code>DevicePolicyManager.setKeyguardDisabledFeatures(KEYGUARD_DISABLE_TRUST_AGENTS)</code></a> method or the <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#setPasswordQuality%28android.content.ComponentName,%20int%29"><code>DevicePolicyManager.setPasswordQuality()</code></a> method with a more restrictive quality constant than <code>PASSWORD_QUALITY_UNSPECIFIED</code> .
-            </li>
-          </ul>
-        </li>
-        <li>The authentication method, if based on biometrics, MUST NOT be treated as a secure lock screen unless it meets all following requirements:
-          <ul>
-            <li>It MUST have a fall-back mechanism to use one of the primary authentication methods which is based on a known secret and meets the requirements to be treated as a secure lock screen.
-            </li>
-            <li>It MUST be disabled and only allow the primary authentication to unlock the screen when the Device Policy Controller (DPC) application has set the keguard feature policy by calling the method <a href="http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#setKeyguardDisabledFeatures%28android.content.ComponentName,%20int%29"><code>DevicePolicyManager.setKeyguardDisabledFeatures(KEYGUARD_DISABLE_FINGERPRINT)</code></a> .
-            </li>
-            <li>It MUST have a false acceptance rate that is equal or stronger than what is required for a fingerprint sensor as described in section 7.3.10, or otherwise MUST be disabled and only allow the primary authentication to unlock the screen when the Device Policy Controller (DPC) application has set the password quality policy via the <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#setPasswordQuality%28android.content.ComponentName,%20int%29"><code>DevicePolicyManager.setPasswordQuality()</code></a> method with a more restrictive quality constant than <code>PASSWORD_QUALITY_BIOMETRIC_WEAK</code> .
-            </li>
-          </ul>
-        </li>
-        <li>If the authentication method can not be treated as a secure lock screen, it:
-          <ul>
-            <li>MUST return <code>false</code> for both the <a href="http://developer.android.com/reference/android/app/KeyguardManager.html#isKeyguardSecure%28%29"><code>KeyguardManager.isKeyguardSecure()</code></a> and the <a href="https://developer.android.com/reference/android/app/KeyguardManager.html#isDeviceSecure%28%29"><code>KeyguardManager.isDeviceSecure()</code></a> methods.
-            </li>
-            <li>MUST be disabled when the Device Policy Controller (DPC) application has set the password quality policy via the <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#setPasswordQuality%28android.content.ComponentName,%20int%29"><code>DevicePolicyManager.setPasswordQuality()</code></a> method with a more restrictive quality constant than <code>PASSWORD_QUALITY_UNSPECIFIED</code> .
-            </li>
-            <li>MUST NOT reset the password expiration timers set by <a href="http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#setPasswordExpirationTimeout%28android.content.ComponentName,%20long%29"><code>DevicePolicyManager.setPasswordExpirationTimeout()</code></a> .
-            </li>
-            <li>MUST NOT authenticate access to keystores if the application has called <a href="https://developer.android.com/reference/android/security/keystore/KeyGenParameterSpec.Builder.html#setUserAuthenticationRequired%28boolean%29"><code>KeyGenParameterSpec.Builder.setUserAuthenticationRequired(true)</code></a> ).
-            </li>
-          </ul>
-        </li>
-        <li>If the authentication method is based on a physical token, the location, or biometrics that has higher false acceptance rate than what is required for fingerprint sensors as described in section 7.3.10, then it:
-          <ul>
-            <li>MUST NOT reset the password expiration timers set by <a href="http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#setPasswordExpirationTimeout%28android.content.ComponentName,%20long%29"><code>DevicePolicyManager.setPasswordExpirationTimeout()</code></a> .
-            </li>
-            <li>MUST NOT authenticate access to keystores if the application has called <a href="https://developer.android.com/reference/android/security/keystore/KeyGenParameterSpec.Builder.html#setUserAuthenticationRequired%28boolean%29"><code>KeyGenParameterSpec.Builder.setUserAuthenticationRequired(true)</code></a> .
-            </li>
-          </ul>
-        </li>
-      </ul>
-      <h2 id="9_12_data_deletion">
-        9.12. Data Deletion
-      </h2>
-      <p>
-        Devices MUST provide users with a mechanism to perform a "Factory Data Reset" that allows logical and physical deletion of all data except for the following:
-      </p>
-      <ul>
-        <li>The system image
-        </li>
-        <li>Any operating system files required by the system image
-        </li>
-      </ul>
-      <p>
-        All user-generated data MUST be deleted. This MUST satisfy relevant industry standards for data deletion such as NIST SP800-88. This MUST be used for the implementation of the wipeData() API (part of the Android Device Administration API) described in <a href="#3_9_device_administration">section 3.9 Device Administration</a> .
-      </p>
-      <p>
-        Devices MAY provide a fast data wipe that conducts a logical data erase.
-      </p>
-      <h2 id="9_13_safe_boot_mode">
-        9.13. Safe Boot Mode
-      </h2>
-      <p>
-        Android provides a mode enabling users to boot up into a mode where only preinstalled system apps are allowed to run and all third-party apps are disabled. This mode, known as "Safe Boot Mode", provides the user the capability to uninstall potentially harmful third-party apps.
-      </p>
-      <p>
-        Android device implementations are STRONGLY RECOMENDED to implement Safe Boot Mode and meet following requirements:
-      </p>
-      <ul>
-        <li>
-          <p>
-            Device implementations SHOULD provide the user an option to enter Safe Boot Mode from the boot menu which is reachable through a workflow that is different from that of normal boot.
-          </p>
-        </li>
-        <li>
-          <p>
-            Device implementations MUST provide the user an option to enter Safe Boot Mode in such a way that is uninterruptible from third-party apps installed on the device, except for when the third party app is a Device Policy Controller and has set the <a href="https://developer.android.com/reference/android/os/UserManager.html#DISALLOW_SAFE_BOOT"><code>UserManager.DISALLOW_SAFE_BOOT</code></a> flag as true.
-          </p>
-        </li>
-        <li>
-          <p>
-            Device implementations MUST provide the user the capability to uninstall any third-party apps within Safe Mode.
-          </p>
-        </li>
-      </ul>
-      <h2 id="9_14_automotive_vehicle_system_isolation">
-        9.14. Automotive Vehicle System Isolation
-      </h2>
-      <p>
-        Android Automotive devices are expected to exchange data with critical vehicle subsystems, e.g., by using the <a href="http://source.android.com/devices/automotive.html">vehicle HAL</a> to send and receive messages over vehicle networks such as CAN bus. Android Automotive device implementations MUST implement security features below the Android framework layers to prevent malicious or unintentional interaction between the Android framework or third-party apps and vehicle subsystems. These security features are as follows:
-      </p>
-      <ul>
-        <li>Gatekeeping messages from Android framework vehicle subsystems, e.g., whitelisting permitted message types and message sources.
-        </li>
-        <li>Watchdog against denial of service attacks from the Android framework or third-party apps. This guards against malicious software flooding the vehicle network with traffic, which may lead to malfunctioning vehicle subsystems.
-        </li>
-      </ul>
-      <h1 id="10_software_compatibility_testing">
-        10. Software Compatibility Testing
-      </h1>
-      <p>
-        Device implementations MUST pass all tests described in this section.
-      </p>
-      <p>
-        However, note that no software test package is fully comprehensive. For this reason, device implementers are <strong>STRONGLY RECOMMENDED</strong> to make the minimum number of changes as possible to the reference and preferred implementation of Android available from the Android Open Source Project. This will minimize the risk of introducing bugs that create incompatibilities requiring rework and potential device updates.
-      </p>
-      <h2 id="10_1_compatibility_test_suite">
-        10.1. Compatibility Test Suite
-      </h2>
-      <p>
-        Device implementations MUST pass the <a href="http://source.android.com/compatibility/index.html">Android Compatibility Test Suite (CTS)</a> available from the Android Open Source Project, using the final shipping software on the device. Additionally, device implementers SHOULD use the reference implementation in the Android Open Source tree as much as possible, and MUST ensure compatibility in cases of ambiguity in CTS and for any reimplementations of parts of the reference source code.
-      </p>
-      <p>
-        The CTS is designed to be run on an actual device. Like any software, the CTS may itself contain bugs. The CTS will be versioned independently of this Compatibility Definition, and multiple revisions of the CTS may be released for Android 7.1. Device implementations MUST pass the latest CTS version available at the time the device software is completed.
-      </p>
-      <h2 id="10_2_cts_verifier">
-        10.2. CTS Verifier
-      </h2>
-      <p>
-        Device implementations MUST correctly execute all applicable cases in the CTS Verifier. The CTS Verifier is included with the Compatibility Test Suite, and is intended to be run by a human operator to test functionality that cannot be tested by an automated system, such as correct functioning of a camera and sensors.
-      </p>
-      <p>
-        The CTS Verifier has tests for many kinds of hardware, including some hardware that is optional. Device implementations MUST pass all tests for hardware that they possess; for instance, if a device possesses an accelerometer, it MUST correctly execute the Accelerometer test case in the CTS Verifier. Test cases for features noted as optional by this Compatibility Definition Document MAY be skipped or omitted.
-      </p>
-      <p>
-        Every device and every build MUST correctly run the CTS Verifier, as noted above. However, since many builds are very similar, device implementers are not expected to explicitly run the CTS Verifier on builds that differ only in trivial ways. Specifically, device implementations that differ from an implementation that has passed the CTS Verifier only by the set of included locales, branding, etc. MAY omit the CTS Verifier test.
-      </p>
-      <h1 id="11_updatable_software">
-        11. Updatable Software
-      </h1>
-      <p>
-        Device implementations MUST include a mechanism to replace the entirety of the system software. The mechanism need not perform “live” upgrades—that is, a device restart MAY be required.
-      </p>
-      <p>
-        Any method can be used, provided that it can replace the entirety of the software preinstalled on the device. For instance, any of the following approaches will satisfy this requirement:
-      </p>
-      <ul>
-        <li>“Over-the-air (OTA)” downloads with offline update via reboot.
-        </li>
-        <li>“Tethered” updates over USB from a host PC.
-        </li>
-        <li>“Offline” updates via a reboot and update from a file on removable storage.
-        </li>
-      </ul>
-      <p>
-        However, if the device implementation includes support for an unmetered data connection such as 802.11 or Bluetooth PAN (Personal Area Network) profile, it MUST support OTA downloads with offline update via reboot.
-      </p>
-      <p>
-        The update mechanism used MUST support updates without wiping user data. That is, the update mechanism MUST preserve application private data and application shared data. Note that the upstream Android software includes an update mechanism that satisfies this requirement.
-      </p>
-      <p>
-        For device implementations that are launching with Android 6.0 and later, the update mechanism SHOULD support verifying that the system image is binary identical to expected result following an OTA. The block-based OTA implementation in the upstream Android Open Source Project, added since Android 5.1, satisfies this requirement.
-      </p>
-      <p>
-        Also, device implementations SHOULD support <a href="https://source.android.com/devices/tech/ota/ab_updates.html">A/B system updates</a> . The AOSP implements this feature using the boot control HAL.
-      </p>
-      <p>
-        If an error is found in a device implementation after it has been released but within its reasonable product lifetime that is determined in consultation with the Android Compatibility Team to affect the compatibility of third-party applications, the device implementer MUST correct the error via a software update available that can be applied per the mechanism just described.
-      </p>
-      <p>
-        Android includes features that allow the Device Owner app (if present) to control the installation of system updates. To facilitate this, the system update subsystem for devices that report android.software.device_admin MUST implement the behavior described in the <a href="http://developer.android.com/reference/android/app/admin/SystemUpdatePolicy.html">SystemUpdatePolicy</a> class.
-      </p>
-      <h1 id="12_document_changelog">
-        12. Document Changelog
-      </h1>
-      <p>
-        For a summary of changes to the Compatibility Definition in this release:
-      </p>
-      <ul>
-        <li>
-          <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/nougat-mr1-dev/?pretty=full&amp;no-merges">Document changelog</a>
-        </li>
-      </ul>
-      <p>
-        For a summary of changes to individuals sections:
-      </p>
-      <ol>
-        <li>
-          <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/nougat-mr1-dev/1_introduction?pretty=full&amp;no-merges">Introduction</a>
-        </li>
-        <li>
-          <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/nougat-mr1-dev/2_device_types?pretty=full&amp;no-merges">Device Types</a>
-        </li>
-        <li>
-          <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/nougat-mr1-dev/3_software?pretty=full&amp;no-merges">Software</a>
-        </li>
-        <li>
-          <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/nougat-mr1-dev/4_application-packaging?pretty=full&amp;no-merges">Application Packaging</a>
-        </li>
-        <li>
-          <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/nougat-mr1-dev/5_multimedia?pretty=full&amp;no-merges">Multimedia</a>
-        </li>
-        <li>
-          <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/nougat-mr1-dev/6_dev-tools-and-options?pretty=full&amp;no-merges">Developer Tools and Options</a>
-        </li>
-        <li>
-          <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/nougat-mr1-dev/7_hardware-compatibility?pretty=full&amp;no-merges">Hardware Compatibility</a>
-        </li>
-        <li>
-          <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/nougat-mr1-dev/8_performance-and-power?pretty=full&amp;no-merges">Performance and Power</a>
-        </li>
-        <li>
-          <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/nougat-mr1-dev/9_security-model?pretty=full&amp;no-merges">Security Model</a>
-        </li>
-        <li>
-          <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/nougat-mr1-dev/10_software-compatibility-testing?pretty=full&amp;no-merges">Software Compatibility Testing</a>
-        </li>
-        <li>
-          <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/nougat-mr1-dev/11_updatable-software?pretty=full&amp;no-merges">Updatable Software</a>
-        </li>
-        <li>
-          <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/nougat-mr1-dev/12_document-changelog?pretty=full&amp;no-merges">Document Changelog</a>
-        </li>
-        <li>
-          <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/nougat-mr1-dev/13_contact-us?pretty=full&amp;no-merges">Contact Us</a>
-        </li>
-      </ol>
-      <h2 id="12_1_changelog_viewing_tips">
-        12.1. Changelog Viewing Tips
-      </h2>
-      <p>
-        Changes are marked as follows:
-      </p>
-      <ul>
-        <li>
-          <p>
-            <strong>CDD</strong><br />
-            Substantive changes to the compatibility requirements.
-          </p>
-        </li>
-        <li>
-          <p>
-            <strong>Docs</strong><br />
-            Cosmetic or build related changes.
-          </p>
-        </li>
-      </ul>
-      <p>
-        For best viewing, append the <code>pretty=full</code> and <code>no-merges</code> URL parameters to your changelog URLs.
-      </p>
-      <h1 id="13_contact_us">
-        13. Contact Us
-      </h1>
-      <p>
-        You can join the <a href="https://groups.google.com/forum/#!forum/android-compatibility">android-compatibility forum</a> and ask for clarifications or bring up any issues that you think the document does not cover.
-      </p>
-    </div>
-  </body>
-</html>
diff --git a/en/compatibility/android-cdd.html b/en/compatibility/android-cdd.html
index 3509896..30b613d 100644
--- a/en/compatibility/android-cdd.html
+++ b/en/compatibility/android-cdd.html
@@ -1,11 +1,13 @@
-<html devsite>
+<html devsite="" xmlns="http://www.w3.org/1999/xhtml">
   <head>
-    <title>Android 7.1 Compatibility Definition</title>
+    <title>
+      Android 8.0 Compatibility Definition
+    </title>
     <meta name="project_path" value="/_project.yaml" />
     <meta name="book_path" value="/_book.yaml" />
   </head>
   <body>
-  <!--
+    <!--
       Copyright 2017 The Android Open Source Project
 
       Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,11392 +22,9412 @@
       See the License for the specific language governing permissions and
       limitations under the License.
   -->
-
-<body>
- <h2 id="1_introduction">
-  1. Introduction
- </h2>
- <p>
-  This document enumerates the requirements that must be met in order for devices
-to be compatible with Android 7.1.
- </p>
- <p>
-  The use of &ldquo;MUST&rdquo;, &ldquo;MUST NOT&rdquo;, &ldquo;REQUIRED&rdquo;, &ldquo;SHALL&rdquo;, &ldquo;SHALL NOT&rdquo;, &ldquo;SHOULD&rdquo;,
-&ldquo;SHOULD NOT&rdquo;, &ldquo;RECOMMENDED&rdquo;, &ldquo;MAY&rdquo;, and &ldquo;OPTIONAL&rdquo; is per the IETF standard
-defined in
-  <a href="http://www.ietf.org/rfc/rfc2119.txt">
-   RFC2119
-  </a>.
- </p>
- <p>
-  As used in this document, a &ldquo;device implementer&rdquo; or &ldquo;implementer&rdquo; is a person
-or organization developing a hardware/software solution running Android
-7.1. A &ldquo;device implementation&rdquo; or &ldquo;implementation is the
-hardware/software solution so developed.
- </p>
- <p>
-  To be considered compatible with Android 7.1, device
-implementations MUST meet the requirements presented in this Compatibility
-Definition, including any documents incorporated via reference.
- </p>
- <p>
-  Where this definition or the software tests described in
-  <a href="#10_software_compatibility_testing">
-   section
-10
-  </a>
-  is silent, ambiguous, or incomplete, it
-is the responsibility of the device implementer to ensure compatibility with
-existing implementations.
- </p>
- <p>
-  For this reason, the
-  <a href="http://source.android.com/">
-   Android Open Source Project
-  </a>
-  is both the reference and preferred implementation of Android. Device
-implementers are STRONGLY RECOMMENDED to base their implementations to the
-greatest extent possible on the &ldquo;upstream&rdquo; source code available from the
-Android Open Source Project. While some components can hypothetically be
-replaced with alternate implementations, it is STRONGLY RECOMMENDED to not
-follow this practice, as passing the software tests will become substantially
-more difficult. It is the implementer&rsquo;s responsibility to ensure full
-behavioral compatibility with the standard Android implementation, including
-and beyond the Compatibility Test Suite. Finally, note that certain component
-substitutions and modifications are explicitly forbidden by this document.
- </p>
- <p>
-  Many of the resources linked to in this document are derived directly or
-indirectly from the Android SDK and will be functionally identical to the
-information in that SDK&rsquo;s documentation. In any cases where this Compatibility
-Definition or the Compatibility Test Suite disagrees with the SDK
-documentation, the SDK documentation is considered authoritative. Any technical
-details provided in the linked resources throughout this document are
-considered by inclusion to be part of this Compatibility Definition.
- </p>
- <h2 id="2_device_types">
-  2. Device Types
- </h2>
- <p>
-  While the Android Open Source Project has been used in the implementation of a
-variety of device types and form factors, many aspects of the architecture and
-compatibility requirements were optimized for handheld devices. Starting from
-Android 5.0, the Android Open Source Project aims to embrace a wider variety of
-device types as described in this section.
- </p>
- <p>
-  <strong>
-   Android Handheld device
-  </strong>
-  refers to an Android device implementation that is
-typically used by holding it in the hand, such as mp3 players, phones, and
-tablets. Android Handheld device implementations:
- </p>
- <ul>
-  <li>
-   MUST have a touchscreen embedded in the device.
-  </li>
-  <li>
-   MUST have a power source that provides mobility, such as a battery.
-  </li>
- </ul>
- <p>
-  <strong>
-   Android Television device
-  </strong>
-  refers to an Android device implementation that
-is an entertainment interface for consuming digital media, movies, games, apps,
-and/or live TV for users sitting about ten feet away (a &ldquo;lean back&rdquo; or &ldquo;10-foot
-user interface&rdquo;). Android Television devices:
- </p>
- <ul>
-  <li>
-   MUST have an embedded screen OR include a video output port, such as VGA,
-    HDMI, or a wireless port for display.
-  </li>
-  <li>
-   MUST declare the features
-   <a href="http://developer.android.com/reference/android/content/pm/PackageManager.html#FEATURE_LEANBACK">
-    android.software.leanback
-   </a>
-   and android.hardware.type.television.
-  </li>
- </ul>
- <p>
-  <strong>
-   Android Watch device
-  </strong>
-  refers to an Android device implementation intended to
-be worn on the body, perhaps on the wrist, and:
- </p>
- <ul>
-  <li>
-   MUST have a screen with the physical diagonal length in the range from 1.1
-    to 2.5 inches.
-  </li>
-  <li>
-   MUST declare the feature android.hardware.type.watch.
-  </li>
-  <li>
-   MUST support uiMode =
-   <a href="http://developer.android.com/reference/android/content/res/Configuration.html#UI_MODE_TYPE_WATCH">
-    UI_MODE_TYPE_WATCH
-   </a>.
-  </li>
- </ul>
- <p>
-  <strong>
-   Android Automotive implementation
-  </strong>
-  refers to a vehicle head unit running
-Android as an operating system for part or all of the system and/or
-infotainment functionality. Android Automotive implementations:
- </p>
- <ul>
-  <li>
-   MUST have a screen with the physical diagonal length equal to or greater
-    than 6 inches.
-  </li>
-  <li>
-   MUST declare the feature android.hardware.type.automotive.
-  </li>
-  <li>
-   MUST support uiMode =
-   <a href="http://developer.android.com/reference/android/content/res/Configuration.html#UI_MODE_TYPE_CAR">
-    UI_MODE_TYPE_CAR
-   </a>.
-  </li>
-  <li>
-   Android Automotive implementations MUST support all public APIs in the
-   <code>
-    android.car.*
-   </code>
-   namespace.
-  </li>
- </ul>
- <p>
-  All Android device implementations that do not fit into any of the above device
-types still MUST meet all requirements in this document to be Android
-7.1 compatible, unless the requirement is explicitly described to
-be only applicable to a specific Android device type from above.
- </p>
- <h3 id="2_1_device_configurations">
-  2.1 Device Configurations
- </h3>
- <p>
-  This is a summary of major differences in hardware configuration by device
-type. (Empty cells denote a &ldquo;MAY&rdquo;). Not all configurations are covered in this
-table; see relevant hardware sections for more detail.
- </p>
- <table>
-  <tr>
-   <th>
-    Category
-   </th>
-   <th>
-    Feature
-   </th>
-   <th>
-    Section
-   </th>
-   <th>
-    Handheld
-   </th>
-   <th>
-    Television
-   </th>
-   <th>
-    Watch
-   </th>
-   <th>
-    Automotive
-   </th>
-   <th>
-    Other
-   </th>
-  </tr>
-  <tr>
-   <td rowspan="3">
-    Input
-   </td>
-   <td>
-    D-pad
-   </td>
-   <td>
-    <a href="#7_2_2_non-touch-navigation">
-     7.2.2. Non-touch Navigation
-    </a>
-   </td>
-   <td>
-   </td>
-   <td>
-    MUST
-   </td>
-   <td>
-   </td>
-   <td>
-   </td>
-   <td>
-   </td>
-  </tr>
-  <tr>
-   <td>
-    Touchscreen
-   </td>
-   <td>
-    <a href="#7_2_4_touchscreen_input">
-     7.2.4. Touchscreen input
-    </a>
-   </td>
-   <td>
-    MUST
-   </td>
-   <td>
-   </td>
-   <td>
-    MUST
-   </td>
-   <td>
-   </td>
-   <td>
-    SHOULD
-   </td>
-  </tr>
-  <tr>
-   <td>
-    Microphone
-   </td>
-   <td>
-    <a href="#7_8_1_microphone">
-     7.8.1. Microphone
-    </a>
-   </td>
-   <td>
-    MUST
-   </td>
-   <td>
-    SHOULD
-   </td>
-   <td>
-    MUST
-   </td>
-   <td>
-    MUST
-   </td>
-   <td>
-    SHOULD
-   </td>
-  </tr>
-  <tr>
-   <td rowspan="2">
-    Sensors
-   </td>
-   <td>
-    Accelerometer
-   </td>
-   <td>
-    <a href="#7_3_1_accelerometer">
-     7.3.1 Accelerometer
-    </a>
-   </td>
-   <td>
-    SHOULD
-   </td>
-   <td>
-   </td>
-   <td>
-    SHOULD
-   </td>
-   <td>
-   </td>
-   <td>
-    SHOULD
-   </td>
-  </tr>
-  <tr>
-   <td>
-    GPS
-   </td>
-   <td>
-    <a href="#7_3_3_gps">
-     7.3.3. GPS
-    </a>
-   </td>
-   <td>
-    SHOULD
-   </td>
-   <td>
-   </td>
-   <td>
-   </td>
-   <td>
-    SHOULD
-   </td>
-   <td>
-   </td>
-  </tr>
-  <tr>
-   <td rowspan="6">
-    Connectivity
-   </td>
-   <td>
-    Wi-Fi
-   </td>
-   <td>
-    <a href="#7_4_2_ieee_802.11">
-     7.4.2. IEEE 802.11
-    </a>
-   </td>
-   <td>
-    SHOULD
-   </td>
-   <td>
-    SHOULD
-   </td>
-   <td>
-   </td>
-   <td>
-    SHOULD
-   </td>
-   <td>
-    SHOULD
-   </td>
-  </tr>
-  <tr>
-   <td>
-    Wi-Fi Direct
-   </td>
-   <td>
-    <a href="#7_4_2_1_wi-fi-direct">
-     7.4.2.1. Wi-Fi Direct
-    </a>
-   </td>
-   <td>
-    SHOULD
-   </td>
-   <td>
-    SHOULD
-   </td>
-   <td>
-   </td>
-   <td>
-   </td>
-   <td>
-    SHOULD
-   </td>
-  </tr>
-  <tr>
-   <td>
-    Bluetooth
-   </td>
-   <td>
-    <a href="#7_4_3_bluetooth">
-     7.4.3. Bluetooth
-    </a>
-   </td>
-   <td>
-    SHOULD
-   </td>
-   <td>
-    MUST
-   </td>
-   <td>
-    MUST
-   </td>
-   <td>
-    MUST
-   </td>
-   <td>
-    SHOULD
-   </td>
-  </tr>
-  <tr>
-   <td>
-    Bluetooth Low Energy
-   </td>
-   <td>
-    <a href="#7_4_3_bluetooth">
-     7.4.3. Bluetooth
-    </a>
-   </td>
-   <td>
-    SHOULD
-   </td>
-   <td>
-    MUST
-   </td>
-   <td>
-    SHOULD
-   </td>
-   <td>
-    SHOULD
-   </td>
-   <td>
-    SHOULD
-   </td>
-  </tr>
-  <tr>
-   <td>
-    Cellular radio
-   </td>
-   <td>
-    <a href="#7_4_5_minimum_network_capability">
-     7.4.5. Minimum Network Capability
-    </a>
-   </td>
-   <td>
-   </td>
-   <td>
-   </td>
-   <td>
-   </td>
-   <td>
-    SHOULD
-   </td>
-   <td>
-   </td>
-  </tr>
-  <tr>
-   <td>
-    USB peripheral/host mode
-   </td>
-   <td>
-    <a href="#7_7_usb">
-     7.7. USB
-    </a>
-   </td>
-   <td>
-    SHOULD
-   </td>
-   <td>
-   </td>
-   <td>
-   </td>
-   <td>
-    SHOULD
-   </td>
-   <td>
-    SHOULD
-   </td>
-  </tr>
-  <tr>
-   <td>
-    Output
-   </td>
-   <td>
-    Speaker and/or Audio output ports
-   </td>
-   <td>
-    <a href="#7_8_2_audio_output">
-     7.8.2. Audio Output
-    </a>
-   </td>
-   <td>
-    MUST
-   </td>
-   <td>
-    MUST
-   </td>
-   <td>
-   </td>
-   <td>
-    MUST
-   </td>
-   <td>
-    MUST
-   </td>
-  </tr>
- </table>
- <h2 id="3_software">
-  3. Software
- </h2>
- <h3 id="3_1_managed_api_compatibility">
-  3.1. Managed API Compatibility
- </h3>
- <p>
-  The managed Dalvik bytecode execution environment is the primary vehicle for
-Android applications. The Android application programming interface (API) is the
-set of Android platform interfaces exposed to applications running in the
-managed runtime environment. Device implementations MUST provide complete
-implementations, including all documented behaviors, of any documented API
-exposed by the
-  <a href="http://developer.android.com/reference/packages.html">
-   Android SDK
-  </a>
-  or any API decorated with the &ldquo;@SystemApi&rdquo; marker in the upstream Android source code.
- </p>
- <p>
-  Device implementations MUST support/preserve all classes, methods, and
-associated elements marked by the TestApi annotation (@TestApi).
- </p>
- <p>
-  Device implementations MUST NOT omit any managed APIs, alter API interfaces or
-signatures, deviate from the documented behavior, or include no-ops, except
-where specifically allowed by this Compatibility Definition.
- </p>
- <p>
-  This Compatibility Definition permits some types of hardware for which Android
-includes APIs to be omitted by device implementations. In such cases, the APIs
-MUST still be present and behave in a reasonable way. See
-  <a href="#7_hardware_compatibility">
-   section 7
-  </a>
-  for specific requirements for this scenario.
- </p>
- <h3 id="3_1_1_android_extensions">
-  3.1.1. Android Extensions
- </h3>
- <p>
-  Android includes the support of extending the managed APIs while keeping the same API
-level version. Android device implementations MUST preload the AOSP implementation
-of both the shared library
-  <code>
-   ExtShared
-  </code>
-  and services
-  <code>
-   ExtServices
-  </code>
-  with versions higher
-than or equal to the minimum versions allowed per each API level.
-For example, Android 7.0 device implementations, running API level 24 MUST include
-at least version 1.
- </p>
- <h3 id="3_2_soft_api_compatibility">
-  3.2. Soft API Compatibility
- </h3>
- <p>
-  In addition to the managed APIs from
-  <a href="#3_1_managed_api_compatibility">
-   section 3.1
-  </a>,
-Android also includes a significant runtime-only &ldquo;soft&rdquo; API, in the form of such
-things as intents, permissions, and similar aspects of Android applications that
-cannot be enforced at application compile time.
- </p>
- <h4 id="3_2_1_permissions">
-  3.2.1. Permissions
- </h4>
- <p>
-  Device implementers MUST support and enforce all permission constants as
-documented by the
-  <a href="http://developer.android.com/reference/android/Manifest.permission.html">
-   Permission reference page
-  </a>.
-Note that
-  <a href="#9_security_model_compatibility">
-   section 9
-  </a>
-  lists additional
-requirements related to the Android security model.
- </p>
- <h4 id="3_2_2_build_parameters">
-  3.2.2. Build Parameters
- </h4>
- <p>
-  The Android APIs include a number of constants on the
-  <a href="http://developer.android.com/reference/android/os/Build.html">
-   android.os.Build class
-  </a>
-  that are intended to describe the current device. To provide consistent,
-meaningful values across device implementations, the table below includes
-additional restrictions on the formats of these values to which device
-implementations MUST conform.
- </p>
- <table>
-  <tr>
-   <th>
-    Parameter
-   </th>
-   <th>
-    Details
-   </th>
-  </tr>
-  <tr>
-   <td>
-    VERSION.RELEASE
-   </td>
-   <td>
-    The version of the currently-executing Android system, in human-readable
-    format. This field MUST have one of the string values defined in
-    <a href="http://source.android.com/compatibility/7.1/versions.html">
-     7.1
-    </a>.
-   </td>
-  </tr>
-  <tr>
-   <td>
-    VERSION.SDK
-   </td>
-   <td>
-    The version of the currently-executing Android system, in a format
-    accessible to third-party application code. For Android 7.1,
-    this field MUST have the integer value 7.1_INT.
-   </td>
-  </tr>
-  <tr>
-   <td>
-    VERSION.SDK_INT
-   </td>
-   <td>
-    The version of the currently-executing Android system, in a format
-    accessible to third-party application code. For Android 7.1,
-    this field MUST have the integer value 7.1_INT.
-   </td>
-  </tr>
-  <tr>
-   <td>
-    VERSION.INCREMENTAL
-   </td>
-   <td>
-    A value chosen by the device implementer designating the specific build
-    of the currently-executing Android system, in human-readable format. This
-    value MUST NOT be reused for different builds made available to end users. A
-    typical use of this field is to indicate which build number or
-    source-control change identifier was used to generate the build. There are
-    no requirements on the specific format of this field, except that it MUST
-    NOT be null or the empty string ("").
-   </td>
-  </tr>
-  <tr>
-   <td>
-    BOARD
-   </td>
-   <td>
-    A value chosen by the device implementer identifying the specific
-    internal hardware used by the device, in human-readable format. A possible
-    use of this field is to indicate the specific revision of the board powering
-    the device. The value of this field MUST be encodable as 7-bit ASCII and
-    match the regular expression &ldquo;^[a-zA-Z0-9_-]+$&rdquo;.
-   </td>
-  </tr>
-  <tr>
-   <td>
-    BRAND
-   </td>
-   <td>
-    A value reflecting the brand name associated with the device as known to
-    the end users. MUST be in human-readable format and SHOULD represent the
-    manufacturer of the device or the company brand under which the device is
-    marketed. The value of this field MUST be encodable as 7-bit ASCII and match
-    the regular expression &ldquo;^[a-zA-Z0-9_-]+$&rdquo;.
-   </td>
-  </tr>
-  <tr>
-   <td>
-    SUPPORTED_ABIS
-   </td>
-   <td>
-    The name of the instruction set (CPU type + ABI convention) of native
-    code. See
-    <a href="#3_3_native_api_compatibility">
-     section 3.3. Native API
-    Compatibility
-    </a>.
-   </td>
-  </tr>
-  <tr>
-   <td>
-    SUPPORTED_32_BIT_ABIS
-   </td>
-   <td>
-    The name of the instruction set (CPU type + ABI convention) of native
-    code. See
-    <a href="#3_3_native_api_compatibility">
-     section 3.3. Native API
-    Compatibility
-    </a>.
-   </td>
-  </tr>
-  <tr>
-   <td>
-    SUPPORTED_64_BIT_ABIS
-   </td>
-   <td>
-    The name of the second instruction set (CPU type + ABI convention) of
-    native code. See
-    <a href="#3_3_native_api_compatibility">
-     section 3.3. Native
-    API Compatibility
-    </a>.
-   </td>
-  </tr>
-  <tr>
-   <td>
-    CPU_ABI
-   </td>
-   <td>
-    The name of the instruction set (CPU type + ABI convention) of native
-    code. See
-    <a href="#3_3_native_api_compatibility">
-     section 3.3. Native API
-    Compatibility
-    </a>.
-   </td>
-  </tr>
-  <tr>
-   <td>
-    CPU_ABI2
-   </td>
-   <td>
-    The name of the second instruction set (CPU type + ABI convention) of
-    native code. See
-    <a href="#3_3_native_api_compatibility">
-     section 3.3. Native
-    API Compatibility
-    </a>.
-   </td>
-  </tr>
-  <tr>
-   <td>
-    DEVICE
-   </td>
-   <td>
-    A value chosen by the device implementer containing the development name
-    or code name identifying the configuration of the hardware features and
-    industrial design of the device. The value of this field MUST be encodable
-    as 7-bit ASCII and match the regular expression
-    &ldquo;^[a-zA-Z0-9_-]+$&rdquo;. This device name MUST NOT change during the
-    lifetime of the product.
-   </td>
-  </tr>
-  <tr>
-   <td>
-    FINGERPRINT
-   </td>
-   <td>
-    A string that uniquely identifies this build. It SHOULD be reasonably
-    human-readable. It MUST follow this template:
-    <p class="small">
-     $(BRAND)/$(PRODUCT)/
-     <br/>
-     &nbsp;&nbsp;&nbsp;&nbsp;$(DEVICE):$(VERSION.RELEASE)/$(ID)/$(VERSION.INCREMENTAL):$(TYPE)/$(TAGS)
+    <h2 id="1_introduction">
+      1. Introduction
+    </h2>
+    <p>
+      This document enumerates the requirements that must be met in order for devices to be compatible with Android 8.0.
     </p>
     <p>
-     For example:
-    </p>
-    <p class="small">
-     acme/myproduct/
-     <br/>
-     &nbsp;&nbsp;&nbsp;&nbsp;mydevice:7.1/LMYXX/3359:userdebug/test-keys
+      The use of “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” is per the IETF standard defined in <a href="http://www.ietf.org/rfc/rfc2119.txt">RFC2119</a>.
     </p>
     <p>
-     The fingerprint MUST NOT include whitespace characters. If other fields
-      included in the template above have whitespace characters, they MUST be
-      replaced in the build fingerprint with another character, such as the
-      underscore ("_") character. The value of this field MUST be encodable as
-      7-bit ASCII.
+      As used in this document, a “device implementer” or “implementer” is a person or organization developing a hardware/software solution running Android 8.0. A “device implementation” or “implementation is the hardware/software solution so developed.
     </p>
-   </td>
-  </tr>
-  <tr>
-   <td>
-    HARDWARE
-   </td>
-   <td>
-    The name of the hardware (from the kernel command line or /proc). It
-    SHOULD be reasonably human-readable. The value of this field MUST be
-    encodable as 7-bit ASCII and match the regular expression
-    &ldquo;^[a-zA-Z0-9_-]+$&rdquo;.
-   </td>
-  </tr>
-  <tr>
-   <td>
-    HOST
-   </td>
-   <td>
-    A string that uniquely identifies the host the build was built on, in
-    human-readable format. There are no requirements on the specific format of
-    this field, except that it MUST NOT be null or the empty string ("").
-   </td>
-  </tr>
-  <tr>
-   <td>
-    ID
-   </td>
-   <td>
-    An identifier chosen by the device implementer to refer to a specific
-    release, in human-readable format. This field can be the same as
-    android.os.Build.VERSION.INCREMENTAL, but SHOULD be a value sufficiently
-    meaningful for end users to distinguish between software builds. The value
-    of this field MUST be encodable as 7-bit ASCII and match the regular
-    expression &ldquo;^[a-zA-Z0-9._-]+$&rdquo;.
-   </td>
-  </tr>
-  <tr>
-   <td>
-    MANUFACTURER
-   </td>
-   <td>
-    The trade name of the Original Equipment Manufacturer (OEM) of the
-    product. There are no requirements on the specific format of this field,
-    except that it MUST NOT be null or the empty string ("").
-   </td>
-  </tr>
-  <tr>
-   <td>
-    MODEL
-   </td>
-   <td>
-    A value chosen by the device implementer containing the name of the
-    device as known to the end user. This SHOULD be the same name under which
-    the device is marketed and sold to end users. There are no requirements on
-    the specific format of this field, except that it MUST NOT be null or the
-    empty string ("").
-   </td>
-  </tr>
-  <tr>
-   <td>
-    PRODUCT
-   </td>
-   <td>
-    A value chosen by the device implementer containing the development name
-    or code name of the specific product (SKU) that MUST be unique within the
-    same brand. MUST be human-readable, but is not necessarily intended for view
-    by end users. The value of this field MUST be encodable as 7-bit ASCII and
-    match the regular expression &ldquo;^[a-zA-Z0-9_-]+$&rdquo;. This product
-    name MUST NOT change during the lifetime of the product.
-   </td>
-  </tr>
-  <tr>
-   <td>
-    SERIAL
-   </td>
-   <td>
-    A hardware serial number, which MUST be available and unique across
-    devices with the same MODEL and MANUFACTURER. The value of this field MUST
-    be encodable as 7-bit ASCII and match the regular expression
-    &ldquo;^([a-zA-Z0-9]{6,20})$&rdquo;.
-   </td>
-  </tr>
-  <tr>
-   <td>
-    TAGS
-   </td>
-   <td>
-    A comma-separated list of tags chosen by the device implementer that
-    further distinguishes the build. This field MUST have one of the values
-    corresponding to the three typical Android platform signing configurations:
-    release-keys, dev-keys, test-keys.
-   </td>
-  </tr>
-  <tr>
-   <td>
-    TIME
-   </td>
-   <td>
-    A value representing the timestamp of when the build occurred.
-   </td>
-  </tr>
-  <tr>
-   <td>
-    TYPE
-   </td>
-   <td>
-    A value chosen by the device implementer specifying the runtime
-    configuration of the build. This field MUST have one of the values
-    corresponding to the three typical Android runtime configurations: user,
-    userdebug, or eng.
-   </td>
-  </tr>
-  <tr>
-   <td>
-    USER
-   </td>
-   <td>
-    A name or user ID of the user (or automated user) that generated the
-    build. There are no requirements on the specific format of this field,
-    except that it MUST NOT be null or the empty string ("").
-   </td>
-  </tr>
-  <tr>
-   <td>
-    SECURITY_PATCH
-   </td>
-   <td>
-    A value indicating the security patch level of a build. It MUST signify
-    that the build is not in any way vulnerable to any of the issues described
-    up through the designated Android Public Security Bulletin. It MUST be in
-    the format [YYYY-MM-DD], matching a defined string documented in the
-    <a href="source.android.com/security/bulletin">
-     Android Public Security
-    Bulletin
-    </a>
-    or in the
-    <a href="http://source.android.com/security/advisory">
-     Android Security Advisory
-    </a>, for example "2015-11-01".
-   </td>
-  </tr>
-  <tr>
-   <td>
-    BASE_OS
-   </td>
-   <td>
-    A value representing the FINGERPRINT parameter of the build that is
-    otherwise identical to this build except for the patches provided in the
-    Android Public Security Bulletin. It MUST report the correct value and if
-    such a build does not exist, report an empty string ("").
-   </td>
-  </tr>
- </table>
- <h4 id="3_2_3_intent_compatibility">
-  3.2.3. Intent Compatibility
- </h4>
- <h5 id="3_2_3_1_core_application_intents">
-  3.2.3.1. Core Application Intents
- </h5>
- <p>
-  Android intents allow application components to request functionality from
-other Android components. The Android upstream project includes a list of
-applications considered core Android applications, which implements several
-intent patterns to perform common actions. The core Android applications are:
- </p>
- <ul>
-  <li>
-   Desk Clock
-  </li>
-  <li>
-   Browser
-  </li>
-  <li>
-   Calendar
-  </li>
-  <li>
-   Contacts
-  </li>
-  <li>
-   Gallery
-  </li>
-  <li>
-   GlobalSearch
-  </li>
-  <li>
-   Launcher
-  </li>
-  <li>
-   Music
-  </li>
-  <li>
-   Settings
-  </li>
- </ul>
- <p>
-  Device implementations MUST include the core Android applications as
-appropriate or a component implementing the same intent patterns defined by
-all the Activity or Service components of these core Android applications
-exposed to other applications, implicitly or explicitly, through the
-  <code>
-   android:exported
-  </code>
-  attribute.
- </p>
- <h5 id="3_2_3_2_intent_resolution">
-  3.2.3.2. Intent Resolution
- </h5>
- <p>
-  As Android is an extensible platform, device implementations MUST allow each
-intent pattern referenced in
-  <a href="#3_2_3_1_core_application_intents">
-   section 3.2.3.1
-  </a>
-  to be overridden by third-party
-applications. The upstream Android open source implementation allows this by
-default; device implementers MUST NOT attach special privileges to system
-applications' use of these intent patterns, or prevent third-party applications
-from binding to and assuming control of these patterns. This prohibition
-specifically includes but is not limited to disabling the &ldquo;Chooser&rdquo; user
-interface that allows the user to select between multiple applications that all
-handle the same intent pattern.
- </p>
- <p>
-  Device implementations MUST provide a user interface for users to modify the
-default activity for intents.
- </p>
- <p>
-  However, device implementations MAY provide default activities for specific URI
-patterns (e.g. http://play.google.com) when the default activity provides a
-more specific attribute for the data URI. For example, an intent filter pattern
-specifying the data URI &ldquo;http://www.android.com&rdquo; is more specific than the
-browser's core intent pattern for &ldquo;http://&rdquo;.
- </p>
- <p>
-  Android also includes a mechanism for third-party apps to declare an
-authoritative default
-  <a href="https://developer.android.com/training/app-links">
-   app linking behavior
-  </a>
-  for certain types of web URI intents. When such authoritative declarations are
-defined in an app's intent filter patterns, device implementations:
- </p>
- <ul>
-  <li>
-   MUST attempt to validate any intent filters by performing the validation
-steps defined in the
-   <a href="https://developers.google.com/digital-asset-links">
-    Digital Asset Links specification
-   </a>
-   as implemented by the Package Manager in the upstream Android Open Source
-Project.
-  </li>
-  <li>
-   MUST attempt validation of the intent filters during the installation of
-the application and set all successfully validated UIR intent filters as
-default app handlers for their UIRs.
-  </li>
-  <li>
-   MAY set specific URI intent filters as default app handlers for their URIs,
-if they are successfully verified but other candidate URI filters fail
-verification. If a device implementation does this, it MUST provide the
-user appropriate per-URI pattern overrides in the settings menu.
-  </li>
-  <li>
-   MUST provide the user with per-app App Links controls in Settings as
-follows:
-   <ul>
-    <li>
-     The user MUST be able to override holistically the default app links
-behavior for an app to be: always open, always ask, or never open,
-which must apply to all candidate URI intent filters equally.
-    </li>
-    <li>
-     The user MUST be able to see a list of the candidate URI intent filters.
-    </li>
-    <li>
-     The device implementation MAY provide the user with the ability to
-override specific candidate URI intent filters that were successfully
-verified, on a per-intent filter basis.
-    </li>
-    <li>
-     The device implementation MUST provide users with the ability to view
-and override specific candidate URI intent filters if the device
-implementation lets some candidate URI intent filters succeed
-verification while some others can fail.
-    </li>
-   </ul>
-  </li>
- </ul>
- <h5 id="3_2_3_3_intent_namespaces">
-  3.2.3.3. Intent Namespaces
- </h5>
- <p>
-  Device implementations MUST NOT include any Android component that honors any
-new intent or broadcast intent patterns using an ACTION, CATEGORY, or other key
-string in the android.
-  <em>
-   or com.android.
-  </em>
-  namespace. Device implementers MUST
-NOT include any Android components that honor any new intent or broadcast
-intent patterns using an ACTION, CATEGORY, or other key string in a package
-space belonging to another organization. Device implementers MUST NOT alter or
-extend any of the intent patterns used by the core apps listed in
-  <a href="#3_2_3_1_core_application_intents">
-   section 3.2.3.1
-  </a>. Device implementations MAY
-include intent patterns using namespaces clearly and obviously associated with
-their own organization. This prohibition is analogous to that specified for Java
-language classes in
-  <a href="#3_6_api_namespaces">
-   section 3.6
-  </a>.
- </p>
- <h5 id="3_2_3_4_broadcast_intents">
-  3.2.3.4. Broadcast Intents
- </h5>
- <p>
-  Third-party applications rely on the platform to broadcast certain intents to
-notify them of changes in the hardware or software environment.
-Android-compatible devices MUST broadcast the public broadcast intents in
-response to appropriate system events. Broadcast intents are described in the
-SDK documentation.
- </p>
- <h5 id="3_2_3_5_default_app_settings">
-  3.2.3.5. Default App Settings
- </h5>
- <p>
-  Android includes settings that provide users an easy way to select their
-default applications, for example for Home screen or SMS. Where it makes sense,
-device implementations MUST provide a similar settings menu and be compatible
-with the intent filter pattern and API methods described in the SDK
-documentation as below.
- </p>
- <p>
-  Device implementations:
- </p>
- <ul>
-  <li>
-   MUST honor the
-   <a href="http://developer.android.com/reference/android/provider/Settings.html#ACTION_HOME_SETTINGS">
-    android.settings.HOME_SETTINGS
-   </a>
-   intent to show a default app settings menu for Home Screen, if the device
-implementation reports android.software.home_screen.
-  </li>
-  <li>
-   MUST provide a settings menu that will call the
-   <a href="http://developer.android.com/reference/android/provider/Telephony.Sms.Intents.html">
-    android.provider.Telephony.ACTION_CHANGE_DEFAULT
-   </a>
-   intent to show a dialog to change the default SMS application, if the
-device implementation reports android.hardware.telephony.
-  </li>
-  <li>
-   MUST honor the
-   <a href="http://developer.android.com/reference/android/provider/Settings.html#ACTION_NFC_PAYMENT_SETTINGS">
-    android.settings.NFC_PAYMENT_SETTINGS
-   </a>
-   intent to show a default app settings menu for Tap and Pay, if the device
-implementation reports android.hardware.nfc.hce.
-  </li>
-  <li>
-   MUST honor the
-   <a href="https://developer.android.com/reference/android/telecom/TelecomManager.html#ACTION_CHANGE_DEFAULT_DIALER">
-    android.telecom.action.CHANGE_DEFAULT_DIALER
-   </a>
-   intent to show a dialog to allow the user to change the default Phone application, if the
-device implementation reports
-   <code>
-    android.hardware.telephony
-   </code>
-   .
-  </li>
-  <li>
-   MUST honor the
-   <a href="https://developer.android.com/reference/android/provider/Settings.html#ACTION_VOICE_INPUT_SETTINGS">
-    android.settings.ACTION_VOICE_INPUT_SETTINGS
-   </a>
-   intent when the device supports the VoiceInteractionService and show a
-    default app settings menu for voice input and assist.
-  </li>
- </ul>
- <h3 id="3_3_native_api_compatibility">
-  3.3. Native API Compatibility
- </h3>
- <p>
-  Native code compatibility is challenging. For this reason, device implementers
-are
-  <strong>
-   STRONGLY RECOMMENDED
-  </strong>
-  to use the implementations of the libraries listed
-below from the upstream Android Open Source Project.
- </p>
- <h4 id="3_3_1_application_binary_interfaces">
-  3.3.1. Application Binary Interfaces
- </h4>
- <p>
-  Managed Dalvik bytecode can call into native code provided in the application
-.apk file as an ELF .so file compiled for the appropriate device hardware
-architecture. As native code is highly dependent on the underlying processor
-technology, Android defines a number of Application Binary Interfaces (ABIs) in
-the Android NDK. Device implementations MUST be compatible with one or more
-defined ABIs, and MUST implement compatibility with the Android NDK, as below.
- </p>
- <p>
-  If a device implementation includes support for an Android ABI, it:
- </p>
- <ul>
-  <li>
-   MUST include support for code running in the managed environment to call
-    into native code, using the standard Java Native Interface (JNI) semantics.
-  </li>
-  <li>
-   MUST be source-compatible (i.e. header compatible) and binary-compatible
-    (for the ABI) with each required library in the list below.
-  </li>
-  <li>
-   MUST support the equivalent 32-bit ABI if any 64-bit ABI is supported.
-  </li>
-  <li>
-   MUST accurately report the native Application Binary Interface (ABI)
-    supported by the device, via the android.os.Build.SUPPORTED_ABIS,
-    android.os.Build.SUPPORTED_32_BIT_ABIS, and
-    android.os.Build.SUPPORTED_64_BIT_ABIS parameters, each a comma separated
-    list of ABIs ordered from the most to the least preferred one.
-  </li>
-  <li>
-   MUST report, via the above parameters, only those ABIs documented and
-    described in the latest version of the
-   <a href="https://developer.android.com/ndk/guides/abis.html">
-    Android NDK ABI Management documentation
-   </a>, and MUST
-    include support for the
-   <a href="http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0388f/Beijfcja.html">
-    Advanced SIMD
-   </a>
-   (a.k.a. NEON) extension.
-  </li>
-  <li>
-   SHOULD be built using the source code and header files available in the
-    upstream Android Open Source Project
-  </li>
- </ul>
- <p>
-  Note that future releases of the Android NDK may introduce support for
-additional ABIs. If a device implementation is not compatible with an existing
-predefined ABI, it MUST NOT report support for any ABIs at all.
- </p>
- <p>
-  The following native code APIs MUST be available to apps that include native code:
- </p>
- <ul>
-  <li>
-   libandroid.so (native Android activity support)
-  </li>
-  <li>
-   libc (C library)
-  </li>
-  <li>
-   libcamera2ndk.so
-  </li>
-  <li>
-   libdl (dynamic linker)
-  </li>
-  <li>
-   libEGL.so (native OpenGL surface management)
-  </li>
-  <li>
-   libGLESv1_CM.so (OpenGL ES 1.x)
-  </li>
-  <li>
-   libGLESv2.so (OpenGL ES 2.0)
-  </li>
-  <li>
-   libGLESv3.so (OpenGL ES 3.x)
-  </li>
-  <li>
-   libicui18n.so
-  </li>
-  <li>
-   libicuuc.so
-  </li>
-  <li>
-   libjnigraphics.so
-  </li>
-  <li>
-   liblog (Android logging)
-  </li>
-  <li>
-   libmediandk.so (native media APIs support)
-  </li>
-  <li>
-   libm (math library)
-  </li>
-  <li>
-   libOpenMAXAL.so (OpenMAX AL 1.0.1 support)
-  </li>
-  <li>
-   libOpenSLES.so (OpenSL ES 1.0.1 audio support)
-  </li>
-  <li>
-   libRS.so
-  </li>
-  <li>
-   libstdc++ (Minimal support for C++)
-  </li>
-  <li>
-   libvulkan.so (Vulkan)
-  </li>
-  <li>
-   libz (Zlib compression)
-  </li>
-  <li>
-   JNI interface
-  </li>
-  <li>
-   Support for OpenGL, as described below
-  </li>
- </ul>
- <p>
-  For the native libraries listed above, the device implementation MUST NOT add
-or remove the public functions.
- </p>
- <p>
-  Native libraries not listed above but implemented and provided in AOSP as system
-libraries are reserved and MUST NOT be exposed to third-party apps targeting API
-level 24 or higher.
- </p>
- <p>
-  Device implementations MAY add non-AOSP libraries and expose them directly as
-an API to third-party apps but the additional libraries SHOULD be in
-  <code>
-   /vendor/lib
-  </code>
-  or
-  <code>
-   /vendor/lib64
-  </code>
-  and MUST be listed in
-  <code>
-   /vendor/etc/public.libraries.txt
-  </code>
-  .
- </p>
- <p>
-  Note that device implementations MUST include libGLESv3.so and in turn, MUST export
-all the OpenGL ES 3.1 and
-  <a href="http://developer.android.com/guide/topics/graphics/opengl.html#aep">
-   Android Extension Pack
-  </a>
-  function symbols as defined in the NDK release android-24. Although all the
-symbols must be present, only the corresponding functions for OpenGL ES versions
-and extensions actually supported by the device must be fully implemented.
- </p>
- <h5 id="3_3_1_1_graphic_libraries">
-  3.3.1.1. Graphic Libraries
- </h5>
- <p>
-  <a href="https://www.khronos.org/registry/vulkan/specs/1.0-wsi_extensions/xhtml/vkspec.html">
-   Vulkan
-  </a>
-  is a low-overhead, cross-platform API for high-performance 3D graphics. Device
-implementations, even if not including support of the Vulkan APIs, MUST satisfy
-the following requirements:
- </p>
- <ul>
-  <li>
-   It MUST always provide a native library named
-   <code>
-    libvulkan.so
-   </code>
-   which exports
-    function symbols for the core Vulkan 1.0 API as well as the
-   <code>
-    VK_KHR_surface
-   </code>
-   ,
-   <code>
-    VK_KHR_android_surface
-   </code>
-   , and
-   <code>
-    VK_KHR_swapchain
-   </code>
-   extensions.
-  </li>
- </ul>
- <p>
-  Device implementations, if including support of the Vulkan APIs:
- </p>
- <ul>
-  <li>
-   MUST report, one or more
-   <code>
-    VkPhysicalDevices
-   </code>
-   through the
-   <code>
-    vkEnumeratePhysicalDevices
-   </code>
-   call.
-  </li>
-  <li>
-   Each enumerated
-   <code>
-    VkPhysicalDevices
-   </code>
-   MUST fully implement the Vulkan 1.0 API.
-  </li>
-  <li>
-   MUST report the correct
-   <a href="https://developer.android.com/reference/android/content/pm/PackageManager.html#FEATURE_VULKAN_HARDWARE_LEVEL">
-    <code>
-     PackageManager#FEATURE_VULKAN_HARDWARE_LEVEL
-    </code>
-   </a>
-   and
-   <a href="https://developer.android.com/reference/android/content/pm/PackageManager.html#FEATURE_VULKAN_HARDWARE_VERSION">
-    <code>
-     PackageManager#FEATURE_VULKAN_HARDWARE_VERSION
-    </code>
-   </a>
-   feature flags.
-  </li>
-  <li>
-   MUST enumerate layers, contained in native libraries named
-   <code>
-    libVkLayer*.so
-   </code>
-   in the application package&rsquo;s native library directory, through the
-   <code>
-    vkEnumerateInstanceLayerProperties
-   </code>
-   and
-   <code>
-    vkEnumerateDeviceLayerProperties
-   </code>
-   functions in
-   <code>
-    libvulkan.so
-   </code>
-  </li>
-  <li>
-   MUST NOT enumerate layers provided by libraries outside of the application
-    package, or provide other ways of tracing or intercepting the Vulkan API,
-    unless the application has the
-   <code>
-    android:debuggable=&rdquo;true&rdquo;
-   </code>
-   attribute.
-  </li>
- </ul>
- <p>
-  Device implementations, if not including support of the Vulkan APIs:
- </p>
- <ul>
-  <li>
-   MUST report 0
-   <code>
-    VkPhysicalDevices
-   </code>
-   through the
-   <code>
-    vkEnumeratePhysicalDevices
-   </code>
-   call.
-  </li>
-  <li>
-   MUST NOT declare any of the Vulkan feature flags
-   <a href="https://developer.android.com/reference/android/content/pm/PackageManager.html#FEATURE_VULKAN_HARDWARE_LEVEL">
-    <code>
-     PackageManager#FEATURE_VULKAN_HARDWARE_LEVEL
-    </code>
-   </a>
-   and
-   <a href="https://developer.android.com/reference/android/content/pm/PackageManager.html#FEATURE_VULKAN_HARDWARE_VERSION">
-    <code>
-     PackageManager#FEATURE_VULKAN_HARDWARE_VERSION
-    </code>
-   </a>.
-  </li>
- </ul>
- <h4 id="3_3_2_32-bit_arm_native_code_compatibility">
-  3.3.2. 32-bit ARM Native Code Compatibility
- </h4>
- <p>
-  The ARMv8 architecture deprecates several CPU operations, including some
-operations used in existing native code. On 64-bit ARM devices, the following
-deprecated operations MUST remain available to 32-bit native ARM code, either
-through native CPU support or through software emulation:
- </p>
- <ul>
-  <li>
-   SWP and SWPB instructions
-  </li>
-  <li>
-   SETEND instruction
-  </li>
-  <li>
-   CP15ISB, CP15DSB, and CP15DMB barrier operations
-  </li>
- </ul>
- <p>
-  Legacy versions of the Android NDK used /proc/cpuinfo to discover CPU features
-from 32-bit ARM native code. For compatibility with applications built using
-this NDK, devices MUST include the following lines in /proc/cpuinfo when it is
-read by 32-bit ARM applications:
- </p>
- <ul>
-  <li>
-   "Features: ", followed by a list of any optional ARMv7 CPU features supported by the device.
-  </li>
-  <li>
-   "CPU architecture: ", followed by an integer describing the device's highest
-    supported ARM architecture (e.g., "8" for ARMv8 devices).
-  </li>
- </ul>
- <p>
-  These requirements only apply when /proc/cpuinfo is read by 32-bit ARM
-applications. Devices SHOULD not alter /proc/cpuinfo when read by 64-bit ARM or
-non-ARM applications.
- </p>
- <h3 id="3_4_web_compatibility">
-  3.4. Web Compatibility
- </h3>
- <h4 id="3_4_1_webview_compatibility">
-  3.4.1. WebView Compatibility
- </h4>
- <div class="note">
-  Android Watch devices MAY, but all other device implementations MUST provide a
-complete implementation of the android.webkit.Webview API.
- </div>
- <p>
-  The platform feature android.software.webview MUST be reported on any device
-that provides a complete implementation of the android.webkit.WebView API, and
-MUST NOT be reported on devices without a complete implementation of the API.
-The Android Open Source implementation uses code from the Chromium Project to
-implement the
-  <a href="http://developer.android.com/reference/android/webkit/WebView.html">
-   android.webkit.WebView
-  </a>.
-Because it is not feasible to develop a comprehensive test suite for a web
-rendering system, device implementers MUST use the specific upstream build of
-Chromium in the WebView implementation. Specifically:
- </p>
- <ul>
-  <li>
-   Device android.webkit.WebView implementations MUST be based on the
-   <a href="http://www.chromium.org/">
-    Chromium
-   </a>
-   build from the upstream Android Open
-    Source Project for Android 7.1. This build includes a specific
-    set of functionality and security fixes for the WebView.
-  </li>
-  <li>
-   <p>
-    The user agent string reported by the WebView MUST be in this format:
-   </p>
-   <p>
-    Mozilla/5.0 (Linux; Android $(VERSION); $(MODEL) Build/$(BUILD); wv)
-AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 $(CHROMIUM_VER) Mobile
-Safari/537.36
-   </p>
-   <ul>
-    <li>
-     The value of the $(VERSION) string MUST be the same as the value for android.os.Build.VERSION.RELEASE.
-    </li>
-    <li>
-     The value of the $(MODEL) string MUST be the same as the value for android.os.Build.MODEL.
-    </li>
-    <li>
-     The value of the $(BUILD) string MUST be the same as the value for android.os.Build.ID.
-    </li>
-    <li>
-     The value of the $(CHROMIUM_VER) string MUST be the version of Chromium in the upstream Android Open Source Project.
-    </li>
-    <li>
-     Device implementations MAY omit Mobile in the user agent string.
-    </li>
-   </ul>
-  </li>
- </ul>
- <p>
-  The WebView component SHOULD include support for as many HTML5 features as
-possible and if it supports the feature SHOULD conform to the
-  <a href="http://html.spec.whatwg.org/multipage/">
-   HTML5 specification
-  </a>.
- </p>
- <h4 id="3_4_2_browser_compatibility">
-  3.4.2. Browser Compatibility
- </h4>
- <div class="note">
-  Android Television, Watch, and Android Automotive implementations MAY omit a
-browser application, but MUST support the public intent patterns as described in
-  <a href="#3_2_3_1_core_application_intents">
-   section 3.2.3.1
-  </a>. All other types of device
-implementations MUST include a standalone Browser application for general user
-web browsing.
- </div>
- <p>
-  The standalone Browser MAY be based on a browser technology other than WebKit.
-However, even if an alternate Browser application is used, the
-android.webkit.WebView component provided to third-party applications MUST be
-based on WebKit, as described in
-  <a href="#3_4_1_webview_compatibility">
-   section 3.4.1
-  </a>.
- </p>
- <p>
-  Implementations MAY ship a custom user agent string in the standalone Browser application.
- </p>
- <p>
-  The standalone Browser application (whether based on the upstream WebKit Browser
-application or a third-party replacement) SHOULD include support for as much of
-  <a href="http://html.spec.whatwg.org/multipage/">
-   HTML5
-  </a>
-  as possible. Minimally, device
-implementations MUST support each of these APIs associated with HTML5:
- </p>
- <ul>
-  <li>
-   <a href="http://www.w3.org/html/wg/drafts/html/master/browsers.html#offline">
-    application cache/offline operation
-   </a>
-  </li>
-  <li>
-   <a href="http://www.w3.org/html/wg/drafts/html/master/semantics.html#video">
-    &lt;video&gt; tag
-   </a>
-  </li>
-  <li>
-   <a href="http://www.w3.org/TR/geolocation-API/">
-    geolocation
-   </a>
-  </li>
- </ul>
- <p>
-  Additionally, device implementations MUST support the HTML5/W3C
-  <a href="http://www.w3.org/TR/webstorage/">
-   webstorage API
-  </a>
-  and SHOULD support the HTML5/W3C
-  <a href="http://www.w3.org/TR/IndexedDB/">
-   IndexedDB API
-  </a>. Note that as the web
-development standards bodies are transitioning to favor IndexedDB over
-webstorage, IndexedDB is expected to become a required component in a future
-version of Android.
- </p>
- <h3 id="3_5_api_behavioral_compatibility">
-  3.5. API Behavioral Compatibility
- </h3>
- <p>
-  The behaviors of each of the API types (managed, soft, native, and web) must be
-consistent with the preferred implementation of the upstream
-  <a href="http://source.android.com/">
-   Android Open Source Project
-  </a>. Some specific areas of
-compatibility are:
- </p>
- <ul>
-  <li>
-   Devices MUST NOT change the behavior or semantics of a standard intent.
-  </li>
-  <li>
-   Devices MUST NOT alter the lifecycle or lifecycle semantics of a particular
-    type of system component (such as Service, Activity, ContentProvider, etc.).
-  </li>
-  <li>
-   Devices MUST NOT change the semantics of a standard permission.
-  </li>
- </ul>
- <p>
-  The above list is not comprehensive. The Compatibility Test Suite (CTS) tests
-significant portions of the platform for behavioral compatibility, but not all.
-It is the responsibility of the implementer to ensure behavioral compatibility
-with the Android Open Source Project. For this reason, device implementers
-SHOULD use the source code available via the Android Open Source Project where
-possible, rather than re-implement significant parts of the system.
- </p>
- <h3 id="3_6_api_namespaces">
-  3.6. API Namespaces
- </h3>
- <p>
-  Android follows the package and class namespace conventions defined by the Java
-programming language. To ensure compatibility with third-party applications,
-device implementers MUST NOT make any prohibited modifications (see below) to
-these package namespaces:
- </p>
- <ul>
-  <li>
-   java.*
-  </li>
-  <li>
-   javax.*
-  </li>
-  <li>
-   sun.*
-  </li>
-  <li>
-   android.*
-  </li>
-  <li>
-   com.android.*
-  </li>
- </ul>
- <p>
-  <strong>
-   Prohibited modifications include
-  </strong>
-  :
- </p>
- <ul>
-  <li>
-   Device implementations MUST NOT modify the publicly exposed APIs on the
-    Android platform by changing any method or class signatures, or by removing
-    classes or class fields.
-  </li>
-  <li>
-   Device implementers MAY modify the underlying implementation of the APIs,
-    but such modifications MUST NOT impact the stated behavior and Java-language
-    signature of any publicly exposed APIs.
-  </li>
-  <li>
-   Device implementers MUST NOT add any publicly exposed elements (such as
-    classes or interfaces, or fields or methods to existing classes or
-    interfaces) to the APIs above.
-  </li>
- </ul>
- <p>
-  A &ldquo;publicly exposed element&rdquo; is any construct that is not decorated with
-the&ldquo;@hide&rdquo; marker as used in the upstream Android source code. In other words,
-device implementers MUST NOT expose new APIs or alter existing APIs in the
-namespaces noted above. Device implementers MAY make internal-only
-modifications, but those modifications MUST NOT be advertised or otherwise
-exposed to developers.
- </p>
- <p>
-  Device implementers MAY add custom APIs, but any such APIs MUST NOT be in a
-namespace owned by or referring to another organization. For instance, device
-implementers MUST NOT add APIs to the com.google.* or similar namespace: only
-Google may do so. Similarly, Google MUST NOT add APIs to other companies'
-namespaces. Additionally, if a device implementation includes custom APIs
-outside the standard Android namespace, those APIs MUST be packaged in an
-Android shared library so that only apps that explicitly use them (via the
-&lt;uses-library&gt; mechanism) are affected by the increased memory usage of such
-APIs.
- </p>
- <p>
-  If a device implementer proposes to improve one of the package namespaces above
-(such as by adding useful new functionality to an existing API, or adding a new
-API), the implementer SHOULD visit
-  <a href="http://source.android.com/">
-   source.android.com
-  </a>
-  and begin the process for
-contributing changes and code, according to the information on that site.
- </p>
- <p>
-  Note that the restrictions above correspond to standard conventions for naming
-APIs in the Java programming language; this section simply aims to reinforce
-those conventions and make them binding through inclusion in this Compatibility
-Definition.
- </p>
- <h3 id="3_7_runtime_compatibility">
-  3.7. Runtime Compatibility
- </h3>
- <p>
-  Device implementations MUST support the full Dalvik Executable (DEX) format and
-  <a href="https://android.googlesource.com/platform/dalvik/">
-   Dalvik bytecode specification and semantics
-  </a>.
-Device implementers SHOULD use ART, the reference upstream implementation of the Dalvik
-Executable Format, and the reference implementation&rsquo;s package management system.
- </p>
- <p>
-  Device implementations MUST configure Dalvik runtimes to allocate memory in
-accordance with the upstream Android platform, and as specified by the following
-table. (See
-  <a href="#7_1_1_screen_configuration">
-   section 7.1.1
-  </a>
-  for screen size and
-screen density definitions.) Note that memory values specified below are
-considered minimum values and device implementations MAY allocate more memory
-per application.
- </p>
- <table>
-  <tr>
-   <th>
-    Screen Layout
-   </th>
-   <th>
-    Screen Density
-   </th>
-   <th>
-    Minimum Application Memory
-   </th>
-  </tr>
-  <tr>
-   <td rowspan="12">
-    Android Watch
-   </td>
-   <td>
-    120 dpi (ldpi)
-   </td>
-   <td rowspan="3">
-    32MB
-   </td>
-  </tr>
-  <tr>
-   <td>
-    160 dpi (mdpi)
-   </td>
-  </tr>
-  <tr>
-   <td>
-    213 dpi (tvdpi)
-   </td>
-  </tr>
-  <tr>
-   <td>
-    240 dpi (hdpi)
-   </td>
-   <td rowspan="2">
-    36MB
-   </td>
-  </tr>
-  <tr>
-   <td>
-    280 dpi (280dpi)
-   </td>
-  </tr>
-  <tr>
-   <td>
-    320 dpi (xhdpi)
-   </td>
-   <td rowspan="2">
-    48MB
-   </td>
-  </tr>
-  <tr>
-   <td>
-    360 dpi (360dpi)
-   </td>
-  </tr>
-  <tr>
-   <td>
-    400 dpi (400dpi)
-   </td>
-   <td>
-    56MB
-   </td>
-  </tr>
-  <tr>
-   <td>
-    420 dpi (420dpi)
-   </td>
-   <td>
-    64MB
-   </td>
-  </tr>
-  <tr>
-   <td>
-    480 dpi (xxhdpi)
-   </td>
-   <td>
-    88MB
-   </td>
-  </tr>
-  <tr>
-   <td>
-    560 dpi (560dpi)
-   </td>
-   <td>
-    112MB
-   </td>
-  </tr>
-  <tr>
-   <td>
-    640 dpi (xxxhdpi)
-   </td>
-   <td>
-    154MB
-   </td>
-  </tr>
-  <tr>
-   <td rowspan="12">
-    small/normal
-   </td>
-   <td>
-    120 dpi (ldpi)
-   </td>
-   <td rowspan="2">
-    32MB
-   </td>
-  </tr>
-  <tr>
-   <td>
-    160 dpi (mdpi)
-   </td>
-  </tr>
-  <tr>
-   <td>
-    213 dpi (tvdpi)
-   </td>
-   <td rowspan="3">
-    48MB
-   </td>
-  </tr>
-  <tr>
-   <td>
-    240 dpi (hdpi)
-   </td>
-  </tr>
-  <tr>
-   <td>
-    280 dpi (280dpi)
-   </td>
-  </tr>
-  <tr>
-   <td>
-    320 dpi (xhdpi)
-   </td>
-   <td rowspan="2">
-    80MB
-   </td>
-  </tr>
-  <tr>
-   <td>
-    360 dpi (360dpi)
-   </td>
-  </tr>
-  <tr>
-   <td>
-    400 dpi (400dpi)
-   </td>
-   <td>
-    96MB
-   </td>
-  </tr>
-  <tr>
-   <td>
-    420 dpi (420dpi)
-   </td>
-   <td>
-    112MB
-   </td>
-  </tr>
-  <tr>
-   <td>
-    480 dpi (xxhdpi)
-   </td>
-   <td>
-    128MB
-   </td>
-  </tr>
-  <tr>
-   <td>
-    560 dpi (560dpi)
-   </td>
-   <td>
-    192MB
-   </td>
-  </tr>
-  <tr>
-   <td>
-    640 dpi (xxxhdpi)
-   </td>
-   <td>
-    256MB
-   </td>
-  </tr>
-  <tr>
-   <td rowspan="12">
-    large
-   </td>
-   <td>
-    120 dpi (ldpi)
-   </td>
-   <td>
-    32MB
-   </td>
-  </tr>
-  <tr>
-   <td>
-    160 dpi (mdpi)
-   </td>
-   <td>
-    48MB
-   </td>
-  </tr>
-  <tr>
-   <td>
-    213 dpi (tvdpi)
-   </td>
-   <td rowspan="2">
-    80MB
-   </td>
-  </tr>
-  <tr>
-   <td>
-    240 dpi (hdpi)
-   </td>
-  </tr>
-  <tr>
-   <td>
-    280 dpi (280dpi)
-   </td>
-   <td>
-    96MB
-   </td>
-  </tr>
-  <tr>
-   <td>
-    320 dpi (xhdpi)
-   </td>
-   <td>
-    128MB
-   </td>
-  </tr>
-  <tr>
-   <td>
-    360 dpi (360dpi)
-   </td>
-   <td>
-    160MB
-   </td>
-  </tr>
-  <tr>
-   <td>
-    400 dpi (400dpi)
-   </td>
-   <td>
-    192MB
-   </td>
-  </tr>
-  <tr>
-   <td>
-    420 dpi (420dpi)
-   </td>
-   <td>
-    228MB
-   </td>
-  </tr>
-  <tr>
-   <td>
-    480 dpi (xxhdpi)
-   </td>
-   <td>
-    256MB
-   </td>
-  </tr>
-  <tr>
-   <td>
-    560 dpi (560dpi)
-   </td>
-   <td>
-    384MB
-   </td>
-  </tr>
-  <tr>
-   <td>
-    640 dpi (xxxhdpi)
-   </td>
-   <td>
-    512MB
-   </td>
-  </tr>
-  <tr>
-   <td rowspan="12">
-    xlarge
-   </td>
-   <td>
-    120 dpi (ldpi)
-   </td>
-   <td>
-    48MB
-   </td>
-  </tr>
-  <tr>
-   <td>
-    160 dpi (mdpi)
-   </td>
-   <td>
-    80MB
-   </td>
-  </tr>
-  <tr>
-   <td>
-    213 dpi (tvdpi)
-   </td>
-   <td rowspan="2">
-    96MB
-   </td>
-  </tr>
-  <tr>
-   <td>
-    240 dpi (hdpi)
-   </td>
-  </tr>
-  <tr>
-   <td>
-    280 dpi (280dpi)
-   </td>
-   <td>
-    144MB
-   </td>
-  </tr>
-  <tr>
-   <td>
-    320 dpi (xhdpi)
-   </td>
-   <td>
-    192MB
-   </td>
-  </tr>
-  <tr>
-   <td>
-    360 dpi (360dpi)
-   </td>
-   <td>
-    240MB
-   </td>
-  </tr>
-  <tr>
-   <td>
-    400 dpi (400dpi)
-   </td>
-   <td>
-    288MB
-   </td>
-  </tr>
-  <tr>
-   <td>
-    420 dpi (420dpi)
-   </td>
-   <td>
-    336MB
-   </td>
-  </tr>
-  <tr>
-   <td>
-    480 dpi (xxhdpi)
-   </td>
-   <td>
-    384MB
-   </td>
-  </tr>
-  <tr>
-   <td>
-    560 dpi (560dpi)
-   </td>
-   <td>
-    576MB
-   </td>
-  </tr>
-  <tr>
-   <td>
-    640 dpi (xxxhdpi)
-   </td>
-   <td>
-    768MB
-   </td>
-  </tr>
- </table>
- <h3 id="3_8_user_interface_compatibility">
-  3.8. User Interface Compatibility
- </h3>
- <h4 id="3_8_1_launcher_(home_screen)">
-  3.8.1. Launcher (Home Screen)
- </h4>
- <p>
-  Android includes a launcher application (home screen) and support for
-third-party applications to replace the device launcher (home screen). Device
-implementations that allow third-party applications to replace the device home
-screen MUST declare the platform feature android.software.home_screen.
- </p>
- <h4 id="3_8_2_widgets">
-  3.8.2. Widgets
- </h4>
- <div class="note">
-  Widgets are optional for all Android device implementations, but SHOULD be
-supported on Android Handheld devices.
- </div>
- <p>
-  Android defines a component type and corresponding API and lifecycle that allows
-applications to expose an
-  <a href="http://developer.android.com/guide/practices/ui_guidelines/widget_design.html">
-   &ldquo;AppWidget&rdquo;
-  </a>
-  to the end user, a feature that is STRONGLY RECOMMENDED to be supported on
-Handheld Device implementations. Device implementations that support embedding
-widgets on the home screen MUST meet the following requirements and declare
-support for platform feature android.software.app_widgets.
- </p>
- <ul>
-  <li>
-   Device launchers MUST include built-in support for AppWidgets and expose
-    user interface affordances to add, configure, view, and remove AppWidgets
-    directly within the Launcher.
-  </li>
-  <li>
-   Device implementations MUST be capable of rendering widgets that are 4 x 4
-    in the standard grid size. See the
-   <a href="http://developer.android.com/guide/practices/ui_guidelines/widget_design.html">
-    App Widget Design
-    Guidelines
-   </a>
-   in the Android SDK documentation for details.
-  </li>
-  <li>
-   Device implementations that include support for lock screen MAY support
-    application widgets on the lock screen.
-  </li>
- </ul>
- <h4 id="3_8_3_notifications">
-  3.8.3. Notifications
- </h4>
- <p>
-  Android includes APIs that allow developers to
-  <a href="http://developer.android.com/guide/topics/ui/notifiers/notifications.html">
-   notify users of notable events
-  </a>
-  using hardware and software features of the device.
- </p>
- <p>
-  Some APIs allow applications to perform notifications or attract attention using
-hardware&mdash;specifically sound, vibration, and light. Device implementations MUST
-support notifications that use hardware features, as described in the SDK
-documentation, and to the extent possible with the device implementation
-hardware. For instance, if a device implementation includes a vibrator, it MUST
-correctly implement the vibration APIs. If a device implementation lacks
-hardware, the corresponding APIs MUST be implemented as no-ops. This behavior is
-further detailed in
-  <a href="#7_hardware_compatibility">
-   section 7
-  </a>.
- </p>
- <p>
-  Additionally, the implementation MUST correctly render all
-  <a href="https://developer.android.com/guide/topics/resources/available-resources.html">
-   resources
-  </a>
-  (icons, animation files etc.) provided for in the APIs, or in the Status/System
-Bar
-  <a href="http://developer.android.com/design/style/iconography.html">
-   icon style guide
-  </a>, which in the
-case of an Android Television device includes the possibility to not display the
-notifications. Device implementers MAY provide an alternative user experience
-for notifications than that provided by the reference Android Open Source
-implementation; however, such alternative notification systems MUST support
-existing notification resources, as above.
- </p>
- <div class="note">
-  Android Automotive implementations MAY manage the visibility and timing of
-notifications to mitigate driver distraction, but MUST display
-notifications that use
-  <a href="https://developer.android.com/reference/android/app/Notification.CarExtender.html">
-   CarExtender
-  </a>
-  when requested by applications.
- </div>
- <p>
-  Android includes support for various notifications, such as:
- </p>
- <ul>
-  <li>
-   <strong>
-    Rich notifications
-   </strong>
-   . Interactive Views for ongoing notifications.
-  </li>
-  <li>
-   <strong>
-    Heads-up notifications
-   </strong>
-   . Interactive Views users can act on or dismiss without leaving the current app.
-  </li>
-  <li>
-   <strong>
-    Lock screen notifications
-   </strong>
-   . Notifications shown over a lock screen with granular control on visibility.
-  </li>
- </ul>
- <p>
-  Android device implementations, when such notifications are made visible, MUST
-properly execute Rich and Heads-up notifications and include the title/name,
-icon, text as
-  <a href="https://developer.android.com/design/patterns/notifications.html">
-   documented in the Android APIs
-  </a>.
- </p>
- <p>
-  Android includes Notification Listener Service APIs that allow apps (once
-explicitly enabled by the user) to receive a copy of all notifications as they
-are posted or updated. Device implementations MUST correctly and promptly send
-notifications in their entirety to all such installed and user-enabled listener
-services, including any and all metadata attached to the Notification object.
- </p>
- <p>
-  Handheld device implementations MUST support the behaviors of updating,
-removing, replying to, and bundling notifications as described in this
-  <a href="https://developer.android.com/guide/topics/ui/notifiers/notifications.html#Managing">
-   section
-  </a>.
- </p>
- <p>
-  Also, handheld device implementations MUST provide:
- </p>
- <ul>
-  <li>
-   The ability to control notifications directly in the notification shade.
-  </li>
-  <li>
-   The visual affordance to trigger the control panel in the notification shade.
-  </li>
-  <li>
-   The ability to BLOCK, MUTE and RESET notification preference from a
-    package, both in the inline control panel as well as in the settings app.
-  </li>
- </ul>
- <p>
-  All 6 direct subclasses of the
-  <code>
-   Notification.Style class
-  </code>
-  MUST be supported as
-described in the
-  <a href="https://developer.android.com/reference/android/app/Notification.Style.html">
-   SDK documents
-  </a>.
- </p>
- <p>
-  Device implementations that support the DND (Do not Disturb) feature MUST meet
-the following requirements:
- </p>
- <ul>
-  <li>
-   MUST implement an activity that would respond to the intent
-   <a href="https://developer.android.com/reference/android/provider/Settings.html#ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS">
-    ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS
-   </a>,
-    which for implementations with UI_MODE_TYPE_NORMAL it MUST be an activity
-    where the user can grant or deny the app access to DND policy
-    configurations.
-  </li>
-  <li>
-   MUST, for when the device implementation has provided a means for the user
-    to grant or deny third-party apps to access the DND policy configuration,
-    display
-   <a href="https://developer.android.com/reference/android/app/NotificationManager.html#addAutomaticZenRule%28android.app.AutomaticZenRule%29">
-    Automatic DND rules
-   </a>
-   created by applications alongside the user-created and pre-defined rules.
-  </li>
-  <li>
-   MUST honor the
-   <a href="https://developer.android.com/reference/android/app/NotificationManager.Policy.html#suppressedVisualEffects">
-    <code>
-     suppressedVisualEffects
-    </code>
-   </a>
-   values passed along the
-   <a href="https://developer.android.com/reference/android/app/NotificationManager.Policy.html#NotificationManager.Policy%28int, int, int, int%29">
-    <code>
-     NotificationManager.Policy
-    </code>
-   </a>
-   and if an app has set any of the SUPPRESSED_EFFECT_SCREEN_OFF or
-    SUPPRESSED_EFFECT_SCREEN_ON flags, it SHOULD indicate to the user that the
-    visual effects are suppressed in the DND settings menu.
-  </li>
- </ul>
- <h4 id="3_8_4_search">
-  3.8.4. Search
- </h4>
- <p>
-  Android includes APIs that allow developers to
-  <a href="http://developer.android.com/reference/android/app/SearchManager.html">
-   incorporate search
-  </a>
-  into their applications and expose their application&rsquo;s data into the global
-system search. Generally speaking, this functionality consists of a single,
-system-wide user interface that allows users to enter queries, displays
-suggestions as users type, and displays results. The Android APIs allow
-developers to reuse this interface to provide search within their own apps and
-allow developers to supply results to the common global search user interface.
- </p>
- <p>
-  Android device implementations SHOULD include global search, a single, shared,
-system-wide search user interface capable of real-time suggestions in response
-to user input. Device implementations SHOULD implement the APIs that allow
-developers to reuse this user interface to provide search within their own
-applications. Device implementations that implement the global search interface
-MUST implement the APIs that allow third-party applications to add suggestions
-to the search box when it is run in global search mode. If no third-party
-applications are installed that make use of this functionality, the default
-behavior SHOULD be to display web search engine results and suggestions.
- </p>
- <p>
-  Android device implementations SHOULD, and Android Automotive implementations
-MUST, implement an assistant on the device to
-handle the
-  <a href="http://developer.android.com/reference/android/content/Intent.html#ACTION_ASSIST">
-   Assist action
-  </a>.
- </p>
- <p>
-  Android also includes the
-  <a href="https://developer.android.com/reference/android/app/assist/package-summary.html">
-   Assist APIs
-  </a>
-  to allow applications to elect how much information of the current context is
-shared with the assistant on the device. Device implementations supporting the
-Assist action MUST indicate clearly to the end user when the context is
-shared by displaying a white light around the edges of the screen. To ensure
-clear visibility to the end user, the indication MUST meet or exceed the
-duration and brightness of the Android Open Source Project implementation.
- </p>
- <p>
-  This indication MAY be disabled by default for preinstalled apps using the Assist and
-VoiceInteractionService API, if all following requirements are met:
- </p>
- <ul>
-  <li>
-   <p>
-    The preinstalled app MUST request the context to be shared only when the
-    user invoked the app by one of the following means, and the app is running in the
-    foreground:
-   </p>
-   <ul>
-    <li>
-     hotword invocation
-    </li>
-    <li>
-     input of the ASSIST navigation key/button/gesture
-    </li>
-   </ul>
-  </li>
-  <li>
-   <p>
-    The device implementation MUST provide an affordance to enable the
-    indication, less than two navigations away from
-    (the default voice input and assistant app settings menu)
-    <a href="#3_2_3_5_default_app_settings">
-     section 3.2.3.5
-    </a>.
-   </p>
-  </li>
- </ul>
- <h4 id="3_8_5_toasts">
-  3.8.5. Toasts
- </h4>
- <p>
-  Applications can use the
-  <a href="http://developer.android.com/reference/android/widget/Toast.html">
-   &ldquo;Toast&rdquo; API
-  </a>
-  to
-display short non-modal strings to the end user that disappear after a brief
-period of time. Device implementations MUST display Toasts from applications to
-end users in some high-visibility manner.
- </p>
- <h4 id="3_8_6_themes">
-  3.8.6. Themes
- </h4>
- <p>
-  Android provides &ldquo;themes&rdquo; as a mechanism for applications to apply styles across
-an entire Activity or application.
- </p>
- <p>
-  Android includes a &ldquo;Holo&rdquo; theme family as a set of defined styles for
-application developers to use if they want to match the
-  <a href="http://developer.android.com/guide/topics/ui/themes.html">
-   Holo theme look and feel
-  </a>
-  as defined by the Android SDK. Device implementations MUST NOT alter any of the
-  <a href="http://developer.android.com/reference/android/R.style.html">
-   Holo theme attributes
-  </a>
-  exposed to applications.
- </p>
- <p>
-  Android includes a &ldquo;Material&rdquo; theme family as a set of defined styles for
-application developers to use if they want to match the design theme&rsquo;s look and
-feel across the wide variety of different Android device types. Device
-implementations MUST support the &ldquo;Material&rdquo; theme family and MUST NOT alter any
-of the
-  <a href="http://developer.android.com/reference/android/R.style.html#Theme_Material">
-   Material theme attributes
-  </a>
-  or their assets exposed to applications.
- </p>
- <p>
-  Android also includes a &ldquo;Device Default&rdquo; theme family as a set of defined styles
-for application developers to use if they want to match the look and feel of the
-device theme as defined by the device implementer. Device implementations MAY
-modify the
-  <a href="http://developer.android.com/reference/android/R.style.html">
-   Device Default theme attributes
-  </a>
-  exposed
-to applications.
- </p>
- <p>
-  Android supports a variant theme with translucent system bars, which allows
-application developers to fill the area behind the status and navigation bar
-with their app content. To enable a consistent developer experience in this
-configuration, it is important the status bar icon style is maintained across
-different device implementations. Therefore, Android device implementations MUST
-use white for system status icons (such as signal strength and battery level)
-and notifications issued by the system, unless the icon is indicating a
-problematic status or an app requests a light status bar using the
-SYSTEM_UI_FLAG_LIGHT_STATUS_BAR flag. When an app requests a light status bar,
-Android device implementations MUST change the color of the system status icons
-to black (for details, refer to
-  <a href="http://developer.android.com/reference/android/R.style.html">
-   R.style
-  </a>
-  ).
- </p>
- <h4 id="3_8_7_live_wallpapers">
-  3.8.7. Live Wallpapers
- </h4>
- <p>
-  Android defines a component type and corresponding API and lifecycle that allows
-applications to expose one or more
-  <a href="http://developer.android.com/reference/android/service/wallpaper/WallpaperService.html">
-   &ldquo;Live Wallpapers&rdquo;
-  </a>
-  to the end user. Live wallpapers are animations, patterns, or similar images
-with limited input capabilities that display as a wallpaper, behind other
-applications.
- </p>
- <p>
-  Hardware is considered capable of reliably running live wallpapers if it can run
-all live wallpapers, with no limitations on functionality, at a reasonable frame
-rate with no adverse effects on other applications. If limitations in the
-hardware cause wallpapers and/or applications to crash, malfunction, consume
-excessive CPU or battery power, or run at unacceptably low frame rates, the
-hardware is considered incapable of running live wallpaper. As an example, some
-live wallpapers may use an OpenGL 2.0 or 3.x context to render their content.
-Live wallpaper will not run reliably on hardware that does not support multiple
-OpenGL contexts because the live wallpaper use of an OpenGL context may conflict
-with other applications that also use an OpenGL context.
- </p>
- <p>
-  Device implementations capable of running live wallpapers reliably as described
-above SHOULD implement live wallpapers, and when implemented MUST report the
-platform feature flag android.software.live_wallpaper.
- </p>
- <h4 id="3_8_8_activity_switching">
-  3.8.8. Activity Switching
- </h4>
- <div class="note">
-  As the Recent function navigation key is OPTIONAL, the requirement to implement
-the overview screen is OPTIONAL for Android Watch and Android Automotive implementations,
-and RECOMMENDED for Android Television devices. There SHOULD still be a
-method to switch between activities on Android Automotive implementations.
- </div>
- <p>
-  The upstream Android source code includes the
-  <a href="http://developer.android.com/guide/components/recents.html">
-   overview screen
-  </a>, a
-system-level user interface for task switching and displaying recently accessed
-activities and tasks using a thumbnail image of the application&rsquo;s graphical
-state at the moment the user last left the application. Device implementations
-including the recents function navigation key as detailed in
-  <a href="#7_2_3_navigation_keys">
-   section 7.2.3
-  </a>
-  MAY alter the interface but MUST meet the
-following requirements:
- </p>
- <ul>
-  <li>
-   MUST support at least up to 20 displayed activities.
-  </li>
-  <li>
-   SHOULD at least display the title of 4 activities at a time.
-  </li>
-  <li>
-   MUST implement the
-   <a href="http://developer.android.com/about/versions/android-5.0.html#ScreenPinning">
-    screen pinning behavior
-   </a>
-   and provide the user with a settings menu to toggle the feature.
-  </li>
-  <li>
-   SHOULD display highlight color, icon, screen title in recents.
-  </li>
-  <li>
-   SHOULD display a closing affordance ("x") but MAY delay this until user interacts with screens.
-  </li>
-  <li>
-   SHOULD implement a shortcut to switch easily to the previous activity
-  </li>
-  <li>
-   MAY display affiliated recents as a group that moves together.
-  </li>
-  <li>
-   SHOULD trigger the fast-switch action between the two most recently used
-    apps, when the recents function key is tapped twice.
-  </li>
-  <li>
-   SHOULD trigger the split-screen multiwindow-mode, if supported, when the
-    recents functions key is long pressed.
-  </li>
- </ul>
- <p>
-  Device implementations are STRONGLY RECOMMENDED to use the upstream Android user
-interface (or a similar thumbnail-based interface) for the overview screen.
- </p>
- <h4 id="3_8_9_input_management">
-  3.8.9. Input Management
- </h4>
- <p>
-  Android includes support for
-  <a href="http://developer.android.com/guide/topics/text/creating-input-method.html">
-   Input Management
-  </a>
-  and support for third-party input method editors. Device implementations that
-allow users to use third-party input methods on the device MUST declare the
-platform feature android.software.input_methods and support IME APIs as defined
-in the Android SDK documentation.
- </p>
- <p>
-  Device implementations that declare the android.software.input_methods feature
-MUST provide a user-accessible mechanism to add and configure third-party input
-methods. Device implementations MUST display the settings interface in response
-to the android.settings.INPUT_METHOD_SETTINGS intent.
- </p>
- <h4 id="3_8_10_lock_screen_media_control">
-  3.8.10. Lock Screen Media Control
- </h4>
- <p>
-  The Remote Control Client API is deprecated from Android 5.0 in favor of the
-  <a href="http://developer.android.com/reference/android/app/Notification.MediaStyle.html">
-   Media Notification Template
-  </a>
-  that allows media applications to integrate with playback controls that are
-displayed on the lock screen. Device implementations that support a lock screen,
-unless an Android Automotive or Watch implementation, MUST display the
-Lock screen Notifications including the Media Notification Template.
- </p>
- <h4 id="3_8_11_screen_savers_(previously_dreams)">
-  3.8.11. Screen savers (previously Dreams)
- </h4>
- <p>
-  Android includes support for
-  <a href="http://developer.android.com/reference/android/service/dreams/DreamService.html">
-   interactivescreensavers
-  </a>,
-previously referred to as Dreams. Screen savers allow users to interact with
-applications when a device connected to a power source is idle or docked in a
-desk dock.  Android Watch devices MAY implement screen savers, but other types
-of device implementations SHOULD include support for screen savers and provide
-a settings option for users toconfigure screen savers in response to the
-  <code>
-   android.settings.DREAM_SETTINGS
-  </code>
-  intent.
- </p>
- <h4 id="3_8_12_location">
-  3.8.12. Location
- </h4>
- <p>
-  When a device has a hardware sensor (e.g. GPS) that is capable of providing the
-location coordinates,
-  <a href="http://developer.android.com/reference/android/provider/Settings.Secure.html#LOCATION_MODE">
-   location modes
-  </a>
-  MUST be displayed in the Location menu within Settings.
- </p>
- <h4 id="3_8_13_unicode_and_font">
-  3.8.13. Unicode and Font
- </h4>
- <p>
-  Android includes support for the emoji characters defined in
-  <a href="http://www.unicode.org/versions/Unicode9.0.0/">
-   Unicode 9.0
-  </a>. All device
-implementations MUST be capable of rendering these emoji characters
-in color glyph and when Android device implementations include an IME,
-it SHOULD provide an input method to the user for these emoji characters.
- </p>
- <p>
-  Android handheld devices SHOULD support the skin tone and diverse family emojis
-as specified in the
-  <a href="http://unicode.org/reports/tr51">
-   Unicode Technical Report #51
-  </a>.
- </p>
- <p>
-  Android includes support for Roboto 2 font with different
-weights&mdash;sans-serif-thin, sans-serif-light, sans-serif-medium, sans-serif-black,
-sans-serif-condensed, sans-serif-condensed-light&mdash;which MUST all be included for
-the languages available on the device and full Unicode 7.0 coverage of Latin,
-Greek, and Cyrillic, including the Latin Extended A, B, C, and D ranges, and all
-glyphs in the currency symbols block of Unicode 7.0.
- </p>
- <h4 id="3_8_14_multi-windows">
-  3.8.14. Multi-windows
- </h4>
- <p>
-  A device implementation MAY choose not to implement any multi-window modes, but
-if it has the capability to display multiple activities at the same time it
-MUST implement such multi-window mode(s) in accordance with the application
-behaviors and APIs described in the Android SDK
-  <a href="https://developer.android.com/preview/features/multi-window.html">
-   multi-window mode support documentation
-  </a>
-  and meet the following requirements:
- </p>
- <ul>
-  <li>
-   Applications can indicate whether they are capable of operating in
-    multi-window mode in the AndroidManifest.xml file, either explicitly via the
-   <a href="https://developer.android.com/reference/android/R.attr.html#resizeableActivity">
-    <code>
-     android:resizeableActivity
-    </code>
-   </a>
-   attribute or implicitly by having the targetSdkVersion &gt; 24. Apps that
-    explicitly set this attribute to false in their manifest MUST not be
-    launched in multi-window mode. Apps that don't set the attribute in their
-    manifest file (targetSdkVersion &lt; 24) can be launched in multi-window mode,
-    but the system MUST provide warning that the app may not work as expected in
-    multi-window mode.
-  </li>
-  <li>
-   Device implementations MUST NOT offer split-screen or freeform mode
-    if both the screen height and width is less than 440 dp.
-  </li>
-  <li>
-   Device implementations with screen size
-   <code>
-    xlarge
-   </code>
-   SHOULD support freeform mode.
-  </li>
-  <li>
-   Android Television device implementations MUST support picture-in-picture (PIP) mode multi-window
-    and place the PIP multi-window in the top right corner when PIP is ON.
-  </li>
-  <li>
-   Device implementations with PIP mode multi-window support
-    MUST allocate at least 240x135 dp for the PIP window.
-  </li>
-  <li>
-   If the PIP multi-window mode is supported the
-   <a href="https://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_WINDOW">
-    <code>
-     KeyEvent.KEYCODE_WINDOW
-    </code>
-   </a>
-   key MUST be used to control the PIP window; otherwise, the key MUST be
-    available to the foreground activity.
-  </li>
- </ul>
- <h3 id="3_9_device_administration">
-  3.9. Device Administration
- </h3>
- <p>
-  Android includes features that allow security-aware applications to perform
-device administration functions at the system level, such as enforcing password
-policies or performing remote wipe, through the
-  <a href="http://developer.android.com/guide/topics/admin/device-admin.html">
-   Android Device Administration API
-  </a>
-  ].
-Device implementations MUST provide an implementation of the
-  <a href="http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html">
-   DevicePolicyManager
-  </a>
-  class. Device implementations that supports a secure lock screen MUST implement
-the full range of
-  <a href="http://developer.android.com/guide/topics/admin/device-admin.html">
-   device administration
-  </a>
-  policies defined in the Android SDK documentation and report the platform
-feature android.software.device_admin.
- </p>
- <h4 id="3_9_1_device_provisioning">
-  3.9.1 Device Provisioning
- </h4>
- <h5 id="3_9_1_1_device_owner_provisioning">
-  3.9.1.1 Device owner provisioning
- </h5>
- <p>
-  If a device implementation declares the
-  <code>
-   android.software.device_admin
-  </code>
-  feature
-then it MUST implement the provisioning of the
-  <a href="http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#isDeviceOwnerApp(java.lang.String)">
-   Device Owner app
-  </a>
-  of a Device Policy Client (DPC) application as indicated below:
- </p>
- <ul>
-  <li>
-   When the device implementation has no user data configured yet, it:
-   <ul>
-    <li>
-     MUST report
-     <code>
-      true
-     </code>
-     for
-     <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#isProvisioningAllowed(java.lang.String)">
-      <code>
-       DevicePolicyManager.isProvisioningAllowed(ACTION_PROVISION_MANAGED_DEVICE)
-      </code>
-     </a>.
-    </li>
-    <li>
-     MUST enroll the DPC application as the Device Owner app in response to
-     the intent action
-     <a href="http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#ACTION_PROVISION_MANAGED_DEVICE">
-      <code>
-       android.app.action.PROVISION_MANAGED_DEVICE
-      </code>
-     </a>.
-    </li>
-    <li>
-     MUST enroll the DPC application as the Device Owner app if the device
-     declares Near-Field Communications (NFC) support via the feature flag
-     <code>
-      android.hardware.nfc
-     </code>
-     and receives an NFC message containing a record
-     with MIME type
-     <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#MIME_TYPE_PROVISIONING_NFC">
-      <code>
-       MIME_TYPE_PROVISIONING_NFC
-      </code>
-     </a>.
-    </li>
-   </ul>
-  </li>
-  <li>
-   When the device implementation has user data, it:
-   <ul>
-    <li>
-     MUST report
-     <code>
-      false
-     </code>
-     for the
-     <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#isProvisioningAllowed(java.lang.String)">
-      <code>
-       DevicePolicyManager.isProvisioningAllowed(ACTION_PROVISION_MANAGED_DEVICE)
-      </code>
-     </a>.
-    </li>
-    <li>
-     MUST not enroll any DPC application as the Device Owner App any more.
-    </li>
-   </ul>
-  </li>
- </ul>
- <p>
-  Device implementations MAY have a preinstalled application performing device
-administration functions but this application MUST NOT be set as the Device
-Owner app without explicit consent or action from the user or the administrator
-of the device.
- </p>
- <h5 id="3_9_1_2_managed_profile_provisioning">
-  3.9.1.2 Managed profile provisioning
- </h5>
- <p>
-  If a device implementation declares the android.software.managed_users, it MUST
-be possible to enroll a Device Policy Controller (DPC) application as the
-  <a href="http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#isProfileOwnerApp(java.lang.String)">
-   owner of a new Managed Profile
-  </a>.
- </p>
- <p>
-  The managed profile provisioning process (the flow initiated by
-  <a href="http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#ACTION_PROVISION_MANAGED_PROFILE">
-   android.app.action.PROVISION_MANAGED_PROFILE
-  </a>
-  )
-user experience MUST align with the AOSP implementation.
- </p>
- <p>
-  Device implementations MUST provide the following user affordances within the
-Settings user interface to indicate to the user when a particular system function
-has been disabled by the Device Policy Controller (DPC):
- </p>
- <ul>
-  <li>
-   A consistent icon or other user affordance (for example the upstream AOSP
-     info icon) to represent when a particular setting is restricted by a
-     Device Admin.
-  </li>
-  <li>
-   A short explanation message, as provided by the Device Admin via the
-   <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#setShortSupportMessage%28android.content.ComponentName, java.lang.CharSequence%29">
-    <code>
-     setShortSupportMessage
-    </code>
-   </a>.
-  </li>
-  <li>
-   The DPC application&rsquo;s icon.
-  </li>
- </ul>
- <h3 id="3_9_2_managed_profile_support">
-  3.9.2 Managed Profile Support
- </h3>
- <p>
-  Managed profile capable devices are those devices that:
- </p>
- <ul>
-  <li>
-   Declare android.software.device_admin (see
-   <a href="#3_9_device_administration">
-    section 3.9 Device Administration
-   </a>
-   ).
-  </li>
-  <li>
-   Are not low RAM devices (see
-   <a href="#7_6_1_minimum_memory_and_storage">
-    section 7.6.1
-   </a>
-   ).
-  </li>
-  <li>
-   Allocate internal (non-removable) storage as shared storage (see
-   <a href="#7_6_2_application_shared_storage">
-    section 7.6.2
-   </a>
-   ).
-  </li>
- </ul>
- <p>
-  Managed profile capable devices MUST:
- </p>
- <ul>
-  <li>
-   Declare the platform feature flag
-   <code>
-    android.software.managed_users
-   </code>
-   .
-  </li>
-  <li>
-   Support managed profiles via the
-   <code>
-    android.app.admin.DevicePolicyManager
-   </code>
-   APIs.
-  </li>
-  <li>
-   Allow one and only
-   <a href="http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#ACTION_PROVISION_MANAGED_PROFILE">
-    one managed profile to be created
-   </a>.
-  </li>
-  <li>
-   Use an icon badge (similar to the AOSP upstream work badge) to represent the
-    managed applications and widgets and other badged UI elements like
-    Recents &amp; Notifications.
-  </li>
-  <li>
-   Display a notification icon (similar to the AOSP upstream work badge) to
-    indicate when user is within a managed profile application.
-  </li>
-  <li>
-   Display a toast indicating that the user is in the managed profile if and
-    when the device wakes up (ACTION_USER_PRESENT) and the foreground
-    application is within the managed profile.
-  </li>
-  <li>
-   Where a managed profile exists, show a visual affordance in the Intent
-    'Chooser' to allow the user to forward the intent from the managed profile
-    to the primary user or vice versa, if enabled by the Device Policy
-    Controller.
-  </li>
-  <li>
-   Where a managed profile exists, expose the following user affordances for
-    both the primary user and the managed profile:
-   <ul>
-    <li>
-     Separate accounting for battery, location, mobile data and storage usage
-    for the primary user and managed profile.
-    </li>
-    <li>
-     Independent management of VPN Applications installed within the primary
-    user or managed profile.
-    </li>
-    <li>
-     Independent management of applications installed within the primary user
-    or managed profile.
-    </li>
-    <li>
-     Independent management of accounts within the primary user or managed
-    profile.
-    </li>
-   </ul>
-  </li>
-  <li>
-   Ensure the preinstalled dialer, contacts and messaging applications can
-    search for and look up caller information from the managed profile (if one
-    exists) alongside those from the primary profile, if the Device Policy
-    Controller permits it. When contacts from the managed profile are displayed
-    in the preinstalled call log, in-call UI, in-progress and missed-call
-    notifications, contacts and messaging apps they SHOULD be badged with the
-    same badge used to indicate managed profile applications.
-  </li>
-  <li>
-   MUST ensure that it satisfies all the security requirements applicable for a
-    device with multiple users enabled (see
-   <a href="#9_5_multi-user_support">
-    section 9.5
-   </a>
-   ),
-    even though the managed profile is not counted as another user in addition
-    to the primary user.
-  </li>
-  <li>
-   Support the ability to specify a separate lock screen meeting the following
-    requirements to grant access to apps running in a managed profile.
-   <ul>
-    <li>
-     Device implementations MUST honor the
-     <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#ACTION_SET_NEW_PASSWORD">
-      <code>
-       DevicePolicyManager.ACTION_SET_NEW_PASSWORD
-      </code>
-     </a>
-     intent and show an interface to configure a separate lock screen
-    credential for the managed profile.
-    </li>
-    <li>
-     The lock screen credentials of the managed profile MUST use the same
-    credential storage and management mechanisms as the parent profile,
-    as documented on the
-     <a href="http://source.android.com/security/authentication/index.html">
-      Android Open Source Project Site
-     </a>
-    </li>
-    <li>
-     The DPC
-     <a href="https://developer.android.com/guide/topics/admin/device-admin.html#pwd">
-      password policies
-     </a>
-     MUST apply to only the managed profile's lock screen credentials unless
-    called upon the
-     <code>
-      DevicePolicyManager
-     </code>
-     instance returned by
-     <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#getParentProfileInstance%28android.content.ComponentName%29">
-      getParentProfileInstance
-     </a>.
-    </li>
-   </ul>
-  </li>
- </ul>
- <h3 id="3_10_accessibility">
-  3.10. Accessibility
- </h3>
- <p>
-  Android provides an accessibility layer that helps users with disabilities to
-navigate their devices more easily. In addition, Android provides platform APIs
-that enable
-  <a href="http://developer.android.com/reference/android/accessibilityservice/AccessibilityService.html">
-   accessibility service implementations
-  </a>
-  to receive callbacks for user and system events and generate alternate feedback
-mechanisms, such as text-to-speech, haptic feedback, and trackball/d-pad
-navigation.
- </p>
- <p>
-  Device implementations include the following requirements:
- </p>
- <ul>
-  <li>
-   Android Automotive implementations SHOULD provide an implementation of the
-    Android accessibility framework consistent with the default Android
-    implementation.
-  </li>
-  <li>
-   Device implementations (Android Automotive excluded) MUST provide an
-    implementation of the Android accessibility framework consistent with the
-    default Android implementation.
-  </li>
-  <li>
-   Device implementations (Android Automotive excluded) MUST support
-    third-party accessibility service implementations through the
-   <a href="http://developer.android.com/reference/android/view/accessibility/package-summary.html">
-    android.accessibilityservice APIs
-   </a>.
-  </li>
-  <li>
-   Device implementations (Android Automotive excluded) MUST generate
-    AccessibilityEvents and deliver these events to all registered
-    AccessibilityService implementations in a manner consistent with the default
-    Android implementation
-  </li>
-  <li>
-   <p>
-    Device implementations (Android Automotive and Android Watch devices with no
-    audio output excluded), MUST provide a user-accessible mechanism to enable
-    and disable accessibility services, and MUST display this interface in
-    response to the android.provider.Settings.ACTION_ACCESSIBILITY_SETTINGS
-    intent.
-   </p>
-  </li>
-  <li>
-   <p>
-    Android device implementations with audio output are STRONGLY RECOMMENDED to provide
-  implementations of accessibility services on the device comparable in or exceeding functionality
-  of the TalkBack** and Switch Access accessibility services (https://github.com/google/talkback).
-   </p>
-  </li>
-  <li>
-   Android Watch devices with audio output SHOULD provide implementations of an accessibility service
-  on the device comparable in or exceeding functionality of the TalkBack accessibility service
-  (https://github.com/google/talkback).
-  </li>
-  <li>
-   Device implementations SHOULD provide a mechanism in the out-of-box setup flow for users to enable
-  relevant accessibility services, as well as options to adjust the font size, display size and
-  magnification gestures.
-  </li>
- </ul>
- <p>
-  ** For languages supported by Text-to-speech.
- </p>
- <p>
-  Also, note that if there is a preloaded accessibility service, it MUST be a Direct Boot aware
-{directBootAware} app if the device has encrypted storage using File Based
-Encryption (FBE).
- </p>
- <h3 id="3_11_text-to-speech">
-  3.11. Text-to-Speech
- </h3>
- <p>
-  Android includes APIs that allow applications to make use of text-to-speech
-(TTS) services and allows service providers to provide implementations of TTS
-services. Device implementations reporting the feature
-android.hardware.audio.output MUST meet these requirements related to the
-  <a href="http://developer.android.com/reference/android/speech/tts/package-summary.html">
-   Android TTS framework
-  </a>.
- </p>
- <p>
-  Android Automotive implementations:
- </p>
- <ul>
-  <li>
-   MUST support the Android TTS framework APIs.
-  </li>
-  <li>
-   MAY support installation of third-party TTS engines. If supported, partners
-    MUST provide a user-accessible interface that allows the user to select a
-    TTS engine for use at system level.
-  </li>
- </ul>
- <p>
-  All other device implementations:
- </p>
- <ul>
-  <li>
-   MUST support the Android TTS framework APIs and SHOULD include a TTS engine
-    supporting the languages available on the device. Note that the upstream
-    Android open source software includes a full-featured TTS engine
-    implementation.
-  </li>
-  <li>
-   MUST support installation of third-party TTS engines.
-  </li>
-  <li>
-   MUST provide a user-accessible interface that allows users to select a TTS
-    engine for use at the system level.
-  </li>
- </ul>
- <h3 id="3_12_tv_input_framework">
-  3.12. TV Input Framework
- </h3>
- <p>
-  The
-  <a href="http://source.android.com/devices/tv/index.html">
-   Android Television Input Framework (TIF)
-  </a>
-  simplifies the delivery of live content to Android Television devices. TIF
-provides a standard API to create input modules that control Android Television
-devices. Android Television device implementations MUST support TV Input
-Framework.
- </p>
- <p>
-  Device implementations that support TIF MUST declare the platform feature
-android.software.live_tv.
- </p>
- <h4 id="3_12_1_tv_app">
-  3.12.1. TV App
- </h4>
- <p>
-  Any device implementation that declares support for Live TV MUST have an
-installed TV application (TV App). The Android Open Source Project provides an
-implementation of the TV App.
- </p>
- <p>
-  The TV App MUST provide facilities to install and use
-  <a href="http://developer.android.com/reference/android/media/tv/TvContract.Channels.html">
-   TV Channels
-  </a>
-  and meet the following requirements:
- </p>
- <ul>
-  <li>
-   Device implementations MUST allow third-party TIF-based inputs
-    (
-   <a href="https://source.android.com/devices/tv/index.html#third-party_input_example">
-    third-party inputs
-   </a>
-   )
-    to be installed and managed.
-  </li>
-  <li>
-   Device implementations MAY provide visual separation between pre-installed
-   <a href="https://source.android.com/devices/tv/index.html#tv_inputs">
-    TIF-based inputs
-   </a>
-   (installed inputs) and third-party inputs.
-  </li>
-  <li>
-   Device implementations MUST NOT display the third-party inputs more than a
-    single navigation action away from the TV App (i.e. expanding a list of
-    third-party inputs from the TV App).
-  </li>
- </ul>
- <h5 id="3_12_1_1_electronic_program_guide">
-  3.12.1.1. Electronic Program Guide
- </h5>
- <p>
-  Android Television device implementations MUST show an informational and
-interactive overlay, which MUST include an electronic program guide (EPG)
-generated from the values in the
-  <a href="https://developer.android.com/reference/android/media/tv/TvContract.Programs.html">
-   TvContract.Programs
-  </a>
-  fields. The EPG MUST meet the following requirements:
- </p>
- <ul>
-  <li>
-   The EPG MUST display information from all installed inputs and third-party
-    inputs.
-  </li>
-  <li>
-   The EPG MAY provide visual separation between the installed inputs and
-    third-party inputs.
-  </li>
-  <li>
-   The EPG is STRONGLY RECOMMENDED to display installed inputs and third-party
-    inputs with equal prominence. The EPG MUST NOT display the third-party
-    inputs more than a single navigation action away from the installed inputs
-    on the EPG.
-  </li>
-  <li>
-   On channel change, device implementations MUST display EPG data for the
-    currently playing program.
-  </li>
- </ul>
- <h5 id="3_12_1_2_navigation">
-  3.12.1.2. Navigation
- </h5>
- <p>
-  The TV App MUST allow navigation for the following functions via the D-pad,
-Back, and Home keys on the Android Television device&rsquo;s input device(s)
-(i.e. remote control, remote control application, or game controller):
- </p>
- <ul>
-  <li>
-   Changing TV channels
-  </li>
-  <li>
-   Opening EPG
-  </li>
-  <li>
-   Configuring and tuning to third-party TIF-based inputs
-  </li>
-  <li>
-   Opening Settings menu
-  </li>
- </ul>
- <p>
-  The TV App SHOULD pass key events to HDMI inputs through CEC.
- </p>
- <h5 id="3_12_1_3_tv_input_app_linking">
-  3.12.1.3. TV input app linking
- </h5>
- <p>
-  Android Television device implementations MUST support
-  <a href="http://developer.android.com/reference/android/media/tv/TvContract.Channels.html#COLUMN_APP_LINK_INTENT_URI">
-   TV input app linking
-  </a>,
-which allows all inputs to provide activity links from the current activity to
-another activity (i.e. a link from live programming to related content). The TV
-App MUST show TV input app linking when it is provided.
- </p>
- <h5 id="3_12_1_4_time_shifting">
-  3.12.1.4. Time shifting
- </h5>
- <p>
-  Android Television device implementations MUST support time shifting, which
-allows the user to pause and resume live content. Device implementations MUST
-provide the user a way to pause and resume the currently playing program, if
-time shifting for that program
-  <a href="https://developer.android.com/reference/android/media/tv/TvInputManager.html#TIME_SHIFT_STATUS_AVAILABLE">
-   is available
-  </a>.
- </p>
- <h5 id="3_12_1_5_tv_recording">
-  3.12.1.5. TV recording
- </h5>
- <p>
-  Android Television device implementations are STRONGLY RECOMMENDED to support
-TV recording. If the TV input supports recording, the EPG MAY provide a way to
-  <a href="https://developer.android.com/reference/android/media/tv/TvInputInfo.html#canRecord%28%29">
-   record a program
-  </a>
-  if the recording of such a program is not
-  <a href="https://developer.android.com/reference/android/media/tv/TvContract.Programs.html#COLUMN_RECORDING_PROHIBITED">
-   prohibited
-  </a>.
-Device implementations SHOULD provide a user interface to play recorded programs.
- </p>
- <h3 id="3_13_quick_settings">
-  3.13. Quick Settings
- </h3>
- <p>
-  Android device implementations SHOULD include a Quick Settings UI component that
-allow quick access to frequently used or urgently needed actions.
- </p>
- <p>
-  Android includes the
-  <a href="https://developer.android.com/reference/android/service/quicksettings/package-summary.html">
-   <code>
-    quicksettings
-   </code>
-  </a>
-  API allowing third party apps to implement tiles that can be added by the user
-alongside the system-provided tiles in the Quick Settings UI component. If a
-device implementation has a Quick Settings UI component, it:
- </p>
- <ul>
-  <li>
-   MUST allow the user to add or remove tiles from a third-party app to Quick
-    Settings.
-  </li>
-  <li>
-   MUST NOT automatically add a tile from a third-party app directly to Quick
-    Settings.
-  </li>
-  <li>
-   MUST display all the user-added tiles from third-party apps alongside the
-    system-provided quick setting tiles.
-  </li>
- </ul>
- <h3 id="3_14_vehicle_ui_apis">
-  3.14. Vehicle UI APIs
- </h3>
- <h4 id="3_14_1__vehicle_media_ui">
-  3.14.1.  Vehicle Media UI
- </h4>
- <p>
-  Any device implementation that
-  <a href="https://developer.android.com/reference/android/content/pm/PackageManager.html?#FEATURE_AUTOMOTIVE?">
-   declares automotive support
-  </a>
-  MUST include a UI framework to support third-party apps consuming the
-  <a href="http://developer.android.com/reference/android/media/browse/MediaBrowser.html">
-   MediaBrowser
-  </a>
-  and
-  <a href="http://developer.android.com/reference/android/media/session/MediaSession.html">
-   MediaSession
-  </a>
-  APIs.
- </p>
- <p>
-  The UI framework supporting third-party apps that depend on MediaBrowser and
-MediaSession has the following visual requirements:
- </p>
- <ul>
-  <li>
-   MUST display
-   <a href="http://developer.android.com/reference/android/media/browse/MediaBrowser.MediaItem.html">
-    MediaItem
-   </a>
-   icons and notification icons unaltered.
-  </li>
-  <li>
-   MUST display those items as described by MediaSession, e.g., metadata, icons,
-  imagery.
-  </li>
-  <li>
-   MUST show app title.
-  </li>
-  <li>
-   MUST have drawer to present
-   <a href="http://developer.android.com/reference/android/media/browse/MediaBrowser.html">
-    MediaBrowser
-   </a>
-   hierarchy.
-  </li>
- </ul>
- <h2 id="4_application_packaging_compatibility">
-  4. Application Packaging Compatibility
- </h2>
- <p>
-  Device implementations MUST install and run Android &ldquo;.apk&rdquo; files as generated
-by the &ldquo;aapt&rdquo; tool included in the
-  <a href="http://developer.android.com/tools/help/index.html">
-   official Android SDK
-  </a>.
-For this reason device implementations SHOULD use the reference implementation&rsquo;s
-package management system.
- </p>
- <p>
-  The package manager MUST support verifying &ldquo;.apk&rdquo; files using the
-  <a href="https://source.android.com/security/apksigning/v2.html">
-   APK Signature Scheme v2
-  </a>
-  and
-  <a href="https://source.android.com/security/apksigning/v2.html#v1-verification">
-   JAR signing
-  </a>.
- </p>
- <p>
-  Devices implementations MUST NOT extend either the
-  <a href="http://developer.android.com/guide/components/fundamentals.html">
-   .apk
-  </a>,
-  <a href="http://developer.android.com/guide/topics/manifest/manifest-intro.html">
-   Android Manifest
-  </a>,
-  <a href="https://android.googlesource.com/platform/dalvik/">
-   Dalvik bytecode
-  </a>, or
-RenderScript bytecode formats in such a way that would prevent those files from
-installing and running correctly on other compatible devices.
- </p>
- <p>
-  Device implementations MUST NOT allow apps other than the current
-"installer of record" for the package to silently uninstall the app without any
-prompt, as documented in the SDK for the
-  <a href="https://developer.android.com/reference/android/Manifest.permission.html#DELETE_PACKAGES">
-   <code>
-    DELETE_PACKAGE
-   </code>
-  </a>
-  permission. The only exceptions are the system package verifier app handling
-  <a href="https://developer.android.com/reference/android/content/Intent.html#ACTION_PACKAGE_NEEDS_VERIFICATION">
-   PACKAGE_NEEDS_VERIFICATION
-  </a>
-  intent and the storage manager app handling
-  <a href="https://developer.android.com/reference/android/os/storage/StorageManager.html#ACTION_MANAGE_STORAGE">
-   ACTION_MANAGE_STORAGE
-  </a>
-  intent.
- </p>
- <h2 id="5_multimedia_compatibility">
-  5. Multimedia Compatibility
- </h2>
- <h3 id="5_1_media_codecs">
-  5.1. Media Codecs
- </h3>
- <p>
-  Device implementations&mdash;
- </p>
- <ul>
-  <li>
-   <p>
-    MUST support the
-    <a href="http://developer.android.com/guide/appendix/media-formats.html">
-     core media
-formats
-    </a>
-    specified in the Android SDK documentation, except where explicitly permitted
-in this document.
-   </p>
-  </li>
-  <li>
-   <p>
-    MUST support the media formats, encoders, decoders, file types, and
-container formats defined in the tables below and reported via
-    <a href="http://developer.android.com/reference/android/media/MediaCodecList.html">
-     MediaCodecList
-    </a>.
-   </p>
-  </li>
-  <li>
-   <p>
-    MUST also be able to decode all profiles reported in its
-    <a href="http://developer.android.com/reference/android/media/CamcorderProfile.html">
-     CamcorderProfile
-    </a>
-   </p>
-  </li>
-  <li>
-   <p>
-    MUST be able to decode all formats it can encode. This includes all
-    bitstreams that its encoders generate.
-   </p>
-  </li>
- </ul>
- <p>
-  Codecs SHOULD aim for minimum codec latency, in other words, codecs&mdash;
- </p>
- <ul>
-  <li>
-   SHOULD NOT consume and store input buffers and return input buffers only
-once processed
-  </li>
-  <li>
-   SHOULD NOT hold onto decoded buffers for longer than as specified by the
-standard (e.g. SPS).
-  </li>
-  <li>
-   SHOULD NOT hold onto encoded buffers longer than required by the GOP
-structure.
-  </li>
- </ul>
- <p>
-  All of the  codecs listed in the table below are provided as software
-implementations in the preferred Android implementation from the Android Open
-Source Project.
- </p>
- <p>
-  Please note that neither Google nor the Open Handset Alliance make any
-representation that these codecs are free from third-party patents. Those
-intending to use this source code in hardware or software products are advised
-that implementations of this code, including in open source software or
-shareware, may require patent licenses from the relevant patent holders.
- </p>
- <h4 id="5_1_1_audio_codecs">
-  5.1.1. Audio Codecs
- </h4>
- <table>
-  <tr>
-   <th>
-    Format/Codec
-   </th>
-   <th>
-    Encoder
-   </th>
-   <th>
-    Decoder
-   </th>
-   <th>
-    Details
-   </th>
-   <th>
-    Supported File Types/Container Formats
-   </th>
-  </tr>
-  <tr>
-   <td>
-    MPEG-4 AAC Profile
-    <br/>
-    (AAC LC)
-   </td>
-   <td>
-    REQUIRED
-    <sup>
-     1
-    </sup>
-   </td>
-   <td>
-    REQUIRED
-   </td>
-   <td>
-    Support for mono/stereo/5.0/5.1
-    <sup>
-     2
-    </sup>
-    content with standard
-    sampling rates from 8 to 48 kHz.
-   </td>
-   <td>
-    <ul>
-     <li class="table_list">
-      3GPP (.3gp)
-     </li>
-     <li class="table_list">
-      MPEG-4 (.mp4, .m4a)
-     </li>
-     <li class="table_list">
-      ADTS raw AAC (.aac, decode in Android 3.1+, encode in
-    Android 4.0+, ADIF not supported)
-     </li>
-     <li class="table_list">
-      MPEG-TS (.ts, not seekable, Android 3.0+)
-     </li>
-    </ul>
-   </td>
-  </tr>
-  <tr>
-   <td>
-    MPEG-4 HE AAC Profile (AAC+)
-   </td>
-   <td>
-    REQUIRED
-    <sup>
-     1
-    </sup>
-    <br/>
-    (Android 4.1+)
-   </td>
-   <td>
-    REQUIRED
-   </td>
-   <td>
-    Support for mono/stereo/5.0/5.1
-    <sup>
-     2
-    </sup>
-    content with standard
-    sampling rates from 16 to 48 kHz.
-   </td>
-   <td>
-   </td>
-  </tr>
-  <tr>
-   <td>
-    MPEG-4 HE AACv2
-    <br/>
-    Profile (enhanced AAC+)
-   </td>
-   <td>
-   </td>
-   <td>
-    REQUIRED
-   </td>
-   <td>
-    Support for mono/stereo/5.0/5.1
-    <sup>
-     2
-    </sup>
-    content with standard
-    sampling rates from 16 to 48 kHz.
-   </td>
-   <td>
-   </td>
-  </tr>
-  <tr>
-   <td>
-    AAC ELD (enhanced low delay AAC)
-   </td>
-   <td>
-    REQUIRED
-    <sup>
-     1
-    </sup>
-    <br/>
-    (Android 4.1+)
-   </td>
-   <td>
-    REQUIRED
-    <br/>
-    (Android 4.1+)
-   </td>
-   <td>
-    Support for mono/stereo content with standard sampling rates from 16 to
-    48 kHz.
-   </td>
-   <td>
-   </td>
-  </tr>
-  <tr>
-   <td>
-    AMR-NB
-   </td>
-   <td>
-    REQUIRED
-    <sup>
-     3
-    </sup>
-   </td>
-   <td>
-    REQUIRED
-    <sup>
-     3
-    </sup>
-   </td>
-   <td>
-    4.75 to 12.2 kbps sampled @ 8 kHz
-   </td>
-   <td>
-    3GPP (.3gp)
-   </td>
-  </tr>
-  <tr>
-   <td>
-    AMR-WB
-   </td>
-   <td>
-    REQUIRED
-    <sup>
-     3
-    </sup>
-   </td>
-   <td>
-    REQUIRED
-    <sup>
-     3
-    </sup>
-   </td>
-   <td>
-    9 rates from 6.60 kbit/s to 23.85 kbit/s sampled @ 16 kHz
-   </td>
-   <td>
-   </td>
-  </tr>
-  <tr>
-   <td>
-    FLAC
-   </td>
-   <td>
-   </td>
-   <td>
-    REQUIRED
-    <br/>
-    (Android 3.1+)
-   </td>
-   <td>
-    Mono/Stereo (no multichannel). Sample rates up to 48 kHz (but up to 44.1
-    kHz is RECOMMENDED on devices with 44.1 kHz output, as the 48 to 44.1 kHz
-    downsampler does not include a low-pass filter). 16-bit RECOMMENDED; no
-    dither applied for 24-bit.
-   </td>
-   <td>
-    FLAC (.flac) only
-   </td>
-  </tr>
-  <tr>
-   <td>
-    MP3
-   </td>
-   <td>
-   </td>
-   <td>
-    REQUIRED
-   </td>
-   <td>
-    Mono/Stereo 8-320Kbps constant (CBR) or variable bitrate (VBR)
-   </td>
-   <td>
-    MP3 (.mp3)
-   </td>
-  </tr>
-  <tr>
-   <td>
-    MIDI
-   </td>
-   <td>
-   </td>
-   <td>
-    REQUIRED
-   </td>
-   <td>
-    MIDI Type 0 and 1. DLS Version 1 and 2. XMF and Mobile XMF. Support for
-    ringtone formats RTTTL/RTX, OTA, and iMelody
-   </td>
-   <td>
-    <ul>
-     <li class="table_list">
-      Type 0 and 1 (.mid, .xmf, .mxmf)
-     </li>
-     <li class="table_list">
-      RTTTL/RTX (.rtttl, .rtx)
-     </li>
-     <li class="table_list">
-      OTA (.ota)
-     </li>
-     <li class="table_list">
-      iMelody (.imy)
-     </li>
-    </ul>
-   </td>
-  </tr>
-  <tr>
-   <td>
-    Vorbis
-   </td>
-   <td>
-   </td>
-   <td>
-    REQUIRED
-   </td>
-   <td>
-   </td>
-   <td>
-    <ul>
-     <li class="table_list">
-      Ogg (.ogg)
-     </li>
-     <li class="table_list">
-      Matroska (.mkv, Android 4.0+)
-     </li>
-    </ul>
-   </td>
-  </tr>
-  <tr>
-   <td>
-    PCM/WAVE
-   </td>
-   <td>
-    REQUIRED
-    <sup>
-     4
-    </sup>
-    <br/>
-    (Android 4.1+)
-   </td>
-   <td>
-    REQUIRED
-   </td>
-   <td>
-    16-bit linear PCM (rates up to limit of hardware). Devices MUST support
-    sampling rates for raw PCM recording at 8000, 11025, 16000, and 44100 Hz
-    frequencies.
-   </td>
-   <td>
-    WAVE (.wav)
-   </td>
-  </tr>
-  <tr>
-   <td>
-    Opus
-   </td>
-   <td>
-   </td>
-   <td>
-    REQUIRED
-    <br/>
-    (Android 5.0+)
-   </td>
-   <td>
-   </td>
-   <td>
-    Matroska (.mkv), Ogg(.ogg)
-   </td>
-  </tr>
- </table>
- <p class="table_footnote">
-  1 Required for device implementations that define
-android.hardware.microphone but optional for Android Watch device
-implementations.
- </p>
- <p class="table_footnote">
-  2 Recording or playback MAY be performed in mono
-or stereo, but the decoding of AAC input buffers of multichannel streams
-(i.e. more than two channels) to PCM through the default AAC audio decoder
-in the android.media.MediaCodec API, the following MUST be supported:
- </p>
- <ul>
-  <li>
-   decoding is performed without downmixing (e.g. a 5.0 AAC stream must be
-decoded to five channels of PCM, a 5.1 AAC stream must be decoded to six
-channels of PCM),
-  </li>
-  <li>
-   dynamic range metadata, as defined in "Dynamic Range Control (DRC)"
-in ISO/IEC 14496-3, and the android.media.MediaFormat DRC keys to
-configure the dynamic range-related behaviors of the audio decoder. The
-AAC DRC keys were introduced in API 21,and are:
-KEY_AAC_DRC_ATTENUATION_FACTOR, KEY_AAC_DRC_BOOST_FACTOR,
-KEY_AAC_DRC_HEAVY_COMPRESSION, KEY_AAC_DRC_TARGET_REFERENCE_LEVEL and
-KEY_AAC_ENCODED_TARGET_LEVEL
-  </li>
- </ul>
- <p class="table_footnote">
-  3 Required for Android Handheld device
-implementations.
- </p>
- <p class="table_footnote">
-  4 Required for device implementations that define
-android.hardware.microphone, including Android Watch device implementations.
- </p>
- <h4 id="5_1_2_image_codecs">
-  5.1.2. Image Codecs
- </h4>
- <table>
-  <tr>
-   <th>
-    Format/Codec
-   </th>
-   <th>
-    Encoder
-   </th>
-   <th>
-    Decoder
-   </th>
-   <th>
-    Details
-   </th>
-   <th>
-    Supported File Types/Container Formats
-   </th>
-  </tr>
-  <tr>
-   <td>
-    JPEG
-   </td>
-   <td>
-    REQUIRED
-   </td>
-   <td>
-    REQUIRED
-   </td>
-   <td>
-    Base+progressive
-   </td>
-   <td>
-    JPEG (.jpg)
-   </td>
-  </tr>
-  <tr>
-   <td>
-    GIF
-   </td>
-   <td>
-   </td>
-   <td>
-    REQUIRED
-   </td>
-   <td>
-   </td>
-   <td>
-    GIF (.gif)
-   </td>
-  </tr>
-  <tr>
-   <td>
-    PNG
-   </td>
-   <td>
-    REQUIRED
-   </td>
-   <td>
-    REQUIRED
-   </td>
-   <td>
-   </td>
-   <td>
-    PNG (.png)
-   </td>
-  </tr>
-  <tr>
-   <td>
-    BMP
-   </td>
-   <td>
-   </td>
-   <td>
-    REQUIRED
-   </td>
-   <td>
-   </td>
-   <td>
-    BMP (.bmp)
-   </td>
-  </tr>
-  <tr>
-   <td>
-    WebP
-   </td>
-   <td>
-    REQUIRED
-   </td>
-   <td>
-    REQUIRED
-   </td>
-   <td>
-   </td>
-   <td>
-    WebP (.webp)
-   </td>
-  </tr>
-  <tr>
-   <td>
-    Raw
-   </td>
-   <td>
-   </td>
-   <td>
-    REQUIRED
-   </td>
-   <td>
-   </td>
-   <td>
-    ARW (.arw), CR2 (.cr2), DNG (.dng), NEF (.nef), NRW (.nrw), ORF (.orf),
-        PEF (.pef), RAF (.raf), RW2 (.rw2), SRW (.srw)
-   </td>
-  </tr>
- </table>
- <h4 id="5_1_3_video_codecs">
-  5.1.3. Video Codecs
- </h4>
- <ul>
-  <li>
-   <p>
-    Codecs advertising HDR profile support MUST support HDR static metadata
-parsing and handling.
-   </p>
-  </li>
-  <li>
-   <p>
-    If a media codec advertises intra refresh support, then it MUST support the
-refresh periods in the range of 10 - 60 frames and accurately operate within
-20% of configured refresh period.
-   </p>
-  </li>
-  <li>
-   <p>
-    Video codecs MUST support output and input bytebuffer sizes that
-accommodate the largest feasible compressed and uncompressed frame as dictated
-by the standard and configuration but also not overallocate.
-   </p>
-  </li>
-  <li>
-   <p>
-    Video encoders and decoders MUST support YUV420 flexible color format
-(COLOR_FormatYUV420Flexible).
-   </p>
-  </li>
- </ul>
- <table>
-  <tr>
-   <th>
-    Format/Codec
-   </th>
-   <th>
-    Encoder
-   </th>
-   <th>
-    Decoder
-   </th>
-   <th>
-    Details
-   </th>
-   <th>
-    Supported File Types/
-    <br/>
-    Container Formats
-   </th>
-  </tr>
-  <tr>
-   <td>
-    H.263
-   </td>
-   <td>
-    MAY
-   </td>
-   <td>
-    MAY
-   </td>
-   <td>
-   </td>
-   <td>
-    <ul>
-     <li class="table_list">
-      3GPP (.3gp)
-     </li>
-     <li class="table_list">
-      MPEG-4 (.mp4)
-     </li>
-    </ul>
-   </td>
-  </tr>
-  <tr>
-   <td>
-    H.264 AVC
-   </td>
-   <td>
-    REQUIRED
-    <sup>
-     2
-    </sup>
-   </td>
-   <td>
-    REQUIRED
-    <sup>
-     2
-    </sup>
-   </td>
-   <td>
-    See
-    <a href="#5_2_video_encoding">
-     section 5.2
-    </a>
-    and
-    <a href="#5_3_video_decoding">
-     5.3
-    </a>
-    for details
-   </td>
-   <td>
-    <ul>
-     <li class="table_list">
-      3GPP (.3gp)
-     </li>
-     <li class="table_list">
-      MPEG-4 (.mp4)
-     </li>
-     <li class="table_list">
-      MPEG-2 TS (.ts, AAC audio only, not seekable, Android
-    3.0+)
-     </li>
-    </ul>
-   </td>
-  </tr>
-  <tr>
-   <td>
-    H.265 HEVC
-   </td>
-   <td>
-   </td>
-   <td>
-    REQUIRED
-    <sup>
-     5
-    </sup>
-   </td>
-   <td>
-    See
-    <a href="#5_3_video_decoding">
-     section 5.3
-    </a>
-    for details
-   </td>
-   <td>
-    MPEG-4 (.mp4)
-   </td>
-  </tr>
-  <tr>
-   <td>
-    MPEG-2
-   </td>
-   <td>
-   </td>
-   <td>
-    STRONGLY RECOMMENDED
-    <sup>
-     6
-    </sup>
-   </td>
-   <td>
-    Main Profile
-   </td>
-   <td>
-    MPEG2-TS
-   </td>
-  </tr>
-  <tr>
-   <td>
-    MPEG-4 SP
-   </td>
-   <td>
-   </td>
-   <td>
-    REQUIRED
-    <sup>
-     2
-    </sup>
-   </td>
-   <td>
-   </td>
-   <td>
-    3GPP (.3gp)
-   </td>
-  </tr>
-  <tr>
-   <td>
-    VP8
-    <sup>
-     3
-    </sup>
-   </td>
-   <td>
-    REQUIRED
-    <sup>
-     2
-    </sup>
-    <br/>
-    (Android 4.3+)
-   </td>
-   <td>
-    REQUIRED
-    <sup>
-     2
-    </sup>
-    <br/>
-    (Android 2.3.3+)
-   </td>
-   <td>
-    See
-    <a href="#5_2_video_encoding">
-     section 5.2
-    </a>
-    and
-    <a href="#5_3_video_decoding">
-     5.3
-    </a>
-    for details
-   </td>
-   <td>
-    <ul>
-     <li class="table_list">
-      <a href="http://www.webmproject.org/">
-       WebM
-    (.webm)
-      </a>
-     </li>
-     <li class="table_list">
-      Matroska (.mkv, Android 4.0+)
-      <sup>
-       4
-      </sup>
-     </li>
-    </ul>
-   </td>
-  </tr>
-  <tr>
-   <td>
-    VP9
-   </td>
-   <td>
-   </td>
-   <td>
-    REQUIRED
-    <sup>
-     2
-    </sup>
-    <br/>
-    (Android 4.4+)
-   </td>
-   <td>
-    See
-    <a href="#5_3_video_decoding">
-     section 5.3
-    </a>
-    for details
-   </td>
-   <td>
-    <ul>
-     <li class="table_list">
-      <a href="http://www.webmproject.org/">
-       WebM
-    (.webm)
-      </a>
-     </li>
-     <li class="table_list">
-      Matroska (.mkv, Android 4.0+)
-      <sup>
-       4
-      </sup>
-     </li>
-    </ul>
-   </td>
-  </tr>
- </table>
- <p class="table_footnote">
-  1 Required for device implementations that include
-camera hardware and define android.hardware.camera or
-android.hardware.camera.front.
- </p>
- <p class="table_footnote">
-  2 Required for device implementations except Android
-Watch devices.
- </p>
- <p class="table_footnote">
-  3 For acceptable quality of web video streaming and
-video-conference services, device implementations SHOULD use a hardware VP8
-codec that meets the
-  <a href="http://www.webmproject.org/hardware/rtc-coding-requirements/">
-   requirements
-  </a>.
- </p>
- <p class="table_footnote">
-  4 Device implementations SHOULD support writing
-Matroska WebM files.
- </p>
- <p class="table_footnote">
-  5 STRONGLY RECOMMENDED for Android Automotive,
-optional for Android Watch, and required for all other device types.
- </p>
- <p class="table_footnote">
-  6 Applies only to Android Television device
-implementations.
- </p>
- <h3 id="5_2_video_encoding">
-  5.2. Video Encoding
- </h3>
- <div class="note">
-  Video codecs are optional for Android Watch device implementations.
- </div>
- <p>
-  H.264, VP8, VP9 and HEVC video encoders&mdash;
- </p>
- <ul>
-  <li>
-   MUST support dynamically configurable bitrates.
-  </li>
-  <li>
-   SHOULD support variable frame rates, where video encoder SHOULD determine
-instantaneous frame duration based on the timestamps of input buffers, and
-allocate its bit bucket based on that frame duration.
-  </li>
- </ul>
- <p>
-  H.263 and MPEG-4 video encoder SHOULD support dynamically configurable
-bitrates.
- </p>
- <p>
-  All video encoders SHOULD meet the following bitrate targets over two sliding
-windows:
- </p>
- <ul>
-  <li>
-   It SHOULD be not more than ~15% over the bitrate between intraframe
-(I-frame) intervals.
-  </li>
-  <li>
-   It SHOULD be not more than ~100% over the bitrate over a sliding window of
-1 second.
-  </li>
- </ul>
- <h4 id="5_2_1_h_263">
-  5.2.1. H.263
- </h4>
- <p>
-  Android device implementations with H.263 encoders MUST support Baseline Profile Level 45.
- </p>
- <h4 id="5_2_2_h-264">
-  5.2.2. H-264
- </h4>
- <p>
-  Android device implementations with H.264 codec support:
- </p>
- <ul>
-  <li>
-   MUST support Baseline Profile Level 3.
-   <br/>
-   However, support for ASO (Arbitrary Slice Ordering), FMO (Flexible Macroblock
-    Ordering) and RS (Redundant Slices) is OPTIONAL. Moreover, to maintain
-    compatibility with other Android devices, it is RECOMMENDED that ASO, FMO
-    and RS are not used for Baseline Profile by encoders.
-  </li>
-  <li>
-   MUST support the  SD (Standard Definition) video encoding profiles in the following table.
-  </li>
-  <li>
-   SHOULD support Main Profile Level 4.
-  </li>
-  <li>
-   SHOULD support the  HD (High Definition) video encoding profiles as indicated in the following table.
-  </li>
-  <li>
-   In addition, Android Television devices are STRONGLY RECOMMENDED to encode HD 1080p video at 30 fps.
-  </li>
- </ul>
- <table>
-  <tr>
-   <th>
-   </th>
-   <th>
-    SD (Low quality)
-   </th>
-   <th>
-    SD (High quality)
-   </th>
-   <th>
-    HD 720p
-    <sup>
-     1
-    </sup>
-   </th>
-   <th>
-    HD 1080p
-    <sup>
-     1
-    </sup>
-   </th>
-  </tr>
-  <tr>
-   <th>
-    Video resolution
-   </th>
-   <td>
-    320 x 240 px
-   </td>
-   <td>
-    720 x 480 px
-   </td>
-   <td>
-    1280 x 720 px
-   </td>
-   <td>
-    1920 x 1080 px
-   </td>
-  </tr>
-  <tr>
-   <th>
-    Video frame rate
-   </th>
-   <td>
-    20 fps
-   </td>
-   <td>
-    30 fps
-   </td>
-   <td>
-    30 fps
-   </td>
-   <td>
-    30 fps
-   </td>
-  </tr>
-  <tr>
-   <th>
-    Video bitrate
-   </th>
-   <td>
-    384 Kbps
-   </td>
-   <td>
-    2 Mbps
-   </td>
-   <td>
-    4 Mbps
-   </td>
-   <td>
-    10 Mbps
-   </td>
-  </tr>
- </table>
- <p class="table_footnote">
-  1 When supported by hardware, but STRONGLY RECOMMENDED
-for Android Television devices.
- </p>
- <h4 id="5_2_3_vp8">
-  5.2.3. VP8
- </h4>
- <p>
-  Android device implementations with VP8 codec support MUST support the SD video
-encoding profiles and SHOULD support the following HD (High Definition) video encoding profiles.
- </p>
- <table>
-  <tr>
-   <th>
-   </th>
-   <th>
-    SD (Low quality)
-   </th>
-   <th>
-    SD (High quality)
-   </th>
-   <th>
-    HD 720p
-    <sup>
-     1
-    </sup>
-   </th>
-   <th>
-    HD 1080p
-    <sup>
-     1
-    </sup>
-   </th>
-  </tr>
-  <tr>
-   <th>
-    Video resolution
-   </th>
-   <td>
-    320 x 180 px
-   </td>
-   <td>
-    640 x 360 px
-   </td>
-   <td>
-    1280 x 720 px
-   </td>
-   <td>
-    1920 x 1080 px
-   </td>
-  </tr>
-  <tr>
-   <th>
-    Video frame rate
-   </th>
-   <td>
-    30 fps
-   </td>
-   <td>
-    30 fps
-   </td>
-   <td>
-    30 fps
-   </td>
-   <td>
-    30 fps
-   </td>
-  </tr>
-  <tr>
-   <th>
-    Video bitrate
-   </th>
-   <td>
-    800 Kbps
-   </td>
-   <td>
-    2 Mbps
-   </td>
-   <td>
-    4 Mbps
-   </td>
-   <td>
-    10 Mbps
-   </td>
-  </tr>
- </table>
- <p class="table_footnote">
-  1 When supported by hardware.
- </p>
- <h3 id="5_3_video_decoding">
-  5.3. Video Decoding
- </h3>
- <div class="note">
-  Video codecs are optional for Android Watch device implementations.
- </div>
- <p>
-  Device implementations&mdash;
- </p>
- <ul>
-  <li>
-   <p>
-    MUST support dynamic video resolution and frame rate switching through the
-    standard Android APIs within the same stream for all VP8, VP9, H.264, and
-    H.265 codecs in real time and up to the maximum resolution supported by each
-    codec on the device.
-   </p>
-  </li>
-  <li>
-   <p>
-    Implementations that support the Dolby Vision decoder&mdash;
-   </p>
-  </li>
-  <li>
-   MUST provide a Dolby Vision-capable extractor.
-  </li>
-  <li>
-   <p>
-    MUST properly display Dolby Vision content on the device screen or on a
-       standard video output port (e.g., HDMI).
-   </p>
-  </li>
-  <li>
-   <p>
-    Implementations that provide a Dolby Vision-capable extractor MUST set the
-    track index of backward-compatible base-layer(s) (if present) to be the same
-    as the combined Dolby Vision layer's track index.
-   </p>
-  </li>
- </ul>
- <h4 id="5_3_1_mpeg-2">
-  5.3.1. MPEG-2
- </h4>
- <p>
-  Android device implementations with MPEG-2 decoders must support the Main
-Profile High Level.
- </p>
- <h4 id="5_3_2_h_263">
-  5.3.2. H.263
- </h4>
- <p>
-  Android device implementations with H.263 decoders MUST support Baseline Profile
-Level 30 and Level 45.
- </p>
- <h4 id="5_3_3_mpeg-4">
-  5.3.3. MPEG-4
- </h4>
- <p>
-  Android device implementations with MPEG-4 decoders MUST support Simple Profile
-Level 3.
- </p>
- <h4 id="5_3_4_h_264">
-  5.3.4. H.264
- </h4>
- <p>
-  Android device implementations with H.264 decoders:
- </p>
- <ul>
-  <li>
-   MUST support Main Profile Level 3.1 and Baseline Profile.
-   <br/>
-   Support for ASO (Arbitrary Slice Ordering), FMO (Flexible Macroblock Ordering)
-    and RS (Redundant Slices) is OPTIONAL.
-  </li>
-  <li>
-   MUST be capable of decoding videos with the SD (Standard Definition)
-    profiles listed in the following table and encoded with the Baseline Profile and
-    Main Profile Level 3.1 (including 720p30).
-  </li>
-  <li>
-   SHOULD be capable of decoding videos with the HD (High Definition) profiles
-    as indicated in the following table.
-  </li>
-  <li>
-   In addition, Android Television devices&mdash;
-   <ul>
-    <li>
-     MUST support High Profile Level 4.2 and the HD 1080p60 decoding profile.
-    </li>
-    <li>
-     MUST be capable of decoding videos with both HD profiles as indicated
-    in the following table and encoded with either the Baseline Profile, Main
-    Profile, or the High Profile Level 4.2
-    </li>
-   </ul>
-  </li>
- </ul>
- <table>
-  <tr>
-   <th>
-   </th>
-   <th>
-    SD (Low quality)
-   </th>
-   <th>
-    SD (High quality)
-   </th>
-   <th>
-    HD 720p
-    <sup>
-     1
-    </sup>
-   </th>
-   <th>
-    HD 1080p
-    <sup>
-     1
-    </sup>
-   </th>
-  </tr>
-  <tr>
-   <th>
-    Video resolution
-   </th>
-   <td>
-    320 x 240 px
-   </td>
-   <td>
-    720 x 480 px
-   </td>
-   <td>
-    1280 x 720 px
-   </td>
-   <td>
-    1920 x 1080 px
-   </td>
-  </tr>
-  <tr>
-   <th>
-    Video frame rate
-   </th>
-   <td>
-    30 fps
-   </td>
-   <td>
-    30 fps
-   </td>
-   <td>
-    60 fps
-   </td>
-   <td>
-    30 fps (60 fps
-    <sup>
-     2
-    </sup>
-    )
-   </td>
-  </tr>
-  <tr>
-   <th>
-    Video bitrate
-   </th>
-   <td>
-    800 Kbps
-   </td>
-   <td>
-    2 Mbps
-   </td>
-   <td>
-    8 Mbps
-   </td>
-   <td>
-    20 Mbps
-   </td>
-  </tr>
- </table>
- <p class="table_footnote">
-  1 REQUIRED for when the height as reported by the
-Display.getSupportedModes() method is equal or greater than the video resolution.
- </p>
- <p class="table_footnote">
-  2 REQUIRED for Android Television device
-implementations.
- </p>
- <h4 id="5_3_5_h_265_(hevc)">
-  5.3.5. H.265 (HEVC)
- </h4>
- <p>
-  Android device implementations, when supporting H.265 codec as described in
-  <a href="#5_1_3_video_codecs">
-   section 5.1.3
-  </a>:
- </p>
- <ul>
-  <li>
-   MUST support the Main Profile Level 3 Main tier and the SD video decoding profiles
-    as indicated in the following table.
-  </li>
-  <li>
-   SHOULD support the HD decoding profiles as indicated in the following table.
-  </li>
-  <li>
-   MUST support the HD decoding profiles as indicated in the following table
-    if there is a hardware decoder.
-  </li>
-  <li>
-   In addition, Android Television devices:
-  </li>
-  <li>
-   MUST support the HD 720p decoding profile.
-  </li>
-  <li>
-   STRONGLY RECOMMENDED to support the HD 1080p decoding profile. If the HD 1080p
-       decoding profile is supported, it MUST support the Main Profile Level 4.1 Main tier.
-  </li>
-  <li>
-   SHOULD support the UHD decoding profile. If the UHD decoding profile is supported the 
-    codec MUST support Main10 Level 5 Main Tier profile.
-  </li>
- </ul>
- <table>
-  <tr>
-   <th>
-   </th>
-   <th>
-    SD (Low quality)
-   </th>
-   <th>
-    SD (High quality)
-   </th>
-   <th>
-    HD 720p
-   </th>
-   <th>
-    HD 1080p
-   </th>
-   <th>
-    UHD
-   </th>
-  </tr>
-  <tr>
-   <th>
-    Video resolution
-   </th>
-   <td>
-    352 x 288 px
-   </td>
-   <td>
-    720 x 480 px
-   </td>
-   <td>
-    1280 x 720 px
-   </td>
-   <td>
-    1920 x 1080 px
-   </td>
-   <td>
-    3840 x 2160 px
-   </td>
-  </tr>
-  <tr>
-   <th>
-    Video frame rate
-   </th>
-   <td>
-    30 fps
-   </td>
-   <td>
-    30 fps
-   </td>
-   <td>
-    30 fps
-   </td>
-   <td>
-    30 fps (60 fps
-    <sup>
-     1
-    </sup>
-    )
-   </td>
-   <td>
-    60 fps
-   </td>
-  </tr>
-  <tr>
-   <th>
-    Video bitrate
-   </th>
-   <td>
-    600 Kbps
-   </td>
-   <td>
-    1.6 Mbps
-   </td>
-   <td>
-    4 Mbps
-   </td>
-   <td>
-    5 Mbps
-   </td>
-   <td>
-    20 Mbps
-   </td>
-  </tr>
- </table>
- <p class="table_footnote">
-  1 REQUIRED for Android Television device
-implementations with H.265 hardware decoding.
- </p>
- <h4 id="5_3_6_vp8">
-  5.3.6. VP8
- </h4>
- <p>
-  Android device implementations, when supporting VP8 codec as described in
-  <a href="https://source.android.com/compatibility/android-cdd.html#5_1_3_video_codecs">
-   section 5.1.3
-  </a>:
- </p>
- <ul>
-  <li>
-   MUST support the SD decoding profiles in the following table.
-  </li>
-  <li>
-   SHOULD support the HD decoding profiles in the following table.
-  </li>
-  <li>
-   Android Television devices MUST support the HD 1080p60 decoding profile.
-  </li>
- </ul>
- <table>
-  <tr>
-   <th>
-   </th>
-   <th>
-    SD (Low quality)
-   </th>
-   <th>
-    SD (High quality)
-   </th>
-   <th>
-    HD 720p
-    <sup>
-     1
-    </sup>
-   </th>
-   <th>
-    HD 1080p
-    <sup>
-     1
-    </sup>
-   </th>
-  </tr>
-  <tr>
-   <th>
-    Video resolution
-   </th>
-   <td>
-    320 x 180 px
-   </td>
-   <td>
-    640 x 360 px
-   </td>
-   <td>
-    1280 x 720 px
-   </td>
-   <td>
-    1920 x 1080 px
-   </td>
-  </tr>
-  <tr>
-   <th>
-    Video frame rate
-   </th>
-   <td>
-    30 fps
-   </td>
-   <td>
-    30 fps
-   </td>
-   <td>
-    30 fps (60 fps
-    <sup>
-     2
-    </sup>
-    )
-   </td>
-   <td>
-    30 (60 fps
-    <sup>
-     2
-    </sup>
-    )
-   </td>
-  </tr>
-  <tr>
-   <th>
-    Video bitrate
-   </th>
-   <td>
-    800 Kbps
-   </td>
-   <td>
-    2 Mbps
-   </td>
-   <td>
-    8 Mbps
-   </td>
-   <td>
-    20 Mbps
-   </td>
-  </tr>
- </table>
- <p class="table_footnote">
-  1 REQUIRED for when the height as reported by the
-Display.getSupportedModes() method is equal or greater than the video resolution.
- </p>
- <p class="table_footnote">
-  2 REQUIRED for Android Television device
-implementations.
- </p>
- <h4 id="5_3_7_vp9">
-  5.3.7. VP9
- </h4>
- <p>
-  Android device implementations, when supporting VP9 codec as described in
-  <a href="https://source.android.com/compatibility/android-cdd.html#5_1_3_video_codecs">
-   section 5.1.3
-  </a>:
- </p>
- <ul>
-  <li>
-   MUST support the SD video decoding profiles as indicated in the following table.
-  </li>
-  <li>
-   SHOULD support the HD decoding profiles as indicated in the following table.
-  </li>
-  <li>
-   MUST support the HD decoding profiles as indicated in the following table,
-    if there is a hardware decoder.
-  </li>
-  <li>
-   <p>
-    In addition, Android Television devices:
-   </p>
-   <ul>
-    <li>
-     MUST support the HD 720p decoding profile.
-    </li>
-    <li>
-     STRONGLY RECOMMENDED to support the HD 1080p decoding profile.
-    </li>
-    <li>
-     SHOULD support the UHD decoding profile. If the UHD video decoding
-    profile is supported, it MUST support 8-bit color depth and SHOULD
-    support VP9 Profile 2 (10-bit).
-    </li>
-   </ul>
-  </li>
- </ul>
- <table>
-  <tr>
-   <th>
-   </th>
-   <th>
-    SD (Low quality)
-   </th>
-   <th>
-    SD (High quality)
-   </th>
-   <th>
-    HD 720p
-   </th>
-   <th>
-    HD 1080p
-   </th>
-   <th>
-    UHD
-   </th>
-  </tr>
-  <tr>
-   <th>
-    Video resolution
-   </th>
-   <td>
-    320 x 180 px
-   </td>
-   <td>
-    640 x 360 px
-   </td>
-   <td>
-    1280 x 720 px
-   </td>
-   <td>
-    1920 x 1080 px
-   </td>
-   <td>
-    3840 x 2160 px
-   </td>
-  </tr>
-  <tr>
-   <th>
-    Video frame rate
-   </th>
-   <td>
-    30 fps
-   </td>
-   <td>
-    30 fps
-   </td>
-   <td>
-    30 fps
-   </td>
-   <td>
-    30 fps (60 fps
-    <sup>
-     1
-    </sup>
-    )
-   </td>
-   <td>
-    60 fps
-   </td>
-  </tr>
-  <tr>
-   <th>
-    Video bitrate
-   </th>
-   <td>
-    600 Kbps
-   </td>
-   <td>
-    1.6 Mbps
-   </td>
-   <td>
-    4 Mbps
-   </td>
-   <td>
-    5 Mbps
-   </td>
-   <td>
-    20 Mbps
-   </td>
-  </tr>
- </table>
- <p class="table_footnote">
-  1 REQUIRED for Android Television
-device implementations with VP9 hardware decoding.
- </p>
- <h3 id="5_4_audio_recording">
-  5.4. Audio Recording
- </h3>
- <p>
-  While some of the requirements outlined in this section are stated as SHOULD
-since Android 4.3, the Compatibility Definition for a future version is planned
-to change these to MUST. Existing and new Android devices are
-  <strong>
-   STRONGLY
-RECOMMENDED
-  </strong>
-  to meet these requirements that are stated as SHOULD, or they
-will not be able to attain Android compatibility when upgraded to the future
-version.
- </p>
- <h4 id="5_4_1_raw_audio_capture">
-  5.4.1. Raw Audio Capture
- </h4>
- <p>
-  Device implementations that declare android.hardware.microphone MUST allow
-capture of raw audio content with the following characteristics:
- </p>
- <ul>
-  <li>
-   <strong>
-    Format
-   </strong>
-   : Linear PCM, 16-bit
-  </li>
-  <li>
-   <strong>
-    Sampling rates
-   </strong>
-   : 8000, 11025, 16000, 44100
-  </li>
-  <li>
-   <strong>
-    Channels
-   </strong>
-   : Mono
-  </li>
- </ul>
- <p>
-  The capture for the above sample rates MUST be done without up-sampling, and
-any down-sampling MUST include an appropriate anti-aliasing filter.
- </p>
- <p>
-  Device implementations that declare android.hardware.microphone SHOULD allow
-capture of raw audio content with the following characteristics:
- </p>
- <ul>
-  <li>
-   <strong>
-    Format
-   </strong>
-   : Linear PCM, 16-bit
-  </li>
-  <li>
-   <strong>
-    Sampling rates
-   </strong>
-   : 22050, 48000
-  </li>
-  <li>
-   <strong>
-    Channels
-   </strong>
-   : Stereo
-  </li>
- </ul>
- <p>
-  If capture for the above sample rates is supported, then the capture MUST be
-done without up-sampling at any ratio higher than 16000:22050 or 44100:48000.
-Any up-sampling or down-sampling MUST include an appropriate anti-aliasing
-filter.
- </p>
- <h4 id="5_4_2_capture_for_voice_recognition">
-  5.4.2. Capture for Voice Recognition
- </h4>
- <p>
-  The android.media.MediaRecorder.AudioSource.VOICE_RECOGNITION audio source MUST
-support capture at one of the sampling rates, 44100 and 48000.
- </p>
- <p>
-  In addition to the above recording specifications, when an application has
-started recording an audio stream using the
-android.media.MediaRecorder.AudioSource.VOICE_RECOGNITION audio source:
- </p>
- <ul>
-  <li>
-   The device SHOULD exhibit approximately flat amplitude versus frequency
-    characteristics: specifically, &plusmn;3 dB, from 100 Hz to 4000 Hz.
-  </li>
-  <li>
-   Audio input sensitivity SHOULD be set such that a 90 dB sound power level
-    (SPL) source at 1000 Hz yields RMS of 2500 for 16-bit samples.
-  </li>
-  <li>
-   PCM amplitude levels SHOULD linearly track input SPL changes over at least a
-    30 dB range from -18 dB to +12 dB re 90 dB SPL at the microphone.
-  </li>
-  <li>
-   Total harmonic distortion SHOULD be less than 1% for 1 kHz at 90 dB SPL
-    input level at the microphone.
-  </li>
-  <li>
-   Noise reduction processing, if present, MUST be disabled.
-  </li>
-  <li>
-   Automatic gain control, if present, MUST be disabled.
-  </li>
- </ul>
- <p>
-  If the platform supports noise suppression technologies tuned for speech
-recognition, the effect MUST be controllable from the
-android.media.audiofx.NoiseSuppressor API. Moreover, the UUID field for the
-noise suppressor&rsquo;s effect descriptor MUST uniquely identify each implementation
-of the noise suppression technology.
- </p>
- <h4 id="5_4_3_capture_for_rerouting_of_playback">
-  5.4.3. Capture for Rerouting of Playback
- </h4>
- <p>
-  The android.media.MediaRecorder.AudioSource class includes the REMOTE_SUBMIX
-audio source. Devices that declare android.hardware.audio.output MUST properly
-implement the REMOTE_SUBMIX audio source so that when an application uses the
-android.media.AudioRecord API to record from this audio source, it can capture
-a mix of all audio streams except for the following:
- </p>
- <ul>
-  <li>
-   STREAM_RING
-  </li>
-  <li>
-   STREAM_ALARM
-  </li>
-  <li>
-   STREAM_NOTIFICATION
-  </li>
- </ul>
- <h3 id="5_5_audio_playback">
-  5.5. Audio Playback
- </h3>
- <p>
-  Device implementations that declare android.hardware.audio.output MUST conform
-to the requirements in this section.
- </p>
- <h4 id="5_5_1_raw_audio_playback">
-  5.5.1. Raw Audio Playback
- </h4>
- <p>
-  The device MUST allow playback of raw audio content with the following
-characteristics:
- </p>
- <ul>
-  <li>
-   <strong>
-    Format
-   </strong>
-   : Linear PCM, 16-bit
-  </li>
-  <li>
-   <strong>
-    Sampling rates
-   </strong>
-   : 8000, 11025, 16000, 22050, 32000, 44100
-  </li>
-  <li>
-   <strong>
-    Channels
-   </strong>
-   : Mono, Stereo
-  </li>
- </ul>
- <p>
-  The device SHOULD allow playback of raw audio content with the following
-characteristics:
- </p>
- <ul>
-  <li>
-   <strong>
-    Sampling rates
-   </strong>
-   : 24000, 48000
-  </li>
- </ul>
- <h4 id="5_5_2_audio_effects">
-  5.5.2. Audio Effects
- </h4>
- <p>
-  Android provides an
-  <a href="http://developer.android.com/reference/android/media/audiofx/AudioEffect.html">
-   API for audio effects
-  </a>
-  for device implementations. Device implementations that declare the feature
-android.hardware.audio.output:
- </p>
- <ul>
-  <li>
-   MUST support the EFFECT_TYPE_EQUALIZER and EFFECT_TYPE_LOUDNESS_ENHANCER
-implementations controllable through the AudioEffect subclasses Equalizer,
-LoudnessEnhancer.
-  </li>
-  <li>
-   MUST support the visualizer API implementation, controllable through the
-Visualizer class.
-  </li>
-  <li>
-   SHOULD support the EFFECT_TYPE_BASS_BOOST, EFFECT_TYPE_ENV_REVERB,
-EFFECT_TYPE_PRESET_REVERB, and EFFECT_TYPE_VIRTUALIZER implementations
-controllable through the AudioEffect sub-classes BassBoost,
-EnvironmentalReverb, PresetReverb, and Virtualizer.
-  </li>
- </ul>
- <h4 id="5_5_3_audio_output_volume">
-  5.5.3. Audio Output Volume
- </h4>
- <p>
-  Android Television device implementations MUST include support for system
-Master Volume and digital audio output volume attenuation on supported outputs,
-except for compressed audio passthrough output (where no audio decoding is done
-on the device).
- </p>
- <p>
-  Android Automotive device implementations SHOULD allow adjusting audio volume
-separately per each audio stream using the content type or usage as defined
-by
-  <a href="" title="http://developer.android.com/reference/android/media/AudioAttributes.html">
-   AudioAttributes
-  </a>
-  and car audio usage as publicly defined in
-  <code>
-   android.car.CarAudioManager
-  </code>
-  .
- </p>
- <h3 id="5_6_audio_latency">
-  5.6. Audio Latency
- </h3>
- <p>
-  Audio latency is the time delay as an audio signal passes through a system.
-Many classes of applications rely on short latencies, to achieve real-time
-sound effects.
- </p>
- <p>
-  For the purposes of this section, use the following definitions:
- </p>
- <ul>
-  <li>
-   <strong>
-    output latency
-   </strong>
-   . The interval between when an application writes a frame
-of PCM-coded data and when the corresponding sound is presented to environment at an on-device transducer
-or signal leaves the device via a port and can be observed externally.
-  </li>
-  <li>
-   <strong>
-    cold output latency
-   </strong>
-   . The output latency for the first frame, when the
-audio output system has been idle and powered down prior to the request.
-  </li>
-  <li>
-   <strong>
-    continuous output latency
-   </strong>
-   . The output latency for subsequent frames,
-after the device is playing audio.
-  </li>
-  <li>
-   <strong>
-    input latency
-   </strong>
-   . The interval between when a sound is presented by environment to device
-at an on-device transducer or signal enters the device via a port
-and when an application reads the corresponding frame of
-PCM-coded data.
-  </li>
-  <li>
-   <strong>
-    lost input
-   </strong>
-   . The initial portion of an input signal that is unusable or unavailable.
-  </li>
-  <li>
-   <strong>
-    cold input latency
-   </strong>
-   . The sum of lost input time and the input latency
-for the first frame, when the audio input system has been idle and powered down
-prior to the request.
-  </li>
-  <li>
-   <strong>
-    continuous input latency
-   </strong>
-   . The input latency for subsequent frames,
-while the device is capturing audio.
-  </li>
-  <li>
-   <strong>
-    cold output jitter
-   </strong>
-   . The variability among separate measurements of cold
-output latency values.
-  </li>
-  <li>
-   <strong>
-    cold input jitter
-   </strong>
-   . The variability among separate measurements of cold
-input latency values.
-  </li>
-  <li>
-   <strong>
-    continuous round-trip latency
-   </strong>
-   . The sum of continuous input latency plus
-continuous output latency plus one buffer period. The buffer period allows
-time for the app to process the signal and time for the app to mitigate phase difference
-between input and output streams.
-  </li>
-  <li>
-   <strong>
-    OpenSL ES PCM buffer queue API
-   </strong>
-   . The set of PCM-related OpenSL ES APIs
-within
-   <a href="https://developer.android.com/ndk/index.html">
-    Android NDK
-   </a>.
-  </li>
- </ul>
- <p>
-  Device implementations that declare android.hardware.audio.output are STRONGLY
-RECOMMENDED to meet or exceed these audio output requirements:
- </p>
- <ul>
-  <li>
-   cold output latency of 100 milliseconds or less
-  </li>
-  <li>
-   continuous output latency of 45 milliseconds or less
-  </li>
-  <li>
-   minimize the cold output jitter
-  </li>
- </ul>
- <p>
-  If a device implementation meets the requirements of this section after any
-initial calibration when using the OpenSL ES PCM buffer queue API, for
-continuous output latency and cold output latency over at least one supported
-audio output device, it is STRONGLY RECOMMENDED to report support for
-low-latency audio, by reporting the feature android.hardware.audio.low_latency
-via the
-  <a href="http://developer.android.com/reference/android/content/pm/PackageManager.html">
-   android.content.pm.PackageManager
-  </a>
-  class. Conversely, if the device implementation does not meet these
-requirements it MUST NOT report support for low-latency audio.
- </p>
- <p>
-  Device implementations that include android.hardware.microphone are STRONGLY
-RECOMMENDED to meet these input audio requirements:
- </p>
- <ul>
-  <li>
-   cold input latency of 100 milliseconds or less
-  </li>
-  <li>
-   continuous input latency of 30 milliseconds or less
-  </li>
-  <li>
-   continuous round-trip latency of 50 milliseconds or less
-  </li>
-  <li>
-   minimize the cold input jitter
-  </li>
- </ul>
- <h3 id="5_7_network_protocols">
-  5.7. Network Protocols
- </h3>
- <p>
-  Devices MUST support the
-  <a href="http://developer.android.com/guide/appendix/media-formats.html">
-   media network protocols
-  </a>
-  for audio and video playback as specified in the Android SDK documentation.
-Specifically, devices MUST support the following media network protocols:
- </p>
- <ul>
-  <li>
-   <p>
-    HTTP(S) progressive streaming
-    <br/>
-    All required codecs and container formats in
-    <a href="#5_1_media_codecs">
-     section 5.1
-    </a>
-    MUST
-    be supported over HTTP(S)
-   </p>
-  </li>
-  <li>
-   <p>
-    <a href="http://tools.ietf.org/html/draft-pantos-http-live-streaming-07">
-     HTTP Live Streaming draft protocol, Version 7
-    </a>
-    <br/>
-    The following media segment formats MUST be supported:
-   </p>
-  </li>
- </ul>
- <table>
-  <tr>
-   <th>
-    Segment formats
-   </th>
-   <th>
-    Reference(s)
-   </th>
-   <th>
-    Required codec support
-   </th>
-  </tr>
-  <tr id="mp2t">
-   <td>
-    MPEG-2 Transport Stream
-   </td>
-   <td>
-    <a href="http://www.iso.org/iso/catalogue_detail?csnumber=44169">
-     ISO 13818
-    </a>
-   </td>
-   <td>
-    Video codecs:
-    <ul>
-     <li class="table_list">
-      H264 AVC
-     </li>
-     <li class="table_list">
-      MPEG-4 SP
-     </li>
-     <li class="table_list">
-      MPEG-2
-     </li>
-    </ul>
-    See
-    <a href="#5_1_3_video_codecs">
-     section 5.1.3
-    </a>
-    for details on H264 AVC, MPEG2-4 SP,
-    <br/>
-    and MPEG-2.
     <p>
-     Audio codecs:
+      To be considered compatible with Android 8.0, device implementations MUST meet the requirements presented in this Compatibility Definition, including any documents incorporated via reference.
+    </p>
+    <p>
+      Where this definition or the software tests described in <a href="#10_software_compatibility_testing">section 10</a> is silent, ambiguous, or incomplete, it is the responsibility of the device implementer to ensure compatibility with existing implementations.
+    </p>
+    <p>
+      For this reason, the <a href="http://source.android.com/">Android Open Source Project</a> is both the reference and preferred implementation of Android. Device implementers are STRONGLY RECOMMENDED to base their implementations to the greatest extent possible on the “upstream” source code available from the Android Open Source Project. While some components can hypothetically be replaced with alternate implementations, it is STRONGLY RECOMMENDED to not follow this practice, as passing the software tests will become substantially more difficult. It is the implementer’s responsibility to ensure full behavioral compatibility with the standard Android implementation, including and beyond the Compatibility Test Suite. Finally, note that certain component substitutions and modifications are explicitly forbidden by this document.
+    </p>
+    <p>
+      Many of the resources linked to in this document are derived directly or indirectly from the Android SDK and will be functionally identical to the information in that SDK’s documentation. In any cases where this Compatibility Definition or the Compatibility Test Suite disagrees with the SDK documentation, the SDK documentation is considered authoritative. Any technical details provided in the linked resources throughout this document are considered by inclusion to be part of this Compatibility Definition.
+    </p>
+    <h3 id="1_1_document_structure">
+      1.1 Document Structure
+    </h3>
+    <h4 id="1_1_1_requirements_by_device_type">
+      1.1.1. Requirements by Device Type
+    </h4>
+    <p>
+      <a href="#2_device_types">Section 2</a> contains all the MUST and STRONGLY RECOMMENDED requirements that apply to a specific device type. Each subsection of <a href="#2_device_types">Section 2</a> is dedicated to a specific device type.
+    </p>
+    <p>
+      All the other requirements, that universally apply to any Android device implementations, are listed in the sections after <a href="#2_device_types">Section 2</a>. These requirements are referenced as "Core Requirements" in this document.
+    </p>
+    <h4 id="1_1_2_requirement_id">
+      1.1.2. Requirement ID
+    </h4>
+    <p>
+      Requirement ID is assigned for MUST requirements.
     </p>
     <ul>
-     <li class="table_list">
-      AAC
-     </li>
+      <li>The ID is assigned for MUST requirements only.
+      </li>
+      <li>STRONGLY RECOMMENDED requirements are marked as [SR] but ID is not assigned.
+      </li>
+      <li>The ID consists of : Device Type ID - Condition ID - Requirement ID (e.g. C-0-1).
+      </li>
     </ul>
-    See
-    <a href="#5_1_1_audio_codecs">
-     section 5.1.1
-    </a>
-    for details on AAC and its variants.
-   </td>
-  </tr>
-  <tr>
-   <td>
-    AAC with ADTS framing and ID3 tags
-   </td>
-   <td>
-    <a href="http://www.iso.org/iso/home/store/catalogue_tc/catalogue_detail.htm?csnumber=43345">
-     ISO 13818-7
-    </a>
-   </td>
-   <td>
-    See
-    <a href="#5_1_1_audio_codecs">
-     section 5.1.1
-    </a>
-    for details on AAC and its variants
-   </td>
-  </tr>
-  <tr>
-   <td>
-    WebVTT
-   </td>
-   <td>
-    <a href="http://dev.w3.org/html5/webvtt/">
-     WebVTT
-    </a>
-   </td>
-   <td>
-   </td>
-  </tr>
- </table>
- <ul>
-  <li>
-   <p>
-    RTSP (RTP, SDP)
-   </p>
-   <p>
-    The following RTP audio video profile and related codecs MUST be supported.
-For exceptions please see the table footnotes in
-    <a href="#5_1_media_codecs">
-     section 5.1
-    </a>.
-   </p>
-  </li>
- </ul>
- <table>
-  <tr>
-   <th>
-    Profile name
-   </th>
-   <th>
-    Reference(s)
-   </th>
-   <th>
-    Required codec support
-   </th>
-  </tr>
-  <tr>
-   <td>
-    H264 AVC
-   </td>
-   <td>
-    <a href="https://tools.ietf.org/html/rfc6184">
-     RFC 6184
-    </a>
-   </td>
-   <td>
-    See
-    <a href="#5_1_3_video_codecs">
-     section 5.1.3
-    </a>
-    for details on H264 AVC
-   </td>
-  </tr>
-  <tr>
-   <td>
-    MP4A-LATM
-   </td>
-   <td>
-    <a href="https://tools.ietf.org/html/rfc6416">
-     RFC 6416
-    </a>
-   </td>
-   <td>
-    See
-    <a href="#5_1_1_audio_codecs">
-     section 5.1.1
-    </a>
-    for details on AAC and its variants
-   </td>
-  </tr>
-  <tr>
-   <td>
-    H263-1998
-   </td>
-   <td>
-    <a href="https://tools.ietf.org/html/rfc3551">
-     RFC 3551
-    </a>
-    <br/>
-    <a href="https://tools.ietf.org/html/rfc4629">
-     RFC 4629
-    </a>
-    <br/>
-    <a href="https://tools.ietf.org/html/rfc2190">
-     RFC 2190
-    </a>
-   </td>
-   <td>
-    See
-    <a href="#5_1_3_video_codecs">
-     section 5.1.3
-    </a>
-    for details on H263
-   </td>
-  </tr>
-  <tr>
-   <td>
-    H263-2000
-   </td>
-   <td>
-    <a href="https://tools.ietf.org/html/rfc4629">
-     RFC 4629
-    </a>
-   </td>
-   <td>
-    See
-    <a href="#5_1_3_video_codecs">
-     section 5.1.3
-    </a>
-    for details on H263
-   </td>
-  </tr>
-  <tr>
-   <td>
-    AMR
-   </td>
-   <td>
-    <a href="https://tools.ietf.org/html/rfc4867">
-     RFC 4867
-    </a>
-   </td>
-   <td>
-    See
-    <a href="#5_1_1_audio_codecs">
-     section 5.1.1
-    </a>
-    for details on AMR-NB
-   </td>
-  </tr>
-  <tr>
-   <td>
-    AMR-WB
-   </td>
-   <td>
-    <a href="https://tools.ietf.org/html/rfc4867">
-     RFC 4867
-    </a>
-   </td>
-   <td>
-    See
-    <a href="#5_1_1_audio_codecs">
-     section 5.1.1
-    </a>
-    for details on AMR-WB
-   </td>
-  </tr>
-  <tr>
-   <td>
-    MP4V-ES
-   </td>
-   <td>
-    <a href="https://tools.ietf.org/html/rfc6416">
-     RFC 6416
-    </a>
-   </td>
-   <td>
-    See
-    <a href="#5_1_3_video_codecs">
-     section 5.1.3
-    </a>
-    for details on MPEG-4 SP
-   </td>
-  </tr>
-  <tr>
-   <td>
-    mpeg4-generic
-   </td>
-   <td>
-    <a href="https://tools.ietf.org/html/rfc3640">
-     RFC 3640
-    </a>
-   </td>
-   <td>
-    See
-    <a href="#5_1_1_audio_codecs">
-     section 5.1.1
-    </a>
-    for details on AAC and its variants
-   </td>
-  </tr>
-  <tr>
-   <td>
-    MP2T
-   </td>
-   <td>
-    <a href="https://tools.ietf.org/html/rfc2250">
-     RFC 2250
-    </a>
-   </td>
-   <td>
-    See
-    <a href="#mp2t">
-     MPEG-2 Transport Stream
-    </a>
-    underneath HTTP Live Streaming for details
-   </td>
-  </tr>
- </table>
- <h3 id="5_8_secure_media">
-  5.8. Secure Media
- </h3>
- <p>
-  Device implementations that support secure video output and are capable of
-supporting secure surfaces MUST declare support for Display.FLAG_SECURE. Device
-implementations that declare support for Display.FLAG_SECURE, if they support a
-wireless display protocol, MUST secure the link with a cryptographically strong
-mechanism such as HDCP 2.x or higher for Miracast wireless displays. Similarly
-if they support a wired external display, the device implementations MUST
-support HDCP 1.2 or higher. Android Television device implementations MUST
-support HDCP 2.2 for devices supporting 4K resolution and HDCP 1.4 or above for
-lower resolutions. The upstream Android open source implementation includes
-support for wireless (Miracast) and wired (HDMI) displays that satisfies this
-requirement.
- </p>
- <h3 id="5_9_musical_instrument_digital_interface_(midi)">
-  5.9. Musical Instrument Digital Interface (MIDI)
- </h3>
- <p>
-  If a device implementation supports the inter-app MIDI software transport
-(virtual MIDI devices), and it supports MIDI over
-  <em>
-   all
-  </em>
-  of the following
-MIDI-capable hardware transports for which it provides generic non-MIDI
-connectivity, it is STRONGLY RECOMMENDED to report support for feature
-android.software.midi via the
-  <a href="http://developer.android.com/reference/android/content/pm/PackageManager.html">
-   android.content.pm.PackageManager
-  </a>
-  class.
- </p>
- <p>
-  The MIDI-capable hardware transports are:
- </p>
- <ul>
-  <li>
-   USB host mode (section 7.7 USB)
-  </li>
-  <li>
-   USB peripheral mode (section 7.7 USB)
-  </li>
-  <li>
-   MIDI over Bluetooth LE acting in central role (section 7.4.3 Bluetooth)
-  </li>
- </ul>
- <p>
-  Conversely, if the device implementation provides generic non-MIDI connectivity
-over a particular MIDI-capable hardware transport listed above, but does not
-support MIDI over that hardware transport, it MUST NOT report support for
-feature android.software.midi.
- </p>
- <h3 id="5_10_professional_audio">
-  5.10. Professional Audio
- </h3>
- <p>
-  If a device implementation meets
-  <em>
-   all
-  </em>
-  of the following requirements, it is
-STRONGLY RECOMMENDED to report support for feature android.hardware.audio.pro
-via the
-  <a href="http://developer.android.com/reference/android/content/pm/PackageManager.html">
-   android.content.pm.PackageManager
-  </a>
-  class.
- </p>
- <ul>
-  <li>
-   The device implementation MUST report support for feature
-android.hardware.audio.low_latency.
-  </li>
-  <li>
-   The continuous round-trip audio latency, as defined in section 5.6 Audio
-Latency, MUST be 20 milliseconds or less and SHOULD be 10 milliseconds or less
-over at least one supported path.
-  </li>
-  <li>
-   If the device includes a 4 conductor 3.5mm audio jack, the continuous
-round-trip audio latency MUST be 20 milliseconds or less over the audio jack
-path, and SHOULD be 10 milliseconds or less over at the audio jack path.
-  </li>
-  <li>
-   The device implementation MUST include a USB port(s) supporting USB host
-mode and USB peripheral mode.
-  </li>
-  <li>
-   The USB host mode MUST implement the USB audio class.
-  </li>
-  <li>
-   If the device includes an HDMI port, the device implementation MUST support
-output in stereo and eight channels at 20-bit or 24-bit depth and 192 kHz
-without bit-depth loss or resampling.
-  </li>
-  <li>
-   The device implementation MUST report support for feature
-android.software.midi.
-  </li>
-  <li>
-   If the device includes a 4 conductor 3.5mm audio jack, the device
-implementation is STRONGLY RECOMMENDED to comply with section
-   <a href="https://source.android.com/accessories/headset/specification.html#mobile_device_jack_specifications">
-    Mobile device
-(jack) specifications
-   </a>
-   of the
-   <a href="https://source.android.com/accessories/headset/specification.html">
-    Wired Audio Headset Specification (v1.1)
-   </a>.
-  </li>
- </ul>
- <p>
-  Latencies and USB audio requirements MUST be met using the
-  <a href="https://developer.android.com/ndk/guides/audio/opensl-for-android.html">
-   OpenSL ES
-  </a>
-  PCM buffer queue API.
- </p>
- <p>
-  In addition, a device implementation that reports support for this feature SHOULD:
- </p>
- <ul>
-  <li>
-   Provide a sustainable level of CPU performance while audio is active.
-  </li>
-  <li>
-   Minimize audio clock inaccuracy and drift relative to standard time.
-  </li>
-  <li>
-   Minimize audio clock drift relative to the CPU
-   <code>
-    CLOCK_MONOTONIC
-   </code>
-   when both are active.
-  </li>
-  <li>
-   Minimize audio latency over on-device transducers.
-  </li>
-  <li>
-   Minimize audio latency over USB digital audio.
-  </li>
-  <li>
-   Document audio latency measurements over all paths.
-  </li>
-  <li>
-   Minimize jitter in audio buffer completion callback entry times, as this affects usable percentage of full CPU bandwidth by the callback.
-  </li>
-  <li>
-   Provide zero audio underruns (output) or overruns (input) under normal use at reported latency.
-  </li>
-  <li>
-   Provide zero inter-channel latency difference.
-  </li>
-  <li>
-   Minimize MIDI mean latency over all transports.
-  </li>
-  <li>
-   Minimize MIDI latency variability under load (jitter) over all transports.
-  </li>
-  <li>
-   Provide accurate MIDI timestamps over all transports.
-  </li>
-  <li>
-   Minimize audio signal noise over on-device transducers, including the period immediately after cold start.
-  </li>
-  <li>
-   Provide zero audio clock difference between the input and output sides of corresponding
-    end-points, when both are active.  Examples of corresponding end-points include
-    the on-device microphone and speaker, or the audio jack input and output.
-  </li>
-  <li>
-   Handle audio buffer completion callbacks for the input and output sides of corresponding
-    end-points on the same thread when both are active, and enter the output callback immediately
-    after the return from the input callback.  Or if it is not feasible to handle the callbacks
-    on the same thread, then enter the output callback shortly after entering the input callback
-    to permit the application to have a consistent timing of the input and output sides.
-  </li>
-  <li>
-   Minimize the phase difference between HAL audio buffering for the input and output
-    sides of corresponding end-points.
-  </li>
-  <li>
-   Minimize touch latency.
-  </li>
-  <li>
-   Minimize touch latency variability under load (jitter).
-  </li>
- </ul>
- <h3 id="5_11_capture_for_unprocessed">
-  5.11. Capture for Unprocessed
- </h3>
- <p>
-  Starting from Android 7.0,
-a new recording source has been added. It can be accessed using
-the
-  <code>
-   android.media.MediaRecorder.AudioSource.UNPROCESSED
-  </code>
-  audio
-source. In OpenSL ES, it can be accessed with the record preset
-  <code>
-   SL_ANDROID_RECORDING_PRESET_UNPROCESSED
-  </code>
-  .
- </p>
- <p>
-  A device MUST satisfy all of the following requirements to report support
-of the unprocessed audio source via the
-  <code>
-   android.media.AudioManager
-  </code>
-  property
-  <a href="http://developer.android.com/reference/android/media/AudioManager.html#PROPERTY_SUPPORT_AUDIO_SOURCE_UNPROCESSED">
-   PROPERTY_SUPPORT_AUDIO_SOURCE_UNPROCESSED
-  </a>:
- </p>
- <ul>
-  <li>
-   <p>
-    The device MUST exhibit approximately flat amplitude-versus-frequency
-characteristics in the mid-frequency range: specifically &plusmn;10dB from
-100 Hz to 7000 Hz.
-   </p>
-  </li>
-  <li>
-   <p>
-    The device MUST exhibit amplitude levels in the low frequency range:
-specifically from &plusmn;20 dB from 5 Hz to 100 Hz compared to the mid-frequency range.
-   </p>
-  </li>
-  <li>
-   <p>
-    The device MUST exhibit amplitude levels in the high frequency range:
-specifically from &plusmn;30 dB from 7000 Hz to 22 KHz compared to the mid-frequency range.
-   </p>
-  </li>
-  <li>
-   <p>
-    Audio input sensitivity MUST be set such that a 1000 Hz sinusoidal tone
-source played at 94 dB Sound Pressure Level (SPL)
-yields a response with RMS of 520 for 16
-bit-samples (or -36 dB Full Scale for floating point/double precision
-samples).
-   </p>
-  </li>
-  <li>
-   <p>
-    SNR &gt; 60 dB (difference between 94 dB SPL and equivalent SPL of self
-noise, A-weighted).
-   </p>
-  </li>
-  <li>
-   <p>
-    Total harmonic distortion MUST be less than 1% for 1 kHZ at 90 dB SPL
-input level at the microphone.
-   </p>
-  </li>
-  <li>
-   <p>
-    The only signal processing allowed in the path is a level multiplier
-to bring the level to desired range. This level multiplier MUST NOT
-introduce delay or latency to the signal path.
-   </p>
-  </li>
-  <li>
-   <p>
-    No other signal processing is allowed in the path, such as Automatic Gain
-Control, High Pass Filter, or Echo Cancellation. If any signal processing
-is present in the architecture for any reason, it MUST be disabled and
-effectively introduce zero delay or extra latency to the signal path.
-   </p>
-  </li>
- </ul>
- <p>
-  All SPL measurements are made directly next to the microphone under test.
- </p>
- <p>
-  For multiple microphone configurations, these requirements apply to each
-microphone.
- </p>
- <p>
-  It is STRONGLY RECOMMENDED that a device satisfy as many of the requirements for the signal
-path for the unprocessed recording source; however, a device must satisfy
-  <em>
-   all
-  </em>
-  of these
-requirements, listed above, if it claims to support the unprocessed audio source.
- </p>
- <h2 id="6_developer_tools_and_options_compatibility">
-  6. Developer Tools and Options Compatibility
- </h2>
- <h3 id="6_1_developer_tools">
-  6.1. Developer Tools
- </h3>
- <p>
-  Device implementations MUST support the Android Developer Tools provided in the
-Android SDK. Android compatible devices MUST be compatible with:
- </p>
- <ul>
-  <li>
-   <a href="http://developer.android.com/tools/help/adb.html">
-    <strong>
-     Android Debug Bridge (adb)
-    </strong>
-   </a>
-   <ul>
-    <li>
-     Device implementations MUST support all adb functions as documented in
-the Android SDK including
-     <a href="https://source.android.com/devices/input/diagnostics.html">
-      dumpsys
-     </a>.
-    </li>
-    <li>
-     The device-side adb daemon MUST be inactive by default and there MUST
-be a user-accessible mechanism to turn on the Android Debug Bridge. If a device
-implementation omits USB peripheral mode, it MUST implement the Android Debug
-Bridge via local-area network (such as Ethernet or 802.11).
-    </li>
-    <li>
-     Android includes support for secure adb. Secure adb enables adb on
-known authenticated hosts. Device implementations MUST support secure adb.
-    </li>
-   </ul>
-  </li>
-  <li>
-   <a href="http://developer.android.com/tools/debugging/ddms.html">
-    <strong>
-     Dalvik Debug Monitor Service (ddms)
-    </strong>
-   </a>
-   <ul>
-    <li>
-     Device implementations MUST support all ddms features as documented in the Android SDK.
-    </li>
-    <li>
-     As ddms uses adb, support for ddms SHOULD be inactive by default, but MUST be supported whenever the user has activated the Android Debug Bridge, as above.
-    </li>
-   </ul>
-  </li>
-  <li>
-   <a href="http://developer.android.com/tools/help/monkey.html">
-    <strong>
-     Monkey
-    </strong>
-   </a>
-   Device
-implementations MUST include the Monkey framework, and make it available for
-applications to use.
-  </li>
-  <li>
-   <a href="http://developer.android.com/tools/help/systrace.html">
-    <strong>
-     SysTrace
-    </strong>
-   </a>
-   <ul>
-    <li>
-     Device implementations MUST support systrace tool as documented in the
-Android SDK. Systrace must be inactive by default, and there MUST be a
-user-accessible mechanism to turn on Systrace.
-    </li>
-    <li>
-     Most Linux-based systems and Apple Macintosh systems recognize Android
-devices using the standard Android SDK tools, without additional support;
-however Microsoft Windows systems typically require a driver for new Android
-devices. (For instance, new vendor IDs and sometimes new device IDs require
-custom USB drivers for Windows systems.)
-    </li>
-    <li>
-     If a device implementation is unrecognized by the adb tool as provided
-in the standard Android SDK, device implementers MUST provide Windows drivers
-allowing developers to connect to the device using the adb protocol. These
-drivers MUST be provided for Windows XP, Windows Vista, Windows 7, Windows 8,
-and Windows 10 in both 32-bit and 64-bit versions.
-    </li>
-   </ul>
-  </li>
- </ul>
- <h3 id="6_2_developer_options">
-  6.2. Developer Options
- </h3>
- <p>
-  Android includes support for developers to configure application
-development-related settings. Device implementations MUST honor the
-  <a href="http://developer.android.com/reference/android/provider/Settings.html#ACTION_APPLICATION_DEVELOPMENT_SETTINGS">
-   android.settings.APPLICATION_DEVELOPMENT_SETTINGS
-  </a>
-  intent to show application development-related settings The upstream Android
-implementation hides the Developer Options menu by default and enables users to
-launch Developer Options after pressing seven (7) times on the
-  <strong>
-   Settings
-  </strong>
-  &gt;
-  <strong>
-   About Device
-  </strong>
-  &gt;
-  <strong>
-   Build Number
-  </strong>
-  menu item. Device implementations MUST
-provide a consistent experience for Developer Options. Specifically, device
-implementations MUST hide Developer Options by default and MUST provide a
-mechanism to enable Developer Options that is consistent with the upstream
-Android implementation.
- </p>
- <div class="note">
-  Android Automotive implementations MAY limit access to the Developer Options
-menu by visually hiding or disabling the menu when the vehicle is in motion.
- </div>
- <h2 id="7_hardware_compatibility">
-  7. Hardware Compatibility
- </h2>
- <p>
-  If a device includes a particular hardware component that has a corresponding
-API for third-party developers, the device implementation MUST implement that
-API as described in the Android SDK documentation. If an API in the SDK
-interacts with a hardware component that is stated to be optional and the
-device implementation does not possess that component:
- </p>
- <ul>
-  <li>
-   Complete class definitions (as documented by the SDK) for the component
-APIs MUST still be presented.
-  </li>
-  <li>
-   The API&rsquo;s behaviors MUST be implemented as no-ops in some reasonable
-fashion.
-  </li>
-  <li>
-   API methods MUST return null values where permitted by the SDK
-documentation.
-  </li>
-  <li>
-   API methods MUST return no-op implementations of classes where null values
-are not permitted by the SDK documentation.
-  </li>
-  <li>
-   API methods MUST NOT throw exceptions not documented by the SDK
-documentation.
-  </li>
- </ul>
- <p>
-  A typical example of a scenario where these requirements apply is the telephony
-API: Even on non-phone devices, these APIs must be implemented as reasonable
-no-ops.
- </p>
- <p>
-  Device implementations MUST consistently report accurate hardware configuration
-information via the getSystemAvailableFeatures() and hasSystemFeature(String)
-methods on the
-  <a href="http://developer.android.com/reference/android/content/pm/PackageManager.html">
-   android.content.pm.PackageManager
-  </a>
-  class for the same build fingerprint.
- </p>
- <h3 id="7_1_display_and_graphics">
-  7.1. Display and Graphics
- </h3>
- <p>
-  Android includes facilities that automatically adjust application assets and UI
-layouts appropriately for the device to ensure that third-party applications
-run well on a
-  <a href="http://developer.android.com/guide/practices/screens_support.html">
-   variety of hardware configurations
-  </a>.
-Devices MUST properly implement these APIs and behaviors, as detailed in this
-section.
- </p>
- <p>
-  The units referenced by the requirements in this section are defined as follows:
- </p>
- <ul>
-  <li>
-   <strong>
-    physical diagonal size
-   </strong>
-   . The distance in inches between two opposing
-corners of the illuminated portion of the display.
-  </li>
-  <li>
-   <strong>
-    dots per inch (dpi)
-   </strong>
-   . The number of pixels encompassed by a linear
-horizontal or vertical span of 1&rdquo;. Where dpi values are listed, both horizontal
-and vertical dpi must fall within the range.
-  </li>
-  <li>
-   <strong>
-    aspect ratio
-   </strong>
-   . The ratio of the pixels of the longer dimension to the
-shorter dimension of the screen. For example, a display of 480x854 pixels would
-be 854/480 = 1.779, or roughly &ldquo;16:9&rdquo;.
-  </li>
-  <li>
-   <strong>
-    density-independent pixel (dp)
-   </strong>
-   . The virtual pixel unit normalized to a
-160 dpi screen, calculated as: pixels = dps * (density/160).
-  </li>
- </ul>
- <h4 id="7_1_1_screen_configuration">
-  7.1.1. Screen Configuration
- </h4>
- <h5 id="7_1_1_1_screen_size">
-  7.1.1.1. Screen Size
- </h5>
- <div class="note">
-  Android Watch devices (detailed in
-  <a href="#2_device_types">
-   section 2
-  </a>
-  ) MAY have
-smaller screen sizes as described in this section.
- </div>
- <p>
-  The Android UI framework supports a variety of different screen sizes, and
-allows applications to query the device screen size (aka &ldquo;screen layout") via
-android.content.res.Configuration.screenLayout with the SCREENLAYOUT_SIZE_MASK.
-Device implementations MUST report the correct
-  <a href="http://developer.android.com/guide/practices/screens_support.html">
-   screen size
-  </a>
-  as
-defined in the Android SDK documentation and determined by the upstream Android
-platform. Specifically, device implementations MUST report the correct screen
-size according to the following logical density-independent pixel (dp) screen
-dimensions.
- </p>
- <ul>
-  <li>
-   Devices MUST have screen sizes of at least 426 dp x 320 dp (&lsquo;small&rsquo;),
-unless it is an Android Watch device.
-  </li>
-  <li>
-   Devices that report screen size &lsquo;normal&rsquo; MUST have screen sizes of at least
-480 dp x 320 dp.
-  </li>
-  <li>
-   Devices that report screen size &lsquo;large&rsquo; MUST have screen sizes of at least
-640 dp x 480 dp.
-  </li>
-  <li>
-   Devices that report screen size &lsquo;xlarge&rsquo; MUST have screen sizes of at least
-960 dp x 720 dp.
-  </li>
- </ul>
- <p>
-  In addition:
- </p>
- <ul>
-  <li>
-   Android Watch devices MUST have a screen with the physical diagonal size in
-the range from 1.1 to 2.5 inches.
-  </li>
-  <li>
-   Android Automotive devices MUST have a screen with the physical diagonal
-size greater than or equal to 6 inches.
-  </li>
-  <li>
-   Android Automotive devices MUST have a screen size of at least 750 dp x
-480 dp.
-  </li>
-  <li>
-   Other types of Android device implementations, with a physically integrated
-screen, MUST have a screen at least 2.5 inches in physical diagonal size.
-  </li>
- </ul>
- <p>
-  Devices MUST NOT change their reported screen size at any time.
- </p>
- <p>
-  Applications optionally indicate which screen sizes they support via the
-&lt;supports-screens&gt; attribute in the AndroidManifest.xml file. Device
-implementations MUST correctly honor applications' stated support for small,
-normal, large, and xlarge screens, as described in the Android SDK
-documentation.
- </p>
- <h5 id="7_1_1_2_screen_aspect_ratio">
-  7.1.1.2. Screen Aspect Ratio
- </h5>
- <p>
-  While there is no restriction to the screen aspect ratio value of the physical
-screen display, the screen aspect ratio of the surface that third-party apps
-are rendered on and which can be derived from the values reported via the
-  <a href="https://developer.android.com/reference/android/util/DisplayMetrics.html">
-   DisplayMetrics
-  </a>
-  MUST meet the following requirements:
- </p>
- <ul>
-  <li>
-   If the
-   <a href="https://developer.android.com/reference/android/content/res/Configuration.html#uiMode">
-    uiMode
-   </a>
-   is configured as UI_MODE_TYPE_WATCH, the aspect ratio value MAY be set as
-1.0 (1:1).
-  </li>
-  <li>
-   If the third-party app indicates that it is resizeable via the
-   <a href="https://developer.android.com/guide/topics/ui/multi-window.html#configuring">
-    android:resizeableActivity
-   </a>
-   attribute, there are no restrictions to the aspect ratio value.
-  </li>
-  <li>
-   For all other cases, the aspect ratio MUST be a value between 1.3333 (4:3)
-and 1.86 (roughly 16:9) unless the app has indicated explicitly that it
-supports a higher screen aspect ratio through  the
-   <a href="https://developer.android.com/guide/practices/screens_support.html#MaxAspectRatio">
-    maxAspectRatio
-   </a>
-   metadata value.
-  </li>
- </ul>
- <h5 id="7_1_1_3_screen_density">
-  7.1.1.3. Screen Density
- </h5>
- <p>
-  The Android UI framework defines a set of standard logical densities to help
-application developers target application resources. By default, device
-implementations MUST report only one of the following logical Android framework
-densities through the
-  <a href="https://developer.android.com/reference/android/util/DisplayMetrics.html#DENSITY_DEVICE_STABLE">
-   DENSITY_DEVICE_STABLE
-  </a>
-  API and this value MUST NOT change at any time; however, the device MAY report
-a different arbitrary density according to the display configuration changes
-made by the user (for example, display size) set after initial boot.
- </p>
- <ul>
-  <li>
-   120 dpi (ldpi)
-  </li>
-  <li>
-   160 dpi (mdpi)
-  </li>
-  <li>
-   213 dpi (tvdpi)
-  </li>
-  <li>
-   240 dpi (hdpi)
-  </li>
-  <li>
-   260 dpi (260dpi)
-  </li>
-  <li>
-   280 dpi (280dpi)
-  </li>
-  <li>
-   300 dpi (300dpi)
-  </li>
-  <li>
-   320 dpi (xhdpi)
-  </li>
-  <li>
-   340 dpi (340dpi)
-  </li>
-  <li>
-   360 dpi (360dpi)
-  </li>
-  <li>
-   400 dpi (400dpi)
-  </li>
-  <li>
-   420 dpi (420dpi)
-  </li>
-  <li>
-   480 dpi (xxhdpi)
-  </li>
-  <li>
-   560 dpi (560dpi)
-  </li>
-  <li>
-   640 dpi (xxxhdpi)
-  </li>
- </ul>
- <p>
-  Device implementations SHOULD define the standard Android framework density
-that is numerically closest to the physical density of the screen, unless that
-logical density pushes the reported screen size below the minimum supported. If
-the standard Android framework density that is numerically closest to the
-physical density results in a screen size that is smaller than the smallest
-supported compatible screen size (320 dp width), device implementations SHOULD
-report the next lowest standard Android framework density.
- </p>
- <p>
-  Device implementations are STRONGLY RECOMMENDED to provide users a setting to change
-the display size. If there is an implementation to change the display size of the device,
-it MUST align with the AOSP implementation as indicated below:
- </p>
- <ul>
-  <li>
-   The display size MUST NOT be scaled any larger than 1.5 times the native density or
-   produce an effective minimum screen dimension smaller than 320dp (equivalent
-   to resource qualifier sw320dp), whichever comes first.
-  </li>
-  <li>
-   Display size MUST NOT be scaled any smaller than 0.85 times the native density.
-  </li>
-  <li>
-   To ensure good usability and consistent font sizes, it is RECOMMENDED that the
-   following scaling of Native Display options be provided (while complying with the limits
-   specified above)
-  </li>
-  <li>
-   Small: 0.85x
-  </li>
-  <li>
-   Default: 1x (Native display scale)
-  </li>
-  <li>
-   Large: 1.15x
-  </li>
-  <li>
-   Larger: 1.3x
-  </li>
-  <li>
-   Largest 1.45x
-  </li>
- </ul>
- <h4 id="7_1_2_display_metrics">
-  7.1.2. Display Metrics
- </h4>
- <p>
-  Device implementations MUST report correct values for all display metrics
-defined in
-  <a href="http://developer.android.com/reference/android/util/DisplayMetrics.html">
-   android.util.DisplayMetrics
-  </a>
-  and MUST report the same values regardless of whether the embedded or external
-screen is used as the default display.
- </p>
- <h4 id="7_1_3_screen_orientation">
-  7.1.3. Screen Orientation
- </h4>
- <p>
-  Devices MUST report which screen orientations they support
-(android.hardware.screen.portrait and/or android.hardware.screen.landscape) and
-MUST report at least one supported orientation. For example, a device with a
-fixed orientation landscape screen, such as a television or laptop, SHOULD only
-report android.hardware.screen.landscape.
- </p>
- <p>
-  Devices that report both screen orientations MUST support dynamic orientation
-by applications to either portrait or landscape screen orientation. That is,
-the device must respect the application&rsquo;s request for a specific screen
-orientation. Device implementations MAY select either portrait or landscape
-orientation as the default.
- </p>
- <p>
-  Devices MUST report the correct value for the device&rsquo;s current orientation,
-whenever queried via the android.content.res.Configuration.orientation,
-android.view.Display.getOrientation(), or other APIs.
- </p>
- <p>
-  Devices MUST NOT change the reported screen size or density when changing orientation.
- </p>
- <h4 id="7_1_4_2d_and_3d_graphics_acceleration">
-  7.1.4. 2D and 3D Graphics Acceleration
- </h4>
- <p>
-  Device implementations MUST support both OpenGL ES 1.0 and 2.0, as embodied and
-detailed in the Android SDK documentations. Device implementations SHOULD
-support OpenGL ES 3.0, 3.1, or 3.2 on devices capable of supporting it. Device
-implementations MUST also support
-  <a href="http://developer.android.com/guide/topics/renderscript/">
-   Android RenderScript
-  </a>,
-as detailed in the Android SDK documentation.
- </p>
- <p>
-  Device implementations MUST also correctly identify themselves as supporting
-OpenGL ES 1.0, OpenGL ES 2.0, OpenGL ES 3.0, OpenGL 3.1, or OpenGL 3.2. That is:
- </p>
- <ul>
-  <li>
-   The managed APIs (such as via the GLES10.getString() method) MUST report
-support for OpenGL ES 1.0 and OpenGL ES 2.0.
-  </li>
-  <li>
-   The native C/C++ OpenGL APIs (APIs available to apps via libGLES_v1CM.so,
-libGLES_v2.so, or libEGL.so) MUST report support for OpenGL ES 1.0 and OpenGL
-ES 2.0.
-  </li>
-  <li>
-   Device implementations that declare support for OpenGL ES 3.0, 3.1, or 3.2 MUST
-support the corresponding managed APIs and include support for native C/C++
-APIs. On device implementations that declare support for OpenGL ES 3.0, 3.1, or
-3.2 libGLESv2.so MUST export the corresponding function symbols in addition to
-the OpenGL ES 2.0 function symbols.
-  </li>
- </ul>
- <p>
-  Android provides an OpenGL ES
-  <a href="https://developer.android.com/reference/android/opengl/GLES31Ext.html">
-   extension pack
-  </a>
-  with Java interfaces and native support for advanced graphics functionality
-such as tessellation and the ASTC texture compression format. Android device
-implementations MUST support the extension pack if the device supports OpenGL
-ES 3.2 and MAY support it otherwise. If the extension pack is supported in its
-entirety, the device MUST identify the support through the
-  <code>
-   android.hardware.opengles.aep
-  </code>
-  feature flag.
- </p>
- <p>
-  Also, device implementations MAY implement any desired OpenGL ES extensions.
-However, device implementations MUST report via the OpenGL ES managed and
-native APIs all extension strings that they do support, and conversely MUST NOT
-report extension strings that they do not support.
- </p>
- <p>
-  Note that Android includes support for applications to optionally specify that
-they require specific OpenGL texture compression formats. These formats are
-typically vendor-specific. Device implementations are not required by Android
-to implement any specific texture compression format. However, they SHOULD
-accurately report any texture compression formats that they do support, via the
-getString() method in the OpenGL API.
- </p>
- <p>
-  Android includes a mechanism for applications to declare that they want to
-enable hardware acceleration for 2D graphics at the Application, Activity,
-Window, or View level through the use of a manifest tag
-  <a href="http://developer.android.com/guide/topics/graphics/hardware-accel.html">
-   android:hardwareAccelerated
-  </a>
-  or direct API calls.
- </p>
- <p>
-  Device implementations MUST enable hardware acceleration by default, and MUST
-disable hardware acceleration if the developer so requests by setting
-android:hardwareAccelerated="false&rdquo; or disabling hardware acceleration directly
-through the Android View APIs.
- </p>
- <p>
-  In addition, device implementations MUST exhibit behavior consistent with the
-Android SDK documentation on
-  <a href="http://developer.android.com/guide/topics/graphics/hardware-accel.html">
-   hardware
-acceleration
-  </a>.
- </p>
- <p>
-  Android includes a TextureView object that lets developers directly integrate
-hardware-accelerated OpenGL ES textures as rendering targets in a UI hierarchy.
-Device implementations MUST support the TextureView API, and MUST exhibit
-consistent behavior with the upstream Android implementation.
- </p>
- <p>
-  Android includes support for EGL_ANDROID_RECORDABLE, an EGLConfig attribute
-that indicates whether the EGLConfig supports rendering to an ANativeWindow
-that records images to a video. Device implementations MUST support
-  <a href="https://www.khronos.org/registry/egl/extensions/ANDROID/EGL_ANDROID_recordable.txt">
-   EGL_ANDROID_RECORDABLE
-  </a>
-  extension.
- </p>
- <h4 id="7_1_5_legacy_application_compatibility_mode">
-  7.1.5. Legacy Application Compatibility Mode
- </h4>
- <p>
-  Android specifies a &ldquo;compatibility mode&rdquo; in which the framework operates in a
-'normal' screen size equivalent (320dp width) mode for the benefit of legacy
-applications not developed for old versions of Android that pre-date
-screen-size independence.
- </p>
- <ul>
-  <li>
-   Android Automotive does not support legacy compatibility mode.
-  </li>
-  <li>
-   All other device implementations MUST include support for legacy
-application compatibility mode as implemented by the upstream Android open
-source code. That is, device implementations MUST NOT alter the triggers or
-thresholds at which compatibility mode is activated, and MUST NOT alter the
-behavior of the compatibility mode itself.
-  </li>
- </ul>
- <h4 id="7_1_6_screen_technology">
-  7.1.6. Screen Technology
- </h4>
- <p>
-  The Android platform includes APIs that allow applications to render rich
-graphics to the display. Devices MUST support all of these APIs as defined by
-the Android SDK unless specifically allowed in this document.
- </p>
- <ul>
-  <li>
-   Devices MUST support displays capable of rendering 16-bit color graphics
-and SHOULD support displays capable of 24-bit color graphics.
-  </li>
-  <li>
-   Devices MUST support displays capable of rendering animations.
-  </li>
-  <li>
-   The display technology used MUST have a pixel aspect ratio (PAR) between
-0.9 and 1.15. That is, the pixel aspect ratio MUST be near square (1.0) with a
-10 ~ 15% tolerance.
-  </li>
- </ul>
- <h4 id="7_1_7_secondary_displays">
-  7.1.7. Secondary Displays
- </h4>
- <p>
-  Android includes support for secondary display to enable media sharing
-capabilities and developer APIs for accessing external displays. If a device
-supports an external display either via a wired, wireless, or an embedded
-additional display connection then the device implementation MUST implement the
-  <a href="http://developer.android.com/reference/android/hardware/display/DisplayManager.html">
-   display manager
-API
-  </a>
-  as described in the Android SDK documentation.
- </p>
- <h3 id="7_2_input_devices">
-  7.2. Input Devices
- </h3>
- <p>
-  Devices MUST support a touchscreen or meet the requirements listed in 7.2.2 for
-non-touch navigation.
- </p>
- <h4 id="7_2_1_keyboard">
-  7.2.1. Keyboard
- </h4>
- <div class="note">
-  Android Watch and Android Automotive implementations MAY implement a soft
-keyboard. All other device implementations MUST implement a soft keyboard and:
- </div>
- <p>
-  Device implementations:
- </p>
- <ul>
-  <li>
-   MUST include support for the Input Management Framework (which allows
-third-party developers to create Input Method Editors&mdash;i.e. soft keyboard) as
-detailed at
-   <a href="http://developer.android.com">
-    http://developer.android.com
-   </a>.
-  </li>
-  <li>
-   MUST provide at least one soft keyboard implementation (regardless of
-whether a hard keyboard is present) except for Android Watch devices where the
-screen size makes it less reasonable to have a soft keyboard.
-  </li>
-  <li>
-   MAY include additional soft keyboard implementations.
-  </li>
-  <li>
-   MAY include a hardware keyboard.
-  </li>
-  <li>
-   MUST NOT include a hardware keyboard that does not match one of the formats
-specified in
-   <a href="http://developer.android.com/reference/android/content/res/Configuration.html">
-    android.content.res.Configuration.keyboard
-   </a>
-   (QWERTY or 12-key).
-  </li>
- </ul>
- <h4 id="7_2_2_non-touch_navigation">
-  7.2.2. Non-touch Navigation
- </h4>
- <div class="note">
-  Android Television devices MUST support D-pad.
- </div>
- <p>
-  Device implementations:
- </p>
- <ul>
-  <li>
-   MAY omit a non-touch navigation option (trackball, d-pad, or wheel) if the
-device implementation is not an Android Television device.
-  </li>
-  <li>
-   MUST report the correct value for
-   <a href="http://developer.android.com/reference/android/content/res/Configuration.html">
-    android.content.res.Configuration.navigation
-   </a>.
-  </li>
-  <li>
-   MUST provide a reasonable alternative user interface mechanism for the
-selection and editing of text, compatible with Input Management Engines. The
-upstream Android open source implementation includes a selection mechanism
-suitable for use with devices that lack non-touch navigation inputs.
-  </li>
- </ul>
- <h4 id="7_2_3_navigation_keys">
-  7.2.3. Navigation Keys
- </h4>
- <div class="note">
-  The availability and visibility requirement of the Home, Recents, and Back
-functions differ between device types as described in this section.
- </div>
- <p>
-  The Home, Recents, and Back functions (mapped to the key events KEYCODE_HOME,
-KEYCODE_APP_SWITCH, KEYCODE_BACK, respectively) are essential to the Android
-navigation paradigm and therefore:
- </p>
- <ul>
-  <li>
-   Android Handheld device implementations MUST provide the Home, Recents, and
-    Back functions.
-  </li>
-  <li>
-   Android Television device implementations MUST provide the Home and Back
-    functions.
-  </li>
-  <li>
-   Android Watch device implementations MUST have the Home function available
-    to the user, and the Back function except for when it is in
-   <code>
-    UI_MODE_TYPE_WATCH
-   </code>
-   .
-  </li>
-  <li>
-   Android Watch device implementations, and no other Android device types,
-    MAY consume the long press event on the key event
-   <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BACK">
-    <code>
-     KEYCODE_BACK
-    </code>
-   </a>
-   and omit it from being sent to the foreground application.
-  </li>
-  <li>
-   Android Automotive implementations MUST provide the Home function and MAY
-    provide Back and Recent functions.
-  </li>
-  <li>
-   All other types of device implementations MUST provide the Home and Back
-    functions.
-  </li>
- </ul>
- <p>
-  These functions MAY be implemented via dedicated physical buttons (such as
-mechanical or capacitive touch buttons), or MAY be implemented using dedicated
-software keys on a distinct portion of the screen, gestures, touch panel, etc.
-Android supports both implementations. All of these functions MUST be accessible
-with a single action (e.g. tap, double-click or gesture) when visible.
- </p>
- <p>
-  Recents function, if provided, MUST have a visible button or icon unless hidden
-together with other navigation functions in full-screen mode. This does not
-apply to devices upgrading from earlier Android versions that have physical
-buttons for navigation and no recents key.
- </p>
- <p>
-  The Home and Back functions, if provided, MUST each have a visible button or
-icon unless hidden together with other navigation functions in full-screen mode
-or when the uiMode UI_MODE_TYPE_MASK is set to UI_MODE_TYPE_WATCH.
- </p>
- <p>
-  The Menu function is deprecated in favor of action bar since Android 4.0.
-Therefore the new device implementations shipping with Android 7.1
-and later MUST NOT implement a dedicated physical button for the Menu function.
-Older device implementations SHOULD NOT implement a dedicated physical button
-for the Menu function, but if the physical Menu button is implemented and the
-device is running applications with targetSdkVersion &gt; 10, the device
-implementation:
- </p>
- <ul>
-  <li>
-   MUST display the action overflow button on the action bar when it is visible
-and the resulting action overflow menu popup is not empty. For a device
-implementation launched before Android 4.4 but upgrading to Android
-7.1, this is RECOMMENDED.
-  </li>
-  <li>
-   MUST NOT modify the position of the action overflow popup displayed by
-selecting the overflow button in the action bar.
-  </li>
-  <li>
-   MAY render the action overflow popup at a modified position on the screen
-when it is displayed by selecting the physical menu button.
-  </li>
- </ul>
- <p>
-  For backwards compatibility, device implementations MUST make the Menu function
-available to applications when targetSdkVersion is less than 10, either by a
-physical button, a software key, or gestures. This Menu function should be
-presented unless hidden together with other navigation functions.
- </p>
- <p>
-  Android device implementations supporting the
-  <a href="http://developer.android.com/reference/android/content/Intent.html#ACTION_ASSIST">
-   Assist action
-  </a>
-  and/or
-  <a href="https://developer.android.com/reference/android/service/voice/VoiceInteractionService.html">
-   <code>
-    VoiceInteractionService
-   </code>
-  </a>
-  MUST be able to launch an assist app with a single interaction (e.g. tap,
-double-click, or gesture) when other navigation keys are visible. It is STRONGLY
-RECOMMENDED to use long press on home as this interaction. The designated
-interaction MUST launch the user-selected assist app, in other words the app
-that implements a VoiceInteractionService, or an activity handling the ACTION_ASSIST intent.
- </p>
- <p>
-  Device implementations MAY use a distinct portion of the screen to display the
-navigation keys, but if so, MUST meet these requirements:
- </p>
- <ul>
-  <li>
-   Device implementation navigation keys MUST use a distinct portion of the
-screen, not available to applications, and MUST NOT obscure or otherwise
-interfere with the portion of the screen available to applications.
-  </li>
-  <li>
-   Device implementations MUST make available a portion of the display to
-applications that meets the requirements defined in
-   <a href="#7_1_1_screen_configuration">
-    section
-7.1.1
-   </a>.
-  </li>
-  <li>
-   Device implementations MUST display the navigation keys when applications do
-not specify a system UI mode, or specify SYSTEM_UI_FLAG_VISIBLE.
-  </li>
-  <li>
-   Device implementations MUST present the navigation keys in an unobtrusive
-&ldquo;low profile&rdquo; (eg. dimmed) mode when applications specify
-SYSTEM_UI_FLAG_LOW_PROFILE.
-  </li>
-  <li>
-   Device implementations MUST hide the navigation keys when applications
-specify SYSTEM_UI_FLAG_HIDE_NAVIGATION.
-  </li>
- </ul>
- <h4 id="7_2_4_touchscreen_input">
-  7.2.4. Touchscreen Input
- </h4>
- <div class="note">
-  Android Handhelds and Watch Devices MUST support touchscreen input.
- </div>
- <p>
-  Device implementations SHOULD have a pointer input system of some kind (either
-mouse-like or touch). However, if a device implementation does not support a
-pointer input system, it MUST NOT report the android.hardware.touchscreen or
-android.hardware.faketouch feature constant. Device implementations that do
-include a pointer input system:
- </p>
- <ul>
-  <li>
-   SHOULD support fully independently tracked pointers, if the device input
-system supports multiple pointers.
-  </li>
-  <li>
-   MUST report the value of
-   <a href="http://developer.android.com/reference/android/content/res/Configuration.html">
-    android.content.res.Configuration.touchscreen
-   </a>
-   corresponding to the type of the specific touchscreen on the device.
-  </li>
- </ul>
- <p>
-  Android includes support for a variety of touchscreens, touch pads, and fake
-touch input devices.
-  <a href="http://source.android.com/devices/tech/input/touch-devices.html">
-   Touchscreen-based device implementations
-  </a>
-  are associated with a display such that the user has the impression of directly
-manipulating items on screen. Since the user is directly touching the screen,
-the system does not require any additional affordances to indicate the objects
-being manipulated. In contrast, a fake touch interface provides a user input
-system that approximates a subset of touchscreen capabilities. For example, a
-mouse or remote control that drives an on-screen cursor approximates touch, but
-requires the user to first point or focus then click. Numerous input devices
-like the mouse, trackpad, gyro-based air mouse, gyro-pointer, joystick, and
-multi-touch trackpad can support fake touch interactions. Android includes the
-feature constant android.hardware.faketouch, which corresponds to a
-high-fidelity non-touch (pointer-based) input device such as a mouse or trackpad
-that can adequately emulate touch-based input (including basic gesture support),
-and indicates that the device supports an emulated subset of touchscreen
-functionality. Device implementations that declare the fake touch feature MUST
-meet the fake touch requirements in
-  <a href="#7_2_5_fake_touch_input">
-   section 7.2.5
-  </a>.
- </p>
- <p>
-  Device implementations MUST report the correct feature corresponding to the type
-of input used. Device implementations that include a touchscreen (single-touch
-or better) MUST report the platform feature constant
-android.hardware.touchscreen. Device implementations that report the platform
-feature constant android.hardware.touchscreen MUST also report the platform
-feature constant android.hardware.faketouch. Device implementations that do not
-include a touchscreen (and rely on a pointer device only) MUST NOT report any
-touchscreen feature, and MUST report only android.hardware.faketouch if they
-meet the fake touch requirements in
-  <a href="#7_2_5_fake_touch_input">
-   section 7.2.5
-  </a>.
- </p>
- <h4 id="7_2_5_fake_touch_input">
-  7.2.5. Fake Touch Input
- </h4>
- <p>
-  Device implementations that declare support for android.hardware.faketouch:
- </p>
- <ul>
-  <li>
-   MUST report the
-   <a href="http://developer.android.com/reference/android/view/MotionEvent.html">
-    absolute X and Y screen positions
-   </a>
-   of the pointer location and display a visual pointer on the screen.
-  </li>
-  <li>
-   MUST report touch event with the action code that specifies the state change
-that occurs on the pointer
-   <a href="http://developer.android.com/reference/android/view/MotionEvent.html">
-    going down or up on the
-screen
-   </a>.
-  </li>
-  <li>
-   MUST support pointer down and up on an object on the screen, which allows
-users to emulate tap on an object on the screen.
-  </li>
-  <li>
-   MUST support pointer down, pointer up, pointer down then pointer up in the
-same place on an object on the screen within a time threshold, which allows
-users to
-   <a href="http://developer.android.com/reference/android/view/MotionEvent.html">
-    emulate double tap
-   </a>
-   on an object on the screen.
-  </li>
-  <li>
-   MUST support pointer down on an arbitrary point on the screen, pointer move
-to any other arbitrary point on the screen, followed by a pointer up, which
-allows users to emulate a touch drag.
-  </li>
-  <li>
-   MUST support pointer down then allow users to quickly move the object to a
-different position on the screen and then pointer up on the screen, which allows
-users to fling an object on the screen.
-  </li>
- </ul>
- <p>
-  Devices that declare support for android.hardware.faketouch.multitouch.distinct
-MUST meet the requirements for faketouch above, and MUST also support distinct
-tracking of two or more independent pointer inputs.
- </p>
- <h4 id="7_2_6_game_controller_support">
-  7.2.6. Game Controller Support
- </h4>
- <p>
-  Android Television device implementations MUST support button mappings for game
-controllers as listed below. The upstream Android implementation includes
-implementation for game controllers that satisfies this requirement.
- </p>
- <h5 id="7_2_6_1_button_mappings">
-  7.2.6.1. Button Mappings
- </h5>
- <p>
-  Android Television device implementations MUST support the following key mappings:
- </p>
- <table>
-  <tr>
-   <th>
-    Button
-   </th>
-   <th>
-    HID Usage
-    <sup>
-     2
-    </sup>
-   </th>
-   <th>
-    Android Button
-   </th>
-  </tr>
-  <tr>
-   <td>
-    <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BUTTON_A">
-     A
-    </a>
-    <sup>
-     1
-    </sup>
-   </td>
-   <td>
-    0x09 0x0001
-   </td>
-   <td>
-    KEYCODE_BUTTON_A (96)
-   </td>
-  </tr>
-  <tr>
-   <td>
-    <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BUTTON_B">
-     B
-    </a>
-    <sup>
-     1
-    </sup>
-   </td>
-   <td>
-    0x09 0x0002
-   </td>
-   <td>
-    KEYCODE_BUTTON_B (97)
-   </td>
-  </tr>
-  <tr>
-   <td>
-    <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BUTTON_X">
-     X
-    </a>
-    <sup>
-     1
-    </sup>
-   </td>
-   <td>
-    0x09 0x0004
-   </td>
-   <td>
-    KEYCODE_BUTTON_X (99)
-   </td>
-  </tr>
-  <tr>
-   <td>
-    <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BUTTON_Y">
-     Y
-    </a>
-    <sup>
-     1
-    </sup>
-   </td>
-   <td>
-    0x09 0x0005
-   </td>
-   <td>
-    KEYCODE_BUTTON_Y (100)
-   </td>
-  </tr>
-  <tr>
-   <td>
-    <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_DPAD_UP">
-     D-pad up
-    </a>
-    <sup>
-     1
-    </sup>
-    <br/>
-    <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_DPAD_DOWN">
-     D-pad down
-    </a>
-    <sup>
-     1
-    </sup>
-   </td>
-   <td>
-    0x01 0x0039
-    <sup>
-     3
-    </sup>
-   </td>
-   <td>
-    <a href="http://developer.android.com/reference/android/view/MotionEvent.html#AXIS_HAT_Y">
-     AXIS_HAT_Y
-    </a>
-    <sup>
-     4
-    </sup>
-   </td>
-  </tr>
-  <tr>
-   <td>
-    <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_DPAD_LEFT">
-     D-pad left
-    </a>
-    1
-    <br/>
-    <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_DPAD_RIGHT">
-     D-pad right
-    </a>
-    <sup>
-     1
-    </sup>
-   </td>
-   <td>
-    0x01 0x0039
-    <sup>
-     3
-    </sup>
-   </td>
-   <td>
-    <a href="http://developer.android.com/reference/android/view/MotionEvent.html#AXIS_HAT_X">
-     AXIS_HAT_X
-    </a>
-    <sup>
-     4
-    </sup>
-   </td>
-  </tr>
-  <tr>
-   <td>
-    <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BUTTON_L1">
-     Left shoulder button
-    </a>
-    <sup>
-     1
-    </sup>
-   </td>
-   <td>
-    0x09 0x0007
-   </td>
-   <td>
-    KEYCODE_BUTTON_L1 (102)
-   </td>
-  </tr>
-  <tr>
-   <td>
-    <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BUTTON_R1">
-     Right shoulder button
-    </a>
-    <sup>
-     1
-    </sup>
-   </td>
-   <td>
-    0x09 0x0008
-   </td>
-   <td>
-    KEYCODE_BUTTON_R1 (103)
-   </td>
-  </tr>
-  <tr>
-   <td>
-    <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BUTTON_THUMBL">
-     Left stick click
-    </a>
-    <sup>
-     1
-    </sup>
-   </td>
-   <td>
-    0x09 0x000E
-   </td>
-   <td>
-    KEYCODE_BUTTON_THUMBL (106)
-   </td>
-  </tr>
-  <tr>
-   <td>
-    <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BUTTON_THUMBR">
-     Right stick click
-    </a>
-    <sup>
-     1
-    </sup>
-   </td>
-   <td>
-    0x09 0x000F
-   </td>
-   <td>
-    KEYCODE_BUTTON_THUMBR (107)
-   </td>
-  </tr>
-  <tr>
-   <td>
-    <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_HOME">
-     Home
-    </a>
-    <sup>
-     1
-    </sup>
-   </td>
-   <td>
-    0x0c 0x0223
-   </td>
-   <td>
-    KEYCODE_HOME (3)
-   </td>
-  </tr>
-  <tr>
-   <td>
-    <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BACK">
-     Back
-    </a>
-    <sup>
-     1
-    </sup>
-   </td>
-   <td>
-    0x0c 0x0224
-   </td>
-   <td>
-    KEYCODE_BACK (4)
-   </td>
-  </tr>
- </table>
- <p class="table_footnote">
-  1
-  <a href="http://developer.android.com/reference/android/view/KeyEvent.html">
-   KeyEvent
-  </a>
- </p>
- <p class="table_footnote">
-  2 The above HID usages must be declared within a Game
-pad CA (0x01 0x0005).
- </p>
- <p class="table_footnote">
-  3 This usage must have a Logical Minimum of 0, a
-Logical Maximum of 7, a Physical Minimum of 0, a Physical Maximum of 315, Units
-in Degrees, and a Report Size of 4. The logical value is defined to be the
-clockwise rotation away from the vertical axis; for example, a logical value of
-0 represents no rotation and the up button being pressed, while a logical value
-of 1 represents a rotation of 45 degrees and both the up and left keys being
-pressed.
- </p>
- <p class="table_footnote">
-  4
-  <a href="http://developer.android.com/reference/android/view/MotionEvent.html">
-   MotionEvent
-  </a>
- </p>
- <table>
-  <tr>
-   <th>
-    Analog Controls
-    <sup>
-     1
-    </sup>
-   </th>
-   <th>
-    HID Usage
-   </th>
-   <th>
-    Android Button
-   </th>
-  </tr>
-  <tr>
-   <td>
-    <a href="http://developer.android.com/reference/android/view/MotionEvent.html#AXIS_LTRIGGER">
-     Left Trigger
-    </a>
-   </td>
-   <td>
-    0x02 0x00C5
-   </td>
-   <td>
-    AXIS_LTRIGGER
-   </td>
-  </tr>
-  <tr>
-   <td>
-    <a href="http://developer.android.com/reference/android/view/MotionEvent.html#AXIS_THROTTLE">
-     Right Trigger
-    </a>
-   </td>
-   <td>
-    0x02 0x00C4
-   </td>
-   <td>
-    AXIS_RTRIGGER
-   </td>
-  </tr>
-  <tr>
-   <td>
-    <a href="http://developer.android.com/reference/android/view/MotionEvent.html#AXIS_Y">
-     Left Joystick
-    </a>
-   </td>
-   <td>
-    0x01 0x0030
-    <br/>
-    0x01 0x0031
-   </td>
-   <td>
-    AXIS_X
-    <br/>
-    AXIS_Y
-   </td>
-  </tr>
-  <tr>
-   <td>
-    <a href="http://developer.android.com/reference/android/view/MotionEvent.html#AXIS_Z">
-     Right Joystick
-    </a>
-   </td>
-   <td>
-    0x01 0x0032
-    <br/>
-    0x01 0x0035
-   </td>
-   <td>
-    AXIS_Z
-    <br/>
-    AXIS_RZ
-   </td>
-  </tr>
- </table>
- <p class="table_footnote">
-  1
-  <a href="http://developer.android.com/reference/android/view/MotionEvent.html">
-   MotionEvent
-  </a>
- </p>
- <h4 id="7_2_7_remote_control">
-  7.2.7. Remote Control
- </h4>
- <p>
-  Android Television device implementations SHOULD provide a remote control to
-allow users to access the TV interface. The remote control MAY be a physical
-remote or can be a software-based remote that is accessible from a mobile phone
-or tablet. The remote control MUST meet the requirements defined below.
- </p>
- <ul>
-  <li>
-   <strong>
-    Search affordance
-   </strong>
-   . Device implementations MUST fire KEYCODE_SEARCH
-(or KEYCODE_ASSIST if the device supports an assistant) when the user
-invokes voice search on either the physical or software-based remote.
-  </li>
-  <li>
-   <strong>
-    Navigation
-   </strong>
-   . All Android Television remotes MUST include
-   <a href="http://developer.android.com/reference/android/view/KeyEvent.html">
-    Back, Home, and Select buttons and support for D-pad events
-   </a>.
-  </li>
- </ul>
- <h3 id="7_3_sensors">
-  7.3. Sensors
- </h3>
- <p>
-  Android includes APIs for accessing a variety of sensor types. Devices
-implementations generally MAY omit these sensors, as provided for in the
-following subsections. If a device includes a particular sensor type that has a
-corresponding API for third-party developers, the device implementation MUST
-implement that API as described in the Android SDK documentation and the
-Android Open Source documentation on
-  <a href="http://source.android.com/devices/sensors/">
-   sensors
-  </a>. For example, device
-implementations:
- </p>
- <ul>
-  <li>
-   MUST accurately report the presence or absence of sensors per the
-   <a href="http://developer.android.com/reference/android/content/pm/PackageManager.html">
-    android.content.pm.PackageManager
-   </a>
-   class.
-  </li>
-  <li>
-   MUST return an accurate list of supported sensors via the
-SensorManager.getSensorList() and similar methods.
-  </li>
-  <li>
-   MUST behave reasonably for all other sensor APIs (for example, by returning
-true or false as appropriate when applications attempt to register listeners,
-not calling sensor listeners when the corresponding sensors are not present;
-etc.).
-  </li>
-  <li>
-   MUST
-   <a href="http://developer.android.com/reference/android/hardware/SensorEvent.html">
-    report all sensor measurements
-   </a>
-   using the relevant International System of Units (metric) values for each
-sensor type as defined in the Android SDK documentation.
-  </li>
-  <li>
-   SHOULD
-   <a href="http://developer.android.com/reference/android/hardware/SensorEvent.html#timestamp">
-    report the event time
-   </a>
-   in nanoseconds as defined in the Android SDK documentation, representing the
-time the event happened and synchronized with the
-SystemClock.elapsedRealtimeNano() clock. Existing and new Android devices are
-   <strong>
-    STRONGLY RECOMMENDED
-   </strong>
-   to meet these requirements so they will be able to
-upgrade to the future platform releases where this might become a REQUIRED
-component. The synchronization error SHOULD be below 100 milliseconds.
-  </li>
-  <li>
-   MUST report sensor data with a maximum latency of 100 milliseconds + 2 *
-sample_time for the case of a sensor streamed with a minimum required latency
-of 5 ms + 2 * sample_time when the application processor is active. This delay
-does not include any filtering delays.
-  </li>
-  <li>
-   MUST report the first sensor sample within 400 milliseconds + 2 *
-sample_time of the sensor being activated. It is acceptable for this sample to
-have an accuracy of 0.
-  </li>
- </ul>
- <p>
-  The list above is not comprehensive; the documented behavior of the Android SDK
-and the Android Open Source Documentations on
-  <a href="http://source.android.com/devices/sensors/">
-   sensors
-  </a>
-  is to be considered
-authoritative.
- </p>
- <p>
-  Some sensor types are composite, meaning they can be derived from data provided
-by one or more other sensors. (Examples include the orientation sensor and the
-linear acceleration sensor.) Device implementations SHOULD implement these
-sensor types, when they include the prerequisite physical sensors as described
-in
-  <a href="https://source.android.com/devices/sensors/sensor-types.html">
-   sensor types
-  </a>. If a
-device implementation includes a composite sensor it MUST implement the sensor
-as described in the Android Open Source documentation on
-  <a href="https://source.android.com/devices/sensors/sensor-types.html#composite_sensor_type_summary">
-   composite sensors
-  </a>.
- </p>
- <p>
-  Some Android sensors support a
-  <a href="https://source.android.com/devices/sensors/report-modes.html#continuous">
-   &ldquo;continuous&rdquo; trigger mode
-  </a>,
-which returns data continuously. For any API indicated by the Android SDK
-documentation to be a continuous sensor, device implementations MUST
-continuously provide periodic data samples that SHOULD have a jitter below 3%,
-where jitter is defined as the standard deviation of the difference of the
-reported timestamp values between consecutive events.
- </p>
- <p>
-  Note that the device implementations MUST ensure that the sensor event stream
-MUST NOT prevent the device CPU from entering a suspend state or waking up from
-a suspend state.
- </p>
- <p>
-  Finally, when several sensors are activated, the power consumption SHOULD NOT
-exceed the sum of the individual sensor&rsquo;s reported power consumption.
- </p>
- <h4 id="7_3_1_accelerometer">
-  7.3.1. Accelerometer
- </h4>
- <p>
-  Device implementations SHOULD include a 3-axis accelerometer. Android Handheld
-devices, Android Automotive implementations, and Android Watch devices are STRONGLY
-RECOMMENDED to include this sensor. If a device implementation does include a
-3-axis accelerometer, it:
- </p>
- <ul>
-  <li>
-   MUST implement and report
-   <a href="http://developer.android.com/reference/android/hardware/Sensor.html#TYPE_ACCELEROMETER">
-    TYPE_ACCELEROMETER sensor
-   </a>.
-  </li>
-  <li>
-   MUST be able to report events up to a frequency of at least 50 Hz for
-Android Watch devices as such devices have a stricter power constraint and 100
-Hz for all other device types.
-  </li>
-  <li>
-   SHOULD report events up to at least 200 Hz.
-  </li>
-  <li>
-   MUST comply with the
-   <a href="http://developer.android.com/reference/android/hardware/SensorEvent.html">
-    Android sensor coordinate system
-   </a>
-   as detailed in the Android APIs. Android Automotive implementations MUST comply
-with the Android
-   <a href="http://source.android.com/devices/sensors/sensor-types.html#auto_axes">
-    car sensor coordinate system
-   </a>.
-  </li>
-  <li>
-   MUST be capable of measuring from freefall up to four times the gravity
-(4g) or more on any axis.
-  </li>
-  <li>
-   MUST have a resolution of at least 12-bits and SHOULD have a resolution of
-at least 16-bits.
-  </li>
-  <li>
-   SHOULD be calibrated while in use if the characteristics changes over the
-life cycle and compensated, and preserve the compensation parameters between
-device reboots.
-  </li>
-  <li>
-   SHOULD be temperature compensated.
-  </li>
-  <li>
-   MUST have a standard deviation no greater than 0.05 m/s^, where the
-standard deviation should be calculated on a per axis basis on samples
-collected over a period of at least 3 seconds at the fastest sampling rate.
-  </li>
-  <li>
-   SHOULD implement the TYPE_SIGNIFICANT_MOTION, TYPE_TILT_DETECTOR,
-TYPE_STEP_DETECTOR, TYPE_STEP_COUNTER composite sensors as described in the
-Android SDK document. Existing and new Android devices are
-   <strong>
-    STRONGLY
-RECOMMENDED
-   </strong>
-   to implement the TYPE_SIGNIFICANT_MOTION composite sensor. If any
-of these sensors are implemented, the sum of their power consumption MUST
-always be less than 4 mW and SHOULD each be below 2 mW and 0.5 mW for when the
-device is in a dynamic or static condition.
-  </li>
-  <li>
-   If a gyroscope sensor is included, MUST implement the TYPE_GRAVITY and
-TYPE_LINEAR_ACCELERATION composite sensors and SHOULD implement the
-TYPE_GAME_ROTATION_VECTOR composite sensor. Existing and new Android devices
-are STRONGLY RECOMMENDED to implement the TYPE_GAME_ROTATION_VECTOR sensor.
-  </li>
-  <li>
-   MUST implement a TYPE_ROTATION_VECTOR composite sensor, if a gyroscope
-sensor and a magnetometer sensor is also included.
-  </li>
- </ul>
- <h4 id="7_3_2_magnetometer">
-  7.3.2. Magnetometer
- </h4>
- <p>
-  Device implementations SHOULD include a 3-axis magnetometer (compass). If a
-device does include a 3-axis magnetometer, it:
- </p>
- <ul>
-  <li>
-   MUST implement the TYPE_MAGNETIC_FIELD sensor and SHOULD also implement
-TYPE_MAGNETIC_FIELD_UNCALIBRATED sensor. Existing and new Android devices are
-STRONGLY RECOMMENDED to implement the TYPE_MAGNETIC_FIELD_UNCALIBRATED sensor.
-  </li>
-  <li>
-   MUST be able to report events up to a frequency of at least 10 Hz and
-SHOULD report events up to at least 50 Hz.
-  </li>
-  <li>
-   MUST comply with the
-   <a href="http://developer.android.com/reference/android/hardware/SensorEvent.html">
-    Android sensor coordinate system
-   </a>
-   as detailed in the Android APIs.
-  </li>
-  <li>
-   MUST be capable of measuring between -900 &micro;T and +900 &micro;T on each axis
-before saturating.
-  </li>
-  <li>
-   MUST have a hard iron offset value less than 700 &micro;T and SHOULD have a value
-below 200 &micro;T, by placing the magnetometer far from dynamic (current-induced)
-and static (magnet-induced) magnetic fields.
-  </li>
-  <li>
-   MUST have a resolution equal or denser than 0.6 &micro;T and SHOULD have a
-resolution equal or denser than 0.2 &micro;T.
-  </li>
-  <li>
-   SHOULD be temperature compensated.
-  </li>
-  <li>
-   MUST support online calibration and compensation of the hard iron bias, and
-preserve the compensation parameters between device reboots.
-  </li>
-  <li>
-   MUST have the soft iron compensation applied&mdash;the calibration can be done
-either while in use or during the production of the device.
-  </li>
-  <li>
-   SHOULD have a standard deviation, calculated on a per axis basis on samples
-collected over a period of at least 3 seconds at the fastest sampling rate, no
-greater than 0.5 &micro;T.
-  </li>
-  <li>
-   MUST implement a TYPE_ROTATION_VECTOR composite sensor, if an accelerometer
-sensor and a gyroscope sensor is also included.
-  </li>
-  <li>
-   MAY implement the TYPE_GEOMAGNETIC_ROTATION_VECTOR sensor if an
-accelerometer sensor is also implemented. However if implemented, it MUST
-consume less than 10 mW and SHOULD consume less than 3 mW when the sensor is
-registered for batch mode at 10 Hz.
-  </li>
- </ul>
- <h4 id="7_3_3_gps">
-  7.3.3. GPS
- </h4>
- <p>
-  Device implementations SHOULD include a GPS/GNSS receiver. If a device implementation
-does include a GPS/GNSS receiver and reports the capability to applications through the
-  <code>
-   android.hardware.location.gps
-  </code>
-  feature flag:
- </p>
- <ul>
-  <li>
-   It is STRONGLY RECOMMENDED that the device continue to deliver normal GPS/GNSS
-    outputs to applications during an emergency phone call and that location output
-    not be blocked during an emergency phone call.
-  </li>
-  <li>
-   It MUST support location outputs at a rate of at least 1 Hz when requested via
-   <code>
-    LocationManager#requestLocationUpdate
-   </code>
-   .
-  </li>
-  <li>
-   It MUST be able to determine the location in open-sky conditions (strong signals,
-    negligible multipath, HDOP &lt; 2) within 10 seconds (fast time to first fix), when
-    connected to a 0.5 Mbps or faster data speed internet connection. This requirement
-    is typically met by the use of some form of Assisted or Predicted GPS/GNSS technique
-    to minimize GPS/GNSS lock-on time (Assistance data includes Reference Time, Reference
-    Location and Satellite Ephemeris/Clock).
-   <ul>
-    <li>
-     After making such a location calculation, it is STRONGLY RECOMMENDED for the device to
-     be able to determine its location, in open sky, within 10 seconds, when location
-     requests are restarted, up to an hour after the initial location calculation,
-     even when the subsequent request is made without a data connection, and/or after a power
-     cycle.
-    </li>
-   </ul>
-  </li>
-  <li>
-   In open sky conditions after determining the location, while stationary or moving with less
-    than 1 meter per second squared of acceleration:
-   <ul>
-    <li>
-     It MUST be able to determine location within 20 meters, and speed within 0.5 meters
-     per second, at least 95% of the time.
-    </li>
-    <li>
-     It MUST simultaneously track and report via
-     <a href="https://developer.android.com/reference/android/location/GnssStatus.Callback.html#GnssStatus.Callback()'">
-      GnssStatus.Callback
-     </a>
-     at least 8 satellites from one constellation.
-    </li>
-    <li>
-     It SHOULD be able to simultaneously track at least 24 satellites, from multiple
-     constellations (e.g. GPS + at least one of Glonass, Beidou, Galileo).
-    </li>
-   </ul>
-  </li>
-  <li>
-   It MUST report the GNSS technology generation through the test API &lsquo;getGnssYearOfHardware&rsquo;.
-  </li>
-  <li>
-   It is STRONGLY RECOMMENDED to meet and MUST meet all requirements below if the GNSS technology
-    generation is reported as the year "2016" or newer.
-   <ul>
-    <li>
-     It MUST report GPS measurements, as soon as they are found, even if a location calculated
-     from GPS/GNSS is not yet reported.
-    </li>
-    <li>
-     It MUST report GPS pseudoranges and pseudorange rates, that, in open-sky conditions
-     after determining the location, while stationary or moving with less than 0.2 meter
-     per second squared of acceleration, are sufficient to calculate position within
-     20 meters, and speed within 0.2 meters per second, at least 95% of the time.
-    </li>
-   </ul>
-  </li>
- </ul>
- <p>
-  Note that while some of the GPS requirements above are stated as STRONGLY RECOMMENDED, the
-Compatibility Definition for the next major version is expected to change these to a MUST.
- </p>
- <h4 id="7_3_4_gyroscope">
-  7.3.4. Gyroscope
- </h4>
- <p>
-  Device implementations SHOULD include a gyroscope (angular change sensor).
-Devices SHOULD NOT include a gyroscope sensor unless a 3-axis accelerometer is
-also included. If a device implementation includes a gyroscope, it:
- </p>
- <ul>
-  <li>
-   MUST implement the TYPE_GYROSCOPE sensor and SHOULD also implement
-TYPE_GYROSCOPE_UNCALIBRATED sensor. Existing and new Android devices are
-STRONGLY RECOMMENDED to implement the SENSOR_TYPE_GYROSCOPE_UNCALIBRATED
-sensor.
-  </li>
-  <li>
-   MUST be capable of measuring orientation changes up to 1,000 degrees per
-second.
-  </li>
-  <li>
-   MUST be able to report events up to a frequency of at least 50 Hz for
-Android Watch devices as such devices have a stricter power constraint and 100
-Hz for all other device types.
-  </li>
-  <li>
-   SHOULD report events up to at least 200 Hz.
-  </li>
-  <li>
-   MUST have a resolution of 12-bits or more and SHOULD have a resolution of
-16-bits or more.
-  </li>
-  <li>
-   MUST be temperature compensated.
-  </li>
-  <li>
-   MUST be calibrated and compensated while in use, and preserve the
-compensation parameters between device reboots.
-  </li>
-  <li>
-   MUST have a variance no greater than 1e-7 rad^2 / s^2 per Hz (variance per
-Hz, or rad^2 / s). The variance is allowed to vary with the sampling rate, but
-must be constrained by this value. In other words, if you measure the variance
-of the gyro at 1 Hz sampling rate it should be no greater than 1e-7 rad^2/s^2.
-  </li>
-  <li>
-   MUST implement a TYPE_ROTATION_VECTOR composite sensor, if an accelerometer
-sensor and a magnetometer sensor is also included.
-  </li>
-  <li>
-   If an accelerometer sensor is included, MUST implement the TYPE_GRAVITY and
-TYPE_LINEAR_ACCELERATION composite sensors and SHOULD implement the
-TYPE_GAME_ROTATION_VECTOR composite sensor. Existing and new Android devices
-are STRONGLY RECOMMENDED to implement the TYPE_GAME_ROTATION_VECTOR sensor.
-  </li>
- </ul>
- <h4 id="7_3_5_barometer">
-  7.3.5. Barometer
- </h4>
- <p>
-  Device implementations SHOULD include a barometer (ambient air pressure
-sensor). If a device implementation includes a barometer, it:
- </p>
- <ul>
-  <li>
-   MUST implement and report TYPE_PRESSURE sensor.
-  </li>
-  <li>
-   MUST be able to deliver events at 5 Hz or greater.
-  </li>
-  <li>
-   MUST have adequate precision to enable estimating altitude.
-  </li>
-  <li>
-   MUST be temperature compensated.
-  </li>
- </ul>
- <h4 id="7_3_6_thermometer">
-  7.3.6. Thermometer
- </h4>
- <p>
-  Device implementations MAY include an ambient thermometer (temperature sensor).
-If present, it MUST be defined as SENSOR_TYPE_AMBIENT_TEMPERATURE and it MUST
-measure the ambient (room) temperature in degrees Celsius.
- </p>
- <p>
-  Device implementations MAY but SHOULD NOT include a CPU temperature sensor. If
-present, it MUST be defined as SENSOR_TYPE_TEMPERATURE, it MUST measure the
-temperature of the device CPU, and it MUST NOT measure any other temperature.
-Note the SENSOR_TYPE_TEMPERATURE sensor type was deprecated in Android 4.0.
- </p>
- <div class="note">
-  For Android Automotive implementations, SENSOR_TYPE_AMBIENT_TEMPERATURE MUST
-measure the temperature inside the vehicle cabin.
- </div>
- <h4 id="7_3_7_photometer">
-  7.3.7. Photometer
- </h4>
- <p>
-  Device implementations MAY include a photometer (ambient light sensor).
- </p>
- <h4 id="7_3_8_proximity_sensor">
-  7.3.8. Proximity Sensor
- </h4>
- <p>
-  Device implementations MAY include a proximity sensor. Devices that can make a
-voice call and indicate any value other than PHONE_TYPE_NONE in getPhoneType
-SHOULD include a proximity sensor. If a device implementation does include a
-proximity sensor, it:
- </p>
- <ul>
-  <li>
-   MUST measure the proximity of an object in the same direction as the
-screen. That is, the proximity sensor MUST be oriented to detect objects close
-to the screen, as the primary intent of this sensor type is to detect a phone
-in use by the user. If a device implementation includes a proximity sensor with
-any other orientation, it MUST NOT be accessible through this API.
-  </li>
-  <li>
-   MUST have 1-bit of accuracy or more.
-  </li>
- </ul>
- <h4 id="7_3_9_high_fidelity_sensors">
-  7.3.9. High Fidelity Sensors
- </h4>
- <p>
-  Device implementations supporting a set of higher quality sensors that can meet
-all the requirements listed in this section MUST identify the support through
-the
-  <code>
-   android.hardware.sensor.hifi_sensors
-  </code>
-  feature flag.
- </p>
- <p>
-  A device declaring android.hardware.sensor.hifi_sensors MUST support all of the
-following sensor types meeting the quality requirements as below:
- </p>
- <ul>
-  <li>
-   SENSOR_TYPE_ACCELEROMETER
-   <ul>
-    <li>
-     MUST have a measurement range between at least -8g and +8g.
-    </li>
-    <li>
-     MUST have a measurement resolution of at least 1024 LSB/G.
-    </li>
-    <li>
-     MUST have a minimum measurement frequency of 12.5 Hz or lower.
-    </li>
-    <li>
-     MUST have a maximum measurement frequency of 400 Hz or higher.
-    </li>
-    <li>
-     MUST have a measurement noise not above 400 uG/&radic;Hz.
-    </li>
-    <li>
-     MUST implement a non-wake-up form of this sensor with a buffering
-    capability of at least 3000 sensor events.
-    </li>
-    <li>
-     MUST have a batching power consumption not worse than 3 mW.
-    </li>
-    <li>
-     SHOULD have a stationary noise bias stability of \&lt;15 &mu;g &radic;Hz from 24hr static
-    dataset.
-    </li>
-    <li>
-     SHOULD have a bias change vs. temperature of &le; +/- 1mg / &deg;C.
-    </li>
-    <li>
-     SHOULD have a best-fit line non-linearity of &le; 0.5%, and sensitivity change vs. temperature of &le;
-    0.03%/C&deg;.
-    </li>
-   </ul>
-  </li>
-  <li>
-   <p>
-    SENSOR_TYPE_GYROSCOPE
-   </p>
-   <ul>
-    <li>
-     MUST have a measurement range between at least -1000 and +1000 dps.
-    </li>
-    <li>
-     MUST have a measurement resolution of at least 16 LSB/dps.
-    </li>
-    <li>
-     MUST have a minimum measurement frequency of 12.5 Hz or lower.
-    </li>
-    <li>
-     MUST have a maximum measurement frequency of 400 Hz or higher.
-    </li>
-    <li>
-     MUST have a measurement noise not above 0.014&deg;/s/&radic;Hz.
-    </li>
-    <li>
-     SHOULD have a stationary bias stability of &lt; 0.0002 &deg;/s &radic;Hz from 24-hour static dataset.
-    </li>
-    <li>
-     SHOULD have a bias change vs. temperature of &le; +/- 0.05 &deg;/ s / &deg;C.
-    </li>
-    <li>
-     SHOULD have a sensitivity change vs. temperature of &le; 0.02% / &deg;C.
-    </li>
-    <li>
-     SHOULD have a best-fit line non-linearity of &le; 0.2%.
-    </li>
-    <li>
-     SHOULD have a noise density of &le; 0.007 &deg;/s/&radic;Hz.
-    </li>
-   </ul>
-  </li>
-  <li>
-   <p>
-    SENSOR_TYPE_GYROSCOPE_UNCALIBRATED with the same quality requirements as
-    SENSOR_TYPE_GYROSCOPE.
-   </p>
-  </li>
-  <li>
-   SENSOR_TYPE_GEOMAGNETIC_FIELD
-   <ul>
-    <li>
-     MUST have a measurement range between at least -900 and +900 uT.
-    </li>
-    <li>
-     MUST have a measurement resolution of at least 5 LSB/uT.
-    </li>
-    <li>
-     MUST have a minimum measurement frequency of 5 Hz or lower.
-    </li>
-    <li>
-     MUST have a maximum measurement frequency of 50 Hz or higher.
-    </li>
-    <li>
-     MUST have a measurement noise not above 0.5 uT.
-    </li>
-   </ul>
-  </li>
-  <li>
-   SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED with the same quality requirements
-    as SENSOR_TYPE_GEOMAGNETIC_FIELD and in addition:
-   <ul>
-    <li>
-     MUST implement a non-wake-up form of this sensor with a buffering
-    capability of at least 600 sensor events.
-    </li>
-   </ul>
-  </li>
-  <li>
-   SENSOR_TYPE_PRESSURE
-   <ul>
-    <li>
-     MUST have a measurement range between at least 300 and 1100 hPa.
-    </li>
-    <li>
-     MUST have a measurement resolution of at least 80 LSB/hPa.
-    </li>
-    <li>
-     MUST have a minimum measurement frequency of 1 Hz or lower.
-    </li>
-    <li>
-     MUST have a maximum measurement frequency of 10 Hz or higher.
-    </li>
-    <li>
-     MUST have a measurement noise not above 2 Pa/&radic;Hz.
-    </li>
-    <li>
-     MUST implement a non-wake-up form of this sensor with a buffering
-    capability of at least 300 sensor events.
-    </li>
-    <li>
-     MUST have a batching power consumption not worse than 2 mW.
-    </li>
-   </ul>
-  </li>
-  <li>
-   SENSOR_TYPE_GAME_ROTATION_VECTOR
-   <ul>
-    <li>
-     MUST implement a non-wake-up form of this sensor with a buffering
-    capability of at least 300 sensor events.
-    </li>
-    <li>
-     MUST have a batching power consumption not worse than 4 mW.
-    </li>
-   </ul>
-  </li>
-  <li>
-   SENSOR_TYPE_SIGNIFICANT_MOTION
-   <ul>
-    <li>
-     MUST have a power consumption not worse than 0.5 mW when device is
-    static and 1.5 mW when device is moving.
-    </li>
-   </ul>
-  </li>
-  <li>
-   SENSOR_TYPE_STEP_DETECTOR
-   <ul>
-    <li>
-     MUST implement a non-wake-up form of this sensor with a buffering
-    capability of at least 100 sensor events.
-    </li>
-    <li>
-     MUST have a power consumption not worse than 0.5 mW when device is
-    static and 1.5 mW when device is moving.
-    </li>
-    <li>
-     MUST have a batching power consumption not worse than 4 mW.
-    </li>
-   </ul>
-  </li>
-  <li>
-   SENSOR_TYPE_STEP_COUNTER
-   <ul>
-    <li>
-     MUST have a power consumption not worse than 0.5 mW when device is
-    static and 1.5 mW when device is moving.
-    </li>
-   </ul>
-  </li>
-  <li>
-   SENSOR_TILT_DETECTOR
-   <ul>
-    <li>
-     MUST have a power consumption not worse than 0.5 mW when device is
-    static and 1.5 mW when device is moving.
-    </li>
-   </ul>
-  </li>
- </ul>
- <p>
-  Also such a device MUST meet the following sensor subsystem requirements:
- </p>
- <ul>
-  <li>
-   The event timestamp of the same physical event reported by the
-Accelerometer, Gyroscope sensor and Magnetometer MUST be within 2.5
-milliseconds of each other.
-  </li>
-  <li>
-   The Gyroscope sensor event timestamps MUST be on the same time base as the
-camera subsystem and within 1 milliseconds of error.
-  </li>
-  <li>
-   High Fidelity sensors MUST deliver samples to applications within 5
-milliseconds from the time when the data is available on the physical sensor
-to the application.
-  </li>
-  <li>
-   The power consumption MUST not be higher than 0.5 mW when device is static
-and 2.0 mW when device is moving when any combination of the following sensors
-are enabled:
-   <ul>
-    <li>
-     SENSOR_TYPE_SIGNIFICANT_MOTION
-    </li>
-    <li>
-     SENSOR_TYPE_STEP_DETECTOR
-    </li>
-    <li>
-     SENSOR_TYPE_STEP_COUNTER
-    </li>
-    <li>
-     SENSOR_TILT_DETECTORS
-    </li>
-   </ul>
-  </li>
- </ul>
- <p>
-  Note that all power consumption requirements in this section do not include the
-power consumption of the Application Processor. It is inclusive of the power
-drawn by the entire sensor chain&mdash;the sensor, any supporting circuitry, any
-dedicated sensor processing system, etc.
- </p>
- <p>
-  The following sensor types MAY also be supported on a device implementation
-declaring android.hardware.sensor.hifi_sensors, but if these sensor types are
-present they MUST meet the following minimum buffering capability requirement:
- </p>
- <ul>
-  <li>
-   SENSOR_TYPE_PROXIMITY: 100 sensor events
-  </li>
- </ul>
- <h4 id="7_3_10_fingerprint_sensor">
-  7.3.10. Fingerprint Sensor
- </h4>
- <p>
-  Device implementations with a secure lock screen SHOULD include a fingerprint
-sensor. If a device implementation includes a fingerprint sensor and has a
-corresponding API for third-party developers, it:
- </p>
- <ul>
-  <li>
-   MUST declare support for the android.hardware.fingerprint feature.
-  </li>
-  <li>
-   MUST fully implement the
-   <a href="https://developer.android.com/reference/android/hardware/fingerprint/package-summary.html">
-    corresponding API
-   </a>
-   as described in the Android SDK documentation.
-  </li>
-  <li>
-   MUST have a false acceptance rate not higher than 0.002%.
-  </li>
-  <li>
-   Is STRONGLY RECOMMENDED to have a false rejection rate of less than 10%, as
-measured on the device
-  </li>
-  <li>
-   Is STRONGLY RECOMMENDED to have a latency below 1 second, measured from
-when the fingerprint sensor is touched until the screen is unlocked, for one
-enrolled finger.
-  </li>
-  <li>
-   MUST rate limit attempts for at least 30 seconds after five false trials
-for fingerprint verification.
-  </li>
-  <li>
-   MUST have a hardware-backed keystore implementation, and perform the
-fingerprint matching in a Trusted Execution Environment (TEE) or on a chip with
-a secure channel to the TEE.
-  </li>
-  <li>
-   MUST have all identifiable fingerprint data encrypted and cryptographically
-authenticated such that they cannot be acquired, read or altered outside of the
-Trusted Execution Environment (TEE) as documented in the
-   <a href="https://source.android.com/devices/tech/security/authentication/fingerprint-hal.html">
-    implementation guidelines
-   </a>
-   on the Android Open Source Project site.
-  </li>
-  <li>
-   MUST prevent adding a fingerprint without first establishing a chain of
-trust by having the user confirm existing or add a new device credential
-(PIN/pattern/password) that's secured by TEE; the Android Open Source Project
-    implementation provides the mechanism in the framework to do so.
-  </li>
-  <li>
-   MUST NOT enable 3rd-party applications to distinguish between individual
-fingerprints.
-  </li>
-  <li>
-   MUST honor the DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT flag.
-  </li>
-  <li>
-   MUST, when upgraded from a version earlier than Android 6.0, have the
-fingerprint data securely migrated to meet the above requirements or removed.
-  </li>
-  <li>
-   SHOULD use the Android Fingerprint icon provided in the Android Open Source
-Project.
-  </li>
- </ul>
- <h4 id="7_3_11_android_automotive-only_sensors">
-  7.3.11. Android Automotive-only sensors
- </h4>
- <p>
-  Automotive-specific sensors are defined in the
-  <code>
-   android.car.CarSensorManager API
-  </code>
-  .
- </p>
- <h5 id="7_3_11_1_current_gear">
-  7.3.11.1. Current Gear
- </h5>
- <p>
-  Android Automotive implementations SHOULD provide current gear as SENSOR_TYPE_GEAR.
- </p>
- <h5 id="7_3_11_2_day_night_mode">
-  7.3.11.2. Day Night Mode
- </h5>
- <p>
-  Android Automotive implementations MUST support day/night mode defined as
-SENSOR_TYPE_NIGHT. The value of this flag MUST be consistent with dashboard
-day/night mode and SHOULD be based on ambient light sensor input. The
-underlying ambient light sensor MAY be the same as
-  <a href="#7_3_7_photometer">
-   Photometer
-  </a>.
- </p>
- <h5 id="7_3_11_3_driving_status">
-  7.3.11.3. Driving Status
- </h5>
- <p>
-  Android Automotive implementations MUST support driving status defined as
-SENSOR_TYPE_DRIVING_STATUS, with a default value of DRIVE_STATUS_UNRESTRICTED
-when the vehicle is fully stopped and parked. It is the responsibility of device
-manufacturers to configure SENSOR_TYPE_DRIVING_STATUS in compliance with all
-laws and regulations that apply to markets where the product is shipping.
- </p>
- <h5 id="7_3_11_4_wheel_speed">
-  7.3.11.4. Wheel Speed
- </h5>
- <p>
-  Android Automotive implementations MUST provide vehicle speed defined as
-SENSOR_TYPE_CAR_SPEED.
- </p>
- <h3 id="7_3_12_pose_sensor">
-  7.3.12. Pose Sensor
- </h3>
- <p>
-  Device implementations MAY support pose sensor with 6 degrees of freedom. Android Handheld
-devices are RECOMMENDED to support this sensor. If a device implementation does support pose
-sensor with 6 degrees of freedom, it:
- </p>
- <ul>
-  <li>
-   MUST implement and report
-   <a href="https://developer.android.com/reference/android/hardware/Sensor.html#TYPE_POSE_6DOF">
-    <code>
-     TYPE_POSE_6DOF
-    </code>
-   </a>
-   sensor.
-  </li>
-  <li>
-   MUST be more accurate than the rotation vector alone.
-  </li>
- </ul>
- <h3 id="7_4_data_connectivity">
-  7.4. Data Connectivity
- </h3>
- <h4 id="7_4_1_telephony">
-  7.4.1. Telephony
- </h4>
- <p>
-  &ldquo;Telephony&rdquo; as used by the Android APIs and this document refers specifically
-to hardware related to placing voice calls and sending SMS messages via a GSM
-or CDMA network. While these voice calls may or may not be packet-switched,
-they are for the purposes of Android considered independent of any data
-connectivity that may be implemented using the same network. In other words,
-the Android &ldquo;telephony&rdquo; functionality and APIs refer specifically to voice
-calls and SMS. For instance, device implementations that cannot place calls or
-send/receive SMS messages MUST NOT report the android.hardware.telephony
-feature or any subfeatures, regardless of whether they use a cellular network
-for data connectivity.
- </p>
- <p>
-  Android MAY be used on devices that do not include telephony hardware. That is,
-Android is compatible with devices that are not phones. However, if a device
-implementation does include GSM or CDMA telephony, it MUST implement full
-support for the API for that technology. Device implementations that do not
-include telephony hardware MUST implement the full APIs as no-ops.
- </p>
- <h5 id="7_4_1_1_number_blocking_compatibility">
-  7.4.1.1. Number Blocking Compatibility
- </h5>
- <p>
-  Android Telephony device implementations MUST include number blocking support
-and:
- </p>
- <ul>
-  <li>
-   MUST fully implement
-   <a href="http://developer.android.com/reference/android/provider/BlockedNumberContract.html">
-    BlockedNumberContract
-   </a>
-   and the corresponding API as described in the SDK documentation.
-  </li>
-  <li>
-   MUST block all calls and messages from a phone number in
-'BlockedNumberProvider' without any interaction with apps. The only exception
-is when number blocking is temporarily lifted as described in the SDK
-documentation.
-  </li>
-  <li>
-   MUST NOT write to the
-   <a href="http://developer.android.com/reference/android/provider/CallLog.html">
-    platform call log provider
-   </a>
-   for a blocked call.
-  </li>
-  <li>
-   MUST NOT write to the
-   <a href="http://developer.android.com/reference/android/provider/Telephony.html">
-    Telephony provider
-   </a>
-   for a blocked message.
-  </li>
-  <li>
-   MUST implement a blocked numbers management UI, which is opened with the
-intent returned by TelecomManager.createManageBlockedNumbersIntent() method.
-  </li>
-  <li>
-   MUST NOT allow secondary users to view or edit the blocked numbers on the
-device as the Android platform assumes the primary user to have full control
-of the telephony services, a single instance, on the device. All blocking
-related UI MUST be hidden for secondary users and the blocked list MUST still
-be respected.
-  </li>
-  <li>
-   SHOULD migrate the blocked numbers into the provider when a device updates
-to Android 7.0.
-  </li>
- </ul>
- <h4 id="7_4_2_ieee_802_11_(wi-fi)">
-  7.4.2. IEEE 802.11 (Wi-Fi)
- </h4>
- <p>
-  All Android device implementations SHOULD include support for one or more forms
-of 802.11. If a device implementation does include support for 802.11 and exposes the
-functionality to a third-party application, it MUST implement the corresponding
-Android API and:
- </p>
- <ul>
-  <li>
-   MUST report the hardware feature flag android.hardware.wifi.
-  </li>
-  <li>
-   MUST implement the
-   <a href="http://developer.android.com/reference/android/net/wifi/WifiManager.MulticastLock.html">
-    multicast API
-   </a>
-   as described in the SDK documentation.
-  </li>
-  <li>
-   MUST support multicast DNS (mDNS) and MUST NOT filter mDNS packets
-(224.0.0.251) at any time of operation including:
-   <ul>
-    <li>
-     Even when the screen is not in an active state.
-    </li>
-    <li>
-     For Android Television device implementations, even when in standby
-power states.
-    </li>
-   </ul>
-  </li>
- </ul>
- <h5 id="7_4_2_1_wi-fi_direct">
-  7.4.2.1. Wi-Fi Direct
- </h5>
- <p>
-  Device implementations SHOULD include support for Wi-Fi Direct (Wi-Fi
-peer-to-peer). If a device implementation does include support for Wi-Fi
-Direct, it MUST implement the
-  <a href="http://developer.android.com/reference/android/net/wifi/p2p/WifiP2pManager.html">
-   corresponding Android API
-  </a>
-  as described in the SDK documentation. If a device implementation includes
-support for Wi-Fi Direct, then it:
- </p>
- <ul>
-  <li>
-   MUST report the hardware feature android.hardware.wifi.direct.
-  </li>
-  <li>
-   MUST support regular Wi-Fi operation.
-  </li>
-  <li>
-   SHOULD support concurrent Wi-Fi and Wi-Fi Direct operation.
-  </li>
- </ul>
- <h5 id="7_4_2_2_wi-fi_tunneled_direct_link_setup">
-  7.4.2.2. Wi-Fi Tunneled Direct Link Setup
- </h5>
- <p>
-  Device implementations SHOULD include support for
-  <a href="http://developer.android.com/reference/android/net/wifi/WifiManager.html">
-   Wi-Fi
-Tunneled Direct Link Setup (TDLS)
-  </a>
-  as described in the Android SDK Documentation. If a device
-implementation does include support for TDLS and TDLS is enabled by the
-WiFiManager API, the device:
- </p>
- <ul>
-  <li>
-   SHOULD use TDLS only when it is possible AND beneficial.
-  </li>
-  <li>
-   SHOULD have some heuristic and NOT use TDLS when its performance might be
-worse than going through the Wi-Fi access point.
-  </li>
- </ul>
- <h4 id="7_4_3_bluetooth">
-  7.4.3. Bluetooth
- </h4>
- <div class="note">
-  Android Watch implementations MUST support Bluetooth. Android Television
-implementations MUST support Bluetooth and Bluetooth LE. Android Automotive
-implementations MUST support Bluetooth and SHOULD support Bluetooth LE.
- </div>
- <p>
-  Device implementations that support
-  <code>
-   android.hardware.vr.high_performance
-  </code>
-  feature MUST
-support Bluetooth 4.2 and Bluetooth LE Data Length Extension.
- </p>
- <p>
-  Android includes support for
-  <a href="http://developer.android.com/reference/android/bluetooth/package-summary.html">
-   Bluetooth and Bluetooth Low Energy
-  </a>.
-Device implementations that include support for Bluetooth and Bluetooth Low
-Energy MUST declare the relevant platform features (android.hardware.bluetooth
-and android.hardware.bluetooth_le respectively) and implement the platform APIs.
-Device implementations SHOULD implement relevant Bluetooth profiles such as
-A2DP, AVCP, OBEX, etc. as appropriate for the device.
- </p>
- <p>
-  Android Automotive implementations SHOULD support Message Access Profile (MAP).
-Android Automotive implementations MUST support the following Bluetooth
-profiles:
- </p>
- <ul>
-  <li>
-   Phone calling over Hands-Free Profile (HFP).
-  </li>
-  <li>
-   Media playback over Audio Distribution Profile (A2DP).
-  </li>
-  <li>
-   Media playback control over Remote Control Profile (AVRCP).
-  </li>
-  <li>
-   Contact sharing using the Phone Book Access Profile (PBAP).
-  </li>
- </ul>
- <p>
-  Device implementations including support for Bluetooth Low Energy:
- </p>
- <ul>
-  <li>
-   MUST declare the hardware feature android.hardware.bluetooth_le.
-  </li>
-  <li>
-   MUST enable the GATT (generic attribute profile) based Bluetooth APIs as
-described in the SDK documentation and
-   <a href="http://developer.android.com/reference/android/bluetooth/package-summary.html">
-    android.bluetooth
-   </a>.
-  </li>
-  <li>
-   are STRONGLY RECOMMENDED to implement a Resolvable Private Address (RPA)
-timeout no longer than 15 minutes and rotate the address at timeout to protect
-user privacy.
-  </li>
-  <li>
-   SHOULD support offloading of the filtering logic to the bluetooth chipset
-when implementing the
-   <a href="https://developer.android.com/reference/android/bluetooth/le/ScanFilter.html">
-    ScanFilter API
-   </a>,
-and MUST report the correct value of where the filtering logic is implemented
-whenever queried via the
-android.bluetooth.BluetoothAdapter.isOffloadedFilteringSupported() method.
-  </li>
-  <li>
-   SHOULD support offloading of the batched scanning to the bluetooth chipset,
-but if not supported, MUST report &lsquo;false&rsquo; whenever queried via the
-android.bluetooth.BluetoothAdapter.isOffloadedScanBatchingSupported() method.
-  </li>
-  <li>
-   SHOULD support multi advertisement with at least 4 slots, but if not
-supported, MUST report &lsquo;false&rsquo; whenever queried via the
-android.bluetooth.BluetoothAdapter.isMultipleAdvertisementSupported() method.
-  </li>
- </ul>
- <h4 id="7_4_4_near-field_communications">
-  7.4.4. Near-Field Communications
- </h4>
- <p>
-  Device implementations SHOULD include a transceiver and related hardware for
-Near-Field Communications (NFC). If a device implementation does include NFC
-hardware and plans to make it available to third-party apps, then it:
- </p>
- <ul>
-  <li>
-   MUST report the android.hardware.nfc feature from the
-   <a href="http://developer.android.com/reference/android/content/pm/PackageManager.html">
-    android.content.pm.PackageManager.hasSystemFeature() method
-   </a>.
-  </li>
-  <li>
-   MUST be capable of reading and writing NDEF messages via the following NFC
-standards:
-   <ul>
-    <li>
-     MUST be capable of acting as an NFC Forum reader/writer (as defined by
-the NFC Forum technical specification NFCForum-TS-DigitalProtocol-1.0) via the
-following NFC standards:
-     <ul>
-      <li>
-       NfcA (ISO14443-3A)
-      </li>
-      <li>
-       NfcB (ISO14443-3B)
-      </li>
-      <li>
-       NfcF (JIS X 6319-4)
-      </li>
-      <li>
-       IsoDep (ISO 14443-4)
-      </li>
-      <li>
-       NFC Forum Tag Types 1, 2, 3, 4 (defined by the NFC Forum)
-      </li>
-     </ul>
-    </li>
-    <li>
-     STRONGLY RECOMMENDED to be capable of reading and writing NDEF messages
-as well as raw data via the following NFC standards. Note that while the NFC
-standards below are stated as STRONGLY RECOMMENDED, the Compatibility
-Definition for a future version is planned to change these to MUST. These
-standards are optional in this version but will be required in future versions.
-Existing and new devices that run this version of Android are very strongly
-encouraged to meet these requirements now so they will be able to upgrade to
-the future platform releases.
-     <ul>
-      <li>
-       NfcV (ISO 15693)
-      </li>
-     </ul>
-    </li>
-    <li>
-     SHOULD be capable of reading the barcode and URL (if encoded) of
-     <a href="http://developer.android.com/reference/android/nfc/tech/NfcBarcode.html">
-      Thinfilm NFC Barcode
-     </a>
-     products.
-    </li>
-    <li>
-     MUST be capable of transmitting and receiving data via the following
-peer-to-peer standards and protocols:
-     <ul>
-      <li>
-       ISO 18092
-      </li>
-      <li>
-       LLCP 1.2 (defined by the NFC Forum)
-      </li>
-      <li>
-       SDP 1.0 (defined by the NFC Forum)
-      </li>
-      <li>
-       <a href="http://static.googleusercontent.com/media/source.android.com/en/us/compatibility/ndef-push-protocol.pdf">
-        NDEF Push Protocol
-       </a>
-      </li>
-      <li>
-       SNEP 1.0 (defined by the NFC Forum)
-      </li>
-     </ul>
-    </li>
-    <li>
-     MUST include support for
-     <a href="http://developer.android.com/guide/topics/connectivity/nfc/nfc.html">
-      Android Beam
-     </a>.
-    </li>
-    <li>
-     MUST implement the SNEP default server. Valid NDEF messages
-received by the default SNEP server MUST be dispatched to applications using
-the android.nfc.ACTION_NDEF_DISCOVERED intent. Disabling Android Beam in
-settings MUST NOT disable dispatch of incoming NDEF message.
-    </li>
-    <li>
-     MUST honor the android.settings.NFCSHARING_SETTINGS intent to show
-     <a href="http://developer.android.com/reference/android/provider/Settings.html#ACTION_NFCSHARING_SETTINGS">
-      NFC sharing settings
-     </a>.
-    </li>
-    <li>
-     MUST implement the NPP server. Messages received by the NPP server
-MUST be processed the same way as the SNEP default server.
-    </li>
-    <li>
-     MUST implement a SNEP client and attempt to send outbound P2P NDEF
-to the default SNEP server when Android Beam is enabled. If no default SNEP
-server is found then the client MUST attempt to send to an NPP server.
-    </li>
-    <li>
-     MUST allow foreground activities to set the outbound P2P NDEF
-message using android.nfc.NfcAdapter.setNdefPushMessage, and
-android.nfc.NfcAdapter.setNdefPushMessageCallback, and
-android.nfc.NfcAdapter.enableForegroundNdefPush.
-    </li>
-    <li>
-     SHOULD use a gesture or on-screen confirmation, such as 'Touch to
-Beam', before sending outbound P2P NDEF messages.
-    </li>
-    <li>
-     SHOULD enable Android Beam by default and MUST be able to send and
-receive using Android Beam, even when another proprietary NFC P2p mode is
-turned on.
-    </li>
-    <li>
-     MUST support NFC Connection handover to Bluetooth when the device
-supports Bluetooth Object Push Profile. Device implementations MUST support
-connection handover to Bluetooth when using
-android.nfc.NfcAdapter.setBeamPushUris, by implementing the
-&ldquo;
-     <a href="http://members.nfc-forum.org/specs/spec_list/#conn_handover">
-      Connection Handover version 1.2
-     </a>
-     &rdquo; and
-&ldquo;
-     <a href="http://members.nfc-forum.org/apps/group_public/download.php/18688/NFCForum-AD-BTSSP_1_1.pdf">
-      Bluetooth Secure Simple Pairing Using NFC version 1.0
-     </a>
-     &rdquo;
-specs from the NFC Forum. Such an implementation MUST implement the handover
-LLCP service with service name &ldquo;urn:nfc:sn:handover&rdquo; for exchanging the
-handover request/select records over NFC, and it MUST use the Bluetooth Object
-Push Profile for the actual Bluetooth data transfer. For legacy reasons (to
-remain compatible with Android 4.1 devices), the implementation SHOULD still
-accept SNEP GET requests for exchanging the handover request/select records
-over NFC. However an implementation itself SHOULD NOT send SNEP GET requests
-for performing connection handover.
-    </li>
-    <li>
-     MUST poll for all supported technologies while in NFC discovery mode.
-    </li>
-    <li>
-     SHOULD be in NFC discovery mode while the device is awake with the
-screen active and the lock-screen unlocked.
-    </li>
-   </ul>
-  </li>
- </ul>
- <p>
-  (Note that publicly available links are not available for the JIS, ISO, and NFC
-Forum specifications cited above.)
- </p>
- <p>
-  Android includes support for NFC Host Card Emulation (HCE) mode. If a device
-implementation does include an NFC controller chipset capable of HCE (for NfcA 
-and/or NfcB) and it supports Application ID (AID) routing, then it:
- </p>
- <ul>
-  <li>
-   MUST report the android.hardware.nfc.hce feature constant.
-  </li>
-  <li>
-   MUST support
-   <a href="http://developer.android.com/guide/topics/connectivity/nfc/hce.html">
-    NFC HCE
-APIs
-   </a>
-   as
-defined in the Android SDK.
-  </li>
- </ul>
- <p>
-  If a device implementation does include an NFC controller chipset capable of HCE
-for NfcF, and it implements the feature for third-party applications, then it:
- </p>
- <ul>
-  <li>
-   MUST report the android.hardware.nfc.hcef feature constant.
-  </li>
-  <li>
-   MUST implement the [NfcF Card Emulation APIs]
-(https://developer.android.com/reference/android/nfc/cardemulation/NfcFCardEmulation.html)
-as defined in the Android SDK.
-  </li>
- </ul>
- <p>
-  Additionally, device implementations MAY include reader/writer support for the
-following MIFARE technologies.
- </p>
- <ul>
-  <li>
-   MIFARE Classic
-  </li>
-  <li>
-   MIFARE Ultralight
-  </li>
-  <li>
-   NDEF on MIFARE Classic
-  </li>
- </ul>
- <p>
-  Note that Android includes APIs for these MIFARE types. If a device
-implementation supports MIFARE in the reader/writer role, it:
- </p>
- <ul>
-  <li>
-   MUST implement the corresponding Android APIs as documented by the Android SDK.
-  </li>
-  <li>
-   MUST report the feature com.nxp.mifare from the
-   <a href="http://developer.android.com/reference/android/content/pm/PackageManager.html">
-    android.content.pm.PackageManager.hasSystemFeature()
-   </a>
-   method. Note that this is not a standard Android feature and as such does not
-appear as a constant in the android.content.pm.PackageManager class.
-  </li>
-  <li>
-   MUST NOT implement the corresponding Android APIs nor report the
-com.nxp.mifare feature unless it also implements general NFC support as
-described in this section.
-  </li>
- </ul>
- <p>
-  If a device implementation does not include NFC hardware, it MUST NOT declare
-the android.hardware.nfc feature from the
-  <a href="http://developer.android.com/reference/android/content/pm/PackageManager.html">
-   android.content.pm.PackageManager.hasSystemFeature()
-  </a>
-  method, and MUST implement the Android NFC API as a no-op.
- </p>
- <p>
-  As the classes android.nfc.NdefMessage and android.nfc.NdefRecord represent a
-protocol-independent data representation format, device implementations MUST
-implement these APIs even if they do not include support for NFC or declare the
-android.hardware.nfc feature.
- </p>
- <h4 id="7_4_5_minimum_network_capability">
-  7.4.5. Minimum Network Capability
- </h4>
- <p>
-  Device implementations MUST include support for one or more forms of data
-networking. Specifically, device implementations MUST include support for at
-least one data standard capable of 200Kbit/sec or greater. Examples of
-technologies that satisfy this requirement include EDGE, HSPA, EV-DO, 802.11g,
-Ethernet, Bluetooth PAN, etc.
- </p>
- <p>
-  Device implementations where a physical networking standard (such as Ethernet)
-is the primary data connection SHOULD also include support for at least one
-common wireless data standard, such as 802.11 (Wi-Fi).
- </p>
- <p>
-  Devices MAY implement more than one form of data connectivity.
- </p>
- <p>
-  Devices MUST include an IPv6 networking stack and support IPv6 communication
-using the managed APIs, such as
-  <code>
-   java.net.Socket
-  </code>
-  and
-  <code>
-   java.net.URLConnection
-  </code>
-  ,
-as well as the native APIs, such as
-  <code>
-   AF_INET6
-  </code>
-  sockets. The required level of
-IPv6 support depends on the network type, as follows:
- </p>
- <ul>
-  <li>
-   Devices that support Wi-Fi networks MUST support dual-stack and IPv6-only
-operation on Wi-Fi.
-  </li>
-  <li>
-   Devices that support Ethernet networks MUST support dual-stack operation on
-Ethernet.
-  </li>
-  <li>
-   Devices that support cellular data SHOULD support IPv6 operation (IPv6-only
-and possibly dual-stack) on cellular data.
-  </li>
-  <li>
-   When a device is simultaneously connected to more than one network (e.g.,
-Wi-Fi and cellular data), it MUST simultaneously meet these requirements on
-each network to which it is connected.
-  </li>
- </ul>
- <p>
-  IPv6 MUST be enabled by default.
- </p>
- <p>
-  In order to ensure that IPv6 communication is as reliable as IPv4, unicast IPv6
-packets sent to the device MUST NOT be dropped, even when the screen is not in
-an active state. Redundant multicast IPv6 packets, such as repeated identical
-Router Advertisements, MAY be rate-limited in hardware or firmware if doing so
-is necessary to save power. In such cases, rate-limiting MUST NOT cause the
-device to lose IPv6 connectivity on any IPv6-compliant network that uses RA
-lifetimes of at least 180 seconds.
- </p>
- <p>
-  IPv6 connectivity MUST be maintained in doze mode.
- </p>
- <h4 id="7_4_6_sync_settings">
-  7.4.6. Sync Settings
- </h4>
- <p>
-  Device implementations MUST have the master auto-sync setting on by default so
-that the method
-  <a href="http://developer.android.com/reference/android/content/ContentResolver.html">
-   getMasterSyncAutomatically()
-  </a>
-  returns &ldquo;true&rdquo;.
- </p>
- <h4 id="7_4_7_data_saver">
-  7.4.7. Data Saver
- </h4>
- <p>
-  Device implementations with a metered connection are STRONGLY RECOMMENDED to provide the
-data saver mode.
- </p>
- <p>
-  If a device implementation provides the data saver mode, it:
- </p>
- <ul>
-  <li>
-   <p>
-    MUST support all the APIs in the
-    <code>
-     ConnectivityManager
-    </code>
-    class as described in the
-    <a href="https://developer.android.com/training/basics/network-ops/data-saver.html">
-     SDK documentation
-    </a>
-   </p>
-  </li>
-  <li>
-   <p>
-    MUST provide a user interface in the settings, allowing users to add
-    applications to or remove applications from the whitelist.
-   </p>
-  </li>
- </ul>
- <p>
-  Conversely if a device implementation does not provide the data saver mode, it:
- </p>
- <ul>
-  <li>
-   <p>
-    MUST return the value
-    <code>
-     RESTRICT_BACKGROUND_STATUS_DISABLED
-    </code>
-    for
-    <a href="https://developer.android.com/reference/android/net/ConnectivityManager.html#getRestrictBackgroundStatus%28%29">
-     <code>
-      ConnectivityManager.getRestrictBackgroundStatus()
-     </code>
-    </a>
-   </p>
-  </li>
-  <li>
-   <p>
-    MUST not broadcast
-    <code>
-     ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED
-    </code>
-   </p>
-  </li>
-  <li>
-   <p>
-    MUST have an activity that handles the
-    <code>
-     Settings.ACTION_IGNORE_BACKGROUND_DATA_RESTRICTIONS_SETTINGS
-    </code>
-    intent but MAY implement it as a no-op.
-   </p>
-  </li>
- </ul>
- <h3 id="7_5_cameras">
-  7.5. Cameras
- </h3>
- <p>
-  Device implementations SHOULD include a rear-facing camera and MAY include a
-front-facing camera. A rear-facing camera is a camera located on the side of
-the device opposite the display; that is, it images scenes on the far side of
-the device, like a traditional camera. A front-facing camera is a camera
-located on the same side of the device as the display; that is, a camera
-typically used to image the user, such as for video conferencing and similar
-applications.
- </p>
- <p>
-  If a device implementation includes at least one camera, it MUST be possible for
-an application to simultaneously allocate 3 RGBA_8888 bitmaps equal to the size
-of the images produced by the largest-resolution camera sensor on the device,
-while camera is open for the purpose of basic preview and still capture.
- </p>
- <h4 id="7_5_1_rear-facing_camera">
-  7.5.1. Rear-Facing Camera
- </h4>
- <p>
-  Device implementations SHOULD include a rear-facing camera. If a device
-implementation includes at least one rear-facing camera, it:
- </p>
- <ul>
-  <li>
-   MUST report the feature flag android.hardware.camera and
-android.hardware.camera.any.
-  </li>
-  <li>
-   MUST have a resolution of at least 2 megapixels.
-  </li>
-  <li>
-   SHOULD have either hardware auto-focus or software auto-focus implemented
-in the camera driver (transparent to application software).
-  </li>
-  <li>
-   MAY have fixed-focus or EDOF (extended depth of field) hardware.
-  </li>
-  <li>
-   MAY include a flash. If the Camera includes a flash, the flash lamp MUST
-NOT be lit while an android.hardware.Camera.PreviewCallback instance has been
-registered on a Camera preview surface, unless the application has explicitly
-enabled the flash by enabling the FLASH_MODE_AUTO or FLASH_MODE_ON attributes
-of a Camera.Parameters object. Note that this constraint does not apply to the
-device&rsquo;s built-in system camera application, but only to third-party
-applications using Camera.PreviewCallback.
-  </li>
- </ul>
- <h4 id="7_5_2_front-facing_camera">
-  7.5.2. Front-Facing Camera
- </h4>
- <p>
-  Device implementations MAY include a front-facing camera. If a device
-implementation includes at least one front-facing camera, it:
- </p>
- <ul>
-  <li>
-   MUST report the feature flag android.hardware.camera.any and
-android.hardware.camera.front.
-  </li>
-  <li>
-   MUST have a resolution of at least VGA (640x480 pixels).
-  </li>
-  <li>
-   MUST NOT use a front-facing camera as the default for the Camera API. The
-camera API in Android has specific support for front-facing cameras and device
-implementations MUST NOT configure the API to to treat a front-facing camera as
-the default rear-facing camera, even if it is the only camera on the device.
-  </li>
-  <li>
-   MAY include features (such as auto-focus, flash, etc.) available to
-rear-facing cameras as described in
-   <a href="#7_5_1_rear-facing_camera">
-    section 7.5.1
-   </a>.
-  </li>
-  <li>
-   MUST horizontally reflect (i.e. mirror) the stream displayed by an app in a
-CameraPreview, as follows:
-   <ul>
-    <li>
-     If the device implementation is capable of being rotated by user (such
-as automatically via an accelerometer or manually via user input), the camera
-preview MUST be mirrored horizontally relative to the device&rsquo;s current
-orientation.
-    </li>
-    <li>
-     If the current application has explicitly requested that the Camera
-display be rotated via a call to the
-     <a href="http://developer.android.com/reference/android/hardware/Camera.html#setDisplayOrientation(int)">
-      android.hardware.Camera.setDisplayOrientation()
-     </a>
-     method, the camera preview MUST be mirrored horizontally relative to the
-orientation specified by the application.
-    </li>
-    <li>
-     Otherwise, the preview MUST be mirrored along the device&rsquo;s default
-horizontal axis.
-    </li>
-   </ul>
-  </li>
-  <li>
-   MUST mirror the image displayed by the postview in the same manner as the
-camera preview image stream. If the device implementation does not support
-postview, this requirement obviously does not apply.
-  </li>
-  <li>
-   MUST NOT mirror the final captured still image or video streams returned to
-application callbacks or committed to media storage.
-  </li>
- </ul>
- <h4 id="7_5_3_external_camera">
-  7.5.3. External Camera
- </h4>
- <p>
-  Device implementations MAY include support for an external camera that is not
-necessarily always connected. If a device includes support for an external camera,
-it:
- </p>
- <ul>
-  <li>
-   MUST declare the platform feature flag
-   <code>
-    android.hardware.camera.external
-   </code>
-   and
-   <code>
-    android.hardware camera.any
-   </code>
-   .
-  </li>
-  <li>
-   MAY support multiple cameras.
-  </li>
-  <li>
-   MUST support USB Video Class (UVC 1.0 or higher) if the external camera
-    connects through the USB port.
-  </li>
-  <li>
-   SHOULD support video compressions such as MJPEG to enable transfer of
-    high-quality unencoded streams (i.e. raw or independently compressed picture
-    streams).
-  </li>
-  <li>
-   MAY support camera-based video encoding. If supported, a simultaneous
-    unencoded / MJPEG stream (QVGA or greater resolution) MUST be accessible to
-    the device implementation.
-  </li>
- </ul>
- <h4 id="7_5_4_camera_api_behavior">
-  7.5.4. Camera API Behavior
- </h4>
- <p>
-  Android includes two API packages to access the camera, the newer
-android.hardware.camera2 API expose lower-level camera control to the app,
-including efficient zero-copy burst/streaming flows and per-frame controls of
-exposure, gain, white balance gains, color conversion, denoising, sharpening,
-and more.
- </p>
- <p>
-  The older API package, android.hardware.Camera, is marked as deprecated in
-Android 5.0 but as it should still be available for apps to use Android device
-implementations MUST ensure the continued support of the API as described in
-this section and in the Android SDK.
- </p>
- <p>
-  Device implementations MUST implement the following behaviors for the
-camera-related APIs, for all available cameras:
- </p>
- <ul>
-  <li>
-   If an application has never called
-android.hardware.Camera.Parameters.setPreviewFormat(int), then the device MUST
-use android.hardware.PixelFormat.YCbCr_420_SP for preview data provided to
-application callbacks.
-  </li>
-  <li>
-   If an application registers an android.hardware.Camera.PreviewCallback
-instance and the system calls the onPreviewFrame() method when the preview
-format is YCbCr_420_SP, the data in the byte[] passed into onPreviewFrame()
-must further be in the NV21 encoding format. That is, NV21 MUST be the default.
-  </li>
-  <li>
-   For android.hardware.Camera, device implementations MUST support the YV12
-format (as denoted by the android.graphics.ImageFormat.YV12 constant) for
-camera previews for both front- and rear-facing cameras. (The hardware video
-encoder and camera may use any native pixel format, but the device
-implementation MUST support conversion to YV12.)
-  </li>
-  <li>
-   For android.hardware.camera2, device implementations must support the
-android.hardware.ImageFormat.YUV_420_888 and android.hardware.ImageFormat.JPEG
-formats as outputs through the android.media.ImageReader API.
-  </li>
- </ul>
- <p>
-  Device implementations MUST still implement the full
-  <a href="http://developer.android.com/reference/android/hardware/Camera.html">
-   Camera
-API
-  </a>
-  included in the Android SDK documentation, regardless of whether the device
-includes hardware autofocus or other capabilities. For instance, cameras that
-lack autofocus MUST still call any registered
-android.hardware.Camera.AutoFocusCallback instances (even though this has no
-relevance to a non-autofocus camera.) Note that this does apply to front-facing
-cameras; for instance, even though most front-facing cameras do not support
-autofocus, the API callbacks must still be &ldquo;faked&rdquo; as described.
- </p>
- <p>
-  Device implementations MUST recognize and honor each parameter name defined as
-a constant on the
-  <a href="http://developer.android.com/reference/android/hardware/Camera.Parameters.html">
-   android.hardware.Camera.Parameters
-  </a>
-  class, if the underlying hardware supports the feature. If the device hardware
-does not support a feature, the API must behave as documented. Conversely,
-device implementations MUST NOT honor or recognize string constants passed to
-the android.hardware.Camera.setParameters() method other than those documented
-as constants on the android.hardware.Camera.Parameters. That is, device
-implementations MUST support all standard Camera parameters if the hardware
-allows, and MUST NOT support custom Camera parameter types. For instance,
-device implementations that support image capture using high dynamic range
-(HDR) imaging techniques MUST support camera parameter Camera.SCENE_MODE_HDR.
- </p>
- <p>
-  Because not all device implementations can fully support all the features of
-the android.hardware.camera2 API, device implementations MUST report the proper
-level of support with the
-  <a href="https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics.html#INFO_SUPPORTED_HARDWARE_LEVEL">
-   android.info.supportedHardwareLevel
-  </a>
-  property as described in the Android SDK and report the appropriate
-  <a href="http://source.android.com/devices/camera/versioning.html">
-   framework feature flags
-  </a>.
- </p>
- <p>
-  Device implementations MUST also declare its Individual camera capabilities of
-android.hardware.camera2 via the android.request.availableCapabilities property
-and declare the appropriate
-  <a href="http://source.android.com/devices/camera/versioning.html">
-   feature flags
-  </a>;
-a device must define the feature flag if any of its attached camera devices
-supports the feature.
- </p>
- <p>
-  Device implementations MUST broadcast the Camera.ACTION_NEW_PICTURE intent
-whenever a new picture is taken by the camera and the entry of the picture has
-been added to the media store.
- </p>
- <p>
-  Device implementations MUST broadcast the Camera.ACTION_NEW_VIDEO intent
-whenever a new video is recorded by the camera and the entry of the picture has
-been added to the media store.
- </p>
- <h4 id="7_5_5_camera_orientation">
-  7.5.5. Camera Orientation
- </h4>
- <p>
-  Both front- and rear-facing cameras, if present, MUST be oriented so that the
-long dimension of the camera aligns with the screen&rsquo;s long dimension. That is,
-when the device is held in the landscape orientation, cameras MUST capture
-images in the landscape orientation. This applies regardless of the device&rsquo;s
-natural orientation; that is, it applies to landscape-primary devices as well
-as portrait-primary devices.
- </p>
- <h3 id="7_6_memory_and_storage">
-  7.6. Memory and Storage
- </h3>
- <h4 id="7_6_1_minimum_memory_and_storage">
-  7.6.1. Minimum Memory and Storage
- </h4>
- <div class="note">
-  Android Television devices MUST have at least 4GB of non-volatile storage
-available for application private data.
- </div>
- <p>
-  The memory available to the kernel and userspace on device implementations MUST
-be at least equal or larger than the minimum values specified by the following
-table. (See
-  <a href="#7_1_1_screen_configuration">
-   section 7.1.1
-  </a>
-  for screen size and
-density definitions.)
- </p>
- <table>
-  <tr>
-   <th>
-    Density and screen size
-   </th>
-   <th>
-    32-bit device
-   </th>
-   <th>
-    64-bit device
-   </th>
-  </tr>
-  <tr>
-   <td>
-    Android Watch devices (due to smaller screens)
-   </td>
-   <td>
-    416MB
-   </td>
-   <td>
-    Not applicable
-   </td>
-  </tr>
-  <tr>
-   <td>
+    <p>
+      Each ID is defined as below:
+    </p>
     <ul>
-     <li class="table_list">
-      280dpi or lower on small/normal screens
-     </li>
-     <li class="table_list">
-      mdpi or lower on large screens
-     </li>
-     <li class="table_list">
-      ldpi or lower on extra large screens
-     </li>
+      <li>Device Type ID (see more on <a href="#2_device_types">2. Device Types</a>)
+        <ul>
+          <li>C: Core (Requirements that are applied to any Android device implementations)
+          </li>
+          <li>H: Android Handheld device
+          </li>
+          <li>T: Android Television device
+          </li>
+          <li>A: Android Automotive implementation
+          </li>
+          <li>W: Android Watch implementation
+          </li>
+        </ul>
+      </li>
+      <li>Condition ID
+        <ul>
+          <li>When the requirement is unconditional, this ID is set as 0.
+          </li>
+          <li>When the requirement is conditional, 1 is assinged for the 1st condition and the number increments by 1 within the same section and the same device type.
+          </li>
+        </ul>
+      </li>
+      <li>Requirement ID
+        <ul>
+          <li>This ID starts from 1 and increments by 1 within the same section and the same condition.
+          </li>
+        </ul>
+      </li>
     </ul>
-   </td>
-   <td>
-    512MB
-   </td>
-   <td>
-    816MB
-   </td>
-  </tr>
-  <tr>
-   <td>
+    <h2 id="2_device_types">
+      2. Device Types
+    </h2>
+    <p>
+      While the Android Open Source Project provides a software stack that can be used for a variety of device types and form factors, there are a few device types that have a relatively better established application distribution ecosystem.
+    </p>
+    <p>
+      This section describes those device types, and additional requirements and recommendations applicable for each device type.
+    </p>
+    <p>
+      All Android device implementations that do not fit into any of the described device types MUST still meet all requirements in the other sections of this Compatibility Definition.
+    </p>
+    <h3 id="2_1_device_configurations">
+      2.1 Device Configurations
+    </h3>
+    <p>
+      For the major differences in hardware configuration by device type, see the device-specific requirements that follow in this section.
+    </p>
+    <h3 id="2_2_handheld_requirements">
+      2.2. Handheld Requirements
+    </h3>
+    <p>
+      An <strong>Android Handheld device</strong> refers to an Android device implementation that is typically used by holding it in the hand, such as an mp3 player, phone, or tablet.
+    </p>
+    <p>
+      Android device implementations are classified as a Handheld if they meet all the following criteria:
+    </p>
     <ul>
-     <li class="table_list">
-      xhdpi or higher on small/normal screens
-     </li>
-     <li class="table_list">
-      hdpi or higher on large screens
-     </li>
-     <li class="table_list">
-      mdpi or higher on extra large screens
-     </li>
+      <li>Have a power source that provides mobility, such as a battery.
+      </li>
+      <li>Have a physical diagonal screen size in the range of 2.5 to 8 inches.
+      </li>
     </ul>
-   </td>
-   <td>
-    608MB
-   </td>
-   <td>
-    944MB
-   </td>
-  </tr>
-  <tr>
-   <td>
+    <p>
+      The additional requirements in the rest of this section are specific to Android Handheld device implementations.
+    </p>
+    <div class="note">
+      <b>Note:</b> Requirements that do not apply to Android Tablet devices are marked with an *.
+    </div>
+    <h4 id="2_2_1_hardware">
+      2.2.1. Hardware
+    </h4>
+    <p>
+      <strong>Screen Size (Section 7.1.1.1)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
     <ul>
-     <li class="table_list">
-      400dpi or higher on small/normal screens
-     </li>
-     <li class="table_list">
-      xhdpi or higher on large screens
-     </li>
-     <li class="table_list">
-      tvdpi or higher on extra large screens
-     </li>
+      <li>[H-0-1] MUST have a screen at least 2.5 inches in physical diagonal size.<sup>*</sup>
+      </li>
     </ul>
-   </td>
-   <td>
-    896MB
-   </td>
-   <td>
-    1280MB
-   </td>
-  </tr>
-  <tr>
-   <td>
+    <p>
+      <strong>Screen Density (Section 7.1.1.3)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
     <ul>
-     <li class="table_list">
-      560dpi or higher on small/normal screens
-     </li>
-     <li class="table_list">
-      400dpi or higher on large screens
-     </li>
-     <li class="table_list">
-      xhdpi or higher on extra large screens
-     </li>
+      <li>[H-SR] Are STRONGLY RECOMMENDED to provide users an affordance to change the display size.
+      </li>
     </ul>
-   </td>
-   <td>
-    1344MB
-   </td>
-   <td>
-    1824MB
-   </td>
-  </tr>
- </table>
- <p>
-  The minimum memory values MUST be in addition to any memory space already
-dedicated to hardware components such as radio, video, and so on that is not
-under the kernel&rsquo;s control.
- </p>
- <p>
-  Device implementations with less than 512MB of memory available to the kernel
-and userspace, unless an Android Watch, MUST return the value "true" for
-ActivityManager.isLowRamDevice().
- </p>
- <p>
-  Android Television devices MUST have at least 4GB and other device
-implementations MUST have at least 3GB of non-volatile storage available for
-application private data. That is, the /data partition MUST be at least 4GB for
-Android Television devices and at least 3GB for other device implementations.
-Device implementations that run Android are
-  <strong>
-   STRONGLY RECOMMENDED
-  </strong>
-  to have at
-least 4GB of non-volatile storage for application private data so they will be
-able to upgrade to the future platform releases.
- </p>
- <p>
-  The Android APIs include a
-  <a href="http://developer.android.com/reference/android/app/DownloadManager.html">
-   Download Manager
-  </a>
-  that applications MAY use to download data files. The device implementation of
-the Download Manager MUST be capable of downloading individual files of at
-least 100MB in size to the default &ldquo;cache&rdquo; location.
- </p>
- <h4 id="7_6_2_application_shared_storage">
-  7.6.2. Application Shared Storage
- </h4>
- <p>
-  Device implementations MUST offer shared storage for applications also often
-referred as &ldquo;shared external storage&rdquo;.
- </p>
- <p>
-  Device implementations MUST be configured with shared storage mounted by
-default, &ldquo;out of the box&rdquo;. If the shared storage is not mounted on the
-Linuxpath /sdcard, then the device MUST include a Linux symbolic link from
-/sdcard to the actual mount point.
- </p>
- <p>
-  Device implementations MAY have hardware for user-accessible removable storage,
-such as a Secure Digital (SD) card slot. If this slot is used to satisfy the
-shared storage requirement, the device implementation:
- </p>
- <ul>
-  <li>
-   MUST implement a toast or pop-up user interface warning the user when there
-is no SD card.
-  </li>
-  <li>
-   MUST include a FAT-formatted SD card 1GB in size or larger OR show on the
-box and other material available at time of purchase that the SD card has to be
-separately purchased.
-  </li>
-  <li>
-   MUST mount the SD card by default.
-  </li>
- </ul>
- <p>
-  Alternatively, device implementations MAY allocate internal (non-removable)
-storage as shared storage for apps as included in the upstream Android Open
-Source Project; device implementations SHOULD use this configuration and
-software implementation. If a device implementation uses internal
-(non-removable) storage to satisfy the shared storage requirement, while that
-storage MAY share space with the application private data, it MUST be at least
-1GB in size and mounted on /sdcard (or /sdcard MUST be a symbolic link to the
-physical location if it is mounted elsewhere).
- </p>
- <p>
-  Device implementations MUST enforce as documented the
-android.permission.WRITE_EXTERNAL_STORAGE permission on this shared storage.
-Shared storage MUST otherwise be writable by any application that obtains that
-permission.
- </p>
- <p>
-  Device implementations that include multiple shared storage paths (such as both
-an SD card slot and shared internal storage) MUST allow only pre-installed &amp;
-privileged Android applications with the WRITE_EXTERNAL_STORAGE permission to
-write to the secondary external storage, except when writing to their
-package-specific directories or within the
-  <code>
-   URI
-  </code>
-  returned by firing the
-  <code>
-   ACTION_OPEN_DOCUMENT_TREE
-  </code>
-  intent.
- </p>
- <p>
-  However, device implementations SHOULD expose content from both storage paths
-transparently through Android&rsquo;s media scanner service and
-android.provider.MediaStore.
- </p>
- <p>
-  Regardless of the form of shared storage used, if the device implementation has
-a USB port with USB peripheral mode support, it MUST provide some mechanism to
-access the contents of shared storage from a host computer. Device
-implementations MAY use USB mass storage, but SHOULD use Media Transfer
-Protocol to satisfy this requirement. If the device implementation supports
-Media Transfer Protocol, it:
- </p>
- <ul>
-  <li>
-   SHOULD be compatible with the reference Android MTP host,
-   <a href="http://www.android.com/filetransfer">
-    Android File Transfer
-   </a>.
-  </li>
-  <li>
-   SHOULD report a USB device class of 0x00.
-  </li>
-  <li>
-   SHOULD report a USB interface name of 'MTP'.
-  </li>
- </ul>
- <h4 id="7_6_3_adoptable_storage">
-  7.6.3. Adoptable Storage
- </h4>
- <p>
-  Device implementations are STRONGLY RECOMMENDED to implement
-  <a href="http://source.android.com/devices/storage/adoptable.html">
-   adoptable storage
-  </a>
-  if the
-removable storage device port is in a long-term stable location, such as within
-the battery compartment or other protective cover.
- </p>
- <p>
-  Device implementations such as a television, MAY enable adoption through USB
-ports as the device is expected to be static and not mobile. But for other
-device implementations that are mobile in nature, it is STRONGLY RECOMMENDED to
-implement the adoptable storage in a long-term stable location, since
-accidentally disconnecting them can cause data loss/corruption.
- </p>
- <h3 id="7_7_usb">
-  7.7. USB
- </h3>
- <p>
-  Device implementations SHOULD support USB peripheral mode and SHOULD support USB
-host mode.
- </p>
- <h4 id="7_7_1_usb_peripheral_mode">
-  7.7.1. USB peripheral mode
- </h4>
- <p>
-  If a device implementation includes a USB port supporting peripheral mode:
- </p>
- <ul>
-  <li>
-   The port MUST be connectable to a USB host that has a standard type-A or
-    type-C USB port.
-  </li>
-  <li>
-   The port SHOULD use micro-B, micro-AB or Type-C USB form factor. Existing
-    and new Android devices are
-   <strong>
-    STRONGLY RECOMMENDED to meet these
-    requirements
-   </strong>
-   so they will be able to upgrade to the future platform
-    releases.
-  </li>
-  <li>
-   The port SHOULD be located on the bottom of the device
-    (according to natural orientation) or enable software screen rotation for
-    all apps (including home screen), so that the display draws correctly when
-    the device is oriented with the port at bottom. Existing and new Android
-    devices are
-   <strong>
-    STRONGLY RECOMMENDED to meet these requirements
-   </strong>
-   so they will
-    be able to upgrade to future platform releases.
-  </li>
-  <li>
-   It MUST allow a USB host connected with the Android device to access the
-    contents of the shared storage volume using either USB mass storage or Media
-    Transfer Protocol.
-  </li>
-  <li>
-   It SHOULD implement the Android Open Accessory (AOA) API and specification
-    as documented in the Android SDK documentation, and if it is an Android
-    Handheld device it MUST implement the AOA API. Device implementations
-    implementing the AOA specification:
-   <ul>
-    <li>
-     MUST declare support for the hardware feature
-     <a href="http://developer.android.com/guide/topics/connectivity/usb/accessory.html">
-      android.hardware.usb.accessory
-     </a>.
-    </li>
-    <li>
-     MUST implement the
-     <a href="http://developer.android.com/reference/android/hardware/usb/UsbConstants.html#USB_CLASS_AUDIO">
-      USB audio class
-     </a>
-     as documented in the Android SDK documentation.
-    </li>
-    <li>
-     The USB mass storage class MUST include the string "android" at the end
-    of the interface description
-     <code>
-      iInterface
-     </code>
-     string of the USB mass storage
-    </li>
-   </ul>
-  </li>
-  <li>
-   It SHOULD implement support to draw 1.5 A current during HS chirp and
-    traffic as specified in the
-   <a href="http://www.usb.org/developers/docs/devclass_docs/BCv1.2_070312.zip">
-    USB Battery Charging specification, revision 1.2
-   </a>.
-    Existing and new Android devices are
-   <strong>
-    STRONGLY RECOMMENDED to meet these
-    requirements
-   </strong>
-   so they will be able to upgrade to the future platform
-    releases.
-  </li>
-  <li>
-   Type-C devices MUST detect 1.5A and 3.0A chargers per the Type-C resistor
-    standard and it must detect changes in the advertisement.
-  </li>
-  <li>
-   Type-C devices also supporting USB host mode are STRONGLY RECOMMENDED to
-    support Power Delivery for data and power role swapping.
-  </li>
-  <li>
-   Type-C devices SHOULD support Power Delivery for high-voltage charging and
-    support for Alternate Modes such as display out.
-  </li>
-  <li>
-   The value of iSerialNumber in USB standard device descriptor MUST be equal
-    to the value of android.os.Build.SERIAL.
-  </li>
-  <li>
-   Type-C devices are STRONGLY RECOMMENDED to not support proprietary charging
-    methods that modify Vbus voltage beyond default levels, or alter sink/source
-    roles as such may result in interoperability issues with the chargers or
-    devices that support the standard USB Power Delivery methods. While this is
-    called out as "STRONGLY RECOMMENDED", in future Android versions we might
-    REQUIRE all type-C devices to support full interoperability with standard
-    type-C chargers.
-  </li>
- </ul>
- <h4 id="7_7_2_usb_host_mode">
-  7.7.2. USB host mode
- </h4>
- <p>
-  If a device implementation includes a USB port supporting host mode, it:
- </p>
- <ul>
-  <li>
-   SHOULD use a type-C USB port, if the device implementation supports USB 3.1.
-  </li>
-  <li>
-   MAY use a non-standard port form factor, but if so MUST ship with a cable or
-    cables adapting the port to a standard type-A or type-C USB port.
-  </li>
-  <li>
-   MAY use a micro-AB USB port, but if so SHOULD ship with a cable or cables adapting the port to a standard type-A or type-C USB port.
-  </li>
-  <li>
-   is
-   <strong>
-    STRONGLY RECOMMENDED
-   </strong>
-   to implement the
-   <a href="http://developer.android.com/reference/android/hardware/usb/UsbConstants.html#USB_CLASS_AUDIO">
-    USB audio class
-   </a>
-   as documented in the Android SDK documentation.
-  </li>
-  <li>
-   MUST implement the Android USB host API as documented in the Android SDK,
-    and MUST declare support for the hardware feature
-   <a href="http://developer.android.com/guide/topics/connectivity/usb/host.html">
-    android.hardware.usb.host
-   </a>.
-  </li>
-  <li>
-   SHOULD support device charging while in host mode; advertising a source
-    current of at least 1.5A as specified in the Termination Parameters section
-    of the [USB Type-C Cable and Connector Specification Revision 1.2] (http://www.usb.org/developers/docs/usb_31_021517.zip)
-    for USB Type-C connectors or using Charging Downstream Port(CDP) output
-    current range as specified in the
-   <a href="http://www.usb.org/developers/docs/devclass_docs/BCv1.2_070312.zip">
-    USB Battery Charging specifications, revision 1.2
-   </a>
-   for Micro-AB connectors.
-  </li>
-  <li>
-   USB Type-C devices are STRONGLY RECOMMENDED to support DisplayPort, SHOULD
-    support USB SuperSpeed Data Rates, and are STRONGLY RECOMMENDED to support
-    Power Delivery for data and power role swapping.
-  </li>
-  <li>
-   Devices with any type-A or type-AB ports MUST NOT ship with an adapter converting
-    from this port to a type-C receptacle.
-  </li>
-  <li>
-   MUST recognize any remotely connected MTP (Media Transfer Protocol) devices
-    and make their contents accessible through the
-   <code>
-    ACTION_GET_CONTENT
-   </code>
-   ,
-   <code>
-    ACTION_OPEN_DOCUMENT
-   </code>
-   , and
-   <code>
-    ACTION_CREATE_DOCUMENT
-   </code>
-   intents, if the Storage Access
-    Framework (SAF) is supported.
-  </li>
-  <li>
-   MUST, if using a Type-C USB port and including support for peripheral mode,
-    implement Dual Role Port functionality as defined by the USB Type-C
-    specification (section 4.5.1.3.3).
-  </li>
-  <li>
-   SHOULD, if the Dual Role Port functionality is supported, implement the
-    Try.* model that is most appropriate for the device form factor. For
-    example a handheld device SHOULD implement the Try.SNK model.
-  </li>
- </ul>
- <h3 id="7_8_audio">
-  7.8. Audio
- </h3>
- <h4 id="7_8_1_microphone">
-  7.8.1. Microphone
- </h4>
- <div class="note">
-  Android Handheld, Watch, and Automotive implementations MUST include a
-microphone.
- </div>
- <p>
-  Device implementations MAY omit a microphone. However, if a device
-implementation omits a microphone, it MUST NOT report the
-android.hardware.microphone feature constant, and MUST implement the audio
-recording API at least as no-ops, per
-  <a href="#7_hardware_compatibility">
-   section 7
-  </a>.
-Conversely, device implementations that do possess a microphone:
- </p>
- <ul>
-  <li>
-   MUST report the android.hardware.microphone feature constant.
-  </li>
-  <li>
-   MUST meet the audio recording requirements in
-   <a href="#5_4_audio_recording">
-    section 5.4
-   </a>.
-  </li>
-  <li>
-   MUST meet the audio latency requirements in
-   <a href="#5_6_audio_latency">
-    section 5.6
-   </a>.
-  </li>
-  <li>
-   STRONGLY RECOMMENDED to support near-ultrasound recording as described in
-   <a href="#7_8_3_near_ultrasound">
-    section 7.8.3
-   </a>.
-  </li>
- </ul>
- <h4 id="7_8_2_audio_output">
-  7.8.2. Audio Output
- </h4>
- <div class="note">
-  Android Watch devices MAY include an audio output.
- </div>
- <p>
-  Device implementations including a speaker or with an audio/multimedia output
-port for an audio output peripheral as a headset or an external speaker:
- </p>
- <ul>
-  <li>
-   MUST report the android.hardware.audio.output feature constant.
-  </li>
-  <li>
-   MUST meet the audio playback requirements in
-   <a href="#5_5_audio_playback">
-    section 5.5
-   </a>.
-  </li>
-  <li>
-   MUST meet the audio latency requirements in
-   <a href="#5_6_audio_latency">
-    section 5.6
-   </a>.
-  </li>
-  <li>
-   STRONGLY RECOMMENDED to support near-ultrasound playback as described in
-   <a href="#7_8_3_near_ultrasound">
-    section 7.8.3
-   </a>.
-  </li>
- </ul>
- <p>
-  Conversely, if a device implementation does not include a speaker or audio
-output port, it MUST NOT report the android.hardware.audio output feature, and
-MUST implement the Audio Output related APIs as no-ops at least.
- </p>
- <p>
-  Android Watch device implementation MAY but SHOULD NOT have audio output, but
-other types of Android device implementations MUST have an audio output and
-declare android.hardware.audio.output.
- </p>
- <h5 id="7_8_2_1_analog_audio_ports">
-  7.8.2.1. Analog Audio Ports
- </h5>
- <p>
-  In order to be compatible with the
-  <a href="http://source.android.com/accessories/headset-spec.html">
-   headsets and other audio accessories
-  </a>
-  using the 3.5mm audio plug across the Android ecosystem, if a device
-implementation includes one or more analog audio ports, at least one of the
-audio port(s) SHOULD be a 4 conductor 3.5mm audio jack. If a device
-implementation has a 4 conductor 3.5mm audio jack, it:
- </p>
- <ul>
-  <li>
-   MUST support audio playback to stereo headphones and stereo headsets with a
-microphone, and SHOULD support audio recording from stereo headsets with a
-microphone.
-  </li>
-  <li>
-   MUST support TRRS audio plugs with the CTIA pin-out order, and SHOULD
-support audio plugs with the OMTP pin-out order.
-  </li>
-  <li>
-   MUST support the detection of microphone on the plugged in audio accessory,
-if the device implementation supports a microphone, and broadcast the
-android.intent.action.HEADSET_PLUG with the extra value microphone set as 1.
-  </li>
-  <li>
-   MUST support the detection and mapping to the keycodes for the following
-3 ranges of equivalent impedance between the microphone and ground conductors
-on the audio plug:
-   <ul>
-    <li>
-     <strong>
-      70 ohm or less
-     </strong>
-     : KEYCODE_HEADSETHOOK
-    </li>
-    <li>
-     <strong>
-      210-290 Ohm
-     </strong>
-     : KEYCODE_VOLUME_UP
-    </li>
-    <li>
-     <strong>
-      360-680 Ohm
-     </strong>
-     : KEYCODE_VOLUME_DOWN
-    </li>
-   </ul>
-  </li>
-  <li>
-   STRONGLY RECOMMENDED to detect and map to the keycode for the following
-range of equivalent impedance between the microphone and ground conductors
-on the audio plug:
-   <ul>
-    <li>
-     <strong>
-      110-180 Ohm:
-     </strong>
-     KEYCODE_VOICE_ASSIST
-    </li>
-   </ul>
-  </li>
-  <li>
-   MUST trigger ACTION_HEADSET_PLUG upon a plug insert, but only after all
-contacts on plug are touching their relevant segments on the jack.
-  </li>
-  <li>
-   MUST be capable of driving at least 150mV &plusmn; 10% of output voltage on a 32
-Ohm speaker impedance.
-  </li>
-  <li>
-   MUST have a microphone bias voltage between 1.8V ~ 2.9V.
-  </li>
- </ul>
- <h4 id="7_8_3_near-ultrasound">
-  7.8.3. Near-Ultrasound
- </h4>
- <p>
-  Near-Ultrasound audio is the 18.5 kHz to 20 kHz band. Device implementations
-MUST correctly report the support of near-ultrasound audio capability via the
-  <a href="http://developer.android.com/reference/android/media/AudioManager.html#getProperty%28java.lang.String%29">
-   AudioManager.getProperty
-  </a>
-  API as follows:
- </p>
- <ul>
-  <li>
-   If
-   <a href="http://developer.android.com/reference/android/media/AudioManager.html#PROPERTY_SUPPORT_MIC_NEAR_ULTRASOUND">
-    PROPERTY_SUPPORT_MIC_NEAR_ULTRASOUND
-   </a>
-   is "true", then the following requirements must be met by the
-VOICE_RECOGNITION and UNPROCESSED audio sources:
-   <ul>
-    <li>
-     The microphone's mean power response in the 18.5 kHz to 20 kHz band
-MUST be no more than 15 dB below the response at 2 kHz.
-    </li>
-    <li>
-     The microphone's unweighted signal to noise ratio over 18.5 kHz to 20 kHz
-for a 19 kHz tone at -26 dBFS MUST be no lower than 50 dB.
-    </li>
-   </ul>
-  </li>
-  <li>
-   If
-   <a href="http://developer.android.com/reference/android/media/AudioManager.html#PROPERTY_SUPPORT_SPEAKER_NEAR_ULTRASOUND">
-    PROPERTY_SUPPORT_SPEAKER_NEAR_ULTRASOUND
-   </a>
-   is "true", then the speaker's mean response in 18.5 kHz - 20 kHz MUST be no
-lower than 40 dB below the response at 2 kHz.
-  </li>
- </ul>
- <h3 id="7_9_virtual_reality">
-  7.9. Virtual Reality
- </h3>
- <p>
-  Android includes APIs and facilities to build "Virtual Reality" (VR) applications including high
-quality mobile VR experiences. Device implementations MUST properly implement these APIs and
-behaviors, as detailed in this section.
- </p>
- <h4 id="7_9_1_virtual_reality_mode">
-  7.9.1. Virtual Reality Mode
- </h4>
- <p>
-  Android handheld device implementations that support a mode for VR applications that handles
-stereoscopic rendering of notifications and disable monocular system UI components while a VR
-application has user focus MUST declare
-  <code>
-   android.software.vr.mode
-  </code>
-  feature. Devices declaring this
-feature MUST include an application implementing
-  <code>
-   android.service.vr.VrListenerService
-  </code>
-  that can be
-enabled by VR applications via
-  <code>
-   android.app.Activity#setVrModeEnabled
-  </code>
-  .
- </p>
- <h4 id="7_9_2_virtual_reality_high_performance">
-  7.9.2. Virtual Reality High Performance
- </h4>
- <p>
-  Android handheld device implementations MUST identify the support of high performance virtual
-reality for longer user periods through the
-  <code>
-   android.hardware.vr.high_performance
-  </code>
-  feature flag and
-meet the following requirements.
- </p>
- <ul>
-  <li>
-   Device implementations MUST have at least 2 physical cores.
-  </li>
-  <li>
-   Device implementations MUST declare android.software.vr.mode feature.
-  </li>
-  <li>
-   Device implementations MAY provide an exclusive core to the foreground
-    application and MAY support the Process.getExclusiveCores API to return
-    the numbers of the cpu cores that are exclusive to the top foreground
-    application. If exclusive core is supported then the core MUST not allow
-    any other userspace processes to run on it (except device drivers used
-    by the application), but MAY allow some kernel processes to run as
-    necessary.
-  </li>
-  <li>
-   Device implementations MUST support sustained performance mode.
-  </li>
-  <li>
-   Device implementations MUST support OpenGL ES 3.2.
-  </li>
-  <li>
-   Device implementations MUST support Vulkan Hardware Level 0 and SHOULD support
-    Vulkan Hardware Level 1.
-  </li>
-  <li>
-   Device implementations MUST implement EGL_KHR_mutable_render_buffer and
-    EGL_ANDROID_front_buffer_auto_refresh, EGL_ANDROID_create_native_client_buffer,
-    EGL_KHR_fence_sync and EGL_KHR_wait_sync so that they may be used for Shared Buffer Mode, and
-    expose the extensions in the list of available EGL extensions.
-  </li>
-  <li>
-   The GPU and display MUST be able to synchronize access to the shared front buffer such that
-    alternating-eye rendering of VR content at 60fps with two render contexts will be displayed with
-    no visible tearing artifacts.
-  </li>
-  <li>
-   Device implementations MUST implement EGL_IMG_context_priority, and expose the extension in the
-    list of available EGL extensions.
-  </li>
-  <li>
-   Device implementations MUST implement GL_EXT_multisampled_render_to_texture, GL_OVR_multiview,
-    GL_OVR_multiview2 and GL_OVR_multiview_multisampled_render_to_texture, and expose the extensions
-    in the list of available GL extensions.
-  </li>
-  <li>
-   Device implementations MUST implement EGL_EXT_protected_content and GL_EXT_protected_textures so
-    that it may be used for Secure Texture Video Playback, and expose the extensions in the list of
-    available EGL and GL extensions.
-  </li>
-  <li>
-   Device implementations MUST support H.264 decoding at least 3840x2160@30fps-40Mbps (equivalent
-    to 4 instances of 1920x1080@30fps-10Mbps or 2 instances of 1920x1080@60fps-20Mbps).
-  </li>
-  <li>
-   Device implementations MUST support HEVC and VP9, MUST be capable to decode at least
-    1920x1080@30fps-10Mbps and SHOULD be capable to decode 3840x2160@30fps-20Mbps (equivalent to
-    4 instances of 1920x1080@30fps-5Mbps).
-  </li>
-  <li>
-   The device implementations are STRONGLY RECOMMENDED to support
-    android.hardware.sensor.hifi_sensors feature and MUST meet the gyroscope, accelerometer, and
-    magnetometer related requirements for android.hardware.hifi_sensors.
-  </li>
-  <li>
-   Device implementations MUST support HardwarePropertiesManager.getDeviceTemperatures API and
-    return accurate values for skin temperature.
-  </li>
-  <li>
-   The device implementation MUST have an embedded screen, and its resolution MUST be at least be
-    FullHD(1080p) and STRONGLY RECOMMENDED TO BE  be QuadHD (1440p) or higher.
-  </li>
-  <li>
-   The display MUST measure between 4.7" and 6" diagonal.
-  </li>
-  <li>
-   The display MUST update at least 60 Hz while in VR Mode.
-  </li>
-  <li>
-   The display latency on Gray-to-Gray, White-to-Black, and Black-to-White switching time MUST
-    be &le; 3 ms.
-  </li>
-  <li>
-   The display MUST support a low-persistence mode with &le;5 ms persistence,persistence being
-    defined as the amount of time for which a pixel is emitting light.
-  </li>
-  <li>
-   Device implementations MUST support Bluetooth 4.2 and Bluetooth LE Data Length Extension
-   <a href="#7_4_3_bluetooth">
-    section 7.4.3
-   </a>.
-  </li>
- </ul>
- <h2 id="8_performance_and_power">
-  8. Performance and Power
- </h2>
- <p>
-  Some minimum performance and power criteria are critical to the user experience
-and impact the baseline assumptions developers would have when developing an
-app. Android Watch devices SHOULD and other type of device implementations MUST
-meet the following criteria.
- </p>
- <h3 id="8_1_user_experience_consistency">
-  8.1. User Experience Consistency
- </h3>
- <p>
-  Device implementations MUST provide a smooth user interface by ensuring a
-consistent frame rate and response times for applications and games. Device
-implementations MUST meet the following requirements:
- </p>
- <ul>
-  <li>
-   <strong>
-    Consistent frame latency
-   </strong>
-   . Inconsistent frame latency or a delay to
-render frames MUST NOT happen more often than 5 frames in a second, and SHOULD
-be below 1 frames in a second.
-  </li>
-  <li>
-   <strong>
-    User interface latency
-   </strong>
-   . Device implementations MUST ensure low latency
-user experience by scrolling a list of 10K list entries as defined by the
-Android Compatibility Test Suite (CTS) in less than 36 secs.
-  </li>
-  <li>
-   <strong>
-    Task switching
-   </strong>
-   . When multiple applications have been launched,
-re-launching an already-running application after it has been launched MUST
-take less than 1 second.
-  </li>
- </ul>
- <h3 id="8_2_file_i/o_access_performance">
-  8.2. File I/O Access Performance
- </h3>
- <p>
-  Device implementations MUST ensure internal storage file access performance
-consistency for read and write operations.
- </p>
- <ul>
-  <li>
-   <strong>
-    Sequential write
-   </strong>
-   . Device implementations MUST ensure a sequential write
-performance of at least 5MB/s for a 256MB file using 10MB write buffer.
-  </li>
-  <li>
-   <strong>
-    Random write
-   </strong>
-   . Device implementations MUST ensure a random write
-performance of at least 0.5MB/s for a 256MB file using 4KB write buffer.
-  </li>
-  <li>
-   <strong>
-    Sequential read
-   </strong>
-   . Device implementations MUST ensure a sequential read
-performance of at least 15MB/s for a 256MB file using 10MB write buffer.
-  </li>
-  <li>
-   <strong>
-    Random read
-   </strong>
-   . Device implementations MUST ensure a random read
-performance of at least 3.5MB/s for a 256MB file using 4KB write buffer.
-  </li>
- </ul>
- <h3 id="8_3_power-saving_modes">
-  8.3. Power-Saving Modes
- </h3>
- <p>
-  Android 6.0 introduced App Standby and Doze power-saving modes to optimize
-battery usage.  All Apps exempted from these modes MUST be made visible to the
-end user. Further, the triggering, maintenance, wakeup algorithms and the use of
-global system settings of these power-saving modes MUST not deviate from the
-Android Open Source Project.
- </p>
- <p>
-  In addition to the power-saving modes, Android device implementations MAY
-implement any or all of the 4 sleeping power states as defined by the Advanced
-Configuration and Power Interface (ACPI), but if it implements S3 and S4
-power states, it can only enter these states when closing a lid that is
-physically part of the device.
- </p>
- <h3 id="8_4_power_consumption_accounting">
-  8.4. Power Consumption Accounting
- </h3>
- <p>
-  A more accurate accounting and reporting of the power consumption provides the
-app developer both the incentives and the tools to optimize the power usage
-pattern of the application. Therefore, device implementations:
- </p>
- <ul>
-  <li>
-   MUST be able to track hardware component power usage and attribute that
-power usage to specific applications. Specifically, implementations:
-   <ul>
-    <li>
-     MUST provide a per-component power profile that defines the
-     <a href="http://source.android.com/devices/tech/power/values.html">
-      current consumption value
-     </a>
-     for each hardware component and the approximate battery drain caused by the
-components over time as documented in the Android Open Source Project site.
-    </li>
-    <li>
-     MUST report all power consumption values in milliampere hours (mAh).
-    </li>
-    <li>
-     SHOULD be attributed to the hardware component itself if unable to
-attribute hardware component power usage to an application.
-    </li>
-    <li>
-     MUST report CPU power consumption per each process's UID. The Android
-Open Source Project meets the requirement through the
-     <code>
-      uid_cputime
-     </code>
-     kernel
-module implementation.
-    </li>
-   </ul>
-  </li>
-  <li>
-   MUST make this power usage available via the
-   <a href="http://source.android.com/devices/tech/power/batterystats.html">
-    <code>
-     adb shell dumpsys batterystats
-    </code>
-   </a>
-   shell command to the app developer.
-  </li>
-  <li>
-   MUST honor the
-   <a href="http://developer.android.com/reference/android/content/Intent.html#ACTION_POWER_USAGE_SUMMARY">
-    android.intent.action.POWER_USAGE_SUMMARY
-   </a>
-   intent and display a settings menu that shows this power usage.
-  </li>
- </ul>
- <h3 id="8_5_consistent_performance">
-  8.5. Consistent Performance
- </h3>
- <p>
-  Performance can fluctuate dramatically for high-performance long-running apps,
-either because of the other apps running in the background or the CPU throttling
-due to temperature limits. Android includes programmatic interfaces so that when
-the device is capable, the top foreground application can request that the system
-optimize the allocation of the resources to address such fluctuations.
- </p>
- <p>
-  Device implementations SHOULD support Sustained Performance Mode which can
-provide the top foreground application a consistent level of performance for a
-prolonged amount of time when requested through the
-  <a href="https://developer.android.com/reference/android/view/Window.html#setSustainedPerformanceMode%28boolean%29">
-   <code>
-    Window.setSustainedPerformanceMode()
-   </code>
-  </a>
-  API method. A Device implementation MUST report the support of Sustained
-Performance Mode accurately through the
-  <a href="https://developer.android.com/reference/android/os/PowerManager.html#isSustainedPerformanceModeSupported%28%29">
-   <code>
-    PowerManager.isSustainedPerformanceModeSupported()
-   </code>
-  </a>
-  API method.
- </p>
- <p>
-  Device implementations with two or more CPU cores SHOULD provide at least one exclusive core that
-can be reserved by the top foreground application. If provided, implementations MUST meet the
-following requirements:
- </p>
- <ul>
-  <li>
-   Implementations MUST report through the
-   <a href="https://developer.android.com/reference/android/os/Process.html#getExclusiveCores%28%29">
-    <code>
-     Process.getExclusiveCores()
-    </code>
-   </a>
-   API method the id numbers of the exclusive cores that can be reserved by the top foreground
-     application.
-  </li>
-  <li>
-   Device implementations MUST not allow any user space processes except the device drivers used
-     by the application to run on the exclusive cores, but MAY allow some kernel processes to run
-     as necessary.
-  </li>
- </ul>
- <p>
-  If a device implementation does not support an exclusive core, it MUST return an
-empty list through the
-  <a href="https://developer.android.com/reference/android/os/Process.html#getExclusiveCores%28%29">
-   <code>
-    Process.getExclusiveCores()
-   </code>
-  </a>
-  API method.
- </p>
- <h2 id="9_security_model_compatibility">
-  9. Security Model Compatibility
- </h2>
- <p>
-  Device implementations MUST implement a security model consistent with the
-Android platform security model as defined in
-  <a href="http://developer.android.com/guide/topics/security/permissions.html">
-   Security and Permissions reference document
-  </a>
-  in the APIs in the Android developer documentation. Device implementations MUST
-support installation of self-signed applications without requiring any
-additional permissions/certificates from any third parties/authorities.
-Specifically, compatible devices MUST support the security mechanisms described
-in the follow subsections.
- </p>
- <h3 id="9_1_permissions">
-  9.1. Permissions
- </h3>
- <p>
-  Device implementations MUST support the
-  <a href="http://developer.android.com/guide/topics/security/permissions.html">
-   Android permissions model
-  </a>
-  as
-defined in the Android developer documentation. Specifically, implementations
-MUST enforce each permission defined as described in the SDK documentation; no
-permissions may be omitted, altered, or ignored. Implementations MAY add
-additional permissions, provided the new permission ID strings are not in the
-android.* namespace.
- </p>
- <p>
-  Permissions with a
-  <code>
-   protectionLevel
-  </code>
-  of
-  <a href="https://developer.android.com/reference/android/content/pm/PermissionInfo.html#PROTECTION_FLAG_PRIVILEGED">
-   'PROTECTION_FLAG_PRIVILEGED'
-  </a>
-  MUST only be granted to apps preloaded in the whitelisted privileged path(s)
-of the system image, such as the
-  <code>
-   system/priv-app
-  </code>
-  path in the AOSP
-implementation.
- </p>
- <p>
-  Permissions with a protection level of dangerous are runtime permissions.
-Applications with targetSdkVersion &gt; 22 request them at runtime. Device
-implementations:
- </p>
- <ul>
-  <li>
-   MUST show a dedicated interface for the user to decide whether to grant the
-requested runtime permissions and also provide an interface for the user to
-manage runtime permissions.
-  </li>
-  <li>
-   MUST have one and only one implementation of both user interfaces.
-  </li>
-  <li>
-   MUST NOT grant any runtime permissions to preinstalled apps unless:
-   <ul>
-    <li>
-     the user's consent can be obtained before the application uses it
-    </li>
-    <li>
-     the runtime permissions are associated with an intent pattern for which
-the preinstalled application is set as the default handler
-    </li>
-   </ul>
-  </li>
- </ul>
- <h3 id="9_2_uid_and_process_isolation">
-  9.2. UID and Process Isolation
- </h3>
- <p>
-  Device implementations MUST support the Android application sandbox model, in
-which each application runs as a unique Unixstyle UID and in a separate
-process. Device implementations MUST support running multiple applications as
-the same Linux user ID, provided that the applications are properly signed and
-constructed, as defined in the
-  <a href="http://developer.android.com/guide/topics/security/permissions.html">
-   Security and Permissions reference
-  </a>.
- </p>
- <h3 id="9_3_filesystem_permissions">
-  9.3. Filesystem Permissions
- </h3>
- <p>
-  Device implementations MUST support the Android file access permissions model
-as defined in the
-  <a href="http://developer.android.com/guide/topics/security/permissions.html">
-   Security and Permissions reference
-  </a>.
- </p>
- <h3 id="9_4_alternate_execution_environments">
-  9.4. Alternate Execution Environments
- </h3>
- <p>
-  Device implementations MAY include runtime environments that execute
-applications using some other software or technology than the Dalvik Executable
-Format or native code. However, such alternate execution environments MUST NOT
-compromise the Android security model or the security of installed Android
-applications, as described in this section.
- </p>
- <p>
-  Alternate runtimes MUST themselves be Android applications, and abide by the
-standard Android security model, as described elsewhere in
-  <a href="#9_security_model_compatibility">
-   section 9
-  </a>.
- </p>
- <p>
-  Alternate runtimes MUST NOT be granted access to resources protected by
-permissions not requested in the runtime&rsquo;s AndroidManifest.xml file via the
-&lt;uses-permission&gt; mechanism.
- </p>
- <p>
-  Alternate runtimes MUST NOT permit applications to make use of features
-protected by Android permissions restricted to system applications.
- </p>
- <p>
-  Alternate runtimes MUST abide by the Android sandbox model. Specifically,
-alternate runtimes:
- </p>
- <ul>
-  <li>
-   SHOULD install apps via the PackageManager into separate Android sandboxes
-(Linux user IDs, etc.).
-  </li>
-  <li>
-   MAY provide a single Android sandbox shared by all applications using the
-alternate runtime.
-  </li>
-  <li>
-   Installed applications using an alternate runtime MUST NOT reuse the
-sandbox of any other app installed on the device, except through the standard
-Android mechanisms of shared user ID and signing certificate.
-  </li>
-  <li>
-   MUST NOT launch with, grant, or be granted access to the sandboxes
-corresponding to other Android applications.
-  </li>
-  <li>
-   MUST NOT be launched with, be granted, or grant to other applications any
-privileges of the superuser (root), or of any other user ID.
-  </li>
- </ul>
- <p>
-  The .apk files of alternate runtimes MAY be included in the system image of a
-device implementation, but MUST be signed with a key distinct from the key used
-to sign other applications included with the device implementation.
- </p>
- <p>
-  When installing applications, alternate runtimes MUST obtain user consent for
-the Android permissions used by the application. If an application needs to
-make use of a device resource for which there is a corresponding Android
-permission (such as Camera, GPS, etc.), the alternate runtime MUST inform the
-user that the application will be able to access that resource. If the runtime
-environment does not record application capabilities in this manner, the
-runtime environment MUST list all permissions held by the runtime itself when
-installing any application using that runtime.
- </p>
- <h3 id="9_5_multi-user_support">
-  9.5. Multi-User Support
- </h3>
- <div class="note">
-  This feature is optional for all device types.
- </div>
- <p>
-  Android includes
-  <a href="http://developer.android.com/reference/android/os/UserManager.html">
-   support for multiple users
-  </a>
-  and
-provides support for full user isolation. Device implementations MAY enable
-multiple users, but when enabled MUST meet the following requirements related
-to
-  <a href="http://source.android.com/devices/storage/traditional.html">
-   multi-user support
-  </a>:
- </p>
- <ul>
-  <li>
-   Android Automotive device implementations with multi-user support enabled
-MUST include a guest account that allows all functions provided by the vehicle
-system without requiring a user to log in.
-  </li>
-  <li>
-   Device implementations that do not declare the android.hardware.telephony
-feature flag MUST support restricted profiles, a feature that allows device
-owners to manage additional users and their capabilities on the device. With
-restricted profiles, device owners can quickly set up separate environments for
-additional users to work in, with the ability to manage finer-grained
-restrictions in the apps that are available in those environments.
-  </li>
-  <li>
-   Conversely device implementations that declare the
-android.hardware.telephony feature flag MUST NOT support restricted profiles
-but MUST align with the AOSP implementation of controls to enable /disable
-other users from accessing the voice calls and SMS.
-  </li>
-  <li>
-   Device implementations MUST, for each user, implement a security model
-consistent with the Android platform security model as defined in
-   <a href="http://developer.android.com/guide/topics/security/permissions.html">
-    Security and Permissions reference document
-   </a>
-   in the APIs.
-  </li>
-  <li>
-   Each user instance on an Android device MUST have separate and isolated
-external storage directories. Device implementations MAY store multiple users'
-data on the same volume or filesystem. However, the device implementation MUST
-ensure that applications owned by and running on behalf a given user cannot
-list, read, or write to data owned by any other user. Note that removable
-media, such as SD card slots, can allow one user to access another&rsquo;s data by
-means of a host PC. For this reason, device implementations that use removable
-media for the external storage APIs MUST encrypt the contents of the SD card if
-multiuser is enabled using a key stored only on non-removable media accessible
-only to the system. As this will make the media unreadable by a host PC, device
-implementations will be required to switch to MTP or a similar system to
-provide host PCs with access to the current user&rsquo;s data. Accordingly, device
-implementations MAY but SHOULD NOT enable multi-user if they use
-   <a href="http://developer.android.com/reference/android/os/Environment.html">
-    removable media
-   </a>
-   for
-primary external storage.
-  </li>
- </ul>
- <h3 id="9_6_premium_sms_warning">
-  9.6. Premium SMS Warning
- </h3>
- <p>
-  Android includes support for warning users of any outgoing
-  <a href="http://en.wikipedia.org/wiki/Short_code">
-   premium SMS message
-  </a>. Premium SMS
-messages are text messages sent to a service registered with a carrier that may
-incur a charge to the user. Device implementations that declare support for
-android.hardware.telephony MUST warn users before sending a SMS message to
-numbers identified by regular expressions defined in /data/misc/sms/codes.xml
-file in the device. The upstream Android Open Source Project provides an
-implementation that satisfies this requirement.
- </p>
- <h3 id="9_7_kernel_security_features">
-  9.7. Kernel Security Features
- </h3>
- <p>
-  The Android Sandbox includes features that use the Security-Enhanced Linux
-(SELinux) mandatory access control (MAC) system, seccomp sandboxing, and other
-security features in the Linux kernel. SELinux or any other security features
-implemented below the Android framework:
- </p>
- <ul>
-  <li>
-   MUST maintain compatibility with existing applications.
-  </li>
-  <li>
-   MUST NOT have a visible user interface when a security violation is
-detected and successfully blocked, but MAY have a visible user interface when
-an unblocked security violation occurs resulting in a successful exploit.
-  </li>
-  <li>
-   SHOULD NOT be user or developer configurable.
-  </li>
- </ul>
- <p>
-  If any API for configuration of policy is exposed to an application that can
-affect another application (such as a Device Administration API), the API MUST
-NOT allow configurations that break compatibility.
- </p>
- <p>
-  Devices MUST implement SELinux or, if using a kernel other than Linux, an
-equivalent mandatory access control system. Devices MUST also meet the
-following requirements, which are satisfied by the reference implementation in
-the upstream Android Open Source Project.
- </p>
- <p>
-  Device implementations:
- </p>
- <ul>
-  <li>
-   MUST set SELinux to global enforcing mode.
-  </li>
-  <li>
-   MUST configure all domains in enforcing mode. No permissive mode domains
-are allowed, including domains specific to a device/vendor.
-  </li>
-  <li>
-   MUST NOT modify, omit, or replace the neverallow rules present within the
-system/sepolicy folder provided in the upstream Android Open Source Project
-(AOSP) and the policy MUST compile with all neverallow rules present, for both
-AOSP SELinux domains as well as device/vendor specific domains.
-  </li>
-  <li>
-   MUST split the media framework into multiple processes so that it
-is possible to more narrowly grant access for each process as
-   <a href="https://source.android.com/devices/media/framework-hardening.html#arch_changes">
-    described
-   </a>
-   in the Android Open Source Project site.
-  </li>
- </ul>
- <p>
-  Device implementations SHOULD retain the default SELinux policy provided in the
-system/sepolicy folder of the upstream Android Open Source Project and only
-further add to this policy for their own device-specific configuration. Device
-implementations MUST be compatible with the upstream Android Open Source
-Project.
- </p>
- <p>
-  Devices MUST implement a kernel application sandboxing mechanism which allows
-filtering of system calls using a configurable policy from multithreaded
-programs. The upstream Android Open Source Project meets this requirement
-through enabling the seccomp-BPF with threadgroup synchronization (TSYNC) as
-described
-  <a href="http://source.android.com/devices/tech/config/kernel.html#Seccomp-BPF-TSYNC">
-   in the Kernel Configuration section of source.android.com
-  </a>.
- </p>
- <h3 id="9_8_privacy">
-  9.8. Privacy
- </h3>
- <p>
-  If the device implements functionality in the system that captures the contents
-displayed on the screen and/or records the audio stream played on the device,
-it MUST continuously notify the user whenever this functionality is enabled and
-actively capturing/recording.
- </p>
- <p>
-  If a device implementation has a mechanism that routes network data traffic
-through a proxy server or VPN gateway by default (for example, preloading a VPN
-service with android.permission.CONTROL_VPN granted), the device implementation
-MUST ask for the user's consent before enabling that mechanism, unless that
-VPN is enabled by the Device Policy Controller via the
-  <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#setAlwaysOnVpnPackage(android.content.ComponentName, java.lang.String, boolean)">
-   <code>
-    DevicePolicyManager.setAlwaysOnVpnPackage()
-   </code>
-  </a>, in which case the user does not need to provide a separate consent, but MUST
-only be notified.
- </p>
- <p>
-  Device implementations MUST ship with an empty user-added Certificate Authority
-(CA) store, and MUST preinstall the same root certificates for the system-trusted
-CA store as
-  <a href="https://source.android.com/security/overview/app-security.html#certificate-authorities">
-   provided
-  </a>
-  in the upstream Android Open Source Project.
- </p>
- <p>
-  When devices are routed through a VPN, or a user root CA is installed, the
-implementation MUST display a warning indicating the network traffic may be
-monitored to the user.
- </p>
- <p>
-  If a device implementation has a USB port with USB peripheral mode support, it
-MUST present a user interface asking for the user's consent before allowing
-access to the contents of the shared storage over the USB port.
- </p>
- <h3 id="9_9_data_storage_encryption">
-  9.9. Data Storage Encryption
- </h3>
- <div class="note">
-  Optional for Android device implementations without a secure lock screen.
- </div>
- <p>
-  If the device implementation supports a secure lock screen as described in section 9.11.1,
-then the device MUST support data storage encryption of the application private data (/data partition), as well as the
-application shared storage partition (/sdcard partition) if it is a permanent,
-non-removable part of the device.
- </p>
- <p>
-  For device implementations supporting data storage encryption and with Advanced
-Encryption Standard (AES) crypto performance above 50MiB/sec, the data storage
-encryption MUST be enabled by default at the time the user has completed the
-out-of-box setup experience. If a device implementation is already launched on
-an earlier Android version with encryption disabled by default, such
-a device cannot meet the requirement through a system software update and thus
-MAY be exempted.
- </p>
- <p>
-  Device implementations SHOULD meet the above data storage encryption requirement
-via implementing
-  <a href="https://source.android.com/security/encryption/file-based.html">
-   File Based Encryption
-  </a>
-  (FBE).
- </p>
- <h4 id="9_9_1_direct_boot">
-  9.9.1. Direct Boot
- </h4>
- <p>
-  All devices MUST implement the
-  <a href="http://developer.android.com/preview/features/direct-boot.html">
-   Direct Boot mode
-  </a>
-  APIs even
-if they do not support Storage Encryption. In particular, the
-  <a href="https://developer.android.com/reference/android/content/Intent.html#LOCKED_BOOT_COMPLETED">
-   LOCKED_BOOT_COMPLETED
-  </a>
-  and
-  <a href="https://developer.android.com/reference/android/content/Intent.html#ACTION_USER_UNLOCKED">
-   ACTION_USER_UNLOCKED
-  </a>
-  Intents must still be broadcast to signal Direct Boot aware applications that
-Device Encrypted (DE) and Credential Encrypted (CE) storage locations are
-available for user.
- </p>
- <h4 id="9_9_2_file_based_encryption">
-  9.9.2. File Based Encryption
- </h4>
- <p>
-  Device implementations supporting FBE:
- </p>
- <ul>
-  <li>
-   MUST boot up without challenging the user for credentials and allow Direct
-  Boot aware apps to access to the Device Encrypted (DE) storage after the
-  LOCKED_BOOT_COMPLETED message is broadcasted.
-  </li>
-  <li>
-   MUST only allow access to Credential Encrypted (CE) storage after the user 
-  has unlocked the device by supplying their credentials (eg. passcode, pin,
-  pattern or fingerprint) and the ACTION_USER_UNLOCKED message is broadcasted.
-  Device implementations MUST NOT offer any
-  method to unlock the CE protected storage without the user supplied
-  credentials.
-  </li>
-  <li>
-   MUST support Verified Boot and ensure that DE keys are cryptographically
-  bound to the device's hardware root of trust.
-  </li>
-  <li>
-   MUST support encrypting file contents using AES with a key length of 256-bits
-  in XTS mode.
-  </li>
-  <li>
-   MUST support encrypting file name using AES with a key length of 256-bits in
-  CBC-CTS mode.
-  </li>
-  <li>
-   MAY support alternative ciphers, key lengths and modes for file content and
-  file name encryption, but MUST use the mandatorily supported ciphers,
-  key lengths and modes by default.
-  </li>
-  <li>
-   SHOULD make preloaded essential apps (e.g. Alarm, Phone, Messenger)
-  Direct Boot aware.
-  </li>
- </ul>
- <p>
-  The keys protecting CE and DE storage areas:
- </p>
- <ul>
-  <li>
-   MUST be cryptographically bound to a hardware-backed Keystore. CE keys
-  must be bound to a user's lock screen credentials. If the user has
-  specified no lock screen credentials then the CE keys MUST be bound to
-  a default passcode.
-  </li>
-  <li>
-   MUST be unique and distinct, in other words no user's CE or DE key
-  may match any other user's CE or DE keys.
-  </li>
- </ul>
- <p>
-  The upstream Android Open Source project provides a preferred implementation of
-this feature based on the Linux kernel ext4 encryption feature.
- </p>
- <h4 id="9_9_3_full_disk_encryption">
-  9.9.3. Full Disk Encryption
- </h4>
- <p>
-  Device implementations supporting
-  <a href="http://source.android.com/devices/tech/security/encryption/index.html">
-   full disk encryption
-  </a>
-  (FDE). MUST use AES with a key of 128-bits
-  (or greater) and a mode designed for storage (for example, AES-XTS,
-  AES-CBC-ESSIV). The encryption key MUST NOT be written to storage at any time
-  without being encrypted. The user MUST be provided with the possibility to AES
-  encrypt the encryption key, except when it is in active use, with the lock
-  screen credentials stretched using a slow stretching algorithm
-  (e.g. PBKDF2 or scrypt). If the user has not specified a lock screen
-  credentials or has disabled use of the passcode for encryption, the system
-  SHOULD use a default passcode to wrap the encryption key. If the device
-  provides a hardware-backed keystore, the password stretching algorithm MUST
-  be cryptographically bound to that keystore. The encryption key MUST NOT be
-  sent off the device (even when wrapped with the user passcode and/or hardware
-  bound key). The upstream Android Open Source project provides a preferred
-  implementation of this feature based on the Linux kernel feature dm-crypt.
- </p>
- <h3 id="9_10_device_integrity">
-  9.10. Device Integrity
- </h3>
- <p>
-  The following requirements ensures there is transparancy to the status of the
-device integrity.
- </p>
- <p>
-  Device implementations MUST correctly report through the System API method
-PersistentDataBlockManager.getFlashLockState() whether their bootloader state
-permits flashing of the system image. The
-  <code>
-   FLASH_LOCK_UNKNOWN
-  </code>
-  state is reserved
-for device implementations upgrading from an earlier version of Android where this
-new system API method did not exist.
- </p>
- <p>
-  Verified boot is a feature that guarantees the integrity of the device
-software. If a device implementation supports the feature, it MUST:
- </p>
- <ul>
-  <li>
-   Declare the platform feature flag android.software.verified_boot.
-  </li>
-  <li>
-   Perform verification on every boot sequence.
-  </li>
-  <li>
-   Start verification from an immutable hardware key that is the root of trust
-and go all the way up to the system partition.
-  </li>
-  <li>
-   Implement each stage of verification to check the integrity and
-authenticity of all the bytes in the next stage before executing the code in
-the next stage.
-  </li>
-  <li>
-   Use verification algorithms as strong as current recommendations from NIST
-for hashing algorithms (SHA-256) and public key sizes (RSA-2048).
-  </li>
-  <li>
-   MUST NOT allow boot to complete when system verification fails, unless the
-user consents to attempt booting anyway, in which case the data from any
-non-verified storage blocks MUST not be used.
-  </li>
-  <li>
-   MUST NOT allow verified partitions on the device to be modified unless the
-user has explicitly unlocked the boot loader.
-  </li>
- </ul>
- <p>
-  The upstream Android Open Source Project provides a preferred implementation of
-this feature based on the Linux kernel feature dm-verity.
- </p>
- <p>
-  Starting from Android 6.0, device implementations with Advanced Encryption
-Standard (AES) crypto performance above 50 MiB/seconds MUST support verified boot
-for device integrity.
- </p>
- <p>
-  If a device implementation is already launched without supporting verified boot
-on an earlier version of Android, such a device can not add support for this feature
-with a system software update and thus are exempted from the requirement.
- </p>
- <h3 id="9_11_keys_and_credentials">
-  9.11. Keys and Credentials
- </h3>
- <p>
-  The
-  <a href="https://developer.android.com/training/articles/keystore.html">
-   Android Keystore System
-  </a>
-  allows
-app developers to store cryptographic keys in a container and use them in
-cryptographic operations through the
-  <a href="https://developer.android.com/reference/android/security/KeyChain.html">
-   KeyChain API
-  </a>
-  or
-the
-  <a href="https://developer.android.com/reference/java/security/KeyStore.html">
-   Keystore API
-  </a>.
- </p>
- <p>
-  All Android device implementations MUST meet the following requirements:
- </p>
- <ul>
-  <li>
-   SHOULD not limit the number of keys that can be generated, and MUST at
-    least allow more than 8,192 keys to be imported.
-  </li>
-  <li>
-   The lock screen authentication MUST rate limit attempts and MUST have an
-    exponential backoff algorithm. Beyond 150 failed attempts, the delay MUST be
-    at least 24 hours per attempt.
-  </li>
-  <li>
-   When the device implementation supports a secure lock screen it MUST back up the
-    keystore implementation with secure hardware and meet following requirements:
-   <ul>
-    <li>
-     MUST have implementations of RSA, AES, ECDSA and HMAC cryptographic
-    algorithms and MD5, SHA1, and SHA-2 family hash functions to properly
-    support the Android Keystore system's supported algorithms in an area
-    that is securely isolated from the code running on the kernel and
-    above. Secure isolation MUST block all potential mechanisms by which
-    kernel or userspace code might access the internal state of the
-    isolated environment, including DMA. The upstream Android Open Source
-    Project (AOSP) meets this requirement by using the
-     <a href="https://source.android.com/security/trusty/">
-      Trusty
-     </a>
-     implementation, but another ARM TrustZone-based solution or a
-    third-party reviewed secure implementation of a proper
-    hypervisor-based isolation are alternative options.
-    </li>
-    <li>
-     MUST perform the lock screen authentication in the isolated execution
-    environment and only when successful, allow the authentication-bound
-    keys to be used. The upstream Android Open Source Project provides
-    the
-     <a href="http://source.android.com/devices/tech/security/authentication/gatekeeper.html">
-      Gatekeeper Hardware Abstraction Layer (HAL)
-     </a>
-     and Trusty, which can be used to satisfy this requirement.
-    </li>
-   </ul>
-  </li>
- </ul>
- <p>
-  Note that if a device implementation is already launched on an earlier Android
-version, such a device is exempted from the requirement to have a
-hardware-backed keystore, unless it declares the
-  <code>
-   android.hardware.fingerprint
-  </code>
-  feature which requires a hardware-backed keystore.
- </p>
- <h4 id="9_11_1_secure_lock_screen">
-  9.11.1. Secure Lock Screen
- </h4>
- <p>
-  Device implementations MAY add or modify the authentication methods to unlock
-the lock screen, but MUST still meet the following requirements:
- </p>
- <ul>
-  <li>
-   The authentication method, if based on a known secret, MUST NOT be treated
-    as a secure lock screen unless it meets all following requirements:
-   <ul>
-    <li>
-     The entropy of the shortest allowed length of inputs MUST be greater
-     than 10 bits.
-    </li>
-    <li>
-     The maximum entropy of all possible inputs MUST be greater than 18 bits.
-    </li>
-    <li>
-     MUST not replace any of the existing authentication methods (PIN,
-     pattern, password) implemented and provided in AOSP.
-    </li>
-    <li>
-     MUST be disabled when the Device Policy Controller (DPC) application
-     has set the password quality policy via the
-     <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#setPasswordQuality%28android.content.ComponentName,%20int%29">
-      <code>
-       DevicePolicyManager.setPasswordQuality()
-      </code>
-     </a>
-     method with a more restrictive quality constant than
-     <code>
-      PASSWORD_QUALITY_SOMETHING
-     </code>
-     .
-    </li>
-   </ul>
-  </li>
-  <li>
-   The authenticaion method, if based on a physical token or the location,
-    MUST NOT be treated as a secure lock screen unless it meets all following
-    requirements:
-   <ul>
-    <li>
-     It MUST have a fall-back mechanism to use one of the primary
-     authentication methods which is based on a known secret and meets
-     the requirements to be treated as a secure lock screen.
-    </li>
-    <li>
-     It MUST be disabled and only allow the primary authentication to
-     unlock the screen when the Device Policy Controller (DPC) application
-     has set the policy with either the
-     <a href="http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#setKeyguardDisabledFeatures%28android.content.ComponentName,%20int%29">
-      <code>
-       DevicePolicyManager.setKeyguardDisabledFeatures(KEYGUARD_DISABLE_TRUST_AGENTS)
-      </code>
-     </a>
-     method or the
-     <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#setPasswordQuality%28android.content.ComponentName,%20int%29">
-      <code>
-       DevicePolicyManager.setPasswordQuality()
-      </code>
-     </a>
-     method with a more restrictive quality constant than
-     <code>
-      PASSWORD_QUALITY_UNSPECIFIED
-     </code>
-     .
-    </li>
-   </ul>
-  </li>
-  <li>
-   The authentication method, if based on biometrics, MUST NOT be treated as a
-     secure lock screen unless it meets all following requirements:
-   <ul>
-    <li>
-     It MUST have a fall-back mechanism to use one of the primary
-      authentication methods which is based on a known secret and meets
-      the requirements to be treated as a secure lock screen.
-    </li>
-    <li>
-     It MUST be disabled and only allow the primary authentication to
-      unlock the screen when the Device Policy Controller (DPC) application
-      has set the keguard feature policy by calling the method
-     <a href="http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#setKeyguardDisabledFeatures%28android.content.ComponentName,%20int%29">
-      <code>
-       DevicePolicyManager.setKeyguardDisabledFeatures(KEYGUARD_DISABLE_FINGERPRINT)
-      </code>
-     </a>.
-    </li>
-    <li>
-     It MUST have a false acceptance rate that is equal or stronger than
-      what is required for a fingerprint sensor as described in
-      section 7.3.10, or otherwise MUST be disabled and only allow the
-      primary authentication to unlock the screen when the Device Policy
-      Controller (DPC) application has set the password quality policy
-      via the
-     <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#setPasswordQuality%28android.content.ComponentName,%20int%29">
-      <code>
-       DevicePolicyManager.setPasswordQuality()
-      </code>
-     </a>
-     method with a more restrictive quality constant than
-     <code>
-      PASSWORD_QUALITY_BIOMETRIC_WEAK
-     </code>
-     .
-    </li>
-   </ul>
-  </li>
-  <li>
-   If the authentication method can not be treated as a secure lock screen,
-     it:
-   <ul>
-    <li>
-     MUST return
-     <code>
-      false
-     </code>
-     for both the
-     <a href="http://developer.android.com/reference/android/app/KeyguardManager.html#isKeyguardSecure%28%29">
-      <code>
-       KeyguardManager.isKeyguardSecure()
-      </code>
-     </a>
-     and the
-     <a href="https://developer.android.com/reference/android/app/KeyguardManager.html#isDeviceSecure%28%29">
-      <code>
-       KeyguardManager.isDeviceSecure()
-      </code>
-     </a>
-     methods.
-    </li>
-    <li>
-     MUST be disabled when the Device Policy Controller (DPC) application
-      has set the password quality policy via the
-     <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#setPasswordQuality%28android.content.ComponentName,%20int%29">
-      <code>
-       DevicePolicyManager.setPasswordQuality()
-      </code>
-     </a>
-     method with a more restrictive quality constant than
-     <code>
-      PASSWORD_QUALITY_UNSPECIFIED
-     </code>
-     .
-    </li>
-    <li>
-     MUST NOT reset the password expiration timers set by
-     <a href="http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#setPasswordExpirationTimeout%28android.content.ComponentName,%20long%29">
-      <code>
-       DevicePolicyManager.setPasswordExpirationTimeout()
-      </code>
-     </a>.
-    </li>
-    <li>
-     MUST NOT authenticate access to keystores if the application has called
-     <a href="https://developer.android.com/reference/android/security/keystore/KeyGenParameterSpec.Builder.html#setUserAuthenticationRequired%28boolean%29">
-      <code>
-       KeyGenParameterSpec.Builder.setUserAuthenticationRequired(true)
-      </code>
-     </a>
-     ).
-    </li>
-   </ul>
-  </li>
-  <li>
-   If the authentication method is based on a physical token, the location,
-     or biometrics that has higher false acceptance rate than what is required
-     for fingerprint sensors as described in section 7.3.10, then it:
-   <ul>
-    <li>
-     MUST NOT reset the password expiration timers set by
-     <a href="http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#setPasswordExpirationTimeout%28android.content.ComponentName,%20long%29">
-      <code>
-       DevicePolicyManager.setPasswordExpirationTimeout()
-      </code>
-     </a>.
-    </li>
-    <li>
-     MUST NOT authenticate access to keystores if the application has called
-     <a href="https://developer.android.com/reference/android/security/keystore/KeyGenParameterSpec.Builder.html#setUserAuthenticationRequired%28boolean%29">
-      <code>
-       KeyGenParameterSpec.Builder.setUserAuthenticationRequired(true)
-      </code>
-     </a>.
-    </li>
-   </ul>
-  </li>
- </ul>
- <h3 id="9_12_data_deletion">
-  9.12. Data Deletion
- </h3>
- <p>
-  Devices MUST provide users with a mechanism to perform a "Factory Data Reset"
-that allows logical and physical deletion of all data except for the following:
- </p>
- <ul>
-  <li>
-   The system image
-  </li>
-  <li>
-   Any operating system files required by the system image
-  </li>
- </ul>
- <p>
-  All user-generated data MUST be deleted. This MUST satisfy relevant industry
-standards for data deletion such as NIST SP800-88. This MUST be used for the
-implementation of the wipeData() API (part of the Android Device Administration
-API) described in
-  <a href="#3_9_device_administration">
-   section 3.9 Device Administration
-  </a>.
- </p>
- <p>
-  Devices MAY provide a fast data wipe that conducts a logical data erase.
- </p>
- <h3 id="9_13_safe_boot_mode">
-  9.13. Safe Boot Mode
- </h3>
- <p>
-  Android provides a mode enabling users to boot up into a mode where only
-preinstalled system apps are allowed to run and all third-party apps are
-disabled. This mode, known as "Safe Boot Mode", provides the user the
-capability to uninstall potentially harmful third-party apps.
- </p>
- <p>
-  Android device implementations are STRONGLY RECOMENDED to implement Safe Boot
-Mode and meet following requirements:
- </p>
- <ul>
-  <li>
-   <p>
-    Device implementations SHOULD provide the user an option to enter Safe Boot
-   Mode from the boot menu which is reachable through a workflow that is different
-   from that of normal boot.
-   </p>
-  </li>
-  <li>
-   <p>
-    Device implementations MUST provide the user an option to enter Safe Boot Mode
-   in such a way that is uninterruptible from third-party apps installed on
-   the device, except for when the third party app is a Device Policy Controller
-   and has set the
-    <a href="https://developer.android.com/reference/android/os/UserManager.html#DISALLOW_SAFE_BOOT">
-     <code>
-      UserManager.DISALLOW_SAFE_BOOT
-     </code>
-    </a>
-    flag as true.
-   </p>
-  </li>
-  <li>
-   <p>
-    Device implementations MUST provide the user the capability to uninstall
-   any third-party apps within Safe Mode.
-   </p>
-  </li>
- </ul>
- <h3 id="9_14_automotive_vehicle_system_isolation">
-  9.14. Automotive Vehicle System Isolation
- </h3>
- <p>
-  Android Automotive devices are expected to exchange data with critical vehicle
-subsystems, e.g., by using the
-  <a href="http://source.android.com/devices/automotive.html">
-   vehicle HAL
-  </a>
-  to send and receive messages over vehicle networks such as CAN bus. Android
-Automotive device implementations MUST implement security features below the
-Android framework layers to prevent malicious or unintentional interaction
-between the Android framework or third-party apps and vehicle subsystems. These
-security features are as follows:
- </p>
- <ul>
-  <li>
-   Gatekeeping messages from Android framework vehicle subsystems, e.g.,
-  whitelisting permitted message types and message sources.
-  </li>
-  <li>
-   Watchdog against denial of service attacks from the Android framework or
-  third-party apps. This guards against malicious software flooding the vehicle
-  network with traffic, which may lead to malfunctioning vehicle subsystems.
-  </li>
- </ul>
- <h2 id="10_software_compatibility_testing">
-  10. Software Compatibility Testing
- </h2>
- <p>
-  Device implementations MUST pass all tests described in this section.
- </p>
- <p>
-  However, note that no software test package is fully comprehensive. For this
-reason, device implementers are
-  <strong>
-   STRONGLY RECOMMENDED
-  </strong>
-  to make the minimum
-number of changes as possible to the reference and preferred implementation of
-Android available from the Android Open Source Project. This will minimize the
-risk of introducing bugs that create incompatibilities requiring rework and
-potential device updates.
- </p>
- <h3 id="10_1_compatibility_test_suite">
-  10.1. Compatibility Test Suite
- </h3>
- <p>
-  Device implementations MUST pass the
-  <a href="http://source.android.com/compatibility/index.html">
-   Android Compatibility Test Suite (CTS)
-  </a>
-  available from the Android Open Source Project, using the final shipping
-software on the device.  Additionally, device implementers SHOULD use the
-reference implementation in the Android Open Source tree as much as possible,
-and MUST ensure compatibility in cases of ambiguity in CTS and for any
-reimplementations of parts of the reference source code.
- </p>
- <p>
-  The CTS is designed to be run on an actual device. Like any software, the CTS
-may itself contain bugs. The CTS will be versioned independently of this
-Compatibility Definition, and multiple revisions of the CTS may be released for
-Android 7.1. Device implementations MUST pass the latest CTS
-version available at the time the device software is completed.
- </p>
- <h3 id="10_2_cts_verifier">
-  10.2. CTS Verifier
- </h3>
- <p>
-  Device implementations MUST correctly execute all applicable cases in the CTS
-Verifier. The CTS Verifier is included with the Compatibility Test Suite, and
-is intended to be run by a human operator to test functionality that cannot be
-tested by an automated system, such as correct functioning of a camera and
-sensors.
- </p>
- <p>
-  The CTS Verifier has tests for many kinds of hardware, including some hardware
-that is optional. Device implementations MUST pass all tests for hardware that
-they possess; for instance, if a device possesses an accelerometer, it MUST
-correctly execute the Accelerometer test case in the CTS Verifier. Test cases
-for features noted as optional by this Compatibility Definition Document MAY be
-skipped or omitted.
- </p>
- <p>
-  Every device and every build MUST correctly run the CTS Verifier, as noted
-above. However, since many builds are very similar, device implementers are not
-expected to explicitly run the CTS Verifier on builds that differ only in
-trivial ways. Specifically, device implementations that differ from an
-implementation that has passed the CTS Verifier only by the set of included
-locales, branding, etc. MAY omit the CTS Verifier test.
- </p>
- <h2 id="11_updatable_software">
-  11. Updatable Software
- </h2>
- <p>
-  Device implementations MUST include a mechanism to replace the entirety of the
-system software. The mechanism need not perform &ldquo;live&rdquo; upgrades&mdash;that is, a
-device restart MAY be required.
- </p>
- <p>
-  Any method can be used, provided that it can replace the entirety of the
-software preinstalled on the device. For instance, any of the following
-approaches will satisfy this requirement:
- </p>
- <ul>
-  <li>
-   &ldquo;Over-the-air (OTA)&rdquo; downloads with offline update via reboot.
-  </li>
-  <li>
-   &ldquo;Tethered&rdquo; updates over USB from a host PC.
-  </li>
-  <li>
-   &ldquo;Offline&rdquo; updates via a reboot and update from a file on removable storage.
-  </li>
- </ul>
- <p>
-  However, if the device implementation includes support for an unmetered data
-connection such as 802.11 or Bluetooth PAN (Personal Area Network) profile, it
-MUST support OTA downloads with offline update via reboot.
- </p>
- <p>
-  The update mechanism used MUST support updates without wiping user data. That
-is, the update mechanism MUST preserve application private data and application
-shared data. Note that the upstream Android software includes an update
-mechanism that satisfies this requirement.
- </p>
- <p>
-  For device implementations that are launching with Android 6.0 and
-later, the update mechanism SHOULD support verifying that the system image is
-binary identical to expected result following an OTA. The block-based OTA
-implementation in the upstream Android Open Source Project, added since Android
-5.1, satisfies this requirement.
- </p>
- <p>
-  Also, device implementations SHOULD support
-  <a href="https://source.android.com/devices/tech/ota/ab_updates.html">
-   A/B system updates
-  </a>.
-The AOSP implements this feature using the boot control HAL.
- </p>
- <p>
-  If an error is found in a device implementation after it has been released but
-within its reasonable product lifetime that is determined in consultation with
-the Android Compatibility Team to affect the compatibility of third-party
-applications, the device implementer MUST correct the error via a software
-update available that can be applied per the mechanism just described.
- </p>
- <p>
-  Android includes features that allow the Device Owner app (if present) to
-control the installation of system updates. To facilitate this, the system
-update subsystem for devices that report android.software.device_admin MUST
-implement the behavior described in the
-  <a href="http://developer.android.com/reference/android/app/admin/SystemUpdatePolicy.html">
-   SystemUpdatePolicy
-  </a>
-  class.
- </p>
- <h2 id="12_document_changelog">
-  12. Document Changelog
- </h2>
- <p>
-  For a summary of changes to the Compatibility Definition in this release:
- </p>
- <ul>
-  <li>
-   <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/nougat-mr1-dev/?pretty=full&amp;no-merges">
-    Document changelog
-   </a>
-  </li>
- </ul>
- <p>
-  For a summary of changes to individuals sections:
- </p>
- <ol>
-  <li>
-   <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/nougat-mr1-dev/1_introduction?pretty=full&amp;no-merges">
-    Introduction
-   </a>
-  </li>
-  <li>
-   <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/nougat-mr1-dev/2_device_types?pretty=full&amp;no-merges">
-    Device Types
-   </a>
-  </li>
-  <li>
-   <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/nougat-mr1-dev/3_software?pretty=full&amp;no-merges">
-    Software
-   </a>
-  </li>
-  <li>
-   <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/nougat-mr1-dev/4_application-packaging?pretty=full&amp;no-merges">
-    Application Packaging
-   </a>
-  </li>
-  <li>
-   <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/nougat-mr1-dev/5_multimedia?pretty=full&amp;no-merges">
-    Multimedia
-   </a>
-  </li>
-  <li>
-   <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/nougat-mr1-dev/6_dev-tools-and-options?pretty=full&amp;no-merges">
-    Developer Tools and Options
-   </a>
-  </li>
-  <li>
-   <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/nougat-mr1-dev/7_hardware-compatibility?pretty=full&amp;no-merges">
-    Hardware Compatibility
-   </a>
-  </li>
-  <li>
-   <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/nougat-mr1-dev/8_performance-and-power?pretty=full&amp;no-merges">
-    Performance and Power
-   </a>
-  </li>
-  <li>
-   <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/nougat-mr1-dev/9_security-model?pretty=full&amp;no-merges">
-    Security Model
-   </a>
-  </li>
-  <li>
-   <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/nougat-mr1-dev/10_software-compatibility-testing?pretty=full&amp;no-merges">
-    Software Compatibility Testing
-   </a>
-  </li>
-  <li>
-   <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/nougat-mr1-dev/11_updatable-software?pretty=full&amp;no-merges">
-    Updatable Software
-   </a>
-  </li>
-  <li>
-   <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/nougat-mr1-dev/12_document-changelog?pretty=full&amp;no-merges">
-    Document Changelog
-   </a>
-  </li>
-  <li>
-   <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/nougat-mr1-dev/13_contact-us?pretty=full&amp;no-merges">
-    Contact Us
-   </a>
-  </li>
- </ol>
- <h3 id="12_1_changelog_viewing_tips">
-  12.1. Changelog Viewing Tips
- </h3>
- <p>
-  Changes are marked as follows:
- </p>
- <ul>
-  <li>
-   <p>
-    <strong>
-     CDD
-    </strong>
-    <br/>
-    Substantive changes to the compatibility requirements.
-   </p>
-  </li>
-  <li>
-   <p>
-    <strong>
-     Docs
-    </strong>
-    <br/>
-    Cosmetic or build related changes.
-   </p>
-  </li>
- </ul>
- <p>
-  For best viewing, append the
-  <code>
-   pretty=full
-  </code>
-  and
-  <code>
-   no-merges
-  </code>
-  URL parameters to your
-changelog URLs.
- </p>
- <h2 id="13_contact_us">
-  13. Contact Us
- </h2>
- <p>
-  You can join the
-  <a href="https://groups.google.com/forum/#!forum/android-compatibility">
-   android-compatibility forum
-  </a>
-  and ask for clarifications or bring up any issues that you think the document does not
-cover.
- </p>
-</body>
+    <p>
+      <strong>Legacy Application Compatibility Mode (Section 7.1.5)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>[H-0-1] MUST include support for legacy application compatibility mode as implemented by the upstream Android open source code. That is, device implementations MUST NOT alter the triggers or thresholds at which compatibility mode is activated, and MUST NOT alter the behavior of the compatibility mode itself.
+      </li>
+    </ul>
+    <p>
+      <strong>Keyboard (Section 7.2.1)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>[H-0-1] MUST include support for third-party Input Method Editor (IME) applications.
+      </li>
+    </ul>
+    <p>
+      <strong>Navigation Keys (Section 7.2.3)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [H-0-1] MUST provide the Home, Recents, and Back functions.
+        </p>
+      </li>
+      <li>
+        <p>
+          [H-0-2] MUST send both the normal and long press event of the Back function (<a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BACK"><code>KEYCODE_BACK</code></a>) to the foreground application.
+        </p>
+      </li>
+    </ul>
+    <p>
+      <strong>Touchscreen Input (Section 7.2.4)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>[H-0-1] MUST support touchscreen input.
+      </li>
+    </ul>
+    <p>
+      <strong>Accelerometer (Section 7.3.1)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>[H-SR] Are STRONGLY RECOMMENDED to include a 3-axis accelerometer.
+      </li>
+    </ul>
+    <p>
+      If Handheld device implementations include a 3-axis accelerometer, they:
+    </p>
+    <ul>
+      <li>[H-1-1] MUST be able to report events up to a frequency of at least 100 Hz.
+      </li>
+    </ul>
+    <p>
+      <strong>Gyroscope (Section 7.3.4)</strong>
+    </p>
+    <p>
+      If Handheld device implementations include a gyroscope, they:
+    </p>
+    <ul>
+      <li>[H-1-1] MUST be able to report events up to a frequency of at least 100 Hz.
+      </li>
+    </ul>
+    <p>
+      <strong>Proximity Sensor (Section 7.3.8 )</strong>
+    </p>
+    <p>
+      Handheld device implementations that can make a voice call and indicate any value other than <code>PHONE_TYPE_NONE</code> in <code>getPhoneType</code>:
+    </p>
+    <ul>
+      <li>SHOULD include a proximity sensor.
+      </li>
+    </ul>
+    <p>
+      <strong>Pose Sensor (Section 7.3.12)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>Are RECOMMENDED to support pose sensor with 6 degrees of freedom.
+      </li>
+    </ul>
+    <p>
+      <strong>Bluetooth (Section 7.4.3)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>SHOULD include support for Bluetooth and Bluetooth LE.
+      </li>
+    </ul>
+    <p>
+      <strong>Data Saver (Section 7.4.7)</strong>
+    </p>
+    <p>
+      If Handheld device implementations include a metered connection, they:
+    </p>
+    <ul>
+      <li>[H-1-1] MUST provide the data saver mode.
+      </li>
+    </ul>
+    <p>
+      <strong>Minimum Memory and Storage (Section 7.6.1)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>[H-0-1] MUST have at least 4GB of non-volatile storage available for application private data (a.k.a. "/data" partition)
+      </li>
+      <li>[H-0-2] MUST return “true” for <code>ActivityManager.isLowRamDevice()</code> when there is less than 1GB of memory available to the kernel and userspace.
+      </li>
+    </ul>
+    <p>
+      If Handheld device implementations are 32-bit:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [H-1-1] The memory available to the kernel and userspace MUST be at least 512MB if any of the following densities are used:
+        </p>
+        <ul>
+          <li>280dpi or lower on small/normal screens<sup>*</sup>
+          </li>
+          <li>ldpi or lower on extra large screens
+          </li>
+          <li>mdpi or lower on large screens
+          </li>
+        </ul>
+      </li>
+      <li>
+        <p>
+          [H-2-1] The memory available to the kernel and userspace MUST be at least 608MB if any of the following densities are used:
+        </p>
+        <ul>
+          <li>xhdpi or higher on small/normal screens<sup>*</sup>
+          </li>
+          <li>hdpi or higher on large screens
+          </li>
+          <li>mdpi or higher on extra large screens
+          </li>
+        </ul>
+      </li>
+      <li>
+        <p>
+          [H-3-1] The memory available to the kernel and userspace MUST be at least 896MB if any of the following densities are used:
+        </p>
+        <ul>
+          <li>400dpi or higher on small/normal screens<sup>*</sup>
+          </li>
+          <li>xhdpi or higher on large screens
+          </li>
+          <li>tvdpi or higher on extra large screens
+          </li>
+        </ul>
+      </li>
+      <li>
+        <p>
+          [H-4-1] The memory available to the kernel and userspace MUST be at least 1344MB if any of the following densities are used:
+        </p>
+        <ul>
+          <li>560dpi or higher on small/normal screens<sup>*</sup>
+          </li>
+          <li>400dpi or higher on large screens
+          </li>
+          <li>xhdpi or higher on extra large screens
+          </li>
+        </ul>
+      </li>
+    </ul>
+    <p>
+      If Handheld device implementations are 64-bit:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [H-5-1] The memory available to the kernel and userspace MUST be at least 816MB if any of the following densities are used:
+        </p>
+        <ul>
+          <li>280dpi or lower on small/normal screens<sup>*</sup>
+          </li>
+          <li>ldpi or lower on extra large screens
+          </li>
+          <li>mdpi or lower on large screens
+          </li>
+        </ul>
+      </li>
+      <li>
+        <p>
+          [H-6-1] The memory available to the kernel and userspace MUST be at least 944MB if any of the following densities are used:
+        </p>
+        <ul>
+          <li>xhdpi or higher on small/normal screens<sup>*</sup>
+          </li>
+          <li>hdpi or higher on large screens
+          </li>
+          <li>mdpi or higher on extra large screens
+          </li>
+        </ul>
+      </li>
+      <li>
+        <p>
+          [H-7-1] The memory available to the kernel and userspace MUST be at least 1280MB if any of the following densities are used:
+        </p>
+        <ul>
+          <li>400dpi or higher on small/normal screens<sup>*</sup>
+          </li>
+          <li>xhdpi or higher on large screens
+          </li>
+          <li>tvdpi or higher on extra large screens
+          </li>
+        </ul>
+      </li>
+      <li>
+        <p>
+          [H-8-1] The memory available to the kernel and userspace MUST be at least 1824MB if any of the following densities are used:
+        </p>
+        <ul>
+          <li>560dpi or higher on small/normal screens<sup>*</sup>
+          </li>
+          <li>400dpi or higher on large screens
+          </li>
+          <li>xhdpi or higher on extra large screens
+          </li>
+        </ul>
+      </li>
+    </ul>
+    <p>
+      Note that the "memory available to the kernel and userspace" above refers to the memory space provided in addition to any memory already dedicated to hardware components such as radio, video, and so on that are not under the kernel’s control on device implementations.
+    </p>
+    <p>
+      <strong>Application Shared Storage (Section 7.6.2)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>[H-0-1] MUST NOT provide an application shared storage smaller than 1 GiB.
+      </li>
+    </ul>
+    <p>
+      <strong>USB peripheral mode (Section 7.7.1)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>SHOULD include a USB port supporting peripheral mode.
+      </li>
+    </ul>
+    <p>
+      If handheld device implementations include a USB port supporting peripheral mode, they:
+    </p>
+    <ul>
+      <li>[H-1-1] MUST implement the Android Open Accessory (AOA) API.<sup>*</sup>
+      </li>
+    </ul>
+    <p>
+      <strong>Microphone (Section 7.8.1)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>[H-0-1] MUST include a microphone.
+      </li>
+    </ul>
+    <p>
+      <strong>Audio Output (Section 7.8.2)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>[H-0-1] MUST have an audio output and declare <code>android.hardware.audio.output</code>.
+      </li>
+    </ul>
+    <p>
+      <strong>Virtual Reality Mode (Section 7.9.1)</strong>
+    </p>
+    <p>
+      If Handheld device implementations include support for the VR mode, they:
+    </p>
+    <ul>
+      <li>[H-1-1] MUST declare the <code>android.software.vr.mode</code> feature.<sup>*</sup>
+      </li>
+    </ul>
+    <p>
+      If device implementations declare <code>android.software.vr.mode</code> feature, they:
+    </p>
+    <ul>
+      <li>[H-2-1] MUST include an application implementing <code>android.service.vr.VrListenerService</code> that can be enabled by VR applications via <code>android.app.Activity#setVrModeEnabled</code>.<sup>*</sup>
+      </li>
+    </ul>
+    <p>
+      <strong>Virtual Reality High Performance (Section 7.9.2)</strong>
+    </p>
+    <p>
+      If Handheld device implementations are capable of meeting all the requirements to declare the <code>android.hardware.vr.high_performance</code> feature flag, they:
+    </p>
+    <ul>
+      <li>[H-1-1] MUST declare the <code>android.hardware.vr.high_performance</code> feature flag.<sup>*</sup>
+      </li>
+    </ul>
+    <h4 id="2_2_2_multimedia">
+      2.2.2. Multimedia
+    </h4>
+    <p>
+      <strong>Audio Encoding (Section 5.1.1)</strong>
+    </p>
+    <p>
+      Handheld device implementations MUST support the following audio encoding:
+    </p>
+    <ul>
+      <li>[H-0-1] AMR-NB
+      </li>
+      <li>[H-0-2] AMR-WB
+      </li>
+      <li>[H-0-3] MPEG-4 AAC Profile (AAC LC)
+      </li>
+      <li>[H-0-4] MPEG-4 HE AAC Profile (AAC+)
+      </li>
+      <li>[H-0-5] AAC ELD (enhanced low delay AAC)
+      </li>
+    </ul>
+    <p>
+      <strong>Audio Decoding (Section 5.1.2)</strong>
+    </p>
+    <p>
+      Handheld device implementations MUST support the following audio decoding:
+    </p>
+    <ul>
+      <li>[H-0-1] AMR-NB
+      </li>
+      <li>[H-0-2] AMR-WB
+      </li>
+    </ul>
+    <p>
+      <strong>Video Encoding (Section 5.2)</strong>
+    </p>
+    <p>
+      Handheld device implementations MUST support the following video encoding and make it available to third-party applications:
+    </p>
+    <ul>
+      <li>[H-0-1] H.264 AVC
+      </li>
+      <li>[H-0-2] VP8
+      </li>
+    </ul>
+    <p>
+      <strong>Video Decoding (Section 5.3)</strong>
+    </p>
+    <p>
+      Handheld device implementations MUST support the following video decoding:
+    </p>
+    <ul>
+      <li>[H-0-1] H.264 AVC.
+      </li>
+      <li>[H-0-2] H.265 HEVC.
+      </li>
+      <li>[H-0-3] MPEG-4 SP.
+      </li>
+      <li>[H-0-4] VP8.
+      </li>
+      <li>[H-0-5] VP9.
+      </li>
+    </ul>
+    <h4 id="2_2_3_software">
+      2.2.3. Software
+    </h4>
+    <p>
+      <strong>WebView Compatibility (Section 3.4.1)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>[H-0-1] MUST provide a complete implementation of the <code>android.webkit.Webview</code> API.
+      </li>
+    </ul>
+    <p>
+      <strong>Browser Compatibility (Section 3.4.2)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>[H-0-1] MUST include a standalone Browser application for general user web browsing.
+      </li>
+    </ul>
+    <p>
+      <strong>Launcher (Section 3.8.1)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [H-SR] Are STRONGLY RECOMMENDED to implement a default launcher that supports in-app pinning of shortcuts and widgets.
+        </p>
+      </li>
+      <li>
+        <p>
+          [H-SR] Are STRONGLY RECOMMENDED to implement a default launcher that provides quick access to the additional shortcuts provided by third-party apps through the <a href="https://developer.android.com/reference/android/content/pm/ShortcutManager.html">ShortcutManager</a> API.
+        </p>
+      </li>
+      <li>
+        <p>
+          [H-SR] Are STRONGLY RECOMMENDED to include a default launcher app that shows badges for the app icons.
+        </p>
+      </li>
+    </ul>
+    <p>
+      <strong>Widgets (Section 3.8.2)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>[H-SR] Are STRONGLY RECOMMENDED to support third-party app widgets.
+      </li>
+    </ul>
+    <p>
+      <strong>Notifications (Section 3.8.3)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>[H-0-1] MUST allow third-party apps to notify users of notable events through the <a href="https://developer.android.com/reference/android/app/Notification.html"><code>Notification</code></a> and <a href="https://developer.android.com/reference/android/app/NotificationManager.html"><code>NotificationManager</code></a> API classes.
+      </li>
+      <li>[H-0-2] MUST support rich notifications.
+      </li>
+      <li>[H-0-3] MUST support heads-up notifications.
+      </li>
+      <li>[H-0-4] MUST include a notification shade, providing the user the ability to directly control (e.g. reply, snooze, dismiss, block) the notifications through user affordance such as action buttons or the control panel as implemented in the AOSP.
+      </li>
+    </ul>
+    <p>
+      <strong>Search (Section 3.8.4)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>[H-SR] Are STRONGLY RECOMMENDED to implement an assistant on the device to handle the <a href="http://developer.android.com/reference/android/content/Intent.html#ACTION_ASSIST">Assist action</a>.
+      </li>
+    </ul>
+    <p>
+      <strong>Lock Screen Media Control (Section 3.8.10)</strong>
+    </p>
+    <p>
+      If Android Handheld device implementations support a lock screen,they:
+    </p>
+    <ul>
+      <li>[H-1-1] MUST display the Lock screen Notifications including the Media Notification Template.
+      </li>
+    </ul>
+    <p>
+      <strong>Device administration (Section 3.9)</strong>
+    </p>
+    <p>
+      If Handheld device implementations support a secure lock screen, they:
+    </p>
+    <ul>
+      <li>[H-1-1] MUST implement the full range of <a href="http://developer.android.com/guide/topics/admin/device-admin.html">device administration</a> policies defined in the Android SDK documentation.
+      </li>
+    </ul>
+    <p>
+      <strong>Accessibility (Section 3.10)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [H-SR] MUST support third-party accessibility services.
+        </p>
+      </li>
+      <li>
+        <p>
+          [H-SR] Are STRONGLY RECOMMENDED to preload accessibility services on the device comparable with or exceeding functionality of the Switch Access and TalkBack (for languages supported by the preloaded Text-to-speech engine) accessibility services as provided in the <a href="https://github.com/google/talkback">talkback open source project</a>.
+        </p>
+      </li>
+    </ul>
+    <p>
+      <strong>Text-to-Speech (Section 3.11)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [H-0-1] MUST support installation of third-party TTS engines.
+        </p>
+      </li>
+      <li>
+        <p>
+          [H-SR] Are STRONGLY RECOMMENDED to include a TTS engine supporting the languages available on the device.
+        </p>
+      </li>
+    </ul>
+    <p>
+      <strong>Quick Settings (Section 3.13)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>[H-SR] Are STRONGLY RECOMMENDED to include a Quick Settings UI component.
+      </li>
+    </ul>
+    <p>
+      <strong>Companion Device Pairing (Section 3.15)</strong>
+    </p>
+    <p>
+      If Android handheld device implementations declare <code>FEATURE_BLUETOOTH</code> or <code>FEATURE_WIFI</code> support, they:
+    </p>
+    <ul>
+      <li>[H-1-1] MUST support the companion device pairing feature.
+      </li>
+    </ul>
+    <h4 id="2_2_4_performance_and_power">
+      2.2.4. Performance and Power
+    </h4>
+    <p>
+      <strong>User Experience Consistency (Section 8.1)</strong>
+    </p>
+    <p>
+      For handheld device implementations:
+    </p>
+    <ul>
+      <li>[H-0-1] <strong>Consistent frame latency</strong>. Inconsistent frame latency or a delay to render frames MUST NOT happen more often than 5 frames in a second, and SHOULD be below 1 frames in a second.
+      </li>
+      <li>[H-0-2] <strong>User interface latency</strong>. Device implementations MUST ensure low latency user experience by scrolling a list of 10K list entries as defined by the Android Compatibility Test Suite (CTS) in less than 36 secs.
+      </li>
+      <li>[H-0-3] <strong>Task switching</strong>. When multiple applications have been launched, re-launching an already-running application after it has been launched MUST take less than 1 second.
+      </li>
+    </ul>
+    <p>
+      <strong>File I/O Access Performance (Section 8.2)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>[H-0-1] MUST ensure a sequential write performance of at least 5 MB/s.
+      </li>
+      <li>[H-0-2] MUST ensure a random write performance of at least 0.5 MB/s.
+      </li>
+      <li>[H-0-3] MUST ensure a sequential read performance of at least 15 MB/s.
+      </li>
+      <li>[H-0-4] MUST ensure a random read performance of at least 3.5 MB/s.
+      </li>
+    </ul>
+    <p>
+      <strong>Power-Saving Modes (Section 8.3)</strong>
+    </p>
+    <p>
+      For handheld device implementations:
+    </p>
+    <ul>
+      <li>[H-0-1] All Apps exempted from App Standby and Doze power-saving modes MUST be made visible to the end user.
+      </li>
+      <li>[H-0-2] The triggering, maintenance, wakeup algorithms and the use of global system settings of App Standby and Doze power-saving modes MUST not deviate from the Android Open Source Project.
+      </li>
+    </ul>
+    <p>
+      <strong>Power Consumption Accounting (Sections 8.4)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>[H-0-1] MUST provide a per-component power profile that defines the <a href="http://source.android.com/devices/tech/power/values.html">current consumption value</a> for each hardware component and the approximate battery drain caused by the components over time as documented in the Android Open Source Project site.
+      </li>
+      <li>[H-0-2] MUST report all power consumption values in milliampere hours (mAh).
+      </li>
+      <li>[H-0-3] MUST report CPU power consumption per each process's UID. The Android Open Source Project meets the requirement through the <code>uid_cputime</code> kernel module implementation.
+      </li>
+      <li>[H-0-4] MUST make this power usage available via the <a href="http://source.android.com/devices/tech/power/batterystats.html"><code>adb shell dumpsys batterystats</code></a> shell command to the app developer.
+      </li>
+      <li>SHOULD be attributed to the hardware component itself if unable to attribute hardware component power usage to an application.
+      </li>
+    </ul>
+    <p>
+      If Handheld device implementations include a screen or video output, they:
+    </p>
+    <ul>
+      <li>[H-1-1] MUST honor the <a href="http://developer.android.com/reference/android/content/Intent.html#ACTION_POWER_USAGE_SUMMARY"><code>android.intent.action.POWER_USAGE_SUMMARY</code></a> intent and display a settings menu that shows this power usage.
+      </li>
+    </ul>
+    <h4 id="2_2_5_security_model">
+      2.2.5. Security Model
+    </h4>
+    <p>
+      <strong>Permissions (Sections 9.1)</strong>
+    </p>
+    <p>
+      Handheld device implementations:
+    </p>
+    <ul>
+      <li>[H-0-1] MUST allow third-party apps to access the usage statistics via the <code>android.permission.PACKAGE_USAGE_STATS</code> permission and provide a user-accessible mechanism to grant or revoke access to such apps in response to the <a href="https://developer.android.com/reference/android/provider/Settings.html#ACTION&amp;lowbar;USAGE&amp;lowbar;ACCESS&amp;lowbar;SETTINGS"><code>android.settings.ACTION_USAGE_ACCESS_SETTINGS</code></a> intent.
+      </li>
+    </ul>
+    <h3 id="2_3_television_requirements">
+      2.3. Television Requirements
+    </h3>
+    <p>
+      An <strong>Android Television device</strong> refers to an Android device implementation that is an entertainment interface for consuming digital media, movies, games, apps, and/or live TV for users sitting about ten feet away (a “lean back” or “10-foot user interface”).
+    </p>
+    <p>
+      Android device implementations are classified as a Television if they meet all the following criteria:
+    </p>
+    <ul>
+      <li>Have provided a mechanism to remotely control the rendered user interface on the display that might sit ten feet away from the user.
+      </li>
+      <li>Have an embedded screen display with the diagonal length larger than 24 inches OR include a video output port, such as VGA, HDMI, DisplayPort or a wireless port for display.
+      </li>
+    </ul>
+    <p>
+      The additional requirements in the rest of this section are specific to Android Television device implementations.
+    </p>
+    <h4 id="2_3_1_hardware">
+      2.3.1. Hardware
+    </h4>
+    <p>
+      <strong>Non-touch Navigation (Section 7.2.2)</strong>
+    </p>
+    <p>
+      Television device implementations:
+    </p>
+    <ul>
+      <li>[T-0-1] MUST support <a href="https://developer.android.com/reference/android/content/res/Configuration.html#NAVIGATION_DPAD">D-pad</a>.
+      </li>
+    </ul>
+    <p>
+      <strong>Navigation Keys (Section 7.2.3)</strong>
+    </p>
+    <p>
+      Television device implementations:
+    </p>
+    <ul>
+      <li>[T-0-1] MUST provide the Home and Back functions.
+      </li>
+      <li>[T-0-2] MUST send both the normal and long press event of the Back function (<a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BACK"><code>KEYCODE_BACK</code></a>) to the foreground application.
+      </li>
+    </ul>
+    <p>
+      <strong>Button Mappings (Section 7.2.6.1)</strong>
+    </p>
+    <p>
+      Television device implementations:
+    </p>
+    <ul>
+      <li>[T-0-1] MUST include support for game controllers and declare the <code>android.hardware.gamepad</code> feature flag.
+      </li>
+    </ul>
+    <p>
+      <strong>Remote Control (Section 7.2.7)</strong>
+    </p>
+    <p>
+      Television device implementations:
+    </p>
+    <ul>
+      <li>SHOULD provide a remote control from which users can access <a href="#7_2_2_non-touch_navigation">non-touch navigation</a> and <a href="#7_2_3_navigation_keys">core navigation keys</a> inputs.
+      </li>
+    </ul>
+    <p>
+      <strong>Gyroscope (Section 7.3.4)</strong>
+    </p>
+    <p>
+      If Television device implementations include a gyroscope, they:
+    </p>
+    <ul>
+      <li>[T-1-1] MUST be able to report events up to a frequency of at least 100 Hz.
+      </li>
+    </ul>
+    <p>
+      <strong>Bluetooth (Section 7.4.3)</strong>
+    </p>
+    <p>
+      Television device implementations:
+    </p>
+    <ul>
+      <li>[T-0-1] MUST support Bluetooth and Bluetooth LE.
+      </li>
+    </ul>
+    <p>
+      <strong>Minimum Memory and Storage (Section 7.6.1)</strong>
+    </p>
+    <p>
+      Television device implementations:
+    </p>
+    <ul>
+      <li>[T-0-1] MUST have at least 4GB of non-volatile storage available for application private data (a.k.a. "/data" partition)
+      </li>
+    </ul>
+    <p>
+      <strong>Microphone (Section 7.8.1)</strong>
+    </p>
+    <p>
+      Television device implementations:
+    </p>
+    <ul>
+      <li>SHOULD include a microphone.
+      </li>
+    </ul>
+    <p>
+      <strong>Audio Output (Section 7.8.2)</strong>
+    </p>
+    <p>
+      Television device implementations:
+    </p>
+    <ul>
+      <li>[T-0-1] MUST have an audio output and declare <code>android.hardware.audio.output</code>.
+      </li>
+    </ul>
+    <h4 id="2_3_2_multimedia">
+      2.3.2. Multimedia
+    </h4>
+    <p>
+      <strong>Audio Encoding (Section 5.1)</strong>
+    </p>
+    <p>
+      Television device implementations MUST support the following audio encoding:
+    </p>
+    <ul>
+      <li>[T-0-1] MPEG-4 AAC Profile (AAC LC)
+      </li>
+      <li>[T-0-2] MPEG-4 HE AAC Profile (AAC+)
+      </li>
+      <li>[T-0-3] AAC ELD (enhanced low delay AAC)
+      </li>
+    </ul>
+    <p>
+      <strong>Video Encoding (Section 5.2)</strong>
+    </p>
+    <p>
+      Television device implementations MUST support the following video encoding:
+    </p>
+    <ul>
+      <li>[T-0-1] H.264 AVC
+      </li>
+      <li>[T-0-2] VP8
+      </li>
+    </ul>
+    <p>
+      <strong>H-264 (Section 5.2.2)</strong>
+    </p>
+    <p>
+      Television device implementations are:
+    </p>
+    <ul>
+      <li>[T-SR] STRONGLY RECOMMENDED to support H.264 encoding of 720p and 1080p resolution videos.
+      </li>
+      <li>[T-SR] STRONGLY RECOMMENDED to support H.264 encoding of 1080p resolution video at 30 frame-per-second (fps).
+      </li>
+    </ul>
+    <p>
+      <strong>Video Decoding (Section 5.3)</strong>
+    </p>
+    <p>
+      Television device implementations MUST support the following video decoding:
+    </p>
+    <ul>
+      <li>[T-0-1] H.264 AVC
+      </li>
+      <li>[T-0-2] H.265 HEVC
+      </li>
+      <li>[T-0-3] MPEG-4 SP
+      </li>
+      <li>[T-0-4] VP8
+      </li>
+      <li>[T-0-5] VP9
+      </li>
+    </ul>
+    <p>
+      Television device implementations are STRONGLY RECOMMENDED to support the following video decoding:
+    </p>
+    <ul>
+      <li>[T-SR] MPEG-2
+      </li>
+    </ul>
+    <p>
+      <strong>H.264 (Section 5.3.4)</strong>
+    </p>
+    <p>
+      If Television device implementations support H.264 decoders, they:
+    </p>
+    <ul>
+      <li>[T-1-1] MUST support High Profile Level 4.2 and the HD 1080p (at 60 fps) decoding profile.
+      </li>
+      <li>[T-1-2] MUST be capable of decoding videos with both HD profiles as indicated in the following table and encoded with either the Baseline Profile, Main Profile, or the High Profile Level 4.2
+      </li>
+    </ul>
+    <p>
+      <strong>H.265 (HEVC) (Section 5.3.5)</strong>
+    </p>
+    <p>
+      If Television device implementations support H.265 codec and the HD 1080p decoding profile, they:
+    </p>
+    <ul>
+      <li>[T-1-1] MUST support the Main Profile Level 4.1 Main tier.
+      </li>
+      <li>[T-SR] Are STRONGLY RECOMMENDED to support 60 fps video frame rate for HD 1080p.
+      </li>
+    </ul>
+    <p>
+      If Television device implementations support H.265 codec and the UHD decoding profile, then:
+    </p>
+    <ul>
+      <li>[T-2-1] The codec MUST support Main10 Level 5 Main Tier profile.
+      </li>
+    </ul>
+    <p>
+      <strong>VP8 (Section 5.3.6)</strong>
+    </p>
+    <p>
+      If Television device implementations support VP8 codec, they:
+    </p>
+    <ul>
+      <li>[T-1-1] MUST support the HD 1080p60 decoding profile.
+      </li>
+    </ul>
+    <p>
+      If Television device implementations support VP8 codec and support 720p, they:
+    </p>
+    <ul>
+      <li>[T-2-1] MUST support the HD 720p60 decoding profile.
+      </li>
+    </ul>
+    <p>
+      <strong>VP9 (Section 5.3.7)</strong>
+    </p>
+    <p>
+      If Television device implementations support VP9 codec and the UHD video decoding, they:
+    </p>
+    <ul>
+      <li>[T-1-1] MUST support 8-bit color depth and SHOULD support VP9 Profile 2 (10-bit).
+      </li>
+    </ul>
+    <p>
+      If Television device implementations support VP9 codec, the 1080p profile and VP9 hardware decoding, they:
+    </p>
+    <ul>
+      <li>[T-2-1] MUST support 60 fps for 1080p.
+      </li>
+    </ul>
+    <p>
+      <strong>Secure Media (Section 5.8)</strong>
+    </p>
+    <p>
+      If device implementations are Android Television devices and support 4K resolution, they:
+    </p>
+    <ul>
+      <li>[T-1-1] MUST support HDCP 2.2 for all wired external displays.
+      </li>
+    </ul>
+    <p>
+      If Television device implementations don't support 4K resolution, they:
+    </p>
+    <ul>
+      <li>[T-2-1] MUST support HDCP 1.4 for all wired external displays.
+      </li>
+    </ul>
+    <p>
+      Television device implementations:
+    </p>
+    <ul>
+      <li>[T-SR] Are STRONGLY RECOMMENDED to support simulataneous decoding of secure streams. At minimum, simultaneous decoding of two steams is STRONGLY RECOMMENDED.
+      </li>
+    </ul>
+    <p>
+      <strong>Audio Output Volume (Section 5.5.3)</strong>
+    </p>
+    <p>
+      Television device implementations:
+    </p>
+    <ul>
+      <li>[T-0-1] MUST include support for system Master Volume and digital audio output volume attenuation on supported outputs, except for compressed audio passthrough output (where no audio decoding is done on the device).
+      </li>
+    </ul>
+    <h4 id="2_3_3_software">
+      2.3.3. Software
+    </h4>
+    <p>
+      Television device implementations:
+    </p>
+    <ul>
+      <li>[T-0-1] MUST declare the features <a href="http://developer.android.com/reference/android/content/pm/PackageManager.html#FEATURE_LEANBACK"><code>android.software.leanback</code></a> and <code>android.hardware.type.television</code>.
+      </li>
+    </ul>
+    <p>
+      <strong>WebView compatibility (Section 3.4.1)</strong>
+    </p>
+    <p>
+      Television device implementations:
+    </p>
+    <ul>
+      <li>[T-0-1] MUST provide a complete implementation of the <code>android.webkit.Webview</code> API.
+      </li>
+    </ul>
+    <p>
+      <strong>Lock Screen Media Control (Section 3.8.10)</strong>
+    </p>
+    <p>
+      If Android Television device implementations support a lock screen,they:
+    </p>
+    <ul>
+      <li>[T-1-1] MUST display the Lock screen Notifications including the Media Notification Template.
+      </li>
+    </ul>
+    <p>
+      <strong>Multi-windows (Section 3.8.14)</strong>
+    </p>
+    <p>
+      Television device implementations:
+    </p>
+    <ul>
+      <li>[T-SR] Are STRONGLY RECOMMENDED to support picture-in-picture (PIP) mode multi-window.
+      </li>
+    </ul>
+    <p>
+      <strong>Accessibility (Section 3.10)</strong>
+    </p>
+    <p>
+      Television device implementations:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [T-SR] MUST support third-party accessibility services.
+        </p>
+      </li>
+      <li>
+        <p>
+          [T-SR] Android Television device implementations are STRONGLY RECOMMENDED to preload accessibility services on the device comparable with or exceeding functionality of the Switch Access and TalkBack (for languages supported by the preloaded Text-to-speech engine) accessibility services as provided in the <a href="https://github.com/google/talkback">talkback open source project</a>.
+        </p>
+      </li>
+    </ul>
+    <p>
+      <strong>Text-to-Speech (Section 3.11)</strong>
+    </p>
+    <p>
+      If device implementations report the feature android.hardware.audio.output, they:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [T-SR] STRONGLY RECOMMENDED to include a TTS engine supporting the languages available on the device.
+        </p>
+      </li>
+      <li>
+        <p>
+          [T-0-1] MUST support installation of third-party TTS engines.
+        </p>
+      </li>
+    </ul>
+    <p>
+      <strong>TV Input Framework (Section 3.12)</strong>
+    </p>
+    <p>
+      Television device implementations:
+    </p>
+    <ul>
+      <li>[T-0-1] MUST support TV Input Framework.
+      </li>
+    </ul>
+    <h4 id="2_3_4_performance_and_power">
+      2.3.4. Performance and Power
+    </h4>
+    <p>
+      <strong>User Experience Consistency (Section 8.1)</strong>
+    </p>
+    <p>
+      For Television device implementations:
+    </p>
+    <ul>
+      <li>[T-0-1] <strong>Consistent frame latency</strong>. Inconsistent frame latency or a delay to render frames MUST NOT happen more often than 5 frames in a second, and SHOULD be below 1 frames in a second.
+      </li>
+    </ul>
+    <p>
+      <strong>File I/O Access Performance (Section 8.2)</strong>
+    </p>
+    <p>
+      Television device implementations:
+    </p>
+    <ul>
+      <li>[T-0-1] MUST ensure a sequential write performance of at least 5MB/s.
+      </li>
+      <li>[T-0-2] MUST ensure a random write performance of at least 0.5MB/s.
+      </li>
+      <li>[T-0-3] MUST ensure a sequential read performance of at least 15MB/s.
+      </li>
+      <li>[T-0-4] MUST ensure a random read performance of at least 3.5MB/s.
+      </li>
+    </ul>
+    <p>
+      <strong>Power-Saving Modes (Section 8.3)</strong>
+    </p>
+    <p>
+      For Television device implementations:
+    </p>
+    <ul>
+      <li>[T-0-1] All Apps exempted from App Standby and Doze power-saving modes MUST be made visible to the end user.
+      </li>
+      <li>[T-0-2] The triggering, maintenance, wakeup algorithms and the use of global system settings of App Standby and Doze power-saving modes MUST not deviate from the Android Open Source Project.
+      </li>
+    </ul>
+    <p>
+      <strong>Power Consumption Accounting (Sections 8.4)</strong>
+    </p>
+    <p>
+      Television device implementations:
+    </p>
+    <ul>
+      <li>[T-0-1] MUST provide a per-component power profile that defines the <a href="http://source.android.com/devices/tech/power/values.html">current consumption value</a> for each hardware component and the approximate battery drain caused by the components over time as documented in the Android Open Source Project site.
+      </li>
+      <li>[T-0-2] MUST report all power consumption values in milliampere hours (mAh).
+      </li>
+      <li>[T-0-3] MUST report CPU power consumption per each process's UID. The Android Open Source Project meets the requirement through the <code>uid_cputime</code> kernel module implementation.
+      </li>
+      <li>SHOULD be attributed to the hardware component itself if unable to attribute hardware component power usage to an application.
+      </li>
+      <li>[T-0-4] MUST make this power usage available via the <a href="http://source.android.com/devices/tech/power/batterystats.html"><code>adb shell dumpsys batterystats</code></a> shell command to the app developer.
+      </li>
+    </ul>
+    <h3 id="2_4_watch_requirements">
+      2.4. Watch Requirements
+    </h3>
+    <p>
+      An <strong>Android Watch device</strong> refers to an Android device implementation intended to be worn on the body, perhaps on the wrist.
+    </p>
+    <p>
+      Android device implementations are classified as a Watch if they meet all the following criteria:
+    </p>
+    <ul>
+      <li>Have a screen with the physical diagonal length in the range from 1.1 to 2.5 inches.
+      </li>
+      <li>Have a mechanism provided to be worn on the body.
+      </li>
+    </ul>
+    <p>
+      The additional requirements in the rest of this section are specific to Android Watch device implementations.
+    </p>
+    <h4 id="2_4_1_hardware">
+      2.4.1. Hardware
+    </h4>
+    <p>
+      <strong>Screen Size (Section 7.1.1.1)</strong>
+    </p>
+    <p>
+      Watch device implementations:
+    </p>
+    <ul>
+      <li>[W-0-1] MUST have a screen with the physical diagonal size in the range from 1.1 to 2.5 inches.
+      </li>
+    </ul>
+    <p>
+      <strong>Navigation Keys (Section 7.2.3)</strong>
+    </p>
+    <p>
+      Watch device implementations:
+    </p>
+    <ul>
+      <li>[W-0-1] MUST have the Home function available to the user, and the Back function except for when it is in <code>UI_MODE_TYPE_WATCH</code>.
+      </li>
+    </ul>
+    <p>
+      <strong>Touchscreen Input (Section 7.2.4)</strong>
+    </p>
+    <p>
+      Watch device implementations:
+    </p>
+    <ul>
+      <li>[W-0-2] MUST support touchscreen input.
+      </li>
+    </ul>
+    <p>
+      <strong>Accelerometer (Section 7.3.1)</strong>
+    </p>
+    <p>
+      Watch device implementations:
+    </p>
+    <ul>
+      <li>[W-SR] Are STRONGLY RECOMMENDED to include a 3-axis accelerometer.
+      </li>
+    </ul>
+    <p>
+      <strong>Bluetooth (Section 7.4.3)</strong>
+    </p>
+    <p>
+      Watch device implementations:
+    </p>
+    <ul>
+      <li>[W-0-1] MUST support Bluetooth.
+      </li>
+    </ul>
+    <p>
+      <strong>Minimum Memory and Storage (Section 7.6.1)</strong>
+    </p>
+    <p>
+      Watch device implementations:
+    </p>
+    <ul>
+      <li>[W-0-1] MUST have at least 1GB of non-volatile storage available for application private data (a.k.a. "/data" partition)
+      </li>
+      <li>[W-0-2] MUST have at least 416MB memory available to the kernel and userspace.
+      </li>
+    </ul>
+    <p>
+      <strong>Microphone (Section 7.8.1)</strong>
+    </p>
+    <p>
+      Watch device implementations:
+    </p>
+    <ul>
+      <li>[W-0-1] MUST include a microphone.
+      </li>
+    </ul>
+    <p>
+      <strong>Audio Output (Section 7.8.1)</strong>
+    </p>
+    <p>
+      Watch device implementations:
+    </p>
+    <ul>
+      <li>MAY but SHOULD NOT have audio output.
+      </li>
+    </ul>
+    <h4 id="2_4_2_multimedia">
+      2.4.2. Multimedia
+    </h4>
+    <p>
+      No additional requirements.
+    </p>
+    <h4 id="2_4_3_software">
+      2.4.3. Software
+    </h4>
+    <p>
+      Watch device implementations:
+    </p>
+    <ul>
+      <li>[W-0-1] MUST declare the feature android.hardware.type.watch.
+      </li>
+      <li>[W-0-2] MUST support uiMode = <a href="http://developer.android.com/reference/android/content/res/Configuration.html#UI_MODE_TYPE_WATCH">UI_MODE_TYPE_WATCH</a>.
+      </li>
+    </ul>
+    <p>
+      <strong>Search (Section 3.8.4)</strong>
+    </p>
+    <p>
+      Watch device implementations:
+    </p>
+    <ul>
+      <li>[W-SR] Are STRONGLY RECOMMENDED to implement an assistant on the device to handle the <a href="http://developer.android.com/reference/android/content/Intent.html#ACTION_ASSIST">Assist action</a>.
+      </li>
+    </ul>
+    <p>
+      <strong>Accessibility (Section 3.10)</strong>
+    </p>
+    <p>
+      Watch device implementations that declare the <code>android.hardware.audio.output</code> feature flag:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [W-1-1] MUST support third-party accessibility services.
+        </p>
+      </li>
+      <li>
+        <p>
+          [W-SR] Are STRONGLY RECOMMENDED to preload accessibility services on the device comparable with or exceeding functionality of the Switch Access and TalkBack (for languages supported by the preloaded Text-to-speech engine) accessibility services as provided in the <a href="https://github.com/google/talkback">talkback open source project</a>.
+        </p>
+      </li>
+    </ul>
+    <p>
+      <strong>Text-to-Speech (Section 3.11)</strong>
+    </p>
+    <p>
+      If Watch device implementations report the feature android.hardware.audio.output, they:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [W-SR] Are STRONGLY RECOMMENDED to include a TTS engine supporting the languages available on the device.
+        </p>
+      </li>
+      <li>
+        <p>
+          [W-0-1] MUST support installation of third-party TTS engines.
+        </p>
+      </li>
+    </ul>
+    <h3 id="2_5_automotive_requirements">
+      2.5. Automotive Requirements
+    </h3>
+    <p>
+      <strong>Android Automotive implementation</strong> refers to a vehicle head unit running Android as an operating system for part or all of the system and/or infotainment functionality.
+    </p>
+    <p>
+      Android device implementations are classified as an Automotive if they declare the feature <code>android.hardware.type.automotive</code> or meet all the following criteria.
+    </p>
+    <ul>
+      <li>Are embedded as part of, or pluggable to, an automotive vehicle.
+      </li>
+      <li>Are using a screen in the driver's seat row as the primary display.
+      </li>
+    </ul>
+    <p>
+      The additional requirements in the rest of this section are specific to Android Automotive device implementations.
+    </p>
+    <h4 id="2_5_1_hardware">
+      2.5.1. Hardware
+    </h4>
+    <p>
+      <strong>Screen Size (Section 7.1.1.1)</strong>
+    </p>
+    <p>
+      Automotive device implementations:
+    </p>
+    <ul>
+      <li>[A-0-1] MUST have a screen at least 6 inches in physical diagonal size.
+      </li>
+      <li>[A-0-2] MUST have a screen size layout of at least 750 dp x 480 dp.
+      </li>
+    </ul>
+    <p>
+      <strong>Navigation Keys (Section 7.2.3)</strong>
+    </p>
+    <p>
+      Automotive device implementations:
+    </p>
+    <ul>
+      <li>[A-0-1] MUST provide the Home function and MAY provide Back and Recent functions.
+      </li>
+      <li>[A-0-2] MUST send both the normal and long press event of the Back function (<a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BACK"><code>KEYCODE_BACK</code></a>) to the foreground application.
+      </li>
+    </ul>
+    <p>
+      <strong>Accelerometer (Section 7.3.1)</strong>
+    </p>
+    <p>
+      Automotive device implementations:
+    </p>
+    <ul>
+      <li>[A-SR] Are STRONGLY RECOMMENDED to include a 3-axis accelerometer.
+      </li>
+    </ul>
+    <p>
+      If Automotive device implementations include a 3-axis accelerometer, they:
+    </p>
+    <ul>
+      <li>[A-1-1] MUST be able to report events up to a frequency of at least 100 Hz.
+      </li>
+      <li>[A-1-2] MUST comply with the Android <a href="http://source.android.com/devices/sensors/sensor-types.html#auto_axes">car sensor coordinate system</a>.
+      </li>
+    </ul>
+    <p>
+      <strong>GPS (Section 7.3.3)</strong>
+    </p>
+    <p>
+      If Automotive device implementations include a GPS/GNSS receiver and report the capability to applications through the <code>android.hardware.location.gps</code> feature flag:
+    </p>
+    <ul>
+      <li>[A-1-1] GNSS technology generation MUST be the year "2017" or newer.
+      </li>
+    </ul>
+    <p>
+      <strong>Gyroscope (Section 7.3.4)</strong>
+    </p>
+    <p>
+      If Automotive device implementations include a gyroscope, they:
+    </p>
+    <ul>
+      <li>[A-1-1] MUST be able to report events up to a frequency of at least 100 Hz.
+      </li>
+    </ul>
+    <p>
+      <strong>Android Automotive-only sensors (Section 7.3.11)</strong> <strong>Current Gear (Section 7.3.11.1)</strong>
+    </p>
+    <p>
+      Automotive device implementations:
+    </p>
+    <ul>
+      <li>SHOULD provide current gear as <code>SENSOR_TYPE_GEAR</code>.
+      </li>
+    </ul>
+    <p>
+      <strong>Day Night Mode (Section 7.3.11.2)</strong>
+    </p>
+    <p>
+      Automotive device implementations:
+    </p>
+    <ul>
+      <li>[A-0-1] MUST support day/night mode defined as <code>SENSOR_TYPE_NIGHT</code>.
+      </li>
+      <li>[A-0-2] The value of the <code>SENSOR_TYPE_NIGHT</code> flag MUST be consistent with dashboard day/night mode and SHOULD be based on ambient light sensor input.
+      </li>
+      <li>The underlying ambient light sensor MAY be the same as <a href="#7_3_7_photometer">Photometer</a>.
+      </li>
+    </ul>
+    <p>
+      <strong>Driving Status (Section 7.3.11.3)</strong>
+    </p>
+    <p>
+      Automotive device implementations:
+    </p>
+    <ul>
+      <li>[A-0-1] MUST support driving status defined as <code>SENSOR_TYPE_DRIVING_STATUS</code>, with a default value of <code>DRIVE_STATUS_UNRESTRICTED</code> when the vehicle is fully stopped and parked. It is the responsibility of device manufacturers to configure <code>SENSOR_TYPE_DRIVING_STATUS</code> in compliance with all laws and regulations that apply to markets where the product is shipping.
+      </li>
+    </ul>
+    <p>
+      <strong>Wheel Speed (Section 7.3.11.4)</strong>
+    </p>
+    <p>
+      Automotive device implementations:
+    </p>
+    <ul>
+      <li>[A-0-1] MUST provide vehicle speed defined as <code>SENSOR_TYPE_CAR_SPEED</code>.
+      </li>
+    </ul>
+    <p>
+      <strong>Bluetooth (Section 7.4.3)</strong>
+    </p>
+    <p>
+      Automotive device implementations:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [A-0-1] MUST support Bluetooth and SHOULD support Bluetooth LE.
+        </p>
+      </li>
+      <li>
+        <p>
+          [A-0-2] Android Automotive implementations MUST support the following Bluetooth profiles:
+        </p>
+        <ul>
+          <li>Phone calling over Hands-Free Profile (HFP).
+          </li>
+          <li>Media playback over Audio Distribution Profile (A2DP).
+          </li>
+          <li>Media playback control over Remote Control Profile (AVRCP).
+          </li>
+          <li>Contact sharing using the Phone Book Access Profile (PBAP).
+          </li>
+        </ul>
+      </li>
+      <li>SHOULD support Message Access Profile (MAP).
+      </li>
+    </ul>
+    <p>
+      <strong>Minimum Network Capability (Section 7.4.5)</strong>
+    </p>
+    <p>
+      Automotive device implementations:
+    </p>
+    <ul>
+      <li>SHOULD include support for cellular network based data connectivity.
+      </li>
+    </ul>
+    <p>
+      <strong>Minimum Memory and Storage (Section 7.6.1)</strong>
+    </p>
+    <p>
+      Automotive device implementations:
+    </p>
+    <ul>
+      <li>[A-0-1] MUST have at least 4GB of non-volatile storage available for application private data (a.k.a. "/data" partition)
+      </li>
+    </ul>
+    <p>
+      <strong>USB peripheral mode (Section 7.7.1)</strong>
+    </p>
+    <p>
+      Automotive device implementations:
+    </p>
+    <ul>
+      <li>SHOULD include a USB port supporting peripheral mode.
+      </li>
+    </ul>
+    <p>
+      <strong>Microphone (Section 7.8.1)</strong>
+    </p>
+    <p>
+      Automotive device implementations:
+    </p>
+    <ul>
+      <li>[A-0-1] MUST include a microphone.
+      </li>
+    </ul>
+    <p>
+      <strong>Audio Output (Section 7.8.2)</strong>
+    </p>
+    <p>
+      Automotive device implementations:
+    </p>
+    <ul>
+      <li>[A-0-1] MUST have an audio output and declare <code>android.hardware.audio.output</code>.
+      </li>
+    </ul>
+    <h4 id="2_5_2_multimedia">
+      2.5.2. Multimedia
+    </h4>
+    <p>
+      <strong>Audio Encoding (Section 5.1)</strong>
+    </p>
+    <p>
+      Automotive device implementations MUST support the following audio encoding:
+    </p>
+    <ul>
+      <li>[A-1-1] MPEG-4 AAC Profile (AAC LC)
+      </li>
+      <li>[A-1-2] MPEG-4 HE AAC Profile (AAC+)
+      </li>
+      <li>[A-1-3] AAC ELD (enhanced low delay AAC)
+      </li>
+    </ul>
+    <p>
+      <strong>Video Encoding (Section 5.2)</strong>
+    </p>
+    <p>
+      Automotive device implementations MUST support the following video encoding:
+    </p>
+    <ul>
+      <li>[A-0-1] H.264 AVC
+      </li>
+      <li>[A-0-2] VP8
+      </li>
+    </ul>
+    <p>
+      <strong>Video Decoding (Section 5.3)</strong>
+    </p>
+    <p>
+      Automotive device implementations MUST support the following video decoding:
+    </p>
+    <ul>
+      <li>[A-0-1] H.264 AVC
+      </li>
+      <li>[A-0-2] MPEG-4 SP
+      </li>
+      <li>[A-0-3] VP8
+      </li>
+      <li>[A-0-4] VP9
+      </li>
+    </ul>
+    <p>
+      Automotive device implementations are STRONGLY RECOMMENDED to support the following video decoding:
+    </p>
+    <ul>
+      <li>[A-SR] H.265 HEVC
+      </li>
+    </ul>
+    <h4 id="2_5_3_software">
+      2.5.3. Software
+    </h4>
+    <p>
+      Automotive device implementations:
+    </p>
+    <ul>
+      <li>[A-0-1] MUST declare the feature android.hardware.type.automotive.
+      </li>
+      <li>[A-0-2] MUST support uiMode = <a href="http://developer.android.com/reference/android/content/res/Configuration.html#UI_MODE_TYPE_CAR">UI_MODE_TYPE_CAR</a>.
+      </li>
+      <li>[A-0-3] Android Automotive implementations MUST support all public APIs in the <code>android.car.*</code> namespace.
+      </li>
+    </ul>
+    <p>
+      <strong>WebView Compatibility (Section 3.4.1)</strong>
+    </p>
+    <p>
+      Automotive device implementations:
+    </p>
+    <ul>
+      <li>[A-0-1] MUST provide a complete implementation of the <code>android.webkit.Webview API</code>.
+      </li>
+    </ul>
+    <p>
+      <strong>Notifications (Section 3.8.3)</strong>
+    </p>
+    <p>
+      Android Automotive device implementations:
+    </p>
+    <ul>
+      <li>[A-0-1] MUST display notifications that use the <a href="https://developer.android.com/reference/android/app/Notification.CarExtender.html"><code>Notification.CarExtender</code></a> API when requested by third-party applications.
+      </li>
+    </ul>
+    <p>
+      <strong>Search (Section 3.8.4)</strong>
+    </p>
+    <p>
+      Automotive device implementations:
+    </p>
+    <ul>
+      <li>[A-0-1] MUST implement an assistant on the device to handle the <a href="http://developer.android.com/reference/android/content/Intent.html#ACTION_ASSIST">Assist action</a>.
+      </li>
+    </ul>
+    <p>
+      <strong>Media UI (Section 3.14)</strong>
+    </p>
+    <p>
+      Automotive device implementations:
+    </p>
+    <ul>
+      <li>[A-0-1] MUST include a UI framework to support third-party apps using the media APIs as described in section 3.14.
+      </li>
+    </ul>
+    <h4 id="2_5_4_performance_and_power">
+      2.5.4. Performance and Power
+    </h4>
+    <p>
+      <strong>Power-Saving Modes (Section 8.3)</strong>
+    </p>
+    <p>
+      For Automotive device implementations:
+    </p>
+    <ul>
+      <li>[A-0-1] All Apps exempted from App Standby and Doze power-saving modes MUST be made visible to the end user.
+      </li>
+      <li>[A-0-2] The triggering, maintenance, wakeup algorithms and the use of global system settings of App Standby and Doze power-saving modes MUST not deviate from the Android Open Source Project.
+      </li>
+    </ul>
+    <p>
+      <strong>Power Consumption Accounting (Sections 8.4)</strong>
+    </p>
+    <p>
+      Automotive device implementations:
+    </p>
+    <ul>
+      <li>[A-0-1] MUST provide a per-component power profile that defines the <a href="http://source.android.com/devices/tech/power/values.html">current consumption value</a> for each hardware component and the approximate battery drain caused by the components over time as documented in the Android Open Source Project site.
+      </li>
+      <li>[A-0-2] MUST report all power consumption values in milliampere hours (mAh).
+      </li>
+      <li>[A-0-3] MUST report CPU power consumption per each process's UID. The Android Open Source Project meets the requirement through the <code>uid_cputime</code> kernel module implementation.
+      </li>
+      <li>SHOULD be attributed to the hardware component itself if unable to attribute hardware component power usage to an application.
+      </li>
+      <li>[A-0-4] MUST make this power usage available via the <a href="http://source.android.com/devices/tech/power/batterystats.html"><code>adb shell dumpsys batterystats</code></a> shell command to the app developer.
+      </li>
+    </ul>
+    <h4 id="2_5_5_security_model">
+      2.5.5. Security Model
+    </h4>
+    <p>
+      <strong>Multi-User Support (Section 9.5)</strong>
+    </p>
+    <p>
+      If Automotive device implementations include multiple users, they:
+    </p>
+    <ul>
+      <li>[A-1-1] MUST include a guest account that allows all functions provided by the vehicle system without requiring a user to log in.
+      </li>
+    </ul>
+    <p>
+      <strong>Automotive Vehicle System Isolation (Section 9.14)</strong>
+    </p>
+    <p>
+      Automotive device implementations:
+    </p>
+    <ul>
+      <li>[A-0-1] MUST gatekeep messages from Android framework vehicle subsystems, e.g., whitelisting permitted message types and message sources.
+      </li>
+      <li>[A-0-2] MUST watchdog against denial of service attacks from the Android framework or third-party apps. This guards against malicious software flooding the vehicle network with traffic, which may lead to malfunctioning vehicle subsystems.
+      </li>
+    </ul>
+    <h3 id="2_6_tablet_requirements">
+      2.6. Tablet Requirements
+    </h3>
+    <p>
+      An <strong>Android Tablet device</strong> refers to an Android device implementation that is typically used by holding in both hands and not in a clamshell form-factor.
+    </p>
+    <p>
+      Android device implementations are classified as a Tablet if they meet all the following criteria:
+    </p>
+    <ul>
+      <li>Have a power source that provides mobility, such as a battery.
+      </li>
+      <li>Have a physical diagonal screen size in the range of 7 to 18 inches.
+      </li>
+    </ul>
+    <p>
+      Tablet device implementations have similar requirements to handheld device implementations. The exceptions are in indicated by and * in that section and noted for reference in this section.
+    </p>
+    <h4 id="2_6_1_hardware">
+      2.6.1. Hardware
+    </h4>
+    <p>
+      <strong>Screen Size (Section 7.1.1.1)</strong>
+    </p>
+    <p>
+      Tablet device implementations:
+    </p>
+    <ul>
+      <li>[Ta-0-1] MUST have a screen in the range of 7 to 18 inches.
+      </li>
+    </ul>
+    <p>
+      <strong>Minimum Memory and Storage (Section 7.6.1)</strong>
+    </p>
+    <p>
+      The screen densities listed for small/normal screens in the handheld requirements are not applicable to tablets.
+    </p>
+    <p>
+      <strong>USB peripheral mode (Section 7.7.1)</strong>
+    </p>
+    <p>
+      If handheld device implementations include a USB port supporting peripheral mode, they:
+    </p>
+    <ul>
+      <li>MAY implement the Android Open Accessory (AOA) API.
+      </li>
+    </ul>
+    <p>
+      <strong>Virtual Reality Mode (Section 7.9.1)</strong>
+    </p>
+    <p>
+      <strong>Virtual Reality High Performance (Section 7.9.2)</strong>
+    </p>
+    <p>
+      Virtual reality requirements are not applicable to tablets.
+    </p>
+    <h2 id="3_software">
+      3. Software
+    </h2>
+    <h3 id="3_1_managed_api_compatibility">
+      3.1. Managed API Compatibility
+    </h3>
+    <p>
+      The managed Dalvik bytecode execution environment is the primary vehicle for Android applications. The Android application programming interface (API) is the set of Android platform interfaces exposed to applications running in the managed runtime environment.
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-0-1] Device implementations MUST provide complete implementations, including all documented behaviors, of any documented API exposed by the <a href="http://developer.android.com/reference/packages.html">Android SDK</a> or any API decorated with the “@SystemApi” marker in the upstream Android source code.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-0-2] Device implementations MUST support/preserve all classes, methods, and associated elements marked by the TestApi annotation (@TestApi).
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-0-3] Device implementations MUST NOT omit any managed APIs, alter API interfaces or signatures, deviate from the documented behavior, or include no-ops, except where specifically allowed by this Compatibility Definition.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-0-4] Device implementations MUST still keep the APIs present and behave in a reasonable way, even when some hardware features for which Android includes APIs are omitted. See <a href="#7_hardware_compatibility">section 7</a> for specific requirements for this scenario.
+        </p>
+      </li>
+    </ul>
+    <h3 id="3_1_1_android_extensions">
+      3.1.1. Android Extensions
+    </h3>
+    <p>
+      Android includes the support of extending the managed APIs while keeping the same API level version.
+    </p>
+    <ul>
+      <li>[C-0-1] Android device implementations MUST preload the AOSP implementation of both the shared library <code>ExtShared</code> and services <code>ExtServices</code> with versions higher than or equal to the minimum versions allowed per each API level. For example, Android 7.0 device implementations, running API level 24 MUST include at least version 1.
+      </li>
+    </ul>
+    <h3 id="3_2_soft_api_compatibility">
+      3.2. Soft API Compatibility
+    </h3>
+    <p>
+      In addition to the managed APIs from <a href="#3_1_managed_api_compatibility">section 3.1</a>, Android also includes a significant runtime-only “soft” API, in the form of such things as intents, permissions, and similar aspects of Android applications that cannot be enforced at application compile time.
+    </p>
+    <h4 id="3_2_1_permissions">
+      3.2.1. Permissions
+    </h4>
+    <ul>
+      <li>[C-0-1] Device implementers MUST support and enforce all permission constants as documented by the <a href="http://developer.android.com/reference/android/Manifest.permission.html">Permission reference page</a>. Note that <a href="#9_security_model_compatibility">section 9</a> lists additional requirements related to the Android security model.
+      </li>
+    </ul>
+    <h4 id="3_2_2_build_parameters">
+      3.2.2. Build Parameters
+    </h4>
+    <p>
+      The Android APIs include a number of constants on the <a href="http://developer.android.com/reference/android/os/Build.html">android.os.Build class</a> that are intended to describe the current device.
+    </p>
+    <ul>
+      <li>[C-0-1] To provide consistent, meaningful values across device implementations, the table below includes additional restrictions on the formats of these values to which device implementations MUST conform.
+      </li>
+    </ul>
+    <table>
+      <tr>
+        <th>
+          Parameter
+        </th>
+        <th>
+          Details
+        </th>
+      </tr>
+      <tr>
+        <td>
+          VERSION.RELEASE
+        </td>
+        <td>
+          The version of the currently-executing Android system, in human-readable format. This field MUST have one of the string values defined in <a href="http://source.android.com/compatibility/8.0/versions.html">8.0</a>.
+        </td>
+      </tr>
+      <tr>
+        <td>
+          VERSION.SDK
+        </td>
+        <td>
+          The version of the currently-executing Android system, in a format accessible to third-party application code. For Android 8.0, this field MUST have the integer value 8.0_INT.
+        </td>
+      </tr>
+      <tr>
+        <td>
+          VERSION.SDK_INT
+        </td>
+        <td>
+          The version of the currently-executing Android system, in a format accessible to third-party application code. For Android 8.0, this field MUST have the integer value 8.0_INT.
+        </td>
+      </tr>
+      <tr>
+        <td>
+          VERSION.INCREMENTAL
+        </td>
+        <td>
+          A value chosen by the device implementer designating the specific build of the currently-executing Android system, in human-readable format. This value MUST NOT be reused for different builds made available to end users. A typical use of this field is to indicate which build number or source-control change identifier was used to generate the build. There are no requirements on the specific format of this field, except that it MUST NOT be null or the empty string ("").
+        </td>
+      </tr>
+      <tr>
+        <td>
+          BOARD
+        </td>
+        <td>
+          A value chosen by the device implementer identifying the specific internal hardware used by the device, in human-readable format. A possible use of this field is to indicate the specific revision of the board powering the device. The value of this field MUST be encodable as 7-bit ASCII and match the regular expression “^[a-zA-Z0-9_-]+$”.
+        </td>
+      </tr>
+      <tr>
+        <td>
+          BRAND
+        </td>
+        <td>
+          A value reflecting the brand name associated with the device as known to the end users. MUST be in human-readable format and SHOULD represent the manufacturer of the device or the company brand under which the device is marketed. The value of this field MUST be encodable as 7-bit ASCII and match the regular expression “^[a-zA-Z0-9_-]+$”.
+        </td>
+      </tr>
+      <tr>
+        <td>
+          SUPPORTED_ABIS
+        </td>
+        <td>
+          The name of the instruction set (CPU type + ABI convention) of native code. See <a href="#3_3_native_api_compatibility">section 3.3. Native API Compatibility</a>.
+        </td>
+      </tr>
+      <tr>
+        <td>
+          SUPPORTED_32_BIT_ABIS
+        </td>
+        <td>
+          The name of the instruction set (CPU type + ABI convention) of native code. See <a href="#3_3_native_api_compatibility">section 3.3. Native API Compatibility</a>.
+        </td>
+      </tr>
+      <tr>
+        <td>
+          SUPPORTED_64_BIT_ABIS
+        </td>
+        <td>
+          The name of the second instruction set (CPU type + ABI convention) of native code. See <a href="#3_3_native_api_compatibility">section 3.3. Native API Compatibility</a>.
+        </td>
+      </tr>
+      <tr>
+        <td>
+          CPU_ABI
+        </td>
+        <td>
+          The name of the instruction set (CPU type + ABI convention) of native code. See <a href="#3_3_native_api_compatibility">section 3.3. Native API Compatibility</a>.
+        </td>
+      </tr>
+      <tr>
+        <td>
+          CPU_ABI2
+        </td>
+        <td>
+          The name of the second instruction set (CPU type + ABI convention) of native code. See <a href="#3_3_native_api_compatibility">section 3.3. Native API Compatibility</a>.
+        </td>
+      </tr>
+      <tr>
+        <td>
+          DEVICE
+        </td>
+        <td>
+          A value chosen by the device implementer containing the development name or code name identifying the configuration of the hardware features and industrial design of the device. The value of this field MUST be encodable as 7-bit ASCII and match the regular expression “^[a-zA-Z0-9_-]+$”. This device name MUST NOT change during the lifetime of the product.
+        </td>
+      </tr>
+      <tr>
+        <td>
+          FINGERPRINT
+        </td>
+        <td>
+          A string that uniquely identifies this build. It SHOULD be reasonably human-readable. It MUST follow this template:
+          <p class="small">
+            $(BRAND)/$(PRODUCT)/<br />
+            &nbsp;&nbsp;&nbsp;&nbsp;$(DEVICE):$(VERSION.RELEASE)/$(ID)/$(VERSION.INCREMENTAL):$(TYPE)/$(TAGS)
+          </p>
+          <p>
+            For example:
+          </p>
+          <p class="small">
+            acme/myproduct/<br />
+            &nbsp;&nbsp;&nbsp;&nbsp;mydevice:8.0/LMYXX/3359:userdebug/test-keys
+          </p>
+          <p>
+            The fingerprint MUST NOT include whitespace characters. If other fields included in the template above have whitespace characters, they MUST be replaced in the build fingerprint with another character, such as the underscore ("_") character. The value of this field MUST be encodable as 7-bit ASCII.
+          </p>
+        </td>
+      </tr>
+      <tr>
+        <td>
+          HARDWARE
+        </td>
+        <td>
+          The name of the hardware (from the kernel command line or /proc). It SHOULD be reasonably human-readable. The value of this field MUST be encodable as 7-bit ASCII and match the regular expression “^[a-zA-Z0-9_-]+$”.
+        </td>
+      </tr>
+      <tr>
+        <td>
+          HOST
+        </td>
+        <td>
+          A string that uniquely identifies the host the build was built on, in human-readable format. There are no requirements on the specific format of this field, except that it MUST NOT be null or the empty string ("").
+        </td>
+      </tr>
+      <tr>
+        <td>
+          ID
+        </td>
+        <td>
+          An identifier chosen by the device implementer to refer to a specific release, in human-readable format. This field can be the same as android.os.Build.VERSION.INCREMENTAL, but SHOULD be a value sufficiently meaningful for end users to distinguish between software builds. The value of this field MUST be encodable as 7-bit ASCII and match the regular expression “^[a-zA-Z0-9._-]+$”.
+        </td>
+      </tr>
+      <tr>
+        <td>
+          MANUFACTURER
+        </td>
+        <td>
+          The trade name of the Original Equipment Manufacturer (OEM) of the product. There are no requirements on the specific format of this field, except that it MUST NOT be null or the empty string (""). This field MUST NOT change during the lifetime of the product.
+        </td>
+      </tr>
+      <tr>
+        <td>
+          MODEL
+        </td>
+        <td>
+          A value chosen by the device implementer containing the name of the device as known to the end user. This SHOULD be the same name under which the device is marketed and sold to end users. There are no requirements on the specific format of this field, except that it MUST NOT be null or the empty string (""). This field MUST NOT change during the lifetime of the product.
+        </td>
+      </tr>
+      <tr>
+        <td>
+          PRODUCT
+        </td>
+        <td>
+          A value chosen by the device implementer containing the development name or code name of the specific product (SKU) that MUST be unique within the same brand. MUST be human-readable, but is not necessarily intended for view by end users. The value of this field MUST be encodable as 7-bit ASCII and match the regular expression “^[a-zA-Z0-9_-]+$”. This product name MUST NOT change during the lifetime of the product.
+        </td>
+      </tr>
+      <tr>
+        <td>
+          SERIAL
+        </td>
+        <td>
+          A hardware serial number, which MUST be available and unique across devices with the same MODEL and MANUFACTURER. The value of this field MUST be encodable as 7-bit ASCII and match the regular expression “^([a-zA-Z0-9]{6,20})$”.
+        </td>
+      </tr>
+      <tr>
+        <td>
+          TAGS
+        </td>
+        <td>
+          A comma-separated list of tags chosen by the device implementer that further distinguishes the build. This field MUST have one of the values corresponding to the three typical Android platform signing configurations: release-keys, dev-keys, test-keys.
+        </td>
+      </tr>
+      <tr>
+        <td>
+          TIME
+        </td>
+        <td>
+          A value representing the timestamp of when the build occurred.
+        </td>
+      </tr>
+      <tr>
+        <td>
+          TYPE
+        </td>
+        <td>
+          A value chosen by the device implementer specifying the runtime configuration of the build. This field MUST have one of the values corresponding to the three typical Android runtime configurations: user, userdebug, or eng.
+        </td>
+      </tr>
+      <tr>
+        <td>
+          USER
+        </td>
+        <td>
+          A name or user ID of the user (or automated user) that generated the build. There are no requirements on the specific format of this field, except that it MUST NOT be null or the empty string ("").
+        </td>
+      </tr>
+      <tr>
+        <td>
+          SECURITY_PATCH
+        </td>
+        <td>
+          A value indicating the security patch level of a build. It MUST signify that the build is not in any way vulnerable to any of the issues described up through the designated Android Public Security Bulletin. It MUST be in the format [YYYY-MM-DD], matching a defined string documented in the <a href="source.android.com/security/bulletin">Android Public Security Bulletin</a> or in the <a href="http://source.android.com/security/advisory">Android Security Advisory</a>, for example "2015-11-01".
+        </td>
+      </tr>
+      <tr>
+        <td>
+          BASE_OS
+        </td>
+        <td>
+          A value representing the FINGERPRINT parameter of the build that is otherwise identical to this build except for the patches provided in the Android Public Security Bulletin. It MUST report the correct value and if such a build does not exist, report an empty string ("").
+        </td>
+      </tr>
+      <tr>
+        <td>
+          <a href="https://developer.android.com/reference/android/os/Build.html#BOOTLOADER">BOOTLOADER</a>
+        </td>
+        <td>
+          A value chosen by the device implementer identifying the specific internal bootloader version used in the device, in human-readable format. The value of this field MUST be encodable as 7-bit ASCII and match the regular expression “^[a-zA-Z0-9._-]+$”.
+        </td>
+      </tr>
+      <tr>
+        <td>
+          <a href="https://developer.android.com/reference/android/os/Build.html#getRadioVersion()">getRadioVersion()</a>
+        </td>
+        <td>
+          MUST (be or return) a value chosen by the device implementer identifying the specific internal radio/modem version used in the device, in human-readable format. If a device does not have any internal radio/modem it MUST return NULL. The value of this field MUST be encodable as 7-bit ASCII and match the regular expression “^[a-zA-Z0-9._-,]+$”.
+        </td>
+      </tr>
+    </table>
+    <h4 id="3_2_3_intent_compatibility">
+      3.2.3. Intent Compatibility
+    </h4>
+    <h5 id="3_2_3_1_core_application_intents">
+      3.2.3.1. Core Application Intents
+    </h5>
+    <p>
+      Android intents allow application components to request functionality from other Android components. The Android upstream project includes a list of applications considered core Android applications, which implements several intent patterns to perform common actions.
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-0-1] Device implementations MUST include these application, service components, or at least a handler, for all the public intent filter patterns defined by the following core Android applications in AOSP:
+        </p>
+        <ul>
+          <li>Desk Clock
+          </li>
+          <li>Browser
+          </li>
+          <li>Calendar
+          </li>
+          <li>Contacts
+          </li>
+          <li>Gallery
+          </li>
+          <li>GlobalSearch
+          </li>
+          <li>Launcher
+          </li>
+          <li>Music
+          </li>
+          <li>Settings
+          </li>
+        </ul>
+      </li>
+    </ul>
+    <h5 id="3_2_3_2_intent_resolution">
+      3.2.3.2. Intent Resolution
+    </h5>
+    <ul>
+      <li>[C-0-1] As Android is an extensible platform, device implementations MUST allow each intent pattern referenced in <a href="#3_2_3_1_core_application_intents">section 3.2.3.1</a> to be overridden by third-party applications. The upstream Android open source implementation allows this by default.
+      </li>
+      <li>
+        <p>
+          [C-0-2] Dvice implementers MUST NOT attach special privileges to system applications' use of these intent patterns, or prevent third-party applications from binding to and assuming control of these patterns. This prohibition specifically includes but is not limited to disabling the “Chooser” user interface that allows the user to select between multiple applications that all handle the same intent pattern.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-0-3] Device implementations MUST provide a user interface for users to modify the default activity for intents.
+        </p>
+      </li>
+      <li>
+        <p>
+          However, device implementations MAY provide default activities for specific URI patterns (e.g. http://play.google.com) when the default activity provides a more specific attribute for the data URI. For example, an intent filter pattern specifying the data URI “http://www.android.com” is more specific than the browser's core intent pattern for “http://”.
+        </p>
+      </li>
+    </ul>
+    <p>
+      Android also includes a mechanism for third-party apps to declare an authoritative default <a href="https://developer.android.com/training/app-links">app linking behavior</a> for certain types of web URI intents. When such authoritative declarations are defined in an app's intent filter patterns, device implementations:
+    </p>
+    <ul>
+      <li>[C-0-4] MUST attempt to validate any intent filters by performing the validation steps defined in the <a href="https://developers.google.com/digital-asset-links">Digital Asset Links specification</a> as implemented by the Package Manager in the upstream Android Open Source Project.
+      </li>
+      <li>[C-0-5] MUST attempt validation of the intent filters during the installation of the application and set all successfully validated UIR intent filters as default app handlers for their UIRs.
+      </li>
+      <li>MAY set specific URI intent filters as default app handlers for their URIs, if they are successfully verified but other candidate URI filters fail verification. If a device implementation does this, it MUST provide the user appropriate per-URI pattern overrides in the settings menu.
+      </li>
+      <li>MUST provide the user with per-app App Links controls in Settings as follows:
+        <ul>
+          <li>[C-0-6] The user MUST be able to override holistically the default app links behavior for an app to be: always open, always ask, or never open, which must apply to all candidate URI intent filters equally.
+          </li>
+          <li>[C-0-7] The user MUST be able to see a list of the candidate URI intent filters.
+          </li>
+          <li>The device implementation MAY provide the user with the ability to override specific candidate URI intent filters that were successfully verified, on a per-intent filter basis.
+          </li>
+          <li>[C-0-8] The device implementation MUST provide users with the ability to view and override specific candidate URI intent filters if the device implementation lets some candidate URI intent filters succeed verification while some others can fail.
+          </li>
+        </ul>
+      </li>
+    </ul>
+    <h5 id="3_2_3_3_intent_namespaces">
+      3.2.3.3. Intent Namespaces
+    </h5>
+    <ul>
+      <li>[C-0-1] Device implementations MUST NOT include any Android component that honors any new intent or broadcast intent patterns using an ACTION, CATEGORY, or other key string in the android. <em>or com.android.</em> namespace.
+      </li>
+      <li>[C-0-2] Device implementers MUST NOT include any Android components that honor any new intent or broadcast intent patterns using an ACTION, CATEGORY, or other key string in a package space belonging to another organization.
+      </li>
+      <li>[C-0-3] Device implementers MUST NOT alter or extend any of the intent patterns used by the core apps listed in <a href="#3_2_3_1_core_application_intents">section 3.2.3.1</a>.
+      </li>
+      <li>Device implementations MAY include intent patterns using namespaces clearly and obviously associated with their own organization. This prohibition is analogous to that specified for Java language classes in <a href="#3_6_api_namespaces">section 3.6</a>.
+      </li>
+    </ul>
+    <h5 id="3_2_3_4_broadcast_intents">
+      3.2.3.4. Broadcast Intents
+    </h5>
+    <p>
+      Third-party applications rely on the platform to broadcast certain intents to notify them of changes in the hardware or software environment.
+    </p>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST broadcast the public broadcast intents in response to appropriate system events as described in the SDK documentation. Note that this requirement is not conflicting with section 3.5 as the limitation for background applications are also described in the SDK documentation.
+      </li>
+    </ul>
+    <h5 id="3_2_3_5_default_app_settings">
+      3.2.3.5. Default App Settings
+    </h5>
+    <p>
+      Android includes settings that provide users an easy way to select their default applications, for example for Home screen or SMS.
+    </p>
+    <p>
+      Where it makes sense, device implementations MUST provide a similar settings menu and be compatible with the intent filter pattern and API methods described in the SDK documentation as below.
+    </p>
+    <p>
+      If device implementations report <code>android.software.home_screen</code>, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST honor the <a href="http://developer.android.com/reference/android/provider/Settings.html#ACTION_HOME_SETTINGS">android.settings.HOME_SETTINGS</a> intent to show a default app settings menu for Home Screen.
+      </li>
+    </ul>
+    <p>
+      If device implementations report <code>android.hardware.telephony</code>, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST provide a settings menu that will call the <a href="http://developer.android.com/reference/android/provider/Telephony.Sms.Intents.html">android.provider.Telephony.ACTION_CHANGE_DEFAULT</a> intent to show a dialog to change the default SMS application.
+      </li>
+    </ul>
+    <p>
+      If device implementations report <code>android.hardware.nfc.hce</code>, they:
+    </p>
+    <ul>
+      <li>[C-3-1] MUST honor the <a href="http://developer.android.com/reference/android/provider/Settings.html#ACTION_NFC_PAYMENT_SETTINGS">android.settings.NFC_PAYMENT_SETTINGS</a> intent to show a default app settings menu for Tap and Pay.
+      </li>
+    </ul>
+    <p>
+      If device implementations report <code>android.hardware.telephony</code>, they:
+    </p>
+    <ul>
+      <li>[C-4-1] MUST honor the <a href="https://developer.android.com/reference/android/telecom/TelecomManager.html#ACTION_CHANGE_DEFAULT_DIALER">android.telecom.action.CHANGE_DEFAULT_DIALER</a> intent to show a dialog to allow the user to change the default Phone application.
+      </li>
+    </ul>
+    <p>
+      If device implementations support the VoiceInteractionService, they:
+    </p>
+    <ul>
+      <li>[C-5-1] MUST honor the <a href="https://developer.android.com/reference/android/provider/Settings.html#ACTION_VOICE_INPUT_SETTINGS">android.settings.ACTION_VOICE_INPUT_SETTINGS</a> intent to show a default app settings menu for voice input and assist.
+      </li>
+    </ul>
+    <h4 id="3_2_4_activities_on_secondary_displays">
+      3.2.4. Activities on secondary displays
+    </h4>
+    <p>
+      If device implementations allow launching normal <a href="https://developer.android.com/reference/android/app/Activity.html">Android Activities</a> on secondary displays, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST set the <code>android.software.activities_on_secondary_displays</code> feature flag.
+      </li>
+      <li>[C-1-2] MUST guarantee API compatibility similar to an activity running on the primary display.
+      </li>
+      <li>[C-1-3] MUST land the new activity on the same display as the activity that launched it, when the new activity is launched without specifying a target display via the <a href="https://developer.android.com/reference/android/app/ActivityOptions.html#setLaunchDisplayId%28int%29"><code>ActivityOptions.setLaunchDisplayId()</code></a> API.
+      </li>
+      <li>[C-1-4] MUST destory all activities, when a display with the <a href="http://developer.android.com/reference/android/view/Display.html#FLAG_PRIVATE"><code>Display.FLAG_PRIVATE</code></a> flag is removed.
+      </li>
+      <li>[C-1-5] MUST resize accordingly all activities on a <a href="https://developer.android.com/reference/android/hardware/display/VirtualDisplay.html"><code>VirtualDisplay</code></a> if the display itself is resized.
+      </li>
+      <li>MAY show an IME (input method editor, a user control that enables users to enter text) on the primary display, when a text input field becomes focused on a secondary display.
+      </li>
+      <li>SHOULD implement the input focus on the secondary display independently of the primary display, when touch or key inputs are supported.
+      </li>
+      <li>SHOULD have <a href="https://developer.android.com/reference/android/content/res/Configuration.html"><code>android.content.res.Configuration</code></a> which corresponds to that display in order to be displayed, operate correctly, and maintain compatibility if an activity is launched on secondary display.
+      </li>
+    </ul>
+    <p>
+      If device implementations allow launching normal <a href="https://developer.android.com/reference/android/app/Activity.html">Android Activities</a> on secondary displays and primary and secondary displays have different <a href="https://developer.android.com/reference/android/util/DisplayMetrics.html">android.util.DisplayMetrics</a>:
+    </p>
+    <ul>
+      <li>[C-2-1] Non-resizeable activities (that have <code>resizeableActivity=false</code> in <code>AndroidManifest.xml</code>) and apps targeting API level 23 or lower MUST NOT be allowed on secondary displays.
+      </li>
+    </ul>
+    <p>
+      If device implementations allow launching normal <a href="https://developer.android.com/reference/android/app/Activity.html">Android Activities</a> on secondary displays and a secondary display has the <a href="https://developer.android.com/reference/android/view/Display.html#FLAG_PRIVATE">android.view.Display.FLAG_PRIVATE</a> flag:
+    </p>
+    <ul>
+      <li>[C-3-1] Only the owner of that display, system, and activities that are already on that display MUST be able to launch to it. Everyone can launch to a display that has <a href="https://developer.android.com/reference/android/view/Display.html#FLAG_PUBLIC">android.view.Display.FLAG_PUBLIC</a> flag.
+      </li>
+    </ul>
+    <h3 id="3_3_native_api_compatibility">
+      3.3. Native API Compatibility
+    </h3>
+    <p>
+      Device implementers are:
+    </p>
+    <p>
+      Native code compatibility is challenging. For this reason, device implementers are:
+    </p>
+    <ul>
+      <li>[SR] STRONGLY RECOMMENDED to use the implementations of the libraries listed below from the upstream Android Open Source Project.
+      </li>
+    </ul>
+    <h4 id="3_3_1_application_binary_interfaces">
+      3.3.1. Application Binary Interfaces
+    </h4>
+    <p>
+      Managed Dalvik bytecode can call into native code provided in the application <code>.apk</code> file as an ELF <code>.so</code> file compiled for the appropriate device hardware architecture. As native code is highly dependent on the underlying processor technology, Android defines a number of Application Binary Interfaces (ABIs) in the Android NDK.
+    </p>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST be compatible with one or more defined ABIs and implement compatibility with the Android NDK.
+      </li>
+      <li>[C-0-2] MUST include support for code running in the managed environment to call into native code, using the standard Java Native Interface (JNI) semantics.
+      </li>
+      <li>[C-0-3] MUST be source-compatible (i.e. header-compatible) and binary-compatible (for the ABI) with each required library in the list below.
+      </li>
+      <li>[C-0-4] MUST support the equivalent 32-bit ABI if any 64-bit ABI is supported.
+      </li>
+      <li>[C-0-5] MUST accurately report the native Application Binary Interface (ABI) supported by the device, via the <code>android.os.Build.SUPPORTED_ABIS</code>, <code>android.os.Build.SUPPORTED_32_BIT_ABIS</code>, and <code>android.os.Build.SUPPORTED_64_BIT_ABIS</code> parameters, each a comma separated list of ABIs ordered from the most to the least preferred one.
+      </li>
+      <li>[C-0-6] MUST report, via the above parameters, only those ABIs documented and described in the latest version of the <a href="https://developer.android.com/ndk/guides/abis.html">Android NDK ABI Management documentation</a>, and MUST include support for the <a href="http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0388f/Beijfcja.html">Advanced SIMD</a> (a.k.a. NEON) extension.
+      </li>
+      <li>
+        <p>
+          [C-0-7] MUST make all the following libraries, providing native APIs, available to apps that include native code:
+        </p>
+        <ul>
+          <li>libaaudio.so (AAudio native audio support)
+          </li>
+          <li>libandroid.so (native Android activity support)
+          </li>
+          <li>libc (C library)
+          </li>
+          <li>libcamera2ndk.so
+          </li>
+          <li>libdl (dynamic linker)
+          </li>
+          <li>libEGL.so (native OpenGL surface management)
+          </li>
+          <li>libGLESv1_CM.so (OpenGL ES 1.x)
+          </li>
+          <li>libGLESv2.so (OpenGL ES 2.0)
+          </li>
+          <li>libGLESv3.so (OpenGL ES 3.x)
+          </li>
+          <li>libicui18n.so
+          </li>
+          <li>libicuuc.so
+          </li>
+          <li>libjnigraphics.so
+          </li>
+          <li>liblog (Android logging)
+          </li>
+          <li>libmediandk.so (native media APIs support)
+          </li>
+          <li>libm (math library)
+          </li>
+          <li>libOpenMAXAL.so (OpenMAX AL 1.0.1 support)
+          </li>
+          <li>libOpenSLES.so (OpenSL ES 1.0.1 audio support)
+          </li>
+          <li>libRS.so
+          </li>
+          <li>libstdc++ (Minimal support for C++)
+          </li>
+          <li>libvulkan.so (Vulkan)
+          </li>
+          <li>libz (Zlib compression)
+          </li>
+          <li>JNI interface
+          </li>
+        </ul>
+      </li>
+      <li>
+        <p>
+          [C-0-8] MUST NOT add or remove the public functions for the native libraries listed above.
+        </p>
+      </li>
+      <li>[C-0-9] MUST list additional non-AOSP libraries exposed directly to third-party apps in <code>/vendor/etc/public.libraries.txt</code>.
+      </li>
+      <li>[C-0-10] MUST NOT expose any other native libraries, implemented and provided in AOSP as system libraries, to third-party apps targeting API level 24 or higher as they are reserved.
+      </li>
+      <li>[C-0-11] MUST export all the OpenGL ES 3.1 and <a href="http://developer.android.com/guide/topics/graphics/opengl.html#aep">Android Extension Pack</a> function symbols, as defined in the NDK, through the <code>libGLESv3.so</code> library. Note that while all the symbols MUST be present, section 7.1.4.1 describes in more detail the requirements for when the full implementation of each corresponding functions are expected.
+      </li>
+      <li>[C-0-12] MUST export function symbols for the core Vulkan 1.0 function symobls, as well as the <code>VK_KHR_surface</code>, <code>VK_KHR_android_surface</code>, <code>VK_KHR_swapchain</code>, <code>VK_KHR_maintenance1</code>, and <code>VK_KHR_get_physical_device_properties2</code> extensions through the <code>libvulkan.so</code> library. Note that while all the symbols MUST be present, section 7.1.4.2 describes in more detail the requirements for when the full implementation of each corresponding functions are expected.
+      </li>
+      <li>SHOULD be built using the source code and header files available in the upstream Android Open Source Project
+      </li>
+    </ul>
+    <p>
+      Note that future releases of the Android NDK may introduce support for additional ABIs.
+    </p>
+    <h4 id="3_3_2_32-bit_arm_native_code_compatibility">
+      3.3.2. 32-bit ARM Native Code Compatibility
+    </h4>
+    <p>
+      If device implementations are 64-bit ARM devices, then:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-1-1] Although the ARMv8 architecture deprecates several CPU operations, including some operations used in existing native code, the following deprecated operations MUST remain available to 32-bit native ARM code, either through native CPU support or through software emulation:
+        </p>
+        <ul>
+          <li>SWP and SWPB instructions
+          </li>
+          <li>SETEND instruction
+          </li>
+          <li>CP15ISB, CP15DSB, and CP15DMB barrier operations
+          </li>
+        </ul>
+      </li>
+    </ul>
+    <p>
+      If device implementations include a 32-bit ARM ABI, they:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-2-1] MUST include the following lines in <code>/proc/cpuinfo</code> when it is read by 32-bit ARM applications to ensure compatibility with applications built using legacy versions of Android NDK.
+        </p>
+        <ul>
+          <li>
+            <code>Features:</code>, followed by a list of any optional ARMv7 CPU features supported by the device.
+          </li>
+          <li>
+            <code>CPU architecture:</code>, followed by an integer describing the device's highest supported ARM architecture (e.g., "8" for ARMv8 devices).
+          </li>
+        </ul>
+      </li>
+      <li>
+        <p>
+          SHOULD not alter <code>/proc/cpuinfo</code> when read by 64-bit ARM or non-ARM applications.
+        </p>
+      </li>
+    </ul>
+    <h3 id="3_4_web_compatibility">
+      3.4. Web Compatibility
+    </h3>
+    <h4 id="3_4_1_webview_compatibility">
+      3.4.1. WebView Compatibility
+    </h4>
+    <p>
+      If device implementations provide a complete implementation of the <code>android.webkit.Webview</code> API, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST report <code>android.software.webview</code>.
+      </li>
+      <li>[C-1-2] MUST use the <a href="http://www.chromium.org/">Chromium</a> Project build from the upstream Android Open Source Project on the Android 8.0 branch for the implementation of the <a href="http://developer.android.com/reference/android/webkit/WebView.html"><code>android.webkit.WebView</code></a> API.
+      </li>
+      <li>
+        <p>
+          [C-1-3] The user agent string reported by the WebView MUST be in this format:
+        </p>
+        <p>
+          Mozilla/5.0 (Linux; Android $(VERSION); $(MODEL) Build/$(BUILD); wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 $(CHROMIUM_VER) Mobile Safari/537.36
+        </p>
+        <ul>
+          <li>The value of the $(VERSION) string MUST be the same as the value for android.os.Build.VERSION.RELEASE.
+          </li>
+          <li>The value of the $(MODEL) string MUST be the same as the value for android.os.Build.MODEL.
+          </li>
+          <li>The value of the $(BUILD) string MUST be the same as the value for android.os.Build.ID.
+          </li>
+          <li>The value of the $(CHROMIUM_VER) string MUST be the version of Chromium in the upstream Android Open Source Project.
+          </li>
+          <li>Device implementations MAY omit Mobile in the user agent string.
+          </li>
+        </ul>
+      </li>
+      <li>
+        <p>
+          The WebView component SHOULD include support for as many HTML5 features as possible and if it supports the feature SHOULD conform to the <a href="http://html.spec.whatwg.org/multipage/">HTML5 specification</a>.
+        </p>
+      </li>
+    </ul>
+    <h4 id="3_4_2_browser_compatibility">
+      3.4.2. Browser Compatibility
+    </h4>
+    <p>
+      If device implementations include a standalone Browser application for general web browsing, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support each of these APIs associated with HTML5:
+        <ul>
+          <li>
+            <a href="http://www.w3.org/html/wg/drafts/html/master/browsers.html#offline">application cache/offline operation</a>
+          </li>
+          <li>
+            <a href="http://www.w3.org/html/wg/drafts/html/master/semantics.html#video">&lt;video&gt; tag</a>
+          </li>
+          <li>
+            <a href="http://www.w3.org/TR/geolocation-API/">geolocation</a>
+          </li>
+        </ul>
+      </li>
+      <li>[C-1-2] MUST support the HTML5/W3C <a href="http://www.w3.org/TR/webstorage/">webstorage API</a> and SHOULD support the HTML5/W3C <a href="http://www.w3.org/TR/IndexedDB/">IndexedDB API</a>. Note that as the web development standards bodies are transitioning to favor IndexedDB over webstorage, IndexedDB is expected to become a required component in a future version of Android.
+      </li>
+      <li>MAY ship a custom user agent string in the standalone Browser application.
+      </li>
+      <li>SHOULD implement support for as much of <a href="http://html.spec.whatwg.org/multipage/">HTML5</a> as possible on the standalone Browser application (whether based on the upstream WebKit Browser application or a third-party replacement).
+      </li>
+    </ul>
+    <p>
+      However, If device implementations do not include a standalone Browser application, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST still support the public intent patterns as described in <a href="#3_2_3_1_core_application_intents">section 3.2.3.1</a>.
+      </li>
+    </ul>
+    <h3 id="3_5_api_behavioral_compatibility">
+      3.5. API Behavioral Compatibility
+    </h3>
+    <p>
+      The behaviors of each of the API types (managed, soft, native, and web) must be consistent with the preferred implementation of the upstream <a href="http://source.android.com/">Android Open Source Project</a>. Some specific areas of compatibility are:
+    </p>
+    <ul>
+      <li>[C-0-1] Devices MUST NOT change the behavior or semantics of a standard intent.
+      </li>
+      <li>[C-0-2] Devices MUST NOT alter the lifecycle or lifecycle semantics of a particular type of system component (such as Service, Activity, ContentProvider, etc.).
+      </li>
+      <li>[C-0-3] Devices MUST NOT change the semantics of a standard permission.
+      </li>
+      <li>Devices MUST NOT alter the limitations enforced on background applications. More specifically, for background apps:
+        <ul>
+          <li>[C-0-4] they MUST stop executing callbacks that are registered by the app to receive outputs from the <a href="https://developer.android.com/reference/android/location/GnssMeasurement.html"><code>GnssMeasurement</code></a> and <a href="https://developer.android.com/reference/android/location/GnssNavigationMessage.html"><code>GnssNavigationMessage</code></a>.
+          </li>
+          <li>[C-0-5] they MUST rate-limit the frequency of updates that are provided to the app through the <a href="https://developer.android.com/reference/android/location/LocationManager.html"><code>LocationManager</code></a> API class or the <a href="https://developer.android.com/reference/android/net/wifi/WifiManager.html#startScan%28%29"><code>WifiManager.startScan()</code></a> method.
+          </li>
+          <li>[C-0-6] if the app is targeting API level 25 or higher, they MUST NOT allow to register broadcast receivers for the implicit broadcasts of standard Android intents in the app's manifest, unless the broadcast intent requires a <code>"signature"</code> or <code>"signatureOrSystem"</code> <a href="https://developer.android.com/guide/topics/manifest/permission-element.html#plevel"><code>protectionLevel</code></a> permission or are on the <a href="https://developer.android.com/preview/features/background-broadcasts.html">exemption list</a> .
+          </li>
+          <li>[C-0-7] if the app is targeting API level 25 or higher, they MUST stop the app's background services, just as if the app had called the services'<a href="https://developer.android.com/reference/android/app/Service.html#stopSelf%28%29"><code>stopSelf()</code></a> method, unless the app is placed on a temporary whitelist to handle a task that's visible to the user.
+          </li>
+          <li>[C-0-8] if the app is targeting API level 25 or higher, they MUST release the wakelocks the app holds.
+          </li>
+        </ul>
+      </li>
+    </ul>
+    <p>
+      The above list is not comprehensive. The Compatibility Test Suite (CTS) tests significant portions of the platform for behavioral compatibility, but not all. It is the responsibility of the implementer to ensure behavioral compatibility with the Android Open Source Project. For this reason, device implementers SHOULD use the source code available via the Android Open Source Project where possible, rather than re-implement significant parts of the system.
+    </p>
+    <h3 id="3_6_api_namespaces">
+      3.6. API Namespaces
+    </h3>
+    <p>
+      Android follows the package and class namespace conventions defined by the Java programming language. To ensure compatibility with third-party applications, device implementers MUST NOT make any prohibited modifications (see below) to these package namespaces:
+    </p>
+    <ul>
+      <li>
+        <code>java.*</code>
+      </li>
+      <li>
+        <code>javax.*</code>
+      </li>
+      <li>
+        <code>sun.*</code>
+      </li>
+      <li>
+        <code>android.*</code>
+      </li>
+      <li>
+        <code>com.android.*</code>
+      </li>
+    </ul>
+    <p>
+      That is, they:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST NOT modify the publicly exposed APIs on the Android platform by changing any method or class signatures, or by removing classes or class fields.
+      </li>
+      <li>[C-0-2] MUST NOT add any publicly exposed elements (such as classes or interfaces, or fields or methods to existing classes or interfaces) or Test or System APIs to the APIs in the above namespaces. A “publicly exposed element” is any construct that is not decorated with the “@hide” marker as used in the upstream Android source code.
+      </li>
+    </ul>
+    <p>
+      Device implementers MAY modify the underlying implementation of the APIs, but such modifications:
+    </p>
+    <ul>
+      <li>[C-0-3] MUST NOT impact the stated behavior and Java-language signature of any publicly exposed APIs.
+      </li>
+      <li>[C-0-4] MUST NOT be advertised or otherwise exposed to developers.
+      </li>
+    </ul>
+    <p>
+      However, device implementers MAY add custom APIs outside the standard Android namespace, but the custom APIs:
+    </p>
+    <ul>
+      <li>[C-0-5] MUST NOT be in a namespace owned by or referring to another organization. For instance, device implementers MUST NOT add APIs to the <code>com.google.*</code> or similar namespace: only Google may do so. Similarly, Google MUST NOT add APIs to other companies' namespaces.
+      </li>
+      <li>[C-0-6] MUST be packaged in an Android shared library so that only apps that explicitly use them (via the &lt;uses-library&gt; mechanism) are affected by the increased memory usage of such APIs.
+      </li>
+    </ul>
+    <p>
+      If a device implementer proposes to improve one of the package namespaces above (such as by adding useful new functionality to an existing API, or adding a new API), the implementer SHOULD visit <a href="http://source.android.com/">source.android.com</a> and begin the process for contributing changes and code, according to the information on that site.
+    </p>
+    <p>
+      Note that the restrictions above correspond to standard conventions for naming APIs in the Java programming language; this section simply aims to reinforce those conventions and make them binding through inclusion in this Compatibility Definition.
+    </p>
+    <h3 id="3_7_runtime_compatibility">
+      3.7. Runtime Compatibility
+    </h3>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-0-1] MUST support the full Dalvik Executable (DEX) format and <a href="https://android.googlesource.com/platform/dalvik/">Dalvik bytecode specification and semantics</a>.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-0-2] MUST configure Dalvik runtimes to allocate memory in accordance with the upstream Android platform, and as specified by the following table. (See <a href="#7_1_1_screen_configuration">section 7.1.1</a> for screen size and screen density definitions.)
+        </p>
+      </li>
+      <li>
+        <p>
+          SHOULD use Android RunTime (ART), the reference upstream implementation of the Dalvik Executable Format, and the reference implementation’s package management system.
+        </p>
+      </li>
+      <li>
+        <p>
+          SHOULD run fuzz tests under various modes of execution and target architectures to assure the stability of the runtime. Refer to <a href="https://android.googlesource.com/platform/art/+/master/tools/dexfuzz/">JFuzz</a> and <a href="https://android.googlesource.com/platform/art/+/master/tools/dexfuzz/">DexFuzz</a> in the Android Open Source Project website.
+        </p>
+      </li>
+    </ul>
+    <p>
+      Note that memory values specified below are considered minimum values and device implementations MAY allocate more memory per application.
+    </p>
+    <table>
+      <tr>
+        <th>
+          Screen Layout
+        </th>
+        <th>
+          Screen Density
+        </th>
+        <th>
+          Minimum Application Memory
+        </th>
+      </tr>
+      <tr>
+        <td rowspan="12">
+          Android Watch
+        </td>
+        <td>
+          120 dpi (ldpi)
+        </td>
+        <td rowspan="3">
+          32MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          160 dpi (mdpi)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          213 dpi (tvdpi)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          240 dpi (hdpi)
+        </td>
+        <td rowspan="2">
+          36MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          280 dpi (280dpi)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          320 dpi (xhdpi)
+        </td>
+        <td rowspan="2">
+          48MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          360 dpi (360dpi)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          400 dpi (400dpi)
+        </td>
+        <td>
+          56MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          420 dpi (420dpi)
+        </td>
+        <td>
+          64MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          480 dpi (xxhdpi)
+        </td>
+        <td>
+          88MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          560 dpi (560dpi)
+        </td>
+        <td>
+          112MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          640 dpi (xxxhdpi)
+        </td>
+        <td>
+          154MB
+        </td>
+      </tr>
+      <tr>
+        <td rowspan="12">
+          small/normal
+        </td>
+        <td>
+          120 dpi (ldpi)
+        </td>
+        <td rowspan="2">
+          32MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          160 dpi (mdpi)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          213 dpi (tvdpi)
+        </td>
+        <td rowspan="3">
+          48MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          240 dpi (hdpi)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          280 dpi (280dpi)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          320 dpi (xhdpi)
+        </td>
+        <td rowspan="2">
+          80MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          360 dpi (360dpi)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          400 dpi (400dpi)
+        </td>
+        <td>
+          96MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          420 dpi (420dpi)
+        </td>
+        <td>
+          112MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          480 dpi (xxhdpi)
+        </td>
+        <td>
+          128MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          560 dpi (560dpi)
+        </td>
+        <td>
+          192MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          640 dpi (xxxhdpi)
+        </td>
+        <td>
+          256MB
+        </td>
+      </tr>
+      <tr>
+        <td rowspan="12">
+          large
+        </td>
+        <td>
+          120 dpi (ldpi)
+        </td>
+        <td>
+          32MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          160 dpi (mdpi)
+        </td>
+        <td>
+          48MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          213 dpi (tvdpi)
+        </td>
+        <td rowspan="2">
+          80MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          240 dpi (hdpi)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          280 dpi (280dpi)
+        </td>
+        <td>
+          96MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          320 dpi (xhdpi)
+        </td>
+        <td>
+          128MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          360 dpi (360dpi)
+        </td>
+        <td>
+          160MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          400 dpi (400dpi)
+        </td>
+        <td>
+          192MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          420 dpi (420dpi)
+        </td>
+        <td>
+          228MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          480 dpi (xxhdpi)
+        </td>
+        <td>
+          256MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          560 dpi (560dpi)
+        </td>
+        <td>
+          384MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          640 dpi (xxxhdpi)
+        </td>
+        <td>
+          512MB
+        </td>
+      </tr>
+      <tr>
+        <td rowspan="12">
+          xlarge
+        </td>
+        <td>
+          120 dpi (ldpi)
+        </td>
+        <td>
+          48MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          160 dpi (mdpi)
+        </td>
+        <td>
+          80MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          213 dpi (tvdpi)
+        </td>
+        <td rowspan="2">
+          96MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          240 dpi (hdpi)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          280 dpi (280dpi)
+        </td>
+        <td>
+          144MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          320 dpi (xhdpi)
+        </td>
+        <td>
+          192MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          360 dpi (360dpi)
+        </td>
+        <td>
+          240MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          400 dpi (400dpi)
+        </td>
+        <td>
+          288MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          420 dpi (420dpi)
+        </td>
+        <td>
+          336MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          480 dpi (xxhdpi)
+        </td>
+        <td>
+          384MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          560 dpi (560dpi)
+        </td>
+        <td>
+          576MB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          640 dpi (xxxhdpi)
+        </td>
+        <td>
+          768MB
+        </td>
+      </tr>
+    </table>
+    <h3 id="3_8_user_interface_compatibility">
+      3.8. User Interface Compatibility
+    </h3>
+    <h4 id="3_8_1_launcher_(home_screen)">
+      3.8.1. Launcher (Home Screen)
+    </h4>
+    <p>
+      Android includes a launcher application (home screen) and support for third-party applications to replace the device launcher (home screen).
+    </p>
+    <p>
+      If device implementations allow third-party applications to replace the device home screen, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST declare the platform feature <code>android.software.home_screen</code>.
+      </li>
+      <li>[C-1-2] MUST return the <a href="https://developer.android.com/reference/android/graphics/drawable/AdaptiveIconDrawable.html"><code>AdaptiveIconDrawable</code></a> object when the third party application use <code>&lt;adaptive-icon&gt;</code> tag to provide their icon, and the <a href="https://developer.android.com/reference/android/content/pm/PackageManager.html"><code>PackageManager</code></a> methods to retrieve icons are called.
+      </li>
+    </ul>
+    <p>
+      If device implementations include a default launcher that supports in-app pinning of shortcuts and widgets, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST report <code>true</code> for <a href="https://developer.android.com/reference/android/content/pm/ShortcutManager.html#isRequestPinShortcutSupported%28%29"><code>ShortcutManager.isRequestPinShortcutSupported()</code></a> and <a href="https://developer.android.com/reference/android/appwidget/AppWidgetManager.html#isRequestPinAppWidgetSupported%28%29"><code>AppWidgetManager.html.isRequestPinAppWidgetSupported()</code></a>.
+      </li>
+      <li>[C-2-2] MUST have user affordance asking the user before adding a shortcut requested by apps via the <a href="https://developer.android.com/reference/android/content/pm/ShortcutManager.html#requestPinShortcut%28android.content.pm.ShortcutInfo,%20android.content.IntentSender%29"><code>ShortcutManager.requestPinShortcut()</code></a> and the <a href="https://developer.android.com/reference/android/appwidget/AppWidgetManager.html#requestPinAppWidget%28android.content.ComponentName,android.os.Bundle,%20android.app.PendingIntent%29"><code>AppWidgetManager.requestPinAddWidget()</code></a> API method.
+      </li>
+    </ul>
+    <p>
+      Conversely, if device implementations do not support in-app pinning, they:
+    </p>
+    <ul>
+      <li>[C-3-1] MUST report <code>false</code> for <a href="https://developer.android.com/reference/android/content/pm/ShortcutManager.html#isRequestPinShortcutSupported%28%29"><code>ShortcutManager.isRequestPinShortcutSupported()</code></a> and <a href="https://developer.android.com/reference/android/appwidget/AppWidgetManager.html#isRequestPinAppWidgetSupported%28%29"><code>AppWidgetManager.html#isRequestPinAppWidgetSupported()</code></a>.
+      </li>
+    </ul>
+    <p>
+      If device implementations implement a default launcher that provides quick access to the additional shortcuts provided by third-party apps through the <a href="https://developer.android.com/reference/android/content/pm/ShortcutManager.html">ShortcutManager</a> API, they:
+    </p>
+    <ul>
+      <li>[C-4-1] MUST support all documented shortcut features (e.g. static and dynamic shortcuts, pinning shortcuts) and fully implement the APIs of the <a href="https://developer.android.com/reference/android/content/pm/ShortcutManager.html"><code>ShortcutManager</code></a> API class.
+      </li>
+    </ul>
+    <p>
+      If device implementations include a default launcher app that shows badges for the app icons, they:
+    </p>
+    <ul>
+      <li>[C-5-1] MUST respect the <a href="https://developer.android.com/reference/android/app/NotificationChannel.html#setShowBadge%28boolean%29"><code>NotificationChannel.setShowBadge()</code></a> API method. In other words, show a visual affordance associated with the app icon if the value is set as <code>true</code>, and do not show any app icon badging scheme when all of the app's notification channels have set the value as <code>false</code>.
+      </li>
+      <li>MAY override the app icon badges with their proprietary badging scheme when third-party applications indicate support of the proprietary badging scheme through the use of proprietary APIs, but SHOULD use the resources and values provided through the notification badges APIs described in <a href="https://developer.android.com/preview/features/notification-badges.html">the SDK</a> , such as the <a href="http://developer.android.com/reference/android/app/Notification.Builder.html#setNumber%28int%29"><code>Notification.Builder.setNumber()</code></a> and the <a href="http://developer.android.com/reference/android/app/Notification.Builder.html#setBadgeIconType%28int%29"><code>Notification.Builder.setBadgeIconType()</code></a> API.
+      </li>
+    </ul>
+    <h4 id="3_8_2_widgets">
+      3.8.2. Widgets
+    </h4>
+    <p>
+      Android supports third-party app widgets by defining a component type and corresponding API and lifecycle that allows applications to expose an <a href="http://developer.android.com/guide/practices/ui_guidelines/widget_design.html">“AppWidget”</a> to the end user.
+    </p>
+    <p>
+      If device implementations support third-party app widgets, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST declare support for platform feature android.software.app_widgets.
+      </li>
+      <li>[C-1-2] MUST include built-in support for AppWidgets and expose user interface affordances to add, configure, view, and remove AppWidgets directly within the Launcher.
+      </li>
+      <li>[C-1-3] MUST be capable of rendering widgets that are 4 x 4 in the standard grid size. See the <a href="http://developer.android.com/guide/practices/ui_guidelines/widget_design.html">App Widget Design Guidelines</a> in the Android SDK documentation for details.
+      </li>
+      <li>MAY support application widgets on the lock screen.
+      </li>
+    </ul>
+    <h4 id="3_8_3_notifications">
+      3.8.3. Notifications
+    </h4>
+    <p>
+      Android includes <a href="https://developer.android.com/reference/android/app/Notification.html"><code>Notification</code></a> and <a href="https://developer.android.com/reference/android/app/NotificationManager.html"><code>NotificationManager</code></a> APIs that allow third-party app developers to notify users of notable events and attract users' attention using the hardware components (e.g. sound, vibration and light) and software features (e.g. notification shade, system bar) of the device.
+    </p>
+    <h5 id="3_8_3_1_presentation_of_notifications">
+      3.8.3.1. Presentation of Notifications
+    </h5>
+    <p>
+      If device implementations allow third party apps to <a href="http://developer.android.com/guide/topics/ui/notifiers/notifications.html">notify users of notable events</a>, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support notifications that use hardware features, as described in the SDK documentation, and to the extent possible with the device implementation hardware. For instance, if a device implementation includes a vibrator, it MUST correctly implement the vibration APIs. If a device implementation lacks hardware, the corresponding APIs MUST be implemented as no-ops. This behavior is further detailed in <a href="#7_hardware_compatibility">section 7</a>.
+      </li>
+      <li>[C-1-2] MUST correctly render all <a href="https://developer.android.com/guide/topics/resources/available-resources.html">resources</a> (icons, animation files etc.) provided for in the APIs, or in the Status/System Bar <a href="http://developer.android.com/design/style/iconography.html">icon style guide</a>, although they MAY provide an alternative user experience for notifications than that provided by the reference Android Open Source implementation.
+      </li>
+      <li>[C-1-3] MUST honor and implement properly the behaviors described for <a href="https://developer.android.com/guide/topics/ui/notifiers/notifications.html#Managing">the APIs</a> to update, remove and group notifications.
+      </li>
+      <li>[C-1-4] MUST provide the full behavior of the <a href="https://developer.android.com/reference/android/app/NotificationChannel.html">NotificationChannel</a> API documented in the SDK.
+      </li>
+      <li>[C-1-5] MUST provide a user affordance to block and modify a certain third-party app's notification per each channel and app package level.
+      </li>
+      <li>[C-1-6] MUST also provide a user affordance to display deleted notification channels.
+      </li>
+      <li>SHOULD support rich notifications.
+      </li>
+      <li>SHOULD present some higher priority notifications as heads-up notifications.
+      </li>
+      <li>SHOULD have user affordance to snooze notifications.
+      </li>
+      <li>MAY only manage the visibility and timing of when third-party apps can notify users of notable events to mitigate safety issues such as driver distraction.
+      </li>
+    </ul>
+    <p>
+      If device implementations support rich notifications, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST use the exact resources as provided through the <a href="https://developer.android.com/reference/android/app/Notification.Style.html"><code>Notification.Style</code></a> API class and its subclasses for the presented resource elements.
+      </li>
+      <li>SHOULD present each and every resource element (e.g. icon, title and summary text) defined in the <a href="https://developer.android.com/reference/android/app/Notification.Style.html"><code>Notification.Style</code></a> API class and its subclasses.
+      </li>
+    </ul>
+    <p>
+      If device impelementations support heads-up notifications: they:
+    </p>
+    <ul>
+      <li>[C-3-1] MUST use the heads-up notification view and resources as described in the <a href="https://developer.android.com/reference/android/app/Notification.Builder.html"><code>Notification.Builder</code></a> API class when heads-up notifications are presented.
+      </li>
+    </ul>
+    <h5 id="3_8_3_2_notification_listener_service">
+      3.8.3.2. Notification Listener Service
+    </h5>
+    <p>
+      Android includes the <a href="https://developer.android.com/reference/android/service/notification/NotificationListenerService.html"><code>NotificationListenerService</code></a> APIs that allow apps (once explicitly enabled by the user) to receive a copy of all notifications as they are posted or updated.
+    </p>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST correctly and promptly update notifications in their entirety to all such installed and user-enabled listener services, including any and all metadata attached to the Notification object.
+      </li>
+      <li>[C-0-2] MUST respect the <a href="https://developer.android.com/reference/android/service/notification/NotificationListenerService.html#snoozeNotification%28java.lang.String,%20long%29"><code>snoozeNotification()</code></a> API call, and dismiss the notification and make a callback after the snooze duration that is set in the API call.
+      </li>
+    </ul>
+    <p>
+      If device implementations have a user affordance to snooze notifications, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST reflect the snoozed notification status properly through the standard APIs such as <a href="https://developer.android.com/reference/android/service/notification/NotificationListenerService.html#getSnoozedNotifications%28%29"><code>NotificationListenerService.getSnoozedNotifications()</code></a>.
+      </li>
+      <li>[C-1-2] MUST make this user affordance available to snooze notifications from each installed third-party app's, unless they are from persistent/foreground services.
+      </li>
+    </ul>
+    <h5 id="3_8_3_3_dnd_(do_not_disturb)">
+      3.8.3.3. DND (Do not Disturb)
+    </h5>
+    <p>
+      If device implementations support the DND feature, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST implement an activity that would respond to the intent <a href="https://developer.android.com/reference/android/provider/Settings.html#ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS">ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS</a>, which for implementations with UI_MODE_TYPE_NORMAL it MUST be an activity where the user can grant or deny the app access to DND policy configurations.
+      </li>
+      <li>[C-1-2] MUST, for when the device implementation has provided a means for the user to grant or deny third-party apps to access the DND policy configuration, display <a href="https://developer.android.com/reference/android/app/NotificationManager.html#addAutomaticZenRule%28android.app.AutomaticZenRule%29">Automatic DND rules</a> created by applications alongside the user-created and pre-defined rules.
+      </li>
+      <li>[C-1-3] MUST honor the <a href="https://developer.android.com/reference/android/app/NotificationManager.Policy.html#suppressedVisualEffects"><code>suppressedVisualEffects</code></a> values passed along the <a href="https://developer.android.com/reference/android/app/NotificationManager.Policy.html#NotificationManager.Policy%28int,%20int,%20int,%20int%29"><code>NotificationManager.Policy</code></a> and if an app has set any of the SUPPRESSED_EFFECT_SCREEN_OFF or SUPPRESSED_EFFECT_SCREEN_ON flags, it SHOULD indicate to the user that the visual effects are suppressed in the DND settings menu.
+      </li>
+    </ul>
+    <h4 id="3_8_4_search">
+      3.8.4. Search
+    </h4>
+    <p>
+      Android includes APIs that allow developers to <a href="http://developer.android.com/reference/android/app/SearchManager.html">incorporate search</a> into their applications and expose their application’s data into the global system search. Generally speaking, this functionality consists of a single, system-wide user interface that allows users to enter queries, displays suggestions as users type, and displays results. The Android APIs allow developers to reuse this interface to provide search within their own apps and allow developers to supply results to the common global search user interface.
+    </p>
+    <ul>
+      <li>Android device implementations SHOULD include global search, a single, shared, system-wide search user interface capable of real-time suggestions in response to user input.
+      </li>
+    </ul>
+    <p>
+      If device implementations implement the global search interface, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST implement the APIs that allow third-party applications to add suggestions to the search box when it is run in global search mode.
+      </li>
+    </ul>
+    <p>
+      If no third-party applications are installed that make use of the global search:
+    </p>
+    <ul>
+      <li>The default behavior SHOULD be to display web search engine results and suggestions.
+      </li>
+    </ul>
+    <p>
+      Android also includes the <a href="https://developer.android.com/reference/android/app/assist/package-summary.html">Assist APIs</a> to allow applications to elect how much information of the current context is shared with the assistant on the device.
+    </p>
+    <p>
+      If device implementations support the Assist action, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST indicate clearly to the end user when the context is shared, by either:
+        <ul>
+          <li>Each time the assist app accesses the context, displaying a white light around the edges of the screen that meet or exceed the duration and brightness of the Android Open Source Project implementation.
+          </li>
+          <li>For the preinstalled assist app, providing a user affordance less than two navigations away from <a href="#3_2_3_5_default_app_settings">the default voice input and assistant app settings menu</a>, and only sharing the context when the assist app is explicitly invoked by the user through a hotword or assist navigation key input.
+          </li>
+        </ul>
+      </li>
+      <li>[C-2-2] The designated interaction to launch the assist app as described in <a href="#7_2_3_navigation_keys">section 7.2.3</a> MUST launch the user-selected assist app, in other words the app that implements <code>VoiceInteractionService</code>, or an activity handling the <code>ACTION_ASSIST</code> intent.
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to use long press on <code>HOME</code> key as this designated interaction.
+      </li>
+    </ul>
+    <h4 id="3_8_5_alerts_and_toasts">
+      3.8.5. Alerts and Toasts
+    </h4>
+    <p>
+      Applications can use the <a href="http://developer.android.com/reference/android/widget/Toast.html"><code>Toast</code></a> API to display short non-modal strings to the end user that disappear after a brief period of time, and use the <a href="http://developer.android.com/reference/android/view/WindowManager.LayoutParams.html#TYPE_APPLICATION_OVERLAY"><code>TYPE_APPLICATION_OVERLAY</code></a> window type API to display alert windows as an overlay over other apps.
+    </p>
+    <p>
+      If device implementations include a screen or video output, they:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-1-1] MUST provide a user affordance to block an app from displaying alert windows that use the <a href="http://developer.android.com/reference/android/view/WindowManager.LayoutParams.html#TYPE_APPLICATION_OVERLAY"><code>TYPE_APPLICATION_OVERLAY</code></a> . The AOSP implementation meets this requirement by having controls in the notification shade.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-1-2] MUST honor the Toast API and display Toasts from applications to end users in some highly visible manner.
+        </p>
+      </li>
+    </ul>
+    <h4 id="3_8_6_themes">
+      3.8.6. Themes
+    </h4>
+    <p>
+      Android provides “themes” as a mechanism for applications to apply styles across an entire Activity or application.
+    </p>
+    <p>
+      Android includes a “Holo” and "Material" theme family as a set of defined styles for application developers to use if they want to match the <a href="http://developer.android.com/guide/topics/ui/themes.html">Holo theme look and feel</a> as defined by the Android SDK.
+    </p>
+    <p>
+      If device implementations include a screen or video output, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST NOT alter any of the <a href="http://developer.android.com/reference/android/R.style.html">Holo theme attributes</a> exposed to applications.
+      </li>
+      <li>[C-1-2] MUST support the “Material” theme family and MUST NOT alter any of the <a href="http://developer.android.com/reference/android/R.style.html#Theme_Material">Material theme attributes</a> or their assets exposed to applications.
+      </li>
+    </ul>
+    <p>
+      Android also includes a “Device Default” theme family as a set of defined styles for application developers to use if they want to match the look and feel of the device theme as defined by the device implementer.
+    </p>
+    <ul>
+      <li>Device implementations MAY modify the <a href="http://developer.android.com/reference/android/R.style.html">Device Default theme attributes</a> exposed to applications.
+      </li>
+    </ul>
+    <p>
+      Android supports a variant theme with translucent system bars, which allows application developers to fill the area behind the status and navigation bar with their app content. To enable a consistent developer experience in this configuration, it is important the status bar icon style is maintained across different device implementations.
+    </p>
+    <p>
+      If device implementations include a system status bar, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST use white for system status icons (such as signal strength and battery level) and notifications issued by the system, unless the icon is indicating a problematic status or an app requests a light status bar using the SYSTEM_UI_FLAG_LIGHT_STATUS_BAR flag.
+      </li>
+      <li>[C-2-2] Android device implementations MUST change the color of the system status icons to black (for details, refer to <a href="http://developer.android.com/reference/android/R.style.html">R.style</a>) when an app requests a light status bar.
+      </li>
+    </ul>
+    <h4 id="3_8_7_live_wallpapers">
+      3.8.7. Live Wallpapers
+    </h4>
+    <p>
+      Android defines a component type and corresponding API and lifecycle that allows applications to expose one or more <a href="http://developer.android.com/reference/android/service/wallpaper/WallpaperService.html">“Live Wallpapers”</a> to the end user. Live wallpapers are animations, patterns, or similar images with limited input capabilities that display as a wallpaper, behind other applications.
+    </p>
+    <p>
+      Hardware is considered capable of reliably running live wallpapers if it can run all live wallpapers, with no limitations on functionality, at a reasonable frame rate with no adverse effects on other applications. If limitations in the hardware cause wallpapers and/or applications to crash, malfunction, consume excessive CPU or battery power, or run at unacceptably low frame rates, the hardware is considered incapable of running live wallpaper. As an example, some live wallpapers may use an OpenGL 2.0 or 3.x context to render their content. Live wallpaper will not run reliably on hardware that does not support multiple OpenGL contexts because the live wallpaper use of an OpenGL context may conflict with other applications that also use an OpenGL context.
+    </p>
+    <ul>
+      <li>Device implementations capable of running live wallpapers reliably as described above SHOULD implement live wallpapers.
+      </li>
+    </ul>
+    <p>
+      If device implementations implement live wallpapers, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST report the platform feature flag android.software.live_wallpaper.
+      </li>
+    </ul>
+    <h4 id="3_8_8_activity_switching">
+      3.8.8. Activity Switching
+    </h4>
+    <p>
+      The upstream Android source code includes the <a href="https://developer.android.com/guide/components/activities/recents.html">overview screen</a>, a system-level user interface for task switching and displaying recently accessed activities and tasks using a thumbnail image of the application’s graphical state at the moment the user last left the application.
+    </p>
+    <p>
+      Device implementations including the recents function navigation key as detailed in <a href="#7_2_3_navigation_keys">section 7.2.3</a> MAY alter the interface.
+    </p>
+    <p>
+      If device implementations including the recents function navigation key as detailed in <a href="#7_2_3_navigation_keys">section 7.2.3</a> alter the interface, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support at least up to 20 displayed activities.
+      </li>
+      <li>SHOULD at least display the title of 4 activities at a time.
+      </li>
+      <li>[C-1-2] MUST implement the <a href="http://developer.android.com/about/versions/android-5.0.html#ScreenPinning">screen pinning behavior</a> and provide the user with a settings menu to toggle the feature.
+      </li>
+      <li>SHOULD display highlight color, icon, screen title in recents.
+      </li>
+      <li>SHOULD display a closing affordance ("x") but MAY delay this until user interacts with screens.
+      </li>
+      <li>SHOULD implement a shortcut to switch easily to the previous activity
+      </li>
+      <li>SHOULD trigger the fast-switch action between the two most recently used apps, when the recents function key is tapped twice.
+      </li>
+      <li>SHOULD trigger the split-screen multiwindow-mode, if supported, when the recents functions key is long pressed.
+      </li>
+      <li>
+        <p>
+          MAY display affiliated recents as a group that moves together.
+        </p>
+      </li>
+      <li>
+        <p>
+          [SR] Device implementations are STRONGLY RECOMMENDED to use the upstream Android user interface (or a similar thumbnail-based interface) for the overview screen.
+        </p>
+      </li>
+    </ul>
+    <h4 id="3_8_9_input_management">
+      3.8.9. Input Management
+    </h4>
+    <p>
+      Android includes support for <a href="http://developer.android.com/guide/topics/text/creating-input-method.html">Input Management</a> and support for third-party input method editors.
+    </p>
+    <p>
+      If device implementations allow users to use third-party input methods on the device, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST declare the platform feature android.software.input_methods and support IME APIs as defined in the Android SDK documentation.
+      </li>
+      <li>[C-1-2] MUST provide a user-accessible mechanism to add and configure third-party input methods in response to the android.settings.INPUT_METHOD_SETTINGS intent.
+      </li>
+    </ul>
+    <p>
+      If device implementations declare the <a href="https://developer.android.com/reference/android/content/pm/PackageManager.html#FEATURE_AUTOFILL"><code>android.software.autofill</code></a> feature flag, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST fully implement the <a href="https://developer.android.com/reference/android/service/autofill/AutofillService.html"><code>AutofillService</code></a> and <a href="https://developer.android.com/reference/android/view/autofill/AutofillManager.html"><code>AutofillManager</code></a> APIs and honor the <a href="https://developer.android.com/reference/android/provider/Settings.html#ACTION_REQUEST_SET_AUTOFILL_SERVICE"><code>android.settings.REQUEST_SET_AUTOFILL_SERVICE</code></a> intent to show a default app settings menu to enable and disable autofill and change the default autofill service for the user.
+      </li>
+    </ul>
+    <h4 id="3_8_10_lock_screen_media_control">
+      3.8.10. Lock Screen Media Control
+    </h4>
+    <p>
+      The Remote Control Client API is deprecated from Android 5.0 in favor of the <a href="http://developer.android.com/reference/android/app/Notification.MediaStyle.html">Media Notification Template</a> that allows media applications to integrate with playback controls that are displayed on the lock screen.
+    </p>
+    <h4 id="3_8_11_screen_savers_(previously_dreams)">
+      3.8.11. Screen savers (previously Dreams)
+    </h4>
+    <p>
+      Android includes support for <a href="http://developer.android.com/reference/android/service/dreams/DreamService.html">interactivescreensavers</a>, previously referred to as Dreams. Screen savers allow users to interact with applications when a device connected to a power source is idle or docked in a desk dock. Android Watch devices MAY implement screen savers, but other types of device implementations SHOULD include support for screen savers and provide a settings option for users toconfigure screen savers in response to the <code>android.settings.DREAM_SETTINGS</code> intent.
+    </p>
+    <h4 id="3_8_12_location">
+      3.8.12. Location
+    </h4>
+    <p>
+      If device implementations include a hardware sensor (e.g. GPS) that is capable of providing the location coordinates:
+    </p>
+    <ul>
+      <li>[C-1-1] <a href="http://developer.android.com/reference/android/provider/Settings.Secure.html#LOCATION_MODE">location modes</a> MUST be displayed in the Location menu within Settings.
+      </li>
+    </ul>
+    <h4 id="3_8_13_unicode_and_font">
+      3.8.13. Unicode and Font
+    </h4>
+    <p>
+      Android includes support for the emoji characters defined in <a href="http://www.unicode.org/versions/Unicode10.0.0/">Unicode 10.0</a>.
+    </p>
+    <p>
+      If device implementations include a screen or video output, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST be capable of rendering these emoji characters in color glyph.
+      </li>
+      <li>[C-1-2] MUST include support for:
+      </li>
+      <li>Roboto 2 font with different weights—sans-serif-thin, sans-serif-light, sans-serif-medium, sans-serif-black, sans-serif-condensed, sans-serif-condensed-light for the languages available on the device.
+      </li>
+      <li>Full Unicode 7.0 coverage of Latin, Greek, and Cyrillic, including the Latin Extended A, B, C, and D ranges, and all glyphs in the currency symbols block of Unicode 7.0.
+      </li>
+      <li>SHOULD support the skin tone and diverse family emojis as specified in the <a href="http://unicode.org/reports/tr51">Unicode Technical Report #51</a>.
+      </li>
+    </ul>
+    <p>
+      If device implementations include an IME, they:
+    </p>
+    <ul>
+      <li>SHOULD provide an input method to the user for these emoji characters.
+      </li>
+    </ul>
+    <h4 id="3_8_14_multi-windows">
+      3.8.14. Multi-windows
+    </h4>
+    <p>
+      If device implementations have the capability to display multiple activities at the same time, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST implement such multi-window mode(s) in accordance with the application behaviors and APIs described in the Android SDK <a href="https://developer.android.com/guide/topics/ui/multi-window.html">multi-window mode support documentation</a> and meet the following requirements:
+      </li>
+      <li>[C-1-2] Applications can indicate whether they are capable of operating in multi-window mode in the <code>AndroidManifest.xml</code> file, either explicitly via setting the <a href="https://developer.android.com/reference/android/R.attr.html#resizeableActivity"><code>android:resizeableActivity</code></a> attribute to <code>true</code> or implicitly by having the targetSdkVersion &gt; 24. Apps that explicitly set this attribute to <code>false</code> in their manifest MUST NOT be launched in multi-window mode. Older apps with targetSdkVersion &lt; 24 that did not set this <code>android:resizeableActivity</code> attribute MAY be launched in multi-window mode, but the system MUST provide warning that the app may not work as expected in multi-window mode.
+      </li>
+      <li>[C-1-3] MUST NOT offer split-screen or freeform mode if the screen height &lt; 440 dp and the screen width &lt; 440 dp.
+      </li>
+      <li>Device implementations with screen size <code>xlarge</code> SHOULD support freeform mode.
+      </li>
+    </ul>
+    <p>
+      If device implementations support multi-window mode(s), and the split screen mode, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST preload a <a href="https://developer.android.com/guide/topics/ui/multi-window.html#configuring">resizeable</a> launcher as the default.
+      </li>
+      <li>[C-2-2] MUST crop the docked activity of a split-screen multi-window but SHOULD show some content of it, if the Launcher app is the focused window.
+      </li>
+      <li>[C-2-3] MUST honor the declared <a href="https://developer.android.com/reference/android/R.styleable.html#AndroidManifestLayout_minWidth"><code>AndroidManifestLayout_minWidth</code></a> and <a href="https://developer.android.com/reference/android/R.styleable.html#AndroidManifestLayout_minHeight"><code>AndroidManifestLayout_minHeight</code></a> values of the third-party launcher application and not override these values in the course of showing some content of the docked activity.
+      </li>
+    </ul>
+    <p>
+      If device implementations support multi-window mode(s) and Picture-in-Picture multi-window mode, they:
+    </p>
+    <ul>
+      <li>[C-3-1] MUST launch activities in picture-in-picture multi-window mode when the app is: * Targeting API level 26 or higher and declares <a href="https://developer.android.com/reference/android/R.attr.html#supportsPictureInPicture"><code>android:supportsPictureInPicture</code></a> * Targeting API level 25 or lower and declares both <a href="https://developer.android.com/reference/android/R.attr.html#resizeableActivity"><code>android:resizeableActivity</code></a> and <a href="https://developer.android.com/reference/android/R.attr.html#supportsPictureInPicture"><code>android:supportsPictureInPicture</code></a>.
+      </li>
+      <li>[C-3-2] MUST expose the actions in their SystemUI as specified by the current PIP activity through the <a href="https://developer.android.com/reference/android/app/PictureInPictureParams.Builder.html#setActions%28java.util.List%3Candroid.app.RemoteAction%3E%29"><code>setActions()</code></a> API.
+      </li>
+      <li>[C-3-3] MUST support aspect ratios greater than or equal to 1:2.39 and less than or equal to 2.39:1, as specified by the PIP activity through the <a href="https://developer.android.com/reference/android/app/PictureInPictureParams.Builder.html#setAspectRatio%28android.util.Rational%29"><code>setAspectRatio()</code></a> API.
+      </li>
+      <li>[C-3-4] MUST use <a href="https://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_WINDOW"><code>KeyEvent.KEYCODE_WINDOW</code></a> to control the PIP window; if PIP mode is not implemented, the key MUST be available to the foreground activity.
+      </li>
+      <li>[C-3-5] MUST provide a user affordance to block an app from displaying in PIP mode; the AOSP implementation meets this requirement by having controls in the notification shade.
+      </li>
+      <li>[C-3-6] MUST allocate minimum width and height of 108 dp for the PIP window and minimum width of 240 dp and height of 135 dp for the PIP window when the <code>Configuration.uiMode</code> is configured as <a href="https://developer.android.com/reference/android/content/res/Configuration.html#UI_MODE_TYPE_TELEVISION"><code>UI_MODE_TYPE_TELEVISION</code></a>
+      </li>
+    </ul>
+    <h3 id="3_9_device_administration">
+      3.9. Device Administration
+    </h3>
+    <p>
+      Android includes features that allow security-aware applications to perform device administration functions at the system level, such as enforcing password policies or performing remote wipe, through the <a href="http://developer.android.com/guide/topics/admin/device-admin.html">Android Device Administration API</a>].
+    </p>
+    <p>
+      If device implementations implement the full range of <a href="http://developer.android.com/guide/topics/admin/device-admin.html">device administration</a> policies defined in the Android SDK documentation, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST declare <code>android.software.device_admin</code>.
+      </li>
+      <li>[C-1-2] MUST support device owner provisioning as described in <a href="#3_9_1_device_provisioning">section 3.9.1</a> and <a href="#3_9_1_1_device_owner_provisioning">section 3.9.1.1</a>.
+      </li>
+      <li>[C-1-3] MUST declare the support of manged profiles via the <code>android.software.managed_users</code> feature flag, except for when the device is configured so that it would <a href="http://developer.android.com/reference/android/app/ActivityManager.html#isLowRamDevice%28%29">report</a> itself as a low RAM device or so that it allocate internal (non-removable) storage as shared storage.
+      </li>
+    </ul>
+    <h4 id="3_9_1_device_provisioning">
+      3.9.1 Device Provisioning
+    </h4>
+    <h5 id="3_9_1_1_device_owner_provisioning">
+      3.9.1.1 Device owner provisioning
+    </h5>
+    <p>
+      If device implementations declare <code>android.software.device_admin</code>, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support enrolling a Device Policy Client (DPC) as a <a href="http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#isDeviceOwnerApp%28java.lang.String%29">Device Owner app</a> as described below:.
+        <ul>
+          <li>when the device implementation has no user data is configured yet, it:
+            <ul>
+              <li>[C-1-3] MUST report <code>true</code> for <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#isProvisioningAllowed(java.lang.String)"><code>DevicePolicyManager.isProvisioningAllowed(ACTION_PROVISION_MANAGED_DEVICE)</code></a>.
+              </li>
+              <li>[C-1-4] MUST enroll the DPC application as the Device Owner app in response to the intent action <a href="http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#ACTION_PROVISION_MANAGED_DEVICE"><code>android.app.action.PROVISION_MANAGED_DEVICE</code></a>.
+              </li>
+              <li>[C-1-5] MUST enroll the DPC application as the Device Owner app if the device declares Near-Field Communications (NFC) support via the feature flag <code>android.hardware.nfc</code> and receives an NFC message containing a record with MIME type <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#MIME_TYPE_PROVISIONING_NFC"><code>MIME_TYPE_PROVISIONING_NFC</code></a>.
+              </li>
+            </ul>
+          </li>
+          <li>When the device implementation has user data, it:
+            <ul>
+              <li>[C-1-6] MUST report <code>false</code> for the <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#isProvisioningAllowed(java.lang.String)"><code>DevicePolicyManager.isProvisioningAllowed(ACTION_PROVISION_MANAGED_DEVICE)</code></a>.
+              </li>
+              <li>[C-1-7] MUST not enroll any DPC application as the Device Owner App any more.
+              </li>
+            </ul>
+          </li>
+        </ul>
+      </li>
+      <li>[C-1-2] MUST NOT set an application (including pre-installed app) as the Device Owner app without explicit consent or action from the user or the administrator of the device.
+      </li>
+    </ul>
+    <p>
+      If device implementations declare <code>android.software.device_admin</code>, but also include a proprietary Device Owner management solution and provide a mechanism to promote an application configured in their solution as a "Device Owner equivalent" to the standard "Device Owner" as recognized by the standard Android <a href="http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html">DevicePolicyManager</a> APIs, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST have a process in place to verify that the specific app being promoted belongs to a legitimate enterprise device management solution and it has been already configured in the proprietary solution to have the rights equivalent as a "Device Owner".
+      </li>
+      <li>[C-2-2] MUST show the same AOSP Device Owner consent disclosure as the flow initiated by <a href="http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#ACTION_PROVISION_MANAGED_DEVICE"><code>android.app.action.PROVISION_MANAGED_DEVICE</code></a> prior to enrolling the DPC application as "Device Owner".
+      </li>
+      <li>MAY have user data on the device prior to enrolling the DPC application as "Device Owner".
+      </li>
+    </ul>
+    <h5 id="3_9_1_2_managed_profile_provisioning">
+      3.9.1.2 Managed profile provisioning
+    </h5>
+    <p>
+      If device implementations declare <code>android.software.managed_users</code>, they:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-1-1] MUST implement the <a href="http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#ACTION_PROVISION_MANAGED_PROFILE">APIs</a> allowing a Device Policy Controller (DPC) application to become the <a href="http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#isProfileOwnerApp%28java.lang.String%29">owner of a new Managed Profile</a>.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-1-2] The managed profile provisioning process (the flow initiated by <a href="http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#ACTION_PROVISION_MANAGED_PROFILE">android.app.action.PROVISION_MANAGED_PROFILE</a>) users experience MUST align with the AOSP implementation.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-1-3] MUST provide the following user affordances within the Settings to indicate to the user when a particular system function has been disabled by the Device Policy Controller (DPC):
+        </p>
+        <ul>
+          <li>A consistent icon or other user affordance (for example the upstream AOSP info icon) to represent when a particular setting is restricted by a Device Admin.
+          </li>
+          <li>A short explanation message, as provided by the Device Admin via the <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#setShortSupportMessage%28android.content.ComponentName,%20java.lang.CharSequence%29"><code>setShortSupportMessage</code></a>.
+          </li>
+          <li>The DPC application’s icon.
+          </li>
+        </ul>
+      </li>
+    </ul>
+    <h3 id="3_9_2_managed_profile_support">
+      3.9.2 Managed Profile Support
+    </h3>
+    <p>
+      If device implementations declare <code>android.software.managed_users</code>, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support managed profiles via the <code>android.app.admin.DevicePolicyManager</code> APIs.
+      </li>
+      <li>[C-1-2] MUST allow one and only <a href="http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#ACTION_PROVISION_MANAGED_PROFILE">one managed profile to be created</a>.
+      </li>
+      <li>[C-1-3] MUST use an icon badge (similar to the AOSP upstream work badge) to represent the managed applications and widgets and other badged UI elements like Recents &amp; Notifications.
+      </li>
+      <li>[C-1-4] MUST display a notification icon (similar to the AOSP upstream work badge) to indicate when user is within a managed profile application.
+      </li>
+      <li>[C-1-5] MUST display a toast indicating that the user is in the managed profile if and when the device wakes up (ACTION_USER_PRESENT) and the foreground application is within the managed profile.
+      </li>
+      <li>[C-1-6] Where a managed profile exists, MUST show a visual affordance in the Intent 'Chooser' to allow the user to forward the intent from the managed profile to the primary user or vice versa, if enabled by the Device Policy Controller.
+      </li>
+      <li>[C-1-7] Where a managed profile exists, MUST expose the following user affordances for both the primary user and the managed profile:
+        <ul>
+          <li>Separate accounting for battery, location, mobile data and storage usage for the primary user and managed profile.
+          </li>
+          <li>Independent management of VPN Applications installed within the primary user or managed profile.
+          </li>
+          <li>Independent management of applications installed within the primary user or managed profile.
+          </li>
+          <li>Independent management of accounts within the primary user or managed profile.
+          </li>
+        </ul>
+      </li>
+      <li>[C-1-8] MUST ensure the preinstalled dialer, contacts and messaging applications can search for and look up caller information from the managed profile (if one exists) alongside those from the primary profile, if the Device Policy Controller permits it.
+      </li>
+      <li>[C-1-9] MUST ensure that it satisfies all the security requirements applicable for a device with multiple users enabled (see<a href="#9_5_multi-user_support">section 9.5</a>), even though the managed profile is not counted as another user in addition to the primary user.
+      </li>
+      <li>[C-1-10] MUST support the ability to specify a separate lock screen meeting the following requirements to grant access to apps running in a managed profile.
+        <ul>
+          <li>Device implementations MUST honor the <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#ACTION_SET_NEW_PASSWORD"><code>DevicePolicyManager.ACTION_SET_NEW_PASSWORD</code></a> intent and show an interface to configure a separate lock screen credential for the managed profile.
+          </li>
+          <li>The lock screen credentials of the managed profile MUST use the same credential storage and management mechanisms as the parent profile, as documented on the <a href="http://source.android.com/security/authentication/index.html">Android Open Source Project Site</a>
+          </li>
+          <li>The DPC <a href="https://developer.android.com/guide/topics/admin/device-admin.html#pwd">password policies</a> MUST apply to only the managed profile's lock screen credentials unless called upon the <code>DevicePolicyManager</code> instance returned by <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#getParentProfileInstance%28android.content.ComponentName%29">getParentProfileInstance</a>.
+          </li>
+        </ul>
+      </li>
+      <li>When contacts from the managed profile are displayed in the preinstalled call log, in-call UI, in-progress and missed-call notifications, contacts and messaging apps they SHOULD be badged with the same badge used to indicate managed profile applications.
+      </li>
+    </ul>
+    <h3 id="3_10_accessibility">
+      3.10. Accessibility
+    </h3>
+    <p>
+      Android provides an accessibility layer that helps users with disabilities to navigate their devices more easily. In addition, Android provides platform APIs that enable accessibility service implementations to receive callbacks for user and system events and generate alternate feedback mechanisms, such as text-to-speech, haptic feedback, and trackball/d-pad navigation.
+    </p>
+    <p>
+      If device implementations support third-party accessibility services, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST provide an implementation of the Android accessibility framework as described in the <a href="http://developer.android.com/reference/android/view/accessibility/package-summary.html">accessibility APIs</a> SDK documentation.
+      </li>
+      <li>[C-1-2] MUST generate accessibility events and deliver the appropriate <code>AccessibilityEvent</code> to all registered <a href="http://developer.android.com/reference/android/accessibilityservice/AccessibilityService.html"><code>AccessibilityService</code></a> implementations as documented in the SDK.
+      </li>
+      <li>[C-1-3] MUST honor the <code>android.settings.ACCESSIBILITY_SETTINGS</code> intent to provide a user-accessible mechanism to enable and disable the third-party accessibility services alongside the preloaded accessibility services.
+      </li>
+      <li>[C-1-4] MUST add a button in the system's navigation bar allowing the user to control the accessibility service when the enabled accessibility services declare the <a href="https://developer.android.com/reference/android/accessibilityservice/AccessibilityServiceInfo.html#FLAG%5FREQUEST%5FACCESSIBILITY%5FBUTTON"><code>AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON</code></a> . Note that for device implementations with no system navigation bar, this requirement is not applicable, but device implementations SHOULD provide a user affordance to control these accessibility services.
+      </li>
+    </ul>
+    <p>
+      If device implementations include preloaded accessibility services, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST implement these preloaded accessibility services as [Direct Boot aware] (https://developer.android.com/reference/android/content/pm/ComponentInfo.html#directBootAware) apps when the data storage is encrypted with File Based Encryption (FBE).
+      </li>
+      <li>SHOULD provide a mechanism in the out-of-box setup flow for users to enable relevant accessibility services, as well as options to adjust the font size, display size and magnification gestures.
+      </li>
+    </ul>
+    <h3 id="3_11_text-to-speech">
+      3.11. Text-to-Speech
+    </h3>
+    <p>
+      Android includes APIs that allow applications to make use of text-to-speech (TTS) services and allows service providers to provide implementations of TTS services.
+    </p>
+    <p>
+      If device implementations reporting the feature android.hardware.audio.output, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support the <a href="http://developer.android.com/reference/android/speech/tts/package-summary.html">Android TTS framework</a> APIs.
+      </li>
+    </ul>
+    <p>
+      If device implementations support installation of third-party TTS engines, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST provide user affordance to allow the user to select a TTS engine for use at system level.
+      </li>
+    </ul>
+    <h3 id="3_12_tv_input_framework">
+      3.12. TV Input Framework
+    </h3>
+    <p>
+      The <a href="http://source.android.com/devices/tv/index.html">Android Television Input Framework (TIF)</a> simplifies the delivery of live content to Android Television devices. TIF provides a standard API to create input modules that control Android Television devices.
+    </p>
+    <p>
+      If device implementations support TIF, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST declare the platform feature <code>android.software.live_tv</code>.
+      </li>
+      <li>[C-1-2] MUST preload a TV application (TV App) and meet all requirements described in <a href="#3_12_tv-input-framework">section 3.12.1</a>.
+      </li>
+    </ul>
+    <h4 id="3_12_1_tv_app">
+      3.12.1. TV App
+    </h4>
+    <p>
+      If device implementations support TIF:
+    </p>
+    <ul>
+      <li>[C-1-1] The TV App MUST provide facilities to install and use <a href="http://developer.android.com/reference/android/media/tv/TvContract.Channels.html">TV Channels</a> and meet the following requirements:
+      </li>
+    </ul>
+    <p>
+      The TV app that is required for Android device implementations declaring the <code>android.software.live_tv</code> feature flag, MUST meet the following requirements:
+    </p>
+    <ul>
+      <li>Device implementations SHOULD allow third-party TIF-based inputs (<a href="https://source.android.com/devices/tv/index.html#third-party_input_example">third-party inputs</a>) to be installed and managed.
+      </li>
+      <li>Device implementations MAY provide visual separation between pre-installed <a href="https://source.android.com/devices/tv/index.html#tv_inputs">TIF-based inputs</a> (installed inputs) and third-party inputs.
+      </li>
+      <li>Device implementations SHOULD NOT display the third-party inputs more than a single navigation action away from the TV App (i.e. expanding a list of third-party inputs from the TV App).
+      </li>
+    </ul>
+    <p>
+      The Android Open Source Project provides an implementation of the TV App that meets the above requirements.
+    </p>
+    <h5 id="3_12_1_1_electronic_program_guide">
+      3.12.1.1. Electronic Program Guide
+    </h5>
+    <p>
+      If device implementations support TIF, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST show an informational and interactive overlay, which MUST include an electronic program guide (EPG) generated from the values in the <a href="https://developer.android.com/reference/android/media/tv/TvContract.Programs.html">TvContract.Programs</a> fields.
+      </li>
+      <li>[C-1-2] On channel change, device implementations MUST display EPG data for the currently playing program.
+      </li>
+      <li>[SR] The EPG is STRONGLY RECOMMENDED to display installed inputs and third-party inputs with equal prominence. The EPG SHOULD NOT display the third-party inputs more than a single navigation action away from the installed inputs on the EPG.
+      </li>
+      <li>The EPG SHOULD display information from all installed inputs and third-party inputs.
+      </li>
+      <li>The EPG MAY provide visual separation between the installed inputs and third-party inputs.
+      </li>
+    </ul>
+    <h5 id="3_12_1_2_navigation">
+      3.12.1.2. Navigation
+    </h5>
+    <p>
+      If device implementations support TIF, they:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-1-1] MUST allow navigation for the following functions via the D-pad, Back, and Home keys on the Android Television device’s input device(s) (i.e. remote control, remote control application, or game controller):
+        </p>
+        <ul>
+          <li>Changing TV channels
+          </li>
+          <li>Opening EPG
+          </li>
+          <li>Configuring and tuning to third-party TIF-based inputs
+          </li>
+          <li>Opening Settings menu
+          </li>
+        </ul>
+      </li>
+      <li>
+        <p>
+          SHOULD pass key events to HDMI inputs through CEC.
+        </p>
+      </li>
+    </ul>
+    <h5 id="3_12_1_3_tv_input_app_linking">
+      3.12.1.3. TV input app linking
+    </h5>
+    <p>
+      If device implementations support TIF, they:
+    </p>
+    <ul>
+      <li>[C-1-1] Android Television device implementations MUST support <a href="http://developer.android.com/reference/android/media/tv/TvContract.Channels.html#COLUMN_APP_LINK_INTENT_URI">TV input app linking</a>, which allows all inputs to provide activity links from the current activity to another activity (i.e. a link from live programming to related content).
+      </li>
+      <li>[C-1-2] The TV App MUST show TV input app linking when it is provided.
+      </li>
+    </ul>
+    <h5 id="3_12_1_4_time_shifting">
+      3.12.1.4. Time shifting
+    </h5>
+    <p>
+      If device implementations support TIF, they:
+    </p>
+    <ul>
+      <li>[SR] STRONGLY RECOMMENDED to support time shifting, which allows the user to pause and resume live content.
+      </li>
+      <li>SHOULD provide the user a way to pause and resume the currently playing program, if time shifting for that program <a href="https://developer.android.com/reference/android/media/tv/TvInputManager.html#TIME_SHIFT_STATUS_AVAILABLE">is available</a>.
+      </li>
+    </ul>
+    <h5 id="3_12_1_5_tv_recording">
+      3.12.1.5. TV recording
+    </h5>
+    <p>
+      If device implementations support TIF, they:
+    </p>
+    <ul>
+      <li>[SR] STRONGLY RECOMMENDED to support TV recording.
+      </li>
+      <li>
+        <p>
+          If the TV input supports recording and the recording of a program is not <a href="https://developer.android.com/reference/android/media/tv/TvContract.Programs.html#COLUMN_RECORDING_PROHIBITED">prohibited</a>, the EPG MAY provide a way to <a href="https://developer.android.com/reference/android/media/tv/TvInputInfo.html#canRecord%28%29">record a program</a>.
+        </p>
+      </li>
+      <li>
+        <p>
+          SHOULD provide a user interface to play recorded programs.
+        </p>
+      </li>
+    </ul>
+    <h3 id="3_13_quick_settings">
+      3.13. Quick Settings
+    </h3>
+    <p>
+      Android provides a Quick Settings UI component that allows quick access to frequently used or urgently needed actions.
+    </p>
+    <p>
+      If device implementations include a Quick Settings UI component, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST allow the user to add or remove the tiles provided through the <a href="https://developer.android.com/reference/android/service/quicksettings/package-summary.html"><code>quicksettings</code></a> APIs from a third-party app.
+      </li>
+      <li>[C-1-2] MUST NOT automatically add a tile from a third-party app directly to the Quick Settings.
+      </li>
+      <li>[C-1-3] MUST display all the user-added tiles from third-party apps alongside the system-provided quick setting tiles.
+      </li>
+    </ul>
+    <h3 id="3_14_media_ui">
+      3.14. Media UI
+    </h3>
+    <p>
+      If device implementations include the UI framework that supports third-party apps that depend on <a href="http://developer.android.com/reference/android/media/browse/MediaBrowser.html"><code>MediaBrowser</code></a> and <a href="http://developer.android.com/reference/android/media/session/MediaSession.html"><code>MediaSession</code></a> , they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST display <a href="http://developer.android.com/reference/android/media/browse/MediaBrowser.MediaItem.html">MediaItem</a> icons and notification icons unaltered.
+      </li>
+      <li>[C-1-2] MUST display those items as described by MediaSession, e.g., metadata, icons, imagery.
+      </li>
+      <li>[C-1-3] MUST show app title.
+      </li>
+      <li>[C-1-4] MUST have drawer to present <a href="http://developer.android.com/reference/android/media/browse/MediaBrowser.html">MediaBrowser</a> hierarchy.
+      </li>
+    </ul>
+    <h3 id="3_15_instant_apps">
+      3.15. Instant Apps
+    </h3>
+    <p>
+      Device implementations MUST satisfy the following requirements:
+    </p>
+    <ul>
+      <li>[C-0-1] Instant Apps MUST only be granted permissions that have the <a href="https://developer.android.com/guide/topics/manifest/permission-element.html#plevel"><code>android:protectionLevel</code></a> set to <code>"ephemeral"</code>.
+      </li>
+      <li>[C-0-2] Instant Apps MUST NOT interact with installed apps via <a href="https://developer.android.com/reference/android/content/Intent.html">implicit intents</a> unless one of the following is true:
+        <ul>
+          <li>The component's intent pattern filter is exposed and has CATEGORY_BROWSABLE
+          </li>
+          <li>The action is one of ACTION_SEND, ACTION_SENDTO, ACTION_SEND_MULTIPLE
+          </li>
+          <li>The target is explicitly exposed with <a href="https://developer.android.com/reference/android/R.attr.html#visibleToInstantApps">android:visibleToInstantApps</a>
+          </li>
+        </ul>
+      </li>
+      <li>[C-0-3] Instant Apps MUST NOT interact explicitly with installed apps unless the component is exposed via android:visibleToInstantApps.
+      </li>
+      <li>[C-0-4] IInstalled Apps MUST NOT see details about Instant Apps on the device unless the Instant App explicitly connects to the installed application.
+      </li>
+    </ul>
+    <h3 id="3_16_companion_device_pairing">
+      3.16. Companion Device Pairing
+    </h3>
+    <p>
+      Android includes support for companion device pairing to more effectively manage association with companion devices and provides the <a href="https://developer.android.com/reference/android/companion/CompanionDeviceManager.html"><code>CompanionDeviceManager</code></a> API for apps to access this feature.
+    </p>
+    <p>
+      If device implementations support the companion device pairing feature, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST declare the feature flag <a href="https://developer.android.com/reference/android/content/pm/PackageManager.html?#FEATURE_COMPANION_DEVICE_SETUP"><code>FEATURE_COMPANION_DEVICE_SETUP</code></a> .
+      </li>
+      <li>[C-1-2] MUST ensure the APIs in the <a href="https://developer.android.com/reference/android/companion/package-summary.html"><code>android.companion</code></a> package is fully implemented.
+      </li>
+      <li>[C-1-3] MUST provide user affordances for the user to select/confirm a companion device is present and operational.
+      </li>
+    </ul>
+    <h2 id="4_application_packaging_compatibility">
+      4. Application Packaging Compatibility
+    </h2>
+    <p>
+      Devices implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST be capable of installing and running Android “.apk” files as generated by the “aapt” tool included in the <a href="http://developer.android.com/tools/help/index.html">official Android SDK</a>.
+      </li>
+      <li>As the above requirement may be challenging, device implementations are RECOMMENDED to use the AOSP reference implementation's package management systemDevice implementations.
+      </li>
+      <li>[C-0-2] MUST support verifying “.apk” files using the <a href="https://source.android.com/security/apksigning/v2.html">APK Signature Scheme v2</a> and <a href="https://source.android.com/security/apksigning/v2.html#v1-verification">JAR signing</a>.
+      </li>
+      <li>[C-0-3] MUST NOT extend either the <a href="http://developer.android.com/guide/components/fundamentals.html">.apk</a>, <a href="http://developer.android.com/guide/topics/manifest/manifest-intro.html">Android Manifest</a>, <a href="https://android.googlesource.com/platform/dalvik/">Dalvik bytecode</a>, or RenderScript bytecode formats in such a way that would prevent those files from installing and running correctly on other compatible devices.
+      </li>
+      <li>[C-0-4] MUST NOT allow apps other than the current "installer of record" for the package to silently uninstall the app without any prompt, as documented in the SDK for the <a href="https://developer.android.com/reference/android/Manifest.permission.html#DELETE_PACKAGES"><code>DELETE_PACKAGE</code></a> permission. The only exceptions are the system package verifier app handling <a href="https://developer.android.com/reference/android/content/Intent.html#ACTION_PACKAGE_NEEDS_VERIFICATION">PACKAGE_NEEDS_VERIFICATION</a> intent and the storage manager app handling <a href="https://developer.android.com/reference/android/os/storage/StorageManager.html#ACTION_MANAGE_STORAGE">ACTION_MANAGE_STORAGE</a> intent.
+      </li>
+    </ul>
+    <p>
+      Device implementations MUST NOT install application packages from unknown sources, unless the app that <a href="https://developer.android.com/reference/android/content/Intent.html#ACTION_INSTALL_PACKAGE">requests the installation</a> meets all the following requirements:
+    </p>
+    <ul>
+      <li>It MUST declare the <a href="http://developer.android.com/reference/android/Manifest.permission.html#REQUEST_INSTALL_PACKAGES"><code>REQUEST_INSTALL_PACKAGES</code></a> permission or have the <code>android:targetSdkVersion</code> set at 24 or lower.
+      </li>
+      <li>It MUST have been granted permission by the user to install apps from unknown sources.
+      </li>
+    </ul>
+    <p>
+      Device implementations MUST have an activity that handles the <a href="http://developer.android.com/reference/android/provider/Settings.html#ACTION_MANAGE_UNKNOWN_APP_SOURCES"><code>android.settings.MANAGE_UNKNOWN_APP_SOURCES</code></a> intent. They SHOULD provide a user affordance to grant/revoke the permission to install apps from unknown sources per application, but MAY choose to implement this as a no-op and return <code>RESULT_CANCELED</code> for <a href="http://developer.android.com/reference/android/app/Activity.html#startActivityForResult%28android.content.Intent,%20int%29"><code>startActivityForResult()</code></a>, if the device implementation does not want to allow users to have this choice. However even in such cases, they SHOULD indicate to the user why there is no such choice presented.
+    </p>
+    <h2 id="5_multimedia_compatibility">
+      5. Multimedia Compatibility
+    </h2>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST support the media formats, encoders, decoders, file types, and container formats defined in <a href="#5_1_media-codecs.md">section 5.1</a> for each and every codec declared by <code>MediaCodecList</code>.
+      </li>
+      <li>[C-0-2] MUST declare and report support of the encoders, decoders available to third-party applications via <a href="http://developer.android.com/reference/android/media/MediaCodecList.html"><code>MediaCodecList</code></a>.
+      </li>
+      <li>[C-0-3] MUST be able to decode and make available to third-party apps all the formats it can encode. This includes all bitstreams that its encoders generate and the profiles reported in its <a href="http://developer.android.com/reference/android/media/CamcorderProfile.html"><code>CamcorderProfile</code></a>.
+      </li>
+    </ul>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>SHOULD aim for minimum codec latency, in others words, they
+        <ul>
+          <li>SHOULD NOT consume and store input buffers and return input buffers only once processed.
+          </li>
+          <li>SHOULD NOT hold onto decoded buffers for longer than as specified by the standard (e.g. SPS).
+          </li>
+          <li>SHOULD NOT hold onto encoded buffers longer than required by the GOP structure.
+          </li>
+        </ul>
+      </li>
+    </ul>
+    <p>
+      All of the codecs listed in the section below are provided as software implementations in the preferred Android implementation from the Android Open Source Project.
+    </p>
+    <p>
+      Please note that neither Google nor the Open Handset Alliance make any representation that these codecs are free from third-party patents. Those intending to use this source code in hardware or software products are advised that implementations of this code, including in open source software or shareware, may require patent licenses from the relevant patent holders.
+    </p>
+    <h3 id="5_1_media_codecs">
+      5.1. Media Codecs
+    </h3>
+    <h4 id="5_1_1_audio_encoding">
+      5.1.1. Audio Encoding
+    </h4>
+    <p>
+      See more details in <a href="#5_1_3_audio_codecs_details">5.1.3. Audio Codecs Details</a>.
+    </p>
+    <p>
+      If device implementations declare <code>android.hardware.microphone</code>, they MUST support the following audio encoding:
+    </p>
+    <ul>
+      <li>[C-1-1] PCM/WAVE
+      </li>
+    </ul>
+    <h4 id="5_1_2_audio_decoding">
+      5.1.2. Audio Decoding
+    </h4>
+    <p>
+      See more details in <a href="#5_1_3_audio_codecs_details">5.1.3. Audio Codecs Details</a>.
+    </p>
+    <p>
+      If device implementations declare support for the <code>android.hardware.audio.output</code> feature, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MPEG-4 AAC Profile (AAC LC)
+      </li>
+      <li>[C-1-2] MPEG-4 HE AAC Profile (AAC+)
+      </li>
+      <li>[C-1-3] MPEG-4 HE AACv2 Profile (enhanced AAC+)
+      </li>
+      <li>[C-1-4] AAC ELD (enhanced low delay AAC)
+      </li>
+      <li>[C-1-5] FLAC
+      </li>
+      <li>[C-1-6] MP3
+      </li>
+      <li>[C-1-7] MIDI
+      </li>
+      <li>[C-1-8] Vorbis
+      </li>
+      <li>[C-1-9] PCM/WAVE
+      </li>
+      <li>[C-1-10] Opus
+      </li>
+    </ul>
+    <p>
+      If device implementations support the decoding of AAC input buffers of multichannel streams (i.e. more than two channels) to PCM through the default AAC audio decoder in the <code>android.media.MediaCodec</code> API, the following MUST be supported:
+    </p>
+    <ul>
+      <li>[C-2-1] Decoding MUST be performed without downmixing (e.g. a 5.0 AAC stream must be decoded to five channels of PCM, a 5.1 AAC stream must be decoded to six channels of PCM).
+      </li>
+      <li>[C-2-2] Dynamic range metadata MUST be as defined in "Dynamic Range Control (DRC)" in ISO/IEC 14496-3, and the <code>android.media.MediaFormat</code> DRC keys to configure the dynamic range-related behaviors of the audio decoder. The AAC DRC keys were introduced in API 21,and are: KEY_AAC_DRC_ATTENUATION_FACTOR, KEY_AAC_DRC_BOOST_FACTOR, KEY_AAC_DRC_HEAVY_COMPRESSION, KEY_AAC_DRC_TARGET_REFERENCE_LEVEL and KEY_AAC_ENCODED_TARGET_LEVEL
+      </li>
+    </ul>
+    <h4 id="5_1_3_audio_codecs_details">
+      5.1.3. Audio Codecs Details
+    </h4>
+    <table>
+      <tr>
+        <th>
+          Format/Codec
+        </th>
+        <th>
+          Details
+        </th>
+        <th>
+          Supported File Types/Container Formats
+        </th>
+      </tr>
+      <tr>
+        <td>
+          MPEG-4 AAC Profile<br />
+          (AAC LC)
+        </td>
+        <td>
+          Support for mono/stereo/5.0/5.1 content with standard sampling rates from 8 to 48 kHz.
+        </td>
+        <td>
+          <ul>
+            <li class="table_list">3GPP (.3gp)
+            </li>
+            <li class="table_list">MPEG-4 (.mp4, .m4a)
+            </li>
+            <li class="table_list">ADTS raw AAC (.aac, ADIF not supported)
+            </li>
+            <li class="table_list">MPEG-TS (.ts, not seekable)
+            </li>
+          </ul>
+        </td>
+      </tr>
+      <tr>
+        <td>
+          MPEG-4 HE AAC Profile (AAC+)
+        </td>
+        <td>
+          Support for mono/stereo/5.0/5.1 content with standard sampling rates from 16 to 48 kHz.
+        </td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>
+          MPEG-4 HE AACv2<br />
+          Profile (enhanced AAC+)
+        </td>
+        <td>
+          Support for mono/stereo/5.0/5.1 content with standard sampling rates from 16 to 48 kHz.
+        </td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>
+          AAC ELD (enhanced low delay AAC)
+        </td>
+        <td>
+          Support for mono/stereo content with standard sampling rates from 16 to 48 kHz.
+        </td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>
+          AMR-NB
+        </td>
+        <td>
+          4.75 to 12.2 kbps sampled @ 8 kHz
+        </td>
+        <td>
+          3GPP (.3gp)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          AMR-WB
+        </td>
+        <td>
+          9 rates from 6.60 kbit/s to 23.85 kbit/s sampled @ 16 kHz
+        </td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>
+          FLAC
+        </td>
+        <td>
+          Mono/Stereo (no multichannel). Sample rates up to 48 kHz (but up to 44.1 kHz is RECOMMENDED on devices with 44.1 kHz output, as the 48 to 44.1 kHz downsampler does not include a low-pass filter). 16-bit RECOMMENDED; no dither applied for 24-bit.
+        </td>
+        <td>
+          FLAC (.flac) only
+        </td>
+      </tr>
+      <tr>
+        <td>
+          MP3
+        </td>
+        <td>
+          Mono/Stereo 8-320Kbps constant (CBR) or variable bitrate (VBR)
+        </td>
+        <td>
+          MP3 (.mp3)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          MIDI
+        </td>
+        <td>
+          MIDI Type 0 and 1. DLS Version 1 and 2. XMF and Mobile XMF. Support for ringtone formats RTTTL/RTX, OTA, and iMelody
+        </td>
+        <td>
+          <ul>
+            <li class="table_list">Type 0 and 1 (.mid, .xmf, .mxmf)
+            </li>
+            <li class="table_list">RTTTL/RTX (.rtttl, .rtx)
+            </li>
+            <li class="table_list">OTA (.ota)
+            </li>
+            <li class="table_list">iMelody (.imy)
+            </li>
+          </ul>
+        </td>
+      </tr>
+      <tr>
+        <td>
+          Vorbis
+        </td>
+        <td></td>
+        <td>
+          <ul>
+            <li class="table_list">Ogg (.ogg)
+            </li>
+            <li class="table_list">Matroska (.mkv, Android 4.0+)
+            </li>
+          </ul>
+        </td>
+      </tr>
+      <tr>
+        <td>
+          PCM/WAVE
+        </td>
+        <td>
+          16-bit linear PCM (rates up to limit of hardware). Devices MUST support sampling rates for raw PCM recording at 8000, 11025, 16000, and 44100 Hz frequencies.
+        </td>
+        <td>
+          WAVE (.wav)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          Opus
+        </td>
+        <td></td>
+        <td>
+          Matroska (.mkv), Ogg(.ogg)
+        </td>
+      </tr>
+    </table>
+    <h4 id="5_1_4_image_encoding">
+      5.1.4. Image Encoding
+    </h4>
+    <p>
+      See more details in <a href="#5_1_6_image_codecs_details">5.1.6. Image Codecs Details</a>.
+    </p>
+    <p>
+      Device implementations MUST support encoding the following image encoding:
+    </p>
+    <ul>
+      <li>[C-0-1] JPEG
+      </li>
+      <li>[C-0-2] PNG
+      </li>
+      <li>[C-0-3] WebP
+      </li>
+    </ul>
+    <h4 id="5_1_5_image_decoding">
+      5.1.5. Image Decoding
+    </h4>
+    <p>
+      See more details in <a href="#5_1_6_image_codecs_details">5.1.6. Image Codecs Details</a>.
+    </p>
+    <p>
+      Device impelementations MUST support encoding the following image decoding:
+    </p>
+    <ul>
+      <li>[C-0-1] JPEG
+      </li>
+      <li>[C-0-2] GIF
+      </li>
+      <li>[C-0-3] PNG
+      </li>
+      <li>[C-0-4] BMP
+      </li>
+      <li>[C-0-5] WebP
+      </li>
+      <li>[C-0-6] Raw
+      </li>
+    </ul>
+    <h4 id="5_1_6_image_codecs_details">
+      5.1.6. Image Codecs Details
+    </h4>
+    <table>
+      <tr>
+        <th>
+          Format/Codec
+        </th>
+        <th>
+          Details
+        </th>
+        <th>
+          Supported File Types/Container Formats
+        </th>
+      </tr>
+      <tr>
+        <td>
+          JPEG
+        </td>
+        <td>
+          Base+progressive
+        </td>
+        <td>
+          JPEG (.jpg)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          GIF
+        </td>
+        <td></td>
+        <td>
+          GIF (.gif)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          PNG
+        </td>
+        <td></td>
+        <td>
+          PNG (.png)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          BMP
+        </td>
+        <td></td>
+        <td>
+          BMP (.bmp)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          WebP
+        </td>
+        <td></td>
+        <td>
+          WebP (.webp)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          Raw
+        </td>
+        <td></td>
+        <td>
+          ARW (.arw), CR2 (.cr2), DNG (.dng), NEF (.nef), NRW (.nrw), ORF (.orf), PEF (.pef), RAF (.raf), RW2 (.rw2), SRW (.srw)
+        </td>
+      </tr>
+    </table>
+    <h4 id="5_1_7_video_codecs">
+      5.1.7. Video Codecs
+    </h4>
+    <ul>
+      <li>For acceptable quality of web video streaming and video-conference services, device implementations SHOULD use a hardware VP8 codec that meets the <a href="http://www.webmproject.org/hardware/rtc-coding-requirements/">requirements</a>.
+      </li>
+    </ul>
+    <p>
+      If device implementations include a video decoder or encoder:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-1-1] Video codecs MUST support output and input bytebuffer sizes that accommodate the largest feasible compressed and uncompressed frame as dictated by the standard and configuration but also not overallocate.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-1-2] Video encoders and decoders MUST support YUV420 flexible color format (COLOR_FormatYUV420Flexible).
+        </p>
+      </li>
+    </ul>
+    <p>
+      If device implementations advertise HDR profile support through <a href="https://developer.android.com/reference/android/view/Display.HdrCapabilities.html"><code>Display.HdrCapabilities</code></a>, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST support HDR static metadata parsing and handling.
+      </li>
+    </ul>
+    <p>
+      If device implementations advertise intra refresh support through <code>FEATURE_IntraRefresh</code> in the <a href="https://developer.android.com/reference/android/media/MediaCodecInfo.CodecCapabilities.html#FEATURE_IntraRefresh"><code>MediaCodecInfo.CodecCapabilities</code></a> class, they:
+    </p>
+    <ul>
+      <li>[C-3-1]MUST support the refresh periods in the range of 10 - 60 frames and accurately operate within 20% of configured refresh period.
+      </li>
+    </ul>
+    <h4 id="5_1_8_video_codecs_list">
+      5.1.8. Video Codecs List
+    </h4>
+    <table>
+      <tr>
+        <th>
+          Format/Codec
+        </th>
+        <th>
+          Details
+        </th>
+        <th>
+          Supported File Types/<br />
+          Container Formats
+        </th>
+      </tr>
+      <tr>
+        <td>
+          H.263
+        </td>
+        <td></td>
+        <td>
+          <ul>
+            <li class="table_list">3GPP (.3gp)
+            </li>
+            <li class="table_list">MPEG-4 (.mp4)
+            </li>
+          </ul>
+        </td>
+      </tr>
+      <tr>
+        <td>
+          H.264 AVC
+        </td>
+        <td>
+          See <a href="#5_2_video_encoding">section 5.2</a> and <a href="#5_3_video_decoding">5.3</a> for details
+        </td>
+        <td>
+          <ul>
+            <li class="table_list">3GPP (.3gp)
+            </li>
+            <li class="table_list">MPEG-4 (.mp4)
+            </li>
+            <li class="table_list">MPEG-2 TS (.ts, AAC audio only, not seekable, Android 3.0+)
+            </li>
+          </ul>
+        </td>
+      </tr>
+      <tr>
+        <td>
+          H.265 HEVC
+        </td>
+        <td>
+          See <a href="#5_3_video_decoding">section 5.3</a> for details
+        </td>
+        <td>
+          MPEG-4 (.mp4)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          MPEG-2
+        </td>
+        <td>
+          Main Profile
+        </td>
+        <td>
+          MPEG2-TS
+        </td>
+      </tr>
+      <tr>
+        <td>
+          MPEG-4 SP
+        </td>
+        <td></td>
+        <td>
+          3GPP (.3gp)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          VP8
+        </td>
+        <td>
+          See <a href="#5_2_video_encoding">section 5.2</a> and <a href="#5_3_video_decoding">5.3</a> for details
+        </td>
+        <td>
+          <ul>
+            <li class="table_list">
+              <a href="http://www.webmproject.org/">WebM (.webm)</a>
+            </li>
+            <li class="table_list">Matroska (.mkv)
+            </li>
+          </ul>
+        </td>
+      </tr>
+      <tr>
+        <td>
+          VP9
+        </td>
+        <td>
+          See <a href="#5_3_video_decoding">section 5.3</a> for details
+        </td>
+        <td>
+          <ul>
+            <li class="table_list">
+              <a href="http://www.webmproject.org/">WebM (.webm)</a>
+            </li>
+            <li class="table_list">Matroska (.mkv)
+            </li>
+          </ul>
+        </td>
+      </tr>
+    </table>
+    <h3 id="5_2_video_encoding">
+      5.2. Video Encoding
+    </h3>
+    <p>
+      If device implementations support any video encoder and make it available to third-party apps, they:
+    </p>
+    <ul>
+      <li>SHOULD NOT be, over two sliding windows, more than ~15% over the bitrate between intraframe (I-frame) intervals.
+      </li>
+      <li>SHOULD NOT be more than ~100% over the bitrate over a sliding window of 1 second.
+      </li>
+    </ul>
+    <p>
+      If device implementations include an embedded screen display with the diagonal length of at least 2.5 inches or include a video output port or declare the support of a camera via the <code>android.hardware.camera.any</code> feature flag, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST include the support of at least one of the VP8 or H.264 video encoders, and make it available for third-party applications.
+      </li>
+      <li>SHOULD support both VP8 and H.264 video encoders, and make it available for third-party applications.
+      </li>
+    </ul>
+    <p>
+      If device implementations support any of the H.264, VP8, VP9 or HEVC video encoders and make it available to third-party applications, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST support dynamically configurable bitrates.
+      </li>
+      <li>SHOULD support variable frame rates, where video encoder SHOULD determine instantaneous frame duration based on the timestamps of input buffers, and allocate its bit bucket based on that frame duration.
+      </li>
+    </ul>
+    <p>
+      If device implementations support the MPEG-4 SP video encoder and make it available to third-party apps, they:
+    </p>
+    <ul>
+      <li>SHOULD support dynamically configurable bitrates for the supported encoder.
+      </li>
+    </ul>
+    <h4 id="5_2_1_h_263">
+      5.2.1. H.263
+    </h4>
+    <p>
+      If device implementations support H.263 encoders and make it available to third-party apps, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support Baseline Profile Level 45.
+      </li>
+      <li>SHOULD support dynamically configurable bitrates for the supported encoder.
+      </li>
+    </ul>
+    <h4 id="5_2_2_h-264">
+      5.2.2. H-264
+    </h4>
+    <p>
+      If device implementations support H.264 codec, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support Baseline Profile Level 3. However, support for ASO (Arbitrary Slice Ordering), FMO (Flexible Macroblock Ordering) and RS (Redundant Slices) is OPTIONAL. Moreover, to maintain compatibility with other Android devices, it is RECOMMENDED that ASO, FMO and RS are not used for Baseline Profile by encoders.
+      </li>
+      <li>[C-1-2] MUST support the SD (Standard Definition) video encoding profiles in the following table.
+      </li>
+      <li>SHOULD support Main Profile Level 4.
+      </li>
+      <li>SHOULD support the HD (High Definition) video encoding profiles as indicated in the following table.
+      </li>
+    </ul>
+    <p>
+      If device implementations report support of H.264 encoding for 720p or 1080p resolution videos through the media APIs, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST support the encoding profiles in the following table.
+      </li>
+    </ul>
+    <table>
+      <tr>
+        <th></th>
+        <th>
+          SD (Low quality)
+        </th>
+        <th>
+          SD (High quality)
+        </th>
+        <th>
+          HD 720p
+        </th>
+        <th>
+          HD 1080p
+        </th>
+      </tr>
+      <tr>
+        <th>
+          Video resolution
+        </th>
+        <td>
+          320 x 240 px
+        </td>
+        <td>
+          720 x 480 px
+        </td>
+        <td>
+          1280 x 720 px
+        </td>
+        <td>
+          1920 x 1080 px
+        </td>
+      </tr>
+      <tr>
+        <th>
+          Video frame rate
+        </th>
+        <td>
+          20 fps
+        </td>
+        <td>
+          30 fps
+        </td>
+        <td>
+          30 fps
+        </td>
+        <td>
+          30 fps
+        </td>
+      </tr>
+      <tr>
+        <th>
+          Video bitrate
+        </th>
+        <td>
+          384 Kbps
+        </td>
+        <td>
+          2 Mbps
+        </td>
+        <td>
+          4 Mbps
+        </td>
+        <td>
+          10 Mbps
+        </td>
+      </tr>
+    </table>
+    <h4 id="5_2_3_vp8">
+      5.2.3. VP8
+    </h4>
+    <p>
+      If device implementations support VP8 codec, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support the SD video encoding profiles.
+      </li>
+      <li>SHOULD support the following HD (High Definition) video encoding profiles.
+      </li>
+      <li>SHOULD support writing Matroska WebM files.
+      </li>
+      <li>SHOULD use a hardware VP8 codec that meets the <a href="http://www.webmproject.org/hardware/rtc-coding-requirements">WebM project RTC hardware coding requirements</a>, to ensure acceptable quality of web video streaming and video-conference services.
+      </li>
+    </ul>
+    <p>
+      If device implementations report support of VP8 encoding for 720p or 1080p resolution videos through the media APIs, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST support the encoding profiles in the following table.
+      </li>
+    </ul>
+    <table>
+      <tr>
+        <th></th>
+        <th>
+          SD (Low quality)
+        </th>
+        <th>
+          SD (High quality)
+        </th>
+        <th>
+          HD 720p
+        </th>
+        <th>
+          HD 1080p
+        </th>
+      </tr>
+      <tr>
+        <th>
+          Video resolution
+        </th>
+        <td>
+          320 x 180 px
+        </td>
+        <td>
+          640 x 360 px
+        </td>
+        <td>
+          1280 x 720 px
+        </td>
+        <td>
+          1920 x 1080 px
+        </td>
+      </tr>
+      <tr>
+        <th>
+          Video frame rate
+        </th>
+        <td>
+          30 fps
+        </td>
+        <td>
+          30 fps
+        </td>
+        <td>
+          30 fps
+        </td>
+        <td>
+          30 fps
+        </td>
+      </tr>
+      <tr>
+        <th>
+          Video bitrate
+        </th>
+        <td>
+          800 Kbps
+        </td>
+        <td>
+          2 Mbps
+        </td>
+        <td>
+          4 Mbps
+        </td>
+        <td>
+          10 Mbps
+        </td>
+      </tr>
+    </table>
+    <h4 id="5_2_4_vp9">
+      5.2.4. VP9
+    </h4>
+    <p>
+      If device implementations support VP9 codec, they:
+    </p>
+    <ul>
+      <li>SHOULD support writing Matroska WebM files.
+      </li>
+    </ul>
+    <h3 id="5_3_video_decoding">
+      5.3. Video Decoding
+    </h3>
+    <p>
+      If device implementations support VP8, VP9, H.264, or H.265 codecs, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support dynamic video resolution and frame rate switching through the standard Android APIs within the same stream for all VP8, VP9, H.264, and H.265 codecs in real time and up to the maximum resolution supported by each codec on the device.
+      </li>
+    </ul>
+    <p>
+      If device implementations declare support for the Dolby Vision decoder through <a href="https://developer.android.com/reference/android/view/Display.HdrCapabilities.html#HDR_TYPE_DOLBY_VISION"><code>HDR_TYPE_DOLBY_VISION</code></a> , they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST provide a Dolby Vision-capable extractor.
+      </li>
+      <li>[C-2-2] MUST properly display Dolby Vision content on the device screen or on a standard video output port (e.g., HDMI).
+      </li>
+      <li>[C-2-3] MUST set the track index of backward-compatible base-layer(s) (if present) to be the same as the combined Dolby Vision layer's track index.
+      </li>
+    </ul>
+    <h4 id="5_3_1_mpeg-2">
+      5.3.1. MPEG-2
+    </h4>
+    <p>
+      If device implementations support MPEG-2 decoders, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support the Main Profile High Level.
+      </li>
+    </ul>
+    <h4 id="5_3_2_h_263">
+      5.3.2. H.263
+    </h4>
+    <p>
+      If device implementations support H.263 decoders, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support Baseline Profile Level 30 and Level 45.
+      </li>
+    </ul>
+    <h4 id="5_3_3_mpeg-4">
+      5.3.3. MPEG-4
+    </h4>
+    <p>
+      If device implementations with MPEG-4 decoders, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support Simple Profile Level 3.
+      </li>
+    </ul>
+    <h4 id="5_3_4_h_264">
+      5.3.4. H.264
+    </h4>
+    <p>
+      If device implementations support H.264 decoders, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support Main Profile Level 3.1 and Baseline Profile. Support for ASO (Arbitrary Slice Ordering), FMO (Flexible Macroblock Ordering) and RS (Redundant Slices) is OPTIONAL.
+      </li>
+      <li>[C-1-2] MUST be capable of decoding videos with the SD (Standard Definition) profiles listed in the following table and encoded with the Baseline Profile and Main Profile Level 3.1 (including 720p30).
+      </li>
+      <li>SHOULD be capable of decoding videos with the HD (High Definition) profiles as indicated in the following table.
+      </li>
+    </ul>
+    <p>
+      If the height that is reported by the <code>Display.getSupportedModes()</code> method is equal or greater than the video resolution, device implementations:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST support the HD 720p video encoding profiles in the following table.
+      </li>
+      <li>[C-2-2] MUST support the HD 1080p video encoding profiles in the following table.
+      </li>
+    </ul>
+    <table>
+      <tr>
+        <th></th>
+        <th>
+          SD (Low quality)
+        </th>
+        <th>
+          SD (High quality)
+        </th>
+        <th>
+          HD 720p
+        </th>
+        <th>
+          HD 1080p
+        </th>
+      </tr>
+      <tr>
+        <th>
+          Video resolution
+        </th>
+        <td>
+          320 x 240 px
+        </td>
+        <td>
+          720 x 480 px
+        </td>
+        <td>
+          1280 x 720 px
+        </td>
+        <td>
+          1920 x 1080 px
+        </td>
+      </tr>
+      <tr>
+        <th>
+          Video frame rate
+        </th>
+        <td>
+          30 fps
+        </td>
+        <td>
+          30 fps
+        </td>
+        <td>
+          60 fps
+        </td>
+        <td>
+          30 fps (60 fps<sup>Television</sup>)
+        </td>
+      </tr>
+      <tr>
+        <th>
+          Video bitrate
+        </th>
+        <td>
+          800 Kbps
+        </td>
+        <td>
+          2 Mbps
+        </td>
+        <td>
+          8 Mbps
+        </td>
+        <td>
+          20 Mbps
+        </td>
+      </tr>
+    </table>
+    <h4 id="5_3_5_h_265_(hevc)">
+      5.3.5. H.265 (HEVC)
+    </h4>
+    <p>
+      If device implementations support H.265 codec, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support the Main Profile Level 3 Main tier and the SD video decoding profiles as indicated in the following table.
+      </li>
+      <li>SHOULD support the HD decoding profiles as indicated in the following table.
+      </li>
+      <li>[C-1-2] MUST support the HD decoding profiles as indicated in the following table if there is a hardware decoder.
+      </li>
+    </ul>
+    <p>
+      If the height that is reported by the <code>Display.getSupportedModes()</code> method is equal to or greater than the video resolution, then:
+    </p>
+    <ul>
+      <li>[C-2-1] Device implementations MUST support at least one of H.265 or VP9 decoding of 720, 1080 and UHD profiles.
+      </li>
+    </ul>
+    <table>
+      <tr>
+        <th></th>
+        <th>
+          SD (Low quality)
+        </th>
+        <th>
+          SD (High quality)
+        </th>
+        <th>
+          HD 720p
+        </th>
+        <th>
+          HD 1080p
+        </th>
+        <th>
+          UHD
+        </th>
+      </tr>
+      <tr>
+        <th>
+          Video resolution
+        </th>
+        <td>
+          352 x 288 px
+        </td>
+        <td>
+          720 x 480 px
+        </td>
+        <td>
+          1280 x 720 px
+        </td>
+        <td>
+          1920 x 1080 px
+        </td>
+        <td>
+          3840 x 2160 px
+        </td>
+      </tr>
+      <tr>
+        <th>
+          Video frame rate
+        </th>
+        <td>
+          30 fps
+        </td>
+        <td>
+          30 fps
+        </td>
+        <td>
+          30 fps
+        </td>
+        <td>
+          30/60 fps (60 fps<sup>Television with H.265 hardware decoding</sup>)
+        </td>
+        <td>
+          60 fps
+        </td>
+      </tr>
+      <tr>
+        <th>
+          Video bitrate
+        </th>
+        <td>
+          600 Kbps
+        </td>
+        <td>
+          1.6 Mbps
+        </td>
+        <td>
+          4 Mbps
+        </td>
+        <td>
+          5 Mbps
+        </td>
+        <td>
+          20 Mbps
+        </td>
+      </tr>
+    </table>
+    <h4 id="5_3_6_vp8">
+      5.3.6. VP8
+    </h4>
+    <p>
+      If device implementations support VP8 codec, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support the SD decoding profiles in the following table.
+      </li>
+      <li>SHOULD use a hardware VP8 codec that meets the <a href="" title="http://www.webmproject.org/hardware/rtc-coding-requirements/">requirements</a>.
+      </li>
+      <li>SHOULD support the HD decoding profiles in the following table.
+      </li>
+    </ul>
+    <p>
+      If the height as reported by the <code>Display.getSupportedModes()</code> method is equal or greater than the video resolution, then:
+    </p>
+    <ul>
+      <li>[C-2-1] Device implementations MUST support 720p profiles in the following table.
+      </li>
+      <li>[C-2-2] Device implementations MUST support 1080p profiles in the following table.
+      </li>
+    </ul>
+    <table>
+      <tr>
+        <th></th>
+        <th>
+          SD (Low quality)
+        </th>
+        <th>
+          SD (High quality)
+        </th>
+        <th>
+          HD 720p
+        </th>
+        <th>
+          HD 1080p
+        </th>
+      </tr>
+      <tr>
+        <th>
+          Video resolution
+        </th>
+        <td>
+          320 x 180 px
+        </td>
+        <td>
+          640 x 360 px
+        </td>
+        <td>
+          1280 x 720 px
+        </td>
+        <td>
+          1920 x 1080 px
+        </td>
+      </tr>
+      <tr>
+        <th>
+          Video frame rate
+        </th>
+        <td>
+          30 fps
+        </td>
+        <td>
+          30 fps
+        </td>
+        <td>
+          30 fps (60 fps<sup>Television</sup>)
+        </td>
+        <td>
+          30 (60 fps<sup>Television</sup>)
+        </td>
+      </tr>
+      <tr>
+        <th>
+          Video bitrate
+        </th>
+        <td>
+          800 Kbps
+        </td>
+        <td>
+          2 Mbps
+        </td>
+        <td>
+          8 Mbps
+        </td>
+        <td>
+          20 Mbps
+        </td>
+      </tr>
+    </table>
+    <h4 id="5_3_7_vp9">
+      5.3.7. VP9
+    </h4>
+    <p>
+      If device implementations support VP9 codec, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support the SD video decoding profiles as indicated in the following table.
+      </li>
+      <li>SHOULD support the HD decoding profiles as indicated in the following table.
+      </li>
+    </ul>
+    <p>
+      If device implementations support VP9 codec and a hardware decoder:
+    </p>
+    <ul>
+      <li>[C-2-2] MUST support the HD decoding profiles as indicated in the following table.
+      </li>
+    </ul>
+    <p>
+      If the height that is reported by the <code>Display.getSupportedModes()</code> method is equal to or greater than the video resolution, then:
+    </p>
+    <ul>
+      <li>[C-3-1] Device implementations MUST support at least one of VP9 or H.265 decoding of the 720, 1080 and UHD profiles.
+      </li>
+    </ul>
+    <table>
+      <tr>
+        <th></th>
+        <th>
+          SD (Low quality)
+        </th>
+        <th>
+          SD (High quality)
+        </th>
+        <th>
+          HD 720p
+        </th>
+        <th>
+          HD 1080p
+        </th>
+        <th>
+          UHD
+        </th>
+      </tr>
+      <tr>
+        <th>
+          Video resolution
+        </th>
+        <td>
+          320 x 180 px
+        </td>
+        <td>
+          640 x 360 px
+        </td>
+        <td>
+          1280 x 720 px
+        </td>
+        <td>
+          1920 x 1080 px
+        </td>
+        <td>
+          3840 x 2160 px
+        </td>
+      </tr>
+      <tr>
+        <th>
+          Video frame rate
+        </th>
+        <td>
+          30 fps
+        </td>
+        <td>
+          30 fps
+        </td>
+        <td>
+          30 fps
+        </td>
+        <td>
+          30 fps (60 fps<sup>Television with VP9 hardware decoding</sup>)
+        </td>
+        <td>
+          60 fps
+        </td>
+      </tr>
+      <tr>
+        <th>
+          Video bitrate
+        </th>
+        <td>
+          600 Kbps
+        </td>
+        <td>
+          1.6 Mbps
+        </td>
+        <td>
+          4 Mbps
+        </td>
+        <td>
+          5 Mbps
+        </td>
+        <td>
+          20 Mbps
+        </td>
+      </tr>
+    </table>
+    <h3 id="5_4_audio_recording">
+      5.4. Audio Recording
+    </h3>
+    <p>
+      While some of the requirements outlined in this section are listed as SHOULD since Android 4.3, the Compatibility Definition for future versions are planned to change these to MUST. Existing and new Android devices are <strong>STRONGLY RECOMMENDED</strong> to meet these requirements that are listed as SHOULD, or they will not be able to attain Android compatibility when upgraded to the future version.
+    </p>
+    <h4 id="5_4_1_raw_audio_capture">
+      5.4.1. Raw Audio Capture
+    </h4>
+    <p>
+      If device implementations declare <code>android.hardware.microphone</code>, they:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-1-1] MUST allow capture of raw audio content with the following characteristics:
+        </p>
+      </li>
+      <li>
+        <p>
+          <strong>Format</strong>: Linear PCM, 16-bit
+        </p>
+      </li>
+      <li>
+        <strong>Sampling rates</strong>: 8000, 11025, 16000, 44100 Hz
+      </li>
+      <li>
+        <p>
+          <strong>Channels</strong>: Mono
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-1-2] MUST capture at above sample rates without up-sampling.
+        </p>
+      </li>
+      <li>[C-1-3] MUST include an appropriate anti-aliasing filter when the sample rates given above are captured with down-sampling.
+      </li>
+      <li>
+        <p>
+          SHOULD allow AM radio and DVD quality capture of raw audio content, which means the following characteristics:
+        </p>
+      </li>
+      <li>
+        <p>
+          <strong>Format</strong>: Linear PCM, 16-bit
+        </p>
+      </li>
+      <li>
+        <strong>Sampling rates</strong>: 22050, 48000 Hz
+      </li>
+      <li>
+        <strong>Channels</strong>: Stereo
+      </li>
+    </ul>
+    <p>
+      If device implementations allow AM radio and DVD quality capture of raw audio content, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST capture without up-sampling at any ratio higher than 16000:22050 or 44100:48000.
+      </li>
+      <li>[C-2-2] MUST include an appropriate anti-aliasing filter for any up-sampling or down-sampling.
+      </li>
+    </ul>
+    <h4 id="5_4_2_capture_for_voice_recognition">
+      5.4.2. Capture for Voice Recognition
+    </h4>
+    <p>
+      If device implementations declare <code>android.hardware.microphone</code>, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST capture <code>android.media.MediaRecorder.AudioSource.VOICE_RECOGNITION</code> audio source at one of the sampling rates, 44100 and 48000.
+      </li>
+      <li>[C-1-2] MUST, by default, disable any noise reduction audio processing when recording an audio stream from the <code>AudioSource.VOICE_RECOGNITION</code> audio source.
+      </li>
+      <li>[C-1-3] MUST, by default, disable any automatic gain control when recording an audio stream from the <code>AudioSource.VOICE_RECOGNITION</code> audio source.
+      </li>
+      <li>SHOULD record the voice recognition audio stream with approximately flat amplitude versus frequency characteristics: specifically, ±3 dB, from 100 Hz to 4000 Hz.
+      </li>
+      <li>SHOULD record the voice recognition audio stream with input sensitivity set such that a 90 dB sound power level (SPL) source at 1000 Hz yields RMS of 2500 for 16-bit samples.
+      </li>
+      <li>SHOULD record the voice recognition audio stream so that the PCM amplitude levels linearly track input SPL changes over at least a 30 dB range from -18 dB to +12 dB re 90 dB SPL at the microphone.
+      </li>
+      <li>SHOULD record the voice recognition audio stream with total harmonic distortion (THD) less than 1% for 1 kHz at 90 dB SPL input level at the microphone.
+      </li>
+    </ul>
+    <p>
+      If device impelementations declare <code>android.hardware.microphone</code> and noise suppression (reduction) technologies tuned for speech recognition, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST allow this audio affect to be controllable with the <code>android.media.audiofx.NoiseSuppressor</code> API.
+      </li>
+      <li>[C-2-2] MUST uniquely identfiy each noise suppression technology implementation via the <code>AudioEffect.Descriptor.uuid</code> field.
+      </li>
+    </ul>
+    <h4 id="5_4_3_capture_for_rerouting_of_playback">
+      5.4.3. Capture for Rerouting of Playback
+    </h4>
+    <p>
+      The <code>android.media.MediaRecorder.AudioSource</code> class includes the <code>REMOTE_SUBMIX</code> audio source.
+    </p>
+    <p>
+      If device implementations declare both <code>android.hardware.audio.output</code> and <code>android.hardware.microphone</code>, they:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-1-1] MUST properly implement the <code>REMOTE_SUBMIX</code> audio source so that when an application uses the <code>android.media.AudioRecord</code> API to record from this audio source, it captures a mix of all audio streams except for the following:
+        </p>
+        <ul>
+          <li>
+            <code>AudioManager.STREAM_RING</code>
+          </li>
+          <li>
+            <code>AudioManager.STREAM_ALARM</code>
+          </li>
+          <li>
+            <code>AudioManager.STREAM_NOTIFICATION</code>
+          </li>
+        </ul>
+      </li>
+    </ul>
+    <h3 id="5_5_audio_playback">
+      5.5. Audio Playback
+    </h3>
+    <p>
+      Android includes the support to allow apps to playback audio through the audio output peripheral as defined in section 7.8.2.
+    </p>
+    <h4 id="5_5_1_raw_audio_playback">
+      5.5.1. Raw Audio Playback
+    </h4>
+    <p>
+      If device implementations declare <code>android.hardware.audio.output</code>, they:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-1-1] MUST allow playback of raw audio content with the following characteristics:
+        </p>
+        <ul>
+          <li>
+            <strong>Format</strong>: Linear PCM, 16-bit
+          </li>
+          <li>
+            <strong>Sampling rates</strong>: 8000, 11025, 16000, 22050, 32000, 44100
+          </li>
+          <li>
+            <strong>Channels</strong>: Mono, Stereo
+          </li>
+        </ul>
+      </li>
+      <li>
+        <p>
+          SHOULD allow playback of raw audio content with the following characteristics:
+        </p>
+        <ul>
+          <li>
+            <strong>Sampling rates</strong>: 24000, 48000
+          </li>
+        </ul>
+      </li>
+    </ul>
+    <h4 id="5_5_2_audio_effects">
+      5.5.2. Audio Effects
+    </h4>
+    <p>
+      Android provides an <a href="http://developer.android.com/reference/android/media/audiofx/AudioEffect.html">API for audio effects</a> for device implementations.
+    </p>
+    <p>
+      If device implementations declare the feature <code>android.hardware.audio.output</code>, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support the <code>EFFECT_TYPE_EQUALIZER</code> and <code>EFFECT_TYPE_LOUDNESS_ENHANCER</code> implementations controllable through the AudioEffect subclasses <code>Equalizer</code>, <code>LoudnessEnhancer</code>.
+      </li>
+      <li>[C-1-2] MUST support the visualizer API implementation, controllable through the <code>Visualizer</code> class.
+      </li>
+      <li>SHOULD support the <code>EFFECT_TYPE_BASS_BOOST</code>, <code>EFFECT_TYPE_ENV_REVERB</code>, <code>EFFECT_TYPE_PRESET_REVERB</code>, and <code>EFFECT_TYPE_VIRTUALIZER</code> implementations controllable through the <code>AudioEffect</code> sub-classes <code>BassBoost</code>, <code>EnvironmentalReverb</code>, <code>PresetReverb</code>, and <code>Virtualizer</code>.
+      </li>
+    </ul>
+    <h4 id="5_5_3_audio_output_volume">
+      5.5.3. Audio Output Volume
+    </h4>
+    <p>
+      Automotive device implementations:
+    </p>
+    <ul>
+      <li>SHOULD allow adjusting audio volume separately per each audio stream using the content type or usage as defined by <a href="" title="http://developer.android.com/reference/android/media/AudioAttributes.html">AudioAttributes</a> and car audio usage as publicly defined in <code>android.car.CarAudioManager</code>.
+      </li>
+    </ul>
+    <h3 id="5_6_audio_latency">
+      5.6. Audio Latency
+    </h3>
+    <p>
+      Audio latency is the time delay as an audio signal passes through a system. Many classes of applications rely on short latencies, to achieve real-time sound effects.
+    </p>
+    <p>
+      For the purposes of this section, use the following definitions:
+    </p>
+    <ul>
+      <li>
+        <strong>output latency</strong>. The interval between when an application writes a frame of PCM-coded data and when the corresponding sound is presented to environment at an on-device transducer or signal leaves the device via a port and can be observed externally.
+      </li>
+      <li>
+        <strong>cold output latency</strong>. The output latency for the first frame, when the audio output system has been idle and powered down prior to the request.
+      </li>
+      <li>
+        <strong>continuous output latency</strong>. The output latency for subsequent frames, after the device is playing audio.
+      </li>
+      <li>
+        <strong>input latency</strong>. The interval between when a sound is presented by environment to device at an on-device transducer or signal enters the device via a port and when an application reads the corresponding frame of PCM-coded data.
+      </li>
+      <li>
+        <strong>lost input</strong>. The initial portion of an input signal that is unusable or unavailable.
+      </li>
+      <li>
+        <strong>cold input latency</strong>. The sum of lost input time and the input latency for the first frame, when the audio input system has been idle and powered down prior to the request.
+      </li>
+      <li>
+        <strong>continuous input latency</strong>. The input latency for subsequent frames, while the device is capturing audio.
+      </li>
+      <li>
+        <strong>cold output jitter</strong>. The variability among separate measurements of cold output latency values.
+      </li>
+      <li>
+        <strong>cold input jitter</strong>. The variability among separate measurements of cold input latency values.
+      </li>
+      <li>
+        <strong>continuous round-trip latency</strong>. The sum of continuous input latency plus continuous output latency plus one buffer period. The buffer period allows time for the app to process the signal and time for the app to mitigate phase difference between input and output streams.
+      </li>
+      <li>
+        <strong>OpenSL ES PCM buffer queue API</strong>. The set of PCM-related <a href="https://developer.android.com/ndk/guides/audio/opensl/index.html">OpenSL ES</a> APIs within <a href="https://developer.android.com/ndk/index.html">Android NDK</a>.
+      </li>
+      <li>
+        <strong>AAudio native audio API</strong>. The set of <a href="https://developer.android.com/ndk/guides/audio/aaudio/aaudio.html">AAudio</a> APIs within <a href="https://developer.android.com/ndk/index.html">Android NDK</a>.
+      </li>
+    </ul>
+    <p>
+      If device implementations declare <code>android.hardware.audio.output</code> they are STRONGLY RECOMMENDED to meet or exceed the following requirements:
+    </p>
+    <ul>
+      <li>[SR] Cold output latency of 100 milliseconds or less
+      </li>
+      <li>[SR] Continuous output latency of 45 milliseconds or less
+      </li>
+      <li>[SR] Minimize the cold output jitter
+      </li>
+    </ul>
+    <p>
+      If device implementations meet the above requirements after any initial calibration when using the OpenSL ES PCM buffer queue API, for continuous output latency and cold output latency over at least one supported audio output device, they are:
+    </p>
+    <ul>
+      <li>[SR] STRONGLY RECOMMENDED to report low latency audio by declaring <code>android.hardware.audio.low_latency</code> feature flag.
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to also meet the requirements for low-latency audio via the AAudio API.
+      </li>
+    </ul>
+    <p>
+      If device implementations do not meet the requirements for low-latency audio via the OpenSL ES PCM buffer queue API, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST NOT report support for low-latency audio.
+      </li>
+    </ul>
+    <p>
+      If device implementations include <code>android.hardware.microphone</code>, they are STRONGLY RECOMMENDED to meet these input audio requirements:
+    </p>
+    <ul>
+      <li>[SR] Cold input latency of 100 milliseconds or less
+      </li>
+      <li>[SR] Continuous input latency of 30 milliseconds or less
+      </li>
+      <li>[SR] Continuous round-trip latency of 50 milliseconds or less
+      </li>
+      <li>[SR] Minimize the cold input jitter
+      </li>
+    </ul>
+    <h3 id="5_7_network_protocols">
+      5.7. Network Protocols
+    </h3>
+    <p>
+      Device implementations MUST support the <a href="http://developer.android.com/guide/appendix/media-formats.html">media network protocols</a> for audio and video playback as specified in the Android SDK documentation.
+    </p>
+    <p>
+      If device implementations include an audio or a video decoder, they:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-1-1] MUST support all required codecs and container formats in <a href="#5_1_media_codecs">section 5.1</a> over HTTP(S).
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-1-2] MUST support the media segment formats shown in the Media Segmant Formats table below over <a href="http://tools.ietf.org/html/draft-pantos-http-live-streaming-07">HTTP Live Streaming draft protocol, Version 7</a>.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-1-3] MUST support the following RTP audio video profile and related codecs in the RTSP table below. For exceptions please see the table footnotes in <a href="#5_1_media_codecs">section 5.1</a>.
+        </p>
+      </li>
+    </ul>
+    <p>
+      Media Segment Formats
+    </p>
+    <table>
+      <tr>
+        <th>
+          Segment formats
+        </th>
+        <th>
+          Reference(s)
+        </th>
+        <th>
+          Required codec support
+        </th>
+      </tr>
+      <tr id="mp2t">
+        <td>
+          MPEG-2 Transport Stream
+        </td>
+        <td>
+          <a href="http://www.iso.org/iso/catalogue_detail?csnumber=44169">ISO 13818</a>
+        </td>
+        <td>
+          Video codecs:
+          <ul>
+            <li class="table_list">H264 AVC
+            </li>
+            <li class="table_list">MPEG-4 SP
+            </li>
+            <li class="table_list">MPEG-2
+            </li>
+          </ul>See <a href="#5_1_3_video_codecs">section 5.1.3</a> for details on H264 AVC, MPEG2-4 SP,<br />
+          and MPEG-2.
+          <p>
+            Audio codecs:
+          </p>
+          <ul>
+            <li class="table_list">AAC
+            </li>
+          </ul>See <a href="#5_1_1_audio_codecs">section 5.1.1</a> for details on AAC and its variants.
+        </td>
+      </tr>
+      <tr>
+        <td>
+          AAC with ADTS framing and ID3 tags
+        </td>
+        <td>
+          <a href="http://www.iso.org/iso/home/store/catalogue_tc/catalogue_detail.htm?csnumber=43345">ISO 13818-7</a>
+        </td>
+        <td>
+          See <a href="#5_1_1_audio_codecs">section 5.1.1</a> for details on AAC and its variants
+        </td>
+      </tr>
+      <tr>
+        <td>
+          WebVTT
+        </td>
+        <td>
+          <a href="http://dev.w3.org/html5/webvtt/">WebVTT</a>
+        </td>
+        <td></td>
+      </tr>
+    </table>
+    <p>
+      RTSP (RTP, SDP)
+    </p>
+    <table>
+      <tr>
+        <th>
+          Profile name
+        </th>
+        <th>
+          Reference(s)
+        </th>
+        <th>
+          Required codec support
+        </th>
+      </tr>
+      <tr>
+        <td>
+          H264 AVC
+        </td>
+        <td>
+          <a href="https://tools.ietf.org/html/rfc6184">RFC 6184</a>
+        </td>
+        <td>
+          See <a href="#5_1_3_video_codecs">section 5.1.3</a> for details on H264 AVC
+        </td>
+      </tr>
+      <tr>
+        <td>
+          MP4A-LATM
+        </td>
+        <td>
+          <a href="https://tools.ietf.org/html/rfc6416">RFC 6416</a>
+        </td>
+        <td>
+          See <a href="#5_1_1_audio_codecs">section 5.1.1</a> for details on AAC and its variants
+        </td>
+      </tr>
+      <tr>
+        <td>
+          H263-1998
+        </td>
+        <td>
+          <a href="https://tools.ietf.org/html/rfc3551">RFC 3551</a><br />
+          <a href="https://tools.ietf.org/html/rfc4629">RFC 4629</a><br />
+          <a href="https://tools.ietf.org/html/rfc2190">RFC 2190</a>
+        </td>
+        <td>
+          See <a href="#5_1_3_video_codecs">section 5.1.3</a> for details on H263
+        </td>
+      </tr>
+      <tr>
+        <td>
+          H263-2000
+        </td>
+        <td>
+          <a href="https://tools.ietf.org/html/rfc4629">RFC 4629</a>
+        </td>
+        <td>
+          See <a href="#5_1_3_video_codecs">section 5.1.3</a> for details on H263
+        </td>
+      </tr>
+      <tr>
+        <td>
+          AMR
+        </td>
+        <td>
+          <a href="https://tools.ietf.org/html/rfc4867">RFC 4867</a>
+        </td>
+        <td>
+          See <a href="#5_1_1_audio_codecs">section 5.1.1</a> for details on AMR-NB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          AMR-WB
+        </td>
+        <td>
+          <a href="https://tools.ietf.org/html/rfc4867">RFC 4867</a>
+        </td>
+        <td>
+          See <a href="#5_1_1_audio_codecs">section 5.1.1</a> for details on AMR-WB
+        </td>
+      </tr>
+      <tr>
+        <td>
+          MP4V-ES
+        </td>
+        <td>
+          <a href="https://tools.ietf.org/html/rfc6416">RFC 6416</a>
+        </td>
+        <td>
+          See <a href="#5_1_3_video_codecs">section 5.1.3</a> for details on MPEG-4 SP
+        </td>
+      </tr>
+      <tr>
+        <td>
+          mpeg4-generic
+        </td>
+        <td>
+          <a href="https://tools.ietf.org/html/rfc3640">RFC 3640</a>
+        </td>
+        <td>
+          See <a href="#5_1_1_audio_codecs">section 5.1.1</a> for details on AAC and its variants
+        </td>
+      </tr>
+      <tr>
+        <td>
+          MP2T
+        </td>
+        <td>
+          <a href="https://tools.ietf.org/html/rfc2250">RFC 2250</a>
+        </td>
+        <td>
+          See <a href="#mp2t">MPEG-2 Transport Stream</a> underneath HTTP Live Streaming for details
+        </td>
+      </tr>
+    </table>
+    <h3 id="5_8_secure_media">
+      5.8. Secure Media
+    </h3>
+    <p>
+      If device implementations support secure video output and are capable of supporting secure surfaces, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST declare support for <code>Display.FLAG_SECURE</code>.
+      </li>
+    </ul>
+    <p>
+      If device implementations declare support for <code>Display.FLAG_SECURE</code> and support wireless display protocol, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST secure the link with a cryptographically strong mechanism such as HDCP 2.x or higher for the displays connected through wireless protocols such as Miracast.
+      </li>
+    </ul>
+    <p>
+      If device implementations declare support for <code>Display.FLAG_SECURE</code> and support wired external display, they:
+    </p>
+    <ul>
+      <li>[C-3-1] MUST support HDCP 1.2 or higher for all wired external displays.
+      </li>
+    </ul>
+    <h3 id="5_9_musical_instrument_digital_interface_(midi)">
+      5.9. Musical Instrument Digital Interface (MIDI)
+    </h3>
+    <p>
+      If a device implementation supports the inter-app MIDI software transport (virtual MIDI devices), and it supports MIDI over <em>all</em> of the following MIDI-capable hardware transports for which it provides generic non-MIDI connectivity, it is:
+    </p>
+    <ul>
+      <li>[SR] STRONGLY RECOMMENDED to report support for feature android.software.midi via the <a href="http://developer.android.com/reference/android/content/pm/PackageManager.html">android.content.pm.PackageManager</a> class.
+      </li>
+    </ul>
+    <p>
+      The MIDI-capable hardware transports are:
+    </p>
+    <ul>
+      <li>USB host mode (section 7.7 USB)
+      </li>
+      <li>USB peripheral mode (section 7.7 USB)
+      </li>
+      <li>MIDI over Bluetooth LE acting in central role (section 7.4.3 Bluetooth)
+      </li>
+    </ul>
+    <p>
+      If the device implementation provides generic non-MIDI connectivity over a particular MIDI-capable hardware transport listed above, but does not support MIDI over that hardware transport, it:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST NOT report support for feature android.software.midi.
+      </li>
+    </ul>
+    <h3 id="5_10_professional_audio">
+      5.10. Professional Audio
+    </h3>
+    <p>
+      If device implementations report support for feature <code>android.hardware.audio.pro</code> via the <a href="http://developer.android.com/reference/android/content/pm/PackageManager.html">android.content.pm.PackageManager</a> class, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST report support for feature <code>android.hardware.audio.low_latency</code>.
+      </li>
+      <li>[C-1-2] MUST have the continuous round-trip audio latency, as defined in <a href="#5_6_audio_latency">section 5.6 Audio Latency</a>, MUST be 20 milliseconds or less and SHOULD be 10 milliseconds or less over at least one supported path.
+      </li>
+      <li>[C-1-3] MUST include a USB port(s) supporting USB host mode and USB peripheral mode.
+      </li>
+      <li>[C-1-4] MUST report support for feature <code>android.software.midi</code>.
+      </li>
+      <li>[C-1-5] MUST meet latencies and USB audio requirements using the <a href="https://developer.android.com/ndk/guides/audio/opensl-for-android.html">OpenSL ES</a> PCM buffer queue API.
+      </li>
+      <li>SHOULD provide a sustainable level of CPU performance while audio is active.
+      </li>
+      <li>SHOULD minimize audio clock inaccuracy and drift relative to standard time.
+      </li>
+      <li>SHOULD minimize audio clock drift relative to the CPU <code>CLOCK_MONOTONIC</code> when both are active.
+      </li>
+      <li>SHOULD minimize audio latency over on-device transducers.
+      </li>
+      <li>SHOULD minimize audio latency over USB digital audio.
+      </li>
+      <li>SHOULD document audio latency measurements over all paths.
+      </li>
+      <li>SHOULD minimize jitter in audio buffer completion callback entry times, as this affects usable percentage of full CPU bandwidth by the callback.
+      </li>
+      <li>SHOULD provide zero audio underruns (output) or overruns (input) under normal use at reported latency.
+      </li>
+      <li>SHOULD provide zero inter-channel latency difference.
+      </li>
+      <li>SHOULD minimize MIDI mean latency over all transports.
+      </li>
+      <li>SHOULD minimize MIDI latency variability under load (jitter) over all transports.
+      </li>
+      <li>SHOULD provide accurate MIDI timestamps over all transports.
+      </li>
+      <li>SHOULD minimize audio signal noise over on-device transducers, including the period immediately after cold start.
+      </li>
+      <li>SHOULD provide zero audio clock difference between the input and output sides of corresponding end-points, when both are active. Examples of corresponding end-points include the on-device microphone and speaker, or the audio jack input and output.
+      </li>
+      <li>SHOULD handle audio buffer completion callbacks for the input and output sides of corresponding end-points on the same thread when both are active, and enter the output callback immediately after the return from the input callback. Or if it is not feasible to handle the callbacks on the same thread, then enter the output callback shortly after entering the input callback to permit the application to have a consistent timing of the input and output sides.
+      </li>
+      <li>SHOULD minimize the phase difference between HAL audio buffering for the input and output sides of corresponding end-points.
+      </li>
+      <li>SHOULD minimize touch latency.
+      </li>
+      <li>SHOULD minimize touch latency variability under load (jitter).
+      </li>
+    </ul>
+    <p>
+      If device implementations meet all of the above requirements, they:
+    </p>
+    <ul>
+      <li>[SR] STRONGLY RECOMMENDED to report support for feature <code>android.hardware.audio.pro</code> via the <a href="http://developer.android.com/reference/android/content/pm/PackageManager.html"><code>android.content.pm.PackageManager</code></a> class.
+      </li>
+    </ul>
+    <p>
+      If device implementations meet the requirements via the OpenSL ES PCM buffer queue API, they:
+    </p>
+    <ul>
+      <li>[SR] STRONGLY RECOMMENDED to also meet the same requirements via the <a href="https://developer.android.com/ndk/guides/audio/aaudio/aaudio.html">AAudio</a> API.
+      </li>
+    </ul>
+    <p>
+      If device implementations include a 4 conductor 3.5mm audio jack, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST have the continuous round-trip audio latency to be 20 milliseconds or less over the audio jack path.
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to comply with section <a href="https://source.android.com/devices/accessories/headset/jack-headset-spec">Mobile device (jack) specifications</a> of the <a href="https://source.android.com/devices/accessories/headset/plug-headset-spec">Wired Audio Headset Specification (v1.1)</a>.
+      </li>
+      <li>The continuous round-trip audio latency SHOULD be 10 milliseconds or less over the audio jack path.
+      </li>
+    </ul>
+    <p>
+      If device implementations omit a 4 conductor 3.5mm audio jack, they:
+    </p>
+    <ul>
+      <li>[C-3-1] MUST have a continuous round-trip audio latency of 20 milliseconds or less.
+      </li>
+      <li>The continuous round-trip audio latency SHOULD be 10 milliseconds or less over the USB host mode port using USB audio class.
+      </li>
+    </ul>
+    <p>
+      If device implementations include a USB port(s) supporting USB host mode, they:
+    </p>
+    <ul>
+      <li>[C-4-1] MUST implement the USB audio class.
+      </li>
+    </ul>
+    <p>
+      If device implementations include an HDMI port, they:
+    </p>
+    <ul>
+      <li>[C-5-1] MUST support output in stereo and eight channels at 20-bit or 24-bit depth and 192 kHz without bit-depth loss or resampling.
+      </li>
+    </ul>
+    <h3 id="5_11_capture_for_unprocessed">
+      5.11. Capture for Unprocessed
+    </h3>
+    <p>
+      Android includes support for recording of unprocessed audio via the <code>android.media.MediaRecorder.AudioSource.UNPROCESSED</code> audio source. In OpenSL ES, it can be accessed with the record preset <code>SL_ANDROID_RECORDING_PRESET_UNPROCESSED</code>.
+    </p>
+    <p>
+      If device implementations intent to support unprocessed audio source and make it available to third-party apps, they:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-1-1] MUST report the support through the <code>android.media.AudioManager</code> property <a href="http://developer.android.com/reference/android/media/AudioManager.html#PROPERTY_SUPPORT_AUDIO_SOURCE_UNPROCESSED">PROPERTY_SUPPORT_AUDIO_SOURCE_UNPROCESSED</a>.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-1-2] MUST exhibit approximately flat amplitude-versus-frequency characteristics in the mid-frequency range: specifically ±10dB from 100 Hz to 7000 Hz for each and every microphone used to record the unprocessed audio source.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-1-3] MUST exhibit amplitude levels in the low frequency range: specifically from ±20 dB from 5 Hz to 100 Hz compared to the mid-frequency range for each and every microphone used to record the unprocessed audio source.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-1-4] MUST exhibit amplitude levels in the high frequency range: specifically from ±30 dB from 7000 Hz to 22 KHz compared to the mid-frequency range for each and every microphone used to record the unprocessed audio source.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-1-5] MUST set audio input sensitivity such that a 1000 Hz sinusoidal tone source played at 94 dB Sound Pressure Level (SPL) yields a response with RMS of 520 for 16 bit-samples (or -36 dB Full Scale for floating point/double precision samples) for each and every microphone used to record the unprocessed audio source.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-1-6] MUST have a signal-to-noise ratio (SNR) at 60 dB or higher for each and every microphone used to record the unprocessed audio source. (whereas the SNR is measured as the difference between 94 dB SPL and equivalent SPL of self noise, A-weighted).
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-1-7] MUST have a total harmonic distortion (THD) less than be less than 1% for 1 kHZ at 90 dB SPL input level at each and every microphone used to record the unprocessed audio source.
+        </p>
+      </li>
+      <li>
+        <p>
+          MUST not have any other signal processing (e.g. Automatic Gain Control, High Pass Filter, or Echo cancellation) in the path other than a level multiplier to bring the level to desired range. In other words:
+        </p>
+      </li>
+      <li>[C-1-8] If any signal processing is present in the architecture for any reason, it MUST be disabled and effectively introduce zero delay or extra latency to the signal path.
+      </li>
+      <li>[C-1-9] The level multiplier, while allowed to be on the path, MUST NOT introduce delay or latency to the signal path.
+      </li>
+    </ul>
+    <p>
+      All SPL measurements are made directly next to the microphone under test. For multiple microphone configurations, these requirements apply to each microphone.
+    </p>
+    <p>
+      If device implementations declare <code>android.hardware.microphone</code> but do not support unprocessed audio source, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST return <code>null</code> for the <code>AudioManager.getProperty(PROPERTY_SUPPORT_AUDIO_SOURCE_UNPROCESSED)</code> API method, to properly indicate the lack of support.
+      </li>
+      <li>[SR] are still STRONGLY RECOMMENDED to satisfy as many of the requirements for the signal path for the unprocessed recording source.
+      </li>
+    </ul>
+    <h2 id="6_developer_tools_and_options_compatibility">
+      6. Developer Tools and Options Compatibility
+    </h2>
+    <h3 id="6_1_developer_tools">
+      6.1. Developer Tools
+    </h3>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST support the Android Developer Tools provided in the Android SDK.
+      </li>
+      <li>
+        <p>
+          <a href="http://developer.android.com/tools/help/adb.html"><strong>Android Debug Bridge (adb)</strong></a>
+        </p>
+        <ul>
+          <li>[C-0-2] MUST support all adb functions as documented in the Android SDK including <a href="https://source.android.com/devices/input/diagnostics.html">dumpsys</a>.
+          </li>
+          <li>[C-0-3] MUST NOT alter the format or the contents of device system events (batterystats , diskstats, fingerprint, graphicsstats, netstats, notification, procstats) logged via dumpsys.
+          </li>
+          <li>[C-0-4] MUST have the device-side adb daemon be inactive by default and there MUST be a user-accessible mechanism to turn on the Android Debug Bridge.
+          </li>
+          <li>[C-0-5] MUST support secure adb. Android includes support for secure adb. Secure adb enables adb on known authenticated hosts.
+          </li>
+          <li>
+            <p>
+              [C-0-6] MUST provide a mechanism allowing adb to be connected from a host machine. For example:
+            </p>
+            <ul>
+              <li>Device implementations without a USB port supporting peripheral mode MUST implement adb via local-area network (such as Ethernet or Wi-Fi).
+              </li>
+              <li>MUST provide drivers for Windows 7, 9 and 10, allowing developers to connect to the device using the adb protocol.
+              </li>
+            </ul>
+          </li>
+        </ul>
+      </li>
+      <li>
+        <p>
+          <a href="http://developer.android.com/tools/debugging/ddms.html"><strong>Dalvik Debug Monitor Service (ddms)</strong></a>
+        </p>
+        <ul>
+          <li>[C-0-7] MUST support all ddms features as documented in the Android SDK. As ddms uses adb, support for ddms SHOULD be inactive by default, but MUST be supported whenever the user has activated the Android Debug Bridge, as above.
+          </li>
+        </ul>
+      </li>
+      <li>
+        <a href="http://developer.android.com/tools/help/monkey.html"><strong>Monkey</strong></a>
+        <ul>
+          <li>[C-0-8] MUST include the Monkey framework and make it available for applications to use.
+          </li>
+        </ul>
+      </li>
+      <li>
+        <a href="http://developer.android.com/tools/help/systrace.html"><strong>SysTrace</strong></a>
+        <ul>
+          <li>[C-0-9] MUST support systrace tool as documented in the Android SDK. Systrace must be inactive by default and there MUST be a user-accessible mechanism to turn on Systrace.
+          </li>
+        </ul>
+      </li>
+    </ul>
+    <h3 id="6_2_developer_options">
+      6.2. Developer Options
+    </h3>
+    <p>
+      Android includes support for developers to configure application development-related settings.
+    </p>
+    <p>
+      Device implementations MUST provide a consistent experience for Developer Options, they:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST honor the <a href="http://developer.android.com/reference/android/provider/Settings.html#ACTION_APPLICATION_DEVELOPMENT_SETTINGS">android.settings.APPLICATION_DEVELOPMENT_SETTINGS</a> intent to show application development-related settings. The upstream Android implementation hides the Developer Options menu by default and enables users to launch Developer Options after pressing seven (7) times on the <strong>Settings</strong> &gt; <strong>About Device</strong> &gt; <strong>Build Number</strong> menu item.
+      </li>
+      <li>[C-0-2] MUST hide Developer Options by default and MUST provide a mechanism to enable Developer Options without the need for any special whitelisting.
+      </li>
+      <li>MAY temporarily limit access to the Developer Options menu, by visually hiding or disabling the menu, to prevent distraction for scenarios where the safety of the user is of concern.
+      </li>
+    </ul>
+    <h2 id="7_hardware_compatibility">
+      7. Hardware Compatibility
+    </h2>
+    <p>
+      If a device includes a particular hardware component that has a corresponding API for third-party developers:
+    </p>
+    <ul>
+      <li>[C-0-1] The device implementation MUST implement that API as described in the Android SDK documentation.
+      </li>
+    </ul>
+    <p>
+      If an API in the SDK interacts with a hardware component that is stated to be optional and the device implementation does not possess that component:
+    </p>
+    <ul>
+      <li>[C-0-2] Complete class definitions (as documented by the SDK) for the component APIs MUST still be presented.
+      </li>
+      <li>[C-0-3] The API’s behaviors MUST be implemented as no-ops in some reasonable fashion.
+      </li>
+      <li>[C-0-4] API methods MUST return null values where permitted by the SDK documentation.
+      </li>
+      <li>[C-0-5] API methods MUST return no-op implementations of classes where null values are not permitted by the SDK documentation.
+      </li>
+      <li>[C-0-6] API methods MUST NOT throw exceptions not documented by the SDK documentation.
+      </li>
+      <li>[C-0-7] Device implementations MUST consistently report accurate hardware configuration information via the <code>getSystemAvailableFeatures()</code> and <code>hasSystemFeature(String)</code> methods on the <a href="http://developer.android.com/reference/android/content/pm/PackageManager.html">android.content.pm.PackageManager</a> class for the same build fingerprint.
+      </li>
+    </ul>
+    <p>
+      A typical example of a scenario where these requirements apply is the telephony API: Even on non-phone devices, these APIs must be implemented as reasonable no-ops.
+    </p>
+    <h3 id="7_1_display_and_graphics">
+      7.1. Display and Graphics
+    </h3>
+    <p>
+      Android includes facilities that automatically adjust application assets and UI layouts appropriately for the device to ensure that third-party applications run well on a <a href="http://developer.android.com/guide/practices/screens_support.html">variety of hardware configurations</a>. Devices MUST properly implement these APIs and behaviors, as detailed in this section.
+    </p>
+    <p>
+      The units referenced by the requirements in this section are defined as follows:
+    </p>
+    <ul>
+      <li>
+        <strong>physical diagonal size</strong>. The distance in inches between two opposing corners of the illuminated portion of the display.
+      </li>
+      <li>
+        <strong>dots per inch (dpi)</strong>. The number of pixels encompassed by a linear horizontal or vertical span of 1”. Where dpi values are listed, both horizontal and vertical dpi must fall within the range.
+      </li>
+      <li>
+        <strong>aspect ratio</strong>. The ratio of the pixels of the longer dimension to the shorter dimension of the screen. For example, a display of 480x854 pixels would be 854/480 = 1.779, or roughly “16:9”.
+      </li>
+      <li>
+        <strong>density-independent pixel (dp)</strong>. The virtual pixel unit normalized to a 160 dpi screen, calculated as: pixels = dps * (density/160).
+      </li>
+    </ul>
+    <h4 id="7_1_1_screen_configuration">
+      7.1.1. Screen Configuration
+    </h4>
+    <h5 id="7_1_1_1_screen_size">
+      7.1.1.1. Screen Size
+    </h5>
+    <p>
+      The Android UI framework supports a variety of different logical screen layout sizes, and allows applications to query the current configuration's screen layout size via <code>Configuration.screenLayout</code> with the <code>SCREENLAYOUT_SIZE_MASK</code> and <code>Configuration.smallestScreenWidthDp</code>.
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-0-1] Device implementations MUST report the correct layout size for the <code>Configuration.screenLayout</code> as defined in the Android SDK documentation. Specifically, device implementations MUST report the correct logical density-independent pixel (dp) screen dimensions as below:
+        </p>
+        <ul>
+          <li>Devices with the <code>Configuration.uiMode</code> set as any value other than UI_MODE_TYPE_WATCH, and reporting a <code>small</code> size for the <code>Configuration.screenLayout</code>, MUST have at least 426 dp x 320 dp.
+          </li>
+          <li>Devices reporting a <code>normal</code> size for the <code>Configuration.screenLayout</code>, MUST have at least 480 dp x 320 dp.
+          </li>
+          <li>Devices reporting a <code>large</code> size for the <code>Configuration.screenLayout</code>, MUST have at least 640 dp x 480 dp.
+          </li>
+          <li>Devices reporting a <code>xlarge</code> size for the <code>Configuration.screenLayout</code>, MUST have at least 960 dp x 720 dp.
+          </li>
+        </ul>
+      </li>
+      <li>
+        <p>
+          [C-0-2] Device implementations MUST correctly honor applications' stated support for screen sizes through the <a href="https://developer.android.com/guide/topics/manifest/supports-screens-element.html">&lt;<code>supports-screens</code>&gt;</a> attribute in the AndroidManifest.xml, as described in the Android SDK documentation.
+        </p>
+      </li>
+    </ul>
+    <h5 id="7_1_1_2_screen_aspect_ratio">
+      7.1.1.2. Screen Aspect Ratio
+    </h5>
+    <p>
+      While there is no restriction to the screen aspect ratio value of the physical screen display, the screen aspect ratio of the logical display that third-party apps are rendered within, as can be derived from the height and width values reported through the <a href="https://developer.android.com/reference/android/view/Display.html"><code>view.Display</code></a> APIs and <a href="https://developer.android.com/reference/android/content/res/Configuration.html">Configuration</a> API, MUST meet the following requirements:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-0-1] Device implementations with the <code>Configuration.uiMode</code> set as <code>UI_MODE_TYPE_NORMAL</code> MUST have an aspect ratio value between 1.3333 (4:3) and 1.86 (roughly 16:9), unless the app can be deemed as ready to be stretched longer by meeting one of the following conditions:
+        </p>
+        <ul>
+          <li>The app has declared that it supports a larger screen aspect ratio through the <a href="https://developer.android.com/guide/practices/screens&amp;lowbar;support.html#MaxAspectRatio"><code>android.max_aspect</code></a> metadata value.
+          </li>
+          <li>The app declares it is resizeable via the <a href="https://developer.android.com/guide/topics/ui/multi-window.html#configuring">android:resizeableActivity</a> attribute.
+          </li>
+          <li>The app is targeting API level 26 or higher and does not declare a <a href="https://developer.android.com/reference/android/R.attr.html#maxAspectRatio"><code>android:MaxAspectRatio</code></a> that would restrict the allowed aspect ratio.
+          </li>
+        </ul>
+      </li>
+      <li>
+        <p>
+          [C-0-2] Device implementations with the <code>Configuration.uiMode</code> set as <code>UI_MODE_TYPE_WATCH</code> MUST have an aspect ratio value set as 1.0 (1:1).
+        </p>
+      </li>
+    </ul>
+    <h5 id="7_1_1_3_screen_density">
+      7.1.1.3. Screen Density
+    </h5>
+    <p>
+      The Android UI framework defines a set of standard logical densities to help application developers target application resources.
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-0-1] By default, device implementations MUST report only one of the following logical Android framework densities through the <a href="https://developer.android.com/reference/android/util/DisplayMetrics.html#DENSITY_DEVICE_STABLE">DENSITY_DEVICE_STABLE</a> API and this value MUST NOT change at any time; however, the device MAY report a different arbitrary density according to the display configuration changes made by the user (for example, display size) set after initial boot.
+        </p>
+        <ul>
+          <li>120 dpi (ldpi)
+          </li>
+          <li>160 dpi (mdpi)
+          </li>
+          <li>213 dpi (tvdpi)
+          </li>
+          <li>240 dpi (hdpi)
+          </li>
+          <li>260 dpi (260dpi)
+          </li>
+          <li>280 dpi (280dpi)
+          </li>
+          <li>300 dpi (300dpi)
+          </li>
+          <li>320 dpi (xhdpi)
+          </li>
+          <li>340 dpi (340dpi)
+          </li>
+          <li>360 dpi (360dpi)
+          </li>
+          <li>400 dpi (400dpi)
+          </li>
+          <li>420 dpi (420dpi)
+          </li>
+          <li>480 dpi (xxhdpi)
+          </li>
+          <li>560 dpi (560dpi)
+          </li>
+          <li>640 dpi (xxxhdpi)
+          </li>
+        </ul>
+      </li>
+      <li>
+        <p>
+          Device implementations SHOULD define the standard Android framework density that is numerically closest to the physical density of the screen, unless that logical density pushes the reported screen size below the minimum supported. If the standard Android framework density that is numerically closest to the physical density results in a screen size that is smaller than the smallest supported compatible screen size (320 dp width), device implementations SHOULD report the next lowest standard Android framework density.
+        </p>
+      </li>
+    </ul>
+    <p>
+      If there is an affordance to change the display size of the device:
+    </p>
+    <ul>
+      <li>[C-1-1] The display size MUST NOT be scaled any larger than 1.5 times the native density or produce an effective minimum screen dimension smaller than 320dp (equivalent to resource qualifier sw320dp), whichever comes first.
+      </li>
+      <li>[C-1-2] Display size MUST NOT be scaled any smaller than 0.85 times the native density.
+      </li>
+      <li>To ensure good usability and consistent font sizes, it is RECOMMENDED that the following scaling of Native Display options be provided (while complying with the limits specified above)
+      </li>
+      <li>Small: 0.85x
+      </li>
+      <li>Default: 1x (Native display scale)
+      </li>
+      <li>Large: 1.15x
+      </li>
+      <li>Larger: 1.3x
+      </li>
+      <li>Largest 1.45x
+      </li>
+    </ul>
+    <h4 id="7_1_2_display_metrics">
+      7.1.2. Display Metrics
+    </h4>
+    <p>
+      If device implementations include a screen or video output, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST report correct values for all display metrics defined in the <a href="https://developer.android.com/reference/android/util/DisplayMetrics.html"><code>android.util.DisplayMetrics</code></a> API.
+      </li>
+    </ul>
+    <p>
+      If device implementations does not include an embedded screen or video output, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST report reasonable values for all display metrics defined in the <a href="https://developer.android.com/reference/android/util/DisplayMetrics.html"><code>android.util.DisplayMetrics</code></a> API for the emulated default <code>view.Display</code>.
+      </li>
+    </ul>
+    <h4 id="7_1_3_screen_orientation">
+      7.1.3. Screen Orientation
+    </h4>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST report which screen orientations they support (<code>android.hardware.screen.portrait</code> and/or <code>android.hardware.screen.landscape</code>) and MUST report at least one supported orientation. For example, a device with a fixed orientation landscape screen, such as a television or laptop, SHOULD only report <code>android.hardware.screen.landscape</code>.
+      </li>
+      <li>[C-0-2] MUST report the correct value for the device’s current orientation, whenever queried via the <code>android.content.res.Configuration.orientation</code>, <code>android.view.Display.getOrientation()</code>, or other APIs.
+      </li>
+    </ul>
+    <p>
+      If device implementations support both screen orientations, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support dynamic orientation by applications to either portrait or landscape screen orientation. That is, the device must respect the application’s request for a specific screen orientation.
+      </li>
+      <li>[C-1-2] MUST NOT change the reported screen size or density when changing orientation.
+      </li>
+      <li>MAY select either portrait or landscape orientation as the default.
+      </li>
+    </ul>
+    <h4 id="7_1_4_2d_and_3d_graphics_acceleration">
+      7.1.4. 2D and 3D Graphics Acceleration
+    </h4>
+    <h5 id="7_1_4_1_opengl_es">
+      7.1.4.1 OpenGL ES
+    </h5>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST correctly identify the supported OpenGL ES versions (1.1, 2.0, 3.0, 3.1, 3.2) through the managed APIs (such as via the <code>GLES10.getString()</code> method) and the native APIs.
+      </li>
+      <li>[C-0-2] MUST include the support for all the corresponding managed APIs and native APIs for every OpenGL ES versions they identified to support.
+      </li>
+    </ul>
+    <p>
+      If device implementations include a screen or video output, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support both OpenGL ES 1.0 and 2.0, as embodied and detailed in the <a href="https://developer.android.com/guide/topics/graphics/opengl.html">Android SDK documentation</a>.
+      </li>
+      <li>[SR] are STRONGLY RECOMMENDED to support OpenGL ES 3.0.
+      </li>
+      <li>SHOULD support OpenGL ES 3.1 or 3.2.
+      </li>
+    </ul>
+    <p>
+      If device implementations support any of the OpenGL ES versions, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST report via the OpenGL ES managed APIs and native APIs any other OpenGL ES extensions they have implemented, and conversely MUST NOT report extension strings that they do not support.
+      </li>
+      <li>[C-2-2] MUST support the <code>EGL_KHR_image</code>, <code>EGL_KHR_image_base</code>, <code>EGL_ANDROID_image_native_buffer</code>, <code>EGL_ANDROID_get_native_client_buffer</code>, <code>EGL_KHR_wait_sync</code>, <code>EGL_KHR_get_all_proc_addresses</code>, <code>EGL_ANDROID_presentation_time</code>, <code>EGL_KHR_swap_buffers_with_damage</code> and <code>EGL_ANDROID_recordable</code> extensions.
+      </li>
+      <li>[SR] are STRONGLY RECOMMENDED to support EGL_KHR_partial_update.
+      </li>
+      <li>SHOULD accurately report via the <code>getString()</code> method, any texture compression format that they support, which is typically vendor-specific.
+      </li>
+    </ul>
+    <p>
+      If device implementations declare support for OpenGL ES 3.0, 3.1, or 3.2, they:
+    </p>
+    <ul>
+      <li>[C-3-1] MUST export the corresponding function symbols for these version in addition to the OpenGL ES 2.0 function symbols in the libGLESv2.so library.
+      </li>
+    </ul>
+    <p>
+      If device implementations support OpenGL ES 3.2, they:
+    </p>
+    <ul>
+      <li>[C-4-1] MUST support the OpenGL ES Android Extension Pack in its entirety.
+      </li>
+    </ul>
+    <p>
+      If device implementations support the OpenGL ES <a href="https://developer.android.com/reference/android/opengl/GLES31Ext.html">Android Extension Pack</a> in its entirety, they:
+    </p>
+    <ul>
+      <li>[C-5-1] MUST identify the support through the <code>android.hardware.opengles.aep</code> feature flag.
+      </li>
+    </ul>
+    <p>
+      If device implementations expose support for the <code>EGL_KHR_mutable_render_buffer</code> extension, they:
+    </p>
+    <ul>
+      <li>[C-6-1] MUST also support the <code>EGL_ANDROID_front_buffer_auto_refresh</code> extension.
+      </li>
+    </ul>
+    <h5 id="7_1_4_2_vulkan">
+      7.1.4.2 Vulkan
+    </h5>
+    <p>
+      Android includes support for <a href="https://www.khronos.org/registry/vulkan/specs/1.0-wsi&amp;lowbarextensions/xhtml/vkspec.html">Vulkan</a> , a low-overhead, cross-platform API for high-performance 3D graphics.
+    </p>
+    <p>
+      If device implementations support OpenGL ES 3.0 or 3.1, they:
+    </p>
+    <ul>
+      <li>[SR] Are STRONGLY RECOMMENDED to include support for Vulkan 1.0 .
+      </li>
+    </ul>
+    <p>
+      If device implementations include a screen or video output, they:
+    </p>
+    <ul>
+      <li>SHOULD include support for Vulkan 1.0.
+      </li>
+    </ul>
+    <p>
+      Device implementations, if including support for Vulkan 1.0:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST report the correct integer value with the <code>android.hardware.vulkan.level</code> and <code>android.hardware.vulkan.version</code> feature flags.
+      </li>
+      <li>[C-1-2] MUST enumarate, at least one <code>VkPhysicalDevice</code> for the Vulkan native API <a href="https://www.khronos.org/registry/vulkan/specs/1.0/man/html/vkEnumeratePhysicalDevices.html"><code>vkEnumeratePhysicalDevices()</code></a> .
+      </li>
+      <li>[C-1-3] MUST fully implement the Vulkan 1.0 APIs for each enumerated <code>VkPhysicalDevice</code>.
+      </li>
+      <li>[C-1-4] MUST enumerate layers, contained in native libraries named as <code>libVkLayer*.so</code> in the application package’s native library directory, through the Vulkan native APIs <a href="https://www.khronos.org/registry/vulkan/specs/1.0/man/html/vkEnumerateInstanceLayerProperties.html"><code>vkEnumerateInstanceLayerProperties()</code></a> and <a href="https://www.khronos.org/registry/vulkan/specs/1.0/man/html/vkEnumerateDeviceLayerProperties.html"><code>vkEnumerateDeviceLayerProperties()</code></a> .
+      </li>
+      <li>[C-1-5] MUST NOT enumerate layers provided by libraries outside of the application package, or provide other ways of tracing or intercepting the Vulkan API, unless the application has the <code>android:debuggable</code> attribute set as <code>true</code>.
+      </li>
+      <li>[C-1-6] MUST report all extension strings that they do support via the Vulkan native APIs , and conversely MUST NOT report extension strings that they do not correctly support.
+      </li>
+    </ul>
+    <p>
+      Device implementations, if not including support for Vulkan 1.0:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST NOT declare any of the Vulkan feature flags (e.g. <code>android.hardware.vulkan.level</code>, <code>android.hardware.vulkan.version</code>).
+      </li>
+      <li>[C-2-2] MUST NOT enumarate any <code>VkPhysicalDevice</code> for the Vulkan native API <code>vkEnumeratePhysicalDevices()</code>.
+      </li>
+    </ul>
+    <h5 id="7_1_4_3_renderscript">
+      7.1.4.3 RenderScript
+    </h5>
+    <ul>
+      <li>[C-0-1] Device implementations MUST support <a href="http://developer.android.com/guide/topics/renderscript/">Android RenderScript</a>, as detailed in the Android SDK documentation.
+      </li>
+    </ul>
+    <h5 id="7_1_4_4_2d_graphics_acceleration">
+      7.1.4.4 2D Graphics Acceleration
+    </h5>
+    <p>
+      Android includes a mechanism for applications to declare that they want to enable hardware acceleration for 2D graphics at the Application, Activity, Window, or View level through the use of a manifest tag <a href="http://developer.android.com/guide/topics/graphics/hardware-accel.html">android:hardwareAccelerated</a> or direct API calls.
+    </p>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST enable hardware acceleration by default, and MUST disable hardware acceleration if the developer so requests by setting android:hardwareAccelerated="false” or disabling hardware acceleration directly through the Android View APIs.
+      </li>
+      <li>[C-0-2] MUST exhibit behavior consistent with the Android SDK documentation on <a href="http://developer.android.com/guide/topics/graphics/hardware-accel.html">hardware acceleration</a>.
+      </li>
+    </ul>
+    <p>
+      Android includes a TextureView object that lets developers directly integrate hardware-accelerated OpenGL ES textures as rendering targets in a UI hierarchy.
+    </p>
+    <ul>
+      <li>[C-0-3] MUST support the TextureView API, and MUST exhibit consistent behavior with the upstream Android implementation.
+      </li>
+    </ul>
+    <h5 id="7_1_4_5_wide-gamut_displays">
+      7.1.4.5 Wide-gamut Displays
+    </h5>
+    <p>
+      If device implementations claim support for wide-gamut displays through <a href="https://developer.android.com/reference/android/view/Display.html#isWideColorGamut%28%29"><code>Display.isWideColorGamut()</code></a> , they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST have a color-calibrated display.
+      </li>
+      <li>[C-1-2] MUST have a display whose gamut covers the sRGB color gamut entirely in CIE 1931 xyY space.
+      </li>
+      <li>[C-1-3] MUST have a display whose gamut has an area of at least 90% of NTSC 1953 in CIE 1931 xyY space.
+      </li>
+      <li>[C-1-4] MUST support OpenGL ES 3.0, 3.1, or 3.2 and report it properly.
+      </li>
+      <li>[C-1-5] MUST advertise support for the <code>EGL_KHR_no_config_context</code>, <code>EGL_EXT_pixel_format_float</code>,<code>EGL_KHR_gl_colorspace</code>, <code>EGL_EXT_colorspace_scrgb_linear</code>, and <code>EGL_GL_colorspace_display_p3</code> extensions.
+      </li>
+      <li>[SR] Are STRONGLY RECOMMENDED to support <code>GL_EXT_sRGB</code>.
+      </li>
+    </ul>
+    <p>
+      Conversely, if device implementations do not support wide-gamut displays, they:
+    </p>
+    <ul>
+      <li>[C-2-1] SHOULD cover 100% or more of sRGB in CIE 1931 xyY space, although the screen color gamut is undefined.
+      </li>
+    </ul>
+    <h4 id="7_1_5_legacy_application_compatibility_mode">
+      7.1.5. Legacy Application Compatibility Mode
+    </h4>
+    <p>
+      Android specifies a “compatibility mode” in which the framework operates in a 'normal' screen size equivalent (320dp width) mode for the benefit of legacy applications not developed for old versions of Android that pre-date screen-size independence.
+    </p>
+    <h4 id="7_1_6_screen_technology">
+      7.1.6. Screen Technology
+    </h4>
+    <p>
+      The Android platform includes APIs that allow applications to render rich graphics to the display. Devices MUST support all of these APIs as defined by the Android SDK unless specifically allowed in this document.
+    </p>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST support displays capable of rendering 16-bit color graphics.
+      </li>
+      <li>SHOULD support displays capable of 24-bit color graphics.
+      </li>
+      <li>[C-0-2] MUST support displays capable of rendering animations.
+      </li>
+      <li>[C-0-3] MUST use the display technology that have a pixel aspect ratio (PAR) between 0.9 and 1.15. That is, the pixel aspect ratio MUST be near square (1.0) with a 10 ~ 15% tolerance.
+      </li>
+    </ul>
+    <h4 id="7_1_7_secondary_displays">
+      7.1.7. Secondary Displays
+    </h4>
+    <p>
+      Android includes support for secondary display to enable media sharing capabilities and developer APIs for accessing external displays.
+    </p>
+    <p>
+      If device implementations support an external display either via a wired, wireless, or an embedded additional display connection, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST implement the <a href="https://developer.android.com/reference/android/hardware/display/DisplayManager.html"><code>DisplayManager</code></a> system service and API as described in the Android SDK documentation.
+      </li>
+    </ul>
+    <h3 id="7_2_input_devices">
+      7.2. Input Devices
+    </h3>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST include an input mechanism, such as a <a href="#7_2_4_touchScreen_input">touchscreen</a> or <a href="#7_2_2_non-touch_navigation">non-touch navigation</a>, to navigate between the UI elements.
+      </li>
+    </ul>
+    <h4 id="7_2_1_keyboard">
+      7.2.1. Keyboard
+    </h4>
+    <p>
+      If device implementations include support for third-party Input Method Editor (IME) applications, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST declare the <a href="https://developer.android.com/reference/android/content/pm/PackageManager.html#FEATURE_INPUT_METHODS"><code>android.software.input_methods</code></a> feature flag.
+      </li>
+      <li>[C-1-2] MUST implement fully <a href="https://developer.android.com/reference/android/view/inputmethod/InputMethodManager.html"><code>Input Management Framework</code></a>
+      </li>
+      <li>[C-1-3] MUST have a preloaded software keyboard.
+      </li>
+    </ul>
+    <p>
+      Device implementations: <em>[C-0-1] MUST NOT include a hardware keyboard that does not match one of the formats specified in <a href="http://developer.android.com/reference/android/content/res/Configuration.html">android.content.res.Configuration.keyboard</a> (QWERTY or 12-key).</em> SHOULD include additional soft keyboard implementations. * MAY include a hardware keyboard.
+    </p>
+    <h4 id="7_2_2_non-touch_navigation">
+      7.2.2. Non-touch Navigation
+    </h4>
+    <p>
+      Android includes support for d-pad, trackball, and wheel as mechanisms for non-touch navigation.
+    </p>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST report the correct value for <a href="https://developer.android.com/reference/android/content/res/Configuration.html#navigation">android.content.res.Configuration.navigation</a>.
+      </li>
+    </ul>
+    <p>
+      If device implementations lack non-touch navigations, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST provide a reasonable alternative user interface mechanism for the selection and editing of text, compatible with Input Management Engines. The upstream Android open source implementation includes a selection mechanism suitable for use with devices that lack non-touch navigation inputs.
+      </li>
+    </ul>
+    <h4 id="7_2_3_navigation_keys">
+      7.2.3. Navigation Keys
+    </h4>
+    <p>
+      The <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_HOME">Home</a>, <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_APP_SWITCH">Recents</a>, and <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BACK">Back</a> functions typically provided via an interaction with a dedicated physical button or a distinct portion of the touch screen, are essential to the Android navigation paradigm and therefore:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST provide the Home function.
+      </li>
+      <li>SHOULD provide buttons for the Recents and Back function.
+      </li>
+    </ul>
+    <p>
+      If the Home, Recents, or Back functions are provided, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST be accessible with a single action (e.g. tap, double-click or gesture) when any of them are accessible.
+      </li>
+      <li>[C-1-2] MUST provide a clear indication of which single action would trigger each function. Having a visible icon imprinted on the button, showing a software icon on the navigation bar portion of the screen, or walking the user through a guided step-by-step demo flow during the out-of-box setup experience are examples of such an indication.
+      </li>
+    </ul>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>[SR] are STRONGLY RECOMMENDED to not provide the input mechanism for the <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BACK">Menu function</a> as it is deprecated in favor of action bar since Android 4.0.
+      </li>
+    </ul>
+    <p>
+      If device implementations provide the Menu function, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST display the action overflow button whenever the action overflow menu popup is not empty and the action bar is visible.
+      </li>
+      <li>[C-2-2] MUST NOT modify the position of the action overflow popup displayed by selecting the overflow button in the action bar, but MAY render the action overflow popup at a modified position on the screen when it is displayed by selecting the Menu function.
+      </li>
+    </ul>
+    <p>
+      If device implementations do not provide the Menu function, for backwards compatibility, they:
+    </p>
+    <ul>
+      <li>[C-3-1] MUST make the Menu function available to applications when <code>targetSdkVersion</code> is less than 10, either by a physical button, a software key, or gestures. This Menu function should be accessible unless hidden together with other navigation functions.
+      </li>
+    </ul>
+    <p>
+      If device implementations provide the <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_ASSIST">Assist function</a>, they:
+    </p>
+    <ul>
+      <li>[C-4-1] MUST make the Assist function accessible with a single action (e.g. tap, double-click or gesture) when other navigation keys are accessible.
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to use long press on HOME function as this designated interaction.
+      </li>
+    </ul>
+    <p>
+      If device implementations use a distinct portion of the screen to display the navigation keys, they:
+    </p>
+    <ul>
+      <li>[C-5-1] Navigation keys MUST use a distinct portion of the screen, not available to applications, and MUST NOT obscure or otherwise interfere with the portion of the screen available to applications.
+      </li>
+      <li>[C-5-2] MUST make available a portion of the display to applications that meets the requirements defined in <a href="#7_1_1_screen_configuration">section 7.1.1</a>.
+      </li>
+      <li>[C-5-3] MUST honor the flags set by the app through the <a href="https://developer.android.com/reference/android/view/View.html#setSystemUiVisibility%28int%29"><code>View.setSystemUiVisibility()</code></a> API method, so that this distinct portion of the screen (a.k.a. the navigation bar) is properly hidden away as documented in the SDK.
+      </li>
+    </ul>
+    <h4 id="7_2_4_touchscreen_input">
+      7.2.4. Touchscreen Input
+    </h4>
+    <p>
+      Android includes support for a variety of pointer input systems, such as touchscreens, touch pads, and fake touch input devices. <a href="http://source.android.com/devices/tech/input/touch-devices.html">Touchscreen-based device implementations</a> are associated with a display such that the user has the impression of directly manipulating items on screen. Since the user is directly touching the screen, the system does not require any additional affordances to indicate the objects being manipulated.
+    </p>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>SHOULD have a pointer input system of some kind (either mouse-like or touch).
+      </li>
+      <li>SHOULD support fully independently tracked pointers.
+      </li>
+    </ul>
+    <p>
+      If device implementations include a touchscreen (single-touch or better), they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST report <code>TOUCHSCREEN_FINGER</code> for the <a href="https://developer.android.com/reference/android/content/res/Configuration.html#touchscreen"><code>Configuration.touchscreen</code></a> API field.
+      </li>
+      <li>[C-1-2] MUST report the <code>android.hardware.touchscreen</code> and <code>android.hardware.faketouch</code> feature flags
+      </li>
+    </ul>
+    <p>
+      If device implementations include a touchscreen that can track more than a single touch, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST report the appropriate feature flags <code>android.hardware.touchscreen.multitouch</code>, <code>android.hardware.touchscreen.multitouch.distinct</code>, <code>android.hardware.touchscreen.multitouch.jazzhand</code> corresponding to the type of the specific touchscreen on the device.
+      </li>
+    </ul>
+    <p>
+      If device implementations do not include a touchscreen (and rely on a pointer device only) and meet the fake touch requirements in <a href="#7_2_5_fake_touch_input">section 7.2.5</a>, they:
+    </p>
+    <ul>
+      <li>[C-3-1] MUST NOT report any feature flag starting with <code>android.hardware.touchscreen</code> and MUST report only <code>android.hardware.faketouch</code>.
+      </li>
+    </ul>
+    <h4 id="7_2_5_fake_touch_input">
+      7.2.5. Fake Touch Input
+    </h4>
+    <p>
+      Fake touch interface provides a user input system that approximates a subset of touchscreen capabilities. For example, a mouse or remote control that drives an on-screen cursor approximates touch, but requires the user to first point or focus then click. Numerous input devices like the mouse, trackpad, gyro-based air mouse, gyro-pointer, joystick, and multi-touch trackpad can support fake touch interactions. Android includes the feature constant android.hardware.faketouch, which corresponds to a high-fidelity non-touch (pointer-based) input device such as a mouse or trackpad that can adequately emulate touch-based input (including basic gesture support), and indicates that the device supports an emulated subset of touchscreen functionality.
+    </p>
+    <p>
+      If device implementations do not include a touchscreen but include another pointer input system which they want to make available, they:
+    </p>
+    <ul>
+      <li>SHOULD declare support for the <code>android.hardware.faketouch</code> feature flag.
+      </li>
+    </ul>
+    <p>
+      If device implementations declare support for <code>android.hardware.faketouch</code>, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST report the <a href="http://developer.android.com/reference/android/view/MotionEvent.html">absolute X and Y screen positions</a> of the pointer location and display a visual pointer on the screen.
+      </li>
+      <li>[C-1-2] MUST report touch event with the action code that specifies the state change that occurs on the pointer <a href="http://developer.android.com/reference/android/view/MotionEvent.html">going down or up on the screen</a>.
+      </li>
+      <li>[C-1-3] MUST support pointer down and up on an object on the screen, which allows users to emulate tap on an object on the screen.
+      </li>
+      <li>[C-1-4] MUST support pointer down, pointer up, pointer down then pointer up in the same place on an object on the screen within a time threshold, which allows users to <a href="http://developer.android.com/reference/android/view/MotionEvent.html">emulate double tap</a> on an object on the screen.
+      </li>
+      <li>[C-1-5] MUST support pointer down on an arbitrary point on the screen, pointer move to any other arbitrary point on the screen, followed by a pointer up, which allows users to emulate a touch drag.
+      </li>
+      <li>[C-1-6] MUST support pointer down then allow users to quickly move the object to a different position on the screen and then pointer up on the screen, which allows users to fling an object on the screen.
+      </li>
+      <li>[C-1-7] MUST report <code>TOUCHSCREEN_NOTOUCH</code> for the <a href="https://developer.android.com/reference/android/content/res/Configuration.html#touchscreen"><code>Configuration.touchscreen</code></a> API field.
+      </li>
+    </ul>
+    <p>
+      If device implementations declare support for <code>android.hardware.faketouch.multitouch.distinct</code>, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST declare support for <code>android.hardware.faketouch</code>.
+      </li>
+      <li>[C-2-2] MUST support distinct tracking of two or more independent pointer inputs.
+      </li>
+    </ul>
+    <p>
+      If device implementations declare support for <code>android.hardware.faketouch.multitouch.jazzhand</code>, they:
+    </p>
+    <ul>
+      <li>[C-3-1] MUST declare support for <code>android.hardware.faketouch</code>.
+      </li>
+      <li>[C-3-2] MUST support distinct tracking of 5 (tracking a hand of fingers) or more pointer inputs fully independently.
+      </li>
+    </ul>
+    <h4 id="7_2_6_game_controller_support">
+      7.2.6. Game Controller Support
+    </h4>
+    <h5 id="7_2_6_1_button_mappings">
+      7.2.6.1. Button Mappings
+    </h5>
+    <p>
+      If device implementations declare the <code>android.hardware.gamepad</code> feature flag, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST have embed a controller or ship with a separate controller in the box, that would provide means to input all the events listed in the below tables.
+      </li>
+      <li>[C-1-2] MUST be capable to map HID events to it's associated Android <code>view.InputEvent</code> constants as listed in the below tables. The upstream Android implementation includes implementation for game controllers that satisfies this requirement.
+      </li>
+    </ul>
+    <table>
+      <tr>
+        <th>
+          Button
+        </th>
+        <th>
+          HID Usage<sup>2</sup>
+        </th>
+        <th>
+          Android Button
+        </th>
+      </tr>
+      <tr>
+        <td>
+          <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BUTTON_A">A</a><sup>1</sup>
+        </td>
+        <td>
+          0x09 0x0001
+        </td>
+        <td>
+          KEYCODE_BUTTON_A (96)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BUTTON_B">B</a><sup>1</sup>
+        </td>
+        <td>
+          0x09 0x0002
+        </td>
+        <td>
+          KEYCODE_BUTTON_B (97)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BUTTON_X">X</a><sup>1</sup>
+        </td>
+        <td>
+          0x09 0x0004
+        </td>
+        <td>
+          KEYCODE_BUTTON_X (99)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BUTTON_Y">Y</a><sup>1</sup>
+        </td>
+        <td>
+          0x09 0x0005
+        </td>
+        <td>
+          KEYCODE_BUTTON_Y (100)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_DPAD_UP">D-pad up</a><sup>1</sup><br />
+          <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_DPAD_DOWN">D-pad down</a><sup>1</sup>
+        </td>
+        <td>
+          0x01 0x0039<sup>3</sup>
+        </td>
+        <td>
+          <a href="http://developer.android.com/reference/android/view/MotionEvent.html#AXIS_HAT_Y">AXIS_HAT_Y</a><sup>4</sup>
+        </td>
+      </tr>
+      <tr>
+        <td>
+          <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_DPAD_LEFT">D-pad left</a>1<br />
+          <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_DPAD_RIGHT">D-pad right</a><sup>1</sup>
+        </td>
+        <td>
+          0x01 0x0039<sup>3</sup>
+        </td>
+        <td>
+          <a href="http://developer.android.com/reference/android/view/MotionEvent.html#AXIS_HAT_X">AXIS_HAT_X</a><sup>4</sup>
+        </td>
+      </tr>
+      <tr>
+        <td>
+          <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BUTTON_L1">Left shoulder button</a><sup>1</sup>
+        </td>
+        <td>
+          0x09 0x0007
+        </td>
+        <td>
+          KEYCODE_BUTTON_L1 (102)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BUTTON_R1">Right shoulder button</a><sup>1</sup>
+        </td>
+        <td>
+          0x09 0x0008
+        </td>
+        <td>
+          KEYCODE_BUTTON_R1 (103)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BUTTON_THUMBL">Left stick click</a><sup>1</sup>
+        </td>
+        <td>
+          0x09 0x000E
+        </td>
+        <td>
+          KEYCODE_BUTTON_THUMBL (106)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BUTTON_THUMBR">Right stick click</a><sup>1</sup>
+        </td>
+        <td>
+          0x09 0x000F
+        </td>
+        <td>
+          KEYCODE_BUTTON_THUMBR (107)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_HOME">Home</a><sup>1</sup>
+        </td>
+        <td>
+          0x0c 0x0223
+        </td>
+        <td>
+          KEYCODE_HOME (3)
+        </td>
+      </tr>
+      <tr>
+        <td>
+          <a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BACK">Back</a><sup>1</sup>
+        </td>
+        <td>
+          0x0c 0x0224
+        </td>
+        <td>
+          KEYCODE_BACK (4)
+        </td>
+      </tr>
+    </table>
+    <p class="table_footnote">
+      1 <a href="http://developer.android.com/reference/android/view/KeyEvent.html">KeyEvent</a>
+    </p>
+    <p class="table_footnote">
+      2 The above HID usages must be declared within a Game pad CA (0x01 0x0005).
+    </p>
+    <p class="table_footnote">
+      3 This usage must have a Logical Minimum of 0, a Logical Maximum of 7, a Physical Minimum of 0, a Physical Maximum of 315, Units in Degrees, and a Report Size of 4. The logical value is defined to be the clockwise rotation away from the vertical axis; for example, a logical value of 0 represents no rotation and the up button being pressed, while a logical value of 1 represents a rotation of 45 degrees and both the up and left keys being pressed.
+    </p>
+    <p class="table_footnote">
+      4 <a href="http://developer.android.com/reference/android/view/MotionEvent.html">MotionEvent</a>
+    </p>
+    <table>
+      <tr>
+        <th>
+          Analog Controls<sup>1</sup>
+        </th>
+        <th>
+          HID Usage
+        </th>
+        <th>
+          Android Button
+        </th>
+      </tr>
+      <tr>
+        <td>
+          <a href="http://developer.android.com/reference/android/view/MotionEvent.html#AXIS_LTRIGGER">Left Trigger</a>
+        </td>
+        <td>
+          0x02 0x00C5
+        </td>
+        <td>
+          AXIS_LTRIGGER
+        </td>
+      </tr>
+      <tr>
+        <td>
+          <a href="http://developer.android.com/reference/android/view/MotionEvent.html#AXIS_THROTTLE">Right Trigger</a>
+        </td>
+        <td>
+          0x02 0x00C4
+        </td>
+        <td>
+          AXIS_RTRIGGER
+        </td>
+      </tr>
+      <tr>
+        <td>
+          <a href="http://developer.android.com/reference/android/view/MotionEvent.html#AXIS_Y">Left Joystick</a>
+        </td>
+        <td>
+          0x01 0x0030<br />
+          0x01 0x0031
+        </td>
+        <td>
+          AXIS_X<br />
+          AXIS_Y
+        </td>
+      </tr>
+      <tr>
+        <td>
+          <a href="http://developer.android.com/reference/android/view/MotionEvent.html#AXIS_Z">Right Joystick</a>
+        </td>
+        <td>
+          0x01 0x0032<br />
+          0x01 0x0035
+        </td>
+        <td>
+          AXIS_Z<br />
+          AXIS_RZ
+        </td>
+      </tr>
+    </table>
+    <p class="table_footnote">
+      1 <a href="http://developer.android.com/reference/android/view/MotionEvent.html">MotionEvent</a>
+    </p>
+    <h4 id="7_2_7_remote_control">
+      7.2.7. Remote Control
+    </h4>
+    <p>
+      See <a href="#2_3_1_hardware">Section 2.3.1</a> for device-specific requirements.
+    </p>
+    <h3 id="7_3_sensors">
+      7.3. Sensors
+    </h3>
+    <p>
+      If device implementations include a particular sensor type that has a corresponding API for third-party developers, the device implementation MUST implement that API as described in the Android SDK documentation and the Android Open Source documentation on <a href="http://source.android.com/devices/sensors/">sensors</a>.
+    </p>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST accurately report the presence or absence of sensors per the <a href="http://developer.android.com/reference/android/content/pm/PackageManager.html"><code>android.content.pm.PackageManager</code></a> class.
+      </li>
+      <li>[C-0-2] MUST return an accurate list of supported sensors via the <code>SensorManager.getSensorList()</code> and similar methods.
+      </li>
+      <li>[C-0-3] MUST behave reasonably for all other sensor APIs (for example, by returning <code>true</code> or <code>false</code> as appropriate when applications attempt to register listeners, not calling sensor listeners when the corresponding sensors are not present; etc.).
+      </li>
+    </ul>
+    <p>
+      If device implementations include a particular sensor type that has a corresponding API for third-party developers, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST <a href="http://developer.android.com/reference/android/hardware/SensorEvent.html">report all sensor measurements</a> using the relevant International System of Units (metric) values for each sensor type as defined in the Android SDK documentation.
+      </li>
+      <li>[C-1-2] MUST report sensor data with a maximum latency of 100 milliseconds
+      </li>
+      <li>2 * sample_time for the case of a sensor streamed with a minimum required latency of 5 ms + 2 * sample_time when the application processor is active. This delay does not include any filtering delays.
+      </li>
+      <li>[C-1-3] MUST report the first sensor sample within 400 milliseconds + 2 * sample_time of the sensor being activated. It is acceptable for this sample to have an accuracy of 0.
+      </li>
+      <li>
+        <p>
+          [SR] SHOULD <a href="http://developer.android.com/reference/android/hardware/SensorEvent.html#timestamp">report the event time</a> in nanoseconds as defined in the Android SDK documentation, representing the time the event happened and synchronized with the SystemClock.elapsedRealtimeNano() clock. Existing and new Android devices are <strong>STRONGLY RECOMMENDED</strong> to meet these requirements so they will be able to upgrade to the future platform releases where this might become a REQUIRED component. The synchronization error SHOULD be below 100 milliseconds.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-1-7] For any API indicated by the Android SDK documentation to be a <a href="https://source.android.com/devices/sensors/report-modes.html#continuous">continuous sensor</a>, device implementations MUST continuously provide periodic data samples that SHOULD have a jitter below 3%, where jitter is defined as the standard deviation of the difference of the reported timestamp values between consecutive events.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-1-8] MUST ensure that the sensor event stream MUST NOT prevent the device CPU from entering a suspend state or waking up from a suspend state.
+        </p>
+      </li>
+      <li>When several sensors are activated, the power consumption SHOULD NOT exceed the sum of the individual sensor’s reported power consumption.
+      </li>
+    </ul>
+    <p>
+      The list above is not comprehensive; the documented behavior of the Android SDK and the Android Open Source Documentations on <a href="http://source.android.com/devices/sensors/">sensors</a> is to be considered authoritative.
+    </p>
+    <p>
+      Some sensor types are composite, meaning they can be derived from data provided by one or more other sensors. (Examples include the orientation sensor and the linear acceleration sensor.)
+    </p>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>SHOULD implement these sensor types, when they include the prerequisite physical sensors as described in <a href="https://source.android.com/devices/sensors/sensor-types.html">sensor types</a>.
+      </li>
+    </ul>
+    <p>
+      If device implementations include a composite sensor, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST implement the sensor as described in the Android Open Source documentation on <a href="https://source.android.com/devices/sensors/sensor-types.html#composite_sensor_type_summary">composite sensors</a>.
+      </li>
+    </ul>
+    <h4 id="7_3_1_accelerometer">
+      7.3.1. Accelerometer
+    </h4>
+    <ul>
+      <li>Device implementations SHOULD include a 3-axis accelerometer.
+      </li>
+    </ul>
+    <p>
+      If device implementations include a 3-axis accelerometer, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST be able to report events up to a frequency of at least 50 Hz.
+      </li>
+      <li>[C-1-2] MUST implement and report <a href="http://developer.android.com/reference/android/hardware/Sensor.html#TYPE_ACCELEROMETER"><code>TYPE_ACCELEROMETER</code></a> sensor.
+      </li>
+      <li>[C-1-3] MUST comply with the <a href="http://developer.android.com/reference/android/hardware/SensorEvent.html">Android sensor coordinate system</a> as detailed in the Android APIs.
+      </li>
+      <li>[C-1-4] MUST be capable of measuring from freefall up to four times the gravity(4g) or more on any axis.
+      </li>
+      <li>[C-1-5] MUST have a resolution of at least 12-bits.
+      </li>
+      <li>[C-1-6] MUST have a standard deviation no greater than 0.05 m/s^, where the standard deviation should be calculated on a per axis basis on samples collected over a period of at least 3 seconds at the fastest sampling rate.
+      </li>
+      <li>[SR] are <strong>STRONGLY RECOMMENDED</strong> to implement the <code>TYPE_SIGNIFICANT_MOTION</code> composite sensor.
+      </li>
+      <li>[SR] are STRONGLY RECOMMENDED to implement the <code>TYPE_ACCELEROMETER_UNCALIBRATED</code> sensor if online accelerometer calibration is available.
+      </li>
+      <li>SHOULD implement the <code>TYPE_SIGNIFICANT_MOTION</code>, <code>TYPE_TILT_DETECTOR</code>, <code>TYPE_STEP_DETECTOR</code>, <code>TYPE_STEP_COUNTER</code> composite sensors as described in the Android SDK document.
+      </li>
+      <li>SHOULD report events up to at least 200 Hz.
+      </li>
+      <li>SHOULD have a resolution of at least 16-bits.
+      </li>
+      <li>SHOULD be calibrated while in use if the characteristics changes over the life cycle and compensated, and preserve the compensation parameters between device reboots.
+      </li>
+      <li>SHOULD be temperature compensated.
+      </li>
+      <li>SHOULD also implement <a href="https://developer.android.com/reference/android/hardware/Sensor.html#STRING_TYPE_ACCELEROMETER_UNCALIBRATED"><code>TYPE_ACCELEROMETER_UNCALIBRATED</code></a> sensor.
+      </li>
+    </ul>
+    <p>
+      If device implementations include a 3-axis accelerometer and any of the <code>TYPE_SIGNIFICANT_MOTION</code>, <code>TYPE_TILT_DETECTOR</code>, <code>TYPE_STEP_DETECTOR</code>, <code>TYPE_STEP_COUNTER</code> composite sensors are implemented:
+    </p>
+    <ul>
+      <li>[C-2-1] The sum of their power consumption MUST always be less than 4 mW.
+      </li>
+      <li>SHOULD each be below 2 mW and 0.5 mW for when the device is in a dynamic or static condition.
+      </li>
+    </ul>
+    <p>
+      If device implementations include a 3-axis accelerometer and a gyroscope sensor, they:
+    </p>
+    <ul>
+      <li>[C-3-1] MUST implement the <code>TYPE_GRAVITY</code> and <code>TYPE_LINEAR_ACCELERATION</code> composite sensors.
+      </li>
+      <li>SHOULD implement the <code>TYPE_GAME_ROTATION_VECTOR</code> composite sensor.
+      </li>
+      <li>[SR] Existing and new Android devices are STRONGLY RECOMMENDED to implement the <code>TYPE_GAME_ROTATION_VECTOR</code> sensor.
+      </li>
+    </ul>
+    <p>
+      If device implementations include a 3-axis accelerometer, a gyroscope sensor and a magnetometer sensor, they:
+    </p>
+    <ul>
+      <li>[C-4-1] MUST implement a <code>TYPE_ROTATION_VECTOR</code> composite sensor.
+      </li>
+    </ul>
+    <h4 id="7_3_2_magnetometer">
+      7.3.2. Magnetometer
+    </h4>
+    <ul>
+      <li>Device implementations SHOULD include a 3-axis magnetometer (compass).
+      </li>
+    </ul>
+    <p>
+      If device impelementations include a 3-axis magnetometer, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST implement the <code>TYPE_MAGNETIC_FIELD</code> sensor.
+      </li>
+      <li>[C-1-2] MUST be able to report events up to a frequency of at least 10 Hz and SHOULD report events up to at least 50 Hz.
+      </li>
+      <li>[C-1-3] MUST comply with the <a href="http://developer.android.com/reference/android/hardware/SensorEvent.html">Android sensor coordinate system</a> as detailed in the Android APIs.
+      </li>
+      <li>[C-1-4] MUST be capable of measuring between -900 µT and +900 µT on each axis before saturating.
+      </li>
+      <li>[C-1-5] MUST have a hard iron offset value less than 700 µT and SHOULD have a value below 200 µT, by placing the magnetometer far from dynamic (current-induced) and static (magnet-induced) magnetic fields.
+      </li>
+      <li>[C-1-6] MUST have a resolution equal or denser than 0.6 µT.
+      </li>
+      <li>[C-1-7] MUST support online calibration and compensation of the hard iron bias, and preserve the compensation parameters between device reboots.
+      </li>
+      <li>[C-1-8] MUST have the soft iron compensation applied—the calibration can be done either while in use or during the production of the device.
+      </li>
+      <li>[C-1-9] MUST have a standard deviation, calculated on a per axis basis on samples collected over a period of at least 3 seconds at the fastest sampling rate, no greater than 1.5 µT; SHOULD have a standard deviation no greater than 0.5 µT.
+      </li>
+      <li>SHOULD implement <code>TYPE_MAGNETIC_FIELD_UNCALIBRATED</code> sensor.
+      </li>
+      <li>[SR] Existing and new Android devices are STRONGLY RECOMMENDED to implement the <code>TYPE_MAGNETIC_FIELD_UNCALIBRATED</code> sensor.
+      </li>
+    </ul>
+    <p>
+      If device impelementations include a 3-axis magnetometer, an accelerometer sensor and a gyroscope sensor, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST implement a <code>TYPE_ROTATION_VECTOR</code> composite sensor.
+      </li>
+    </ul>
+    <p>
+      If device impelementations include a 3-axis magnetometer, an accelerometer, they:
+    </p>
+    <ul>
+      <li>MAY implement the <code>TYPE_GEOMAGNETIC_ROTATION_VECTOR</code> sensor.
+      </li>
+    </ul>
+    <p>
+      If device impelementations include a 3-axis magnetometer, an accelerometer and <code>TYPE_GEOMAGNETIC_ROTATION_VECTOR</code> sensor, they:
+    </p>
+    <ul>
+      <li>[C-3-1] MUST consume less than 10 mW.
+      </li>
+      <li>SHOULD consume less than 3 mW when the sensor is registered for batch mode at 10 Hz.
+      </li>
+    </ul>
+    <h4 id="7_3_3_gps">
+      7.3.3. GPS
+    </h4>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>SHOULD include a GPS/GNSS receiver.
+      </li>
+    </ul>
+    <p>
+      If device implementations include a GPS/GNSS receiver and report the capability to applications through the <code>android.hardware.location.gps</code> feature flag, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support location outputs at a rate of at least 1 Hz when requested via <code>LocationManager#requestLocationUpdate</code>.
+      </li>
+      <li>[C-1-2] MUST be able to determine the location in open-sky conditions (strong signals, negligible multipath, HDOP &lt; 2) within 10 seconds (fast time to first fix), when connected to a 0.5 Mbps or faster data speed internet connection. This requirement is typically met by the use of some form of Assisted or Predicted GPS/GNSS technique to minimize GPS/GNSS lock-on time (Assistance data includes Reference Time, Reference Location and Satellite Ephemeris/Clock).
+        <ul>
+          <li>[SR] After making such a location calculation, it is STRONGLY RECOMMENDED for the device to be able to determine its location, in open sky, within 10 seconds, when location requests are restarted, up to an hour after the initial location calculation, even when the subsequent request is made without a data connection, and/or after a power cycle.
+          </li>
+        </ul>
+      </li>
+      <li>
+        <p>
+          In open sky conditions after determining the location, while stationary or moving with less than 1 meter per second squared of acceleration:
+        </p>
+        <ul>
+          <li>[C-1-3] MUST be able to determine location within 20 meters, and speed within 0.5 meters per second, at least 95% of the time.
+          </li>
+          <li>[C-1-4] MUST simultaneously track and report via <a href="https://developer.android.com/reference/android/location/GnssStatus.Callback.html#GnssStatus.Callback()'"><code>GnssStatus.Callback</code></a> at least 8 satellites from one constellation.
+          </li>
+          <li>SHOULD be able to simultaneously track at least 24 satellites, from multiple constellations (e.g. GPS + at least one of Glonass, Beidou, Galileo).
+          </li>
+          <li>[C-1-5] MUST report the GNSS technology generation through the test API ‘getGnssYearOfHardware’.
+          </li>
+          <li>[SR] Continue to deliver normal GPS/GNSS location outputs during an emergency phone call.
+          </li>
+          <li>[SR] Report GNSS measurements from all constellations tracked (as reported in GnssStatus messages), with the exception of SBAS.
+          </li>
+          <li>[SR] Report AGC, and Frequency of GNSS measurement.
+          </li>
+          <li>[SR] Report all accuracy estimates (including Bearing, Speed, and Vertical) as part of each GPS Location.
+          </li>
+          <li>[SR] are STRONGLY RECOMMENDED to meet as many as possible from the additional mandatory requirements for devices reporting the year "2016" or "2017" through the Test API <code>LocationManager.getGnssYearOfHardware()</code>.
+          </li>
+        </ul>
+      </li>
+    </ul>
+    <p>
+      If device implementations include a GPS/GNSS receiver and report the capability to applications through the <code>android.hardware.location.gps</code> feature flag and the <code>LocationManager.getGnssYearOfHardware()</code> Test API reports the year "2016" or newer, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST report GPS measurements, as soon as they are found, even if a location calculated from GPS/GNSS is not yet reported.
+      </li>
+      <li>[C-2-2] MUST report GPS pseudoranges and pseudorange rates, that, in open-sky conditions after determining the location, while stationary or moving with less than 0.2 meter per second squared of acceleration, are sufficient to calculate position within 20 meters, and speed within 0.2 meters per second, at least 95% of the time.
+      </li>
+    </ul>
+    <p>
+      If device implementations include a GPS/GNSS receiver and report the capability to applications through the <code>android.hardware.location.gps</code> feature flag and the <code>LocationManager.getGnssYearOfHardware()</code> Test API reports the year "2017" or newer, they:
+    </p>
+    <ul>
+      <li>[C-3-1] MUST continue to deliver normal GPS/GNSS location outputs during an emergency phone call.
+      </li>
+      <li>[C-3-2] MUST report GNSS measurements from all constellations tracked (as reported in GnssStatus messages), with the exception of SBAS.
+      </li>
+      <li>[C-3-3] MUST report AGC, and Frequency of GNSS measurement.
+      </li>
+      <li>[C-3-4] MUST report all accuracy estimates (including Bearing, Speed, and Vertical) as part of each GPS Location.
+      </li>
+    </ul>
+    <h4 id="7_3_4_gyroscope">
+      7.3.4. Gyroscope
+    </h4>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>SHOULD include a gyroscope (angular change sensor).
+      </li>
+      <li>SHOULD NOT include a gyroscope sensor unless a 3-axis accelerometer is also included.
+      </li>
+    </ul>
+    <p>
+      If device implementations include a gyroscope, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST be able to report events up to a frequency of at least 50 Hz.
+      </li>
+      <li>[C-1-2] MUST implement the <code>TYPE_GYROSCOPE</code> sensor and SHOULD also implement <code>TYPE_GYROSCOPE_UNCALIBRATED</code> sensor.
+      </li>
+      <li>[C-1-3] MUST be capable of measuring orientation changes up to 1,000 degrees per second.
+      </li>
+      <li>[C-1-4] MUST have a resolution of 12-bits or more and SHOULD have a resolution of 16-bits or more.
+      </li>
+      <li>[C-1-5] MUST be temperature compensated.
+      </li>
+      <li>[C-1-6] MUST be calibrated and compensated while in use, and preserve the compensation parameters between device reboots.
+      </li>
+      <li>[C-1-7] MUST have a variance no greater than 1e-7 rad^2 / s^2 per Hz (variance per Hz, or rad^2 / s). The variance is allowed to vary with the sampling rate, but MUST be constrained by this value. In other words, if you measure the variance of the gyro at 1 Hz sampling rate it SHOULD be no greater than 1e-7 rad^2/s^2.
+      </li>
+      <li>[SR] Existing and new Android devices are STRONGLY RECOMMENDED to implement the <code>SENSOR_TYPE_GYROSCOPE_UNCALIBRATED</code> sensor.
+      </li>
+      <li>[SR] Calibration error is STRONGLY RECOMMENDED to be less than 0.01 rad/s when device is stationary at room temperature.
+      </li>
+      <li>SHOULD report events up to at least 200 Hz.
+      </li>
+    </ul>
+    <p>
+      If device implementations include a gyroscope, an accelerometer sensor and a magnetometer sensor, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST implement a <code>TYPE_ROTATION_VECTOR</code> composite sensor.
+      </li>
+    </ul>
+    <p>
+      If device implementations include a gyroscope and a accelerometer sensor, they:
+    </p>
+    <ul>
+      <li>[C-3-1] MUST implement the <code>TYPE_GRAVITY</code> and <code>TYPE_LINEAR_ACCELERATION</code> composite sensors.
+      </li>
+      <li>[SR] Existing and new Android devices are STRONGLY RECOMMENDED to implement the <code>TYPE_GAME_ROTATION_VECTOR</code> sensor.
+      </li>
+      <li>SHOULD implement the <code>TYPE_GAME_ROTATION_VECTOR</code> composite sensor.
+      </li>
+    </ul>
+    <h4 id="7_3_5_barometer">
+      7.3.5. Barometer
+    </h4>
+    <ul>
+      <li>Device implementations SHOULD include a barometer (ambient air pressure sensor).
+      </li>
+    </ul>
+    <p>
+      If device implementations include a barometer, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST implement and report <code>TYPE_PRESSURE</code> sensor.
+      </li>
+      <li>[C-1-2] MUST be able to deliver events at 5 Hz or greater.
+      </li>
+      <li>[C-1-3] MUST be temperature compensated.
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to be able to report pressure measurements in the range 300hPa to 1100hPa.
+      </li>
+      <li>SHOULD have an absolute accuracy of 1hPa.
+      </li>
+      <li>SHOULD have a relative accuracy of 0.12hPa over 20hPa range (equivalent to ~1m accuracy over ~200m change at sea level).
+      </li>
+    </ul>
+    <h4 id="7_3_6_thermometer">
+      7.3.6. Thermometer
+    </h4>
+    <p>
+      Device implementations: <em>MAY include an ambient thermometer (temperature sensor).</em> MAY but SHOULD NOT include a CPU temperature sensor.
+    </p>
+    <p>
+      If device implementations include an ambient thermometer (temperature sensor), they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST be defined as <code>SENSOR_TYPE_AMBIENT_TEMPERATURE</code> and MUST measure the ambient (room/vehicle cabin) temperature from where the user is interacting with the device in degrees Celsius.
+      </li>
+      <li>[C-1-2] MUST be defined as <code>SENSOR_TYPE_TEMPERATURE</code>.
+      </li>
+      <li>[C-1-3] MUST measure the temperature of the device CPU.
+      </li>
+      <li>[C-1-4] MUST NOT measure any other temperature.
+      </li>
+    </ul>
+    <p>
+      Note the <code>SENSOR_TYPE_TEMPERATURE</code> sensor type was deprecated in Android 4.0.
+    </p>
+    <h4 id="7_3_7_photometer">
+      7.3.7. Photometer
+    </h4>
+    <ul>
+      <li>Device implementations MAY include a photometer (ambient light sensor).
+      </li>
+    </ul>
+    <h4 id="7_3_8_proximity_sensor">
+      7.3.8. Proximity Sensor
+    </h4>
+    <ul>
+      <li>Device implementations MAY include a proximity sensor.
+      </li>
+    </ul>
+    <p>
+      If device implementations include a proximity sensor, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST measure the proximity of an object in the same direction as the screen. That is, the proximity sensor MUST be oriented to detect objects close to the screen, as the primary intent of this sensor type is to detect a phone in use by the user. If device implementations include a proximity sensor with any other orientation, it MUST NOT be accessible through this API.
+      </li>
+      <li>[C-1-2] MUST have 1-bit of accuracy or more.
+      </li>
+    </ul>
+    <h4 id="7_3_9_high_fidelity_sensors">
+      7.3.9. High Fidelity Sensors
+    </h4>
+    <p>
+      If device implementations include a set of higher quality sensors as defined in this section, and make available them to third-party apps, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST identify the capability through the <code>android.hardware.sensor.hifi_sensors</code> feature flag.
+      </li>
+    </ul>
+    <p>
+      If device implementations declare <code>android.hardware.sensor.hifi_sensors</code>, they:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-2-1] MUST have a <code>TYPE_ACCELEROMETER</code> sensor which:
+        </p>
+        <ul>
+          <li>MUST have a measurement range between at least -8g and +8g.
+          </li>
+          <li>MUST have a measurement resolution of at least 1024 LSB/G.
+          </li>
+          <li>MUST have a minimum measurement frequency of 12.5 Hz or lower.
+          </li>
+          <li>MUST have a maximum measurement frequency of 400 Hz or higher.
+          </li>
+          <li>MUST have a measurement noise not above 400 uG/√Hz.
+          </li>
+          <li>MUST implement a non-wake-up form of this sensor with a buffering capability of at least 3000 sensor events.
+          </li>
+          <li>MUST have a batching power consumption not worse than 3 mW.
+          </li>
+          <li>SHOULD have a stationary noise bias stability of \&lt;15 μg √Hz from 24hr static dataset.
+          </li>
+          <li>SHOULD have a bias change vs. temperature of ≤ +/- 1mg / °C.
+          </li>
+          <li>SHOULD have a best-fit line non-linearity of ≤ 0.5%, and sensitivity change vs. temperature of ≤ 0.03%/C°.
+          </li>
+          <li>SHOULD have white noise spectrum to ensure adequate qualification of sensor’s noise integrity.
+          </li>
+        </ul>
+      </li>
+      <li>
+        <p>
+          [C-2-2] MUST have a <code>TYPE_ACCELEROMETER_UNCALIBRATED</code> with the same quality requirements as <code>TYPE_ACCELEROMETER</code>.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-2-3] MUST have a <code>TYPE_GYROSCOPE</code> sensor which:
+        </p>
+        <ul>
+          <li>MUST have a measurement range between at least -1000 and +1000 dps.
+          </li>
+          <li>MUST have a measurement resolution of at least 16 LSB/dps.
+          </li>
+          <li>MUST have a minimum measurement frequency of 12.5 Hz or lower.
+          </li>
+          <li>MUST have a maximum measurement frequency of 400 Hz or higher.
+          </li>
+          <li>MUST have a measurement noise not above 0.014°/s/√Hz.
+          </li>
+          <li>SHOULD have a stationary bias stability of &lt; 0.0002 °/s √Hz from 24-hour static dataset.
+          </li>
+          <li>SHOULD have a bias change vs. temperature of ≤ +/- 0.05 °/ s / °C.
+          </li>
+          <li>SHOULD have a sensitivity change vs. temperature of ≤ 0.02% / °C.
+          </li>
+          <li>SHOULD have a best-fit line non-linearity of ≤ 0.2%.
+          </li>
+          <li>SHOULD have a noise density of ≤ 0.007 °/s/√Hz.
+          </li>
+          <li>SHOULD have white noise spectrum to ensure adequate qualification of sensor’s noise integrity.
+          </li>
+          <li>SHOULD have calibration error less than 0.002 rad/s in temperature range 10 ~ 40 ℃ when device is stationary.
+          </li>
+        </ul>
+      </li>
+      <li>
+        <p>
+          [C-2-4] MUST have a <code>TYPE_GYROSCOPE_UNCALIBRATED</code> with the same quality requirements as <code>TYPE_GYROSCOPE</code>.
+        </p>
+      </li>
+      <li>[C-2-5] MUST have a <code>TYPE_GEOMAGNETIC_FIELD</code> sensor which:
+        <ul>
+          <li>MUST have a measurement range between at least -900 and +900 uT.
+          </li>
+          <li>MUST have a measurement resolution of at least 5 LSB/uT.
+          </li>
+          <li>MUST have a minimum measurement frequency of 5 Hz or lower.
+          </li>
+          <li>MUST have a maximum measurement frequency of 50 Hz or higher.
+          </li>
+          <li>MUST have a measurement noise not above 0.5 uT.
+          </li>
+        </ul>
+      </li>
+      <li>[C-2-6] MUST have a <code>TYPE_MAGNETIC_FIELD_UNCALIBRATED</code> with the same quality requirements as <code>TYPE_GEOMAGNETIC_FIELD</code> and in addition:
+        <ul>
+          <li>MUST implement a non-wake-up form of this sensor with a buffering capability of at least 600 sensor events.
+          </li>
+          <li>SHOULD have white noise spectrum to ensure adequate qualification of sensor’s noise integrity.
+          </li>
+        </ul>
+      </li>
+      <li>[C-2-7] MUST have a <code>TYPE_PRESSURE</code> sensor which:
+        <ul>
+          <li>MUST have a measurement range between at least 300 and 1100 hPa.
+          </li>
+          <li>MUST have a measurement resolution of at least 80 LSB/hPa.
+          </li>
+          <li>MUST have a minimum measurement frequency of 1 Hz or lower.
+          </li>
+          <li>MUST have a maximum measurement frequency of 10 Hz or higher.
+          </li>
+          <li>MUST have a measurement noise not above 2 Pa/√Hz.
+          </li>
+          <li>MUST implement a non-wake-up form of this sensor with a buffering capability of at least 300 sensor events.
+          </li>
+          <li>MUST have a batching power consumption not worse than 2 mW.
+          </li>
+        </ul>
+      </li>
+      <li>[C-2-8] MUST have a <code>TYPE_GAME_ROTATION_VECTOR</code> sensor which:
+        <ul>
+          <li>MUST implement a non-wake-up form of this sensor with a buffering capability of at least 300 sensor events.
+          </li>
+          <li>MUST have a batching power consumption not worse than 4 mW.
+          </li>
+        </ul>
+      </li>
+      <li>[C-2-9] MUST have a <code>TYPE_SIGNIFICANT_MOTION</code> sensor which:
+        <ul>
+          <li>MUST have a power consumption not worse than 0.5 mW when device is static and 1.5 mW when device is moving.
+          </li>
+        </ul>
+      </li>
+      <li>[C-2-10] MUST have a <code>TYPE_STEP_DETECTOR</code> sensor which:
+        <ul>
+          <li>MUST implement a non-wake-up form of this sensor with a buffering capability of at least 100 sensor events.
+          </li>
+          <li>MUST have a power consumption not worse than 0.5 mW when device is static and 1.5 mW when device is moving.
+          </li>
+          <li>MUST have a batching power consumption not worse than 4 mW.
+          </li>
+        </ul>
+      </li>
+      <li>[C-2-11] MUST have a <code>TYPE_STEP_COUNTER</code> sensor which:
+        <ul>
+          <li>MUST have a power consumption not worse than 0.5 mW when device is static and 1.5 mW when device is moving.
+          </li>
+        </ul>
+      </li>
+      <li>[C-2-12] MUST have a <code>TILT_DETECTOR</code> sensor which:
+        <ul>
+          <li>MUST have a power consumption not worse than 0.5 mW when device is static and 1.5 mW when device is moving.
+          </li>
+        </ul>
+      </li>
+      <li>[C-2-13] The event timestamp of the same physical event reported by the Accelerometer, Gyroscope sensor and Magnetometer MUST be within 2.5 milliseconds of each other.
+      </li>
+      <li>[C-2-14] MUST have Gyroscope sensor event timestamps on the same time base as the camera subsystem and within 1 milliseconds of error.
+      </li>
+      <li>[C-2-15] MUST deliver samples to applications within 5 milliseconds from the time when the data is available on any of the above physical sensors to the application.
+      </li>
+      <li>[C-2-16] MUST not have a power consumption higher than 0.5 mW when device is static and 2.0 mW when device is moving when any combination of the following sensors are enabled:
+        <ul>
+          <li>
+            <code>SENSOR_TYPE_SIGNIFICANT_MOTION</code>
+          </li>
+          <li>
+            <code>SENSOR_TYPE_STEP_DETECTOR</code>
+          </li>
+          <li>
+            <code>SENSOR_TYPE_STEP_COUNTER</code>
+          </li>
+          <li>
+            <code>SENSOR_TILT_DETECTORS</code>
+          </li>
+        </ul>
+      </li>
+      <li>[C-2-17] MAY have a <code>TYPE_PROXIMITY</code> sensor, but if present MUST have a minimum buffer capability of 100 sensor events.
+      </li>
+    </ul>
+    <p>
+      Note that all power consumption requirements in this section do not include the power consumption of the Application Processor. It is inclusive of the power drawn by the entire sensor chain—the sensor, any supporting circuitry, any dedicated sensor processing system, etc.
+    </p>
+    <p>
+      If device implementations include direct sensor support, they:
+    </p>
+    <ul>
+      <li>[C-3-1] MUST correctly declare support of direct channel types and direct report rates level through the <a href="https://developer.android.com/reference/android/hardware/Sensor.html#isDirectChannelTypeSupported%28int%29"><code>isDirectChannelTypeSupported</code></a> and <a href="https://developer.android.com/reference/android/hardware/Sensor.html#getHighestDirectReportRateLevel%28%29"><code>getHighestDirectReportRateLevel</code></a> API.
+      </li>
+      <li>[C-3-2] MUST support at least one of the two sensor direct channel types for all sensors that declare support for sensor direct channel:
+        <ul>
+          <li>
+            <a href="https://developer.android.com/reference/android/hardware/SensorDirectChannel.html#TYPE_HARDWARE_BUFFER"><code>TYPE_HARDWARE_BUFFER</code></a>
+          </li>
+          <li>
+            <a href="https://developer.android.com/reference/android/hardware/SensorDirectChannel.html#TYPE_MEMORY_FILE"><code>TYPE_MEMORY_FILE</code></a>
+          </li>
+        </ul>
+      </li>
+      <li>SHOULD support event reporting through sensor direct channel for primary sensor (non-wakeup variant) of the following types:
+        <ul>
+          <li>
+            <code>TYPE_ACCELEROMETER</code>
+          </li>
+          <li>
+            <code>TYPE_ACCELEROMETER_UNCALIBRATED</code>
+          </li>
+          <li>
+            <code>TYPE_GYROSCOPE</code>
+          </li>
+          <li>
+            <code>TYPE_GYROSCOPE_UNCALIBRATED</code>
+          </li>
+          <li>
+            <code>TYPE_MAGNETIC_FIELD</code>
+          </li>
+          <li>
+            <code>TYPE_MAGNETIC_FIELD_UNCALIBRATED</code>
+          </li>
+        </ul>
+      </li>
+    </ul>
+    <h4 id="7_3_10_fingerprint_sensor">
+      7.3.10. Fingerprint Sensor
+    </h4>
+    <p>
+      If device implementations include a secure lock screen, they:
+    </p>
+    <ul>
+      <li>SHOULD include a fingerprint sensor.
+      </li>
+    </ul>
+    <p>
+      If device implementations include a fingerprint sensor and make the sensor available to third-party apps, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST declare support for the <code>android.hardware.fingerprint</code> feature.
+      </li>
+      <li>[C-1-2] MUST fully implement the <a href="https://developer.android.com/reference/android/hardware/fingerprint/package-summary.html">corresponding API</a> as described in the Android SDK documentation.
+      </li>
+      <li>[C-1-3] MUST have a false acceptance rate not higher than 0.002%.
+      </li>
+      <li>[C-1-4] MUST rate limit attempts for at least 30 seconds after five false trials for fingerprint verification.
+      </li>
+      <li>[C-1-5] MUST have a hardware-backed keystore implementation, and perform the fingerprint matching in a Trusted Execution Environment (TEE) or on a chip with a secure channel to the TEE.
+      </li>
+      <li>[C-1-6] MUST have all identifiable fingerprint data encrypted and cryptographically authenticated such that they cannot be acquired, read or altered outside of the Trusted Execution Environment (TEE) as documented in the <a href="https://source.android.com/devices/tech/security/authentication/fingerprint-hal.html">implementation guidelines</a> on the Android Open Source Project site.
+      </li>
+      <li>[C-1-7] MUST prevent adding a fingerprint without first establishing a chain of trust by having the user confirm existing or add a new device credential (PIN/pattern/password) that's secured by TEE; the Android Open Source Project implementation provides the mechanism in the framework to do so.
+      </li>
+      <li>[C-1-8] MUST NOT enable 3rd-party applications to distinguish between individual fingerprints.
+      </li>
+      <li>[C-1-9] MUST honor the DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT flag.
+      </li>
+      <li>[C-1-10] MUST, when upgraded from a version earlier than Android 6.0, have the fingerprint data securely migrated to meet the above requirements or removed.
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to have a false rejection rate of less than 10%, as measured on the device.
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to have a latency below 1 second, measured from when the fingerprint sensor is touched until the screen is unlocked, for one enrolled finger.
+      </li>
+      <li>SHOULD use the Android Fingerprint icon provided in the Android Open Source Project.
+      </li>
+    </ul>
+    <h4 id="7_3_11_android_automotive-only_sensors">
+      7.3.11. Android Automotive-only sensors
+    </h4>
+    <p>
+      Automotive-specific sensors are defined in the <code>android.car.CarSensorManager API</code>.
+    </p>
+    <h5 id="7_3_11_1_current_gear">
+      7.3.11.1. Current Gear
+    </h5>
+    <p>
+      See <a href="#2_5_1_hardware">Section 2.5.1</a> for device-specific requirements.
+    </p>
+    <h5 id="7_3_11_2_day_night_mode">
+      7.3.11.2. Day Night Mode
+    </h5>
+    <p>
+      See <a href="#2_5_1_hardware">Section 2.5.1</a> for device-specific requirements.
+    </p>
+    <h5 id="7_3_11_3_driving_status">
+      7.3.11.3. Driving Status
+    </h5>
+    <p>
+      See <a href="#2_5_1_hardware">Section 2.5.1</a> for device-specific requirements.
+    </p>
+    <h5 id="7_3_11_4_wheel_speed">
+      7.3.11.4. Wheel Speed
+    </h5>
+    <p>
+      See <a href="#2_5_1_hardware">Section 2.5.1</a> for device-specific requirements.
+    </p>
+    <h3 id="7_3_12_pose_sensor">
+      7.3.12. Pose Sensor
+    </h3>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>MAY support pose sensor with 6 degrees of freedom.
+      </li>
+    </ul>
+    <p>
+      If device implementations support pose sensor with 6 degrees of freedom, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST implement and report <a href="https://developer.android.com/reference/android/hardware/Sensor.html#TYPE_POSE_6DOF"><code>TYPE_POSE_6DOF</code></a> sensor.
+      </li>
+      <li>[C-1-2] MUST be more accurate than the rotation vector alone.
+      </li>
+    </ul>
+    <h3 id="7_4_data_connectivity">
+      7.4. Data Connectivity
+    </h3>
+    <h4 id="7_4_1_telephony">
+      7.4.1. Telephony
+    </h4>
+    <p>
+      “Telephony” as used by the Android APIs and this document refers specifically to hardware related to placing voice calls and sending SMS messages via a GSM or CDMA network. While these voice calls may or may not be packet-switched, they are for the purposes of Android considered independent of any data connectivity that may be implemented using the same network. In other words, the Android “telephony” functionality and APIs refer specifically to voice calls and SMS. For instance, device implementations that cannot place calls or send/receive SMS messages are not considered a telephony device, regardless of whether they use a cellular network for data connectivity.
+    </p>
+    <ul>
+      <li>Android MAY be used on devices that do not include telephony hardware. That is, Android is compatible with devices that are not phones.
+      </li>
+    </ul>
+    <p>
+      If device implementations include GSM or CDMA telephony, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST declare the <code>android.hardware.telephony</code> feature flag and other sub-feature flags according to the technology.
+      </li>
+      <li>[C-1-2] MUST implement full support for the API for that technology.
+      </li>
+    </ul>
+    <p>
+      If device implementations do not include telephony hardware, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST implement the full APIs as no-ops.
+      </li>
+    </ul>
+    <h5 id="7_4_1_1_number_blocking_compatibility">
+      7.4.1.1. Number Blocking Compatibility
+    </h5>
+    <p>
+      If device implementations report the <code>android.hardware.telephony feature</code>, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST include number blocking support
+      </li>
+      <li>[C-1-2] MUST fully implement <a href="http://developer.android.com/reference/android/provider/BlockedNumberContract.html"><code>BlockedNumberContract</code></a> and the corresponding API as described in the SDK documentation.
+      </li>
+      <li>[C-1-3] MUST block all calls and messages from a phone number in 'BlockedNumberProvider' without any interaction with apps. The only exception is when number blocking is temporarily lifted as described in the SDK documentation.
+      </li>
+      <li>[C-1-4] MUST NOT write to the <a href="http://developer.android.com/reference/android/provider/CallLog.html">platform call log provider</a> for a blocked call.
+      </li>
+      <li>[C-1-5] MUST NOT write to the <a href="http://developer.android.com/reference/android/provider/Telephony.html">Telephony provider</a> for a blocked message.
+      </li>
+      <li>[C-1-6] MUST implement a blocked numbers management UI, which is opened with the intent returned by <code>TelecomManager.createManageBlockedNumbersIntent()</code> method.
+      </li>
+      <li>[C-1-7] MUST NOT allow secondary users to view or edit the blocked numbers on the device as the Android platform assumes the primary user to have full control of the telephony services, a single instance, on the device. All blocking related UI MUST be hidden for secondary users and the blocked list MUST still be respected.
+      </li>
+      <li>SHOULD migrate the blocked numbers into the provider when a device updates to Android 7.0.
+      </li>
+    </ul>
+    <h4 id="7_4_2_ieee_802_11_(wi-fi)">
+      7.4.2. IEEE 802.11 (Wi-Fi)
+    </h4>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>SHOULD include support for one or more forms of 802.11.
+      </li>
+    </ul>
+    <p>
+      If device implementations include support for 802.11 and expose the functionality to a third-party application, they
+    </p>
+    <ul>
+      <li>[C-1-1] MUST implement the corresponding Android API.
+      </li>
+      <li>[C-1-2] MUST report the hardware feature flag <code>android.hardware.wifi</code>.
+      </li>
+      <li>[C-1-3] MUST implement the <a href="http://developer.android.com/reference/android/net/wifi/WifiManager.MulticastLock.html">multicast API</a> as described in the SDK documentation.
+      </li>
+      <li>[C-1-4] MUST support multicast DNS (mDNS) and MUST NOT filter mDNS packets (224.0.0.251) at any time of operation including:
+        <ul>
+          <li>Even when the screen is not in an active state.
+          </li>
+          <li>For Android Television device implementations, even when in standby power states.
+          </li>
+        </ul>
+      </li>
+      <li>SHOULD randomize the source MAC address and sequence number of probe request frames, once at the beginning of each scan, while STA is disconnected.
+        <ul>
+          <li>Each group of probe request frames comprising one scan should use one consistent MAC address (SHOULD NOT randomize MAC address halfway through a scan).
+          </li>
+          <li>Probe request sequence number should iterate as normal (sequentially) between the probe requests in a scan
+          </li>
+          <li>Probe request sequence number should randomize between the last probe request of a scan and the first probe request of the next scan
+          </li>
+        </ul>
+      </li>
+      <li>SHOULD only allow the following information elements in probe request frames, while STA is disconnected:
+        <ul>
+          <li>SSID Parameter Set (0)
+          </li>
+          <li>DS Parameter Set (3)
+          </li>
+        </ul>
+      </li>
+    </ul>
+    <h5 id="7_4_2_1_wi-fi_direct">
+      7.4.2.1. Wi-Fi Direct
+    </h5>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>SHOULD include support for Wi-Fi Direct (Wi-Fi peer-to-peer).
+      </li>
+    </ul>
+    <p>
+      If device implementations include support for Wi-Fi Direct, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST implement the <a href="http://developer.android.com/reference/android/net/wifi/p2p/WifiP2pManager.html">corresponding Android API</a> as described in the SDK documentation.
+      </li>
+      <li>[C-1-2] MUST report the hardware feature <code>android.hardware.wifi.direct</code>.
+      </li>
+      <li>[C-1-3] MUST support regular Wi-Fi operation.
+      </li>
+      <li>SHOULD support Wi-Fi and Wi-Fi Direct operations concurrently.
+      </li>
+    </ul>
+    <h5 id="7_4_2_2_wi-fi_tunneled_direct_link_setup">
+      7.4.2.2. Wi-Fi Tunneled Direct Link Setup
+    </h5>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>SHOULD include support for <a href="http://developer.android.com/reference/android/net/wifi/WifiManager.html">Wi-Fi Tunneled Direct Link Setup (TDLS)</a> as described in the Android SDK Documentation.
+      </li>
+    </ul>
+    <p>
+      If device implementations include support for TDLS and TDLS is enabled by the WiFiManager API, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST declare support for TDLS through [<code>WifiManager.isTdlsSupported</code>] (https://developer.android.com/reference/android/net/wifi/WifiManager.html#isTdlsSupported%28%29).
+      </li>
+      <li>SHOULD use TDLS only when it is possible AND beneficial.
+      </li>
+      <li>SHOULD have some heuristic and NOT use TDLS when its performance might be worse than going through the Wi-Fi access point.
+      </li>
+    </ul>
+    <h5 id="7_4_2_3_wi-fi_aware">
+      7.4.2.3. Wi-Fi Aware
+    </h5>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>SHOULD include support for <a href="http://www.wi-fi.org/discover-wi-fi/wi-fi-aware">Wi-Fi Aware</a>.
+      </li>
+    </ul>
+    <p>
+      If device implementations include support for Wi-Fi Aware and expose the functionality to third-party apps, then they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST implement the <code>WifiAwareManager</code> APIs as described in the <a href="http://developer.android.com/reference/android/net/wifi/aware/WifiAwareManager.html">SDK documentation</a>.
+      </li>
+      <li>[C-1-2] MUST declare the <code>android.hardware.wifi.aware</code> feature flag.
+      </li>
+      <li>[C-1-3] MUST support Wi-Fi and Wi-Fi Aware operations concurrently.
+      </li>
+      <li>[C-1-4] MUST randomize the Wi-Fi Aware management interface address at intervals no longer then 30 minutes and whenever Wi-Fi Aware is enabled.
+      </li>
+    </ul>
+    <h5 id="7_4_2_4_wi-fi_passpoint">
+      7.4.2.4. Wi-Fi Passpoint
+    </h5>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>SHOULD include support for <a href="http://www.wi-fi.org/discover-wi-fi/wi-fi-certified-passpoint">Wi-Fi Passpoint</a>.
+      </li>
+    </ul>
+    <p>
+      If device implementations include support for Wi-Fi Passpoint, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST implement the Passpoint related <code>WifiManager</code> APIs as described in the <a href="http://developer.android.com/reference/android/net/wifi/WifiManager.html">SDK documentation</a>.
+      </li>
+      <li>[C-1-2] MUST support IEEE 802.11u standard, specifically related to Network Discovery and Selection, such as Generic Advertisement Service (GAS) and Access Network Query Protocol (ANQP).
+      </li>
+    </ul>
+    <p>
+      Conversely if device implementations do not include support for Wi-Fi Passpoint:
+    </p>
+    <ul>
+      <li>[C-2-1] The implementation of the Passpoint related <code>WifiManager</code> APIs MUST throw an <code>UnsupportedOperationException</code>.
+      </li>
+    </ul>
+    <h4 id="7_4_3_bluetooth">
+      7.4.3. Bluetooth
+    </h4>
+    <p>
+      If device implementations support Bluetooth Audio profile, they:
+    </p>
+    <ul>
+      <li>SHOULD support Advanced Audio Codecs and Bluetooth Audio Codecs (e.g. LDAC).
+      </li>
+    </ul>
+    <p>
+      If device implementations declare <code>android.hardware.vr.high_performance</code> feature, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support Bluetooth 4.2 and Bluetooth LE Data Length Extension.
+      </li>
+    </ul>
+    <p>
+      Android includes support for <a href="http://developer.android.com/reference/android/bluetooth/package-summary.html">Bluetooth and Bluetooth Low Energy</a>.
+    </p>
+    <p>
+      If device implementations include support for Bluetooth and Bluetooth Low Energy, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST declare the relevant platform features (<code>android.hardware.bluetooth</code> and <code>android.hardware.bluetooth_le</code> respectively) and implement the platform APIs.
+      </li>
+      <li>SHOULD implement relevant Bluetooth profiles such as A2DP, AVCP, OBEX, etc. as appropriate for the device.
+      </li>
+    </ul>
+    <p>
+      If device implementations include support for Bluetooth Low Energy, they:
+    </p>
+    <ul>
+      <li>[C-3-1] MUST declare the hardware feature <code>android.hardware.bluetooth_le</code>.
+      </li>
+      <li>[C-3-2] MUST enable the GATT (generic attribute profile) based Bluetooth APIs as described in the SDK documentation and <a href="http://developer.android.com/reference/android/bluetooth/package-summary.html">android.bluetooth</a>.
+      </li>
+      <li>[C-3-3] MUST report the correct value for <code>BluetoothAdapter.isOffloadedFilteringSupported()</code> to indicate whether the filtering logic for the <a href="https://developer.android.com/reference/android/bluetooth/le/ScanFilter.html">ScanFilter</a> API classes is implemented.
+      </li>
+      <li>[C-3-4] MUST report the correct value for <code>BluetoothAdapter.isMultipleAdvertisementSupported()</code> to indicate whether Low Energy Advertising is supported.
+      </li>
+      <li>SHOULD support offloading of the filtering logic to the bluetooth chipset when implementing the <a href="https://developer.android.com/reference/android/bluetooth/le/ScanFilter.html">ScanFilter API</a>.
+      </li>
+      <li>SHOULD support offloading of the batched scanning to the bluetooth chipset.
+      </li>
+      <li>
+        <p>
+          SHOULD support multi advertisement with at least 4 slots.
+        </p>
+      </li>
+      <li>
+        <p>
+          [SR] STRONGLY RECOMMENDED to implement a Resolvable Private Address (RPA) timeout no longer than 15 minutes and rotate the address at timeout to protect user privacy.
+        </p>
+      </li>
+    </ul>
+    <h4 id="7_4_4_near-field_communications">
+      7.4.4. Near-Field Communications
+    </h4>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>SHOULD include a transceiver and related hardware for Near-Field Communications (NFC).
+      </li>
+      <li>[C-0-1] MUST implement <code>android.nfc.NdefMessage</code> and <code>android.nfc.NdefRecord</code> APIs even if they do not include support for NFC or declare the <code>android.hardware.nfc</code> feature as the classes represent a protocol-independent data representation format.
+      </li>
+    </ul>
+    <p>
+      If device implementations include NFC hardware and plan to make it available to third-party apps, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST report the <code>android.hardware.nfc</code> feature from the <a href="http://developer.android.com/reference/android/content/pm/PackageManager.html"><code>android.content.pm.PackageManager.hasSystemFeature()</code> method</a>.
+      </li>
+      <li>MUST be capable of reading and writing NDEF messages via the following NFC standards as below:
+      </li>
+      <li>[C-1-2] MUST be capable of acting as an NFC Forum reader/writer (as defined by the NFC Forum technical specification NFCForum-TS-DigitalProtocol-1.0) via the following NFC standards:
+      </li>
+      <li>NfcA (ISO14443-3A)
+      </li>
+      <li>NfcB (ISO14443-3B)
+      </li>
+      <li>NfcF (JIS X 6319-4)
+      </li>
+      <li>IsoDep (ISO 14443-4)
+      </li>
+      <li>NFC Forum Tag Types 1, 2, 3, 4, 5 (defined by the NFC Forum)
+      </li>
+      <li>
+        <p>
+          [SR] STRONGLY RECOMMENDED to be capable of reading and writing NDEF messages as well as raw data via the following NFC standards. Note that while the NFC standards are stated as STRONGLY RECOMMENDED, the Compatibility Definition for a future version is planned to change these to MUST. These standards are optional in this version but will be required in future versions. Existing and new devices that run this version of Android are very strongly encouraged to meet these requirements now so they will be able to upgrade to the future platform releases.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-1-3] MUST be capable of transmitting and receiving data via the following peer-to-peer standards and protocols:
+        </p>
+      </li>
+      <li>ISO 18092
+      </li>
+      <li>LLCP 1.2 (defined by the NFC Forum)
+      </li>
+      <li>SDP 1.0 (defined by the NFC Forum)
+      </li>
+      <li>
+        <a href="http://static.googleusercontent.com/media/source.android.com/en/us/compatibility/ndef-push-protocol.pdf">NDEF Push Protocol</a>
+      </li>
+      <li>SNEP 1.0 (defined by the NFC Forum)
+      </li>
+      <li>[C-1-4] MUST include support for <a href="http://developer.android.com/guide/topics/connectivity/nfc/nfc.html">Android Beam</a> and SHOULD enable Android Beam by default.
+      </li>
+      <li>[C-1-5] MUST be able to send and receive using Android Beam, when Android Beam is enabled or another proprietary NFC P2p mode is turned on.
+      </li>
+      <li>[C-1-6] MUST implement the SNEP default server. Valid NDEF messages received by the default SNEP server MUST be dispatched to applications using the <code>android.nfc.ACTION_NDEF_DISCOVERED</code> intent. Disabling Android Beam in settings MUST NOT disable dispatch of incoming NDEF message.
+      </li>
+      <li>[C-1-7] MUST honor the <code>android.settings.NFCSHARING_SETTINGS</code> intent to show <a href="http://developer.android.com/reference/android/provider/Settings.html#ACTION_NFCSHARING_SETTINGS">NFC sharing settings</a>.
+      </li>
+      <li>[C-1-8] MUST implement the NPP server. Messages received by the NPP server MUST be processed the same way as the SNEP default server.
+      </li>
+      <li>[C-1-9] MUST implement a SNEP client and attempt to send outbound P2P NDEF to the default SNEP server when Android Beam is enabled. If no default SNEP server is found then the client MUST attempt to send to an NPP server.
+      </li>
+      <li>[C-1-10] MUST allow foreground activities to set the outbound P2P NDEF message using <code>android.nfc.NfcAdapter.setNdefPushMessage</code>, and <code>android.nfc.NfcAdapter.setNdefPushMessageCallback</code>, and <code>android.nfc.NfcAdapter.enableForegroundNdefPush</code>.
+      </li>
+      <li>SHOULD use a gesture or on-screen confirmation, such as 'Touch to Beam', before sending outbound P2P NDEF messages.
+      </li>
+      <li>[C-1-11] MUST support NFC Connection handover to Bluetooth when the device supports Bluetooth Object Push Profile.
+      </li>
+      <li>[C-1-12] MUST support connection handover to Bluetooth when using <code>android.nfc.NfcAdapter.setBeamPushUris</code>, by implementing the “<a href="http://members.nfc-forum.org/specs/spec_list/#conn_handover">Connection Handover version 1.2</a>” and “<a href="http://members.nfc-forum.org/apps/group_public/download.php/18688/NFCForum-AD-BTSSP_1_1.pdf">Bluetooth Secure Simple Pairing Using NFC version 1.0</a>” specs from the NFC Forum. Such an implementation MUST implement the handover LLCP service with service name “urn:nfc:sn:handover” for exchanging the handover request/select records over NFC, and it MUST use the Bluetooth Object Push Profile for the actual Bluetooth data transfer. For legacy reasons (to remain compatible with Android 4.1 devices), the implementation SHOULD still accept SNEP GET requests for exchanging the handover request/select records over NFC. However an implementation itself SHOULD NOT send SNEP GET requests for performing connection handover.
+      </li>
+      <li>[C-1-13] MUST poll for all supported technologies while in NFC discovery mode.
+      </li>
+      <li>SHOULD be in NFC discovery mode while the device is awake with the screen active and the lock-screen unlocked.
+      </li>
+      <li>SHOULD be capable of reading the barcode and URL (if encoded) of <a href="http://developer.android.com/reference/android/nfc/tech/NfcBarcode.html">Thinfilm NFC Barcode</a> products.
+      </li>
+    </ul>
+    <p>
+      (Note that publicly available links are not available for the JIS, ISO, and NFC Forum specifications cited above.)
+    </p>
+    <p>
+      Android includes support for NFC Host Card Emulation (HCE) mode.
+    </p>
+    <p>
+      If device implementations include an NFC controller chipset capable of HCE (for NfcA and/or NfcB) and support Application ID (AID) routing, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST report the <code>android.hardware.nfc.hce</code> feature constant.
+      </li>
+      <li>[C-2-2] MUST support <a href="http://developer.android.com/guide/topics/connectivity/nfc/hce.html">NFC HCE APIs</a> as defined in the Android SDK.
+      </li>
+    </ul>
+    <p>
+      If device implementations include an NFC controller chipset capable of HCE for NfcF, and implement the feature for third-party applications, they:
+    </p>
+    <ul>
+      <li>[C-3-1] MUST report the <code>android.hardware.nfc.hcef</code> feature constant.
+      </li>
+      <li>[C-3-2] MUST implement the [NfcF Card Emulation APIs] (https://developer.android.com/reference/android/nfc/cardemulation/NfcFCardEmulation.html) as defined in the Android SDK.
+      </li>
+    </ul>
+    <p>
+      If device implementations include general NFC support as described in this section and support MIFARE technologies (MIFARE Classic, MIFARE Ultralight, NDEF on MIFARE Classic) in the reader/writer role, they:
+    </p>
+    <ul>
+      <li>[C-4-1] MUST implement the corresponding Android APIs as documented by the Android SDK.
+      </li>
+      <li>[C-4-2] MUST report the feature <code>com.nxp.mifare</code> from the <a href="http://developer.android.com/reference/android/content/pm/PackageManager.html"><code>android.content.pm.PackageManager.hasSystemFeature</code>()</a> method. Note that this is not a standard Android feature and as such does not appear as a constant in the <code>android.content.pm.PackageManager</code> class.
+      </li>
+    </ul>
+    <h4 id="7_4_5_minimum_network_capability">
+      7.4.5. Minimum Network Capability
+    </h4>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST include support for one or more forms of data networking. Specifically, device implementations MUST include support for at least one data standard capable of 200Kbit/sec or greater. Examples of technologies that satisfy this requirement include EDGE, HSPA, EV-DO, 802.11g, Ethernet, Bluetooth PAN, etc.
+      </li>
+      <li>[C-0-2] MUST include an IPv6 networking stack and support IPv6 communication using the managed APIs, such as <code>java.net.Socket</code> and <code>java.net.URLConnection</code>, as well as the native APIs, such as <code>AF_INET6</code> sockets.
+      </li>
+      <li>[C-0-3] MUST enable IPv6 by default.
+      </li>
+      <li>MUST ensure that IPv6 communication is as reliable as IPv4, for example.
+      </li>
+      <li>[C-0-4] MUST maintain IPv6 connectivity in doze mode.
+      </li>
+      <li>[C-0-5] Rate-limiting MUST NOT cause the device to lose IPv6 connectivity on any IPv6-compliant network that uses RA lifetimes of at least 180 seconds.
+      </li>
+      <li>SHOULD also include support for at least one common wireless data standard, such as 802.11 (Wi-Fi) when a physical networking standard (such as Ethernet) is the primary data connection
+      </li>
+      <li>MAY implement more than one form of data connectivity.
+      </li>
+    </ul>
+    <p>
+      The required level of IPv6 support depends on the network type, as follows:
+    </p>
+    <p>
+      If devices implementations support Wi-Fi networks, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support dual-stack and IPv6-only operation on Wi-Fi.
+      </li>
+    </ul>
+    <p>
+      If device impelementations support Ethernet networks, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST support dual-stack operation on Ethernet.
+      </li>
+    </ul>
+    <p>
+      If device implementations support cellular data, they:
+    </p>
+    <ul>
+      <li>[C-3-1] MUST simultaneously meet these requirements on each network to which it is connected when a device is simultaneously connected to more than one network (e.g., Wi-Fi and cellular data), .
+      </li>
+      <li>SHOULD support IPv6 operation (IPv6-only and possibly dual-stack) on cellular data.
+      </li>
+    </ul>
+    <h4 id="7_4_6_sync_settings">
+      7.4.6. Sync Settings
+    </h4>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST have the master auto-sync setting on by default so that the method <a href="http://developer.android.com/reference/android/content/ContentResolver.html"><code>getMasterSyncAutomatically()</code></a> returns “true”.
+      </li>
+    </ul>
+    <h4 id="7_4_7_data_saver">
+      7.4.7. Data Saver
+    </h4>
+    <p>
+      If device implementations include a metered connection, they are:
+    </p>
+    <ul>
+      <li>[SR] STRONGLY RECOMMENDED to provide the data saver mode.
+      </li>
+    </ul>
+    <p>
+      If device implementations provide the data saver mode, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support all the APIs in the <code>ConnectivityManager</code> class as described in the <a href="https://developer.android.com/training/basics/network-ops/data-saver.html">SDK documentation</a>
+      </li>
+      <li>[C-1-2] MUST provide a user interface in the settings, that handles the <a href="https://developer.android.com/reference/android/provider/Settings.html#ACTION_IGNORE_BACKGROUND_DATA_RESTRICTIONS_SETTINGS"><code>Settings.ACTION_IGNORE_BACKGROUND_DATA_RESTRICTIONS_SETTINGS</code></a> intent, allowing users to add applications to or remove applications from the whitelist.
+      </li>
+    </ul>
+    <p>
+      If device implementations do not provide the data saver mode, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST return the value <code>RESTRICT_BACKGROUND_STATUS_DISABLED</code> for <a href="https://developer.android.com/reference/android/net/ConnectivityManager.html#getRestrictBackgroundStatus%28%29"><code>ConnectivityManager.getRestrictBackgroundStatus()</code></a>
+      </li>
+      <li>[C-2-2] MUST NOT broadcast <code>ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED</code>.
+      </li>
+      <li>[C-2-3] MUST have an activity that handles the <code>Settings.ACTION_IGNORE_BACKGROUND_DATA_RESTRICTIONS_SETTINGS</code> intent but MAY implement it as a no-op.
+      </li>
+    </ul>
+    <h3 id="7_5_cameras">
+      7.5. Cameras
+    </h3>
+    <p>
+      If device implementations include at least one camera, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST declare the <code>android.hardware.camera.any</code> feature flag.
+      </li>
+      <li>[C-1-2] MUST be possible for an application to simultaneously allocate 3 RGBA_8888 bitmaps equal to the size of the images produced by the largest-resolution camera sensor on the device, while camera is open for the purpose of basic preview and still capture.
+      </li>
+    </ul>
+    <h4 id="7_5_1_rear-facing_camera">
+      7.5.1. Rear-Facing Camera
+    </h4>
+    <p>
+      A rear-facing camera is a camera located on the side of the device opposite the display; that is, it images scenes on the far side of the device, like a traditional camera.
+    </p>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>SHOULD include a rear-facing camera.
+      </li>
+    </ul>
+    <p>
+      If device implementations include at least one rear-facing camera, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST report the feature flag <code>android.hardware.camera</code> and <code>android.hardware.camera.any</code>.
+      </li>
+      <li>[C-1-2] MUST have a resolution of at least 2 megapixels.
+      </li>
+      <li>SHOULD have either hardware auto-focus or software auto-focus implemented in the camera driver (transparent to application software).
+      </li>
+      <li>MAY have fixed-focus or EDOF (extended depth of field) hardware.
+      </li>
+      <li>MAY include a flash.
+      </li>
+    </ul>
+    <p>
+      If the Camera includes a flash:
+    </p>
+    <ul>
+      <li>[C-2-1] the flash lamp MUST NOT be lit while an <code>android.hardware.Camera.PreviewCallback</code> instance has been registered on a Camera preview surface, unless the application has explicitly enabled the flash by enabling the <code>FLASH_MODE_AUTO</code> or <code>FLASH_MODE_ON</code> attributes of a <code>Camera.Parameters</code> object. Note that this constraint does not apply to the device’s built-in system camera application, but only to third-party applications using <code>Camera.PreviewCallback</code>.
+      </li>
+    </ul>
+    <h4 id="7_5_2_front-facing_camera">
+      7.5.2. Front-Facing Camera
+    </h4>
+    <p>
+      A front-facing camera is a camera located on the same side of the device as the display; that is, a camera typically used to image the user, such as for video conferencing and similar applications.
+    </p>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>MAY include a front-facing camera
+      </li>
+    </ul>
+    <p>
+      If device implementations include at least one front-facing camera, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST report the feature flag <code>android.hardware.camera.any</code> and <code>android.hardware.camera.front</code>.
+      </li>
+      <li>[C-1-2] MUST have a resolution of at least VGA (640x480 pixels).
+      </li>
+      <li>[C-1-3] MUST NOT use a front-facing camera as the default for the Camera API and MUST NOT configure the API to treat a front-facing camera as the default rear-facing camera, even if it is the only camera on the device.
+      </li>
+      <li>[C-1-5] The camera preview MUST be mirrored horizontally relative to the orientation specified by the application when the current application has explicitly requested that the Camera display be rotated via a call to the <a href="http://developer.android.com/reference/android/hardware/Camera.html#setDisplayOrientation(int)"><code>android.hardware.Camera.setDisplayOrientation()</code></a> method. Conversely, the preview MUST be mirrored along the device’s default horizontal axis when the current application does not explicitly request that the Camera display be rotated via a call to the <a href="http://developer.android.com/reference/android/hardware/Camera.html#setDisplayOrientation(int)"><code>android.hardware.Camera.setDisplayOrientation()</code></a> method.
+      </li>
+      <li>[C-1-6] MUST NOT mirror the final captured still image or video streams returned to application callbacks or committed to media storage.
+      </li>
+      <li>[C-1-7] MUST mirror the image displayed by the postview in the same manner as the camera preview image stream.
+      </li>
+      <li>MAY include features (such as auto-focus, flash, etc.) available to rear-facing cameras as described in <a href="#7_5_1_rear-facing_camera">section 7.5.1</a>.
+      </li>
+    </ul>
+    <p>
+      If device implementations are capable of being rotated by user (such as automatically via an accelerometer or manually via user input):
+    </p>
+    <ul>
+      <li>[C-2-1] The camera preview MUST be mirrored horizontally relative to the device’s current orientation.
+      </li>
+    </ul>
+    <h4 id="7_5_3_external_camera">
+      7.5.3. External Camera
+    </h4>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>MAY include support for an external camera that is not necessarily always connected.
+      </li>
+    </ul>
+    <p>
+      If device impelmentations include support for an external camera, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST declare the platform feature flag <code>android.hardware.camera.external</code> and <code>android.hardware camera.any</code>.
+      </li>
+      <li>[C-1-2] MUST support USB Video Class (UVC 1.0 or higher) if the external camera connects through the USB port.
+      </li>
+      <li>SHOULD support video compressions such as MJPEG to enable transfer of high-quality unencoded streams (i.e. raw or independently compressed picture streams).
+      </li>
+      <li>MAY support multiple cameras.
+      </li>
+      <li>MAY support camera-based video encoding. If supported, a simultaneous unencoded / MJPEG stream (QVGA or greater resolution) MUST be accessible to the device implementation.
+      </li>
+    </ul>
+    <h4 id="7_5_4_camera_api_behavior">
+      7.5.4. Camera API Behavior
+    </h4>
+    <p>
+      Android includes two API packages to access the camera, the newer android.hardware.camera2 API expose lower-level camera control to the app, including efficient zero-copy burst/streaming flows and per-frame controls of exposure, gain, white balance gains, color conversion, denoising, sharpening, and more.
+    </p>
+    <p>
+      The older API package, <code>android.hardware.Camera</code>, is marked as deprecated in Android 5.0 but as it should still be available for apps to use. Android device implementations MUST ensure the continued support of the API as described in this section and in the Android SDK.
+    </p>
+    <p>
+      Device implementations MUST implement the following behaviors for the camera-related APIs, for all available cameras. Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST use <code>android.hardware.PixelFormat.YCbCr_420_SP</code> for preview data provided to application callbacks when an application has never called <code>android.hardware.Camera.Parameters.setPreviewFormat(int)</code>.
+      </li>
+      <li>[C-0-2] MUST further be in the NV21 encoding format when an application registers an <code>android.hardware.Camera.PreviewCallback</code> instance and the system calls the <code>onPreviewFrame()</code> method and the preview format is YCbCr_420_SP, the data in the byte[] passed into <code>onPreviewFrame()</code>. That is, NV21 MUST be the default.
+      </li>
+      <li>[C-0-3] MUST support the YV12 format (as denoted by the <code>android.graphics.ImageFormat.YV12</code> constant) for camera previews for both front- and rear-facing cameras for <code>android.hardware.Camera</code>. (The hardware video encoder and camera may use any native pixel format, but the device implementation MUST support conversion to YV12.)
+      </li>
+      <li>[C-0-4] MUST support the <code>android.hardware.ImageFormat.YUV_420_888</code> and <code>android.hardware.ImageFormat.JPEG</code> formats as outputs through the <code>android.media.ImageReader</code> API for <code>android.hardware.camera2</code>.
+      </li>
+      <li>[C-0-5] MUST still implement the full <a href="http://developer.android.com/reference/android/hardware/Camera.html">Camera API</a> included in the Android SDK documentation, regardless of whether the device includes hardware autofocus or other capabilities. For instance, cameras that lack autofocus MUST still call any registered <code>android.hardware.Camera.AutoFocusCallback</code> instances (even though this has no relevance to a non-autofocus camera.) Note that this does apply to front-facing cameras; for instance, even though most front-facing cameras do not support autofocus, the API callbacks must still be “faked” as described.
+      </li>
+      <li>[C-0-6] MUST recognize and honor each parameter name defined as a constant on the <a href="http://developer.android.com/reference/android/hardware/Camera.Parameters.html"><code>android.hardware.Camera.Parameters</code></a> class. Conversely, device implementations MUST NOT honor or recognize string constants passed to the <code>android.hardware.Camera.setParameters()</code> method other than those documented as constants on the <code>android.hardware.Camera.Parameters</code>. That is, device implementations MUST support all standard Camera parameters if the hardware allows, and MUST NOT support custom Camera parameter types. For instance, device implementations that support image capture using high dynamic range (HDR) imaging techniques MUST support camera parameter <code>Camera.SCENE_MODE_HDR</code>.
+      </li>
+      <li>[C-0-7] MUST report the proper level of support with the <a href="https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics.html#INFO_SUPPORTED_HARDWARE_LEVEL"><code>android.info.supportedHardwareLevel</code></a> property as described in the Android SDK and report the appropriate <a href="http://source.android.com/devices/camera/versioning.html">framework feature flags</a>.
+      </li>
+      <li>[C-0-8] MUST also declare its individual camera capabilities of <code>android.hardware.camera2</code> via the <code>android.request.availableCapabilities</code> property and declare the appropriate <a href="http://source.android.com/devices/camera/versioning.html">feature flags</a>; MUST define the feature flag if any of its attached camera devices supports the feature.
+      </li>
+      <li>[C-0-9] MUST broadcast the <code>Camera.ACTION_NEW_PICTURE</code> intent whenever a new picture is taken by the camera and the entry of the picture has been added to the media store.
+      </li>
+      <li>[C-0-10] MUST broadcast the <code>Camera.ACTION_NEW_VIDEO</code> intent whenever a new video is recorded by the camera and the entry of the picture has been added to the media store.
+      </li>
+    </ul>
+    <h4 id="7_5_5_camera_orientation">
+      7.5.5. Camera Orientation
+    </h4>
+    <p>
+      If device implementations have a front- or a rear-facing camera, such camera(s):
+    </p>
+    <ul>
+      <li>[C-1-1] MUST be oriented so that the long dimension of the camera aligns with the screen’s long dimension. That is, when the device is held in the landscape orientation, cameras MUST capture images in the landscape orientation. This applies regardless of the device’s natural orientation; that is, it applies to landscape-primary devices as well as portrait-primary devices.
+      </li>
+    </ul>
+    <h3 id="7_6_memory_and_storage">
+      7.6. Memory and Storage
+    </h3>
+    <h4 id="7_6_1_minimum_memory_and_storage">
+      7.6.1. Minimum Memory and Storage
+    </h4>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST include a <a href="http://developer.android.com/reference/android/app/DownloadManager.html">Download Manager</a> that applications MAY use to download data files and they MUST be capable of downloading individual files of at least 100MB in size to the default “cache” location.
+      </li>
+    </ul>
+    <h4 id="7_6_2_application_shared_storage">
+      7.6.2. Application Shared Storage
+    </h4>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST offer storage to be shared by applications, also often referred as “shared external storage”, "application shared storage" or by the Linux path "/sdcard" it is mounted on.
+      </li>
+      <li>[C-0-2] MUST be configured with shared storage mounted by default, in other words “out of the box”, regardless of whether the storage is implemented on an internal storage component or a removable storage medium (e.g. Secure Digital card slot).
+      </li>
+      <li>[C-0-3] MUST mount the application shared storage directly on the Linux path <code>sdcard</code> or include a Linux symbolic link from <code>sdcard</code> to the actual mount point.
+      </li>
+      <li>[C-0-4] MUST enforce the <code>android.permission.WRITE_EXTERNAL_STORAGE</code> permission on this shared storage as documented in the SDK. Shared storage MUST otherwise be writable by any application that obtains that permission.
+      </li>
+    </ul>
+    <p>
+      Device implementations MAY meet the above requirements using either:
+    </p>
+    <ul>
+      <li>a user-accessible removable storage, such as a Secure Digital (SD) card slot.
+      </li>
+      <li>a portion of the internal (non-removable) storage as implemented in the Android Open Source Project (AOSP).
+      </li>
+    </ul>
+    <p>
+      If device implementations use removable storage to satisfy the above requirements, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST implement a toast or pop-up user interface warning the user when there is no storage medium inserted in the slot.
+      </li>
+      <li>[C-1-2] MUST include a FAT-formatted storage medium (e.g. SD card) or show on the box and other material available at time of purchase that the storage medium has to be purchased separately.
+      </li>
+    </ul>
+    <p>
+      If device implementations use a protion of the non-removable storage to satisfy the above requirements, they:
+    </p>
+    <ul>
+      <li>SHOULD use the AOSP implementation of the internal application shared storage.
+      </li>
+      <li>MAY share the storage space with the application private data.
+      </li>
+    </ul>
+    <p>
+      If device implementations include multiple shared storage paths (such as both an SD card slot and shared internal storage), they:
+    </p>
+    <ul>
+      <li>[C-3-1] MUST allow only pre-installed and privileged Android applications with the <code>WRITE_EXTERNAL_STORAGE</code> permission to write to the secondary external storage, except when writing to their package-specific directories or within the <code>URI</code> returned by firing the <code>ACTION_OPEN_DOCUMENT_TREE</code> intent.
+      </li>
+    </ul>
+    <p>
+      If device implementations have a USB port with USB peripheral mode support, they:
+    </p>
+    <ul>
+      <li>[C-3-1] MUST provide a mechanism to access the data on the application shared storage from a host computer.
+      </li>
+      <li>SHOULD expose content from both storage paths transparently through Android’s media scanner service and <code>android.provider.MediaStore</code>.
+      </li>
+      <li>MAY use USB mass storage, but SHOULD use Media Transfer Protocol to satisfy this requirement.
+      </li>
+    </ul>
+    <p>
+      If device implementations have a USB port with USB peripheral mode and support Media Transfer Protocol, they:
+    </p>
+    <ul>
+      <li>SHOULD be compatible with the reference Android MTP host, <a href="http://www.android.com/filetransfer">Android File Transfer</a>.
+      </li>
+      <li>SHOULD report a USB device class of 0x00.
+      </li>
+      <li>SHOULD report a USB interface name of 'MTP'.
+      </li>
+    </ul>
+    <h4 id="7_6_3_adoptable_storage">
+      7.6.3. Adoptable Storage
+    </h4>
+    <p>
+      If the device is expected to be mobile in nature unlike Television, device implementations are:
+    </p>
+    <ul>
+      <li>[SR] STRONGLY RECOMMENDED to implement the adoptable storage in a long-term stable location, since accidentally disconnecting them can cause data loss/corruption.
+      </li>
+    </ul>
+    <p>
+      If the removable storage device port is in a long-term stable location, such as within the battery compartment or other protective cover, device implementations are:
+    </p>
+    <ul>
+      <li>[SR] STRONGLY RECOMMENDED to implement <a href="http://source.android.com/devices/storage/adoptable.html">adoptable storage</a>.
+      </li>
+    </ul>
+    <h3 id="7_7_usb">
+      7.7. USB
+    </h3>
+    <p>
+      If device implementations have a USB port, they:
+    </p>
+    <ul>
+      <li>SHOULD support USB peripheral mode and SHOULD support USB host mode.
+      </li>
+    </ul>
+    <h4 id="7_7_1_usb_peripheral_mode">
+      7.7.1. USB peripheral mode
+    </h4>
+    <p>
+      If device implementations include a USB port supporting peripheral mode:
+    </p>
+    <ul>
+      <li>[C-1-1] The port MUST be connectable to a USB host that has a standard type-A or type-C USB port.
+      </li>
+      <li>[C-1-2] MUST report the correct value of <code>iSerialNumber</code> in USB standard device descriptor through <code>android.os.Build.SERIAL</code>.
+      </li>
+      <li>[C-1-3] MUST detect 1.5A and 3.0A chargers per the Type-C resistor standard and MUST detect changes in the advertisement if they support Type-C USB.
+      </li>
+      <li>[SR] The port SHOULD use micro-B, micro-AB or Type-C USB form factor. Existing and new Android devices are <strong>STRONGLY RECOMMENDED to meet these requirements</strong> so they will be able to upgrade to the future platform releases.
+      </li>
+      <li>[SR] The port SHOULD be located on the bottom of the device (according to natural orientation) or enable software screen rotation for all apps (including home screen), so that the display draws correctly when the device is oriented with the port at bottom. Existing and new Android devices are <strong>STRONGLY RECOMMENDED to meet these requirements</strong> so they will be able to upgrade to future platform releases.
+      </li>
+      <li>[SR] SHOULD implement support to draw 1.5 A current during HS chirp and traffic as specified in the <a href="http://www.usb.org/developers/docs/devclass_docs/BCv1.2_070312.zip">USB Battery Charging specification, revision 1.2</a>. Existing and new Android devices are <strong>STRONGLY RECOMMENDED to meet these requirements</strong> so they will be able to upgrade to the future platform releases.
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to not support proprietary charging methods that modify Vbus voltage beyond default levels, or alter sink/source roles as such may result in interoperability issues with the chargers or devices that support the standard USB Power Delivery methods. While this is called out as "STRONGLY RECOMMENDED", in future Android versions we might REQUIRE all type-C devices to support full interoperability with standard type-C chargers.
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to support Power Delivery for data and power role swapping when they support Type-C USB and USB host mode.
+      </li>
+      <li>SHOULD support Power Delivery for high-voltage charging and support for Alternate Modes such as display out.
+      </li>
+      <li>SHOULD implement the Android Open Accessory (AOA) API and specification as documented in the Android SDK documentation.
+      </li>
+    </ul>
+    <p>
+      If device implementations including a USB port, implement the AOA specification, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST declare support for the hardware feature <a href="http://developer.android.com/guide/topics/connectivity/usb/accessory.html"><code>android.hardware.usb.accessory</code></a>.
+      </li>
+      <li>[C-2-2] The USB mass storage class MUST include the string "android" at the end of the interface description <code>iInterface</code> string of the USB mass storage
+      </li>
+      <li>SHOULD NOT implement <a href="https://source.android.com/devices/accessories/aoa2#audio-support">AOAv2 audio</a> documented in the Android Open Accessory Protocol 2.0 documentation. AOAv2 audio is deprecated as of Android version 8.0 (API level 26).
+      </li>
+    </ul>
+    <h4 id="7_7_2_usb_host_mode">
+      7.7.2. USB host mode
+    </h4>
+    <p>
+      If device implementations include a USB port supporting host mode, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST implement the Android USB host API as documented in the Android SDK and MUST declare support for the hardware feature <a href="http://developer.android.com/guide/topics/connectivity/usb/host.html"><code>android.hardware.usb.host</code></a>.
+      </li>
+      <li>[C-1-2] MUST implement support to connect standard USB peripherals, in other words, they MUST either:
+        <ul>
+          <li>Have an on-device type C port or ship with cable(s) adapting an on-device proprietary port to a standard USB type-C port (USB Type-C device).
+          </li>
+          <li>Have an on-device type A or ship with cable(s) adapting an on-device proprietary port to a standard USB type-A port.
+          </li>
+          <li>Have an on-device micro-AB port, which SHOULD ship with a cable adapting to a standard type-A port.
+          </li>
+        </ul>
+      </li>
+      <li>[C-1-3] MUST NOT ship with an adapter converting from USB type A or micro-AB ports to a type-C port (receptacle).
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to implement the <a href="http://developer.android.com/reference/android/hardware/usb/UsbConstants.html#USB_CLASS_AUDIO">USB audio class</a> as documented in the Android SDK documentation.
+      </li>
+      <li>SHOULD support charging the connected USB peripheral device while in host mode; advertising a source current of at least 1.5A as specified in the Termination Parameters section of the <a href="http://www.usb.org/developers/docs/usb_31_021517.zip">USB Type-C Cable and Connector Specification Revision 1.2</a> for USB Type-C connectors or using Charging Downstream Port(CDP) output current range as specified in the <a href="http://www.usb.org/developers/docs/devclass_docs/BCv1.2_070312.zip">USB Battery Charging specifications, revision 1.2</a> for Micro-AB connectors.
+      </li>
+      <li>SHOULD implement and support USB Type-C standards.
+      </li>
+    </ul>
+    <p>
+      If device implementations include a USB port supporting host mode and the USB audio class, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST support the <a href="https://developer.android.com/reference/android/hardware/usb/UsbConstants.html#USB_CLASS_HID">USB HID class</a>
+      </li>
+      <li>[C-2-2] MUST support the detection and mapping of the following HID data fields specified in the <a href="http://www.usb.org/developers/hidpage/Hut1_12v2.pdf">USB HID Usage Tables</a> and the <a href="http://www.usb.org/developers/hidpage/Voice_Command_Usage.pdf">Voice Command Usage Request</a> to the <a href="https://developer.android.com/reference/android/view/KeyEvent.html"><code>KeyEvent</code></a> constants as below:
+        <ul>
+          <li>Usage Page (0xC) Usage ID (0x0CD): <code>KEYCODE_MEDIA_PLAY_PAUSE</code>
+          </li>
+          <li>Usage Page (0xC) Usage ID (0x0E9): <code>KEYCODE_VOLUME_UP</code>
+          </li>
+          <li>Usage Page (0xC) Usage ID (0x0EA): <code>KEYCODE_VOLUME_DOWN</code>
+          </li>
+          <li>Usage Page (0xC) Usage ID (0x0CF): <code>KEYCODE_VOICE_ASSIST</code>
+          </li>
+        </ul>
+      </li>
+    </ul>
+    <p>
+      If device implementations include a USB port supporting host mode and the Storage Access Framework (SAF), they:
+    </p>
+    <ul>
+      <li>[C-3-1] MUST recognize any remotely connected MTP (Media Transfer Protocol) devices and make their contents accessible through the <code>ACTION_GET_CONTENT</code>, <code>ACTION_OPEN_DOCUMENT</code>, and <code>ACTION_CREATE_DOCUMENT</code> intents. .
+      </li>
+    </ul>
+    <p>
+      If device implementations include a USB port supporting host mode and USB Type-C, they:
+    </p>
+    <ul>
+      <li>[C-4-1] MUST implement Dual Role Port functionality as defined by the USB Type-C specification (section 4.5.1.3.3).
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to support DisplayPort, SHOULD support USB SuperSpeed Data Rates, and are STRONGLY RECOMMENDED to support Power Delivery for data and power role swapping.
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to NOT support Audio Adapter Accessory Mode as described in the Appendix A of the <a href="http://www.usb.org/developers/docs/">USB Type-C Cable and Connector Specification Revision 1.2</a>.
+      </li>
+      <li>SHOULD implement the Try.* model that is most appropriate for the device form factor. For example a handheld device SHOULD implement the Try.SNK model.
+      </li>
+    </ul>
+    <h3 id="7_8_audio">
+      7.8. Audio
+    </h3>
+    <h4 id="7_8_1_microphone">
+      7.8.1. Microphone
+    </h4>
+    <p>
+      If device implementations include a microphone, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST report the <code>android.hardware.microphone</code> feature constant.
+      </li>
+      <li>[C-1-2] MUST meet the audio recording requirements in <a href="#5_4_audio_recording">section 5.4</a>.
+      </li>
+      <li>[C-1-3] MUST meet the audio latency requirements in <a href="#5_6_audio_latency">section 5.6</a>.
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to support near-ultrasound recording as described in <a href="#7_8_3_near_ultrasound">section 7.8.3</a>.
+      </li>
+    </ul>
+    <p>
+      If device implementations omit a microphone, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST NOT report the <code>android.hardware.microphone</code> feature constant.
+      </li>
+      <li>[C-2-2] MUST implement the audio recording API at least as no-ops, per <a href="#7_hardware_compatibility">section 7</a>.
+      </li>
+    </ul>
+    <h4 id="7_8_2_audio_output">
+      7.8.2. Audio Output
+    </h4>
+    <p>
+      If device implementations include a speaker or an audio/multimedia output port for an audio output peripheral such as a 4 conductor 3.5mm audio jack or USB host mode port using <a href="https://source.android.com/devices/audio/usb#audioClass">USB audio class</a>, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST report the <code>android.hardware.audio.output</code> feature constant.
+      </li>
+      <li>[C-1-2] MUST meet the audio playback requirements in <a href="#5_5_audio_playback">section 5.5</a>.
+      </li>
+      <li>[C-1-3] MUST meet the audio latency requirements in <a href="#5_6_audio_latency">section 5.6</a>.
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to support near-ultrasound playback as described in <a href="#7_8_3_near_ultrasound">section 7.8.3</a>.
+      </li>
+    </ul>
+    <p>
+      If device implementations do not include a speaker or audio output port, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST NOT report the <code>android.hardware.audio output</code> feature.
+      </li>
+      <li>[C-2-2] MUST implement the Audio Output related APIs as no-ops at least.
+      </li>
+    </ul>
+    <p>
+      For the purposes of this section, an "output port" is a <a href="https://en.wikipedia.org/wiki/Computer_port_%28hardware%29">physical interface</a> such as a 3.5mm audio jack, HDMI, or USB host mode port with USB audio class. Support for audio output over radio-based protocols such as Bluetooth, WiFi, or cellular network does not qualify as including an "output port".
+    </p>
+    <h5 id="7_8_2_1_analog_audio_ports">
+      7.8.2.1. Analog Audio Ports
+    </h5>
+    <p>
+      In order to be compatible with the <a href="http://source.android.com/accessories/headset-spec.html">headsets and other audio accessories</a> using the 3.5mm audio plug across the Android ecosystem, if a device implementation includes one or more analog audio ports, at least one of the audio port(s) SHOULD be a 4 conductor 3.5mm audio jack.
+    </p>
+    <p>
+      If device implementations have a 4 conductor 3.5mm audio jack, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support audio playback to stereo headphones and stereo headsets with a microphone.
+      </li>
+      <li>[C-1-2] MUST support TRRS audio plugs with the CTIA pin-out order.
+      </li>
+      <li>[C-1-3] MUST support the detection and mapping to the keycodes for the following 3 ranges of equivalent impedance between the microphone and ground conductors on the audio plug:
+        <ul>
+          <li>
+            <strong>70 ohm or less</strong>: <code>KEYCODE_HEADSETHOOK</code>
+          </li>
+          <li>
+            <strong>210-290 ohm</strong>: <code>KEYCODE_VOLUME_UP</code>
+          </li>
+          <li>
+            <strong>360-680 ohm</strong>: <code>KEYCODE_VOLUME_DOWN</code>
+          </li>
+        </ul>
+      </li>
+      <li>[C-1-4] MUST trigger <code>ACTION_HEADSET_PLUG</code> upon a plug insert, but only after all contacts on plug are touching their relevant segments on the jack.
+      </li>
+      <li>[C-1-5] MUST be capable of driving at least 150mV ± 10% of output voltage on a 32 ohm speaker impedance.
+      </li>
+      <li>[C-1-6] MUST have a microphone bias voltage between 1.8V ~ 2.9V.
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to detect and map to the keycode for the following range of equivalent impedance between the microphone and ground conductors on the audio plug:
+        <ul>
+          <li>
+            <strong>110-180 ohm:</strong> <code>KEYCODE_VOICE_ASSIST</code>
+          </li>
+        </ul>
+      </li>
+      <li>SHOULD support audio plugs with the OMTP pin-out order.
+      </li>
+      <li>SHOULD support audio recording from stereo headsets with a microphone.
+      </li>
+    </ul>
+    <p>
+      If device implementations have a 4 conductor 3.5mm audio jack and support a microphone, and broadcast the <code>android.intent.action.HEADSET_PLUG</code> with the extra value microphone set as 1, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST support the detection of microphone on the plugged in audio accessory.
+      </li>
+    </ul>
+    <h4 id="7_8_3_near-ultrasound">
+      7.8.3. Near-Ultrasound
+    </h4>
+    <p>
+      Near-Ultrasound audio is the 18.5 kHz to 20 kHz band.
+    </p>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>MUST correctly report the support of near-ultrasound audio capability via the <a href="http://developer.android.com/reference/android/media/AudioManager.html#getProperty%28java.lang.String%29">AudioManager.getProperty</a> API as follows:
+      </li>
+    </ul>
+    <p>
+      If <a href="http://developer.android.com/reference/android/media/AudioManager.html#PROPERTY_SUPPORT_MIC_NEAR_ULTRASOUND"><code>PROPERTY_SUPPORT_MIC_NEAR_ULTRASOUND</code></a> is "true", the following requirements MUST be met by the <code>VOICE_RECOGNITION</code> and <code>UNPROCESSED</code> audio sources:
+    </p>
+    <ul>
+      <li>[C-1-1] The microphone's mean power response in the 18.5 kHz to 20 kHz band MUST be no more than 15 dB below the response at 2 kHz.
+      </li>
+      <li>[C-1-2] The microphone's unweighted signal to noise ratio over 18.5 kHz to 20 kHz for a 19 kHz tone at -26 dBFS MUST be no lower than 50 dB.
+      </li>
+    </ul>
+    <p>
+      If <a href="http://developer.android.com/reference/android/media/AudioManager.html#PROPERTY_SUPPORT_SPEAKER_NEAR_ULTRASOUND"><code>PROPERTY_SUPPORT_SPEAKER_NEAR_ULTRASOUND</code></a> is "true":
+    </p>
+    <ul>
+      <li>[C-2-1] The speaker's mean response in 18.5 kHz - 20 kHz MUST be no lower than 40 dB below the response at 2 kHz.
+      </li>
+    </ul>
+    <h3 id="7_9_virtual_reality">
+      7.9. Virtual Reality
+    </h3>
+    <p>
+      Android includes APIs and facilities to build "Virtual Reality" (VR) applications including high quality mobile VR experiences. Device implementations MUST properly implement these APIs and behaviors, as detailed in this section.
+    </p>
+    <h4 id="7_9_1_virtual_reality_mode">
+      7.9.1. Virtual Reality Mode
+    </h4>
+    <p>
+      Android includes support for <a href="https://developer.android.com/reference/android/app/Activity.html#setVrModeEnabled%28boolean,%20android.content.ComponentName%29">VR Mode</a>, a feature which handles stereoscopic rendering of notifications and disables monocular system UI components while a VR application has user focus.
+    </p>
+    <h4 id="7_9_2_virtual_reality_high_performance">
+      7.9.2. Virtual Reality High Performance
+    </h4>
+    <p>
+      If device implementations identify the support of high performance VR for longer user periods through the <code>android.hardware.vr.high_performance</code> feature flag, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST have at least 2 physical cores.
+      </li>
+      <li>[C-1-2] MUST declare <code>android.software.vr.mode feature</code>.
+      </li>
+      <li>[C-1-3] MUST support sustained performance mode.
+      </li>
+      <li>[C-1-4] MUST support OpenGL ES 3.2.
+      </li>
+      <li>[C-1-5] MUST support Vulkan Hardware Level 0 and SHOULD support Vulkan Hardware Level 1.
+      </li>
+      <li>[C-1-6] MUST implement <a href="https://www.khronos.org/registry/EGL/extensions/KHR/EGL_KHR_mutable_render_buffer.txt"><code>EGL_KHR_mutable_render_buffer</code></a>, <a href="https://www.khronos.org/registry/EGL/extensions/ANDROID/EGL_ANDROID_front_buffer_auto_refresh.txt"><code>EGL_ANDROID_front_buffer_auto_refresh</code></a>, <a href="https://www.khronos.org/registry/EGL/extensions/ANDROID/EGL_ANDROID_get_native_client_buffer.txt"><code>EGL_ANDROID_get_native_client_buffer</code></a>, <a href="https://www.khronos.org/registry/EGL/extensions/KHR/EGL_KHR_fence_sync.txt"><code>EGL_KHR_fence_sync</code></a>, <a href="https://www.khronos.org/registry/EGL/extensions/KHR/EGL_KHR_wait_sync.txt"><code>EGL_KHR_wait_sync</code></a>, <a href="https://www.khronos.org/registry/EGL/extensions/IMG/EGL_IMG_context_priority.txt"><code>EGL_IMG_context_priority</code></a>, <a href="https://www.khronos.org/registry/EGL/extensions/EXT/EGL_EXT_protected_content.txt"><code>EGL_EXT_protected_content</code></a>, and expose the extensions in the list of available EGL extensions.
+      </li>
+      <li>[C-1-7] The GPU and display MUST be able to synchronize access to the shared front buffer such that alternating-eye rendering of VR content at 60fps with two render contexts will be displayed with no visible tearing artifacts.
+      </li>
+      <li>[C-1-8] MUST implement <a href="https://www.khronos.org/registry/OpenGL/extensions/EXT/EXT_multisampled_render_to_texture.txt"><code>GL_EXT_multisampled_render_to_texture</code></a>, <a href="https://www.khronos.org/registry/OpenGL/extensions/OVR/OVR_multiview.txt"><code>GL_OVR_multiview</code></a>, <a href="https://www.khronos.org/registry/OpenGL/extensions/OVR/OVR_multiview2.txt"><code>GL_OVR_multiview2</code></a>, <a href="https://www.khronos.org/registry/OpenGL/extensions/OVR/OVR_multiview_multisampled_render_to_texture.txt"><code>GL_OVR_multiview_multisampled_render_to_texture</code></a>, <a href="https://www.khronos.org/registry/OpenGL/extensions/EXT/EXT_protected_textures.txt"><code>GL_EXT_protected_textures</code></a>, and expose the extensions in the list of available GL extensions.
+      </li>
+      <li>[C-1-9] MUST implement support for <a href="https://developer.android.com/ndk/reference/hardware__buffer_8h.html"><code>AHardwareBuffer</code></a> flags <code>AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER</code> and <code>AHARDWAREBUFFER_USAGE_SENSOR_DIRECT_DATA</code> as described in the NDK.
+      </li>
+      <li>[C-1-10] MUST implement support for <code>AHardwareBuffers</code> with more than one layer.
+      </li>
+      <li>[C-1-11] MUST support H.264 decoding at least 3840x2160@30fps-40Mbps (equivalent to 4 instances of 1920x1080@30fps-10Mbps or 2 instances of 1920x1080@60fps-20Mbps).
+      </li>
+      <li>[C-1-12] MUST support HEVC and VP9, MUST be capable to decode at least 1920x1080@30fps-10Mbps and SHOULD be capable to decode 3840x2160@30fps-20Mbps (equivalent to 4 instances of 1920x1080@30fps-5Mbps).
+      </li>
+      <li>[C-1-13] MUST support <code>HardwarePropertiesManager.getDeviceTemperatures</code> API and return accurate values for skin temperature.
+      </li>
+      <li>[C-1-14] MUST have an embedded screen, and its resolution MUST be at least be FullHD(1080p) and STRONGLY RECOMMENDED TO BE be QuadHD (1440p) or higher.
+      </li>
+      <li>[C-1-15] The display MUST measure between 4.7" and 6.3" diagonal.
+      </li>
+      <li>[C-1-16] The display MUST update at least 60 Hz while in VR Mode.
+      </li>
+      <li>[C-1-17] The display latency on Gray-to-Gray, White-to-Black, and Black-to-White switching time MUST be ≤ 3 ms.
+      </li>
+      <li>[C-1-18] The display MUST support a low-persistence mode with ≤5 ms persistence, persistence being defined as the amount of time for which a pixel is emitting light.
+      </li>
+      <li>[C-1-19] MUST support Bluetooth 4.2 and Bluetooth LE Data Length Extension <a href="#7_4_3_bluetooth">section 7.4.3</a>.
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to support <code>android.hardware.sensor.hifi_sensors</code> feature and MUST meet the gyroscope, accelerometer, and magnetometer related requirements for <code>android.hardware.hifi_sensors</code>.
+      </li>
+      <li>MAY provide an exclusive core to the foreground application and MAY support the <code>Process.getExclusiveCores</code> API to return the numbers of the cpu cores that are exclusive to the top foreground application. If exclusive core is supported then the core MUST not allow any other userspace processes to run on it (except device drivers used by the application), but MAY allow some kernel processes to run as necessary.
+      </li>
+    </ul>
+    <h2 id="8_performance_and_power">
+      8. Performance and Power
+    </h2>
+    <p>
+      Some minimum performance and power criteria are critical to the user experience and impact the baseline assumptions developers would have when developing an app.
+    </p>
+    <h3 id="8_1_user_experience_consistency">
+      8.1. User Experience Consistency
+    </h3>
+    <p>
+      A smooth user interface can be provided to the end user if there are certain minimum requirements to ensure a consistent frame rate and response times for applications and games. Device implementations, depending on the device type, MAY have measurable requirements for the user interface latency and task switching as described in <a href="#2_device-types">section 2</a>.
+    </p>
+    <h3 id="8_2_file_i/o_access_performance">
+      8.2. File I/O Access Performance
+    </h3>
+    <p>
+      Providing a common baseline for a consistent file access performance on the application private data storage (<code>/data</code> partition) allows app developers to set a proper expectation that would help their software design. Device implementations, depending on the device type, MAY have certain requirements described in <a href="#2_device-type">section 2</a> for the following read and write operations:
+    </p>
+    <ul>
+      <li>
+        <strong>Sequential write performance</strong>. Measured by writing a 256MB file using 10MB write buffer.
+      </li>
+      <li>
+        <strong>Random write performance</strong>. Measured by writing a 256MB file using 4KB write buffer.
+      </li>
+      <li>
+        <strong>Sequential read performance</strong>. Measured by reading a 256MB file using 10MB write buffer.
+      </li>
+      <li>
+        <strong>Random read performance</strong>. Measured by reading a 256MB file using 4KB write buffer.
+      </li>
+    </ul>
+    <h3 id="8_3_power-saving_modes">
+      8.3. Power-Saving Modes
+    </h3>
+    <p>
+      Android includes App Standby and Doze power-saving modes to optimize battery usage. <em>[SR] All Apps exempted from these modes are STRONGLY RECOMMENDED to be made visible to the end user.</em> [SR] The triggering, maintenance, wakeup algorithms and the use of global system settings of these power-saving modes are STRONGLY RECOMMENDED NOT to deviate from the Android Open Source Project.
+    </p>
+    <p>
+      In addition to the power-saving modes, Android device implementations MAY implement any or all of the 4 sleeping power states as defined by the Advanced Configuration and Power Interface (ACPI).
+    </p>
+    <p>
+      If device implementations implements S3 and S4 power states as defined by the ACPI, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST only enter these states when closing a lid that is physically part of the device.
+      </li>
+    </ul>
+    <h3 id="8_4_power_consumption_accounting">
+      8.4. Power Consumption Accounting
+    </h3>
+    <p>
+      A more accurate accounting and reporting of the power consumption provides the app developer both the incentives and the tools to optimize the power usage pattern of the application.
+    </p>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>[SR] STRONGLY RECOMMENDED to provide a per-component power profile that defines the <a href="http://source.android.com/devices/tech/power/values.html">current consumption value</a> for each hardware component and the approximate battery drain caused by the components over time as documented in the Android Open Source Project site.
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to report all power consumption values in milliampere hours (mAh).
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to report CPU power consumption per each process's UID. The Android Open Source Project meets the requirement through the <code>uid_cputime</code> kernel module implementation.
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to make this power usage available via the <a href="http://source.android.com/devices/tech/power/batterystats.html"><code>adb shell dumpsys batterystats</code></a> shell command to the app developer.
+      </li>
+      <li>SHOULD be attributed to the hardware component itself if unable to attribute hardware component power usage to an application.
+      </li>
+    </ul>
+    <h3 id="8_5_consistent_performance">
+      8.5. Consistent Performance
+    </h3>
+    <p>
+      Performance can fluctuate dramatically for high-performance long-running apps, either because of the other apps running in the background or the CPU throttling due to temperature limits. Android includes programmatic interfaces so that when the device is capable, the top foreground application can request that the system optimize the allocation of the resources to address such fluctuations.
+    </p>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-0-1] MUST report the support of Sustained Performance Mode accurately through the <a href="https://developer.android.com/reference/android/os/PowerManager.html#isSustainedPerformanceModeSupported%28%29"><code>PowerManager.isSustainedPerformanceModeSupported()</code></a> API method.
+        </p>
+      </li>
+      <li>
+        <p>
+          SHOULD support Sustained Performance Mode.
+        </p>
+      </li>
+    </ul>
+    <p>
+      If device implementations report support of Sustained Performance Mode, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST provide the top foreground application a consistent level of performance for at least 30 minutes, when the app requests it.
+      </li>
+      <li>[C-1-2] MUST honor the <a href="https://developer.android.com/reference/android/view/Window.html#setSustainedPerformanceMode%28boolean%29"><code>Window.setSustainedPerformanceMode()</code></a> API and other related APIs.
+      </li>
+    </ul>
+    <p>
+      If device implementations include two or more CPU cores, they:
+    </p>
+    <ul>
+      <li>SHOULD provide at least one exclusive core that can be reserved by the top foreground application.
+      </li>
+    </ul>
+    <p>
+      If device implementations support reserving one exclusive core for the top foreground application, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST report through the <a href="https://developer.android.com/reference/android/os/Process.html#getExclusiveCores%28%29"><code>Process.getExclusiveCores()</code></a> API method the ID numbers of the exclusive cores that can be reserved by the top foreground application.
+      </li>
+      <li>[C-2-2] MUST not allow any user space processes except the device drivers used by the application to run on the exclusive cores, but MAY allow some kernel processes to run as necessary.
+      </li>
+    </ul>
+    <p>
+      If device implementations do not support an exclusive core, they:
+    </p>
+    <ul>
+      <li>[C-3-1] MUST return an empty list through the <a href="https://developer.android.com/reference/android/os/Process.html#getExclusiveCores%28%29"><code>Process.getExclusiveCores()</code></a> API method.
+      </li>
+    </ul>
+    <h2 id="9_security_model_compatibility">
+      9. Security Model Compatibility
+    </h2>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-0-1] MUST implement a security model consistent with the Android platform security model as defined in <a href="http://developer.android.com/guide/topics/security/permissions.html">Security and Permissions reference document</a> in the APIs in the Android developer documentation.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-0-2] MUST support installation of self-signed applications without requiring any additional permissions/certificates from any third parties/authorities. Specifically, compatible devices MUST support the security mechanisms described in the follow subsections.
+        </p>
+      </li>
+    </ul>
+    <h3 id="9_1_permissions">
+      9.1. Permissions
+    </h3>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-0-1] MUST support the <a href="http://developer.android.com/guide/topics/security/permissions.html">Android permissions model</a> as defined in the Android developer documentation. Specifically, they MUST enforce each permission defined as described in the SDK documentation; no permissions may be omitted, altered, or ignored.
+        </p>
+      </li>
+      <li>
+        <p>
+          MAY add additional permissions, provided the new permission ID strings are not in the <code>android.\*</code> namespace.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-0-2] Permissions with a <code>protectionLevel</code> of <a href="https://developer.android.com/reference/android/content/pm/PermissionInfo.html#PROTECTION&amp;lowbar;FLAG&amp;lowbar;PRIVILEGED"><code>PROTECTION_FLAG_PRIVILEGED</code></a> MUST only be granted to apps preloaded in the privileged path(s) of the system image and within the subset of the explicitly whitelisted permissions for each app. The AOSP implementation meets this requirement by reading and honoring the whitelisted permissions for each app from the files in the <code>etc/permissions/</code> path and using the <code>system/priv-app</code> path as the privileged path.
+        </p>
+      </li>
+    </ul>
+    <p>
+      Permissions with a protection level of dangerous are runtime permissions. Applications with <code>targetSdkVersion</code> &gt; 22 request them at runtime.
+    </p>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-3] MUST show a dedicated interface for the user to decide whether to grant the requested runtime permissions and also provide an interface for the user to manage runtime permissions.
+      </li>
+      <li>[C-0-4] MUST have one and only one implementation of both user interfaces.
+      </li>
+      <li>[C-0-5] MUST NOT grant any runtime permissions to preinstalled apps unless:
+      </li>
+      <li>the user's consent can be obtained before the application uses it
+      </li>
+      <li>the runtime permissions are associated with an intent pattern for which the preinstalled application is set as the default handler
+      </li>
+    </ul>
+    <p>
+      If device implementations include a pre-installed app or wish to allow third-party apps to access the usage statistics, they:
+    </p>
+    <ul>
+      <li>[C-1-1] are STRONGLY RECOMMENDED provide user-accessible mechanism to grant or revoke access to the usage stats in response to the <a href="https://developer.android.com/reference/android/provider/Settings.html#ACTION&amp;lowbar;USAGE&amp;lowbar;ACCESS&amp;lowbar;SETTINGS"><code>android.settings.ACTION_USAGE_ACCESS_SETTINGS</code></a> intent for apps that declare the <code>android.permission.PACKAGE_USAGE_STATS</code> permission.
+      </li>
+    </ul>
+    <p>
+      If device implementations intend to disallow any apps, including pre-installed apps, from accessing the usage statistics, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST still have an activity that handles the <a href="https://developer.android.com/reference/android/provider/Settings.html#ACTION&amp;lowbar;USAGE&amp;lowbar;ACCESS&amp;lowbar;SETTINGS"><code>android.settings.ACTION_USAGE_ACCESS_SETTINGS</code></a> intent pattern but MUST implement it as a no-op, that is to have an equivalent behavior as when the user is declined for access.
+      </li>
+    </ul>
+    <h3 id="9_2_uid_and_process_isolation">
+      9.2. UID and Process Isolation
+    </h3>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST support the Android application sandbox model, in which each application runs as a unique Unixstyle UID and in a separate process.
+      </li>
+      <li>[C-0-2] MUST support running multiple applications as the same Linux user ID, provided that the applications are properly signed and constructed, as defined in the <a href="http://developer.android.com/guide/topics/security/permissions.html">Security and Permissions reference</a>.
+      </li>
+    </ul>
+    <h3 id="9_3_filesystem_permissions">
+      9.3. Filesystem Permissions
+    </h3>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST support the Android file access permissions model as defined in the <a href="http://developer.android.com/guide/topics/security/permissions.html">Security and Permissions reference</a>.
+      </li>
+    </ul>
+    <h3 id="9_4_alternate_execution_environments">
+      9.4. Alternate Execution Environments
+    </h3>
+    <p>
+      Device implementations MUST keep consistency of the Android security and permission model, even if they include runtime environments that execute applications using some other software or technology than the Dalvik Executable Format or native code. In other words:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-0-1] Alternate runtimes MUST themselves be Android applications, and abide by the standard Android security model, as described elsewhere in <a href="#9_security_model_compatibility">section 9</a>.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-0-2] Alternate runtimes MUST NOT be granted access to resources protected by permissions not requested in the runtime’s <code>AndroidManifest.xml</code> file via the &lt;<code>uses-permission</code>&gt; mechanism.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-0-3] Alternate runtimes MUST NOT permit applications to make use of features protected by Android permissions restricted to system applications.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-0-4] Alternate runtimes MUST abide by the Android sandbox model and installed applications using an alternate runtime MUST NOT reuse the sandbox of any other app installed on the device, except through the standard Android mechanisms of shared user ID and signing certificate.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-0-5] Alternate runtimes MUST NOT launch with, grant, or be granted access to the sandboxes corresponding to other Android applications.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-0-6] Alternate runtimes MUST NOT be launched with, be granted, or grant to other applications any privileges of the superuser (root), or of any other user ID.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-0-7] When the <code>.apk</code> files of alternate runtimes are included in the system image of device implementations, it MUST be signed with a key distinct from the key used to sign other applications included with the device implementations.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-0-8] When installing applications, alternate runtimes MUST obtain user consent for the Android permissions used by the application.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-0-9] When an application needs to make use of a device resource for which there is a corresponding Android permission (such as Camera, GPS, etc.), the alternate runtime MUST inform the user that the application will be able to access that resource.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-0-10] When the runtime environment does not record application capabilities in this manner, the runtime environment MUST list all permissions held by the runtime itself when installing any application using that runtime.
+        </p>
+      </li>
+      <li>
+        <p>
+          Alternate runtimes SHOULD install apps via the <code>PackageManager</code> into separate Android sandboxes (Linux user IDs, etc.).
+        </p>
+      </li>
+      <li>
+        <p>
+          Alternate runtimes MAY provide a single Android sandbox shared by all applications using the alternate runtime.
+        </p>
+      </li>
+    </ul>
+    <h3 id="9_5_multi-user_support">
+      9.5. Multi-User Support
+    </h3>
+    <p>
+      Android includes <a href="http://developer.android.com/reference/android/os/UserManager.html">support for multiple users</a> and provides support for full user isolation.
+    </p>
+    <ul>
+      <li>Device implementations MAY but SHOULD NOT enable multi-user if they use <a href="http://developer.android.com/reference/android/os/Environment.html">removable media</a> for primary external storage.
+      </li>
+    </ul>
+    <p>
+      If device implementations include multiple users, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST meet the following requirements related to <a href="http://source.android.com/devices/storage/traditional.html">multi-user support</a>.
+      </li>
+      <li>[C-1-2] MUST, for each user, implement a security model consistent with the Android platform security model as defined in <a href="http://developer.android.com/guide/topics/security/permissions.html">Security and Permissions reference document</a> in the APIs.
+      </li>
+      <li>[C-1-3] MUST have separate and isolated shared application storage (a.k.a. <code>/sdcard</code>) directories for each user instance.
+      </li>
+      <li>[C-1-4] MUST ensure that applications owned by and running on behalf a given user cannot list, read, or write to the files owned by any other user, even if the data of both users are stored on the same volume or filesystem.
+      </li>
+      <li>[C-1-5] MUST encrypt the contents of the SD card when multiuser is enabled using a key stored only on non-removable media accessible only to the system if device implementations use removable media for the external storage APIs. As this will make the media unreadable by a host PC, device implementations will be required to switch to MTP or a similar system to provide host PCs with access to the current user’s data.
+      </li>
+    </ul>
+    <p>
+      If device implementations include multiple users and do not declare the <code>android.hardware.telephony</code> feature flag, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST support restricted profiles, a feature that allows device owners to manage additional users and their capabilities on the device. With restricted profiles, device owners can quickly set up separate environments for additional users to work in, with the ability to manage finer-grained restrictions in the apps that are available in those environments.
+      </li>
+    </ul>
+    <p>
+      If device implementations include multiple users and declare the <code>android.hardware.telephony</code> feature flag, they:
+    </p>
+    <ul>
+      <li>[C-3-1] MUST NOT support restricted profiles but MUST align with the AOSP implementation of controls to enable /disable other users from accessing the voice calls and SMS.
+      </li>
+    </ul>
+    <h3 id="9_6_premium_sms_warning">
+      9.6. Premium SMS Warning
+    </h3>
+    <p>
+      Android includes support for warning users of any outgoing <a href="http://en.wikipedia.org/wiki/Short_code">premium SMS message</a>. Premium SMS messages are text messages sent to a service registered with a carrier that may incur a charge to the user.
+    </p>
+    <p>
+      If device implementations declare support for <code>android.hardware.telephony</code>, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST warn users before sending a SMS message to numbers identified by regular expressions defined in <code>/data/misc/sms/codes.xml</code> file in the device. The upstream Android Open Source Project provides an implementation that satisfies this requirement.
+      </li>
+    </ul>
+    <h3 id="9_7_kernel_security_features">
+      9.7. Kernel Security Features
+    </h3>
+    <p>
+      The Android Sandbox includes features that use the Security-Enhanced Linux (SELinux) mandatory access control (MAC) system, seccomp sandboxing, and other security features in the Linux kernel. Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST maintain compatibility with existing applications, even when SELinux or any other security features are implemented below the Android framework.
+      </li>
+      <li>[C-0-2] MUST NOT have a visible user interface when a security violation is detected and successfully blocked by the security feature implemented below the Android framework, but MAY have a visible user interface when an unblocked security violation occurs resulting in a successful exploit.
+      </li>
+      <li>[C-0-3] MUST NOT make SELinux or any other security features implemented below the Android framework configurable to the user or app developer.
+      </li>
+      <li>[C-0-4] MUST NOT allow an application that can affect another application through an API (such as a Device Administration API) to configure a policy that breaks compatibility.
+      </li>
+      <li>[C-0-5] MUST split the media framework into multiple processes so that it is possible to more narrowly grant access for each process as <a href="https://source.android.com/devices/media/framework-hardening.html#arch_changes">described</a> in the Android Open Source Project site.
+      </li>
+      <li>[C-0-6] MUST implement a kernel application sandboxing mechanism which allows filtering of system calls using a configurable policy from multithreaded programs. The upstream Android Open Source Project meets this requirement through enabling the seccomp-BPF with threadgroup synchronization (TSYNC) as described <a href="http://source.android.com/devices/tech/config/kernel.html#Seccomp-BPF-TSYNC">in the Kernel Configuration section of source.android.com</a>.
+      </li>
+    </ul>
+    <p>
+      Kernel integrity and self-protection features are integral to Android security. Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-7] MUST implement kernel stack buffer overflow protections (e.g. <code>CONFIG_CC_STACKPROTECTOR_STRONG</code>).
+      </li>
+      <li>[C-0-8] MUST implement strict kernel memory protections where executable code is read-only, read-only data is non-executable and non-writable, and writable data is non-executable (e.g. <code>CONFIG_DEBUG_RODATA</code> or <code>CONFIG_STRICT_KERNEL_RWX</code>).
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to keep kernel data which is written only during initialization marked read-only after initialization (e.g. <code>__ro_after_init</code>).
+      </li>
+      <li>[SR} STRONGLY RECOMMENDED to implement static and dynamic object size bounds checking of copies between user-space and kernel-space (e.g. <code>CONFIG_HARDENED_USERCOPY</code>).
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to never execute user-space memory when running in the kernel (e.g. hardware PXN, or emulated via <code>CONFIG_CPU_SW_DOMAIN_PAN</code> or <code>CONFIG_ARM64_SW_TTBR0_PAN</code>).
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to never read or write user-space memory in the kernel outside of normal usercopy access APIs (e.g. hardware PAN, or emulated via <code>CONFIG_CPU_SW_DOMAIN_PAN</code> or <code>CONFIG_ARM64_SW_TTBR0_PAN</code>).
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to randomize the layout of the kernel code and memory, and to avoid exposures that would compromise the randomization (e.g. <code>CONFIG_RANDOMIZE_BASE</code> with bootloader entropy via the <a href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/chosen.txt"><code>/chosen/kaslr-seed Device Tree node</code></a> or <a href="https://docs.microsoft.com/en-us/windows-hardware/drivers/bringup/efi-rng-protocol"><code>EFI_RNG_PROTOCOL</code></a>).
+      </li>
+    </ul>
+    <p>
+      If device implementations use a Linux kernel, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST implement SELinux.
+      </li>
+      <li>[C-1-2] MUST set SELinux to global enforcing mode.
+      </li>
+      <li>[C-1-3] MUST configure all domains in enforcing mode. No permissive mode domains are allowed, including domains specific to a device/vendor.
+      </li>
+      <li>[C-1-4] MUST NOT modify, omit, or replace the neverallow rules present within the system/sepolicy folder provided in the upstream Android Open Source Project (AOSP) and the policy MUST compile with all neverallow rules present, for both AOSP SELinux domains as well as device/vendor specific domains.
+      </li>
+      <li>SHOULD retain the default SELinux policy provided in the system/sepolicy folder of the upstream Android Open Source Project and only further add to this policy for their own device-specific configuration.
+      </li>
+    </ul>
+    <p>
+      If device implementations use kernel other than Linux, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST use an mandatory access control system that is equivalent to SELinux.
+      </li>
+    </ul>
+    <h3 id="9_8_privacy">
+      9.8. Privacy
+    </h3>
+    <h4 id="9_8_1_usage_history">
+      9.8.1. Usage History
+    </h4>
+    <p>
+      Android stores the history of the user's choices and manages such history by <a href="https://developer.android.com/reference/android/app/usage/UsageStatsManager.html">UsageStatsManager</a>.
+    </p>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST keep a reasonable retention period of such user history.
+      </li>
+      <li>[SR] Are STRONGLY RECOMMENDED to keep the 14 days retention period as configured by default in the AOSP implementation.
+      </li>
+    </ul>
+    <h4 id="9_8_2_recording">
+      9.8.2. Recording
+    </h4>
+    <p>
+      If device implementations include functionality in the system that captures the contents displayed on the screen and/or records the audio stream played on the device, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST have an ongoing notification to the user whenever this functionality is enabled and actively capturing/recording.
+      </li>
+    </ul>
+    <p>
+      If device implementations include a component enabled out-of-box, capable of recording ambient audio to infer useful information about user’s context, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST NOT store in persistent on-device storage or transmit off the device the recorded raw audio or any format that can be converted back into the original audio or a near facsimile, except with explicit user consent.
+      </li>
+    </ul>
+    <h4 id="9_8_3_connectivity">
+      9.8.3. Connectivity
+    </h4>
+    <p>
+      If device implementations have a USB port with USB peripheral mode support, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST present a user interface asking for the user's consent before allowing access to the contents of the shared storage over the USB port.
+      </li>
+    </ul>
+    <h4 id="9_8_4_network_traffic">
+      9.8.4. Network Traffic
+    </h4>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST preinstall the same root certificates for the system-trusted Certificate Authority (CA) store as <a href="https://source.android.com/security/overview/app-security.html#certificate-authorities">provided</a> in the upstream Android Open Source Project.
+      </li>
+      <li>[C-0-2] MUST ship with an empty user root CA store.
+      </li>
+      <li>[C-0-3] MUST display a warning to the user indicating the network traffic may be monitored, when a user root CA is added.
+      </li>
+    </ul>
+    <p>
+      If device traffic is routed through a VPN, device implementations:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST display a warning to the user indicating either:
+        <ul>
+          <li>That network traffic may be monitored.
+          </li>
+          <li>That network traffic is being routed through the specific VPN application providing the VPN.
+          </li>
+        </ul>
+      </li>
+    </ul>
+    <p>
+      If device implementations have a mechanism, enabled out-of-box by default, that routes network data traffic through a proxy server or VPN gateway (for example, preloading a VPN service with <code>android.permission.CONTROL_VPN</code> granted), they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST ask for the user's consent before enabling that mechanism, unless that VPN is enabled by the Device Policy Controller via the <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#setAlwaysOnVpnPackage%28android.content.ComponentName,%20java.lang.String,%20boolean%29"><code>DevicePolicyManager.setAlwaysOnVpnPackage()</code></a> , in which case the user does not need to provide a separate consent, but MUST only be notified.
+      </li>
+    </ul>
+    <h3 id="9_9_data_storage_encryption">
+      9.9. Data Storage Encryption
+    </h3>
+    <p>
+      If device implementations support a secure lock screen as described in <a href="#9_11_1_secure_lock_screen">section 9.11.1</a>, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST support data storage encryption of the application private data (<code>/data partition</code>), as well as the application shared storage partition (<code>/sdcard partition</code>) if it is a permanent, non-removable part of the device.
+      </li>
+    </ul>
+    <p>
+      If device implementations support a secure lock screen as described in <a href="#9_11_1_secure_lock_screen">section 9.11.1</a> and support data storage encryption with Advanced Encryption Standard (AES) crypto performance above 50MiB/sec, they:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-2-1] MUST enable the data storage encryption by default at the time the user has completed the out-of-box setup experience. If device implementations are already launched on an earlier Android version with encryption disabled by default, such a device cannot meet the requirement through a system software update and thus MAY be exempted.
+        </p>
+      </li>
+      <li>
+        <p>
+          SHOULD meet the above data storage encryption requirement via implementing <a href="https://source.android.com/security/encryption/file-based.html">File Based Encryption</a> (FBE).
+        </p>
+      </li>
+    </ul>
+    <h4 id="9_9_1_direct_boot">
+      9.9.1. Direct Boot
+    </h4>
+    <p>
+      Device implementations:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-0-1] MUST implement the <a href="http://developer.android.com/preview/features/direct-boot.html">Direct Boot mode</a> APIs even if they do not support Storage Encryption.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-0-2] The <a href="https://developer.android.com/reference/android/content/Intent.html#ACTION_LOCKED_BOOT_COMPLETED"><code>ACTION_LOCKED_BOOT_COMPLETED</code></a> and <a href="https://developer.android.com/reference/android/content/Intent.html#ACTION_USER_UNLOCKED"><code>ACTION_USER_UNLOCKED</code></a> Intents MUST still be broadcast to signal Direct Boot aware applications that Device Encrypted (DE) and Credential Encrypted (CE) storage locations are available for user.
+        </p>
+      </li>
+    </ul>
+    <h4 id="9_9_2_file_based_encryption">
+      9.9.2. File Based Encryption
+    </h4>
+    <p>
+      If device implementations support FBE, they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST boot up without challenging the user for credentials and allow Direct Boot aware apps to access to the Device Encrypted (DE) storage after the <code>ACTION_LOCKED_BOOT_COMPLETED</code> message is broadcasted.
+      </li>
+      <li>[C-1-2] MUST only allow access to Credential Encrypted (CE) storage after the user has unlocked the device by supplying their credentials (eg. passcode, pin, pattern or fingerprint) and the <code>ACTION_USER_UNLOCKED</code> message is broadcasted.
+      </li>
+      <li>[C-1-3] MUST NOT offer any method to unlock the CE protected storage without the user-supplied credentials.
+      </li>
+      <li>[C-1-4] MUST support Verified Boot and ensure that DE keys are cryptographically bound to the device's hardware root of trust.
+      </li>
+      <li>[C-1-5] MUST support encrypting file contents using AES with a key length of 256-bits in XTS mode.
+      </li>
+      <li>
+        <p>
+          [C-1-6] MUST support encrypting file name using AES with a key length of 256-bits in CBC-CTS mode.
+        </p>
+      </li>
+      <li>
+        <p>
+          The keys protecting CE and DE storage areas:
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-1-7] MUST be cryptographically bound to a hardware-backed Keystore.
+        </p>
+      </li>
+      <li>[C-1-8] CE keys MUST be bound to a user's lock screen credentials.
+      </li>
+      <li>[C-1-9] CE keys MUST be bound to a default passcode when the user has not specified lock screen credentials.
+      </li>
+      <li>
+        <p>
+          [C-1-10] MUST be unique and distinct, in other words no user's CE or DE key matches any other user's CE or DE keys.
+        </p>
+      </li>
+      <li>
+        <p>
+          SHOULD make preloaded essential apps (e.g. Alarm, Phone, Messenger) Direct Boot aware.
+        </p>
+      </li>
+      <li>MAY support alternative ciphers, key lengths and modes for file content and file name encryption, but MUST use the mandatorily supported ciphers, key lengths and modes by default.
+      </li>
+    </ul>
+    <p>
+      The upstream Android Open Source project provides a preferred implementation of this feature based on the Linux kernel ext4 encryption feature.
+    </p>
+    <h4 id="9_9_3_full_disk_encryption">
+      9.9.3. Full Disk Encryption
+    </h4>
+    <p>
+      If device implementations support <a href="http://source.android.com/devices/tech/security/encryption/index.html">full disk encryption</a> (FDE), they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST use AES with a key of 128-bits (or greater) and a mode designed for storage (for example, AES-XTS, AES-CBC-ESSIV).
+      </li>
+      <li>[C-1-2] MUST use a default passcode to wrap the encryption key and MUST NOT write the encryption key to storage at any time without being encrypted.
+      </li>
+      <li>[C-1-3] MUST provide the user the possibility to AES encrypt the encryption key, except when it is in active use, with the lock screen credentials stretched using a slow stretching algorithm (e.g. PBKDF2 or scrypt).
+      </li>
+      <li>[C-1-4] The above default password stretching algorithm MUST be cryptographically bound to that keystore when the user has not specified a lock screen credentials or has disabled use of the passcode for encryption and the device provides a hardware-backed keystore.
+      </li>
+      <li>[C-1-5] MUST NOT send encryption key off the device (even when wrapped with the user passcode and/or hardware bound key).
+      </li>
+    </ul>
+    <p>
+      The upstream Android Open Source project provides a preferred implementation of this feature, based on the Linux kernel feature dm-crypt.
+    </p>
+    <h3 id="9_10_device_integrity">
+      9.10. Device Integrity
+    </h3>
+    <p>
+      The following requirements ensures there is transparancy to the status of the device integrity. Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST correctly report through the System API method <code>PersistentDataBlockManager.getFlashLockState()</code> whether their bootloader state permits flashing of the system image. The <code>FLASH_LOCK_UNKNOWN</code> state is reserved for device implementations upgrading from an earlier version of Android where this new system API method did not exist.
+      </li>
+    </ul>
+    <p>
+      Verified boot is a feature that guarantees the integrity of the device software. If a device implementation supports the feature, it:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST declare the platform feature flag <code>android.software.verified_boot</code>.
+      </li>
+      <li>[C-2-1] MUST perform verification on every boot sequence.
+      </li>
+      <li>[C-3-1] MUST start verification from an immutable hardware key that is the root of trust and go all the way up to the system partition.
+      </li>
+      <li>[C-4-1] MUST implement each stage of verification to check the integrity and authenticity of all the bytes in the next stage before executing the code in the next stage.
+      </li>
+      <li>[C-5-1] MUST use verification algorithms as strong as current recommendations from NIST for hashing algorithms (SHA-256) and public key sizes (RSA-2048).
+      </li>
+      <li>[C-6-1] MUST NOT allow boot to complete when system verification fails, unless the user consents to attempt booting anyway, in which case the data from any non-verified storage blocks MUST not be used.
+      </li>
+      <li>[C-7-1] MUST NOT allow verified partitions on the device to be modified unless the user has explicitly unlocked the boot loader.
+      </li>
+      <li>[SR] If there are multiple discrete chips in the device (e.g. radio, specialized image processor), the boot process of each of those chips is STRONGLY RECOMMENDED to verify every stage upon booting.
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to use tamper-evident storage: for when the bootloader is unlocked. Tamper-evident storage means that the boot loader can detect if the storage has been tampered with from inside the HLOS (High Level Operating System).
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to prompt the user, while using the device, and require physical confirmation before allowing a transition from boot loader locked mode to boot loader unlocked mode.
+      </li>
+      <li>[SR] STRONGLY RECOMMENDED to implement rollback protection for the HLOS (e.g. boot, system partitions) and to use tamper-evident storage for storing the metadata used for determining the minimum allowable OS version.
+      </li>
+      <li>SHOULD implement rollback protection for any component with persistent firmware (e.g. modem, camera) and SHOULD use tamper-evident storage for storing the metadata used for determining the minimum allowable version.
+      </li>
+    </ul>
+    <p>
+      The upstream Android Open Source Project provides a preferred implementation of this feature in the <a href="http://android.googlesource.com/platform/external/avb/"><code>external/avb/</code></a> repository, which can be integrated into the boot loader used for loading Android.
+    </p>
+    <p>
+      Device implementations with Advanced Encryption Standard (AES) crypto performance above 50 MiB/seconds:
+    </p>
+    <ul>
+      <li>[C-8-1] MUST support verified boot for device integrity.
+      </li>
+    </ul>
+    <p>
+      If a device implementation is already launched without supporting verified boot on an earlier version of Android, such a device can not add support for this feature with a system software update and thus are exempted from the requirement.
+    </p>
+    <h3 id="9_11_keys_and_credentials">
+      9.11. Keys and Credentials
+    </h3>
+    <p>
+      The <a href="https://developer.android.com/training/articles/keystore.html">Android Keystore System</a> allows app developers to store cryptographic keys in a container and use them in cryptographic operations through the <a href="https://developer.android.com/reference/android/security/KeyChain.html">KeyChain API</a> or the <a href="https://developer.android.com/reference/java/security/KeyStore.html">Keystore API</a>. Device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST at least allow more than 8,192 keys to be imported.
+      </li>
+      <li>[C-0-2] The lock screen authentication MUST rate-limit attempts and MUST have an exponential backoff algorithm. Beyond 150 failed attempts, the delay MUST be at least 24 hours per attempt.
+      </li>
+      <li>SHOULD not limit the number of keys that can be generated
+      </li>
+    </ul>
+    <p>
+      When the device implementation supports a secure lock screen, it:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST back up the keystore implementation with secure hardware.
+      </li>
+      <li>[C-1-2] MUST have implementations of RSA, AES, ECDSA and HMAC cryptographic algorithms and MD5, SHA1, and SHA-2 family hash functions to properly support the Android Keystore system's supported algorithms in an area that is securely isolated from the code running on the kernel and above. Secure isolation MUST block all potential mechanisms by which kernel or userspace code might access the internal state of the isolated environment, including DMA. The upstream Android Open Source Project (AOSP) meets this requirement by using the <a href="https://source.android.com/security/trusty/">Trusty</a> implementation, but another ARM TrustZone-based solution or a third-party reviewed secure implementation of a proper hypervisor-based isolation are alternative options.
+      </li>
+      <li>[C-1-3] MUST perform the lock screen authentication in the isolated execution environment and only when successful, allow the authentication-bound keys to be used. The upstream Android Open Source Project provides the <a href="http://source.android.com/devices/tech/security/authentication/gatekeeper.html">Gatekeeper Hardware Abstraction Layer (HAL)</a> and Trusty, which can be used to satisfy this requirement.
+      </li>
+      <li>[C-1-4] MUST support key attestation where the attestation signing key is protected by secure hardware and signing is performed in secure hardware. The attestation signing keys MUST be shared across large enough number of devices to prevent the keys from being used as device identifiers. One way of meeting this requirement is to share the same attestation key unless at least 100,000 units of a given SKU are produced. If more than 100,000 units of an SKU are produced, a different key MAY be used for each 100,000 units.
+      </li>
+    </ul>
+    <p>
+      Note that if a device implementation is already launched on an earlier Android version, such a device is exempted from the requirement to have a hardware-backed keystore, unless it declares the <code>android.hardware.fingerprint</code> feature which requires a hardware-backed keystore.
+    </p>
+    <h4 id="9_11_1_secure_lock_screen">
+      9.11.1. Secure Lock Screen
+    </h4>
+    <p>
+      If device implementations have a secure lock screen and include one or more trust agent, which implements the <code>TrustAgentService</code> System API, then they:
+    </p>
+    <ul>
+      <li>[C-1-1] MUST indicate the user in the Settings and Lock screen user interface of situations where either the screen auto-lock is deferred or the screen lock can be unlocked by the trust agent. The AOSP meets the requirement by showing a text description for the "Automatically lock setting" and "Power button instantly locks setting" menus and a distinguishable icon on the lock screen.
+      </li>
+      <li>[C-1-2] MUST respect and fully implement all trust agent APIs in the <code>DevicePolicyManager</code> class, such as the <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#KEYGUARD&amp;lowbarDISABLE&amp;lowbarTRUST&amp;lowbarAGENTS"><code>KEYGUARD_DISABLE_TRUST_AGENTS</code></a> constant.
+      </li>
+      <li>[C-1-3] MUST NOT fully implement the <code>TrustAgentService.addEscrowToken()</code> function on a device that is used as the primary personal device (e.g. handheld) but MAY fully implement the function on device implementations typically shared.
+      </li>
+      <li>[C-1-4] MUST encrypt the tokens added by <code>TrustAgentService.addEscrowToken()</code> before storing them on the device.
+      </li>
+      <li>[C-1-5] MUST NOT store the encryption key on the device.
+      </li>
+      <li>[C-1-6] MUST inform the user about the security implications before enabling the escrow token to decrypt the data storage.
+      </li>
+    </ul>
+    <p>
+      If device implementations add or modify the authentication methods to unlock the lock screen, then for such an authentication method to be treated as a secure way to lock the screen, they:
+    </p>
+    <ul>
+      <li>[C-2-1] MUST be the user authentication method as described in <a href="https://developer.android.com/training/articles/keystore.html#UserAuthentication">Requiring User Authentication For Key Use</a>.
+      </li>
+      <li>[C-2-2] MUST unlock all keys for a third-party developer app to use when the user unlocks the secure lock screen. For example, all keys MUST be available for a third-party developer app through relevant APIs, such as <a href="https://developer.android.com/reference/android/app/KeyguardManager.html#createConfirmDeviceCredentialIntent%28java.lang.CharSequence,%20java.lang.CharSequence%29"><code>createConfirmDeviceCredentialIntent</code></a> and <a href="https://developer.android.com/reference/android/security/keystore/KeyGenParameterSpec.Builder.html#setUserAuthenticationRequired%28boolean%29"><code>setUserAuthenticationRequired</code></a>.
+      </li>
+    </ul>
+    <p>
+      If device implementations add or modify the authentication methods to unlock the lock screen if based on a known secret then for such an authentication method to be treated as a secure way to lock the screen, they:
+    </p>
+    <ul>
+      <li>[C-3-1] The entropy of the shortest allowed length of inputs MUST be greater than 10 bits.
+      </li>
+      <li>[C-3-2] The maximum entropy of all possible inputs MUST be greater than 18 bits.
+      </li>
+      <li>[C-3-3] MUST not replace any of the existing authentication methods (PIN,pattern, password) implemented and provided in AOSP.
+      </li>
+      <li>[C-3-4] MUST be disabled when the Device Policy Controller (DPC) application has set the password quality policy via the <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#setPasswordQuality%28android.content.ComponentName,%20int%29"><code>DevicePolicyManager.setPasswordQuality()</code></a> method with a more restrictive quality constant than <code>PASSWORD_QUALITY_SOMETHING</code>.
+      </li>
+    </ul>
+    <p>
+      If device implementations add or modify the authentication methods to unlock the lock screen if based on a physical token or the location, then for such an authentication method to be treated as a secure way to lock the screen, they:
+    </p>
+    <ul>
+      <li>[C-4-1] MUST have a fall-back mechanism to use one of the primary authentication methods which is based on a known secret and meets the requirements to be treated as a secure lock screen.
+      </li>
+      <li>[C-4-2] MUST be disabled and only allow the primary authentication to unlock the screen when the Device Policy Controller (DPC) application has set the policy with either the <a href="http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#setKeyguardDisabledFeatures%28android.content.ComponentName,%20int%29"><code>DevicePolicyManager.setKeyguardDisabledFeatures(KEYGUARD_DISABLE_TRUST_AGENTS)</code></a> method or the <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#setPasswordQuality%28android.content.ComponentName,%20int%29"><code>DevicePolicyManager.setPasswordQuality()</code></a> method with a more restrictive quality constant than <code>PASSWORD_QUALITY_UNSPECIFIED</code>.
+      </li>
+      <li>[C-4-3] The user MUST be challenged for the primary authentication (e.g.PIN, pattern, password) at least once every 72 hours or less.
+      </li>
+    </ul>
+    <p>
+      If device implementations add or modify the authentication methods to unlock the lock screen based on biometrics, then for such an authentication method to be treated as a secure way to lock the screen, they:
+    </p>
+    <ul>
+      <li>[C-5-1] MUST have a fall-back mechanism to use one of the primary authentication methods which is based on a known secret and meets the requirements to be treated as a secure lock screen.
+      </li>
+      <li>[C-5-2] MUST be disabled and only allow the primary authentication to unlock the screen when the Device Policy Controller (DPC) application has set the keguard feature policy by calling the method <a href="http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#setKeyguardDisabledFeatures%28android.content.ComponentName,%20int%29"><code>DevicePolicyManager.setKeyguardDisabledFeatures(KEYGUARD_DISABLE_FINGERPRINT)</code></a>.
+      </li>
+      <li>[C-5-3] MUST have a false acceptance rate that is equal or stronger than what is required for a fingerprint sensor as described in section 7.3.10, or otherwise MUST be disabled and only allow the primary authentication to unlock the screen when the Device Policy Controller (DPC) application has set the password quality policy via the <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#setPasswordQuality%28android.content.ComponentName,%20int%29"><code>DevicePolicyManager.setPasswordQuality()</code></a> method with a more restrictive quality constant than <code>PASSWORD_QUALITY_BIOMETRIC_WEAK</code>.
+      </li>
+      <li>[C-5-4] The user MUST be challenged for the primary authentication (e.g.PIN, pattern, password) at least once every 72 hours or less.
+      </li>
+    </ul>
+    <p>
+      If device implementations add or modify the authentication methods to unlock the lock screen and if such an authentication method will be used to unlock the keyguard, but will not be treated as a secure lock screen, then they:
+    </p>
+    <ul>
+      <li>[C-6-1] MUST return <code>false</code> for both the <a href="http://developer.android.com/reference/android/app/KeyguardManager.html#isKeyguardSecure%28%29"><code>KeyguardManager.isKeyguardSecure()</code></a> and the <a href="https://developer.android.com/reference/android/app/KeyguardManager.html#isDeviceSecure%28%29"><code>KeyguardManager.isDeviceSecure()</code></a> methods.
+      </li>
+      <li>[C-6-2] MUST be disabled when the Device Policy Controller (DPC) application has set the password quality policy via the <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#setPasswordQuality%28android.content.ComponentName,%20int%29"><code>DevicePolicyManager.setPasswordQuality()</code></a> method with a more restrictive quality constant than <code>PASSWORD_QUALITY_UNSPECIFIED</code>.
+      </li>
+      <li>[C-6-3] MUST NOT reset the password expiration timers set by <a href="http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#setPasswordExpirationTimeout%28android.content.ComponentName,%20long%29"><code>DevicePolicyManager.setPasswordExpirationTimeout()</code></a>.
+      </li>
+      <li>[C-6-4] MUST NOT authenticate access to keystores if the application has called <a href="https://developer.android.com/reference/android/security/keystore/KeyGenParameterSpec.Builder.html#setUserAuthenticationRequired%28boolean%29"><code>KeyGenParameterSpec.Builder.setUserAuthenticationRequired(true)</code></a>).
+      </li>
+    </ul>
+    <h3 id="9_12_data_deletion">
+      9.12. Data Deletion
+    </h3>
+    <p>
+      All device implementations:
+    </p>
+    <ul>
+      <li>[C-0-1] MUST provide users a mechanism to perform a "Factory Data Reset".
+      </li>
+      <li>[C-0-2] MUST delete all user-generated data. That is, all data except for the following:
+        <ul>
+          <li>The system image
+          </li>
+          <li>Any operating system files required by the system image
+          </li>
+        </ul>
+      </li>
+      <li>[C-0-3] MUST delete the data in such a way that will satisfy relevant industry standards such as NIST SP800-88.
+      </li>
+      <li>[C-0-4] MUST trigger the above "Factory Data Reset" process when the <a href="https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#wipeData%28int%29"><code>DevicePolicyManager.wipeData()</code></a> API is called by the primary user's Device Policy Controller app.
+      </li>
+      <li>MAY provide a fast data wipe option that conducts only a logical data erase.
+      </li>
+    </ul>
+    <h3 id="9_13_safe_boot_mode">
+      9.13. Safe Boot Mode
+    </h3>
+    <p>
+      Android provides Safe Boot Mode, which allows users to boot up into a mode where only preinstalled system apps are allowed to run and all third-party apps are disabled. This mode, known as "Safe Boot Mode", provides the user the capability to uninstall potentially harmful third-party apps.
+    </p>
+    <p>
+      Device implementations are:
+    </p>
+    <ul>
+      <li>[SR] STRONGLY RECOMMENDED to implement Safe Boot Mode.
+      </li>
+    </ul>
+    <p>
+      If device implementations implement Safe Boot Mode, they:
+    </p>
+    <ul>
+      <li>
+        <p>
+          [C-1-1] MUST provide the user an option to enter Safe Boot Mode in such a way that is uninterruptible from third-party apps installed on the device, except when the third-party app is a Device Policy Controller and has set the <a href="https://developer.android.com/reference/android/os/UserManager.html#DISALLOW_SAFE_BOOT"><code>UserManager.DISALLOW_SAFE_BOOT</code></a> flag as true.
+        </p>
+      </li>
+      <li>
+        <p>
+          [C-1-2] MUST provide the user the capability to uninstall any third-party apps within Safe Mode.
+        </p>
+      </li>
+      <li>
+        <p>
+          SHOULD provide the user an option to enter Safe Boot Mode from the boot menu using a workflow that is different from that of a normal boot.
+        </p>
+      </li>
+    </ul>
+    <h3 id="9_14_automotive_vehicle_system_isolation">
+      9.14. Automotive Vehicle System Isolation
+    </h3>
+    <p>
+      Android Automotive devices are expected to exchange data with critical vehicle subsystems by using the <a href="http://source.android.com/devices/automotive.html">vehicle HAL</a> to send and receive messages over vehicle networks such as CAN bus.
+    </p>
+    <p>
+      The data exchange can be secured by implementing security features below the Android framework layers to prevent malicious or unintentional interaction with these subsystems.
+    </p>
+    <h2 id="10_software_compatibility_testing">
+      10. Software Compatibility Testing
+    </h2>
+    <p>
+      Device implementations MUST pass all tests described in this section.
+    </p>
+    <p>
+      However, note that no software test package is fully comprehensive. For this reason, device implementers are <strong>STRONGLY RECOMMENDED</strong> to make the minimum number of changes as possible to the reference and preferred implementation of Android available from the Android Open Source Project. This will minimize the risk of introducing bugs that create incompatibilities requiring rework and potential device updates.
+    </p>
+    <h3 id="10_1_compatibility_test_suite">
+      10.1. Compatibility Test Suite
+    </h3>
+    <p>
+      Device implementations MUST pass the <a href="http://source.android.com/compatibility/index.html">Android Compatibility Test Suite (CTS)</a> available from the Android Open Source Project, using the final shipping software on the device. Additionally, device implementers SHOULD use the reference implementation in the Android Open Source tree as much as possible, and MUST ensure compatibility in cases of ambiguity in CTS and for any reimplementations of parts of the reference source code.
+    </p>
+    <p>
+      The CTS is designed to be run on an actual device. Like any software, the CTS may itself contain bugs. The CTS will be versioned independently of this Compatibility Definition, and multiple revisions of the CTS may be released for Android 8.0. Device implementations MUST pass the latest CTS version available at the time the device software is completed.
+    </p>
+    <h3 id="10_2_cts_verifier">
+      10.2. CTS Verifier
+    </h3>
+    <p>
+      Device implementations MUST correctly execute all applicable cases in the CTS Verifier. The CTS Verifier is included with the Compatibility Test Suite, and is intended to be run by a human operator to test functionality that cannot be tested by an automated system, such as correct functioning of a camera and sensors.
+    </p>
+    <p>
+      The CTS Verifier has tests for many kinds of hardware, including some hardware that is optional. Device implementations MUST pass all tests for hardware that they possess; for instance, if a device possesses an accelerometer, it MUST correctly execute the Accelerometer test case in the CTS Verifier. Test cases for features noted as optional by this Compatibility Definition Document MAY be skipped or omitted.
+    </p>
+    <p>
+      Every device and every build MUST correctly run the CTS Verifier, as noted above. However, since many builds are very similar, device implementers are not expected to explicitly run the CTS Verifier on builds that differ only in trivial ways. Specifically, device implementations that differ from an implementation that has passed the CTS Verifier only by the set of included locales, branding, etc. MAY omit the CTS Verifier test.
+    </p>
+    <h2 id="11_updatable_software">
+      11. Updatable Software
+    </h2>
+    <p>
+      Device implementations MUST include a mechanism to replace the entirety of the system software. The mechanism need not perform “live” upgrades—that is, a device restart MAY be required.
+    </p>
+    <p>
+      Any method can be used, provided that it can replace the entirety of the software preinstalled on the device. For instance, any of the following approaches will satisfy this requirement:
+    </p>
+    <ul>
+      <li>“Over-the-air (OTA)” downloads with offline update via reboot.
+      </li>
+      <li>“Tethered” updates over USB from a host PC.
+      </li>
+      <li>“Offline” updates via a reboot and update from a file on removable storage.
+      </li>
+    </ul>
+    <p>
+      However, if the device implementation includes support for an unmetered data connection such as 802.11 or Bluetooth PAN (Personal Area Network) profile, it MUST support OTA downloads with offline update via reboot.
+    </p>
+    <p>
+      The update mechanism used MUST support updates without wiping user data. That is, the update mechanism MUST preserve application private data and application shared data. Note that the upstream Android software includes an update mechanism that satisfies this requirement.
+    </p>
+    <p>
+      For device implementations that are launching with Android 6.0 and later, the update mechanism SHOULD support verifying that the system image is binary identical to expected result following an OTA. The block-based OTA implementation in the upstream Android Open Source Project, added since Android 5.1, satisfies this requirement.
+    </p>
+    <p>
+      Also, device implementations SHOULD support <a href="https://source.android.com/devices/tech/ota/ab_updates.html">A/B system updates</a>. The AOSP implements this feature using the boot control HAL.
+    </p>
+    <p>
+      If an error is found in a device implementation after it has been released but within its reasonable product lifetime that is determined in consultation with the Android Compatibility Team to affect the compatibility of third-party applications, the device implementer MUST correct the error via a software update available that can be applied per the mechanism just described.
+    </p>
+    <p>
+      Android includes features that allow the Device Owner app (if present) to control the installation of system updates. To facilitate this, the system update subsystem for devices that report android.software.device_admin MUST implement the behavior described in the <a href="http://developer.android.com/reference/android/app/admin/SystemUpdatePolicy.html">SystemUpdatePolicy</a> class.
+    </p>
+    <h2 id="12_document_changelog">
+      12. Document Changelog
+    </h2>
+    <p>
+      For a summary of changes to the Compatibility Definition in this release:
+    </p>
+    <ul>
+      <li>
+        <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/oreo-dev/?pretty=full&amp;no-merges">Document changelog</a>
+      </li>
+    </ul>
+    <p>
+      For a summary of changes to individuals sections:
+    </p>
+    <ol>
+      <li>
+        <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/oreo-dev/1_introduction?pretty=full&amp;no-merges">Introduction</a>
+      </li>
+      <li>
+        <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/oreo-dev/2_device_types?pretty=full&amp;no-merges">Device Types</a>
+      </li>
+      <li>
+        <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/oreo-dev/3_software?pretty=full&amp;no-merges">Software</a>
+      </li>
+      <li>
+        <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/oreo-dev/4_application-packaging?pretty=full&amp;no-merges">Application Packaging</a>
+      </li>
+      <li>
+        <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/oreo-dev/5_multimedia?pretty=full&amp;no-merges">Multimedia</a>
+      </li>
+      <li>
+        <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/oreo-dev/6_dev-tools-and-options?pretty=full&amp;no-merges">Developer Tools and Options</a>
+      </li>
+      <li>
+        <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/oreo-dev/7_hardware-compatibility?pretty=full&amp;no-merges">Hardware Compatibility</a>
+      </li>
+      <li>
+        <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/oreo-dev/8_performance-and-power?pretty=full&amp;no-merges">Performance and Power</a>
+      </li>
+      <li>
+        <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/oreo-dev/9_security-model?pretty=full&amp;no-merges">Security Model</a>
+      </li>
+      <li>
+        <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/oreo-dev/10_software-compatibility-testing?pretty=full&amp;no-merges">Software Compatibility Testing</a>
+      </li>
+      <li>
+        <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/oreo-dev/11_updatable-software?pretty=full&amp;no-merges">Updatable Software</a>
+      </li>
+      <li>
+        <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/oreo-dev/12_document-changelog?pretty=full&amp;no-merges">Document Changelog</a>
+      </li>
+      <li>
+        <a href="https://android.googlesource.com/platform/compatibility/cdd/+log/oreo-dev/13_contact-us?pretty=full&amp;no-merges">Contact Us</a>
+      </li>
+    </ol>
+    <h3 id="12_1_changelog_viewing_tips">
+      12.1. Changelog Viewing Tips
+    </h3>
+    <p>
+      Changes are marked as follows:
+    </p>
+    <ul>
+      <li>
+        <p>
+          <strong>CDD</strong><br />
+          Substantive changes to the compatibility requirements.
+        </p>
+      </li>
+      <li>
+        <p>
+          <strong>Docs</strong><br />
+          Cosmetic or build related changes.
+        </p>
+      </li>
+    </ul>
+    <p>
+      For best viewing, append the <code>pretty=full</code> and <code>no-merges</code> URL parameters to your changelog URLs.
+    </p>
+    <h2 id="13_contact_us">
+      13. Contact Us
+    </h2>
+    <p>
+      You can join the <a href="https://groups.google.com/forum/#!forum/android-compatibility">android-compatibility forum</a> and ask for clarifications or bring up any issues that you think the document does not cover.
+    </p>
   </body>
 </html>
diff --git a/en/compatibility/cdd.html b/en/compatibility/cdd.html
index f1464c4..59bfbaf 100644
--- a/en/compatibility/cdd.html
+++ b/en/compatibility/cdd.html
@@ -71,6 +71,12 @@
     <th>Strings</th>
   </tr>
   <tr>
+    <td>8.0</td>
+    <td><a href="8.0/android-8.0-cdd.pdf">android-8.0-cdd.pdf</a></td>
+    <td><a href="8.0/android-8.0-cdd.html">android-8.0-cdd.html</a></td>
+    <td><a href="8.0/versions.html">Version 8.0</a></td>
+  </tr>
+  <tr>
     <td>7.1</td>
     <td><a href="7.1/android-7.1-cdd.pdf">android-7.1-cdd.pdf</a></td>
     <td><a href="7.1/android-7.1-cdd.html">android-7.1-cdd.html</a></td>
diff --git a/en/compatibility/cts/downloads.html b/en/compatibility/cts/downloads.html
index 241043b..bc1b12e 100644
--- a/en/compatibility/cts/downloads.html
+++ b/en/compatibility/cts/downloads.html
@@ -50,77 +50,77 @@
 <h2 id="android-71">Android 7.1</h2>
 <p>Android 7.1 is the release of the development milestone code-named Nougat-MR1.
 The source code for the following tests can be synced with the
-'android-cts-7.1_r8' tag in the open-source tree.</p>
+'android-cts-7.1_r9' tag in the open-source tree.</p>
 <ul>
 <li><a
-href="https://dl.google.com/dl/android/cts/android-cts-7.1_r8-linux_x86-arm.zip">Android
-7.1 R8 Compatibility Test Suite (CTS) - ARM</a></li>
+href="https://dl.google.com/dl/android/cts/android-cts-7.1_r9-linux_x86-arm.zip">Android
+7.1 R9 Compatibility Test Suite (CTS) - ARM</a></li>
 <li><a
-href="https://dl.google.com/dl/android/cts/android-cts-7.1_r8-linux_x86-x86.zip">Android
-7.1 R8 Compatibility Test Suite (CTS) - x86</a></li>
+href="https://dl.google.com/dl/android/cts/android-cts-7.1_r9-linux_x86-x86.zip">Android
+7.1 R9 Compatibility Test Suite (CTS) - x86</a></li>
 <li><a
-href="https://dl.google.com/dl/android/cts/android-cts-verifier-7.1_r8-linux_x86-arm.zip">Android
-7.1 R8 CTS Verifier - ARM</a></li>
+href="https://dl.google.com/dl/android/cts/android-cts-verifier-7.1_r9-linux_x86-arm.zip">Android
+7.1 R9 CTS Verifier - ARM</a></li>
 <li><a
-href="https://dl.google.com/dl/android/cts/android-cts-verifier-7.1_r8-linux_x86-x86.zip">Android
-7.1 R8 CTS Verifier - x86</a></li>
+href="https://dl.google.com/dl/android/cts/android-cts-verifier-7.1_r9-linux_x86-x86.zip">Android
+7.1 R9 CTS Verifier - x86</a></li>
 </ul>
 
 <h2 id="android-70">Android 7.0</h2>
 <p>Android 7.0 is the release of the development milestone code-named Nougat.
 The source code for the following tests can be synced with the
-'android-cts-7.0_r12' tag in the open-source tree.</p>
+'android-cts-7.0_r13' tag in the open-source tree.</p>
 <ul>
 <li><a
-href="https://dl.google.com/dl/android/cts/android-cts-7.0_r12-linux_x86-arm.zip">Android
-7.0 R12 Compatibility Test Suite (CTS) - ARM</a></li>
+href="https://dl.google.com/dl/android/cts/android-cts-7.0_r13-linux_x86-arm.zip">Android
+7.0 R13 Compatibility Test Suite (CTS) - ARM</a></li>
 <li><a
-href="https://dl.google.com/dl/android/cts/android-cts-7.0_r12-linux_x86-x86.zip">Android
-7.0 R12 Compatibility Test Suite (CTS) - x86</a></li>
+href="https://dl.google.com/dl/android/cts/android-cts-7.0_r13-linux_x86-x86.zip">Android
+7.0 R13 Compatibility Test Suite (CTS) - x86</a></li>
 <li><a
-href="https://dl.google.com/dl/android/cts/android-cts-verifier-7.0_r12-linux_x86-arm.zip">Android
-7.0 R12 CTS Verifier - ARM</a></li>
+href="https://dl.google.com/dl/android/cts/android-cts-verifier-7.0_r13-linux_x86-arm.zip">Android
+7.0 R13 CTS Verifier - ARM</a></li>
 <li><a
-href="https://dl.google.com/dl/android/cts/android-cts-verifier-7.0_r12-linux_x86-x86.zip">Android
-7.0 R12 CTS Verifier - x86</a></li>
+href="https://dl.google.com/dl/android/cts/android-cts-verifier-7.0_r13-linux_x86-x86.zip">Android
+7.0 R13 CTS Verifier - x86</a></li>
 </ul>
 
 <h2 id="android-60">Android 6.0</h2>
 <p>Android 6.0 is the release of the development milestone code-named Marshmallow.
 The source code for the following tests can be synced with the
-'android-cts-6.0_r21' tag in the open-source tree.</p>
+'android-cts-6.0_r22' tag in the open-source tree.</p>
 <ul>
 <li><a
-href="https://dl.google.com/dl/android/cts/android-cts-6.0_r21-linux_x86-arm.zip">Android
-6.0 R21 Compatibility Test Suite (CTS) - ARM</a></li>
+href="https://dl.google.com/dl/android/cts/android-cts-6.0_r22-linux_x86-arm.zip">Android
+6.0 R22 Compatibility Test Suite (CTS) - ARM</a></li>
 <li><a
-href="https://dl.google.com/dl/android/cts/android-cts-6.0_r21-linux_x86-x86.zip">Android
-6.0 R21 Compatibility Test Suite (CTS) - x86</a></li>
+href="https://dl.google.com/dl/android/cts/android-cts-6.0_r22-linux_x86-x86.zip">Android
+6.0 R22 Compatibility Test Suite (CTS) - x86</a></li>
 <li><a
-href="https://dl.google.com/dl/android/cts/android-cts-verifier-6.0_r21-linux_x86-arm.zip">Android
-6.0 R21 CTS Verifier - ARM</a></li>
+href="https://dl.google.com/dl/android/cts/android-cts-verifier-6.0_r22-linux_x86-arm.zip">Android
+6.0 R22 CTS Verifier - ARM</a></li>
 <li><a
-href="https://dl.google.com/dl/android/cts/android-cts-verifier-6.0_r21-linux_x86-x86.zip">Android
-6.0 R21 CTS Verifier - x86</a></li>
+href="https://dl.google.com/dl/android/cts/android-cts-verifier-6.0_r22-linux_x86-x86.zip">Android
+6.0 R22 CTS Verifier - x86</a></li>
 </ul>
 
 <h2 id="android-51">Android 5.1</h2>
 <p>Android 5.1 is the release of the development milestone code-named Lollipop-MR1.
 The source code for the following tests can be synced with the
-'android-cts-5.1_r22' tag in the open source tree.</p>
+'android-cts-5.1_r23' tag in the open source tree.</p>
 <ul>
 <li><a
-href="https://dl.google.com/dl/android/cts/android-cts-5.1_r22-linux_x86-arm.zip">Android
-5.1 R22 Compatibility Test Suite (CTS) - ARM</a></li>
+href="https://dl.google.com/dl/android/cts/android-cts-5.1_r23-linux_x86-arm.zip">Android
+5.1 R23 Compatibility Test Suite (CTS) - ARM</a></li>
 <li><a
-href="https://dl.google.com/dl/android/cts/android-cts-5.1_r22-linux_x86-x86.zip">Android
-5.1 R22 Compatibility Test Suite (CTS) - x86</a></li>
+href="https://dl.google.com/dl/android/cts/android-cts-5.1_r23-linux_x86-x86.zip">Android
+5.1 R23 Compatibility Test Suite (CTS) - x86</a></li>
 <li><a
-href="https://dl.google.com/dl/android/cts/android-cts-verifier-5.1_r22-linux_x86-arm.zip">Android
-5.1 R22 CTS Verifier - ARM</a></li>
+href="https://dl.google.com/dl/android/cts/android-cts-verifier-5.1_r23-linux_x86-arm.zip">Android
+5.1 R23 CTS Verifier - ARM</a></li>
 <li><a
-href="https://dl.google.com/dl/android/cts/android-cts-verifier-5.1_r22-linux_x86-x86.zip">Android
-5.1 R22 CTS Verifier - x86</a></li>
+href="https://dl.google.com/dl/android/cts/android-cts-verifier-5.1_r23-linux_x86-x86.zip">Android
+5.1 R23 CTS Verifier - x86</a></li>
 </ul>
 
 <h2 id="android-50">Android 5.0</h2>
@@ -230,6 +230,7 @@
 <h2 id="cts-media-files">CTS Media Files</h2>
 <p>These media files are required for the CTS media stress tests.</p>
 <ul>
+<li><a href="https://dl.google.com/dl/android/cts/android-cts-media-1.4.zip">CTS Media 1.4</a></li>
 <li><a href="https://dl.google.com/dl/android/cts/android-cts-media-1.3.zip">CTS Media 1.3</a></li>
 <li><a href="https://dl.google.com/dl/android/cts/android-cts-media-1.2.zip">CTS Media 1.2</a></li>
 <li><a href="https://dl.google.com/dl/android/cts/android-cts-media-1.1.zip">CTS Media 1.1</a></li>
diff --git a/en/compatibility/cts/setup.html b/en/compatibility/cts/setup.html
index 65bd848..9069b8b 100644
--- a/en/compatibility/cts/setup.html
+++ b/en/compatibility/cts/setup.html
@@ -24,6 +24,22 @@
 
 
 <h2 id=physical_environment>Physical environment</h2>
+<h3 id=ble_beacons>Bluetooth LE beacons</h3>
+<p>If the DUT supports the Bluetooth LE feature, then at least three
+Bluetooth LE beacons should be placed within five meters of the DUT for Bluetooth
+LE scan testing. Those beacons can be any kind, do not need to be
+configured or emit anything specific, and can include iBeacon,
+Eddystone, or even devices simulating BLE beacons.</p>
+
+<h3 id="gnss">GPS/GNSS</h3>
+<p>If the DUT supports the Global Positioning System (GPS) Global Navigation
+Satellite System (GNSS) feature, then a GPS/GNSS signal, with GPS portion
+compliant with ICD-GPS-200C, should be provided to the DUT at a suitable signal
+level for reception and GPS location calculation. The GPS/GNSS signal source can
+be of any kind, ranging from a satellite simulator, to a GPS/GNSS repeater of
+outdoor signals, simply to placement of the DUT close enough to a window such that
+it can directly receive enough GPS/GNSS signal.</p>
+
 <h3 id=wifi>Wi-Fi and IPv6</h3>
 <p>CTS tests require a Wi-Fi network that supports IPv6, can treat the Device
 Under Test (DUT) as an isolated client, and has an internet
@@ -39,13 +55,6 @@
 href="http://en.wikipedia.org/wiki/List_of_IPv6_tunnel_brokers">list of IPv6
 tunnel brokers</a>.</p>
 
-<h3 id=ble_beacons>Bluetooth LE beacons</h3>
-<p>If the DUT supports the Bluetooth LE feature, then at least three
-Bluetooth LE beacons should be placed within five meters of the DUT for Bluetooth
-LE scan testing. Those beacons can be any kind, do not need to be
-configured or emit anything specific, and can include iBeacon,
-Eddystone, or even devices simulating BLE beacons.</p>
-
 <h2 id=desktop_setup>Desktop machine setup</h2>
 <p>CTS currently supports 64-bit Linux and Mac OS host machines.</p>
 
diff --git a/en/compatibility/overview.html b/en/compatibility/overview.html
index e781014..962a5b7 100644
--- a/en/compatibility/overview.html
+++ b/en/compatibility/overview.html
@@ -83,8 +83,8 @@
 <p>The Android compatibility program consists of three key components:</p>
 <ul>
 <li>The <a href="https://android.googlesource.com/">Android Open Source Project</a> source code</li>
-<li>The <a href="cdd.html">Compatilbility Definition Document (CDD)<a/>, representing the "policy" aspect of compatibility</li>
-<li>The <a href="cts/index.html">Compatilbility Test Suite (CTS)</a>, representing the "mechanism" of compatibility</li>
+<li>The <a href="cdd.html">Compatibility Definition Document (CDD)<a/>, representing the "policy" aspect of compatibility</li>
+<li>The <a href="cts/index.html">Compatibility Test Suite (CTS)</a>, representing the "mechanism" of compatibility</li>
 </ul>
 
 <p>Just as each version of the Android platform exists in a separate branch in
diff --git a/en/devices/_toc-interfaces.yaml b/en/devices/_toc-interfaces.yaml
index 6c13a21..5a78a71 100644
--- a/en/devices/_toc-interfaces.yaml
+++ b/en/devices/_toc-interfaces.yaml
@@ -294,7 +294,7 @@
 - title: Input
   section:
   - title: Overview
-    path: /devices/input/overview
+    path: /devices/input/
   - title: Key Layout Files
     path: /devices/input/key-layout-files
   - title: Key Character Map Files
diff --git a/en/devices/_toc-tech.yaml b/en/devices/_toc-tech.yaml
index 14c55a3..76f2621 100644
--- a/en/devices/_toc-tech.yaml
+++ b/en/devices/_toc-tech.yaml
@@ -179,6 +179,8 @@
     path: /devices/tech/ota/sign_builds
   - title: A/B System Updates
     path: /devices/tech/ota/ab_updates
+  - title: Implementing A/B Updates
+    path: /devices/tech/ota/ab_implement
 - title: Performance
   section:
   - title: Overview
diff --git a/en/devices/architecture/hidl/fmq.html b/en/devices/architecture/hidl/fmq.html
index c09fd1c..13a7961 100644
--- a/en/devices/architecture/hidl/fmq.html
+++ b/en/devices/architecture/hidl/fmq.html
@@ -181,7 +181,7 @@
 </ul>
 
 <p>For the long form, the <code>EventFlag</code> can be supplied explicitly in
-each <code>blockingRead()</code> and <code>blockingWrite()</code> call. One of
+each <code>readBlocking()</code> and <code>writeBlocking()</code> call. One of
 the queues may be initialized with an internal event flag, which must then be
 extracted from that queue's <code>MessageQueue</code> objects using
 <code>getEventFlagWord()</code> and used to create <code>EventFlag</code>
diff --git a/en/devices/architecture/kernel/modular-kernels.html b/en/devices/architecture/kernel/modular-kernels.html
index 98ac052..004b8f7 100644
--- a/en/devices/architecture/kernel/modular-kernels.html
+++ b/en/devices/architecture/kernel/modular-kernels.html
@@ -21,8 +21,8 @@
       limitations under the License.
   -->
 
-<p>In Android O, the device kernel splits into System-on-Chip (SoC), device, and
-board-specific deliverables. This sets up the kernel and Android such that
+<p>In Android 8.0, the device kernel splits into System-on-Chip (SoC), device,
+and board-specific deliverables. This sets up the kernel and Android such that
 Original Device Manufacturers (ODMs) and Original Equipment Manufacturers (OEMs)
 can work in isolated board–specific trees for board–specific features, drivers,
 etc., enabling them to override common kernel configuration, add new drivers in
@@ -91,12 +91,11 @@
 in the future.</p>
 
 <h3 id="file-locations">File locations</h3>
-<p>While Android 7.x and earlier do not mandate against kernel modules (and
-include support for <code>insmod</code> and <code>rmmod</code>), Android O
-recommends the use of kernel modules in the ecosystem. The following table shows
-potential board–specific peripheral support required across three Android boot
-modes:</p>
-
+<p>While Android 7.x and earlier versions do not mandate against kernel modules
+(and include support for <code>insmod</code> and <code>rmmod</code>), Android
+8.0 recommends the use of kernel modules in the ecosystem. The following table
+shows potential board–specific peripheral support required across three Android
+boot modes:</p>
 <table>
 <tr>
 <th>Boot Mode</th>
@@ -119,7 +118,7 @@
 <td><span class="compare-yes"></span></td>
 <td><span class="compare-no"></span></td>
 <td><span class="compare-no"></span></td>
-<td><span class="compare-no"></span></td>>
+<td><span class="compare-no"></span></td>
 <td><span class="compare-no"></span></td>
 </tr>
 <tr>
@@ -179,9 +178,9 @@
 </ul>
 
 <p>In Android 7.x and earlier, <code>/vendor</code> and <code>/odm</code>
-partitions are <strong>not</strong> mounted early. In Android O, to make module
-loading from these partitions possible, provisions have been made to mount
-partitions early for both
+partitions are <strong>not</strong> mounted early. In Android 8.0, to make
+module loading from these partitions possible, provisions have been made to
+mount partitions early for both
 <a href="https://source.android.com/devices/tech/ota/ab_updates">non-A/B and A/B
 devices</a>. This also ensures the partitions are mounted in both Android and
 Charger modes.</p>
@@ -234,12 +233,41 @@
         /vendor/lib/modules module_a module_b module_c ...
 </pre>
 
-<p>The kernel image may be updated separately from the vendor image, meaning
-that kernel modules may be used with kernels other than the one they were
-originally compiled against. To allow for this, and to protect against ABI
-breakages, module versioning is used. Module versioning is enabled by
-<code>CONFIG_MODVERSIONS=y</code> (one of the required kernel configuration
-options mentioned above) and is documented in the kernel tree at
+<p>Typically, a kernel module must be compiled with the kernel that the module
+is to be used with (otherwise the kernel will refuse to load the module).
+<code>CONFIG_MODVERSIONS</code> provides a workaround by detecting breakages in
+the ABI. This feature calculates a Cyclic Redundancy Check (CRC) value for the
+prototype of each exported symbol in the kernel and stores the values as part of
+the kernel; for symbols used by a kernel module, the values are also stored in
+the kernel module. When the module is loaded, the values for the symbols used by
+the module are compared with the ones in the kernel. If the values match, the
+module is loaded; otherwise the load fails.</p>
+
+<p>To enable the updating of the kernel image separately from the vendor image,
+enable <code>CONFIG_MODVERSIONS</code>. Doing so allows small updates to the
+kernel (such as bug fixes from LTS) to be made while maintaining compatibility
+with existing kernel modules in the vendor image. However,
+<code>CONFIG_MODVERSIONS</code> does not itself fix an ABI breakage. If the
+prototype of an exported symbol in the kernel changes, either due to
+modification of the source or because the kernel configuration changed, this
+breaks compatibility with kernel modules that use that symbol. In such cases,
+the kernel module must be recompiled.</p>
+
+<p>For example, the <code>task_struct</code> structure in the kernel (defined in
+<code>include/linux/sched.h</code>) contains many fields conditionally included
+depending on the kernel configuration. The <code>sched_info</code> field is
+present only if <code>CONFIG_SCHED_INFO</code> is enabled (which occurs when
+<code>CONFIG_SCHEDSTATS</code> or <code>CONFIG_TASK_DELAY_ACCT</code> are
+enabled). If these configuration options change state, the layout of the
+<code>task_struct</code> structure changes and any exported interfaces from the
+kernel that use <code>task_struct</code> are altered (e.g.
+<code>set_cpus_allowed_ptr</code> in <code>kernel/sched/core.c</code>).
+Compatibility with previously-compiled kernel modules that use these interfaces
+breaks, requiring those modules to be rebuilt with the new kernel
+configuration.</p>
+
+<p>For more details on <code>CONFIG_MODVERSIONS</code>, refer to the
+documentation in the kernel tree at
 <code>Documentation/kbuild/modules.txt</code>.</p>
 
 <h2 id="mounting-partitions-early-first-stage-mount">Mounting partitions early
@@ -255,9 +283,9 @@
 Android 8.0</a>.</aside>
 
 <p>Android must have access to the filesystem(s) on which the modules reside. To
-enable, Android O supports mounting <code>/system</code>, <code>/vendor</code>,
-or <code>/odm</code> as early as <code>init</code>'s first stage (i.e before
-selinux is initialized). Device makers can use
+enable, Android 8.0 supports mounting <code>/system</code>,
+<code>/vendor</code>, or <code>/odm</code> as early as <code>init</code>'s first
+stage (i.e before selinux is initialized). Device makers can use
 <a href="/devices/architecture/dto/index.html">device tree overlays</a> to
 specify <code>fstab</code> entries for early mounted partitions.</p>
 
@@ -315,7 +343,7 @@
 
 <h3 id="early-mounting-device-tree-vboot-1-0">Early mounting device tree, VBoot
 1.0</h3>
-<p>In Android O, <code>init</code> parses the device tree and creates
+<p>In Android 8.0, <code>init</code> parses the device tree and creates
 <code>fstab</code> entries to mount the partition early during its first stage.
 An fstab entry takes the form:</p>
 
@@ -557,7 +585,7 @@
 
 <p>In Android 7.x and earlier, Android did not require device tree support and
 did not provide recommendations regarding how vendors pass DT blobs to the
-kernel or where they store them. Android O recommends such support to keep the
+kernel or where they store them. Android 8.0 recommends such support to keep the
 board–specific and SoC-only parts of the kernel separate.</p>
 
 <h3 id="partitioning-requirements">Partitioning requirements</h3>
@@ -607,7 +635,7 @@
 <a href="/devices/architecture/dto/index.html">Device Tree Overlays</a>.</p>
 
 <h2 id="core-kernel-requirements">Core kernel requirements</h2>
-<p>Android O mandates a minimum kernel version and kernel configuration and
+<p>Android 8.0 mandates a minimum kernel version and kernel configuration and
 checks them both in VTS as well as during an OTA. Android device kernels must
 enable the kernel <code>.config</code> support along with the option to read the
 kernel configuration at runtime through <code>procfs</code>.</p>
@@ -627,13 +655,13 @@
 <p>Kernel version requirements:</p>
 <ul>
 <li>All SoCs productized in 2017 must launch with kernel 4.4 or newer.</li>
-<li>All other SoCs launching new Android devices running Android O must use
+<li>All other SoCs launching new Android devices running Android 8.0 must use
 kernel 3.18 or newer.</li>
-<li>Regardless of launch date, all SoCs with device launches on Android O remain
-subject to kernel changes required to enable Treble.</li>
-<li>Older Android devices released prior to Android O but that will be upgraded
-to Android O can continue to use their original base kernel version if
-desired.</li>
+<li>Regardless of launch date, all SoCs with device launches on Android 8.0
+remain subject to kernel changes required to enable Treble.</li>
+<li>Older Android devices released prior to Android 8.0 but that will be
+upgraded to Android 8.0 can continue to use their original base kernel version
+if desired.</li>
 </ul>
 
 <h3 id="device-tree-support">Device tree support</h3>
@@ -664,8 +692,8 @@
 <code>debugfs</code>. It may be enabled, but VTS testing may be done with
 <code>debugfs</code> unmounted.</p>
 
-<h2 id="beyond-android-o">Beyond Android O</h2>
-<p>Android O recommends any board–specific kernel functionality to be in the
+<h2 id="beyond-android-o">Beyond Android 8.0</h2>
+<p>Android 8.0 recommends any board–specific kernel functionality to be in the
 form of loadable kernel modules and device–tree overlays. The rest of the kernel
 is treated monolithically with respect to Android (whether or not is it is
 actually a monolithic kernel, or parts of it are compiled as kernel modules).
@@ -701,13 +729,13 @@
 unified–per–SoC–kernel scenario:</p>
 
 <img src="../images/treble_kernel_treble.png">
-<figcaption><strong>Figure 2.</strong> Android O and higher device
+<figcaption><strong>Figure 2.</strong> Android 8.0 and higher device
 kernels.</figcaption>
 
 <p>This is intended to solve the problem of fragmented kernel repos by
 recommending and working with device manufacturers to stay up to date with the
-common SoC kernel. Android O provides all possible options to ODMs to help them
-avoid maintaining their own SoC kernels and instead rely on the common SoC
+common SoC kernel. Android 8.0 provides all possible options to ODMs to help
+them avoid maintaining their own SoC kernels and instead rely on the common SoC
 kernel for LTS upgrades/bug fixes/security patches/etc.</p>
 
 <p>As a start, we want to facilitate all ODMs/vendors using a single kernel
diff --git a/en/devices/architecture/vintf/objects.html b/en/devices/architecture/vintf/objects.html
index 87abeed..76d78ee 100644
--- a/en/devices/architecture/vintf/objects.html
+++ b/en/devices/architecture/vintf/objects.html
@@ -125,7 +125,7 @@
         &lt;/interface>
     &lt;/hal>
     &lt;hal>
-        &lt;name>android.framework.sensorservice&lt;/name>
+        &lt;name>android.frameworks.sensorservice&lt;/name>
         &lt;transport>hwbinder&lt;/transport>
         &lt;version>1.0&lt;/version>
         &lt;interface>
diff --git a/en/devices/architecture/vintf/resources.html b/en/devices/architecture/vintf/resources.html
index 6582850..0f408a8 100644
--- a/en/devices/architecture/vintf/resources.html
+++ b/en/devices/architecture/vintf/resources.html
@@ -143,6 +143,52 @@
     -c $(TARGET_OUT_VENDOR)/manifest.xml \
 </pre>
 
+<h4><strong>Example:</strong> Generate device manifest from fragments</h4>
+
+<p>Multiple device manifest fragments can be bundled at build time. For example:</p>
+
+<pre class="prettyprint">
+&lt;!-- device/manufacturer/device_name/manifest_common.xml -->
+&lt;manifest version="1.0" type="device">
+    &lt;!-- common HALs here -->
+&lt;/manifest>
+</pre>
+
+<pre class="prettyprint">
+&lt;!-- device/manufacturer/device_name/ir.xml -->
+&lt;manifest version="1.0" type="device">
+    &lt;hal>
+        &lt;name>android.hardware.ir&lt;/name>
+        &lt;version>1.0&lt;/version>
+        &lt;!-- other fields -->
+    &lt;/hal>
+&lt;/manifest>
+</pre>
+
+<pre class="prettyprint">
+# device/manufacturer/device_name/BoardConfig.mk
+DEVICE_MANIFEST_FILE := device/manufacturer/device_name/manifest_common.xml
+ifdef BOARD_ENABLE_IR
+    DEVICE_MANIFEST_FILE += device/manufacturer/device_name/ir.xml
+endif
+</pre>
+
+<p>Then, <code>assemble_vintf</code> adds Ir HAL to device manifest if <code>BOARD_ENABLE_IR</code>
+is defined, and omits it if <code>BOARD_ENABLE_IR</code> is not defined. The following commands
+(modified to omit implementation details) are executed to generate the device manifest:</p>
+
+<pre class="prettyprint">
+# if BOARD_ENABLE_IR is defined
+BOARD_SEPOLICY_VERS=10000.0 assemble_vintf \
+    -i device/manufacturer/device_name/manifest_common.xml:device/manufacturer/device_name/ir.xml \
+    -o $(TARGET_OUT_VENDOR)/manifest.xml
+
+# if BOARD_ENABLE_IR is not defined
+BOARD_SEPOLICY_VERS=10000.0 assemble_vintf \
+    -i device/manufacturer/device_name/manifest_common.xml \
+    -o $(TARGET_OUT_VENDOR)/manifest.xml
+</pre>
+
 <p>For details, see:</p>
 
 <pre class="devsite-terminal">assemble_vintf --help</pre>
diff --git a/en/devices/bluetooth/hci_requirements.html b/en/devices/bluetooth/hci_requirements.html
index d77825d..217850d 100644
--- a/en/devices/bluetooth/hci_requirements.html
+++ b/en/devices/bluetooth/hci_requirements.html
@@ -1232,8 +1232,8 @@
                   (<code>num_of_records)]</code></td>
               </tr>
             </table>
-      <h2 id="advertisement-packet-content-filter">Advertisement packet content
-        filte</h2>
+      <h2 id="advertising-packet-content-filter">Advertising Packet Content
+        Filter</h2>
         <p>Use this to enable/disable/setup the
         Advertising Packet Content Filter (APCF) in the controller.</p>
 
diff --git a/en/devices/input/index.html b/en/devices/input/index.html
index c25ed4f..67247b6 100644
--- a/en/devices/input/index.html
+++ b/en/devices/input/index.html
@@ -1,6 +1,6 @@
 <html devsite>
   <head>
-    <title>Input Technical Information</title>
+    <title>Overview</title>
     <meta name="project_path" value="/_project.yaml" />
     <meta name="book_path" value="/_book.yaml" />
   </head>
@@ -21,13 +21,228 @@
       limitations under the License.
   -->
 
+<img style="float: right; margin: 0px 15px 15px 15px;"
+     src="images/ape_fwk_hal_input.png" alt="Android Input HAL icon"/>
 
-
-<img style="float: right; margin: 0px 135px 15px 15px;" src="images/ape_fwk_hal_input.png" alt="Android Input HAL icon"/>
-
-<p>The Android input subsystem supports many different device classes,
-including keyboard, joystick, trackball, mouse, and touch screen. The documentation in this section describes how to configure,
-calibrate, test, and write drivers for input devices.</p>
+<p>The Android input subsystem nominally consists of an event pipeline
+that traverses multiple layers of the system.</p>
+<h2 id="input-pipeline">Input Pipeline</h2>
+<p>At the lowest layer, the physical input device produces signals that
+describe state changes such as key presses and touch contact points.
+The device firmware encodes and transmits these signals in some way
+such as by sending USB HID reports to the system or by producing
+interrupts on an I2C bus.</p>
+<p>The signals are then decoded by a device driver in the Linux kernel.
+The Linux kernel provides drivers for many standard peripherals,
+particularly those that adhere to the HID protocol.  However, an OEM
+must often provide custom drivers for embedded devices that are
+tightly integrated into the system at a low-level, such as touch screens.</p>
+<p>The input device drivers are responsible for translating device-specific
+signals into a standard input event format, by way of the Linux
+input protocol.  The Linux input protocol defines a standard set of
+event types and codes in the <code>linux/input.h</code> kernel header file.
+In this way, components outside the kernel do not need to care about
+the details such as physical scan codes, HID usages, I2C messages,
+GPIO pins, and the like.</p>
+<p>Next, the Android <code>EventHub</code> component reads input events from the kernel
+by opening the <code>evdev</code> driver associated with each input device.
+The Android InputReader component then decodes the input events
+according to the device class and produces a stream of Android input
+events.  As part of this process, the Linux input protocol event codes
+are translated into Android event codes according to the
+input device configuration, keyboard layout files, and various
+mapping tables.</p>
+<p>Finally, the <code>InputReader</code> sends input events to the InputDispatcher
+which forwards them to the appropriate window.</p>
+<h2 id="control-points">Control Points</h2>
+<p>There are several stages in the input pipeline which effect control
+over the behavior of the input device.</p>
+<h3 id="driver-and-firmware-configuration">Driver and Firmware Configuration</h3>
+<p>Input device drivers frequently configure the behavior of the input
+device by setting parameters in registers or even uploading the
+firmware itself.  This is particularly the case for embedded
+devices such as touch screens where a large part of the calibration
+process involves tuning these parameters or fixing the firmware
+to provide the desired accuracy and responsiveness and to suppress
+noise.</p>
+<p>Driver configuration options are often specified as module parameters
+in the kernel board support package (BSP) so that the same driver
+can support multiple different hardware implementations.</p>
+<p>This documentation does attempt to describe driver or firmware
+configuration, but it does offer guidance as to device calibration
+in general.</p>
+<h3 id="board-configuration-properties">Board Configuration Properties</h3>
+<p>The kernel board support package (BSP) may export board configuration
+properties via SysFS that are used by the Android InputReader component,
+such as the placement of virtual keys on a touch screen.</p>
+<p>Refer to the device class sections for details about how different
+devices use board configuration properties.</p>
+<h3 id="resource-overlays">Resource Overlays</h3>
+<p>A few input behaviors are configured by way of resource overlays
+in <code>config.xml</code> such as the operation of lid switch.</p>
+<p>Here are a few examples:</p>
+<ul>
+<li>
+<p><code>config_lidKeyboardAccessibility</code>: Specifies the effect of the
+    lid switch on whether the hardware keyboard is accessible or hidden.</p>
+</li>
+<li>
+<p><code>config_lidNavigationAccessibility</code>: Specifies the effect of the
+    lid switch on whether the trackpad is accessible or hidden.</p>
+</li>
+<li>
+<p><code>config_longPressOnPowerBehavior</code>: Specifies what should happen when
+    the user holds down the power button.</p>
+</li>
+<li>
+<p><code>config_lidOpenRotation</code>: Specifies the effect of the lid switch
+    on screen orientation.</p>
+</li>
+</ul>
+<p>Refer to the documentation within <code>frameworks/base/core/res/res/values/config.xml</code>
+for details about each configuration option.</p>
+<h3 id="key-maps">Key Maps</h3>
+<p>Key maps are used by the Android <code>EventHub</code> and <code>InputReader</code> components
+to configure the mapping from Linux event codes to Android event codes
+for keys, joystick buttons and joystick axes.  The mapping may
+be device or language dependent.</p>
+<p>Refer to the device class sections for details about how different
+devices use key maps.</p>
+<h3 id="input-device-configuration-files">Input Device Configuration Files</h3>
+<p>Input device configuration files are used by the Android <code>EventHub</code> and
+<code>InputReader</code> components to configure special device characteristics
+such as how touch size information is reported.</p>
+<p>Refer to the device class sections for details about how different
+devices use input device configuration maps.</p>
+<h2 id="understanding-hid-usages-and-event-codes">Understanding HID Usages and Event Codes</h2>
+<p>There are often several different identifiers used to refer to any
+given key on a keyboard, button on a game controller, joystick axis
+or other control.  The relationships between these identifiers
+are not always the same: they are dependent on a set of mapping tables,
+some of which are fixed, and some which vary based on characteristics
+of the device, the device driver, the current locale, the system
+configuration, user preferences and other factors.</p>
+<dl>
+<dt>Physical Scan Code</dt>
+<dd>
+<p>A physical scan code is a device-specific identifier that is associated
+with each key, button or other control.  Because physical scan codes
+often vary from one device to another, the firmware or device driver
+is responsible for mapping them to standard identifiers such as
+HID Usages or Linux key codes.</p>
+<p>Scan codes are mainly of interest for keyboards.  Other devices
+typically communicate at a low-level using GPIO pins, I2C messages
+or other means.  Consequently, the upper layers of the software
+stack rely on the device drivers to make sense of what is going on.</p>
+</dd>
+<dt>HID Usage</dt>
+<dd>
+<p>A HID usage is a standard identifier that is used to report the
+state of a control such as a keyboard key, joystick axis,
+mouse button, or touch contact point.  Most USB and Bluetooth
+input devices conform to the HID specification, which enables
+the system to interface with them in a uniform manner.</p>
+<p>The Android Framework relies on the Linux kernel HID drivers to
+translate HID usage codes into Linux key codes and other identifiers.
+Therefore HID usages are mainly of interest to peripheral manufacturers.</p>
+</dd>
+<dt>Linux Key Code</dt>
+<dd>
+<p>A Linux key code is a standard identifier for a key or button.
+Linux key codes are defined in the <code>linux/input.h</code> header file using
+constants that begin with the prefix <code>KEY_</code> or <code>BTN_</code>.  The Linux
+kernel input drivers are responsible for translating physical
+scan codes, HID usages and other device-specific signals into Linux
+key codes and delivering information about them as part of
+<code>EV_KEY</code> events.</p>
+<p>The Android API sometimes refers to the Linux key code associated
+with a key as its "scan code".  This is technically incorrect in
+but it helps to distinguish Linux key codes from Android key codes
+in the API.</p>
+</dd>
+<dt>Linux Relative or Absolute Axis Code</dt>
+<dd>
+<p>A Linux relative or absolute axis code is a standard identifier
+for reporting relative movements or absolute positions along an
+axis, such as the relative movements of a mouse along its X axis
+or the absolute position of a joystick along its X axis.
+Linux axis code are defined in the <code>linux/input.h</code> header file using
+constants that begin with the prefix <code>REL_</code> or <code>ABS_</code>.  The Linux
+kernel input drivers are responsible for translating HID usages
+and other device-specific signals into Linux axis codes and
+delivering information about them as part of <code>EV_REL</code> and
+<code>EV_ABS</code> events.</p>
+</dd>
+<dt>Linux Switch Code</dt>
+<dd>
+<p>A Linux switch code is a standard identifier for reporting the
+state of a switch on a device, such as a lid switch.  Linux
+switch codes are defined in the <code>linux/input.h</code> header file
+using constants that begin with the prefix <code>SW_</code>.  The Linux
+kernel input drivers report switch state changes as <code>EV_SW</code> events.</p>
+<p>Android applications generally do not receive events from switches,
+but the system may use them internally to control various
+device-specific functions.</p>
+</dd>
+<dt>Android Key Code</dt>
+<dd>
+<p>An Android key code is a standard identifier defined in the Android
+API for indicating a particular key such as 'HOME'.  Android key codes
+are defined by the <code>android.view.KeyEvent</code> class as constants that
+begin with the prefix <code>KEYCODE_</code>.</p>
+<p>The key layout specifies how Linux key codes are mapped to Android
+key codes.  Different key layouts may be used depending on the keyboard
+model, language, country, layout, or special functions.</p>
+<p>Combinations of Android key codes are transformed into character codes
+using a device and locale specific key character map.  For example,
+when the keys identified as <code>KEYCODE_SHIFT</code> and <code>KEYCODE_A</code> are both
+pressed together, the system looks up the combination in the key
+character map and finds the capital letter 'A', which is then inserted
+into the currently focused text widget.</p>
+</dd>
+<dt>Android Axis Code</dt>
+<dd>
+<p>An Android axis code is a standard identifier defined in the Android
+API for indicating a particular device axis.  Android axis codes are
+defined by the <code>android.view.MotionEvent</code> class as constants that
+begin with the prefix <code>AXIS_</code>.</p>
+<p>The key layout specifies how Linux Axis Codes are mapped to Android
+axis codes.  Different key layouts may be used depending on the device
+model, language, country, layout, or special functions.</p>
+</dd>
+<dt>Android Meta State</dt>
+<dd>
+<p>An Android meta state is a standard identifier defined in the Android
+API for indicating which modifier keys are pressed.  Android meta states
+are defined by the <code>android.view.KeyEvent</code> class as constants that
+begin with the prefix <code>META_</code>.</p>
+<p>The current meta state is determined by the Android InputReader
+component which monitors when modifier keys such as <code>KEYCODE_SHIFT_LEFT</code>
+are pressed / released and sets / resets the appropriate meta state flag.</p>
+<p>The relationship between modifier keys and meta states is hardcoded
+but the key layout can alter how the modifier keys themselves are
+mapped which in turns affects the meta states.</p>
+</dd>
+<dt>Android Button State</dt>
+<dd>
+<p>An Android button state is a standard identifier defined in the Android
+API for indicating which buttons (on a mouse or stylus) are pressed.
+Android button states are defined by the <code>android.view.MotionEvent</code>
+class as constants that begin with the prefix <code>BUTTON_</code>.</p>
+<p>The current button state is determined by the Android InputReader
+component which monitors when buttons (on a mouse or stylus) are
+pressed / released and sets / resets appropriate button state flag.</p>
+<p>The relationship between buttons and button states is hardcoded.</p>
+</dd>
+</dl>
+<h2 id="further-reading">Further Reading</h2>
+<ol>
+<li><a href="http://www.kernel.org/doc/Documentation/input/event-codes.txt">Linux input event codes</a></li>
+<li><a href="http://www.kernel.org/doc/Documentation/input/multi-touch-protocol.txt">Linux multi-touch protocol</a></li>
+<li><a href="http://www.kernel.org/doc/Documentation/input/input.txt">Linux input drivers</a></li>
+<li><a href="http://www.kernel.org/doc/Documentation/input/ff.txt">Linux force feedback</a></li>
+<li><a href="http://www.usb.org/developers/hidpage">HID information, including HID usage tables</a></li>
+</ol>
 
   </body>
 </html>
diff --git a/en/devices/input/overview.html b/en/devices/input/overview.html
deleted file mode 100644
index 4256320..0000000
--- a/en/devices/input/overview.html
+++ /dev/null
@@ -1,247 +0,0 @@
-<html devsite>
-  <head>
-    <title>Overview</title>
-    <meta name="project_path" value="/_project.yaml" />
-    <meta name="book_path" value="/_book.yaml" />
-  </head>
-  <body>
-  <!--
-      Copyright 2017 The Android Open Source Project
-
-      Licensed under the Apache License, Version 2.0 (the "License");
-      you may not use this file except in compliance with the License.
-      You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-      Unless required by applicable law or agreed to in writing, software
-      distributed under the License is distributed on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-      See the License for the specific language governing permissions and
-      limitations under the License.
-  -->
-
-
-
-<p>The Android input subsystem nominally consists of an event pipeline
-that traverses multiple layers of the system.</p>
-<h2 id="input-pipeline">Input Pipeline</h2>
-<p>At the lowest layer, the physical input device produces signals that
-describe state changes such as key presses and touch contact points.
-The device firmware encodes and transmits these signals in some way
-such as by sending USB HID reports to the system or by producing
-interrupts on an I2C bus.</p>
-<p>The signals are then decoded by a device driver in the Linux kernel.
-The Linux kernel provides drivers for many standard peripherals,
-particularly those that adhere to the HID protocol.  However, an OEM
-must often provide custom drivers for embedded devices that are
-tightly integrated into the system at a low-level, such as touch screens.</p>
-<p>The input device drivers are responsible for translating device-specific
-signals into a standard input event format, by way of the Linux
-input protocol.  The Linux input protocol defines a standard set of
-event types and codes in the <code>linux/input.h</code> kernel header file.
-In this way, components outside the kernel do not need to care about
-the details such as physical scan codes, HID usages, I2C messages,
-GPIO pins, and the like.</p>
-<p>Next, the Android <code>EventHub</code> component reads input events from the kernel
-by opening the <code>evdev</code> driver associated with each input device.
-The Android InputReader component then decodes the input events
-according to the device class and produces a stream of Android input
-events.  As part of this process, the Linux input protocol event codes
-are translated into Android event codes according to the
-input device configuration, keyboard layout files, and various
-mapping tables.</p>
-<p>Finally, the <code>InputReader</code> sends input events to the InputDispatcher
-which forwards them to the appropriate window.</p>
-<h2 id="control-points">Control Points</h2>
-<p>There are several stages in the input pipeline which effect control
-over the behavior of the input device.</p>
-<h3 id="driver-and-firmware-configuration">Driver and Firmware Configuration</h3>
-<p>Input device drivers frequently configure the behavior of the input
-device by setting parameters in registers or even uploading the
-firmware itself.  This is particularly the case for embedded
-devices such as touch screens where a large part of the calibration
-process involves tuning these parameters or fixing the firmware
-to provide the desired accuracy and responsiveness and to suppress
-noise.</p>
-<p>Driver configuration options are often specified as module parameters
-in the kernel board support package (BSP) so that the same driver
-can support multiple different hardware implementations.</p>
-<p>This documentation does attempt to describe driver or firmware
-configuration, but it does offer guidance as to device calibration
-in general.</p>
-<h3 id="board-configuration-properties">Board Configuration Properties</h3>
-<p>The kernel board support package (BSP) may export board configuration
-properties via SysFS that are used by the Android InputReader component,
-such as the placement of virtual keys on a touch screen.</p>
-<p>Refer to the device class sections for details about how different
-devices use board configuration properties.</p>
-<h3 id="resource-overlays">Resource Overlays</h3>
-<p>A few input behaviors are configured by way of resource overlays
-in <code>config.xml</code> such as the operation of lid switch.</p>
-<p>Here are a few examples:</p>
-<ul>
-<li>
-<p><code>config_lidKeyboardAccessibility</code>: Specifies the effect of the
-    lid switch on whether the hardware keyboard is accessible or hidden.</p>
-</li>
-<li>
-<p><code>config_lidNavigationAccessibility</code>: Specifies the effect of the
-    lid switch on whether the trackpad is accessible or hidden.</p>
-</li>
-<li>
-<p><code>config_longPressOnPowerBehavior</code>: Specifies what should happen when
-    the user holds down the power button.</p>
-</li>
-<li>
-<p><code>config_lidOpenRotation</code>: Specifies the effect of the lid switch
-    on screen orientation.</p>
-</li>
-</ul>
-<p>Refer to the documentation within <code>frameworks/base/core/res/res/values/config.xml</code>
-for details about each configuration option.</p>
-<h3 id="key-maps">Key Maps</h3>
-<p>Key maps are used by the Android <code>EventHub</code> and <code>InputReader</code> components
-to configure the mapping from Linux event codes to Android event codes
-for keys, joystick buttons and joystick axes.  The mapping may
-be device or language dependent.</p>
-<p>Refer to the device class sections for details about how different
-devices use key maps.</p>
-<h3 id="input-device-configuration-files">Input Device Configuration Files</h3>
-<p>Input device configuration files are used by the Android <code>EventHub</code> and
-<code>InputReader</code> components to configure special device characteristics
-such as how touch size information is reported.</p>
-<p>Refer to the device class sections for details about how different
-devices use input device configuration maps.</p>
-<h2 id="understanding-hid-usages-and-event-codes">Understanding HID Usages and Event Codes</h2>
-<p>There are often several different identifiers used to refer to any
-given key on a keyboard, button on a game controller, joystick axis
-or other control.  The relationships between these identifiers
-are not always the same: they are dependent on a set of mapping tables,
-some of which are fixed, and some which vary based on characteristics
-of the device, the device driver, the current locale, the system
-configuration, user preferences and other factors.</p>
-<dl>
-<dt>Physical Scan Code</dt>
-<dd>
-<p>A physical scan code is a device-specific identifier that is associated
-with each key, button or other control.  Because physical scan codes
-often vary from one device to another, the firmware or device driver
-is responsible for mapping them to standard identifiers such as
-HID Usages or Linux key codes.</p>
-<p>Scan codes are mainly of interest for keyboards.  Other devices
-typically communicate at a low-level using GPIO pins, I2C messages
-or other means.  Consequently, the upper layers of the software
-stack rely on the device drivers to make sense of what is going on.</p>
-</dd>
-<dt>HID Usage</dt>
-<dd>
-<p>A HID usage is a standard identifier that is used to report the
-state of a control such as a keyboard key, joystick axis,
-mouse button, or touch contact point.  Most USB and Bluetooth
-input devices conform to the HID specification, which enables
-the system to interface with them in a uniform manner.</p>
-<p>The Android Framework relies on the Linux kernel HID drivers to
-translate HID usage codes into Linux key codes and other identifiers.
-Therefore HID usages are mainly of interest to peripheral manufacturers.</p>
-</dd>
-<dt>Linux Key Code</dt>
-<dd>
-<p>A Linux key code is a standard identifier for a key or button.
-Linux key codes are defined in the <code>linux/input.h</code> header file using
-constants that begin with the prefix <code>KEY_</code> or <code>BTN_</code>.  The Linux
-kernel input drivers are responsible for translating physical
-scan codes, HID usages and other device-specific signals into Linux
-key codes and delivering information about them as part of
-<code>EV_KEY</code> events.</p>
-<p>The Android API sometimes refers to the Linux key code associated
-with a key as its "scan code".  This is technically incorrect in
-but it helps to distinguish Linux key codes from Android key codes
-in the API.</p>
-</dd>
-<dt>Linux Relative or Absolute Axis Code</dt>
-<dd>
-<p>A Linux relative or absolute axis code is a standard identifier
-for reporting relative movements or absolute positions along an
-axis, such as the relative movements of a mouse along its X axis
-or the absolute position of a joystick along its X axis.
-Linux axis code are defined in the <code>linux/input.h</code> header file using
-constants that begin with the prefix <code>REL_</code> or <code>ABS_</code>.  The Linux
-kernel input drivers are responsible for translating HID usages
-and other device-specific signals into Linux axis codes and
-delivering information about them as part of <code>EV_REL</code> and
-<code>EV_ABS</code> events.</p>
-</dd>
-<dt>Linux Switch Code</dt>
-<dd>
-<p>A Linux switch code is a standard identifier for reporting the
-state of a switch on a device, such as a lid switch.  Linux
-switch codes are defined in the <code>linux/input.h</code> header file
-using constants that begin with the prefix <code>SW_</code>.  The Linux
-kernel input drivers report switch state changes as <code>EV_SW</code> events.</p>
-<p>Android applications generally do not receive events from switches,
-but the system may use them internally to control various
-device-specific functions.</p>
-</dd>
-<dt>Android Key Code</dt>
-<dd>
-<p>An Android key code is a standard identifier defined in the Android
-API for indicating a particular key such as 'HOME'.  Android key codes
-are defined by the <code>android.view.KeyEvent</code> class as constants that
-begin with the prefix <code>KEYCODE_</code>.</p>
-<p>The key layout specifies how Linux key codes are mapped to Android
-key codes.  Different key layouts may be used depending on the keyboard
-model, language, country, layout, or special functions.</p>
-<p>Combinations of Android key codes are transformed into character codes
-using a device and locale specific key character map.  For example,
-when the keys identified as <code>KEYCODE_SHIFT</code> and <code>KEYCODE_A</code> are both
-pressed together, the system looks up the combination in the key
-character map and finds the capital letter 'A', which is then inserted
-into the currently focused text widget.</p>
-</dd>
-<dt>Android Axis Code</dt>
-<dd>
-<p>An Android axis code is a standard identifier defined in the Android
-API for indicating a particular device axis.  Android axis codes are
-defined by the <code>android.view.MotionEvent</code> class as constants that
-begin with the prefix <code>AXIS_</code>.</p>
-<p>The key layout specifies how Linux Axis Codes are mapped to Android
-axis codes.  Different key layouts may be used depending on the device
-model, language, country, layout, or special functions.</p>
-</dd>
-<dt>Android Meta State</dt>
-<dd>
-<p>An Android meta state is a standard identifier defined in the Android
-API for indicating which modifier keys are pressed.  Android meta states
-are defined by the <code>android.view.KeyEvent</code> class as constants that
-begin with the prefix <code>META_</code>.</p>
-<p>The current meta state is determined by the Android InputReader
-component which monitors when modifier keys such as <code>KEYCODE_SHIFT_LEFT</code>
-are pressed / released and sets / resets the appropriate meta state flag.</p>
-<p>The relationship between modifier keys and meta states is hardcoded
-but the key layout can alter how the modifier keys themselves are
-mapped which in turns affects the meta states.</p>
-</dd>
-<dt>Android Button State</dt>
-<dd>
-<p>An Android button state is a standard identifier defined in the Android
-API for indicating which buttons (on a mouse or stylus) are pressed.
-Android button states are defined by the <code>android.view.MotionEvent</code>
-class as constants that begin with the prefix <code>BUTTON_</code>.</p>
-<p>The current button state is determined by the Android InputReader
-component which monitors when buttons (on a mouse or stylus) are
-pressed / released and sets / resets appropriate button state flag.</p>
-<p>The relationship between buttons and button states is hardcoded.</p>
-</dd>
-</dl>
-<h2 id="further-reading">Further Reading</h2>
-<ol>
-<li><a href="http://www.kernel.org/doc/Documentation/input/event-codes.txt">Linux input event codes</a></li>
-<li><a href="http://www.kernel.org/doc/Documentation/input/multi-touch-protocol.txt">Linux multi-touch protocol</a></li>
-<li><a href="http://www.kernel.org/doc/Documentation/input/input.txt">Linux input drivers</a></li>
-<li><a href="http://www.kernel.org/doc/Documentation/input/ff.txt">Linux force feedback</a></li>
-<li><a href="http://www.usb.org/developers/hidpage">HID information, including HID usage tables</a></li>
-</ol>
-
-  </body>
-</html>
diff --git a/en/devices/tech/config/filesystem.html b/en/devices/tech/config/filesystem.html
index c1bf33d..10b7f0b 100644
--- a/en/devices/tech/config/filesystem.html
+++ b/en/devices/tech/config/filesystem.html
@@ -132,7 +132,7 @@
    <td>The filesystem path to configure. A path ending in / is considered a dir,
    else it's a file.
    <br><br>It is an error to specify multiple sections with the same
-   <code>[path]</code> in different files. In Python versions <= 3.2, the same
+   <code>[path]</code> in different files. In Python versions &lt;= 3.2, the same
    file may contain sections that override the previous section; in Python 3.2,
    it's set to strict mode.</td>
   </tr>
diff --git a/en/devices/tech/dalvik/index.html b/en/devices/tech/dalvik/index.html
index 88cd47b..2c84a8e 100644
--- a/en/devices/tech/dalvik/index.html
+++ b/en/devices/tech/dalvik/index.html
@@ -144,12 +144,13 @@
 <h2 id="Reporting_Problems">Reporting Problems</h2>
 
 <p>If you run into any issues that aren’t due to app JNI issues, please report
-them via the Android Open Source Project Issue Tracker at <a
-href="http://b.android.com">http://b.android.com</a>.
-Please include an <code>"adb bugreport"</code> and link to the app in Google
-Play store if available. Otherwise, if possible, attach an APK that reproduces
-the issue. Please note that issues (including attachments) are publicly
-visible.</p>
+them through the <a href="/source/report-bugs#platform">Android Open Source
+Project Issue Tracker</a>. Include an <code>adb bugreport</code> and link to
+the app in Google Play store if available. Otherwise, if possible, attach an
+APK that reproduces the issue.</p>
+
+<aside class="caution"><strong>Reminder</strong>: Issues (including attachments)
+are publicly visible.</aside>
 
   </body>
 </html>
diff --git a/en/devices/tech/ota/ab_implement.html b/en/devices/tech/ota/ab_implement.html
new file mode 100644
index 0000000..4470c97
--- /dev/null
+++ b/en/devices/tech/ota/ab_implement.html
@@ -0,0 +1,333 @@
+<html devsite>
+  <head>
+    <title>Implementing A/B Updates</title>
+    <meta name="project_path" value="/_project.yaml" />
+    <meta name="book_path" value="/_book.yaml" />
+  </head>
+  <body>
+  <!--
+      Copyright 2017 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>OEMs and SoC vendors who want to implement A/B system updates must ensure
+their bootloader implements the boot_control HAL and passes the
+<a href="#kernel">correct parameters</a> to the kernel.</p>
+
+
+<h2 id=bootcontrol>Implementing the boot control HAL</h2>
+<p>A/B-capable bootloaders must implement the <code>boot_control</code> HAL at
+<code><a href="https://android.googlesource.com/platform/hardware/libhardware/+/master/include/hardware/boot_control.h" class="external">hardware/libhardware/include/hardware/boot_control.h</a></code>. You can test implementations using the
+<code><a href="https://android.googlesource.com/platform/system/extras/+/master/bootctl/" class="external">system/extras/bootctl</a></code> utility and
+<code><a href="https://android.googlesource.com/platform/system/extras/+/refs/heads/master/tests/bootloader/" class="external">system/extras/tests/bootloader/</a></code>.
+</p>
+
+<p>You must also implement the state machine shown below:</p>
+<img src="images/ab-updates-state-machine.png">
+<figcaption><strong>Figure 1.</strong> Bootloader state machine</figcaption>
+
+<h2 id=kernel>Setting up the kernel</h2>
+<p>To implement A/B system updates:</p>
+<ol>
+<li>Cherrypick the following kernel patch series (if needed):
+ <ul>
+ <li>If booting without ramdisk and using "boot as recovery", cherrypick
+ <a href="https://android-review.googlesource.com/#/c/158491/" class="external">android-review.googlesource.com/#/c/158491/</a>.</li>
+ <li>To set up dm-verity without ramdisk, cherrypick
+ <a href="https://android-review.googlesource.com/#/q/status:merged+project:kernel/common+branch:android-3.18+topic:A_B_Changes_3.18" class="external">android-review.googlesource.com/#/q/status:merged+project:kernel/common+branch:android-3.18+topic:A_B_Changes_3.18</a>.</li>
+ </ul>
+</li>
+<li>Ensure kernel command line arguments contain the following extra arguments:
+<pre class="devsite-click-to-copy">
+<code class="devsite-terminal">skip_initramfs rootwait ro init=/init root="/dev/dm-0 dm=system none ro,0 1 android-verity &lt;public-key-id&gt; &lt;path-to-system-partition&gt;"</code></pre>
+... where the <code>&lt;public-key-id&gt;</code> value is the ID of the public
+key used to verify the verity table signature (for details, see
+<a href="/security/verifiedboot/dm-verity.html">dm-verity</a>).</li>
+<li>Add the .X509 certificate containing the public key to the system keyring:
+ <ol>
+ <li>Copy the .X509 certificate formatted in the <code>.der</code> format to the
+ root of the <code>kernel</code> directory. If the .X509 certificate is
+ formatted as a <code>.pem</code> file, use the following <code>openssl</code>
+ command to convert from <code>.pem</code> to <code>.der</code> format:
+ <pre class="devsite-terminal devsite-click-to-copy">
+openssl x509 -in &lt;x509-pem-certificate&gt; -outform der -out &lt;x509-der-certificate&gt;</pre>
+ </li>
+ <li>Build the <code>zImage</code> to include the certificate as part of the
+ system keyring. To verify,check the <code>procfs</code> entry (requires
+ <code>KEYS_CONFIG_DEBUG_PROC_KEYS</code> to be enabled):
+<pre class="devsite-click-to-copy">
+angler:/# cat /proc/keys
+
+1c8a217e I------     1 perm 1f010000     0     0 asymmetri
+Android: 7e4333f9bba00adfe0ede979e28ed1920492b40f: X509.RSA 0492b40f []
+2d454e3e I------     1 perm 1f030000     0     0 keyring
+.system_keyring: 1/4</pre>
+ Successful inclusion of the .X509 certificate indicates the presence of the
+ public key in the system keyring (highlight denotes the public key ID).</li>
+ <li>Replace the space with <code>#</code> and pass it as
+ <code>&lt;public-key-id&gt;</code> in the kernel command line. For example,
+ pass <code>Android:#7e4333f9bba00adfe0ede979e28ed1920492b40f</code> in place of
+ <code>&lt;public-key-id&gt;</code>.</li>
+ </ol>
+</li>
+</ol>
+
+<h2 id="build-variables">Setting build variables</h2>
+
+<p>A/B-capable bootloaders must meet the following build variable criteria:</p>
+
+<table>
+<tr>
+<th>Must define for A/B target</th>
+<td>
+<ul>
+<li><code>AB_OTA_UPDATER := true</code></li>
+<li><code>AB_OTA_PARTITIONS := \</code><br/>
+<code>&nbsp; boot \</code><br/>
+<code>&nbsp; system \</code><br/>
+<code>&nbsp; vendor</code><br/>
+and other partitions updated through <code>update_engine</code> (radio,
+bootloader, etc.)</li>
+<li><code>BOARD_BUILD_SYSTEM_ROOT_IMAGE := true</code></li>
+<li><code>TARGET_NO_RECOVERY := true</code></li>
+<li><code>BOARD_USES_RECOVERY_AS_BOOT := true</code></li>
+<li><code>PRODUCT_PACKAGES += \</code><br/>
+<code>&nbsp; update_engine \</code><br/>
+<code>&nbsp; update_verifier</code></li>
+</ul>
+
+For an example, refer to
+<code><a href="https://android.googlesource.com/device/google/marlin/+/android-7.1.0_r1/device-common.mk" class="external">/device/google/marlin/+/android-7.1.0_r1/device-common.mk</a></code>.
+You can optionally conduct the post-install (but pre-reboot) dex2oat step
+described in <a href="#compilation">Compiling</a>.
+</td>
+</tr>
+<th>Cannot define for A/B target</th>
+<td>
+<ul>
+<li><code>BOARD_RECOVERYIMAGE_PARTITION_SIZE</code></li>
+<li><code>BOARD_CACHEIMAGE_PARTITION_SIZE</code></li>
+<li><code>BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE</code></li>
+</ul>
+</td>
+</tr>
+<tr>
+<th>Optional for debug builds</th>
+<td><code>PRODUCT_PACKAGES_DEBUG += update_engine_client</code></td>
+</tr>
+<tr>
+</table>
+
+<h2 id="partitions">Setting partitions (slots)</h2>
+<p>A/B devices do not need a recovery partition or cache partition because
+Android no longer uses these partitions. The data partition is now used for the
+downloaded OTA package, and the recovery image code is on the boot partition.
+All partitions that are A/B-ed should be named as follows (slots are always
+named <code>a</code>, <code>b</code>, etc.): <code>boot_a</code>,
+<code>boot_b</code>, <code>system_a</code>, <code>system_b</code>,
+<code>vendor_a</code>, <code>vendor_b</code>.</p>
+
+<h3 id=cache>Cache</h3>
+
+<p>For non-A/B updates, the cache partition was used to store downloaded OTA
+packages and to stash blocks temporarily while applying updates. There was
+never a good way to size the cache partition: how large it needed to be
+depended on what updates you wanted to apply. The worst case would be a cache
+partition as large as the system image. With A/B updates there's no need to
+stash blocks (because you're always writing to a partition that isn't currently
+used) and with streaming A/B there's no need to download the whole OTA package
+before applying it.</p>
+
+<h3 id=recovery>Recovery</h3>
+
+<p>The recovery RAM disk is now contained in the <code>boot.img</code> file.
+When going into recovery, the bootloader <strong>cannot</strong> put the
+<code>skip_initramfs</code> option on the kernel command line.</p>
+
+<p>For non-A/B updates, the recovery partition contains the code used to apply
+updates. A/B updates are applied by <code>update_engine</code> running in the
+regular booted system image. There is still a recovery mode used to implement
+factory data reset and sideloading of update packages (which is where the name
+"recovery" came from). The code and data for recovery mode is stored in the
+regular boot partition in a ramdisk; to boot into the system image, the
+bootloader tells the kernel to skip the ramdisk (otherwise the device boots into
+recovery mode. Recovery mode is small (and much of it was already on the boot
+partition), so the boot partition doesn't increase in size.</p>
+
+<h3 id="fstab">Fstab</h3>
+
+<p>The <code>slotselect</code> argument <strong>must</strong> be on the line for
+the A/B-ed partitions. For example:</p>
+
+<pre class="devsite-click-to-copy">
+&lt;path-to-block-device&gt;/vendor  /vendor  ext4  ro
+wait,verify=&lt;path-to-block-device&gt;/metadata,slotselect
+</pre>
+
+<p>No partition should be named <code>vendor</code>. Instead, partition
+<code>vendor_a</code> or <code>vendor_b</code> will be selected and mounted on
+the <code>/vendor</code> mount point.</p>
+
+<h3 id="kernel-slot-arguments">Kernel slot arguments</h3>
+
+<p>The current slot suffix should be passed either through a specific device
+tree (DT) node (<code>/firmware/android/slot_suffix</code>) or through the
+<code>androidboot.slot_suffix</code> command line argument.</p>
+
+<p>By default, fastboot flashes only slot <code>a</code> on an A/B device and
+sets the current slot to <code>a</code>. If the update package also contains
+images for slot <code>b</code>, fastboot flashes those images as well. Available
+options include:</p>
+
+<ul>
+<li><code>--slot</code>. Prompt fastboot to use slot <code>b</code> instead of
+slot <code>a</code>.</li>
+<li><code>--set-active</code>. Set the slot as active.</li>
+<li><code>fastboot --help</code>. Get details on commands.</li>
+</ul>
+
+<p>If the bootloader implements fastboot, it should support the command
+<code>set_active &lt;slot&gt;</code> that sets the current active slot
+to the given slot (this must also clear the unbootable flag for that slot and
+reset the retry count to default values). The bootloader should also support the
+following variables:</p>
+
+<ul>
+<li><code>has-slot:&lt;partition-base-name-without-suffix&gt;</code>. Returns
+“yes” if the given partition supports slots, “no” otherwise.</li>
+<li><code>current-slot</code>. Returns the slot suffix that will be booted from
+next.</li>
+<li><code>slot-count</code>. Returns an integer representing the number of
+available slots. Currently, two slots are supported so this value is
+<code>2</code>.</li>
+<li><code>slot-successful:&lt;slot-suffix&gt;</code>. Returns "yes" if the given
+slot has been marked as successfully booting, "no" otherwise.</li>
+<li><code>slot-unbootable:&lt;slot-suffix&gt;</code>. Returns “yes” if the given
+slot is marked as unbootable, "no" otherwise.</li>
+<li><code>slot-retry-count<slot suffix></code>. Number of retries remaining to
+attempt to boot the given slot.</li>
+</ul>
+
+<p>To view all variables, run
+<code class="devsite-terminal devsite-click-to-copy">fastboot getvar all</code>.
+</p>
+
+<h2 id="ota-package-generation">Generating OTA packages</h2>
+
+<p>The <a href="/devices/tech/ota/tools.html">OTA package tools</a> follow the
+same commands as the commands for non-A/B devices. The
+<code>target_files.zip</code> file must be generated by defining the build
+variables for the A/B target. The OTA package tools automatically identify and
+generate packages in the format for the A/B updater.</p>
+
+<p>Examples:</p>
+<ul>
+<li>To generate a full OTA:
+<pre class="devsite-terminal devsite-click-to-copy">
+./build/tools/releasetools/ota_from_target_files \
+  dist_output/tardis-target_files.zip ota_update.zip
+</pre>
+</li>
+<li>To generate an incremental OTA:
+<pre class="devsite-terminal devsite-click-to-copy">
+./build/tools/releasetools/ota_from_target_files \
+  -i PREVIOUS-tardis-target_files.zip \
+  dist_output/tardis-target_files.zip incremental_ota_update.zip
+</pre>
+</li>
+</ul>
+
+<h2 id="configuration">Configuring partitions</h2>
+
+<p>The <code>update_engine</code> can update any pair of A/B partitions defined
+in the same disk. A pair of partitions has a common prefix (such as
+<code>system</code> or <code>boot</code>) and per-slot suffix (such as
+<code>_a</code>). The list of partitions for which the payload generator defines
+an update is configured by the <code>AB_OTA_PARTITIONS</code> make variable.</p>
+
+<p>For example, if a pair of partitions <code>bootloader_a</code> and
+<code>booloader_b</code> are included (<code>_a</code> and <code>_b</code> are
+the slot suffixes), you can update these partitions by specifying the following
+on the product or board configuration:</p>
+
+<pre class="devsite-click-to-copy">
+AB_OTA_PARTITIONS := \
+  boot \
+  system \
+  bootloader
+</pre>
+
+<p>All partitions updated by <code>update_engine</code> must not be modified by
+the rest of the system. During incremental or <em>delta</em> updates, the binary
+data from the current slot is used to generate the data in the new slot. Any
+modification may cause the new slot data to fail verification during the update
+process, and therefore fail the update.</p>
+
+<h2 id="post-install">Configuring post-installation</h2>
+
+<p>You can configure the post-install step differently for each updated
+partition using a set of key-value pairs. To run a program located at
+<code>/system/usr/bin/postinst</code> in a new image, specify the path relative
+to the root of the filesystem in the system partition.</p>
+
+<p>For example, <code>usr/bin/postinst</code> is
+<code>system/usr/bin/postinst</code> (if not using a RAM disk). Additionally,
+specify the filesystem type to pass to the <code>mount(2)</code> system call.
+Add the following to the product or device <code>.mk</code> files (if
+applicable):</p>
+
+<pre class="devsite-click-to-copy">
+AB_OTA_POSTINSTALL_CONFIG += \
+  RUN_POSTINSTALL_system=true \
+  POSTINSTALL_PATH_system=usr/bin/postinst \
+  FILESYSTEM_TYPE_system=ext4
+</pre>
+
+<h2 id="compilation">Compiling</h2>
+<p>For security reasons, <code>system_server</code> cannot use
+<a href="/devices/tech/dalvik/jit-compiler">just-in-time (JIT)</a> compilation.
+This means you must compile ahead of time odex files for
+<code>system_server</code> and its dependencies at a minimum; anything else is
+optional.</p>
+
+<p>To compile apps in the background, you must add the following to the
+product's device configuration (in the product's device.mk):</p>
+
+<ol>
+<li>Include the native components in the build to ensure compilation script and
+binaries are compiled and included in the system image.
+<pre class="devsite-click-to-copy">
+  # A/B OTA dexopt package
+  PRODUCT_PACKAGES += otapreopt_script
+</pre></li>
+<li>Connect the compilation script to <code>update_engine</code> such that runs
+as a post-install step.
+<pre class="devsite-click-to-copy">
+  # A/B OTA dexopt update_engine hookup
+  AB_OTA_POSTINSTALL_CONFIG += \
+    RUN_POSTINSTALL_system=true \
+    POSTINSTALL_PATH_system=system/bin/otapreopt_script \
+    FILESYSTEM_TYPE_system=ext4 \
+    POSTINSTALL_OPTIONAL_system=true
+</pre>
+</li>
+</ol>
+
+<p>For help installing the preopted files in the unused second system partition,
+refer to <a href="/devices/tech/dalvik/configure.html#other_odex">First boot
+installation of DEX_PREOPT files</a>.</p>
+
+  </body>
+</html>
diff --git a/en/devices/tech/ota/ab_updates.html b/en/devices/tech/ota/ab_updates.html
index 871d8f6..5d51df1 100644
--- a/en/devices/tech/ota/ab_updates.html
+++ b/en/devices/tech/ota/ab_updates.html
@@ -21,138 +21,134 @@
       limitations under the License.
   -->
 
+<p>A/B system updates, also known as seamless updates, ensure a workable booting
+system remains on the disk during an
+<a href="/devices/tech/ota/index.html">over-the-air (OTA) update</a>. This
+approach reduces the likelihood of an inactive device after an update, which
+means fewer device replacements and device reflashes at repair and warranty
+centers. Other commercial-grade operating systems such as
+<a href="https://www.chromium.org/chromium-os">ChromeOS</a> also use A/B updates
+successfully.</p>
 
-
-<p>
-  A/B system updates, also known as seamless updates, ensure a workable booting
-  system remains on the disk during an <a href="/devices/tech/ota/index.html"
-  >over-the-air (OTA) update</a>. This reduces the likelihood of an inactive
-  device afterward, which means fewer device replacements and device reflashes at
-  repair and warranty centers. This approach is already explored successfully by
-  other commercial-grade operating systems, such as <a
-  href="https://www.chromium.org/chromium-os">ChromeOS</a>, and Android 8.0
-  comes with the necessary platform changes to conduct streaming updates.</p>
-
-<p class="note"><strong>Note:</strong> Android 7.1, in which A/B updates were
-introduced, requires the following patches to be cherrypicked before streaming
-updates can be enabled. This is true whether using <a
-href="https://www.android.com/gms/">Google Mobile Services (GMS)</a> or any
-other update client.</p>
+<p>A/B system updates provide the following benefits:</p>
 
 <ul>
-  <li><a href="https://android-review.googlesource.com/333624">Allow to cancel a proxy resolution request</a></li>
-  <li><a href="https://android-review.googlesource.com/333625">Fix terminating a transfer while resolving proxies</a></li>
-  <li><a href="https://android-review.googlesource.com/333626">Add unittest for TerminateTrasnfer between ranges</a></li>
-  <li><a href="https://android-review.googlesource.com/333627">Cleanup the RetryTimeoutCallback()</a></li>
+<li>OTA updates can occur while the system is running, without interrupting the
+user (including app optimizations that occur after a reboot). This means users
+can continue to use their devices during an OTA&mdash;the only downtime during
+an update is when the device reboots into the updated disk partition.</li>
+<li>If an OTA fails, the device boots into the pre-OTA disk partition and
+remains usable. The download of the OTA can be attempted again.</li>
+<li>Any errors (such as I/O errors) affect only the <strong>unused</strong>
+partition set and can be retried. Such errors also become less likely because
+the I/O load is deliberately low to avoid degrading the user experience.</li>
+<li>The cache partition is no longer used to store OTA update packages, so there
+is no need for sizing the cache partition.</li>
+<li><a href="/security/verifiedboot/dm-verity.html">dm-verity</a> guarantees a
+device will boot an uncorrupted image. If a device doesn't boot due to a bad OTA
+or dm-verity issue, the device can reboot into an old image. (Android
+<a href="/security/verifiedboot/">Verified Boot</a> does not require A/B
+updates.)</li>
 </ul>
 
-<p>
-  Users don't always have enough space on <code>/data</code> to download the
-  update package, and neither OEMs nor users want to waste space on a
-  <code>/cache</code> partition; so some users go without updates because
-  they have nowhere to store the update package. A/B updates have the option of
-  streaming the update to address this issue: streaming writes blocks
-  straight to the B partition as they are downloaded, without having to store
-  them on <code>/data</code>. Therefore, streaming A/B updates need almost no
-  temporary storage and need just enough for roughly 100 KiB of metadata.</p>
+<h2 id=overview>About A/B system updates</h2>
 
-<p>Customers can continue to use their devices during an OTA. The only downtime
-  during an update is when the device reboots into the updated disk partition. If
-  the OTA fails, the device is still useable since it will boot into the pre-OTA
-  disk partition. The download of the OTA can be attempted again. A/B system
-  updates implemented through OTA are recommended for new devices only. </p>
-
-<p>
-  A/B system updates affect:
-</p>
+<p>A/B system updates affect the following:</p>
 
 <ul>
-  <li>Interactions with the bootloader</li>
-  <li>Partition selection</li>
-  <li>The build process</li>
-  <li>OTA update package generation</li>
+<li>Partition selection (slots), the <code>update_engine</code> daemon, and
+bootloader interactions (described below)</li>
+<li>Build process and OTA update package generation (described in
+<a href="/devices/tech/ota/ab_implement.html">Implementing A/B Updates</a>)</li>
 </ul>
 
-<p>
-  The existing <a href="/security/verifiedboot/dm-verity.html">dm-verity</a>
-  feature guarantees the device will boot an uncorrupted image. If
-  a device doesn't boot, because of a bad OTA or dm-verity issue, the device can
-  reboot into an old image.
+<aside class="note"><strong>Note:</strong> A/B system updates implemented through
+OTA are recommended for new devices only.</aside>
+
+<h3 id=slots>Partition selection (slots)</h3>
+
+<p>A/B system updates use two sets of partitions referred to as <em>slots</em>
+(normally slot A and slot B). The system runs from the <em>current</em> slot
+while the partitions in the <em>unused</em> slot are not accessed by the running
+system during normal operation. This approach makes updates fault resistant by
+keeping the unused slot as a fallback: If an error occurs during or immediately
+after an update, the system can rollback to the old slot and continue to have a
+working system. To achieve this goal, no partition used by the <em>current</em>
+slot should be updated as part of the OTA update (including partitions for which
+there is only one copy).</p>
+
+<p>Each slot has a <em>bootable</em> attribute that states whether the slot
+contains a correct system from which the device can boot. The current slot is
+bootable when the system is running, but the other slot may have an old (still
+correct) version of the system, a newer version, or invalid data. Regardless of
+what the <em>current</em> slot is, there is one slot that is the <em>active</em>
+slot (the one the bootloader will boot form on the next boot) or the
+<em>preferred</em> slot.</p>
+
+Each slot also has a <em>successful</em> attribute set by the user space, which
+is relevant only if the slot is also bootable. A successful slot should be able
+to boot, run, and update itself. A bootable slot that was not marked as
+successful (after several attempts were made to boot from it) should be marked
+as unbootable by the bootloader, including changing the active slot to another
+bootable slot (normally to the slot running immediately before the attempt to
+boot into the new, active one). The specific details of the interface are
+defined in
+<code><a href="https://android.googlesource.com/platform/hardware/libhardware/+/master/include/hardware/boot_control.h" class="external-link">boot_control.h</a></code>.
 </p>
 
-<p class="note"><strong>Note:</strong> Android <a
-  href="/security/verifiedboot/">Verified Boot</a> does not require A/B
-  updates.</p>
+<h3 id="update-engine">Update engine daemon</h3>
 
-<h2 id="overview">Overview</h2>
+<p>A/B system updates use a background daemon called <code>update_engine</code>
+to prepare the system to boot into a new, updated version. This daemon can
+perform the following actions:</p>
 
-<p>
-  The A/B system is robust because any errors (such as I/O errors) affect only
-  the <strong>unused</strong> partition set and can be retried. Such errors also
-  become less likely because the I/O load is deliberately low to avoid degrading
-  the user experience.
+<ul>
+<li>Read from the current slot A/B partitions and write any data to the unused
+slot A/B partitions as instructed by the OTA package.</li>
+<li>Call the <code>boot_control</code> interface in a pre-defined workflow.</li>
+<li>Run a <em>post-install</em> program from the <em>new</em> partition after
+writing all the unused slot partitions, as instructed by the OTA package. (For
+details, see <a href="#post-installation">Post-installation</a>).</li>
+</ul>
+
+<p>As the <code>update_engine</code> daemon is not involved in the boot process
+itself, it is limited in what it can do during an update by the
+<a href="/security/selinux/">SELinux</a> policies and features in the
+<em>current</em> slot (such policies and features can't be updated until the
+system boots into a new version). To maintain a robust system, the update
+process <strong>should not</strong> modify the partition table, the contents of
+partitions in the current slot, or the contents of non-A/B partitions that can't
+be wiped with a factory reset.</p>
+
+<p>The <code>update_engine</code> source is located in
+<code><a href="https://android.googlesource.com/platform/system/update_engine/" class="external">system/update_engine</a></code>.
+The A/B OTA dexopt files are split between <code>installd</code> and a package
+manager:</p>
+<ul>
+<li><code><a href="https://android.googlesource.com/platform/frameworks/native/+/master/cmds/installd/" class="external-link">frameworks/native/cmds/installd/</a></code>ota*
+includes the postinstall script, the binary for chroot, the installd clone that
+calls dex2oat, the post-OTA move-artifacts script, and the rc file for the move
+script.</li>
+<li><code><a href="https://android.googlesource.com/platform/frameworks/base/+/master/services/core/java/com/android/server/pm/OtaDexoptService.java" class="external-link">frameworks/base/services/core/java/com/android/server/pm/OtaDexoptService.java</a></code>
+(plus <code><a href="https://android.googlesource.com/platform/frameworks/base/+/master/services/core/java/com/android/server/pm/OtaDexoptShellCommand.java" class="external-link">OtaDexoptShellCommand</a></code>)
+is the package manager that prepares dex2oat commands for applications.</li>
+</ul>
+
+<p>For a working example, refer to
+<code><a href="https://android.googlesource.com/device/google/marlin/+/nougat-dr1-release/device-common.mk" class="external-link">/device/google/marlin/device-common.mk</a></code>.
 </p>
 
-<p>
-  OTA updates can occur while the system is running, without interrupting the
-  user. This includes the app optimizations that occur after a reboot.
-  Additionally, the cache partition is no longer used to store OTA update
-  packages; there is no need for sizing the cache partition.
-</p>
+<h3 id="bootloader-interactions">Bootloader interactions</h3>
 
-<p>
-  A/B system updates use a background daemon called <code>update_engine</code>
-  and two sets of partitions. The two sets of partitions are referred to as
-  <em>slots</em>, normally as slot A and slot B. The system runs from one slot,
-  the <em>current</em> slot, while the partitions in the <em>unused</em> slot are
-  not accessed by the running system (for normal operation).
-</p>
-
-<p>
-  The goal of this feature is to make updates fault resistant by keeping the
-  unused slot as a fallback. If there is an error during an update or immediately
-  after an update, the system can rollback to the old slot and continue to have a
-  working system. To achieve this goal, none of the partitions used by the
-  <em>current</em> slot should be updated as part of the OTA update (including
-  partitions for which there is only one copy).
-</p>
-
-<p>
-  Each slot has a <em>bootable</em> attribute, which states whether the slot
-  contains a correct system from which the device can boot. The current slot is
-  clearly bootable when the system is running, but the other slot may have an old
-  (still correct) version of the system, a newer version, or invalid data.
-  Regardless of what the <em>current</em> slot is, there is one slot which is the
-  <em>active</em> or preferred slot. The active slot is the one the bootloader
-  will boot from on the next boot. Finally, each slot has a <em>successful</em>
-  attribute set by the user space, which is only relevant if the slot is also
-  bootable.
-</p>
-
-<p>
-  A successful slot should be able to boot, run, and update itself. A bootable
-  slot that was not marked as successful (after several attempts were made to
-  boot from it) should be marked as unbootable by the bootloader, including
-  changing the active slot to another bootable slot (normally to the slot running
-  right before the attempt to boot into the new, active one). The specific
-  details of the interface are defined in
-  <code><a class="external-link" target="_blank"
-           href="https://android.googlesource.com/platform/hardware/libhardware/+/master/include/hardware/boot_control.h" >boot_control.h</a></code>.
-</p>
-
-<h3 id="bootloader-state-examples">Bootloader state examples</h3>
-
-<p>
-  The <code>boot_control</code> HAL is used by <code>update_engine</code> (and
-  possibly other daemons) to instruct the bootloader what to boot from. These
-  are common example scenarios and their associated states:
-</p>
+<p>The <code>boot_control</code> HAL is used by <code>update_engine</code> (and
+possibly other daemons) to instruct the bootloader what to boot from. Common
+example scenarios and their associated states include the following:</p>
 
 <ul>
   <li>
     <strong>Normal case</strong>: The system is running from its current slot,
-    either slot A or B. No updates have been applied so far. The system's current
-    slot is bootable, successful, and the active slot.
+    either slot A or B. No updates have been applied so far. The system's
+    current slot is bootable, successful, and the active slot.
   </li>
   <li>
     <strong>Update in progress</strong>: The system is running from slot B, so
@@ -163,706 +159,229 @@
   <li>
     <strong>Update applied, reboot pending</strong>: The system is running from
     slot B, slot B is bootable and successful, but slot A was marked as active
-    (and therefore is marked as bootable). Slot A is not yet marked as successful
-    and some number of attempts to boot from slot A should be made by the
-    bootloader.
+    (and therefore is marked as bootable). Slot A is not yet marked as
+    successful and some number of attempts to boot from slot A should be made by
+    the bootloader.
   </li>
   <li>
     <strong>System rebooted into new update</strong>: The system is running from
-    slot A for the first time, slot B is still bootable and successful while slot
-    A is only bootable, and still active but not successful. A user space daemon
-    should mark slot A as successful after some checks are made.
+    slot A for the first time, slot B is still bootable and successful while
+    slot A is only bootable, and still active but not successful. A user space
+    daemon should mark slot A as successful after some checks are made.
   </li>
 </ul>
 
-<h3 id="update-engine-features">Update Engine features</h3>
+<h2 id="streaming-updates">Streaming updates</h2>
+<p>User devices don't always have enough space on <code>/data</code> to download
+the update package. As neither OEMs nor users want to waste space on a
+<code>/cache</code> partition, some users go without updates because the device
+has nowhere to store the update package. To address this issue, Android 8.0 adds
+support for streaming A/B updates that write blocks directly to the B partition
+as they are downloaded, without having to store the blocks on
+<code>/data</code>. Streaming A/B updates need almost no temporary storage and
+require just enough storage for roughly 100 KiB of metadata.</p>
 
-<p>
-  The <code>update_engine</code> daemon runs in the background and prepares the
-  system to boot into a new, updated version. The <code>update_engine</code>
-  daemon is not involved in the boot process itself and is limited in what it can
-  do during an update. The <code>update_engine</code> daemon can do the
-  following:
-</p>
-
+<p>To enable streaming updates in Android 7.1, cherrypick the following
+patches:</p>
 <ul>
-  <li>
-    Read from the current slot A/B partitions and write any data to the unused
-    slot A/B partitions as instructed by the OTA package
-  </li>
-  <li>
-    Call the <code>boot_control</code> interface in a pre-defined workflow
-  </li>
-  <li>
-    Run a <em>post-install</em> program from the <em>new</em> partition after
-    writing all the unused slot partitions, as instructed by the OTA package
-  </li>
+<li>
+<a href="https://android-review.googlesource.com/333624" class="external">Allow
+to cancel a proxy resolution request</a></li>
+<li>
+<a href="https://android-review.googlesource.com/333625" class="external">Fix
+terminating a transfer while resolving proxies</a></li>
+<li>
+<a href="https://android-review.googlesource.com/333626" class="external">Add
+unittest for TerminateTransfer between ranges</a></li>
+<li>
+<a href="https://android-review.googlesource.com/333627" class="external">Cleanup
+the RetryTimeoutCallback()</a></li>
 </ul>
 
-<p>
-  The post-install step is described in detail below. Note that the
-  <code>update_engine</code> daemon is limited by the
-  <a href="/security/selinux/">SELinux</a> policies and features in the
-  <em>current</em> slot; those policies and features can't be updated until the
-  system boots into a new version. To achieve a robustness goal, the update
-  process should not:
-</p>
-
-<ul>
-  <li>Modify the partition table</li>
-  <li>Modify the contents of partitions in the current slot</li>
-  <li>
-    Modify the contents of non-A/B partitions that can't be wiped with a
-    factory reset
-  </li>
-  </ul>
-
-  <h3 id="update-engine-source">Update Engine source</h3>
-
-<p>The source to <code>update_engine</code> is in <code><a
-    class="external-link" target="_blank" href="https://android.googlesource.com/platform/system/update_engine/">system/update_engine</a></code>.
-  The A/B OTA dexopt files are split between installd and package manager:</p>
-<ul>
-  <li><code><a class="external-link" target="_blank" href="https://android.googlesource.com/platform/frameworks/native/+/master/cmds/installd/">frameworks/native/cmds/installd/</a></code>ota*
---- the postinstall script, the binary for chroot, the installd clone
-that calls dex2oat, the post-OTA move-artifacts script, the rc file for
-the move script.</li>
-  <li><code><a class="external-link" target="_blank"
-        href="https://android.googlesource.com/platform/frameworks/base/+/master/services/core/java/com/android/server/pm/OtaDexoptService.java">frameworks/base/services/core/java/com/android/server/pm/OtaDexoptService.java</a></code>
-    (plus <code><a class="external-link" target="_blank" href="https://android.googlesource.com/platform/frameworks/base/+/master/services/core/java/com/android/server/pm/OtaDexoptShellCommand.java">OtaDexoptShellCommand</a></code>) is the package manager side that will prepare
-    all the dex2oat commands for the apps</li>
-</ul>
-
-<p>A working example can be found in <code><a class="external-link" target="_blank" href="https://android.googlesource.com/device/google/marlin/+/nougat-dr1-release/device-common.mk">/device/google/marlin/device-common.mk</a></code>.</p>
+<p>These patches are required for Android 7.1 whether using
+<a href="https://www.android.com/gms/">Google Mobile Services (GMS)</a> or any
+other update client.</p>
 
 <h2 id="life-of-an-a-b-update">Life of an A/B update</h2>
 
-<p>
-  The update process starts when an OTA package, referred to in code as a
-  <em>payload</em>, is available for downloading. Policies in the device may
-  defer the payload download and application based on battery level, user
-  activity, whether it is connected to a charger, or other policies. But since
-  the update runs in the background, the user might not know that an update is
-  in progress and the process can be interrupted at any point due to policies or
-  unexpected reboots.
-</p>
+<p>The update process starts when an OTA package (referred to in code as a
+<em>payload</em>) is available for downloading. Policies in the device may defer
+the payload download and application based on battery level, user activity,
+charging status, or other policies. In addition, because the update runs in the
+background, users might not know an update is in progress. All of this means the
+update process might be interrupted at any point due to policies, unexpected
+reboots, or user actions.</p>
 
-<p>
-   Optionally, metadata in the OTA package itself indicates the update can be
-   streamed. The same package can be used for non-streaming installation, as
-   well. The server may use the metadata to tell the client it's streaming
-   so the client will hand off the OTA to <code>update_engine</code> correctly.
-   To enable streaming updates, manufacturers with their own server and client
-   would need to:
-   <ol>
-     <li>on the server, identify the update is streaming (or just assume all are)</li>
-     <li>on the client, make the correct call to <code>update_engine</code> for streaming</li>
-   </ol>
+<p>Optionally, metadata in the OTA package itself indicates the update can be
+streamed; the same package can also be used for non-streaming installation. The
+server may use the metadata to tell the client it's streaming so the client will
+hand off the OTA to <code>update_engine</code> correctly. Device manufacturers
+with their own server and client can enable streaming updates by ensuring the
+server identifies the update is streaming (or assumes all updates are streaming)
+and the client makes the correct call to <code>update_engine</code> for
+streaming. Manufacturers can use the fact that the package is of the streaming
+variant to send a flag to the client to trigger hand off to the framework side
+as streaming.</p>
 
-<p>
-  Device manufacturers should use the fact that the package is of the streaming
-  variant to send a flag to the client to trigger hand off to the framework
-  side as streaming.
-</p>
+<p>After a payload is available, the update process is as follows:</p>
 
-<p>
-  The steps in the update process after a payload is available are as follows:
-</p>
+<table>
+<tr>
+<th>Step</th>
+<th>Activities</th>
+</tr>
+<tr>
+<td>1</td>
+<td>The current slot (or "source slot") is marked as successful (if not already
+marked) with <code>markBootSuccessful()</code>.</td>
+</tr>
+<tr>
+<td>2</td>
+<td>The unused slot (or "target slot") is marked as unbootable by calling the
+function <code>setSlotAsUnbootable()</code>. The current slot is always marked
+as successful at the beginning of the update to prevent the bootloader from
+falling back to the unused slot, which will soon have invalid data. If the
+system has reached the point where it can start applying an update, the current
+slot is marked as successful even if other major components are broken (such as
+the UI in a crash loop) as it is possible to push new software to fix these
+problems.
+<br><br>
+The update payload is an opaque blob with the instructions to update to the new
+version. The update payload consists of the following:
+<ul>
+<li><em>Metadata</em>. A relatively small portion of the update payload, the
+metadata contains a list of operations to produce and verify the new version on
+the target slot. For example, an operation could decompress a certain blob and
+write it to specific blocks in a target partition, or read from a source
+partition, apply a binary patch, and write to certain blocks in a target
+partition.</li>
+<li><em>Extra data</em>. As the bulk of the update payload, the extra data
+associated with the operations consists of the compressed blob or binary patch
+in these examples.</li>
+</ul>
+</td>
+</tr>
+<tr>
+<td>3</td>
+<td>The payload metadata is downloaded.</td>
+</tr>
+<tr>
+<td>4</td>
+<td>For each operation defined in the metadata, in order, the associated data
+(if any) is downloaded to memory, the operation is applied, and the associated
+memory is discarded.</td>
+</tr>
+<tr>
+<td>5</td>
+<td>The whole partitions are re-read and verified against the expected hash.
+</td>
+</tr>
+<tr>
+<td>6</td>
+<td>The post-install step (if any) is run. In the case of an error during the
+execution of any step, the update fails and is re-attempted with possibly a
+different payload. If all the steps so far have succeeded, the update succeeds
+and the last step is executed.</td>
+</tr>
+<tr>
+<td>7</td>
+<td>The <em>unused slot</em> is marked as active by calling
+<code>setActiveBootSlot()</code>. Marking the unused slot as active doesn't mean
+it will finish booting. The bootloader (or system itself) can switch the active
+slot back if it doesn't read a successful state.</td>
+</tr>
+<tr>
+<td>8</td>
+<td>Post-installation (described below) involves running a program from the
+"new update" version while still running in the old version. If defined in the
+OTA package, this step is <strong>mandatory</strong> and the program must return
+with exit code <code>0</code>; otherwise, the update fails.</td>
+</tr>
+</table>
 
-<p>
-  <strong>Step 1:</strong> The current slot (or "source slot") is marked as
-  successful (if not already marked) with <code>markBootSuccessful()</code>.
-</p>
+<aside class="note"><strong>Note:</strong> Steps 3 and 4 take most of the update
+time as they involve writing and downloading large amounts of data, and are
+likely to be interrupted for reasons of policy or reboot.</aside>
 
-<p>
-  <strong>Step 2:</strong> The unused slot (or "target slot") is marked as
-  unbootable by calling the function <code>setSlotAsUnbootable()</code>.
-</p>
+<h3 id="post-installation">Post-installation</h3>
 
-<p>
-  The current slot is always marked as successful at the beginning of the update
-  to prevent the bootloader from falling back to the unused slot, which will soon
-  have invalid data. If the system has reached the point where it can start
-  applying an update, the current slot is marked as successful even if other
-  major components are broken (such as the UI in a crash loop) since it's
-  possible to push new software to fix these major problems.
-</p>
+<p>For every partition where a post-install step is defined,
+<code>update_engine</code> mounts the new partition into a specific location and
+executes the program specified in the OTA relative to the mounted partition. For
+example, if the post-install program is defined as
+<code>usr/bin/postinstall</code> in the system partition, this partition from
+the unused slot will be mounted in a fixed location (such as
+<code>/postinstall_mount</code>) and the
+<code>/postinstall_mount/usr/bin/postinstall</code> command is executed.</p>
 
-<p>
-  The update payload is an opaque blob with the instructions to update to the
-  new version. The update payload consists of basically two parts: the metadata
-  and the extra data associated with the instructions. The metadata is
-  relatively small and contains a list of operations to produce and verify the
-  new version on the target slot. For example, an operation could decompress a
-  certain blob and write it to certain blocks in a target partition, or read from
-  a source partition, apply a binary patch, and write to certain blocks in a
-  target partition. The extra data associated to the operations, not included in
-  the metadata, is the bulk of the update payload and would consist of the
-  compressed blob or binary patch in these examples.
-</p>
-
-<p>
-  <strong>Step 3:</strong> The payload metadata is downloaded.
-</p>
-
-<p>
-  <strong>Step 4:</strong> For each operation defined in the metadata, in order,
-  the associated data (if any) is downloaded to memory, the operation is applied,
-  and the associated memory is discarded.
-</p>
-
-<p>
-  These two steps take most of the update time, as they involve writing and
-  downloading large amounts of data, and are likely to be interrupted for reasons
-  of policy or reboot.
-</p>
-
-<p>
-  <strong>Step 5:</strong> The whole partitions are re-read and verified against
-  the expected hash.
-</p>
-
-<p>
-  <strong>Step 6:</strong> The post-install step (if any) is run.
-</p>
-
-<p>
-  In the case of an error during the execution of any step, the update fails and
-  is re-attempted with possibly a different payload. If all the steps so far have
-  succeeded, the update succeeds and the last step is executed.
-</p>
-
-<p>
-  <strong>Step 7:</strong> The <em>unused slot</em> is marked as active by
-  calling <code>setActiveBootSlot()</code>.
-</p>
-
-<p>
-  Marking the unused slot as active doesn't mean it will finish booting. The
-  bootloader—or system itself—can switch the active slot back if it doesn't
-  read a successful state.
-</p>
-
-<h3 id="post-install-step">Post-install step</h3>
-
-<p>
-  The post-install step consists of running a program from the "new update"
-  version while still running in the old version. If defined in the OTA package,
-  this step is mandatory and the program must return with exit code
-  <code>0</code>; otherwise, the update fails.
-</p>
-
-<p>
-  For every partition where a post-install step is defined,
-  <code>update_engine</code> mounts the new partition into a specific location
-  and executes the program specified in the OTA relative to the mounted
-  partition. For example, if the post-install program is defined as
-  <code>usr/bin/postinstall</code> in the system partition, this partition from
-  the unused slot will be mounted in a fixed location (for example, in
-  <code>/postinstall_mount</code>) and the
-  <code>/postinstall_mount/usr/bin/postinstall</code> command will be executed.
-  Note that for this step to work, the following are required:
-</p>
+<p>For post-installation to succeed, the old kernel must be able to:</p>
 
 <ul>
-  <li>
-    The old kernel needs to be able to mount the new filesystem format. The
-    filesystem type cannot change unless there's support for it in the old
-    kernel (which includes details such as the compression algorithm used if
-    using a compressed filesystem like SquashFS).
-  </li>
-  <li>
-    The old kernel needs to understand the new partition's post-install program
-    format. If using an ELF binary, it should be compatible with the old
-    kernel (e.g. a 64-bit new program running on an old 32-bit kernel if the
-    architecture switched from 32- to 64-bit builds). Also, the libraries
-    will be loaded from the old system image, not the new one, unless the loader
-    (<code>ld</code>) is instructed to use other paths or build a static binary.
-  </li>
-  <li>
-    The new post-install program will be limited by the SELinux policies defined
-    in the old system.
-  </li>
+<li><strong>Mount the new filesystem format</strong>. The filesystem type cannot
+change unless there's support for it in the old kernel, including details such
+as the compression algorithm used if using a compressed filesystem (i.e.
+SquashFS).</li>
+<li><strong>Understand the new partition's post-install program format</strong>.
+If using an Executable and Linkable Format (ELF) binary, it should be compatible
+with the old kernel (e.g. a 64-bit new program running on an old 32-bit kernel
+if the architecture switched from 32- to 64-bit builds). Unless the loader
+(<code>ld</code>) is instructed to use other paths or build a static binary,
+libraries will be loaded from the old system image and not the new one.</li>
 </ul>
 
-<p>
-  An example case is to use a shell script as a post-install program (interpreted
-  by the old system's shell binary with a <code>#!</code> marker at the top) and
-  then set up library paths from the new environment for executing a more complex
-  binary post-install program.
-</p>
+<p>For example, you could use a shell script as a post-install program
+(interpreted by the old system's shell binary with a <code>#!</code> marker at
+the top), then set up library paths from the new environment for executing a
+more complex binary post-install program. Alternatively, you could run the
+post-install step from a dedicated smaller partition to enable the filesystem
+format in the main system partition to be updated without incurring backward
+compatibility issues or stepping-stone updates; this would allow users to update
+directly to the latest version from a factory image.</p>
 
-<p>
-  Another example case is to run the post-install step from a dedicated smaller
-  partition, so the filesystem format in the main system partition can be updated
-  without incurring backward compatibility issues or stepping-stone updates,
-  allowing users to update straight to the latest version from a factory image.
-</p>
+<p>The new post-install program is limited by the SELinux policies defined in
+the old system. As such, the post-install step is suitable for performing tasks
+required by design on a given device or other best-effort tasks (i.e. updating
+the A/B-capable firmware or bootloader, preparing copies of databases for the
+new version, etc.). The post-install step is <strong>not suitable</strong> for
+one-off bug fixes before reboot that require unforeseen permissions.</p>
 
-<p>
-  Due to the SELinux policies, the post-install step is suitable for
-  performing tasks required by design on a given device or other best-effort
-  tasks: update the A/B-capable firmware or bootloader, prepare copies of some
-  databases for the new version, etc. This step is not suitable for one-off bug
-  fixes before reboot that require unforeseen permissions.
-</p>
+<p>The selected post-install program runs in the <code>postinstall</code>
+SELinux context. All the files in the new mounted partition will be tagged with
+<code>postinstall_file</code>, regardless of what their attributes are after
+rebooting into that new system. Changes to the SELinux attributes in the new
+system won't impact the post-install step. If the post-install program needs
+extra permissions, those must be added to the post-install context.</p>
 
-<p>
-  The selected post-install program runs in the <code>postinstall</code> SELinux
-  context. All the files in the new mounted partition will be tagged with
-  <code>postinstall_file</code>, regardless of what their attributes are after
-  rebooting into that new system. Changes to the SELinux attributes in the new
-  system won't impact the post-install step. If the post-install program needs
-  extra permissions, those must be added to the post-install context.
-</p>
-
-<h2 id="implementation">Implementation</h2>
-
-<p>
-  OEMs and SoC vendors who wish to implement the feature must add the following
-  support to their bootloaders:
-</p>
-
-<ul>
-  <li>
-    Pass the <a href="#kernel-command-line-arguments">correct parameters</a>
-    to the kernel
-  </li>
-  <li>
-    Implement the <code>boot_control</code> HAL
-    (<code><a class="external-link nowrap" target="_blank"
-        href="https://android.googlesource.com/platform/hardware/libhardware/+/master/include/hardware/boot_control.h"
-        >hardware/libhardware/include/hardware/boot_control.h</a></code>)
-  </li>
-  <li>Implement the state machine as shown in Figure 1:</li>
-</ul>
-
-<img src="/devices/tech/ota/images/ab-updates-state-machine.png">
-
-<p class="img-caption"><strong>Figure 1.</strong> Bootloader state machine</p>
-
-<p>
-  The boot control HAL can be tested using the
-  <code><a class="external-link" target="_blank"
-     href="https://android.googlesource.com/platform/system/extras/+/master/bootctl/"
-     >system/extras/bootctl</a></code> utility.
-</p>
-
-<p>Some tests have been implemented for Brillo:</p>
-
-<ul>
-  <li>
-    <code><a class="external-link nowrap" target="_blank"
-       href="https://android.googlesource.com/platform/system/extras/+/refs/heads/master/tests/bootloader/"
-       >system/extras/tests/bootloader/</a></code>
-  </li>
-  <li>
-    <a class="external-link nowrap" target="_blank"
-       href="https://chromium.googlesource.com/chromiumos/third_party/autotest/+/master/server/site_tests/brillo_BootLoader/brillo_BootLoader.py"
-    >chromium.googlesource.com/chromiumos/third_party/autotest/+/master/server/site_tests/brillo_BootLoader/brillo_BootLoader.py</a>
-  </li>
-</ul>
-
-<h3 id="kernel-patches">Kernel patches</h3>
-
-<ul>
-  <li>
-    <a class="external-link nowrap" target="_blank"
-       href="https://android-review.googlesource.com/#/c/158491/"
-    >android-review.googlesource.com/#/c/158491/</a>
-  </li>
-  <li>
-    <a class="external-link nowrap" target="_blank"
-       href="https://android-review.googlesource.com/#/q/status:merged+project:kernel/common+branch:android-3.18+topic:A_B_Changes_3.18"
-    >android-review.googlesource.com/#/q/status:merged+project:kernel/common+branch:android-3.18+topic:A_B_Changes_3.18</a>
-  </li>
-</ul>
-
-<h3 id="kernel-command-line-arguments">Kernel command line arguments</h3>
-
-<p>
-  The kernel command line arguments <strong>must</strong> contain the following
-  extra arguments:
-</p>
-
-<pre class="devsite-click-to-copy">
-<code class="devsite-terminal">skip_initramfs rootwait ro init=/init root="/dev/dm-0 dm=system none ro,0 1 \
-  android-verity &lt;public-key-id&gt; &lt;path-to-system-partition&gt;"</code>
-</pre>
-
-<p>
-  The <code>&lt;public-key-id&gt;</code> value is the ID of the public key used
-  to verify the verity table signature (see
-  <a href="/security/verifiedboot/dm-verity.html">dm-verity</a>).
-</p>
-
-<h4>
-  To add the .X509 certificate containing the public key to the system keyring:
-</h4>
-
-<ol>
-  <li>
-    Copy the .X509 certificate formatted in the <code>.der</code>
-    format to the root of the <code>kernel</code> directory. Use the following
-    <code>openssl</code> command to convert from <code>.pem</code> to
-    <code>.der</code> format (if the .X509 certificate is formatted in
-    <code>.pem</code> format):
-<pre class="devsite-terminal devsite-click-to-copy">
-openssl x509 -in &lt;x509-pem-certificate&gt; -outform der -out &lt;x509-der-certificate&gt;
-</pre>
-  </li>
-  <li>
-    Once copied to the kernel build root, build the <code>zImage</code> to
-    include the certificate as part of the system keyring. This can be verified
-    from the following <code>procfs</code> entry (requires
-    <code>KEYS_CONFIG_DEBUG_PROC_KEYS</code> to be enabled):
-<pre class="devsite-click-to-copy">
-angler:/# cat /proc/keys
-
-1c8a217e I------     1 perm 1f010000     0     0 asymmetri
-Android: 7e4333f9bba00adfe0ede979e28ed1920492b40f: X509.RSA 0492b40f []
-2d454e3e I------     1 perm 1f030000     0     0 keyring
-.system_keyring: 1/4
-</pre>
-  </li>
-</ol>
-
-<p>
-  Successful inclusion of the .X509 certificate indicates the presence of the
-  public key in the system keyring. The highlighted portion denotes the public
-  key ID.
-</p>
-
-<p>
-  As the next step, replace the space with ‘#’ and pass it as
-  <code>&lt;public-key-id&gt;</code> in the kernel command line. For example, in the
-  above case, the following is passed in the place of
-  <code>&lt;public-key-id&gt;</code>:
-  <code>Android:#7e4333f9bba00adfe0ede979e28ed1920492b40f</code>
-</p>
-
-<h3 id="recovery">Recovery</h3>
-
-<p>
-  The recovery RAM disk is now contained in the <code>boot.img</code> file. When
-  going into recovery, the bootloader <strong>cannot</strong> put the
-  <code>skip_initramfs</code> option on the kernel command line.
-</p>
-<p>
-  For non-A/B updates, the recovery partition contains the code used to apply
-  updates. A/B updates are applied by <code>update_engine</code> running in the regular
-  booted system image. There is still a recovery mode used to implement factory
-  data reset and sideloading of update packages, which is where the name
-  "recovery" came from. The code and data for recovery mode is stored in the
-  regular boot partition now, in a ramdisk. So to boot into the system image,
-  the bootloader tells the kernel to skip the ramdisk; otherwise we'll boot
-  into recovery mode. Recovery mode is small (and much of it was already on the
-  boot partition), so the boot partition doesn't increase in size.</p>
-
-<h3 id="build-variables">Build variables</h3>
-
-<p>To implement A/B updates, you need a new A/B-capable bootloader and have
-`AB_OTA_UPDATER := true` in your board configuration and list the
-partitions to which A/B applies.</p>
-<h5>Must define for the A/B target:</h5>
-
-<ul>
-  <li><code>AB_OTA_UPDATER := true</code></li>
-  <li>
-    <code>AB_OTA_PARTITIONS := \</code><br/>
-    <code>&nbsp; boot \</code><br/>
-    <code>&nbsp; system \</code><br/>
-    <code>&nbsp; vendor</code><br/>
-    and other partitions updated through <code>update_engine</code> (radio,
-    bootloader, etc.)
-  </li>
-  <li>
-    <code>BOARD_BUILD_SYSTEM_ROOT_IMAGE := true</code>
-  </li>
-  <li><code>TARGET_NO_RECOVERY := true</code></li>
-  <li>
-    <code>BOARD_USES_RECOVERY_AS_BOOT := true</code>
-  </li>
-  <li>
-    <code>PRODUCT_PACKAGES += \</code><br/>
-    <code>&nbsp; update_engine \</code><br/>
-    <code>&nbsp; update_verifier</code>
-  </li>
-  </ul>
-<p>For an example, see:<br>
-<code><a href="https://android.googlesource.com/device/google/marlin/+/android-7.1.0_r1/device-common.mk">/device/google/marlin/+/android-7.1.0_r1/device-common.mk</a></code></p>
-
-<p>Optionally, conduct the post-install (but pre-reboot) dex2oat step described
-within the <a href="#compilation">Compilation</a> section.</p>
-
-<h5>Optionally define for debug builds:</h5>
-
-<ul>
-  <li>
-    <code>PRODUCT_PACKAGES_DEBUG += update_engine_client</code>
-  </li>
-</ul>
-
-<h5>Cannot define for the A/B target:</h5>
-
-<ul>
-  <li><code>BOARD_RECOVERYIMAGE_PARTITION_SIZE</code></li>
-  <li><code>BOARD_CACHEIMAGE_PARTITION_SIZE</code></li>
-  <li><code>BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE</code></li>
-</ul>
-
-<h3 id="partitions">Partitions</h3>
-<p>
-    A/B devices do not need a recovery partition or cache partition because
-    Android no longer uses these partitions. The data partition is now used for
-    the downloaded OTA package, and the recovery image code is on the boot
-    partition.
-    All partitions that are A/B-ed should be named as follows (slots are always
-    named <code>a</code>, <code>b</code>, etc.): <code>boot_a</code>,
-    <code>boot_b</code>, <code>system_a</code>, <code>system_b</code>,
-    <code>vendor_a</code>, <code>vendor_b</code>.
-</p>
-
-<p>For non-A/B updates, the cache partition was used to store downloaded OTA
-packages and to stash blocks temporarily while applying updates. There was
-never a good way to size the cache partition: how large it needed to be
-depended on what updates you wanted to apply. The worst case would be a cache
-partition as large as the system image. With A/B updates there's no need to
-stash blocks (because you're always writing to a partition that isn't currently
-used) and with streaming A/B there's no need to download the whole OTA package
-before applying it.</p>
-
-<h3 id="fstab">Fstab</h3>
-
-<p>
-  The <code>slotselect</code> argument <strong>must</strong> be on the line for
-  the A/B-ed partitions. For example:
-</p>
-
-<pre class="devsite-click-to-copy">
-&lt;path-to-block-device&gt;/vendor  /vendor  ext4  ro
-wait,verify=&lt;path-to-block-device&gt;/metadata,slotselect
-</pre>
-
-<p>
-  Please note that there should be no partition named <code>vendor</code> but
-  instead the partition <code>vendor_a</code> or <code>vendor_b</code> will be
-  selected and mounted on the <code>/vendor</code> mount point.
-</p>
-
-<h3 id="kernel-slot-arguments">Kernel slot arguments</h3>
-
-<p>
-  The current slot suffix should be passed either through a specific DT node
-  (<code>/firmware/android/slot_suffix</code>) or through the
-  <code>androidboot.slot_suffix</code> command line argument.
-</p>
-
-<p>By default, fastboot will flash just slot 'a' on an A/B device, and set the
-current slot to 'a'. An update package can contain images for slot 'b' too, in
-which case they will also be flashed. A new '--slot' option lets you ask
-fastboot to use slot 'b' instead of slot 'a', and the '--set-active' option
-lets you set that slot as active too. There's also a new 'fastboot set_active'
-command. See 'fastboot --help' for more details.</p>
-
-<p>
-  Optionally, if the bootloader implements fastboot, the following commands and
-  variables should be supported:
-</p>
-
-<h4>Commands</h4>
-<ul>
-  <li>
-    <code>set_active &lt;slot&gt;</code> —Sets the current active slot to
-    the given slot. This must also clear the unbootable flag for that slot, and
-    reset the retry count to default values.
-  </li>
-</ul>
-
-<h4>Variables</h4>
-<ul>
-  <li>
-    <code>has-slot:&lt;partition-base-name-without-suffix&gt;</code>
-      —Returns “yes” if the given partition supports slots, “no” otherwise.
-  </li>
-  <li>
-    <code>current-slot</code> —Returns the slot suffix that will be booted from
-    next.
-  </li>
-  <li>
-    <code>slot-count</code> —Returns an integer representing the number of
-    available slots. Currently, two slots are supported so this value is
-    <code>2</code>.
-  </li>
-  <li>
-    <code>slot-successful:&lt;slot-suffix&gt;</code> —Returns "yes" if the given
-    slot has been marked as successfully booting, "no" otherwise.
-  </li>
-  <li>
-    <code>slot-unbootable:&lt;slot-suffix&gt;</code> —Returns “yes” if the given
-    slot is marked as unbootable, "no" otherwise.
-  </li>
-  <li>
-    <code>slot-retry-count:<slot suffix></code> —Number of retries remaining to
-    attempt to boot the given slot.
-  </li>
-  <li>
-    These variables should all appear under the following:
-    <code>fastboot getvar all</code>
-  </li>
-</ul>
-
-<h3 id="ota-package-generation">OTA package generation</h3>
-
-<p>
-  The <a href="/devices/tech/ota/tools.html">OTA package tools</a>
-  follow the same commands as the commands for non-A/B devices. The
-  <code>target_files.zip</code> file must be generated by defining the build
-  variables for the A/B target. The OTA package tools automatically identify and
-  generate packages in the format for the A/B updater.
-</p>
-
-<p>
-  For example, use the following to generate a full OTA:
-</p>
-
-<pre class="devsite-terminal devsite-click-to-copy">
-./build/tools/releasetools/ota_from_target_files \
-  dist_output/tardis-target_files.zip ota_update.zip
-</pre>
-
-<p>
-  Or, generate an incremental OTA:
-</p>
-
-<pre class="devsite-terminal devsite-click-to-copy">
-./build/tools/releasetools/ota_from_target_files \
-  -i PREVIOUS-tardis-target_files.zip \
-  dist_output/tardis-target_files.zip incremental_ota_update.zip
-</pre>
-
-<h2 id="configuration">Configuration</h2>
-
-<h3 id="config-partitions">Partitions</h3>
-
-<p>
-  The Update Engine can update any pair of A/B partitions defined in the same
-  disk.
-</p>
-
-<p>
-  A pair of partitions has a common prefix (such as <code>system</code> or
-  <code>boot</code>) and per-slot suffix (such as <code>_a</code>). The list of
-  partitions for which the payload generator defines an update is configured by
-  the <code>AB_OTA_PARTITIONS</code> make variable. For example, if a pair of
-  partitions <code>bootloader_a</code> and <code>booloader_b</code> are included
-  (<code>_a</code> and <code>_b</code> are the slot suffixes), these partitions
-  can be updated by specifying the following on the product or board
-  configuration:
-</p>
-
-<pre class="devsite-click-to-copy">
-AB_OTA_PARTITIONS := \
-  boot \
-  system \
-  bootloader
-</pre>
-
-<p>
-  All the partitions updated by the Update Engine must not be modified by the
-  rest of the system. During incremental or <em>delta</em> updates, the binary
-  data from the current slot is used to generate the data in the new slot. Any
-  modification may cause the new slot data to fail verification during the
-  update process, and therefore fail the update.
-</p>
-
-<h3 id="post-install">Post-install</h3>
-
-<p>
-  The post-install step can be configured differently for each updated partition
-  using a set of key-value pairs.
-</p>
-
-<p>
-  To run a program located at <code>/system/usr/bin/postinst</code> in a
-  new image, specify the path relative to the root of the filesystem in the
-  system partition. For example, <code>usr/bin/postinst</code> is
-  <code>system/usr/bin/postinst</code> (if not using a RAM disk). Additionally,
-  specify the filesystem type to pass to the <code>mount(2)</code> system call.
-  Add the following to the product or device <code>.mk</code> files (if
-  applicable):
-</p>
-
-<pre class="devsite-click-to-copy">
-AB_OTA_POSTINSTALL_CONFIG += \
-  RUN_POSTINSTALL_system=true \
-  POSTINSTALL_PATH_system=usr/bin/postinst \
-  FILESYSTEM_TYPE_system=ext4
-</pre>
-
-<h3 id="compilation">Compilation</h3>
-<p>Minimally, you must compile ahead of time odex files for system_server and
-its dependencies (because system_server isn't allowed to JIT for security
-reasons); but anything else is optional.</p>
-
-<p>Compiling apps in the background for A/B updates requires the following two
-  additions to the product's device configuration (in the product's device.mk):</p>
-
-<ol>
-  <li>Include the native components in the build. This ensures the compilation
-  script and binaries are compiled and included in the system image.
-<pre class="devsite-click-to-copy">
-  # A/B OTA dexopt package
-  PRODUCT_PACKAGES += otapreopt_script
-</pre>
-  </li>
-  <li>Connect the compilation script to <code>update_engine</code> such that it
-  is run as a post-install step.
-<pre class="devsite-click-to-copy">
-  # A/B OTA dexopt update_engine hookup
-  AB_OTA_POSTINSTALL_CONFIG += \
-    RUN_POSTINSTALL_system=true \
-    POSTINSTALL_PATH_system=system/bin/otapreopt_script \
-    FILESYSTEM_TYPE_system=ext4 \
-    POSTINSTALL_OPTIONAL_system=true
-  </pre>
-  </li>
-</ol>
-
-<p>See <a href="/devices/tech/dalvik/configure.html#other_odex">First
-boot installation of DEX_PREOPT files</a> to install the preopted files in the
-unused second system partition.</p>
-
-<h2>Frequently asked questions </h2>
+<h2 id=faq>Frequently asked questions</h2>
 
 <h3>Has Google used A/B OTAs on any devices?</h3>
 
-<p>Yes. The marketing name for this feature is <em>seamless updates</em>. The
-Pixel and Pixel XL phones from October 2016 shipped with A/B. Additionally, all
-Chromebooks use the same <code>update_engine</code> implementation of A/B. The
-necessary platform code implementation is public in Android 7.1 and later.</p>
+<p>Yes. The marketing name for A/B updates is <em>seamless updates</em>. Pixel
+and Pixel XL phones from October 2016 shipped with A/B, and all Chromebooks use
+the same <code>update_engine</code> implementation of A/B. The necessary
+platform code implementation is public in Android 7.1 and higher.</p>
 
 <h3>Why are A/B OTAs better?</h3>
 
-<p>As the name of seamless updates implies, A/B OTAs provide a
-better user experience when taking updates. Measurements from monthly
-security updates show this feature has already proven a success: As of May
-2017, 95% of Pixel owners are running the latest security update after a month
-compared to 87% of Nexus users, and the Pixel users update sooner than Nexus
-users would. Failures to update blocks during an OTA no longer result in a
-device that won't boot; until the new system image has successfully booted,
-Android retains the ability to fall back to the previous working system image.</p>
+<p>A/B OTAs provide a better user experience when taking updates. Measurements
+from monthly security updates show this feature has already proven a success: As
+of May 2017, 95% of Pixel owners are running the latest security update after a
+month compared to 87% of Nexus users, and Pixel users update sooner than Nexus
+users. Failures to update blocks during an OTA no longer result in a device that
+won't boot; until the new system image has successfully booted, Android retains
+the ability to fall back to the previous working system image.</p>
 
 <h3>How did A/B affect the 2016 Pixel partition sizes?</h3>
 
-<p>See the following table for the shipping A/B configuration versus the internally-tested non-A/B configuration:</p>
+<p>The following table contains details on the shipping A/B configuration versus
+the internally-tested non-A/B configuration:</p>
 
 <table>
   <tbody>
     <tr>
       <th>Pixel partition sizes</th>
-      <th>A/B</th>
-      <th>Non-A/B</th>
+      <th width="33%">A/B</th>
+      <th width="33%">Non-A/B</th>
     </tr>
     <tr>
       <td>Bootloader</td>
@@ -907,34 +426,31 @@
   </tbody>
 </table>
 
-<p>Therefore, A/B updates require an increase of only 320 MiB in flash.
-Savings of 32MiB come from removing the recovery partition, while another
-100MiB is preserved by removing the cache partition.</p>
+<p>A/B updates require an increase of only 320 MiB in flash, with a savings of
+32MiB from removing the recovery partition and another 100MiB preserved by
+removing the cache partition. This balances the cost of the B partitions for
+the bootloader, the boot partition, and the radio partition. The vendor
+partition doubled in size (the vast majority of the size increase). Pixel's
+A/B system image is half the size of the original non-A/B system image.
+</p>
 
-<p>This roughly balanced out the cost of the B partitions for the bootloader, the
-boot partition, and the radio partition. The vendor partition doubled in size.
-(This was the vast majority of the size increase.) Pixel's A/B system image is
-half the size of the original non-A/B system image.</p>
-
-<p>So for Pixel, the A/B and non-A/B variants tested internally (only A/B
-shipped), the space used differed by only 320MiB. On a 32GiB device, this is
-just under 1%. For a 16GiB device this would be less than 2%, and for an 8GiB
-device almost 4% (assuming all three devices had the same system image).</p>
+<p>For the Pixel A/B and non-A/B variants tested internally (only A/B shipped),
+the space used differed by only 320MiB. On a 32GiB device, this is just under
+1%. For a 16GiB device this would be less than 2%, and for an 8GiB device almost
+4% (assuming all three devices had the same system image).</p>
 
 <h3>Why didn't you use SquashFS?</h3>
 
-<p>Android did experiment with SquashFS but wasn't able to achieve the
-performance desired for a high-end device. Android doesn't use or recommend
-SquashFS for handheld devices.</p>
+<p>We experimented with SquashFS but weren't able to achieve the performance
+desired for a high-end device. We don't use or recommend SquashFS for handheld
+devices.</p>
 
-<p>
-  SquashFS provided about 50% size savings on the system partition, but the
-  overwhelming majority of the files that compressed well were the precompiled
-  .odex files. Those files had very high compression ratios (approaching 80%),
-  but the compression ratio for the rest of the system partition was much
-  lower.</p>
-
-<p>And there were serious concerns about performance with SquashFS in N:</p>
+<p>More specifically, SquashFS provided about 50% size savings on the system
+partition, but the overwhelming majority of the files that compressed well were
+the precompiled .odex files. Those files had very high compression ratios
+(approaching 80%), but the compression ratio for the rest of the system
+partition was much lower. In addition, SquashFS in Android 7.0 raised the
+following performance concerns:</p>
 
 <ul>
   <li>Pixel has very fast flash compared to earlier devices but not a huge
@@ -943,32 +459,32 @@
   <li>I/O changes that perform well on an artificial benchmark run on an
     unloaded system sometimes don't work well on real-world use cases under
     real-world load (such as crypto on Nexus 6).</li>
-  <li>Benchmarking showed 85% regressions in some places. As SquashFS matures
-    and adds features to reduce CPU impact (such as a whitelist of
-    commonly-accessed files that shouldn't be compressed), the Android team
-    will continue to evaluate SquashFS and then offer recommendations to
-    device manufacturers.</li>
-</ul>
+  <li>Benchmarking showed 85% regressions in some places.</li>
+  </ul>
+
+<p>As SquashFS matures and adds features to reduce CPU impact (such as a
+whitelist of commonly-accessed files that shouldn't be compressed), we will
+continue to evaluate it and offer recommendations to device manufacturers.</p>
 
 <h3>How did you halve the size of the system partition without SquashFS?</h3>
 
 <p>Applications are stored in .apk files, which are actually ZIP archives. Each
 .apk file has inside it one or more .dex files containing portable Dalvik
-bytecode. An .odex file (optimized .dex) lives separately from the apk file
-and can contain machine code specific to the device. If an odex file is
+bytecode. An .odex file (optimized .dex) lives separately from the .apk file
+and can contain machine code specific to the device. If an .odex file is
 available, Android can run applications at ahead-of-time compiled speeds
 without having to wait for the code to be compiled each time the application is
-launched. An odex file isn't strictly necessary: Android can actually run the
+launched. An .odex file isn't strictly necessary: Android can actually run the
 .dex code directly via interpretation or Just-In-Time (JIT) compilation, but an
-odex file provides the best combination of launch speed and run-time speed if
+.odex file provides the best combination of launch speed and run-time speed if
 space is available.</p>
 
-<p>If you look at the installed-files.txt from a Nexus 6P N MR1 build, where
-the total system image size is 2628MiB (2755792836 bytes), the breakdown of the
-largest contributors to overall system image size by file type looks like
-this:</p>
+<p>Example: For the installed-files.txt from a Nexus 6P running Android 7.1 with
+a total system image size of 2628MiB (2755792836 bytes), the breakdown of the
+largest contributors to overall system image size by file type is as follows:
+</p>
 
-<table class="style0">
+<table>
 <tbody>
 <tr>
 <td>.odex</td>
@@ -1004,75 +520,72 @@
 </table>
 
 <p>These figures are similar for other devices too, so on Nexus/Pixel
-devices, odex files take up roughly half of the system partition. This meant
-that we could continue to use ext4 but write the odex files to the B partition
+devices, .odex files take up approximately half the system partition. This meant
+we could continue to use ext4 but write the .odex files to the B partition
 at the factory and then copy them to <code>/data</code> on first boot. The
-actual storage used on Marlin/Sailfish with ext4 A/B is identical to SquashFS
-A/B, because if we'd used SquashFS we would have shipped the preopted odex
-files on system_a instead of system_b.</p>
+actual storage used with ext4 A/B is identical to SquashFS A/B, because if we
+had used SquashFS we would have shipped the preopted .odex files on system_a
+instead of system_b.</p>
 
-<h3>Doesn't copying odex files to /data mean that the space saved on system
-  is lost on data?</h3>
+<h3>Doesn't copying .odex files to /data mean the space saved on /system is
+lost on /data?</h3>
 
-<p>Not exactly. On Pixel, most of the space taken by odex files are for apps.
-These typically exist on <code>/data</code> anyway. Since apps take Google
-Play updates, the apk and odex files on the system image are unused for
-most of the life of the device. So these files can be excluded entirely and
-replaced by small profile-driven odex files when the user actually uses each
-app and requiring no space for apps the user doesn't use. (This was discussed
-       at Google I/O 2016 in <a
-  href="https://www.youtube.com/watch?v=fwMM6g7wpQ8">The Evolution of Art</a>.</p>
+<p>Not exactly. On Pixel, most of the space taken by .odex files is for apps,
+which typically exist on <code>/data</code>. These apps take Google Play
+updates, so the .apk and .odex files on the system image are unused for most of
+the life of the device. Such files can be excluded entirely and replaced by
+small, profile-driven .odex files when the user actually uses each app (thus
+requiring no space for apps the user doesn't use). For details, refer to the
+Google I/O 2016 talk <a href="https://www.youtube.com/watch?v=fwMM6g7wpQ8">The
+Evolution of Art</a>.</p>
 
-<p>These are the key reasons why comparison is difficult:</p>
+<p>The comparison is difficult for a few key reasons:</p>
 <ul>
-  <li>Apps updated by Google Play have always had their odex files on <code>/data</code> as soon as they receive their first update.</li>
-<li>Apps that the user doesn't run don't need an odex file at all.</li>
-<li>Profile-driven compilation generates smaller odex files than ahead-of-time
-  compilation (because the former optimizes only performance-critical
-  code).</li>
+<li>Apps updated by Google Play have always had their .odex files on
+<code>/data</code> as soon as they receive their first update.</li>
+<li>Apps the user doesn't run don't need an .odex file at all.</li>
+<li>Profile-driven compilation generates smaller .odex files than ahead-of-time
+compilation (because the former optimizes only performance-critical code).</li>
 </ul>
 
-<p>The <a href="/devices/tech/dalvik/configure.html">Configuring ART</a>
-documentation explains the tuning options available to the OEM.</p>
+<p>For details on the tuning options available to OEMs, see
+<a href="/devices/tech/dalvik/configure.html">Configuring ART</a>.</p>
 
-<h3>Aren't there two copies of the odex files on /data?</h3>
+<h3>Aren't there two copies of the .odex files on /data?</h3>
 
-<p>It's a little more complicated than that...<br>
-After the new system image has been written, the new version of dex2oat is run
-against the new dex files to generate the new odex files. This happens while
-the old system is still running, and so the old and new odex files are both on
-<code>/data</code> at the same time.</p>
+<p>It's a little more complicated ... After the new system image has been
+written, the new version of dex2oat is run against the new .dex files to
+generate the new .odex files. This occurs while the old system is still running,
+so the old and new .odex files are both on <code>/data</code> at the same time.
+</p>
 
-<p>The code in OtaDexoptService (<code><a
-          href="https://android.googlesource.com/platform/frameworks/base/+/nougat-mr1-release/services/core/java/com/android/server/pm/OtaDexoptService.java#200">frameworks/base/+/nougat-mr1-release/services/core/java/com/android/server/pm/OtaDexoptService.java#200</a></code>)
+<p>The code in OtaDexoptService
+(<code><a href="https://android.googlesource.com/platform/frameworks/base/+/nougat-mr1-release/services/core/java/com/android/server/pm/OtaDexoptService.java#200" class="external">frameworks/base/+/nougat-mr1-release/services/core/java/com/android/server/pm/OtaDexoptService.java#200</a></code>)
 calls <code>getAvailableSpace</code> before optimizing each package to avoid
 over-filling <code>/data</code>. Note that <em>available</em> here is still
 conservative: it's the amount of space left <em>before</em> hitting the usual
 system low space threshold (measured as both a percentage and a byte count). So
-if <code>/data</code> is full, there won't be two copies of every odex file.<br>
-The same code also has a BULK_DELETE_THRESHOLD: if the device gets that close
-to filling the available space (as just described), the odex files belonging to
+if <code>/data</code> is full, there won't be two copies of every .odex file.
+The same code also has a BULK_DELETE_THRESHOLD: If the device gets that close
+to filling the available space (as just described), the .odex files belonging to
 apps that aren't used are removed. That's another case without two copies of
-every odex file.</p>
+every .odex file.</p>
 
-<p>In the worst case where <code>/data</code> is completely full, the update waits
-until the device has rebooted into the new system and no longer need the old
-system's odex files.</p>
-
-<p>The PackageManager handles this: (<code><a
-          href="https://android.googlesource.com/platform/frameworks/base/+/nougat-mr1-release/services/core/java/com/android/server/pm/PackageManagerService.java#7215">frameworks/base/+/nougat-mr1-release/services/core/java/com/android/server/pm/PackageManagerService.java#7215</a></code>).</p>
-
-<p>Once the new system has successfully booted, <code>installd</code> (<code><a
-          href="https://android.googlesource.com/platform/frameworks/native/+/nougat-mr1-release/cmds/installd/commands.cpp#2192">frameworks/native/+/nougat-mr1-release/cmds/installd/commands.cpp#2192</a></code>)
-can remove the odex files that were used by the old system, returning the
+<p>In the worst case where <code>/data</code> is completely full, the update
+waits until the device has rebooted into the new system and no longer needs the
+old system's .odex files. The PackageManager handles this:
+(<code><a href="https://android.googlesource.com/platform/frameworks/base/+/nougat-mr1-release/services/core/java/com/android/server/pm/PackageManagerService.java#7215" class="external">frameworks/base/+/nougat-mr1-release/services/core/java/com/android/server/pm/PackageManagerService.java#7215</a></code>). After the new system has
+successfully booted, <code>installd</code>
+(<code><a href="https://android.googlesource.com/platform/frameworks/native/+/nougat-mr1-release/cmds/installd/commands.cpp#2192" class="external">frameworks/native/+/nougat-mr1-release/cmds/installd/commands.cpp#2192</a></code>)
+can remove the .odex files that were used by the old system, returning the
 device back to the steady state where there's only one copy.</p>
 
-<p>So to return to the original question: it is possible that
-<code>/data</code> contains two copies of all the odex files, but (a) only
-temporarily and (b) only if you had plenty of free space on <code>/data</code>
-anyway. Except during an update, there's only one copy. And as part of ART's
-general robustness features, it will never fill <code>/data</code> with odex
-files anyway (because that would be a problem on a non-A/B system too).</p>
+<p>So, while it is possible that <code>/data</code> contains two copies of all
+the .odex files, (a) this is temporary and (b) only occurs if you had plenty of
+free space on <code>/data</code> anyway. Except during an update, there's only
+one copy. And as part of ART's general robustness features, it will never fill
+<code>/data</code> with .odex files anyway (because that would be a problem on a
+non-A/B system too).</p>
 
 <h3>Doesn't all this writing/copying increase flash wear?</h3>
 
@@ -1083,31 +596,30 @@
 
 <h3>Does flashing two system partitions increase factory flashing time?</h3>
 
-<p>Pixel didn't increase in system image size (it merely divided the space
-across two partitions). So no, factory flashing time did not grow.</p>
+<p>No. Pixel didn't increase in system image size (it merely divided the space
+across two partitions).</p>
 
-<h3>Doesn't keeping odex files on B make rebooting after factory data reset slow?</h3>
+<h3>Doesn't keeping .odex files on B make rebooting after factory data reset
+slow?</h3>
 
-<p>Yes. If you've actually used a device and taken an OTA and then perform a
-factory data reset, the first reboot will be slower than it would otherwise be
-(taking 1m40s vs 40s on a Pixel XL just tested) because the odex files will
-have been lost from B after the first OTA and so can't be copied to
-<code>/data</code>. That's the trade-off.</p>
+<p>Yes. If you've actually used a device, taken an OTA, and performed a factory
+data reset, the first reboot will be slower than it would otherwise be (1m40s vs
+40s on a Pixel XL) because the .odex files will have been lost from B after the
+first OTA and so can't be copied to <code>/data</code>. That's the trade-off.</p>
 
-<p>Factory data reset should be a rare operation - certainly
-compared to regular boot - so the time taken is less important. (This doesn't
-affect users or reviewers who get their device from the factory, because in
-that case the B partition is available.) Thanks to the JIT compiler, we also
-don't need to recompile <em>everything</em>, so it's not as bad as you might
-think. It's also possible to mark apps as requiring ahead-of-time compilation
-using <code>coreApp="true"</code> in the manifest: (<code><a
-          href="https://android.googlesource.com/platform/frameworks/base/+/nougat-mr1-release/packages/SystemUI/AndroidManifest.xml#23">frameworks/base/+/nougat-mr1-release/packages/SystemUI/AndroidManifest.xml#23</a></code>)</p>
+<p>Factory data reset should be a rare operation when compared to regular boot
+so the time taken is less important. (This doesn't affect users or reviewers who
+get their device from the factory, because in that case the B partition is
+available.) Use of the JIT compiler means we don't need to recompile
+<em>everything</em>, so it's not as bad as you might think. It's also possible
+to mark apps as requiring ahead-of-time compilation using
+<code>coreApp="true"</code> in the manifest:
+(<code><a href="https://android.googlesource.com/platform/frameworks/base/+/nougat-mr1-release/packages/SystemUI/AndroidManifest.xml#23" class="external">frameworks/base/+/nougat-mr1-release/packages/SystemUI/AndroidManifest.xml#23</a></code>).
+This is currently used by <code>system_server</code> because it's not allowed to
+JIT for security reasons.</p>
 
-<p>This is currently used by system_server because it's not allowed to JIT for
-security reasons.</p>
-
-<h3>Doesn't keeping odex files on /data rather than /system make rebooting
-  after an OTA slow?</h3>
+<h3>Doesn't keeping .odex files on /data rather than /system make rebooting
+after an OTA slow?</h3>
 
 <p>No. As explained above, the new dex2oat is run while the old system image is
 still running to generate the files that will be needed by the new system. The
@@ -1117,13 +629,13 @@
 
 <p>32GiB works well as it was proven on Pixel, and 320MiB out of 16GiB means a
 reduction of 2%. Similarly, 320MiB out of 8GiB a reduction of 4%. Obviously
-A/B, would not be the recommended choice on devices with 4GiB, as the 320MiB
+A/B would not be the recommended choice on devices with 4GiB, as the 320MiB
 overhead is almost 10% of the total available space.</p>
 
 <h3>Does AVB2.0 require A/B OTAs?</h3>
 
-<p>No. Android <a href="/security/verifiedboot/">Verified Boot</a> has always required block-based
-updates, but not necessarily A/B updates.</p>
+<p>No. Android <a href="/security/verifiedboot/">Verified Boot</a> has always
+required block-based updates, but not necessarily A/B updates.</p>
 
 <h3>Do A/B OTAs require AVB2.0?</h3>
 
@@ -1141,18 +653,18 @@
 consider it to be the current system image.</p>
 
 <h3>If you're installing an update while the system is running, isn't that
-  slow?</h3>
+slow?</h3>
 
 <p>With non-A/B updates, the aim is to install the update as quickly as
 possible because the user is waiting and unable to use their device while the
 update is applied. With A/B updates, the opposite is true; because the user is
-still using their device, as little impact as possible is the goal, so the update
-is deliberately slow. Android also (via logic in the Java system update client, in
-Google’s case GmsCore, the core package provided by GMS) try to choose a time
-when the users aren't using their devices at all. The platform supports
-pausing/resuming the update, and the client can use that to pause the update if
-the user starts to use the device and resume it when the device is idle
-again.</p>
+still using their device, as little impact as possible is the goal, so the
+update is deliberately slow. Via logic in the Java system update client (which
+for Google is GmsCore, the core package provided by GMS), Android also attempts
+to choose a time when the users aren't using their devices at all. The platform
+supports pausing/resuming the update, and the client can use that to pause the
+update if the user starts to use the device and resume it when the device is
+idle again.</p>
 
 <p>There are two phases while taking an OTA, shown clearly in the UI as
 <em>Step 1 of 2</em> and <em>Step 2 of 2</em> under the progress bar. Step 1
@@ -1191,22 +703,18 @@
 
 <p>In Google's A/B implementation, the platform APIs and
 <code>update_engine</code> provide the mechanism while GmsCore provides the
-policy. That is, the platform knows <em>how</em> to apply an A/B update, and
-all that code is in AOSP (as mentioned above); but it's GmsCore that decides
+policy. That is, the platform knows <em>how</em> to apply an A/B update and all
+that code is in AOSP (as mentioned above); but it's GmsCore that decides
 <em>what</em> and <em>when</em> to apply.</p>
 
-<p>If you’re not using GmsCore, you can write your own replacement using the same
-platform APIs. The platform Java API for controlling <code>update_engine</code>
-is <code>android.os.UpdateEngine</code>:</p>
-<code><a class="external-link" target="_blank"
-                                href="https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/os/UpdateEngine.java">frameworks/base/core/java/android/os/UpdateEngine.java</a></code>
-
-<p>Callers can provide an <code>UpdateEngineCallback</code> to be notified of
-status updates:</p>
-<code><a class="external-link" target="_blank"
-                                href="https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/os/UpdateEngineCallback.java">frameworks/base/+/master/core/java/android/os/UpdateEngineCallback.java</a></code>
-
-<p>See the reference files for the core classes to use the interface.</p>
+<p>If you’re not using GmsCore, you can write your own replacement using the
+same platform APIs. The platform Java API for controlling
+<code>update_engine</code> is <code>android.os.UpdateEngine</code>:
+<code><a href="https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/os/UpdateEngine.java" class="external-link">frameworks/base/core/java/android/os/UpdateEngine.java</a></code>.
+Callers can provide an <code>UpdateEngineCallback</code> to be notified of status
+updates:
+<code><a href="https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/os/UpdateEngineCallback.java" class="external-link">frameworks/base/+/master/core/java/android/os/UpdateEngineCallback.java</a></code>.
+Refer to the reference files for the core classes to use the interface.</p>
 
 <h3>Which systems on a chip (SoCs) support A/B?</h3>
 
@@ -1215,8 +723,8 @@
 <tbody>
 <tr>
 <td></td>
-<td><strong>N Release</strong></td>
-<td><strong>OC Release</strong></td>
+<td><strong>Android 7.x Release</strong></td>
+<td><strong>Android 8.x Release</strong></td>
 </tr>
 <tr>
 <td><strong>Qualcomm</strong></td>
@@ -1231,8 +739,8 @@
 </tbody>
 </table>
 
-<p>Please check with your SoC contacts for more details on their schedules. If
-there are SoCs not listed here, please reach out your SoC directly. </p>
+<p>For details on schedules, check with your SoC contacts. For SoCs not listed
+above, reach out to your SoC directly.</p>
 
   </body>
 </html>
diff --git a/en/devices/tech/ota/images/ab-updates-state-machine.png b/en/devices/tech/ota/images/ab-updates-state-machine.png
index a125efd..04b7952 100644
--- a/en/devices/tech/ota/images/ab-updates-state-machine.png
+++ b/en/devices/tech/ota/images/ab-updates-state-machine.png
Binary files differ
diff --git a/en/devices/tech/ota/reduce_size.html b/en/devices/tech/ota/reduce_size.html
index 227c40d..1695762 100644
--- a/en/devices/tech/ota/reduce_size.html
+++ b/en/devices/tech/ota/reduce_size.html
@@ -22,154 +22,183 @@
   -->
 
 
-<p>This page describes build changes added to AOSP to reduce unnecessary file changes between
-  builds. Device implementers who maintain their own build system can use this information as a
-  guide for reducing over-the-air (OTA) update size.</p>
+<p>This page describes build changes added to AOSP to reduce unnecessary file
+changes between builds. Device implementers who maintain their own build system
+can use this information as a guide for reducing over-the-air (OTA) update size.
+</p>
 
-<p>Android OTAs occasionally contain changed files that do not correspond to code changes but are
-  instead artifacts of the build system. This can occurs when the same code built at different
-  times, from different directories, or on different machines, produces a large number of changed
-  files. These excess files not only increase the size of an OTA, but make it difficult to
-  determine which code is changed in the OTA.</p>
+<p>Android OTAs occasionally contain changed files that do not correspond to
+code changes but are instead artifacts of the build system. This can occur when
+the same code built at different times, from different directories, or on
+different machines produces a large number of changed files. These excess files
+not only increase the size of an OTA, but make it difficult to determine which
+code is changed in the OTA.</p>
 
-<p>To make the contents of an OTA more transparent, AOSP includes build system changes designed to
-  reduce OTA size by eliminating unnecessary file changes between builds. The aim is to reduce
-  the size of OTAs to include only the files that relate to the patches contained in the OTA. AOSP
-  also includes a <a href="#the_build_diff_tool">build diff tool</a> that filters out common
-  build-related file changes and provides a cleaner build file diff.</p>
+<p>To make the contents of an OTA more transparent, AOSP includes build system
+changes designed to reduce OTA size by eliminating unnecessary file changes
+between builds. The aim is to reduce the size of OTAs to include only the files
+that relate to the patches contained in the OTA. AOSP also includes a
+<a href="#the_build_diff_tool">build diff tool</a>, which filters out common
+build-related file changes and provides a cleaner build file diff, and a
+<a href="#block-mapping-tool">block mapping tool</a>, which helps you keep block
+allocation consistent.</p>
 
-<p>The build system can create unnecessary file diffs in several ways. The following sections
-  discuss some of these issues and solutions, providing examples of fixes in AOSP when possible).</p>
+<p>The build system can create unnecessary file diffs in several ways. The
+following sections discuss some of these issues and solutions, providing
+examples of fixes in AOSP when possible.</p>
 
 <h2 id=file_order>File order</h2>
 
-<p><strong>Problem</strong>: Filesystems don’t guarantee a file order when asked for a list of files
-  in a directory, though it’s commonly the same for the same checkout. Tools such as <code>ls</code>
-  sort the results by default, but the wildcard function used by commands such as <code>find</code>
-  and <code>make</code> do not. Before using these tools, you must sort the outputs.</p>
+<p><strong>Problem</strong>: Filesystems don’t guarantee a file order when asked
+for a list of files in a directory, though it’s commonly the same for the same
+checkout. Tools such as <code>ls</code> sort the results by default, but the
+wildcard function used by commands such as <code>find</code> and
+<code>make</code> do not. Before using these tools, you must sort the outputs.
+</p>
 
-<p><strong>Solution</strong>: Users of tools such as <code>find</code> and <code>make</code> with
-  wildcard must sort the output of these commands before using them. Use of
-  <code>$(wildcard )</code> or <code>$(shell find )</code> in Android.mk files should also be
-  sorted. Some tools, such as Java, do sort inputs so verify sorting is necessary.</p>
+<p><strong>Solution</strong>: Users of tools such as <code>find</code> and
+<code>make</code> with wildcard must sort the output of these commands before
+using them. Use of <code>$(wildcard)</code> or <code>$(shell find)</code> in
+<code>Android.mk</code> files should also be sorted. Some tools, such as Java,
+do sort inputs so first verify sorting is necessary.</p>
 
-<p><strong>Examples:</strong> Many instances were fixed in the core build system using the builtin
-  <code>all-*-files-under</code> macro, which includes <code>all-cpp-files-under</code> (as several
-  definitions were spread out in other makefiles). For details, refer to the following CLs:</p>
+<p><strong>Examples:</strong> Many instances were fixed in the core build system
+using the builtin <code>all-*-files-under</code> macro, which includes
+<code>all-cpp-files-under</code> (as several definitions were spread out in
+other makefiles). For details, refer to the following CLs:</p>
 
 <ul>
-  <li><a href="https://android.googlesource.com/platform/build/+/4d66adfd0e6d599d8502007e4ea9aaf82e95569f">https://android.googlesource.com/platform/build/+/4d66adfd0e6d599d8502007e4ea9aaf82e95569f</a>
-  <li><a href="https://android.googlesource.com/platform/build/+/379f9f9cec4fe1c66b6d60a6c19fecb81b9eb410">https://android.googlesource.com/platform/build/+/379f9f9cec4fe1c66b6d60a6c19fecb81b9eb410</a>
-  <li><a href="https://android.googlesource.com/platform/build/+/7c3e3f8314eec2c053012dd97d2ae649ebeb5653">https://android.googlesource.com/platform/build/+/7c3e3f8314eec2c053012dd97d2ae649ebeb5653</a>
-  <li><a href="https://android.googlesource.com/platform/build/+/5c64b4e81c1331cab56d8a8c201f26bb263b630c">https://android.googlesource.com/platform/build/+/5c64b4e81c1331cab56d8a8c201f26bb263b630c</a>
+  <li><a href="https://android.googlesource.com/platform/build/+/4d66adfd0e6d599d8502007e4ea9aaf82e95569f" class="external">https://android.googlesource.com/platform/build/+/4d66adfd0e6d599d8502007e4ea9aaf82e95569f</a>
+  <li><a href="https://android.googlesource.com/platform/build/+/379f9f9cec4fe1c66b6d60a6c19fecb81b9eb410" class="external">https://android.googlesource.com/platform/build/+/379f9f9cec4fe1c66b6d60a6c19fecb81b9eb410</a>
+  <li><a href="https://android.googlesource.com/platform/build/+/7c3e3f8314eec2c053012dd97d2ae649ebeb5653" class="external">https://android.googlesource.com/platform/build/+/7c3e3f8314eec2c053012dd97d2ae649ebeb5653</a>
+  <li><a href="https://android.googlesource.com/platform/build/+/5c64b4e81c1331cab56d8a8c201f26bb263b630c" class="external">https://android.googlesource.com/platform/build/+/5c64b4e81c1331cab56d8a8c201f26bb263b630c</a>
 </ul>
 
 <h2 id=build_directory>Build directory</h2>
 
-<p><strong>Problem:</strong> Changing the directory in which things are built can cause the binaries
-  to be different. Most paths in the Android build are relative paths so <code>__FILE__</code> in
-  C/C++ isn’t a problem. However, the debug symbols encode the full pathname by default, and the
-  <code>.note.gnu.build-id</code> is generated from hashing the pre-stripped binary, so it will
-  change if the debug symbols change.</p>
+<p><strong>Problem:</strong> Changing the directory in which things are built
+can cause the binaries to be different. Most paths in the Android build are
+relative paths so <code>__FILE__</code> in C/C++ isn’t a problem. However, the
+debug symbols encode the full pathname by default, and the
+<code>.note.gnu.build-id</code> is generated from hashing the pre-stripped
+binary, so it will change if the debug symbols change.</p>
 
-<p><strong>Solution:</strong> AOSP now makes debug paths relative. For details, refer to CL:
-  <a href="https://android.googlesource.com/platform/build/+/6a66a887baadc9eb3d0d60e26f748b8453e27a02">https://android.googlesource.com/platform/build/+/6a66a887baadc9eb3d0d60e26f748b8453e27a02</a>.</p>
+<p><strong>Solution:</strong> AOSP now makes debug paths relative. For details,
+refer to CL: <a href="https://android.googlesource.com/platform/build/+/6a66a887baadc9eb3d0d60e26f748b8453e27a02" class="external">https://android.googlesource.com/platform/build/+/6a66a887baadc9eb3d0d60e26f748b8453e27a02</a>.
+</p>
 
 <h2 id=timestamps>Timestamps</h2>
 
-<p><strong>Problem:</strong> Timestamps in the build output result in unnecessary file changes. This
-  is likely to happen in the following locations:</p>
+<p><strong>Problem:</strong> Timestamps in the build output result in
+unnecessary file changes. This is likely to happen in the following
+locations:</p>
 
 <ul>
-  <li><code> __DATE__/__TIME__/__TIMESTAMP__ </code> macros in C or C++ code.</li>
+  <li><code>__DATE__/__TIME__/__TIMESTAMP__</code> macros in C or C++ code.</li>
   <li>Timestamps embedded in zip-based archives.</li>
 </ul>
 
-<p><strong>Solutions/Examples:</strong> To remove timestamps from the build output, use the
-  instructions in the sections below.</p>
+<p><strong>Solutions/Examples:</strong> To remove timestamps from the build
+output, use the instructions in the sections below.</p>
 
 <h3 id=date_time_timestamp_in_c_c>__DATE__/__TIME__/__TIMESTAMP__ in C/C++</h3>
 
-<p>These macros always produce different outputs for different builds, so they shouldn’t be used.
-  Here are a few options on how to eliminate these macros:</p>
+<p>These macros always produce different outputs for different builds, so they
+shouldn’t be used. Here are a few options on how to eliminate these macros:</p>
 
 <ul>
   <li>Just remove them, they often aren’t necessary. For an example, refer to
-    <a href="https://android.googlesource.com/platform/system/core/+/30622bbb209db187f6851e4cf0cdaa147c2fca9f">https://android.googlesource.com/platform/system/core/+/30622bbb209db187f6851e4cf0cdaa147c2fca9f</a></li>
-  <li>To uniquely identify the running binary, read the build-id from the ELF header.</li>
-  <li>To know when the OS was built, read the <code>ro.build.date</code> (should work for everything
-    except incremental builds, which may not update this date). For an example, refer to
-    <a href="https://android.googlesource.com/platform/external/libchrome/+/8b7977eccc94f6b3a3896cd13b4aeacbfa1e0f84">https://android.googlesource.com/platform/external/libchrome/+/8b7977eccc94f6b3a3896cd13b4aeacbfa1e0f84</a></li>
+  <a href="https://android.googlesource.com/platform/system/core/+/30622bbb209db187f6851e4cf0cdaa147c2fca9f" class="external">https://android.googlesource.com/platform/system/core/+/30622bbb209db187f6851e4cf0cdaa147c2fca9f</a>.</li>
+  <li>To uniquely identify the running binary, read the build-id from the ELF
+  header.</li>
+  <li>To know when the OS was built, read the <code>ro.build.date</code> (should
+  work for everything except incremental builds, which may not update this
+  date). For an example, refer to
+  <a href="https://android.googlesource.com/platform/external/libchrome/+/8b7977eccc94f6b3a3896cd13b4aeacbfa1e0f84" class="external">https://android.googlesource.com/platform/external/libchrome/+/8b7977eccc94f6b3a3896cd13b4aeacbfa1e0f84</a>.</li>
 </ul>
 
-    <p class="note"><strong>Note:</strong>We turned on <code>-Werror=date-time</code> so using
-      timestamps is a build error.</p>
+<aside class="note"><strong>Note:</strong> Android 7.0 turned on
+<code>-Werror=date-time</code>, so using timestamps is a build error.</aside>
 
-<h3 id=embedded_timestamps_in_zip-based_archives_zip_jar>Embedded timestamps in archives (zip, jar)</h3>
+<h3 id=embedded_timestamps_in_zip-based_archives_zip_jar>Embedded timestamps in
+archives (zip, jar)</h3>
 
-<p>We fixed the problem of embedded timestamps in zip archives by adding <code>-X</code> to all uses
-  of the <code>zip</code> command, so the UID/GID of the builder and the extended Unix timestamp are
-  not embedded in the zip file.</p>
+<p>Android 7.0 fixed the problem of embedded timestamps in zip archives by
+adding <code>-X</code> to all uses of the <code>zip</code> command, so the
+UID/GID of the builder and the extended Unix timestamp are not embedded in the
+zip file.</p>
 
-<p>A new tool, <code>ziptime</code> (located in <code>
-  <a href="https://android.googlesource.com/platform/build/+/master/tools/ziptime/">/platform/build/+/master/tools/ziptime/</a></code>)
-  resets the normal timestamps in the zip headers. For details, refer to the
-  <a href="https://android.googlesource.com/platform/build/+/master/tools/ziptime/README.txt">README
-    file</a>.</p>
+<p>A new tool, <code>ziptime</code> (located in
+<code><a href="https://android.googlesource.com/platform/build/+/master/tools/ziptime/" class="external">/platform/build/+/master/tools/ziptime/</a></code>)
+resets the normal timestamps in the zip headers. For details, refer to the
+<a href="https://android.googlesource.com/platform/build/+/master/tools/ziptime/README.txt" class="external">README
+file</a>.</p>
 
-<p>The <code>signapk</code> tool sets timestamps for the APK files that may vary depending on the
-  server timezone. For details, refer to the CL
-  <a href="https://android.googlesource.com/platform/build/+/6c41036bcf35fe39162b50d27533f0f3bfab3028">https://android.googlesource.com/platform/build/+/6c41036bcf35fe39162b50d27533f0f3bfab3028</a>.</p>
+<p>The <code>signapk</code> tool sets timestamps for the APK files that may vary
+depending on the server timezone. For details, refer to the CL
+<a href="https://android.googlesource.com/platform/build/+/6c41036bcf35fe39162b50d27533f0f3bfab3028" class="external">https://android.googlesource.com/platform/build/+/6c41036bcf35fe39162b50d27533f0f3bfab3028</a>.
+</p>
 
 <h2 id=version_strings>Version strings</h2>
 
-<p><strong>Problem:</strong> APK version strings often had the BUILD_NUMBER appended to the
-  hardcoded version. Even if nothing else changed in the APK, the APK would still be different.</p>
+<p><strong>Problem:</strong> APK version strings often had the
+<code>BUILD_NUMBER</code> appended to the hardcoded version. Even if nothing
+else changed in the APK, the APK would still be different.</p>
 
-<p><strong>Solution:</strong> Remove the build number from the APK version string.</p>
+<p><strong>Solution:</strong> Remove the build number from the APK version
+string.</p>
 
 <p><strong>Examples:</strong></p>
 
 <ul>
-  <li><a href="https://android.googlesource.com/platform/packages/apps/Camera2/+/5e0f4cf699a4c7c95e2c38ae3babe6f20c258d27">https://android.googlesource.com/platform/packages/apps/Camera2/+/5e0f4cf699a4c7c95e2c38ae3babe6f20c258d27</a></li>
-  <li><a href="https://android.googlesource.com/platform/build/+/d75d893da8f97a5c7781142aaa7a16cf1dbb669c">https://android.googlesource.com/platform/build/+/d75d893da8f97a5c7781142aaa7a16cf1dbb669c</a></li>
+  <li><a href="https://android.googlesource.com/platform/packages/apps/Camera2/+/5e0f4cf699a4c7c95e2c38ae3babe6f20c258d27" class="external">https://android.googlesource.com/platform/packages/apps/Camera2/+/5e0f4cf699a4c7c95e2c38ae3babe6f20c258d27</a></li>
+  <li><a href="https://android.googlesource.com/platform/build/+/d75d893da8f97a5c7781142aaa7a16cf1dbb669c" class="external">https://android.googlesource.com/platform/build/+/d75d893da8f97a5c7781142aaa7a16cf1dbb669c</a></li>
 </ul>
 
 <h2 id=consistent_build_tools>Consistent build tools</h2>
 
-<p><strong>Problem:</strong> Tools that generate installed files must be consistent (the same input
-  should always produce the same output).</p>
+<p><strong>Problem:</strong> Tools that generate installed files must be
+consistent (the same input should always produce the same output).</p>
 
-<p><strong>Solutions/Examples:</strong> Changes were required in the following build tools:</p>
+<p><strong>Solutions/Examples:</strong> Changes were required in the following
+build tools:</p>
 
 <ul>
-  <li><strong>NOTICE file creator</strong>. The NOTICE file creator needed the changes. Refer to CL:
-    <a href="https://android.googlesource.com/platform/build/+/8ae4984c2c8009e7a08e2a76b1762c2837ad4f64">https://android.googlesource.com/platform/build/+/8ae4984c2c8009e7a08e2a76b1762c2837ad4f64</a></li>
-  <li><strong>Java Android Compiler Kit (Jack)</strong>. The Jack toolchain required an update to
-    handle an occasional change in generated constructor ordering. Refer to CL:
-    <a href="https://android.googlesource.com/toolchain/jack/+/056a5425b3ef57935206c19ecb198a89221ca64b">https://android.googlesource.com/toolchain/jack/+/056a5425b3ef57935206c19ecb198a89221ca64b</a></li>
-  <li><strong>ART AOT compiler (dex2oat)</strong>. The ART compiler binary required an update to
-    create a deterministic image. Refer to CL:
-    <a href="https://android.googlesource.com/platform/art/+/ace0dc1dd5480ad458e622085e51583653853fb9">https://android.googlesource.com/platform/art/+/ace0dc1dd5480ad458e622085e51583653853fb9</a></li>
-  <li><strong>The libpac.so file (V8)</strong>Every build creates a different
-    <code>/system/lib/libpac.so</code> file because the V8 snapshot changes for each build. The
-    solution is to remove the snapshot. Refer to CL:
-    <a href="https://android.googlesource.com/platform/external/v8/+/e537f38c36600fd0f3026adba6b3f4cbcee1fb29">https://android.googlesource.com/platform/external/v8/+/e537f38c36600fd0f3026adba6b3f4cbcee1fb29</a></li>
-  <li><strong>Application pre-dexopt’d (.odex) files</strong>. The pre-dexopt’d (.odex) files
-    contained uninitialized padding on 64-bit systems. Refer to CL:
-    <a href="https://android.googlesource.com/platform/art/+/34ed3afc41820c72a3c0ab9770be66b6668aa029">https://android.googlesource.com/platform/art/+/34ed3afc41820c72a3c0ab9770be66b6668aa029</a></li>
+  <li><strong>NOTICE file creator</strong>. The NOTICE file creator needed the
+  changes. Refer to CL:
+  <a href="https://android.googlesource.com/platform/build/+/8ae4984c2c8009e7a08e2a76b1762c2837ad4f64" class="external">https://android.googlesource.com/platform/build/+/8ae4984c2c8009e7a08e2a76b1762c2837ad4f64</a>.
+  </li>
+  <li><strong>Java Android Compiler Kit (Jack)</strong>. The Jack toolchain
+  required an update to handle an occasional change in generated constructor
+  ordering. Refer to CL:
+  <a href="https://android.googlesource.com/toolchain/jack/+/056a5425b3ef57935206c19ecb198a89221ca64b" class="external">https://android.googlesource.com/toolchain/jack/+/056a5425b3ef57935206c19ecb198a89221ca64b</a>.
+  </li>
+  <li><strong>ART AOT compiler (dex2oat)</strong>. The ART compiler binary
+  required an update to create a deterministic image. Refer to CL:
+  <a href="https://android.googlesource.com/platform/art/+/ace0dc1dd5480ad458e622085e51583653853fb9" class="external">https://android.googlesource.com/platform/art/+/ace0dc1dd5480ad458e622085e51583653853fb9</a>.
+  </li>
+  <li><strong>The libpac.so file (V8)</strong>. Every build creates a different
+  <code>/system/lib/libpac.so</code> file because the V8 snapshot changes for
+  each build. The solution is to remove the snapshot. Refer to CL:
+  <a href="https://android.googlesource.com/platform/external/v8/+/e537f38c36600fd0f3026adba6b3f4cbcee1fb29" class="external">https://android.googlesource.com/platform/external/v8/+/e537f38c36600fd0f3026adba6b3f4cbcee1fb29</a>.
+  </li>
+  <li><strong>Application pre-dexopt’d (.odex) files</strong>. The pre-dexopt’d
+  (.odex) files contained uninitialized padding on 64-bit systems. Refer to CL:
+  <a href="https://android.googlesource.com/platform/art/+/34ed3afc41820c72a3c0ab9770be66b6668aa029" class="external">https://android.googlesource.com/platform/art/+/34ed3afc41820c72a3c0ab9770be66b6668aa029</a>.
+  </li>
 </ul>
 
 <h2 id=the_build_diff_tool>Using the build diff tool</h2>
 
-<p>For cases where it is not possible to eliminate build-related file changes, we supply a build
-  diff tool,
-  <code><a href="https://android.googlesource.com/platform/build/+/master/tools/releasetools/target_files_diff.py">target_files_diff.py</a></code>
-  for use in comparing two file packages. This tool performs a recursive diff between two builds,
-  excluding common build-related file changes, such as:</p>
+<p>For cases where it is not possible to eliminate build-related file changes,
+AOSP includes a build diff tool,
+<code><a href="https://android.googlesource.com/platform/build/+/master/tools/releasetools/target_files_diff.py" class="external">target_files_diff.py</a></code>
+for use in comparing two file packages. This tool performs a recursive diff
+between two builds, excluding common build-related file changes, such as:</p>
 
 <ul>
-  <li>Expected changes in the build output (for example, due to a build number change).</li>
+  <li>Expected changes in the build output (for example, due to a build number
+  change).</li>
   <li>Changes due to known issues in the current build system.</li>
 </ul>
 
@@ -179,8 +208,34 @@
 target_files_diff.py dir1 dir2
 </pre>
 
-<p><code>dir1</code> and <code>dir2</code> are base directories that contain the extracted target
-  files for each build.</p>
+<p><code>dir1</code> and <code>dir2</code> are base directories that contain the
+extracted target files for each build.</p>
+
+<h2 id=block-mapping-tool>Keeping block allocation consistent</h2>
+<p>In an non-A/B OTA, one of the factors that contribute to the time is block
+moves. For a given file, although its contents remain the same between two
+builds, the actual blocks that hold the data might have changed. As a result,
+the updater performs unnecessarily I/O to move the blocks around during an OTA.
+</p>
+
+<p>To address this issue, in Android 7.0 we extended the
+<code>make_ext4fs</code> tool that tries to keep the block allocation consistent
+across builds. <code>make_ext4fs</code> accepts an optional
+<code>-d base_fs</code> flag that attempts to allocate files to the same blocks
+when generating an <code>ext4</code> image. You can extract the block mapping
+files (i.e. the <code>base_fs</code> map files) from a previous build's target
+files zip file (<code>IMAGES/system.map</code> and
+<code>IMAGES/vendor.map</code>). The <code>base_fs</code> files can then be
+checked in and specified via <code>PRODUCT_SYSTEM_BASE_FS_PATH</code> and
+<code>PRODUCT_VENDOR_BASE_FS_PATH</code>. For example,</p>
+
+<pre class="devsite-click-to-copy">
+  PRODUCT_SYSTEM_BASE_FS_PATH := path/to/base_fs_files/base_system.map
+  PRODUCT_VENDOR_BASE_FS_PATH := path/to/base_fs_files/base_vendor.map
+</pre>
+
+<p>While this doesn’t help reduce the overall OTA package size, it does
+improve OTA performance by reducing the amount of I/O.</p>
 
   </body>
 </html>
diff --git a/en/security/_toc.yaml b/en/security/_toc.yaml
index f7dbdf2..6a09aa5 100644
--- a/en/security/_toc.yaml
+++ b/en/security/_toc.yaml
@@ -37,6 +37,8 @@
     path: /security/advisory/
   - title: 2017 Bulletins
     section:
+    - title: September
+      path: /security/bulletin/2017-09-01
     - title: August
       path: /security/bulletin/2017-08-01
     - title: July
diff --git a/en/security/authentication/index.html b/en/security/authentication/index.html
index 73da7ac..27eed8a 100644
--- a/en/security/authentication/index.html
+++ b/en/security/authentication/index.html
@@ -42,7 +42,7 @@
 state with the keystore service via an authenticated channel.</p>
 
 <ul>
-  <li><strong>The <a href="/security/keystore/index.html">hardware-backed Keystore</a>.</strong>
+  <li>The <strong><a href="/security/keystore/index.html">hardware-backed Keystore</a>.</strong>
   Cryptographic services, including hardware-backed cryptography for key storage,
   which might include a Trusted Execution Environment (TEE).</li>
   <li><strong><a href="gatekeeper.html">Gatekeeper</a>.</strong> Components for PIN, pattern, and password authentication.</li>
diff --git a/en/security/bulletin/2017-09-01.html b/en/security/bulletin/2017-09-01.html
new file mode 100644
index 0000000..3a0daf4
--- /dev/null
+++ b/en/security/bulletin/2017-09-01.html
@@ -0,0 +1,1384 @@
+<html devsite>
+  <head>
+    <title>Android Security Bulletin—September 2017</title>
+    <meta name="project_path" value="/_project.yaml" />
+    <meta name="book_path" value="/_book.yaml" />
+  </head>
+  <body>
+  <!--
+      Copyright 2017 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
+
+          //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><em>Published September 5, 2017 | Updated September 13, 2017</em></p>
+
+<p>The Android Security Bulletin contains details of security vulnerabilities
+affecting Android devices. Security patch levels of September 05, 2017 or later
+address all of these issues. Refer to the <a
+href="https://support.google.com/pixelphone/answer/4457705#pixel_phones&nexus_devices">Pixel
+and Nexus update schedule</a> to learn how to check a device's security patch
+level.</p>
+
+<p>Partners were notified of the issues described in the bulletin at least a month
+ago. Source code patches for these issues have been released to the Android Open
+Source Project (AOSP) repository and linked from this bulletin. This bulletin
+also includes links to patches outside of AOSP.</p>
+
+<p>The most severe of these issues is a critical severity vulnerability in media
+framework that could enable a remote attacker using a specially crafted file to
+execute arbitrary code within the context of a privileged process. The
+<a href="/security/overview/updates-resources.html#severity">severity
+assessment</a> is based on the effect that exploiting the vulnerability would
+possibly have on an affected device, assuming the platform and service
+mitigations are turned off for development purposes or if successfully bypassed.</p>
+
+<p>We have had no reports of active customer exploitation or abuse of these newly
+reported issues. Refer to the
+<a href="#mitigations">Android and Google Play Protect mitigations</a> section
+for details on the <a href="/security/enhancements/index.html">Android
+security platform protections</a> and Google Play Protect, which improve the
+security of the Android platform.</p>
+
+<p>We encourage all customers to accept these updates to their devices.</p>
+
+<p class="note"><strong>Note:</strong> Information on the latest over-the-air update (OTA) and
+firmware images for Google devices is available in the
+<a href="#google-device-updates">Google device updates</a> section.</p>
+
+<h2 id="announcements">Announcements</h2>
+<ul>
+  <li>This bulletin has two security patch level strings to provide Android
+  partners with the flexibility to more quickly fix a subset of vulnerabilities
+  that are similar across all Android devices. See
+  <a href="#questions">Common questions and answers</a> for additional information:
+    <ul>
+     <li><strong>2017-09-01</strong>: Partial security patch level string. This
+    security patch level string indicates that all issues associated with 2017-09-01
+    (and all previous security patch level strings) are addressed.</li>
+     <li><strong>2017-09-05</strong>: Complete security patch level string. This
+    security patch level string indicates that all issues associated with 2017-09-01
+    and 2017-09-05 (and all previous security patch level strings) are
+    addressed.</li>
+    </ul>
+  </li>
+</ul>
+
+<h2 id="mitigations">Android and Google service mitigations</h2>
+<p>This is a summary of the mitigations provided by the
+<a href="/security/enhancements/index.html">Android security platform</a>
+and service protections such as
+<a href="https://www.android.com/play-protect">Google Play Protect</a>. These
+capabilities reduce the likelihood that security vulnerabilities could be
+successfully exploited on Android.</p>
+<ul>
+  <li>Exploitation for many issues on Android is made more difficult by
+  enhancements in newer versions of the Android platform. We encourage all users
+  to update to the latest version of Android where possible.</li>
+  <li>The Android security team actively monitors for abuse through <a
+  href="https://www.android.com/play-protect">Google Play Protect</a> and warns
+  users about <a
+  href="/security/reports/Google_Android_Security_PHA_classifications.pdf">Potentially
+  Harmful Applications</a>. Google Play Protect is enabled by default on devices
+  with <a href="http://www.android.com/gms">Google Mobile Services</a>, and is
+  especially important for users who install apps from outside of Google
+  Play.</li>
+</ul>
+<h2 id="2017-09-01-details">2017-09-01 security patch level—Vulnerability details</h2>
+<p>In the sections below, we provide details for each of the security
+vulnerabilities that apply to the 2017-09-01 patch level. Vulnerabilities are
+grouped under the component that they affect. There is a description of the
+issue and a table with the CVE, associated references,
+<a href="#type">type of vulnerability</a>,
+<a href="/security/overview/updates-resources.html#severity">severity</a>,
+and updated AOSP versions (where applicable). When available, we link the public
+change that addressed the issue to the bug ID, like the AOSP change list. When
+multiple changes relate to a single bug, additional references are linked to
+numbers following the bug ID.</p>
+
+
+<h3 id="framework">Framework</h3>
+<p>The most severe vulnerability in this section could enable a local malicious
+application to bypass user interaction requirements in order to gain access to
+additional permissions.</p>
+
+<table>
+  <col width="17%">
+  <col width="19%">
+  <col width="9%">
+  <col width="14%">
+  <col width="39%">
+  <tr>
+    <th>CVE</th>
+    <th>References</th>
+    <th>Type</th>
+    <th>Severity</th>
+    <th>Updated AOSP versions</th>
+  </tr>
+  <tr>
+    <td>CVE-2017-0752</td>
+    <td><a href="https://android.googlesource.com/platform/frameworks/base/+/6ca2eccdbbd4f11698bd5312812b4d171ff3c8ce">
+        A-62196835</a>
+       [<a href="https://android.googlesource.com/platform/packages/apps/Settings/+/fc65be941a4dbebfdbe53cd0bd6cc5cc1142a908">2</a>]</td>
+    <td>EoP</td>
+    <td>High</td>
+    <td>4.4.4, 5.0.2, 5.1.1, 6.0, 6.0.1, 7.0, 7.1.1, 7.1.2</td>
+  </tr>
+</table>
+
+
+<h3 id="libraries">Libraries</h3>
+<p>The most severe vulnerability in this section could enable a remote attacker
+using a specially crafted file to execute arbitrary code within the context of
+an unprivileged process.</p>
+
+<table>
+  <col width="17%">
+  <col width="19%">
+  <col width="9%">
+  <col width="14%">
+  <col width="39%">
+  <tr>
+    <th>CVE</th>
+    <th>References</th>
+    <th>Type</th>
+    <th>Severity</th>
+    <th>Updated AOSP versions</th>
+  </tr>
+  <tr>
+    <td>CVE-2017-0753</td>
+    <td><a href="https://android.googlesource.com/platform/manifest/+/c0218b536c4243993bb666910d888cf16191dfd1">
+        A-62218744</a></td>
+    <td>RCE</td>
+    <td>High</td>
+    <td>7.1.1, 7.1.2, 8.0</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-6983</td>
+    <td><a href="https://android.googlesource.com/platform/external/sqlite/+/a1b4a910e8bf11e03479d91004652fc5919f475b">
+        A-63852675</a></td>
+    <td>RCE</td>
+    <td>High</td>
+    <td>4.4.4, 5.0.2, 5.1.1, 6.0, 6.0.1, 7.0, 7.1.1, 7.1.2, 8.0</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-0755</td>
+    <td><a href="https://android.googlesource.com/platform/frameworks/minikin/+/0dfb3527ba1ebbe97ad927e1f773427201aab501">
+        A-32178311</a></td>
+    <td>EoP</td>
+    <td>High</td>
+    <td>5.0.2, 5.1.1, 6.0, 6.0.1, 7.0, 7.1.1, 7.1.2, 8.0</td>
+  </tr>
+</table>
+
+
+<h3 id="media-framework">Media Framework</h3>
+<p>The most severe vulnerability in this section could enable a remote attacker
+using a specially crafted file to execute arbitrary code within the context of
+a privileged process.</p>
+
+<table>
+  <col width="17%">
+  <col width="19%">
+  <col width="9%">
+  <col width="14%">
+  <col width="39%">
+  <tr>
+    <th>CVE</th>
+    <th>References</th>
+    <th>Type</th>
+    <th>Severity</th>
+    <th>Updated AOSP versions</th>
+  </tr>
+  <tr>
+   <td>CVE-2017-0756</td>
+   <td><a href="https://android.googlesource.com/platform/frameworks/av/+/9aa026d0b867b270149dd7323ce36f4f9bfea980">
+   A-34621073</a></td>
+   <td>RCE</td>
+   <td>Critical</td>
+   <td>4.4.4, 5.0.2, 5.1.1, 6.0, 6.0.1, 7.0, 7.1.1, 7.1.2</td>
+  </tr>
+  <tr>
+   <td>CVE-2017-0757</td>
+   <td><a href="https://android.googlesource.com/platform/external/libavc/+/bb88d4430189b66270c66ff9167fc5bcf4356cf2">
+   A-36006815</a></td>
+   <td>RCE</td>
+   <td>Critical</td>
+   <td>6.0, 6.0.1, 7.0, 7.1.1, 7.1.2</td>
+  </tr>
+  <tr>
+   <td>CVE-2017-0758</td>
+   <td><a href="https://android.googlesource.com/platform/external/libhevc/+/4a534a34b14944f3513b7c101fc74ab0ec9eac0d">
+   A-36492741</a></td>
+   <td>RCE</td>
+   <td>Critical</td>
+   <td>5.0.2, 5.1.1, 6.0, 6.0.1, 7.0, 7.1.1, 7.1.2</td>
+  </tr>
+  <tr>
+   <td>CVE-2017-0759</td>
+   <td><a href="https://android.googlesource.com/platform/frameworks/av/+/6c91acf543ea20281f7e3d83414fab3cc64f1938">
+   A-36715268</a></td>
+   <td>RCE</td>
+   <td>Critical</td>
+   <td>6.0, 6.0.1, 7.0, 7.1.1, 7.1.2</td>
+  </tr>
+  <tr>
+   <td>CVE-2017-0760</td>
+   <td><a href="https://android.googlesource.com/platform/frameworks/av/+/9cb10d49b1319ea1207cc2f445089aa9266ffc71">
+   A-37237396</a></td>
+   <td>RCE</td>
+   <td>Critical</td>
+   <td>6.0, 6.0.1, 7.0, 7.1.1, 7.1.2</td>
+  </tr>
+  <tr>
+   <td>CVE-2017-0761</td>
+   <td><a href="https://android.googlesource.com/platform/external/libavc/+/ce512058186120a0de2916f6e22be58455df1a49">
+   A-38448381</a></td>
+   <td>RCE</td>
+   <td>Critical</td>
+   <td>6.0, 6.0.1, 7.0, 7.1.1, 7.1.2, 8.0</td>
+  </tr>
+  <tr>
+   <td>CVE-2017-0762</td>
+   <td><a href="https://android.googlesource.com/platform/external/libhevc/+/50acbc692998474c598834c9453ca9675b8fb95b">
+   A-62214264</a></td>
+   <td>RCE</td>
+   <td>Critical</td>
+   <td>5.0.2, 5.1.1, 6.0, 6.0.1, 7.0, 7.1.1, 7.1.2</td>
+  </tr>
+  <tr>
+   <td>CVE-2017-0763</td>
+   <td><a href="https://android.googlesource.com/platform/external/libhevc/+/0b57e70715c17e038b2fec0f808c1cd2172f4775">
+   A-62534693</a></td>
+   <td>RCE</td>
+   <td>Critical</td>
+   <td>5.0.2, 5.1.1, 6.0, 6.0.1, 7.0, 7.1.1, 7.1.2, 8.0</td>
+  </tr>
+  <tr>
+   <td>CVE-2017-0764</td>
+   <td><a href="https://android.googlesource.com/platform/external/tremolo/+/dbf3d0fa7b89aa09ec7bf69699f6233c59070dbc">
+   A-62872015</a></td>
+   <td>RCE</td>
+   <td>Critical</td>
+   <td>4.4.4, 5.0.2, 5.1.1, 6.0, 6.0.1, 7.0, 7.1.1, 7.1.2, 8.0</td>
+  </tr>
+  <tr>
+   <td>CVE-2017-0765</td>
+   <td><a href="https://android.googlesource.com/platform/frameworks/av/+/7c4c7fa208e31dc6f355a4488f267122015730a3">
+   A-62872863</a></td>
+   <td>RCE</td>
+   <td>Critical</td>
+   <td>6.0, 6.0.1, 7.0, 7.1.1, 7.1.2, 8.0</td>
+  </tr>
+  <tr>
+   <td>CVE-2017-0766</td>
+   <td><a href="https://android.googlesource.com/platform/manifest/+/c0218b536c4243993bb666910d888cf16191dfd1">
+   A-37776688</a></td>
+   <td>RCE</td>
+   <td>High</td>
+   <td>4.4.4, 5.0.2, 5.1.1, 6.0, 6.0.1, 7.0, 7.1.1, 7.1.2</td>
+  </tr>
+  <tr>
+   <td>CVE-2017-0767</td>
+   <td><a href="https://android.googlesource.com/platform/frameworks/av/+/2410a6fa4286efc8c5b5a5f33f6eeb023bfb6abb">
+   A-37536407</a>
+[<a href="https://android.googlesource.com/platform/hardware/qcom/audio/+/045e30499e3c73fb05b0a97da2420fd27bb263a3">2</a>]</td>
+   <td>EoP</td>
+   <td>High</td>
+   <td>4.4.4, 5.0.2, 5.1.1, 6.0, 6.0.1, 7.0, 7.1.1, 7.1.2</td>
+  </tr>
+  <tr>
+   <td>CVE-2017-0768</td>
+   <td><a href="https://android.googlesource.com/platform/frameworks/av/+/d8cc1fe9294accf05c6afcbe7821a485b9939af7">
+   A-62019992</a></td>
+   <td>EoP</td>
+   <td>High</td>
+   <td>4.4.4, 5.0.2, 5.1.1, 6.0, 6.0.1, 7.0, 7.1.1, 7.1.2, 8.0</td>
+  </tr>
+  <tr>
+   <td>CVE-2017-0769</td>
+   <td><a href="https://android.googlesource.com/platform/frameworks/av/+/0be8a2541594feec746195d6dbbc0db6c602175e">
+   A-37662122</a></td>
+   <td>EoP</td>
+   <td>High</td>
+   <td>7.0, 7.1.1, 7.1.2, 8.0</td>
+  </tr>
+  <tr>
+   <td>CVE-2017-0770</td>
+   <td><a href="https://android.googlesource.com/platform/frameworks/av/+/292d85545c6dec3c4386ec1fc2877597ea0ac5cc">
+   A-38234812</a></td>
+   <td>EoP</td>
+   <td>High</td>
+   <td>4.4.4, 5.0.2, 5.1.1, 6.0, 6.0.1, 7.0, 7.1.1, 7.1.2, 8.0</td>
+  </tr>
+  <tr>
+   <td>CVE-2017-0771</td>
+   <td><a href="https://android.googlesource.com/platform/external/skia/+/f593adeec75fe65771dfe67deca33fa4434b4e8a">
+   A-37624243</a></td>
+   <td>DoS</td>
+   <td>High</td>
+   <td>7.0, 7.1.1, 7.1.2</td>
+  </tr>
+  <tr>
+   <td>CVE-2017-0772</td>
+   <td><a href="https://android.googlesource.com/platform/external/libavc/+/1e0b52c25b20685ff9d6a14603b6a30f698824a7">
+   A-38115076</a></td>
+   <td>DoS</td>
+   <td>High</td>
+   <td>6.0, 6.0.1, 7.0, 7.1.1, 7.1.2, 8.0</td>
+  </tr>
+  <tr>
+   <td>CVE-2017-0773</td>
+   <td><a href="https://android.googlesource.com/platform/external/libhevc/+/9a03f9511559f82d034603e1df1425a4e0650f92">
+   A-37615911</a></td>
+   <td>DoS</td>
+   <td>High</td>
+   <td>5.0.2, 5.1.1, 6.0, 6.0.1, 7.0, 7.1.1, 7.1.2, 8.0</td>
+  </tr>
+  <tr>
+   <td>CVE-2017-0774</td>
+   <td><a href="https://android.googlesource.com/platform/frameworks/av/+/d4af2450c500c7d153fd66771b613f6e6882bf08">
+   A-62673844</a>
+[<a href="https://android.googlesource.com/platform/frameworks/av/+/5f56ec847a7f6250abd36a2f8a7b7baf4f966d11">2</a>]</td>
+   <td>DoS</td>
+   <td>High</td>
+   <td>4.4.4, 5.0.2, 5.1.1, 6.0, 6.0.1, 7.0, 7.1.1, 7.1.2</td>
+  </tr>
+  <tr>
+   <td>CVE-2017-0775</td>
+   <td><a href="https://android.googlesource.com/platform/frameworks/av/+/a1d5b40aaaa050af40c0f95d8b2d3e1ae8cfebbf">
+   A-62673179</a></td>
+   <td>DoS</td>
+   <td>High</td>
+   <td>4.4.4, 5.0.2, 5.1.1, 6.0, 6.0.1, 7.0, 7.1.1, 7.1.2, 8.0</td>
+  </tr>
+  <tr>
+   <td rowspan="2" >CVE-2017-0776</td>
+   <td rowspan="2" ><a href="https://android.googlesource.com/platform/external/libavc/+/5863b2e39357d82d53b3163afd38ad3bb0a07042">
+   A-38496660</a></td>
+   <td>ID</td>
+   <td>Moderate</td>
+   <td>7.0, 7.1.1, 7.1.2, 8.0</td>
+  </tr>
+  <tr>
+   <td>DoS</td>
+   <td>High</td>
+   <td>6.0.1</td>
+  </tr>
+  <tr>
+   <td rowspan="2" >CVE-2017-0777</td>
+   <td rowspan="2" ><a href="https://android.googlesource.com/platform/external/sonivox/+/112d9533b13134edbf4b7ee17db735b4b1468297">
+   A-38342499</a></td>
+   <td>ID</td>
+   <td>Moderate</td>
+   <td>7.0, 7.1.1, 7.1.2</td>
+  </tr>
+  <tr>
+   <td>DoS</td>
+   <td>High</td>
+   <td>4.4.4, 5.0.2, 5.1.1, 6.0, 6.0.1</td>
+  </tr>
+  <tr>
+   <td rowspan="2" >CVE-2017-0778</td>
+   <td rowspan="2" ><a href="https://android.googlesource.com/platform/frameworks/av/+/d7a044350bc151c7f7c04e04aaf136488630d655">
+   A-62133227</a></td>
+   <td>ID</td>
+   <td>Moderate</td>
+   <td>7.0, 7.1.1, 7.1.2</td>
+  </tr>
+  <tr>
+   <td>DoS</td>
+   <td>High</td>
+   <td>5.0.2, 5.1.1, 6.0, 6.0.1</td>
+  </tr>
+  <tr>
+   <td>CVE-2017-0779</td>
+   <td><a href="https://android.googlesource.com/platform/frameworks/av/+/ff4c8310ab7976ea9930b1dc4e3383720d5b5a8d">
+   A-38340117</a>
+[<a href="https://android.googlesource.com/platform/frameworks/av/+/b58464fa783c75ba9d304f670a4392df6fa98ed8">2</a>]</td>
+   <td>ID</td>
+   <td>Moderate</td>
+   <td>4.4.4, 5.0.2, 5.1.1, 6.0, 6.0.1, 7.0, 7.1.1, 7.1.2</td>
+  </tr>
+</table>
+
+
+<h3 id="runtime">Runtime</h3>
+<p>The most severe vulnerability in this section could enable a remote attacker
+using a specially crafted file to cause an application to hang.</p>
+
+<table>
+  <col width="17%">
+  <col width="19%">
+  <col width="9%">
+  <col width="14%">
+  <col width="39%">
+  <tr>
+    <th>CVE</th>
+    <th>References</th>
+    <th>Type</th>
+    <th>Severity</th>
+    <th>Updated AOSP versions</th>
+  </tr>
+  <tr>
+    <td>CVE-2017-0780</td>
+    <td><a href="https://android.googlesource.com/platform/packages/apps/Messaging/+/06cbd7f26ba58399f296d85fd155442c7f2ac837">
+        A-37742976</a></td>
+    <td>DoS</td>
+    <td>High</td>
+    <td>6.0, 6.0.1, 7.0, 7.1.1, 7.1.2, 8.0</td>
+  </tr>
+</table>
+
+
+<h3 id="system">System</h3>
+<p>The most severe vulnerability in this section could enable a proximate
+attacker to execute arbitrary code within the context of a privileged
+process.</p>
+
+<table>
+  <col width="17%">
+  <col width="19%">
+  <col width="9%">
+  <col width="14%">
+  <col width="39%">
+  <tr>
+    <th>CVE</th>
+    <th>References</th>
+    <th>Type</th>
+    <th>Severity</th>
+    <th>Updated AOSP versions</th>
+  </tr>
+  <tr>
+    <td>CVE-2017-0781</td>
+    <td><a href="https://android.googlesource.com/platform/system/bt/+/c513a8ff5cfdcc62cc14da354beb1dd22e56be0e">
+        A-63146105</a>
+       [<a href="https://android.googlesource.com/platform/system/bt/+/1e0bb31f6a809b49014483dc118b9d9ad31ade68">2</a>]</td>
+    <td>RCE</td>
+    <td>Critical</td>
+    <td>4.4.4, 5.0.2, 5.1.1, 6.0, 6.0.1, 7.0, 7.1.1, 7.1.2, 8.0</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-0782</td>
+    <td><a href="https://android.googlesource.com/platform/system/bt/+/4e47f3db62bab524946c46efe04ed6a2b896b150">
+        A-63146237</a>
+       [<a href="https://android.googlesource.com/platform/system/bt/+/1b08775917413f1674882130a948add1ae44cc91">2</a>]
+       [<a href="https://android.googlesource.com/platform/system/bt/+/c568fa9088ded964e0ac99db236e612de5d82177">3</a>]</td>
+    <td>RCE</td>
+    <td>Critical</td>
+    <td>4.4.4, 5.0.2, 5.1.1, 6.0, 6.0.1, 7.0, 7.1.1, 7.1.2, 8.0</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-0783</td>
+    <td><a href="https://android.googlesource.com/platform/system/bt/+/1e77fefc8b9c832239e1b32c6a6880376065e24e">
+        A-63145701</a></td>
+    <td>ID</td>
+    <td>High</td>
+    <td>4.4.4, 5.0.2, 5.1.1, 6.0, 6.0.1, 7.0, 7.1.1, 7.1.2, 8.0</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-0784</td>
+    <td><a href="https://android.googlesource.com/platform/packages/apps/Nfc/+/e216bc208bc0f0f685d8271ef8a0b5da8fae1088">
+        A-37287958</a></td>
+    <td>EoP</td>
+    <td>Moderate</td>
+    <td>5.0.2, 5.1.1, 6.0, 6.0.1, 7.0, 7.1.1, 7.1.2</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-0785</td>
+    <td><a href="https://android.googlesource.com/platform/system/bt/+/226ea26684d4cd609a5b456d3d2cc762453c2d75">
+        A-63146698</a></td>
+    <td>ID</td>
+    <td>Moderate</td>
+    <td>4.4.4, 5.0.2, 5.1.1, 6.0, 6.0.1, 7.0, 7.1.1, 7.1.2, 8.0</td>
+  </tr>
+</table>
+
+<h2 id="2017-09-05-details">2017-09-05
+security patch level—Vulnerability details</h2>
+<p>In the sections below, we provide details for each of the security
+vulnerabilities that apply to the 2017-09-05 patch level. Vulnerabilities are
+grouped under the component that they affect and include details such as the
+CVE, associated references, <a href="#type">type of vulnerability</a>,
+<a href="/security/overview/updates-resources.html#severity">severity</a>,
+component (where applicable), and updated AOSP versions (where applicable). When
+available, we link the public change that addressed the issue to the bug ID,
+like the AOSP change list. When multiple changes relate to a single bug,
+additional references are linked to numbers following the bug ID.</p>
+<h3 id="broadcom-components">Broadcom components</h3>
+<p>The most severe vulnerability in this section could enable a proximate
+attacker using a specially crafted file to execute arbitrary code within the
+context of a privileged process.</p>
+
+<table>
+  <col width="17%">
+  <col width="19%">
+  <col width="9%">
+  <col width="14%">
+  <col width="39%">
+  <tr>
+    <th>CVE</th>
+    <th>References</th>
+    <th>Type</th>
+    <th>Severity</th>
+    <th>Component</th>
+  </tr>
+  <tr>
+    <td>CVE-2017-7065</td>
+    <td>A-62575138<a href="#asterisk">*</a><br />
+        B-V2017061202</td>
+    <td>RCE</td>
+    <td>Critical</td>
+    <td>Wi-Fi driver</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-0786</td>
+    <td>A-37351060<a href="#asterisk">*</a><br />
+        B-V2017060101</td>
+    <td>EoP</td>
+    <td>High</td>
+    <td>Wi-Fi driver</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-0787</td>
+    <td>A-37722970<a href="#asterisk">*</a><br />
+        B-V2017053104</td>
+    <td>EoP</td>
+    <td>Moderate</td>
+    <td>Wi-Fi driver</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-0788</td>
+    <td>A-37722328<a href="#asterisk">*</a><br />
+        B-V2017053103</td>
+    <td>EoP</td>
+    <td>Moderate</td>
+    <td>Wi-Fi driver</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-0789</td>
+    <td>A-37685267<a href="#asterisk">*</a><br />
+        B-V2017053102</td>
+    <td>EoP</td>
+    <td>Moderate</td>
+    <td>Wi-Fi driver</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-0790</td>
+    <td>A-37357704<a href="#asterisk">*</a><br />
+        B-V2017053101</td>
+    <td>EoP</td>
+    <td>Moderate</td>
+    <td>Wi-Fi driver</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-0791</td>
+    <td>A-37306719<a href="#asterisk">*</a><br />
+        B-V2017052302</td>
+    <td>EoP</td>
+    <td>Moderate</td>
+    <td>Wi-Fi driver</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-0792</td>
+    <td>A-37305578<a href="#asterisk">*</a><br />
+        B-V2017052301</td>
+    <td>ID</td>
+    <td>Moderate</td>
+    <td>Wi-Fi driver</td>
+  </tr>
+</table>
+
+
+<h3 id="imgtk-components">Imgtk components</h3>
+<p>The most severe vulnerability in this section could enable a local malicious
+application to access data outside of its permission levels.</p>
+
+<table>
+  <col width="17%">
+  <col width="19%">
+  <col width="9%">
+  <col width="14%">
+  <col width="39%">
+  <tr>
+    <th>CVE</th>
+    <th>References</th>
+    <th>Type</th>
+    <th>Severity</th>
+    <th>Component</th>
+  </tr>
+  <tr>
+    <td>CVE-2017-0793</td>
+    <td>A-35764946<a href="#asterisk">*</a></td>
+    <td>ID</td>
+    <td>High</td>
+    <td>Memory subsystem</td>
+  </tr>
+</table>
+
+
+<h3 id="kernel-components">Kernel components</h3>
+<p>The most severe vulnerability in this section could enable a remote attacker
+using a specially crafted file to execute arbitrary code within the context of
+a privileged process.</p>
+
+<table>
+  <col width="17%">
+  <col width="19%">
+  <col width="9%">
+  <col width="14%">
+  <col width="39%">
+  <tr>
+    <th>CVE</th>
+    <th>References</th>
+    <th>Type</th>
+    <th>Severity</th>
+    <th>Component</th>
+  </tr>
+  <tr>
+    <td>CVE-2017-8890</td>
+    <td>A-38413975<br />
+        <a href="http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=657831ffc38e30092a2d5f03d385d710eb88b09a">
+Upstream kernel</a></td>
+    <td>RCE</td>
+    <td>Critical</td>
+    <td>Networking subsystem</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-9076</td>
+    <td>A-62299478<br />
+        <a href="http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=83eaddab4378db256d00d295bda6ca997cd13a52">
+Upstream kernel</a></td>
+    <td>EoP</td>
+    <td>High</td>
+    <td>Networking subsystem</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-9150</td>
+    <td>A-62199770<br />
+        <a href="http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=0d0e57697f162da4aa218b5feafe614fb666db07">
+Upstream kernel</a></td>
+    <td>ID</td>
+    <td>High</td>
+    <td>Linux kernel</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-7487</td>
+    <td>A-62070688<br />
+        <a href="http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=ee0d8d8482345ff97a75a7d747efc309f13b0d80">
+Upstream kernel</a></td>
+    <td>EoP</td>
+    <td>High</td>
+    <td>IPX protocol driver</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-6214</td>
+    <td>A-37901268<br />
+        <a href="http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=ccf7abb93af09ad0868ae9033d1ca8108bdaec82">
+Upstream kernel</a></td>
+    <td>DoS</td>
+    <td>High</td>
+    <td>Networking subsystem</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-6346</td>
+    <td>A-37897645<br />
+        <a href=" 
+http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=d199fab63c11998a602205f7ee7ff7c05c97164b">
+Upstream kernel</a></td>
+    <td>EoP</td>
+    <td>High</td>
+    <td>Linux kernel</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-5897</td>
+    <td>A-37871211<br />
+        <a href="https://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git/commit/?id=7892032cfe67f4bde6fc2ee967e45a8fbaf33756">
+Upstream kernel</a></td>
+    <td>ID</td>
+    <td>High</td>
+    <td>Networking subsystem</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-7495</td>
+    <td>A-62198330<br />
+        <a href="http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=06bd3c36a733ac27962fea7d6f47168841376824">
+Upstream kernel</a></td>
+    <td>ID</td>
+    <td>High</td>
+    <td>File system</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-7616</td>
+    <td>A-37751399<br />
+        <a href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=cf01fb9985e8deb25ccf0ea54d916b8871ae0e62">
+Upstream kernel</a></td>
+    <td>ID</td>
+    <td>Moderate</td>
+    <td>Linux kernel</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-12146</td>
+    <td>A-35676417<br />
+        <a href="https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/commit/?h=driver-core-next&id=6265539776a0810b7ce6398c27866ddb9c6bd154">
+Upstream kernel</a></td>
+    <td>EoP</td>
+    <td>Moderate</td>
+    <td>Linux kernel</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-0794</td>
+    <td>A-35644812<a href="#asterisk">*</a></td>
+    <td>EoP</td>
+    <td>Moderate</td>
+    <td>SCSI driver</td>
+  </tr>
+</table>
+
+
+<h3 id="mediatek-components">MediaTek components</h3>
+<p>The most severe vulnerability in this section could enable a local malicious
+application to execute arbitrary code within the context of a privileged
+process.</p>
+
+<table>
+  <col width="17%">
+  <col width="19%">
+  <col width="9%">
+  <col width="14%">
+  <col width="39%">
+  <tr>
+    <th>CVE</th>
+    <th>References</th>
+    <th>Type</th>
+    <th>Severity</th>
+    <th>Component</th>
+  </tr>
+  <tr>
+    <td>CVE-2017-0795</td>
+    <td>A-36198473<a href="#asterisk">*</a><br />
+        M-ALPS03361480</td>
+    <td>EoP</td>
+    <td>High</td>
+    <td>Accessory detector driver</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-0796</td>
+    <td>A-62458865<a href="#asterisk">*</a><br />
+        M-ALPS03353884<br />
+        M-ALPS03353886<br />
+        M-ALPS03353887</td>
+    <td>EoP</td>
+    <td>High</td>
+    <td>AUXADC driver</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-0797</td>
+    <td>A-62459766<a href="#asterisk">*</a><br />
+        M-ALPS03353854</td>
+    <td>EoP</td>
+    <td>High</td>
+    <td>Accessory detector driver</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-0798</td>
+    <td>A-36100671<a href="#asterisk">*</a><br />
+        M-ALPS03365532</td>
+    <td>EoP</td>
+    <td>High</td>
+    <td>Kernel</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-0799</td>
+    <td>A-36731602<a href="#asterisk">*</a><br />
+        M-ALPS03342072</td>
+    <td>EoP</td>
+    <td>High</td>
+    <td>Lastbus</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-0800</td>
+    <td>A-37683975<a href="#asterisk">*</a><br />
+        M-ALPS03302988</td>
+    <td>EoP</td>
+    <td>High</td>
+    <td>TEEI</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-0801</td>
+    <td>A-38447970<a href="#asterisk">*</a><br />
+        M-ALPS03337980</td>
+    <td>EoP</td>
+    <td>High</td>
+    <td>LibMtkOmxVdec</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-0802</td>
+    <td>A-36232120<a href="#asterisk">*</a><br />
+        M-ALPS03384818</td>
+    <td>EoP</td>
+    <td>Moderate</td>
+    <td>Kernel</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-0803</td>
+    <td>A-36136137<a href="#asterisk">*</a><br />
+        M-ALPS03361477</td>
+    <td>EoP</td>
+    <td>Moderate</td>
+    <td>Accessory detector driver</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-0804</td>
+    <td>A-36274676<a href="#asterisk">*</a><br />
+        M-ALPS03361487</td>
+    <td>EoP</td>
+    <td>Moderate</td>
+    <td>MMC driver</td>
+  </tr>
+</table>
+
+
+<h3 id="qualcomm-components">Qualcomm components</h3>
+<p>The most severe vulnerability in this section could enable a remote attacker
+using a specially crafted file to execute arbitrary code within the context of
+a privileged process.</p>
+
+<table>
+  <col width="17%">
+  <col width="19%">
+  <col width="9%">
+  <col width="14%">
+  <col width="39%">
+  <tr>
+    <th>CVE</th>
+    <th>References</th>
+    <th>Type</th>
+    <th>Severity</th>
+    <th>Component</th>
+  </tr>
+  <tr>
+    <td>CVE-2017-11041</td>
+    <td>A-36130225<a href="#asterisk">*</a><br />
+        QC-CR#2053101</td>
+    <td>RCE</td>
+    <td>Critical</td>
+    <td>LibOmxVenc</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-10996</td>
+    <td>A-38198574<br />
+        <a href="https://source.codeaurora.org/quic/la/kernel/msm-3.18/commit/?id=9f261e5dfe101bbe35043822a89bffa78e080b3b">
+QC-CR#901529</a></td>
+    <td>ID</td>
+    <td>High</td>
+    <td>Linux kernel</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-9725</td>
+    <td>A-38195738<br />
+        <a href="https://source.codeaurora.org/quic/la/kernel/msm-4.4/commit/?h=aosp/android-4.4&id=1f8f9b566e8446c13b954220c226c58d22076f88">
+QC-CR#896659</a></td>
+    <td>EoP</td>
+    <td>High</td>
+    <td>Memory subsystem</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-9724</td>
+    <td>A-38196929<br />
+        <a href="https://source.codeaurora.org/quic/la/kernel/msm-3.10/commit/?id=5328a92fa26eabe2ba259b1d813f9de488efc9ec">
+QC-CR#863303</a></td>
+    <td>EoP</td>
+    <td>High</td>
+    <td>Linux kernel</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-8278</td>
+    <td>A-62379474<br />
+        <a href="https://source.codeaurora.org/quic/la/platform/hardware/qcom/audio/commit/?id=16caa80d6bd59fc645afda37dec4104d451e2f66">
+QC-CR#2013236</a></td>
+    <td>EoP</td>
+    <td>High</td>
+    <td>Audio driver</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-10999</td>
+    <td>A-36490777<a href="#asterisk">*</a><br />
+        QC-CR#2010713</td>
+    <td>EoP</td>
+    <td>Moderate</td>
+    <td>IPA driver</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-11001</td>
+    <td>A-36815555<a href="#asterisk">*</a><br />
+        QC-CR#270292</td>
+    <td>ID</td>
+    <td>Moderate</td>
+    <td>Wi-Fi driver</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-11002</td>
+    <td>A-37712167<a href="#asterisk">*</a><br />
+        QC-CR#2058452 QC-CR#2054690 QC-CR#2058455</td>
+    <td>ID</td>
+    <td>Moderate</td>
+    <td>Wi-Fi driver</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-8250</td>
+    <td>A-62379051<br />
+        <a href="https://source.codeaurora.org/quic/la/kernel/msm-3.18/commit/?id=9be5b16de622c2426408425e3df29e945cd21d37">
+QC-CR#2003924</a></td>
+    <td>EoP</td>
+    <td>Moderate</td>
+    <td>GPU driver</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-9677</td>
+    <td>A-62379475<br />
+        <a href="https://source.codeaurora.org/quic/la/kernel/msm-3.18/commit/?id=dc333eb1c31b5bdd2b6375d7cb890086d8f27d8b">
+QC-CR#2022953</a></td>
+    <td>EoP</td>
+    <td>Moderate</td>
+    <td>Audio driver</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-10998</td>
+    <td>A-38195131<br />
+        <a href="https://source.codeaurora.org/quic/la//kernel/msm-3.18/commit/?id=208e72e59c8411e75d4118b48648a5b7d42b1682">
+QC-CR#108461</a></td>
+    <td>EoP</td>
+    <td>Moderate</td>
+    <td>Audio driver</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-9676</td>
+    <td>A-62378596<br />
+        <a href="https://source.codeaurora.org/quic/la/kernel/msm-3.18/commit/?id=c1f749639030305a3b02185c180240a8195fb715">
+QC-CR#2016517</a></td>
+    <td>ID</td>
+    <td>Moderate</td>
+    <td>File system</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-8280</td>
+    <td>A-62377236<br />
+        <a href="https://source.codeaurora.org/quic/la/kernel/msm-3.18/commit/?id=49b9a02eaaeb0b70608c6fbcadff7d83833b9614">
+QC-CR#2015858</a></td>
+    <td>EoP</td>
+    <td>Moderate</td>
+    <td>WLAN driver</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-8251</td>
+    <td>A-62379525<br />
+        <a href="https://source.codeaurora.org/quic/la/kernel/msm-4.4/commit/?id=771254edea3486535453dbb76d090cd6bcf92af9">
+QC-CR#2006015</a></td>
+    <td>EoP</td>
+    <td>Moderate</td>
+    <td>Camera driver</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-10997</td>
+    <td>A-33039685<a href="#asterisk">*</a><br />
+        QC-CR#1103077</td>
+    <td>EoP</td>
+    <td>Moderate</td>
+    <td>PCI driver</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-11000</td>
+    <td>A-36136563<a href="#asterisk">*</a><br />
+        QC-CR#2031677</td>
+    <td>EoP</td>
+    <td>Moderate</td>
+    <td>Camera driver</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-8247</td>
+    <td>A-62378684<br />
+        <a href="https://source.codeaurora.org/quic/la/kernel/msm-4.4/commit/?id=84f8c42e5d848b1d04f49d253f98296e8c2280b9">
+QC-CR#2023513</a></td>
+    <td>EoP</td>
+    <td>Moderate</td>
+    <td>Camera driver</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-9720</td>
+    <td>A-36264696<a href="#asterisk">*</a><br />
+        QC-CR#2041066</td>
+    <td>EoP</td>
+    <td>Moderate</td>
+    <td>Camera driver</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-8277</td>
+    <td>A-62378788<br />
+        <a href="https://source.codeaurora.org/quic/la//kernel/msm-4.4/commit/?id=c9a6f09f1030cec591df837622cb54bbb2d24ddc">
+QC-CR#2009047</a></td>
+    <td>EoP</td>
+    <td>Moderate</td>
+    <td>Video driver</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-8281</td>
+    <td>A-62378232<br />
+        <a href="https://source.codeaurora.org/quic/la/kernel/msm-3.18/commit/?id%3D9be5b16de622c2426408425e3df29e945cd21d37&sa=D&usg=AFQjCNHuM63XOo5Y0C7bMJQIIedBHSDKjw">
+QC-CR#2015892</a></td>
+    <td>ID</td>
+    <td>Moderate</td>
+    <td>Automotive multimedia</td>
+  </tr>
+  <tr>
+    <td>CVE-2017-11040</td>
+    <td>A-37567102<a href="#asterisk">*</a><br />
+        QC-CR#2038166</td>
+    <td>ID</td>
+    <td>Moderate</td>
+    <td>Video driver</td>
+  </tr>
+</table>
+
+<h2 id="google-device-updates">Google device updates</h2>
+<p>This table contains the security patch level in the latest over-the-air update
+(OTA) and firmware images for Google devices. The Google device OTAs may also
+contain additional updates. The Google device firmware images are available on
+the <a href="https://developers.google.com/android/nexus/images">Google
+Developer site</a>.</p>
+<aside class="note">Pixel, Pixel XL, Pixel C, Nexus Player, Nexus 5X, and Nexus 6P
+devices will be receiving the September security patches as part of the
+upgrade to Android Oreo.</aside>
+<table>
+  <tr>
+   <th>Google device</th>
+   <th>Security patch level</th>
+  </tr>
+  <tr>
+   <td>Pixel / Pixel XL</td>
+   <td>2017-09-05</td>
+  </tr>
+  <tr>
+   <td>Nexus 5X</td>
+   <td>2017-09-05</td>
+  </tr>
+  <tr>
+   <td>Nexus 6</td>
+   <td>2017-09-05</td>
+  </tr>
+  <tr>
+   <td>Nexus 6P</td>
+   <td>2017-09-05</td>
+  </tr>
+  <tr>
+   <td>Nexus 9</td>
+   <td>2017-09-05</td>
+  </tr>
+  <tr>
+   <td>Nexus Player</td>
+   <td>2017-09-05</td>
+  </tr>
+  <tr>
+   <td>Pixel C</td>
+   <td>2017-09-05</td>
+  </tr>
+</table>
+<h2 id="acknowledgements">Acknowledgements</h2>
+<p>We would like to thank these researchers for their contributions:</p>
+
+<table>
+  <col width="17%">
+  <col width="83%">
+  <tr>
+   <th>CVEs</th>
+   <th>Researchers</th>
+  </tr>
+  <tr>
+   <td>CVE-2017-11000</td>
+   <td>Baozeng Ding (<a href="https://twitter.com/sploving1">@sploving</a>),
+Chengming Yang, and Yang Song of Alibaba Mobile Security Group</td>
+  </tr>
+  <tr>
+   <td>CVE-2017-0781, CVE-2017-0782, CVE-2017-0783, CVE-2017-0785</td>
+   <td>Ben Seri and Gregory Vishnepolsky of Armis, Inc. (<a href="https://armis.com">https://armis.com</a>)</td>
+  </tr>
+  <tr>
+   <td>CVE-2017-0800, CVE-2017-0798</td>
+   <td>Chengming Yang, Baozeng Ding, and Yang Song of Alibaba Mobile Security
+Group</td>
+  </tr>
+  <tr>
+   <td>CVE-2017-0765</td>
+   <td><a href="mailto:zc1991@mail.ustc.edu.cn">Chi Zhang</a>, Mingjian Zhou (<a
+href="https://twitter.com/Mingjian_Zhou">@Mingjian_Zhou</a>), and Xuxian Jiang
+of <a href="http://c0reteam.org">C0RE Team</a></td>
+  </tr>
+  <tr>
+   <td>CVE-2017-0758</td>
+   <td><a href="http://weibo.com/csddl">Chong Wang</a> and 金哲 (Zhe Jin) of
+Chengdu Security Response Center, Qihoo 360 Technology Co. Ltd.</td>
+  </tr>
+  <tr>
+   <td>CVE-2017-0752</td>
+   <td>Cong Zheng (<a href="https://twitter.com/shellcong">@shellcong</a>),
+Wenjun Hu, Xiao Zhang, and Zhi Xu of Palo Alto Networks</td>
+  </tr>
+  <tr>
+   <td>CVE-2017-0801</td>
+   <td><a href="mailto:shaodacheng2016@gmail.com">Dacheng Shao</a>, Mingjian
+Zhou (<a href="https://twitter.com/Mingjian_Zhou">@Mingjian_Zhou</a>), and
+Xuxian Jiang of <a href="http://c0reteam.org">C0RE Team</a></td>
+  </tr>
+  <tr>
+   <td>CVE-2017-0775, CVE-2017-0774, CVE-2017-0771</td>
+   <td>Elphet and Gong Guang of Alpha Team, Qihoo 360 Technology Co. Ltd.</td>
+  </tr>
+  <tr>
+   <td>CVE-2017-0784</td>
+   <td>En He (<a href="https://twitter.com/heeeeen4x">@heeeeen4x</a>) and Bo Liu
+of <a href="http://www.ms509.com">MS509Team</a></td>
+  </tr>
+  <tr>
+   <td>CVE-2017-10997</td>
+   <td>Gengjia Chen (<a
+href="https://twitter.com/chengjia4574">@chengjia4574</a>) and <a
+href="http://weibo.com/jfpan">pjf</a> of IceSword Lab, Qihoo 360 Technology Co.
+Ltd.</td>
+  </tr>
+  <tr>
+   <td>CVE-2017-0786, CVE-2017-0792, CVE-2017-0791, CVE-2017-0790,
+CVE-2017-0789, CVE-2017-0788, CVE-2017-0787</td>
+   <td>Hao Chen and Guang Gong of Alpha Team, Qihoo 360 Technology Co. Ltd.</td>
+  </tr>
+  <tr>
+   <td>CVE-2017-0802</td>
+   <td>Jake Corina and Nick Stephens of Shellphish Grill Team</td>
+  </tr>
+  <tr>
+   <td>CVE-2017-0780</td>
+   <td>Jason Gu and Seven Shen of Trend Micro</td>
+  </tr>
+  <tr>
+   <td>CVE-2017-0769</td>
+   <td>Mingjian Zhou (<a
+href="https://twitter.com/Mingjian_Zhou">@Mingjian_Zhou</a>), <a
+href="mailto:shaodacheng2016@gmail.com">Dacheng Shao</a>, and Xuxian Jiang of <a
+href="http://c0reteam.org">C0RE Team</a></td>
+  </tr>
+  <tr>
+   <td>CVE-2017-0794, CVE-2017-9720, CVE-2017-11001, CVE-2017-10999,
+CVE-2017-0766</td>
+   <td>Pengfei Ding (丁鹏飞), Chenfu Bao (包沉浮), Lenx Wei (韦韬) of Baidu X-Lab
+(百度安全实验室)</td>
+  </tr>
+  <tr>
+   <td>CVE-2017-0772</td>
+   <td>Seven Shen of Trend Micro</td>
+  </tr>
+  <tr>
+   <td>CVE-2017-0757</td>
+   <td>Vasily Vasiliev</td>
+  </tr>
+  <tr>
+   <td>CVE-2017-0768, CVE-2017-0779</td>
+   <td><a href="mailto:vancouverdou@gmail.com">Wenke Dou</a>, Mingjian Zhou (<a
+href="https://twitter.com/Mingjian_Zhou">@Mingjian_Zhou</a>), and Xuxian Jiang
+of <a href="http://c0reteam.org">C0RE Team</a></td>
+  </tr>
+  <tr>
+   <td>CVE-2017-0759</td>
+   <td><a href="https://twitter.com/sunblate">Weichao Sun</a> of Alibaba Inc.</td>
+  </tr>
+  <tr>
+   <td>CVE-2017-0796</td>
+   <td>Xiangqian Zhang, Chengming Yang, Baozeng Ding, and Yang Song of Alibaba
+       Mobile Security Group</td>
+  </tr>
+  <tr>
+   <td>CVE-2017-0753</td>
+   <td>Yangkang (<a href="https://twitter.com/dnpushme">@dnpushme</a>) and
+hujianfei of Qihoo360 Qex Team</td>
+  </tr>
+  <tr>
+   <td>CVE-2017-12146</td>
+   <td>Yonggang Guo (<a href="https://twitter.com/guoygang">@guoygang</a>) of
+IceSword Lab, Qihoo 360 Technology Co. Ltd.</td>
+  </tr>
+  <tr>
+   <td>CVE-2017-0767</td>
+   <td>Yongke Wang and Yuebin Sun of <a href="http://xlab.tencent.com">Tencent's
+Xuanwu Lab</a></td>
+  </tr>
+  <tr>
+   <td>CVE-2017-0804, CVE-2017-0803, CVE-2017-0799, CVE-2017-0795</td>
+   <td><a href="http://weibo.com/panyu6325">Yu Pan</a> and <a
+href="mailto:huahuaisadog@gmail.com">Yang Dai</a> of Vulpecker Team, Qihoo 360
+Technology Co. Ltd</td>
+  </tr>
+  <tr>
+   <td>CVE-2017-0760</td>
+   <td><a href="http://weibo.com/ele7enxxh">Zinuo Han</a> and 金哲 (Zhe Jin) of
+Chengdu Security Response Center, Qihoo 360 Technology Co. Ltd.</td>
+  </tr>
+  <tr>
+   <td>CVE-2017-0764, CVE-2017-0761, CVE-2017-0776, CVE-2017-0777, CVE-2017-0778</td>
+   <td><a href="http://weibo.com/ele7enxxh">Zinuo Han</a> of Chengdu Security
+Response Center, Qihoo 360 Technology Co. Ltd.</td>
+  </tr>
+</table>
+<h2 id="questions">Common questions and answers</h2>
+<p>This section answers common questions that may occur after reading this
+bulletin.</p>
+
+<p><strong>1. How do I determine if my device is updated to address these issues?
+</strong></p>
+
+<p>To learn how to check a device's security patch level, read the instructions on
+the <a
+href="https://support.google.com/pixelphone/answer/4457705#pixel_phones&nexus_devices">Pixel
+and Nexus update schedule</a>.</p>
+<ul>
+  <li>Security patch levels of 2017-09-01 or later address all issues associated
+  with the 2017-09-01 security patch level.</li>
+  <li>Security patch levels of 2017-09-05 or later address all issues associated
+  with the 2017-09-05 security patch level and all previous patch levels.
+  </li>
+</ul>
+<p>Device manufacturers that include these updates should set the patch string
+level to:</p>
+<ul>
+  <li>[ro.build.version.security_patch]:[2017-09-01]</li>
+  <li>[ro.build.version.security_patch]:[2017-09-05]</li>
+</ul>
+<p><strong>2. Why does this bulletin have two security patch levels?</strong></p>
+
+<p>This bulletin has two security patch levels so that Android partners have the
+flexibility to fix a subset of vulnerabilities that are similar across all
+Android devices more quickly. Android partners are encouraged to fix all issues
+in this bulletin and use the latest security patch level.</p>
+<ul>
+  <li>Devices that use the 2017-09-01 security patch level must include all issues
+  associated with that security patch level, as well as fixes for all issues
+  reported in previous security bulletins.</li>
+  <li>Devices that use the security patch level of 2017-09-05 or newer must
+  include all applicable patches in this (and previous) security
+  bulletins.</li>
+</ul>
+<p>Partners are encouraged to bundle the fixes for all issues they are addressing
+in a single update.</p>
+
+<p id="type">
+<strong>3. What do the entries in the <em>Type</em> column mean?</strong></p>
+
+<p>Entries in the <em>Type</em> column of the vulnerability details table reference
+the classification of the security vulnerability.</p>
+
+<table>
+  <col width="25%">
+  <col width="75%">
+  <tr>
+   <th>Abbreviation</th>
+   <th>Definition</th>
+  </tr>
+  <tr>
+   <td>RCE</td>
+   <td>Remote code execution</td>
+  </tr>
+  <tr>
+   <td>EoP</td>
+   <td>Elevation of privilege</td>
+  </tr>
+  <tr>
+   <td>ID</td>
+   <td>Information disclosure</td>
+  </tr>
+  <tr>
+   <td>DoS</td>
+   <td>Denial of service</td>
+  </tr>
+  <tr>
+   <td>N/A</td>
+   <td>Classification not available</td>
+  </tr>
+</table>
+<p><strong>4. What do the entries in the <em>References</em> column mean?</strong></p>
+
+<p>Entries under the <em>References</em> column of the vulnerability details table
+may contain a prefix identifying the organization to which the reference value
+belongs.</p>
+
+<table>
+  <col width="25%">
+  <col width="75%">
+  <tr>
+   <th>Prefix</th>
+   <th>Reference</th>
+  </tr>
+  <tr>
+   <td>A-</td>
+   <td>Android bug ID</td>
+  </tr>
+  <tr>
+   <td>QC-</td>
+   <td>Qualcomm reference number</td>
+  </tr>
+  <tr>
+   <td>M-</td>
+   <td>MediaTek reference number</td>
+  </tr>
+  <tr>
+   <td>N-</td>
+   <td>NVIDIA reference number</td>
+  </tr>
+  <tr>
+   <td>B-</td>
+   <td>Broadcom reference number</td>
+  </tr>
+</table>
+<p id="asterisk"><strong>5. What does a * next to the Android bug ID in the <em>References</em>
+column mean?</strong></p>
+
+<p>Issues that are not publicly available have a * next to the Android bug ID in
+the <em>References</em> column. The update for that issue is generally contained
+in the latest binary drivers for Nexus devices available from the <a
+href="https://developers.google.com/android/nexus/drivers">Google Developer
+site</a>.</p>
+
+<h2 id="versions">Versions</h2>
+<table>
+  <col width="25%">
+  <col width="25%">
+  <col width="50%">
+  <tr>
+   <th>Version</th>
+   <th>Date</th>
+   <th>Notes</th>
+  </tr>
+  <tr>
+   <td>1.0</td>
+   <td>September 5, 2017</td>
+   <td>Bulletin published.</td>
+  </tr>
+  <tr>
+   <td>1.1</td>
+   <td>September 12, 2017</td>
+   <td>Added details for CVE-2017-0781, CVE-2017-0782, CVE-2017-0783, and
+CVE-2017-0785 as part of industry-coordinated disclosure.</td>
+  </tr>
+  <tr>
+   <td>1.2</td>
+   <td>September 13, 2017</td>
+   <td>Bulletin revised to include AOSP links.</td>
+  </tr>
+</table>
+</body>
+</html>
diff --git a/en/security/bulletin/2017.html b/en/security/bulletin/2017.html
index c4d18c4..2da8877 100644
--- a/en/security/bulletin/2017.html
+++ b/en/security/bulletin/2017.html
@@ -37,6 +37,22 @@
     <th>Security patch level</th>
  </tr>
  <tr>
+    <td><a href="2017-09-01.html">September 2017</a></td>
+    <td>Coming soon
+      <!--
+      <a href="/security/bulletin/2017-09-01.html">English</a>&nbsp;/
+      <a href="/security/bulletin/2017-09-01.html?hl=ja">日本語</a>&nbsp;/
+      <a href="/security/bulletin/2017-09-01.html?hl=ko">한국어</a>&nbsp;/
+      <a href="/security/bulletin/2017-09-01.html?hl=ru">ру́сский</a>&nbsp;/
+      <a href="/security/bulletin/2017-09-01.html?hl=zh-cn">中文&nbsp;(中国)</a>&nbsp;/
+      <a href="/security/bulletin/2017-09-01.html?hl=zh-tw">中文&nbsp;(台灣)</a>
+      -->
+    </td>
+    <td>September 5, 2017</td>
+    <td>2017-09-01<br>
+        2017-09-05</td>
+ </tr>
+ <tr>
     <td><a href="2017-08-01.html">August 2017</a></td>
     <td>Coming soon
       <!--
diff --git a/en/security/bulletin/index.html b/en/security/bulletin/index.html
index e14f60e..b577159 100644
--- a/en/security/bulletin/index.html
+++ b/en/security/bulletin/index.html
@@ -34,7 +34,7 @@
 <ul>
   <li><a href="https://lgsecurity.lge.com/security_updates.html">LG</a></li>
   <li><a href="https://motorola-global-portal.custhelp.com/app/software-upgrade-security/g_id/5593">Motorola</a></li>
-  <li><a href="http://security.samsungmobile.com/smrupdate.html">Samsung</a></li>
+  <li><a href="https://security.samsungmobile.com/securityUpdate.smsb">Samsung</a></li>
 </ul>
 
 <h3 id="notification">Notifications</h3>
@@ -76,6 +76,22 @@
     <th>Security patch level</th>
  </tr>
  <tr>
+    <td><a href="/security/bulletin/2017-09-01.html">September 2017</a></td>
+    <td>Coming soon
+     <!--
+     <a href="/security/bulletin/2017-09-01.html">English</a>&nbsp;/
+     <a href="/security/bulletin/2017-09-01.html?hl=ja">日本語</a>&nbsp;/
+     <a href="/security/bulletin/2017-09-01.html?hl=ko">한국어</a>&nbsp;/
+     <a href="/security/bulletin/2017-09-01.html?hl=ru">ру́сский</a>&nbsp;/
+     <a href="/security/bulletin/2017-09-01.html?hl=zh-cn">中文&nbsp;(中国)</a>&nbsp;/
+     <a href="/security/bulletin/2017-09-01.html?hl=zh-tw">中文&nbsp;(台灣)</a>
+     -->
+    </td>
+    <td>September 5, 2017</td>
+    <td>2017-09-01<br>
+        2017-09-05</td>
+ </tr>
+ <tr>
     <td><a href="/security/bulletin/2017-08-01.html">August 2017</a></td>
     <td>Coming soon
      <!--
diff --git a/en/security/keystore/attestation.html b/en/security/keystore/attestation.html
index 7b03c25..80d55d3 100644
--- a/en/security/keystore/attestation.html
+++ b/en/security/keystore/attestation.html
@@ -1,6 +1,6 @@
 <html devsite>
   <head>
-    <title>Key Attestation</title>
+    <title>Key and ID Attestation</title>
     <meta name="project_path" value="/_project.yaml" />
     <meta name="book_path" value="/_book.yaml" />
   </head>
@@ -24,76 +24,39 @@
 Keystore provides a more secure place to create, store, and use cryptographic
 keys in a controlled way. When hardware-backed key storage is available and
 used, key material is more secure against extraction from the device, and
-keymaster1 enforces restrictions in a hard-to-subvert way.
+Keymaster enforces restrictions that are difficult to subvert.
 </p>
 <p>
 This is only true, however, if the keystore keys are known to be in
-hardware-backed storage. There is presently no way for apps or remote servers to
-reliably verify if this is the case. The keystore daemon loads the available
-keymaster HAL and believes whatever the HAL says with respect to hardware
+hardware-backed storage. In Keymaster 1, there was no way for apps or remote servers to
+reliably verify if this was the case. The keystore daemon loaded the available
+keymaster HAL and believed whatever the HAL said with respect to hardware
 backing of keys.
 </p>
 <p>
-Key attestation aims to provide a way to strongly determine if an asymmetric key
-pair is hardware-backed, what the properties of the key are, and what
-constraints are applied to its usage.
+To remedy this, Keymaster introduced key attestation in Android 7.0 (Keymaster 2)
+and ID attestation in Android 8.0 (Keymaster 3).
 </p>
-<h2 id="java-api">Java API</h2>
-<p class="note">
-Note: This section is informational only. Keymaster2 implementers neither
-implement nor use the Java API. This is provided to help implementers understand
-how the feature is used by applications. System components may use it
-differently, which is why it's crucial this section not be treated as normative.
-</p>
-
-<section class="expandable">
-  <h4 class="showalways">How application developers use attestation</h4>
-<ul>
-<li>Creates a key generation request, specifying a key alias and key generation
-parameters for an EC or RSA key pair.</li>
-<li>Sets the "attestation challenge" for the request, with
-<code>KeyPairGenerator.setAttestationChallenge(byte[])</code>. This both
-provides challenge data (which may be empty), and indicates that an attestation
-is requested.</li>
-<li>Generates the key pair.</li>
-<li>Requests the certificate chain from <code>AndroidKeyStore</code>. The first
-certificate in the chain is the attestation; the other certificates provide the
-chain of trust back to and including the root attestation key.</li>
-</ul>
 <p>
-This example generates a key pair and requests an attestation.
+Key attestation aims to provide a way to strongly
+determine if an asymmetric key pair is hardware-backed, what the properties
+of the key are, and what constraints are applied to its usage.
+</p>
+<p>
+ID attestation allows the device to provide proof of its hardware identifiers,
+such as serial number or IMEI.
+
+<p class="note">To support Keymaster 3's transition from the old-style C-structure
+HAL to the C++ HAL interface generated from a definition in the new
+Hardware Interface Definition Language (HIDL), tag and method names have changed
+in Android 8.0. Tags, like all other keymaster enums, are now defined as C++
+scoped enums. For example, tags, formerly prefixed with <code>KM_TAG_</code>,
+are now prefixed with <code>Tag::</code> and methods are in camel case. The
+examples below use Keymaster 3 terms, unless specified otherwise.
 </p>
 
-<pre class="prettyprint">// Create KeyPairGenerator and set generation parameters for an ECDSA key pair
-// using the NIST P-256 curve.  "Key1" is the key alias.
-KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(
-    KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore");
-    keyPairGenerator.initialize(
-         new KeyGenParameterSpec.Builder("Key1", KeyProperties.PURPOSE_SIGN)
-             .setAlgorithmParameterSpec(new ECGenParameterSpec("secp256r1"))
-             .setDigests(KeyProperties.DIGEST_SHA256,
-                         KeyProperties.DIGEST_SHA384,
-                         KeyProperties.DIGEST_SHA512)
-             // Only permit the private key to be used if the user
-             // authenticated within the last five minutes.
-             .setUserAuthenticationRequired(true)
-             .setUserAuthenticationValidityDurationSeconds(5 * 60)
-             // Request an attestation with challenge "hello world".
-             .setAttestationChallenge("hello world".toBytes());
-             .build());
-// Generate the key pair. This will result in calls to both generate_key() and
-// attest_key() at the keymaster2 HAL.
-KeyPair keyPair = keyPairGenerator.generateKeyPair();
-// Get the certificate chain
-KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
-keyStore.load(null);
-Certificate[] certs = keyStore.getCertificateChain("Key1");
-// certs[0] is the attestation certificate. certs[1] signs certs[0], etc.,
-// up to certs[certs.length - 1].
-</pre>
-</section>
-
-<h2 id="hal-changes">HAL changes</h2>
+<h2 id="key-attestation">Key attestation</h2>
+</p>
 <p>
 To support key attestation, Android 7.1 introduced a set of tags, type, and
 method to the HAL.
@@ -102,24 +65,31 @@
 <strong>Tags</strong>
 </p>
 <ul>
-<li><code>KM_TAG_ATTESTATION_CHALLENGE</code></li>
-<li><code>KM_TAG_INCLUDE_UNIQUE_ID</code></li>
-<li><code>KM_TAG_RESET_SINCE_ID_ROTATION</code> </li>
+<li><code>Tag::ATTESTATION_CHALLENGE</code></li>
+<li><code>Tag::INCLUDE_UNIQUE_ID</code></li>
+<li><code>Tag::RESET_SINCE_ID_ROTATION</code></li>
 </ul>
 <p>
 <strong>Type</strong>
 </p>
 
-<pre class="prettyprint">typedef struct {
+<p><strong>Keymaster 2 and below</strong></p>
+<pre class="devsite-click-to-copy">typedef struct {
     keymaster_blob_t* entries;
     size_t entry_count;
 } keymaster_cert_chain_t;
 </pre>
 
 <p>
-<strong><code>Attest_key</code> method</strong></p>
+<strong><code>AttestKey</code> method</strong></p>
 
-<pre class="prettyprint">keymaster_error_t (*attest_key)(const struct keymaster2_device* dev,
+<p><strong>Keymaster 3</strong></p>
+<pre class="devsite-click-to-copy">
+    attestKey(vec&lt;uint8_t&gt; keyToAttest, vec&lt;KeyParameter&gt; attestParams)
+        generates(ErrorCode error, vec&lt;vec&lt;uint8_t&gt;&gt; certChain);</pre>
+
+<p><strong>Keymaster 2 and below</strong></p>
+<pre class="devsite-click-to-copy">keymaster_error_t (*attest_key)(const struct keymaster2_device* dev,
         const keymaster_key_blob_t* key_to_attest,
         const keymaster_key_param_set_t* attest_params,
         keymaster_cert_chain_t* cert_chain);
@@ -127,28 +97,28 @@
 
 <ul>
 <li><code>dev</code> is the keymaster device structure.</li>
-<li><code>key_to_attest</code> is the key blob returned from
-<code>generate_key</code> for which the attestation will be created.</li>
-<li><code>attest_params</code> is a list of any parameters necessary for
-attestation. This includes <code>KM_TAG_ATTESTATION_CHALLENGE</code> and
-possibly <code>KM_TAG_RESET_SINCE_ID_ROTATION</code>, as well as
-<code>KM_TAG_APPLICATION_ID</code> and <code>KM_TAG_APPLICATION_DATA</code>. The
+<li><code>keyToAttest</code> is the key blob returned from
+<code>generateKey</code> for which the attestation will be created.</li>
+<li><code>attestParams</code> is a list of any parameters necessary for
+attestation. This includes <code>Tag::ATTESTATION_CHALLENGE</code> and
+possibly <code>Tag::RESET_SINCE_ID_ROTATION</code>, as well as
+<code>Tag::APPLICATION_ID</code> and <code>Tag::APPLICATION_DATA</code>. The
 latter two are necessary to decrypt the key blob if they were specified during
 key generation.</li>
-<li><code>cert_chain</code> is the output parameter, which returns an array of
+<li><code>certChain</code> is the output parameter, which returns an array of
 certificates. Entry 0 is the attestation certificate, meaning it
-certifies the key from <code>key_to_attest</code> and contains the
+certifies the key from <code>keyToAttest</code> and contains the
 attestation extension.</li>
 </ul>
 
 <p>
-The <code>attest_key</code> method is considered a public key operation on the
+The <code>attestKey</code> method is considered a public key operation on the
 attested key, because it can be called at any time and doesn't need to meet
 authorization constraints. For example, if the attested key needs user
 authentication for use, an attestation can be generated without user
 authentication.
 </p>
-<h2 id="attestation-certificate">Attestation certificate</h2>
+<h3 id="attestation-certificate">Attestation certificate</h3>
 <p>
 The attestation certificate is a standard X.509 certificate, with an optional
 attestation extension that contains a description of the attested key. The
@@ -161,7 +131,7 @@
 contain any additional fields. Some fields specify a fixed field value. CTS
 tests validate that the certificate content is exactly as defined.
 </p>
-<h3 id="certificate-sequence">Certificate SEQUENCE</h3>
+<h4 id="certificate-sequence">Certificate SEQUENCE</h4>
 <table>
   <tr>
    <th>Field name (see
@@ -184,7 +154,7 @@
   </tr>
 </table>
 
-<h3 id="tbscertificate-sequence">TBSCertificate SEQUENCE</h3>
+<h4 id="tbscertificate-sequence">TBSCertificate SEQUENCE</h4>
 
 <table>
   <tr>
@@ -212,13 +182,14 @@
   <tr>
    <td><code>validity</code></td>
    <td>SEQUENCE of two dates, containing the values of
-   <code>KM_TAG_ACTIVE_DATETIME</code> and
-   <code>KM_TAG_USAGE_EXPIRE_DATETIME</code>. Those values are in milliseconds
-   since Jan 1, 1970. See <a href="https://tools.ietf.org/html/rfc5280">RFC
-	   5280</a> for correct date representations in certificates.<br />
-   If <code>KM_TAG_ACTIVE_DATETIME</code> is not present, use the value of
-   <code>KM_TAG_CREATION_DATETIME</code>. If
-   <code>KM_TAG_USAGE_EXPIRE_DATETIME</code> is not present, use the expiration
+   <a href="/security/keystore/tags#active_datetime">Tag::ACTIVE_DATETIME</a> and
+   <a href="/security/keystore/tags#usage_expire_datetime">Tag::USAGE_EXPIRE_DATETIME</a>.
+   Those values are in milliseconds since Jan 1, 1970.
+   See <a href="https://tools.ietf.org/html/rfc5280">RFC 5280</a> for correct
+   date representations in certificates.<br />
+   If <code>Tag::ACTIVE_DATETIME</code> is not present, use the value of
+   <code>Tag::CREATION_DATETIME</code>. If
+   <code>Tag::USAGE_EXPIRE_DATETIME</code> is not present, use the expiration
    date of the batch attestation key certificate.</td>
   </tr>
   <tr>
@@ -231,8 +202,8 @@
   </tr>
   <tr>
    <td><code>extensions/Key Usage</code></td>
-   <td>digitalSignature: set if key has purpose <code>KM_PURPOSE_SIGN</code> or
-   <code>KM_PURPOSE_VERIFY</code>. All other bits unset.</td>
+   <td>digitalSignature: set if key has purpose <code>KeyPurpose::SIGN</code> or
+   <code>KeyPurpose::VERIFY</code>. All other bits unset.</td>
   </tr>
   <tr>
    <td><code>extensions/CRL Distribution Points</code></td>
@@ -247,16 +218,19 @@
   </tr>
 </table>
 
-<h2 id="attestation-extension">Attestation extension</h2>
+<h3 id="attestation-extension">Attestation extension</h3>
 <p>
 The attestation extension contains a complete description of the keymaster
 authorizations associated with the key, in a structure that directly corresponds
 to the authorization lists as used in Android and the keymaster HAL. Each tag in
 an authorization list is represented by an ASN.1 SEQUENCE entry, explicitly
 tagged with the keymaster tag number, but with the type descriptor (four high
-order bits) masked out. For example, <code>KM_TAG_PURPOSE</code> is defined in
-keymaster_defs.h as <code>KM_ENUM_REP</code> | 1. For the attestation extension,
-the <code>KM_ENUM_REP</code> value is removed, leaving tag 1.
+order bits) masked out.</p>
+<p>For example, in Keymaster 3, <code>Tag::PURPOSE</code> is defined in
+types.hal as <code>ENUM_REP | 1</code>. For the attestation extension,
+the <code>ENUM_REP</code> value is removed, leaving tag <code>1</code>.
+(For Keymaster 2 and below, <code>KM_TAG_PURPOSE</code> is defined in 
+keymaster_defs.h.)
 </p>
 <p>
 Values are translated in a straightforward way to ASN.1 types, per this table:
@@ -267,63 +241,67 @@
    <th>ASN.1 type</th>
   </tr>
   <tr>
-   <td><code>KM_ENUM</code></td>
+   <td><code>ENUM</code></td>
    <td>INTEGER</td>
   </tr>
   <tr>
-   <td><code>KM_ENUM_REP</code></td>
+   <td><code>ENUM_REP</code></td>
    <td>SET of INTEGER</td>
   </tr>
   <tr>
-   <td><code>KM_UINT</code></td>
+   <td><code>UINT</code></td>
    <td>INTEGER</td>
   </tr>
   <tr>
-   <td><code>KM_UINT_REP</code></td>
+   <td><code>UINT_REP</code></td>
    <td>SET of INTEGER</td>
   </tr>
   <tr>
-   <td><code>KM_ULONG</code></td>
+   <td><code>ULONG</code></td>
    <td>INTEGER</td>
   </tr>
   <tr>
-   <td><code>KM_ULONG_REP</code></td>
+   <td><code>ULONG_REP</code></td>
    <td>SET of INTEGER</td>
   </tr>
   <tr>
-   <td><code>KM_DATE</code></td>
+   <td><code>DATE</code></td>
    <td>INTEGER (milliseconds since Jan 1, 1970 00:00:00 GMT)</td>
   </tr>
   <tr>
-   <td><code>KM_BOOL</code></td>
+   <td><code>BOOL</code></td>
    <td>NULL (in keymaster, tag present means true, absent means false.<br />
        The same semantics apply to the ASN.1 encoding)</td>
   </tr>
   <tr>
-   <td><code>KM_BIGNUM</code></td>
+   <td><code>BIGNUM</code></td>
    <td>Not presently used, so no mapping is defined</td>
   </tr>
   <tr>
-   <td><code>KM_BYTES</code></td>
+   <td><code>BYTES</code></td>
    <td>OCTET_STRING</td>
   </tr>
 </table>
 <p class="note">
 <strong>Note:</strong> Some tags are omitted from the schema and should not be
-included in attestations. For example, the values of <code>KM_TAG_USER_ID</code>
-and <code>KM_TAG_SECURE_USER_ID</code> have no meaning off-device, and
-<code>KM_TAG_MIN_MAC_LENGTH</code> and <code>KM_TAG_CALLER_NONCE</code> are
+included in attestations. For example, the values of <code>Tag::USER_ID</code>
+and <code>Tag::SECURE_USER_ID</code> have no meaning off-device, and
+<code>Tag::MIN_MAC_LENGTH</code> and <code>Tag::CALLER_NONCE</code> are
 useless with asymmetric keys.
 </p>
 
-<h3 id="schema">Schema</h3>
+<h4 id="schema">Schema</h4>
 <p>
-The attestation extension content is described by the following ASN.1 schema:
+The attestation extension content is described by the following ASN.1 schema.
+This example also includes Keymaster 3 updates to include
+<a href="#id-attestation">ID attestation</a> features, which are in bold with
+comments.
 </p>
 
-<pre class="prettyprint">
+
+<pre class="devsite-click-to-copy">
 KeyDescription ::= SEQUENCE {
-  attestationVersion         INTEGER,
+  <strong>attestationVersion         INTEGER,</strong> # KM2 value is 1. KM3 value is 2.
   attestationSecurityLevel   SecurityLevel,
   keymasterVersion           INTEGER,
   keymasterSecurityLevel     SecurityLevel,
@@ -360,6 +338,15 @@
   rootOfTrust                [704] EXPLICIT RootOfTrust OPTIONAL,
   osVersion                  [705] EXPLICIT INTEGER OPTIONAL,
   osPatchLevel               [706] EXPLICIT INTEGER OPTIONAL,
+  <strong>attestationApplicationId   [709] EXPLICIT OCTET_STRING OPTIONAL,</strong> # KM3
+  <strong>attestationIdBrand         [710] EXPLICIT OCTET_STRING OPTIONAL,</strong> # KM3
+  <strong>attestationIdDevice        [711] EXPLICIT OCTET_STRING OPTIONAL,</strong> # KM3
+  <strong>attestationIdProduct       [712] EXPLICIT OCTET_STRING OPTIONAL,</strong> # KM3
+  <strong>attestationIdSerial        [713] EXPLICIT OCTET_STRING OPTIONAL,</strong> # KM3
+  <strong>attestationIdImei          [714] EXPLICIT OCTET_STRING OPTIONAL,</strong> # KM3
+  <strong>attestationIdMeid          [715] EXPLICIT OCTET_STRING OPTIONAL,</strong> # KM3
+  <strong>attestationIdManufacturer  [716] EXPLICIT OCTET_STRING OPTIONAL,</strong> # KM3
+  <strong>attestationIdModel         [717] EXPLICIT OCTET_STRING OPTIONAL,</strong> # KM3
 }
 RootOfTrust ::= SEQUENCE {
   verifiedBootKey            OCTET_STRING,
@@ -374,8 +361,7 @@
   Failed                     (3),
 }</pre>
 
-
-<h3 id="keydescription-fields">KeyDescription fields</h3>
+<h4 id="keydescription-fields">KeyDescription fields</h4>
 <p>
 The keymasterVersion and attestationChallenge fields are identified
 positionally, rather than by tag, so the tags in the encoded form only specify
@@ -413,14 +399,14 @@
   <tr>
    <td><code>attestationChallenge</code></td>
    <td>OCTET_STRING</td>
-   <td>Value of <code>KM_TAG_ATTESTATION_CHALLENGE</code>, specified to
+   <td>Value of <code>Tag::ATTESTATION_CHALLENGE</code>, specified to
 attestation request.</td>
   </tr>
   <tr>
    <td><code>uniqueId</code></td>
    <td>OCTET_STRING</td>
    <td>Optional unique ID, present if key has
-<code>KM_TAG_INCLUDE_UNIQUE_ID</code></td>
+<code>Tag::INCLUDE_UNIQUE_ID</code></td>
   </tr>
   <tr>
    <td><code>softwareEnforced</code></td>
@@ -435,25 +421,26 @@
   </tr>
 </table>
 
-<h3 id="authorizationlist-fields">AuthorizationList fields</h3>
+<h4 id="authorizationlist-fields">AuthorizationList fields</h4>
 <p>
 AuthorizationList fields are all optional and are identified by keymaster tag
 value, with the type bits masked out. Explicit tagging is used so the fields
 also contain a tag indicating their ASN.1 type, for easier parsing.
 </p>
 <p>
-See keymaster_defs.h for details on each field's values. Keymaster tag names
+For details on each field's values, see types.hal for Keymaster 3 and 
+keymaster_defs.h for Keymaster 2 and below. Keymaster tag names
 were transformed into field names by omitting the KM_TAG prefix and changing the
-remainder to camel case, so <code>KM_TAG_KEY_SIZE</code> became
+remainder to camel case, so <code>Tag::KEY_SIZE</code> became
 <code>keySize</code>.
 </p>
 <p class="note">
-<strong>Note</strong>: Many tags from keymaster_defs.h are not included in the
+<strong>Note</strong>: Many tags from types.hal and keymaster_defs.h are not included in the
 schema. Some tags are not applicable to asymmetric keys, some have no meaning
 off-device, etc.
 </p>
 
-<h3 id="rootoftrust-fields">RootOfTrust fields</h3>
+<h4 id="rootoftrust-fields">RootOfTrust fields</h4>
 <p>
 The RootOfTrust Fields are identified positionally.
 </p>
@@ -496,7 +483,7 @@
 2016 would be represented as 201604.</td>
   </tr>
 </table>
-<h3 id="verifiedbootstate-values">VerifiedBootState values</h3>
+<h4 id="verifiedbootstate-values">VerifiedBootState values</h4>
 <p>
 The values of <code>verifiedBootState</code> have the following meanings:
 </p>
@@ -537,7 +524,7 @@
   </tr>
 </table>
 
-<h3 id="securitylevel-values">SecurityLevel values</h3>
+<h4 id="securitylevel-values">SecurityLevel values</h4>
 <p>
 The values of securityLevel have the following meanings:
 </p>
@@ -560,13 +547,13 @@
 compromise and moderately resistant to compromise by direct hardware attack.</td>
   </tr>
 </table>
-<h2 id="unique-id">Unique ID</h2>
+<h3 id="unique-id">Unique ID</h3>
 <p>
 The Unique ID is a 128-bit value that identifies the device, but only for a
 limited period of time. The value is computed with:
 </p>
 
-<pre class="prettyprint">
+<pre class="devsite-click-to-copy">
 HMAC_SHA256(T || C || R, HBK)
 </pre>
 
@@ -576,11 +563,11 @@
 
 <ul>
 <li><code>T</code> is the "temporal counter value", computed by dividing the
-value of <code>KM_TAG_CREATION_DATETIME</code> by 2592000000, dropping any
+value of <code>Tag::CREATION_DATETIME</code> by 2592000000, dropping any
 remainder. <code>T</code> changes every 30 days (2592000000 = 30 * 24 * 60 * 60
 * 1000).</li>
-<li><code>C</code> is the value of <code>KM_TAG_APPLICATION_ID</code></li>
-<li><code>R</code> is 1 if <code>KM_TAG_RESET_SINCE_ID_ROTATION</code> is
+<li><code>C</code> is the value of <code>Tag::APPLICATION_ID</code></li>
+<li><code>R</code> is 1 if <code>Tag::RESET_SINCE_ID_ROTATION</code> is
 present in the attest_params parameter to the attest_key call, or 0 if the tag
 is not present.</li>
 <li><code>HBK</code> is a unique hardware-bound secret known to the Trusted
@@ -593,11 +580,230 @@
 Truncate the HMAC_SHA256 output to 128 bits.
 </p>
 
-<h2 id="attestation-keys-and-certificates">Attestation keys and
-certificates</h2>
+<h3 id="attestation-keys-and-certificates">Attestation keys and
+certificates</h3>
 <p>
 Two keys, one RSA and one ECDSA, and the corresponding certificate chains, are
 securely provisioned into the device.
 </p>
+
+<h2 id="id-attestation">ID attestation</h2>
+
+<p>
+Android 8.0 includes optional support for ID attestation for devices with
+Keymaster 3. ID attestation allows the device to provide proof of its hardware
+identifiers, such as serial number or IMEI. Although an optional feature, it is
+highly recommended that all Keymaster 3 implementations provide support for it
+because being able to prove the device's identity enables use cases such as true
+zero-touch remote configuration to be more secure (because the remote side can
+be certain it is talking to the right device, not a device spoofing its
+identity).
+</p>
+<p>
+ID attestation works by creating copies of the device's hardware identifiers
+that only the Trusted Execution Environment (TEE) can access before the device
+leaves the factory. A user may unlock the device's bootloader and change the
+system software and the identifiers reported by the Android frameworks. The
+copies of the identifiers held by the TEE cannot be manipulated in this way,
+ensuring that device ID attestation will only ever attest to the device's
+original hardware identifiers thereby thwarting spoofing attempts.
+</p>
+<p>
+The main API surface for ID attestation builds on top of the existing key
+attestation mechanism introduced with Keymaster 2. When requesting an attestation
+certificate for a key held by keymaster, the caller may request that the
+device's hardware identifiers be included in the attestation certificate's
+metadata. If the key is held in the TEE, the certificate will chain back to a
+known root of trust. The recipient of such a certificate can verify that the
+certificate and its contents, including the hardware identifiers, were written
+by the TEE. When asked to include hardware identifiers in the attestation
+certificate, the TEE attests only to the identifiers held in its storage, as
+populated on the factory floor.
+</p>
+
+<h3 id="storage-properties">Storage properties</h3>
+<p>
+The storage that holds the device's identifiers needs to have these properties:
+</p>
+<ul>
+  <li>The values derived from the device's original identifiers are copied to the
+  storage before the device leaves the factory.</li>
+  <li>The <code>destroyAttestationIds()</code> method can permanently destroy this
+  copy of the identifier-derived data. Permanent destruction means the data is
+  completely removed so neither a factory reset nor any other procedure performed
+  on the device can restore it. This is especially important for devices where
+  a user has unlocked the bootloader and changed the system software and modified
+  the identifiers returned by Android frameworks.</li>
+  <li>RMA facilities should have the ability to
+  generate fresh copies of the hardware identifier-derived data. This way, a
+  device that passes through RMA can perform ID attestation again. The mechanism
+  used by RMA facilities must be protected so that users cannot invoke it
+  themselves, as that would allow them to obtain attestations of spoofed IDs.</li>
+  <li>No code other than Keymaster trusted app in the TEE is able to read the
+  identifier-derived data kept in the storage.</li>
+  <li>The storage is tamper-evident: If the content of the storage has been
+  modified, the TEE treats it the same as if the copies of the content had been
+  destroyed and refuses all ID attestation attempts. This is implemented by
+  signing or MACing the storage <a href="#construction">as described below</a>.</li>
+  <li>The storage does not hold the original identifiers. Because ID attestation
+  involves a challenge, the caller always supplies the identifiers to be attested.
+  The TEE only needs to verify that these match the values they originally had.
+  Storing secure hashes of the original values rather than the values enables this
+  verification.</li>
+</ul>
+
+<h3 id="construction">Construction</h3>
+<p>
+To create an implementation that has the properties listed above, store the
+ID-derived values in the following construction S. Do not store other copies of
+the ID values, excepting the normal places in the system, which a device owner
+may modify by rooting:
+</p>
+
+<pre class="devsite-click-to-copy">S = D || HMAC(HBK, D)</pre>
+<p>
+where:
+</p>
+<ul>
+  <li><code>D = HMAC(HBK, ID<sub>1</sub>) || HMAC(HBK, ID<sub>2</sub>) || ... ||
+  HMAC(HBK, ID<sub>n</sub>)</code></li>
+  <li><code>HMAC</code> is the HMAC construction with an appropriate secure hash
+  (SHA-256 recommended)</li>
+  <li><code>HBK</code> is a hardware-bound key not used for any other purpose</li>
+  <li><code>ID<sub>1</sub>...ID<sub>n</sub></code> are the original ID values; association of a
+  particular value to a particular index is implementation-dependent, as different
+  devices will have different numbers of identifiers</li>
+  <li><code>||</code> represents concatenation</li>
+</ul>
+<p>
+Because the HMAC outputs are fixed size, no headers or other structure are
+required to be able to find individual ID hashes, or the HMAC of D. In addition
+to checking provided values to perform attestation, implementations need to 
+validate S by extracting D from S, computing HMAC(HBK, D) and comparing it to
+the value in S to verify that no individual IDs were modified/corrupted. Also,
+implementations must use constant-time comparisons for all individual ID
+elements and the validation of S. Comparison time must be constant regardless of
+the number of IDs provided and the correct matching of any part of the test.
+</p>
+<h3 id="hardware-identifiers">Hardware identifiers</h3>
+<p>
+ID attestation supports the following hardware identifiers:
+</p>
+<ol>
+  <li>Brand name, as returned by <code>Build.BRAND</code> in Android</li>
+  <li>Device name, as returned by <code>Build.DEVICE</code> in Android</li>
+  <li>Product name, as returned by <code>Build.PRODUCT</code> in Android</li>
+  <li>Manufacturer name, as returned by <code>Build.MANUFACTURER</code> in Android</li>
+  <li>Model name, as returned by <code>Build.MODEL</code> in Android</li>
+  <li>Serial number</li>
+  <li>IMEIs of all radios</li>
+  <li>MEIDs of all radios</li>
+</ol>
+<p>
+To support device ID attestation, a device attests to these identifiers. All
+devices running Android have the first six and they are necessary for this
+feature to work. If the device has any radios, it needs to support attestation
+for the IMEIs and/or MEIDs of the radios, too.
+</p>
+<p>
+ID attestation is requested by performing a key attestation and including the
+device identifiers to attest in the request. The identifiers are tagged as:
+</p>
+<ul>
+  <li><code>ATTESTATION_ID_BRAND</code></li>
+  <li><code>ATTESTATION_ID_DEVICE</code></li>
+  <li><code>ATTESTATION_ID_PRODUCT</code></li>
+  <li><code>ATTESTATION_ID_MANUFACTURER</code></li>
+  <li><code>ATTESTATION_ID_MODEL</code></li>
+  <li><code>ATTESTATION_ID_SERIAL</code></li>
+  <li><code>ATTESTATION_ID_IMEI</code></li>
+  <li><code>ATTESTATION_ID_MEID</code></li>
+</ul>
+<p>
+The identifier to attest is a UTF-8 encoded byte string. This format applies to
+numerical identifiers, as well. Each identifier to attest is expressed as a
+UTF-8 encoded string.
+</p>
+<p>
+If the device does not support ID attestation (or
+<code>destroyAttestationIds()</code> was previously called and the device can no
+longer attest its IDs), any key attestation request that includes one or more of
+these tags fails with <code>ErrorCode::CANNOT_ATTEST_IDS</code>.
+</p>
+<p>
+If the device supports ID attestation and one or more of the above tags have
+been included in a key attestation request, the TEE verifies the identifier
+supplied with each of the tags matches its copy of the hardware identifiers. If
+one or more identifiers do not match, the entire attestation fails with
+<code>ErrorCode::CANNOT_ATTEST_IDS</code>. It is valid for the same tag to be
+supplied multiple times. This can be useful, for example, when attesting IMEIs:
+A device may have multiple radios with multiple IMEIs. An attestation request is
+valid if the value supplied with each <code>ATTESTATION_ID_IMEI</code> matches
+one of the device's radios. The same applies to all other tags.
+</p>
+<p>
+If attestation is successful, the attested IDs is added to the
+<a href="#attestation-extension">attestation extension</a>
+(OID 1.3.6.1.4.1.11129.2.1.17) of the issued attestation certificate,
+using the <a href="#schema">schema from above</a>. Changes from the Keymaster 2
+attestation schema are <strong>bolded</strong>, with comments.
+</p>
+
+
+<h2 id="java-api">Java API</h2>
+<p>
+This section is informational only. Keymaster implementers neither
+implement nor use the Java API. This is provided to help implementers understand
+how the feature is used by applications. System components may use it
+differently, which is why it's crucial this section not be treated as normative.
+</p>
+
+<section class="expandable">
+  <h4 class="showalways">How application developers use attestation</h4>
+<ul>
+<li>Creates a key generation request, specifying a key alias and key generation
+parameters for an EC or RSA key pair.</li>
+<li>Sets the "attestation challenge" for the request, with
+<code>KeyPairGenerator.setAttestationChallenge(byte[])</code>. This both
+provides challenge data (which may be empty), and indicates that an attestation
+is requested.</li>
+<li>Generates the key pair.</li>
+<li>Requests the certificate chain from <code>AndroidKeyStore</code>. The first
+certificate in the chain is the attestation; the other certificates provide the
+chain of trust back to and including the root attestation key.</li>
+</ul>
+<p>
+This example generates a key pair and requests an attestation.
+</p>
+
+<pre class="devsite-click-to-copy">// Create KeyPairGenerator and set generation parameters for an ECDSA key pair
+// using the NIST P-256 curve.  "Key1" is the key alias.
+KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(
+    KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore");
+    keyPairGenerator.initialize(
+         new KeyGenParameterSpec.Builder("Key1", KeyProperties.PURPOSE_SIGN)
+             .setAlgorithmParameterSpec(new ECGenParameterSpec("secp256r1"))
+             .setDigests(KeyProperties.DIGEST_SHA256,
+                         KeyProperties.DIGEST_SHA384,
+                         KeyProperties.DIGEST_SHA512)
+             // Only permit the private key to be used if the user
+             // authenticated within the last five minutes.
+             .setUserAuthenticationRequired(true)
+             .setUserAuthenticationValidityDurationSeconds(5 * 60)
+             // Request an attestation with challenge "hello world".
+             .setAttestationChallenge("hello world".toBytes());
+             .build());
+// Generate the key pair. This will result in calls to both generate_key() and
+// attest_key() at the keymaster2 HAL.
+KeyPair keyPair = keyPairGenerator.generateKeyPair();
+// Get the certificate chain
+KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
+keyStore.load(null);
+Certificate[] certs = keyStore.getCertificateChain("Key1");
+// certs[0] is the attestation certificate. certs[1] signs certs[0], etc.,
+// up to certs[certs.length - 1].
+</pre>
+</section>
+
 </body>
 </html>
diff --git a/en/security/keystore/features.html b/en/security/keystore/features.html
index 05da174..e907609 100644
--- a/en/security/keystore/features.html
+++ b/en/security/keystore/features.html
@@ -26,20 +26,24 @@
 <p>This page contains information about the cryptographic features of
 <a href="index.html">Keystore</a> in Android 6.0 and above.</p>
 
-<h2 id=cryptographic_primitives>Cryptographic primitives</h2>
+<p class="note"><strong>Note</strong>: Tags and functions are written in
+Keymaster 3 style. For more information, see the
+<a href="/security/keystore/index##hidl-overview">HIDL overview</a>.</p>
+
+<h2 id="cryptographic_primitives">Cryptographic primitives</h2>
 
 <p>Keystore provides the following categories of operations:</p>
 
 <ul>
-  <li>Key generation
-  <li>Import and export of asymmetric keys (no key wrapping)
-  <li>Import of raw symmetric keys (no key wrapping)
-  <li>Asymmetric encryption and decryption with appropriate padding modes
+  <li>Key generation</li>
+  <li>Import and export of asymmetric keys (no key wrapping)</li>
+  <li>Import of raw symmetric keys (no key wrapping)</li>
+  <li>Asymmetric encryption and decryption with appropriate padding modes</li>
   <li>Asymmetric signing and verification with digesting and appropriate padding
-modes
+modes</li>
   <li>Symmetric encryption and decryption in appropriate modes, including an AEAD
-mode
-  <li>Generation and verification of symmetric message authentication codes
+mode</li>
+  <li>Generation and verification of symmetric message authentication codes</li>
 </ul>
 
 <p>Protocol elements, such as purpose, mode and padding, as well
@@ -60,48 +64,54 @@
 <ul>
   <li><a href="http://en.wikipedia.org/wiki/RSA_(cryptosystem)">RSA</a>
   <ul>
-    <li>2048, 3072, and 4096-bit key support
-    <li>Support for public exponent F4 (2^16+1)
+    <li>2048, 3072, and 4096-bit key support</li>
+    <li>Support for public exponent F4 (2^16+1)</li>
     <li>Padding modes for RSA signing:
-    <ul>
-      <li>RSASSA-PSS (<code>KM_PAD_RSA_PSS</code>)
-      <li>RSASSA-PKCS1-v1_5 (<code>KM_PAD_RSA_PKCS1_1_5_SIGN</code>)
-    </ul>
+      <ul>
+        <li>RSASSA-PSS (<code>PaddingMode::RSA_PSS</code>)</li>
+        <li>RSASSA-PKCS1-v1_5 (<code>PaddingMode::RSA_PKCS1_1_5_SIGN</code>)</li>
+      </ul>
+    </li>
     <li>Digest modes for RSA signing:
-    <ul>
-      <li>SHA-256
-    </ul>
+      <ul>
+        <li>SHA-256</li>
+      </ul>
+    </li>
     <li>Padding modes for RSA encryption/decryption:
-    <ul>
-      <li>Unpadded
-      <li>RSAES-OAEP (<code>KM_PAD_RSA_OAEP</code>)
-      <li>RSAES-PKCS1-v1_5 (<code>KM_PAD_RSA_PKCS1_1_5_ENCRYPT</code>)
-    </ul>
+      <ul>
+        <li>Unpadded</li>
+        <li>RSAES-OAEP (<code>PaddingMode::RSA_OAEP</code>)</li>
+        <li>RSAES-PKCS1-v1_5 (<code>PaddingMode::RSA_PKCS1_1_5_ENCRYPT</code>)</li>
+      </ul>
+    </li>
   </ul>
+  </li>
   <li><a href="http://en.wikipedia.org/wiki/Elliptic_Curve_DSA">ECDSA</a>
   <ul>
-    <li>224, 256, 384, and 521-bit key support are supported, using the NIST P-224,
-P-256, P-384, and P-521 curves, respectively
+    <li>224, 256, 384, and 521-bit key support are supported, using the
+    NIST P-224, P-256, P-384, and P-521 curves, respectively</li>
     <li>Digest modes for ECDSA:
     <ul>
       <li>No digest (deprecated, will be removed in the future)</li>
       <li>SHA-256</li>
     </ul>
+    </li>
   </ul>
+  </li>
   <li><a href="http://en.wikipedia.org/wiki/Advanced_Encryption_Standard">AES</a>
   <ul>
-    <li>128 and 256-bit keys are supported
+    <li>128 and 256-bit keys are supported</li>
     <li><a href="http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher-block_chaining_.28CBC.29">CBC</a>,
     CTR, ECB, and GCM. The GCM implementation does not allow the use of tags
-smaller than 96 bits or nonce lengths other than 96 bits.
-    <li>Padding modes <code>KM_PAD_NONE</code> and <code>KM_PAD_PKCS7</code> is
+    smaller than 96 bits or nonce lengths other than 96 bits.</li>
+    <li>Padding modes <code>PaddingMode::NONE</code> and <code>PaddingMode::PKCS7</code> is
     supported for CBC and ECB modes. With no padding, CBC or ECB mode
-    encryption fails if the input isn't a multiple of the block size.
+    encryption fails if the input isn't a multiple of the block size.</li>
   </ul>
+  </li>
   <li><a href="http://en.wikipedia.org/wiki/Hash-based_message_authentication_code">HMAC</a>
   <a href="http://en.wikipedia.org/wiki/SHA-2">SHA-256</a>, with any key size up
-  to at least 32 bytes.
-</ul>
+  to at least 32 bytes.</li>
 </ul>
 
 <p>SHA1 and the other members of the SHA2 family (SHA-224, SHA384 and SHA512) are
@@ -111,11 +121,11 @@
 <p>Some primitives are also recommended for interoperability with other systems:</p>
 
 <ul>
-  <li>Smaller key sizes for RSA
-  <li>Arbitrary public exponents for RSA
+  <li>Smaller key sizes for RSA</li>
+  <li>Arbitrary public exponents for RSA</li>
 </ul>
 
-<h2 id=key_access_control>Key access control</h2>
+<h2 id="key_access_control">Key access control</h2>
 
 <p>Hardware-based keys that can never be extracted from the device don't provide
 much security if an attacker can use them at will (though they're more secure
@@ -134,53 +144,57 @@
 key for any cryptographic operation fails if the final authorization list is
 modified.</p>
 
-<p>The set of possible tags is defined in the enumeration
+<p>For Keymaster 2 and earlier, the set of possible tags
+is defined in the enumeration
 <code>keymaster_authorization_tag_t</code> and
 is permanently fixed (though it can be extended).
-Names are prefixed with <code>KM_TAG_</code>. The top
+Names were prefixed with <code>KM_TAG</code>. The top
 four bits of tag IDs are used to indicate the type.</p>
 
+<p>Keymaster 3 changed the <code>KM_TAG</code> prefix to
+<code>Tag::</code>.</p>
+
 <p>Possible types include:</p>
 
-<p><strong><code>KM_ENUM</code>:</strong> Many tags' values are defined in
-enumerations. For example, the possible values of <code>KM_TAG_PURPOSE</code>
+<p><strong><code>ENUM</code>:</strong> Many tags' values are defined in
+enumerations. For example, the possible values of <code>TAG::PURPOSE</code>
 are defined in enum <code>keymaster_purpose_t</code>.</p>
 
-<p><strong><code>KM_ENUM_REP</code></strong>: Same as <code>KM_ENUM</code>,
+<p><strong><code>ENUM_REP</code></strong>: Same as <code>ENUM</code>,
 except that the tag may be repeated in an authorization list. Repetition
 indicates multiple authorized values. For example, an encryption key
-likely has <code>KM_PURPOSE_ENCRYPT</code> and <code>KM_PURPOSE_DECRYPT</code>.</p>
+likely has <code>KeyPurpose::ENCRYPT</code> and <code>KeyPurpose::DECRYPT</code>.</p>
 
-<p><strong><code>KM_UINT</code>:</strong> 32-bit unsigned integers. Example:
-<code>KM_TAG_KEY_SIZE</code></p>
+<p><strong><code>UINT</code>:</strong> 32-bit unsigned integers. Example:
+<code>TAG::KEY_SIZE</code></p>
 
-<p><strong><code>KM_UINT_REP</code></strong>: Same as <code>KM_UINT</code>,
+<p><strong><code>UINT_REP</code></strong>: Same as <code>UINT</code>,
 except that the tag may be repeated in an authorization list. Repetition
 indicates multiple authorized values.</p>
 
-<p><strong><code>KM_ULONG</code></strong>: 64-bit unsigned integers. Example:
-<code>KM_TAG_RSA_PUBLIC_EXPONENT</code></p>
+<p><strong><code>ULONG</code></strong>: 64-bit unsigned integers. Example:
+<code>TAG::RSA_PUBLIC_EXPONENT</code></p>
 
-<p><strong><code>KM_ULONG_REP</code></strong>: Same as <code>KM_ULONG</code>,
+<p><strong><code>ULONG_REP</code></strong>: Same as <code>ULONG</code>,
 except that the tag may be repeated in an authorization list. Repetition
 indicates multiple authorized values.</p>
 
-<p><strong><code>KM_DATE</code></strong>: Date/time values, expressed as
+<p><strong><code>DATE</code></strong>: Date/time values, expressed as
 milliseconds since January 1, 1970.
-Example: <code>KM_TAG_PRIVKEY_EXPIRE_DATETIME</code></p>
+Example: <code>TAG::PRIVKEY_EXPIRE_DATETIME</code></p>
 
-<p><strong><code>KM_BOOL</code></strong>: True or false. A tag of type
-<code>KM_BOOL</code> is assumed to be "false" if the tag is not present and
-"true" if present. Example: <code>KM_TAG_ROLLBACK_RESISTANT</code></p>
+<p><strong><code>BOOL</code></strong>: True or false. A tag of type
+<code>BOOL</code> is assumed to be "false" if the tag is not present and
+"true" if present. Example: <code>TAG::ROLLBACK_RESISTANT</code></p>
 
-<p><strong><code>KM_BIGNUM</code></strong>: Arbitrary-length integers,
+<p><strong><code>BIGNUM</code></strong>: Arbitrary-length integers,
 expressed as a byte array in big-endian order. Example:
-<code>KM_TAG_RSA_PUBLIC_EXPONENT</code></p>
+<code>TAG::RSA_PUBLIC_EXPONENT</code></p>
 
-<p><strong><code>KM_BYTES</code></strong>: A sequence of bytes. Example:
-<code>KM_TAG_ROOT_OF_TRUST</code></p>
+<p><strong><code>BYTES</code></strong>: A sequence of bytes. Example:
+<code>TAG::ROOT_OF_TRUST</code></p>
 
-<h3 id=hardware_vs_software_enforcement>Hardware vs. software enforcement</h3>
+<h3 id="hardware_vs_software_enforcement">Hardware vs. software enforcement</h3>
 
 <p>Not all secure hardware implementations contain the same features. To support
 a variety of approaches, Keymaster distinguishes between secure and non-secure
@@ -190,14 +204,11 @@
 <p>All implementations:</p>
 
 <ul>
-
   <li>Enforce exact matching (not enforcement) of all authorizations.
   Authorization lists in key blobs exactly match the authorizations
   returned during key generation, including ordering. Any mismatch causes an
-  error diagnostic.
-
-  <li>Declare the authorizations whose semantic values are enforced.
-
+  error diagnostic.</li>
+  <li>Declare the authorizations whose semantic values are enforced.</li>
 </ul>
 
 <p>The API mechanism for declaring hardware-enforced authorizations is in the
@@ -212,7 +223,7 @@
 <p>For example, consider a TrustZone-based implementation that does not support
 key expiration. A key with an expiration date may still be created. That key's
 authorization list will include the tag
-<code>KM_TAG_ORIGINATION_EXPIRE_DATETIME</code> with the expiration date. A
+<code>TAG::ORIGINATION_EXPIRE_DATETIME</code> with the expiration date. A
 request to Keystore for the key characteristics will find this tag in the
 <code>sw_enforced</code> list and the secure hardware will not enforce the
 expiration requirement. However, attempts to use the key after expiration will
@@ -220,37 +231,38 @@
 
 <p>If the device is then upgraded with secure hardware that does support
 expiration, then a request for key characteristics will find
-<code>KM_TAG_ORIGINATION_EXPIRE_DATETIME</code> in the <code>hw_enforced</code>
+<code>TAG::ORIGINATION_EXPIRE_DATETIME</code> in the <code>hw_enforced</code>
 list, and attempts to use the key after expiration will fail even if the
 keystore is somehow subverted or bypassed.</p>
 
 <p>For more information about determining whether keys are hardware-backed,
-see <a href="/security/keystore/attestation">Key attestation</a>.
+see <a href="/security/keystore/attestation">Key attestation</a>.</p>
 
-<h3 id=cryptographic_message_construction_authorizations>Cryptographic message construction authorizations</h3>
+<h3 id="cryptographic_message_construction_authorizations">
+Cryptographic message construction authorizations</h3>
 
 <p>The following tags are used to define the cryptographic characteristics of
-operations using the associated key: <code>KM_TAG_ALGORITHM</code>,
-<code>KM_TAG_KEY_SIZE</code>, <code>KM_TAG_BLOCK_MODE</code>,
-<code>KM_TAG_PADDING</code>, <code>KM_TAG_CALLER_NONCE</code>,
-and <code>KM_TAG_DIGEST</code></p>
+operations using the associated key: <code>TAG::ALGORITHM</code>,
+<code>TAG::KEY_SIZE</code>, <code>TAG::BLOCK_MODE</code>,
+<code>TAG::PADDING</code>, <code>TAG::CALLER_NONCE</code>,
+and <code>TAG::DIGEST</code></p>
 
-<p><code>KM_TAG_PADDING</code>, <code>KM_TAG_DIGEST</code>,
-and <code>KM_PAD_BLOCK_MODE</code> are repeatable, meaning that multiple values
+<p><code>TAG::PADDING</code>, <code>TAG::DIGEST</code>,
+and <code>PaddingMode::BLOCK_MODE</code> are repeatable, meaning that multiple values
 may be associated with a single key, and the value to be used is specified at
 operation time.</p>
 
-<h3 id=purpose>Purpose</h3>
+<h3 id="purpose">Purpose</h3>
 
 <p>Keys have an associated set of purposes, expressed as one or more authorization
-entries with tag <code>KM_TAG_PURPOSE</code>, which defines how they can be used.
+entries with tag <code>TAG::PURPOSE</code>, which defines how they can be used.
 The purposes are:</p>
 
 <ul>
-  <li><code>KM_PURPOSE_ENCRYPT</code>
-  <li><code>KM_PURPOSE_DECRYPT</code>
-  <li><code>KM_PURPOSE_SIGN</code>
-  <li><code>KM_PURPOSE_VERIFY</code>
+  <li><code>KeyPurpose::ENCRYPT</code></li>
+  <li><code>KeyPurpose::DECRYPT</code></li>
+  <li><code>KeyPurpose::SIGN</code></li>
+  <li><code>KeyPurpose::VERIFY</code></li>
 </ul>
 
 <p>Any key can have any subset of these purposes. Note that some combinations
@@ -258,26 +270,26 @@
 encrypt and to sign allows an attacker who can convince the system to decrypt
 arbitrary data to generate signatures.</p>
 
-<h3 id=import_and_export>Import and export</h3>
+<h3 id="import_and_export">Import and export</h3>
 
 <p>Keymaster supports export of public keys only, in X.509 format, and import of:</p>
 
 <ul>
   <li>Public and private key pairs in DER-encoded PKCS#8 format, without
-password-based encryption, and
-  <li>Symmetric keys as raw bytes
+password-based encryption, and</li>
+  <li>Symmetric keys as raw bytes</li>
 </ul>
 
 <p>To ensure that imported keys can be distinguished from securely-generated
-keys, <code>KM_TAG_ORIGIN</code> is included in the appropriate key
+keys, <code>TAG::ORIGIN</code> is included in the appropriate key
 authorization list. For example, if a key
-was generated in secure hardware, <code>KM_TAG_ORIGIN</code> with
-value <code>KM_ORIGIN_GENERATED</code> will be found in
+was generated in secure hardware, <code>TAG::ORIGIN</code> with
+value <code>KeyOrigin::GENERATED</code> will be found in
 the <code>hw_enforced</code> list of the key characteristics, while a key
 that was imported into secure
-hardware will have the value <code>KM_ORIGIN_IMPORTED</code>.</p>
+hardware will have the value <code>KeyOrigin::IMPORTED</code>.</p>
 
-<h3 id=user_authentication>User authentication</h3>
+<h3 id="user_authentication">User authentication</h3>
 
 <p>Secure Keymaster implementations do not implement user authentication, but
 depend on other trusted apps which do. For the interface that these apps
@@ -287,28 +299,28 @@
 set indicate which user can use the key:</p>
 
 <ul>
-  <li><code>KM_TAG_ALL_USERS</code> indicates the key is usable by all users. If
-  present, <code>KM_TAG_USER_ID</code> and <code>KM_TAG_USER_SECURE_ID</code> is
+  <li><code>TAG::ALL_USERS</code> indicates the key is usable by all users. If
+  present, <code>TAG::USER_ID</code> and <code>TAG::USER_SECURE_ID</code> is
   not present.</li>
-  <li><code>KM_TAG_USER_ID</code> has a numeric value specifying the ID of the
+  <li><code>TAG::USER_ID</code> has a numeric value specifying the ID of the
    authorized user. Note that this is the Android user ID (for multi-user), not
    the application UID, and it is enforced by non-secure software only. If
-   present, <code>KM_TAG_ALL_USERS</code> is not present.</li>
-  <li><code>KM_TAG_USER_SECURE_ID</code> has a 64-bit numeric value specifying
+   present, <code>TAG::ALL_USERS</code> is not present.</li>
+  <li><code>TAG::USER_SECURE_ID</code> has a 64-bit numeric value specifying
    the secure user ID that is provided in a secure authentication token to
    unlock use of the key. If repeated, the key may be used if any of the values
    is provided in a secure authentication token.</li>
 </ul>
 
 <p>The second set indicates whether and when the user needs to be authenticated.
-If neither of these tags is present, but <code>KM_TAG_USER_SECURE_ID</code> is,
+If neither of these tags is present, but <code>TAG::USER_SECURE_ID</code> is,
 authentication is required for every use of the key.</p>
 
 <ul>
-  <li><code>KM_NO_AUTHENTICATION_REQUIRED</code> indicates no user
+  <li><code>NO_AUTHENTICATION_REQUIRED</code> indicates no user
   authentication is required, though the key still may only be used by apps
-  running as the user(s) specified by <code>KM_TAG_USER_ID</code>.</li>
-  <li><code>KM_TAG_AUTH_TIMEOUT</code> is a numeric value specifying, in
+  running as the user(s) specified by <code>TAG::USER_ID</code>.</li>
+  <li><code>TAG::AUTH_TIMEOUT</code> is a numeric value specifying, in
   seconds, how fresh the user authentication needs to be to authorize key usage.
   This applies only to private/secret key operations. Public key operations
   don't require authentication. Timeouts do not cross reboots; after a reboot,
@@ -317,35 +329,35 @@
   years; presumably Android devices are rebooted more often than that).</li>
 </ul>
 
-<h3 id=client_binding>Client binding</h3>
+<h3 id="client_binding">Client binding</h3>
 
 <p>Client binding, the association of a key with a particular client
 application, is done via an optional client ID and some optional client data
-(<code>KM_TAG_APPLICATION_ID</code> and <code>KM_TAG_APPLICATION_DATA</code>,
+(<code>TAG::APPLICATION_ID</code> and <code>TAG::APPLICATION_DATA</code>,
 respectively). Keystore treats these values as opaque blobs, only ensuring that
 the same blobs presented during key generation/import are presented for every
 use and are byte-for-byte identical. The client binding data is not returned by
 Keymaster. The caller has to know it in order to use the key.</p>
 
-<p>This feature is not exposed to applications.
+<p>This feature is not exposed to applications.</p>
 
-<h3 id=expiration>Expiration</h3>
+<h3 id="expiration">Expiration</h3>
 
 <p>Keystore supports restricting key usage by date. Key start of validity and
 key expirations can be associated with a key and Keymaster refuses to
 perform key operations if the current date/time is outside of the valid
 range. The key validity range is specified with the tags
-<code>KM_TAG_ACTIVE_DATETIME</code>,
-<code>KM_TAG_ORIGINATION_EXPIRE_DATETIME</code>, and
-<code>KM_TAG_USAGE_EXPIRE_DATETIME</code>.  The distinction between
+<code>TAG::ACTIVE_DATETIME</code>,
+<code>TAG::ORIGINATION_EXPIRE_DATETIME</code>, and
+<code>TAG::USAGE_EXPIRE_DATETIME</code>.  The distinction between
 "origination" and "usage" is based on whether the key is being used to
 "originate" a new ciphertext/signature/etc., or to "use" an existing
 ciphertext/signature/etc. Note that this distinction is not exposed to
 applications.</p>
 
-<p>The <code>KM_TAG_ACTIVE_DATETIME</code>,
-<code>KM_TAG_ORIGINATION_EXPIRE_DATETIME</code>,
-and <code>KM_TAG_USAGE_EXPIRE_DATETIME</code> tags are optional. If the tags
+<p>The <code>TAG::ACTIVE_DATETIME</code>,
+<code>TAG::ORIGINATION_EXPIRE_DATETIME</code>,
+and <code>TAG::USAGE_EXPIRE_DATETIME</code> tags are optional. If the tags
 are absent, it is assumed that the key in
 question can always be used to decrypt/verify messages.</p>
 
@@ -355,7 +367,7 @@
 trusted time and data, for example via a challenge response protocol with a
 trusted remote timeserver.</p>
 
-<h3 id=root_of_trust_binding>Root of trust binding</h3>
+<h3 id="root_of_trust_binding">Root of trust binding</h3>
 
 <p>Keystore requires keys to be bound to a root of trust, which is a bitstring
 provided to the Keymaster secure hardware during startup, preferably by the
@@ -371,31 +383,31 @@
 software-enforced key access controls by making it impossible for an
 attacker-installed operating system to use Keymaster keys.</p>
 
-<h3 id=standalone_keys>Standalone keys</h3>
+<h3 id="standalone_keys">Standalone keys</h3>
 
 <p>Some Keymaster secure hardware may choose to store key material internally
 and return handles rather than encrypted key material. Or there may be other
 cases in which keys cannot be used until some other non-secure or secure world
 system component is available. The Keymaster HAL allows the caller to
-request that a key be "standalone," via the <code>KM_TAG_STANDALONE</code> tag,
+request that a key be "standalone," via the <code>TAG::STANDALONE</code> tag,
 meaning that no resources other than the blob and the running Keymaster system
 are required. The tags associated with a key may be inspected to see whether a
 key is standalone. At present, only two values are defined:</p>
 
 <ul>
-  <li><code>KM_BLOB_STANDALONE</code>
-  <li><code>KM_BLOB_REQUIRES_FILE_SYSTEM</code>
+  <li><code>KeyBlobUsageRequirements::STANDALONE</code></li>
+  <li><code>KeyBlobUsageRequirements::REQUIRES_FILE_SYSTEM</code></li>
 </ul>
 
-<p>This feature is not exposed to applications.
+<p>This feature is not exposed to applications.</p>
 
-<h3 id=velocity>Velocity</h3>
+<h3 id="velocity">Velocity</h3>
 
 <p>When it's created, the maximum usage velocity can be specified
-with <code>KM_TAG_MIN_SECONDS_BETWEEN_OPS</code>.
+with <code>TAG::MIN_SECONDS_BETWEEN_OPS</code>.
 TrustZone implementations refuse to perform cryptographic operations
 with that key if an operation was performed less
-than <code>KM_TAG_MIN_SECONDS_BETWEEN_OPS</code> seconds earlier.</p>
+than <code>TAG::MIN_SECONDS_BETWEEN_OPS</code> seconds earlier.</p>
 
 <p>The simple approach to implementing velocity limits is a table of key IDs and
 last-use timestamps. This table will likely be of limited size, but
@@ -405,14 +417,14 @@
 entries expires. It is acceptable for all entries to expire upon reboot.</p>
 
 <p>Keys can also be limited to <em>n</em> uses per boot with
-<code>KM_TAG_MAX_USES_PER_BOOT</code>. This also requires a tracking table,
+<code>TAG::MAX_USES_PER_BOOT</code>. This also requires a tracking table,
 which accommodates at least four keys and also fails safe. Note that
 applications will be unable to create per-boot limited keys. This feature
 is not exposed through Keystore and is reserved for system operations.</p>
 
 <p>This feature is not exposed to applications.</p>
 
-<h3 id=random_number_generator_re-seeding>Random number generator re-seeding</h3>
+<h3 id="random_number_generator_re-seeding">Random number generator re-seeding</h3>
 
 <p>Because secure hardware generates random numbers for key material and
 Initialization Vectors (IVs), and because hardware random number generators may
@@ -428,7 +440,7 @@
 
 <p>This feature is not exposed to applications but is used by the framework,
 which regularly provides additional entropy, retrieved from a Java SecureRandom
-instance, to the secure hardware.
+instance, to the secure hardware.</p>
 
   </body>
 </html>
diff --git a/en/security/keystore/implementer-ref.html b/en/security/keystore/implementer-ref.html
index 9043b30..d003e98 100644
--- a/en/security/keystore/implementer-ref.html
+++ b/en/security/keystore/implementer-ref.html
@@ -20,12 +20,19 @@
       See the License for the specific language governing permissions and
       limitations under the License.
   -->
-<p>This page provides details to assist implementers of Keymaster HALs.
-It covers each function in the API and which Keymaster version that
-function is available in. It describes the default implementation.
-For tags, see the
+<p>This page provides details to assist implementers of Keymaster 
+Hardware Abstraction Layers (HALs). It covers each function in the
+API and which Keymaster version that function is available in and
+describes the default implementation. For tags, see the
 <a href="/security/keystore/tags">Keymaster Tags</a> page.</p>
 
+<p class="note">To support Keymaster 3's transition from the old-style
+C-structure HAL to the C++ HAL interface generated from a definition in the new
+Hardware Interface Definition Language (HIDL), function names have changed in
+Android 8.0. To support this, functions are now in camel case. For example,
+<code>get_key_characteristics</code> is now <code>getKeyCharacteristics</code>.
+</p>
+
 <h2 id="general_implementation_guidelines">General implementation guidelines</h2>
 
 <p>The following guidelines apply to all functions in the API.</p>
@@ -36,13 +43,16 @@
 
 <p>Input pointer parameters that are not used for a given call may be <code>NULL</code>.
 The caller is not required to provide placeholders. For example, some key
-types and modes may not use any values from the <code>in_params</code> argument
-to <a href="#begin">begin</a>, so the caller may set <code>in_params</code>
+types and modes may not use any values from the <code>inParams</code> argument
+to <a href="#begin">begin</a>, so the caller may set <code>inParams</code>
 to <code>NULL</code> or provide an empty parameter set. Callers can also
 provide unused parameters, and Keymaster methods should not issue errors.</p>
 
 <p>If a required input parameter is NULL, Keymaster methods should return
-<code>KM_ERROR_UNEXPECTED_NULL_POINTER</code>.</p>
+<code>ErrorCode::UNEXPECTED_NULL_POINTER</code>.</p>
+
+<p>Starting in Keymaster 3, there are no pointer parameters. All parameters
+are passed by value or const references.</p>
 
 
 <h3 id="output_pointer_parameters">Output pointer parameters</h3>
@@ -52,15 +62,17 @@
 <p>Similar to input pointer parameters, unused output pointer parameters
 may be <code>NULL</code>. If a method needs to return data in an output
 parameter found to be <code>NULL</code>, it should return
-<code>KM_ERROR_OUTPUT_PARAMETER_NULL</code>.</p>
+<code>ErrorCode::OUTPUT_PARAMETER_NULL</code>.</p>
+<p>Starting in Keymaster 3, there are no pointer parameters. All parameters
+are passed by value or const references.</p>
 
 
 <h3 id="api_misuse">API misuse</h3>
 
-<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Version</strong>: 1, 2, 3</p>
 
 <p>There are many ways that callers can make requests that don't make sense or are
-foolish but not technically wrong. Keymaster1 implementations are not required
+foolish but not technically wrong. Keymaster implementations are not required
 to fail in such cases or issue a diagnostic. Use of too-small keys,
 specification of irrelevant input parameters, reuse of IVs or nonces,
 generation of keys with no purposes (hence useless) and the like should not be
@@ -70,8 +82,808 @@
 <p>It is the responsibility of apps, the framework, and Android keystore to ensure
 that the calls to Keymaster modules are sensible and useful.</p>
 
+<p class="caution">Keymaster implementations should attempt to diagnose
+serious errors, such as omission of required parameters, specification of invalid
+required parameters, and similar errors that compromise the integrity of the
+Keymaster implementation.</p>
+
 <h2 id="functions">Functions</h2>
 
+<h3 id="get_hardware_features">getHardwareFeatures</h3>
+<p><strong>Version</strong>: 3</p>
+
+<p>
+The new <code>getHardwareFeatures</code> method exposes to clients some important
+characteristics of the underlying secure hardware. The method takes no arguments
+and returns four values, all booleans:
+</p>
+<ul>
+  <li><code>isSecure</code> is <code>true</code> if keys are stored in
+  secure hardware (TEE, etc.) and never leave it.</li>
+  <li><code>supportsEllipticCurve</code> is <code>true</code> if the
+  hardware supports Elliptic Curve cryptography with the NIST curves (P-224,
+  P-256, P-384, and P-521).</li>
+  <li><code>supportsSymmetricCryptography</code> is <code>true</code>
+  if the hardware supports symmetric cryptography, including AES and HMAC.</li>
+  <li><code>supportsAttestation</code> is <code>true</code> if the
+  hardware supports generation of Keymaster public key attestation certificates,
+  signed with a key injected in a secure environment.</li>
+</ul>
+<p>
+The only error codes this method may return are <code>ErrorCode:OK</code>,
+<code>ErrorCode::KEYMASTER_NOT_CONFIGURED</code> or one of the error codes
+indicating a failure to communicate with the secure hardware.
+</p>
+<pre class="devsite-click-to-copy">
+getHardwareFeatures()
+    generates(bool isSecure, bool supportsEllipticCurve, bool supportsSymmetricCryptography,
+              bool supportsAttestation, bool supportsAllDigests, string keymasterName,
+              string keymasterAuthorName);</pre>
+
+<h3 id="configure">configure</h3>
+<p><strong>Version</strong>: 2</p>
+<p>This function was introduced in Keymaster 2 and deprecated in Keymaster
+3, as this information is available in system properties files, and manufacturer
+implementations read those files during startup.</p>
+
+<p>Configures keymaster. This method is called once after the device is opened and before
+it is used. It's used to provide
+<a href="/security/keystore/tags#os_version">KM_TAG_OS_VERSION</a> and
+<a href="/security/keystore/tags#os_patchlevel">KM_TAG_OS_PATCHLEVEL</a> to keymaster.
+Until this method is called, all other methods return
+<code>KM_ERROR_KEYMASTER_NOT_CONFIGURED</code>. The values provided by this
+method are only accepted by keymaster once per boot. Subsequent
+calls return <code>KM_ERROR_OK</code>, but do nothing.</p>
+<p>
+If the keymaster implementation is in secure hardware and the OS version and patch level
+values provided do not match the values provided to the secure hardware by the bootloader (or
+if the bootloader did not provide values), then this method returns
+<code>KM_ERROR_INVALID_ARGUMENT</code>, and all other methods continue returning
+<code>KM_ERROR_KEYMASTER_NOT_CONFIGURED</code>.</p>
+<pre class="devsite-click-to-copy">
+keymaster_error_t (*configure)(const struct keymaster2_device* dev,
+                               const keymaster_key_param_set_t* params);</pre>
+
+<h3 id="add_rng_entropy">addRngEntropy</h3>
+
+<p><strong>Version</strong>: 1, 2, 3</p>
+<p>This function was introduced in Keymaster 1 as <code>add_rng_entropy</code>
+and renamed in Keymaster 3.</p>
+
+<p>Adds caller-provided entropy to the pool used by the Keymaster 1 implementation
+for generating random numbers, for keys, IVs, etc.</p>
+
+<p>Keymaster implementations need to securely mix the provided
+entropy into their pool, which also must contain
+internally-generated entropy from a hardware random number generator.
+Mixing should be handled so that an attacker who has complete control
+of either the <code>addRngEntropy</code>-provided bits or the hardware-generated bits,
+but not both, has no non-neglible advantage in predicting the bits generated
+from the entropy pool.</p>
+
+<p>Keymaster implementations that attempt to estimate the entropy in their
+internal pool assume that data provided by
+<code>addRngEntropy</code> contains no entropy. Keymaster implementations may
+return <code>ErrorCode::INVALID_INPUT_LENGTH</code> if they're given more than 2
+KiB of data in a single call.</p>
+
+
+<h3 id="generate_key">generateKey</h3>
+
+<p><strong>Version</strong>: 1, 2, 3</p>
+<p>This function was introduced in Keymaster 1 as <code>generate_key</code>
+and renamed in Keymaster 3.</p>
+
+<p>Generates a new cryptographic key, specifying associated authorizations, which
+are permanently bound to the key. Keymaster implementations make it
+impossible to use a key in any way inconsistent with the authorizations
+specified at generation time. With respect to authorizations that the secure
+hardware cannot enforce, the secure hardware's obligation is limited to
+ensuring that the unenforceable authorizations associated with the key cannot
+be modified, so that every call to
+<a href="#get_key_characteristics">getKeyCharacteristics</a>
+returns the original value. In addition, the characteristics returned by
+<code>generateKey</code> allocates authorizations correctly between the
+hardware-enforced and software-enforced lists. See
+<a href="#get_key_characteristics">getKeyCharacteristics</a> for more details.</p>
+
+<p>The parameters provided to <code>generateKey</code> depend on the type of key
+being generated. This section summarizes the necessary and optional tags for each
+type of key. <a href="/security/keystore/tags#algorithm">Tag::ALGORITHM</a>
+is always necessary, to specify the type.</p>
+
+<h4 id="generate_key_rsa_keys">RSA keys</h4>
+
+<p>The following parameters are necessary to generate an RSA key.</p>
+
+<ul>
+  <li><a href="/security/keystore/tags#key_size">Tag::KEY_SIZE</a>
+  specifies the size of the public modulus, in bits. If omitted,
+  the method returns <code>ErrorCode::UNSUPPORTED_KEY_SIZE</code>.
+  Supported values are 1024, 2048, 3072 and 4096. Recommended values
+  are all key sizes that are a multiple of 8.</li>
+  <li><a href="/security/keystore/tags#rsa_public_exponent">Tag::RSA_PUBLIC_EXPONENT</a>
+  specifies the RSA public exponent value. If omitted, the method
+  returns <code>ErrorCode::INVALID_ARGUMENT</code>.
+  Supported values are 3 and 65537. Recommended values are
+  all prime values up to 2^64.</li>
+</ul>
+
+<p>The following parameters are not necessary to generate an RSA key, but creating
+an RSA key without them produces a key that is unusable. However, the
+<code>generateKey</code> function doesn't return an error if these parameters are omitted.</p>
+
+<ul>
+  <li><a href="/security/keystore/tags#purpose">Tag::PURPOSE</a> specifies allowed purposes.
+  All purposes need to be supported for RSA keys, in
+  any combination.</li>
+  <li><a href="/security/keystore/tags#digest">Tag::DIGEST</a> specifies
+  digest algorithms that may be used with the new key. Implementations
+  that do not support all digest algorithms need to accept key generation requests
+  that include unsupported digests. The unsupported digests should be placed in
+  the "software-enforced" list in the returned key characteristics. This is
+  because the key is usable with those other digests, but digesting is
+  performed in software. Then hardware is called to perform the operation
+  with <code>Digest::NONE</code>.</li>
+  <li><a href="/security/keystore/tags#padding">Tag::PADDING</a> specifies the padding modes
+  that may be used with the new key. Implementations
+  that do not support all digest algorithms need to place <code>PaddingMode::RSA_PSS</code>
+  and <code>PaddingMode::RSA_OAEP</code> in the software-enforced list of the key
+  characteristics if any unsupported digest algorithms are specified.</li>
+</ul>
+
+<h4 id="generate_key_ecdsa_keys">ECDSA keys</h4>
+
+<p>Only <a href="/security/keystore/tags#key_size">Tag::KEY_SIZE</a> is
+necessary to generate an ECDSA key. It is used to select the EC group.
+Supported values are 224, 256, 384 and 521, which indicate the
+NIST p-224, p-256, p-384 and p521 curves, respectively.</p>
+
+<p><a href="/security/keystore/tags#digest">Tag::DIGEST</a>
+ is also necessary for a useful ECDSA key,
+ but is not required for generation.</p>
+
+<h4 id="generate_key_aes_keys">AES keys</h4>
+
+<p>Only <a href="/security/keystore/tags#key_size">Tag::KEY_SIZE</a>
+ is necessary to generate an AES key. If omitted, the method returns
+ <code>ErrorCode::UNSUPPORTED_KEY_SIZE</code>. Supported values are
+ 128 and 256, with optional support for 192-bit AES keys.</p>
+
+<p>The following parameters are particularly relevant for AES keys, but not
+necessary to generate one:</p>
+
+<ul>
+  <li><code>Tag::BLOCK_MODE</code> specifies the block modes with which
+  the new key may be used.</li>
+  <li><code>Tag::PADDING</code> specifies the padding modes that may be
+  used. This is only relevant for ECB and CBC modes.</li>
+</ul>
+
+<p>If the GCM block mode is specified, then provide the
+<a href="/security/keystore/tags#min_mac_length">Tag::MIN_MAC_LENGTH</a>.
+If omitted, the method returns <code>ErrorCode::MISSING_MIN_MAC_LENGTH</code>.
+The tag's value is a multiple of 8 and between 96 and 128.</p>
+
+<h4 id="generate_key_hmac_keys">HMAC keys</h4>
+
+<p>The following parameters are required for HMAC key generation:</p>
+
+<ul>
+  <li><a href="/security/keystore/tags#key_size">Tag::KEY_SIZE</a>
+  specifies the key size in bits. Values smaller than 64
+  and values that are not multiples of 8 are not supported. All
+  multiples of 8, from 64 to 512, are supported. Larger values may be supported.</li>
+  <li><a href="/security/keystore/tags#min_mac_length">Tag::MIN_MAC_LENGTH</a>
+  specifies the minimum length of
+  MACs that can be generated or verified with this key. The value is a multiple of
+  8 and at least 64.</li>
+  <li><a href="/security/keystore/tags#digest">Tag::DIGEST</a>
+  specifies the digest algorithm for the key. Exactly
+  one digest is specified, otherwise return <code>ErrorCode::UNSUPPORTED_DIGEST</code>.
+  If the digest is not supported by the trustlet, return
+  <code>ErrorCode::UNSUPPORTED_DIGEST</code>.</li>
+</ul>
+
+<h4 id="key_characteristics">Key characteristics</h4>
+
+<p>If the characteristics argument is non-NULL,
+<code>generateKey</code> returns the newly-generated
+key's characteristics divided appropriately
+into hardware-enforced and software-enforced lists.
+See <a href="#get_key_characteristics">getKeyCharacteristics</a>
+for a description of which characteristics go in which list. The returned
+characteristics include all of the parameters specified to key generation,
+except <a href="/security/keystore/tags#application_id">Tag::APPLICATION_ID</a> and
+<a href="/security/keystore/tags#application_data">Tag::APPLICATION_DATA</a>.
+If these tags were included in the key parameters, they are removed from
+the returned characteristics so that it is not be possible to find their values by
+examining the returned key blob. However, they are cryptographically bound
+to the key blob, so that if the correct values are not provided when the key is
+used, usage fails. Similarly,
+<a href="/security/keystore/tags#root_of_trust">Tag::ROOT_OF_TRUST</a> is
+cryptographically bound to the key, but it may not be specified during
+key creation or import and is never returned.</p>
+
+<p>In addition to the provided tags, the trustlet also
+adds <a href="/security/keystore/tags#origin">Tag::ORIGIN</a>,
+with the value <code>KeyOrigin::GENERATED</code>,
+and if the key is rollback resistant,
+<a href="/security/keystore/tags#rollback_resistant">Tag::ROLLBACK_RESISTANT</a>.</p>
+
+<h4 id="rollback_resistance">Rollback resistance</h4>
+
+<p>Rollback resistance means that once a key is deleted with
+<a href="#delete_key">deleteKey</a> or <a href="#delete_all_keys">deleteAllKeys</a>,
+it is guaranteed by secure hardware never to be usable again. Implementations
+without rollback resistance typically return generated or imported key
+material to the caller as a key blob, an encrypted and authenticated form. When
+keystore deletes the key blob, the key is gone, but an attacker who has
+previously managed to retrieve the key material can potentially restore it to
+the device.</p>
+
+<p>A key is rollback resistant if the secure hardware guarantees that deleted keys
+cannot be restored later. This is generally done by storing additional key
+metadata in a trusted location that cannot be manipulated by an attacker. On
+mobile devices, the mechanism used for this is usually Replay Protected Memory
+Blocks (RPMB). Because the number of keys that may be created is essentially
+unbounded and the trusted storage used for rollback resistance may be limited
+in size, this method needs to succeed even if rollback resistance
+cannot be provided for the new key. In that case,
+<a href="/security/keystore/tags#rollback_resistant">Tag::ROLLBACK_RESISTANT</a>
+should not be added to the key characteristics.</p>
+
+<h3 id="get_key_characteristics">getKeyCharacteristics</h3>
+
+<p><strong>Version</strong>: 1, 2, 3</p>
+<p>This function was introduced in Keymaster 1 as <code>get_key_characteristics</code>
+and renamed in Keymaster 3.</p>
+
+<p>Returns parameters and authorizations associated with the provided key, divided
+into two sets: hardware-enforced and software-enforced. The description here
+applies equally to the key characteristics lists returned
+by <a href="#generate_key">generateKey</a> and <a href="#import_key">importKey</a>.</p>
+
+<p>If <code>Tag::APPLICATION_ID</code> was provided during key generation
+or import, the same value is provided to
+this method in the <code>clientId</code> argument. Otherwise, the
+method returns <code>ErrorCode::INVALID_KEY_BLOB</code>. Similarly,
+if <code>Tag::APPLICATION_DATA</code> was provided during generation
+or import, the same value is provided to
+this method in the <code>appData</code> argument.</p>
+
+<p>The characteristics returned by this method completely describe the type and
+usage of the specified key.</p>
+
+<p>The general rule for deciding whether a given tag belongs in the
+hardware-enforced or software-enforced list is that if the meaning of the tag
+is fully assured by secure hardware, it is hardware enforced. Otherwise, it's
+software enforced. Below is a list of specific tags whose correct allocation
+may be unclear:</p>
+
+<ul>
+  <li><a href="/security/keystore/tags#algorithm">Tag::ALGORITHM</a>,
+   <a href="/security/keystore/tags#key_size">Tag::KEY_SIZE</a>,
+  and <a href="/security/keystore/tags#rsa_public_exponent">Tag::RSA_PUBLIC_EXPONENT</a>
+  are intrinsic properties of the key. For any key that is secured by hardware,
+  these tags will be in the hardware-enforced list.</li>
+  <li><a href="/security/keystore/tags#digest">Tag::DIGEST</a> values
+  that are supported by the secure hardware are placed in the
+  hardware-supported list. Unsupported digests go in the software-supported list.</li>
+  <li><a href="/security/keystore/tags#padding">Tag::PADDING</a> values
+  generally go in the hardware-supported list, unlessthere is a
+  possibility that a specific padding mode may have to be performed by software.
+  In that case, they go in the software-enforced list. Such a possibility
+  arises for RSA keys that permit PSS or OAEP padding with digest algorithms
+  that are not supported by the secure hardware.</li>
+  <li><a href="/security/keystore/tags#user_secure_id">Tag::USER_SECURE_ID</a>
+  and <a href="/security/keystore/tags#mac_length">Tag::USER_AUTH_TYPE</a>
+  are hardware-enforced only if user authentication is hardware enforced. To
+  accomplish this, the Keymaster trustlet and the relevant authentication
+  trustlet both have to be secure and share a secret HMAC key used to sign and
+  validate authentication tokens. See the
+  <a href="/security/authentication/">Authentication</a> page for details.</li>
+  <li><a href="/security/keystore/tags#active_datetime">Tag::ACTIVE_DATETIME</a>,
+  <a href="/security/keystore/tags#origination_expire_datetime">Tag::ORIGINATION_EXPIRE_DATETIME</a>,
+  and <a href="/security/keystore/tags#usage_expire_datetime">Tag::USAGE_EXPIRE_DATETIME</a> tags
+  require access to a verifiably correct wall clock. Most secure hardware
+  only has access to time information provided by the non-secure OS, which
+  means the tags are software enforced.</li>
+  <li><a href="/security/keystore/tags#origin">Tag::ORIGIN</a> is
+  always in the hardware list for hardware-bound keys. Its presence in that
+  list is the way higher layers determine that a key is hardware-backed.</li>
+</ul>
+
+<h3 id="import_key">importKey</h3>
+
+<p><strong>Version</strong>: 1, 2, 3</p>
+<p>This function was introduced in Keymaster 1 as <code>import_key</code>
+and renamed in Keymaster 3.</p>
+
+<p>Imports key material into Keymaster hardware. Key definition parameters and
+output characteristics are handled the same as for <code>generateKey</code>,
+with the following exceptions:</p>
+
+<ul>
+  <li><a href="/security/keystore/tags#key_size">Tag::KEY_SIZE</a> and
+  <a href="/security/keystore/tags#rsa_public_exponent">Tag::RSA_PUBLIC_EXPONENT</a>
+  (for RSA keys only) are not necessary in the input parameters. If not provided,
+  the trustlet deduces the values from the provided key material and adds
+  appropriate tags and values to the key characteristics. If the parameters are
+  provided, the trustlet validates them against the key material. In the
+  event of a mismatch, the method returns <code>ErrorCode::IMPORT_PARAMETER_MISMATCH</code>.</li>
+  <li>The returned <a href="/security/keystore/tags#origin">Tag::ORIGIN</a> has the
+  same value as <code>KeyOrigin::IMPORTED</code>.</li>
+</ul>
+
+<h3 id="export_key">exportKey</h3>
+
+<p><strong>Version</strong>: 1, 2, 3</p>
+<p>This function was introduced in Keymaster 1 as <code>export_key</code>
+and renamed in Keymaster 3.</p>
+
+<p>Exports a public key from a Keymaster RSA or EC key pair.</p>
+
+<p>If <code>Tag::APPLICATION_ID</code> was provided during key generation or import,
+the same value is provided to this method in the
+<code>clientId</code> argument. Otherwise, the method returns
+<code>ErrorCode::INVALID_KEY_BLOB</code>. Similarly, if
+<code>Tag::APPLICATION_DATA</code>
+was provided during generation or import, the same value is provided to
+this method in the <code>appData</code> argument.</p>
+
+<h3 id="delete_key">deleteKey</h3>
+
+<p><strong>Version</strong>: 1, 2, 3</p>
+<p>This function was introduced in Keymaster 1 as <code>delete_key</code>
+and renamed in Keymaster 3.</p>
+
+<p>Deletes the provided key. This method is optional, and is only
+implemented by Keymaster modules that provide rollback resistance.</p>
+
+<h3 id="delete_all_keys">deleteAllKeys</h3>
+
+<p><strong>Version</strong>: 1, 2, 3</p>
+<p>This function was introduced in Keymaster 1 as <code>delete_all_keys</code>
+and renamed in Keymaster 3.</p>
+
+<p>Deletes all keys. This method is optional, and is only implemented
+by Keymaster modules that provide rollback resistance.</p>
+
+
+<h3 id="destroy_attestation_ids">destroyAttestationIds</h3>
+<p><strong>Version</strong>: 3</p>
+<p>
+The <code>destroyAttestationIds()</code> method is used to permanently
+disable the new (optional, but highly recommended)
+<a href="/security/keystore/attestation#id-attestation">ID attestation</a>
+feature. If the TEE has no way to ensure that ID attestation is permanently
+disabled after this method is called, then ID attestation must not be
+implemented at all, in which case this method does nothing and
+returns <code>ErrorCode::UNIMPLEMENTED</code>. If ID attestation is
+supported, this method needs to be implemented and must permanently disable
+all future ID attestation attempts. The method may be called any number of
+times. If ID attestation is permanently disabled already, the method does
+nothing and returns <code>ErrorCode::OK</code>.
+</p>
+<p>
+The only error codes this method may return are
+<code>ErrorCode::UNIMPLEMENTED</code> (if ID attestation is not supported),
+<code>ErrorCode:OK</code>, <code>ErrorCode::KEYMASTER_NOT_CONFIGURED</code> or
+one of the error codes indicating a failure to communicate with the secure
+hardware.
+</p>
+
+<h3 id="begin">begin</h3>
+
+<p><strong>Version</strong>: 1, 2, 3</p>
+
+<p>Begins a cryptographic operation, using the specified key, for the specified
+purpose, with the specified parameters (as appropriate), and returns an
+operation handle that is used with <a href="#update">update</a> and <a
+href="#finish">finish</a> to complete the operation. The operation handle is
+also used as the "challenge" token in authenticated operations, and for such
+operations is included in the <code>challenge</code> field of the
+authentication token.</p>
+
+<p>A Keymaster implementation supports at least 16 concurrent
+operations. Keystore uses up to 15, leaving one for vold to use for password
+encryption. When Keystore has 15 operations in progress (<code>begin</code> has
+been called, but <code>finish</code> or <code>abort</code> have not yet been
+called) and it receives a request to begin a 16th, it calls
+<code>abort</code> on the least-recently used operation to reduce the number of
+active operations to 14 before calling <code>begin</code> to start the
+newly-requested operation.</p>
+
+<p>If <a href="/security/keystore/tags#application_id">Tag::APPLICATION_ID</a>
+or <a href="#application_data">Tag::APPLICATION_DATA</a> were specified
+during key generation or import, calls to <code>begin</code> include those
+tags with the originally-specified values in the <code>inParams</code> argument
+to this method.</p>
+
+<h4 id="begin_authorization_enforcement">Authorization enforcement</h4>
+
+<p>During this method, the following key authorizations are enforced by the
+trustlet if the implementation placed them in the "hardware-enforced"
+characteristics and if the operation is not a public key operation. Public key
+operations, meaning <code>KeyPurpose::ENCRYPT</code> and <code>KeyPurpose::VERIFY</code>,
+with RSA or EC keys, are allowed to succeed even if authorization
+requirements are not met.</p>
+
+<ul>
+  <li><a href="/security/keystore/tags#purpose">Tag::PURPOSE</a>: The purpose
+   specified in the <code>begin()</code> call has to match one of the purposes
+   in the key authorizations, unless the requested operation is a public key
+   operation. If the specified purpose does not match and the operation is not
+   a public key operation, <code>begin</code> will return
+   <code>ErrorCode::UNSUPPORTED_PURPOSE</code>. Public key operations are
+   asymmetric encryption or verification operations.</li>
+  <li><a href="/security/keystore/tags#active_datetime">Tag::ACTIVE_DATETIME</a>
+  can only be enforced if a trusted UTC time source is available. If the
+  current date and time is prior to the tag value, the method returns
+  <code>ErrorCode::KEY_NOT_YET_VALID</code>.</li>
+  <li><a href="/security/keystore/tags#origination_expire_datetime">Tag::ORIGINATION_EXPIRE_DATETIME</a>
+  can only be enforced if a trusted UTC time source is available. If the
+  current date and time is later than the tag value and the purpose is
+  <code>KeyPurpose::ENCRYPT</code> or <code>KeyPurpose::SIGN</code>, the method
+  returns <code>ErrorCode::KEY_EXPIRED</code>.</li>
+  <li><a href="/security/keystore/tags#usage_expire_datetime">Tag::USAGE_EXPIRE_DATETIME</a>
+  can only be enforced if a trusted UTC time source is available. If the
+  current date and time is later than the tag value and the purpose is
+  <code>KeyPurpose::DECRYPT</code> or <code>KeyPurpose::VERIFY</code>, the method
+  returns <code>ErrorCode::KEY_EXPIRED</code>.</li>
+  <li><a href="/security/keystore/tags#min_seconds_between_ops">Tag::MIN_SECONDS_BETWEEN_OPS</a>
+  is compared with a trusted relative timer indicating the last use of
+  the key. If the last use time plus the tag value is less than the current time,
+  the method returns <code>ErrorCode::KEY_RATE_LIMIT_EXCEEDED</code>. See the
+  <a href="/security/keystore/tags#min_seconds_between_ops">tag description</a>
+  for important implementation details.</li>
+  <li><a href="/security/keystore/tags#max_uses_per_boot">Tag::MAX_USES_PER_BOOT</a>
+  is compared against a secure counter that tracks the uses of the key
+  since boot time. If the count of previous uses exceeds the tag value, the
+  method returns <code>ErrorCode::KEY_MAX_OPS_EXCEEDED</code>.</li>
+  <li><a href="/security/keystore/tags#user_secure_id">Tag::USER_SECURE_ID</a>
+  is enforced by this method only if the key also has
+  <a href="/security/keystore/tags#auth_timeout">Tag::AUTH_TIMEOUT</a>.
+  If the key has both, then this method must receive a valid
+  <a href="/security/keystore/tags#auth_token">Tag::AUTH_TOKEN</a> in
+  <code>inParams</code>. For the auth token to be valid, all of the following
+  has to be true:
+   <ul>
+     <li>The HMAC field validates correctly.</li>
+     <li>At least one of the
+     <a href="/security/keystore/tags#user_secure_id">Tag::USER_SECURE_ID</a>
+     values from the key matches at least one of the secure ID values in the
+     token.</li>
+     <li>The key has a
+     <a href="/security/keystore/tags#mac_length">Tag::USER_AUTH_TYPE</a>
+     that matches the auth type in the token.</li>
+   </ul>
+  <p>If any of these conditions aren't met, the method returns
+  <code>ErrorCode::KEY_USER_NOT_AUTHENTICATED</code>.</p></li>
+  <li><a href="/security/keystore/tags#caller_nonce">Tag::CALLER_NONCE</a>
+  allows the caller to specify a nonce or initialization vector (IV). If the key
+  doesn't have this tag, but the caller provided
+  <a href="/security/keystore/tags#nonce">Tag::NONCE</a> to this method,
+  <code>ErrorCode::CALLER_NONCE_PROHIBITED</code> is returned.</li>
+  <li><a href="/security/keystore/tags#bootloader_only">Tag::BOOTLOADER_ONLY</a>
+   specifies that only the bootloader may use the key. If this method is
+   called with a bootloader-only key after the bootloader has finished executing,
+   it returns <code>ErrorCode::INVALID_KEY_BLOB</code>.</li>
+</ul>
+
+<h4 id="begin_rsa_keys">RSA keys</h4>
+
+<p>All RSA key operations specify exactly one padding mode in <code>inParams</code>.
+If unspecified or specified more than once, the method returns
+<code>ErrorCode::UNSUPPORTED_PADDING_MODE</code>.</p>
+
+<p>RSA signing and verification operations need a digest, as do RSA encryption
+and decryption operations with OAEP padding mode. For those cases, the caller
+specifies exactly one digest in <code>inParams</code>. If unspecified or specified
+more than once, the method returns <code>ErrorCode::UNSUPPORTED_DIGEST</code>.</p>
+
+<p>Private key operations (<code>KeyPurpose::DECYPT</code> and <code>KeyPurpose::SIGN</code>)
+need authorization of digest and padding, which means that the key authorizations
+need to contain the specified values. If not, the method returns
+<code>ErrorCode::INCOMPATIBLE_DIGEST</code>
+or <code>ErrorCode::INCOMPATIBLE_PADDING</code>, as appropriate. Public key operations
+(<code>KeyPurpose::ENCRYPT</code> and <code>KeyPurpose::VERIFY</code>) are permitted with
+unauthorized digest or padding.</p>
+
+<p>With the exception of <code>PaddingMode::NONE</code>, all RSA padding modes are
+applicable only to certain purposes. Specifically,
+<code>PaddingMode::RSA_PKCS1_1_5_SIGN</code> and <code>PaddingMode::RSA_PSS</code>
+only support signing and verification, while <code>PaddingMode::RSA_PKCS1_1_1_5_ENCRYPT</code>
+and <code>PaddingMode::RSA_OAEP</code> only support encryption and decryption.
+The method returns <code>ErrorCode::UNSUPPORTED_PADDING_MODE</code> if the
+specified mode does not support the specified purpose.</p>
+
+<p>There are some important interactions between padding modes and digests:</p>
+
+<ul>
+
+  <li><code>PaddingMode::NONE</code> indicates that a "raw" RSA operation is
+  performed. If signing or verifying, <code>Digest::NONE</code> is
+  specified for the digest. No digest is necessary for unpadded encryption or
+  decryption.</li>
+  <li><code>PaddingMode::RSA_PKCS1_1_5_SIGN</code> padding requires a digest. The
+  digest may be <code>Digest::NONE</code>, in which case the Keymaster
+  implementation cannot build a proper PKCS#1 v1.5 signature structure, because
+  it cannot add the DigestInfo structure. Instead, the implementation
+  constructs <code>0x00 || 0x01 || PS || 0x00 || M</code>, where M is the
+  provided message and PS is the padding string. The size of the RSA key has to
+  be at least 11 bytes larger than the message, otherwise the method returns
+  <code>ErrorCode::INVALID_INPUT_LENGTH</code>.</li>
+  <li><code>PaddingMode::RSA_PKCS1_1_1_5_ENCRYPT</code> padding does not require a digest.</li>
+  <li><code>PaddingMode::RSA_PSS</code> padding requires a digest, which may not be
+  <code>Digest::NONE</code>. If <code>Digest::NONE</code> is specified, the
+  method returns <code>ErrorCode::INCOMPATIBLE_DIGEST</code>. In addition, the
+  size of the RSA key has to be at least 2 + D bytes larger than the output
+  size of the digest, where D is the size of the digest, in bytes. Otherwise
+  the method returns <code>ErrorCode::INCOMPATIBLE_DIGEST</code>. The salt size
+  is D.</li>
+  <li><code>PaddingMode::RSA_OAEP</code> padding requires a digest, which may not be
+  <code>Digest::NONE</code>. If <code>Digest::NONE</code> is specified, the
+  method returns <code>ErrorCode::INCOMPATIBLE_DIGEST</code>.</li>
+</ul>
+
+<h4 id="begin_ec_keys">EC keys</h4>
+
+<p>EC key operations specify exactly one padding mode in <code>inParams</code>.
+If unspecified or specified more than once, the method
+returns <code>ErrorCode::UNSUPPORTED_PADDING_MODE</code>.</p>
+
+<p>Private key operations (<code>KeyPurpose::SIGN</code>) need authorization
+of digest and padding, which means that the key authorizations
+need to contain the specified values. If not, return
+<code>ErrorCode::INCOMPATIBLE_DIGEST</code>. Public key operations
+(<code>KeyPurpose::VERIFY</code>) are permitted with unauthorized digest or padding.</p>
+
+<h4 id="begin_aes_keys">AES keys</h4>
+
+<p>AES key operations specify exactly one block mode and one padding mode
+in <code>inParams</code>. If either value is unspecified or specified more
+than once, return <code>ErrorCode::UNSUPPORTED_BLOCK_MODE</code> or
+<code>ErrorCode::UNSUPPORTED_PADDING_MODE</code>. The specified modes have to be
+authorized by the key, otherwise the method returns
+<code>ErrorCode::INCOMPATIBLE_BLOCK_MODE</code> or
+<code>ErrorCode::INCOMPATIBLE_PADDING_MODE</code>.</p>
+
+<p>If the block mode is <code>BlockMode::GCM</code>, <code>inParams</code>
+specifies <code>Tag::MAC_LENGTH</code>, and the
+specified value is a multiple of 8 that is not greater than 128
+or less than the value of <code>Tag::MIN_MAC_LENGTH</code> in the
+key authorizations. For MAC lengths greater than 128 or non-multiples of
+8, return <code>ErrorCode::UNSUPPORTED_MAC_LENGTH</code>. For values less
+than the key's minimum length, return <code>ErrorCode::INVALID_MAC_LENGTH</code>.</p>
+
+<p>If the block mode is <code>BlockMode::GCM</code> or <code>BlockMode::CTR</code>,
+the specified padding mode has to be <code>PaddingMode::NONE</code>.
+For <code>BlockMode::ECB</code> or <code>BlockMode::CBC</code>, the mode may be
+<code>PaddingMode::NONE</code> or <code>PaddingMode::PKCS7</code>. If the padding mode
+doesn't meet these conditions, return <code>ErrorCode::INCOMPATIBLE_PADDING_MODE</code>.</p>
+
+<p>If the block mode is <code>BlockMode::CBC</code>, <code>BlockMode::CTR</code>,
+or <code>BlockMode::GCM</code>, an initialization vector or nonce is needed.
+In most cases, callers shouldn't provide an IV or nonce. In that case, the
+Keymaster implementation generates a random IV or nonce and returns it via
+<a href="/security/keystore/tags#nonce">Tag::NONCE</a> in <code>outParams</code>.
+CBC and CTR IVs are 16 bytes. GCM nonces are 12 bytes. If the key
+authorizations contain
+<a href="/security/keystore/tags#caller_nonce">Tag::CALLER_NONCE</a>,
+then the caller may provide an IV/nonce with
+<a href="/security/keystore/tags#nonce">Tag::NONCE</a>
+in <code>inParams</code>. If a nonce is provided when
+<a href="/security/keystore/tags#caller_nonce">Tag::CALLER_NONCE</a>
+is not authorized, return <code>ErrorCode::CALLER_NONCE_PROHIBITED</code>.
+If a nonce is not provided when
+<a href="/security/keystore/tags#caller_nonce">Tag::CALLER_NONCE</a>
+is authorized, generate a random IV/nonce.</p>
+
+<h4 id="begin_hmac_keys">HMAC keys</h4>
+
+<p>HMAC key operations specify <code>Tag::MAC_LENGTH</code> in <code>inParams</code>.
+The specified value must be a multiple of 8 that is not greater than the
+digest length or less than the value of <code>Tag::MIN_MAC_LENGTH</code>
+in the key authorizations. For MAC lengths greater than the digest length or
+non-multiples of 8, return <code>ErrorCode::UNSUPPORTED_MAC_LENGTH</code>.
+For values less than the key's minimum length, return
+<code>ErrorCode::INVALID_MAC_LENGTH</code>.</p>
+
+<h3 id="update">update</h3>
+
+<p><strong>Version</strong>: 1, 2, 3</p>
+
+<p>Provides data to process in an ongoing operation started with <a href="#begin">begin</a>.
+The operation is specified by the <code>operationHandle</code> parameter.</p>
+
+<p>To provide more flexibility for buffer handling, implementations of this method
+have the option of consuming less data than was provided. The caller is
+responsible for looping to feed the rest of the data in subsequent calls. The
+amount of input consumed is returned in the <code>inputConsumed</code> parameter.
+Implementations always consume at least one byte, unless the
+operation cannot accept any more; if more than zero bytes are provided and zero
+bytes are consumed, callers consider this an error and abort the operation.</p>
+
+<p>Implementations may also choose how much data to return, as a result of the
+update. This is only relevant for encryption and decryption operations, because
+signing and verification return no data until <a href="#finish">finish</a>.
+Return data as early as possible, rather than buffer it.</p>
+
+<h4 id="error_handling">Error handling</h4>
+
+<p>If this method returns an error code other than <code>ErrorCode::OK</code>,
+the operation is aborted and the operation handle is invalidated. Any
+future use of the handle, with this method,
+<a href="#finish">finish</a>, or <a href="#abort">abort</a>,
+returns <code>ErrorCode::INVALID_OPERATION_HANDLE</code>.</p>
+
+<h4 id="update_authorization_enforcement">Authorization enforcement</h4>
+
+<p>Key authorization enforcement is performed primarily in <a href="#begin">begin</a>.
+The one exception is the case where the key has:</p>
+
+<ul>
+  <li>One or more <a href="/security/keystore/tags#user_secure_id">Tag::USER_SECURE_IDs</a>, and</li>
+  <li>Does not have a <a href="/security/keystore/tags#auth_timeout">Tag::AUTH_TIMEOUT</a></li>
+</ul>
+
+<p>In this case, the key requires an authorization per operation, and the update
+method receives a <a href="/security/keystore/tags#auth_token">Tag::AUTH_TOKEN</a>
+in the <code>inParams</code> argument. HMAC verifies that the token is valid and contains
+a matching secure user ID, matches the key's
+<a href="/security/keystore/tags#mac_length">Tag::USER_AUTH_TYPE</a>,
+and contains the operation handle of the current operation in the
+challenge field. If these conditions aren't met, return
+<code>ErrorCode::KEY_USER_NOT_AUTHENTICATED</code>.</p>
+
+<p>The caller provides the authentication token to every call to <a href="#update">update</a> and
+<a href="#finish">finish</a>. The implementation need only validate the token once if it prefers.</p>
+
+<h4 id="update_rsa_keys">RSA keys</h4>
+
+<p>For signing and verification operations with <code>Digest::NONE</code>,
+this method accepts the entire block to be signed or verified in a single
+update. It may not consume only a portion of the block. However, if the caller
+chooses to provide the data in multiple updates, this method accepts it.
+If the caller provides more data to sign than can be used (length of
+data exceeds RSA key size), return <code>ErrorCode::INVALID_INPUT_LENGTH</code>.</p>
+
+<h4 id="update_ecdsa_keys">ECDSA keys</h4>
+
+<p>For signing and verification operations with <code>Digest::NONE</code>,
+this method accepts the entire block to be signed or verified in a single
+update. This method may not consume only a portion of the block.</p>
+
+<p>However, if the caller chooses to provide the data in multiple updates,
+this method accepts it. If the caller provides more data to sign
+than can be used, the data is silently truncated. (This differs from the
+handling of excess data provided in similar RSA operations. The reason for this
+is compatibility with legacy clients.)</p>
+
+<h4 id="update_aes_keys">AES keys</h4>
+
+<p>AES GCM mode supports "associated authentication data," provided via the
+<a href="/security/keystore/tags#associated_data">Tag::ASSOCIATED_DATA</a>
+tag in the <code>inParams</code> argument.
+The associated data may be provided in repeated calls (important if
+the data is too large to send in a single block) but always precedes data
+to be encrypted or decrypted. An update call may receive both associated data
+and data to encrypt/decrypt, but subsequent updates may not include associated
+data. If the caller provides associated data to an update call after a call
+that includes data to encrypt/decrypt, return <code>ErrorCode::INVALID_TAG</code>.</p>
+
+<p>For GCM encryption, the tag is appended to the ciphertext by
+<a href="#finish">finish</a>. During decryption, the last
+<code>Tag::MAC_LENGTH</code> bytes of the data provided to the last
+update call is the tag. Since a given invocation of
+<a href="#update">update</a> cannot know if it's the last invocation,
+it processes all but the tag length and buffer the possible tag data
+during <a href="#finish">finish</a>.</p>
+
+<h3 id="finish">finish</h3>
+
+<p><strong>Version</strong>: 1, 2, 3</p>
+
+<p>Finishes an ongoing operation started with <a href="#begin">begin</a>,
+processing all of the as-yet-unprocessed data provided by
+<a href="#update">update</a>(s).</p>
+
+<p>This method is the last one called in an operation, so all
+processed data is returned.</p>
+
+<p>Whether it completes successfully or returns an error, this method finalizes
+the operation and therefore invalidates the provided operation handle. Any
+future use of the handle, with this method or <a href="#update">update</a> or
+<a href="#abort">abort</a>, returns <code>ErrorCode::INVALID_OPERATION_HANDLE</code>.</p>
+
+<p>Signing operations return the signature as the output. Verification operations
+accept the signature in the <code>signature</code> parameter, and return no output.</p>
+
+<h4 id="finish_authorization_enforcement">Authorization enforcement</h4>
+
+<p>Key authorization enforcement is performed primarily in
+<a href="#begin">begin</a>. The one exception is the case where the key has:</p>
+
+<ul>
+  <li>One or more
+  <a href="/security/keystore/tags#user_secure_id">Tag::USER_SECURE_IDs</a>, and</li>
+  <li>Does not have a
+  <a href="/security/keystore/tags#auth_timeout">Tag::AUTH_TIMEOUT</a></li>
+</ul>
+
+<p>In this case, the key requires an authorization per operation, and the update
+method receives a <a href="/security/keystore/tags#auth_token">Tag::AUTH_TOKEN</a>
+in the <code>inParams</code> argument. HMAC verifies that the token
+is valid and contains a matching secure user ID, matches the key's
+<a href="/security/keystore/tags#mac_length">Tag::USER_AUTH_TYPE</a>, and
+contains the operation handle of the current operation in the
+challenge field. If these conditions aren't met, return
+<code>ErrorCode::KEY_USER_NOT_AUTHENTICATED</code>.</p>
+
+<p>The caller provides the authentication token to every call to
+<a href="#update">update</a> and <a href="#finish">finish</a>.
+The implementation need only validate the token once if it prefers.</p>
+
+<h4 id="finish_rsa_keys">RSA keys</h4>
+
+<p>Some additional requirements, depending on the padding mode:</p>
+
+<ul>
+  <li><code>PaddingMode::NONE</code>. For unpadded signing and encryption operations,
+  if the provided data is shorter than the key, the data is be zero-padded on
+  the left before signing/encryption. If the data is the same length as the key,
+  but numerically larger, return <code>ErrorCode::INVALID_ARGUMENT</code>. For
+  verification and decryption operations, the data must be exactly as long
+  as the key. Otherwise, return <code>ErrorCode::INVALID_INPUT_LENGTH.</code></li>
+  <li><code>PaddingMode::RSA_PSS</code>. For PSS-padded signature operations,
+  the PSS salt is at least 20 bytes in length and randomly-generated.
+  The salt may be longer; the reference implementation uses maximally-sized salt.
+  The digest specified with <a href="/security/keystore/tags#digest">Tag::DIGEST</a>
+  in <code>inputParams</code> on <a href="#begin">begin</a> is used as the PSS digest
+  algorithm, and SHA1 is used as the MGF1 digest algorithm.</li>
+  <li><code>PaddingMode::RSA_OAEP</code>. The digest specified with
+  <a href="/security/keystore/tags#digest">Tag::DIGEST</a> in
+  <code>inputParams</code> on <a href="#begin">begin</a> is used as the OAEP
+  digest algorithm, and SHA1 is used as the MGF1 digest algorithm.</li>
+</ul>
+
+<h4 id="finish_ecdsa_keys">ECDSA keys</h4>
+
+<p>If the data provided for unpadded signing or verification is too long, truncate
+it.</p>
+
+<h4 id="finish_aes_keys">AES keys</h4>
+
+<p>Some additional conditions, depending on block mode:</p>
+
+<ul>
+  <li><code>BlockMode::ECB</code> or <code>BlockMode::CBC</code>.
+  If padding is <code>PaddingMode::NONE</code> and the
+  data length is not a multiple of the AES block size, return
+  <code>ErrorCode::INVALID_INPUT_LENGTH</code>. If padding is
+  <code>PaddingMode::PKCS7</code>, pad the data per the PKCS#7 specification.
+  Note that PKCS#7 recommends adding an additional padding block
+  if the data is a multiple of the block length.</li>
+  <li><code>BlockMode::GCM</code>. During encryption, after processing
+  all plaintext, compute the tag
+  (<a href="/security/keystore/tags#mac_length">Tag::MAC_LENGTH</a> bytes)
+  and append it to the returned ciphertext. During decryption, process
+  the last <a href="/security/keystore/tags#mac_length">Tag::MAC_LENGTH</a>
+  bytes as the tag. If tag verification fails, return
+  <code>ErrorCode::VERIFICATION_FAILED</code>.</li>
+</ul>
+
+<h3 id="abort">abort</h3>
+
+<p><strong>Version</strong>: 1, 2, 3</p>
+
+<p>Aborts the in-progress operation. After the call to abort, return
+<code>ErrorCode::INVALID_OPERATION_HANDLE</code> for
+any subsequent use of the provided operation handle with <a href="#update">update</a>,
+<a href="#finish">finish</a>, or <a href="#abort">abort</a>.</p>
+
 <h3 id="get_supported_algorithms">get_supported_algorithms</h3>
 
 <p><strong>Version</strong>: 1</p>
@@ -93,7 +905,7 @@
 
 <p>For RSA, EC and HMAC, which are not block ciphers, the method returns an
 empty list for all valid purposes. Invalid purposes should cause the method to
-return <code>KM_ERROR_INVALID_PURPOSE</code>.</p>
+return <code>ErrorCode::INVALID_PURPOSE</code>.</p>
 
 <p>Keymaster 1 implementations support ECB, CBC, CTR and GCM for AES
 encryption and decryption.</p>
@@ -108,7 +920,7 @@
 
 <p>HMAC and EC have no notion of padding so the method returns an empty list
 for all valid purposes. Invalid purposes should cause the method to return
-<code>KM_ERROR_INVALID_PURPOSE</code>.</p>
+<code>ErrorCode::INVALID_PURPOSE</code>.</p>
 
 <p>For RSA, Keymaster 1 implementations support:</p>
 
@@ -161,702 +973,6 @@
 <p>Keymaster1 implementations support the X.509 format for exporting RSA and
 EC public keys. Export of private keys or asymmetric keys is not supported.</p>
 
-<h3 id="add_rng_entropy">add_rng_entropy</h3>
-
-<p><strong>Version</strong>: 1, 2</p>
-
-<p>Adds caller-provided entropy to the pool used by the Keymaster1 implementation
-for generating random numbers, for keys, IVs, etc.</p>
-
-<p>Keymaster1 implementations <strong>securely</strong> mix the provided
-entropy into their pool, which also contains
-internally-generated entropy from a hardware random number generator.
-With this structure, an attacker with complete control of either the
-<code>add_rng_entropy</code>-provided bits or the hardware-generated bits,
-but not both, would not have an advangage in predicting the bits generated
-from the entropy pool.</p>
-
-<p>Keymaster implementations that attempt to estimate the entropy in their
-internal pool assume that data provided by
-<code>add_rng_entropy</code> contains no entropy. Keymaster implementations may
-return <code>KM_ERROR_INVALID_INPUT_LENGTH</code> if they're given more than 2
-KiB of data in a single call.</p>
-
-<h3 id="generate_key">generate_key</h3>
-
-<p><strong>Version</strong>: 1, 2</p>
-
-<p>Generates a new cryptographic key, specifying associated authorizations, which
-are permanently bound to the key. Keymaster implementations make it
-impossible to use a key in any way inconsistent with the authorizations
-specified at generation time. With respect to authorizations that the secure
-hardware cannot enforce, the secure hardware's obligation is limited to
-ensuring that the unenforceable authorizations associated with the key cannot
-be modified, so that every call to <a href="#get_key_characteristics">get_key_characteristics</a>
-returns the original value. In addition, the characteristics returned by <code>generate_key</code>
-allocates authorizations correctly between the hardware-enforced and
-software-enforced lists. See <a href="#get_key_characteristics">get_key_characteristics</a>
-for more details.</p>
-
-<p>The parameters provided to <code>generate_key</code> depend on the type of key
-being generated. This section summarizes the necessary and optional tags for each
-type of key. <a href="/security/keystore/tags#algorithm">KM_TAG_ALGORITHM</a>
-is always necessary, to specify the type.</p>
-
-<h4 id="rsa_keys">RSA keys</h4>
-
-<p>The following parameters are necessary to generate an RSA key.</p>
-
-<ul>
-  <li><a href="/security/keystore/tags#key_size">KM_TAG_KEY_SIZE</a>
-  specifies the size of the public modulus, in bits. If omitted,
-  the method returns <code>KM_ERROR_UNSUPPORTED_KEY_SIZE</code>.
-  Supported values are 1024, 2048, 3072 and 4096. Recommended values
-  are all key sizes that are a multiple of 8.</li>
-  <li><a href="/security/keystore/tags#rsa_public_exponent">KM_TAG_RSA_PUBLIC_EXPONENT</a>
-  specifies the RSA public exponent value. If omitted, the method
-  returns <code>KM_ERROR_INVALID_ARGUMENT</code>.
-  Supported values are 3 and 65537. Recommended values are
-  all prime values up to 2^64.</li>
-</ul>
-
-<p>The following parameters are not necessary to generate an RSA key, but creating
-an RSA key without them produces a key that is unusable. However, the
-<code>generate_key</code> function doesn't return an error if these parameters are omitted.</p>
-
-<ul>
-  <li><a href="/security/keystore/tags#purpose">KM_TAG_PURPOSE</a> specifies allowed purposes.
-  All purposes need to be supported for RSA keys, in
-  any combination.</li>
-  <li><a href="/security/keystore/tags#digest">KM_TAG_DIGEST</a> specifies
-  digest algorithms that may be used with the new key. Implementations
-  that do not support all digest algorithms need to accept key generation requests
-  that include unsupported digests. The unsupported digests should be placed in
-  the "software-enforced" list in the returned key characteristics. This is
-  because the key is usable with those other digests, but digesting is
-  performed in software. Then hardware is called to perform the operation
-  with <code>KM_DIGEST_NONE</code>.</li>
-  <li><a href="/security/keystore/tags#padding">KM_TAG_PADDING</a> specifies the padding modes
-  that may be used with the new key. Implementations
-  that do not support all digest algorithms need to place <code>KM_PAD_RSA_PSS</code>
-  and <code>KM_PAD_RSA_OAEP</code> in the software-enforced list of the key
-  characteristics if any unsupported digest algorithms are specified.</li>
-</ul>
-
-<h4 id="ecdsa_keys">ECDSA keys</h4>
-
-<p>Only <a href="/security/keystore/tags#key_size">KM_TAG_KEY_SIZE</a> is
-necessary to generate an ECDSA key. It is used to select the EC group.
-Supported values are 224, 256, 384 and 521, which indicate the
-NIST p-224, p-256, p-384 and p521 curves, respectively.</p>
-
-<p><a href="/security/keystore/tags#digest">KM_TAG_DIGEST</a>
- is also necessary for a useful ECDSA key,
- but is not required for generation.</p>
-
-<h4 id="aes_keys">AES keys</h4>
-
-<p>Only <a href="/security/keystore/tags#key_size">KM_TAG_KEY_SIZE</a>
- is necessary to generate an AES key. If omitted, the method returns
- <code>KM_ERROR_UNSUPPORTED_KEY_SIZE</code>. Supported values are
- 128 and 256, with optional support for 192-bit AES keys.</p>
-
-<p>The following parameters are particularly relevant for AES keys, but not
-necessary to generate one:</p>
-
-<ul>
-  <li><code>KM_TAG_BLOCK_MODE</code> specifies the block modes with which the new key may be used.</li>
-  <li><code>KM_TAG_PADDING</code> specifies the padding modes that may be used. This is only
-  relevant for ECB and CBC modes.</li>
-</ul>
-
-<p>If the GCM block mode is specified, then provide the
-<a href="/security/keystore/tags#min_mac_length">KM_TAG_MIN_MAC_LENGTH</a>.
-If omitted, the method returns <code>KM_ERROR_MISSING_MIN_MAC_LENGTH</code>.
-The tag's value is a multiple of 8 and between 96 and 128.</p>
-
-<h4 id="hmac_keys">HMAC keys</h4>
-
-<p>The following parameters are required for HMAC key generation:</p>
-
-<ul>
-  <li><a href="/security/keystore/tags#key_size">KM_TAG_KEY_SIZE</a>
-  specifies the key size in bits. Values smaller than 64
-  and values that are not multiples of 8 are not supported. All
-  multiples of 8, from 64 to 512, are supported. Larger values may be supported.</li>
-  <li><a href="/security/keystore/tags#min_mac_length">KM_TAG_MIN_MAC_LENGTH</a>
-  specifies the minimum length of
-  MACs that can be generated or verified with this key. The value is a multiple of
-  8 and at least 64.</li>
-  <li><a href="/security/keystore/tags#digest">KM_TAG_DIGEST</a>
-  specifies the digest algorithm for the key. Exactly
-  one digest is specified, otherwise return <code>KM_ERROR_UNSUPPORTED_DIGEST</code>.
-  If the digest is not supported by the trustlet, return
-  <code>KM_ERROR_UNSUPPORTED_DIGEST</code>.</li>
-</ul>
-
-<h4 id="key_characteristics">Key characteristics</h4>
-
-<p>If the characteristics argument is non-NULL,
-<code>generate_key</code> returns the newly-generated
-key's characteristics divided appropriately
-into hardware-enforced and software-enforced lists.
-See <a href="#get_key_characteristics">get_key_characteristics</a>
-for a description of which characteristics go in which list. The returned
-characteristics include all of the parameters specified to key generation,
-except <a href="/security/keystore/tags#application_id">KM_TAG_APPLICATION_ID</a> and
-<a href="/security/keystore/tags#application_data">KM_TAG_APPLICATION_DATA</a>.
-If these tags were included in the key parameters, they are removed from
-the returned characteristics so that it is not be possible to find their values by
-examining the returned key blob. However, they are cryptographically bound
-to the key blob, so that if the correct values are not provided when the key is
-used, usage fails. Similarly,
-<a href="/security/keystore/tags#root_of_trust">KM_TAG_ROOT_OF_TRUST</a> is
-cryptographically bound to the key, but it may not be specified during
-key creation or import and is never returned.</p>
-
-<p>In addition to the provided tags, the trustlet also
-adds <a href="/security/keystore/tags#origin">KM_TAG_ORIGIN</a>,
-with the value <code>KM_ORIGIN_GENERATED</code>,
-and if the key is rollback resistant,
-<a href="/security/keystore/tags#rollback_resistant">KM_TAG_ROLLBACK_RESISTANT</a>.</p>
-
-<h4 id="rollback_resistance">Rollback resistance</h4>
-
-<p>Rollback resistance means that once a key is deleted with
-<a href="#delete_key">delete_key</a> or <a href="#delete_all_keys">delete_all_keys</a>,
-it is guaranteed by secure hardware never to be usable again. Implementations
-without rollback resistance typically return generated or imported key
-material to the caller as a key blob, an encrypted and authenticated form. When
-keystore deletes the key blob, the key is gone, but an attacker who has
-previously managed to retrieve the key material can potentially restore it to
-the device.</p>
-
-<p>A key is rollback resistant if the secure hardware guarantees that deleted keys
-cannot be restored later. This is generally done by storing additional key
-metadata in a trusted location that cannot be manipulated by an attacker. On
-mobile devices, the mechanism used for this is usually Replay Protected Memory
-Blocks (RPMB). Because the number of keys that may be created is essentially
-unbounded and the trusted storage used for rollback resistance may be limited
-in size, this method needs to succeed even if rollback resistance
-cannot be provided for the new key. In that case,
-<a href="/security/keystore/tags#rollback_resistant">KM_TAG_ROLLBACK_RESISTANT</a>
-should not be added to the key characteristics.</p>
-
-<h3 id="get_key_characteristics">get_key_characteristics</h3>
-
-<p><strong>Version</strong>: 1, 2</p>
-
-<p>Returns parameters and authorizations associated with the provided key, divided
-into two sets: hardware-enforced and software-enforced. The description here
-applies equally to the key characteristics lists returned
-by <a href="#generate_key">generate_key</a> and <a href="#import_key">import_key</a>.</p>
-
-<p>If <code>KM_TAG_APPLICATION_ID</code> was provided during key generation
-or import, the same value is provided to
-this method in the <code>client_id</code> argument. Otherwise, the
-method returns <code>KM_ERROR_INVALID_KEY_BLOB</code>. Similarly,
-if <code>KM_TAG_APPLICATION_DATA</code> was provided during generation
-or import, the same value is provided to
-this method in the <code>app_data</code> argument.</p>
-
-<p>The characteristics returned by this method completely describe the type and
-usage of the specified key.</p>
-
-<p>The general rule for deciding whether a given tag belongs in the
-hardware-enforced or software-enforced list is that if the meaning of the tag
-is fully assured by secure hardware, it is hardware enforced. Otherwise, it's
-software enforced. Below is a list of specific tags whose correct allocation
-may be unclear:</p>
-
-<ul>
-  <li><a href="/security/keystore/tags#algorithm">KM_TAG_ALGORITHM</a>,
-   <a href="/security/keystore/tags#key_size">KM_TAG_KEY_SIZE</a>,
-  and <a href="/security/keystore/tags#rsa_public_exponent">KM_TAG_RSA_PUBLIC_EXPONENT</a>
-  are intrinsic properties of the key. For any key that is secured by hardware,
-  these tags will be in the hardware-enforced list.</li>
-  <li><a href="/security/keystore/tags#digest">KM_TAG_DIGEST</a> values
-  that are supported by the secure hardware are placed in the
-  hardware-supported list. Unsupported digests go in the software-supported list.</li>
-  <li><a href="/security/keystore/tags#padding">KM_TAG_PADDING</a> values
-  generally go in the hardware-supported list, unlessthere is a
-  possibility that a specific padding mode may have to be performed by software.
-  In that case, they go in the software-enforced list. Such a possibility
-  arises for RSA keys that permit PSS or OAEP padding with digest algorithms
-  that are not supported by the secure hardware.</li>
-  <li><a href="/security/keystore/tags#user_secure_id">KM_TAG_USER_SECURE_ID</a>
-  and <a href="/security/keystore/tags#mac_length">KM_TAG_USER_AUTH_TYPE</a>
-  are hardware-enforced only if user authentication is hardware enforced. To
-  accomplish this, the Keymaster trustlet and the relevant authentication
-  trustlet both have to be secure and share a secret HMAC key used to sign and
-  validate authentication tokens. See the
-  <a href="/security/authentication/">Authentication</a> page for details.</li>
-  <li><a href="/security/keystore/tags#active_datetime">KM_TAG_ACTIVE_DATETIME</a>,
-  <a href="/security/keystore/tags#origination_expire_datetime">KM_TAG_ORIGINATION_EXPIRE_DATETIME</a>,
-  and <a href="/security/keystore/tags#usage_expire_datetime">KM_TAG_USAGE_EXPIRE_DATETIME</a> tags
-  require access to a verifiably correct wall clock. Most secure hardware
-  only has access to time information provided by the non-secure OS, which
-  means the tags are software enforced.</li>
-  <li><a href="/security/keystore/tags#origin">KM_TAG_ORIGIN</a> is
-  always in the hardware list for hardware-bound keys. Its presence in that
-  list is the way higher layers determine that a key is hardware-backed.</li>
-</ul>
-
-<h3 id="import_key">import_key</h3>
-
-<p><strong>Version</strong>: 1, 2</p>
-
-<p>Imports key material into Keymaster hardware. Key definition parameters and
-output characteristics are handled the same as for <code>generate_key</code>,
-with the following exceptions:</p>
-
-<ul>
-  <li><a href="/security/keystore/tags#key_size">KM_TAG_KEY_SIZE</a> and
-  <a href="/security/keystore/tags#rsa_public_exponent">KM_TAG_RSA_PUBLIC_EXPONENT</a>
-  (for RSA keys only) are not necessary in the input parameters. If not provided,
-  the trustlet deduces the values from the provided key material and adds
-  appropriate tags and values to the key characteristics. If the parameters are
-  provided, the trustlet validates them against the key material. In the
-  event of a mismatch, the method returns <code>KM_ERROR_IMPORT_PARAMETER_MISMATCH</code>.</li>
-  <li>The returned <a href="/security/keystore/tags#origin">KM_TAG_ORIGIN</a> has the
-  same value as <code>KM_ORIGIN_IMPORTED</code>.</li>
-</ul>
-
-<h3 id="export_key">export_key</h3>
-
-<p><strong>Version</strong>: 1, 2</p>
-
-<p>Exports a public key from a Keymaster RSA or EC key pair.</p>
-
-<p>If <code>KM_TAG_APPLICATION_ID</code> was provided during key generation or import,
-the same value is provided to this method in the
-<code>client_id</code> argument. Otherwise, the method returns
-<code>KM_ERROR_INVALID_KEY_BLOB</code>. Similarly, if
-<code>KM_TAG_APPLICATION_DATA</code>
-was provided during generation or import, the same value is provided to
-this method in the <code>app_data</code> argument.</p>
-
-<h3 id="delete_key">delete_key</h3>
-
-<p><strong>Version</strong>: 1, 2</p>
-
-<p>Deletes the provided key. This method is optional, and is only
-implemented by Keymaster modules that provide rollback resistance.</p>
-
-<h3 id="delete_all_keys">delete_all_keys</h3>
-
-<p><strong>Version</strong>: 1, 2</p>
-
-<p>Deletes all keys. This method is optional, and is only implemented
-by Keymaster modules that provide rollback resistance.</p>
-
-<h3 id="begin">begin</h3>
-
-<p><strong>Version</strong>: 1, 2</p>
-
-<p>Begins a cryptographic operation, using the specified key, for the specified
-purpose, with the specified parameters (as appropriate), and returns an
-operation handle that is used with <a href="#update">update</a> and <a
-href="#finish">finish</a> to complete the operation. The operation handle is
-also used as the "challenge" token in authenticated operations, and for such
-operations is included in the <code>challenge</code> field of the
-authentication token.</p>
-
-<p>A Keymaster implementation supports at least 16 concurrent
-operations. Keystore uses up to 15, leaving one for vold to use for password
-encryption. When Keystore has 15 operations in progress (<code>begin</code> has
-been called, but <code>finish</code> or <code>abort</code> have not yet been
-called) and it receives a request to begin a 16th, it calls
-<code>abort</code> on the least-recently used operation to reduce the number of
-active operations to 14 before calling <code>begin</code> to start the
-newly-requested operation.
-
-<p>If <a href="/security/keystore/tags#application_id">KM_TAG_APPLICATION_ID</a>
-or <a href="#km_tag_application_data">KM_TAG_APPLICATION_DATA</a> were specified
-during key generation or import, calls to <code>begin</code> include those
-tags with the originally-specified values in the <code>in_params</code> argument
-to this method.</p>
-
-<h4 id="authorization_enforcement">Authorization enforcement</h4>
-
-<p>During this method, the following key authorizations are enforced by the
-trustlet if the implementation placed them in the "hardware-enforced"
-characteristics and if the operation is not a public key operation. Public key
-operations, meaning <code>KM_PURPOSE_ENCRYPT</code> and <code>KM_PURPOSE_VERIFY</code>,
-with RSA or EC keys, are allowed to succeed even if authorization
-requirements are not met.</p>
-
-<ul>
-  <li><a href="/security/keystore/tags#purpose">KM_TAG_PURPOSE</a>: The purpose
-   specified in the <code>begin()</code> call has to match one of the purposes
-   in the key authorizations, unless the requested operation is a public key
-   operation. If the specified purpose does not match and the operation is not
-   a public key operation, <code>begin</code> will return
-   <code>KM_ERROR_UNSUPPORTED_PURPOSE</code>. Public key operations are
-   asymmetric encryption or verification operations.</li>
-  <li><a href="/security/keystore/tags#active_datetime">KM_TAG_ACTIVE_DATETIME</a>
-  can only be enforced if a trusted UTC time source is available. If the
-  current date and time is prior to the tag value, the method returns
-  <code>KM_ERROR_KEY_NOT_YET_VALID</code>.</li>
-  <li><a href="/security/keystore/tags#origination_expire_datetime">KM_TAG_ORIGINATION_EXPIRE_DATETIME</a>
-  can only be enforced if a trusted UTC time source is available. If the
-  current date and time is later than the tag value and the purpose is
-  <code>KM_PURPOSE_ENCRYPT</code> or <code>KM_PURPOSE_SIGN</code>, the method
-  returns <code>KM_ERROR_KEY_EXPIRED</code>.</li>
-  <li><a href="/security/keystore/tags#usage_expire_datetime">KM_TAG_USAGE_EXPIRE_DATETIME</a>
-  can only be enforced if a trusted UTC time source is available. If the
-  current date and time is later than the tag value and the purpose is
-  <code>KM_PURPOSE_DECRYPT</code> or <code>KM_PURPOSE_VERIFY</code>, the method
-  returns <code>KM_ERROR_KEY_EXPIRED</code>.</li>
-  <li><a href="/security/keystore/tags#min_seconds_between_ops">KM_TAG_MIN_SECONDS_BETWEEN_OPS</a>
-  is compared with a trusted relative timer indicating the last use of
-  the key. If the last use time plus the tag value is less than the current time,
-  the method returns <code>KM_ERROR_KEY_RATE_LIMIT_EXCEEDED</code>. See the
-  <a href="/security/keystore/tags#min_seconds_between_ops">tag description</a>
-  for important implementation details.</li>
-  <li><a href="/security/keystore/tags#max_uses_per_boot">KM_TAG_MAX_USES_PER_BOOT</a>
-  is compared against a secure counter that tracks the uses of the key
-  since boot time. If the count of previous uses exceeds the tag value, the
-  method returns <code>KM_ERROR_KEY_MAX_OPS_EXCEEDED</code>.</li>
-  <li><a href="/security/keystore/tags#user_secure_id">KM_TAG_USER_SECURE_ID</a>
-  is enforced by this method only if the key also has
-  <a href="/security/keystore/tags#auth_timeout">KM_TAG_AUTH_TIMEOUT</a>.
-  If the key has both, then this method must receive a valid
-  <a href="/security/keystore/tags#auth_token">KM_TAG_AUTH_TOKEN</a> in
-  <code>in_params</code>. For the auth token to be valid, all of the following
-  has to be true:
-   <ul>
-     <li>The HMAC field validates correctly.</li>
-     <li>At least one of the
-     <a href="/security/keystore/tags#user_secure_id">KM_TAG_USER_SECURE_ID</a>
-     values from the key matches at least one of the secure ID values in the
-     token.</li>
-     <li>The key has a
-     <a href="/security/keystore/tags#mac_length">KM_TAG_USER_AUTH_TYPE</a>
-     that matches the auth type in the token.</li>
-   </ul>
-  <p>If any of these conditions aren't met, the method returns
-  <code>KM_ERROR_KEY_USER_NOT_AUTHENTICATED</code>.</p></li>
-  <li><a href="/security/keystore/tags#caller_nonce">KM_TAG_CALLER_NONCE</a>
-  allows the caller to specify a nonce or initialization vector (IV). If the key
-  doesn't have this tag, but the caller provided
-  <a href="/security/keystore/tags#nonce">KM_TAG_NONCE</a> to this method,
-  <code>KM_ERROR_CALLER_NONCE_PROHIBITED</code> is returned.</li>
-  <li><a href="/security/keystore/tags#bootloader_only">KM_TAG_BOOTLOADER_ONLY</a>
-   specifies that only the bootloader may use the key. If this method is
-   called with a bootloader-only key after the bootloader has finished executing,
-   it returns <code>KM_ERROR_INVALID_KEY_BLOB</code>.</li>
-</ul>
-
-<h4 id="begin-rsa_keys">RSA keys</h4>
-
-<p>All RSA key operations specify exactly one padding mode in <code>in_params</code>.
-If unspecified or specified more than once, the method returns
-<code>KM_ERROR_UNSUPPORTED_PADDING_MODE</code>.</p>
-
-<p>RSA signing and verification operations need a digest, as do RSA encryption
-and decryption operations with OAEP padding mode. For those cases, the caller
-specifies exactly one digest in <code>in_params</code>. If unspecified or specified
-more than once, the method returns <code>KM_ERROR_UNSUPPORTED_DIGEST</code>.</p>
-
-<p>Private key operations (<code>KM_PURPOSE_DECYPT</code> and <code>KM_PURPOSE_SIGN</code>)
-need authorization of digest and padding, which means that the key authorizations
-need to contain the specified values. If not, the method returns
-<code>KM_ERROR_INCOMPATIBLE_DIGEST</code>
-or <code>KM_ERROR_INCOMPATIBLE_PADDING</code>, as appropriate. Public key operations
-(<code>KM_PURPOSE_ENCRYPT</code> and <code>KM_PURPOSE_VERIFY</code>) are permitted with
-unauthorized digest or padding.</p>
-
-<p>With the exception of <code>KM_PAD_NONE</code>, all RSA padding modes are applicable only to
-certain purposes. Specifically, <code>KM_PAD_RSA_PKCS1_1_5_SIGN</code> and <code>KM_PAD_RSA_PSS</code>
-only support signing and verification, while <code>KM_PAD_RSA_PKCS1_1_1_5_ENCRYPT</code> and
-<code>KM_PAD_RSA_OAEP</code> only support encryption and decryption. The method returns
-<code>KM_ERROR_UNSUPPORTED_PADDING_MODE</code> if the specified mode does not support the specified purpose.</p>
-
-<p>There are some important interactions between padding modes and digests:</p>
-
-<ul>
-
-  <li><code>KM_PAD_NONE</code> indicates that a "raw" RSA operation is
-  performed. If signing or verifying, <code>KM_DIGEST_NONE</code> is
-  specified for the digest. No digest is necessary for unpadded encryption or
-  decryption.</li>
-  <li><code>KM_PAD_RSA_PKCS1_1_5_SIGN</code> padding requires a digest. The
-  digest may be <code>KM_DIGEST_NONE</code>, in which case the Keymaster
-  implementation cannot build a proper PKCS#1 v1.5 signature structure, because
-  it cannot add the DigestInfo structure. Instead, the implementation
-  constructs <code>0x00 || 0x01 || PS || 0x00 || M</code>, where M is the
-  provided message and PS is the padding string. The size of the RSA key has to
-  be at least 11 bytes larger than the message, otherwise the method returns
-  <code>KM_ERROR_INVALID_INPUT_LENGTH</code>.</li>
-  <li><code>KM_PAD_RSA_PKCS1_1_1_5_ENCRYPT</code> padding does not require a digest.</li>
-  <li><code>KM_PAD_RSA_PSS</code> padding requires a digest, which may not be
-  <code>KM_DIGEST_NONE</code>. If <code>KM_DIGEST_NONE</code> is specified, the
-  method returns <code>KM_ERROR_INCOMPATIBLE_DIGEST</code>. In addition, the
-  size of the RSA key has to be at least 2 + D bytes larger than the output
-  size of the digest, where D is the size of the digest, in bytes. Otherwise
-  the method returns <code>KM_ERROR_INCOMPATIBLE_DIGEST</code>. The salt size
-  is D.</li>
-  <li><code>KM_PAD_RSA_OAEP</code> padding requires a digest, which may not be
-  <code>KM_DIGEST_NONE</code>. If <code>KM_DIGEST_NONE</code> is specified, the
-  method returns <code>KM_ERROR_INCOMPATIBLE_DIGEST</code>.</li>
-</ul>
-
-<h4 id="ec_keys">EC keys</h4>
-
-<p>EC key operations specify exactly one padding mode in <code>in_params</code>.
-If unspecified or specified more than once, the method
-returns <code>KM_ERROR_UNSUPPORTED_PADDING_MODE</code>.</p>
-
-<p>Private key operations (<code>KM_PURPOSE_SIGN</code>) need authorization
-of digest and padding, which means that the key authorizations
-need to contain the specified values. If not, return
-<code>KM_ERROR_INCOMPATIBLE_DIGEST</code>. Public key operations
-(<code>KM_PURPOSE_VERIFY</code>) are permitted with unauthorized digest or padding.</p>
-
-<h4 id="begin-aes_keys">AES keys</h4>
-
-<p>AES key operations specify exactly one block mode and one padding mode
-in <code>in_params</code>. If either value is unspecified or specified more
-than once, return <code>KM_ERROR_UNSUPPORTED_BLOCK_MODE</code> or
-<code>KM_ERROR_UNSUPPORTED_PADDING_MODE</code>. The specified modes have to be
-authorized by the key, otherwise the method returns
-<code>KM_ERROR_INCOMPATIBLE_BLOCK_MODE</code> or
-<code>KM_ERROR_INCOMPATIBLE_PADDING_MODE</code>.</p>
-
-<p>If the block mode is <code>KM_MODE_GCM</code>, <code>in_params</code>
-specifies <code>KM_TAG_MAC_LENGTH</code>, and the
-specified value is a multiple of 8 that is not greater than 128
-or less than the value of <code>KM_TAG_MIN_MAC_LENGTH</code> in the
-key authorizations. For MAC lengths greater than 128 or non-multiples of
-8, return <code>KM_ERROR_UNSUPPORTED_MAC_LENGTH</code>. For values less
-than the key's minimum length, return <code>KM_ERROR_INVALID_MAC_LENGTH</code>.</p>
-
-<p>If the block mode is <code>KM_MODE_GCM</code> or <code>KM_MODE_CTR</code>,
-the specified padding mode has to be <code>KM_PAD_NONE</code>.
-For <code>KM_MODE_ECB</code> or <code>KM_MODE_CBC</code>, the mode may be
-<code>KM_PAD_NONE</code> or <code>KM_PAD_PKCS7</code>. If the padding mode
-doesn't meet these conditions, return <code>KM_ERROR_INCOMPATIBLE_PADDING_MODE</code>.</p>
-
-<p>If the block mode is <code>KM_MODE_CBC</code>, <code>KM_MODE_CTR</code>,
-or <code>KM_MODE_GCM</code>, an initialization vector or nonce is needed.
-In most cases, callers shouldn't provide an IV or nonce. In that case, the
-Keymaster implementation generates a random IV or nonce and returns it via
-<a href="/security/keystore/tags#nonce">KM_TAG_NONCE</a> in <code>out_params</code>.
-CBC and CTR IVs are 16 bytes. GCM nonces are 12 bytes. If the key
-authorizations contain
-<a href="/security/keystore/tags#caller_nonce">KM_TAG_CALLER_NONCE</a>,
-then the caller may provide an IV/nonce with
-<a href="/security/keystore/tags#nonce">KM_TAG_NONCE</a>
-in <code>in_params</code>. If a nonce is provided when
-<a href="/security/keystore/tags#caller_nonce">KM_TAG_CALLER_NONCE</a>
-is not authorized, return <code>KM_ERROR_CALLER_NONCE_PROHIBITED</code>.
-If a nonce is not provided when
-<a href="/security/keystore/tags#caller_nonce">KM_TAG_CALLER_NONCE</a>
-is authorized, generate a random IV/nonce.</p>
-
-<h4 id="begin-hmac_keys">HMAC keys</h4>
-
-<p>HMAC key operations specify <code>KM_TAG_MAC_LENGTH</code> in <code>in_params</code>.
-The specified value must be a multiple of 8 that is not greater than the
-digest length or less than the value of <code>KM_TAG_MIN_MAC_LENGTH</code>
-in the key authorizations. For MAC lengths greater than the digest length or
-non-multiples of 8, return <code>KM_ERROR_UNSUPPORTED_MAC_LENGTH</code>.
-For values less than the key's minimum length, return
-<code>KM_ERROR_INVALID_MAC_LENGTH</code>.</p>
-
-<h3 id="update">update</h3>
-
-<p><strong>Version</strong>: 1, 2</p>
-
-<p>Provides data to process in an ongoing operation started with <a href="#begin">begin</a>.
-The operation is specified by the <code>operation_handle</code> parameter.</p>
-
-<p>To provide more flexibility for buffer handling, implementations of this method
-have the option of consuming less data than was provided. The caller is
-responsible for looping to feed the rest of the data in subsequent calls. The
-amount of input consumed is returned in the <code>input_consumed</code> parameter.
-Implementations always consume at least one byte, unless the
-operation cannot accept any more; if more than zero bytes are provided and zero
-bytes are consumed, callers consider this an error and abort the operation.</p>
-
-<p>Implementations may also choose how much data to return, as a result of the
-update. This is only relevant for encryption and decryption operations, because
-signing and verification return no data until <a href="#finish">finish</a>.
-Return data as early as possible, rather than buffer it.</p>
-
-<h4 id="error_handling">Error handling</h4>
-
-<p>If this method returns an error code other than <code>KM_ERROR_OK</code>,
-the operation is aborted and the operation handle is invalidated. Any
-future use of the handle, with this method,
-<a href="#finish">finish</a>, or <a href="#abort">abort</a>,
-returns <code>KM_ERROR_INVALID_OPERATION_HANDLE</code>.</p>
-
-<h4 id="update-authorization_enforcement">Authorization enforcement</h4>
-
-<p>Key authorization enforcement is performed primarily in <a href="#begin">begin</a>.
-The one exception is the case where the key has:</p>
-
-<ul>
-  <li>One or more <a href="/security/keystore/tags#user_secure_id">KM_TAG_USER_SECURE_IDs</a>, and</li>
-  <li>Does not have a <a href="/security/keystore/tags#auth_timeout">KM_TAG_AUTH_TIMEOUT</a></li>
-</ul>
-
-<p>In this case, the key requires an authorization per operation, and the update
-method receives a <a href="/security/keystore/tags#auth_token">KM_TAG_AUTH_TOKEN</a>
-in the <code>in_params</code> argument. HMAC verifies that the token is valid and contains
-a matching secure user ID, matches the key's
-<a href="/security/keystore/tags#mac_length">KM_TAG_USER_AUTH_TYPE</a>,
-and contains the operation handle of the current operation in the
-challenge field. If these conditions aren't met, return
-<code>KM_ERROR_KEY_USER_NOT_AUTHENTICATED</code>.</p>
-
-<p>The caller provides the authentication token to every call to <a href="#update">update</a> and
-<a href="#finish">finish</a>. The implementation need only validate the token once if it prefers.</p>
-
-<h4 id="update-rsa_keys">RSA keys</h4>
-
-<p>For signing and verification operations with <code>KM_DIGEST_NONE</code>,
-this method accepts the entire block to be signed or verified in a single
-update. It may not consume only a portion of the block. However, if the caller
-chooses to provide the data in multiple updates, this method accepts it.
-If the caller provides more data to sign than can be used (length of
-data exceeds RSA key size), return <code>KM_ERROR_INVALID_INPUT_LENGTH</code>.</p>
-
-<h4 id="update-ecdsa_keys">ECDSA keys</h4>
-
-<p>For signing and verification operations with <code>KM_DIGEST_NONE</code>,
-this method accepts the entire block to be signed or verified in a single
-update. This method may not consume only a portion of the block.</p>
-
-<p>However, if the caller chooses to provide the data in multiple updates,
-this method accepts it. If the caller provides more data to sign
-than can be used, the data is silently truncated. (This differs from the
-handling of excess data provided in similar RSA operations. The reason for this
-is compatibility with legacy clients.)</p>
-
-<h4 id="update-aes_keys">AES keys</h4>
-
-<p>AES GCM mode supports "associated authentication data," provided via the
-<a href="/security/keystore/tags#associated_data">KM_TAG_ASSOCIATED_DATA</a>
-tag in the <code>in_params</code> argument.
-The associated data may be provided in repeated calls (important if
-the data is too large to send in a single block) but always precedes data
-to be encrypted or decrypted. An update call may receive both associated data
-and data to encrypt/decrypt, but subsequent updates may not include associated
-data. If the caller provides associated data to an update call after a call
-that includes data to encrypt/decrypt, return <code>KM_ERROR_INVALID_TAG</code>.</p>
-
-<p>For GCM encryption, the tag is appended to the ciphertext by
-<a href="#finish">finish</a>. During decryption, the last
-<code>KM_TAG_MAC_LENGTH</code> bytes of the data provided to the last
-update call is the tag. Since a given invocation of
-<a href="#update">update</a> cannot know if it's the last invocation,
-it processes all but the tag length and buffer the possible tag data
-during <a href="#finish">finish</a>.</p>
-
-<h3 id="finish">finish</h3>
-
-<p><strong>Version</strong>: 1, 2</p>
-
-<p>Finishes an ongoing operation started with <a href="#begin">begin</a>,
-processing all of the as-yet-unprocessed data provided by
-<a href="#update">update</a>(s).</p>
-
-<p>This method is the last one called in an operation, so all
-processed data is returned.</p>
-
-<p>Whether it completes successfully or returns an error, this method finalizes
-the operation and therefore invalidates the provided operation handle. Any
-future use of the handle, with this method or <a href="#update">update</a> or
-<a href="#abort">abort</a>, returns <code>KM_ERROR_INVALID_OPERATION_HANDLE</code>.</p>
-
-<p>Signing operations return the signature as the output. Verification operations
-accept the signature in the <code>signature</code> parameter, and return no output.</p>
-
-<h4 id="finish-authorization_enforcement">Authorization enforcement</h4>
-
-<p>Key authorization enforcement is performed primarily in
-<a href="#begin">begin</a>. The one exception is the case where the key has:</p>
-
-<ul>
-  <li>One or more
-  <a href="/security/keystore/tags#user_secure_id">KM_TAG_USER_SECURE_IDs</a>, and</li>
-  <li>Does not have a
-  <a href="/security/keystore/tags#auth_timeout">KM_TAG_AUTH_TIMEOUT</a></li>
-</ul>
-
-<p>In this case, the key requires an authorization per operation, and the update
-method receives a <a href="/security/keystore/tags#auth_token">KM_TAG_AUTH_TOKEN</a>
-in the <code>in_params</code> argument. HMAC verifies that the token
-is valid and contains a matching secure user ID, matches the key's
-<a href="/security/keystore/tags#mac_length">KM_TAG_USER_AUTH_TYPE</a>, and
-contains the operation handle of the current operation in the
-challenge field. If these conditions aren't met, return
-<code>KM_ERROR_KEY_USER_NOT_AUTHENTICATED</code>.</p>
-
-<p>The caller provides the authentication token to every call to
-<a href="#update">update</a> and <a href="#finish">finish</a>.
-The implementation need only validate the token once if it prefers.</p>
-
-<h4 id="finish-rsa_keys">RSA keys</h4>
-
-<p>Some additional requirements, depending on the padding mode:</p>
-
-<ul>
-  <li><strong>KM_PAD_NONE</strong>. For unpadded signing and encryption operations,
-  if the provided data is shorter than the key, the data is be zero-padded on
-  the left before signing/encryption. If the data is the same length as the key,
-  but numerically larger, return <code>KM_ERROR_INVALID_ARGUMENT</code>. For
-  verification and decryption operations, the data must be exactly as long
-  as the key. Otherwise, return <code>KM_ERROR_INVALID_INPUT_LENGTH.</code></li>
-  <li><strong>KM_PAD_RSA_PSS</strong>. For PSS-padded signature operations,
-  the PSS salt is at least 20 bytes in length and randomly-generated.
-  The salt may be longer; the reference implementation uses maximally-sized salt.
-  The digest specified with <a href="/security/keystore/tags#digest">KM_TAG_DIGEST</a>
-  in <code>input_params</code> on <a href="#begin">begin</a> is used as the PSS digest
-  algorithm, and SHA1 is used as the MGF1 digest algorithm.</li>
-  <li><strong>KM_PAD_RSA_OAEP</strong>. The digest specified with
-  <a href="/security/keystore/tags#digest">KM_TAG_DIGEST</a> in
-  <code>input_params</code> on <a href="#begin">begin</a> is used as the OAEP
-  digest algorithm, and SHA1 is used as the MGF1 digest algorithm.</li>
-</ul>
-
-<h4 id="finish-ecdsa_keys">ECDSA keys</h4>
-
-<p>If the data provided for unpadded signing or verification is too long, truncate
-it.</p>
-
-<h4 id="finish-aes_keys">AES keys</h4>
-
-<p>Some additional conditions, depending on block mode:</p>
-
-<ul>
-  <li><strong>KM_MODE_ECB</strong> or <strong>KM_MODE_CBC</strong>.
-  If padding is <code>KM_PAD_NONE</code> and the
-  data length is not a multiple of the AES block size, return
-  <code>KM_ERROR_INVALID_INPUT_LENGTH</code>. If padding is
-  <code>KM_PAD_PKCS7</code>, pad the data per the PKCS#7 specification.
-  Note that PKCS#7 recommends adding an additional padding block
-  if the data is a multiple of the block length.</li>
-  <li><strong>KM_MODE_GCM</strong>. During encryption, after processing
-  all plaintext, compute the tag
-  (<a href="/security/keystore/tags#mac_length">KM_TAG_MAC_LENGTH</a> bytes)
-  and append it to the returned ciphertext. During decryption, process
-  the last <a href="/security/keystore/tags#mac_length">KM_TAG_MAC_LENGTH</a>
-  bytes as the tag. If tag verification fails, return
-  <code>KM_ERROR_VERIFICATION_FAILED</code>.</li>
-</ul>
-
-<h3 id="abort">abort</h3>
-
-<p><strong>Version</strong>: 1, 2</p>
-
-<p>Aborts the in-progress operation. After the call to abort, return
-<code>KM_ERROR_INVALID_OPERATION_HANDLE</code> for
-any subsequent use of the provided operation handle with <a href="#update">update</a>,
-<a href="#finish">finish</a>, or <a href="#abort">abort</a>.</p>
 
 <h2 id="historical-functions">Historical functions</h2>
 
@@ -888,5 +1004,13 @@
   <li><code> get_supported_import_formats</code></li>
   <li><code>get_supported_export_formats</code></li>
 </ul>
+
+<h3 id="km2">Keymaster 2</h3>
+<p>The following functions belong to the Keymaster 2 definition, but were
+removed in Keymaster 3, along with the Keymaster 1 functions listed above.
+</p>
+<ul>
+  <li><code>configure</code></li>
+</ul>
   </body>
 </html>
diff --git a/en/security/keystore/index.html b/en/security/keystore/index.html
index 0c9e727..155027e 100644
--- a/en/security/keystore/index.html
+++ b/en/security/keystore/index.html
@@ -66,9 +66,29 @@
 a previous release causes the keys to be unusable.
 </p>
 
-<h2 id=goals>Goals</h2>
+<p>
+In Android 8.0, Keymaster 3 transitioned from the old-style C-structure Hardware
+Abstraction Layer (HAL) to the C++ HAL interface generated from a definition
+in the new Hardware Interface Definition Language (HIDL). As part of the change,
+many of the argument types changed, though types and methods have a one-to-one
+correspondence with the old types and the HAL struct methods. See the
+<a href="/security/keystore/implementer-ref">Functions</a> page for more details.
+</p>
+<p>
+In addition to this interface revision, Android 8.0 extends Keymaster 2's
+attestation feature to support
+<a href="/security/keystore/attestation#id-attestation">ID attestation</a>.
+ID attestation provides a limited and optional mechanism for strongly attesting
+to hardware identifiers, such as device serial number, product name, and phone
+ID (IMEI / MEID). To implement this addition, change the ASN.1 attestation
+schema to add ID attestation. Keymaster implementations need to find some secure
+way to retrieve the relevant data items, as well as to define a mechanism for
+securely and permanently disabling the feature.
+</p>
 
-<p>The Android 7.0 Keystore API and the underlying Keymaster HAL
+<h2 id="goals">Goals</h2>
+
+<p>The Android Keystore API and the underlying Keymaster HAL
 provides a basic but adequate set of cryptographic primitives to allow the
 implementation of protocols using access-controlled, hardware-backed keys.</p>
 
@@ -77,12 +97,12 @@
 
 <ul>
   <li>A usage control scheme to allow key usage to be limited, to mitigate the risk
-of security compromise due to misuse of keys
+of security compromise due to misuse of keys</li>
   <li>An access control scheme to enable restriction of keys to specified users,
-clients, and a defined time range
+clients, and a defined time range</li>
 </ul>
 
-<h2 id=architecture>Architecture</h2>
+<h2 id="architecture">Architecture</h2>
 
 <p>The Keymaster HAL is an OEM-provided, dynamically-loadable library used by the
 Keystore service to provide hardware-backed cryptographic services. To keep
@@ -108,7 +128,7 @@
 algorithms but only to marshal and unmarshal requests to the secure world. The
 wire format is implementation-defined.</p>
 
-<h2 id=compatibility_with_previous_versions>Compatibility with previous versions</h2>
+<h2 id="compatibility_with_previous_versions">Compatibility with previous versions</h2>
 
 <p>The Keymaster 1 HAL is completely incompatible with the
 previously-released HALs, e.g. Keymaster 0.2 and 0.3. To facilitate
@@ -126,5 +146,94 @@
 once, and simplifies implementation of AEAD decryption.
 </p>
 
+<p>In Android 8.0, Keymaster 3 transitioned from the old-style C-structure
+HAL to the C++ HAL interface generated from a definition in the new
+Hardware Interface Definition Language (HIDL). A new-style HAL
+implementation is created by subclassing the generated
+<code>IKeymasterDevice</code> class and implementing the pure virtual
+methods. As part of the change, many of the argument types have changed,
+though types and methods have a one-to-one correspondence with the old
+types and the HAL struct methods.</p>
+
+
+<h3 id="hidl-overview">HIDL overview</h3>
+
+<p>
+The Hardware Interface Definition Language (HIDL) provides an implementation
+language-independent mechanism for specifying hardware interfaces. The HIDL
+tooling currently supports generation of C++ and Java interfaces. It's expected
+that most Trusted Execution Environment (TEE) implementers will find the C++
+tooling more convenient, so this document discusses only the C++ representation.
+</p>
+<p>
+HIDL interfaces consist of a set of methods, expressed as:
+</p>
+<pre class="devsite-click-to-copy">
+	methodName(<var>INPUT ARGUMENTS</var>) generates (<var>RESULT ARGUMENTS</var>);
+</pre>
+<p>
+There are various pre-defined types, and HALs can define new enumerated and
+structure types. For more details on HIDL, see the <a
+     href="/reference/">Reference section</a>.
+</p>
+<p>
+An example method from the Keymaster 3 <code>IKeymasterDevice.hal</code> is:
+</p>
+
+
+<pre class="devsite-click-to-copy">generateKey(vec&lt;KeyParameter&gt; keyParams)
+        generates(ErrorCode error, vec&lt;uint8_t&gt; keyBlob, 
+                  KeyCharacteristics keyCharacteristics);</pre>
+<p>
+This is the equivalent of the following from the keymaster2 HAL.:
+</p>
+
+<pre class="devsite-click-to-copy">keymaster_error_t (*generate_key)(
+        const struct keymaster2_device* dev,
+        const keymaster_key_param_set_t* params,
+        keymaster_key_blob_t* key_blob,
+        keymaster_key_characteristics_t* characteristics);
+</pre>
+<p>
+In the HIDL version, the <code>dev</code> argument is removed, because it's
+implicit. The <code>params</code> argument is no longer a struct containing a
+pointer referencing an array of <code>key_parameter_t</code> objects, but a
+<code>vec</code> (vector) containing <code>KeyParameter</code> objects. The
+return values are listed in the "<code>generates</code>" clause, including a
+vector of <code>uint8_t</code> values for the key blob.
+</p>
+<p>
+The C++ virtual method generated by the HIDL compiler is:
+</p>
+
+<pre class="devsite-click-to-copy">
+Return&lt;void&gt; generateKey(const hidl_vec&lt;KeyParameter&gt;& keyParams,
+                         generateKey_cb _hidl_cb) override;
+</pre>
+<p>
+Where <code>generate_cb</code> is a function pointer defined as:
+</p>
+
+<pre class="devsite-click-to-copy">std::function&lt;void(ErrorCode error, const hidl_vec&lt;uint8_t&gt;& keyBlob,
+                   const KeyCharacteristics& keyCharacteristics)&gt;
+</pre>
+<p>
+That is, <code>generate_cb</code> is a function that takes the return values
+listed in the generate clause. The HAL implementation class overrides this
+<code>generateKey</code> method and calls the <code>generate_cb</code> function
+pointer to return the result of the operation to the caller. Note the function
+pointer call is <strong>synchronous</strong>. The caller calls
+<code>generateKey</code> and <code>generateKey</code> calls the supplied
+function pointer, which executes to completion, returning control to the
+<code>generateKey</code> implementation, which then returns to the caller.
+</p>
+<p>
+For a detailed example, see the default implementation in
+<code>hardware/interfaces/keymaster/3.0/default/KeymasterDevice.cpp</code>.
+The default implementation provides backward compatibility for devices with
+old-style keymaster0, keymaster1, or keymaster2 HALS.</p>
+
+
+
   </body>
 </html>
diff --git a/en/security/keystore/tags.html b/en/security/keystore/tags.html
index 73880c8..8253b7e 100644
--- a/en/security/keystore/tags.html
+++ b/en/security/keystore/tags.html
@@ -26,31 +26,56 @@
 It covers each tag in the HAL, which Keymaster version that tag is available
 in, and whether the tag is repeatable. Except as noted in the tag descriptions,
 all of the tags below are used during key generation to specify key
-characteristics. For functions, see the
+characteristics.</p>
+<p>For Keymaster 3, tags are defined in
+<code>platform/hardware/interfaces/keymaster/3.0/types.hal</code>. For
+Keymaster 2 and below, tags are defined in 
+<code><a href="https://android.googlesource.com/platform/hardware/libhardware/+/master/include/hardware">
+hardware/libhardware/include/hardware/keymaster_defs.h</a></code>.</p>
+
+<p>For functions, see the
 <a href="/security/keystore/implementer-ref">Keymaster Functions</a> page.</p>
 
-<h2 id="active_datetime">KM_TAG_ACTIVE_DATETIME</h2>
+<p class="note">To support Keymaster 3's transition from the old-style
+C-structure HAL to the C++ HAL interface generated from a definition in the new
+Hardware Interface Definition Language (HIDL), tag names have changed in
+Android 8.0. Tags, like all other keymaster enums, are now defined as C++
+scoped enums. For example, tags, formerly prefixed with <code>KM_TAG_</code>,
+are now prefixed with <code>Tag::</code>.</p>
 
-<p><strong>Version</strong>: 1, 2</p>
+<h2 id="active_datetime">Tag::ACTIVE_DATETIME</h2>
+
+<p><strong>Version</strong>: 1, 2, 3</p>
 <p><strong>Repeatable</strong>? No</p>
 
 <p>Specifies the date and time at which the key becomes active. Prior to this
 time, any attempt to use the key fails with
-<code>KM_ERROR_KEY_NOT_YET_VALID</code>.</p>
+<code>ErrorCode::KEY_NOT_YET_VALID</code>.</p>
 
 <p>The value is a 64-bit integer representing milliseconds since January 1,
 1970.</p>
 
 
-<h2 id="algorithm">KM_TAG_ALGORITHM</h2>
+<h2 id="algorithm">Tag::ALGORITHM</h2>
 
-<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Version</strong>: 1, 2, 3</p>
 <p><strong>Repeatable</strong>? No</p>
 
 <p>Specifies the cryptographic algorithm with which the key is used.</p>
 
 <p>Possible values are defined by the following enumeration:</p>
 
+<strong>Keymaster 3</strong>
+<pre class="devsite-click-to-copy">
+enum class Algorithm : uint32_t {
+    RSA = 1,
+    EC = 3,
+    AES = 32,
+    HMAC = 128,
+};
+</pre>
+
+<strong>Keymaster 2 and earlier</strong>
 <pre class="devsite-click-to-copy">
 typedef enum {
     KM_ALGORITHM_RSA = 1,
@@ -61,17 +86,17 @@
 </pre>
 
 
-<h2 id="all_applications">KM_TAG_ALL_APPLICATIONS</h2>
+<h2 id="all_applications">Tag::ALL_APPLICATIONS</h2>
 
-<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Version</strong>: 1, 2, 3</p>
 <p><strong>Repeatable</strong>? No</p>
 
 <p>Reserved for future use.</p>
 
 
-<h2 id="allow_while_on_body">KM_TAG_ALLOW_WHILE_ON_BODY</h2>
+<h2 id="allow_while_on_body">Tag::ALLOW_WHILE_ON_BODY</h2>
 
-<p><strong>Version</strong>: 2</p>
+<p><strong>Version</strong>: 2, 3</p>
 <p><strong>Repeatable</strong>? No</p>
 
 <p>This tag is applicable only for Android Wear devices with on-body sensors. At
@@ -79,23 +104,30 @@
 to an on-body sensor, or that on-body sensors are very secure, so this is
 expected to be a purely software-enforced feature.</p>
 
-<h2 id="application_data">KM_TAG_APPLICATION_DATA</h2>
+<h2 id="all_users">Tag::ALL_USERS</h2>
 
-<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Version</strong>: 3</p>
+<p><strong>Repeatable</strong>? No</p>
+
+<p>Reserved for future use.</p>
+
+<h2 id="application_data">Tag::APPLICATION_DATA</h2>
+
+<p><strong>Version</strong>: 1, 2, 3</p>
 <p><strong>Repeatable</strong>? No</p>
 
 <p>When provided to
-<a href="/security/keystore/implementer-ref#generate_key">generate_key</a>
-or <a href="/security/keystore/implementer-ref#import_key">import_key</a>,
+<a href="/security/keystore/implementer-ref#generate_key">generateKey</a>
+or <a href="/security/keystore/implementer-ref#import_key">importKey</a>,
 this tag specifies data that is necessary during all uses of the key. In
 particular, calls to
-<a href="/security/keystore/implementer-ref#export_key">export_key</a> and
-<a href="/security/keystore/implementer-ref#get_key_characteristics">get_key_characteristics</a>
-need to provide the same value to the <code>client_id</code> parameter, and calls
+<a href="/security/keystore/implementer-ref#export_key">exportKey</a> and
+<a href="/security/keystore/implementer-ref#get_key_characteristics">getKeyCharacteristics</a>
+need to provide the same value to the <code>clientId</code> parameter, and calls
 to <a href="/security/keystore/implementer-ref#begin">begin</a> need to provide
-this tag and the same associated data as part of the <code>in_params</code>
+this tag and the same associated data as part of the <code>inParams</code>
 set. If the correct data is not provided, the function returns
-<code>KM_ERROR_INVALID_KEY_BLOB</code>.</p>
+<code>ErrorCode::INVALID_KEY_BLOB</code>.</p>
 
 <p>The content of this tag is bound to the key <em>cryptographically</em>,
 meaning it must not be possible for an adversary who has access to all of the
@@ -106,23 +138,23 @@
 <p>The value is a blob, an arbitrary-length array of bytes.</p>
 
 
-<h2 id="application_id">KM_TAG_APPLICATION_ID</h2>
+<h2 id="application_id">Tag::APPLICATION_ID</h2>
 
-<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Version</strong>: 1, 2, 3</p>
 <p><strong>Repeatable</strong>? No</p>
 
 <p>When provided to
-<a href="/security/keystore/implementer-ref#generate_key">generate_key</a>
-or <a href="/security/keystore/implementer-ref#import_key">import_key</a>,
+<a href="/security/keystore/implementer-ref#generate_key">generateKey</a>
+or <a href="/security/keystore/implementer-ref#import_key">importKey</a>,
 this tag specifies data that is necessary during all uses of the key. In
 particular, calls to
-<a href="/security/keystore/implementer-ref#export_key">export_key</a> and
-<a href="/security/keystore/implementer-ref#get_key_characteristics">get_key_characteristics</a>
-need to provide the same value in the <code>client_id</code> parameter, and
+<a href="/security/keystore/implementer-ref#export_key">exportKey</a> and
+<a href="/security/keystore/implementer-ref#get_key_characteristics">getKeyCharacteristics</a>
+need to provide the same value in the <code>clientId</code> parameter, and
 calls to <a href="/security/keystore/implementer-ref#begin">begin</a> need to
 provide this tag and the same associated data as part of the
-<code>in_params</code> set. If the correct data is not provided, the function
-returns <code>KM_ERROR_INVALID_KEY_BLOB</code>.</p>
+<code>inParams</code> set. If the correct data is not provided, the function
+returns <code>ErrorCode::INVALID_KEY_BLOB</code>.</p>
 
 <p>The content of this tag is bound to the key <em>cryptographically</em>,
 meaning it an adversary who can access all of the secure world secrets—but
@@ -132,9 +164,9 @@
 <p>The value is a blob, an arbitrary-length array of bytes.</p>
 
 
-<h2 id="associated_data">KM_TAG_ASSOCIATED_DATA</h2>
+<h2 id="associated_data">Tag::ASSOCIATED_DATA</h2>
 
-<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Version</strong>: 1, 2, 3</p>
 <p><strong>Repeatable</strong>? No</p>
 
 <p>Provides "associated data" for AES-GCM encryption or decryption. This tag is
@@ -144,44 +176,162 @@
 
 <p>The value is a blob, an arbitrary-length array of bytes.</p>
 
+<h2 id="attestation_application_id">Tag::ATTESTATION_APPLICATION_ID</h2>
+<p><strong>Version</strong>: 3</p>
+<p><strong>Repeatable</strong>? No</p>
 
-<h2 id="auth_timeout">KM_TAG_AUTH_TIMEOUT</h2>
+ <p>Used to identify the set of possible applications of which one
+ has initiated a key attestation.</p>
 
-<p><strong>Version</strong>: 1, 2</p>
+<p>The value is a blob, an arbitrary-length array of bytes.</p>
+
+<h2 id="attestation_challenge">Tag::ATTESTATION_CHALLENGE</h2>
+<p><strong>Version</strong>: 3</p>
+<p><strong>Repeatable</strong>? No</p>
+
+<p>Used to provide challenge in attestation.</p>
+<p>The value is a blob, an arbitrary-length array of bytes.</p>
+
+<h2 id="attestation_id_brand">Tag::ATTESTATION_ID_BRAND</h2>
+<p><strong>Version</strong>: 3</p>
+<p><strong>Repeatable</strong>? No</p>
+
+<p>Provides the device's brand name, as returned by <code>Build.BRAND</code>
+in Android. This field is set only when requesting attestation of the
+device's identifiers.</p>
+<p>If the device does not support ID attestation (or
+<code>destroyAttestationIds()</code> was previously called and the device can
+no longer attest its IDs), any key attestation request that includes
+this tag fails with <code>ErrorCode::CANNOT_ATTEST_IDS</code>.</p>
+<p>The value is a blob, an arbitrary-length array of bytes.</p>
+
+<h2 id="attestation_id_device">Tag::ATTESTATION_ID_DEVICE</h2>
+<p><strong>Version</strong>: 3</p>
+<p><strong>Repeatable</strong>? No</p>
+
+<p>Provides the device's device name, as returned by <code>Build.DEVICE</code>
+in Android. This field is set only when requesting attestation of the
+device's identifiers.</p>
+<p>If the device does not support ID attestation (or
+<code>destroyAttestationIds()</code> was previously called and the device can
+no longer attest its IDs), any key attestation request that includes
+this tag fails with <code>ErrorCode::CANNOT_ATTEST_IDS</code>.</p>
+<p>The value is a blob, an arbitrary-length array of bytes.</p>
+
+<h2 id="attestation_id_imei">Tag::ATTESTATION_ID_IMEI</h2>
+<p><strong>Version</strong>: 3</p>
+<p><strong>Repeatable</strong>? Yes</p>
+
+<p>Provides the IMEIs for all radios on the device. This field is set only
+when requesting attestation of the device's identifiers.</p>
+<p>If the device does not support ID attestation (or
+<code>destroyAttestationIds()</code> was previously called and the device can
+no longer attest its IDs), any key attestation request that includes
+this tag fails with <code>ErrorCode::CANNOT_ATTEST_IDS</code>.</p>
+<p>The value is a blob, an arbitrary-length array of bytes.</p>
+
+<h2 id="attestation_id_manufacturer">Tag::ATTESTATION_ID_MANUFACTURER</h2>
+<p><strong>Version</strong>: 3</p>
+<p><strong>Repeatable</strong>? No</p>
+
+<p>Provides the device's manufacturer name, as returned by
+<code>Build.MANUFACTURER</code> in Android. This field is set only when
+requesting attestation of the device's identifiers.</p>
+<p>If the device does not support ID attestation (or
+<code>destroyAttestationIds()</code> was previously called and the device can
+no longer attest its IDs), any key attestation request that includes
+this tag fails with <code>ErrorCode::CANNOT_ATTEST_IDS</code>.</p>
+<p>The value is a blob, an arbitrary-length array of bytes.</p>
+
+<h2 id="attestation_id_meid">Tag::ATTESTATION_ID_MEID</h2>
+<p><strong>Version</strong>: 3</p>
+<p><strong>Repeatable</strong>? Yes</p>
+
+<p>Provides the MEIDs for all radios on the device. This field will only be set
+when requesting attestation of the device's identifiers.</p>
+<p>If the device does not support ID attestation (or
+<code>destroyAttestationIds()</code> was previously called and the device can
+no longer attest its IDs), any key attestation request that includes
+this tag fails with <code>ErrorCode::CANNOT_ATTEST_IDS</code>.</p>
+<p>The value is a blob, an arbitrary-length array of bytes.</p>
+
+<h2 id="attestation_id_model">Tag::ATTESTATION_ID_MODEL</h2>
+<p><strong>Version</strong>: 3</p>
+<p><strong>Repeatable</strong>? No</p>
+
+<p>Provides the device's model name, as returned by
+<code>Build.MODEL</code> in Android. This field is set only when
+requesting attestation of the device's identifiers.</p>
+<p>If the device does not support ID attestation (or
+<code>destroyAttestationIds()</code> was previously called and the device can
+no longer attest its IDs), any key attestation request that includes
+this tag fails with <code>ErrorCode::CANNOT_ATTEST_IDS</code>.</p>
+
+<p>The value is a blob, an arbitrary-length array of bytes.</p>
+
+
+<h2 id="attestation_id_product">Tag::ATTESTATION_ID_PRODUCT</h2>
+<p><strong>Version</strong>: 3</p>
+<p><strong>Repeatable</strong>? No</p>
+
+<p>Provides the device's product name, as returned by
+<code>Build.PRODUCT</code> in Android. This field is set only when
+requesting attestation of the device's identifiers.</p>
+<p>If the device does not support ID attestation (or
+<code>destroyAttestationIds()</code> was previously called and the device can
+no longer attest its IDs), any key attestation request that includes
+this tag fails with <code>ErrorCode::CANNOT_ATTEST_IDS</code>.</p>
+<p>The value is a blob, an arbitrary-length array of bytes.</p>
+
+<h2 id="attestation_id_serial">Tag::ATTESTATION_ID_SERIAL</h2>
+<p><strong>Version</strong>: 3</p>
+<p><strong>Repeatable</strong>? No</p>
+
+<p>Provides the device's serial number. This field is set only when
+requesting attestation of the device's identifiers.</p>
+<p>If the device does not support ID attestation (or
+<code>destroyAttestationIds()</code> was previously called and the device can
+no longer attest its IDs), any key attestation request that includes
+this tag fails with <code>ErrorCode::CANNOT_ATTEST_IDS</code>.</p>
+<p>The value is a blob, an arbitrary-length array of bytes.</p>
+
+<h2 id="auth_timeout">Tag::AUTH_TIMEOUT</h2>
+
+<p><strong>Version</strong>: 1, 2, 3</p>
 <p><strong>Repeatable</strong>? No</p>
 
 <p>Specifies the time in seconds for which the key is authorized for use, after
-authentication. If <a href="#user_secure_id">KM_TAG_USER_SECURE_ID</a>
+authentication. If <a href="#user_secure_id">Tag::USER_SECURE_ID</a>
 is present and this tag is not, then the key needs authentication for every
 usage (see <a href="/security/keystore/implementer-ref#begin">begin</a> for the
 details of the authentication-per-operation flow).</p>
 
 <p>The value is a 32-bit integer specifying the time in seconds after a successful
 authentication of the user specified by
-<a href="#user_secure_id">KM_TAG_USER_SECURE_ID</a> with
+<a href="#user_secure_id">Tag::USER_SECURE_ID</a> with
 the authentication method specified
-by <a href="#mac_length">KM_TAG_USER_AUTH_TYPE</a> that the key can be used.</p>
+by <a href="#mac_length">Tag::USER_AUTH_TYPE</a> that the key can be used.</p>
 
 
-<h2 id="auth_token">KM_TAG_AUTH_TOKEN</h2>
+<h2 id="auth_token">Tag::AUTH_TOKEN</h2>
 
-<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Version</strong>: 1, 2, 3</p>
 <p><strong>Repeatable</strong>? No</p>
 
-<p>Provides an authentication token (see the
-<a href="/security/keystore/features#user_authentication">Authentication</a>
-page) to <a href="/security/keystore/implementer-ref#begin">begin</a>,
+<p>Provides an
+<a href="/security/keystore/authentication/#authentication_token_format">authentication
+token</a> to <a href="/security/keystore/implementer-ref#begin">begin</a>,
 <a href="/security/keystore/implementer-ref#update">update</a> or
 <a href="/security/keystore/implementer-ref#finish">finish</a>,
 to prove user authentication for a key operation that requires
-it (key has <a href="#user_secure_id">KM_TAG_USER_SECURE_ID</a>).</p>
+it (key has <a href="#user_secure_id">Tag::USER_SECURE_ID</a>).</p>
 
 <p>The value is a blob which contains a <code>hw_auth_token_t</code> structure.</p>
 
 
-<h2 id="blob_usage_requirements">KM_TAG_BLOB_USAGE_REQUIREMENTS</h2>
+<h2 id="blob_usage_requirements">Tag::BLOB_USAGE_REQUIREMENTS</h2>
 
-<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Version</strong>: 1, 2, 3</p>
 <p><strong>Repeatable</strong>? No</p>
 
 <p>Specifies the necessary system environment conditions for the generated
@@ -189,6 +339,15 @@
 
 <p>Possible values are defined by the following enumeration:</p>
 
+<strong>Keymaster 3</strong>
+<pre class="devsite-click-to-copy">
+enum class KeyBlobUsageRequirements : uint32_t {
+    STANDALONE = 0,
+    REQUIRES_FILE_SYSTEM = 1,
+};
+</pre>
+
+<strong>Keymaster 2 and earlier</strong>
 <pre class="devsite-click-to-copy">
 typedef enum {
     KM_BLOB_STANDALONE = 0,
@@ -199,18 +358,18 @@
 <p>This tag can be specified during key generation to require that the key is
 usable in the specified condition. It needs to be returned with the key
 characteristics from
-<a href="/security/keystore/implementer-ref#generate_key">generate_key</a> and
-<a href="/security/keystore/implementer-ref#get_key_characteristics">get_key_characteristics</a>.
-If the caller specifies <code>KM_TAG_BLOB_USAGE_REQUIREMENTS</code> with
-value <code>KM_BLOB_STANDALONE</code> the trustlet returns a key blob
+<a href="/security/keystore/implementer-ref#generate_key">generateKey</a> and
+<a href="/security/keystore/implementer-ref#get_key_characteristics">getKeyCharacteristics</a>.
+If the caller specifies <code>Tag::BLOB_USAGE_REQUIREMENTS</code> with
+value <code>KeyBlobUsageRequirements::STANDALONE</code> the trustlet returns a key blob
 that can be used without file system support. This is critical for devices
 with encrypted disks, where the file system may not be available until
 after a Keymaster key is used to decrypt the disk.</p>
 
 
-<h2 id="block_mode">KM_TAG_BLOCK_MODE</h2>
+<h2 id="block_mode">Tag::BLOCK_MODE</h2>
 
-<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Version</strong>: 1, 2, 3</p>
 <p><strong>Repeatable</strong>? Yes</p>
 
 <p>Specifies the block cipher mode(s) with which the key may be used.
@@ -218,6 +377,17 @@
 
 <p>Possible values are defined by the following enumeration:</p>
 
+<strong>Keymaster 3</strong>
+<pre class="devsite-click-to-copy">
+enum class BlockMode : uint32_t {
+    ECB = 1,
+    CBC = 2,
+    CTR = 3,
+    GCM = 32,
+};
+</pre>
+
+<strong>Keymaster 2 and earlier</strong>
 <pre class="devsite-click-to-copy">
 typedef enum {
     KM_MODE_ECB = 1,
@@ -228,15 +398,15 @@
 </pre>
 
 <p>This tag is repeatable, and for AES key operations specify a mode in
-the <code>additional_params</code> argument of
+the <code>additionalParams</code> argument of
 <a href="/security/keystore/implementer-ref#begin">begin</a>.
 If the specifiedmode is not in the modes associated with the key, the
-operation fails with <code>KM_ERROR_INCOMPATIBLE_BLOCK_MODE</code>.</p>
+operation fails with <code>ErrorCode::INCOMPATIBLE_BLOCK_MODE</code>.</p>
 
 
-<h2 id="bootloader_only">KM_TAG_BOOTLOADER_ONLY</h2>
+<h2 id="bootloader_only">Tag::BOOTLOADER_ONLY</h2>
 
-<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Version</strong>: 1, 2, 3</p>
 <p><strong>Repeatable</strong>? No</p>
 
 <p>Specifies only the bootloader can use the key.</p>
@@ -244,13 +414,13 @@
 <p>This tag is boolean, so the possible values are true (if the tag is present)
 and false (if the tag is not present).</p>
 
-<p>Any attempt to use a key with <code>KM_TAG_BOOTLOADER_ONLY</code> from the
-Android system fails with <code>KM_ERROR_INVALID_KEY_BLOB</code>.</p>
+<p>Any attempt to use a key with <code>Tag::BOOTLOADER_ONLY</code> from the
+Android system fails with <code>ErrorCode::INVALID_KEY_BLOB</code>.</p>
 
 
-<h2 id="caller_nonce">KM_TAG_CALLER_NONCE</h2>
+<h2 id="caller_nonce">Tag::CALLER_NONCE</h2>
 
-<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Version</strong>: 1, 2, 3</p>
 <p><strong>Repeatable</strong>? No</p>
 
 <p>Specifies that the caller can provide a nonce for nonce-requiring operations.</p>
@@ -260,23 +430,23 @@
 
 <p>This tag is used only for AES keys, and is only relevant for CBC, CTR and GCM
 block modes. If the tag is not present, implementations should reject any
-operation that provides <a href="#nonce">KM_TAG_NONCE</a> to
+operation that provides <a href="#nonce">Tag::NONCE</a> to
 <a href="/security/keystore/implementer-ref#begin">begin</a>
-with <code>KM_ERROR_CALLER_NONCE_PROHIBITED</code>.</p>
+with <code>ErrorCode::CALLER_NONCE_PROHIBITED</code>.</p>
 
 
-<h2 id="creation_datetime">KM_TAG_CREATION_DATETIME</h2>
+<h2 id="creation_datetime">Tag::CREATION_DATETIME</h2>
 
-<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Version</strong>: 1, 2, 3</p>
 <p><strong>Repeatable</strong>? No</p>
 
 <p>Specifies the date and time the key was created, in milliseconds since January
 1, 1970. This tag is optional and informational only.</p>
 
 
-<h2 id="digest">KM_TAG_DIGEST</h2>
+<h2 id="digest">Tag::DIGEST</h2>
 
-<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Version</strong>: 1, 2, 3</p>
 <p><strong>Repeatable</strong>? Yes</p>
 
 <p>Specifies the digest algorithms that may be used with the key to perform
@@ -285,6 +455,20 @@
 
 <p>Possible values are defined by the following enumeration:</p>
 
+<strong>Keymaster 3</strong>
+<pre class="devsite-click-to-copy">
+enum class Digest : uint32_t {
+    NONE = 0,
+    MD5 = 1,
+    SHA1 = 2,
+    SHA_2_224 = 3,
+    SHA_2_256 = 4,
+    SHA_2_384 = 5,
+    SHA_2_512 = 6,
+};
+</pre>
+
+<strong>Keymaster 2 and earlier</strong>
 <pre class="devsite-click-to-copy">
 typedef enum {
     KM_DIGEST_NONE = 0,
@@ -299,23 +483,34 @@
 </pre>
 
 <p>This tag is repeatable. For signing and verification operations, specify
-a digest in the <code>additional_params</code> argument of
+a digest in the <code>additionalParams</code> argument of
 <a href="/security/keystore/implementer-ref#begin">begin</a>.
 If the specified digest is not in the digests associated with the key, the
-operation fails with <code>KM_ERROR_INCOMPATIBLE_DIGEST</code>.</p>
+operation fails with <code>ErrorCode::INCOMPATIBLE_DIGEST</code>.</p>
 
-<h2 id="ec_curve">KM_TAG_EC_CURVE</h2>
+<h2 id="ec_curve">Tag::EC_CURVE</h2>
 
-<p><strong>Version</strong>: 2</p>
+<p><strong>Version</strong>: 2, 3</p>
 <p><strong>Repeatable</strong>? No</p>
 
 <p>In Keymaster 1, the curve used for EC keys was guessed from the specified key
 size. To improve flexibility moving forward, Keymaster 2 introduced an explicit
 way to specify curves. EC key generation requests may have
-<code>KM_TAG_EC_CURVE</code>, <code>KM_TAG_KEY_SIZE</code>, or both.</p>
+<code>Tag::EC_CURVE</code>, <code>Tag::KEY_SIZE</code>, or both.</p>
 
 <p>Possible values are defined by the following enumeration:</p>
 
+<strong>Keymaster 3</strong>
+<pre class="devsite-click-to-copy">
+enum class EcCurve : uint32_t {
+    P_224 = 0,
+    P_256 = 1,
+    P_384 = 2,
+    P_521 = 3,
+};
+</pre>
+
+<strong>Keymaster 2 and earlier</strong>
 <pre class="devsite-click-to-copy">
 enum class EcCurve : uint32_t {
     P_224 = 0,
@@ -325,53 +520,63 @@
 };
 </pre>
 
-<p>If a generation request only contains <code>KM_TAG_KEY_SIZE</code>,
+<p>If a generation request only contains <code>Tag::KEY_SIZE</code>,
 fall back to the Keymaster 1 logic, choosing the appropriate NIST curve.</p>
 
-<p>If the request only contains <code>KM_TAG_EC_CURVE</code>, use the
-specified curve. Curves are defined in <code>keymaster_ec_curve_t</code>.</p>
+<p>If the request only contains <code>Tag::EC_CURVE</code>, use the
+specified curve. For Keymaster 3 and later, curves are defined in
+<code>EcCurve</code>. For Keymaster 2 and earlier, curves are defined
+in <code>keymaster_ec_curve_t</code>.</p>
 
 <p>If the request contains both, use the curve specified by
-<code>KM_TAG_EC_CURVE</code>, and validate that the specified key size is
+<code>Tag::EC_CURVE</code>, and validate that the specified key size is
 appropriate for that curve. If not, return
-<code>KM_ERROR_INVALID_ARGUMENT</code>.</p>
+<code>ErrorCode::INVALID_ARGUMENT</code>.</p>
 
 
-<h2 id="include_unique_id">KM_TAG_INCLUDE_UNIQUE_ID</h2>
+<h2 id="include_unique_id">Tag::INCLUDE_UNIQUE_ID</h2>
 
-<p><strong>Version</strong>: 2</p>
+<p><strong>Version</strong>: 2, 3</p>
 <p><strong>Repeatable</strong>? No</p>
 
 <p>This tag is specified during key generation to indicate that an attestation
-certificate for the generated key should contain a Unique ID.</p>
+certificate for the generated key should contain an application-scoped and
+time-bounded device-unique ID, as specified by
+<a href="#unique_id">Tag::UNIQUE_ID</a>.</p>
 
+<p>This tag is boolean, so the possible values are true (if the tag is present)
+and false (if the tag is not present).</p>
 
-<h2 id="key_size">KM_TAG_KEY_SIZE</h2>
+<h2 id="key_size">Tag::KEY_SIZE</h2>
 
-<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Version</strong>: 1, 2, 3</p>
 <p><strong>Repeatable</strong>? No</p>
 
 <p>Specifies the size, in bits, of the key, measuring in the normal way for the
-key's algorithm. For example, for RSA keys, <code>KM_TAG_KEY_SIZE</code> specifies
+key's algorithm. For example, for RSA keys, <code>Tag::KEY_SIZE</code> specifies
 the size of the public modulus. For AES keys it specifies the length
 of the secret key material.</p>
+<p class="note">In Keymaster 2 and later, <code>Tag::KEY_SIZE</code> is no longer the
+preferred mechanism for selecting ECC (elliptic curve cryptography) curves.
+While it is unchanged for other key types, ECC curves are selected using the
+tag <a href="#ec_curve"><code>Tag::EC_CURVE</code></a>.</p>
 
 
-<h2 id="mac_length">KM_TAG_MAC_LENGTH</h2>
+<h2 id="mac_length">Tag::MAC_LENGTH</h2>
 
-<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Version</strong>: 1, 2, 3</p>
 <p><strong>Repeatable</strong>? No</p>
 
 <p>Provides the requested length of a MAC or GCM authentication tag, in bits.</p>
 
 <p>The value is the MAC length in bits. It is a multiple of 8 and at
-least as large as the value of <a href="#min_mac_length">KM_TAG_MIN_MAC_LENGTH</a>
+least as large as the value of <a href="#min_mac_length">Tag::MIN_MAC_LENGTH</a>
 associated with the key.</p>
 
 
-<h2 id="max_uses_per_boot">KM_TAG_MAX_USES_PER_BOOT</h2>
+<h2 id="max_uses_per_boot">Tag::MAX_USES_PER_BOOT</h2>
 
-<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Version</strong>: 1, 2, 3</p>
 <p><strong>Repeatable</strong>? No</p>
 
 <p>Specifies the maximum number of times that a key may be used between system
@@ -383,18 +588,18 @@
 should be incremented during the
 <a href="/security/keystore/implementer-ref#begin">begin</a> call. After the key
 counter has exceeded this value, all subsequent attempts to use the key fail
-with <code>KM_ERROR_MAX_OPS_EXCEEDED</code>, until the device is restarted. This
+with <code>ErrorCode::MAX_OPS_EXCEEDED</code>, until the device is restarted. This
 implies that a trustlet keeps a table of use counters for keys with this tag.
 Because Keymaster memory is often limited, this table can have a fixed maximum
 size and Keymaster can fail operations that attempt to use keys with this tag
 when the table is full. The table needs to acommodate at least 16 keys. If an
 operation fails because the table is full, Keymaster returns
-<code>KM_ERROR_TOO_MANY_OPERATIONS</code>.</p>
+<code>ErrorCode::TOO_MANY_OPERATIONS</code>.</p>
 
 
-<h2 id="min_mac_length">KM_TAG_MIN_MAC_LENGTH</h2>
+<h2 id="min_mac_length">Tag::MIN_MAC_LENGTH</h2>
 
-<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Version</strong>: 1, 2, 3</p>
 <p><strong>Repeatable</strong>? No</p>
 
 <p>This tag specifies the minimum length of MAC that can be requested or
@@ -405,9 +610,9 @@
 and no more than 128.</p>
 
 
-<h2 id="min_seconds_between_ops">KM_TAG_MIN_SECONDS_BETWEEN_OPS</h2>
+<h2 id="min_seconds_between_ops">Tag::MIN_SECONDS_BETWEEN_OPS</h2>
 
-<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Version</strong>: 1, 2, 3</p>
 <p><strong>Repeatable</strong>? No</p>
 
 <p>Specifies the minimum amount of time that elapses between allowed
@@ -421,32 +626,32 @@
 <a href="/security/keystore/implementer-ref#abort">abort</a> call. Any
 call to <a href="/security/keystore/implementer-ref#begin">begin</a> that is received
 before the timer indicates that the interval specified by
-<code>KM_TAG_MIN_SECONDS_BETWEEN_OPS</code> has elapsed fails with
-<code>KM_ERROR_KEY_RATE_LIMIT_EXCEEDED</code>.This
+<code>Tag::MIN_SECONDS_BETWEEN_OPS</code> has elapsed fails with
+<code>ErrorCode::KEY_RATE_LIMIT_EXCEEDED</code>.This
 implies that a trustlet keeps a table of use counters for keys with this tag.
 Because Keymaster memory is often limited, this table can have a fixed maximum size
 and Keymaster can fail operations that attempt to use keys with this tag
 when the table is full. The table needs to acommodate at least 32 in-use
 keys and aggressively reuse table slots when key minimum-usage intervals expire.
 If an operation fails because the table is full, Keymaster returns
-<code>KM_ERROR_TOO_MANY_OPERATIONS</code>.</p>
+<code>ErrorCode::TOO_MANY_OPERATIONS</code>.</p>
 
 
-<h2 id="no_auth_required">KM_TAG_NO_AUTH_REQUIRED</h2>
+<h2 id="no_auth_required">Tag::NO_AUTH_REQUIRED</h2>
 
-<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Version</strong>: 1, 2, 3</p>
 <p><strong>Repeatable</strong>? No</p>
 
 <p>Specifies that no authentication is required to use this key. This tag is
-mutually exclusive with <a href="#user_secure_id">KM_TAG_USER_SECURE_ID</a>.</p>
+mutually exclusive with <a href="#user_secure_id">Tag::USER_SECURE_ID</a>.</p>
 
 <p>This tag is boolean, so the possible values are true (if the tag is present)
 and false (if the tag is not present).</p>
 
 
-<h2 id="nonce">KM_TAG_NONCE</h2>
+<h2 id="nonce">Tag::NONCE</h2>
 
-<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Version</strong>: 1, 2, 3</p>
 <p><strong>Repeatable</strong>? No</p>
 
 <p>Provides or returns a nonce or Initialization Vector (IV) for AES GCM, CBC, or
@@ -454,7 +659,7 @@
 <a href="/security/keystore/implementer-ref#begin">begin</a>
 during encryption and decryption operations. It is only provided to
 <a href="/security/keystore/implementer-ref#begin">begin</a>
-if the key has <a href="#caller_nonce">KM_TAG_CALLER_NONCE</a>. If not provided,
+if the key has <a href="#caller_nonce">Tag::CALLER_NONCE</a>. If not provided,
 an appropriate nonce or IV will be randomly generated by
 Keymaster and returned from begin.</p>
 
@@ -463,17 +668,29 @@
 length.</p>
 
 
-<h2 id="origin">KM_TAG_ORIGIN</h2>
+<h2 id="origin">Tag::ORIGIN</h2>
 
-<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Version</strong>: 1, 2, 3</p>
 <p><strong>Repeatable</strong>? No</p>
 
 <p>Specifies where the key was created, if known. This tag may not be specified
 during key generation or import, and must be added to the key characteristics
 by the trustlet.</p>
 
-<p>The possible values are defined in <code>keymaster_origin_t</code>:</p>
+<strong>Keymaster 3</strong>
+<p>The possible values are defined in
+<code>android::hardware::keymaster::v3_0::KeyOrigin</code>:</p>
+<pre class="devsite-click-to-copy">
+enum class KeyOrigin : uint32_t {
+    GENERATED = 0,
+    DERIVED = 1,
+    IMPORTED = 2,
+    UNKNOWN = 3,
+};
+</pre>
 
+<strong>Keymaster 2 and earlier</strong>
+<p>The possible values are defined in <code>keymaster_origin_t</code>:</p>
 <pre class="devsite-click-to-copy">
 typedef enum {
     KM_ORIGIN_GENERATED = 0,
@@ -485,44 +702,47 @@
 <p>The full meaning of the value depends not only on the value but on whether it's
 found in the hardware-enforced or software-enforced characteristics list.</p>
 
-<p><code>KM_ORIGIN_GENERATED</code> indicates that Keymaster generated the key.
+<p><code>GENERATED</code> indicates that Keymaster generated the key.
 If in the hardware-enforced list,
-the key was generated in secure hardware and is permanently hardware-bound. If
+the key was generated in secure hardware and is permanently hardware bound. If
 in the software-enforced list, the key was generated in SoftKeymaster and is
-not hardware-bound.</p>
+not hardware bound.</p>
 
-<p><code>KM_ORIGIN_IMPORTED</code> indicates that the key was generated outside
+<p><code>DERIVED</code> indicates that the key was derived inside Keymaster.
+Likely exists off-device.</p>
+
+<p><code>IMPORTED</code> indicates that the key was generated outside
 of Keymaster and imported into
-Keymaster. If in the hardware-enforced list, it is permanently hardware-bound,
+Keymaster. If in the hardware-enforced list, it is permanently hardware bound,
 although copies outside of secure hardware may exist. If in the
 software-enforces list, the key was imported into SoftKeymaster and is not
-hardware-bound.</p>
+hardware bound.</p>
 
-<p><code>KM_ORIGIN_UNKNOWN</code> should only appear in the hardware-enforced list.
+<p><code>UNKNOWN</code> should only appear in the hardware-enforced list.
 It indicates that the key is
-hardware-bound, but it is not known whether the key was originally generated in
+hardware bound, but it is not known whether the key was originally generated in
 secure hardware or was imported. This only occurs when keymaster0 hardware is
 being used to emulate keymaster1 services.</p>
 
 
-<h2 id="origination_expire_datetime">KM_TAG_ORIGINATION_EXPIRE_DATETIME</h2>
+<h2 id="origination_expire_datetime">Tag::ORIGINATION_EXPIRE_DATETIME</h2>
 
-<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Version</strong>: 1, 2, 3</p>
 <p><strong>Repeatable</strong>? No</p>
 
 <p>Specifies the date and time at which the key expires for signing and encryption
 purposes. After this time, any attempt to use a key
-with <a href="#purpose">KM_PURPOSE_SIGN</a> or
-<a href="#purpose">KM_PURPOSE_ENCRYPT</a> provided
+with <a href="#purpose">KeyPurpose::SIGN</a> or
+<a href="#purpose">KeyPurpose::ENCRYPT</a> provided
 to <a href="/security/keystore/implementer-ref#begin">begin</a> fails
-with <code>KM_ERROR_KEY_EXPIRED</code>.</p>
+with <code>ErrorCode::KEY_EXPIRED</code>.</p>
 
 <p>The value is a 64-bit integer representing milliseconds since January 1, 1970.</p>
 
 
-<h2 id="os_patchlevel">KM_TAG_OS_PATCHLEVEL</h2>
+<h2 id="os_patchlevel">Tag::OS_PATCHLEVEL</h2>
 
-<p><strong>Version</strong>: 2</p>
+<p><strong>Version</strong>: 2, 3</p>
 <p><strong>Repeatable</strong>? No</p>
 
 <p>This tag is never sent to the keymaster TA, but is added to the
@@ -536,15 +756,15 @@
 <p>Keys that have a patch level different than the current patch level are not
 usable. An attempt to use such a key causes
 <a href="/security/keystore/implementer-ref#begin">begin</a>,
-<a href="/security/keystore/implementer-ref#get_key_characteristics">get_key_characteristics</a>,
-or <a href="/security/keystore/implementer-ref#export_key">export_key</a>
-to return <code>KM_ERROR_KEY_REQUIRES_UPGRADE</code>. See
+<a href="/security/keystore/implementer-ref#get_key_characteristics">getKeyCharacteristics</a>,
+or <a href="/security/keystore/implementer-ref#export_key">exportKey</a>
+to return <code>ErrorCode::KEY_REQUIRES_UPGRADE</code>. See
 <a href="/security/keystore/version-binding">Version Binding</a> for more details.</p>
 
 
-<h2 id="os_version">KM_TAG_OS_VERSION</h2>
+<h2 id="os_version">Tag::OS_VERSION</h2>
 
-<p><strong>Version</strong>: 2</p>
+<p><strong>Version</strong>: 2, 3</p>
 <p><strong>Repeatable</strong>? No</p>
 
 <p>This tag is never sent to the keymaster TA, but is added to the
@@ -556,9 +776,9 @@
 would be 040003.</p>
 
 
-<h2 id="padding">KM_TAG_PADDING</h2>
+<h2 id="padding">Tag::PADDING</h2>
 
-<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Version</strong>: 1, 2, 3</p>
 <p><strong>Repeatable</strong>? Yes</p>
 
 <p>Specifies the padding modes that may be used with the key. This tag is
@@ -566,6 +786,19 @@
 
 <p>Possible values are defined by the following enumeration:</p>
 
+<strong>Keymaster 3</strong>
+<pre class="devsite-click-to-copy">
+enum class PaddingMode : uint32_t {
+    NONE = 1,
+    RSA_OAEP = 2,
+    RSA_PSS = 3,
+    RSA_PKCS1_1_5_ENCRYPT = 4,
+    RSA_PKCS1_1_5_SIGN = 5,
+    PKCS7 = 64,
+};
+</pre>
+
+<strong>Keymaster 2 and earlier</strong>
 <pre class="devsite-click-to-copy">
 typedef enum {
     KM_PAD_NONE = 1,
@@ -577,37 +810,55 @@
 } keymaster_padding_t;
 </pre>
 
-<p><code>KM_PAD_RSA_OAEP</code> and <code>KM_PAD_RSA_PKCS1_1_5_ENCRYPT</code> are used
+<p><code>PaddingMode::RSA_OAEP</code> and
+<code>PaddingMode::RSA_PKCS1_1_5_ENCRYPT</code> are used
 only for RSA encryption/decryption keys and specify RSA PKCS#1v2 OAEP
-padding and RSA PKCS#1 v1.5 randomized padding, respectively. <code>KM_PAD_RSA_PSS</code> and
-<code>KM_PAD_RSA_PKCS1_1_5_SIGN</code> are used only for RSA signing/verification keys and
-specify RSA PKCS#1v2 PSS
-padding and RSA PKCS#1 v1.5 deterministic padding, respectively. Note also that
-the RSA PSS padding mode is incompatible with <a href="#digest">KM_DIGEST_NONE</a>.</p>
+padding and RSA PKCS#1 v1.5 randomized padding, respectively.
+<code>PaddingMode::RSA_PSS</code> and
+<code>PaddingMode::RSA_PKCS1_1_5_SIGN</code> are used only for RSA
+signing/verification keys and specify RSA PKCS#1v2 PSS
+padding and RSA PKCS#1 v1.5 deterministic padding, respectively.</p>
 
-<p><code>KM_PAD_NONE</code> may be used with either RSA or AES keys. For AES keys,
-if <code>KM_PAD_NONE</code> is used with block mode ECB or CBC and the data to be encrypted
-or decrypted
-is not a multiple of the AES block size in length, the call to finish fails
-with <code>KM_ERROR_INVALID_INPUT_LENGTH</code>.</p>
+<p class="note"><strong>Note</strong>: The RSA PSS padding mode is
+incompatible with <a href="#digest">Digest::NONE</a>.</p>
 
-<p><code>KM_PAD_PKCS7</code> may only be used with AES keys, and only with ECB and CBC modes.</p>
+<p><code>PaddingMode::NONE</code> may be used with either RSA or 
+AES keys. For AES keys, if <code>PaddingMode::NONE</code> is used
+with block mode ECB or CBC and the data to be encrypted or decrypted
+is not a multiple of the AES block size in length, the call to finish
+fails with <code>ErrorCode::INVALID_INPUT_LENGTH</code>.</p>
+
+<p><code>PaddingMode::PKCS7</code> may only be used with AES keys, and
+only with ECB and CBC modes.</p>
 
 <p>This tag is repeatable. A padding mode must be specified in the call to
 <a href="/security/keystore/implementer-ref#begin">begin</a>.
 If the specified mode is not authorized for the key, the operation fails
-with <code>KM_ERROR_INCOMPATIBLE_BLOCK_MODE</code>.</p>
+with <code>ErrorCode::INCOMPATIBLE_BLOCK_MODE</code>.</p>
 
 
-<h2 id="purpose">KM_TAG_PURPOSE</h2>
+<h2 id="purpose">Tag::PURPOSE</h2>
 
-<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Version</strong>: 1, 2, 3</p>
 <p><strong>Repeatable</strong>? Yes</p>
 
 <p>Specifies the set of purposes for which the key may be used.</p>
 
 <p>Possible values are defined by the following enumeration:</p>
 
+<strong>Keymaster 3</strong>
+<pre class="devsite-click-to-copy">
+enum class KeyPurpose : uint32_t {
+    ENCRYPT = 0,
+    DECRYPT = 1,
+    SIGN = 2,
+    VERIFY = 3,
+    DERIVE_KEY = 4,  // since 3.0
+    WRAP_KEY = 5,    // since 3.0
+};
+</pre>
+
+<strong>Keymaster 2 and earlier</strong>
 <pre class="devsite-click-to-copy">
 typedef enum {
     KM_PURPOSE_ENCRYPT = 0,
@@ -622,16 +873,28 @@
 <a href="/security/keystore/implementer-ref#begin">begin</a> function is called to
 start an operation, the purpose of the operation is
 specified. If the purpose specified to the operation is not authorized by the
-key, the operation fails with <code>KM_ERROR_INCOMPATIBLE_PURPOSE</code>.</p>
+key, the operation fails with <code>ErrorCode::INCOMPATIBLE_PURPOSE</code>.</p>
 
-<h2 id="rollback_resistant">KM_TAG_ROLLBACK_RESISTANT</h2>
 
-<p><strong>Version</strong>: 1, 2</p>
+<h2 id="reset_since_id_rotation">Tag::RESET_SINCE_ID_ROTATION</h2>
+
+<p><strong>Version</strong>: 3</p>
+<p><strong>Repeatable</strong>? No</p>
+<p>Specifies whether the device has beeen factory reset
+since the last unique ID rotation. Used for key attestation.</p>
+
+<p>This tag is boolean, so the possible values are true (if the tag is present)
+and false (if the tag is not present).</p>
+
+
+<h2 id="rollback_resistant">Tag::ROLLBACK_RESISTANT</h2>
+
+<p><strong>Version</strong>: 1, 2, 3</p>
 <p><strong>Repeatable</strong>? No</p>
 
 <p>Indicates that the key is rollback-resistant, meaning that when deleted
-by <a href="/security/keystore/implementer-ref#delete_key">delete_key</a> or
-<a href="/security/keystore/implementer-ref#delete_all_keys">delete_all_keys</a>,
+by <a href="/security/keystore/implementer-ref#delete_key">deleteKey</a> or
+<a href="/security/keystore/implementer-ref#delete_all_keys">deleteAllKeys</a>,
 the key is guaranteed to be permanently deleted and unusable. It's possible
 that keys without this tag could be deleted and then restored from backup.</p>
 
@@ -639,9 +902,9 @@
 and false (if the tag is not present).</p>
 
 
-<h2 id="root_of_trust">KM_TAG_ROOT_OF_TRUST</h2>
+<h2 id="root_of_trust">Tag::ROOT_OF_TRUST</h2>
 
-<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Version</strong>: 1, 2, 3</p>
 <p><strong>Repeatable</strong>? No</p>
 
 
@@ -649,39 +912,47 @@
 validate the operating system booted (if any). This tag is never provided
 to or returned from Keymaster in the key characteristics.</p>
 
-<h2 id="rsa_public_exponent">KM_TAG_RSA_PUBLIC_EXPONENT</h2>
+<h2 id="rsa_public_exponent">Tag::RSA_PUBLIC_EXPONENT</h2>
 
-<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Version</strong>: 1, 2, 3</p>
 <p><strong>Repeatable</strong>? No</p>
 
 <p>Specifies the value of the public exponent for an RSA key pair. This tag is
 relevant only to RSA keys, and necessary for all RSA keys.</p>
 
 <p>The value is a 64-bit unsigned integer that satisfies the requirements of an
-RSA public exponent. Because it is specified by the caller and therefore cannot
-be chosen by the implementation, it is a prime number. Trustlets support the
+RSA public exponent. This value has to be a prime number. Trustlets support the
 value 2^16+1 and may support other reasonable values, in particular the value 3.
 If no exponent is specified or if the specified exponent is not supported,
-key generation fails with <code>KM_ERROR_INVALID_ARGUMENT</code>.</p>
+key generation fails with <code>ErrorCode::INVALID_ARGUMENT</code>.</p>
 
 
-<h2 id="usage_expire_datetime">KM_TAG_USAGE_EXPIRE_DATETIME</h2>
+<h2 id="unique_id">Tag::UNIQUE_ID</h2>
 
-<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Version</strong>: 3</p>
+<p><strong>Repeatable</strong>? No</p>
+
+<p>Used to provide unique ID in attestation.</p>
+<p>The value is a blob, an arbitrary-length array of bytes.</p>
+
+
+<h2 id="usage_expire_datetime">Tag::USAGE_EXPIRE_DATETIME</h2>
+
+<p><strong>Version</strong>: 1, 2, 3</p>
 <p><strong>Repeatable</strong>? No</p>
 
 <p>Specifies the date and time at which the key expires for verification and
 decryption purposes. After this time, any attempt to use a key with
-<a href="#purpose">KM_PURPOSE_VERIFY</a> or <a href="#purpose">KM_PURPOSE DECRYPT</a>
+<a href="#purpose">KeyPurpose::VERIFY</a> or <a href="#purpose">KeyPurpose::DECRYPT</a>
 provided to <a href="/security/keystore/implementer-ref#begin">begin</a> fails
-with <code>KM_ERROR_KEY_EXPIRED</code>.</p>
+with <code>ErrorCode::KEY_EXPIRED</code>.</p>
 
 <p>The value is a 64-bit integer representing milliseconds since January 1, 1970.</p>
 
 
-<h2 id="user_auth_type">KM_TAG_USER_AUTH_TYPE</h2>
+<h2 id="user_auth_type">Tag::USER_AUTH_TYPE</h2>
 
-<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Version</strong>: 1, 2, 3</p>
 <p><strong>Repeatable</strong>? No</p>
 
 <p>Specifies the types of user authenticators that may be used to authorize this
@@ -695,6 +966,17 @@
 
 <p>The value is a 32-bit integer bitmask of values from the enumeration:</p>
 
+<strong>Keymaster 3</strong>
+<pre class="devsite-click-to-copy">
+enum class HardwareAuthenticatorType : uint32_t {
+    NONE = 0u, // 0
+    PASSWORD = 1 &lt;&lt; 0,
+    FINGERPRINT = 1 &lt;&lt; 1,
+    ANY = UINT32_MAX,
+};
+</pre>
+
+<strong>Keymaster 2 and earlier</strong>
 <pre class="devsite-click-to-copy">
 typedef enum {
     HW_AUTH_NONE = 0,
@@ -706,19 +988,19 @@
 </pre>
 
 
-<h2 id="user_secure_id">KM_TAG_USER_SECURE_ID</h2>
+<h2 id="user_secure_id">Tag::USER_SECURE_ID</h2>
 
-<p><strong>Version</strong>: 1, 2</p>
+<p><strong>Version</strong>: 1, 2, 3</p>
 <p><strong>Repeatable</strong>? No</p>
 
 <p>Specifies that a key may only be used under a particular secure user
 authentication state. This tag is mutually exclusive
-with <a href="#no_auth_required">KM_TAG_NO_AUTH_REQUIRED</a>.</p>
+with <a href="#no_auth_required">Tag::NO_AUTH_REQUIRED</a>.</p>
 
 <p>The value is a 64-bit integer specifying the authentication policy state value
 which needs to be present in an authentication token (provided to
 <a href="/security/keystore/implementer-ref#begin">begin</a> with
-the <a href="#auth_token">KM_TAG_AUTH_TOKEN</a>) to authorize use of the key. Any
+the <a href="#auth_token">Tag::AUTH_TOKEN</a>) to authorize use of the key. Any
 call to <a href="/security/keystore/implementer-ref#begin">begin</a>
 with a key with this tag that does not provide an
 authentication token, or provides an
@@ -726,7 +1008,7 @@
 
 <p>This tag is repeatable. If any of the provided values matches any policy state
 value in the authentication token, the key is authorized for use. Otherwise the operation
-fails with <code>KM_ERROR_KEY_USER_NOT_AUTHENTICATED</code>.</p>
+fails with <code>ErrorCode::KEY_USER_NOT_AUTHENTICATED</code>.</p>
 
 </body>
 </html>
diff --git a/en/security/keystore/version-binding.html b/en/security/keystore/version-binding.html
index 930e648..17059d5 100644
--- a/en/security/keystore/version-binding.html
+++ b/en/security/keystore/version-binding.html
@@ -20,12 +20,11 @@
       See the License for the specific language governing permissions and
       limitations under the License.
   -->
-
+ 
 <p>
-In Keymaster1, all keymaster keys were cryptographically bound to the device
-<em>Root of Trust</em>, the <a href="/security/verifiedboot/">verified boot
-key</a>. In Keymaster2, all keys are
-also bound to the operating system and patch level of the system image.
+In Keymaster 1, all keymaster keys were cryptographically bound to the device
+<em>Root of Trust</em>, or the verified boot key. In Keymaster 2 and above, all
+keys are also bound to the operating system and patch level of the system image.
 This ensures that an attacker who discovers a weakness in an old
 version of system or TEE software cannot roll a device back to the vulnerable
 version and use keys created with the newer version. In addition, when a key
@@ -37,37 +36,42 @@
 unusable.
 </p>
 
-<h2 id="hal-changes">HAL changes</h2>
+<h2 id="hal-changes">HAL Changes</h2>
 <p>
 To support version binding and version attestation, Android 7.1 added the tags
-<code>KM_TAG_OS_VERSION</code> and <code>KM_TAG_OS_PATCHLEVEL</code> and the
-methods <code>configure</code> and <code>upgrade_key</code>. The version tags
-are automatically added by keymaster2 implementations to all newly-generated (or
+<code>Tag::OS_VERSION</code> and <code>Tag::OS_PATCHLEVEL</code> and the
+methods <code>configure</code> and <code>upgradeKey</code>. The version tags
+are automatically added by Keymaster 2+ implementations to all newly-generated (or
 updated) keys. Further, any attempt to use a key that does not have an OS
 version or patch level matching the current system OS version or patch level,
-respectively, is rejected with <code>KM_ERROR_KEY_REQUIRES_UPGRADE</code>.
+respectively, is rejected with <code>ErrorCode::KEY_REQUIRES_UPGRADE</code>.
 </p>
 <p>
-<code>KM_TAG_OS_VERSION</code> is a <code>KM_UINT</code> that represents the
+<code>Tag::OS_VERSION</code> is a <code>UINT</code> that represents the
 major, minor, and sub-minor portions of an Android system version as MMmmss,
 where MM is the major version, mm is the minor version and ss is the sub-minor
 version. For example 6.1.2 would be represented as 060102.
 </p>
 <p>
-<code>KM_TAG_OS_PATCHLEVEL</code> is a <code>KM_UINT</code> that represents the
+<code>Tag::OS_PATCHLEVEL</code> is a <code>UINT</code> that represents the
 year and month of the last update to the system as YYYYMM, where YYYY is the
 four-digit year and MM is the two-digit month. For example, March 2016 would be
 represented as 201603.
 </p>
 
-<h3 id="upgrade_key">Upgrade_key</h3>
+<h3 id="upgrade_key">UpgradeKey</h3>
 <p>
 To allow keys to be upgraded to the new OS version and patch level of the system
-image, Android 7.1 added the <code>upgrade_key</code> method to the HAL:
+image, Android 7.1 added the <code>upgradeKey</code> method to the HAL:
 </p>
 
-<pre
-class="prettyprint">keymaster_error_t (*upgrade_key)(const struct keymaster2_device* dev,
+<p><strong>Keymaster 3</strong></p>
+<pre class="devsite-click-to-copy">
+    upgradeKey(vec<uint8_t> keyBlobToUpgrade, vec<KeyParameter> upgradeParams)
+        generates(ErrorCode error, vec<uint8_t> upgradedKeyBlob);</pre>
+<p><strong>Keymaster 2</strong></p>
+<pre class="devsite-click-to-copy">
+keymaster_error_t (*upgrade_key)(const struct keymaster2_device* dev,
     const keymaster_key_blob_t* key_to_upgrade,
     const keymaster_key_param_set_t* upgrade_params,
     keymaster_key_blob_t* upgraded_key);
@@ -75,39 +79,47 @@
 
 <ul>
   <li><code>dev</code> is the device structure</li>
-  <li><code>key_to_upgrade</code> is the key which needs to be upgraded</li>
-  <li><code>upgrade_params</code> are parameters needed to upgrade the key. These
-  will include <code>KM_TAG_APPLICATION_ID</code> and
-  <code>KM_TAG_APPLICATION_DATA</code>, which are necessary to decrypt the key
+  <li><code>keyBlobToUpgrade</code> is the key which needs to be upgraded</li>
+  <li><code>upgradeParams</code> are parameters needed to upgrade the key. These
+  will include <code>Tag::APPLICATION_ID</code> and
+  <code>Tag::APPLICATION_DATA</code>, which are necessary to decrypt the key
   blob, if they were provided during generation.</li>
-  <li><code>upgraded_key</code> is the output parameter, used to return the new
+  <li><code>upgradedKeyBlob</code> is the output parameter, used to return the new
   key blob.</li>
 </ul>
 
+
 <p>
-If <code>upgrade_key</code> is called with a key blob that cannot be parsed or
-is otherwise invalid, it returns <code>KM_ERROR_INVALID_KEY_BLOB</code>. If it
+If <code>upgradeKey</code> is called with a key blob that cannot be parsed or
+is otherwise invalid, it returns <code>ErrorCode::INVALID_KEY_BLOB</code>. If it
 is called with a key whose patch level is greater than the current system value,
-it returns <code>KM_ERROR_INVALID_ARGUMENT</code>. If it is called with a key
+it returns <code>ErrorCode::INVALID_ARGUMENT</code>. If it is called with a key
 whose OS version is greater than the current system value, and the system value
-is non-zero, it returns KM_ERROR_INVALID_ARGUMENT. OS version upgrades from
-non-zero to zero are allowed. In the event of errors communicating with the
-secure world, it returns an appropriate error value (e.g.
-<code>KM_SECURE_HW_ACCESS_DENIED</code>, <code>KM_SECURE_HW_BUSY</code>, etc.)
-Otherwise, it returns <code>KM_ERROR_OK</code> and returns a new key blob in
-<code>upgraded_key</code>.
+is non-zero, it returns <code>ErrorCode::INVALID_ARGUMENT</code>. OS version
+upgrades from non-zero to zero are allowed. In the event of errors
+communicating with the secure world, it returns an appropriate error value (e.g.
+<code>ErrorCode::SECURE_HW_ACCESS_DENIED</code>, <code>ErrorCode::SECURE_HW_BUSY</code>, etc.)
+Otherwise, it returns <code>ErrorCode::OK</code> and returns a new key blob in
+<code>upgradedKeyBlob</code>.
 </p>
 <p>
-<code>key_to_upgrade</code> remains valid after the <code>upgrade_key</code>
+<code>keyBlobToUpgrade</code> remains valid after the <code>upgradeKey</code>
 call, and could theoretically be used again if the device were downgraded. In
-practice, keystore generally calls <code>delete_key</code> on the
-<code>key_to_upgrade</code> blob shortly after the call to upgrade_key. If
-<code>key_to_upgrade</code> had tag <code>KM_TAG_ROLLBACK_RESISTANT</code>, then
-<code>upgraded_key</code> should have it as well (and should be rollback
+practice, keystore generally calls <code>deleteKey</code> on the
+<code>keyBlobToUpgrade</code> blob shortly after the call to <code>upgradeKey</code>. If
+<code>keyBlobToUpgrade</code> had tag <code>Tag::ROLLBACK_RESISTANT</code>, then
+<code>upgradedKeyBlob</code> should have it as well (and should be rollback
 resistant).
 </p>
 
 <h2 id="secure-configuration">Secure configuration</h2>
+
+<p class="note">
+<strong>Note</strong>: Keymaster 3 removed the Keymaster 2 method
+<code>configure</code>. The information previously provided to Keymaster HALs
+through <code>configure</code> is available in system properties files, and
+manufacturer implementations read those files during startup.
+</p>
 <p>
 To implement version binding, the keymaster TA needs a way to securely receive
 the current OS version and patch level (version information), and to ensure that
@@ -133,26 +145,26 @@
 
 
 <pre
-class="prettyprint">keymaster_error_t (*configure)(const struct keymaster2_device* dev,
+class="devsite-click-to-copy">keymaster_error_t (*configure)(const struct keymaster2_device* dev,
 	const keymaster_key_param_set_t* params);
 </pre>
 
 <p>
-The <code>params</code> argument contains <code>KM_TAG_OS_VERSION</code> and
-<code>KM_TAG_OS_PATCHLEVEL</code>. This method is called by keymaster2 clients
+The <code>params</code> argument contains <code>Tag::OS_VERSION</code> and
+<code>Tag::OS_PATCHLEVEL</code>. This method is called by keymaster2 clients
 after opening the HAL, but before calling any other methods. If any other method
 is called before configure, the TA returns
-<code>KM_ERROR_KEYMASTER_NOT_CONFIGURED</code>.
+<code>ErrorCode::KEYMASTER_NOT_CONFIGURED</code>.
 </p>
 
 <p>
 The first time <code>configure</code> is called after the device boots, it
 should verify that the version information provided matches what was provided by
 the bootloader. If the version information does not match,
-<code>configure</code> returns <code>KM_ERROR_INVALID_ARGUMENT</code>, and all
+<code>configure</code> returns <code>ErrorCode::INVALID_ARGUMENT</code>, and all
 other keymaster methods continue returning
-<code>KM_ERROR_KEYMASTER_NOT_CONFIGURED</code>. If the information matches,
-<code>configure</code> returns <code>KM_ERROR_OK</code>, and other keymaster
+<code>ErrorCode::KEYMASTER_NOT_CONFIGURED</code>. If the information matches,
+<code>configure</code> returns <code>ErrorCode::OK</code>, and other keymaster
 methods begin functioning normally.
 </p>
 
diff --git a/en/security/overview/acknowledgements.html b/en/security/overview/acknowledgements.html
index 53994b0..f287c44 100644
--- a/en/security/overview/acknowledgements.html
+++ b/en/security/overview/acknowledgements.html
@@ -27,7 +27,7 @@
 parties for helping to improve Android security. They have done this either by
 finding and responsibly reporting security vulnerabilities through the AOSP bug
 tracker <a
-href="https://code.google.com/p/android/issues/entry?template=Security%20bug%20report">Security
+href="https://www.google.com/appserve/security-bugs/m2/new">Security
 bug report</a> template or by committing code that has a positive
 impact on Android security, including code that qualifies
 for the <a href="https://www.google.com/about/appsecurity/patch-rewards/">Patch
@@ -55,6 +55,8 @@
 
 <p>Ben Actis (<a href="https://twitter.com/ben_ra">@Ben_RA</a>)</p>
 
+<p>Ben Seri of <a href="https://armis.com">Armis, Inc.</a></p>
+
 <p>Billy Lau of Android Security</p>
 
 <p>Bo Liu of <a href="http://www.ms509.com">MS509Team</a></p>
@@ -69,6 +71,12 @@
 <p>Chiachih Wu (<a href="https://twitter.com/chiachih_wu">@chiachih_wu</a>)
 of <a href="http://c0reteam.org">C0RE Team</a></p>
 
+<p><a href="http://weibo.com/csddl">Chong Wang</a> of
+Chengdu Security Response Center, Qihoo 360 Technology Co. Ltd.</p>
+
+<p>Cong Zheng (<a href="https://twitter.com/shellcong">@shellcong</a>)
+of Palo Alto Networks</p>
+
 <p><a href="mailto:shaodacheng2016@gmail.com">Dacheng Shao</a>
 of <a href="http://c0reteam.org">C0RE Team</a></p>
 
@@ -110,6 +118,8 @@
 
 <p>Google WebM Team</p>
 
+<p>Gregory Vishnepolsky of <a href="https://armis.com">Armis, Inc.</a></p>
+
 <p>Guang Gong (龚广) (<a href="http://twitter.com/oldfresher">@oldfresher</a>) of
   Alpha Team, <a href="http://www.360.com">Qihoo 360 Technology Co. Ltd.</a></p>
 
@@ -130,12 +140,16 @@
 <p><a href="mailto:hlhan@bupt.edu.cn">Hongli Han</a> of
    <a href="http://c0reteam.org">C0RE Team</a></p>
 
+<p>hujianfei of Qihoo360 Qex Team</p>
+
 <p>Ian Foster (<a href="https://twitter.com/lanrat">@lanrat</a>)</p>
 
 <p>Jack Tang of Trend Micro Inc.</p>
 
 <p>Jake Corina of Shellphish Grill Team</p>
 
+<p>Jason Gu of Trend Micro</p>
+
 <p>Jeff Sharkey of Google</p>
 
 <p>Jeff Trim</p>
@@ -265,6 +279,8 @@
 <p>Weichao Sun (<a href="https://twitter.com/sunblate">@sunblate</a>) of
   Alibaba Inc.</p>
 
+<p>Wenjun Hu of Palo Alto Networks</p>
+
 <p><a href="mailto:vancouverdou@gmail.com">Wenke Dou</a> of
    <a href="http://c0reteam.org">C0RE Team</a></p>
 
@@ -275,6 +291,8 @@
 (<a href="http://www.weibo.com/wishlinux">吴潍浠</a> 此彼) of Ant-financial Light-Year
   Security Lab</p>
 
+<p>Xiao Zhang of Palo Alto Networks</p>
+
 <p><a href="mailto:wisedd@gmail.com">Xiaodong Wang</a>
 of <a href="http://c0reteam.org">C0RE Team</a></p>
 
@@ -291,6 +309,9 @@
 
 <p>Yang Cheng of Xiaomi Inc.</p>
 
+<p><a href="mailto:huahuaisadog@gmail.com">Yang Dai</a> of Vulpecker Team, Qihoo
+360 Technology Co. Ltd</p>
+
 <p>Yang Song of Alibaba Mobile Security Group</p>
 
 <p>Yangkang (<a href="https://twitter.com/dnpushme">@dnpushme</a>) of Qex Team, Qihoo 360</p>
@@ -308,11 +329,14 @@
 
 <p>Dr. Yossi Oren of Ben Gurion University Cyber Lab</p>
 
-<p>Yu Pan of Vulpecker Team, Qihoo 360 Technology Co. Ltd</p>
+<p><a href="http://weibo.com/panyu6325">Yu Pan</a> of Vulpecker Team, Qihoo 360 Technology Co. Ltd</p>
 
 <p><a href="mailto:computernik@gmail.com">Yuan-Tsung Lo</a> of
    <a href="http://c0reteam.org">C0RE Team</a></p>
 
+<p>Yuebin Sun of <a href="http://xlab.tencent.com">Tencent's
+Xuanwu Lab</a></p>
+
 <p>Yuqi Lu (<a href="https://twitter.com/nikos233__">@nikos233</a>)
 of <a href="http://c0reteam.org">C0RE Team</a></p>
 
@@ -322,10 +346,15 @@
 <p>Zhanpeng Zhao (行之) (<a href="https://twitter.com/0xr0ot">@0xr0ot</a>) of
   Security Research Lab, <a href="http://www.cmcm.com/">Cheetah Mobile</a></p>
 
+<p>Zhe Jin (金哲) of
+Chengdu Security Response Center, Qihoo 360 Technology Co. Ltd.</p>
+
 <p><a href="mailto:zhouzhenster@gmail.com">Zhen Zhou</a> (
  <a href="https://twitter.com/henices">@henices</a>) of 
  <a href="http://www.nsfocus.com">NSFocus</a></p>
 
+<p>Zhi Xu of Palo Alto Networks</p>
+
  <p><a href="mailto:sundaywind2004@gmail.com">Zhixin Li</a> of 
  <a href="http://www.nsfocus.com">NSFocus</a></p>
 
diff --git a/en/source/build-numbers.html b/en/source/build-numbers.html
index 84de44f..e50741a 100644
--- a/en/source/build-numbers.html
+++ b/en/source/build-numbers.html
@@ -208,6 +208,30 @@
   </thead>
   <tbody>
     <tr>
+      <td>OPR6.170623.017</td>
+      <td>android-8.0.0_r11</td>
+      <td>Oreo</td>
+      <td>Nexus 6P</td>
+    </tr>
+    <tr>
+      <td>OPR4.170623.006</td>
+      <td>android-8.0.0_r10</td>
+      <td>Oreo</td>
+      <td>Nexus 5X</td>
+    </tr>
+    <tr>
+      <td>OPR3.170623.007</td>
+      <td>android-8.0.0_r9</td>
+      <td>Oreo</td>
+      <td>Pixel XL, Pixel</td>
+    </tr>
+    <tr>
+      <td>OPR1.170623.026</td>
+      <td>android-8.0.0_r7</td>
+      <td>Oreo</td>
+      <td>Pixel XL, Pixel, Pixel C</td>
+    </tr>
+    <tr>
       <td>OPR6.170623.013</td>
       <td>android-8.0.0_r4</td>
       <td>Oreo</td>
@@ -395,6 +419,24 @@
       <td>Pixel C</td>
     </tr>
     <tr>
+      <td>N9F27L</td>
+      <td>android-7.1.1_r53</td>
+      <td>Nougat</td>
+      <td>Nexus 9</td>
+    </tr>
+    <tr>
+      <td>NGI55D</td>
+      <td>android-7.1.1_r52</td>
+      <td>Nougat</td>
+      <td>Nexus 6</td>
+    </tr>
+    <tr>
+      <td>N4F27O</td>
+      <td>android-7.1.1_r51</td>
+      <td>Nougat</td>
+      <td>Nexus 9 (volantisg)</td>
+    </tr>
+    <tr>
       <td>N8I11B</td>
       <td>android-7.1.1_r50</td>
       <td>Nougat</td>
diff --git a/en/source/devices.html b/en/source/devices.html
index 27b2401..b3e7b51 100644
--- a/en/source/devices.html
+++ b/en/source/devices.html
@@ -140,8 +140,13 @@
   </li>
   <li>Update the kernel in the boot image.
     <ul>
-      <li>Copy hi3660-hikey960.dtb (<code>arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dtb</code>) to the hikey-kernel directory as file hi3660-hikey960.dtb.</li>
-      <li>Copy the Image file <code>(arch/arm64/boot/Image.gz</code>) to the hikey-kernel directory as file Image.gz-hikey960.</li>
+      <li>Copy <code>hi3660-hikey960.dtb</code>
+        (<code>arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dtb</code>) to the
+        <code>hikey-kernel</code> directory as file:
+      <code>hi3660-hikey960.dtb-4.9</code></li>
+      <li>Copy the Image file <code>(arch/arm64/boot/Image.gz</code>) to the
+        <code>hikey-kernel</code> directory as file:
+        <code>Image.gz-hikey960-4.9</code></li>
     </ul>
   <li>Make the boot image:
 <pre class="devsite-terminal devsite-click-to-copy">
@@ -326,7 +331,7 @@
 <code class="devsite-terminal">. ./build/envsetup.sh</code>
 <code class="devsite-terminal">lunch hikey-userdebug</code>
 <code class="devsite-terminal">. device/google/contexthub/firmware/toolchain-setup.sh</code>
-<code class="devsite-terminal">command make -C device/google/contexthub/firmware/variant/neonkey</code>
+<code class="devsite-terminal">make -C device/google/contexthub/firmware/variant/neonkey</code>
 <code class="devsite-terminal">adb push device/google/contexthub/firmware/out/nanohub/neonkey/full.bin /data/local/tmp</code>
 </pre>
 </li>
diff --git a/en/source/images/jack_jill.png b/en/source/images/jack_jill.png
new file mode 100644
index 0000000..445edf4
--- /dev/null
+++ b/en/source/images/jack_jill.png
Binary files differ
diff --git a/en/source/images/jack_library.png b/en/source/images/jack_library.png
new file mode 100644
index 0000000..bf0361b
--- /dev/null
+++ b/en/source/images/jack_library.png
Binary files differ
diff --git a/en/source/images/jack_overview.png b/en/source/images/jack_overview.png
new file mode 100644
index 0000000..a315fc2
--- /dev/null
+++ b/en/source/images/jack_overview.png
Binary files differ
diff --git a/en/source/images/jack_predex.png b/en/source/images/jack_predex.png
new file mode 100644
index 0000000..2563814
--- /dev/null
+++ b/en/source/images/jack_predex.png
Binary files differ
diff --git a/en/source/jack.html b/en/source/jack.html
index b7f3f5a..558eef7 100644
--- a/en/source/jack.html
+++ b/en/source/jack.html
@@ -21,184 +21,195 @@
       limitations under the License.
   -->
 
+<aside class="warning"><strong>Warning:</strong> As of this
+<a href="https://android-developers.googleblog.com/2017/03/future-of-java-8-language-feature.html" class="external">March
+14, 2017 announcement</a>, the Jack toolchain is deprecated. While you may
+continue to use Jack, we strongly encourage using the latest
+<a href="https://developer.android.com/studio/preview/index.html" class="external">preview
+version of Android Studio</a> instead, which provides improved support for
+<a href="https://developer.android.com/studio/preview/features/java8-support.html" class="external">Java
+8 language features</a> built into the default toolchain.</aside>
 
+<p>Jack is an Android toolchain that compiles Java source into Android dex
+bytecode. It replaces the previous Android toolchain that consisted of multiple
+tools such as javac, ProGuard, jarjar, and dx. As Jack is the default Android
+build toolchain for Android 6.x, you don’t have to do anything differently to
+use Jack&mdash;just use your standard makefile commands to compile the tree or
+your project.</p>
 
-<h2 id=the_jack_toolchain>The Jack toolchain</h2>
-
-<p class="warning">
-  <b>The Jack toolchain is deprecated</b>, as per
-  <a href="https://android-developers.googleblog.com/2017/03/future-of-java-8-language-feature.html">
-  this announcement</a>. You may continue to use it or try the latest
-  <a href="https://developer.android.com/studio/preview/index.html">preview version of
-  Android Studio</a>, which provides improved support for <a href="https://developer.android.com/studio/preview/features/java8-support.html">
-  Java 8 language features built into the default toolchain</a>.
-</p>
-
-<p>Jack is an Android toolchain that compiles Java
-source into Android dex bytecode.  It replaces the previous Android toolchain,
-which consists of multiple tools, such as javac, ProGuard, jarjar, and dx.</p>
-
+<h2 class="overview">About Jack</h2>
 <p>The Jack toolchain provides the following advantages:</p>
 
-<ul>
-  <li> <strong>Completely open source</strong><br>
-Available in AOSP; users are welcome to contribute.
-  <li> <strong>Speeds compilation time</strong><br>
+<img src="./images/jack_overview.png" alt="Jack overview"/>
+<figcaption><strong>Figure 1.</strong> Jack overview.</figcaption>
 
-Jack has specific supports to reduce compilation time: pre-dexing, incremental
-compilation and a Jack compilation server.
-  <li> <strong>Handles shrinking, obfuscation, repackaging and multidex</strong><br>
-Using a separate package such as ProGuard is no longer necessary.
+<ul>
+<li><strong>Completely open source</strong>. Jack is available in AOSP and users
+are welcome to contribute.</li>
+<li><strong>Speeds compilation time</strong>. Jack has specific support for
+reducing compilation time using pre-dexing, incremental compilation, and a Jack
+compilation server.</li>
+<li><strong>Handles shrinking, obfuscation, repackaging, and multidex</strong>.
+Using a separate package (such as ProGuard) is no longer necessary.</li>
 </ul>
 
-<p class="note">Note that beginning in Android 7.0 (N), Jack supports code coverage with JaCoCo.
-See <a href="https://android.googlesource.com/platform/prebuilts/sdk/+/master/tools/README-jack-code-coverage.md">
-Code Coverage with JaCoCo</a> and <a href="https://developer.android.com/preview/j8-jack.html">
-Java 8 Language Features</a> for details.</p>
+<p>As of Android 7.0, Jack supports code coverage with JaCoCo. For details,
+refer to
+<a href="https://android.googlesource.com/platform/prebuilts/sdk/+/master/tools/README-jack-code-coverage.md" class="external">Code
+Coverage with JaCoCo</a> and
+<a href="https://developer.android.com/preview/j8-jack.html" class="external">Java
+8 Language Features</a>.</p>
 
-<img src="/images/jack-overview.png" height="75%" width="75%" alt="Jack overview" />
-<p class="img-caption"><strong>Figure 1. </strong>Jack overview</p>
+<h3 id=jack_library>Jack library format</h3>
 
-
-<h2 id=the_jack_library_format>The .jack library format</h2>
-
-<p>Jack has its own .jack file format, which contains the pre-compiled dex code
+<p>Jack has its own .jack file format that contains the pre-compiled dex code
 for the library, allowing for faster compilation (pre-dex).</p>
 
-<img src="/images/jack-library-file.png" height="75%" width="75%" alt="Jack library file contents" />
-<p class="img-caption"><strong>Figure 2. </strong>Jack library file contents</p>
+<img src="./images/jack_library.png" alt="Jack library file contents"/>
+<figcaption><strong>Figure 2.</strong> Jack library file contents.</figcaption>
 
-<h2 id=jill>Jill</h2>
+<h3 id=jill>Jill</h3>
 
 <p>The Jill tool translates the existing .jar libraries into the new library
 format, as shown below.</p>
 
-<img src="/images/jill.png" alt="Importing existing .jar libraries using Jill" />
-<p class="img-caption"><strong>Figure 3. </strong>Workflow to import an existing .jar library</p>
+<img src="./images/jack_jill.png" alt="Importing .jar libraries with Jill"/>
+<figcaption><strong>Figure 3.</strong> Workflow to import an existing .jar
+library.</figcaption>
 
-<h2 id=using_jack_in_your_android_build>Using Jack in your Android build</h2>
+<h2 id=using_jack>Jack compilation server</h2>
 
-<div class="note">For instructions on using Jack in Android 7.0 (N) and later, see the <a
-href="https://android.googlesource.com/platform/prebuilts/sdk/+/master/tools/README-jack-server.md">Jack
-server documentation</a>. For Android 6.0 (M), use the instructions in this section.</div>
-
-<p>You don’t have to do anything differently to use Jack — just use your
-standard makefile commands to compile the tree or your project.  Jack is the
-default Android build toolchain for M.</p>
+<aside class="note"><strong>Note:</strong> The following instructions apply only
+to using Jack in Android 6.x; for instructions on using Jack in Android 7.x and
+higher, refer to
+<a href="https://android.googlesource.com/platform/prebuilts/sdk/+/master/tools/README-jack-server.md" class="external">Jack
+server documentation</a>.</aside>
 
 <p>The first time Jack is used, it launches a local Jack compilation server on
-your computer:</p>
+your computer. This server:</p>
 
 <ul>
-  <li> This server brings an intrinsic speedup, because it avoids launching a new host
-JRE JVM, loading Jack code, initializing Jack and warming up the JIT at each
+<li>Brings an intrinsic speedup because it avoids launching a new host JRE JVM,
+loading Jack code, initializing Jack, and warming up the JIT at each
 compilation. It also provides very good compilation times during small
-compilations (e.g. in incremental mode).
-  <li> The server is also a short-term solution to control the number of parallel Jack
-compilations, and so to avoid overloading your computer (memory or disk issue),
-because it limits the number of parallel compilations.
+compilations (e.g. in incremental mode).</li>
+<li>Is a short-term solution to control the number of parallel Jack
+compilations. It avoids overloading your computer (memory or disk issue) because
+it limits the number of parallel compilations.</li>
 </ul>
 
 <p>The Jack server shuts itself down after an idle time without any compilation.
-It uses two TCP ports on the localhost interface, and so is not available
-externally. All these parameters (number of parallel compilations, timeout,
-ports number, etc) can be modified by editing the<code> $HOME/.jack</code> file.</p>
+It uses two TCP ports on the localhost interface and is not available
+externally. All parameters (number of parallel compilations, timeout, ports
+number, etc.) can be modified by editing the <code>$HOME/.jack</code> file.</p>
 
-<h3 id=$home_jack_file>$HOME/.jack file</h3>
+<h3 id=home_jack_file>$HOME/.jack file</h3>
 
-<p>The <code>$HOME/.jack</code> file contains settings for Jack server variables, in a full bash syntax. </p>
-
-<p>Here are the available settings, with their definitions and default values:</p>
+<p>The <code>$HOME/.jack</code> file contains the following settings for Jack
+server variables in a full bash syntax:</p>
 
 <ul>
-  <li> <strong><code>SERVER=true</strong> </code>Enable the server feature of Jack.
-  <li> <strong><code>SERVER_PORT_SERVICE=8072</code>
-</strong>Set the TCP port number of the server for compilation purposes.
-  <li> <strong><code>SERVER_PORT_ADMIN=8073</code></strong>
-Set the TCP port number of the server for admin purposes.
-  <li> <strong><code>SERVER_COUNT=1</code></strong>
-Unused at present.
-  <li> <strong><code>SERVER_NB_COMPILE=4</code></strong>
-Maximum number of parallel compilations allowed.
-  <li> <strong><code>SERVER_TIMEOUT=60</code></strong>
-Number of idle seconds the server has to wait without any compilation before
-shutting itself down.
-  <li> <strong><code>SERVER_LOG=${SERVER_LOG:=$SERVER_DIR/jack-$SERVER_PORT_SERVICE.log}</code></strong>
-File where server logs are written. By default, this variable can be
-overloaded by an environment variable.
-  <li> <strong><code>JACK_VM_COMMAND=${JACK_VM_COMMAND:=java}</code></strong>
-The default command used to launch a JVM on the host. By default, this
-variable can be overloaded by environment variable.
+<li><code>SERVER=true</code>. Enable the server feature of Jack.</li>
+<li><code>SERVER_PORT_SERVICE=8072</code>. Set the TCP port number of the server
+for compilation purposes.</li>
+<li><code>SERVER_PORT_ADMIN=8073</code>. Set the TCP port number of the server
+for admin purposes.</li>
+<li><code>SERVER_COUNT=1</code>. Unused.
+<li><code>SERVER_NB_COMPILE=4</code>. Set the maximum number of allowed parallel
+compilations.</li>
+<li><code>SERVER_TIMEOUT=60</code>. Set the number of idle seconds the server
+must wait without any compilation before shutting itself down.</li>
+<li><code>SERVER_LOG=${SERVER_LOG:=$SERVER_DIR/jack-$SERVER_PORT_SERVICE.log}</code>.
+Set the file where server logs are written. By default, this variable can be
+overloaded by an environment variable.</li>
+<li><code>JACK_VM_COMMAND=${JACK_VM_COMMAND:=java}</code>. Set the default
+command used to launch a JVM on the host. By default, this variable can be
+overloaded by environment variable.</li>
 </ul>
 
-<h3 id=jack_troubleshooting>Jack troubleshooting</h3>
+<h3 id=jack_troubleshooting>Troubleshooting Jack compilations</h3>
 
-<p><strong>If your computer becomes unresponsive during compilation or if you experience
-Jack compilations failing on “Out of memory error”</strong></p>
-
-<p>You can improve the situation by reducing the number of Jack simultaneous
-compilations by editing your<code> $HOME/.jack</code> and changing<code> SERVER_NB_COMPILE</code> to a lower value.</p>
-
-<p><strong>If your compilations are failing on “Cannot launch background server”</strong></p>
-
-<p>The most likely cause is TCP ports are already used on your computer. Try to
-change it by editing your <code>$HOME/.jack </code>(<code>SERVER_PORT_SERVICE</code> and <code>SERVER_PORT_ADMIN</code> variables).</p>
-
-<p>If it doesn’t solve the problem, please report and attach your compilation log
-and the Jack server log (see ‘Finding the Jack log’ below to know where to find
-the server log file). To unblock the situation, disable jack compilation server
-by editing your <code>$HOME/.jack</code> and changing <code>SERVER</code> to false. Unfortunately this will significantly slow down your compilation and
-may force you to launch <code>make -j</code> with load control (option "<code>-l</code>" of <code>make</code>). </p>
-
-<p><strong>If your compilation gets stuck without any progress</strong></p>
-
-<p>Please report this and give us the following  additional information (where
-possible):</p>
-
-<ul>
-  <li> The command line at which you are stuck.
-  <li> The output of this command line.
-  <li> The result of executing <code>jack-admin server-stat</code>.
-  <li> The <code>$HOME/.jack</code> file.
-  <li> The content of the server log with the server state dumped.  To get this — 
-  <ul>
-    <li> Find the Jack background server process by running <code>jack-admin list-server</code>.
-    <li> Send a <code>kill -3</code> command to this server to dump its state into the log file.
-    <li> To locate the server log file, see ‘Finding the Jack log’ below.
-  </ul>
-  <li> The result of executing <code>ls -lR $TMPDIR/jack-$USER.</code>
-  <li> The result of running <code>ps j -U $USER.</code>
-</ul>
-
-<p>You should be able to unblock yourself by killing the Jack background server
-(use <code>jack-admin kill-server</code>), and then by removing its temporary directories contained in <code>jack-$USER</code> of your temporary directory (<code>/tmp</code> or <code>$TMPDIR</code>).</p>
-
-<p><strong>If you have any other issues </strong></p>
-
-<p>To report bugs or request features, please use our public issue tracker,
-available at <a href="http://b.android.com">http://b.android.com</a>,  with the <a href="https://code.google.com/p/android/issues/entry?template=Jack%20bug%20report">Jack tool bug report</a> or <a href="https://code.google.com/p/android/issues/entry?template=Jack%20feature%20request">Jack tool feature request</a> templates. Please attach the Jack log to the bug report. </p>
 <table>
- <tr>
-    <td><strong>Finding the Jack log</strong>
-<ul>
-  <li> If you ran a make command with a dist target,  the Jack log is located at <code>$ANDROID_BUILD_TOP/out/dist/logs/jack-server.log</code> 
-  <li> Otherwise you can find it in by running <code>jack-admin server-log</code>
-</ul>
+<tr>
+<th>Problem</th>
+<th>Action</th>
+</tr>
+<tr>
+<td>Your computer becomes unresponsive during compilation or you experience
+Jack compilations failing on “Out of memory error”</td>
+<td>You can improve the situation by reducing the number of simultaneous Jack
+compilations by editing <code>$HOME/.jack</code> and changing
+<code>SERVER_NB_COMPILE</code> to a lower value.</td>
+</tr>
+<tr>
+<td>Compilations are failing on “Cannot launch background server”</td>
+<td>The most likely cause is TCP ports are already used on your computer. Change
+ports by editing <code>$HOME/.jack</code> (<code>SERVER_PORT_SERVICE</code> and
+<code>SERVER_PORT_ADMIN</code> variables).
+
+<br><br>If it doesn’t solve the problem, report the error (be sure to attach
+your compilation log and the <a href="#jack_log">Jack server log</a>). To
+unblock the situation, disable the Jack compilation server by editing
+<code>$HOME/.jack</code> and changing <code>SERVER</code> to false.
+Unfortunately this will significantly slow down your compilation and may force
+you to launch <code>make -j</code> with load control (option <code>-l</code>
+of <code>make</code>).
 </td>
- </tr>
+</tr>
+<tr>
+<td>Compilation gets stuck without any progress</td>
+<td>Report and provide the following information when possible:
+<br>
+<ul>
+<li>Command line at which you are stuck.</li>
+<li>Output of this command line.</li>
+<li>Result of executing <code>jack-admin server-stat</code>.</li>
+<li><code>$HOME/.jack</code> file.</li>
+<li>Content of the <a href="#jack_log">Jack server log</a> with the server state
+dumped. To get the server log:
+ <ul>
+ <li>Find the Jack background server process by running
+ <code>jack-admin list-server</code>.</li>
+ <li>Send a <code>kill -3</code> command to this server to dump its state into
+ the log file.</li>
+ </ul>
+</li>
+<li>Result of executing <code>ls -lR $TMPDIR/jack-$USER</code>.</li>
+<li>Result of running <code>ps j -U $USER</code>.</li>
+</ul>
+
+To unblock the situation, kill the Jack background server using
+<code>jack-admin kill-server</code>) then remove the temporary directories
+contained in <code>jack-$USER</code> of your temporary directory
+(<code>/tmp</code> or <code>$TMPDIR</code>).
+</td>
+</tr>
+<tr>
+<td>Other issues</td>
+<td>To report bugs or request features, use the public issue tracker at
+<a href="http://b.android.com" class="external">http://b.android.com</a>.
+Use the
+<a href="https://code.google.com/p/android/issues/entry?template=Jack%20bug%20report" class="external">Jack
+tool bug report</a> or
+<a href="https://code.google.com/p/android/issues/entry?template=Jack%20feature%20request" class="external">Jack
+tool feature request</a> templates and remember to attach the Jack log to the
+bug report.</td>
+</tr>
 </table>
 
-<p>In case of reproducible Jack failures, you can get a more detailed log by
-setting one variable, as follows:</p>
+<h3 id="jack_log">Finding the Jack log</h3>
+If you ran a <code>make</code> command with a dist target, the Jack log is
+located at <code>$ANDROID_BUILD_TOP/out/dist/logs/jack-server.log</code>.
+Otherwise, you can find the log by running <code>jack-admin server-log</code>.
+In case of reproducible Jack failures, you can get a more detailed log by
+setting the following variable:</p>
 
 <pre class="devsite-terminal devsite-click-to-copy">
 export ANDROID_JACK_EXTRA_ARGS="--verbose debug --sanity-checks on -D sched.runner=single-threaded"
 </pre>
 
-<p>Then use your standard makefile commands to compile the tree or your project
-and attach its standard output and error.</p>
-
-<p>To remove detailed build logs use:</p>
+<p>Use standard makefile commands to compile the tree (or your project) and
+attach standard output and error. To remove detailed build logs, run:</p>
 
 <pre class="devsite-terminal devsite-click-to-copy">
 unset ANDROID_JACK_EXTRA_ARGS
@@ -207,72 +218,53 @@
 <h3 id=jack_limitations>Jack limitations</h3>
 
 <ul>
-  <li> The Jack server is mono-user by default, so can be only used by one user on a
-computer. If it is not the case, please, choose different port numbers for each
-user and adjust SERVER_NB_COMPILE accordingly. You can also disable the Jack
-server by setting SERVER=false in your $HOME/.jack.
-  <li> CTS compilation is slow due to current vm-tests-tf integration.
-  <li> Bytecode manipulation tools, like JaCoCo, are not supported.
+<li>By default, the Jack server is mono-user and can be used by only one user on
+a computer. To support additional users, select different port numbers for each
+user and adjust <code>SERVER_NB_COMPILE</code> accordingly. You can also disable
+the Jack server by setting <code>SERVER=false</code> in
+<code>$HOME/.jack</code>.</li>
+<li>CTS compilation is slow due to current <code>vm-tests-tf</code> integration.
+<li>Bytecode manipulation tools (such as JaCoCo) are not supported.</li>
 </ul>
 
-<h2 id=using_jack_features>Using Jack features</h2>
+<h2 id=using_jack_features>Using Jack</h2>
 
-<p>Jack supports Java programming language 1.7 and integrates additional features
-described below.</p>
+<p>Jack supports Java programming language 1.7 and integrates the additional
+features described below.</p>
 
-<h3 id=predexing>Predexing </h3>
+<h3 id=predexing>Predexing</h3>
 
 <p>When generating a Jack library file, the .dex of the library is generated and
-stored inside the .jack library file as a pre-dex.  When compiling, Jack reuses
-the pre-dex from each library.</p>
+stored inside the .jack library file as a pre-dex. When compiling, Jack reuses
+the pre-dex from each library. All libraries are pre-dexed:</p>
 
-<p>All libraries are pre-dexed.</p>
+<img src="./images/jack_predex.png" alt="Jack libraries with pre-dex" />
+<figcaption><strong>Figure 4.</strong> Jack libraries with pre-dex.</figcaption>
 
-<img src="/images/pre-dex.png" height="75%" width="75%" alt="Jack libraries with pre-dex" />
-<p class="img-caption"><strong>Figure 4. </strong>Jack libraries with pre-dex</p>
-
-<h4 id=limitations>Limitations</h4>
-
-
-<p>Currently, Jack does not reuse the library pre-dex if
-shrinking/obfuscation/repackaging is used in the compilation.</p>
+<p>Jack does not reuse the library pre-dex if shrinking, obfuscation, or
+repackaging is used in the compilation.</p>
 
 <h3 id=incremental_compilation>Incremental compilation</h3>
 
+<p>Incremental compilation means that only the components touched since the last
+compilation (and their dependencies) are recompiled. Incremental compilation can
+be significantly faster than a full compilation when changes are limited to a
+set of components.</p>
 
-<p>Incremental compilation means that only components that were touched since the
-last compilation, and their dependencies, are recompiled.  Incremental
-compilation can be significantly faster than a full compilation when changes
-are limited to only a limited set of components.</p>
+<p>Incremental compilation is not enabled by default (and is automatically
+deactivated when shrinking, obfuscation, repackaging or multi-dex legacy is
+enabled). To enable incremental builds, add the following line to the
+<code>Android.mk</code> file of the project you want to build incrementally:</p>
 
-<h4 id=limitations>Limitations</h4>
+<pre class="devsite-click-to-copy">LOCAL_JACK_ENABLED := incremental</pre>
 
+<aside class="note"><strong>Note:</strong> If some dependencies are not built
+the first time you build your project with Jack, use <code>mma</code> to build
+them. After doing so you can use the standard build command.</aside>
 
-<p>Incremental compilation is deactivated when shrinking, obfuscation, repackaging
-or multi-dex legacy is enabled.</p>
+<h3 id=shrinking_and_obfuscation>Shrinking and obfuscation</h3>
 
-<h4 id=enabling_incremental_builds>Enabling incremental builds</h4>
-
-
-<p>Currently incremental compilation is not enabled by default.  To enable
-incremental builds, add the following line to the Android.mk file of the
-project that you want to build incrementally:</p>
-
-<pre class="devsite-click-to-copy">
-LOCAL_JACK_ENABLED := incremental
-</pre>
-
-<p class="note"><strong>Note:</strong> The first time that you build your project with Jack if some dependencies
-are not built, use <code>mma</code> to build them, and after that you can use the standard build command.</p>
-
-<h3 id=shrinking_and_obfuscation>Shrinking and Obfuscation</h3>
-
-<p>Jack has shrinking and obfuscation support and uses proguard configuration
-files to enable shrinking and obfuscation features. Here are the supported and
-ignored options:</p>
-
-<h4 id=supported_common_options>Supported common options</h4>
-
+<p>Jack uses proguard configuration files to enable shrinking and obfuscation.</p>
 
 <p>Common options include the following:</p>
 
@@ -292,18 +284,12 @@
   <li> <code>-printseeds</code>
 </ul>
 
-<h4 id=supported_shrinking_options>Supported shrinking options</h4>
-
-
 <p>Shrinking options include the following:</p>
 
 <ul>
-  <li> <code>-dontshrink</code>
+  <li><code>-dontshrink</code>
 </ul>
 
-<h4 id=supported_obfuscation_options>Supported obfuscation options</h4>
-
-
 <p>Obfuscation options include the following:</p>
 
 <ul>
@@ -322,9 +308,6 @@
   <li> <code>-adaptclassstrings</code>
 </ul>
 
-<h4 id=ignored_options>Ignored options</h4>
-
-
 <p>Ignored options include the following:</p>
 
 <ul>
@@ -353,24 +336,23 @@
   <li> <code>-dump</code>
 </ul>
 
-<p class="note"><strong>Note:</strong>  Other options will generate an error.</p>
+<aside class="note"><strong>Note:</strong> Other options will generate an
+error.</aside>
 
 <h3 id=repackaging>Repackaging</h3>
 
-<p>Jack uses jarjar configuration files to do the repackaging.</p>
-
-<p class="note"><strong>Note:</strong> Jack is compatible with "rule" rule types, but is not compatible with "zap" or
-"keep" rule types. If you need "zap" or "keep" rule types please file a feature
+<p>Jack uses jarjar configuration files to do repackaging. While Jack is
+compatible with "rule" rule types, it is not compatible with "zap" or
+"keep" rule types. If you need "zap" or "keep" rule types, file a feature
 request with a description of how you use the feature in your app.</p>
 
 <h3 id=multidex_support>Multidex support</h3>
 
-
-<p>Since dex files are limited to 65K methods, apps with over 65K methods must be
-split into multiple dex files.  (See <a href="http://developer.android.com/tools/building/multidex.html">‘Building Apps with Over 65K Methods’</a> for more information about multidex.)</p>
-
-<p>Jack offers native  and legacy multidex support. </p>
-
+<p>Jack offers native and legacy multidex support. Since dex files are limited
+to 65K methods, apps with over 65K methods must be split into multiple dex
+files. For more details, refer to
+<a href="http://developer.android.com/tools/building/multidex.html" class="external">Building
+Apps with Over 65K Methods</a>.</p>
 
   </body>
 </html>
diff --git a/en/source/site-updates.html b/en/source/site-updates.html
index 402eb8b..821ced7 100644
--- a/en/source/site-updates.html
+++ b/en/source/site-updates.html
@@ -465,17 +465,17 @@
 DRM/KMS in addition to merging down the DRM/KMS framework from the android
 common kernel.
 </p>
-<!--
+
 <h3 id="keystore">Keystore</h3>
 
-<h4>Keymaster3 Implementer's guide</h4>
+<h4>Keymaster 3</h4>
 <p>
 Android 8.0 updates Keymaster, the keystore HAL, by extending the capabilities of
-hardware-backed key storage on Android devices. This builds upon the Android N
-MR2 updates to Keymaster2. For more information, see <a
+hardware-backed key storage on Android devices. This builds upon the Android 7.1.2
+updates to Keymaster 2. For more information, see <a
 href="/security/keystore/index.html">Keymaster 3 documentation</a>.
 </p>
--->
+
 <h3 id="security-enhancements">Security Enhancements</h3>
 
 <h4>Insecure TLS Version Fallback removed from HttpsURLConnection</h4>
diff --git a/zh-cn/devices/accessories/audio.html b/zh-cn/devices/accessories/audio.html
new file mode 100644
index 0000000..01854df
--- /dev/null
+++ b/zh-cn/devices/accessories/audio.html
@@ -0,0 +1,55 @@
+<html devsite><head>
+    <title>构建音频配件</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 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>在实现耳机、头戴式耳机放大器、麦克风、DAC/ADC 或基座等音频配件时,请考虑配件连接到 Android 设备的方式。以下部分将介绍 3.5 毫米有线耳机连接、通用串行总线 (USB) 连接和用于流式传输音乐或其他音频内容的蓝牙连接。</p>
+
+<h2 id="audio-over-35mm">通过 3.5 毫米耳机接口传输音频</h2>
+<p>许多 Android 设备都配有 3.5 毫米(“迷你”)耳机接口。除了传统的立体声输出和单声道输入功能,<a href="headset/plug-headset-spec.html">3.5 毫米耳机规格</a>还定义了标准阻抗和用来支持各种 Android 设备和耳机之间互操作性的功能。</p>
+
+<h2 id="audio-over-usb">通过 USB 传输音频</h2>
+<p>Android 可以在多种模式下使用 USB:</p>
+  <ul>
+    <li><strong>开发</strong>。不支持音频。</li>
+    <li><strong>配件</strong>。由 Android Open Accessory (AOA) 2.0 提供,并提供有限的音频功能,如<a href="custom.html#audio-over-usb">通过 USB 连接自定义音频</a>一节中所述。</li>
+    <li><strong>主机</strong>。使 Android 设备能够驱动 USB 总线,并且可以使用各种 USB 外设(包括音频接口)。实现主机模式的设备将与符合 <a href="/devices/accessories/headset/usb-headset-spec.html">USB 耳机规格</a>的 USB 耳机相兼容。有关主机模式音频的详细信息,请参见 <a href="/devices/audio/usb.html">USB 数字音频</a>一文。
+  </li></ul>
+
+<h2 id="audio-over-bluetooth">通过蓝牙传输音频</h2>
+<p>通过蓝牙连接 Android 的配件可以使用高级音频传输配置文件 (A2DP) 连接流式传输音乐,以便进行播放。在 Android 1.5(API 3 级)和更高版本上支持使用 A2DP 通过蓝牙播放音频。Android 用户可以使用系统“设置”&gt;“蓝牙”,连接到支持此配置文件的配件,然后直接向该配件播放音乐,而不必使用辅助应用。</p>
+
+<p>从 Android 3.0(API 11 级)开始,应用可以使用 <a href="http://developer.android.com/reference/android/bluetooth/BluetoothA2dp.html"><code>BluetoothA2dp</code></a> 类来操作 A2DP 连接。要提供自定义应用来输出到音频配件,您必须使用 Android 3.0 或更高版本。
+</p>
+
+<h3 id="next-steps_1">后续步骤</h3>
+<p>要开始构建使用蓝牙连接的音频配件,请执行以下操作:
+</p>
+<ul>
+<li>选择可支持蓝牙通信和 A2DP 连接配置文件的硬件平台或构建此类硬件设备。</li>
+<li>查看 ADK 2012 <a href="http://developer.android.com/tools/adk/adk2.html#src-download">固件源代码</a> (<code>&lt;adk-src&gt;/adk2012/board/library/ADK2/</code>),其中包括使用蓝牙连接的音频播放配件的实现示例。</li>
+</ul>
+
+<p class="note"><strong>注意</strong>:ADK 2012 源代码包括为 Texas Instruments CC2564 芯片构建的开放源代码蓝牙堆栈,但其目的是与任何实现标准主机/控制器接口 (HCI) 的蓝牙芯片配合使用。</p>
+
+<h2 id="midi-over-usb">通过 USB 和蓝牙 LE 传输 MIDI</h2>
+<p>USB 和蓝牙低功耗连接都可以用于传输 <a href="http://en.wikipedia.org/wiki/MIDI">MIDI</a> 协议。有关详细信息,请参阅 <a href="/devices/audio/midi.html">MIDI</a> 一文。</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/accessories/custom.html b/zh-cn/devices/accessories/custom.html
new file mode 100644
index 0000000..727f040
--- /dev/null
+++ b/zh-cn/devices/accessories/custom.html
@@ -0,0 +1,71 @@
+<html devsite><head>
+    <title>自定义配件</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 The Android Open Source Project
+
+      Licensed under the Apache License, Version 2.0 (the "License");
+      you may not use this file except in compliance with the License.
+      You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      See the License for the specific language governing permissions and
+      limitations under the License.
+  -->
+
+<p>Android 的配件可以是任何设备:键盘、温度计、机器人、照明控制系统或您可以想象到的任何设备。所有 Android 配件都以某种方式连接到 Android 设备,因此在构建配件时,您必须考虑配件将使用的连接类型。本页概括介绍了 Android 配件的连接选项,以及可帮助您快速入门的资源列表。</p>
+
+<h2 id="connecting-over-usb">通过 USB 进行连接</h2>
+<p>通过 USB 数据线连接到 Android 设备的配件必须支持 Android 开源配件 (AOA) 协议,该协议指定了配件如何通过 USB 与 Android 设备建立通信。由于 Android 设备的输出功率较低,因此 AOA 需要配件充当 USB 主机,这意味着连接的配件必须为总线供电。</p>
+
+<p>AOA 有两个支持不同通信类型的版本:</p>
+<ul>
+<li><strong>AOAv1</strong>。支持通用配件通信和 adb 调试。适用于 Android 3.1(API 级别 12)及更高版本,在 Android 2.3.4(API 级别10)及更高版本中通过<a href="https://developers.google.com/android/add-ons/google-apis/">插件库</a>获得支持。</li>
+<li><strong>AOAv2</strong>。支持音频流式传输和人机接口设备 (HID) 功能。适用于 Android 4.1(API 级别 16)。</li>
+</ul>
+
+<p>如果您使用通用配件协议(而不是使用 adb 或音频协议)与配件通信,则必须提供可以检测 USB 配件连接并建立通信的 Android 应用。
+</p>
+
+<h3 id="next-steps_0">后续步骤</h3>
+<p>开始构建使用 USB 连接的 Android 配件:</p>
+<ul>
+<li>选择可支持 USB 主机模式的硬件平台或构建此类硬件设备。</li>
+<li>查看 <a href="protocol.html">AOA</a> 规范,以了解如何在您的配件硬件上实现此协议。建议为所有新的 Android USB 配件实现 <a href="aoa2.html">AOAv2</a>。</li>
+<li>查看 ADK 2012 <a href="http://developer.android.com/tools/adk/adk2.html#src-download">固件源代码</a> (<code>&lt;adk-src&gt;/adk2012/board/library/ADK2/</code>),该代码展示了使用 USB 连接进行常规数据通信和音频流式传输的配件实现。</li>
+<li>当计划构建通过 USB 与配件通信的 Android 应用时,请查看 ADK 2012 Android <a href="http://developer.android.com/tools/adk/adk2.html#src-download">应用源代码</a> (<code>&lt;adk-src&gt;/adk2012/app/</code>)。</li>
+</ul>
+
+<h2 id="connecting-over-bluetooth">通过蓝牙进行连接</h2>
+<p>通过蓝牙连接与 Android 设备连接的配件可以使用 Android 支持的连接配置文件,包括简单串行协议 (SSP) 和高级音频分发配置文件 (A2DP)。使用蓝牙连接到 Android 设备的配件必须支持蓝牙通信以及至少一个受支持的连接配置文件。
+</p>
+<p>用户必须在 Android 设备上启用蓝牙功能,并与您的配件配对以使用该配件。您还可以提供一个辅助 Android 应用,负责处理专门的通信(如数据输入或控制输出),以与您的配件进行连接。</p>
+
+<h3 id="next-steps_1">后续步骤</h3>
+<p>开始构建使用蓝牙连接的 Android 配件:</p>
+<ul>
+<li>选择可支持蓝牙通信和 Android 支持的连接配置文件(如 SSP 或 A2DP)的硬件平台或构建此类硬件设备。</li>
+<li>查看 ADK 2012 <a href="http://developer.android.com/tools/adk/adk2.html#src-download">固件源代码</a> (<code>&lt;adk-src&gt;/adk2012/board/library/ADK2/</code>),其中包含使用蓝牙连接进行常规数据通信和音频流式传输的一个示例实现。</li>
+<li>当计划构建通过蓝牙与配件通信的 Android 应用时,请查看 ADK 2012 Android <a href="http://developer.android.com/tools/adk/adk2.html#src-download">应用源代码</a> (<code>&lt;adk-src&gt;/adk2012/app/</code>)。</li>
+</ul>
+
+<p class="note"><strong>注意</strong>:ADK 2012 源代码包括为 Texas Instruments CC2564 芯片构建的开放源代码蓝牙堆栈,但其可与支持标准主机/控制器接口 (HCI) 的任何蓝牙芯片配合使用。</p>
+
+<h2 id="audio-over-usb">通过 USB 连接音频</h2>
+<p>通过 USB 连接 Android 的配件可以使用 AOAv2(在 Android 4.1(API 级别 16)和更高版本上受支持)。在 Android 设备连接到支持此协议的配件后,Android 系统便会将其视为标准音频输出设备,并将所有音频导向到该配件。在 Android 设备上不需要辅助软件应用。</p>
+
+<p class="note"><strong>注意</strong>:由于 Android 设备的输出功率较低,因此 AOA 需要配件充当 USB 主机,这意味着连接的配件必须为总线供电。</p>
+
+<h3 id="next-steps_2">后续步骤</h3>
+<p>要开始构建使用 USB 连接的音频配件,请参阅 <a href="#next-steps_0">USB 连接的后续步骤</a>。</p>
+
+<p>AOAv2 还通过 USB 连接支持<a href="aoa2.html#hid-support">人机接口设备</a> (HID) 协议,使诸如音频基座等配件能够提供硬件播放控件,如暂停、快进或音量按钮。</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/accessories/headset/expected-behavior.html b/zh-cn/devices/accessories/headset/expected-behavior.html
new file mode 100644
index 0000000..f39a629
--- /dev/null
+++ b/zh-cn/devices/accessories/headset/expected-behavior.html
@@ -0,0 +1,148 @@
+<html devsite><head>
+    <title>耳机预期行为</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 The Android Open Source Project
+
+      Licensed under the Apache License, Version 2.0 (the "License");
+      you may not use this file except in compliance with the License.
+      You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      See the License for the specific language governing permissions and
+      limitations under the License.
+  -->
+
+<p>本文详细介绍了 <a href="plug-headset-spec.html">3.5 毫米插头</a>和 <a href="usb-headset-spec.html">USB</a> 耳机的功能要求。</p>
+<p>在验证设备和音频耳机的行为时,请注意以下要求:</p>
+<ul>
+  <li>仅在没有其他可用音频配件(如蓝牙)时适用</li>
+  <li>涵盖设备的默认行为,不适用于使用音频导向 API 来选择要使用的音频外设的应用</li>
+</ul>
+
+<h2 id="media">媒体</h2>
+
+<p>如果用户在播放媒体时将耳机连接到设备,则只能通过耳机听到音频输出(声音)。</p>
+
+<p>例如,当使用<a href="https://github.com/googlesamples/android-UniversalMusicPlayer">开放源代码</a><a href="https://android-developers.blogspot.com/2015/03/a-new-reference-app-for-multi-device.html">通用音乐播放器</a>播放媒体时,按播放/暂停按钮应暂停播放。在媒体暂停时按同一按钮应恢复播放。</p>
+
+<p>如果耳机具有音量控制按钮:</p>
+
+<ul>
+  <li>每次按下调高音量按钮都应逐渐调高音量,直到达到最大音量。如果一直按住调高音量按钮,音量应逐渐增加到最大音量设置。
+  </li><li>每次按下调低音量按钮都应逐渐调低音量,直到完全静音。如果一直按住调低音量按钮,音量应逐渐降低至静音。
+  </li><li>在静音状态下按下调高音量按钮,应从静音开始一次增加一个等级的音量。
+</li></ul>
+
+<p><strong>针对应用的建议</strong>:断开耳机连接时,声音输出应停止,且播放应暂停。在重新连接时,播放不应再次开始,除非用户按下播放按钮。按下播放时,应再次限于通过耳机输出声音。</p>
+
+<h3 id="one_button">一个按钮</h3>
+
+<img src="images/media_one.png" alt="单按钮耳机处理媒体流的按钮功能。"/>
+
+<p class="img-caption"><strong>图 1.</strong> 单按钮耳机处理媒体流的按钮功能。</p>
+
+<h3 id="two_buttons">两个按钮</h3>
+
+<img src="images/media_two.png" alt="双按钮耳机处理媒体流的按钮功能。"/>
+
+<p class="img-caption"><strong>图 2.</strong> 双按钮耳机处理媒体流的按钮功能。</p>
+
+<h3 id="three_buttons">三个按钮</h3>
+
+<img src="images/media_three.png" alt="三按钮耳机处理媒体流的按钮功能。"/>
+
+<p class="img-caption"><strong>图 3.</strong> 三按钮耳机处理媒体流的按钮功能。</p>
+
+<h3 id="four_buttons">四个按钮</h3>
+
+<img src="images/media_four.png" alt="四按钮耳机处理媒体流的按钮功能。"/>
+
+<p class="img-caption"><strong>图 4.</strong> 四按钮耳机处理媒体流的按钮功能。</p>
+
+<h2 id="telephony">电话</h2>
+
+<p>如果用户在通话过程中将耳机连接到设备,则应在耳机上继续通话。通话不应被打断,且麦克风不应静音。音量按钮(如果存在)的行为应与媒体播放完全相同。</p>
+
+<p class="note"><strong>注意</strong>:静音和挂断电话的操作可能会因 Android 设备而异。本文描述的是最常见的行为;但对于某些设备,短按耳机按钮会使通话静音,而长按会挂断电话。</p>
+
+<h3 id="one_button">一个按钮</h3>
+
+<img src="images/telephony_one.png" alt="单按钮耳机处理通话的按钮功能。"/>
+
+<p class="img-caption"><strong>图 5.</strong> 单按钮耳机处理通话的按钮功能。</p>
+
+<h3 id="two_buttons">两个按钮</h3>
+
+<img src="images/telephony_two.png" alt="双按钮耳机处理通话的按钮功能。"/>
+
+<p class="img-caption"><strong>图 6.</strong> 双按钮耳机处理通话的按钮功能。</p>
+
+<h3 id="three_buttons">三个按钮</h3>
+
+<img src="images/telephony_three.png" alt="三按钮耳机处理通话的按钮功能。"/>
+
+<p class="img-caption"><strong>图 7.</strong> 三按钮耳机处理通话的按钮功能。</p>
+
+<h3 id="four_buttons">四个按钮</h3>
+
+<img src="images/telephony_four.png" alt="四按钮耳机处理通话的按钮功能。"/>
+<p class="img-caption"><strong>图 8.</strong> 四按钮耳机处理通话的按钮功能。</p>
+
+<h2 id="voice_command">语音指令</h2>
+
+<p>语音指令按钮是一种新的内嵌控制标准,用于从任何已获批的穿戴式音频设备一致且方便地访问语音指令功能。通过按下此处定义的按钮,用户将听到双音信号<a href="http://en.wikipedia.org/wiki/Earcon">耳标</a>,表示设备正在聆听并准备好接收查询。</p>
+
+<p>无论是内嵌到多功能按钮中还是单独采用单个按钮,都应可快速访问,符合人体工程学,并按照以下部分所述放置在显著位置。</p>
+
+<h2 id="buttons_and_function_mapping">按钮和功能映射建议</h2>
+
+<p>下图描述了 Android 语音指令按钮的可接受配置。</p>
+
+<h3 id="options">选项</h3>
+
+<img src="images/button_configuration.png" alt="按钮配置选项。"/>
+
+<p class="img-caption"><strong>图 9.</strong> 按钮配置选项。</p>
+
+<p>按钮应始终朝向前方且隔开,以便只通过触摸便可轻松找到它们。</p>
+
+<h3 id="spacing">间距</h3>
+
+<p>按钮直径必须大于 5 毫米,并且按钮之间的距离必须至少为 5 毫米。对于四按钮耳机,按钮 D 与其他按钮集群之间必须至少有 9 毫米的间隔。</p>
+
+<img src="images/button_spacing.png" alt="按钮间距要求"/>
+
+<p class="img-caption"><strong>图 10.</strong> 按钮间距要求。</p>
+
+<h3 id="icon">图标</h3>
+
+<p>在下图中,A 未标记或用圆点进行标记。B 用 + 或向上箭头进行标记。C 用 - 或向下箭头进行标记。D 用选定的按钮图标进行标记。</p>
+
+<img src="images/button_icons.png" alt="按钮图标要求"/>
+<p class="img-caption"><strong>图 11.</strong> 按钮图标要求。</p>
+
+<h3 id="sizing">大小</h3>
+
+<p>下图显示了按钮图标与其周围空间的比例。</p>
+
+<img src="images/icon_sizing.png" alt="语音搜索按钮图标大小要求"/>
+
+<p class="img-caption"><strong>图 12.</strong> 语音搜索按钮图标大小要求。</p>
+
+<h3 id="microphone_port">麦克风端口</h3>
+
+<p>在操作按钮时,麦克风绝不应被遮挡。将端口放在远离手指触摸界面区域的位置。</p>
+
+<img src="images/microphone.png" alt="麦克风位置"/>
+
+<p class="img-caption"><strong>图 13.</strong> 麦克风位置。</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/accessories/headset/index.html b/zh-cn/devices/accessories/headset/index.html
new file mode 100644
index 0000000..9bd7c49
--- /dev/null
+++ b/zh-cn/devices/accessories/headset/index.html
@@ -0,0 +1,29 @@
+<html devsite><head>
+    <title>Android 音频耳机</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 The Android Open Source Project
+
+      Licensed under the Apache License, Version 2.0 (the "License");
+      you may not use this file except in compliance with the License.
+      You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      See the License for the specific language governing permissions and
+      limitations under the License.
+  -->
+
+<p>本部分介绍了 Android 耳机配件接口的开发和测试。本文档介绍的是 Android 耳机内置遥控器的接口指南。</p>
+
+<p>配件制造商应遵循 <a href="plug-headset-spec.html">3.5 毫米耳机规范</a>或 <a href="usb-headset-spec.html">USB 耳机规范</a>中的准则。设备制造商应遵循 <a href="jack-headset-spec.html">3.5 毫米耳机插孔规范</a>或 <a href="/devices/audio/usb.html">USB 数字音频页面</a>中的准则。</p>
+
+<p>这样做的目标是保持一定的一致性和设计标准,同时允许在设计表达上自由发挥。如果您选择实现专用的 Android 耳机配件,请遵循上述准则,确保耳机与符合 <a href="/compatibility/android-cdd.pdf">Android 兼容性定义文档 (CDD)</a> 中的建议的设备兼容。</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/accessories/headset/jack-headset-spec.html b/zh-cn/devices/accessories/headset/jack-headset-spec.html
new file mode 100644
index 0000000..508887f
--- /dev/null
+++ b/zh-cn/devices/accessories/headset/jack-headset-spec.html
@@ -0,0 +1,228 @@
+<html devsite><head>
+    <title>3.5 毫米耳机插孔:设备规范</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 The Android Open Source Project
+
+      Licensed under the Apache License, Version 2.0 (the "License");
+      you may not use this file except in compliance with the License.
+      You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      See the License for the specific language governing permissions and
+      limitations under the License.
+  -->
+
+<p>为了实现与 <a href="plug-headset-spec.html">3.5 毫米插头耳机规范</a>的兼容性,配备 4 导体 3.5 毫米音频插孔的设备必须符合以下规范。有关 Android 兼容性要求,请参阅 <a href="/compatibility/android-cdd.html#7_8_audio">Android CDD</a> 的“模拟音频端口”部分。<em></em></p>
+
+<h2 id="headset_jack_functions">功能</h2>
+
+<table>
+ <tbody><tr>
+    <th>功能</th>
+    <th>设备支持</th>
+ </tr>
+ <tr>
+    <td>立体声音频输出</td>
+    <td>必需</td>
+ </tr>
+ <tr>
+    <td>音频输入(麦克风)</td>
+    <td>必需</td>
+ </tr>
+ <tr>
+    <td>接地</td>
+    <td>必需</td>
+ </tr>
+</tbody></table>
+
+<h2 id="software_mapping">软件映射</h2>
+
+<table>
+ <tbody><tr>
+    <th style="width:33%">功能</th>
+    <th style="width:33%">设备支持</th>
+    <th style="width:33%">说明</th>
+ </tr>
+ <tr>
+    <td>功能 A 控件事件</td>
+    <td>必需</td>
+    <td>输入事件:<code>KEY_MEDIA</code>
+<p>Android 按键:<code>KEYCODE_HEADSETHOOK<code></code></code></p></td>
+ </tr>
+ <tr>
+    <td>功能 D 控件事件</td>
+    <td>必需</td>
+    <td>输入事件:<code>KEY_VOICECOMMAND</code>
+<p>Android 按键:<code>KEYCODE_VOICE_ASSIST</code></p></td>
+ </tr>
+ <tr>
+    <td>功能 B 控件事件</td>
+    <td>必需</td>
+    <td>输入事件:<code>KEY_VOLUMEUP</code>
+<p>Android 按键:<code>VOLUME_UP</code></p></td>
+ </tr>
+ <tr>
+    <td>功能 C 控件事件</td>
+    <td>必需</td>
+    <td>输入事件:<code>KEY_VOLUMEDOWN</code>
+<p>Android 按键:<code>VOLUME_DOWN</code></p></td>
+ </tr>
+ <tr>
+    <td>耳机插入检测</td>
+    <td>必需</td>
+    <td>输入事件:<code>SW_JACK_PHYSICAL_INSERT 7</code></td>
+ </tr>
+ <tr>
+    <td rowspan="2">耳机类型检测</td>
+    <td>麦克风</td>
+    <td>输入事件:<code>SW_MICROPHONE_INSERT 4</code></td>
+ </tr>
+ <tr>
+    <td>无麦克风</td>
+    <td>输入事件:<code>SW_HEADPHONE_INSERT 2</code></td>
+ </tr>
+ <tr>
+    <td rowspan="2">耳机扬声器阻抗</td>
+    <td>必需耳机(低)</td>
+    <td>故障模式用于指示耳机开启相关限制</td>
+ </tr>
+ <tr>
+    <td>必需线路输入(高)</td>
+    <td>输入事件:<code>SW_LINEOUT_INSERT 6</code></td>
+ </tr>
+</tbody></table>
+
+<h2 id="mechanical11">机械</h2>
+
+<table>
+ <tbody><tr>
+    <th style="width:33%">功能</th>
+    <th style="width:33%">设备支持</th>
+    <th style="width:33%">说明</th>
+ </tr>
+ <tr>
+    <td>4 导体 3.5 毫米插孔</td>
+    <td>必需</td>
+    <td></td>
+ </tr>
+ <tr>
+    <td>CTIA 引脚顺序 (LRGM)</td>
+    <td>必需</td>
+    <td>兼容 3 脚插头和单声道插头</td>
+ </tr>
+ <tr>
+    <td>OMTP 引脚顺序 (LRMG)</td>
+    <td>可选,但强烈建议支持</td>
+    <td></td>
+ </tr>
+ <tr>
+    <td>耳机检测序列</td>
+    <td>必需</td>
+    <td>仅当插头上的所有触点接触其相关部分之后才触发插头插入通知(这样可防止因插入缓慢而导致耳机检测不可靠)。</td>
+ </tr>
+</tbody></table>
+
+<h2 id="electrical12">电气</h2>
+
+<h3 id="general">概述</h3>
+
+<table>
+ <tbody><tr>
+    <th style="width:33%">功能</th>
+    <th style="width:33%">设备支持</th>
+    <th style="width:33%">备注</th>
+ </tr>
+ <tr>
+    <td>最大输出电压驱动</td>
+    <td>150 毫伏</td>
+    <td>&gt;= 150 毫伏(电阻为 32 欧姆)<p>测试条件:EN50332-2</p></td>
+ </tr>
+ <tr>
+    <td>麦克风偏置电阻</td>
+    <td>必需</td>
+    <td>可以灵活选择所使用的检测方法和麦克风偏置电阻器。需要检测以下指定的所有按钮电阻值范围,并将其与各自的功能相关联</td>
+ </tr>
+ <tr>
+    <td>麦克风偏置电压</td>
+    <td>1.8 伏 - 2.9 伏</td>
+    <td>可保证与通用麦克风咪头的兼容性。</td>
+ </tr>
+</tbody></table>
+
+<h3 id="function_impedance_and_threshold_detection">功能阻抗和阈值检测</h3>
+
+<p>设备必须检测配件上的以下电阻梯形。按照上一部分展示的标准电路图(参考耳机测试电路)对配件进行测试,当通过 2.2 千欧电阻器对按钮施加 2.2 伏麦克风偏置电压时,将测量从 MIC 终端到 GND 的总阻抗。这是与按钮检测电路(具有与按钮电阻器并联的麦克风)相同的有效电阻。</p>
+
+<table>
+ <tbody><tr>
+    <th style="width:40%">按钮阻抗级别</th>
+    <th style="width:20%">设备支持</th>
+    <th style="width:40%">备注</th>
+ </tr>
+ <tr>
+    <td>不超过 70 欧姆</td>
+    <td>必需</td>
+    <td>[功能 A]</td>
+ </tr>
+ <tr>
+    <td>110 - 180 欧姆</td>
+    <td>必需</td>
+    <td>[功能 D]</td>
+ </tr>
+ <tr>
+    <td>210 - 290 欧姆</td>
+    <td>必需</td>
+    <td>[功能 B]</td>
+ </tr>
+ <tr>
+    <td>360 - 680 欧姆</td>
+    <td>必需</td>
+    <td>[功能 C]</td>
+ </tr>
+ </tbody></table>
+
+ <table>
+ <tbody><tr>
+    <th style="width:40%">耳机扬声器阻抗级别</th>
+    <th style="width:20%">设备支持</th>
+    <th style="width:40%">备注</th>
+ </tr>
+ <tr>
+    <td>低阈值检测</td>
+    <td>必需</td>
+    <td>耳机(低)&lt; 1 千欧</td>
+ </tr>
+ <tr>
+    <td>高阈值检测</td>
+    <td>必需</td>
+    <td>线路输入(高)&gt; 5 千欧</td>
+ </tr>
+</tbody></table>
+
+ <table>
+ <tbody><tr>
+    <th style="width:40%">4 段插头检测电阻(第 3 段与第 4 段之间)</th>
+    <th style="width:20%">设备支持</th>
+    <th style="width:40%">备注</th>
+ </tr>
+ <tr>
+    <td>4 段插头阈值</td>
+    <td>必需</td>
+    <td>电阻 &gt;= 100 欧姆</td>
+ </tr>
+ <tr>
+    <td>3 段插头阈值</td>
+    <td>必需</td>
+    <td>电阻 &lt; 100 欧姆</td>
+ </tr>
+</tbody></table>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/accessories/headset/plug-headset-spec.html b/zh-cn/devices/accessories/headset/plug-headset-spec.html
new file mode 100644
index 0000000..da83b61
--- /dev/null
+++ b/zh-cn/devices/accessories/headset/plug-headset-spec.html
@@ -0,0 +1,176 @@
+<html devsite><head>
+    <title>3.5 毫米耳机:配件规范</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 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>本文介绍了有关使 3.5 毫米插头耳机在整个 Android 生态系统中实现一致功能的要求。</p>
+
+<p>有关其他要求,设备制造商应参考 <a href="jack-headset-spec.html">3.5 毫米耳机插孔规范</a>和 <a href="/compatibility/android-cdd.html">Android 兼容性定义文档</a> (CDD)。</p>
+
+<h2 id="functions">功能</h2>
+
+<table style="width:50%">
+ <tbody><tr>
+    <th>功能</th>
+    <th>配件支持</th>
+ </tr>
+ <tr>
+    <td>立体声音频输出</td>
+    <td>必需</td>
+ </tr>
+ <tr>
+    <td>音频输入(麦克风)</td>
+    <td>必需</td>
+ </tr>
+ <tr>
+    <td>接地</td>
+    <td>必需</td>
+ </tr>
+</tbody></table>
+
+<h2 id="control-function_mapping">控制功能映射</h2>
+
+<table>
+ <tbody><tr>
+    <th style="width:33%">控制功能</th>
+    <th style="width:33%">配件支持</th>
+    <th style="width:33%">说明</th>
+ </tr>
+ <tr>
+    <td>功能 A</td>
+    <td>必需</td>
+    <td>播放/暂停/接挂机(短按)、触发辅助(长按)、下一个(双击)</td>
+ </tr>
+ <tr>
+    <td>功能 B</td>
+    <td>可选</td>
+    <td>调高音量</td>
+ </tr>
+ <tr>
+    <td>功能 C</td>
+    <td>可选</td>
+    <td>调低音量</td>
+ </tr>
+ <tr>
+    <td>功能 D</td>
+    <td>可选</td>
+    <td>保留(Nexus 设备使用此功能来启动语音命令)</td>
+ </tr>
+</tbody></table>
+
+<p>按钮的功能分配如下:</p>
+
+<ul>
+  <li>所有单按钮耳机都必须实现功能 A。</li><li>具有多个按钮的耳机必须按照以下方式实现功能:<ul>
+    <li>2 个功能:A 和 D</li><li>3 个功能:A、B、C</li><li>4 个功能:A、B、C、D</li></ul>
+</li></ul>
+
+<h2 id="mechanical">机械</h2>
+
+<table>
+ <tbody><tr>
+    <th style="width:33%">功能</th>
+    <th style="width:33%">配件支持</th>
+    <th style="width:33%">备注</th>
+ </tr>
+ <tr>
+    <td>4 段式 3.5 毫米插头</td>
+    <td>必需</td>
+    <td>参考号:EIAJ-RC5325A 标准</td>
+ </tr>
+ <tr>
+    <td>CTIA 引脚顺序 (LRGM)</td>
+    <td>必需</td>
+    <td>对 OMTP 引脚有法律要求的区域除外</td>
+ </tr>
+ <tr>
+    <td>OMTP 引脚顺序 (LRMG)</td>
+    <td>可选</td>
+    <td></td>
+ </tr>
+ <tr>
+    <td>麦克风</td>
+    <td>必需</td>
+    <td>在操作耳机控件时不能被遮挡</td>
+ </tr>
+</tbody></table>
+
+<h2 id="electrical">电气</h2>
+
+<table>
+ <tbody><tr>
+    <th style="width:33%">功能</th>
+    <th style="width:33%">配件支持</th>
+    <th style="width:33%">说明</th>
+ </tr>
+ <tr>
+    <td>耳机扬声器阻抗</td>
+    <td>16 欧姆或更高</td>
+    <td>推荐 32 - 300 欧姆</td>
+ </tr>
+ <tr>
+    <td>麦克风直流电阻</td>
+    <td>1000 欧姆或更高</td>
+    <td>麦克风特性必须符合最新 <a href="/compatibility/android-cdd.html#5_4_audio_recording">Android CDD</a> 中第 5.4 节“音频录制”的要求<em></em></td>
+ </tr>
+ <tr>
+    <td rowspan="4">控制功能等效阻抗*</td>
+    <td>0 欧姆</td>
+    <td>[功能 A] 播放/暂停/接挂机</td>
+ </tr>
+ <tr>
+    <td>240 欧姆 +/- 1% 电阻</td>
+    <td>[功能 B]</td>
+ </tr>
+ <tr>
+    <td>470 欧姆 ± 1% 电阻</td>
+    <td>[功能 C]</td>
+ </tr>
+ <tr>
+    <td>135 欧姆 +/- 1% 电阻</td>
+    <td>[功能 D]</td>
+ </tr>
+</tbody></table>
+
+<p><em>*当按下按钮(通过 2.2 千欧姆电阻应用 2.2 伏麦克风偏置电压)时,从正极麦克风端子到 GND 的总阻抗</em></p>
+
+<p>在下图中,按钮 A 对应功能 A,按钮 B 对应功能 B,依此类推。</p>
+
+<h2 id="reference_headsets">参考耳机测试电路</h2>
+
+<p>下图“参考耳机测试电路 1”显示了 4 段式插头的 CTIA 引脚。对于 OMTP 引脚,交换 MIC 段和 GND 段的位置。</p>
+
+<img src="images/headset-circuit1.png" alt="参考耳机测试电路 1"/>
+<p class="img-caption"><strong>图 1.</strong> 参考耳机测试电路 1</p>
+
+<p>下图“参考耳机测试电路 2”显示了如何更改实际电阻值 (R1 - R4) 以符合本规范。</p>
+
+<img src="images/headset-circuit2.png" alt="参考耳机测试电路 2"/>
+<p class="img-caption"><strong>图 2.</strong> 参考耳机测试电路 2</p>
+
+<p>与麦克风平行的按钮的实际电阻 (R1 - R4) 基于麦克风套管电阻 (Rmic) 和等效阻抗值 (ReqA - ReqD)。使用以下公式:</p>
+
+<p><em>Req<sub>N</sub>=(R<sub>mic</sub>*R<sub>n</sub>)/(R<sub>mic</sub>+R<sub>n</sub>)</em></p>
+
+<p>其中 R<em>n</em> 是按钮的实际电阻,Req<em>N</em> 是该按钮的等效阻抗值(已提供),Rmic 是麦克风阻抗值。</p>
+
+<p>以上示例假设麦克风阻抗 (Rmic) 为 5 千欧姆;为达到 135 欧姆的等效 R4 阻抗 (ReqD),实际电阻值 (R4) 必须为 139 欧姆。</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/accessories/headset/testing.html b/zh-cn/devices/accessories/headset/testing.html
new file mode 100644
index 0000000..b365f26
--- /dev/null
+++ b/zh-cn/devices/accessories/headset/testing.html
@@ -0,0 +1,92 @@
+<html devsite><head>
+    <title>测试</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 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>为了确保您的耳机与所要求的基本功能兼容,请执行以下测试。</p>
+
+<h2 id="headset_insertion">耳机插入</h2>
+
+<ol>
+  <li>先关闭 Android 设备。
+  </li><li>插入耳机。
+  </li><li>启动设备。
+  </li><li>解锁。
+  </li><li>打开<a href="https://github.com/googlesamples/android-UniversalMusicPlayer">开放源代码</a><a href="https://android-developers.blogspot.com/2015/03/a-new-reference-app-for-multi-device.html">通用音乐播放器</a>。
+  </li><li>按设备音量按钮以将媒体音量调至最大。
+  </li><li>开始播放音乐,并确认耳机是否有声音。
+  </li><li>在播放音乐时断开耳机连接,确认音乐是否停止。
+  </li><li>重新连接耳机,再次播放音乐,确认耳机是否有声音。
+</li></ol>
+
+<h2 id="volume_buttons">音量按钮</h2>
+
+<ol>
+  <li>播放音乐,并确保耳机中可以传出声音。
+  </li><li>按音量调低按钮。确认音量面板显示媒体音量降一个等级,且音量输出如预期降低。
+  </li><li>长按音量调低按钮。确认音量面板显示媒体音量一直降低,且音量输出逐渐降至静音。
+  </li><li>按音量调高按钮。确认音量面板显示媒体音量升一个等级,且音量输出如预期升高。
+  </li><li>长按音量调高按钮。确认音量面板显示媒体音量一直升至最高,且音量输出如预期升高。
+</li></ol>
+
+<h2 id="play_pause_for_music">针对音乐的播放/暂停操作</h2>
+
+<p>快速按下播放/暂停按钮,确认耳机中的音乐停止播放。如果音乐尚未播放,则应开始从耳机中播放出来。</p>
+
+<h2 id="play_pause_for_telephony">针对电话的播放/暂停操作</h2>
+<p>不同 Android 设备上的静音和挂断电话操作可能有所不同。本测试记录了最常见的行为。</p>
+
+<ol>
+  <li>拨打电话。
+  </li><li>在通话过程中长按播放/暂停按钮。
+  </li><li>确认麦克风处于静音状态。如果您再次长按,则麦克风应取消静音。
+  </li><li>在通话过程中,短按播放/暂停按钮。
+  </li><li>确认短按可结束通话。
+  </li><li>在 Android 设备上接听电话。
+  </li><li>在响铃时短按播放/暂停按钮,确认电话已接听。
+  </li><li>在 Android 设备上再次接听电话。
+  </li><li>在电话响铃时长按播放/暂停按钮,确认电话已被拒接。
+</li></ol>
+
+<h2 id="play_pause_for_voice_commands_microphone">针对语音指令和麦克风的播放/暂停操作</h2>
+
+<ol>
+  <li>解锁 Android 设备并进入主屏幕。
+  </li><li>长按播放/暂停按钮。
+  </li><li>确认:<ol>
+    <li>您听到提示音,之后应能够进行语音搜索查询,如“现在几点?”
+    </li><li>您听到“现在的时间是…”这样的回应。
+  </li></ol>
+  </li></ol>
+
+<h2 id="voice_button_for_voice_commands_microphone">适用于语音指令和麦克风的语音指令按钮</h2>
+
+<ol>
+  <li>解锁 Android 设备并进入主屏幕。
+  </li><li>短按语音指令按钮。
+  </li><li>确认:<ol>
+    <li>您听到提示音,之后应能够进行搜索查询,如“现在几点?”
+    </li><li>您听到“现在的时间是…”这样的回应。
+  </li></ol>
+  </li></ol>
+
+<p class="note"><strong>重要提示</strong>:按下语音指令按钮可启动任何搜索应用,例如 Google 搜索。</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/accessories/index.html b/zh-cn/devices/accessories/index.html
new file mode 100644
index 0000000..ed5aa82
--- /dev/null
+++ b/zh-cn/devices/accessories/index.html
@@ -0,0 +1,42 @@
+<html devsite><head>
+    <title>Android 配件</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 The Android Open Source Project
+
+      Licensed under the Apache License, Version 2.0 (the "License");
+      you may not use this file except in compliance with the License.
+      You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      See the License for the specific language governing permissions and
+      limitations under the License.
+  -->
+
+<p>借助一套标准协议,您可以实现可在各种 Android 设备中扩展 Android 功能的强大配件。
+</p>
+
+<div class="layout-content-row">
+
+  <div class="layout-content-col span-6">
+        <h4 id="audio-accessories">音频配件</h4>
+        <p>Android 不但支持设备本地音频,而且支持经由 3.5 毫米有线耳机插孔、USB 或蓝牙连接的设备外远程音频。制造商应该查看<a href="headset/index.html">耳机规范</a>,而用户可以了解如何<a href="https://support.google.com/nexus/answer/6127700">使用 USB 主机模式录制和播放音频</a>。</p>
+        <p><a href="audio.html">» 音频配件</a></p>
+  </div>
+
+  <div class="layout-content-col span-6">
+        <h4 id="custom-accessories">自定义配件</h4>
+        <p>您想要将什么配件连接到您的 Android 设备?闹钟?键盘?恒温器?机器人?了解如何使用 Android 开源配件 (AOA) 协议将现有设备或您自己独有的硬件连接到 Android。</p>
+        <p><a href="custom.html">» 自定义配件</a></p>
+ </div>
+
+</div>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/accessories/stylus.html b/zh-cn/devices/accessories/stylus.html
new file mode 100644
index 0000000..da8dd83
--- /dev/null
+++ b/zh-cn/devices/accessories/stylus.html
@@ -0,0 +1,98 @@
+<html devsite><head>
+    <title>触控笔</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 The Android Open Source Project
+
+      Licensed under the Apache License, Version 2.0 (the "License");
+      you may not use this file except in compliance with the License.
+      You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      See the License for the specific language governing permissions and
+      limitations under the License.
+  -->
+
+<p>Android 6.0 及更高版本支持蓝牙 (BT)、蓝牙低功耗 (BTLE) 或 USB 协议的蓝牙触控笔连接适用的标准数据格式。平台会分析触摸输入和触控笔数据之间的时间关系并进行关联,然后提供触控笔数据,以便在前台应用中呈现 MotionEvent。下面几节提供的指南适用于原始设备制造商 (OEM) 设备实现者、触控笔配件制造者和触控笔应用开发者。</p>
+
+<h2 id="guide-partners">面向 OEM 设备实现者的指南</h2>
+<p>要启用蓝牙触控笔支持,OEM 设备实现者必须支持蓝牙(并且应支持 BTLE 以实现更广泛的兼容性)。平台会针对支持的触控笔事件处理数据收集、时间关联操作,以及应用呈现。</p>
+
+<p>目前,Android CTS <strong>不</strong>包括相关测试来确保现有触摸事件 API 支持默认行为。要解决此问题,我们建议您构建触控笔配件或可模拟触控笔事件的模拟器。</p>
+
+<h2 id="guide-creators">面向触控笔配件制造者的指南</h2>
+<p>要在触控笔设备上实现支持,设备实现者必须使用下方所示的触控笔人机接口设备 (HID) 描述符,来描述触控笔数据(压力感应、橡皮擦、侧边按钮、设备 ID 等)的表示方式。触控笔设备会将 HID 信息发送到 Android 移动设备,使平台能够将 HID 数据与触摸屏的触摸数据相关联,以通过 MotionEvent 产生触控笔事件。数据可通过蓝牙 (BT)、蓝牙低功耗 (BTLE) 或 USB 发送。</p>
+
+<h3 id="hid-descriptor">HID 描述符</h3>
+
+<pre class="devsite-click-to-copy">
+UsagePage(Digitizer)
+Usage(Pen)
+Collection(Application)
+    Usage(Stylus)
+    Collection(Logical)
+        Usage(Tip Pressure)
+        Logical Minimum(0)
+        Logical Maximum(1023)
+        Report Count(1)
+        Report Size(10)
+        Input(Data, Variable, Absolute, No Null)
+
+        Usage(Barrel Switch)
+        Usage(Secondary Barrel Switch)
+        Usage(Tip Switch)
+        Usage(Invert)
+        Logical Maximum(1)
+        Report Count(4)
+        Report Size(1)
+        Input(Data, Variable, Absolute, No Null)
+
+        Usage(Transducer Serial Number)
+        Report Count(1)
+        Report Size(128)
+        Feature(Constant, Variable)
+    EndCollection
+EndCollection
+
+unsigned char HID_DESC[] = {
+    0x05, 0x0D, // UsagePage(Digitizer)
+    0x09, 0x02, // Usage(Pen)
+    0xA1, 0x01, // Collection(Application)
+    0x09, 0x20, // Usage(Stylus)
+    0xA1, 0x02, // Collection(Logical)
+    0x09, 0x30, // Usage(Tip Pressure)
+    0x15, 0x00, // Logical Minimum(0)
+    0x26, 0xFF, 0x03, // Logical Maximum(1023)
+    0x95, 0x01, // Report Count(1)
+    0x75, 0x0A, // Report Size(10)
+    0x81, 0x02, // Input(Data, Variable, Absolute, No Null)
+
+    0x09, 0x44, // Usage(Barrel Switch)
+    0x09, 0x5A, // Usage(Secondary Barrel Switch)
+    0x09, 0x42, // Usage(Tip Switch)
+    0x09, 0x3C, // Usage(Invert)
+    0x25, 0x01, // Logical Maximum(1)
+    0x95, 0x04, // Report Count(4)
+    0x75, 0x01, // Report Size(1)
+    0x81, 0x02, // Input(Data, Variable, Absolute, No Null)
+
+    0x09, 0x5B, // Usage(Transducer Serial Number)
+    0x95, 0x01, // Report Count(1)
+    0x75, 0x80, // Report Size(128)
+    0xB1, 0x03, // Feature(Constant, Variable)
+    0xC0, // End Collection
+    0xC0, // End Collection
+}
+</pre>
+
+<h2 id="guidelines-devs">面向触控笔应用开发者的指南</h2>
+<p>Android 6.0 平台会自动处理配对和事件关联操作,因此 Android 6.0 上运行的现有应用和新应用均默认支持蓝牙触控笔。要详细了解蓝牙触控笔 API,请参阅 <a href="http://developer.android.com/about/versions/marshmallow/android-6.0.html#bluetooth-stylus">developer.android.com</a>。
+
+</p></body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/audio/attributes.html b/zh-cn/devices/audio/attributes.html
new file mode 100644
index 0000000..3b28b5f
--- /dev/null
+++ b/zh-cn/devices/audio/attributes.html
@@ -0,0 +1,214 @@
+<html devsite><head>
+    <title>音频属性</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 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>音频播放器支持定义音频系统如何处理指定来源的导向、音量和焦点决策的属性。应用可以将属性附加到音频播放(例如流式传输服务播放的音乐或新电子邮件通知)上,然后将音频源的属性传递给框架,此时音频系统会使用这些属性做出混音决策并将系统状态通知给应用。</p>
+
+<p class="note"><strong>注意</strong>:应用还可以将属性附加到音频录制(例如在视频录制中截取的音频)上,但此功能不会在公共 API 中提供。</p>
+
+<p>在 Android 4.4 及更早版本中,框架仅使用音频流类型做出混音决策。但是,基于流类型做出这些决策太过于限制,无法在多个应用和设备上产生优质输出。例如,在移动设备上,某些应用(例如 Google 地图)基于 STREAM_MUSIC 流类型播放驾驶方向;但是,在采用投影仪模式(例如 Android Auto)的移动设备上,应用不能将驾驶方向与其他媒体流混合在一起播放。</p>
+
+<p>现在,应用可以使用<a href="http://developer.android.com/reference/android/media/AudioAttributes.html">音频属性 API</a> 为音频系统提供有关特定音频源的详细信息:</p>
+
+<ul>
+<li><b>用法</b>。指定播放来源的原因,并控制导向、焦点和音量决策。</li>
+<li><b>内容类型</b>。指定播放来源的类型(音乐、电影、语音、发音、未知)。</li>
+<li><b>标记</b>。指定来源的播放方式。包括对可听性强制执行(一些国家/地区要求发出相机快门提示音)和硬件音频/视频同步的支持。</li>
+</ul>
+
+<p>对于动态处理,应用必须区分电影、音乐和语音内容。关于数据本身的信息也可能非常重要,例如响度和峰值采样值。</p>
+
+<h2 id="using">使用属性</h2>
+
+<p>用法指定了在何种环境中使用相关流类型,并提供有关播放相关声音的原因以及该声音用法的信息。用法信息比流类型信息更丰富,并且使平台或导向策略可以优化音量或导向决策。</p>
+
+<p>为任何实例提供以下用法值之一:</p>
+
+<ul>
+<li><code>USAGE_UNKNOWN</code></li>
+<li><code>USAGE_MEDIA</code></li>
+<li><code>USAGE_VOICE_COMMUNICATION</code></li>
+<li><code>USAGE_VOICE_COMMUNICATION_SIGNALLING</code></li>
+<li><code>USAGE_ALARM</code></li>
+<li><code>USAGE_NOTIFICATION</code></li>
+<li><code>USAGE_NOTIFICATION_RINGTONE</code></li>
+<li><code>USAGE_NOTIFICATION_COMMUNICATION_INSTANT</code></li>
+<li><code>USAGE_NOTIFICATION_COMMUNICATION_DELAYED</code></li>
+<li><code>USAGE_NOTIFICATION_EVENT</code></li>
+<li><code>USAGE_ASSISTANCE_ACCESSIBILITY</code></li>
+<li><code>USAGE_ASSISTANCE_NAVIGATION_GUIDANCE</code></li>
+<li><code>USAGE_ASSISTANCE_SONIFICATION</code></li>
+<li><code>USAGE_GAME</code></li>
+</ul>
+
+<p>音频属性用法值是互斥的。有关示例,请参阅 <code>
+<a href="http://developer.android.com/reference/android/media/AudioAttributes.html#USAGE_MEDIA">
+USAGE_MEDIA</a></code> 和 <code>
+<a href="http://developer.android.com/reference/android/media/AudioAttributes.html#USAGE_ALARM">
+USAGE_ALARM</a></code> 定义;有关异常,请参阅 <code>
+<a href="http://developer.android.com/reference/android/media/AudioAttributes.Builder.html">
+AudioAttributes.Builder</a></code> 定义。</p>
+
+<h2 id="content-type">内容类型</h2>
+
+<p>内容类型定义了声音是什么,并指明内容的常规类别,如电影、语音或提示音/铃声。音频框架使用内容类型信息来选择性地配置音频处理后块。尽管提供内容类型是可选的,但只要内容类型已知,您就应该包含类型信息,例如针对电影流式传输服务使用 <code>CONTENT_TYPE_MOVIE</code>,或针对音乐播放应用使用 <code>CONTENT_TYPE_MUSIC</code>。</p>
+
+<p>为任何实例提供以下内容类型值之一:</p>
+
+<ul>
+<li><code>CONTENT_TYPE_UNKNOWN</code>(默认)</li>
+<li><code>CONTENT_TYPE_MOVIE</code></li>
+<li><code>CONTENT_TYPE_MUSIC</code></li>
+<li><code>CONTENT_TYPE_SONIFICATION</code></li>
+<li><code>CONTENT_TYPE_SPEECH</code></li>
+</ul>
+
+<p>音频属性内容类型值是互斥的。有关内容类型的详细信息,请参阅<a href="http://developer.android.com/reference/android/media/AudioAttributes.html">音频属性 API</a>。</p>
+
+<h2 id="flags">标记</h2>
+
+<p>标记会指定音频框架如何对音频播放应用效果。请为一个实例提供以下一个或多个标记:</p>
+
+<ul>
+<li><code>FLAG_AUDIBILITY_ENFORCED</code>。请求系统确保声音的可听性。用于满足旧版 <code>STREAM_SYSTEM_ENFORCED</code> 的需求(如强制要求发出相机快门提示音)。</li>
+<li><code>HW_AV_SYNC</code>。请求系统选择支持硬件 A/V 同步的输出流。</li>
+</ul>
+
+<p>音频属性标记是非专有的(可以组合使用)。要详细了解这些标记,请参阅<a href="http://developer.android.com/reference/android/media/AudioAttributes.html">音频属性 API</a>。</p>
+
+<h2 id="example">示例</h2>
+
+<p>在此示例中,AudioAttributes.Builder 定义了一个新的 AudioTrack 实例将使用的音频属性:</p>
+
+<pre class="devsite-click-to-copy">
+AudioTrack myTrack = new AudioTrack(
+  new AudioAttributes.Builder()
+ .setUsage(AudioAttributes.USAGE_MEDIA)
+    .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
+    .build(),
+  myFormat, myBuffSize, AudioTrack.MODE_STREAM, mySession);
+</pre>
+
+<h2 id="compatibility">兼容性</h2>
+
+<p>应用开发者在为 Android 5.0 创建或更新应用时应使用音频属性。但是,应用并非必须要利用这些属性;它们可以仅处理旧版流类型,或者一直不了解属性(例如对其播放的内容一无所知的常规媒体播放器)。</p>
+
+<p>在此类情况下,框架通过自动将旧版音频流类型转换为音频属性,保持对旧设备和 Android 版本的向后兼容性。但是,框架不会针对各个设备、制造商或 Android 版本强制要求或保证具备这种映射。</p>
+
+<p>兼容性映射:</p>
+
+<table>
+<tbody><tr>
+  <th>Android 5.0</th>
+  <th>Android 4.4 及更早版本</th>
+</tr>
+<tr>
+  <td>
+  <code>CONTENT_TYPE_SPEECH</code><br />
+  <code>USAGE_VOICE_COMMUNICATION</code>
+  </td>
+  <td>
+  <code>STREAM_VOICE_CALL</code>
+  </td>
+</tr>
+<tr>
+  <td>
+  <code>CONTENT_TYPE_SONIFICATION</code><br />
+  <code>USAGE_ASSISTANCE_SONIFICATION</code>
+  </td>
+  <td>
+  <code>STREAM_SYSTEM</code>
+  </td>
+</tr>
+<tr>
+  <td>
+  <code>CONTENT_TYPE_SONIFICATION</code><br />
+  <code>USAGE_NOTIFICATION_RINGTONE</code>
+  </td>
+  <td>
+  <code>STREAM_RING</code>
+  </td>
+</tr>
+<tr>
+  <td>
+  <code>CONTENT_TYPE_MUSIC</code><br />
+  <code>USAGE_UNKNOWN</code><br />
+  <code>USAGE_MEDIA</code><br />
+  <code>USAGE_GAME</code><br />
+  <code>USAGE_ASSISTANCE_ACCESSIBILITY</code><br />
+  <code>USAGE_ASSISTANCE_NAVIGATION_GUIDANCE</code>
+  </td>
+  <td>
+  <code>STREAM_MUSIC</code>
+  </td>
+</tr>
+<tr>
+  <td>
+  <code>CONTENT_TYPE_SONIFICATION</code><br />
+  <code>USAGE_ALARM</code>
+  </td>
+  <td>
+  <code>STREAM_ALARM</code>
+  </td>
+</tr>
+<tr>
+  <td>
+  <code>CONTENT_TYPE_SONIFICATION</code><br />
+  <code>USAGE_NOTIFICATION</code><br />
+  <code>USAGE_NOTIFICATION_COMMUNICATION_REQUEST</code><br />
+  <code>USAGE_NOTIFICATION_COMMUNICATION_INSTANT</code><br />
+  <code>USAGE_NOTIFICATION_COMMUNICATION_DELAYED</code><br />
+  <code>USAGE_NOTIFICATION_EVENT</code>
+  </td>
+  <td>
+  <code>STREAM_NOTIFICATION</code>
+  </td>
+</tr>
+<tr>
+  <td>
+  <code>CONTENT_TYPE_SPEECH</code>
+  </td>
+  <td>
+  (@hide)<code> STREAM_BLUETOOTH_SCO</code>
+  </td>
+</tr>
+<tr>
+  <td>
+  <code>FLAG_AUDIBILITY_ENFORCED</code>
+  </td>
+  <td>
+  (@hide)<code> STREAM_SYSTEM_ENFORCED</code>
+  </td>
+</tr>
+<tr>
+  <td>
+  <code>CONTENT_TYPE_SONIFICATION</code><br />
+  <code>USAGE_VOICE_COMMUNICATION_SIGNALLING</code>
+  </td>
+  <td>
+  (@hide)<code> STREAM_DTMF</code>
+  </td>
+</tr>
+</tbody></table>
+
+<p class="note"><strong>注意</strong>:@hide 流在框架内部使用,不是公共 API 的一部分。</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/audio/avoiding_pi.html b/zh-cn/devices/audio/avoiding_pi.html
new file mode 100644
index 0000000..f3dd959
--- /dev/null
+++ b/zh-cn/devices/audio/avoiding_pi.html
@@ -0,0 +1,224 @@
+<html devsite><head>
+    <title>避免优先级倒置</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 The Android Open Source Project
+
+      Licensed under the Apache License, Version 2.0 (the "License");
+      you may not use this file except in compliance with the License.
+      You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      See the License for the specific language governing permissions and
+      limitations under the License.
+  -->
+
+<p>
+本文介绍了 Android 的音频系统如何尝试避免优先级倒置,还重点介绍了您可以使用的技术。
+</p>
+
+<p>
+对于高性能音频应用的开发者、原始设备制造商 (OEM) 和要实现音频 HAL 的 SoC 提供商而言,这些技术可能很有用。请注意,实现这些技术不能保证一定不会出现错误或其他故障,尤其在音频环境之外使用时。使用不同的技术,获得的结果可能也会不同,您需要自己进行评估和测试。
+</p>
+
+<h2 id="background">背景</h2>
+
+<p>
+Android AudioFlinger 音频服务器和 AudioTrack/AudioRecord 客户端实现正在进行架构调整,以缩短延迟时间。这项工作从 Android 4.1 开始,在 4.2、4.3、4.4 和 5.0 中得到了进一步改进。
+</p>
+
+<p>
+为了缩短延迟时间,需要对整个系统进行大量更改。其中一项重要更改是采用预测性更高的调度策略将 CPU 资源分配给对时间要求严格的线程。可靠的调度可减小音频缓冲区的大小和数目,同时仍可避免欠载和溢出。
+</p>
+
+<h2 id="priorityInversion">优先级倒置</h2>
+
+<p>
+<a href="http://en.wikipedia.org/wiki/Priority_inversion">优先级倒置</a>是实时系统的一种典型故障模式,在这种模式下,优先级较高的任务会因等待优先级较低的任务释放<a href="http://en.wikipedia.org/wiki/Mutual_exclusion">互斥</a>(保护的共享状态)等资源而无限时受阻。
+</p>
+
+<p>
+在音频系统中,如果使用环形缓冲区或其在响应命令时延迟,优先级倒置通常表现为音频<a href="http://en.wikipedia.org/wiki/Glitch">错误</a>(咔嗒声、爆裂声、音频丢失)和<a href="http://en.wikipedia.org/wiki/Max_Headroom_(character)">音频重复</a>。
+</p>
+
+<p>
+优先级倒置的常见解决方法是增加音频缓冲区大小。不过,这种方法会增加延迟时间,仅仅将问题隐藏,而非解决问题。最好的方法是了解并防止优先级倒置,如下所示。
+</p>
+
+<p>
+在 Android 音频实现中,优先级倒置最有可能发生在以下位置。因此,您应该重点关注这些位置:
+</p>
+
+<ul>
+
+<li>
+AudioFlinger 中的常规混合器线程和快速混合器线程之间
+</li>
+
+<li>
+快速 AudioTrack 的应用回调线程和快速混合器线程之间(它们的优先级都较高,但略有不同)
+</li>
+
+<li>
+快速 AudioRecord 的应用回调线程和快速捕获线程之间(与上一种情况类似)
+</li>
+
+<li>
+在音频硬件抽象层 (HAL) 实现(例如用于电话或回声消除的实现)中
+</li>
+
+<li>
+在内核的音频驱动程序中
+</li>
+
+<li>
+AudioTrack 或 AudioRecord 回调线程和其他应用线程(这不在我们的控制范围内)之间
+</li>
+
+</ul>
+
+<h2 id="commonSolutions">常用解决方法</h2>
+
+<p>
+一般采用的解决方法包括:
+</p>
+
+<ul>
+
+<li>
+停用中断
+</li>
+
+<li>
+优先级继承互斥
+</li>
+
+</ul>
+
+<p>
+停用中断在 Linux 用户空间中不可行,且不适用于对称多处理器 (SMP)。
+</p>
+
+<p>
+优先级继承 <a href="http://en.wikipedia.org/wiki/Futex">futex</a>(快速用户空间互斥)在 Linux 内核中可用,但目前并未由 Android C 运行时库 <a href="http://en.wikipedia.org/wiki/Bionic_(software)">Bionic</a> 采用。由于它们的负载相对较重,且依赖于可信客户端,因此不用于音频系统中。
+</p>
+
+<h2 id="androidTechniques">Android 使用的技术</h2>
+
+<p>
+实验从“尝试锁定”(try lock) 和超时锁定开始。它们是互斥锁定操作的非阻塞和有界阻塞变体。尝试锁定和超时锁定的效果相当不错,但容易受到几个罕见故障模式的影响:如果客户端繁忙,则不能保证服务器一定能够访问共享状态;如果一长系列不相关的锁定都已超时,则累积的超时时间可能会过长。
+</p>
+
+<p>
+我们还使用<a href="http://en.wikipedia.org/wiki/Linearizability">原子操作</a>,例如:
+</p>
+
+<ul>
+<li>递增</li>
+<li>按位“或”</li>
+<li>按位“和”</li>
+</ul>
+
+<p>
+所有这些操作均返回之前的值,并包含必要的 SMP 屏障。缺点在于它们可能需要无限次重试。在实践中,我们发现重试并不是问题。
+</p>
+
+<p class="note"><strong>注意</strong>:原子操作及其与内存屏障的互动遭到非常严重的误解和误用。我们在此处提供这些方法,是为了提供完整的信息;不过,建议您同时阅读 <a href="https://developer.android.com/training/articles/smp.html">SMP Primer for Android</a> 这篇文章,以了解更多信息。
+</p>
+
+<p>
+我们仍然保有和使用上述大多数工具,并在最近添加了以下技术:
+</p>
+
+<ul>
+
+<li>
+针对数据使用非阻塞单读取器单写入器 <a href="http://en.wikipedia.org/wiki/Circular_buffer">FIFO 队列</a>。
+</li>
+
+<li>
+在高优先级和低优先级模块之间尝试“复制”状态而非“共享”状态。<i></i><i></i>
+</li>
+
+<li>
+如果确实需要共享状态,请将状态的大小上限设为一个<a href="http://en.wikipedia.org/wiki/Word_(computer_architecture)">字</a>,在不重试的情况下,可以在单个总线操作中通过原子方式访问该状态。
+</li>
+
+<li>
+对于复杂的多字状态,请使用状态队列。状态队列基本上只是用于状态(而非数据)的非阻塞单读取器单写入器 FIFO 队列,写入器将相邻推送收成单个推送这一情况除外。
+</li>
+
+<li>
+注意<a href="http://en.wikipedia.org/wiki/Memory_barrier">内存屏障</a>,以保证 SMP 的准确性。
+</li>
+
+<li>
+<a href="http://en.wikipedia.org/wiki/Trust,_but_verify">信任,但要验证</a>。在进程之间共享“状态”时,请勿假定状态的格式正确无误。<i></i>例如,检查索引是否在范围内。在同一个进程中的线程之间,以及在相互信任的进程(通常具有相同的 UID)之间,不需要进行验证。此外,也无需验证共享的“数据”,例如出现非继发性损坏的 PCM 音频。<i></i>
+</li>
+
+</ul>
+
+<h2 id="nonBlockingAlgorithms">非阻塞算法</h2>
+
+<p>
+<a href="http://en.wikipedia.org/wiki/Non-blocking_algorithm">非阻塞算法</a>是我们最近一直在研究的一项内容。不过,除了单读取器单写入器 FIFO 队列之外,我们发现此类算法复杂且容易出错。
+</p>
+
+<p>
+从 Android 4.2 开始,您可以在以下位置找到我们的非阻塞单读取器/写入器类:
+</p>
+
+<ul>
+
+<li>
+frameworks/av/include/media/nbaio/
+</li>
+
+<li>
+frameworks/av/media/libnbaio/
+</li>
+
+<li>
+frameworks/av/services/audioflinger/StateQueue*
+</li>
+
+</ul>
+
+<p>
+它们是专为 AudioFlinger 设计的,并不通用。非阻塞算法因其难以调试而臭名昭著。您可以将此代码视为一种模型。不过请注意,非阻塞算法可能会出现错误,且不能保证这些类一定适合用于其他用途。
+</p>
+
+<p>
+对于开发者来说,应该更新部分示例 OpenSL ES 应用代码,以使用非阻塞算法或参照非 Android 开放源代码库。
+</p>
+
+<p>
+我们发布了一个示例非阻塞 FIFO 实现,该实现专为应用代码设计。请在平台源目录 <code>frameworks/av/audio_utils</code> 中查看以下文件:
+</p>
+<ul>
+  <li><a href="https://android.googlesource.com/platform/system/media/+/master/audio_utils/include/audio_utils/fifo.h">include/audio_utils/fifo.h</a></li>
+  <li><a href="https://android.googlesource.com/platform/system/media/+/master/audio_utils/fifo.c">fifo.c</a></li>
+  <li><a href="https://android.googlesource.com/platform/system/media/+/master/audio_utils/include/audio_utils/roundup.h">include/audio_utils/roundup.h</a></li>
+  <li><a href="https://android.googlesource.com/platform/system/media/+/master/audio_utils/roundup.c">roundup.c</a></li>
+</ul>
+
+<h2 id="tools">工具</h2>
+
+<p>
+据我们所知,目前没有用于找出优先级倒置(尤其是在优先级倒置发生之前)的自动工具。一些研究型静态代码分析工具如果能够访问整个代码库,就能找出优先级倒置。当然,如果涉及到任意用户代码(这里指应用)或用户代码是一个大型代码库(如 Linux 内核和设备驱动程序),则进行静态分析可能会不切实际。最重要的是,请务必认真阅读代码,并充分理解整个系统和各种交互操作。<a href="http://developer.android.com/tools/help/systrace.html">systrace</a> 和 <code>ps -t -p</code> 等工具有助于在优先级倒置发生后及时发现,但并不会提前告知您。
+</p>
+
+<h2 id="aFinalWord">总结</h2>
+
+<p>
+经过上述讨论后,请不要害怕互斥。一般情况下,互斥会是您的得力助手,例如,在时间不紧急的一般使用情形中正确使用和实现互斥时。但在高优先级任务和低优先级任务之间以及在时间敏感型系统中,互斥更有可能会导致出现问题。
+</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/audio/data_formats.html b/zh-cn/devices/audio/data_formats.html
new file mode 100644
index 0000000..574800a
--- /dev/null
+++ b/zh-cn/devices/audio/data_formats.html
@@ -0,0 +1,305 @@
+<html devsite><head>
+    <title>数据格式</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 The Android Open Source Project
+
+      Licensed under the Apache License, Version 2.0 (the "License");
+      you may not use this file except in compliance with the License.
+      You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      See the License for the specific language governing permissions and
+      limitations under the License.
+  -->
+
+<p>
+Android 在内部使用各种音频<a href="http://en.wikipedia.org/wiki/Data_format">数据格式</a>,并在公共 API、<a href="http://en.wikipedia.org/wiki/Audio_file_format">文件格式</a>和<a href="https://en.wikipedia.org/wiki/Hardware_abstraction">硬件抽象层</a> (HAL) 中公布了其中的一部分。
+</p>
+
+<h2 id="properties">属性</h2>
+
+<p>
+音频数据格式是按其属性进行分类:
+</p>
+
+<dl>
+
+  <dt><a href="https://en.wikipedia.org/wiki/Data_compression">压缩</a></dt>
+  <dd>
+    <a href="http://en.wikipedia.org/wiki/Raw_data">未压缩</a>、<a href="http://en.wikipedia.org/wiki/Lossless_compression">无损压缩</a>或<a href="http://en.wikipedia.org/wiki/Lossy_compression">有损压缩</a>。PCM 是最常见的未压缩音频格式。FLAC 是一种无损压缩格式,而 MP3 和 AAC 是有损压缩格式。
+  </dd>
+
+  <dt><a href="http://en.wikipedia.org/wiki/Audio_bit_depth">位元深度</a></dt>
+  <dd>
+    每个音频样本的有效位数量。
+  </dd>
+
+  <dt><a href="https://en.wikipedia.org/wiki/Sizeof">容器大小</a></dt>
+  <dd>
+    用于存储或传输样本的位数。通常与位元深度相同,但是有时会为了对齐而分配额外的填充位。例如,一个 24 位样本可以包含在一个 32 位字中。
+  </dd>
+
+  <dt><a href="http://en.wikipedia.org/wiki/Data_structure_alignment">对齐方式</a></dt>
+  <dd>
+    如果容器大小与位元深度完全相同,该表示法被称为“打包”。<em></em>否则,表示法为“解包”。<em></em>样本的有效位通常与容器的最左(最高有效)或最右(最低有效)位对齐。<em></em><em></em>通常只有当位元深度不是 <a href="http://en.wikipedia.org/wiki/Power_of_two">2 的幂</a>时,才使用术语“打包”和“解包”。
+  </dd>
+
+  <dt><a href="http://en.wikipedia.org/wiki/Signedness">符号</a></dt>
+  <dd>
+    样本是有符号,还是无符号。
+  </dd>
+
+  <dt>表示法</dt>
+  <dd>
+    定点数或浮点数(见下文)。
+  </dd>
+
+</dl>
+
+<h2 id="fixed">定点数表示法</h2>
+
+<p>
+<a href="http://en.wikipedia.org/wiki/Fixed-point_arithmetic">定点数</a>是未压缩 PCM 音频数据的最常见表示法,特别是对于硬件接口。
+</p>
+
+<p>
+定点数在<a href="https://en.wikipedia.org/wiki/Radix_point">小数点</a>前后具有固定(恒定)位数。我们所有的表示法都使用<a href="https://en.wikipedia.org/wiki/Binary_number">基数 2</a>,所以我们用“位”代替“位数”,用“二进制点”或简单的“点”代替“小数点”。<em></em><em><em></em><em></em><em></em></em>点左边的位是整数部分,点右边的位是<a href="https://en.wikipedia.org/wiki/Fractional_part">小数部分</a>。
+</p>
+
+<p>
+我们之所以用“整数 PCM”,是因为定点数值通常作为整数值进行存储和操作。<em></em>作为定点数的解释是隐含的。
+</p>
+
+<p>
+我们对所有有符号的定点数表示法使用<a href="https://en.wikipedia.org/wiki/Two%27s_complement">二进制补码</a>,因此下列表达式的值可使用一个 <a href="https://en.wikipedia.org/wiki/Least_significant_bit">LSB</a> 来实现:
+</p>
+<pre class="devsite-click-to-copy">
+|largest negative value| = |largest positive value| + 1
+</pre>
+
+<h3 id="q">Q 和 U 标记</h3>
+
+<p>
+有各种<a href="https://en.wikipedia.org/wiki/Fixed-point_arithmetic#Notation">标记</a>用于整数中的定点数表示法。我们使用 <a href="https://en.wikipedia.org/wiki/Q_(number_format)">Q 标记</a>:Qm.n 表示 m 个整数位,n 个小数位。<em></em><em></em><em></em><em></em>“Q”计为一位,尽管值以二进制补码表示。总位数为 m + n + 1。<em></em><em></em>
+</p>
+
+<p>
+Um.n 用于无符号数:m 个整数位和 n 个小数位,并且“U”计为零位。<em></em><em></em><em></em><em></em>总位数为 m + n。<em></em><em></em>
+</p>
+
+<p>
+整数部分可以在最终结果中使用,也可以临时使用。在后一种情况下,构成整数部分的位称为“保护位”。<em></em>保护位允许中间计算溢出,只要最终值在范围内,或者可以限制到范围内。请注意,定点数保护位位于左侧,而用于减少舍入误差的浮点数单元<a href="https://en.wikipedia.org/wiki/Guard_digit">保护位</a>位于右侧。
+</p>
+
+<h2 id="floating">浮点数表示法</h2>
+
+<p>
+<a href="https://en.wikipedia.org/wiki/Floating_point">浮点数</a>是定点数的替代,其中点的位置可以变化。浮点数的主要优点包括:</p>
+
+<ul>
+  <li>更大的<a href="https://en.wikipedia.org/wiki/Headroom_(audio_signal_processing)">余量</a>和<a href="https://en.wikipedia.org/wiki/Dynamic_range">动态范围</a>;在中间计算过程中,浮点数运算能够容许超出标称范围,并且只在最后限制值</li>
+  <li>支持特殊值,如无穷数和 NaN</li>
+  <li>在许多情况下,更易于使用</li>
+</ul>
+
+<p>
+一直以来,浮点数运算比整数或定点数运算慢,但现在只要控制流决策不是基于计算的值,浮点数运算的速度通常会更快。
+</p>
+
+<h2 id="androidFormats">Android 音频格式</h2>
+
+<p>
+主要的 Android 音频格式如下表所列:
+</p>
+
+<table>
+
+<tbody><tr>
+  <th></th>
+  <th colspan="6"><center>标记</center></th>
+</tr>
+
+<tr>
+  <th>属性</th>
+  <th>Q0.15</th>
+  <th>Q0.7 <sup>1</sup></th>
+  <th>Q0.23</th>
+  <th>Q0.31</th>
+  <th>浮点数</th>
+</tr>
+
+<tr>
+  <td>容器<br />位</td>
+  <td>16</td>
+  <td>8</td>
+  <td>24 或 32 <sup>2</sup></td>
+  <td>32</td>
+  <td>32</td>
+</tr>
+
+<tr>
+  <td>有效位<br />包括符号</td>
+  <td>16</td>
+  <td>8</td>
+  <td>24</td>
+  <td>24 或 32 <sup>2</sup></td>
+  <td>25 <sup>3</sup></td>
+</tr>
+
+<tr>
+  <td>余量<br />(以 dB 为单位)</td>
+  <td>0</td>
+  <td>0</td>
+  <td>0</td>
+  <td>0</td>
+  <td>126 <sup>4</sup></td>
+</tr>
+
+<tr>
+  <td>动态范围<br />(以 dB 为单位)</td>
+  <td>90</td>
+  <td>42</td>
+  <td>138</td>
+  <td>138 到 186</td>
+  <td>900 <sup>5</sup></td>
+</tr>
+
+</tbody></table>
+
+<p>
+上述所有定点数格式的标称范围均为 -1.0 至 +1.0 减去一个 LSB。由于采用二进制补码表示法的缘故,负值要比正值多一个。
+</p>
+
+<p>
+脚注:
+</p>
+
+<ol>
+
+<li>
+以上所有格式表示的是有符号的样本值。8 位格式通常称为“无符号”,但实际上是偏差为 <code>0.10000000</code> 的有符号值。
+</li>
+
+<li>
+Q0.23 可以打包成 24 位(三个 8 位字节),或者解包成 32 位。如果解包,则有效位向右对齐到 LSB,以符号扩展填充到 MSB (Q8.23);或向左对齐到 MSB,以零填充到 LSB (Q0.31)。Q0.31 理论上允许多达 32 个有效位,但接受 Q0.31 的硬件接口很少使用所有位。
+</li>
+
+<li>
+单精度浮点数具有 23 个显式位以及一个隐藏位和符号位,因而一共有 25 个有效位。
+<a href="https://en.wikipedia.org/wiki/Denormal_number">非规格化数</a>的有效位要少一些。
+</li>
+
+<li>
+单精度浮点数可以表达高达 ±1.7e + 38 的值,这也是大余量的原因所在。
+</li>
+
+<li>
+所示的动态范围适用于非规格化数一直到最大标称值 ±1.0。请注意,某些特定于架构的浮点数实现(如 <a href="https://en.wikipedia.org/wiki/ARM_architecture#NEON">NEON</a>)不支持非规格化数。
+</li>
+
+</ol>
+
+<h2 id="conversions">转换</h2>
+
+<p>
+本节将讨论各种表示法之间的<a href="https://en.wikipedia.org/wiki/Data_conversion">数据</a>转换。
+</p>
+
+<h3 id="floatConversions">浮点数转换</h3>
+
+<p>
+将值从 Qm.n 格式转换为浮点数:<em></em><em></em>
+</p>
+
+<ol>
+  <li>将值转换为浮点数,就像它是一个整数(通过忽略该点)。</li>
+  <li>乘以 2<sup>-n</sup>。<em></em></li>
+</ol>
+
+<p>
+例如,要将 Q4.27 内部值转换为浮点数,请使用:
+</p>
+<pre class="devsite-click-to-copy">
+float = integer * (2 ^ -27)
+</pre>
+
+<p>
+从浮点数转换为定点数会遵循以下规则:
+</p>
+
+<ul>
+
+<li>
+单精度浮点数的标称范围为 ±1.0,但中间值的完整范围为 ±1.7e+38。外部表示法中的浮点数和定点数之间的转换(例如输出到音频设备)将仅考虑标称范围,对超过该范围的值会进行限制。尤其是,当 +1.0 被转换为定点数格式时,它将被限制为 +1.0 减去一个 LSB。
+</li>
+
+<li>
+非规格化数(次正规数)和 +/- 0.0 在表示法中都允许使用,但在处理过程中可能会静默转换为 0.0。
+</li>
+
+<li>
+无穷数可能会通过操作,或者静默硬限制为 +/- 1.0。通常后者用于转换为定点数格式。
+</li>
+
+<li>
+NaN 行为尚未定义:NaN 可以作为相同的 NaN 传递,也可以转换为默认 NaN;可以静默地硬限制为 +/- 1.0,也可以静默地转换为 0.0,或者导致错误。
+</li>
+
+</ul>
+
+<h3 id="fixedConversion">定点数转换</h3>
+
+<p>
+不同 Qm.n 格式之间的转换会遵循以下规则:<em></em><em></em>
+</p>
+
+<ul>
+
+<li>
+当 m 增加时,用符号扩展左边的整数部分。<em></em>
+</li>
+
+<li>
+当 m 减小时,限制整数部分。<em></em>
+</li>
+
+<li>
+当 n 增加时,用零扩展右边的小数部分。<em></em>
+</li>
+
+<li>
+当 n 减少时,抖动、舍入或截断右侧的多余小数位。<em></em>
+</li>
+
+</ul>
+
+<p>
+例如,要将 Q4.27 值转换为 Q0.15(无抖动或舍入),则将 Q4.27 值右移 12 位,并限制超过 16 位有符号范围的任何结果。这样将对齐 Q 表示法的点。
+</p>
+
+<p>要将 Q7.24 转换为 Q7.23,可进行带符号除以 2,或者等价地将符号位添加到 Q7.24 整数,然后带符号右移 1。请注意,简单带符号右移不等于带符号除以 2。<em></em>
+</p>
+
+<h3 id="lossyConversion">有损和无损转换</h3>
+
+<p>
+如果转换<a href="https://en.wikipedia.org/wiki/Inverse_function">可逆</a>,则是无损的:从 <code>A</code> 转换到 <code>B</code> 再到 <code>C</code>,那么可以得出 <code>A = C</code>。否则,转换是<a href="https://en.wikipedia.org/wiki/Lossy_data_conversion">有损</a>的。<em></em>
+</p>
+
+<p>
+无损转换允许<a href="https://en.wikipedia.org/wiki/Round-trip_format_conversion">往返格式转换</a>。
+</p>
+
+<p>
+从具有 25 位或更少有效位的定点数表示法转换到浮点数是无损的。从浮点数转换到任何常见的定点数表示法则是有损的。
+</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/audio/debugging.html b/zh-cn/devices/audio/debugging.html
new file mode 100644
index 0000000..e04f6f8
--- /dev/null
+++ b/zh-cn/devices/audio/debugging.html
@@ -0,0 +1,346 @@
+<html devsite><head>
+    <title>音频调试</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 The Android Open Source Project
+
+      Licensed under the Apache License, Version 2.0 (the "License");
+      you may not use this file except in compliance with the License.
+      You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      See the License for the specific language governing permissions and
+      limitations under the License.
+  -->
+
+<p>
+本文介绍了一些与 Android 音频调试有关的提示和技巧。
+</p>
+
+<h2 id="teeSink">Tee Sink</h2>
+
+<p>
+“tee sink”是一种 AudioFlinger 调试功能,仅在定制版本中提供,用于获取最近音频的短片段以供日后分析。这方便我们比较实际播放或录制的内容与预期内容。
+</p>
+
+<p>
+出于隐私考虑,tee sink 在编译时和运行时均默认处于停用状态。要使用 tee sink,您需要通过重新编译以及设置属性来启用它。完成调试后,请务必停用此功能;tee sink 在正式版中不能保持启用状态。
+</p>
+
+<p>
+本节其余部分的说明适用于 Android 5.x 和 6.x。对于 Android 7.x,请将 <code>/data/misc/media</code> 替换为 <code>/data/misc/audioserver</code>。此外,您还必须使用 userdebug 或 eng 版本。如果您使用 userdebug 版本,请使用以下命令停用 verity:</p>
+
+<pre class="devsite-terminal devsite-click-to-copy">
+adb root &amp;&amp; adb disable-verity &amp;&amp; adb reboot
+</pre>
+
+<h3 id="compile">编译时设置</h3>
+
+<ol>
+  <li><code class="devsite-terminal">cd frameworks/av/services/audioflinger</code></li>
+<li>修改 <code>Configuration.h</code>。</li>
+<li>取消注释 <code>#define TEE_SINK</code>。</li>
+<li>重新编译 <code>libaudioflinger.so</code>。</li>
+<li><code class="devsite-terminal">adb root</code></li>
+<li><code class="devsite-terminal">adb remount</code></li>
+<li>将新的 <code>libaudioflinger.so</code> 推送或同步到设备的 <code>/system/lib</code>。</li>
+</ol>
+
+<h3 id="runtime">运行时设置</h3>
+
+<ol>
+<li><code class="devsite-terminal">adb shell getprop | grep ro.debuggable</code>
+<br />确认输出是:<code>[ro.debuggable]: [1]</code>
+</li>
+<li><code class="devsite-terminal">adb shell</code></li>
+<li><code class="devsite-terminal">ls -ld /data/misc/media</code>
+<br />
+<p>
+确认输出是:</p>
+<pre>
+drwx------ media media ... media
+</pre>
+<p>
+如果目录不存在,请使用如下格式创建:</p>
+<pre class="devsite-click-to-copy">
+<code class="devsite-terminal">mkdir /data/misc/media</code>
+<code class="devsite-terminal">chown media:media /data/misc/media</code>
+</pre>
+</li>
+<li><code class="devsite-terminal">echo af.tee=# &gt; /data/local.prop</code>
+<br />其中 <code>af.tee</code> 值是一个数字,在下文中有所说明。
+</li>
+<li><code class="devsite-terminal">chmod 644 /data/local.prop</code></li>
+<li><code class="devsite-terminal">reboot</code></li>
+</ol>
+
+<h4><code>af.tee</code> 属性的值</h4>
+
+<p>
+<code>af.tee</code> 的值是 0-7 之间的数字,表示多个位的总和(每个功能一个位)。请参阅位于 <code>AudioFlinger.cpp</code> 中的 <code>AudioFlinger::AudioFlinger()</code> 的代码,了解各个位的简短说明:</p>
+<ul>
+<li>1 = 输出</li>
+<li>2 = FastMixer 输出</li>
+<li>4 = 各曲目的 AudioRecord 和 AudioTrack</li>
+</ul>
+
+<p>
+目前还没有针对深度缓冲区和常规混合器的位,不过您可以使用“4”获取类似结果。
+</p>
+
+<h3 id="test">测试和获取数据</h3>
+
+<ol>
+<li>运行您的音频测试。</li>
+<li><code class="devsite-terminal">adb shell dumpsys media.audio_flinger</code></li>
+<li>在 dumpsys 输出中查找如下行:<br />
+<code>tee copied to /data/misc/media/20131010101147_2.wav</code>
+<br />这是一个 PCM .wav 文件。
+</li>
+<li>然后 <code>adb pull</code> 任何感兴趣的 <code>/data/misc/media/*.wav</code> 文件;请注意,曲目专用的转储文件名不会显示在 dumpsys 输出中,但仍会在曲目关闭后保存到 <code>/data/misc/media</code>。
+</li>
+<li>在与其他人分享之前,请先查看转储文件是否涉及隐私权问题。</li>
+</ol>
+
+<h4>建议</h4>
+
+<p>要获取更实用的结果,请尝试以下方法:</p>
+
+<ul>
+<li>停用触摸提示音和按键音,以减少测试输出过程中的中断。</li>
+<li>将所有音量调到最大。</li>
+<li>停用通过麦克风发出声音或录音的应用(如果这些应用与测试无关)。</li>
+<li>曲目专用的转储仅在曲目关闭时保存;您可能需要强制关闭某个应用才能转储其曲目专用数据。</li>
+<li>在测试后立即执行 <code>dumpsys</code>;可用的录制空间是有限的。</li>
+<li>要确保转储文件不会丢失,请定期将其上传到您的主机。您只能保留有限数量的转储文件;达到此数量上限后,系统会移除较旧的转储。</li>
+</ul>
+
+<h3 id="restore">恢复</h3>
+
+<p>
+如上文所述,tee sink 功能不能保持启用状态。要恢复您的版本和设备,请执行以下操作:</p>
+<ol>
+<li>将源代码更改还原到 <code>Configuration.h</code>。</li>
+<li>重新编译 <code>libaudioflinger.so</code>。</li>
+<li>将恢复的 <code>libaudioflinger.so</code> 推送或同步到设备的 <code>/system/lib</code>。
+</li>
+<li><code class="devsite-terminal">adb shell</code></li>
+<li><code class="devsite-terminal">rm /data/local.prop</code></li>
+<li><code class="devsite-terminal">rm /data/misc/media/*.wav</code></li>
+<li><code class="devsite-terminal">reboot</code></li>
+</ol>
+
+<h2 id="mediaLog">media.log</h2>
+
+<h3 id="alogx">ALOGx 宏</h3>
+
+<p>
+Android SDK 中的标准 Java 语言 Logging API 是 <a href="http://developer.android.com/reference/android/util/Log.html">android.util.Log</a>。
+</p>
+
+<p>
+Android NDK 中的对应 C 语言 API 是 <code>&lt;android/log.h&gt;</code> 中声明的 <code>__android_log_print</code>。
+</p>
+
+<p>
+在 Android 框架的原生部分,我们倾向于使用名为 <code>ALOGE</code>、<code>ALOGW</code>、<code>ALOGI</code>、<code>ALOGV</code> 等的宏。这些宏会在 <code>&lt;utils/Log.h&gt;</code> 中声明,在本文中,我们将它们统称为 <code>ALOGx</code>。
+</p>
+
+<p>
+由于所有这些 API 均易于使用和理解,因此在整个 Android 平台中得到了广泛应用。尤其是 <code>mediaserver</code> 进程(其中包括 AudioFlinger 声音服务器),它使用了大量 <code>ALOGx</code>。
+</p>
+
+<p>
+不过,<code>ALOGx</code> 和相关项也存在一些限制:</p>
+
+<ul>
+<li>
+它们容易受到“日志垃圾”的影响:日志缓冲区是一种共享资源,因此容易因不相关的日志条目而溢出,进而导致信息缺失。默认情况下,<code>ALOGV</code> 变量在编译时处于停用状态。但是,毋庸置疑,如果启用该变量,则会导致日志垃圾产生。
+</li>
+<li>
+底层内核系统调用会出现阻塞,从而可能导致优先级倒置、测量干扰和不准确性。对于 <code>FastMixer</code> 和 <code>FastCapture</code> 等具有时效性的线程来说,这是需要特别关注的问题。
+</li>
+<li>
+如果出于减少日志垃圾的目的而停用特定日志,则会丢失该日志本应捕获的所有信息。当明确了特定日志本该是有意义的日志后,已不可能以追溯方式启用它。<i></i>
+</li>
+</ul>
+
+<h3 id="nblog">NBLOG、media.log 和 MediaLogService</h3>
+
+<p>
+<code>NBLOG</code> API 和关联的 <code>media.log</code> 进程以及 <code>MediaLogService</code> 服务共同形成较新的媒体日志记录系统,专为解决上述问题而设计。我们将使用术语“media.log”来泛指所有这三个元素。但是严格来说,<code>NBLOG</code> 是 C++ Logging API、<code>media.log</code> 是 Linux 进程名称,而 <code>MediaLogService</code> 是用于检查日志的 Android Binder 服务。
+</p>
+
+<p>
+<code>media.log</code>“时间轴”是一系列相对排序得到保留的日志条目。按照惯例,每个线程都应该使用其自己的时间轴。
+</p>
+
+<h3 id="benefits">优势</h3>
+
+<p>
+<code>media.log</code> 系统的优势在于:
+</p>
+<ul>
+<li>除非需要,否则它不会在主日志中产生垃圾内容。</li>
+<li>即使在 <code>mediaserver</code> 崩溃或中断时,也可以对其进行检查。</li>
+<li>在每个时间轴均是非阻塞的。</li>
+<li>对性能的干扰较小(当然完全不会产生干扰的日志是不存在的)。
+</li>
+</ul>
+
+<h3 id="architecture">架构</h3>
+
+<p>
+以下示意图展示了在引入 <code>media.log</code> 之前,<code>mediaserver</code> 进程和 <code>init</code> 进程之间的关系:</p>
+<img src="images/medialog_before.png" alt="引入 media.log 前的架构" id="figure1"/>
+<p class="img-caption">
+  <strong>图 1. </strong> 引入 media.log 前的架构</p>
+
+<p>
+值得注意的几点是:</p>
+<ul>
+<li><code>init</code> 会派生并执行 <code>mediaserver</code>。</li>
+<li><code>init</code> 可检测到 <code>mediaserver</code> 故障,并根据需要重新派生。</li>
+<li><code>ALOGx</code> 记录不会显示。</li>
+</ul>
+
+<p>
+以下示意图展示了将 <code>media.log</code> 添加到架构之后组件之间的新关系:</p>
+<img src="images/medialog_after.png" alt="添加 media.log 后的架构" id="figure2"/>
+<p class="img-caption">
+  <strong>图 2. </strong> 添加 media.log 后的架构</p>
+
+<p>
+重要变化:</p>
+
+<ul>
+
+<li>
+客户端使用 <code>NBLOG</code> API 构建日志条目,并将它们附加到共享内存中的环形缓冲区。
+</li>
+
+<li>
+<code>MediaLogService</code> 可以随时转储循环缓冲区的内容。
+</li>
+
+<li>
+环形缓冲区的设计方式使其具有以下特点:任何共享内存损坏都不会导致 <code>MediaLogService</code> 崩溃,并且仍然能够转储尽可能多的不受损坏影响的缓冲区内容。
+</li>
+
+<li>
+无论是写入新条目还是读取现有条目,环形缓冲区都是非阻塞和无锁定的。
+</li>
+
+<li>
+无需内核系统调用即可对环形缓冲区(可选时间戳除外)执行写入或读取操作。
+</li>
+
+</ul>
+
+<h4>使用范围</h4>
+
+<p>
+自 Android 4.4 起,AudioFlinger 中只有几个日志点使用 <code>media.log</code> 系统。虽然新 API 不像 <code>ALOGx</code> 那样易于使用,但也不是特别难用。我们建议您学习如何使用新的日志记录系统,以便应对必须使用新系统的情况。具体而言,建议您针对必须频繁、定期且无阻塞运行的 AudioFlinger 线程(例如 <code>FastMixer</code> 和 <code>FastCapture</code> 线程)使用新系统。
+</p>
+
+<h3 id="how">使用方法</h3>
+
+<h4>添加日志</h4>
+
+<p>
+首先,您需要将日志添加到代码中。
+</p>
+
+<p>
+在 <code>FastMixer</code> 和 <code>FastCapture</code> 线程中,请使用如下代码:
+</p>
+<pre class="devsite-click-to-copy">
+logWriter-&gt;log("string");
+logWriter-&gt;logf("format", parameters);
+logWriter-&gt;logTimestamp();
+</pre>
+<p>
+由于该 <code>NBLog</code> 时间轴仅供 <code>FastMixer</code> 和 <code>FastCapture</code> 线程使用,因此不需要互斥。
+</p>
+
+<p>
+在其他 AudioFlinger 线程中,请使用 <code>mNBLogWriter</code>:
+</p>
+<pre class="devsite-click-to-copy">
+mNBLogWriter-&gt;log("string");
+mNBLogWriter-&gt;logf("format", parameters);
+mNBLogWriter-&gt;logTimestamp();
+</pre>
+<p>
+对于除 <code>FastMixer</code> 和 <code>FastCapture</code> 之外的线程,线程的 <code>NBLog</code> 时间轴既可以由线程本身使用,也可由 binder 操作使用。由于 <code>NBLog::Writer</code> 不会按时间轴提供任何隐式互斥,因此请确保所有日志都发生在线程的互斥 <code>mLock</code> 所在的上下文中。
+</p>
+
+<p>
+添加日志后,请重新编译 AudioFlinger。
+</p>
+
+<p class="caution"><strong>注意</strong>:由于时间轴的设计略去了互斥,因此每个线程需要有单独的 <code>NBLog::Writer</code> 时间轴,以确保线程安全性。如果您希望多个线程使用同一时间轴,则可以使用现有的互斥进行保护(如上文中有关 <code>mLock</code> 的部分所述)。或者您也可以使用 <code>NBLog::LockedWriter</code> 封装容器而非 <code>NBLog::Writer</code>。不过,这会使该 API 的以下这项主要优势无效:非阻塞行为。
+</p>
+
+<p>完整的 <code>NBLog</code> API 位于 <code>frameworks/av/include/media/nbaio/NBLog.h</code>。
+</p>
+
+<h4>启用 media.log</h4>
+
+<p>
+<code>media.log</code> 默认处于停用状态,仅当属性 <code>ro.test_harness</code> 为 <code>1</code> 时才会启用。启用方式如下:</p>
+
+<pre class="devsite-click-to-copy">
+<code class="devsite-terminal">adb root</code>
+<code class="devsite-terminal">adb shell</code>
+<code class="devsite-terminal">echo ro.test_harness=1 &gt; /data/local.prop</code>
+<code class="devsite-terminal">chmod 644 /data/local.prop</code>
+<code class="devsite-terminal">reboot</code>
+</pre>
+
+<p>
+重新启动时会丢失连接,因此:
+</p>
+<pre class="devsite-terminal devsite-click-to-copy">
+adb shell
+</pre>
+
+<code>ps media</code> 命令现在将显示两个进程:
+<ul>
+<li>media.log</li>
+<li>mediaserver</li>
+</ul>
+<p>
+请留意 <code>mediaserver</code> 的进程 ID,以供稍后使用。
+</p>
+
+<h4>显示时间轴</h4>
+
+<p>
+您随时可以手动请求日志转储。此命令会显示来自最近的所有活动中时间轴的日志,然后将其清除:</p>
+<pre class="devsite-terminal devsite-click-to-copy">
+dumpsys media.log
+</pre>
+
+<p>
+请注意,根据设计,时间轴是独立的,没有用于合并时间轴的功能。
+</p>
+
+<h4>在出现 mediaserver 故障后恢复日志</h4>
+
+<p>
+现在尝试终止 <code>mediaserver</code> 进程:<code>kill -9 #</code>;其中 # 是之前提到的进程 ID。您应该在主 <code>logcat</code> 的 <code>media.log</code> 中看到一个转储,其中会显示导致最终崩溃的所有日志。
+</p>
+
+<pre class="devsite-terminal devsite-click-to-copy">
+dumpsys media.log
+</pre>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/audio/implement-policy.html b/zh-cn/devices/audio/implement-policy.html
new file mode 100644
index 0000000..2a2aeaa
--- /dev/null
+++ b/zh-cn/devices/audio/implement-policy.html
@@ -0,0 +1,325 @@
+<html devsite><head>
+    <title>配置音频政策</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 The Android Open Source Project
+
+      Licensed under the Apache License, Version 2.0 (the "License");
+      you may not use this file except in compliance with the License.
+      You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      See the License for the specific language governing permissions and
+      limitations under the License.
+  -->
+
+<p>Android 7.0 引入了一种新的音频政策配置文件格式 (XML),用于描述音频拓扑。</p>
+
+<p>以前的 Android 版本需要使用 <code>device/&lt;company&gt;/&lt;device&gt;/audio/audio_policy.conf</code> 来声明您产品上存在的音频设备(您可以在 <code>device/samsung/tuna/audio/audio_policy.conf</code> 中查看此文件针对 Galaxy Nexus 音频硬件的示例)。但是,.conf 是一种简单的专有格式,有较大的局限性,无法描述电视和汽车等应用的复杂拓扑。</p>
+
+<p>Android 7.0 弃用了 <code>audio_policy.conf</code>,并增加了对使用 XML 文件格式来定义音频拓扑的支持,这种文件格式更通俗易懂,具有多种编辑和解析工具,并且足够灵活,可以描述复杂的音频拓扑。</p>
+
+<p .="" class="note"><strong>注意</strong>:Android 7.0 仍支持使用 <code>audio_policy.conf</code>;默认使用这种旧版格式。要使用 XML 文件格式,需要在设备 Makefile 中添加构建选项 <code>USE_XML_AUDIO_POLICY_CONF
+:= 1</code>。</p>
+
+<h2 id="xml_advantages">XML 格式的优势</h2>
+<p>与在 .conf 文件中一样,新的 XML 文件支持定义输出输入流配置文件、可用于播放和捕获的设备以及音频属性的数量和类型。此外,XML 格式还提供以下增强功能:</p>
+
+<ul>
+<li>音频配置文件目前的结构类似于 HDMI 简单音频描述符,支持每种音频格式使用一组不同的采样率/声道掩码。</li>
+<li>设备和流之间所有可能连接的显式定义。以前,借助隐式规则,可以使连接到同一 HAL 模块的所有设备互连,从而阻止音频政策控制使用音频补丁程序 API 请求的连接。现在,在 XML 格式中,拓扑描述定义了连接限制。</li>
+<li>对“包含”的支持可避免出现重复的标准 A2DP、USB 或重新导向提交定义。<em></em></li>
+<li>可自定义的音量曲线。以前,音量表采用硬编码格式。在 XML 格式中,音量表通过描述来定义,并且可自定义。</li>
+</ul>
+
+<p><code>frameworks/av/services/audiopolicy/config/audio_policy_configuration.xml</code> 中的模板展示了很多已在使用的上述功能。</p>
+
+<h2 id="xml_file_format">文件格式和位置</h2>
+<p>新的音频政策配置文件是 <code>audio_policy_configuration.xml</code>,位于 <code>/system/etc</code>。要查看采用新的 XML 文件格式的简单音频政策配置,请查看以下示例。</p>
+
+  <section class="expandable">
+    <h4 class="showalways">显示音频政策示例</h4>
+<pre class="devsite-click-to-copy">
+&lt;?xml version="1.0" encoding="UTF-8" standalone="yes"?&gt;
+&lt;audioPolicyConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude"&gt;
+    &lt;globalConfiguration speaker_drc_enabled="true"/&gt;
+    &lt;modules&gt;
+        &lt;module name="primary" halVersion="3.0"&gt;
+            &lt;attachedDevices&gt;
+                &lt;item&gt;Speaker&lt;/item&gt;
+                &lt;item&gt;Earpiece&lt;/item&gt;
+                &lt;item&gt;Built-In Mic&lt;/item&gt;
+            &lt;/attachedDevices&gt;
+            &lt;defaultOutputDevice&gt;Speaker&lt;/defaultOutputDevice&gt;
+            &lt;mixPorts&gt;
+                &lt;mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY"&gt;
+                    &lt;profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/&gt;
+                &lt;/mixPort&gt;
+                &lt;mixPort name="primary input" role="sink"&gt;
+                    &lt;profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000,16000,48000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO"/&gt;
+                &lt;/mixPort&gt;
+            &lt;/mixPorts&gt;
+            &lt;devicePorts&gt;
+                &lt;devicePort tagName="Earpiece" type="AUDIO_DEVICE_OUT_EARPIECE" role="sink"&gt;
+                   &lt;profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                            samplingRates="48000" channelMasks="AUDIO_CHANNEL_IN_MONO"/&gt;
+                &lt;/devicePort&gt;
+                &lt;devicePort tagName="Speaker" role="sink" type="AUDIO_DEVICE_OUT_SPEAKER" address=""&gt;
+                    &lt;profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/&gt;
+                &lt;/devicePort&gt;
+                &lt;devicePort tagName="Wired Headset" type="AUDIO_DEVICE_OUT_WIRED_HEADSET" role="sink"&gt;
+                    &lt;profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/&gt;
+                &lt;/devicePort&gt;
+                &lt;devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source"&gt;
+                    &lt;profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000,16000,48000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO"/&gt;
+                &lt;/devicePort&gt;
+                &lt;devicePort tagName="Wired Headset Mic" type="AUDIO_DEVICE_IN_WIRED_HEADSET" role="source"&gt;
+                    &lt;profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000,16000,48000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO"/&gt;
+                &lt;/devicePort&gt;
+            &lt;/devicePorts&gt;
+            &lt;routes&gt;
+                &lt;route type="mix" sink="Earpiece" sources="primary output"/&gt;
+                &lt;route type="mix" sink="Speaker" sources="primary output"/&gt;
+                &lt;route type="mix" sink="Wired Headset" sources="primary output"/&gt;
+                &lt;route type="mix" sink="primary input" sources="Built-In Mic,Wired Headset Mic"/&gt;
+            &lt;/routes&gt;
+        &lt;/module&gt;
+        &lt;xi:include href="a2dp_audio_policy_configuration.xml"/&gt;
+    &lt;/modules&gt;
+
+    &lt;xi:include href="audio_policy_volumes.xml"/&gt;
+    &lt;xi:include href="default_volume_tables.xml"/&gt;
+&lt;/audioPolicyConfiguration&gt;
+</pre></section>
+
+<p>顶层结构中包含与各个音频 HAL 硬件模块对应的模块,其中每个模块都有一系列混合端口、设备端口和导向:</p>
+<ul>
+<li><strong>混合端口</strong>描述了可以在音频 HAL 处打开以供播放和捕获的流的可能配置文件。</li>
+<li><strong>设备端口</strong>描述了可以附上其类型(以及(可选)地址和音频属性,如果相关)的设备。</li>
+<li><strong>导向</strong>(新)现在已从混合端口描述符中分离出来,支持描述从设备到设备或从流到设备的导向。</li>
+</ul>
+
+<p>音量表是定义用于将界面索引转换为音量(以 dB 为单位)的曲线的点的简单列表。单独的包含文件提供默认曲线,但每个对应于指定使用情形和设备类别的曲线都可以被替换。</p>
+
+  <section class="expandable">
+    <h4 class="showalways">显示音量表示例</h4>
+<pre class="devsite-click-to-copy">
+&lt;?xml version="1.0" encoding="UTF-8"?&gt;
+&lt;volumes&gt;
+    &lt;reference name="FULL_SCALE_VOLUME_CURVE"&gt;
+        &lt;point&gt;0,0&lt;/point&gt;
+        &lt;point&gt;100,0&lt;/point&gt;
+    &lt;/reference&gt;
+    &lt;reference name="SILENT_VOLUME_CURVE"&gt;
+        &lt;point&gt;0,-9600&lt;/point&gt;
+        &lt;point&gt;100,-9600&lt;/point&gt;
+    &lt;/reference&gt;
+    &lt;reference name="DEFAULT_VOLUME_CURVE"&gt;
+        &lt;point&gt;1,-4950&lt;/point&gt;
+        &lt;point&gt;33,-3350&lt;/point&gt;
+        &lt;point&gt;66,-1700&lt;/point&gt;
+        &lt;point&gt;100,0&lt;/point&gt;
+    &lt;/reference&gt;
+&lt;/volumes&gt;
+</pre></section>
+
+  <section class="expandable">
+    <h4 class="showalways">显示音量示例</h4>
+<pre class="devsite-click-to-copy">
+&lt;?xml version="1.0" encoding="UTF-8"?&gt;
+&lt;volumes&gt;
+    &lt;volume stream="AUDIO_STREAM_VOICE_CALL" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_VOLUME_CURVE"/&gt;
+    &lt;volume stream="AUDIO_STREAM_VOICE_CALL" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/&gt;
+    &lt;volume stream="AUDIO_STREAM_VOICE_CALL" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/&gt;
+    &lt;volume stream="AUDIO_STREAM_VOICE_CALL" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_VOLUME_CURVE"/&gt;
+
+    &lt;volume stream="AUDIO_STREAM_SYSTEM" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_VOLUME_CURVE"/&gt;
+    &lt;volume stream="AUDIO_STREAM_SYSTEM" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/&gt;
+    &lt;volume stream="AUDIO_STREAM_SYSTEM" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/&gt;
+    &lt;volume stream="AUDIO_STREAM_SYSTEM" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_VOLUME_CURVE"/&gt;
+
+    &lt;volume stream="AUDIO_STREAM_RING" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_VOLUME_CURVE"/&gt;
+    &lt;volume stream="AUDIO_STREAM_RING" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/&gt;
+    &lt;volume stream="AUDIO_STREAM_RING" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/&gt;
+    &lt;volume stream="AUDIO_STREAM_RING" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA"ref="DEFAULT_VOLUME_CURVE"/&gt;
+
+    &lt;volume stream="AUDIO_STREAM_MUSIC" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_VOLUME_CURVE"/&gt;
+    &lt;volume stream="AUDIO_STREAM_MUSIC" deviceCategory="DEVICE_CATEGORY_SPEAKER"&gt;
+        &lt;point&gt;1,-5500&lt;/point&gt;
+        &lt;point&gt;20,-4300&lt;/point&gt;
+        &lt;point&gt;86,-1200&lt;/point&gt;
+        &lt;point&gt;100,0&lt;/point&gt;
+    &lt;/volume&gt;
+    &lt;volume stream="AUDIO_STREAM_MUSIC" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/&gt;
+    &lt;volume stream="AUDIO_STREAM_MUSIC" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_VOLUME_CURVE"/&gt;
+
+    &lt;volume stream="AUDIO_STREAM_ALARM" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_VOLUME_CURVE"/&gt;
+    &lt;volume stream="AUDIO_STREAM_ALARM" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/&gt;
+    &lt;volume stream="AUDIO_STREAM_ALARM" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/&gt;
+    &lt;volume stream="AUDIO_STREAM_ALARM" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_VOLUME_CURVE"/&gt;
+
+    &lt;volume stream="AUDIO_STREAM_NOTIFICATION" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_VOLUME_CURVE"/&gt;
+    &lt;volume stream="AUDIO_STREAM_NOTIFICATION" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/&gt;
+    &lt;volume stream="AUDIO_STREAM_NOTIFICATION" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/&gt;
+    &lt;volume stream="AUDIO_STREAM_NOTIFICATION" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_VOLUME_CURVE"/&gt;
+
+    &lt;volume stream="AUDIO_STREAM_BLUETOOTH_SCO" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_VOLUME_CURVE"/&gt;
+    &lt;volume stream="AUDIO_STREAM_BLUETOOTH_SCO" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/&gt;
+    &lt;volume stream="AUDIO_STREAM_BLUETOOTH_SCO" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/&gt;
+    &lt;volume stream="AUDIO_STREAM_BLUETOOTH_SCO" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_VOLUME_CURVE"/&gt;
+
+    &lt;volume stream="AUDIO_STREAM_ENFORCED_AUDIBLE" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_VOLUME_CURVE"/&gt;
+    &lt;volume stream="AUDIO_STREAM_ENFORCED_AUDIBLE" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/&gt;
+    &lt;volume stream="AUDIO_STREAM_ENFORCED_AUDIBLE" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/&gt;
+    &lt;volume stream="AUDIO_STREAM_ENFORCED_AUDIBLE" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_VOLUME_CURVE"/&gt;
+
+    &lt;volume stream="AUDIO_STREAM_DTMF" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/&gt;
+    &lt;volume stream="AUDIO_STREAM_DTMF" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/&gt;
+    &lt;volume stream="AUDIO_STREAM_DTMF" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/&gt;
+    &lt;volume stream="AUDIO_STREAM_DTMF" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_VOLUME_CURVE"/&gt;
+
+    &lt;volume stream="AUDIO_STREAM_TTS" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="SILENT_VOLUME_CURVE"/&gt;
+    &lt;volume stream="AUDIO_STREAM_TTS" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="FULL_SCALE_VOLUME_CURVE"/&gt;
+    &lt;volume stream="AUDIO_STREAM_TTS" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="SILENT_VOLUME_CURVE"/&gt;
+    &lt;volume stream="AUDIO_STREAM_TTS" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="SILENT_VOLUME_CURVE"/&gt;
+
+    &lt;volume stream="AUDIO_STREAM_ACCESSIBILITY" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_VOLUME_CURVE"/&gt;
+    &lt;volume stream="AUDIO_STREAM_ACCESSIBILITY" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/&gt;
+    &lt;volume stream="AUDIO_STREAM_ACCESSIBILITY" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/&gt;
+    &lt;volume stream="AUDIO_STREAM_ACCESSIBILITY" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_VOLUME_CURVE"/&gt;
+
+    &lt;volume stream="AUDIO_STREAM_REROUTING" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="FULL_SCALE_VOLUME_CURVE"/&gt;
+    &lt;volume stream="AUDIO_STREAM_REROUTING" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="FULL_SCALE_VOLUME_CURVE"/&gt;
+    &lt;volume stream="AUDIO_STREAM_REROUTING" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="FULL_SCALE_VOLUME_CURVE"/&gt;
+    &lt;volume stream="AUDIO_STREAM_REROUTING" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="FULL_SCALE_VOLUME_CURVE"/&gt;
+
+    &lt;volume stream="AUDIO_STREAM_PATCH" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="FULL_SCALE_VOLUME_CURVE"/&gt;
+    &lt;volume stream="AUDIO_STREAM_PATCH" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="FULL_SCALE_VOLUME_CURVE"/&gt;
+    &lt;volume stream="AUDIO_STREAM_PATCH" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="FULL_SCALE_VOLUME_CURVE"/&gt;
+    &lt;volume stream="AUDIO_STREAM_PATCH" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="FULL_SCALE_VOLUME_CURVE"/&gt;
+&lt;/volumes&gt;
+</pre></section>
+
+<h2 id="file_inclusions">文件包含</h2>
+<p>XML 包含 (XInclude) 方法可用于包含位于其他 XML 文件中的音频政策配置信息。所有包含的文件必须遵循上述结构,同时满足以下限制条件:</p>
+<ul>
+<li>文件只能包含顶层元素。</li>
+<li>文件不能包含 Xinclude 元素。</li>
+</ul>
+<p>使用“包含”可避免将标准 Android 开放源代码项目 (AOSP) 音频 HAL 模块配置信息复制到所有音频政策配置文件(这样做容易出错)。我们为以下音频 HAL 提供了标准音频政策配置 xml 文件:</p>
+<ul>
+<li><strong>A2DP</strong>:<code>a2dp_audio_policy_configuration.xml</code></li>
+<li><strong>重新导向子混音</strong>:<code>rsubmix_audio_policy_configuration.xml</code></li>
+<li><strong>USB</strong>:<code>usb_audio_policy_configuration.xml</code></li>
+</ul>
+
+<h2 id="code_reorg">音频政策代码重组</h2>
+<p>Android 7.0 将 <code>AudioPolicyManager.cpp</code> 拆分为多个模块,使其更易于维护,并突出显示可配置的内容。<code>frameworks/av/services/audiopolicy</code> 的新组织包括以下模块:</p>
+
+<table>
+<tbody><tr>
+<th>模块</th>
+<th>说明</th>
+</tr>
+
+<tr>
+<td><code>/managerdefault</code></td>
+<td>包含所有应用通用的常规接口和行为实现。类似于剥离了引擎功能和基本类的 <code>AudioPolicyManager.cpp</code>。</td>
+</tr>
+
+<tr>
+<td><code>/common</code></td>
+<td>定义基本类(例如,输入输出音频流配置文件、音频设备描述符、音频补丁程序、音频端口等的数据结构)。以前,该模块在 <code>AudioPolicyManager.cpp</code> 内定义。</td>
+</tr>
+
+<tr>
+<td><code>/engine</code></td>
+<td><p>实现规则,这些规则定义应将哪些设备和音量用于指定使用情形。该模块会实现标准接口(包含通用部分),例如,为指定的播放或捕获使用情形获取适当的设备,或设置可以改变导向选择的已连接设备或外部状态(即强制使用的调用状态)。</p>
+<p>两种版本(自定义版本和默认版本)中都提供该模块;使用构建选项 <code>USE_CONFIGURABLE_AUDIO_POLICY</code> 进行选择。</p></td>
+</tr>
+
+<tr>
+<td><code>/engineconfigurable</code></td>
+<td>依赖参数框架的政策引擎实现(请参阅下文)。配置基于参数框架,相关政策由 XML 文件定义。</td>
+</tr>
+
+<tr>
+<td><code>/enginedefault</code></td>
+<td>基于以前的 Android 音频政策管理器实现的政策引擎实现。这是默认模块,包含当前 Nexus 和 AOSP 实现对应的硬编码规则。</td>
+</tr>
+
+<tr>
+<td><code>/service</code></td>
+<td>包含 Binder 接口、线程和锁定实现(包含连接框架其余部分的接口)。</td>
+</tr>
+
+</tbody></table>
+
+<h2 id="policy_config">使用参数框架的配置</h2>
+<p>Android 7.0 重组了音频政策代码,使其更易于理解和维护,同时也支持完全由配置文件定义的音频政策。重组和音频政策设计基于 Intel 的参数框架,该框架基于插件和规则,用于处理各种参数。</p>
+
+<p>通过使用新的可配置音频政策,供应商和原始设备制造商 (OEM) 可以:</p>
+<ul>
+<li>用 XML 来描述系统的结构及其参数。</li>
+<li>编写(用 C++ 语言)或重复使用后端(插件)来访问所描述的参数。</li>
+<li>定义(用 XML 或特定于网域的语言)指定参数必须取指定值所依据的条件/规则。</li>
+</ul>
+
+<p>AOSP 中包含使用参数框架的音频政策配置文件示例,路径为:<code>Frameworks/av/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/PolicyConfigurableDomains.xml</code>。有关详情,请参阅介绍<a href="https://github.com/01org/parameter-framework">参数框架</a>和 <a href="http://01org.github.io/parameter-framework/hosting/Android_M_Configurable_Audio_Policy.pdf">Android 可配置音频政策</a>的 Intel 文档。</p>
+
+<h2 id="policy_routing_apis">音频政策导向 API</h2>
+<p>Android 6.0 引入了一个公共 Enumeration and Selection API,位于音频补丁程序/音频端口基础架构之上。借助它,应用开发者可以为连接的音频录制或轨道指明特定设备输出或输入的偏好设置。</p>
+<p>在 Android 7.0 中,Enumeration and Selection API 通过了 CTS 测试的验证,并经过扩展,可导向原生 C/C++ (OpenSL ES) 音频流。原生流的导向仍然由 Java 完成,另外还添加了 <code>AudioRouting</code> 接口,该接口会取代、合并、弃用特定于 <code>AudioTrack</code> 和 <code>AudioRecord</code> 类的显式导向方法。</p>
+
+<p>要详细了解 Enumeration and Selection API,请参阅 <a href="https://developer.android.com/ndk/guides/audio/opensl-for-android.html?hl=fi#configuration-interface">Android 配置接口</a>和 <code>OpenSLES_AndroidConfiguration.h</code>。要详细了解音频导向,请参阅 <a href="https://developer.android.com/reference/android/media/AudioRouting.html">AudioRouting</a>。
+</p>
+
+<h2 id="multichannel">多声道支持</h2>
+
+<p>如果您的硬件和驱动程序通过 HDMI 支持多声道音频,则可以将音频流直接输出到音频硬件(这样可以绕过 AudioFlinger 混音器,也就不会被降混成两个声道)。音频 HAL 必须展示输出流配置文件是否支持多声道音频功能。如果 HAL 展示其功能,则默认的政策管理器会允许通过 HDMI 进行多声道播放。有关实现的详情,请参阅 <code>device/samsung/tuna/audio/audio_hw.c</code>。</p>
+
+<p>要指定您的产品包含多声道音频输出,请修改音频政策配置文件,对产品的多声道输出进行描述。以下示例来自 Galaxy Nexus,其展示了动态声道掩码,这表示音频政策管理器会在连接后查询 HDMI 接收器支持的实际声道掩码。<em></em></p>
+
+<pre class="devsite-click-to-copy">
+audio_hw_modules {
+  primary {
+    outputs {
+        ...
+        hdmi {
+          sampling_rates 44100|48000
+          channel_masks dynamic
+          formats AUDIO_FORMAT_PCM_16_BIT
+          devices AUDIO_DEVICE_OUT_AUX_DIGITAL
+          flags AUDIO_OUTPUT_FLAG_DIRECT
+        }
+        ...
+    }
+    ...
+  }
+  ...
+}
+</pre>
+
+<p>您也可以指定静态声道掩码,例如 <code>AUDIO_CHANNEL_OUT_5POINT1</code>。当把内容发送到不支持多声道音频的音频设备时,AudioFlinger 的混音器会自动将该内容降混成立体声。</p>
+
+<h2 id="codecs">媒体编解码器</h2>
+
+<p>确保针对您的产品正确声明您的硬件和驱动程序支持的音频编解码器。有关详情,请参阅<a href="/devices/media/index.html#expose">将编解码器展示给框架</a>。</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/audio/implement-pre-processing.html b/zh-cn/devices/audio/implement-pre-processing.html
new file mode 100644
index 0000000..6a794c2
--- /dev/null
+++ b/zh-cn/devices/audio/implement-pre-processing.html
@@ -0,0 +1,109 @@
+<html devsite><head>
+    <title>配置预处理效果</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 The Android Open Source Project
+
+      Licensed under the Apache License, Version 2.0 (the "License");
+      you may not use this file except in compliance with the License.
+      You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      See the License for the specific language governing permissions and
+      limitations under the License.
+  -->
+
+<p>Android 平台向 <a href="http://developer.android.com/reference/android/media/audiofx/package-summary.html">audiofx</a> 软件包(可供开发者访问)中支持的设备提供音频效果。例如,Nexus 10 支持以下预处理效果:</p>
+
+<ul>
+<li>
+<a href="http://developer.android.com/reference/android/media/audiofx/AcousticEchoCanceler.html">回声消除</a></li>
+<li>
+<a href="http://developer.android.com/reference/android/media/audiofx/AutomaticGainControl.html">自动增益控制</a></li>
+<li>
+<a href="http://developer.android.com/reference/android/media/audiofx/NoiseSuppressor.html">噪音抑制</a></li>
+</ul>
+
+<h2 id="audiosources">与 AudioSources 配对</h2>
+<p>预处理效果与在其下请求预处理的使用情形模式配对。在 Android 应用的开发过程中,使用情形称为 <code>AudioSource</code>;且应用开发者会要求使用 <code>AudioSource</code> 的抽象,而不是实际的音频硬件设备。Android 音频政策管理器根据特定于产品的规则将 <code>AudioSource</code> 映射到指定的捕获路径配置(设备、增益、预处理等)。我们向开发者提供了以下来源:</p>
+
+<ul>
+<li><code>android.media.MediaRecorder.AudioSource.CAMCORDER</code></li>
+<li><code>android.media.MediaRecorder.AudioSource.VOICE_COMMUNICATION</code></li>
+<li><code>android.media.MediaRecorder.AudioSource.VOICE_CALL</code></li>
+<li><code>android.media.MediaRecorder.AudioSource.VOICE_DOWNLINK</code></li>
+<li><code>android.media.MediaRecorder.AudioSource.VOICE_UPLINK</code></li>
+<li><code>android.media.MediaRecorder.AudioSource.VOICE_RECOGNITION</code></li>
+<li><code>android.media.MediaRecorder.AudioSource.MIC</code></li>
+<li><code>android.media.MediaRecorder.AudioSource.DEFAULT</code></li>
+</ul>
+
+<p>针对各个 <code>AudioSource</code> 请求的默认预处理效果在 <code>/system/etc/audio_effects.conf</code> 文件中指定。要为各个 <code>AudioSource</code> 指定您自己的默认效果,请创建一个 <code>/system/vendor/etc/audio_effects.conf</code> 文件,并指定要开启的预处理效果。有关示例,请参阅 <code>device/samsung/manta/audio_effects.conf</code> 中的 Nexus 10 实现。AudioEffect 实例在创建和销毁时获取和释放会话,因此效果(如响度增强器)能够在整个会话期间持续存在。</p>
+
+<p class="warning"><strong>警告</strong>:对于 <code>VOICE_RECOGNITION</code> 使用情形,请勿启用噪音抑制预处理效果。从此音频来源录制时,该效果应默认处于停用状态,您不得在自己的 audio_effects.conf 文件中启用它。无论该效果处于默认启用状态的原因在于配置文件,还是音频 HAL 实现的默认行为,都将导致设备无法满足<a href="/compatibility/index.html">兼容性要求</a>。</p>
+
+<p>以下示例为 VoIP <code>AudioSource</code> 和摄像机 <code>AudioSource</code> 启用了预处理。通过以这种方式声明 <code>AudioSource</code> 配置,框架会自动向音频 HAL 请求使用这些效果。</p>
+
+<pre class="devsite-click-to-copy">
+pre_processing {
+   voice_communication {
+       aec {}
+       ns {}
+   }
+   camcorder {
+       agc {}
+   }
+}
+</pre>
+
+<h2 id="tuning">来源调谐</h2>
+
+<p><code>AudioSource</code> 调谐对音频增益或音频处理没有明确的要求,但语音识别 (<code>VOICE_RECOGNITION</code>) 除外。语音识别的要求包括:</p>
+
+<ul>
+<li>100Hz 至 4kHz 范围内的平坦频率响应 (+/- 3dB)</li>
+<li>近距离通话配置:90dB SPL 读取值为 2500 的 RMS(16 位样本)</li>
+<li>在 -18dB 至 +12dB 范围内相对于 90dB SPL 的呈线性的电平轨道</li>
+<li>THD &lt; 1%(100Hz 至 4000Hz 范围内的 90dB SPL)</li>
+<li>近超声要求(有关测试,请参阅<a href="/compatibility/cts/near-ultrasound.html">近超声测试</a>):<ul>
+<li>支持 CDD 中第 7.8.3 节中定义的 SUPPORT_PROPERTY_MIC_NEAR_ULTRASOUND。</li>
+<li>支持 44100 或 48000 采样率中的一个,或者两者都支持(无带通或抗混叠滤波器的情况下)。</li>
+</ul></li>
+<li>效果/预处理必须默认处于停用状态。</li>
+</ul>
+
+<p>关于调谐不同来源的不同效果,示例如下:</p>
+
+<ul>
+<li>噪音抑制器<ul>
+<li>调谐 <code>CAMCORDER</code> 的风噪抑制器</li>
+<li>调谐 <code>VOICE_COMMUNICATION</code> 的静态噪音抑制器</li>
+</ul>
+</li>
+<li>自动增益控制<ul>
+<li>调谐 <code>VOICE_COMMUNICATION</code> 和手机主麦克风的近距离通话</li>
+<li>调谐 <code>CAMCORDER</code> 的远距离通话</li>
+</ul>
+</li>
+</ul>
+
+<h2 id="resources">资源</h2>
+
+<p>有关详情,请参阅以下资源:</p>
+
+<ul>
+<li><a href="http://developer.android.com/reference/android/media/audiofx/package-summary.html">audiofx 软件包</a>的相关 Android 文档</li>
+
+<li><a href="http://developer.android.com/reference/android/media/audiofx/NoiseSuppressor.html">噪音抑制音频效果</a>的相关 Android 文档</li>
+
+<li>Nexus 10 的 <code>device/samsung/manta/audio_effects.conf</code> 文件</li>
+</ul>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/audio/implement-shared-library.html b/zh-cn/devices/audio/implement-shared-library.html
new file mode 100644
index 0000000..838a979
--- /dev/null
+++ b/zh-cn/devices/audio/implement-shared-library.html
@@ -0,0 +1,75 @@
+<html devsite><head>
+    <title>配置共享库</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 The Android Open Source Project
+
+      Licensed under the Apache License, Version 2.0 (the "License");
+      you may not use this file except in compliance with the License.
+      You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      See the License for the specific language governing permissions and
+      limitations under the License.
+  -->
+
+<p>创建<a href="/devices/audio/implement-policy.html">音频政策配置后</a>,您必须将 HAL 实现打包到共享库中,并将其复制到相应位置:</p>
+
+<ol>
+<li>创建一个 <code>device/&lt;company&gt;/&lt;device&gt;/audio</code> 目录以包含您的库的源文件。</li>
+<li>创建一个 <code>Android.mk</code> 文件来编译共享库。确保 Makefile 包含以下行:<br />
+<pre class="devsite-click-to-copy">
+LOCAL_MODULE := audio.primary.&lt;device&gt;
+</pre>
+<br />
+<p>您的库必须命名为 <code>audio.primary.&lt;device&gt;.so</code>,以便 Android 可以正确加载库。此文件名的 <code>primary</code> 部分表示此共享库用于设备上的主要音频硬件。模块名称 <code>audio.a2dp.&lt;device&gt;</code> 和 <code>audio.usb.&lt;device&gt;</code> 也可用于蓝牙和 USB 音频接口。以下是 Galaxy Nexus 音频硬件的 <code>Android.mk</code> 示例:</p>
+
+<pre class="devsite-click-to-copy">
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := audio.primary.tuna
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_SRC_FILES := audio_hw.c ril_interface.c
+LOCAL_C_INCLUDES += \
+        external/tinyalsa/include \
+        $(call include-path-for, audio-utils) \
+        $(call include-path-for, audio-effects)
+LOCAL_SHARED_LIBRARIES := liblog libcutils libtinyalsa libaudioutils libdl
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_SHARED_LIBRARY)
+</pre>
+</li>
+<br />
+<li>如果您的产品支持 Android CDD 指定的低延迟音频,请将相应的 XML 功能文件复制到您的产品中。例如,在您产品的 <code>device/&lt;company&gt;/&lt;device&gt;/device.mk</code> Makefile 中:<pre class="devsite-click-to-copy">
+PRODUCT_COPY_FILES := ...
+
+PRODUCT_COPY_FILES += \
+frameworks/native/data/etc/android.hardware.audio.low_latency.xml:system/etc/permissions/android.hardware.audio.low_latency.xml \
+</pre>
+</li>
+<br />
+<li>将您之前创建的音频政策配置文件复制到您产品的 <code>device/&lt;company&gt;/&lt;device&gt;/device.mk</code> Makefile 的 <code>system/etc/</code> 目录下。例如:<pre class="devsite-click-to-copy">
+PRODUCT_COPY_FILES += \
+        device/samsung/tuna/audio/audio_policy.conf:system/etc/audio_policy.conf
+</pre>
+</li>
+<br />
+<li>在您产品的 <code>device/&lt;company&gt;/&lt;device&gt;/device.mk</code> Makefile 中声明您的产品所需的音频 HAL 的共享模块。例如,Galaxy Nexus 需要主要音频 HAL 模块和蓝牙音频 HAL 模块:<pre class="devsite-click-to-copy">
+PRODUCT_PACKAGES += \
+        audio.primary.tuna \
+        audio.a2dp.default
+</pre>
+</li>
+</ol>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/audio/implement.html b/zh-cn/devices/audio/implement.html
new file mode 100644
index 0000000..a4ee6b4
--- /dev/null
+++ b/zh-cn/devices/audio/implement.html
@@ -0,0 +1,50 @@
+<html devsite><head>
+    <title>音频实现</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 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>本部分介绍了如何实现音频硬件抽象层 (HAL),提供了有关配置音频策略(文件格式、代码组织、预处理效果)的详细信息,并说明了如何配置共享库(创建 <code>Android.mk</code> 文件)。</p>
+
+<h2 id="implementing">实现音频 HAL</h2>
+
+<p>音频 HAL 由以下接口组成:</p>
+
+<ul>
+<li><code>hardware/libhardware/include/hardware/audio.h</code>:表示音频设备的主函数。</li>
+<li><code>hardware/libhardware/include/hardware/audio_effect.h</code>:表示可应用于音频的效果,如缩混、回音或噪音抑制。</li>
+</ul>
+
+<p>您必须实现所有接口。</p>
+
+<h2 id="headers">音频标头文件</h2>
+<p>要查看您可以定义的属性的参考,请参阅音频标头文件:</p>
+
+<ul>
+<li>在 Android 6.0 及更高版本中,请参阅 <code>system/media/audio/include/system/audio.h</code>。</li>
+<li>在 Android 5.1 及更低版本中,请参阅 <code>system/core/include/system/audio.h</code>。</li>
+</ul>
+
+<p>例如,在 <code>device/samsung/tuna/audio</code> 中参阅 Galaxy Nexus 的实现。</p>
+
+<h2 id="next-steps">后续步骤</h2>
+
+<p>除了实现音频 HAL 之外,您还必须创建<a href="/devices/audio/implement-policy.html">音频策略配置文件</a>,用于描述您的音频拓扑,并将 HAL 实现打包到<a href="/devices/audio/implement-shared-library.html">共享库</a>中。您还可以配置<a href="/devices/audio/implement-pre-processing.html">预处理效果</a>,如自动增益控制和噪音抑制。</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/audio/index.html b/zh-cn/devices/audio/index.html
new file mode 100644
index 0000000..67dddb7
--- /dev/null
+++ b/zh-cn/devices/audio/index.html
@@ -0,0 +1,99 @@
+<html devsite><head>
+    <title>音频</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 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.
+  -->
+
+<img style="float: right; margin: 0px 15px 15px 15px;" src="images/ape_fwk_hal_audio.png" alt="Android 音频 HAL 图标"/>
+
+<p>
+Android 的音频硬件抽象层 (HAL) 可将 <a href="http://developer.android.com/reference/android/media/package-summary.html">android.media</a> 中特定于音频的较高级别的框架 API 连接到底层音频驱动程序和硬件。本部分介绍了有关提升性能的实现说明和提示。
+</p>
+
+<h2 id="Architecture">音频架构</h2>
+<p>
+Android 音频架构定义了音频功能的实现方式,并指出实现中所涉及的相关源代码。
+</p>
+
+<img src="images/ape_fwk_audio.png" alt="音频架构" id="figure1"/>
+
+<p class="img-caption">
+<strong>图 1. </strong> Android 音频架构</p>
+
+<dl>
+
+<dt>
+应用框架
+</dt>
+<dd>
+应用框架包含应用代码,该代码可使用 <a href="http://developer.android.com/reference/android/media/package-summary.html">android.media</a> API 与音频硬件进行互动。在内部,此代码会调用相应的 JNI 粘合类,以访问与音频硬件互动的原生代码。
+</dd>
+
+<dt>
+JNI
+</dt>
+<dd>
+与 <a href="http://developer.android.com/reference/android/media/package-summary.html">android.media</a> 关联的 JNI 代码可调用较低级别的原生代码,以访问音频硬件。JNI 位于 <code>frameworks/base/core/jni/</code> 和 <code>frameworks/base/media/jni</code> 中。
+</dd>
+
+<dt>
+原生框架
+</dt>
+<dd>
+原生框架可提供相当于 <a href="http://developer.android.com/reference/android/media/package-summary.html">android.media</a> 软件包的原生软件包,从而调用 Binder IPC 代理以访问媒体服务器的特定于音频的服务。原生框架代码位于 <code>frameworks/av/media/libmedia</code> 中。
+</dd>
+
+<dt>
+Binder IPC
+</dt>
+<dd>Binder IPC 代理用于促进跨越进程边界的通信。代理位于 <code>frameworks/av/media/libmedia</code> 中,并以字母“I”开头。
+</dd>
+
+<dt>
+媒体服务器
+</dt>
+<dd>
+媒体服务器包含音频服务,这些音频服务是与您的 HAL 实现进行互动的实际代码。媒体服务器位于 <code>frameworks/av/services/audioflinger</code> 中。
+</dd>
+
+<dt>
+HAL
+</dt>
+<dd>
+HAL 定义了由音频服务调用且您必须实现以确保音频硬件功能正常运行的标准接口。音频 HAL 接口位于 <code>hardware/libhardware/include/hardware</code> 中。如需了解详情,请参阅 <a href="https://android.googlesource.com/platform/hardware/libhardware/+/master/include/hardware/audio.h">audio.h</a>。
+</dd>
+
+<dt>
+内核驱动程序
+</dt>
+<dd>
+音频驱动程序可与您的硬件和 HAL 实现进行互动。您可以使用高级 Linux 声音体系 (ALSA)、开放声音系统 (OSS) 或自定义驱动程序(HAL 与驱动程序无关)。
+<p class="note"><strong>注意</strong>:如果您使用 ALSA,我们建议将 <code>external/tinyalsa</code> 用于驱动程序的用户部分,因为它具有兼容的许可(标准的用户模式库已获得 GPL 许可)。</p>
+</dd>
+
+<dt>
+基于 Open SL ES 的 Android 原生音频(未显示)<em></em>
+</dt>
+<dd>
+此 API 作为 <a href="https://developer.android.com/tools/sdk/ndk/index.html">Android NDK</a> 的一部分提供,且与 <a href="http://developer.android.com/reference/android/media/package-summary.html">android.media</a> 位于同一架构层级。
+</dd>
+
+</dl>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/audio/latency.html b/zh-cn/devices/audio/latency.html
new file mode 100644
index 0000000..2296cf3
--- /dev/null
+++ b/zh-cn/devices/audio/latency.html
@@ -0,0 +1,63 @@
+<html devsite><head>
+    <title>音频延迟</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 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>音频延迟是音频信号通过系统时的时间延迟。
+</p>
+
+<h3 id="resources">资源</h3>
+
+<table>
+<tbody><tr>
+  <th>主题</th>
+  <th>链接</th>
+</tr>
+<tr>
+  <td>为确保 Android 兼容性的音频延迟说明</td>
+  <td><a href="/compatibility/android-cdd.pdf">Android CDD</a><br /><em>第 5.5 节:音频延迟</em></td>
+</tr>
+<tr>
+  <td>音频延迟的常见原因</td>
+  <td><a href="latency_contrib.html">音频延迟的作用因素</a></td>
+</tr>
+<tr>
+  <td>为减少 Android 的音频延迟所做的努力</td>
+  <td><a href="latency_design.html">减少延迟的设计</a></td>
+</tr>
+<tr>
+  <td>衡量音频延迟的技术</td>
+  <td>
+    <a href="latency_measure.html">衡量音频延迟</a><br />
+    <a href="testing_circuit.html">灯光测试电路</a><br />
+    <a href="loopback.html">音频环回软件狗</a>
+  </td>
+</tr>
+<tr>
+  <td>往返音频延迟结果</td>
+  <td><a href="latency_measurements.html">音频延迟衡量</a></td>
+</tr>
+<tr>
+  <td>应用</td>
+  <td><a href="latency_app.html">音频延迟(适用于应用开发者)</a></td>
+</tr>
+</tbody></table>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/audio/latency_app.html b/zh-cn/devices/audio/latency_app.html
new file mode 100644
index 0000000..75ee7a1
--- /dev/null
+++ b/zh-cn/devices/audio/latency_app.html
@@ -0,0 +1,142 @@
+<html devsite><head>
+    <title>音频延迟时间(适用于应用开发者)</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 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>为了尽可能缩短音频延迟时间,我们建议您使用基于 OpenSL ES 1.0.1 的 Android 原生音频。</p>
+
+<h2 id="implementation">实现核对清单</h2>
+
+<p>要使用 Android 原生音频,请执行以下操作:</p>
+
+<ol>
+
+<li>
+下载并安装 <a href="https://developer.android.com/tools/sdk/ndk/index.html">Android NDK</a>。在本文档的其余部分,我们将假设 <code>NDKroot</code> 是您安装 NDK 所使用的目录。</li>
+
+<li>
+阅读<a href="#supporting">支持文档</a>。
+</li>
+
+<li>
+确认 API 级别不低于 9 级。
+</li>
+
+<li>
+检查 <a href="http://developer.android.com/guide/topics/manifest/uses-feature-element.html#hw-features">android.hardware.audio.low_latency</a> 功能。
+</li>
+
+<li>
+使用由以下对象返回的建议的原生缓冲区空间和采样率:<a href="http://developer.android.com/reference/android/media/AudioManager.html#getProperty(java.lang.String)">android.media.AudioManager.getProperty(java.lang.String)</a>
+<p> <strong>注意</strong>:输入时,还应使用相同的缓冲区空间和采样率。</p>
+</li>
+
+<li>
+通常 1 个 OpenSL ES 缓冲区就足够了。
+</li>
+
+<li>
+确保您的回调处理程序比较短,没有突发的 CPU 占用或不受控制的阻塞。避免<a href="avoiding_pi.html">优先级反转</a>。
+</li>
+
+<li>
+考虑使用<a href="avoiding_pi.html#nonBlockingAlgorithms">非阻塞算法</a>,以在输入和输出回调处理程序之间以及回调处理程序与您应用的其余部分之间进行通信。
+</li>
+
+</ol>
+
+<h2 id="supporting">支持文档</h2>
+
+<h3 id="opensl_es_1_0_1">OpenSL ES 1.0.1</h3>
+
+<p>
+使用 PDF 查看器查看 <a href="https://www.khronos.org/registry/sles/specs/OpenSL_ES_Specification_1.0.1.pdf">OpenSL 1.0.1 规范</a>。这份参考资料很长,并非所有内容都适用于您;不过,您需要查阅这份参考资料来了解有关 API 的详细信息。</p>
+
+<p class="note">
+<strong>注意</strong>:本文档介绍了完整的 OpenSL ES 1.0.1,但 Android 原生音频实际上是基于 OpenSL ES 1.0.1 的一个子集,而该子集含有一些特定于 Android 的扩展程序。
+</p>
+
+<p>
+更高版本的 OpenSL ES(如 1.1)的说明文档与 Android 不相关。
+</p>
+
+<h3 id="opensl_es_for_android">OpenSL ES for Android</h3>
+
+<p>NDK 的安装文件中提供了“OpenSL ES for Android”文档,该文档目前没有在线提供。在浏览器中打开此链接:</p>
+
+<pre class="devsite-click-to-copy">
+NDKroot/docs/Additional_library_docs/opensles/index.html
+</pre>
+
+<p>
+您需要浏览整篇文档,但要特别注意“编程注释”部分的“性能”子部分。
+</p>
+
+<p>
+“OpenSL ES 1.0.1 中受支持的功能”部分介绍了 Android 所支持的子集。
+</p>
+
+<p>
+“Android 扩展程序”部分介绍了底层 OpenSL ES 1.0.1 中没有的特定于 Android 的扩展程序。
+</p>
+
+<h3 id="relationship">与 OpenSL ES 1.0.1 的关系</h3>
+
+<p>
+该维恩图显示了 Android 原生音频与 OpenSL ES 1.0.1 之间的关系。
+</p>
+
+<img src="images/venn.png" alt="维恩图" id="figure1"/>
+<p class="img-caption">
+  <strong>图 1.</strong> 维恩图</p>
+
+<h2 id="resources">其他资源</h2>
+
+<h3 id="source_android_com">source.android.com</h3>
+
+<p>
+<a href="/">source.android.com</a> 网站主要面向制造 Android 设备的原始设备制造商 (OEM),以及为这些原始设备制造商提供组件的 SoC 供应商。</p>
+
+<p>
+不过,该网站上提供了大量有关延迟时间的实用信息,因此您可能需要查看这些信息。请查看<a href="latency.html">音频延迟时间</a>的相关文章。
+</p>
+
+<h3 id="android_ndk">android-ndk</h3>
+
+<p>
+如果您对如何使用 Android 原生音频有疑问,请在 <a href="https://groups.google.com/forum/#!forum/android-ndk">android-ndk</a> 论坛中提问。
+</p>
+
+<h3 id="videos">视频</h3>
+
+<dl>
+
+<dt><a href="https://youtu.be/d3kfEeMZ65c">Android 上的高性能音频</a>(2013 年 Google I/O 大会)</dt>
+<dd>整个视频都是关于延迟时间的。</dd>
+
+<dt><a href="https://youtu.be/92fgcUNCHic">在 Android 上打造出色的多媒体体验</a>(2014 年 Google I/O 大会)</dt>
+<dd>前 14 分钟大致介绍了一下音频,尤其是输入延迟时间。</dd>
+
+<dt><a href="https://youtu.be/PnDK17zP9BI">音频延迟时间:缓冲区空间</a> (100 Days of Google Dev)</dt>
+<dd>介绍音频延迟时间、缓冲区空间和任务工作表之间的关系。</dd>
+
+</dl>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/audio/latency_contrib.html b/zh-cn/devices/audio/latency_contrib.html
new file mode 100644
index 0000000..3c43dd6
--- /dev/null
+++ b/zh-cn/devices/audio/latency_contrib.html
@@ -0,0 +1,107 @@
+<html devsite><head>
+    <title>音频延迟的促成因素</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 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>本页面重点介绍输出延迟的促成因素,但是类似的内容也适用于输入延迟。
+</p>
+<p>假设模拟电路的促成作用没有那么显著,那么音频延迟的主要 Surface 级促成因素如下:</p>
+
+<ul>
+  <li>应用</li>
+  <li>通道中的缓冲区总数</li>
+  <li>每个缓冲区的大小(以帧为单位)</li>
+  <li>应用处理器之后的额外延迟,例如来自 DSP 的延迟</li>
+</ul>
+
+<p>上述促成因素列表在尽量做到准确的同时,可能也存在误导。原因在于缓冲区计数和缓冲区大小更像是影响而非原因。<em></em><em></em>通常发生的情况是实现并测试一个指定的缓冲区方案,但是在测试期间,音频欠载或过载听到的声音是“咔哒声”或“砰砰声”。作为补偿措施,系统设计人员因此增加了缓冲区大小或缓冲区计数。这样一来,虽然达到了消除欠载或过载这一预期效果,但是也带来了延迟时间变长的负面影响。有关缓冲区大小的更多信息,请观看视频<a href="https://youtu.be/PnDK17zP9BI">音频延迟:缓冲区大小</a>。
+
+</p>
+
+<p>更好的方法是了解欠载和过载的原因,然后纠正这些问题。这样可消除我们能听见的杂音,并且允许使用更小或更少的缓冲区,从而缩短延迟。
+</p>
+
+<p>根据我们的经验,最常见的欠载和过载的原因包括:</p>
+<ul>
+  <li>Linux CFS(完全公平的调度程序)</li>
+  <li>具有 SCHED_FIFO 调度的高优先级线程</li>
+  <li>优先级倒置</li>
+  <li>长时间调度延迟</li>
+  <li>长时间运行的中断处理程序</li>
+  <li>长时间中断禁用</li>
+  <li>电源管理</li>
+  <li>安全内核</li>
+</ul>
+
+<h3 id="linuxCfs">Linux CFS 和 SCHED_FIFO 调度</h3>
+<p>Linux CFS 旨在公平地对待共享通用 CPU 资源的竞争性工作负载。这种公平性体现在在每个线程中使用 nice 参数。<em></em>nice 值范围从 -19(最不友好,即分配最多的 CPU 时间)到 20(最友好,即分配最少的 CPU 时间)。一般来说,具有指定 nice 值的所有线程会获得差不多相同的 CPU 时间,而 nice 值较低的线程预计会获得更多的 CPU 时间。不过,只有在相对较长的观察期内,才能看出 CFS 是“公平”的。在较短的观察期内,CFS 可能会以意想不到的方式分配 CPU 资源。例如,它可能会将具有较低 nice 值的线程上的 CPU 转移到具有较高 nice 值的线程。对于音频而言,这可能会导致欠载或过载。
+</p>
+
+<p>显而易见的解决方案是避免将 CFS 用于高性能音频线程。从 Android 4.1 开始,此类线程现在使用 <code>SCHED_FIFO</code> 调度策略,而非通过 CFS 实现的 <code>SCHED_NORMAL</code>(也称为 <code>SCHED_OTHER</code>)调度策略。</p>
+
+<h3 id="schedFifo">SCHED_FIFO 优先级</h3>
+<p>虽然高性能音频线程现在使用 <code>SCHED_FIFO</code>,但是它们仍然很容易受到其他优先级更高的 <code>SCHED_FIFO</code> 线程的影响。这些线程通常是内核 Worker 线程,但也可能存在一些采用策略 <code>SCHED_FIFO</code> 的非音频用户线程。可用的 <code>SCHED_FIFO</code> 优先级范围是从 1 到 99。音频线程的运行优先级为 2 或 3。这使得优先级 1 可用于优先级较低的线程,而优先级 4 到 99 则适用于优先级较高的线程。我们建议您尽可能使用优先级 1,并保留优先级 4 到 99 以用于以下线程:保证在有限时间内完成、执行时间短于音频线程时间并且已知不会干扰音频线程调度的线程。
+</p>
+
+<h3 id="rms">速率单调调度</h3>
+<p>有关固定优先级分配理论的更多信息,请参阅维基百科文章<a href="http://en.wikipedia.org/wiki/Rate-monotonic_scheduling">速率单调调度</a> (RMS)。关键在于,固定优先级应严格按照周期分配,较高优先级分配给较短周期的线程,而不是基于观察到的“重要性”。可以使用最大执行频率和每次执行的最大计算能力将非周期性线程建模为周期性线程。如果非周期性线程不能建模为周期性线程(例如,它可以按无限频率执行或每次执行使用无限计算能力),则不应为其分配固定优先级,否则会与真正的周期性线程的调度不兼容。
+</p>
+
+<h3 id="priorityInversion">优先级倒置</h3>
+<p>
+  <a href="http://en.wikipedia.org/wiki/Priority_inversion">优先级倒置</a>是实时系统的一种典型故障模式,是指优先级较高的任务因等待优先级较低的任务释放资源(如受<a href="http://en.wikipedia.org/wiki/Mutual_exclusion">互斥</a>保护的共享状态)而无限受阻。请参阅“<a href="avoiding_pi.html">避免优先级倒置</a>”一文,了解缓和这种情况的技术。
+</p>
+
+<h3 id="schedLatency">调度延迟</h3>
+<p>调度延迟是指从线程已准备好运行到环境切换完成可以在 CPU 上实际运行线程之间的间隔时间。延迟越短越好,一旦超过 2 毫秒,就会造成音频问题。在模式转换期间最有可能出现长时间的调度延迟,例如,启动或关闭 CPU、在安全内核和普通内核之间切换、从全功率模式切换为低功率模式或者调整 CPU 时钟频率和电压。
+</p>
+
+<h3 id="interrupts">中断</h3>
+<p>在许多设计中,CPU 0 为所有外部中断提供服务。因此,长时间运行的中断处理程序可能会延迟其他中断,尤其是音频直接内存访问 (DMA) 完成中断。将中断处理程序设计为快速完成并将冗长的工作延迟到某个线程(最好是 CFS 线程或优先级为 1 的 <code>SCHED_FIFO</code> 线程)。
+</p>
+
+<p>同样,如果将 CPU 0 上的中端停用很长一段时间,会带来与延迟音频中断服务一样的效果。长时间中断停用通常发生在等待内核自旋锁定时。<i></i>检查这些自旋锁定,确保它们有时间限制。
+</p>
+
+<h3 id="power">电源、性能和散热管理</h3>
+<p>
+  <a href="http://en.wikipedia.org/wiki/Power_management">电源管理</a>是一个广义的术语,涵盖为了监控并减少电耗、同时优化性能所采取的措施。
+  <a href="http://en.wikipedia.org/wiki/Thermal_management_of_electronic_devices_and_systems">散热管理</a>和<a href="http://en.wikipedia.org/wiki/Computer_cooling">计算机冷却</a>类似,但寻求测量并控制热量,以避免因过热而造成损坏。在 Linux 内核中,CPU <a href="http://en.wikipedia.org/wiki/Governor_%28device%29">调节器</a>负责低级别的策略,而用户模式则配置高级别的策略。用到的技术包括:</p>
+
+<ul>
+  <li>动态电压调节</li>
+  <li>动态频率调节</li>
+  <li>动态核心启用</li>
+  <li>集群切换</li>
+  <li>电源门控</li>
+  <li>热插拔(热交换)</li>
+  <li>各种睡眠模式(中断、停止、空闲、暂停等)</li>
+  <li>进程迁移</li>
+  <li><a href="http://en.wikipedia.org/wiki/Processor_affinity">处理器关联</a></li>
+</ul>
+
+<p>一些管理操作会导致“停工”或者在一段时间内应用处理器未执行任何有用的工作。这些停工会干扰音频,因此应该设计管理措施,确保音频处于活动状态时,最糟糕的停工情况可接受。当然,当出现散热失控的紧急情况时,避免永久损坏比音频更重要!
+</p>
+
+<h3 id="security">安全内核</h3>
+<p>用于<a href="http://en.wikipedia.org/wiki/Digital_rights_management">数字版权管理</a> (DRM) 的<a href="http://en.wikipedia.org/wiki/Security_kernel">安全内核</a>可以运行在用于主要操作系统内核和应用代码的同一应用处理器内核上。只要安全内核操作在一个核心上处于活动状态,就会导致在该核心上本应正常运行的普通工作停止。尤其是,这可能包括音频工作。本质上来看,从较高层级无法预测安全内核的内部行为,因而安全内核引起的任何性能异常会特别严重。例如,安全内核操作通常不会出现在环境切换的跟踪中。我们称之为“黑暗时期”,即在流逝却无法观察到的时间。安全内核应该经过设计,确保音频处于活动状态时,最糟糕的停工情况可接受。
+</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/audio/latency_measure.html b/zh-cn/devices/audio/latency_measure.html
new file mode 100644
index 0000000..c263714
--- /dev/null
+++ b/zh-cn/devices/audio/latency_measure.html
@@ -0,0 +1,132 @@
+<html devsite><head>
+    <title>测量音频延迟</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 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>本页面介绍了测量输入和输出延迟的常用方法。
+</p>
+
+<h2 id="measuringOutput">测量输出延迟</h2>
+
+<p>有多种技术可用于测量输出延迟,这些技术的准确度和运行难易程度各不相同,具体情况如下所述。此外,要查看示例测试环境,请参阅<a href="testing_circuit.html">测试电路</a>。
+</p>
+
+<h3 id="ledTest">LED 和示波器测试</h3>
+<p>该测试测量与设备的 LED 指示灯相关的延迟。如果您的正式版设备未安装 LED,您可以将 LED 安装在原型设备上。为了提高在电路外露的原型设备上测试时的准确度,请直接将一个示波器探头连接到 LED,以绕开光传感器,从而避免光传感器产生的延迟。
+  </p>
+
+<p>如果您无法在正式版或原型设备上安装 LED,请尝试以下解决方法:</p>
+
+<ul>
+  <li>出于同一目的使用通用输入/输出 (GPIO) 引脚。</li>
+  <li>使用 JTAG 或其他调试端口。</li>
+  <li>使用屏幕背光。这种方法可能存在风险,因为背光可能具有无法忽略的延迟,并且可能导致延迟读数不准确。
+  </li>
+</ul>
+
+<p>要进行该测试,请执行以下操作:</p>
+
+<ol>
+  <li>运行一个定期使 LED 闪烁并同时输出音频的应用。
+  <p class="note"><strong>注意</strong>:要获得实用的结果,请务必在测试应用中使用正确的 API,以便运用快速音频输出路径。有关背景信息,请参阅<a href="latency_design.html">降低延迟的设计</a>。</p>
+  </li>
+  <li>在 LED 旁边放置一个光传感器。</li>
+  <li>将双通道示波器的探头连接到有线耳机插孔(线路输出)和光传感器。</li>
+  <li>使用示波器测量观察的线路输出信号与光传感器信号之间的时间差。</li>
+</ol>
+
+  <p>假设 LED 延迟和光传感器延迟均为零,上述时间差就是近似的音频输出延迟。通常情况下,LED 和光传感器各有大约 1 毫秒或更短的相对较低延迟,此延迟低到可以忽略。</p>
+
+<h2 id="measuringRoundTrip">测量往返延迟</h2>
+
+<p>
+  <a href="http://en.wikipedia.org/wiki/Round-trip_delay_time">往返延迟</a>是输出延迟和输入延迟的总和。
+</p>
+
+<h3 id="larsenTest">拉尔森测试</h3>
+<p>最简单的延迟测试之一是音频反馈(拉尔森效应)测试。该测试通过测定脉冲响应循环的时间来粗略衡量合并的输出和输入延迟。由于该测试的性质,它本身对于进行详细的分析并不是很有用,但对于校准其他测试以及确定上限来说会比较实用。</p>
+
+<p>要进行该测试,请执行以下操作:</p>
+<ol>
+  <li>运行从麦克风捕获音频并立即通过扬声器播放捕获的数据的应用。</li>
+  <li>在外部发出一个声音,例如在麦克风旁边轻击铅笔。该噪音会生成一个反馈循环。或者,测试人员也可以使用软件将脉冲注入循环中。</li>
+  <li>测量反馈脉冲之间的时间间隔,以得出输出延迟、输入延迟和应用开销的总和。</li>
+</ol>
+
+  <p>该方法不会分解组件时间,在输出延迟和输入延迟彼此独立的情况下,这一点非常重要。因此,单独测量精确的输出延迟或输入延迟值时,不建议使用该方法,但在确定粗略的估算值时,该方法可能有用。</p>
+
+  <p>设备上的扬声器的输出延迟可能明显高于耳机连接器的输出延迟。这是因为扬声器有校正和保护机制。
+  </p>
+
+<p>我们已经在 <a href="https://android.googlesource.com/platform/frameworks/wilhelm/+/master/tests/examples/slesTestFeedback.cpp">slesTestFeedback.cpp</a> 中发布了一个示例实现。它是一个命令行应用,使用平台构建环境构建而成;但是对其他环境来说,直接采用相关代码也应该很简单。此外,您还需要 <code>audio_utils</code> 库中的<a href="avoiding_pi.html#nonBlockingAlgorithms">非阻塞</a> FIFO 代码。
+</p>
+
+<h3 id="loopback">音频环回软件狗</h3>
+
+<p><a href="loopback.html">Dr. Rick O'Rang 音频环回软件狗</a>可用于测量耳机连接器的往返延迟,非常方便。下图演示了向循环中注入一次脉冲然后使反馈循环振荡的结果。振荡的周期就是往返延迟。此处并未指定具体设备、软件版本和测试条件。因此,不应对显示的结果进行外推。
+</p>
+
+<img src="images/round_trip.png" alt="往返测量" id="figure1"/>
+<p class="img-caption">
+  <strong>图 1.</strong>  往返测量</p>
+
+<p>您可能需要拔出 USB 数据线以减少噪音,并调整音量以获得稳定的振荡。
+</p>
+
+<h2 id="measuringInput">测量输入延迟</h2>
+
+<p>与输出延迟相比,输入延迟的测量难度较大。以下测试方案可能有助于测量此类延迟。
+</p>
+
+<p>一种方案是先使用 LED 和示波器方法确定输出延迟,然后使用音频反馈(拉尔森)测试来确定输出延迟和输入延迟的总和。这两个测量值之间的差值就是输入延迟。
+</p>
+
+<p>另一种方案是在原型设备上使用 GPIO 引脚。在外部,向设备提供音频信号的同时脉冲输入 GPIO 信号。运行一个应用,比较 GPIO 信号和音频数据在到达时间上的差异。
+</p>
+
+<h2 id="reducing">降低延迟</h2>
+
+<p>要实现较低的音频延迟,则在整个系统中从调度、中断处理、电源管理和设备驱动程序设计,都需要特别注意。您的目标是防止平台的任何部分阻塞 <code>SCHED_FIFO</code> 音频线程的时间超过几毫秒。通过采用这类系统性方案,您可以降低音频延迟,顺便获得更加可预测的整体性能。
+</p>
+
+ <p>通常只有在特定条件下或只有在转换时,才可以检测到音频欠载(如果确有发生)。您可以通过启动新的应用以及在各种显示之间快速滚动,尝试增加系统负载。但请注意,某些测试条件的负载过大,会超出设计目标。例如,生成错误报告会使系统负载大量增加,因而在这种情况下发生欠载可以接受。
+</p>
+
+<p>测试欠载时,请执行以下操作:</p>
+  <ul>
+  <li>在应用处理器后配置任意 DSP,以尽量避免增加延迟。</li>
+  <li>在不同的条件下运行测试,例如开启或关闭屏幕、插入或拔出 USB、开启或关闭 WLAN、开启或关闭蓝牙、开启或关闭电话和数据网络。</li>
+  <li>选择您非常熟悉的相对安静的音乐,这类音乐中的欠载比较容易听出来。</li>
+  <li>使用有线耳机,以实现更高的灵敏度。</li>
+  <li>安排休息时间,这样您不会有“耳朵疲劳”的感觉。</li>
+  </ul>
+
+<p>在您找出发生欠载的根本原因后,请减少缓冲区计数和大小,以便充分利用它。如果在分析欠载并解决欠载问题之前就急于减少缓冲区计数和大小,只会适得其反。<i></i>
+</p>
+
+<h3 id="tools">工具</h3>
+<p>
+  <code>systrace</code> 是一款出色的通用工具,用于诊断系统级别性能故障。
+</p>
+
+<p><code>dumpsys media.audio_flinger</code> 的输出中还包含一个称为“simple moving statistics”(简单的移动统计信息)的实用部分,其中包含每个混音和 I/O 周期如何随时间变化的摘要。理想情况下,所有的时间测量值都应该等于平均值或标称周期时间。如果您看到极小的最小值或极大的最大值,则表示存在问题,有可能是调度延迟过高或中断停用时间过长。输出的尾部部分特别有用,因为它突出显示了 +/- 3 标准偏差之外的变化。<i></i>
+</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/audio/latency_measurements.html b/zh-cn/devices/audio/latency_measurements.html
new file mode 100644
index 0000000..46a6e11
--- /dev/null
+++ b/zh-cn/devices/audio/latency_measurements.html
@@ -0,0 +1,378 @@
+<html devsite><head>
+    <title>音频延迟时间测量</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 The Android Open Source Project
+
+      Licensed under the Apache License, Version 2.0 (the "License");
+      you may not use this file except in compliance with the License.
+      You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      See the License for the specific language governing permissions and
+      limitations under the License.
+  -->
+
+<p><a href="http://en.wikipedia.org/wiki/Latency_%28engineering%29">延迟时间</a>是一项重要的系统性能指标。<a href="latency.html">音频延迟时间</a>指标有多种类型,其中一个很实用且易于理解的指标是<a href="latency_measure.html#measuringRoundTrip">往返延迟时间</a>。根据该指标的定义,音频延迟时间是指音频信号进入移动设备的输入设备,由应用处理器上运行的应用进行处理,然后退出输出设备,这整个过程所花费的时间。</p>
+
+<img src="images/round_trip_on_device.png" alt="设备上的往返音频延迟时间" id="figure1"/>
+<p class="img-caption"><strong>图 1. </strong> 设备上的往返音频延迟时间:T<sub>output</sub> - T<sub>input</sub></p>
+
+<p>本页提供了选定 Nexus/Pixel 设备和 Android 平台版本的往返音频延迟时间测量结果。</p>
+
+<h2 id="why">为什么要测量延迟时间</h2>
+
+<p>Google 会测量和报告延迟时间,以便 Android 应用开发者获取所需数据,从而针对实际设备上的可用延迟时间做出明智决策。我们会分享选定 Nexus 和 Pixel 设备的延迟时间数值,以此鼓励整个 Android 社区的成员来测量、发布和减少所有 Android 设备上的延迟时间。<em></em>欢迎加入我们,一起为减少音频延迟时间而努力!</p>
+
+<h2 id="app">应用对延迟时间的影响</h2>
+
+<p>信号处理技术可能会在延迟时间中添加以下类型的延迟:</p>
+<ul>
+<li><strong>算法</strong>:这是一种固有延迟,不会因 CPU 而异。例如由<a href="http://en.wikipedia.org/wiki/Finite_impulse_response">有限脉冲响应</a> (FIR) 过滤器增加的延迟。</li>
+<li><strong>计算</strong>:这种延迟与所需的 CPU 周期数有关。例如,信号的衰减通常通过乘法运算完成,而该运算所需的周期数则取决于 CPU。</li>
+</ul>
+
+<h2 id="how">如何测量</h2>
+
+<p>我们使用 <a href="loopback.html">Dr. Rick O'Rang 音频环回软件狗</a>和<a href="latency_measure.html#larsenTest">音频反馈(拉尔森效应)测试</a>得出了本页列出的测量结果。测量假设应用信号处理技术增加了零算法延迟时间和近零计算延迟时间。</p>
+
+<p>我们通过耳机连接器来测量往返延迟时间有以下几个原因:</p>
+<img src="images/round_trip_via_headset_connector.png" alt="通过耳机连接器测量的往返延迟时间" id="figure2"/>
+<p class="img-caption"><strong>图 2. </strong> 通过耳机连接器测量的往返延迟时间:T<sub>output</sub> - T<sub>input</sub></p>
+<ul>
+<li>重要的音乐应用(如吉他和语音处理)一般会使用耳机连接器。</li>
+<li>测量设备上的麦克风和扬声器之间的往返延迟时间可能会比较麻烦,因为在露天环境下难以避免反馈环进入不受控制的振荡状态。</li>
+<li>设备上的换能器都很小,为了实现它们的小尺寸则需要牺牲频率响应。出于补偿目的,换能器会应用数字信号处理技术,但这会增加设备上路径的算法延迟时间。</li>
+</ul>
+
+<p>在有些情况下,设备上的麦克风和扬声器延迟时间确实有重要作用,但这通常是针对单向延迟而不是往返延迟。<em></em><a href="latency_measure.html#measuringOutput">测量输出设备延迟时间</a>和<a href="latency_measure.html#measuringInput">测量输入设备延迟时间</a>中介绍了测量单向延迟时间的相关技术。</p>
+
+<h2 id="measurements">测量结果示例</h2>
+
+<p>下面列出的是特定于某个<a href="/source/build-numbers.html">版本号</a>的测量结果。设备按初始版本和平台版本的大致顺序列出;您也可以<a href="#chart">查看图表中的延迟时间</a>。测试应用会使用 Android 原生音频 API(基于 OpenSL ES)。</p>
+
+<table>
+<tbody><tr>
+  <th>型号</th>
+  <th>平台<br />版本</th>
+  <th>版本<br />号</th>
+  <th>抽样频率<br />(Hz)</th>
+  <th>缓冲区空间<br />(帧)</th>
+  <th>缓冲区空间<br />(毫秒)</th>
+  <th>往返<br />延迟时间(毫秒)<br />± 1 个缓冲区</th>
+</tr>
+
+<tr>
+  <td>Nexus One</td>
+  <td>2.3.6</td>
+  <td>GRK39F</td>
+  <td>44100</td>
+  <td>768</td>
+  <td>17.4</td>
+  <td>345</td>
+</tr>
+
+<tr>
+  <td>Nexus S</td>
+  <td>2.3.6</td>
+  <td>GRK39F</td>
+  <td>44100</td>
+  <td>1024</td>
+  <td>23.2</td>
+  <td>260</td>
+</tr>
+
+<tr>
+  <td>Nexus S</td>
+  <td>4.0.4</td>
+  <td>IMM76D</td>
+  <td>44100</td>
+  <td>1024</td>
+  <td>23.2</td>
+  <td>260</td>
+</tr>
+
+<tr>
+  <td>Nexus S</td>
+  <td>4.1.2</td>
+  <td>JZO54K</td>
+  <td>44100</td>
+  <td>880</td>
+  <td>20</td>
+  <td>210</td>
+</tr>
+
+<tr>
+  <td>Galaxy Nexus</td>
+  <td>4.0.1</td>
+  <td>ITL41D</td>
+  <td>44100</td>
+  <td>976</td>
+  <td>22.1</td>
+  <td>270</td>
+</tr>
+
+<tr>
+  <td>Galaxy Nexus</td>
+  <td>4.3</td>
+  <td>JWR66Y</td>
+  <td>44100</td>
+  <td>144</td>
+  <td>3.3</td>
+  <td>130</td>
+</tr>
+
+<tr>
+  <td>Nexus 4</td>
+  <td>4.2.2</td>
+  <td>JDQ39E</td>
+  <td>48000</td>
+  <td>240</td>
+  <td>5</td>
+  <td>195</td>
+</tr>
+
+<tr>
+  <td>Nexus 4</td>
+  <td>5.1</td>
+  <td>LMY47O</td>
+  <td>48000</td>
+  <td>240</td>
+  <td>5</td>
+  <td>58</td>
+</tr>
+
+<tr>
+  <td>Nexus 10</td>
+  <td>5.0.2</td>
+  <td>LRX22G</td>
+  <td>44100</td>
+  <td>256</td>
+  <td>5.8</td>
+  <td>36</td>
+</tr>
+
+<tr>
+  <td>Nexus 10</td>
+  <td>5.1</td>
+  <td>LMY47D</td>
+  <td>44100</td>
+  <td>256</td>
+  <td>5.8</td>
+  <td>35</td>
+</tr>
+
+<tr>
+  <td>Nexus 7<br />2013</td>
+  <td>4.3</td>
+  <td>JSR78D</td>
+  <td>48000</td>
+  <td>240</td>
+  <td>5</td>
+  <td>149</td>
+</tr>
+
+<tr>
+  <td>Nexus 7<br />2013</td>
+  <td>4.4</td>
+  <td>KRT16S</td>
+  <td>48000</td>
+  <td>240</td>
+  <td>5</td>
+  <td>85</td>
+</tr>
+
+<tr>
+  <td>Nexus 7<br />2013</td>
+  <td>5.0.2</td>
+  <td>LRX22G</td>
+  <td>48000</td>
+  <td>240</td>
+  <td>5</td>
+  <td>64</td>
+</tr>
+
+<tr>
+  <td>Nexus 7<br />2013</td>
+  <td>5.1</td>
+  <td>LMY47O</td>
+  <td>48000</td>
+  <td>240</td>
+  <td>5</td>
+  <td>55</td>
+</tr>
+
+<tr>
+  <td>Nexus 7<br />2013</td>
+  <td>6.0</td>
+  <td>MRA58K</td>
+  <td>48000</td>
+  <td>240</td>
+  <td>5</td>
+  <td>55</td>
+</tr>
+
+<tr>
+  <td>Nexus 5</td>
+  <td>4.4.4</td>
+  <td>KTU84P</td>
+  <td>48000</td>
+  <td>240</td>
+  <td>5</td>
+  <td>95</td>
+</tr>
+
+<tr>
+  <td>Nexus 5</td>
+  <td>5.0.0</td>
+  <td>LRX21O</td>
+  <td>48000</td>
+  <td>240</td>
+  <td>5</td>
+  <td>47</td>
+</tr>
+
+<tr>
+  <td>Nexus 5</td>
+  <td>5.1</td>
+  <td>LMY47I</td>
+  <td>48000</td>
+  <td>240</td>
+  <td>5</td>
+  <td>42</td>
+</tr>
+
+<tr>
+  <td>Nexus 5</td>
+  <td>6.0</td>
+  <td>MRA58K</td>
+  <td>48000</td>
+  <td>192</td>
+  <td>4</td>
+  <td>38</td>
+</tr>
+
+<tr>
+  <td>Nexus 9</td>
+  <td>5.0.0</td>
+  <td>LRX21L</td>
+  <td>48000</td>
+  <td>256</td>
+  <td>5.3</td>
+  <td>35</td>
+</tr>
+
+<tr>
+  <td>Nexus 9</td>
+  <td>5.0.1</td>
+  <td>LRX22C</td>
+  <td>48000</td>
+  <td>256</td>
+  <td>5.3</td>
+  <td>38</td>
+</tr>
+
+<tr>
+  <td>Nexus 9</td>
+  <td>5.1.1</td>
+  <td>LMY47X</td>
+  <td>48000</td>
+  <td>256</td>
+  <td>5.3</td>
+  <td>32</td>
+</tr>
+
+<tr>
+  <td>Nexus 9</td>
+  <td>6.0</td>
+  <td>MRA58K</td>
+  <td>48000</td>
+  <td>128</td>
+  <td>2.6</td>
+  <td>15</td>
+</tr>
+
+<tr>
+  <td>Nexus 6</td>
+  <td>5.0.1</td>
+  <td>LRX22C</td>
+  <td>48000</td>
+  <td>240</td>
+  <td>5</td>
+  <td>65</td>
+</tr>
+
+<tr>
+  <td>Nexus 6</td>
+  <td>5.1</td>
+  <td>LMY47I</td>
+  <td>48000</td>
+  <td>240</td>
+  <td>5</td>
+  <td>42</td>
+</tr>
+
+<tr>
+  <td>Nexus 6</td>
+  <td>6.0</td>
+  <td>MRA58K</td>
+  <td>48000</td>
+  <td>192</td>
+  <td>4</td>
+  <td>33</td>
+</tr>
+
+<tr>
+  <td>Nexus 5X</td>
+  <td>6.0</td>
+  <td>MDA89E</td>
+  <td>48000</td>
+  <td>192</td>
+  <td>4</td>
+  <td>18</td>
+</tr>
+
+<tr>
+  <td>Nexus 6P</td>
+  <td>6.0</td>
+  <td>MDA89D</td>
+  <td>48000</td>
+  <td>192</td>
+  <td>4</td>
+  <td>18</td>
+</tr>
+
+<tr>
+  <td>Pixel</td>
+  <td>7.1.2</td>
+  <td>NHG47L</td>
+  <td>48000</td>
+  <td>192</td>
+  <td>4</td>
+  <td>18</td>
+</tr>
+
+<tr>
+  <td>Pixel XL</td>
+  <td>7.1.2</td>
+  <td>NHG47L</td>
+  <td>48000</td>
+  <td>192</td>
+  <td>4</td>
+  <td>18</td>
+</tr>
+
+</tbody></table>
+
+<a id="chart"></a>
+<img src="/devices/audio/images/round-trip-latencies.png"/>
+<p class="img-caption"><strong>图 3. </strong> 往返延迟时间。</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/audio/loopback.html b/zh-cn/devices/audio/loopback.html
new file mode 100644
index 0000000..c4c4322
--- /dev/null
+++ b/zh-cn/devices/audio/loopback.html
@@ -0,0 +1,41 @@
+<html devsite><head>
+    <title>音频环回适配器</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 The Android Open Source Project
+
+      Licensed under the Apache License, Version 2.0 (the "License");
+      you may not use this file except in compliance with the License.
+      You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      See the License for the specific language governing permissions and
+      limitations under the License.
+  -->
+
+<p>下面的示意图和照片展示的是<a href="http://en.wikipedia.org/wiki/Phone_connector_(audio)">耳机连接器</a>的音频环回<a href="http://en.wikipedia.org/wiki/Dongle">适配器</a>,我们称之为“Dr. Rick O'Rang 音频环回适配器”。Chrome 硬件团队设计了此电路和插头以进行功能测试,不过它还有许多其他用途。Android 音频团队根据拉尔森效应(反馈环)用其测量<a href="latency_measure.html#measuringRoundTrip">往返音频延迟</a>。
+</p>
+
+<h2 id="loopbackCircuit">电路</h2>
+
+<img src="images/loopback_circuit.png" alt="电路" id="figure1"/>
+<p class="img-caption">
+  <strong>图 1.</strong> 电路图</p>
+
+<p>为了确保输出信号不会超出麦克风输入负荷,我们使其音量降低了约 20 分贝。麦克风极性开关可从电阻器负载得知,音频环回适配器是一种美标/CTIA 4 段式 TRRS 插头。
+</p>
+
+<h2 id="loopbackAssembled">组装完成图</h2>
+
+<img src="images/loopback_assembled.jpg" alt="完全组装" id="figure2"/>
+<p class="img-caption">
+  <strong>图 2. </strong> 组装完成图</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/audio/midi.html b/zh-cn/devices/audio/midi.html
new file mode 100644
index 0000000..74b38c1
--- /dev/null
+++ b/zh-cn/devices/audio/midi.html
@@ -0,0 +1,106 @@
+<html devsite><head>
+    <title>MIDI</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 The Android Open Source Project
+
+      Licensed under the Apache License, Version 2.0 (the "License");
+      you may not use this file except in compliance with the License.
+      You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      See the License for the specific language governing permissions and
+      limitations under the License.
+  -->
+
+<p>
+<a href="http://en.wikipedia.org/wiki/MIDI">MIDI</a>(乐器数字接口)是用于将计算机与乐器、舞台灯光和其他时间型媒体相互连接的标准协议。
+</p>
+
+<p>严格来说,MIDI 与音频无关。但是,由于 MIDI 通常用于音乐处理,因此将本文安排在了音频部分。
+</p>
+
+<h2 id="transports">传输</h2>
+
+<p>首版 MIDI 1.0 中指定的物理<a href="http://en.wikipedia.org/wiki/Transport_layer">传输层</a>是一个具有 <a href="http://en.wikipedia.org/wiki/DIN_connector">5 针 DIN</a> 连接器的电流回路。
+</p>
+
+<p>自 MIDI 1.0 推出以来,还定义了其他传输协议,包括通过 USB 传输 MIDI 以及通过<a href="http://en.wikipedia.org/wiki/Bluetooth_low_energy">蓝牙低功耗</a> (BLE) 传输 MIDI 的提议草案。
+</p>
+
+<h2 id="for-android">在 Android 上使用 MIDI</h2>
+
+<p>Android 3.1 及更高版本支持 <a href="http://en.wikipedia.org/wiki/USB_On-The-Go">USB On-The-Go</a>,允许 Android 设备充当 USB 主机来驱动 USB 外设。在 Android 3.1 中引入的 USB 主机模式 API 允许开发者在应用级别通过 USB 实现 MIDI,但直到最近才推出了针对 MIDI 的内置平台 API。</p>
+
+<p>从 Android 6.0 (Marshmallow) 版本开始,设备制造商可以在平台中启用可选的 MIDI 支持。Android 直接支持 USB、BLE 草案和虚拟(应用间)传输。Android 通过外部适配器间接支持 MIDI 1.0。
+</p>
+
+<p>有关使用新 MIDI API 进行应用编程的详细信息,请参阅 <a href="https://developer.android.com/reference/android/media/midi/package-summary.html"><code>android.media.midi</code></a> 软件包。
+</p>
+
+<p>本文的其余部分讨论了 Android 设备制造商如何在平台中启用 MIDI 支持。
+</p>
+
+<h2 id="transport">启用传输</h2>
+
+<p>该实现以 ALSA 为基础来实现 USB 主机模式和 USB 外设模式传输。ALSA 不用于 BLE 和虚拟传输。
+</p>
+
+<h3 id="usb-host">USB 主机模式</h3>
+
+<p>要为 USB 主机模式启用 MIDI,请首先在总体上支持 USB 主机模式,然后在内核配置中启用 <code>CONFIG_SND_RAWMIDI</code> 和 <code>CONFIG_SND_USB_MIDI</code>。请参阅 <a href="/devices/tech/config/kernel.html">Android 内核配置</a>。
+</p>
+
+<p>通过 USB 传输 MIDI 由 <a href="http://www.usb.org/">USB Implementers Forum, Inc</a> 发布的<a href="http://www.usb.org/developers/docs/devclass_docs/midi10.pdf">关于 MIDI 设备的通用串行总线设备类定义 1.0 版(1999 年 11 月 1 日)</a>标准正式给出定义。</p>
+
+<h3 id="usb-peripheral">USB 外设模式</h3>
+
+<p>要为 USB 外设模式启用 MIDI,您可能需要将补丁程序应用到 Linux 内核,才能将 <code>drivers/usb/gadget/f_midi.c</code> 集成到 USB 小工具驱动程序中。在撰写本文时,这些补丁程序可用于 Linux 内核版本 3.10。这些补丁程序尚未针对 <a href="http://en.wikipedia.org/wiki/Configfs">ConfigFs</a>(适用于 USB 小工具驱动程序的新架构)进行更新,也未合并到上游 <a href="http://kernel.org">kernel.org</a>。
+</p>
+
+<p>补丁程序按位于项目 <code>kernel/common</code> 分支 <code>android-3.10</code> 的内核树的提交顺序显示:</p>
+<ol>
+<li><a href="https://android-review.googlesource.com/#/c/127450/">https://android-review.googlesource.com/#/c/127450/</a></li>
+<li><a href="https://android-review.googlesource.com/#/c/127452/">https://android-review.googlesource.com/#/c/127452/</a></li>
+<li><a href="https://android-review.googlesource.com/#/c/143714/">https://android-review.googlesource.com/#/c/143714/</a></li>
+</ol>
+
+<p><em></em>此外,最终用户还必须在“设置”/“开发者选项”/“网络”/“选择 USB 配置”对话框中勾选 MIDI 框,或者在连接到 USB 主机时从屏幕顶部向下拉,选择条目“USB 的用途…”,然后选择 <strong>MIDI</strong>。</p>
+
+<h3 id="ble">BLE</h3>
+
+<p>只要设备支持 BLE,通过 BLE 传输 MIDI 的功能就始终处于启用状态。由于此传输协议还处于草案阶段,因此可能会发生变化。
+</p>
+
+<h3 id="virtual">虚拟(应用间)</h3>
+
+<p>虚拟(应用间)传输始终处于启用状态。
+</p>
+
+<h2 id="claim-feature">声明功能</h2>
+
+<p>应用可以使用 <code>android.software.midi</code> 功能来检查设备是否支持 MIDI。
+</p>
+
+<p>要声明 MIDI 支持,请将以下行添加到您的 <code>device.mk</code>:</p>
+<pre class="devsite-click-to-copy">
+PRODUCT_COPY_FILES += \
+frameworks/native/data/etc/android.software.midi.xml:system/etc/permissions/android.software.midi.xml
+</pre>
+
+<p>要了解声明相关功能的要求,请参阅 <a href="/compatibility/android-cdd.pdf">Android 兼容性定义文档 (CDD)</a>。
+</p>
+
+<h2 id="hostDebugging">在主机模式下进行调试</h2>
+
+<p>在 USB 主机模式下,无法通过 USB 进行 Android 调试桥 (adb) 调试。请参阅 <a href="http://developer.android.com/tools/help/adb.html">Android 调试桥</a>的<a href="http://developer.android.com/tools/help/adb.html#wireless">无线用法</a>部分,了解备选方案。
+</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/audio/midi_arch.html b/zh-cn/devices/audio/midi_arch.html
new file mode 100644
index 0000000..553043c
--- /dev/null
+++ b/zh-cn/devices/audio/midi_arch.html
@@ -0,0 +1,133 @@
+<html devsite><head>
+    <title>MIDI 架构</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 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>本文介绍了独立于任何平台实现、API 或平台专享功能的通用 MIDI 架构。
+</p>
+
+<h2 id="keyConcepts">主要概念</h2>
+
+<h3 id="events">事件</h3>
+
+<p>MIDI 协议专为基于事件的通信而设计。<a href="https://en.wikipedia.org/wiki/Event_(computing)">事件</a>表示已经发生或即将在特定时间发生的事情。MIDI 事件用信息(原子形式的信息包)表示。<em></em>
+</p>
+
+<h3 id="transport">传输</h3>
+
+<p>MIDI 信息通过<a href="https://en.wikipedia.org/wiki/Transport_layer">传输层</a>(缩写形式为“传输”)进行编码和传递,传输会将原始 MIDI 数据发送给接收者,以便接收者随后将数据解码到信息中。<em></em>
+</p>
+
+<p>基于硬件的 MIDI 传输包括:
+</p>
+<ul>
+<li>使用 <a href="https://en.wikipedia.org/wiki/DIN_connector">5-pin DIN</a> 连接器的 MIDI 1.0 电流回路</li>
+<li>USB</li>
+<li>蓝牙低功耗 (BLE)</li>
+</ul>
+
+<h3 id="messageRepresentation">信息呈现方式</h3>
+
+<p>MIDI 传输规范介绍了信息的传递方式。尽管信息的封装在最低级别是特定于传输进行的,但是在较高级别,应用可以将按时间排序的信息序列视为划分界线的<a href="https://en.wikipedia.org/wiki/Bytestream">字节流</a>。这可能是因为,如果信息边界的起点已知,则每条信息都会包含足够的信息来确定其总长度。
+</p>
+
+<p>大多数 MIDI 信息都比较短(一到三个字节),不过您可以通过 SysEx 实现较长的信息。<em></em>
+</p>
+
+<h3 id="timestamps">时间戳</h3>
+
+<p><a href="https://en.wikipedia.org/wiki/Timestamp">时间戳</a>是在原始时间或接收信息后(具体取决于传输)附加到信息的可选标签。时间戳用时间单位表示,如秒或<a href="https://en.wikipedia.org/wiki/Jiffy_(time)">滴答声</a>。
+</p>
+
+<p>在没有显式时间戳的情况下,系统必须替换紧挨着的上一条信息或电流时间的时间戳。这些时间戳(无论显式或隐式)的准确性是影响基于 MIDI 的系统的可靠性的重要因素。
+</p>
+
+<p>时间戳不是 MIDI 1.0 协议的组成部分,它们通常会被添加为平台专用 API 的一部分。BLE 传输中有相应时间戳,可以表明一个 BLE 文件包内的多条信息各自的发送时间。
+</p>
+
+<h3 id="devices">设备</h3>
+
+<p><a href="https://en.wikipedia.org/wiki/Peripheral">外围设备</a>为计算机提供输入/输出 (I/O) 功能。“MIDI 外围设备”和“MIDI 设备”这两个术语通常指支持 MIDI 协议的各种硬件或软件模块。<em></em><em></em>在本文中,MIDI 外围设备指物理实体,MIDI 设备指实际实现 MIDI 的模块。
+<em></em><em></em></p>
+
+<h3 id="ports">端口</h3>
+
+<p><a href="https://en.wikipedia.org/wiki/Computer_port_(hardware)">端口</a>是计算机和外围设备之间的接口点。
+</p>
+
+<p>MIDI 1.0 使用 5-pin DIN 插座作为端口。端口有三种:OUT(MIDI 数据的源)、IN(MIDI 数据的接收器)或 THRU(表示直接路由到 OUT 的 IN)。<em></em><em></em><em></em><em></em><em></em>
+</p>
+
+<p>USB 和 BLE 等其他传输端口是<a href="https://en.wikipedia.org/wiki/Computer_port_(software)">端口概念</a>的延伸。
+</p>
+
+<p>MIDI 设备拥有至少一个 OUT 端口、IN 端口,或同时具有两种端口。<em></em><em></em>
+</p>
+
+<p>MIDI 设备提供源自每个 OUT 端口的信息流,并接收抵达每个 IN 端口的信息流。<em></em><em></em>当然,术语 IN 和 OUT 对应于一个端口;反向的术语对应于另一个端口。<em></em><em></em>
+</p>
+
+<h3 id="connection">连接</h3>
+
+<p>在 MIDI 1.0 传输中,由于电流回路的性质,一个 OUT 端口最多能连接一个 IN 或 THRU 端口。<em></em><em></em><em></em>USB 和 BLE 传输中最底层的情况也是如此(尽管您可以通过实现修复信息流,以便它能传送到多个 IN 端口)。<em></em>
+</p>
+
+<h3 id="cable">线缆</h3>
+
+<p>MIDI 1.0 <a href="https://en.wikipedia.org/wiki/Cable">线缆</a>是连接 OUT 端口和 IN 或 THRU 端口的物理线束。<em></em><em></em><em></em>线缆仅用于传输数据。
+</p>
+
+<p class="note">
+<strong>注意</strong>:有一种针对 MIDI 的非标准修改,可以通过两个未使用的 PIN 供电,称为“幻象电源”。<em></em>
+</p>
+
+<p><a href="https://en.wikipedia.org/wiki/USB#Cabling">USB 线缆</a>和 MIDI 1.0 线缆类似,不过它有多种连接器类型,并且 IN/OUT/THRU 概念被替换为主机/外围设备角色。<em></em><em></em><em></em>
+</p>
+
+<p>在 USB 主机模式下操作时,主机设备会为 MIDI 外围设备供电。大多数小型 MIDI 外围设备使用一个 USB 单元负载 (100mA) 或者更少电量,而一些较大型的外围设备或配有音频输出或指示灯的外围设备所需的电量比主机设备能够提供的电量多。如果您遇到问题,请尝试其他 MIDI 外围设备或接通电源的 USB 集线器。
+</p>
+
+<h3 id="channel">通道</h3>
+
+<p>每个 MIDI 信息流均在 16 个通道间进行多路复用。<em></em>大多数信息都针对特定通道,不过也有些信息类型不是针对特定通道。按照惯例,尽管通道值用 0 到 15 表示,但通道按 1 到 16 计数。
+</p>
+
+<p>如果应用需要超过 16 个通道,或者需要的吞吐量超过一个信息流所能支持的限度,则必须使用多个端口。
+</p>
+
+<p>在 MIDI 1.0 中,可使用多根线缆连接端口对来实现上述目的。
+</p>
+
+<p>在使用 USB 传输的 MIDI 中,单个 USB 端点可以支持多个端口,每个端口由线缆编号 [sic] 标识。<em></em>根据 USB MIDI 规范,线缆编号可标识端点中的虚拟端口。<em></em>
+</p>
+
+<p class="note">
+<strong>注意</strong>:在标识端口时,端口编号是一个更为准确的术语。<em></em>
+</p>
+
+<p>这样一来,单个 USB 物理线缆就可以承载 16 个以上的通道。
+</p>
+
+<h2 id="platformImplementation">平台实现</h2>
+
+<p>如简介中所述,这些通用 MIDI 概念适用于所有实现。有关 Android 平台上的概念的解释说明,请参阅<a href="http://developer.android.com/reference/android/media/midi/package-summary.html">针对 <code>android.media.midi</code> 的 Android MIDI 用户指南</a>。
+</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/audio/src.html b/zh-cn/devices/audio/src.html
new file mode 100644
index 0000000..d452c4f
--- /dev/null
+++ b/zh-cn/devices/audio/src.html
@@ -0,0 +1,80 @@
+<html devsite><head>
+    <title>采样率转换</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 The Android Open Source Project
+
+      Licensed under the Apache License, Version 2.0 (the "License");
+      you may not use this file except in compliance with the License.
+      You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      See the License for the specific language governing permissions and
+      limitations under the License.
+  -->
+
+<h2 id="srcIntro">简介</h2>
+
+<p>
+有关采样率转换(也称为“重新采样”)的一般定义,请参阅维基百科文章<a href="http://en.wikipedia.org/wiki/Resampling_(audio)">重新采样(音频)</a>。本文的其余部分将介绍 Android 中的重新采样。相关术语,请参阅<a href="terminology.html#srcTerms">采样率转换</a>一节。
+</p>
+
+<p>
+采样率转换是将具有某一采样率的离散样本流更改为具有另一采样率的流的过程。采样率转换器(即重新采样器)是执行采样率转换的模块。对于重新采样器,原始流称为源信号,而重新采样的流称为设备信号。
+</p>
+
+<p>
+在 Android 中有多处需要用到重新采样器。例如,以 44.1 kHz 采样率编码的 MP3 文件,需要在内部支持 48 kHz 音频的 Android 设备上进行播放。在这种情况下,会使用重新采样器将 MP3 输出音频从 44.1 kHz 源采样率升采样到 Android 设备中使用的 48 kHz 设备采样率。
+</p>
+
+<p>
+重新采样器的特性可以使用指标来表示,包括:
+</p>
+
+<ul>
+<li>信号整体幅度的保存程度</li>
+<li>信号频率带宽的保存程度(受设备采样率的限制)</li>
+<li>通过重新采样器的整体延迟时间</li>
+<li>有关频率的一致相位和群组延迟</li>
+<li>计算复杂度(以 CPU 周期或功耗表示)</li>
+<li>允许的源采样率和设备采样率的比率</li>
+<li>动态更改采样率比率的能力</li>
+<li>支持的数字音频采样格式</li>
+</ul>
+
+<p>
+理想的重新采样器具有如下特点:精确保留源信号的幅度和频率带宽(受设备采样率的限制)、具有最短且一致的延迟时间、计算复杂度极低、允许任意动态转换比率,并且支持所有常见的数字音频采样格式。实际上,理想的重新采样器并不存在,实际的重新采样器会在这些特性上进行折衷。例如,理想质量的目标与短延迟时间和低复杂度相冲突。
+</p>
+
+<p>
+Android 包括各种音频重新采样器,因此可以根据应用使用情形和负载进行适当折衷。下面的<a href="#srcResamplers">重新采样器实现</a>部分列出了可用的重新采样器,总结了它们的特性,并且确定了它们通常的使用情形。
+</p>
+
+<h2 id="srcResamplers">重新采样器实现</h2>
+
+<p>
+可用的重新采样器实现会频繁变化,并且可由原始设备制造商 (OEM) 自定义。从 Android 4.4 开始,默认重新采样器包括(按照信号失真降序和计算复杂度升序的顺序):</p>
+
+<ul>
+<li>线性</li>
+<li>立方</li>
+<li>具有原始系数的 sinc</li>
+<li>具有修订系数的 sinc</li>
+</ul>
+
+<p>
+一般来说,sinc 重新采样器更适合用来播放品质较高的音乐,而其他重新采样器也应保留下来,以便在质量要求不那么高的情况(例如“按键声”或类似情况)下使用。
+</p>
+
+<p>
+所选择的特定重新采样器实现取决于使用情形、负载以及系统属性 <code>af.resampler.quality</code> 的值。有关详细信息,请参阅 AudioFlinger 中的音频重新采样器源代码。
+</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/audio/testing_circuit.html b/zh-cn/devices/audio/testing_circuit.html
new file mode 100644
index 0000000..e15a02d
--- /dev/null
+++ b/zh-cn/devices/audio/testing_circuit.html
@@ -0,0 +1,63 @@
+<html devsite><head>
+    <title>灯光测试电路</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 The Android Open Source Project
+
+      Licensed under the Apache License, Version 2.0 (the "License");
+      you may not use this file except in compliance with the License.
+      You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      See the License for the specific language governing permissions and
+      limitations under the License.
+  -->
+
+<p>文件 <a href="http://developer.android.com/downloads/partner/audio/av_sync_board.zip">av_sync_board.zip</a> 包含用于 A/V 同步和延迟测试印刷电路板 (PCB) 的 CAD 文件。此类文件包括制作图、EAGLE CAD、原理图和 BOM。请参阅<a href="latency.html">音频延迟</a>,了解推荐的测试方法。
+</p>
+
+<p>此 PCB 可用于帮助测量设备的通知 LED 或屏幕背光闪烁与检测到音频信号之间间隔的时间。当结合使用双通道示波器和适用的测试应用时,它可以显示检测到灯光与检测到音频之间的时间差。这假设 LED 或背光的响应时间和灯光检测器的响应时间相对于音频来说可忽略不计。
+</p>
+
+<p>此设计按“原样”提供,对于设计中的任何错误,我们概不负责。不过,如果您有任何改进建议,请将其发布到 <a href="https://groups.google.com/forum/#!forum/android-porting">android-porting</a> 网上论坛。
+</p>
+
+<p>当然,这并不是测量 A/V 同步和延迟的唯一方式(也不一定是最佳方式),如果您有其他方法,也欢迎您发布到 android-porting 网上论坛。
+</p>
+
+<p>目前对于使用此特定 PCB 并没有兼容性要求。我们提供 PCB 是为了鼓励您继续关注音频效果。
+</p>
+
+<h2 id="images">图片</h2>
+
+<p>下方图片显示的是实际操作中的电路。
+</p>
+
+<img style="margin:1.5em auto" src="images/breadboard.jpg" alt="电路试验板原型" id="figure1"/>
+<p class="img-caption">
+  <strong>图 1. </strong> 电路试验板原型</p>
+
+<img style="margin:1.5em auto" src="images/pcb.jpg" alt="PCB 的早期运行阶段" id="figure2"/>
+<p class="img-caption">
+  <strong>图 2. </strong> PCB 的早期运行阶段</p>
+
+<img style="margin:1.5em auto" src="images/display.jpg" alt="示例显示屏" id="figure3"/>
+<p class="img-caption">
+  <strong>图 3. </strong> 示例显示屏</p>
+
+<p>此图显示的是未指定设备、软件版本和测试条件的范围显示屏;得出的不是典型结果,不能用于推断其他情况。
+</p>
+
+<h2 id="video">视频</h2>
+
+<p>此 <a href="http://www.youtube.com/watch?v=f95S2IILBJY">YouTube 视频</a>显示了正在运行的电路试验板版本的测试电路。请跳至 1:00 处查看电路。
+</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/audio/usb.html b/zh-cn/devices/audio/usb.html
new file mode 100644
index 0000000..345a947
--- /dev/null
+++ b/zh-cn/devices/audio/usb.html
@@ -0,0 +1,364 @@
+<html devsite><head>
+    <title>USB 数字音频</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 The Android Open Source Project
+
+      Licensed under the Apache License, Version 2.0 (the "License");
+      you may not use this file except in compliance with the License.
+      You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      See the License for the specific language governing permissions and
+      limitations under the License.
+  -->
+
+<p>本文综述了 Android 对 USB 数字音频和相关 USB 协议的支持。
+</p>
+
+<h3 id="audience">目标读者</h3>
+
+<p>本文的目标读者是 Android 设备原始设备制造商 (OEM)、SoC 供应商、USB 音频外设供应商、高级音频应用开发者以及希望详细了解 Android 上的 USB 数字音频内件的其他人士。
+</p>
+
+<p>Nexus 设备的最终用户则应该查看 <a href="https://support.google.com/nexus/">Nexus 帮助中心</a>中的<a href="https://support.google.com/nexus/answer/6127700">使用 USB 主机模式录制和播放音频</a>一文。虽然这篇文章并非面向最终用户,但某些发烧友级消费者可能会发现感兴趣的部分。</p>
+
+<h2 id="overview">USB 概览</h2>
+
+<p>维基百科 <a href="http://en.wikipedia.org/wiki/USB">USB</a> 一文对通用串行总线 (USB) 进行了非正式描述,而 <a href="http://www.usb.org/">USB Implementers Forum, Inc</a> 发布的标准给出了正式定义。为了方便起见,我们在本文中总结了重要的 USB 概念,但上述标准仍是权威参考。
+</p>
+
+<h3 id="terminology">基本概念和术语</h3>
+
+<p>USB 是一种<a href="http://en.wikipedia.org/wiki/Bus_(computing)">总线</a>,具有单个数据传输操作启动器,称为“主机”。<i></i>主机通过总线与<a href="http://en.wikipedia.org/wiki/Peripheral">外设</a>进行通信。
+</p>
+
+<p class="note"><strong>注意</strong>:术语“设备”和“配件”是“外设”的常见同义词。<i></i><i></i><i></i>在本文中,我们避免使用这些术语,因为它们可能与 Android <a href="http://en.wikipedia.org/wiki/Mobile_device">设备</a>或称为<a href="http://developer.android.com/guide/topics/connectivity/usb/accessory.html">配件模式</a>的 Android 特定概念相混淆。
+</p>
+
+<p>主机的一个重要作用是“枚举”:检测哪些外设连接到总线并通过“描述符”查询其属性的过程。<i></i><i></i>
+</p>
+
+<p>外设可能是一个物理对象,但实际上实现了多个逻辑“功能”。<i></i>例如,摄像头外设可以兼备相机功能和麦克风音频功能。
+</p>
+
+<p>每个外设功能都有一个“接口”,用于定义与该功能通信所用的协议。<i></i>
+</p>
+
+<p>主机通过连接到<a href="http://en.wikipedia.org/wiki/Communication_endpoint">端点</a>、数据源或外设功能之一提供的接收器的<a href="http://en.wikipedia.org/wiki/Stream_(computing)">管道</a>与外设进行通信。
+</p>
+
+<p>有两种管道:“消息”和“信息流”。<i></i><i></i>消息管道用于双向控制和状态。信息流管道用于单向数据传输。
+</p>
+
+<p>主机发起所有数据传输,因此术语“输入”和“输出”是相对于主机而言的。<i></i><i></i>输入操作将数据从外设传输到主机,而输出操作则将数据从主机传输到外设。
+</p>
+
+<p>有三种主要的数据传输模式:“中断”、“批量”和“等时”。<i></i><i></i><i></i>我们将在音频上下文中进一步讨论等时模式。
+</p>
+
+<p>外设可能具有连接到外部世界(超出外设自身范围)的“终端”。<i></i>这样,外设可以在 USB 协议和“实际”信号之间进行转换。终端是功能的逻辑对象。
+</p>
+
+<h2 id="androidModes">Android USB 模式</h2>
+
+<h3 id="developmentMode">开发模式</h3>
+
+<p>
+自 Android 首次发布以来,“开发模式”就一直存在。<i></i>在运行桌面操作系统(如 Linux、Mac OS X 或 Windows)的主机 PC 中,Android 设备显示为 USB 外设。唯一可见的外设功能是 <a href="http://en.wikipedia.org/wiki/Android_software_development#Fastboot">Android fastboot</a> 或 <a href="http://developer.android.com/tools/help/adb.html">Android 调试桥 (adb)</a>。fastboot 和 adb 协议所在层高于 USB 批量数据传输模式所在层。
+</p>
+
+<h3 id="hostMode">主机模式</h3>
+
+<p>
+<i></i>“主机模式”在 Android 3.1(API 级别 12)中被引入。
+</p>
+
+<p>由于 Android 设备必须充当主机,并且大多数 Android 设备都包含一个不直接允许主机操作的微型 USB 连接器,因此通常需要如下 On-The-Go (<a href="http://en.wikipedia.org/wiki/USB_On-The-Go">OTG</a>) 适配器:</p>
+
+<img src="images/otg.jpg" style="image-orientation: 90deg;" height="50%" width="50%" alt="OTG" id="figure1"/>
+<p class="img-caption">
+  <strong>图 1.</strong> On-The-Go (OTG) 适配器</p>
+
+<p>Android 设备可能无法提供充足的电力来运行特定的外设,具体取决于外设需要的电力以及 Android 设备能够提供的电力。即使能够提供充足的电力,Android 设备的电池电量也可能会大幅下降。对于这些情况,请使用供电<a href="http://en.wikipedia.org/wiki/USB_hub">集线器</a>,如下图所示:</p>
+
+<img src="images/hub.jpg" alt="电源集线器" id="figure2"/>
+<p class="img-caption">
+  <strong>图 2.</strong> 供电集线器</p>
+
+<h3 id="accessoryMode">配件模式</h3>
+
+<p>
+配件模式在 Android 3.1(API 级别 12)中被引入,并将其反向移植到 Android 2.3.4。<i></i>在这种模式下,Android 设备作为 USB 外设运行,并受另一个设备(例如,充当主机的基座)控制。开发模式与配件模式之间的区别在于,在配件模式下,除了 adb 之外,主机还可以看到其他 USB 功能。Android 设备从开发模式开始运行,然后通过重新协商过程转换到配件模式。
+</p>
+
+<p>配件模式在 Android 4.1 中增加了功能,特别是下述音频功能。
+</p>
+
+<h2 id="usbAudio">USB 音频</h2>
+
+<h3 id="class">USB 类</h3>
+
+<p>每个外设功能都有一个关联的设备类文档,用于指定该功能的标准协议。<i></i>这使得类兼容主机和外设功能可以互操作,而无需详细了解彼此的运行原理。<i></i>如果主机和外设由不同的实体提供,则类兼容性至关重要。
+</p>
+
+<p>术语“免驱动”是“类兼容”的常见同义词,表示可以使用此类外设的标准功能,而无需安装特定于操作系统的<a href="http://en.wikipedia.org/wiki/Device_driver">驱动程序</a>。<i></i><i></i>您可以认为,如果某个外设宣称“无需驱动程序”便可用于主要桌面操作系统,那么该外设属于类兼容外设,但可能有例外情况。
+</p>
+
+<h3 id="audioClass">USB 音频类</h3>
+
+<p>在本文中,我们只关注实现音频功能的外设,因而仅介绍音频设备类。USB 音频类规范存在以下两个版本:类 1 (UAC1) 和类 2 (UAC2)。
+</p>
+
+<h3 id="otherClasses">与其他类比较</h3>
+
+<p>USB 包括许多其他设备类,其中一些类可能会与音频类相混淆。<a href="http://en.wikipedia.org/wiki/USB_mass_storage_device_class">大容量存储类</a> (MSC) 用于面向扇区的媒体访问,而<a href="http://en.wikipedia.org/wiki/Media_Transfer_Protocol">媒体传输协议</a> (MTP) 则用于对媒体进行完全文件访问。MSC 和 MTP 可以用于传输音频文件,但只有 USB 音频类适用于实时流式传输。
+</p>
+
+<h3 id="audioTerminals">音频终端</h3>
+
+<p>音频外设的终端通常是模拟的。在外设输入终端提供的模拟信号通过<a href="http://en.wikipedia.org/wiki/Analog-to-digital_converter">模拟转数字转换器</a> (ADC) 转换为数字,并通过 USB 协议进行传输,以供主机消耗。ADC 是主机的数据源。<i></i>同样,主机通过 USB 协议将数字音频信号发送到外设,然后<a href="http://en.wikipedia.org/wiki/Digital-to-analog_converter">数字转模拟转换器</a> (DAC) 对信号进行转换并呈现给模拟输出终端。DAC 是主机的接收器。<i></i>
+</p>
+
+<h3 id="channels">通道</h3>
+
+<p>具有音频功能的外设可以包括源终端、接收终端或两者。每个方向可能有一个通道(单声道)、两个通道(立体声)或更多。<i></i><i></i>具有两个以上通道的外设称为多声道。<i></i>通常将立体声流解释为由左和右声道组成,并且延伸为将多通道流解释为具有对应于每个声道的空间位置。<i></i><i></i>然而,没有为每个通道分配任何特定的标准空间含义也是非常合适的(相较于 <a href="http://en.wikipedia.org/wiki/HDMI">HDMI</a> 而言,对于 USB 音频尤为如此)。在这种情况下,由应用和用户决定每个通道的使用方式。例如,四通道 USB 输入流可以将前三个通道连接到房间内的各种麦克风,最后一个通道从 AM 收音机接收输入。
+</p>
+
+<h3 id="isochronous">等时传输模式</h3>
+
+<p>USB 音频采用等时传输模式实现其实时特性,但代价是无法实现错误恢复。在等时模式下,带宽得到保证,并使用循环冗余校验 (CRC) 检测数据传输错误。但是在发生错误的情况下,不会进行包确认或重新传输。
+</p>
+
+<p>在每个起始帧 (SOF) 周期内发生等时传输。SOF 周期为全速 1 毫秒,高速 125 微秒。每个全速帧可承载高达 1023 字节的有效载荷,高速帧可承载 1024 字节。综合这两种情况,我们计算出最大传输速率为每秒 1023000 或 8192000 字节。这为组合音频采样率、通道数和位深设置了理论上限。实际上限更低。
+</p>
+
+<p>在等时模式下,有三种子模式:</p>
+
+<ul>
+<li>自动调节</li>
+<li>异步</li>
+<li>同步</li>
+</ul>
+
+<p>在自动调节子模式下,外设接收器或信号源根据主机的潜在变化采样率进行调节。
+</p>
+
+<p>在异步(也称为隐式反馈)子模式下,接收器或信号源确定采样率,然后主机相应地做出调整。异步子模式的主要理论优势是信号源或接收器 USB 时钟在物理和电气上更接近于驱动 DAC 或 ADC 的时钟(实际上可能与驱动 DAC 或 ADC 的时钟相同或从其衍生而来)。这种接近意味着异步子模式应该不太容易受到时钟抖动的影响。此外,DAC 或 ADC 使用的时钟可能具有比主机时钟更高的精度和更低的偏移。
+</p>
+
+<p>在同步子模式下,每个 SOF 周期传输固定数量的字节。音频采样率实际上派生自 USB 时钟。同步子模式不常用于音频,因为主机和外设均受到 USB 时钟的控制。
+</p>
+
+<p>下表对等时子模式进行了总结:</p>
+
+<table>
+<tbody><tr>
+  <th>子模式</th>
+  <th>每包<br />字节数</th>
+  <th>采样率<br />决定因素</th>
+  <th>是否用于音频</th>
+</tr>
+<tr>
+  <td>自动调节</td>
+  <td>不固定</td>
+  <td>主机</td>
+  <td>是</td>
+</tr>
+<tr>
+  <td>异步</td>
+  <td>不固定</td>
+  <td>外设</td>
+  <td>是</td>
+</tr>
+<tr>
+  <td>同步</td>
+  <td>固定</td>
+  <td>USB 时钟</td>
+  <td>否</td>
+</tr>
+</tbody></table>
+
+<p>在实践中,子模式当然重要,但也应考虑其他因素。
+</p>
+
+<h2 id="androidSupport">Android 对 USB 音频类的支持</h2>
+
+<h3 id="developmentAudio">开发模式</h3>
+
+<p>开发模式不支持 USB 音频。
+</p>
+
+<h3 id="hostAudio">主机模式</h3>
+
+<p>Android 5.0(API 级别 21)及以上版本支持 USB 音频类 1 (UAC1) 功能的一部分:</p>
+
+<ul>
+<li>Android 设备必须作为主机</li>
+<li>音频格式必须是 PCM(接口类型 I)</li>
+<li>位深必须是 16 位、24 位或 32 位,其中 24 位有用音频数据在 32 位字的最高有效位内左对齐</li>
+<li>采样率必须是 48 kHz、44.1 kHz、32 kHz、24 kHz、22.05 kHz、16 kHz、12 kHz、11.025 kHz 或 8 kHz</li>
+<li>通道数必须为 1(单声道)或 2(立体声)</li>
+</ul>
+
+<p>查看 Android 框架源代码时,可能会发现除支持这些功能所需最低代码之外的附加代码。但此代码尚未经过验证,因此尚未声明更高级的功能。
+</p>
+
+<h3 id="accessoryAudio">配件模式</h3>
+
+<p>Android 4.1(API 级别 16)增加了对主机音频播放的有限支持。在配件模式下,Android 会自动将其音频输出导向到 USB。也就是说,Android 设备充当主机(例如基座)的数据源。
+</p>
+
+<p>配件模式音频具有以下特点:</p>
+
+<ul>
+<li>Android 设备必须由能够首先将 Android 设备从开发模式切换到配件模式的信息丰富的主机控制,然后主机必须从适当的端点传输音频数据。因此,Android 设备不会对主机显示为“免驱动”。
+</li>
+<li>方向必须为输入(相对于主机而言)<i></i></li>
+<li>音频格式必须为 16 位 PCM</li>
+<li>采样率必须为 44.1 kHz</li>
+<li>通道数必须为 2(立体声)</li>
+</ul>
+
+<p>配件模式音频尚未广泛采用,目前不推荐用于新设计。
+</p>
+
+<h2 id="applications">USB 数字音频的应用</h2>
+
+<p>顾名思义,USB 数字音频信号由<a href="http://en.wikipedia.org/wiki/Digital_data">数字</a>数据流表示,而非常见的 TRS 迷你<a href="http://en.wikipedia.org/wiki/Phone_connector_(audio)">耳机连接器</a>使用的<a href="http://en.wikipedia.org/wiki/Analog_signal">模拟</a>信号。最终任何数字信号都必须先转换为模拟信号,然后才能被听到。选择在哪里进行转换时需要做出取舍。
+</p>
+
+<h3 id="comparison">两种 DAC 设计</h3>
+
+<p>在下面的示例图中,我们比较了两种设计。首先,我们设计了一个配有应用处理器 (AP)、板载 DAC、放大器和连接到耳机的模拟 TRS 连接器的移动设备。我们还考虑设计一个将 USB 连接到外部 USB DAC 和放大器并且配备耳机的移动设备。
+</p>
+
+<img src="images/dac.png" alt="DAC 比较" id="figure3"/>
+<p class="img-caption">
+  <strong>图 3.</strong> 两个 DAC 的比较</p>
+
+<p>哪个设计更好?答案取决于您的需求。每个设计各有优缺点。
+</p>
+<p class="note"><strong>注意</strong>:这是一个人为的比较,因为真正的 Android 设备可能同时具有这两种选项。
+</p>
+
+<p>第一个设计 A 更简单、更便宜、消耗更少的功率,并且将是更可靠的设计(假设其他组件同等可靠)。然而,通常需要权衡音频质量和其他要求。例如,如果这是一个大众市场设备,则可能需要适应普通消费者的需求,而不是针对发烧友。
+</p>
+
+<p>在第二个设计中,外部音频外设 C 可以专为更高的音频质量和更大的功率输出而设计,不会影响基本大众市场 Android 设备 B 的成本。是的,这是一个更昂贵的设计,而且成本只有真正有需求的人会去承担。
+</p>
+
+<p>移动设备因具有高密度电路板而声名狼藉,因为带来了更多<a href="http://en.wikipedia.org/wiki/Crosstalk_(electronics)">串扰</a>机会,可能会降低相邻的模拟信号质量。数字通信不易受<a href="http://en.wikipedia.org/wiki/Noise_(electronics)">噪音</a>影响,因此将 DAC 从 Android 设备 A 移到外部电路板 C,可使最终的模拟阶段在物理和电气上与密集且嘈杂的电路板相隔离,从而产生更高的保真音频。
+</p>
+
+<p>另一方面,第二种设计更为复杂,复杂性越高,失败的几率就越高。还有来自 USB 控制器的额外延迟。
+</p>
+
+<h3 id="hostApplications">主机模式应用</h3>
+
+<p>典型的 USB 主机模式音频应用包括:</p>
+
+<ul>
+<li>听音乐</li>
+<li>电话</li>
+<li>即时通讯和语音聊天</li>
+<li>录音</li>
+</ul>
+
+<p>对于所有这些应用,Android 会检测到兼容的 USB 数字音频外设,并根据音频策略规则自动导向音频播放和捕获。立体声内容在外设的前两个通道上播放。
+</p>
+
+<p>没有特定于 USB 数字音频的 API。对于高级用途,自动导向可能会干扰 USB 感知的应用。对于这样的应用,请通过<a href="http://developer.android.com/tools/index.html">设置/开发者选项</a>的媒体部分中的相应控件停用自动导向。
+</p>
+
+<h3 id="hostDebugging">在主机模式下进行调试</h3>
+
+<p>在 USB 主机模式下,通过 USB 进行 adb 调试不可用。请参阅 <a href="http://developer.android.com/tools/help/adb.html">Android 调试桥</a>的<a href="http://developer.android.com/tools/help/adb.html#wireless">无线用法</a>部分,了解备选方案。
+</p>
+
+<h2 id="compatibility">实现 USB 音频</h2>
+
+<h3 id="recommendationsPeripheral">面向音频外设供应商的建议</h3>
+
+<p>为了与 Android 设备进行互操作,音频外设供应商应该:</p>
+
+<ul>
+<li>采用兼容音频类的设计;目前 Android 目标是类 1,但是计划兼容类 2 是明智之举</li>
+<li>避免<a href="http://en.wiktionary.org/wiki/quirk">怪异行为</a></li>
+<li>测试与参考和热门 Android 设备的互操作性</li>
+<li>清楚地记录支持的功能、音频类兼容性、电源要求等,以便消费者做出明智的决定</li>
+</ul>
+
+<h3 id="recommendationsAndroid">面向 Android 设备 OEM 和 SoC 供应商的建议</h3>
+
+<p>为了支持 USB 数字音频,设备 OEM 和 SoC 供应商应该:</p>
+
+<ul>
+<li>设计支持 USB 主机模式的硬件</li>
+<li>通过 <code>android.hardware.usb.host.xml</code> 功能标记在框架级别启用通用 USB 主机支持</li>
+<li>启用所有需要的内核功能:USB 主机模式、USB 音频、等时传输模式;请参阅 <a href="/devices/tech/config/kernel.html">Android 内核配置</a></li>
+<li>及时了解最新的内核版本和补丁程序;尽管类兼容是一个至高的目标,但是仍然存在具有<a href="http://en.wiktionary.org/wiki/quirk">怪异行为</a>的音频外设,不过最新的内核提供了解决这些怪异行为的方法</li>
+<li>启用 USB 音频策略,如下所述</li>
+<li>将 audio.usb.default 添加到 device.mk 中的 PRODUCT_PACKAGES</li>
+<li>测试与常见 USB 音频外设的互操作性</li>
+</ul>
+
+<h3 id="enable">如何启用 USB 音频策略</h3>
+
+<p>要启用 USB 音频,请在音频策略配置文件中添加一个条目。通常位于以下位置:</p>
+<pre class="devsite-click-to-copy">
+device/oem/codename/audio_policy.conf
+</pre>
+<p>路径名中的“oem”应替换为制造 Android 设备的 OEM 的名称,“codename”应替换为设备代号。
+</p>
+
+<p>以下是一个示例条目:</p>
+
+<pre class="devsite-click-to-copy">
+audio_hw_modules {
+  ...
+  usb {
+    outputs {
+      usb_accessory {
+        sampling_rates 44100
+        channel_masks AUDIO_CHANNEL_OUT_STEREO
+        formats AUDIO_FORMAT_PCM_16_BIT
+        devices AUDIO_DEVICE_OUT_USB_ACCESSORY
+      }
+      usb_device {
+        sampling_rates dynamic
+        channel_masks dynamic
+        formats dynamic
+        devices AUDIO_DEVICE_OUT_USB_DEVICE
+      }
+    }
+    inputs {
+      usb_device {
+        sampling_rates dynamic
+        channel_masks AUDIO_CHANNEL_IN_STEREO
+        formats AUDIO_FORMAT_PCM_16_BIT
+        devices AUDIO_DEVICE_IN_USB_DEVICE
+      }
+    }
+  }
+  ...
+}
+</pre>
+
+<h3 id="sourceCode">源代码</h3>
+
+<p>用于 USB 音频的音频硬件抽象层 (HAL) 实现位于以下位置:</p>
+<pre class="devsite-click-to-copy">
+hardware/libhardware/modules/usbaudio/
+</pre>
+<p>USB 音频 HAL 在很大程度上取决于 tinyalsa(如<a href="terminology.html">音频术语</a>中所述)。<i></i>虽然 USB 音频依赖于等时传输,但这是通过 ALSA 实现抽象出来的。所以,USB 音频 HAL 和 tinyalsa 不需要关注 USB 协议的这部分。
+</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/audio/warmup.html b/zh-cn/devices/audio/warmup.html
new file mode 100644
index 0000000..6edf399
--- /dev/null
+++ b/zh-cn/devices/audio/warmup.html
@@ -0,0 +1,76 @@
+<html devsite><head>
+    <title>音频预热</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 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>音频预热是设备中的音频放大电路充满电并达到正常运行状态所需的时间。音频预热时间的主要影响因素是电源管理以及用于稳定电路的任何“de-pop”逻辑。
+</p>
+
+<p>本文档介绍了如何测量音频预热时间以及缩短预热时间的可行方法。</p>
+
+<h2 id="measuringOutput">测量输出预热时间</h2>
+
+<p>AudioFlinger 的 FastMixer 线程可自动测量输出预热时间并在 <code>dumpsys media.audio_flinger</code> 命令的输出中报告相关信息。在预热期间,FastMixer 会重复调用 <code>write()</code>,直到两个 <code>write()</code> 之间的时间达到预期值。FastMixer 通过查看硬件抽象层 (HAL) <code>write()</code> 达到稳定状态所需的时间来确定音频预热时间。
+</p>
+
+<p>要测量音频预热时间,请在启动后的不同时间针对内置扬声器和有线耳机执行以下操作。每种输出设备的预热时间通常是不同的,启动相应设备之后,请立即执行以下操作:</p>
+
+<ol>
+  <li>确保 FastMixer 已启用。</li>
+  <li>通过依次在设备上选择<b>设置 &gt; 声音 &gt; 触摸提示音</b>,启用触摸提示音。</li>
+  <li>确保音频至少已关闭三秒钟。五秒钟或更长时间会更好,因为除了 AudioFlinger 的 3 秒钟时间之外,硬件本身可能也存在自己的电源逻辑。</li>
+  <li>按主屏幕按钮,您应该会听到点击声音。</li>
+  <li>运行以下命令以接收测量的预热时间:<br /><code>adb shell dumpsys media.audio_flinger | grep measuredWarmup</code>
+
+<p>您应该会看到类似以下内容的输出:</p>
+
+<pre>
+sampleRate=44100 frameCount=256 measuredWarmup=X ms, warmupCycles=X
+</pre>
+
+<p><code>measuredWarmup=X</code> 表示完成第一组 HAL <code>write()</code> 耗用了 X 毫秒。
+</p>
+
+<p><code>warmupCycles=X</code> 表示 <code>write()</code> 的执行时间达到预期前发出的 HAL 写入请求数量。
+</p>
+</li>
+<li>进行五次测量并记录所有值及平均值。如果并非所有值都完全接近,那么可能其中的某次测量不准确。例如,音频关闭后,如果您未等待足够长的时间,将会出现预热时间小于平均值的情况。
+</li>
+</ol>
+
+<h2 id="measuringInput">测量输入预热时间</h2>
+
+<p>目前还没有用于测量音频输入预热时间的工具。不过,通过观察返回 <a href="http://developer.android.com/reference/android/media/AudioRecord.html#startRecording()">startRecording()</a> 所需的时间,可估算输入预热时间。
+</p>
+
+<h2 id="reducing">缩短预热时间</h2>
+
+<p>通常通过实施以下优化组合,可以缩短预热时间:</p>
+  <ul>
+  <li>良好的电路设计</li>
+  <li>内核设备驱动程序中的时间延迟很精确</li>
+  <li>并行(而非按顺序)执行独立的预热操作</li>
+  <li>使电路保持通电状态,或者不重新配置时钟(会增加闲置功耗)</li>
+  <li>缓存计算过的参数</li>
+  </ul>
+<p>不过,请注意避免过度优化。您可能会发现,您需要在较短预热时间和电源转换时无爆鸣之间进行权衡。
+</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/automotive.html b/zh-cn/devices/automotive.html
new file mode 100644
index 0000000..6ce780e
--- /dev/null
+++ b/zh-cn/devices/automotive.html
@@ -0,0 +1,177 @@
+<html devsite><head>
+    <title>汽车</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 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.
+  -->
+
+<img style="float: right; margin: 0px 15px 15px 15px;" src="images/ape_fwk_hal_vehicle.png" alt="Android 车载 HAL 图标"/>
+
+<p>借助各种总线拓扑,很多汽车子系统都可以实现互连以及与车载信息娱乐 (IVI) 系统的连接。不同的制造商提供的确切总线类型和协议之间有很大差异(甚至同一品牌的不同车型之间也是如此),例如控制器区域网络 (CAN) 总线、局域互联网络 (LIN) 总线、面向媒体的系统传输 (MOST) 总线以及汽车级以太网和 TCP/IP 网络(如 BroadR-Reach)。
+</p>
+<p>Android Automotive 的硬件抽象层 (HAL) 可为 Android 框架提供一致的接口,无论物理传输层如何。此车载 HAL 是开发 Android Automotive 实现的接口。</p>
+<p>系统集成商可以将特定于功能的平台 HAL 接口(如 HVAC)与特定于技术的网络接口(如 CAN 总线)连接,以实现车载 HAL 模块。典型的实现可能包括运行专有实时操作系统 (RTOS) 的专用微控制器单元 (MCU),以用于 CAN 总线访问或类似操作,该微控制器单元可通过串行链路连接到运行 Android Automotive 的 CPU。除了专用的 MCU,还可以将总线访问作为虚拟 CPU 来实现。只要实现符合车载 HAL 的接口要求,每个合作伙伴都可以选择适合硬件的架构。</p>
+
+<h2 id="arch">架构</h2>
+<p>车载 HAL 是汽车与车辆网络服务之间的接口定义:</p>
+
+<img src="images/vehicle_hal_arch.png" alt="Android 车载 HAL 架构"/>
+<p class="img-caption"><strong>图 1</strong>. 车载 HAL 与 Android Automotive 架构</p>
+
+<ul>
+<li><strong>Car API</strong>:包含 CarHvacManager、CarSensorManager 和 CarCameraManager 等 API。如需详细了解所有受支持的 API,请参阅 <code>/platform/packages/services/Car/car-lib</code>。</li>
+<li><strong>CarService</strong>:位于 <code>/platform/packages/services/Car/</code>。</li>
+<li><strong>VehicleNetworkService</strong>:通过内置安全机制控制车载 HAL。仅限访问系统组件(第三方应用等非系统组件需使用 Car API)。原始设备制造商 (OEM) 可以通过 <code>vns_policy.xml</code> 和 <code>vendor_vns_policy.xml</code> 控制访问权限。位于 <code>/platform/packages/services/Car/vehicle_network_service/</code>;有关访问车辆网络的库,请参阅 <code>/platform/packages/services/Car/libvehiclenetwork/</code>。</li>
+<li><strong>车载 HAL</strong>:定义 OEM 可以实现的属性且包含属性元数据的接口(例如,属性是否为 int,允许使用哪些更改模式)。位于 <code>hardware/libhardware/include/hardware/vehicle.h</code>。有关基本参考实现,请参阅 <code>hardware/libhardware/modules/vehicle/</code>。</li>
+</ul>
+
+<h2 id="prop">车辆属性</h2>
+<p>车载 HAL 接口基于访问(读取、写入、订阅)属性,这是特定函数的抽象表示。属性可以是只读、只写(用于将信息传递到车载 HAL 级别),或者读取和写入。对大多数属性的支持都是可选的。</p>
+<p>每个属性都由 int32 键唯一标识,且具有预定义的类型 (<code>value_type</code>):</p>
+
+<ul>
+<li><code>INT32</code>(和数组)、<code>INT64</code>、<code>BOOLEAN</code>、<code>FLOAT</code>(和数组)、字符串、字节。</li>
+<li>区域类型除了值之外还有区域。</li>
+</ul>
+
+<h3 id-="zone_type">区域类型</h3>
+<p>车载 HAL 定义了 3 种区域类型:</p>
+<ul>
+<li><code>vehicle_zone</code>:基于排的区域。</li>
+<li><code>vehicle_seat</code>:基于座位的区域。</li>
+<li><code>vehicle_window</code>:基于窗户的区域。</li>
+</ul>
+<p>每个区域属性都应使用预定义的区域类型。如有必要,您可以为每个属性使用自定义区域类型(有关详情,请参阅<a href="#prop_custom">处理自定义属性</a>)。</p>
+
+<h3 id="prop_config">配置属性</h3>
+<p>使用 <code>vehicle_prop_config_t</code> 为每个属性提供配置信息。具体信息包括:</p>
+<ul>
+<li><code>access</code>(r、w、rw)</li>
+<li><code>change_mode</code>(表示监视属性的方式:变化模式还是连续模式)</li>
+<li><code>min_value</code>(int32、float、int64)、<code>max_value</code>(int32、float、int64)</li>
+<li><code>min_sample_rate</code>、<code>max_sample_rate</code></li>
+<li><code>permission_model</code></li>
+<li><code>prop</code>(属性 ID、int)</li>
+<li><code>value_type</code></li>
+<li><code>zone_flags</code>(将受支持的区域表示为位标记)</li>
+</ul>
+<p>此外,某些属性具有表示功能的具体配置标记。</p>
+
+<h2 id="interfaces">HAL 接口</h2>
+<p>车载 HAL 使用以下接口:</p>
+<ul>
+<li><code>vehicle_prop_config_t const *(*list_properties)(..., int*
+num_properties)</code>。列出车载 HAL 所支持的所有属性的配置。车辆网络服务仅使用受支持的属性。
+</li>
+<li><code>(*get)(..., vehicle_prop_value_t *data)</code>。读取属性的当前值。对于区域属性,每个区域都可能具有不同的值。</li>
+<li><code>(*set)(..., const vehicle_prop_value_t *data)</code>。为属性写入一个值。写入结果按每个属性进行定义。</li>
+<li><code>(*subscribe)(..., int32_t prop, float sample_rate, int32_t
+zones)</code>。<ul>
+<li>开始监视属性值的变化。对于区域属性,订阅适用于请求的区域。Zones = 0 用于请求所有受支持的区域。
+</li>
+<li>车载 HAL 应该在属性值发生变化(即变化类型)或出现常量间隔(即连续类型)时调用单独的回调。</li></ul></li>
+<li><code>(*release_memory_from_get)(struct vehicle_hw_device* device,
+vehicle_prop_value_t *data)</code>。释放从 get 调用分配的内存。</li></ul>
+
+<p>车载 HAL 使用以下回调接口:</p>
+<ul>
+<li><code>(*vehicle_event_callback_fn)(const vehicle_prop_value_t
+*event_data)</code>。通知车辆属性值的变化。应只针对已订阅属性执行。</li>
+<li><code>(*vehicle_error_callback_fn)(int32_t error_code, int32_t property,
+int32_t operation).</code> 返回全局车载 HAL 级别错误或每个属性的错误。全局错误会导致 HAL 重新启动,这可能导致包括应用在内的其他组件重新启动。</li>
+</ul>
+
+<h2 id="zone_prop">处理区域属性</h2>
+<p>区域属性相当于多个属性的集合,其中每个子属性都可由指定的区域值访问。</p>
+<ul>
+<li>区域属性的 <code>get</code> 调用始终包含请求中的区域,因此,只应返回所请求区域的当前值。</li>
+<li>区域属性的 <code>set</code> 调用始终包含请求中的区域,因此,只应更改所请求的区域。</li>
+<li><code>subscribe</code> 调用包括所有已订阅区域的标记。不应报告来自未订阅区域的事件。</li>
+</ul>
+
+<h3 id="get">Get 调用</h3>
+<p>在初始化期间,由于尚未收到匹配的车辆网络消息,属性的值可能不可用。在这种情况下,<code>get</code> 调用应该返回 <code>-EAGAIN</code>。某些属性(如 HVAC)具有独立的电源开/关属性。这种属性的 <code>get</code> 的调用(关机时)应返回特殊值 <code>(VEHICLE_INT_OUT_OF_RANGE_OFF/VEHICLE_FLOAT_OUT_OF_RANGE_OFF)</code>,而不是返回错误。</p>
+<p>此外,某些属性(如 HVAC 温度)可以用某个值来表示其处于最大功率模式,而不是特定的温度值。在这种情况下,请使用特殊值表示这种状态。</p>
+<ul>
+<li>VEHICLE_INT_OUT_OF_RANGE_MAX/MIN</li>
+<li>VEHICLE_FLOAT_OUT_OF_RANGE_MAX/MIN</li>
+</ul>
+
+<p>示例:获取 HVAC 温度</p>
+<img src="images/vehicle_hvac_get.png" alt="车载 HAL get HVAC 的示例"/>
+<p class="img-caption"><strong>图 2</strong>. 获取 HVAC 温度(CS = CarService、VNS = VehicleNetworkService、VHAL = 车载 HAL)</p>
+
+<h3 id="set">Set 调用</h3>
+<p><code>set</code> 调用属于异步操作,涉及进行所请求更改之后的事件通知。在典型的操作中,<code>set</code> 调用会导致在车辆网络中发出更改请求。拥有该属性的电子控制单元 (ECU) 执行更改后,更新后的值通过车辆网络返回,而车载 HAL 会将更新后的值作为事件发送给车辆网络服务 (VNS)。</p>
+<p>某些 <code>set</code> 调用可能要求准备好初始数据,而这些数据在初始化期间可能尚不可用。在这种情况下,<code>set</code> 调用应该返回 <code>-EAGAIN</code>。某些具有独立的电源开/关的属性应在属性关闭且无法设置时返回 <code>-ESHUTDOWN</code>。</p>
+<p>在 <code>set</code> 生效之前,<code>get</code> 不一定会返回所设置的值。例外情况是更改模式为 <code>VEHICLE_PROP_CHANGE_MODE_ON_SET.</code> 的属性。此属性仅在被 Android 之外的外部组件(如 <code>VEHICLE_PROPERTY_UNIX_TIME</code> 等时钟属性)设置时才通知更改。</p>
+
+<p>示例:设置 HVAC 温度</p>
+<img src="images/vehicle_hvac_set.png" alt="车载 HAL set HVAC 的示例"/>
+<p class="img-caption"><strong>图 3</strong>. 设置 HVAC 温度(CD = CarService、VNS = VehicleNetworkService、VHAL = 车载 HAL)</p>
+
+<h2 id="prop_custom">处理自定义属性</h2>
+<p>为了满足合作伙伴的特定需求,车载 HAL 允许使用针对系统应用的自定义属性。在使用自定义属性时,请遵循以下指南:</p>
+<ul>
+<li>键值应该在 [<code>VEHICLE_PROPERTY_CUSTOM_START,
+VEHICLE_PROPERTY_CUSTOM_END</code>] 范围内。其他范围会预留以供将来的扩展功能使用;使用这种范围可能会导致将来的 Android 版本中出现冲突。</li>
+<li>仅使用定义的 <code>value_type</code>。BYTES 类型允许传递原始数据,因此,在大多数情况下是足够的。通过自定义属性频繁发送大数据可能会减缓整个车辆网络的访问速度,因此,在添加大量需要 HAL 处理的数据时要小心谨慎。</li>
+<li>将访问策略添加到 <code>vendor_vns_policy.xml</code>(否则所有访问都将被拒)。</li>
+<li>通过 <code>VendorExtensionManager</code>(适用于 Java 组件)或 Vehicle Network Service API(适用于本机)访问。请勿修改其他汽车 API,因为这样做可能会在将来导致兼容性问题。</li>
+</ul>
+
+<h2 id="prop_hvac">处理 HVAC 属性</h2>
+<p>您可以使用车载 HAL 控制 HVAC,具体方法是设置与 HVAC 相关的属性。大多数 HVAC 属性都是区域属性,但也有一些非区域(全局)属性。定义的示例属性包括:</p>
+<ul>
+<li><code>VEHICLE_PROPERTY_HVAC_TEMPERATURE_SET</code>(按每个区域设置温度)。</li>
+<li><code>VEHICLE_PROPERTY_HVAC_RECIRC_ON</code>(按每个区域控制再循环)。</li>
+</ul>
+<p>有关 HVAC 属性的完整列表,请在 <code>vehicle.h</code> 中搜索 <code>VEHICLE_PROPERTY_HVAC_*</code>。</p>
+
+<h2 id="prop_sensor">处理传感器属性</h2>
+<p>车载 HAL 传感器属性表示真实的传感器数据或策略信息,如驾驶状态。某些传感器信息(如驾驶状态和日间/夜间模式)不限制任何应用的访问,因为这些数据是构建安全车载应用所必需的。其他传感器信息(如车辆速度)更为敏感,需要用户可以管理的特定权限。</p>
+<p>支持的传感器属性包括:</p>
+<ul>
+<li><code>DRIVING_STATUS</code>(应该支持):表示在当前驾驶状态下允许的操作。此信息用于在驾驶过程中屏蔽不安全的应用。</li>
+<li><code>NIGHT_MODE</code>(应该支持):确定日间/夜间显示模式。</li>
+<li><code>GEAR_SELECTION/CURRENT_GEAR</code>:驾驶员选择的挡位与实际挡位。</li>
+<li><code>VEHICLE_SPEED</code>:车速。受权限保护。</li>
+<li><code>ODOMETER</code>:当前里程表读数。受权限保护。
+</li>
+<li><code>FUEL_LEVEL</code>:当前油位 (%)。</li>
+<li><code>FUEL_LEVEL_LOW</code>:油位是否较低(布尔值)。</li>
+</ul>
+
+<h2 id="security">安全性</h2>
+<p>车载 HAL 支持 3 个级别的数据访问安全性:</p>
+<ul>
+<li>仅限系统(由 <code>vns_policy.xml</code> 控制)</li>
+<li>允许拥有权限的应用访问(通过汽车服务)</li>
+<li>无需任何权限即可访问(通过汽车服务)</li>
+</ul>
+<p>仅允许部分系统组件直接访问车辆属性,而车辆网络服务是把关程序。大多数应用需通过汽车服务的额外把关(例如,只有系统应用可以控制 HVAC,因为这需要仅授予系统应用的系统权限)。</p>
+
+<h2 id="validation">验证</h2>
+<p>AOSP 包含以下用于开发过程的测试资源:</p>
+<ul>
+<li><code>hardware/libhardware/tests/vehicle/vehicle-hal-tool.c</code>:加载车载 HAL 并执行简单操作的命令行原生工具,有助于在开发的早期阶段让系统正常运行。</li>
+<li><code>packages/services/Car/tests/carservice_test/</code>:包含使用模拟车载 HAL 属性进行的汽车服务测试。每个属性的预期行为都会在测试中实现,这是了解预期行为的绝佳起点。</li>
+<li><code>hardware/libhardware/modules/vehicle/</code>:基本参考实现。</li>
+</ul>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/bluetooth.html b/zh-cn/devices/bluetooth.html
new file mode 100644
index 0000000..8a2b2c6
--- /dev/null
+++ b/zh-cn/devices/bluetooth.html
@@ -0,0 +1,89 @@
+<html devsite><head>
+    <title>蓝牙</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 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.
+  -->
+
+<img style="float: right; margin: 0px 15px 15px 15px;" src="images/ape_fwk_hal_bluetooth.png" alt="Android 蓝牙 HAL 图标"/>
+
+<p>Android 提供了一个默认蓝牙堆栈,该堆栈具有以下两个层级:实现核心蓝牙功能的蓝牙嵌入式系统 (BTE) 以及与 Android 框架应用通信的蓝牙应用层 (BTA)。</p>
+
+<p>要充分利用 Android 5.0 中添加的<a href="http://developer.android.com/about/versions/android-5.0.html#BluetoothBroadcasting">蓝牙低功耗 API</a>,您应实现 <a href="Android-6.0-Bluetooth-HCI-Reqs.pdf">Android 6.0 蓝牙 HCI 要求</a>。该文档最初是作为 <a href="Android-5.0-Bluetooth-HCI-Reqs.pdf">Android 5.0 蓝牙 HCI 要求</a>编写而成。</p>
+
+<h2 id="architecture">架构</h2>
+<p>蓝牙系统服务通过 JNI 与蓝牙堆栈进行通信,并通过 Binder IPC 与应用通信。系统服务向开发者提供了对各种蓝牙配置文件的访问权限。下图显示了蓝牙堆栈的常规结构:</p>
+
+<img src="images/ape_fwk_bluetooth.png" alt="Android 蓝牙架构" id="figure1"/>
+<p class="img-caption">
+  <strong>图 1.</strong> 蓝牙架构</p>
+
+<dl>
+  <dt>应用框架</dt>
+  <dd>处于应用框架级别的是应用代码,它利用 <a href="http://developer.android.com/reference/android/bluetooth/package-summary.html">android.bluetooth</a> API 与蓝牙硬件进行交互。此代码在内部通过 Binder IPC 机制调用蓝牙进程。</dd>
+
+  <dt>蓝牙系统服务</dt>
+  <dd>蓝牙系统服务(位于 <code>packages/apps/Bluetooth</code> 中)被打包为 Android 应用,并在 Android 框架层实现蓝牙服务和配置文件。该应用通过 JNI 调用 HAL 层。</dd>
+
+  <dt>JNI</dt>
+  <dd>与 <a href="http://developer.android.com/reference/android/bluetooth/package-summary.html">android.bluetooth</a> 相关联的 JNI 代码位于 <code>packages/apps/Bluetooth/jni</code> 中。当发生特定蓝牙操作时(例如发现设备时),JNI 代码会调用 HAL 层并从 HAL 接收回调。</dd>
+
+  <dt>HAL</dt>
+  <dd>硬件抽象层定义了 <a href="http://developer.android.com/reference/android/bluetooth/package-summary.html">android.bluetooth</a> API 和蓝牙进程会调用的标准接口,并且您必须实现该接口才能使蓝牙硬件正常工作。蓝牙 HAL 的头文件是 <code>hardware/libhardware/include/hardware/bluetooth.h</code>。另外,请查看所有 <code>hardware/libhardware/include/hardware/bt_*.h</code> 文件。
+  </dd>
+
+    <dt>蓝牙堆栈</dt>
+  <dd>系统为您提供了默认蓝牙堆栈(位于 <code>system/bt</code> 中)。该堆栈会实现常规蓝牙 HAL,并通过扩展程序和更改配置对其进行自定义。
+  </dd>
+
+    <dt>供应商扩展程序</dt>
+  <dd>要添加自定义扩展程序和用于跟踪的 HCI 层,您可以创建一个 libbt-vendor 模块并指定这些组件。
+  </dd>
+
+  </dl>
+
+<h2 id="implementing">实现 HAL</h2>
+<p>蓝牙 HAL 位于 <code>/hardware/libhardware/include/hardware/bluetooth.h</code> 中。因此,<code>bluetooth.h</code> 文件包含蓝牙堆栈的基本接口,并且您必须实现其功能。</p>
+
+<p>特定于配置文件的文件位于同一目录中。有关详情,请参阅 <a href="/reference/hal/dir_6b11132f1a015b03f2670f21bef1d871.html">HAL 文件参考</a>。</p>
+
+<p>以下是与配置文件相关的文件的<strong>部分</strong>列表。有关<strong>完整列表</strong>,请参阅 <code>/hardware/libhardware/include/hardware/</code> 目录:</p>
+
+<ul>
+  <li><code>bt_av.h</code>:包含 A2DP 配置文件的接口定义。</li>
+  <li><code>bt_gatt.h</code>、<code>bt_gatt_client.h</code> 和 <code>bt_gatt_server.h</code>:包含 GATT 配置文件的接口定义。</li>
+  <li><code>bt_hf.h</code>:包含 HFP 配置文件的接口定义。</li>
+  <li><code>bt_hh.h</code>:包含 HID 主机配置文件的接口定义。</li>
+  <li><code>bt_hl.h</code>:包含 HDP 配置文件的接口定义。</li>
+  <li><code>bt_mce.h</code>:包含 MAP 配置文件的接口定义。</li>
+  <li><code>bt_pan.h</code>:包含 PAN 配置文件的接口定义。</li>
+  <li><code>bt_rc.h</code>:包含 AVRCP 配置文件的接口定义。</li>
+  <li><code>bt_sock.h</code>:包含 RFCOMM 套接字的接口定义。</li>
+</ul>
+
+<p>请记住,您的蓝牙实现不限于 HAL 中提供的功能和配置文件。您可以在 <code>system/bt</code> 目录中找到蓝牙堆栈中的默认实现,该堆栈实现了默认的 HAL 以及其他功能和自定义设置。</p>
+
+<h2 id="customizing">自定义原生蓝牙堆栈</h2>
+<p>如果您使用的是默认蓝牙堆栈,但想要进行一些自定义设置,则可以执行以下操作:</p>
+<ul>
+	<li>自定义蓝牙配置文件 - 如果要添加没有由 Android 提供的 HAL 接口的蓝牙配置文件,则必须提供 SDK 插件下载方式,以使配置文件可供应用开发者使用,使这些 API 在蓝牙系统-&gt;进程应用 (<code>packages/apps/Bluetooth</code>) 间可用,并将它们添加到默认堆栈 (<code>system/bt</code>)。</li>
+	<li>自定义供应商扩展程序和配置更改 - 您可以通过创建 <code>libbt-vendor</code> 模块来添加内容,例如额外的 AT 命令或特定于设备的配置更改。有关示例,请参阅 <code>/hardware/broadcom/libbt</code> 目录。</li>
+	<li>主机控制器接口 (HCI) - 您可以通过创建一个主要用于调试跟踪的 <code>libbt-hci</code> 模块来提供自己的 HCI。有关示例,请参阅 <code>external/bluetooth/hci</code> 目录。</li>
+</ul>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/camera/camera3.html b/zh-cn/devices/camera/camera3.html
new file mode 100644
index 0000000..2dd0d59
--- /dev/null
+++ b/zh-cn/devices/camera/camera3.html
@@ -0,0 +1,75 @@
+<html devsite><head>
+    <title>相机 HAL3</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 The Android Open Source Project
+
+      Licensed under the Apache License, Version 2.0 (the "License");
+      you may not use this file except in compliance with the License.
+      You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      See the License for the specific language governing permissions and
+      limitations under the License.
+  -->
+
+<p>Android 的相机硬件抽象层 (HAL) 可将 <a href="http://developer.android.com/reference/android/hardware/Camera.html">android.hardware.Camera</a> 中较高级别的相机框架 API 连接到底层相机驱动程序和硬件。Android 5.0 推出了一种新的底层相机堆栈实现。如果您之前为旧版 Android 开发过相机 HAL 模块和驱动程序,请注意相机管道中发生的重大变化。</p>
+
+<p class="note"><strong>注意</strong>:新版相机 HAL 正在积极开发当中,随时可能会发生变化。本文档概括介绍了相机子系统的设计;如需了解详情,请参阅<a href="/devices/camera/versioning.html">相机版本支持</a>。</p>
+
+<h2 id="overview">相机 HAL1 概览</h2>
+
+<p>相机子系统的第 1 个版本被设计为具有高级控件和以下三种运行模式的黑盒子:</p>
+
+<ul>
+<li>预览</li>
+<li>视频录制</li>
+<li>静态拍摄</li>
+</ul>
+
+<p>三种模式具有略有不同又相互重叠的功能。这样就难以实现新类型的功能(例如连拍模式),因为新类型的功能会介于其中两种模式之间。</p>
+
+<img src="images/camera_block.png" alt="相机程序块示意图" id="figure1"/>
+<p class="img-caption"><strong>图 1. </strong> 相机组件</p>
+
+<p>由于很多设备仍然依赖相机 HAL1,因此 Android 7.0 继续支持该模块。此外,Android 相机服务还支持同时实现两个 HAL(1 和 3),如果您希望通过相机 HAL1 支持性能略低的前置摄像头,并通过相机 HAL3 支持更为高级的后置摄像头,那么这项支持将非常有用。</p>
+
+<p class="note"><strong>注意</strong>:相机 HAL2 不受支持,因为它是过渡到相机 HAL3 的临时步骤。</p>
+
+<p>有一种单独的相机 HAL 模块(拥有自己的<a href="/devices/camera/versioning.html#module_version">版本号</a>),其中列出了多种独立的相机设备,每种都有自己的版本号。<em></em>要支持设备 2 或更新版本,必须使用相机模块 2 或更新版本,而且此类相机模块可以具有混合的相机设备版本(我们在上文中提到 Android 支持同时实现两种 HAL,就是这个含义)。</p>
+
+<h2 id="v3-enhance">相机 HAL3 增强功能</h2>
+
+<p>重新设计 Android Camera API 的目的在于大幅提高应用对于 Android 设备上的相机子系统的控制能力,同时重新组织 API,提高其效率和可维护性。借助额外的控制能力,您可以更轻松地在 Android 设备上构建高品质的相机应用,这些应用可在多种产品上稳定运行,同时仍会尽可能使用设备专用算法来最大限度地提升质量和性能。</p>
+
+<p>版本 3 相机子系统将多个运行模式整合为一个统一的视图,您可以使用这种视图实现之前的任何模式以及一些其他模式,例如连拍模式。这样一来,便可以提高用户对聚焦、曝光以及更多后期处理(例如降噪、对比度和锐化)效果的控制能力。此外,这种简化的视图还能够使应用开发者更轻松地使用相机的各种功能。</p>
+<p>API 将相机子系统塑造为一个管道,该管道可按照 1:1 的基准将传入的帧捕获请求转化为帧。这些请求会封装有关帧的捕获和处理的所有配置信息,其中包括分辨率和像素格式;手动传感器、镜头和闪光灯控件;3A 运行模式;RAW-&gt;YUV 处理控件;统计信息生成等等。</p>
+
+<p>简单来说,应用框架从相机子系统请求帧,然后相机子系统将结果返回到输出流。此外,系统还会针对每组结果生成包含色彩空间和镜头阴影等信息的元数据。您可以将相机版本 3 看作相机版本 1 的单向流管道。它会将每个捕获请求转化为传感器捕获的一张图像,这张图像将被处理成:</p>
+
+<ul>
+<li>包含有关捕获的元数据的结果对象。</li>
+<li>图像数据的 1 到 N 个缓冲区,每个缓冲区会进入自己的目的地 Surface。</li>
+</ul>
+
+<p>可能的输出 Surface 组经过预配置:</p>
+
+<ul>
+<li>每个 Surface 都是一个固定分辨率的图像缓冲区流的目标位置。</li>
+<li>一次只能将少量 Surface 配置为输出(约 3 个)。
+</li>
+</ul>
+
+<p>一个请求中包含所需的全部捕获设置,以及要针对该请求将图像缓冲区(从总配置组)推送到其中的输出 Surface 的列表。请求可以只发生一次(使用 <code>capture()</code>),也可以无限重复(使用 <code>setRepeatingRequest()</code>)。捕获的优先级高于重复请求的优先级。</p>
+
+<img src="images/camera_simple_model.png" alt="相机数据模式" id="figure2"/>
+<p class="img-caption"><strong>图 2. </strong> 相机核心运行模式</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/camera/camera3_error_stream.html b/zh-cn/devices/camera/camera3_error_stream.html
new file mode 100644
index 0000000..4d80403
--- /dev/null
+++ b/zh-cn/devices/camera/camera3_error_stream.html
@@ -0,0 +1,64 @@
+<html devsite><head>
+    <title>错误和信息流处理</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 The Android Open Source Project
+
+      Licensed under the Apache License, Version 2.0 (the "License");
+      you may not use this file except in compliance with the License.
+      You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      See the License for the specific language governing permissions and
+      limitations under the License.
+  -->
+
+<h2 id="error-mgmt">错误管理</h2>
+<p>如果出现严重错误,则具有返回值的相机 HAL 设备操作函数将全部返回 -ENODEV/NULL。这意味着该设备无法继续操作,必须由框架进行关闭。一旦某种方法返回了此错误,或者如果调用 notify() 且返回 ERROR_DEVICE,则只能成功调用 close() 方法。所有其他方法都将返回 -ENODEV/NULL。<br />如果以错误顺序调用了设备操作,例如如果框架先调用 configure_streams() 后调用 initialize(),则该设备将会从调用中返回 -ENOSYS,且不执行任何操作。<br />图片拍摄过程中的瞬时错误必须通过 notify() 进行报告,如下所述:</p>
+<ul>
+  <li>如果整个拍摄过程失败,则必须由 HAL 进行报告,具体方法是调用 notify() 且返回 ERROR_REQUEST。在这种情况下,不能报告结果元数据或输出缓冲区的单个错误。</li>
+  <li>如果无法生成拍摄的元数据,但已填充某些图像缓冲区,则 HAL 必须调用 notify() 且返回 ERROR_RESULT。</li>
+  <li>如果无法填充输出图像缓冲区,但已生成元数据或已填充其他一些缓冲区,则 HAL 必须为各个失败的缓冲区调用 notify() 且返回 ERROR_BUFFER。</li>
+</ul>
+<p>在发生此类瞬时失败的情况下,HAL 必须仍然调用 process_capture_result 且返回有效的输出 buffer_handle_t。如果无法生成结果元数据,则应该为 NULL。如果无法填充某些缓冲区,则其同步栅栏必须设为错误状态。<br />无效的输入参数会导致相应方法返回 -EINVAL。在这种情况下,框架必须表现为如同从未进行过该调用一样。</p>
+<h2 id="stream-mgmt">信息流管理</h2>
+<h3 id="configure_streams">configure_streams</h3>
+<p>重置 HAL 相机设备的处理管道,并设置新的输入和输出信息流。此调用将使用 stream_list 中定义的信息流来替换任何现有的信息流配置。在使用 process_capture_request() 提交请求之前,此方法会在 initialize() 之后至少被调用一次。<br />stream_list 必须包含至少一个支持输出的信息流,但不得包含多个支持输入的信息流。<br />stream_list 可包含同时属于当前有效的信息流组(源自先前对 configure_stream() 的调用)中的信息流。此类信息流已具有用法、maxbuffer 和私有指针的有效值。如果此类信息流已注册缓冲区,则系统不会针对这样的信息流再次调用 register_stream_buffers(),信息流中的缓冲区可立即列入输入请求中。<br />HAL 如果需要将现有信息流的流配置更改为新的配置,可能会在配置调用期间重写用法和/或 maxbuffer 的值。该框架会检测到此类更改,然后重新分配信息流缓冲区,并且在请求中使用该信息流中的缓冲区之前会再次调用 register_stream_buffers()。<br />如果 stream_list 中不包含当前有效的信息流,则 HAL 可以安全地移除对该信息流的任何引用。在框架稍后调用 configure() 期间也不会重复使用该信息流,并且在 configure_streams() 调用返回之后,它的所有 gralloc 缓冲区都将被释放。<br />stream_list 结构归框架所有,在此调用完成后可能就无法被访问了。单个 camera3streamt 结构的地址将仍然可供 HAL 访问,直到第一个 configure_stream() 调用结束(该调用的 stream_list 参数中不再包含该 camera3streamt)。除了在 configure_streams() 调用期间的用法和 maxbuffer 的成员之外,HAL 可能不会更改私有指针之外的信息流结构中的值。<br />如果是新的信息流,则其结构的用法、maxbuffer 和私有指针字段都将被设为 0。HAL 设备必须在 configure_streams() 调用返回之前设置这些字段。随后,框架和平台 gralloc 模块将使用这些字段为各个信息流分配 gralloc 缓冲区。<br />框架使用此类新信息流来调用 register_stream_buffers() 之后,信息流的缓冲区便可以列入拍摄请求中。不过,在提交请求之前,并不要求框架为所有信息流注册缓冲区。这样一来,预览信息流就可以快速启动(举例说明),而其他信息流的分配则稍后或同时发生。</p>
+<h4><strong>前提条件</strong></h4>
+<p>仅当没有正在处理的拍摄时,框架才会调用此方法。也就是说,所有结果已返回到框架,所有进行中的输入和输出缓冲区已返回,且其释放同步栅栏已收到 HAL 发出的信号。在 configure_streams() 调用过程中,框架不会提交新的拍摄请求。</p>
+<h4><strong>后置条件</strong></h4>
+<p>如相机设备的静态元数据中所述,HAL 设备必须自行配置,从而根据给定的输出信息流大小和格式提供尽可能高的输出帧速率。</p>
+<h4><strong>效果预期</strong></h4>
+<p>此调用预计为重型调用,由于可能需要重置和重新配置图片传感器和相机处理管道,因此可能需要几百毫秒才能完成。不过,HAL 设备应尽量避免重新配置延迟,以尽可能避免在应用操作模式改变(例如从静态拍摄切换到视频录制)期间出现用户可见的停顿。</p>
+<h4><strong>返回值</strong></h4>
+<ul>
+  <li>0:信息流配置成功时返回</li>
+  <li>未定义的返回值</li>
+  <li>-EINVAL:如果请求的信息流配置无效,则返回此值。以下是一些无效信息流配置的示例:<ul>
+      <li>包括多个支持输入的信息流(INPUT 或 BIDIRECTIONAL)</li>
+      <li>不包括任何支持输出的信息流(OUTPUT 或 BIDIRECTIONAL)</li>
+      <li>包括采用不受支持格式(或者格式的不受支持大小)的信息流。</li>
+      <li>包括过多特定格式的输出信息流。</li>
+      <li>请注意,鉴于信息流配置在配置之前经过检查确认,因此框架提交无效信息流配置不属于正常操作。无效配置意味着框架代码中存在错误,或者 HAL 的静态元数据与对信息流的要求不相符。</li>
+    </ul>
+  </li>
+  <li>-ENODEV:如果出现致命错误且设备不再运行,则返回此值。返回此错误后,框架只能成功调用 close()。</li>
+</ul>
+<h3 id="register-stream">register_stream_buffers</h3>
+<p>通过 HAL 设备为指定的信息流注册缓冲区。框架调用此方法发生在 configure_streams 定义新信息流之后、该信息流的缓冲区被列入拍摄请求之前。如果随后的 configure_streams() 调用中列出了同一信息流,框架将不会为该信息流再次调用 register_stream_buffers。<br />框架不需要在提交第一个拍摄请求之前,为配置的所有信息流注册缓冲区。这样可以在其他信息流仍然处于分配过程中时快速启动预览(或类似用例)。<br />此方法旨在让 HAL 设备映射或以其他方式准备缓冲区以供稍后使用。传入的缓冲区将被锁定以供使用。在调用结束时,所有缓冲区都必须准备好返回到信息流。bufferset 参数仅在此调用期间有效。<br />如果信息流格式设为 HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,则相机 HAL 应在此处检查传入的缓冲区,以确定任何平台专用的像素格式信息。</p>
+<h4><strong>返回值</strong></h4>
+<ul>
+  <li>0:新信息流的缓冲区注册成功时返回。</li>
+  <li>-EINVAL:如果 streambufferset 不引用有效的活动信息流或者缓冲区数组无效,则返回此值。</li>
+  <li>-ENOMEM:如果注册缓冲区时出错,则返回此值。框架必须将所有信息流缓冲区视为未注册,并且可尝试稍后重新注册。</li>
+  <li>-ENODEV:如果出现致命错误且设备不再运行,则返回此值。返回此错误后,框架只能成功调用 close()。</li>
+</ul>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/camera/camera3_metadata.html b/zh-cn/devices/camera/camera3_metadata.html
new file mode 100644
index 0000000..b57f9b8
--- /dev/null
+++ b/zh-cn/devices/camera/camera3_metadata.html
@@ -0,0 +1,34 @@
+<html devsite><head>
+    <title>元数据和控件</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 The Android Open Source Project
+
+      Licensed under the Apache License, Version 2.0 (the "License");
+      you may not use this file except in compliance with the License.
+      You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      See the License for the specific language governing permissions and
+      limitations under the License.
+  -->
+
+<h2 id="metadata">元数据支持</h2>
+<p>要支持通过 Android 框架保存原始图片文件,需要具有大量有关传感器特性的元数据,包括色彩空间和镜头遮蔽功能等信息。</p>
+<p>其中大多数信息是相机子系统的静态属性,因此可以在配置任何输出通道或提交任何请求之前进行查询。新的相机 API 极大地扩展了 getCameraInfo() 方法提供的信息,以便将此类信息提供给应用。</p>
+<p>此外,手动控制相机子系统需要各种设备提供的有关其当前状态的反馈,以及在捕获指定帧时使用的实际参数。必须在输出元数据中包含硬件实际使用的控件(曝光时间、帧持续时间和敏感度)的实际值。这一点至关重要,这样应用就知道钳位或舍入何时发生,并且可以补偿用于图片捕获的实际设置。</p>
+<p>例如,如果应用在请求中将帧持续时间设置为 0,则 HAL 必须将帧持续时间钳位到该请求的实际最小帧持续时间,并在输出结果元数据中报告这一钳位最小持续时间。</p>
+<p>因此,如果应用需要实现一个自定义 3A 例程(例如,为了适当地测量 HDR 连拍),则需要知道用于捕获其收到的最新一组结果的设置,以便更新下一个请求的设置。因此,新的相机 API 会向每个捕获的帧添加大量动态元数据。这包括用于捕获的已请求参数和实际参数,以及时间戳和统计信息生成器输出等其他每帧元数据。</p>
+<h2 id="per-setting">每个设置的控件</h2>
+<p>对于大多数设置而言,它们应该能够随着每一个帧进行更改,而不会给输出帧流带来明显的卡顿或延迟。理想情况下,输出帧速率应该仅由捕获请求的帧持续时间字段控制,且不受处理块配置发生的任何变化影响。实际上,我们已经知道一些特定控件发生变化的速度非常缓慢;这些控件包括相机通道的输出分辨率和输出格式,以及影响镜头聚焦距离等物理设备的控件。下文稍后会详细说明每个控件集的确切要求。</p>
+<h2 id="raw-sensor">原始传感器数据支持</h2>
+<p>除了旧 API 支持的像素格式之外,新 API 还针对高级相机应用增加了对原始传感器数据 (Bayer RAW) 的支持要求,同时需支持原始图片文件。</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/camera/camera3_requests_hal.html b/zh-cn/devices/camera/camera3_requests_hal.html
new file mode 100644
index 0000000..8ebc078
--- /dev/null
+++ b/zh-cn/devices/camera/camera3_requests_hal.html
@@ -0,0 +1,278 @@
+<html devsite><head>
+    <title>HAL 子系统</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 The Android Open Source Project
+
+      Licensed under the Apache License, Version 2.0 (the "License");
+      you may not use this file except in compliance with the License.
+      You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      See the License for the specific language governing permissions and
+      limitations under the License.
+  -->
+
+<h2 id="requests">请求</h2>
+<p>应用框架针对捕获的结果向相机子系统发出请求。一个请求对应一组结果。请求包含有关捕获和处理这些结果的所有配置信息。其中包括分辨率和像素格式;手动传感器、镜头和闪光灯控件;3A 操作模式;RAW 到 YUV 处理控件;以及统计信息的生成。这样一来,便可更好地控制结果的输出和处理。一次可发起多个请求,而且提交的请求不会出现阻塞的情况。请求始终按照接收的顺序进行处理。<br />
+  <img src="images/camera_model.png" alt="相机请求模型" id="figure1"/>
+  </p><p class="img-caption">
+  <strong>图 1.</strong>  相机模型</p>
+<h2 id="hal-subsystem">HAL 和相机子系统</h2>
+<p>相机子系统包括相机管道中组件的实现,例如 3A 算法和处理控件。相机 HAL 为您提供了实现您版本的这些组件所需的接口。为了保持多个设备制造商和图像信号处理器(ISP,也称为相机传感器)供应商之间的跨平台兼容性,相机管道模型是虚拟的,且不直接对应任何真正的 ISP。不过,它与真正的处理管道足够相似,因此您可以有效地将其映射到硬件。此外,它足够抽象,可支持多种不同的算法和操作顺序,而不会影响质量、效率或跨设备兼容性。<br />相机管道还支持应用框架开启自动对焦等功能的触发器。它还会将通知发送回应用框架,以通知应用自动对焦锁定或错误等事件。<br />
+  <img src="images/camera_hal.png" alt="相机硬件抽象层" id="figure2"/>
+  </p><p class="img-caption">
+  <strong>图 2.</strong>  相机管道</p>请注意,上图所示的一些图像处理块在初始版本中没有明确定义。<br />相机管道假设如下方面:<p></p>
+<ul>
+  <li>RAW Bayer 输出在 ISP 内部不经过任何处理。</li>
+  <li>统计信息根据原始传感器数据生成。</li>
+  <li>将原始传感器数据转换为 YUV 的各种处理块按任意顺序排列。</li>
+  <li>当显示多个刻度和剪裁单元时,所有的缩放器单元共享输出区域控件(数字缩放)。不过,每个单元都可能具有不同的输出分辨率和像素格式。</li>
+</ul>
+<p><strong>API 用途摘要</strong><br />下面简要介绍使用 Android Camera API 的步骤。有关这些步骤(包括 API 调用)的详细说明,请参阅“启动和预期操作顺序”部分。</p>
+<ol>
+  <li>监听和枚举相机设备。</li>
+  <li>打开设备并连接监听器。</li>
+  <li>配置目标使用情形的输出(如静态捕获、录制等)。</li>
+  <li>为目标使用情形创建请求。</li>
+  <li>捕获/重复请求和连拍。</li>
+  <li>接收结果元数据和图片数据。</li>
+  <li>切换使用情形时,返回到第 3 步。</li>
+</ol>
+<p><strong>HAL 操作摘要</strong></p>
+<ul>
+  <li>捕获的异步请求来自于框架。</li>
+  <li>HAL 设备必须按顺序处理请求。对于每个请求,均产生输出结果元数据以及一个或多个输出图片缓冲区。</li>
+  <li>请求和结果以及后续请求引用的流遵守先进先出规则。</li>
+  <li>指定请求的所有输出的时间戳必须完全相同,以便框架可以根据需要将它们匹配在一起。</li>
+  <li>所有捕获配置和状态(不包括 3A 例程)都包含在请求和结果中。</li>
+</ul>
+<img src="images/camera-hal-overview.png" alt="相机 HAL 概览" id="figure3"/>
+<p class="img-caption">
+  <strong>图 3.</strong>  相机 HAL 概览</p>
+<h2 id="startup">启动和预期操作顺序</h2>
+<p>本节包含有关使用 Camera API 时预期步骤的详细说明。有关这些结构和方法的定义,请参阅 <a href="https://android.googlesource.com/platform/hardware/libhardware/+/master/include/hardware/camera3.h">platform/hardware/libhardware/include/hardware/camera3.h</a>。</p>
+<ol>
+  <li>框架调用 camera_module_t-&gt;common.open(),而这会返回一个 hardware_device_t 结构。</li>
+  <li>框架检查 hardware_device_t-&gt;version 字段,并为该版本的相机硬件设备实例化相应的处理程序。如果版本是 CAMERA_DEVICE_API_VERSION_3_0,则该设备会转型为 camera3_device_t。</li>
+  <li>框架调用 camera3_device_t-&gt;ops-&gt;initialize() 并显示框架回调函数指针。在调用 ops 结构中的任何其他函数之前,这只会在 open() 之后调用一次。</li>
+  <li>框架调用 camera3_device_t-&gt;ops-&gt;configure_streams() 并显示到 HAL 设备的输入/输出流列表。</li>
+  <li>框架为 configure_streams 中列出的至少一个输出流分配 gralloc 缓冲区并调用 camera3_device_t-&gt;ops-&gt;register_stream_buffers()。相同的流仅注册一次。</li>
+  <li>框架通过调用 camera3_device_t-&gt;ops-&gt;construct_default_request_settings() 来为某些使用情形请求默认设置。这可能会在第 3 步之后的任何时间发生。</li>
+  <li>框架通过基于其中一组默认设置的设置以及至少一个框架之前注册的输出流来构建第一个捕获请求并将其发送到 HAL。它通过 camera3_device_t-&gt;ops-&gt;process_capture_request() 发送到 HAL。HAL 必须阻止此调用返回,直到准备好发送下一个请求。</li>
+  <li>框架继续提交请求,并且可能会为尚未注册的流调用 register_stream_buffers(),并调用 construct_default_request_settings 来为其他使用情形获取默认设置缓冲区。</li>
+  <li>当请求捕获开始(传感器开始曝光以进行捕获)时,HAL 会调用 camera3_callback_ops_t-&gt;notify() 并显示 SHUTTER 事件,包括帧号和开始曝光的时间戳。此通知调用必须在第一次调用该帧号的 process_capture_result() 之前进行。</li>
+  <li>在某个管道延迟后,HAL 开始使用 camera3_callback_ops_t-&gt;process_capture_result() 将完成的捕获返回到框架。这些捕获按照与提交请求相同的顺序返回。一次可发起多个请求,具体取决于相机 HAL 设备的管道深度。</li>
+  <li>一段时间后,框架可能会停止提交新的请求、等待现有捕获完成(所有缓冲区都已填充,所有结果都已返回),然后再次调用 configure_streams()。这会重置相机硬件和管道,以获得一组新的输入/输出流。可重复使用先前配置中的部分流;如果这些流的缓冲区已经过 HAL 注册,则不会再次注册。如果至少还有一个已注册的输出流,则框架从第 7 步继续(否则,需要先完成第 5 步)。</li>
+  <li>或者,框架可能会调用 camera3_device_t-&gt;common-&gt;close() 以结束相机会话。当框架中没有其他处于活动状态的调用时,它可能随时会被调用;尽管在所有发起的捕获完成(所有结果都已返回,所有缓冲区都已填充)之前,调用可能会阻塞。在 close 调用返回后,不允许再从 HAL 对 camera3_callback_ops_t 函数进行更多调用。一旦进行 close() 调用,该框架可能不会调用任何其他 HAL 设备函数。</li>
+  <li>在发生错误或其他异步事件时,HAL 必须调用 camera3_callback_ops_t-&gt;notify() 并返回相应的错误/事件消息。从严重的设备范围错误通知返回后,HAL 应表现为在其上调用了 close()。但是,HAL 必须在调用 notify() 之前取消或完成所有待处理的捕获,以便在调用 notify() 并返回严重错误时,框架不会收到来自设备的更多回调。在严重的错误消息返回 notify() 方法后,close() 之外的方法应该返回 -ENODEV 或 NULL。</li>
+</ol>
+<img src="images/camera-ops-flow.png" width="600" height="434" alt="相机操作流程" id="figure4"/>
+<p class="img-caption">
+  <strong>图 4.</strong>  相机操作流程</p>
+<h2 id="ops-modes">操作模式</h2>
+<p>相机 HAL3 设备可以实现以下两种可能的操作模式之一:有限和全面模式。更加高端的新设备有望实现全面支持。有限模式的硬件要求与相机 HAL 设备 v1 实现的硬件要求大致一致,旧版设备或便宜设备会实现这一模式。全面模式是有限模式的严格超集,它们有着基本相同的操作流程,如上所述。</p>
+<p>HAL 必须使用 android.info.supportedHardwareLevel 静态元数据条目来表示其支持级别,0 表示有限模式支持,1 表示全面模式支持。</p>
+<p>大致来说,有限模式设备不允许应用控制捕获设置(仅限 3A 控件)、高速率捕获高分辨率图片、读取原始传感器或支持高于最大录制分辨率的 YUV 输出流(JPEG 仅适用于较大图片)。<br />以下是有限模式行为的详细信息:</p>
+<ul>
+  <li>有限模式设备不需要在捕获请求设置和捕获的实际图片数据之间实现准确的同步。相反,对设置的更改可能会在将来的某个时间生效,并且可能不是针对每个设置条目的相同输出帧。对设置进行快速更改可能会导致某些设置永远不能用于捕获。但是,包含高分辨率输出缓冲区 (&gt; 1080p) 的捕获必须使用指定的设置(不过,要了解处理速率,请参阅下文)。</li>
+  <li>有限模式下包含高分辨率 (&gt; 1080p) 输出缓冲区的捕获可能会在 process_capture_request() 中阻塞,直到填满所有输出缓冲区。全面模式 HAL 设备必须以该像素格式的静态元数据中显示的速率处理高分辨率请求的序列。HAL 仍必须调用 process_capture_result() 以提供输出;框架必须做好准备,以便 process_capture_request() 进行阻塞,直至该请求的 process_capture_result() 为有限模式设备完成高分辨率捕获。</li>
+  <li>有限模式设备不需要支持大多数设置/结果/静态信息元数据。有限模式 HAL 设备只需消耗或生成以下设置:<ul>
+      <li>android.control.aeAntibandingMode(控件)</li>
+      <li>android.control.aeExposureCompensation(控件)</li>
+      <li>android.control.aeLock(控件)</li>
+      <li>android.control.aeMode(控件)</li>
+      <li>[OFF 表示 ON_FLASH_TORCH]</li>
+      <li>android.control.aeRegions(控件)</li>
+      <li>android.control.aeTargetFpsRange(控件)</li>
+      <li>android.control.afMode(控件)</li>
+      <li>[OFF 表示无限远聚焦]</li>
+      <li>android.control.afRegions(控件)</li>
+      <li>android.control.awbLock(控件)</li>
+      <li>android.control.awbMode(控件)</li>
+      <li>[不支持 OFF]</li>
+      <li>android.control.awbRegions(控件)</li>
+      <li>android.control.captureIntent(控件)</li>
+      <li>android.control.effectMode(控件)</li>
+      <li>android.control.mode(控件)</li>
+      <li>[不支持 OFF]</li>
+      <li>android.control.sceneMode(控件)</li>
+      <li>android.control.videoStabilizationMode(控件)</li>
+      <li>android.control.aeAvailableAntibandingModes(静态)</li>
+      <li>android.control.aeAvailableModes(静态)</li>
+      <li>android.control.aeAvailableTargetFpsRanges(静态)</li>
+      <li>android.control.aeCompensationRange(静态)</li>
+      <li>android.control.aeCompensationStep(静态)</li>
+      <li>android.control.afAvailableModes(静态)</li>
+      <li>android.control.availableEffects(静态)</li>
+      <li>android.control.availableSceneModes(静态)</li>
+      <li>android.control.availableVideoStabilizationModes(静态)</li>
+      <li>android.control.awbAvailableModes(静态)</li>
+      <li>android.control.maxRegions(静态)</li>
+      <li>android.control.sceneModeOverrides(静态)</li>
+      <li>android.control.aeRegions(动态)</li>
+      <li>android.control.aeState(动态)</li>
+      <li>android.control.afMode(动态)</li>
+      <li>android.control.afRegions(动态)</li>
+      <li>android.control.afState(动态)</li>
+      <li>android.control.awbMode(动态)</li>
+      <li>android.control.awbRegions(动态)</li>
+      <li>android.control.awbState(动态)</li>
+      <li>android.control.mode(动态)</li>
+      <li>android.flash.info.available(静态)</li>
+      <li>android.info.supportedHardwareLevel(静态)</li>
+      <li>android.jpeg.gpsCoordinates(控件)</li>
+      <li>android.jpeg.gpsProcessingMethod(控件)</li>
+      <li>android.jpeg.gpsTimestamp(控件)</li>
+      <li>android.jpeg.orientation(控件)</li>
+      <li>android.jpeg.quality(控件)</li>
+      <li>android.jpeg.thumbnailQuality(控件)</li>
+      <li>android.jpeg.thumbnailSize(控件)</li>
+      <li>android.jpeg.availableThumbnailSizes(静态)</li>
+      <li>android.jpeg.maxSize(静态)</li>
+      <li>android.jpeg.gpsCoordinates(动态)</li>
+      <li>android.jpeg.gpsProcessingMethod(动态)</li>
+      <li>android.jpeg.gpsTimestamp(动态)</li>
+      <li>android.jpeg.orientation(动态)</li>
+      <li>android.jpeg.quality(动态)</li>
+      <li>android.jpeg.size(动态)</li>
+      <li>android.jpeg.thumbnailQuality(动态)</li>
+      <li>android.jpeg.thumbnailSize(动态)</li>
+      <li>android.lens.info.minimumFocusDistance(静态)</li>
+      <li>android.request.id(控件)</li>
+      <li>android.request.id(动态)</li>
+      <li>android.scaler.cropRegion(控件)</li>
+      <li>[忽略 (x,y),假定中心缩放]</li>
+      <li>android.scaler.availableFormats(静态)</li>
+      <li>[不支持 RAW]</li>
+      <li>android.scaler.availableJpegMinDurations(静态)</li>
+      <li>android.scaler.availableJpegSizes(静态)</li>
+      <li>android.scaler.availableMaxDigitalZoom(静态)</li>
+      <li>android.scaler.availableProcessedMinDurations(静态)</li>
+      <li>android.scaler.availableProcessedSizes(静态)</li>
+      <li>[不支持完整分辨率]</li>
+      <li>android.scaler.maxDigitalZoom(静态)</li>
+      <li>android.scaler.cropRegion(动态)</li>
+      <li>android.sensor.orientation(静态)</li>
+      <li>android.sensor.timestamp(动态)</li>
+      <li>android.statistics.faceDetectMode(控件)</li>
+      <li>android.statistics.info.availableFaceDetectModes(静态)</li>
+      <li>android.statistics.faceDetectMode(动态)</li>
+      <li>android.statistics.faceIds(动态)</li>
+      <li>android.statistics.faceLandmarks(动态)</li>
+      <li>android.statistics.faceRectangles(动态)</li>
+      <li>android.statistics.faceScores(动态)</li>
+    </ul>
+  </li>
+</ul>
+<h2 id="interaction">应用捕获请求之间的互动、3A 控件和处理管道</h2>
+<p>根据 3A 控件块中的设置,相机管道会忽略应用捕获请求中的某些参数,并改用 3A 控件例程提供的值。例如,启用自动曝光时,传感器的曝光时间、帧持续时间和敏感度参数由平台 3A 算法控制,且所有应用指定的值都会被忽略。必须在输出元数据中报告由 3A 例程为帧选择的值。下表描述了 3A 控件块的不同模式和由这些模式控制的属性。有关这些属性的定义,请参阅 <a href="https://android.googlesource.com/platform/system/media/+/master/camera/docs/docs.html">platform/system/media/camera/docs/docs.html</a> 文件。</p>
+<table>
+  <tbody><tr>
+    <th>参数</th>
+    <th>状态</th>
+    <th>受控制的属性</th>
+  </tr>
+  <tr>
+    <td>android.control.aeMode</td>
+    <td>OFF</td>
+    <td>无</td>
+  </tr>
+  <tr>
+    <td></td>
+    <td>ON</td>
+    <td>android.sensor.exposureTime
+android.sensor.frameDuration
+android.sensor.sensitivity android.lens.aperture(如果支持的话)
+android.lens.filterDensity(如果支持的话)</td>
+  </tr>
+  <tr>
+    <td></td>
+    <td>ON_AUTO_FLASH</td>
+    <td>均已开启,还有 android.flash.firingPower、android.flash.firingTime 和 android.flash.mode</td>
+  </tr>
+  <tr>
+    <td></td>
+    <td>ON_ALWAYS_FLASH</td>
+    <td>与 ON_AUTO_FLASH 相同</td>
+  </tr>
+  <tr>
+    <td></td>
+    <td>ON_AUTO_FLASH_RED_EYE</td>
+    <td>与 ON_AUTO_FLASH 相同</td>
+  </tr>
+  <tr>
+    <td>android.control.awbMode</td>
+    <td>OFF</td>
+    <td>无</td>
+  </tr>
+  <tr>
+    <td></td>
+    <td>WHITE_BALANCE_*</td>
+    <td>android.colorCorrection.transform。如果 android.colorCorrection.mode 为 FAST 或 HIGH_QUALITY,则进行特定于平台的调整。</td>
+  </tr>
+  <tr>
+    <td>android.control.afMode</td>
+    <td>OFF</td>
+    <td>无</td>
+  </tr>
+  <tr>
+    <td></td>
+    <td>FOCUS_MODE_*</td>
+    <td>android.lens.focusDistance</td>
+  </tr>
+  <tr>
+    <td>android.control.videoStabilization</td>
+    <td>OFF</td>
+    <td>无</td>
+  </tr>
+  <tr>
+    <td></td>
+    <td>ON</td>
+    <td>可调整 android.scaler.cropRegion 来实现视频防抖</td>
+  </tr>
+  <tr>
+    <td>android.control.mode</td>
+    <td>OFF</td>
+    <td>AE、AWB 和 AF 处于停用状态</td>
+  </tr>
+  <tr>
+    <td></td>
+    <td>AUTO</td>
+    <td>单独使用 AE、AWB 和 AF 设置</td>
+  </tr>
+  <tr>
+    <td></td>
+    <td>SCENE_MODE_*</td>
+    <td>可替换上述所有参数。各个 3A 控件均处于停用状态。</td>
+  </tr>
+</tbody></table>
+<p>针对 3A 算法提供的控件大多一对一映射到旧 API 的参数(例如,曝光补偿、取景模式或白平衡模式)上。<br />在图 2 中,图像处理块中的控件都以类似的原理操作,并且每个块一般都具有 3 种模式:</p>
+<ul>
+  <li>OFF:该处理块处于停用状态。无法停用去马赛克、色彩校正和色调曲线调整块。</li>
+  <li>FAST:与 OFF 模式相比,此模式下的处理块可能不会降低输出帧速率,但是考虑到限制条件,它应该会产生能够产生的最优质输出。通常,这会用于预览或视频录制模式,或用于连拍静态图片。在某些设备上,这可能等同于 OFF 模式(不能在不降低帧速率的情况下进行处理);而在某些设备上,这可能等同于 HIGH_QUALITY 模式(最佳质量仍不会降低帧速率)。</li>
+  <li>HIGHQUALITY:在这种模式下,处理块应尽可能产生最优质结果,根据需要减缓输出帧速率。通常,这会用于静态捕获优质图片。一些块包括可以进行选择的手动控件(而非 FAST 或 HIGHQUALITY)。例如,颜色校正块支持颜色变换矩阵,而色调曲线调整支持任意的全局色调映射曲线。</li>
+</ul>
+  <p>相机子系统可以支持的最大帧速率受到多种因素的影响:</p>
+<ul>
+  <li>所请求的输出图片流的分辨率</li>
+  <li>在成像器上提供分箱/跳过模式</li>
+  <li>成像器接口的带宽</li>
+  <li>各种 ISP 处理块的带宽</li>
+</ul>
+<p>由于这些因素在不同的 ISP 和传感器之间可能有很大差异,因此相机 HAL 接口会尝试将带宽限制抽象为尽可能简单的模型。显示的模型具有以下特性:</p>
+<ul>
+  <li>考虑到应用的已请求输出流大小,图片传感器始终配置为尽可能输出最小的分辨率。最小分辨率定义为至少与请求的最大输出流一样大。</li>
+  <li>因为任何请求都可能使用任意或所有当前配置的输出流,所以传感器和 ISP 必须配置为支持同时将单个捕获扩展到所有流。</li>
+  <li>对于不包含 JPEG 流的请求,它们表现得像经过处理的 YUV 流一样;在直接引用它们的请求中,它们用作 JPEG 流。</li>
+  <li>JPEG 处理器可以并行运行到相机管道的剩余部分,但不能一次处理多个捕获。</li>
+</ul>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/camera/camera3_requests_methods.html b/zh-cn/devices/camera/camera3_requests_methods.html
new file mode 100644
index 0000000..0509315
--- /dev/null
+++ b/zh-cn/devices/camera/camera3_requests_methods.html
@@ -0,0 +1,63 @@
+<html devsite><head>
+    <title>创建和提交请求</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 The Android Open Source Project
+
+      Licensed under the Apache License, Version 2.0 (the "License");
+      you may not use this file except in compliance with the License.
+      You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      See the License for the specific language governing permissions and
+      limitations under the License.
+  -->
+
+<h2 id="request-creation">创建和提交请求</h2>
+<h3 id="default-settings">construct_default_request_settings</h3>
+<p>为标准相机用例创建拍照设置。设备必须返回配置为满足所请求用例的设置缓冲区,该用例必须是其中一个 CAMERA3_TEMPLATE_* 枚举。所有请求控制字段都必须包括在内。<br />
+  HAL 保留对此结构的所有权,但指向该结构的指针必须在设备关闭之前保持有效。此调用返回缓冲区后,框架和 HAL 不能对其进行修改。可以为同一模板或其他模板的后续调用返回相同的缓冲区。</p>
+<h4><strong>返回值</strong></h4>
+<ul>
+  <li>有效的元数据:在成功创建默认设置缓冲区时返回。</li>
+  <li>NULL:在发生致命错误时返回。返回此值后,框架只能成功调用 close() 方法。</li>
+</ul>
+<h3 id="process-request">process_capture_request</h3>
+<p>向 HAL 发送新的拍照请求。HAL 在准备好接受下一个要处理的请求之前,不会从这里调用返回。框架一次只能对 process_capture_request() 执行一次调用,而且调用将全部来自同一个线程。新请求及其关联的缓冲区可用后,会立即对 process_capture_request() 进行下一次调用。在正常的预览场景中,这意味着框架几乎会立即重新调用该函数。<br />
+  实际请求处理是异步的,拍照结果由 HAL 通过 process_capture_result() 调用返回。此调用要求结果元数据可用,但输出缓冲区可以只提供等待的同步栅栏。多个请求应同时发出,以保持全输出帧速率。<br />
+  框架保留对请求结构的所有权。这仅保证在此调用中有效。HAL 设备必须复制需要保留用于拍照处理的信息。HAL 负责等待和关闭缓冲区的栅栏并将缓冲区句柄返回给框架。<br />
+  如果 input_buffer 的返回值不是 NULL,则 HAL 必须将输入缓冲区释放同步栅栏的文件描述符写入 input_buffer-&gt;release_fence。如果 HAL 为输入缓冲区释放同步栅栏返回 -1,则框架可以立即重新使用输入缓冲区。否则,框架将等待同步栅栏,然后再重新填充和重新使用输入缓冲区。</p>
+<h4><strong>返回值</strong></h4>
+<ul>
+  <li>0:在成功开始处理拍照请求时返回。</li>
+  <li>-EINVAL:在输入格式不正确(在不允许的情况下设置为 NULL、没有输出缓冲区等),且拍照处理无法开始时返回。请求处理过程中的故障应通过调用 camera3_callback_ops_t.notify() 来处理。如果出现此错误,框架仍会负责处理流缓冲区的栅栏和缓冲区句柄;HAL 不应通过 process_capture_result 关闭栅栏或者返回这些缓冲区。</li>
+  <li>-ENODEV:在相机设备遇到严重错误时返回。返回此错误后,框架只能成功调用 close() 方法。</li>
+</ul>
+<h2 id="misc-methods">其他方法</h2>
+<h3 id="get-metadata">get_metadata_vendor_tag_ops</h3>
+<p>获取方法以查询供应商扩展元数据标签信息。HAL 应填充所有供应商标签操作方法;或者在没有定义供应商标签的情况下,保持操作不变。vendor_tag_query_ops_t 的定义可以在 system/media/camera/include/system/camera_metadata.h 中找到。</p>
+<h3 id="dump">转储</h3>
+<p>打印出相机设备的调试状态。当相机服务要求进行调试转储时,框架将调用调试转储。在使用 dumpsys 工具或捕获错误报告时,就会出现这种情况。传入文件描述符可用于使用 dprintf() 或 write() 来编写调试文本。该文本应仅采用 ASCII 编码。</p>
+<h3 id="flush">刷新</h3>
+<p>在给定设备上的管道中,刷新当前正在进行的所有拍照和所有缓冲区。框架将使用它来尽快转储所有状态,以准备 configure_streams() 调用。<br />
+  由于无需成功返回缓冲区,因此在 flush()(不管是否成功填充)时持有的每个缓冲区都可能返回 CAMERA3_BUFFER_STATUS_ERROR。请注意,仍允许 HAL 在此调用期间返回有效的 (STATUS_OK) 缓冲区,前提是已成功填充缓冲区。<br />
+  目前在 HAL 中的所有请求都会尽快返回。未在处理的请求会立即返回错误。所有可中断的硬件块均会停止,而所有不可中断的块均会等待。<br />
+  仅当 HAL 中不再有未完成的缓冲区或请求时,flush() 才会返回。框架可能会调用 configure_streams(因为 HAL 状态现在为已停顿),也可能会发出新的请求。<br />
+  flush() 调用只需要 100 毫秒或更短时间,最多花费 1 秒钟。</p>
+<h4><strong>版本信息</strong></h4>
+<p>版本信息仅在设备版本不低于 CAMERA_DEVICE_API_VERSION_3_1 时可用。</p>
+<h4><strong>返回值</strong></h4>
+<ul>
+  <li>0:在成功刷新相机 HAL 时返回。</li>
+  <li>-EINVAL:在输入格式不正确时(设备无效)返回。</li>
+  <li>-ENODEV:在相机设备遇到严重错误时返回。返回此错误后,框架只能成功调用 close() 方法。</li>
+</ul>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/camera/index.html b/zh-cn/devices/camera/index.html
new file mode 100644
index 0000000..a1def4a
--- /dev/null
+++ b/zh-cn/devices/camera/index.html
@@ -0,0 +1,109 @@
+<html devsite><head>
+    <title>相机</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 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.
+  -->
+
+<img style="float: right; margin: 0px 15px 15px 15px;" src="images/ape_fwk_hal_camera.png" alt="Android 相机 HAL 图标"/>
+
+<p>Android 的相机硬件抽象层 (HAL) 可将 <a href="http://developer.android.com/reference/android/hardware/package-summary.html">android.hardware</a> 中较高级别的相机框架 API 连接到底层的相机驱动程序和硬件。相机子系统包括相机管道组件的实现,而相机 HAL 则可提供用于实现您的这些组件版本的接口。</p>
+
+<p>有关最新信息,请参阅以下资源:</p>
+<ul>
+<li><a href="https://android.googlesource.com/platform/hardware/libhardware/+/master/include/hardware/camera.h">camera.h</a> 源文件</li>
+<li><a href="https://android.googlesource.com/platform/hardware/libhardware/+/master/include/hardware/camera3.h">camera3.h</a> 源文件</li>
+<li><a href="https://android.googlesource.com/platform/hardware/libhardware/+/master/include/hardware/camera_common.h">camera_common.h</a> 源文件</li>
+<li><a href="https://developer.android.com/reference/android/hardware/camera2/CameraMetadata.html">CameraMetadata</a> 面向开发者的参考资料</li>
+</ul>
+
+<h2 id="architecture">架构</h2>
+<p>下列图表和列表说明了 HAL 组件:</p>
+
+<img src="images/ape_fwk_camera.png" alt="Android 相机架构" id="figure1"/>
+<p class="img-caption"><strong>图 1.</strong> 相机架构</p>
+
+<dl>
+  <dt>应用框架</dt>
+  <dd>应用代码位于应用框架级别,它利用 <a href="http://developer.android.com/reference/android/hardware/Camera.html">android.hardware.Camera</a> API 来与相机硬件互动。在内部,此代码会调用相应的 JNI 粘合类,以访问与该相机互动的原生代码。</dd>
+  <dt>JNI</dt>
+  <dd>与 <a href="http://developer.android.com/reference/android/hardware/Camera.html">android.hardware.Camera</a> 关联的 JNI 代码位于 <code>frameworks/base/core/jni/android_hardware_Camera.cpp</code>。此代码会调用较低级别的原生代码以获取对物理相机的访问权限,并返回用于在框架级别创建 <a href="http://developer.android.com/reference/android/hardware/Camera.html">android.hardware.Camera</a> 对象的数据。</dd>
+  <dt>原生框架</dt><dt>
+  </dt><dd>在 <code>frameworks/av/camera/Camera.cpp</code> 中定义的原生框架可提供相当于 <a href="http://developer.android.com/reference/android/hardware/Camera.html">android.hardware.Camera</a> 类的原生类。此类会调用 IPC binder 代理,以获取对相机服务的访问权限。</dd>
+  <dt>Binder IPC 代理</dt>
+  <dd>IPC binder 代理有助于越过进程边界实现通信。调用相机服务的 <code>frameworks/av/camera</code> 目录中有 3 个相机 binder 类。ICameraService 是相机服务的接口,ICamera 是已打开的特定相机设备的接口,ICameraClient 是返回应用框架的设备接口。</dd>
+  <dt>相机服务</dt>
+  <dd>位于 <code>frameworks/av/services/camera/libcameraservice/CameraService.cpp</code> 下的相机服务是与 HAL 进行互动的实际代码。</dd>
+  <dt>HAL</dt>
+  <dd>硬件抽象层定义了由相机服务调用且您必须实现以确保相机硬件正常运行的标准接口。</dd>
+  <dt>内核驱动程序</dt>
+  <dd>相机的驱动程序可与实际相机硬件和您的 HAL 实现进行互动。相机和驱动程序必须支持 YV12 和 NV21 图片格式,以便在显示和视频录制时支持预览相机图片。</dd>
+</dl>
+
+<h2 id="implementing">实现 HAL</h2>
+<p>HAL 位于相机驱动程序和更高级别的 Android 框架之间,并可定义您必须实现的接口,以便应用可以正确操作相机硬件。HAL 接口在 <code>hardware/libhardware/include/hardware/camera.h</code> 和 <code>hardware/libhardware/include/hardware/camera_common.h</code> 标头文件中定义。
+</p>
+
+<p><code>camera_common.h</code> 可定义 <code>camera_module</code>;这是一个标准结构,可用于获取有关相机的一般信息,例如相机 ID 和所有相机通用的属性(例如,摄像头是前置摄像头还是后置摄像头)。</p>
+
+<p>
+<code>camera.h</code> 包含与 <a href="http://developer.android.com/reference/android/hardware/Camera.html">android.hardware.Camera</a> 相对应的代码。此标头文件会声明一个 <code>camera_device</code> 结构,该结构又反过来包含一个带函数指针(可实现 HAL 接口)的 <code>camera_device_ops</code> 结构。有关开发者可以设置的相机参数的文档,请参阅 <code>frameworks/av/include/camera/CameraParameters.h</code>。通过 HAL 中的 <code>int
+(*set_parameters)(struct camera_device *, const char *parms)</code> 来设置这些参数以及指向的函数。</p>
+
+<p>有关 HAL 实现的示例,请参阅 <code>hardware/ti/omap4xxx/camera</code> 中的 Galaxy Nexus HAL 实现。</p>
+
+<h2 id="configuring">配置共享库</h2>
+<p>设置 Android 编译系统,以将 HAL 实现正确打包到共享库中,并通过创建 <code>Android.mk</code> 文件将其复制到相应位置:</p>
+
+<ol>
+<li>创建一个 <code>device/&lt;company_name&gt;/&lt;device_name&gt;/camera</code> 目录以包含您库的源文件。</li>
+
+<li>创建一个 <code>Android.mk</code> 文件来编译共享库。确保 Makefile 包含以下行:<pre class="devsite-click-to-copy">
+LOCAL_MODULE := camera.&lt;device_name&gt;
+LOCAL_MODULE_RELATIVE_PATH := hw
+</pre>
+<p>您的库必须命名为 <code>camera.&lt;device_name&gt;</code>(自动附加 <code>.so</code>),以便 Android 可以正确加载库。例如,请参阅 <code>hardware/ti/omap4xxx/Android.mk</code> 中的 Galaxy Nexus 相机的 Makefile。</p></li>
+
+<li>使用您设备的 Makefile 复制 <code>frameworks/native/data/etc</code> 目录中的必要功能 XML 文件,以指定您的设备具有相机功能。例如,要指定您的设备具有相机闪光灯并可自动对焦,请在您设备的 <code>&lt;device&gt;/&lt;company_name&gt;/&lt;device_name&gt;/device.mk</code> Makefile 中添加以下行:<pre class="devsite-click-to-copy">
+PRODUCT_COPY_FILES := \ ...
+
+PRODUCT_COPY_FILES += \
+frameworks/native/data/etc/android.hardware.camera.flash-autofocus.xml:system/etc/permissions/android.hardware.camera.flash-autofocus.xml \
+</pre>
+<p>有关设备 Makefile 的示例,请参阅 <code>device/samsung/tuna/device.mk</code>。</p></li>
+
+<li>在 <code>device/&lt;company_name&gt;/&lt;device_name&gt;/media_profiles.xml</code> 和 <code>device/&lt;company_name&gt;/&lt;device_name&gt;/media_codecs.xml</code> XML 文件中声明您相机的媒体编解码器、格式和分辨率功能。有关详细信息,请参阅<a href="/devices/media/index.html#expose">将编解码器展示给框架</a>。</li>
+
+<li>在您设备的 <code>device/&lt;company_name&gt;/&lt;device_name&gt;/device.mk</code> Makefile 中添加以下行,以将 <code>media_profiles.xml</code> 和 <code>media_codecs.xml</code> 文件复制到相应位置:<pre class="devsite-click-to-copy">
+# media config xml file
+PRODUCT_COPY_FILES += \
+    &lt;device&gt;/&lt;company&gt;/&lt;device&gt;/media_profiles.xml:system/etc/media_profiles.xml
+
+# media codec config xml file
+PRODUCT_COPY_FILES += \
+    &lt;device&gt;/&lt;company&gt;/&lt;device&gt;/media_codecs.xml:system/etc/media_codecs.xml
+</pre></li>
+
+<li>要将相机应用包含在您设备的系统映像中,请在设备的 <code>device/&lt;company&gt;/&lt;device&gt;/device.mk</code> Makefile 中的 <code>PRODUCT_PACKAGES</code> 变量中指定该应用:<pre class="devsite-click-to-copy">
+PRODUCT_PACKAGES := \
+Gallery2 \
+...
+</pre></li>
+</ol>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/camera/versioning.html b/zh-cn/devices/camera/versioning.html
new file mode 100644
index 0000000..dad51f1
--- /dev/null
+++ b/zh-cn/devices/camera/versioning.html
@@ -0,0 +1,269 @@
+<html devsite><head>
+    <title>相机版本支持</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 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>本页详细介绍了 Camera HAL、API 和相关的 Android 兼容性测试套件 (CTS) 测试中的版本差异。还介绍了在 Android 7.0 中为增强和提高相机框架安全性而进行的几项架构更改,以及供应商在其相机实现中为支持这些更改所必须进行的更新。</p>
+
+<h2 id="glossary">术语</h2>
+
+<p>本页中用到以下术语:</p>
+
+<dl>
+
+<dt>Camera API1</dt>
+<dd>Android 4.4 及更低版本设备上的应用级相机框架,通过 <code>android.hardware.Camera</code> 类提供。</dd>
+
+<dt>Camera API2</dt>
+<dd>Android 5.0 及更高版本设备上的应用级相机框架,通过<code> android.hardware.camera2</code> 包提供。</dd>
+
+<dt>Camera HAL</dt>
+<dd>由 SoC 供应商实现的相机模块层。该应用级公共框架基于 Camera HAL 构建而成。</dd>
+
+<dt>Camera HAL3.1</dt>
+<dd>随 Android 4.4 发布的相机设备 HAL 版本。</dd>
+
+<dt>Camera HAL3.2</dt>
+<dd>随 Android 5.0 发布的相机设备 HAL 版本。</dd>
+
+<dt>Camera API1 CTS</dt>
+<dd>在 Camera API1 之上运行的相机兼容性测试套件 (CTS) 测试集。</dd>
+
+<dt>Camera API2 CTS</dt>
+<dd>在 Camera API2 之上运行的另一个相机 CTS 测试集。</dd>
+
+</dl>
+
+<h2 id="camera_apis">相机 API</h2>
+<p>Android 包含以下相机 API。</p>
+
+<h3 id="camera_api1">Camera API1</h3>
+
+<p>Android 5.0 已弃用 Camera API1,而且随着新平台开发的重点放在 Camera API2 上,Camera API1 会逐渐被淘汰。但是,该淘汰期限将会很长,而且 Android 版本将会在一段时间内继续支持 Camera API1 应用。具体来说,将继续为以下内容提供支持:</p>
+
+<ul>
+<li><em></em>应用的 Camera API1 接口。在 Camera API1 之上构建的相机应用应该与运行早期 Android 版本的设备一样工作。
+</li>
+<li>Camera HAL 版本。<em></em>包括对 Camera HAL1.0 的支持。</li>
+</ul>
+
+<h3 id="camera_api2">Camera API2</h3>
+
+<p>Camera API2 框架为应用提供较低级别的相机控件,包括高效的零复制连拍/视频流以及曝光、增益、白平衡增益、颜色转换、去噪、锐化等方面的每帧控件。有关详细信息,请观看 <a href="https://www.youtube.com/watch?v=92fgcUNCHic&feature=youtu.be&t=29m50s">Google I/O 视频概览</a>。</p>
+
+<p>Android 5.0 及更高版本包括 Camera API2;但是,运行 Android 5.0 及更高版本的设备可能并非支持所有 Camera API2 功能。应用可以通过 Camera API2 接口查询的 <code>android.info.supportedHardwareLevel</code> 属性会报告以下支持级别之一:</p>
+
+<ul>
+<li><code>LEGACY</code>。这些设备通过 Camera API2 接口为应用提供功能,而且这些功能与通过 Camera API1 接口提供给应用的功能大致相同。旧版框架代码在概念上将 Camera API2 调用转换为 Camera API1 调用;旧版设备不支持 Camera API2 功能,例如每帧控件。</li>
+<li><code>FULL</code>。这些设备支持 Camera API2 的所有主要功能,并且必须使用 Camera HAL 3.2 或更高版本以及 Android 5.0 或更高版本。</li>
+<li><code>LIMITED</code>。这些设备支持部分(但不是全部)Camera API2 功能,并且必须使用 Camera HAL 3.2 或更高版本。</li>
+</ul>
+
+<p>各项功能通过 Camera API2 接口中的 <code>android.request.availableCapabilities</code> 属性提供。<code>FULL</code> 设备需要 <code>MANUAL_SENSOR</code> 和 <code>MANUAL_POST_PROCESSING</code> 等功能。即使对于 <code>FULL</code> 设备,<code>RAW</code> 功能也是可选的。
+<code>LIMITED</code> 设备可以播发这些功能的任何子集,包括空子集。但是,必须始终定义 <code>BACKWARD_COMPATIBLE</code> 功能。</p>
+
+<p>设备支持的硬件级别及其支持的特定 Camera API2 功能采用以下功能标记的形式提供,以允许 Google Play 过滤 Camera API2 相机应用。</p>
+
+<ul>
+  <li><code>android.hardware.camera.hardware_level.full</code>
+  </li><li><code>android.hardware.camera.capability.raw</code>
+  </li><li><code>android.hardware.camera.capability.manual_sensor</code>
+  </li><li><code>android.hardware.camera.capability.manual_post_processing</code>
+</li></ul>
+
+<h2 id="cts_requirements">CTS 要求</h2>
+
+<p>运行 Android 5.0 及更高版本的设备必须通过 Camera API1 CTS、Camera API2 CTS 和 CTS 验证程序相机测试。</p>
+
+<p>不具备 Camera HAL3.2 实现且不能支持完整的 Camera API2 接口的设备仍必须通过 Camera API2 CTS 测试。但是,该设备将在 Camera API2 <code>LEGACY</code> 模式下运行(在该模式下,Camera API2 调用在概念上映射到 Camera API1 调用),因此与 Camera API1 之外的特征或功能相关的任何 Camera API2 CTS 测试都将自动跳过。</p>
+
+<p>在旧版设备上,未跳过的 Camera API2 CTS 测试使用现有的公共 Camera API1 接口和功能,没有新的要求。显示的错误(并导致 Camera API2 CTS 失败)是设备现有 Camera HAL 中已经存在的错误,因此可由现有 Camera API1 应用找到。我们预计不会出现太多此类错误(但是,任何此类错误均必须修复,才能通过 Camera API2 CTS 测试)。</p>
+
+<h2 id="hardening">相机框架强化</h2>
+
+<p>为了增强媒体和相机框架安全性,Android 7.0 已将相机服务从 mediaserver 中移出。供应商可能需要根据正在使用的 API 和 HAL 版本对 Camera HAL 进行更改。以下部分详细介绍了在 HAL1 和 HAL3 的 AP1 和 AP2 中进行的架构更改,以及常规要求。</p>
+
+<h3 id="hardening_api1">API1 的架构更改</h3>
+<p>API1 视频录制可能会假定相机和视频编码器存在于同一进程中。在以下对象上使用 API1 时:</p>
+
+<ul>
+<li>HAL3,其中相机服务使用 BufferQueue 在进程之间传递缓冲区,<strong>不需要供应商更新</strong>。
+<p><img src="images/ape_camera_n_api1_hal3.png" alt="HAL3 上 API1 中的 Android 7.0 相机和媒体堆栈" id="figure1"/></p>
+<p class="img-caption"><strong>图 1. </strong>HAL3 上 API1 中的 Android 7.0 相机和媒体堆栈。</p>
+</li>
+<li>HAL1,支持在视频缓冲区中传递元数据,<strong>供应商必须更新 HAL 才能使用 kMetadataBufferTypeNativeHandleSource</strong>(Android 7.0 中不再支持 <code>kMetadataBufferTypeCameraSource</code>)。
+<p><img src="images/ape_camera_n_api1_hal1.png" alt="HAL1 上 API1 中的 Android 7.0 相机和媒体堆栈" id="figure1"/></p>
+<p class="img-caption"><strong>图 2. </strong>HAL1 上 API1 中的 Android 7.0 相机和媒体。</p>
+</li>
+</ul>
+
+<h3 id="hardening_api2">API2 的架构更改</h3>
+<p>对于 HAL1 或 HAL3 上的 API2,BufferQueue 会传递缓冲区,以便这些路径继续工作。以下对象上用于 API2 的 Android 7.0 架构:</p>
+
+<ul>
+<li>HAL1 不受 cameraservice 移动的影响,并且<strong>不需要供应商更新</strong>。</li>
+<li><em></em>HAL3 会受到影响,但<strong>不需要供应商更新</strong>:<p><img src="images/ape_camera_n_api2_hal3.png" alt="HAL2 上 API2 中的 Android 7.0 相机和媒体堆栈" id="figure1"/></p>
+<p class="img-caption"><strong>图 3. </strong>HAL3 上 API2 中的 Android 7.0 相机和媒体堆栈。</p>
+</li>
+</ul>
+
+<h3 id="hardening_general">其他要求</h3>
+<p>为增强媒体和相机框架安全性而进行的架构更改包括以下附加设备要求。</p>
+
+<ul>
+<li><strong>常规</strong>。由于 IPC,设备需要额外带宽,这可能会影响对时间敏感的相机使用情况,例如高速视频录制。供应商可以通过运行 <code>android.hardware.camera2.cts.PerformanceTest</code> 和 Google 相机应用进行 120/240 FPS 高速视频录制,以衡量实际影响。设备还需要少量额外的 RAM 来创建新进程。</li>
+<li><strong>在视频缓冲区中传递元数据</strong>(仅限 HAL1)。<em></em>如果 HAL1 在视频缓冲区中存储元数据而非实际的 YUV 帧数据,则 HAL 必须使用 <code>kMetadataBufferTypeNativeHandleSource</code> 作为元数据缓冲区类型,并在视频缓冲区中传递 <code>VideoNativeHandleMetadata</code>(<code>kMetadataBufferTypeCameraSource</code> 在 Android 7.0 中不再受支持)。通过 <code>VideoNativeHandleMetadata</code>,相机和媒体框架能够正确地对原生句柄进行序列化和反序列化,从而在进程之间传递视频缓冲区。</li>
+<li><strong>缓冲区句柄地址不一定始终存储相同的缓冲区</strong>(仅限 HAL3)。<em></em>对于每个捕获请求,HAL3 会获取缓冲区句柄的地址。HAL 不能使用地址来识别缓冲区,因为地址可能会在 HAL 返回缓冲区之后存储另一个缓冲区句柄。您必须更新 HAL,以便使用缓冲区句柄来标识缓冲区。例如:HAL 接收缓冲区句柄地址 A,该地址存储缓冲区句柄 A。在 HAL 返回缓冲区句柄 A 之后,缓冲区句柄地址 A 可能在 HAL 下次接收到它时存储缓冲区句柄 B。</li>
+<li><strong>更新用于 cameraserver 的 SELinux 策略</strong>。如果设备特定的 SELinux 策略向 mediaserver 授予运行相机的权限,则您必须更新 SELinux 策略,以授予 cameraserver 正确的权限。我们建议不要为 cameraserver 复制 mediaserver 的 SELinux 策略(因为 mediaserver 和 cameraserver 通常在系统中需要不同的资源)。Cameraserver 应仅具有执行相机功能所需的权限,并且 mediaserver 中任何不必要的相机相关权限均应被删除。<p></p>
+
+<h3 id="hardening_validation">验证</h3>
+<p>对于包含相机且运行 Android 7.0 的所有设备,请通过运行 Android 7.0 CTS 来验证相关实现。尽管 Android 7.0 不包含验证相机服务更改的新 CTS 测试,但如果您尚未进行上述更新,则现有 CTS 测试将失败。</p>
+
+<h2 id="version-history">Camera HAL 版本历史记录</h2>
+<p>有关可用于评估 Android Camera HAL 的测试列表,请参阅 <a href="/compatibility/cts/camera-hal.html">Camera HAL 测试核对清单</a>。</p>
+
+<h3 id="34">3.4</h3>
+
+<p>对受支持的元数据添加了少许内容并对 data_space 支持进行了更改:</p>
+
+<ul>
+<li>如果支持 <code>RAW_OPAQUE</code> 格式,则必须强制添加 <code>ANDROID_SENSOR_OPAQUE_RAW_SIZE</code> 静态元数据。</li>
+<li>如果支持任何 RAW 格式,则必须强制添加 <code>ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE</code> 静态元数据。</li>
+<li>使用数据空间编码的版本 0 定义,将 <code>camera3_stream_t data_space</code> 字段切换为更灵活的定义。</li>
+<li>可用于 HALv3.2 或更高版本的常规元数据添加项:<ul>
+  <li>
+  <a href="https://developer.android.com/reference/android/hardware/camera2/CameraMetadata.html#INFO_SUPPORTED_HARDWARE_LEVEL_3"><code>ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_3</code>
+  </a></li>
+  <li><code>ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST</code></li>
+  <li><code>ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE</code></li>
+  <li><code>ANDROID_SENSOR_DYNAMIC_BLACK_LEVEL</code></li>
+  <li><code>ANDROID_SENSOR_DYNAMIC_WHITE_LEVEL</code></li>
+  <li><code>ANDROID_SENSOR_OPAQUE_RAW_SIZE</code></li>
+  <li><code>ANDROID_SENSOR_OPTICAL_BLACK_REGIONS</code></li>
+  </ul>
+  </li><li>
+</li></ul>
+
+<h3 id="33">3.3</h3>
+
+<p>扩展功能 HAL 的小修订:</p>
+
+<ul>
+  <li>OPAQUE 和 YUV 重新处理 API 更新。</li>
+  <li>对深度输出缓冲区的基本支持。</li>
+  <li>为 <code>camera3_stream_t</code> 添加了 <code>data_space</code> 字段。</li>
+  <li>为 <code>camera3_stream_t</code> 添加了旋转字段。</li>
+  <li>为 <code>camera3_stream_configuration_t</code> 添加了 camera3 流配置操作模式。</li>
+</ul>
+
+<h3 id="32">3.2</h3>
+
+<p>扩展功能 HAL 的小修订:</p>
+
+<ul>
+<li>弃用了 <code>get_metadata_vendor_tag_ops</code>。在 <code>camera_common.h</code> 中改用 <code>get_vendor_tag_ops</code>。</li>
+<li>弃用了 <code>register_stream_buffers</code>。框架在 <code>process_capture_request</code> 中提供给 HAL 的所有 gralloc 缓冲区在任何时候可能都是新的。</li>
+<li>添加了部分结果支持。在获得完整结果之前,通过多次调用 <code>process_capture_result</code> 可以获得可用结果的子集。</li>
+<li>为 <code>camera3_request_template</code> 添加了手动模板。应用可以使用此模板直接控制捕获设置。</li>
+<li>重新制定双向和输入流规范。</li>
+<li>更改输入缓冲区返回路径。缓冲区在 <code>process_capture_result</code> 而不是 <code>process_capture_request</code> 中返回。</li>
+</ul>
+
+<h3 id="31">3.1</h3>
+
+<p>扩展功能 HAL 的小修订:</p>
+
+<ul>
+<li><code>configure_streams</code> 将消耗方使用标记传递给 HAL。</li>
+<li>刷新调用以尽可能快地丢弃所有传输中的请求/缓冲区。</li>
+</ul>
+
+<h3 id="30">3.0</h3>
+
+<p>扩展功能 HAL 的首次修订:</p>
+
+<ul>
+<li>重要版本更改,因为 ABI 完全不同。在所需的硬件功能或操作模式方面,与 2.0 相比没有更改。</li>
+<li>重新设计了输入请求和流队列接口:框架调用 HAL 且后续请求和流缓冲区已经出队。包含同步框架支持,这是高效实现所必需的。</li>
+<li>已将触发器移动到请求中,将大多数通知移动到结果中。</li>
+<li>将框架中的所有回调合并到一个结构中,并将所有设置方法合并到单个 <code>initialize()</code> 调用中。</li>
+<li>将信息流配置整合到单个调用中,从而简化信息流管理。双向信息流替代 STREAM_FROM_STREAM 构造。</li>
+<li>为较旧/受限的硬件设备限制了模式语义。</li>
+</ul>
+
+<h3 id="20">2.0</h3>
+
+<p>初始版本的扩展功能 HAL (Android 4.2) [camera2.h]:</p>
+
+<ul>
+<li>足够实现现有 <code>android.hardware.Camera</code> API。</li>
+<li>允许用于相机服务层中的 ZSL 队列。</li>
+<li>未针对任何新功能(如手动捕获控制、Bayer RAW 捕获,RAW 数据的重新处理等)进行测试。</li>
+</ul>
+
+<h3 id="10">1.0</h3>
+
+<p>初始 Android Camera HAL (Android 4.0) [camera.h]:</p>
+
+<ul>
+<li>已从 C++ CameraHardwareInterface 抽象层进行转换。</li>
+<li>支持 <code>android.hardware.Camera</code> API。</li>
+</ul>
+
+<h2 id="module_version">相机模块版本历史记录</h2>
+
+<p>本部分基于 <code>camera_module_t.common.module_api_version</code> 提供了相机硬件模块的模块版本控制信息。两个最重要的十六进制数字表示主要版本,而两个最不重要的数字表示次要版本。</p>
+
+<h3 id="24">2_4</h3>
+
+<p>此相机模块版本添加了以下 API 更改:</p>
+
+<ol>
+ <li>手电筒模式支持。<em></em>框架可以为具有闪光灯元件的任何相机设备打开手电筒模式,而无需打开相机设备。相机设备对闪光灯单元的访问优先级高于相机模块;如果已通过模块接口启用手电筒,则打开相机设备会关闭手电筒。当出现任何资源冲突时(例如调用 <code>open()</code> 以打开相机设备),Camera HAL 模块必须通过手电筒模式状态回调通知框架,指明手电筒模式已关闭。</li>
+
+ <li>外部相机(如 USB 热插拔相机)支持。<em></em>仅当相机已连接且准备好用于外部热插拔相机时,API 更新才会指明相机静态信息可用。当相机状态不是 <code>CAMERA_DEVICE_STATUS_PRESENT</code> 时,获取静态信息的调用将为无效调用。框架仅依赖设备状态更改回调来管理可用的外部相机列表。
+ </li>
+
+ <li>相机仲裁提示。<em></em>添加了相关支持,以明确指明可以同时打开和使用的相机设备数量。要指定有效的设备组合,应始终在由 <code>get_camera_info</code> 调用返回的 <code>camera_info</code> 结构中设置 <code>resource_cost</code> 和 <code>conflicting_devices</code> 字段。</li>
+
+ <li>模块初始化方法。<em></em>在加载 HAL 模块后由相机服务调用,以允许初始化 HAL 一次。该方法在调用任何其他模块方法之前调用。</li>
+</ol>
+
+<h3 id="23">2_3</h3>
+
+<p>该相机模块版本添加了对打开旧版 Camera HAL 设备的支持。如果同一设备可以支持多个设备 API 版本,则框架利用该支持可以打开相机设备作为较低设备 HAL 版本的 HAL 设备。标准硬件模块打开调用 (common.methods-&gt;open) 会继续使用支持的最新版本(即 <code>camera_info_t.device_version</code> 中列出的版本)打开相机设备。</p>
+
+<h3 id="22">2_2</h3>
+
+<p>该相机模块版本添加了模块供应商标记支持,并且弃用了以前只能通过打开设备才可访问的旧版 <code>vendor_tag_query_ops</code>。</p>
+
+<h3 id="21">2_1</h3>
+
+<p>该相机模块版本添加了对从 Camera HAL 模块到框架的异步回调支持,利用该支持可以通知框架关于相机模块状态的更改。提供有效 <code>set_callbacks()</code> 方法的模块必须至少报告此版本号。</p>
+
+<h3 id="20">2_0</h3>
+
+<p>报告此版本号的相机模块会实现相机模块 HAL 接口的第二个版本。可通过此模块打开的相机设备可能支持 1.0 版本或 2.0 版本的相机设备 HAL 接口。camera_info 的 <code>device_version</code> 字段始终有效;如果 <code>device_version</code> 字段为 2.0 或更高版本,则 <code>camera_info</code> 的 <code>static_camera_characteristics</code> 字段有效。</p>
+
+<h3 id="10">1_0</h3>
+
+<p>报告这些版本号的相机模块实现了初始相机模块 HAL 接口。可通过此模块打开的所有相机设备仅支持版本 1 的相机设备 HAL。<code>camera_info</code> 的 <code>device_version</code> 和 <code>static_camera_characteristics</code> 字段无效。只有 <code>android.hardware.Camera</code> API 受该模块及其设备的支持。</p>
+
+</li></ul></body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/drm.html b/zh-cn/devices/drm.html
new file mode 100644
index 0000000..ba19cc5
--- /dev/null
+++ b/zh-cn/devices/drm.html
@@ -0,0 +1,172 @@
+<html devsite><head>
+    <title>DRM</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 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.
+  -->
+
+<img style="float: right; margin: 0px 15px 15px 15px;" src="images/ape_fwk_hal_drm.png" alt="Android DRM HAL 图标"/>
+
+<p>本文档概要介绍了 Android DRM 框架,并介绍了 DRM 插件必须实现的接口。本文档不提供可由 DRM 方案定义的稳健性规则或合规性规则的相关说明。</p>
+
+<h2 id="introduction">简介</h2>
+
+<p>Android 平台提供了一个可扩展的 DRM 框架,以便应用根据与受版权保护的内容相关的许可限制条件来管理这些内容。DRM 框架支持多种 DRM 方案;设备具体支持哪些 DRM 方案由设备制造商决定。Android 3.0 中引入的 DRM 框架为应用开发者提供了一个统一接口,并隐藏了 DRM 操作的复杂性。DRM 框架为受保护和不受保护的内容提供了一致的操作模式。DRM 方案可以定义非常复杂的许可元数据使用模型。DRM 框架提供了 DRM 内容与许可之间的关联,并处理权限管理。这样可以将媒体播放器从受 DRM 保护或不受保护的内容中提取出来。请参阅 <a href="https://developer.android.com/reference/android/media/MediaDrm.html">MediaDrm</a>,了解如何使用该类来获取用于解密受保护的媒体流的密钥。</p>
+
+ <img src="/devices/images/ape_fwk_drm.png" alt="Android DRM HAL"/>
+
+<p class="img-caption"><strong>图 1. </strong> DRM 硬件抽象层</p>
+
+<p>提供丰富数字内容的能力对于移动设备用户来说非常重要。为保证内容的广泛覆盖面,Android 开发者和数字内容发布者需要在整个 Android 生态系统中实现受支持的一致的 DRM。为了使此类数字内容适用于 Android 设备并确保至少有一个一致的 DRM 可用于所有设备,Google 在 Android 兼容设备上提供了无需支付许可费用的 DRM。在 Android 3.0 及更高版本的平台上,DRM 插件与 Android DRM 框架集成在一起,并且可以使用由硬件支持的保护功能来保护付费内容和用户凭据。
+</p>
+
+<p>DRM 插件提供的内容保护取决于底层硬件平台的安全性和内容保护功能。设备的硬件功能包括硬件安全启动,可建立加密密钥的安全性和保护的信任链。设备的内容保护功能包括设备内加密帧的保护和通过可信输出保护机制实现的内容保护。并非任意硬件平台都支持上述所有的安全性和内容保护功能。安全性绝不会在堆栈的单个位置实现,而是依赖于硬件、软件和服务的集成。将硬件安全性功能、可信启动机制以及用于处理安全性功能的隔离安全操作系统组合使用是交付安全设备的关键。</p>
+
+<h2 id="architecture">架构</h2>
+<p>DRM 框架与实现无关,可在方案特定的 DRM 插件中提取特定 DRM 方案实现的详情。DRM 框架包括可执行以下操作的简单 API:处理复杂的 DRM 操作、向在线 DRM 服务注册用户和设备、从许可中提取限制信息、将 DRM 内容与其许可相关联,以及最终解密 DRM 内容。</p>
+
+<p>Android DRM 框架在以下两个架构层中实现:</p>
+<ul>
+<li>DRM framework API:通过 Android 应用框架提供给应用,并通过适用于标准应用的 Dalvik VM 运行。</li>
+<li>本机代码 DRM 管理器:用于实现 DRM 框架,并为 DRM 插件(代理)提供接口,以便处理各种 DRM 方案的版权管理和解密操作。</li>
+</ul>
+
+ <img src="images/ape_fwk_drm_2.png" alt="Android DRM 框架"/>
+
+<p class="img-caption"><strong>图 2. </strong> DRM 框架</p>
+
+<p>有关详情,请参阅 <a href="http://developer.android.com/reference/android/drm/package-summary.html">Android DRM 文件包参考</a>。</p>
+
+<h2 id="plug-ins">插件</h2>
+<p>如下图所示,DRM 框架使用插件架构来支持各种 DRM 方案。DRM 管理器服务在一个独立进程中运行,以确保隔离执行 DRM 插件。从 DrmManagerClient 到 DrmManagerService 的每个 API 调用都需要使用 binder IPC 机制来跨越进程边界。DrmManagerClient 提供了 Java 编程语言实现,作为运行时应用的通用接口;此外,它还提供了 DrmManagerClient 本机实现作为本机模块的接口。DRM 框架的调用者仅访问 DrmManagerClient,无需了解每个 DRM 方案。</p>
+
+ <img src="images/ape_fwk_drm_plugins.png" alt="Android DRM 插件"/>
+
+<p class="img-caption"><strong>图 3. </strong> 带有插件的 DRM 框架</p>
+
+<p>当 DrmManagerService 启动时,插件会自动加载。如下图所示,DRM 插件管理器会加载/取消加载所有可用插件。DRM 框架会在以下目录中查找并自动加载插件:</p>
+<pre class="devsite-click-to-copy">
+/system/lib/drm/plugins/native/
+</pre>
+
+<img src="images/ape_fwk_drm_plugins_life.png" alt="Android DRM 插件生命周期"/>
+
+<p class="img-caption"><strong>图 4. </strong> DRM 插件生命周期</p>
+
+<p>插件开发者应确保插件位于 DRM 框架插件的发现目录中。请参阅下文中的实现说明了解详细信息。</p>
+
+<h2 id="implementation">实现</h2>
+
+<h3 id="IDrmEngine">IDrmEngine</h3>
+
+<p>IDrmEngine 是一种接口,包含一组用于 DRM 用例的 API。插件开发者必须实现 IDrmEngine 中指定的接口和下方指定的监听器接口。源代码树在以下目录中提供了接口定义:</p><p>
+</p><pre class="devsite-click-to-copy">
+<var>PLATFORM_ROOT</var>/frameworks/av/drm/libdrmframework/plugins/common/include
+</pre>
+
+<h3 id="DrmInfo">DRM 信息</h3>
+<p>DrmInfo 是一种封装容器类,可封装与 DRM 服务器通信的协议。通过处理 DrmInfo 的实例,可以实现服务器注册、注销、许可获取或任何其他服务器相关的事务。该协议应当由 XML 格式的插件进行描述。每个 DRM 插件将通过解释该协议来完成相应的事务。DRM 框架定义了一个 API 来检索名为 acquireDrmInfo() 的 DrmInfo 实例。</p>
+
+<pre class="devsite-click-to-copy prettyprint">
+DrmInfo* acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest);
+</pre>
+<p>检索有关注册、注销或权限获取信息的必要信息。请参阅 <a href="http://developer.android.com/reference/android/drm/DrmInfoRequest.html">DrmInfoRequest</a> 了解更多信息。</p>
+
+<pre class="devsite-click-to-copy prettyprint">
+DrmInfoStatus* processDrmInfo(int uniqueId, const DrmInfo* drmInfo);
+</pre>
+<p>processDrmInfo() 以异步方式运行,事务的结果可通过 OnEventListener 或 OnErrorListener 检索。</p>
+
+<h3 id="drm-rights">DRM 权限</h3>
+
+<p>要播放 DRM 内容,需要将 DRM 内容与其许可相关联。建立关联后,许可将在 DRM 框架中处理,从而可将媒体播放器应用从具体的证书中提取出来。</p>
+
+<pre class="devsite-click-to-copy prettyprint">
+int checkRightsStatus(int uniqueId, const String8&amp; path, int action);
+</pre>
+
+<p>检查指定内容是否具备有效权限。输入参数是已保存内容所在的内容文件路径和查询权限的操作,例如:Action::DEFAULT、Action::PLAY。返回受保护内容的权限状态,例如:RightsStatus::RIGHTS_VALID、RightsStatus::RIGHTS_EXPIRED。</p>
+
+<pre class="devsite-click-to-copy prettyprint">
+status_t saveRights(int uniqueId, const DrmRights&amp; drmRights, const String8&amp; rightsPath, const String8&amp; contentPath);
+</pre>
+
+<p>将 DRM 权限保存到指定的权限路径并与内容路径相关联。输入参数是要保存的 DrmRights、权限要保存到的权限文件路径,以及已保存内容所在的内容文件路径。</p>
+
+<h3 id="metadata">许可元数据</h3>
+<p>许可元数据(如许可到期时间、可重复计数等)可嵌入受保护内容的权限内。Android DRM 框架提供了 API 来返回与输入内容相关联的限制条件。请参阅 <a href="http://developer.android.com/reference/android/drm/DrmManagerClient.html">DrmManagerClient</a> 了解更多信息。</p>
+
+<pre class="devsite-click-to-copy prettyprint">
+DrmConstraints* getConstraints(int uniqueId, const String path, int
+action);
+</pre>
+<p>getConstraint 函数调用可返回受保护内容中嵌入的限制条件的键值对。要检索这些限制条件,则需要 uniqueId(受保护内容的会话和路径的唯一标识符)。此外,还需要执行被定义为 Action::DEFAULT、Action::PLAY 等的操作。</p>
+
+ <img src="images/ape_fwk_drm_retrieve_license.png" alt="Android DRM 许可元数据"/>
+
+<p class="img-caption"><strong>图 5. </strong> 检索许可元数据</p>
+
+<pre class="devsite-click-to-copy prettyprint">
+DrmMetadata* getMetadata(int uniqueId, const String path);
+</pre>
+<p>获取与受保护内容指定路径下的输入内容相关联的元数据信息,以返回元数据的键值对。</p>
+
+<h3 id="metadata">解密会话</h3>
+<p>为了保持解密会话,DRM 框架的调用者必须在解密序列开始时调用 openDecryptSession()。openDecryptSession() 会询问每个 DRM 插件是否能够处理输入 DRM 内容。</p>
+<pre class="devsite-click-to-copy prettyprint">
+status_t openDecryptSession(
+   int uniqueId, DecryptHandle* decryptHandle, int fd, off64_t offset, off64_t length);
+</pre>
+
+<p>上述调用允许您将 DRM 权限保存到指定的权限路径并与内容路径相关联。DrmRights 参数是要保存的权限、权限的正确文件路径,以及内容应该保存到的内容文件路径。</p>
+
+<h3 id="listeners">DRM 插件监听器</h3>
+
+<p>DRM 框架中的某些 API 在 DRM 事务中异步运行。一个应用可以将三个监听器类注册到 DRM 框架。</p>
+
+<ul>
+<li>OnEventListener:用于异步 API 的结果</li>
+<li>OnErrorListener:用于接收异步 API 的错误</li>
+<li>OnInfoListener:用于 DRM 事务期间的任何补充信息</li>
+</ul>
+
+<h3 id="source">源代码</h3>
+
+<p>Android DRM 框架包括几个示例、一个 passthru 插件和一个转发锁定插件,它们的位置如下:</p>
+<pre class="devsite-click-to-copy">
+<var>PLATFORM_ROOT</var>/frameworks/av/drm/libdrmframework/plugins/passthru
+<var>PLATFORM_ROOT</var>/frameworks/av/drm/libdrmframework/plugins/forward-lock
+</pre>
+
+<h3 id="build">构建和集成</h3>
+
+<p>将以下内容添加到插件实现的 Android.mk 中。passthruplugin 作为示例使用。</p>
+
+<pre class="devsite-click-to-copy">
+PRODUCT_COPY_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/<var>PLUGIN_LIBRARY</var>:system/lib/drm/plugins/native/<var>PLUGIN_LIBRARY</var>
+</pre>
+<p>例如</p>
+<pre class="devsite-click-to-copy">
+PRODUCT_COPY_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libdrmpassthruplugin.so:system/lib/drm/plugins/native/libdrmpassthruplugin.so
+</pre>
+<p>插件开发者必须在如下目录中找到各自的插件:</p>
+<pre class="devsite-click-to-copy">
+/system/lib/drm/plugins/native/libdrmpassthruplugin.so
+</pre>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/graphics/arch-bq-gralloc.html b/zh-cn/devices/graphics/arch-bq-gralloc.html
new file mode 100644
index 0000000..292d070
--- /dev/null
+++ b/zh-cn/devices/graphics/arch-bq-gralloc.html
@@ -0,0 +1,70 @@
+<html devsite><head>
+    <title>BufferQueue 和 gralloc</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 The Android Open Source Project
+
+      Licensed under the Apache License, Version 2.0 (the "License");
+      you may not use this file except in compliance with the License.
+      You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      See the License for the specific language governing permissions and
+      limitations under the License.
+  -->
+
+<p>要了解 Android 图形系统,需首先了解后台的 BufferQueue 和 gralloc HAL。</p>
+
+<p>BufferQueue 类是 Android 中所有图形处理操作的核心。它的作用很简单:将生成图形数据缓冲区的一方(生产方)连接到接受数据以进行显示或进一步处理的一方(消耗方)。<em></em><em></em>几乎所有在系统中移动图形数据缓冲区的内容都依赖于 BufferQueue。</p>
+
+<p>gralloc 内存分配器会进行缓冲区分配,并通过供应商特定的 HAL 接口来实现(请参见 <code>hardware/libhardware/include/hardware/gralloc.h</code>)。<code>alloc()</code> 函数获得预期的参数(宽度、高度、像素格式)以及一组用法标记(详见下文)。</p>
+
+<h2 id="BufferQueue">BufferQueue 生产方和消耗方</h2>
+
+<p>基本用法很简单:生产方请求一个可用的缓冲区 (<code>dequeueBuffer()</code>),并指定一组特性,包括宽度、高度、像素格式和用法标记。生产方填充缓冲区并将其返回到队列 (<code>queueBuffer()</code>)。随后,消耗方获取该缓冲区 (<code>acquireBuffer()</code>) 并使用该缓冲区的内容。当消耗方操作完毕后,将该缓冲区返回到队列 (<code>releaseBuffer()</code>)。</p>
+
+<p><em></em>最新的 Android 设备支持“同步框架”,这使得系统能够在与可以异步处理图形数据的硬件组件结合使用时提高工作效率。例如,生产方可以提交一系列 OpenGL ES 绘制命令,然后在渲染完成之前将输出缓冲区加入队列。该缓冲区伴有一个栅栏,当内容准备就绪时,栅栏会发出信号。当该缓冲区返回到空闲列表时,会伴有第二个栅栏,因此消耗方可以在内容仍在使用期间释放该缓冲区。该方法缩短了缓冲区通过系统时的延迟时间,并提高了吞吐量。</p>
+
+<p>队列的一些特性(例如可以容纳的最大缓冲区数)由生产方和消耗方联合决定。但是,BufferQueue 负责根据需要分配缓冲区。除非特性发生变化,否则将会保留缓冲区;例如,如果生产方请求具有不同大小的缓冲区,则系统会释放旧的缓冲区,并根据需要分配新的缓冲区。</p>
+
+<p>生产方和消耗方可以存在于不同的进程中。目前,消耗方始终创建和拥有数据结构。在旧版本的 Android 中,只有生产方才进行 Binder 处理(即生产方可能在远程进程中,但消耗方必须存在于创建队列的进程中)。Android 4.4 和更高版本已发展为更常规的实现。</p>
+
+<p>BufferQueue 永远不会复制缓冲区内容(移动如此多的数据是非常低效的操作)。相反,缓冲区始终通过句柄进行传递。</p>
+
+<h2 id="gralloc_HAL">gralloc HAL 用法标记</h2>
+
+<p>gralloc 分配器不仅仅是在原生堆上分配内存的另一种方法;在某些情况下,分配的内存可能并非缓存一致,或者可能完全无法从用户空间访问。分配的性质由用法标记确定,这些标记包括以下属性:</p>
+
+<ul>
+<li>从软件 (CPU) 访问内存的频率</li>
+<li>从硬件 (GPU) 访问内存的频率</li>
+<li>是否将内存用作 OpenGL ES (GLES) 纹理</li>
+<li>视频编码器是否会使用内存</li>
+</ul>
+
+<p>例如,如果您的格式指定 RGBA 8888 像素,并且您指明将从软件访问缓冲区(这意味着您的应用将直接触摸像素),则分配器必须按照 R-G-B-A 的顺序为每个像素创建 4 个字节的缓冲区。相反,如果您指明仅从硬件访问缓冲区且缓冲区作为 GLES 纹理,则分配器可以执行 GLES 驱动程序所需的任何操作 - BGRA 排序、非线性搅和布局、替代颜色格式等。允许硬件使用其首选格式可以提高性能。</p>
+
+<p>某些值在特定平台上无法组合。例如,视频编码器标记可能需要 YUV 像素,因此将无法添加软件访问权并指定 RGBA 8888。</p>
+
+<p>gralloc 分配器返回的句柄可以通过 Binder 在进程之间传递。</p>
+
+<h2 id="tracking">使用 Systrace 跟踪 BufferQueue</h2>
+
+<p>要真正了解图形缓冲区如何移动,请使用 Systrace。系统级图形代码经过很好的检测,很多相关的应用框架代码也是如此。</p>
+
+<p>要完整地说明如何有效地使用 Systrace,则需要很长的篇幅。我们首先介绍如何启用 <code>gfx</code>、<code>view</code> 和 <code>sched</code> 标记。您还将在跟踪记录中看到 BufferQueue。如果您以前使用过 Systrace,则可能已经见到过它们,但不知道它们是什么。例如,如果您在 <a href="https://github.com/google/grafika">Grafika</a> 的“播放视频 (SurfaceView)”正在运行时获取跟踪记录,则标有 SurfaceView 的行会告诉您在任何给定时间排队的缓冲区数量。<em></em></p>
+
+<p>当应用处于活动状态时,该值会递增(触发 MediaCodec 解码器渲染帧),而在 SurfaceFlinger 正在工作和消耗缓冲区时,该值会递减。当以 30fps 的帧率显示视频时,队列的值从 0 变为 1,因为大约 60fps 的显示速度可以轻松跟上来源的帧率。(另请注意,SurfaceFlinger 仅在有工作要执行时才被唤醒,而不是每秒唤醒 60 次。系统会尽力尝试避免工作,而且如果屏幕没有任何更新,将完全停用 VSYNC。)</p>
+
+<p>如果您切换到 Grafika 的“播放视频 (TextureView)”并获取新的跟踪记录,将看到一个标为 com.android.grafika/com.android.grafika.PlayMovieActivity 的行。这是主界面层,其只是另一个 BufferQueue。由于 TextureView 渲染到界面层(而不是单独的层),因此您将在此看到所有视频驱动的更新。</p>
+
+<p>有关 Systrace 工具的更多信息,请参阅 <a href="https://developer.android.com/studio/profile/systrace-commandline.html">Systrace 文档</a>。</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/graphics/arch-egl-opengl.html b/zh-cn/devices/graphics/arch-egl-opengl.html
new file mode 100644
index 0000000..cc2833f
--- /dev/null
+++ b/zh-cn/devices/graphics/arch-egl-opengl.html
@@ -0,0 +1,47 @@
+<html devsite><head>
+    <title>EGLSurface 和 OpenGL ES</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 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>OpenGL ES 定义了一个渲染图形的 API,但没有定义窗口系统。为了让 GLES 能够适合各种平台,GLES 将与知道如何通过操作系统创建和访问窗口的库结合使用。用于 Android 的库称为 EGL。如果要绘制纹理多边形,应使用 GLES 调用;如果要在屏幕上进行渲染,应使用 EGL 调用。</p>
+
+<p>在使用 GLES 进行任何操作之前,需要创建一个 GL 上下文。在 EGL 中,这意味着要创建一个 EGLContext 和一个 EGLSurface。GLES 操作适用于当前上下文,该上下文通过线程局部存储访问,而不是作为参数进行传递。这意味着您必须注意渲染代码在哪个线程上执行,以及该线程上的当前上下文。</p>
+
+ <h2 id="egl_surface">EGLSurface</h2>
+
+<p>EGLSurface 可以是由 EGL 分配的离屏缓冲区(称为“pbuffer”),或由操作系统分配的窗口。EGL 窗口 Surface 通过 <code>eglCreateWindowSurface()</code> 调用被创建。该调用将“窗口对象”作为参数,在 Android 上,该对象可以是 SurfaceView、SurfaceTexture、SurfaceHolder 或 Surface,所有这些对象下面都有一个 BufferQueue。当您进行此调用时,EGL 将创建一个新的 EGLSurface 对象,并将其连接到窗口对象的 BufferQueue 的生产方接口。此后,渲染到该 EGLSurface 会导致一个缓冲区离开队列、进行渲染,然后排队等待消耗方使用。(术语“窗口”表示预期用途,但请注意,输出内容不一定会显示在显示屏上。)</p>
+
+<p>EGL 不提供锁定/解锁调用,而是由您发出绘制命令,然后调用 <code>eglSwapBuffers()</code> 来提交当前帧。方法名称来自传统的前后缓冲区交换,但实际实现可能会有很大的不同。</p>
+
+<p>一个 Surface 一次只能与一个 EGLSurface 关联(您只能将一个生产方连接到一个 BufferQueue),但是如果您销毁该 EGLSurface,它将与该 BufferQueue 断开连接,并允许其他内容连接到该 BufferQueue。</p>
+
+<p>通过更改“当前”EGLSurface,指定线程可在多个 EGLSurface 之间进行切换。一个 EGLSurface 一次只能在一个线程上处于当前状态。</p>
+
+<p>关于 EGLSurface 最常见的一个错误理解就是假设它只是 Surface 的另一方面(如 SurfaceHolder)。它是一个相关但独立的概念。您可以在没有 Surface 作为支持的 EGLSurface 上绘制,也可以在没有 EGL 的情况下使用 Surface。EGLSurface 仅为 GLES 提供一个绘制的地方。</p>
+
+<h2 id="anativewindow">ANativeWindow</h2>
+
+<p>公开的 Surface 类以 Java 编程语言实现。C/C++ 中的同等项是 ANATIONWindow 类,由 <a href="https://developer.android.com/ndk/index.html">Android NDK</a> 半公开。您可以使用 <code>ANativeWindow_fromSurface()</code> 调用从 Surface 获取 ANativeWindow。就像它的 Java 语言同等项一样,您可以对 ANativeWindow 进行锁定、在软件中进行渲染,以及解锁并发布。</p>
+
+<p>要从原生代码创建 EGL 窗口 Surface,可将 EGLNativeWindowType 的实例传递到 <code>eglCreateWindowSurface()</code>。EGLNativeWindowType 是 ANativeWindow 的同义词,您可以自由地在它们之间转换。</p>
+
+<p>基本的“原生窗口”类型只是封装 BufferQueue 的生产方,这一点并不足为奇。</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/graphics/arch-gameloops.html b/zh-cn/devices/graphics/arch-gameloops.html
new file mode 100644
index 0000000..fde6781
--- /dev/null
+++ b/zh-cn/devices/graphics/arch-gameloops.html
@@ -0,0 +1,82 @@
+<html devsite><head>
+    <title>游戏循环</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 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>实现游戏循环的热门方法如下所示:</p>
+
+<pre class="devsite-click-to-copy">
+while (playing) {
+    advance state by one frame
+    render the new frame
+    sleep until it’s time to do the next frame
+}
+</pre>
+
+<p>此方法还存在一些问题,最根本的问题是游戏可以定义什么是“帧”这一情况。不同的显示屏将以不同的速率刷新,并且该速率可能会随时间变化。如果您生成帧的速度快于显示屏能够显示的速度,则您偶尔不得不丢掉一个帧。如果生成帧的速度过慢,则 SurfaceFlinger 会定期无法找到新的缓冲区来获取帧,并将重新显示上一帧。这两种情况都会导致明显异常。</p>
+
+<p>您要做的是匹配显示屏的帧速率,并根据从上一帧起经过的时间推进游戏状态。有两种方法可以实现这一点:(1) 将 BufferQueue 填满并依赖“交换缓冲区”背压;(2) 使用 Choreographer (API 16+)。</p>
+
+<h2 id="stuffing">队列填充</h2>
+
+<p>只需尽快交换缓冲区,即可轻松实现队列填充。在 Android 的早期版本中,这样做实际上可能会使您遭受处罚,其中 <code>SurfaceView#lockCanvas()</code> 会让您休眠 100 毫秒。现在,它由 BufferQueue 调节,且 BufferQueue 的清空速度与 SurfaceFlinger 的消费能力相关。</p>
+
+<p>可在 <a href="https://code.google.com/p/android-breakout/">Android Breakout</a> 中找到此方法的一个示例。它使用 GLSurfaceView,后者在一个循环中运行,而该循环会调用应用的 onDrawFrame() 回调,然后交换缓冲区。如果 BufferQueue 已满,则直到缓冲区可用之后才会调用 <code>eglSwapBuffers()</code>。当 SurfaceFlinger 获取一个新的用于显示的缓冲区后,便会释放之前获取的缓冲区,这时这些缓冲区就变为可用状态。因为这发生在 VSYNC 上,所以您的绘图循环时间将与刷新率相匹配。大多数情况下是这样的。</p>
+
+<p>此方法存在几个问题。首先,应用与 SurfaceFlinger 操作组件关联,后者所花费的时间各不相同,具体取决于要执行的工作量以及是否与其他进程抢占 CPU 时间。由于您的游戏状态根据缓冲区交换的间隔时间推进,因此动画不会以一致的速率更新。但是以 60fps 的速率运行时,不一致会在一段时间之后达到平衡,因此您可能不会注意到卡顿。</p>
+
+<p>其次,由于 BufferQueue 尚未填满,因此前几次缓冲区交换的速度会非常快。所计算的帧间隔时间将接近于零,因此游戏会生成几个不会发生任何操作的帧。在 Breakout 这样的游戏(每次刷新都会更新屏幕)中,除了游戏首次启动(或取消暂停)时之外,队列总是满的,因此效果不明显。偶尔暂停动画,然后返回到快速模式的游戏可能会出现异常问题。</p>
+
+<h2 id="choreographer">Choreographer</h2>
+
+<p>通过 Choreographer,您可以设置在下一个 VSYNC 上触发的回调。实际的 VSYNC 时间以参数形式传入。因此,即使您的应用不会立即唤醒,您仍然可以准确了解显示屏刷新周期何时开始。使用此值(而非当前时间)可为您的游戏状态更新逻辑产生一致的时间源。</p>
+
+<p>遗憾的是,您在每个 VSYNC 之后得到回调这一事实并不能保证及时执行回调,也无法保证您能够迅速高效地对其进行操作。您的应用需要手动检测卡顿和丢帧的情况。</p>
+
+<p>Grafika 中的“记录 GL 应用”操作组件提供了此情况的示例。在某些设备(例如 Nexus 4 和 Nexus 5)上,如果您只是坐视不理,则操作组件会开始丢帧。GL 呈现微不足道,但有时会重新绘制 View 元素;如果设备已进入降低功耗模式,则测量/布局传递可能需要很长时间(根据 systrace,Android 4.4 上的时钟速度减慢之后,这一传递需要 28 毫秒,而不是 6 毫秒。如果您在屏幕上拖动手指,它会认为您在与该操作组件互动,因此时钟会保持高速状态,您永远不会丢帧)。</p>
+
+<p>如果当前时间超过 VSYNC 时间后 N 毫秒,则简单的解决办法是在 Choreographer 回调中丢掉一帧。理想情况下,N 的值取决于先前观察到的 VSYNC 间隔。例如,如果刷新周期是 16.7 毫秒 (60fps),而您的运行时间延迟超过 15 毫秒,则可能会丢失一帧。</p>
+
+<p>如果您查看“记录 GL 应用”运行情况,则会看到丢帧计数器计数增加了,甚至会在丢帧时在边框中看到红色闪烁情况。除非您的观察力非常强,否则不会看到动画卡顿现象。以 60fps 的速率运行时,只要动画以固定速率继续播放,应用可以偶尔丢帧,没有任何人会注意到。您成功的几率在一定程度上取决于您正在绘制的内容、显示屏的特性,以及使用该应用的用户发现卡顿的擅长程度。</p>
+
+<h2 id="thread">线程管理</h2>
+
+<p>一般而言,如果您要呈现到 SurfaceView、GLSurfaceView 或 TextureView 上,则需要在专用线程中进行呈现。请勿在界面线程上进行任何“繁重”或花费时间不定的操作。</p>
+
+<p>Breakout 和“记录 GL 应用”使用专用呈现程序线程,并且也在该线程上更新动画状态。只要可以快速更新游戏状态,这就是合理的方法。</p>
+
+<p>其他游戏将游戏逻辑和呈现完全分开。如果您有一个简单的游戏,只是每 100 毫秒移动一个块,则您可以使用一个只进行以下操作的专用线程:</p>
+
+<pre class="devsite-click-to-copy">
+    run() {
+        Thread.sleep(100);
+        synchronized (mLock) {
+            moveBlock();
+        }
+    }
+</pre>
+
+<p>(您可能需要让休眠时间基于固定的时钟,以防止漂移现象 - sleep() 不完全一致,并且 moveBlock() 需要花费的时间不为零 - 但是您了解就行。)</p>
+
+<p>当绘图代码唤醒时,它就会抓住锁,获取块的当前位置,释放锁,然后进行绘制。您无需基于帧间增量时间进行分数移动,只需要有一个移动对象的线程,以及另一个在绘制开始时随地绘制对象的线程。</p>
+
+<p>如果您想要针对复杂的场景创建即将到来的事件列表(按唤醒时间排序),且场景在下一个事件结束之前保持休眠状态,则原理是一样的。</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/graphics/arch-sf-hwc.html b/zh-cn/devices/graphics/arch-sf-hwc.html
new file mode 100644
index 0000000..79d34db
--- /dev/null
+++ b/zh-cn/devices/graphics/arch-sf-hwc.html
@@ -0,0 +1,96 @@
+<html devsite><head>
+    <title>SurfaceFlinger 和 Hardware Composer</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 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>拥有图形数据缓冲区的确不错,如果还能在设备屏幕上查看它们就更是锦上添花了。这正是 SurfaceFlinger 和 Hardware Composer HAL 的用武之地。</p>
+
+<h2 id="surfaceflinger">SurfaceFlinger</h2>
+
+<p>SurfaceFlinger 的作用是接受来自多个来源的数据缓冲区,对它们进行合成,然后发送到显示设备。以前,该过程通过软件到硬件帧缓冲区(例如 <code>/dev/graphics/fb0</code>)的位块传输来实现,但是这样的日子已经远去。</p>
+
+<p>当应用进入前台时,WindowManager 服务会向 SurfaceFlinger 请求一个绘图 Surface。SurfaceFlinger 会创建一个其主要组件为 BufferQueue 的层,而 SurfaceFlinger 是其消耗方。生产方端的 Binder 对象通过 WindowManager 传递到应用,然后应用可以开始直接将帧发送到 SurfaceFlinger。</p>
+
+<p class="note"><strong>注意:</strong>尽管本部分使用 SurfaceFlinger 术语,但 WindowManager 会使用术语“窗口”(而不是“层”)…而将“层”用来表示其他内容。<em></em><em></em>(有人认为 SurfaceFlinger 实际上应称为 LayerFlinger。)</p>
+
+<p>大多数应用通常在屏幕上有三个层:屏幕顶部的状态栏、底部或侧面的导航栏以及应用的界面。有些应用会拥有更多或更少的层(例如,默认主屏幕应用有一个单独的壁纸层,而全屏游戏可能会隐藏状态栏)。每个层都可以单独更新。状态栏和导航栏由系统进程渲染,而应用层由应用渲染,两者之间不进行协调。</p>
+
+<p>设备显示会按一定速率刷新,在手机和平板电脑上通常为每秒 60 帧。如果显示内容在刷新期间更新,则会出现撕裂现象;因此,请务必只在周期之间更新内容。在可以安全更新内容时,系统便会收到来自显示设备的信号。由于历史原因,我们将该信号称为 VSYNC 信号。</p>
+
+<p>刷新率可能会随时间而变化,例如,一些移动设备的刷新率范围在 58 fps 到 62 fps 之间,具体要视当前条件而定。对于连接了 HDMI 的电视,刷新率在理论上可以下降到 24 Hz 或 48 Hz,以便与视频相匹配。由于每个刷新周期只能更新屏幕一次,因此以 200 fps 的刷新率为显示设备提交缓冲区只是在做无用功,因为大多数帧永远不会被看到。SurfaceFlinger 不会在应用提交缓冲区时执行操作,而是在显示设备准备好接收新的缓冲区时才会唤醒。</p>
+
+<p>当 VSYNC 信号到达时,SurfaceFlinger 会遍历它的层列表,以寻找新的缓冲区。如果找到新的缓冲区,它会获取该缓冲区;否则,它会继续使用以前获取的缓冲区。SurfaceFlinger 总是需要可显示的内容,因此它会保留一个缓冲区。如果在某个层上没有提交缓冲区,则该层会被忽略。</p>
+
+<p>SurfaceFlinger 在收集可见层的所有缓冲区之后,便会询问 Hardware Composer 应如何进行合成。</p>
+
+<h2 id="hwc">Hardware Composer</h2>
+
+<p>Hardware Composer HAL (HWC) 是在 Android 3.0 中推出的,并且多年来一直都在不断演进。它主要是用来确定通过可用硬件来合成缓冲区的最有效方法。作为 HAL,其实现是特定于设备的,而且通常由显示设备硬件原始设备制造商 (OEM) 完成。</p>
+
+<p>当考虑叠加平面时,很容易发现这种方法的好处。它的目的是在显示硬件(而不是 GPU)中将多个缓冲区合成在一起。例如,假设有一部处于纵向模式的普通 Android 手机,其状态栏在顶部,导航栏在底部,其他地方为应用内容。<em></em>每个层的内容都在单独的缓冲区中。您可以使用以下任一方法处理合成:</p>
+
+<ul>
+<li>将应用内容渲染到暂存缓冲区中,然后在其上渲染状态栏,再在其上渲染导航栏,最后将暂存缓冲区传送到显示硬件。</li>
+<li>将三个缓冲区全部传送到显示硬件,并告知它从不同的缓冲区读取屏幕不同部分的数据。</li>
+</ul>
+
+<p>后一种方法可以显著提高效率。</p>
+
+<p>显示处理器功能差异很大。叠加层的数量(无论层是否可以旋转或混合)以及对定位和叠加的限制很难通过 API 表达。HWC 会尝试通过一系列决策来适应这种多样性:</p>
+
+<ol>
+<li>SurfaceFlinger 向 HWC 提供一个完整的层列表,并询问“您希望如何处理这些层?”</li>
+<li>HWC 的响应方式是将每个层标记为叠加层或 GLES 合成。</li>
+<li>SurfaceFlinger 会处理所有 GLES 合成,将输出缓冲区传送到 HWC,并让 HWC 处理其余部分。</li>
+</ol>
+
+<p>由于硬件供应商可以定制决策代码,因此可以在每台设备上实现最佳性能。</p>
+
+<p>当屏幕上的内容没有变化时,叠加平面的效率可能会低于 GL 合成。当叠加层内容具有透明像素且叠加层混合在一起时,尤其如此。在此类情况下,HWC 可以选择为部分或全部层请求 GLES 合成,并保留合成的缓冲区。如果 SurfaceFlinger 返回要求合成同一组缓冲区,HWC 可以继续显示先前合成的暂存缓冲区。这可以延长闲置设备的电池续航时间。</p>
+
+<p>运行 Android 4.4 或更高版本的设备通常支持 4 个叠加平面。尝试合成多于叠加层的层会导致系统对其中一些层使用 GLES 合成,这意味着应用使用的层数会对功耗和性能产生重大影响。</p>
+
+<h2 id="virtual-displays">虚拟显示设备</h2>
+
+<p>SurfaceFlinger 支持一个主要显示设备(即内置在手机或平板电脑中的显示屏)、一个外部显示设备(如通过 HDMI 连接的电视)以及一个或多个令合成的输出在系统中可用的虚拟显示设备。虚拟显示设备可用于记录屏幕或通过网络发送屏幕。</p>
+
+<p>虚拟显示设备可以与主显示设备共享相同的一组层(层堆叠),也可拥有自己的一组层。虚拟显示设备没有 VSYNC,因此主显示设备的 VSYNC 用于为所有显示设备触发合成。</p>
+
+<p>在旧版本的 Android 中,虚拟显示设备总是通过 GLES 合成,而 Hardware Composer 管理的合成仅用于主要显示设备。在 Android 4.4 中,Hardware Composer 能够参与虚拟显示设备合成。</p>
+
+<p>正如您所预期的,为虚拟显示设备生成的帧会写入 BufferQueue。</p>
+
+<h2 id="screenrecord">案例研究:screenrecord</h2>
+
+<p><a href="https://android.googlesource.com/platform/frameworks/av/+/marshmallow-release/cmds/screenrecord/">screenrecord 命令</a>可让您将屏幕上显示的所有内容作为一个 .mp4 文件记录在磁盘上。为此,我们必须从 SurfaceFlinger 接收合成的帧,将它们写入视频编码器,然后将已编码的视频数据写入一个文件。视频编解码器由单独的进程 (mediaserver) 进行管理,因此我们必须在系统中移动大量图形缓冲区。为了使其更具挑战性,我们尝试以全分辨率录制 60 fps 的视频。高效完成这项工作的关键是 BufferQueue。</p>
+
+<p>MediaCodec 类允许应用以缓冲区中的原始字节或通过 <a href="/devices/graphics/arch-sh.html">Surface</a> 来提供数据。当 screenrecord 请求访问视频编码器时,mediaserver 会创建一个 BufferQueue,将其自身连接到消耗方端,然后将生产方端作为 Surface 传回到 screenrecord。</p>
+
+<p>然后,screenrecord 命令要求 SurfaceFlinger 创建一个镜像主显示设备的虚拟显示设备(即,它具有完全相同的层),并指示它将输出发送到来自 mediaserver 的 Surface。在这种情况下,SurfaceFlinger 是缓冲区的生产方,而不是消耗方。</p>
+
+<p>配置完成后,screenrecord 会等待显示编码数据。在应用绘制时,其缓冲区会前往 SurfaceFlinger,SurfaceFlinger 将它们合成为单个缓冲区,然后直接发送到 mediaserver 中的视频编码器。screenrecord 进程甚至从未看到过完整的帧。在内部,mediaserver 具有自己的移动缓冲区的方式,这种方式还通过句柄传递数据,从而最大限度地降低开销。</p>
+
+<h2 id="simulate-secondary">案例研究:模拟辅助显示设备</h2>
+
+<p>WindowManager 可以要求 SurfaceFlinger 创建一个可见层,将 SurfaceFlinger 作为其 BufferQueue 消耗方。也可以要求 SurfaceFlinger 创建一个虚拟显示设备,同样以 SurfaceFlinger 作为其 BufferQueue 生产方。如果连接它们并配置渲染到可见层的虚拟显示设备,会出现什么情况?</p>
+
+<p>创建一个闭合循环,其中合成的屏幕显示在窗口中。该窗口现在是合成输出的一部分,因此在下一次刷新时,该窗口中的合成图像也会显示窗口内容(然后<a href="https://en.wikipedia.org/wiki/Turtles_all_the_way_down">一直循环下去</a>)。要实际查看该过程,请在设置中启用<a href="http://developer.android.com/tools/index.html">开发者选项</a>,选择<strong>模拟辅助显示设备</strong>,然后启用一个窗口。另外有个好处是,可使用 screenrecord 捕获启用显示设备的操作,然后逐帧播放。</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/graphics/arch-sh.html b/zh-cn/devices/graphics/arch-sh.html
new file mode 100644
index 0000000..a067acc
--- /dev/null
+++ b/zh-cn/devices/graphics/arch-sh.html
@@ -0,0 +1,51 @@
+<html devsite><head>
+    <title>Surface 和 SurfaceHolder</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 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>从 1.0 开始,<a href="http://developer.android.com/reference/android/view/Surface.html">Surface</a> 类一直是公共 API 的一部分。它的描述简单如下:“在由屏幕合成器管理的原始缓冲区上进行处理”。这句描述在最初编写时是准确的,但在现代系统上却远远不足。</p>
+
+<p>Surface 表示通常(但并非总是!)由 SurfaceFlinger 消耗的缓冲区队列的生产方。当您渲染到 Surface 上时,产生的结果将进入相关缓冲区,该缓冲区被传递给消耗方。Surface 不仅仅是您可以随意擦写的原始内存数据块。</p>
+
+<p>用于显示 Surface 的 BufferQueue 通常配置为三重缓冲;但按需分配缓冲区。因此,如果生产方足够缓慢地生成缓冲区 - 也许是以 30fps 的速度在 60fps 的显示屏上播放动画 - 队列中可能只有两个分配的缓冲区。这有助于最小化内存消耗。您可以看到与 <code>dumpsys SurfaceFlinger</code> 输出中每个层级相关的缓冲区的摘要。</p>
+
+<h2 id="canvas">画布渲染</h2>
+
+<p>曾经有一段时间所有渲染都是用软件完成的,您今天仍然可以这样做。低级实现由 Skia 图形库提供。如果要绘制一个矩形,您可以调用库,然后它会在缓冲区中适当地设置字节。为了确保两个客户端不会同时更新某个缓冲区,或者在该缓冲区正在被显示时写入该缓冲区,您必须锁定该缓冲区才能进行访问。<code>lockCanvas()</code> 可锁定该缓冲区并返回用于绘制的 Canvas,<code>unlockCanvasAndPost()</code> 则解锁该缓冲区并将其发送到合成器。</p>
+
+<p>随着时间的推移,出现了具有通用 3D 引擎的设备,于是 Android 围绕 OpenGL ES 进行了重新定位。然而,必须确保旧 API 依然适用于应用和应用框架代码,所以我们努力对 Canvas API 进行了硬件加速。从<a href="http://developer.android.com/guide/topics/graphics/hardware-accel.html">硬件加速</a>页面的图表可以看出,整个过程并非一帆风顺。特别要注意的一点是,虽然提供给 View 的 <code>onDraw()</code> 方法的 Canvas 可能已硬件加速,但是当应用通过 <code>lockCanvas()</code> 直接锁定 Surface 时所获得的 Canvas 从未获得硬件加速。</p>
+
+<p>当您锁定一个 Surface 以便访问 Canvas 时,“CPU 渲染器”将连接到 BufferQueue 的生产方,直到 Surface 被销毁时才会断开连接。大多数其他生产方(如 GLES)可以断开连接并重新连接到 Surface,但是基于 Canvas 的“CPU 渲染器”则不能。这意味着如果您已经为某个 Canvas 将相关 Surface 锁定,则无法使用 GLES 在该 Surface 上进行绘制或从视频解码器向其发送帧。</p>
+
+<p>生产方首次从 BufferQueue 请求缓冲区时,缓冲区将被分配并初始化为零。有必要进行初始化,以避免意外地在进程之间共享数据。然而,当您重新使用缓冲区时,以前的内容仍然存在。如果您反复调用 <code>lockCanvas()</code> 和 <code>unlockCanvasAndPost()</code> 而不绘制任何内容,则会在先前渲染的帧之间循环。</p>
+
+<p>Surface 锁定/解锁代码会保留对先前渲染的缓冲区的引用。如果在锁定 Surface 时指定了脏区域,那么它将从以前的缓冲区复制非脏像素。缓冲区很有可能由 SurfaceFlinger 或 HWC 处理;但是由于我们只需从中读取内容,所以无需等待独占访问。</p>
+
+<p>应用直接在 Surface 上进行绘制的主要非 Canvas 方法是通过 OpenGL ES。相关说明请参阅 <a href="#eglsurface">EGLSurface 和 OpenGL ES</a> 部分。</p>
+
+<h2 id="surfaceholder">SurfaceHolder</h2>
+
+<p>与 Surface 配合使用的一些功能需要 SurfaceHolder,特别是 SurfaceView。最初的想法是,Surface 代表合成器管理的原始缓冲区,而 SurfaceHolder 由应用管理,并跟踪更高层次的信息(如维度和格式)。Java 语言定义对应的是底层本机实现。可以说,这种划分方式已不再有用,但它长期以来一直是公共 API 的一部分。</p>
+
+<p>一般来说,与 View 相关的任何内容都涉及到 SurfaceHolder。一些其他 API(如 MediaCodec)将在 Surface 本身上运行。您可以轻松地从 SurfaceHolder 获取 Surface,因此当您拥有 SurfaceHolder 时,使用它即可。</p>
+
+<p>用于获取和设置 Surface 参数(例如大小和格式)的 API 是通过 SurfaceHolder 实现的。</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/graphics/arch-st.html b/zh-cn/devices/graphics/arch-st.html
new file mode 100644
index 0000000..c1c9d6f
--- /dev/null
+++ b/zh-cn/devices/graphics/arch-st.html
@@ -0,0 +1,91 @@
+<html devsite><head>
+    <title>SurfaceTexture</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 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>SurfaceTexture 类是在 Android 3.0 中推出的。就像 SurfaceView 是 Surface 和 View 的组合一样,SurfaceTexture 是 Surface 和 GLES 纹理的粗略组合(包含几个注意事项)。</p>
+
+<p>当您创建 SurfaceTexture 时,会创建一个应用是其消耗方的 BufferQueue。如果生产方将新的缓冲区加入队列,您的应用便会通过回调 (<code>onFrameAvailable()</code>) 获得通知。应用调用 <code>updateTexImage()</code>(这会释放先前保留的缓冲区),从队列中获取新的缓冲区,然后发出一些 EGL 调用,让缓冲区可作为外部纹理供 GLES 使用。</p>
+
+<h2 id="ext_texture">外部纹理</h2>
+<p>外部纹理 (<code>GL_TEXTURE_EXTERNAL_OES</code>) 与 GLES (<code>GL_TEXTURE_2D</code>) 创建的纹理并不完全相同:您对渲染器的配置必须有所不同,而且有一些操作是不能对外部纹理执行的。关键是,您可以直接从 BufferQueue 接收到的数据中渲染纹理多边形。gralloc 支持各种格式,因此我们需要保证缓冲区中数据的格式是 GLES 可以识别的格式。为此,当 SurfaceTexture 创建 BufferQueue 时,它将消耗方用法标记设置为 <code>GRALLOC_USAGE_HW_TEXTURE</code>,确保由 gralloc 创建的缓冲区均可供 GLES 使用。</p>
+
+<p>由于 SurfaceTexture 会与 EGL 上下文交互,因此您必须小心地从正确的会话中调用其方法(详见类文档)。</p>
+
+<h2 id="time_transforms">时间戳和转换</h2>
+<p>如果您深入阅读类文档,您会看到两个奇怪的调用。一个调用会检索时间戳,而另一个调用是转换矩阵,每个调用的值都通过事先调用 <code>updateTexImage()</code> 来设置。事实证明,BufferQueue 不只是向消耗方传递缓冲区句柄。每个缓冲区都附有时间戳和转换参数。</p>
+
+<p>提供转换是为了提高效率。在某些情况下,源数据可能以错误的方向传递给消耗方;但是,我们可以按照数据的当前方向发送数据并使用转换对其进行更正,而不是在发送数据之前对其进行旋转。在使用数据时,转换矩阵可以与其他转换合并,从而最大限度降低开销。</p>
+
+<p>时间戳对于某些缓冲区来源非常有用。例如,假设您将生产方接口连接到相机的输出端(使用 <code>setPreviewTexture()</code>)。要创建视频,您需要为每个帧设置演示时间戳;不过您需要根据截取帧的时间(而不是应用收到缓冲区的时间)来设置该时间戳。随缓冲区提供的时间戳由相机代码设置,从而获得一系列更一致的时间戳。</p>
+
+<h2 id="surfacet">SurfaceTexture 和 Surface</h2>
+
+<p>如果仔细观察 API,您会发现应用只能通过一种方式来创建简单 Surface,即通过将 SurfaceTexture 作为唯一参数的构造函数来创建。(在 API 11 之前,根本没有用于 Surface 的公开构造函数。)如果将 SurfaceTexture 视为 Surface 和纹理的组合,这看起来可能有点落后。</p>
+
+<p>深入来看,SurfaceTexture 称为 GLConsumer,它更准确地反映了其作为 BufferQueue 的所有方和消耗方的角色。从 SurfaceTexture 创建 Surface 时,您所做的是创建一个表示 SurfaceTexture 的 BufferQueue 生产方端的对象。</p>
+
+<h2 id="continuous_capture">案例研究:Grafika 的连续拍摄</h2>
+
+<p>相机可以提供一个适合作为电影进行录制的帧流。要在屏幕上显示它,您可以创建一个 SurfaceView,将 Surface 传递给 <code>setPreviewDisplay()</code>,然后让生产方(相机)和消耗方 (SurfaceFlinger) 完成所有工作。要录制视频,您可以使用 MediaCodec 的 <code>createInputSurface()</code> 创建一个 Surface,将其传递给相机,然后便可高枕无忧了。若要边显示边录制,您必须使用更多内容。</p>
+
+<p>在录制视频时,连续拍摄 Activity 会显示相机录制的视频。<em></em>在这种情况下,已编码的视频将写入内存中的环形缓冲区,该缓冲区可随时保存到磁盘。实现起来非常简单,只要您跟踪所有内容所在的位置即可。
+</p>
+
+<p>该流程涉及三个 BufferQueue,分别是由应用、SurfaceFlinger 和 mediaserver 所创建:</p>
+<ul>
+<li><strong>应用</strong>。该应用使用 SurfaceTexture 从相机接收帧,并将其转换为外部 GLES 纹理。</li>
+<li><strong>SurfaceFlinger</strong>。该应用声明一个我们用来显示帧的 SurfaceView。</li>
+<li><strong>MediaServer</strong>。您可以使用输入 Surface 配置 MediaCodec 编码器,以创建视频。</li>
+</ul>
+
+<img src="images/continuous_capture_activity.png" alt="Grafika 连续拍摄 Activity"/>
+
+<p class="img-caption"><strong>图 1.</strong>Grafika 的连续拍摄 Activity。箭头指示相机的数据传输路径,BufferQueue 则用颜色标示(生产方为青色,消耗方为绿色)。</p>
+
+<p>已编码的 H.264 视频在应用进程中进入 RAM 中的环形缓冲区,并在点击拍摄按钮时使用 MediaMuxer 类写入到磁盘上的 MP4 文件中。</p>
+
+<p>三个 BufferQueue 都在应用中通过单个 EGL 上下文处理,且 GLES 操作在 UI 线程上执行。通常,不鼓励在 UI 线程上执行 SurfaceView 渲染,但是由于我们执行的是由 GLES 驱动程序异步处理的简单操作,因此没有问题。(如果视频编码器锁定,并且我们阻止尝试将缓冲区移出队列,该应用便会停止响应。而此时,我们无论怎样操作都可能会失败。)对已编码数据的处理(管理环形缓冲区并将其写入磁盘)是在单独的线程中执行的。</p>
+
+<p>大部分配置是在 SurfaceView 的 <code>surfaceCreated()</code> 回调中进行的。系统会创建 EGLContext,并为显示设备和视频编码器创建 EGLSurface。当新的帧到达时,我们会告知 SurfaceTexture 去获取它,并将其作为 GLES 纹理进行提供,然后使用 GLES 命令在每个 EGLSurface 上渲染它(从 SurfaceTexture 转发转换和时间戳)。编码器线程从 MediaCodec 拉取编码的输出内容,并将其存储在内存中。</p>
+
+<h2 id="st_vid_play">安全纹理视频播放</h2>
+<p>Android 7.0 支持对受保护的视频内容进行 GPU 后处理。这允许将 GPU 用于复杂的非线性视频效果(例如扭曲),将受保护的视频内容映射到纹理,以用于常规图形场景(例如,使用 OpenGL ES)和虚拟现实 (VR)。</p>
+
+<img src="images/graphics_secure_texture_playback.png" alt="安全纹理视频播放"/>
+<p class="img-caption"><strong>图 2.</strong>安全纹理视频播放</p>
+
+<p>使用以下两个扩展程序实现支持:</p>
+<ul>
+<li><strong>EGL 扩展程序</strong> (<code><a href="https://www.khronos.org/registry/egl/extensions/EXT/EGL_EXT_protected_content.txt">EGL_EXT_protected_content</a></code>)。允许创建受保护的 GL 上下文和 Surface,它们都可以对受保护的内容进行操作。</li>
+<li><strong>GLES 扩展程序</strong> (<code><a href="https://www.khronos.org/registry/gles/extensions/EXT/EXT_protected_textures.txt">GL_EXT_protected_textures</a></code>)。允许将纹理标记为受保护,以便它们可以用作帧缓冲区纹理附件。</li>
+</ul>
+
+<p>Android 7.0 还会更新 SurfaceTexture 和 ACodec (<code>libstagefright.so</code>),这样一来,即使窗口 Surface 没有加入窗口编写器(例如 SurfaceFlinger)的队列,也允许发送受保护的内容,并且提供受保护的视频 Surface 以在受保护的上下文中使用。该操作通过在受保护的上下文(由 ACodec 验证)中创建的 Surface 上设置正确的受保护消耗方位 (<code>GRALLOC_USAGE_PROTECTED</code>) 来完成。</p>
+
+<p>这些更改可使以下对象受益:应用开发者,他们可以创建应用来执行增强的视频效果,或在 GL 中(例如在 VR 中)使用受保护的内容来应用视频纹理;最终用户,他们可以在 GL 环境中(例如在 VR 中)查看高价值的视频内容(如电影和电视节目);以及原始设备制造商 (OEM),他们可通过增加设备功能(例如在 VR 中观看高清电影)提高产品销量。新的 EGL 和 GLES 扩展程序可以由系统芯片 (SoC) 提供商和其他供应商使用,目前是在 Nexus 6P 中使用的 Qualcomm MSM8994 SoC 芯片组上实现。
+
+</p><p>安全纹理视频播放为在 OpenGL ES 环境中进行强大的 DRM 实现奠定了基础。如果没有诸如 Widevine 级别 1 这样的强大 DRM 实现,许多内容提供商将不允许在 OpenGL ES 环境中渲染其高价值内容,从而阻止重要的 VR 用例(例如在 VR 中观看受 DRM 保护的内容)。</p>
+
+<p>AOSP 包括用于安全纹理视频播放的框架代码;驱动程序支持取决于供应商。设备实现人员必须实现 <code>EGL_EXT_protected_content</code> 和 <code>GL_EXT_protected_textures extensions</code>。使用您自己的编解码器库(替代 libstagefright)时,请注意,只要消耗方用法位包含 <code>GRALLOC_USAGE_PROTECTED</code>,<code>/frameworks/av/media/libstagefright/SurfaceUtils.cpp</code> 中的更改便会允许将标记为 <code>GRALLOC_USAGE_PROTECTED</code> 的缓冲区发送到 ANativeWindow,即便 ANativeWindow 没有直接加入窗口编写器的队列也可以。有关实现扩展程序的详细文档,请参见 Khronos 注册表(<a href="https://www.khronos.org/registry/egl/extensions/EXT/EGL_EXT_protected_content.txt">EGL_EXT_protected_content</a>、<a href="https://www.khronos.org/registry/gles/extensions/EXT/EXT_protected_textures.txt">GL_EXT_protected_textures</a>)。</p>
+
+<p>设备实现人员可能还需要进行硬件更改,才能确保映射到 GPU 的受保护内存仍受保护,且不可由未受保护的代码读取。</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/graphics/arch-tv.html b/zh-cn/devices/graphics/arch-tv.html
new file mode 100644
index 0000000..5f6606b
--- /dev/null
+++ b/zh-cn/devices/graphics/arch-tv.html
@@ -0,0 +1,62 @@
+<html devsite><head>
+    <title>TextureView</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 The Android Open Source Project
+
+      Licensed under the Apache License, Version 2.0 (the "License");
+      you may not use this file except in compliance with the License.
+      You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      See the License for the specific language governing permissions and
+      limitations under the License.
+  -->
+
+<p>我们在 Android 4.0 中引入了 TextureView 类,它结合了 View 与 SurfaceTexture,是我们在此讨论的最复杂的 View 对象。</p>
+
+<h2 id="render_gles">使用 GLES 呈现</h2>
+<p>我们已经知道,SurfaceTexture 是一个“GL 消费者”,它会占用图形数据的缓冲区,并将它们作为纹理进行提供。TextureView 会对 SurfaceTexture 进行封装,并接管对回调做出响应以及获取新缓冲区的责任。新缓冲区的就位会导致 TextureView 发出 View 失效请求。当被要求进行绘图时,TextureView 会使用最近收到的缓冲区的内容作为数据源,并根据 View 状态的指示,以相应的方式在相应的位置进行呈现。</p>
+
+<p>您可以使用 GLES 在 TextureView 上呈现内容,就像在 SurfaceView 上一样。只需将 SurfaceTexture 传递到 EGL 窗口创建调用即可。不过,这样做会导致潜在问题。</p>
+
+<p>在我们看到的大部分内容中,BufferQueue 是在不同进程之间传递缓冲区。当使用 GLES 呈现到 TextureView 时,生产者和消费者处于同一进程中,它们甚至可能会在单个线程上得到处理。假设我们以快速连续的方式从界面线程提交多个缓冲区。EGL 缓冲区交换调用需要使一个缓冲区从 BufferQueue 出列,而在有可用的缓冲区之前,它将处于暂停状态。只有当消费者获取一个缓冲区用于呈现时才会有可用的缓冲区,但是这一过程也会发生在界面线程上…因此我们陷入了困境。</p>
+
+<p>解决方案是让 BufferQueue 确保始终有一个可用的缓冲区能够出列,以使缓冲区交换始终不会暂停。要保证能够实现这一点,一种方法是让 BufferQueue 在新缓冲区加入队列时舍弃之前加入队列的缓冲区的内容,并对最小缓冲区计数和最大获取缓冲区计数施加限制(如果您的队列有三个缓冲区,而所有这三个缓冲区均被消费者获取,那么就没有可以出列的缓冲区,缓冲区交换调用必然会暂停或失败。因此我们需要防止消费者一次获取两个以上的缓冲区)。丢弃缓冲区通常是不可取的,因此仅允许在特定情况下发生,例如生产者和消费者处于同一进程中时。</p>
+
+<h2 id="surface_or_texture">SurfaceView 还是 TextureView?</h2>SurfaceView 和 TextureView 扮演的角色类似,但是拥有截然不同的实现。要作出最合适的选择,则需要了解它们各自的利弊。<p></p>
+
+<p>因为 TextureView 是 View 层次结构的固有成员,所以其行为与其他所有 View 一样,可以与其他元素相互叠加。您可以执行任意转换,并通过简单的 API 调用将内容检索为位图。</p>
+
+<p>影响 TextureView 的主要因素是合成步骤的表现。使用 SurfaceView 时,内容可以写到 SurfaceFlinger(理想情况下使用叠加层)合成的独立分层中。使用 TextureView 时,View 合成往往使用 GLES 执行,并且对其内容进行的更新也可能会导致其他 View 元素重绘(例如,如果它们位于 TextureView 上方)。View 呈现完成后,应用界面层必须由 SurfaceFlinger 与其他分层合成,以便您可以高效地将每个可见像素合成两次。对于全屏视频播放器,或任何其他相当于位于视频上方的界面元素的应用,SurfaceView 可以带来更好的效果。</p>
+
+<p>如之前所述,受 DRM 保护的视频只能在叠加平面上呈现。支持受保护内容的视频播放器必须使用 SurfaceView 进行实现。</p>
+
+<h2 id="grafika">案例研究:Grafika 的视频播放 (TextureView)</h2>
+
+<p>Grafika 包括一对视频播放器,一个用 TextureView 实现,另一个用 SurfaceView 实现。对于这两个视频播放器来说,仅将帧从 MediaCodec 发送到 Surface 的视频解码部分是一样的。这两种实现之间最有趣的区别是呈现正确宽高比所需的步骤。</p>
+
+<p>SurfaceView 需要 FrameLayout 的自定义实现,而要重新调整 SurfaceTexture 的大小,只需使用 <code>TextureView#setTransform()</code> 配置转换矩阵即可。对于前者,您会通过 WindowManager 向 SurfaceFlinger 发送新的窗口位置和大小值;对于后者,您仅仅是在以不同的方式呈现它。</p>
+
+<p>否则,两种实现均遵循相同的模式。创建 Surface 后,系统会启用播放。点击“播放”时,系统会启动视频解码线程,并将 Surface 作为输出目标。之后,应用代码不需要执行任何操作,SurfaceFlinger(适用于 SurfaceView)或 TextureView 会处理合成和显示。</p>
+
+<h2 id="decode">案例研究:Grafika 的双重解码</h2>
+
+<p>此操作组件演示了在 TextureView 中对 SurfaceTexture 的操控。</p>
+
+<p>此操作组件的基本结构是一对显示两个并排播放的不同视频的 TextureView。为了模拟视频会议应用的需求,我们希望在操作组件因屏幕方向发生变化而暂停和恢复时,MediaCodec 解码器能保持活动状态。原因在于,如果不对 MediaCodec 解码器使用的 Surface 进行完全重新配置,就无法更改它,而这是成本相当高的操作;因此我们希望 Surface 保持活动状态。Surface 只是 SurfaceTexture 的 BufferQueue 中生产者界面的句柄,而 SurfaceTexture 由 TextureView 管理;因此我们还需要 SurfaceTexture 保持活动状态。那么我们如何处理 TextureView 被关闭的情况呢?</p>
+
+<p>TextureView 提供的 <code>setSurfaceTexture()</code> 调用正好能够满足我们的需求。我们从 TextureView 获取对 SurfaceTexture 的引用,并将它们保存在静态字段中。当操作组件被关闭时,我们从 <code>onSurfaceTextureDestroyed()</code> 回调返回“false”,以防止 SurfaceTexture 被销毁。当操作组件重新启动时,我们将原来的 SurfaceTexture 填充到新的 TextureView 中。TextureView 类负责创建和破坏 EGL 上下文。</p>
+
+<p>每个视频解码器都是从单独的线程驱动的。乍一看,我们似乎需要每个线程的本地 EGL 上下文;但请注意,具有解码输出的缓冲区实际上是从 mediaserver 发送给我们的 BufferQueue 消费者 (SurfaceTexture)。TextureView 会为我们处理呈现,并在界面线程上执行。</p>
+
+<p>使用 SurfaceView 实现该操作组件可能较为困难。我们不能只创建一对 SurfaceView 并将输出引导至它们,因为 Surface 在屏幕方向改变期间会被销毁。此外,这样做会增加两个层,而由于可用叠加层的数量限制,我们不得不尽量将层数量减到最少。与上述方法不同,我们希望创建一对 SurfaceTexture,以从视频解码器接收输出,然后在应用中执行呈现,使用 GLES 将两个纹理间隙呈现到 SurfaceView 的 Surface。</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/graphics/arch-vulkan.html b/zh-cn/devices/graphics/arch-vulkan.html
new file mode 100644
index 0000000..1295603
--- /dev/null
+++ b/zh-cn/devices/graphics/arch-vulkan.html
@@ -0,0 +1,70 @@
+<html devsite><head>
+    <title>Vulkan</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 The Android Open Source Project
+
+      Licensed under the Apache License, Version 2.0 (the "License");
+      you may not use this file except in compliance with the License.
+      You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      See the License for the specific language governing permissions and
+      limitations under the License.
+  -->
+
+<p>Android 7.0 添加了对 <a href="https://www.khronos.org/vulkan/">Vulkan</a> 的支持。Vulkan 是用于高性能 3D 图形的低开销、跨平台 API。与 OpenGL ES 一样,Vulkan 提供多种用于在应用中创建高质量的实时图形的工具。Vulkan 的优势包括降低 CPU 开销以及支持 <a href="https://www.khronos.org/spir">SPIR-V 二进制中间</a>语言。
+</p>
+
+<p>系统芯片 (SoC) 供应商(如 GPU 独立硬件供应商 (IHV))可以编写适用于 Android 的 Vulkan 驱动程序;原始设备制造商 (OEM) 只需为特定设备集成这些驱动程序即可。要详细了解 Vulkan 驱动程序如何与系统进行交互、应如何安装特定于 GPU 的工具以及特定于 Android 的要求,请参阅<a href="/devices/graphics/implement-vulkan.html">实现 Vulkan</a>。</p>
+
+<p>应用开发者可以利用 Vulkan 来创建在 GPU 上执行命令的应用,大幅降低开销。此外,Vulkan 还可以更直接地映射到当前图形硬件中的功能,最大限度地降低驱动程序的出错概率,并减少开发者的测试时间(例如,排查 Vulkan 错误所需的时间更短)。</p>
+
+<p>有关 Vulkan 的常规信息,请参阅 <a href="http://khr.io/vulkanlaunchoverview">Vulkan 概览</a>或查看下文中的<a href="#resources">资源</a>列表。</p>
+
+<h2 id="vulkan_components">Vulkan 组件</h2>
+<p>Vulkan 支持包含以下组件:</p>
+<p><img src="/devices/graphics/images/ape_graphics_vulkan.png"/></p>
+<p class="img-caption">图 1:Vulkan 组件</p>
+
+<ul>
+<li><strong>Vulkan 验证层</strong>(在 Android NDK 中提供)。<em></em>这是开发者在开发 Vulkan 应用期间使用的一组库。图形供应商提供的 Vulkan 运行时库和 Vulkan 驱动程序不包含使 Vulkan 运行时保持高效的运行时错误检查功能,而是使用验证库(仅在开发过程中)来查找应用在使用 Vulkan API 时出现的错误。Vulkan 验证库在开发过程中关联到应用并执行此错误检查。在找出所有 API 使用问题之后,该应用将不再需要包含这些库。</li>
+<li><strong>Vulkan 运行时</strong>(由 Android 提供)。<em></em>这是一个原生库 (<code>(libvulkan.so</code>),提供称为 <a href="https://www.khronos.org/vulkan">Vulkan</a> 的新公共原生 API。大多数功能由 GPU 供应商提供的驱动程序实现;运行时会封装驱动程序、提供 API 拦截功能(针对调试和其他开发者工具)以及管理驱动程序与平台依赖项(如 BufferQueue)之间的交互。</li>
+<li><strong>Vulkan 驱动程序</strong>(由 SoC 提供)。<em></em>将 Vulkan API 映射到特定于硬件的 GPU 命令以及与内核图形驱动程序的交互。</li>
+</ul>
+
+<h2 id="modified_components">已修改的组件</h2>
+<p>为支持 Vulkan,Android 7.0 对以下现有图形组件进行了修改:</p>
+
+<ul>
+<li><strong>BufferQueue</strong>:Vulkan 运行时通过现有 <code>ANativeWindow</code> 接口与现有的 BufferQueue 组件进行交互。对 <code>ANativeWindow</code> 和 BufferQueue 进行了细微的修改(新枚举值和新方法),而架构没有任何变更。</li>
+<li><strong>Gralloc HAL</strong>:添加了一个新的可选接口,用于了解是否可将某种指定格式用于特定生产方/消费方组合,而无需实际分配缓冲区。</li>
+</ul>
+
+<p>有关这些组件的详情,请参阅 <a href="/devices/graphics/arch-bq-gralloc.html">BufferQueue 和 gralloc</a>(有关 <code>ANativeWindow</code> 的详情,请参阅 <a href="/devices/graphics/arch-egl-opengl.html">EGLSurface 和 OpenGL ES</a>)。
+
+</p><h2 id="apis">Vulkan API</h2>
+<p>Android 平台包括来自 Khronos Group 的 <a href="https://www.khronos.org/vulkan/">Vulkan API 规范</a>的 <a href="https://developer.android.com/ndk/guides/graphics/index.html">Android 特定实现</a>。Android 应用必须使用 <a href="/devices/graphics/implement-vulkan.html#wsi">Window 系统集成 (WSI) 扩展程序</a>来输出其呈现内容。</p>
+
+<h2 id="resources">资源</h2>
+<p>通过以下资源详细了解 Vulkan:</p>
+<ul>
+
+<li>
+位于 <code>platform/frameworks/native/vulkan</code> 的 <a href="https://android.googlesource.com/platform/frameworks/native/+/master/vulkan/#">Vulkan 加载程序</a> (libvulkan.so):包含 Android 的 Vulkan 加载程序,以及一些对平台开发者十分有用的 Vulkan 相关工具。</li>
+
+<li><a href="https://android.googlesource.com/platform/frameworks/native/+/master/vulkan/doc/implementors_guide/implementors_guide.html">Vulkan 实现人员指南</a>:旨在帮助 GPU IHV 编写适用于 Android 的 Vulkan 驱动程序,以及指导原始设备制造商 (OEM) 为特定设备集成这些驱动程序。该指南介绍了 Vulkan 驱动程序如何与系统进行交互、应如何安装特定于 GPU 的工具,以及特定于 Android 的要求。</li>
+
+<li><a href="https://developer.android.com/ndk/guides/graphics/index.html">Vulkan Graphics API 指南</a>:介绍了如何开始在 Android 应用中使用 Vulkan、Android 平台上的 Vulkan 设计指南详情、如何使用 Vulkan 的着色程序编译器,以及如何使用验证层来帮助确保使用 Vulkan 的应用的稳定性。</li>
+
+<li><a href="https://www.khronos.org/#slider_vulkan">Vulkan 新闻</a>:包含事件、补丁程序、教程以及更多与 Vulkan 相关的新闻报道。</li>
+</ul>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/graphics/build-tests.html b/zh-cn/devices/graphics/build-tests.html
new file mode 100644
index 0000000..cd6e0da
--- /dev/null
+++ b/zh-cn/devices/graphics/build-tests.html
@@ -0,0 +1,308 @@
+<html devsite><head>
+    <title>编译测试程序</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 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>相关人员在设计测试框架时考虑到了可移植性。仅有的强制性要求是针对 I/O、线程和套接字的全面 C++ 支持和标准系统库。</p>
+
+<h2 id="cmake_build_system">CMake 编译系统</h2>
+
+<p>deqp 来源具有适用于 CMake 的编译脚本,这是编译测试程序的首选工具。</p>
+
+<p>CMake 是一个开放源代码编译系统,支持多种平台和工具链。CMake 从与目标无关的配置文件生成原生 Makefile 或 IDE 项目文件。要详细了解 CMake,请参阅 <a href="http://www.cmake.org/cmake/help/documentation.html">CMake</a> 文档。</p>
+
+<p>CMake 支持且建议在源代码树之外进行编译,也就是说,您应该始终在源代码树之外的独立编译目录中创建 Makefile 或项目文件。CMake 没有任何类型的“distclean”目标,因此,您必须手动移除 CMake 生成的任何文件。</p>
+
+<p>配置选项通过 <code>-D<var>OPTION_NAME</var>=<var>VALUE</var></code> 语法提供给 CMake。deqp 的一些常用选项如下所示。</p>
+
+<table>
+ <tbody><tr>
+   <th>配置选项</th>
+   <th>说明</th>
+ </tr>
+
+ <tr>
+    <td><code>DEQP_TARGET</code></td>
+<td><p>目标名称,例如“android”</p>
+<p>deqp CMake 脚本将包含文件 <code>targets/<var>DEQP_TARGET</var>/<var>DEQP_TARGET</var>.cmake</code>,这里应该可以找到特定于目标的编译选项。</p>
+</td>
+ </tr>
+ <tr>
+    <td><code>CMAKE_TOOLCHAIN_FILE</code></td>
+<td><p>CMake 工具链文件的路径。用于交叉编译。</p></td>
+ </tr>
+ <tr>
+    <td><code>CMAKE_BUILD_TYPE</code></td>
+<td><p>Makefile 目标的编译类型。有效值为“Debug”和“Release”</p>
+<p>注意,解释和默认类型取决于目标编译系统。如需了解详情,请参阅 CMake 文档。</p>
+</td>
+ </tr>
+</tbody></table>
+
+<h2 id="creating_target_build_file">创建目标编译文件</h2>
+
+<p>针对新目标的 deqp 编译系统使用目标编译文件进行配置。目标编译文件可定义该平台支持哪些功能以及需要哪些库或其他包含路径。目标文件名遵循 <code>targets/<var>NAME</var>/<var>NAME</var>.cmake</code> 格式,且目标的选择会用到 <code>DEQP_TARGET</code> 编译参数。</p>
+
+<p>目标文件中的文件路径与基本的 <code>deqp</code> 目录(而非 <code>targets/<var>NAME</var></code> 目录)相关。目标编译文件可以设置以下标准变量。</p>
+
+<table>
+ <tbody><tr>
+   <th>变量</th>
+   <th>说明</th>
+ </tr>
+ <tr>
+    <td><code>
+DEQP_TARGET_NAME</code></td>
+<td><p>目标名称(将包含在测试日志中)</p>
+</td>
+ </tr>
+ <tr>
+    <td><code>
+DEQP_SUPPORT_GLES2</code></td>
+<td><p>是否支持 GLES2(默认值:OFF)</p>
+</td>
+ </tr>
+ <tr>
+    <td><code>
+DEQP_GLES2_LIBRARIES</code></td>
+<td><p>GLES2 库(如果不受支持或使用的是动态加载,则留空)</p>
+</td>
+ </tr>
+ <tr>
+    <td><code>
+DEQP_SUPPORT_GLES3</code></td>
+<td><p>是否支持 GLES3.x(默认值:OFF)</p>
+</td>
+ </tr>
+ <tr>
+    <td><code>
+DEQP_GLES3_LIBRARIES</code></td>
+<td><p>GLES3.x 库(如果不受支持或使用的是动态加载,则留空)</p>
+</td>
+ </tr>
+ <tr>
+    <td><code>
+DEQP_SUPPORT_VG</code></td>
+<td><p>是否支持 OpenVG(默认值:OFF)</p>
+</td>
+ </tr>
+ <tr>
+    <td><code>
+DEQP_OPENVG_LIBRARIES</code></td>
+<td><p>OpenVG 库(如果不受支持或使用的是动态加载,则留空)</p>
+</td>
+ </tr>
+ <tr>
+    <td><code>
+DEQP_SUPPORT_EGL</code></td>
+<td><p>是否支持 EGL(默认值:OFF)</p>
+</td>
+ </tr>
+ <tr>
+    <td><code>
+DEQP_EGL_LIBRARIES</code></td>
+<td><p>EGL 库(如果不受支持或使用的是动态加载,则留空)</p>
+</td>
+ </tr>
+ <tr>
+    <td><code>
+DEQP_PLATFORM_LIBRARIES</code></td>
+<td><p>进行链接所需的特定于平台的附加库</p>
+</td>
+ </tr>
+ <tr>
+    <td><code>
+DEQP_PLATFORM_COPY_LIBRARIES</code></td>
+<td><p>复制到每个测试二进制文件编译目录的库列表。可用于复制运行测试所需但不在默认搜索路径中的库。</p>
+</td>
+ </tr>
+ <tr>
+    <td><code>
+TCUTIL_PLATFORM_SRCS</code></td>
+<td><p>平台端口来源列表。默认来源取决于功能和操作系统。</p>
+
+<p><strong>注意</strong>:路径相对于 <code>framework/platform</code></p>
+</td>
+ </tr>
+</tbody></table>
+
+<p>目标编译文件可以使用 <code>include_directories()</code> 和 <code>link_directories()</code> CMake 函数添加其他包含或链接路径。</p>
+
+<h2 id="win32_build">Win32 编译</h2>
+
+<p>为 Windows 编译 deqp 模块最简单的方法是使用 CMake 编译系统。您需要使用 CMake 2.6.12 或更高版本以及 Microsoft Visual C/C++ 编译器。deqp 已通过 Visual Studio 2013 测试。</p>
+
+<p>可以使用以下命令生成 Visual Studio 项目文件:</p>
+
+<pre class="devsite-terminal devsite-click-to-copy">
+cmake path\to\src\deqp -G "Visual Studio 12"
+</pre>
+
+<p>选择“Visual Studio VERSION Win64”作为编译生成器可制作 64 位版本:<var></var></p>
+
+<pre class="devsite-terminal devsite-click-to-copy">
+cmake path\to\src\deqp -G "Visual Studio 12 Win64"
+</pre>
+
+<p>您还可以通过 <code>-G "NMake Makefiles"</code> 选项和编译类型(<code>-DCMAKE_BUILD_TYPE="Debug"</code> 或 <code>"Release"</code>)生成 NMake Makefile。</p>
+
+<h3 id="rendering_context_creation">渲染上下文的创建</h3>
+
+<p>渲染上下文可通过 WGL 或 Windows 上的 EGL 进行创建。</p>
+
+<h4 id="wgl_support">WGL 支持</h4>
+
+<p>所有 Win32 二进制文件都支持使用 WGL 创建 GL 上下文,因为它只需要标准库。使用 <code>--deqp-gl-context-type=wgl</code> 命令行参数可选择 WGL 上下文。在 WGL 模式下,deqp 使用 <code>WGL_EXT_create_context_es_profile</code> 扩展程序创建 OpenGL ES 上下文。经过测试,该程序可与 NVIDIA 和 Intel 的最新驱动程序配合使用。AMD 驱动程序不支持所需的扩展程序。</p>
+
+<h4 id="egl_support">EGL 支持</h4>
+
+<p>如果 DEQP_SUPPORT_EGL 的状态为“ON”(这是大多数目标中的默认状态),则通过动态加载为 Windows 上的 EGL 构建 deqp。接下来,如果主机有可用的 EGL 库,则可以通过命令行参数 <code>--deqp-gl-context-type=egl</code> 对其运行测试。</p>
+
+<h2 id="android_build">Android 编译</h2>
+
+<p>Android 编译使用 CMake 编译脚本来编译原生测试代码。Java 部分(即测试执行服务器和测试应用存根)使用标准的 Android 编译工具进行编译。</p>
+
+<p>要使用提供的编译脚本编译 Android 的 deqp 测试程序,您需要:</p>
+
+<ul>
+  <li>最新版本的 <a href="http://developer.android.com/tools/sdk/ndk/index.html">Android NDK</a>;<code>android/scripts/common.py</code> 文件列有所需的版本
+  </li><li>Android 独立 SDK(已安装 API 13、SDK 工具、SDK 平台工具和 SDK 编译工具<a href="http://developer.android.com/sdk/index.html#Other">软件包</a>)
+  </li><li><a href="http://ant.apache.org/bindownload.cgi">Apache Ant 1.9.4</a>(Java 代码编译所需)
+  </li><li><a href="http://www.cmake.org/download/">CMake 2.8.12</a> 或更高版本
+  </li><li><a href="https://www.python.org/downloads/">Python 2.6</a> 或更高版本(2.x 系列);不支持 Python 3.x
+  </li><li>对于 Windows:<code>PATH</code> 中的 NMake 或 JOM
+  <ul>
+    <li><a href="http://qt-project.org/wiki/jom">JOM</a> 的编译速度更快
+  </li></ul>
+  </li><li>可选:Linux 上还支持 Ninja make
+</li></ul>
+
+<p>Ant 和 SDK 二进制文件的位置取决于具有特定覆盖默认值的 PATH 环境变量。具体逻辑由 <code>android/scripts/common.py</code> 控制。</p>
+
+<p>NDK 目录必须为 <code>~/android-ndk-<var>VERSION</var></code> 或 <code>C:/android/android-ndk-<var>VERSION</var></code>,或者通过 <code>ANDROID_NDK_PATH</code> 环境变量进行定义。</p>
+
+<p>Deqp 设备组件、测试执行服务和测试程序均通过执行 <code>android/scripts/build.py</code> 脚本进行编译。最终 .apk 在 <code>android/package/bin</code> 中创建,并可通过 <code>install.py</code> 脚本进行安装。如果使用<a href="port-tests.html#test_execution_service">命令行执行程序</a>,则可以在设备上通过 ADB 使用 <code>launch.py</code> 脚本启动 ExecService。这些脚本可以从任何目录执行。</p>
+
+<h2 id="linux_build">Linux 编译</h2>
+
+<p>通过使用 CMake 生成 Makefile,可以编译适用于 Linux 的测试二进制文件和命令行实用工具。其中有多个预定义的编译目标对 Linux 编译很有帮助。</p>
+
+<table>
+ <tbody><tr>
+   <th>编译目标</th>
+   <th>说明</th>
+ </tr>
+
+ <tr>
+    <td><code>default</code></td>
+<td><p>默认目标;使用 CMake 平台自省来确定是否支持各种 API。</p>
+</td>
+ </tr>
+
+<tr>
+    <td><code>
+x11_glx</code></td>
+<td><p>使用 GLX 创建 OpenGL (ES) 上下文。</p>
+</td>
+ </tr>
+
+<tr>
+    <td><code>
+x11_egl</code></td>
+<td><p>使用 EGL 创建 OpenGL (ES) 上下文。</p>
+</td>
+ </tr>
+
+ <tr>
+    <td><code>
+x11_egl_glx</code></td>
+<td><p>同时支持带有 X11 的 GLX 和 EGL。</p>
+</td>
+ </tr>
+</tbody></table>
+
+<p>始终使用 <code>-DCMAKE_BUILD_TYPE=&lt;Debug|Release&gt;</code> 来定义编译类型。<code>Release</code> 是一个很实用的默认值。如果没有该值,则默认创建未优化的编译版本。</p>
+
+<p><code>-DCMAKE_C_FLAGS</code> 和 <code>-DCMAKE_CXX_FLAGS</code> 命令行参数可用于将额外的参数传递给编译器。例如,可以通过分别设置 <code>-DCMAKE_C(XX)_FLAGS="-m32"</code> 或 <code>"-m64"</code> 来实现 32 位 或 64 位编译。如果未指定,则使用工具链原生架构(通常会为 64 位工具链生成 64 位版本)。</p>
+
+<p><code>-DCMAKE_LIBRARY_PATH</code> 和 <code>-DCMAKE_INCLUDE_PATH</code> 参数可用于 CMake,为 CMake 提供额外的库或包含搜索路径。</p>
+
+<p>用于针对自定义位置中的驱动程序头文件和库执行 32 位调试编译的完整命令行示例如下:</p>
+
+<pre class="devsite-click-to-copy">
+<code class="devsite-terminal">cmake &lt;path to src&gt;/deqp -DDEQP_TARGET=x11_egl -DCMAKE_C_FLAGS="-m32"
+-DCMAKE_CXX_FLAGS="-m32" -DCMAKE_BUILD_TYPE=Debug
+-DCMAKE_LIBRARY_PATH="<var>PATH_TO_DRIVER</var>/lib"
+-DCMAKE_INCLUDE_PATH="<var>PATH_TO_DRIVER</var>/inc"</code>
+<code class="devsite-terminal">make -j4</code>
+</pre>
+
+<h2 id="cross-compiling">交叉编译</h2>
+
+<p>使用 CMake 工具链文件可实现交叉编译。工具链文件可指定要使用的编译器,以及用于库和标头的自定义搜索路径。一些适用于常见场景的工具链文件包含在 <code>framework/delibs/cmake</code> 目录下的发布包中。</p>
+
+<p>除了标准的 CMake 变量之外,工具链文件还可以设置以下特定于 deqp 的变量。CMake 通常可以正确检测 <code>DE_OS</code>、<code>DE_COMPILER</code> 和 <code>DE_PTR_SIZE</code>,但 <code>DE_CPU</code> 必须由工具链文件设置。</p>
+
+<table>
+ <tbody><tr>
+   <th>变量</th>
+   <th>说明</th>
+ </tr>
+ <tr>
+   <td><code>
+DE_OS</code></td>
+   <td><p>操作系统。支持的值包括:<code>DE_OS_WIN32, DE_OS_UNIX, DE_OS_WINCE, DE_OS_OSX, DE_OS_ANDROID, DE_OS_SYMBIAN, DE_OS_IOS</code></p>
+   </td>
+ </tr>
+ <tr>
+    <td><code>
+DE_COMPILER</code></td>
+<td><p>编译器类型。支持的值包括:<code>DE_COMPILER_GCC, DE_COMPILER_MSC, DE_COMPILER_CLANG</code></p>
+</td>
+ </tr>
+ <tr>
+    <td><code>
+DE_CPU</code></td>
+<td><p>CPU 类型。支持的值包括:<code>DE_CPU_ARM, DE_CPU_X86</code>。</p>
+</td>
+ </tr>
+ <tr>
+    <td><code>
+DE_PTR_SIZE</code></td>
+<td><p>平台上的 sizeof(void*)。支持的值包括:4 和 8</p>
+</td>
+ </tr>
+</tbody></table>
+
+<p>使用 <code>CMAKE_TOOLCHAIN_FILE</code> 编译参数可选择工具链文件。例如,以下代码将使用适用于 ARM/Linux 的 CodeSourcery 交叉编译器为编译创建 Makefile:</p>
+
+<pre class="devsite-terminal devsite-click-to-copy">
+cmake <var>PATH_TO_SRC</var>/deqp –DDEQP_BUILD_TYPE="Release"
+–DCMAKE_TOOLCHAIN_FILE=<var>PATH_TO_SRC</var>/delibs/cmake/toolchain-arm-cs.cmake
+–DARM_CC_BASE=<var>PATH_TO_CC_DIRECTORY</var>
+</pre>
+
+<h2 id="run-time_linking_of_gles_and_egl_libraries">GLES 和 EGL 库的运行时链接</h2>
+
+<p>deqp 在链接时期间不需要正在测试的 API 接入点。测试代码始终通过函数指针访问 API。这样接入点便可以在运行时动态加载,或者平台端口也可以在链接时提供接入点。</p>
+
+<p>如果在编译设置中启用了对 API 的支持且未提供链接库,则 deqp 将在运行时加载所需的接入点。如果需要静态链接,请在 <code>DEQP_&lt;API&gt;_LIBRARIES</code> 编译配置变量中提供所需的链接库。</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/graphics/cts-integration.html b/zh-cn/devices/graphics/cts-integration.html
new file mode 100644
index 0000000..64dd41d
--- /dev/null
+++ b/zh-cn/devices/graphics/cts-integration.html
@@ -0,0 +1,50 @@
+<html devsite><head>
+    <title>与 Android CTS 集成</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 The Android Open Source Project
+
+      Licensed under the Apache License, Version 2.0 (the "License");
+      you may not use this file except in compliance with the License.
+      You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      See the License for the specific language governing permissions and
+      limitations under the License.
+  -->
+
+<p>Android CTS 发布包(可从 <a href="/compatibility/cts/downloads.html">Android 兼容性下载</a>中获得)包括 deqp 测试,其中一个测试子集(称为 <code>mustpass</code> 列表)要求必须通过。对于不支持目标 API 或扩展程序的设备,将跳过测试并报告为已通过。</p>
+
+<p><code>mustpass</code> 列表包括 OpenGL ES 3.0、OpenGL ES 3.1、OpenGL ES 3.2 和 Android Extension Pack 测试。<code>mustpass</code> 文件可以在 deqp 源代码树中的 <code>android/cts</code> 目录下找到。您可以使用以下命令通过 <code>cts-tradefed</code> 实用程序运行 deqp 测试:</p>
+
+<pre class="devsite-terminal devsite-click-to-copy">
+cts-tradefed run cts --plan CTS-DEQP
+</pre>
+
+<h2 id="duplicating_runs_without_cts">在没有 CTS 的情况下复制运行</h2>
+
+<p>要复制 CTS 运行,请安装 CTS 包的 deqp APK 并使用以下命令:</p>
+
+<pre class="devsite-terminal devsite-click-to-copy">
+adb -d shell am start -n com.drawelements.deqp/android.app.NativeActivity -e \
+cmdLine "deqp --deqp-case=dEQP-GLES3.some_group.* --deqp-gl-config-name=rgba8888d24s8 --deqp-log-filename=/sdcard/dEQP-Log.qpa
+</pre>
+
+<p>关键部分是 <code>--deqp-gl-config-name=rgba8888d24s8</code> 参数,它要求在具有 24 位深度缓冲区和 8 位模板缓冲区的 RGBA 8888 屏幕 Surface 上运行测试。请记得使用 <code>--deqp-case</code> 参数设置所需的测试。</p>
+
+<h2 id="mapping_of_the_cts_results">CTS 结果映射</h2>
+
+<p>在 Android CTS 中,测试用例最终呈现以下三种状态之一:通过、失败或未执行(deqp 会提供更多的结果代码)。CTS 会自动将 deqp 结果代码映射到 CTS 结果:</p>
+<ul>
+<li>CTS 通过可包括 <code>Pass</code>、<code>NotSupported</code>、<code>QualityWarning</code> 和 <code>CompatibilityWarning</code>。</li>
+<li>CTS 失败可包括 <code>Fail</code>、<code>ResourceError</code>、<code>Crash</code>、<code>Timeout</code> 和 <code>InternalError</code>。</li>
+</ul>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/graphics/implement-hwc.html b/zh-cn/devices/graphics/implement-hwc.html
new file mode 100644
index 0000000..cb293d5
--- /dev/null
+++ b/zh-cn/devices/graphics/implement-hwc.html
@@ -0,0 +1,156 @@
+<html devsite><head>
+    <title>实现 Hardware Composer HAL</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 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>Hardware Composer HAL (HWC) 由 SurfaceFlinger 用来将 Surface 合成到屏幕。HWC 可以抽象出叠加层和 2D 位块传送器等对象,有助于分载通常使用 OpenGL 完成的一些工作。</p>
+
+<p>Android 7.0 包含新版本的 HWC (HWC2),由 SurfaceFlinger 用来与专门的窗口合成硬件进行通信。SurfaceFlinger 包含使用 3D 图形处理器 (GPU) 执行窗口合成任务的备用路径,但由于以下几个原因,此路径并不理想:</p>
+
+<ul>
+  <li>通常,GPU 未针对此用例进行过优化,因此能耗可能要大于执行合成所需的能耗。</li>
+  <li>每次 SurfaceFlinger 使用 GPU 进行合成时,应用都无法使用处理器进行自我渲染,因此应尽可能使用专门的硬件而不是 GPU 进行合成。</li>
+</ul>
+
+<h2 id="guidance">常规准则</h2>
+
+<p>由于 Hardware Composer 抽象层后的物理显示设备硬件可因设备而异,因此很难就具体功能提供建议。一般来说,请遵循以下准则:</p>
+
+<ul>
+  <li>HWC 应至少支持 4 个叠加层(状态栏、系统栏、应用和壁纸/背景)。</li>
+  <li>层可以大于屏幕,因此 HWC 应能处理大于显示屏的层(例如壁纸)。</li>
+  <li>应同时支持预乘每像素 Alpha 混合和每平面 Alpha 混合。</li>
+  <li>HWC 应能消耗 GPU、相机和视频解码器生成的相同缓冲区,因此支持以下某些属性很有帮助:
+  <ul>
+    <li>RGBA 打包顺序</li>
+    <li>YUV 格式</li>
+    <li>平铺、重排和步幅属性</li>
+  </ul>
+  </li><li>为了支持受保护的内容,必须提供受保护视频播放的硬件路径。</li>
+  </ul>
+
+<p>常规建议是首先实现非运行的 HWC;在结构完成后,实现一个简单的算法,以将合成委托给 HWC(例如,仅将前 3 个或前 4 个 Surface 委托给 HWC 的叠加硬件)。</p>
+
+<p>专注于优化,例如智能地选择要发送到叠加硬件的 Surface,以最大限度提高从 GPU 移除的负载。另一种优化是检测屏幕是否正在更新;如果不是,则将合成委托给 OpenGL 而不是 HWC,以节省电量。当屏幕再次更新时,继续将合成分载到 HWC。</p>
+
+<p>为常见用例做准备,如:</p>
+
+<ul>
+  <li>纵向和横向模式下的全屏游戏</li>
+  <li>带有字幕和播放控件的全屏视频</li>
+  <li>主屏幕(合成状态栏、系统栏、应用窗口和动态壁纸)</li>
+  <li>受保护的视频播放</li>
+  <li>多显示设备支持</li>
+</ul>
+
+<p>这些用例应针对常规可预测的用途,而不是很少遇到的边缘用例(否则,优化将收效甚微)。实现必须平衡动画流畅性和交互延迟时间这两个相互矛盾的目标。</p>
+
+<h2 id="interface_activities">HWC2 接口 Activity</h2>
+
+<p>HWC2 提供了几个基元(层、显示设备)来表示合成工作及其与显示设备硬件的交互。</p>
+<p>层是合成的最重要单元;每个层都有一组属性,用于定义它与其他层的交互方式。<em></em>包括的属性类别如下:</p>
+
+<ul>
+<li><strong>定位</strong>。定义层在其显示设备上的显示位置。包括层边缘的位置及其相对于其他层的 Z 顺序(指示该层在其他层之前还是之后)等信息。<em></em></li>
+<li><strong>内容</strong>。定义应如何在定位属性定义的边界内呈现层上显示的内容。包括诸如剪裁(用来扩展内容的一部分以填充层的边界)和转换(用来显示旋转或翻转的内容)等信息。</li>
+<li><strong>合成</strong>。定义层应如何与其他层合成。包括混合模式和用于 <a href="https://en.wikipedia.org/wiki/Alpha_compositing#Alpha_blending">Alpha 合成</a>的全层 Alpha 值等信息。</li>
+<li><strong>优化</strong>。提供对于正确合成层并非绝对必要但可由 HWC 设备用来优化合成执行方式的信息。包括层的可见区域以及层的哪个部分自上一帧以来已经更新等信息。</li>
+</ul>
+
+<p>显示设备是合成的另一个重要单元。<em></em>每个层只能在一个显示设备上呈现。系统可以具有多个显示设备,并且在正常系统操作期间可以添加或删除显示设备。该添加/删除可以应 HWC 设备的请求(通常是响应插入设备或从设备中移除的外部显示设备,这称为热插拔<em></em>),或者应客户端的请求进行,这允许创建虚拟显示设备,其内容会渲染到离屏缓冲区(而不是物理显示设备)。<em></em></p>
+<p>HWC2 提供相应函数来确定给定显示设备的属性,在不同配置(例如 4k 或 1080p 分辨率)和颜色模式(例如原生颜色或真正的 SRGB)之间切换,以及打开、关闭显示设备或将其切换到低功率模式(如果支持)。</p>
+<p>除了层和显示设备之外,HWC2 还提供对硬件垂直同步 (VSYNC) 信号的控制,以及对于客户端的回调,用于通知它何时发生 vsync 事件。</p>
+
+<h3 id="func_pointers">函数指针</h3>
+<p>在本部分和 HWC2 标头注释中,HWC 接口函数由 lowerCamelCase 名称引用,这些名称并未作为命名的字段实际存在于接口中。相反,几乎每个函数都是通过使用 <code>hwc2_device_t</code> 提供的 <code>getFunction</code> 请求函数指针来进行加载。例如,函数 <code>createLayer</code> 是一个 <code>HWC2_PFN_CREATE_LAYER</code> 类型的函数指针,当枚举值 <code>HWC2_FUNCTION_CREATE_LAYER</code> 传递到 <code>getFunction</code> 中时便会返回该指针。</p>
+<p>有关函数的详细文档(包括每个 HWC2 实现所需的函数),请参见 <a href="https://android.googlesource.com/platform/hardware/libhardware/+/master/include/hardware/hwcomposer2.h">HWC2 标头</a>。</p>
+
+<h3 id="layer_display_handles">层和显示设备句柄</h3>
+<p>层和显示设备由不透明的句柄操纵。</p>
+<p>当 SurfaceFlinger 想要创建新层时,它会调用 <code>createLayer</code> 函数,然后返回一个 <code>hwc2_layer_t</code> 类型的不透明句柄。在此之后,SurfaceFlinger 每次想要修改该层的属性时,都会将该 <code>hwc2_layer_t</code> 值以及进行修改所需的任何其他信息传递给相应的修改函数。<code>hwc2_layer_t</code> 类型句柄的大小足以容纳一个指针或一个索引,并且 SurfaceFlinger 会将其视为不透明,从而为 HWC 实现人员提供最大的灵活性。</p>
+<p>以上大部分内容也适用于显示设备句柄,尽管根据句柄是热插拔(其中句柄通过热插拔回调传递)还是应客户端请求作为虚拟显示设备(句柄从 <code>createVirtualDisplay</code> 返回),会以不同的方式创建句柄。</p>
+
+<h2 id="display_comp_ops">显示设备合成操作</h2>
+<p>如果 SurfaceFlinger 具有可合成的新内容,则会唤醒,且每个硬件 vsync 唤醒一次。该新内容可以是来自应用的新图像缓冲区,也可以只是一个或多个层的属性更改。当 SurfaceFlinger 唤醒时,会执行以下步骤:</p>
+
+<ol>
+<li>应用事务(如果存在)。包括由窗口管理器指定的层的属性更改,但不包括层的内容更改(例如来自应用的图形缓冲区)。</li>
+<li>如果存在新的图形缓冲区,则将其锁定(从它们各自的应用获取其句柄)。</li>
+<li>如果步骤 1 或 2 导致显示内容更改,则执行新的合成(如下所述)。</li>
+</ol>
+
+<p>步骤 1 和 2 有一些细微差别(如延迟的事务和演示时间戳),这些内容不在本节讨论范围之内。但是,步骤 3 涉及 HWC 接口,下面将详细说明。</p>
+<p>在合成过程开始时,SurfaceFlinger 将创建和销毁层或修改层状态(如适用)。SurfaceFlinger 还将使用诸如 <code>setLayerBuffer</code> 或 <code>setLayerColor</code> 等调用,用层的当前内容来更新层。更新所有层之后,SurfaceFlinger 将调用 <code>validateDisplay</code>,以告诉设备检查各个层的状态,并确定如何进行合成。尽管在某些情况下可能会强制由客户端进行合成,但在默认情况下,SurfaceFlinger 通常会尝试配置每个层,以使其由设备进行合成。</p>
+<p>SurfaceFlinger 在调用 <code>validateDisplay</code> 之后,会继续调用 <code>getChangedCompositionTypes</code>,以查看设备是否需要在执行实际合成之前更改任何层的合成类型。SurfaceFlinger 可以选择:</p>
+
+<ul>
+<li>更改部分层合成类型并重新验证显示设备。</li>
+</ul>
+
+<em><strong>或</strong></em>
+
+<ul>
+<li>调用 <code>acceptDisplayChanges</code>,其效果等同于按照设备请求更改合成类型,并重新验证而不再次实际调用 <code>validateDisplay</code>。</li>
+</ul>
+
+<p>在实践中,SurfaceFlinger 始终采用后一种选择(调用 <code>acceptDisplayChanges</code>),尽管这一点将来可能会改变。</p>
+<p>目前,该行为会根据是否将任何层标记为进行客户端合成而有所不同。如果已将任何(或所有)层标记为进行客户端合成,SurfaceFlinger 现在会将所有这些层合成到客户端目标缓冲区中。该缓冲区将通过 <code>setClientTarget</code> 调用提供给设备,以便可以直接在屏幕上显示,或者进一步与未标记为进行客户端合成的层合成。如果没有将任何层标记为进行客户端合成,则会跳过客户端合成步骤。</p>
+<p>最后,在验证所有状态并且执行客户端合成(如果需要)后,SurfaceFlinger 将会调用 <code>presentDisplay</code>。这会提示 HWC 设备完成合成过程并显示最终结果。</p>
+
+<h2 id="multiple_displays">Android 7.0 中的多个显示设备</h2>
+<p>尽管 HWC2 接口非常灵活,能够支持系统中存在多个显示设备,但 Android 框架的其他部分尚不具备这样的灵活性。在设计要在 Android 7.0 上使用的 HWC2 实现时,还存在一些 HWC 定义本身并不存在的额外限制:
+</p>
+
+<ul>
+<li>假定只有一个主显示设备;也就是说,存在一个物理显示设备,该显示设备将在设备初始化期间(特别是在注册热插拔回调之后)立即热插拔。<em></em></li>
+<li>在设备的正常操作期间,除了主显示设备之外,仅可热插拔一个外部显示设备。<em></em></li>
+</ul>
+
+<p>尽管上述 SurfaceFlinger 操作按显示设备执行(最终目标是能够相互独立地合成多个显示),但当前会对所有活动的显示设备依序执行这些操作,即使只更新了一个显示设备的内容也不例外。</p>
+<p>例如,如果只更新了外部显示设备,则顺序为:</p>
+
+<pre class="devsite-click-to-copy">
+// Update state for internal display
+// Update state for external display
+validateDisplay(&lt;internal display&gt;)
+validateDisplay(&lt;external display&gt;)
+presentDisplay(&lt;internal display&gt;)
+presentDisplay(&lt;external display&gt;)
+</pre>
+
+<h2 id="sync_fences">同步栅栏</h2>
+<p>同步栅栏是 Android 图形系统的关键部分。栅栏允许 CPU 工作与并行的 GPU 工作相互独立进行,仅在存在真正的依赖关系时才会阻塞。</p>
+<p>例如,当应用提交在 GPU 上生成的缓冲区时,它还将提交一个栅栏对象;该栅栏仅在 GPU 完成写入缓冲区的操作时才会变为有信号量状态。由于真正需要 GPU 写入完成的唯一系统部分是显示设备硬件(由 HWC HAL 抽象的硬件),因此图形通道能够通过 SurfaceFlinger 将该栅栏与缓冲区一起传递到 HWC 设备。只有在即将显示该缓冲区之前,设备才需要实际检查栅栏是否已经变为有信号量状态。</p>
+<p>同步栅栏紧密集成到 HWC2 中,并且按以下类别进行划分:</p>
+
+<ol>
+<li>获取栅栏会与输入缓冲区一起传递到 <code>setLayerBuffer</code> 和 <code>setClientTarget</code> 调用。这些栅栏表示正在等待写入缓冲区,并且必须在 HWC 客户端或设备尝试从关联缓冲区读取数据以执行合成之前变为有信号量状态。
+</li>
+<li>释放栅栏在调用 <code>presentDisplay</code> 之后使用 <code>getReleaseFences</code> 调用进行检索,并与将在下一次合成期间被替换的缓冲区一起传回至应用。这些栅栏表示正在等待从缓冲区读取数据,并且必须在应用尝试将新内容写入缓冲区之前变为有信号量状态。</li>
+<li>退出栅栏作为对 <code>presentDisplay</code> 的调用的一部分返回,每帧一个,说明该帧的合成何时完成,或者何时不再需要上一帧的合成结果。对于物理显示设备,这是当前帧显示在屏幕上之时,而且还可以解释为在其之后可以再次安全写入客户端目标缓冲区(如果适用)的时间。对于虚拟显示设备,这是可以安全地从输出缓冲区读取数据的时间。</li>
+</ol>
+
+<h3 id="hwc2_changes">HWC2 中的更改</h3>
+<p>HWC 2.0 中同步栅栏的含义相对于以前版本的 HAL 已有很大的改变。</p>
+<p>在 HWC v1.x 中,释放栅栏和退出栅栏是推测性的。在帧 N 中检索到的缓冲区的释放栅栏或显示设备的退出栅栏不会先于在帧 N + 1 中检索到的栅栏变为有信号量状态。换句话说,该栅栏的含义是“不再需要您为帧 N 提供的缓冲区内容”。这是推测性的,因为在理论上,SurfaceFlinger 在帧 N 之后的一段不确定的时间内可能无法再次运行,这将使得这些栅栏在该时间段内不会变为有信号量状态。</p>
+<p>在 HWC 2.0 中,释放栅栏和退出栅栏是非推测性的。在帧 N 中检索到的释放栅栏或退出栅栏,将在相关缓冲区的内容替换帧 N - 1 中缓冲区的内容后立即变为有信号量状态,或者换句话说,该栅栏的含义是“您为帧 N 提供的缓冲区内容现在已经替代以前的内容”。这是非推测性的,因为在硬件呈现此帧的内容之后,该栅栏应该在 <code>presentDisplay</code> 被调用后立即变为有信号量状态。</p>
+<p>有关实现的详细信息,请参见 <a href="https://android.googlesource.com/platform/hardware/libhardware/+/master/include/hardware/hwcomposer2.h">HWC2 标头</a>。</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/graphics/implement-vsync.html b/zh-cn/devices/graphics/implement-vsync.html
new file mode 100644
index 0000000..7f94096
--- /dev/null
+++ b/zh-cn/devices/graphics/implement-vsync.html
@@ -0,0 +1,229 @@
+<html devsite><head>
+    <title>实现 VSYNC</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 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>VSYNC 可将某些事件同步到显示设备的刷新周期。应用总是在 VSYNC 边界上开始绘制,而 SurfaceFlinger 总是在 VSYNC 边界上进行合成。这样可以消除卡顿,并提升图形的视觉表现。</p>
+
+<p>Hardware Composer (HWC) 具有一个函数指针,用于指示要为 VSYNC 实现的函数:</p>
+
+<pre class="prettyprint">
+int (waitForVsync*) (int64_t *timestamp)
+</pre>
+
+<p>在发生 VSYNC 并返回实际 VSYNC 的时间戳之前,这个函数会处于阻塞状态。每次发生 VSYNC 时,都必须发送一条消息。客户端会以指定的间隔收到 VSYNC 时间戳,或者以 1 为间隔连续收到 VSYNC 时间戳。您必须实现最大延迟时间为 1 毫秒(建议 0.5 毫秒或更短)的 VSYNC;返回的时间戳必须非常准确。</p>
+
+<h2 id="explicit_synchronization">显式同步</h2>
+
+<p>显式同步是必需的,它提供了一种以同步方式获取和释放 Gralloc 缓冲区的机制。显式同步允许图形缓冲区的生产方和消耗方在完成对缓冲区的处理时发出信号。这允许 Android 异步地将要读取或写入的缓冲区加入队列,并且确定另一个消耗方或生产方当前不需要它们。有关详细信息,请参阅<a href="/devices/graphics/index.html#synchronization_framework">同步框架</a>一文。</p>
+
+<p>显式同步的优点包括设备之间的行为变化较小、调试支持更好,并且测试指标更完善。例如,同步框架输出可以很容易地识别问题区域和根本原因,而集中的 SurfaceFlinger 演示时间戳可以显示何时在系统的正常流程中发生事件。</p>
+
+<p>该通信是通过使用同步栅栏来促进的。在请求用于消耗或生产的缓冲区时,必须使用同步栅栏。同步框架由三个主要构造块组成:<code>sync_timeline</code>、<code>sync_pt</code> 和 <code>sync_fence</code>。</p>
+
+<h3 id="sync_timeline">sync_timeline</h3>
+
+<p><code>sync_timeline</code> 是一个单调递增的时间轴,应为每个驱动程序实例(如 GL 上下文、显示控制器或 2D 位块传送器)实现该时间轴。这本质上是针对提交到特定硬件内核的作业的计数器。它为相关操作的顺序提供了保证,并允许特定于硬件的实现。</p>
+
+<p>sync_timeline 作为仅限 CPU 的参考实现进行提供(称为 <code>sw_sync</code>(软件同步))。如果可能,请使用它而不是 <code>sync_timeline</code>,以节省资源并避免复杂性。如果您没有使用硬件资源,则 <code>sw_sync</code> 应该就够了。</p>
+
+<p>如果必须实现 <code>sync_timeline</code>,请使用 <code>sw_sync</code> 驱动程序作为起点,并遵循以下准则:</p>
+
+<ul>
+<li>为所有驱动程序、时间轴和栅栏指定实用的名称。这可简化调试。</li>
+<li>在时间轴中实现 <code>timeline_value_str</code> 和 <code>pt_value_str</code> 运算符,使调试输出更易于理解。</li>
+<li>如果您希望用户空间库(如 GL 库)可以访问时间轴的私有数据,请实现填充 driver_data 运算符。这能让您获得不可变 sync_fence 和 <code>sync_pts</code> 的相关信息,从而在其基础上构建命令行。</li>
+</ul>
+
+<p>实现 <code>sync_timeline</code> 时,<strong>请勿</strong>:</p>
+
+<ul>
+<li>使其基于任何实际的时间。例如,当一个挂钟到达某个时间点或其他工作可能结束时的时间点。最好创建一个您可以控制的抽象时间轴。</li>
+<li>允许用户空间明确创建栅栏或使其变为有信号量状态。这会导致一个用户通道创建可停止所有功能的拒绝服务攻击。这是因为用户空间不能代表内核做出承诺。</li>
+<li>明确访问 <code>sync_timeline</code>、<code>sync_pt</code> 或 <code>sync_fence</code> 元素,因为 API 应该提供所有必需的函数。</li>
+</ul>
+
+<h3 id="sync_pt">sync_pt</h3>
+
+<p><code>sync_pt</code> 是 sync_timeline 上的单个值或点。点具有三种状态:活动、有信号量和错误。点最初处于活动状态,然后转变为有信号量状态或错误状态。例如,当图像消耗方不再需要缓冲区时,此 sync_point 会处于有信号量状态,以便图像生产方知道可以再次写入缓冲区。</p>
+
+<h3 id="sync_fence">sync_fence</h3>
+
+<p><code>sync_fence</code> 是 <code>sync_pts</code> 的集合,它通常具有不同的 <code>sync_timeline</code> 父项(例如,用于显示控制器和 GPU)。这些是驱动程序和用户空间用来传达依赖关系的主要基元。栅栏是内核在接受已加入队列的工作时给予的承诺,可确保工作在有限的时间内完成。</p>
+
+<p>可让多个消耗方或生产方发出信号,指明它们正在使用一个缓冲区,并允许通过一个函数参数来传达该信息。栅栏由文件描述符提供支持,可以从内核空间传递到用户空间。例如,栅栏可以包含两个 <code>sync_points</code>,它们指示两个单独的图像消耗方何时完成缓冲区读取。当栅栏变为有信号量状态时,图像生产方便知道两个消耗方都已完成消耗。</p>
+
+<p>栅栏(如 <code>sync_pts</code>)最初处于活动状态,然后根据它们的点的状态改变状态。如果所有 <code>sync_pts</code> 都变为有信号量状态,<code>sync_fence</code> 就会变为有信号量状态。如果一个 <code>sync_pt</code> 变为错误状态,则整个 sync_fence 会变为错误状态。</p>
+
+<p>创建栅栏后,<code>sync_fence</code> 中的成员是不可变的。由于 <code>sync_pt</code> 只能在一个栅栏中,因此它是作为副本包含在内。即使两个点具有相同的值,栅栏中也会有两个 <code>sync_pt</code> 副本。为了在栅栏中获得多个点,当来自两个完全不同栅栏的点添加到第三个栅栏时,将进行合并操作。如果其中一个点在原始栅栏中处于有信号量状态,另一个点未处于有信号量状态,那么第三个栅栏也不会处于有信号量状态。</p>
+
+<p>要实现显式同步,请提供以下内容:</p>
+
+<ul>
+<li>为特定硬件实现同步时间轴的内核空间驱动程序。需要感知栅栏的驱动程序通常是访问 Hardware Composer 或与其通信的任何程序。关键文件包括:
+<ul>
+<li>核心实现:
+<ul>
+ <li><code>kernel/common/include/linux/sync.h</code></li>
+ <li><code>kernel/common/drivers/base/sync.c</code></li>
+</ul></li>
+<li><code>sw_sync</code>:
+<ul>
+ <li><code>kernel/common/include/linux/sw_sync.h</code></li>
+ <li><code>kernel/common/drivers/base/sw_sync.c</code></li>
+</ul></li>
+<li><code>kernel/common//Documentation/sync.txt</code> 中的文档。</li>
+<li>与 <code>platform/system/core/libsync</code> 中的内核空间进行通信的库。</li>
+</ul></li>
+<li>支持新同步功能的 Hardware Composer HAL(v1.3 或更高版本)。您必须为 HAL 中的 <code>set()</code> 和 <code>prepare()</code> 函数提供适当的同步栅栏作为参数。</li>
+<li>图形驱动程序中的两个与栅栏相关的 GL 扩展程序(<code>EGL_ANDROID_native_fence_sync</code> 和 <code>EGL_ANDROID_wait_sync</code>)以及栅栏支持。</li>
+</ul>
+
+<p>例如,要使用支持同步函数的 API,您可以开发具有显示设备缓冲区函数的显示设备驱动程序。在同步框架出现之前,此函数会接收 dma-buf,将这些缓冲区放在显示设备上,并在缓冲区可见时阻塞。例如:</p>
+
+<pre class="prettyprint">
+/*
+ * assumes buf is ready to be displayed.  returns when buffer is no longer on
+ * screen.
+ */
+void display_buffer(struct dma_buf *buf);
+</pre>
+
+<p>对于同步框架,API 调用稍微复杂一点。在将缓冲区放在显示设备上时,请将其与指示该缓冲区何时准备就绪的栅栏相关联。您可以让工作排队等候,并在栅栏清除后启动。</p>
+
+<p>这样,不会阻塞任何内容。您会立即返回自己的栅栏,这是对缓冲区何时离开显示设备的保证。让缓冲区排队等候时,内核将列出与同步框架的依赖关系:</p>
+
+<pre class="prettyprint">
+/*
+ * will display buf when fence is signaled.  returns immediately with a fence
+ * that will signal when buf is no longer displayed.
+ */
+struct sync_fence* display_buffer(struct dma_buf *buf, struct sync_fence
+*fence);
+</pre>
+
+<h2 id="sync_integration">同步集成</h2>
+<p>本部分将介绍如何将低级同步框架与 Android 框架的不同部分以及与彼此必须通信的驱动程序进行集成。</p>
+
+<h3 id="integration_conventions">集成规范</h3>
+
+<p>用于图形的 Android HAL 接口会遵循统一的规范,因此当文件描述符通过 HAL 接口传递时,始终会传输文件描述符的所有权。这意味着:</p>
+
+<ul>
+<li>如果您从同步框架收到栅栏文件描述符,就必须将其关闭。</li>
+<li>如果您将栅栏文件描述符返回到同步框架,框架将关闭它。</li>
+<li>要继续使用栅栏文件描述符,您必须复制该描述符。</li>
+</ul>
+
+<p>每当栅栏通过 BufferQueue(例如某个窗口将栅栏传递到 BufferQueue,指明其新内容何时准备就绪)时,该栅栏对象将被重命名。由于内核栅栏支持允许栅栏使用字符串作为名称,因此同步框架使用正在排队的窗口名称和缓冲区索引来命名栅栏(例如 <code>SurfaceView:0</code>)。这有助于进行调试来找出死锁的来源,因为名称会显示在 <code>/d/sync</code> 的输出和错误报告中。</p>
+
+<h3 id="anativewindow_integration">ANativeWindow 集成</h3>
+
+<p>ANativeWindow 是栅栏感知的,而且 <code>dequeueBuffer</code>、<code>queueBuffer</code> 和 <code>cancelBuffer</code> 具有栅栏参数。
+</p>
+
+<h3 id="opengl_es_integration">OpenGL ES 集成</h3>
+
+<p>OpenGL ES 同步集成依赖于两个 EGL 扩展程序:</p>
+
+<ul>
+<li><code>EGL_ANDROID_native_fence_sync</code>。提供一种在 EGLSyncKHR 对象中包装或创建原生 Android 栅栏文件描述符的方法。</li>
+<li><code>EGL_ANDROID_wait_sync</code>。允许 GPU 端停止而不是在 CPU 中停止,使 GPU 等待 EGLSyncKHR。这与 <code>EGL_KHR_wait_sync</code> 扩展程序基本相同(有关详细信息,请参阅相关规范)。</li>
+</ul>
+
+<p>这些扩展程序可以独立使用,并由 libgui 中的编译标记控制。要使用它们,请首先实现 <code>EGL_ANDROID_native_fence_sync</code> 扩展程序以及关联的内核支持。接下来,为驱动程序添加对栅栏的 ANATIONWindow 支持,然后在 libgui 中启用支持以使用 <code>EGL_ANDROID_native_fence_sync</code> 扩展程序。</p>
+
+<p>其次,在驱动程序中启用 <code>EGL_ANDROID_wait_sync</code> 扩展程序,并单独打开它。<code>EGL_ANDROID_native_fence_sync</code> 扩展程序包含完全不同的原生栅栏 EGLSync 对象类型,因此适用于现有 EGLSync 对象类型的扩展程序不一定适用于 <code>EGL_ANDROID_native_fence</code> 对象,以避免不必要的交互。</p>
+
+<p>EGL_ANDROID_native_fence_sync 扩展程序使用相应的原生栅栏文件描述符属性,该属性只能在创建时设置,不能从现有同步对象直接向前查询。该属性可以设置为以下两种模式之一:</p>
+
+<ul>
+<li><em></em>有效的栅栏文件描述符。在 EGLSyncKHR 对象中包装现有的原生 Android 栅栏文件描述符。</li>
+<li><em></em>-1。从 EGLSyncKHR 对象创建原生 Android 栅栏文件描述符。</li>
+</ul>
+
+<p>DupNativeFenceFD 函数调用用于从原生 Android 栅栏文件描述符中提取 EGLSyncKHR 对象。这与查询已设置的属性具有相同的结果,但遵守由收件人关闭栅栏的规范(因此是重复操作)。最后,清除 EGLSync 对象应该会关闭内部栅栏属性。</p>
+
+<h3 id="hardware_composer_integration">Hardware Composer 集成</h3>
+
+<p>Hardware Composer 可处理三种类型的同步栅栏:</p>
+
+<ul>
+<li><em></em>获取栅栏。每层一个,在调用 <code>HWC::set</code> 之前设置。当 Hardware Composer 可以读取缓冲区时,该栅栏会变为有信号量状态。</li>
+<li><em></em>释放栅栏。每层一个,在 <code>HWC::set</code> 中由驱动程序填充。当 Hardware Composer 完成对缓冲区的读取时,该栅栏会变为有信号量状态,以便框架可以再次开始将该缓冲区用于特定层。</li>
+<li><em></em>退出栅栏。整个框架一个,每次调用 <code>HWC::set</code> 时由驱动程序填充。HWC::set 操作会覆盖所有的层,并且当所有层的 HWC::set 操作完成时会变成有信号量状态并通知框架。当在屏幕上进行下一设置操作时,退出栅栏将变为有信号量状态。</li>
+</ul>
+
+<p>退出栅栏可用于确定每个帧在屏幕上的显示时长。这有助于识别延迟的位置和来源,例如卡顿的动画。</p>
+
+<h2 id="vsync_offset">VSYNC 偏移</h2>
+
+<p>应用和 SurfaceFlinger 渲染循环应同步到硬件 VSYNC。在 VSYNC 事件中,显示设备开始显示帧 N,而 SurfaceFlinger 开始为帧 N+1 合成窗口。应用处理等待的输入并生成帧 N+2。</p>
+
+<p>与 VSYNC 同步会实现一致的延迟时间。它可以减少应用和 SurfaceFlinger 中的错误,以及相位内外显示设备之间的漂移。但是,这要假定应用和 SurfaceFlinger 的每帧时间没有很大变化。尽管如此,延迟至少为两帧。</p>
+
+<p>为了解决此问题,您可以通过使应用和合成信号与硬件 VSYNC 相关,从而利用 VSYNC 偏移减少输入设备到显示设备的延迟。这是有可能的,因为应用加合成通常需要不到 33 毫秒的时间。</p>
+
+<p>VSYNC 偏移的结果是具有相同周期和偏移相位的三个信号:</p>
+
+<ul>
+<li><code>HW_VSYNC_0</code>。显示设备开始显示下一帧。</li>
+<li><code>VSYNC</code>。应用读取输入内容并生成下一帧。</li>
+<li><code>SF VSYNC</code>。SurfaceFlinger 开始为下一帧进行合成。</li>
+</ul>
+
+<p>通过 VSYNC 偏移,SurfaceFlinger 接收缓冲区并合成帧,而应用处理输入内容并渲染帧,所有这些操作都在一个时间段内完成。</p>
+
+<p class="note"><strong>注意</strong>:VSYNC 偏移会缩短可用于应用和合成的时间,因此增加了出错几率。</p>
+
+<h3 id="dispsync">DispSync</h3>
+
+<p>DispSync 维护显示设备基于硬件的周期性 VSYNC 事件的模型,并使用该模型在硬件 VSYNC 事件的特定相位偏移处执行周期性回调。</p>
+
+<p>DispSync 实质上是一个软件锁相回路 (PLL),它可以生成由 Choreographer 和 SurfaceFlinger 使用的 VSYNC 和 SF VSYNC 信号,即使没有来自硬件 VSYNC 的偏移也是如此。</p>
+
+<img src="images/dispsync.png" alt="DispSync 流程"/>
+
+<p class="img-caption"><strong>图 1.</strong> DispSync 流程</p>
+
+<p>DispSync 具有以下特点:</p>
+
+<ul>
+<li><em></em>参考。HW_VSYNC_0。</li>
+<li><em></em>输出。VSYNC 和 SF VSYNC。</li>
+<li><em></em>反馈。来自 Hardware Composer 的退出栅栏有信号量状态时间戳。
+</li>
+</ul>
+
+<h3 id="vsync_retire_offset">VSYNC/退出偏移</h3>
+
+<p>退出栅栏的有信号量状态时间戳必须与 HW VSYNC 相符,即使在不使用偏移相位的设备上也是如此。否则,实际造成的错误会严重得多。智能面板通常有一个增量:退出栅栏是对显示设备内存进行直接内存访问 (DMA) 的终点,但是实际的显示切换和 HW VSYNC 会晚一段时间。</p>
+
+<p><code>PRESENT_TIME_OFFSET_FROM_VSYNC_NS</code> 在设备的 BoardConfig.mk Makefile 中设置。它基于显示控制器和面板特性。从退出栅栏时间戳到 HW VSYNC 信号的时间是以纳秒为单位进行测量。</p>
+
+<h3 id="vsync_and_sf_vsync_offsets">VSYNC 和 SF_VSYNC 偏移</h3>
+
+<p><code>VSYNC_EVENT_PHASE_OFFSET_NS</code> 和 <code>SF_VSYNC_EVENT_PHASE_OFFSET_NS</code> 是在高负载用例的基础上进行保守设置,例如在窗口转换期间进行部分 GPU 合成或 Chrome 滚动显示包含动画的网页。这些偏移允许较长的应用渲染时间和较长的 GPU 合成时间。</p>
+
+<p>超过一两毫秒的延迟时间是非常明显的。我们建议集成彻底的自动化错误测试,以便在不显著增加错误计数的前提下最大限度减少延迟时间。</p>
+
+<p class="note"><strong>注意:</strong>这些偏移同样在设备的 BoardConfig.mk 文件中配置。两个设置都是 HW_VSYNC_0 之后以纳秒为单位的偏移,默认值为零(如未设置的话),也可以为负值。</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/graphics/implement-vulkan.html b/zh-cn/devices/graphics/implement-vulkan.html
new file mode 100644
index 0000000..6475e81
--- /dev/null
+++ b/zh-cn/devices/graphics/implement-vulkan.html
@@ -0,0 +1,163 @@
+<html devsite><head>
+    <title>实现 Vulkan</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 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>Vulkan 是用于高性能 3D 图形处理的低开销、跨平台 API。与 OpenGL ES 一样,Vulkan 提供多种用于在应用中创建高质量的实时图形的工具。Vulkan 的优势包括降低 CPU 开销和支持 <a href="https://www.khronos.org/spir">SPIR-V 二进制中间</a>语言。</p>
+
+<p class="note"><strong>注意</strong>:本部分介绍的是 Vulkan 实现;有关 Vulkan 架构、优势、API 和其他资源的详细信息,请参阅 <a href="/devices/graphics/arch-vulkan.html">Vulkan 架构</a>。</p>
+
+<p>要实现 Vulkan,设备:</p>
+<ul>
+<li>必须在构建环境中包含 Vulkan 加载程序(由 Android 提供)。</li>
+<li>必须包含实现 <a href="https://www.khronos.org/registry/vulkan/specs/1.0-wsi_extensions/xhtml/vkspec.html">Vulkan API</a> 的 Vulkan 驱动程序(由 SoC 提供,如 GPU IHV)。为了支持 Vulkan 功能,Android 设备需要功能满足需求的 GPU 硬件和相关驱动程序。请咨询您的 SoC 供应商,以请求获取驱动程序支持。</li>
+</ul>
+<p>如果设备上有可用的 Vulkan 驱动程序,则该设备需要声明 <code>FEATURE_VULKAN_HARDWARE_LEVEL</code> 和 <code>FEATURE_VULKAN_HARDWARE_VERSION</code> 系统功能,并且相关版本能够准确反映设备的功能。</p>
+
+<h2 id="vulkan_loader">Vulkan 加载程序</h2>
+<p>Vulkan 应用和设备的 Vulkan 驱动程序之间的主要接口是 Vulkan 加载程序,它是 Android 开放源代码项目 (AOSP) (<code>platform/frameworks/native/vulkan</code>) 的一部分,并安装在 <code>/system/lib[64]/libvulkan.so</code>。加载程序会提供核心 Vulkan API 入口点,以及 Android 上必需且始终存在的一些扩展程序的入口点。尤其是,窗口系统集成 (WSI) 扩展程序由加载程序导出,并主要在加载程序(而非驱动程序)中实现。此外,加载程序还支持枚举和加载可显示其他扩展程序且/或在核心 API 调用到达驱动程序的途中对其进行拦截的层。</p>
+
+<p>NDK 包含一个存根 <code>libvulkan.so</code> 库,该库可导出与加载程序相同的符号(用于进行关联)。在设备上运行时,应用会调用从 <code>libvulkan.so</code>(真正的库,而非存根)导出的 Vulkan 函数,以进入加载程序中的 trampoline 函数(然后根据其第一个参数分派到相应的层或驱动程序)。<code>vkGetDeviceProcAddr</code> 调用返回 trampoline 将分派到的函数指针(即它直接调用核心 API 代码),由于通过这些函数指针(而非导出的符号)进行调用跳过了 trampoline 和分派,因此其效率更高一些。不过,<code>vkGetInstanceProcAddr</code> 必须仍调用 trampoline 代码。</p>
+
+<h2 id="driver_emun">驱动程序枚举和加载</h2>
+<p>Android 要求在构建系统映像时系统可用的 GPU 是已知状态。加载程序使用现有 HAL 机制(请参阅 <code><a href="https://android.googlesource.com/platform/hardware/libhardware/+/master/include/hardware/hardware.h">hardware.h</a></code>)来发现和加载驱动程序。32 位和 64 位 Vulkan 驱动程序的首选路径分别为:</p>
+
+<p>
+</p><pre class="devsite-click-to-copy">
+/vendor/lib/hw/vulkan.&lt;ro.product.platform&gt;.so
+/vendor/lib64/hw/vulkan.&lt;ro.product.platform&gt;.so
+</pre>
+<p></p>
+
+<p>其中,&lt;<code>ro.product.platform</code>&gt; 需替换为具有该名称的系统属性的值。有关详细信息和受支持的备选位置,请参阅 <code><a href="https://android.googlesource.com/platform/hardware/libhardware/+/master/hardware.c">libhardware/hardware.c</a></code>。</p>
+
+<p>在 Android 7.0 中,Vulkan <code>hw_module_t</code> 衍生微不足道;仅支持一个驱动程序,并将常量字符串 <code>HWVULKAN_DEVICE_0</code> 传递给 open 函数。如果在 Android 后续版本中添加对多个驱动程序的支持,则 HAL 模块将导出可以传递给 <code>module open</code> 调用的字符串列表。</p>
+
+<p>Vulkan <code>hw_device_t</code> 衍生对应单个驱动程序,尽管该驱动程序可以支持多个物理设备。可以扩展 <code>hw_device_t</code> 结构,以导出 <code>vkGetGlobalExtensionProperties</code>、<code>vkCreateInstance</code> 和 <code>vkGetInstanceProcAddr</code> 函数。加载程序可以通过调用 <code>vkGetInstanceProcAddr</code> 找到所有其他 <code>VkInstance</code>、<code>VkPhysicalDevice</code> 和 <code>vkGetDeviceProcAddr</code> 函数。</p>
+
+<h2 id="layer_discover">发现和加载层</h2>
+<p>Vulkan 加载程序支持枚举和加载可显示其他扩展程序且/或在核心 API 调用到达驱动程序的途中对其进行拦截的层。Android 7.0 在系统映像上不包含层;但是,应用可以在其 APK 中包含层。</p>
+<p>使用层时请注意,Android 的安全模型和政策与其他平台截然不同。尤其是,Android 不允许将外部代码加载到正式版(未取得 root 权限)设备上的不可调试进程中,也不允许外部代码检查或控制进程的内存、状态等。这包括禁止将核心转储、API 跟踪等保存到磁盘以供日后进行检查。只有作为应用一部分提交的层会在正式版设备上启用,而且驱动程序不得提供违反这些政策的功能。</p>
+
+<p>层的使用情形包括:</p>
+<ul>
+<li><strong>开发期间的层</strong>。这些层(验证层,用于跟踪/分析/调试工具的 Shim 层等)不得安装在正式版设备的系统映像上(因为它们会浪费用户的空间),并且应当可在无需系统更新的情况下进行更新。想要在开发过程中使用这些层之一的开发者可以修改应用包(例如,向其原生库目录中添加一个文件)。对于想要在即将推出的不可修改应用中诊断故障的 IHV 和原始设备制造商 (OEM) 工程师,假定其能够访问系统映像的非正式(已取得 root 权限)版本。</li>
+<li><strong>实用工具层</strong>。这些层几乎总是显示扩展程序,例如为设备内存实现内存管理器的层。开发者可选择要在其应用中使用的层(以及这些层的版本);使用相同层的不同应用仍可使用不同的版本。开发者可选择要在其应用包中包含哪些层。</li>
+<li><strong>注入(隐含)层</strong>。在应用不知情或未经应用同意的情况下,包含用户或一些其他应用提供的层,如帧速率、社交网络或游戏启动器叠加层。这些层违反了 Android 的安全政策,因此不受支持。</li>
+</ul>
+
+<p>在正常状态下,加载程序仅在应用的原生库目录中搜索层,并尝试加载任何名称符合特定格式(例如 <code>libVKLayer_foo.so</code>)的库。它不需要单独的清单文件,因为开发者有意包含这些层,而避免在启用库之前加载它们的原因不适用。</p>
+
+<p>Android 允许在 Android 与其他平台之间移植层(包括编译环境更改)。有关层与加载程序之间接口的详细信息,请参阅 <a href="https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/blob/master/loader/LoaderAndLayerInterface.md">Vulkan 加载程序规范和架构概览</a>。已经过验证可在 Android 上构建和运行的 LunarG 验证层的版本托管在 GitHub 上 <a href="https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/tree/android_layers">KhronosGroup/Vulkan-LoaderAndValidationLayers</a> 项目的 android_layers 分支下。</p>
+
+<h2 id="wsi">窗口系统集成 (WSI)</h2>
+<p>窗口系统集成 (WSI) 扩展程序 <code>VK_KHR_surface</code>、<code>VK_KHR_android_surface</code> 和 <code>VK_KHR_swapchain</code> 由 Android 平台实现并存在于 <code>libvulkan.so</code> 中。<code>VkSurfaceKHR</code> 和 <code>VkSwapchainKHR</code> 对象以及与 <code>ANativeWindow</code> 的所有互动都由 Android 平台处理,不会提供给驱动程序。WSI 实现依赖于必须受驱动程序支持的 <code>VK_ANDROID_native_buffer</code> 扩展程序(如下所述);此扩展程序仅由 WSI 实现使用,不会提供给应用。</p>
+
+<h3 id="gralloc_usage_flags">Gralloc 用途标记</h3>
+<p>实现可能需要使用由实现定义的私密 gralloc 用途标记来分配交换链缓冲区。创建交换链时,Android 平台要求驱动程序将请求的格式和图像用途标记转换为 gralloc 用途标记,具体方法是调用:</p>
+
+<p>
+</p><pre class="devsite-click-to-copy">
+VkResult VKAPI vkGetSwapchainGrallocUsageANDROID(
+    VkDevice            device,
+    VkFormat            format,
+    VkImageUsageFlags   imageUsage,
+    int*                grallocUsage
+);
+</pre>
+<p></p>
+
+<p><code>format</code> 和 <code>imageUsage</code> 参数来自 <code>VkSwapchainCreateInfoKHR</code> 结构。驱动程序应使用相关格式和用途所需的 gralloc 用途标记来填充 <code>*grallocUsage</code>(分配缓冲区时,与交换链消费者请求的用途标记配合使用)。</p>
+
+<h3 id="gralloc_usage_flags">由 Gralloc 支持的图像</h3>
+
+<p><code>VkNativeBufferANDROID</code> 是一个 <code>vkCreateImage</code> 扩展程序结构,用于创建由 gralloc 缓冲区支持的图像。该结构提供给 <code>VkImageCreateInfo</code> 结构链中的 <code>vkCreateImage</code>。在第一次调用 <code>vkGetSwapChainInfoWSI(..
+VK_SWAP_CHAIN_INFO_TYPE_IMAGES_WSI ..)</code> 期间,会调用具有此结构的 <code>vkCreateImage</code>。WSI 实现为交换链分配请求的原生缓冲区数,然后为每个缓冲区创建一个 <code>VkImage</code>:</p>
+
+<pre class="devsite-click-to-copy">
+typedef struct {
+    VkStructureType             sType; // must be VK_STRUCTURE_TYPE_NATIVE_BUFFER_ANDROID
+    const void*                 pNext;
+
+    // Buffer handle and stride returned from gralloc alloc()
+    buffer_handle_t             handle;
+    int                         stride;
+
+    // Gralloc format and usage requested when the buffer was allocated.
+    int                         format;
+    int                         usage;
+} VkNativeBufferANDROID;
+</pre>
+
+<p>创建由 gralloc 支持的图像时,<code>VkImageCreateInfo</code> 具有以下数据:</p>
+
+<pre class="devsite-click-to-copy">
+ .imageType           = VK_IMAGE_TYPE_2D
+  .format              = a VkFormat matching the format requested for the gralloc buffer
+  .extent              = the 2D dimensions requested for the gralloc buffer
+  .mipLevels           = 1
+  .arraySize           = 1
+  .samples             = 1
+  .tiling              = VK_IMAGE_TILING_OPTIMAL
+  .usage               = VkSwapChainCreateInfoWSI::imageUsageFlags
+  .flags               = 0
+  .sharingMode         = VkSwapChainCreateInfoWSI::sharingMode
+  .queueFamilyCount    = VkSwapChainCreateInfoWSI::queueFamilyCount
+  .pQueueFamilyIndices = VkSwapChainCreateInfoWSI::pQueueFamilyIndices
+</pre><p></p>
+
+<h3 id="acquire_image">获取图像</h3>
+<p><code>vkAcquireImageANDROID</code> 会获取交换链图像的所有权,并将已获得外部信号量的原生栅栏同时导入到现有的 <code>VkSemaphore</code> 对象和现有的 <code>VkFence</code> 对象:</p>
+
+<pre class="devsite-click-to-copy">
+VkResult VKAPI vkAcquireImageANDROID(
+    VkDevice            device,
+    VkImage             image,
+    int                 nativeFenceFd,
+    VkSemaphore         semaphore,
+    VkFence             fence
+);
+</pre>
+
+<p>此函数在 <code>vkAcquireNextImageWSI</code> 期间被调用,以将原生栅栏导入到应用提供的 <code>VkSemaphore</code> 和 <code>VkFence</code> 对象中(不过,在此调用中,信号量和栅栏对象均是可选的)。驱动程序可能也会借此机会识别和处理 gralloc 缓冲区状态的所有外部更改;许多驱动程序在此无需进行任何操作。此调用会将 <code>VkSemaphore</code> 和 <code>VkFence</code> 分别置于与 <code>vkQueueSignalSemaphore</code> 和 <code>vkQueueSubmit</code> 相同的待处理状态,因此队列可以等待信号量,应用可以等待栅栏。</p>
+
+<p>当底层的原生栅栏发出信号时,两个对象都处于有信号量的状态;如果原生栅栏已经处于有信号量状态,则当该函数返回时,信号量也处于有信号量的状态。驱动程序拥有栅栏 fd 的所有权,负责在其不再需要时将其关闭。即使没有提供信号量或栅栏对象,或者即使 <code>vkAcquireImageANDROID</code> 失败并返回错误,它也必须这样做。如果 fenceFd 为 -1,就如同原生栅栏已处于有信号量的状态。</p>
+
+<h3 id="acquire_image">释放图像</h3>
+<p><code>vkQueueSignalReleaseImageANDROID</code> 会准备交换链图像以供外部使用,创建一个原生栅栏,并安排其在队列上的前期工作完成后收到信号:</p>
+
+<pre class="devsite-click-to-copy">
+VkResult VKAPI vkQueueSignalReleaseImageANDROID(
+    VkQueue             queue,
+    VkImage             image,
+    int*                pNativeFenceFd
+);
+</pre>
+
+<p>此 API 在提供的队列上的 <code>vkQueuePresentWSI</code> 期间被调用。具体效果与 <code>vkQueueSignalSemaphore</code> 类似,但使用的是原生栅栏,而非信号量。不过,与 <code>vkQueueSignalSemaphore</code> 不同的是,此调用会创建并返回将收到信号(而非作为输入进行提供)的同步对象。如果调用此函数时队列已经闲置,则允许其(但并非必需)将 <code>*pNativeFenceFd</code> 设置为 -1。调用方拥有 *<code>pNativeFenceFd</code> 中返回的文件描述符并会将其关闭。</p>
+
+<h3 id="update_drivers">更新驱动程序</h3>
+
+<p>很多驱动程序可以忽略图像参数,但有些驱动程序可能需要准备与 gralloc 缓冲区相关联的 CPU 端数据结构,以供外部图像消费者使用。作为将图像转换为 <code>VK_IMAGE_LAYOUT_PRESENT_SRC_KHR</code> 的一个环节,准备外部消费者使用的缓冲区内容应该异步完成。</p>
+
+<h2 id="validation">验证</h2>
+<p>OEM 可以使用 CTS 测试其 Vulkan 实现,其中包括使用 Vulkan 运行时的 <a href="/devices/graphics/cts-integration.html">drawElements 质量计划 (dEQP)</a> 测试。</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/graphics/implement.html b/zh-cn/devices/graphics/implement.html
new file mode 100644
index 0000000..e9ae88f
--- /dev/null
+++ b/zh-cn/devices/graphics/implement.html
@@ -0,0 +1,104 @@
+<html devsite><head>
+    <title>实现图形</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 The Android Open Source Project
+
+      Licensed under the Apache License, Version 2.0 (the "License");
+      you may not use this file except in compliance with the License.
+      You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      See the License for the specific language governing permissions and
+      limitations under the License.
+  -->
+
+<p>要实现 Android 图形 HAL,请查看以下要求、实现详情和测试建议。</p>
+
+<h2 id="requirements">要求</h2>
+
+<p>Android 图形支持需要以下组件:</p>
+
+<ul>
+    <li>EGL 驱动程序</li>
+    <li>OpenGL ES 1.x 驱动程序</li>
+    <li>OpenGL ES 2.0 驱动程序</li>
+    <li>OpenGL ES 3.x 驱动程序(可选)</li>
+    <li>Vulkan(可选)</li>
+    <li>Gralloc HAL 实现</li>
+    <li>Hardware Composer HAL 实现</li>
+</ul>
+
+<h2 id="implementation">实现</h2>
+
+<h3 id="opengl_and_egl_drivers">OpenGL 和 EGL 驱动程序</h3>
+
+<p>您必须为 EGL、OpenGL ES 1.x 和 OpenGL ES 2.0 提供驱动程序(对 OpenGL 3.x 的支持是可选的)。主要注意事项包括:</p>
+
+<ul>
+    <li>GL 驱动程序必须稳定可靠且符合 OpenGL ES 标准。</li>
+    <li>请勿限制 GL 上下文的数量。由于 Android 允许应用在后台运行,并且会尝试使 GL 上下文保持活动状态,因此您不应限制驱动程序中的上下文数量。</li>
+    <li>通常可同时具有 20-30 个活动的 GL 上下文,因此请注意为每个上下文分配的内存量。</li>
+    <li>支持来自系统中其他组件(如媒体编解码器或相机)的 YV12 图像格式和其他 YUV 图像格式。</li>
+    <li>支持强制扩展程序:<code>GL_OES_texture_external</code>、<code>EGL_ANDROID_image_native_buffer</code> 和 <code>EGL_ANDROID_recordable</code>。另外,对于 Hardware Composer v1.1 及更高版本,还需要 <code>EGL_ANDROID_framebuffer_target</code> 扩展程序。</li>
+    </ul>
+<p>我们还强烈建议支持 <code>EGL_ANDROID_blob_cache</code>、<code>EGL_KHR_fence_sync</code>、<code>EGL_KHR_wait_sync</code> 和 <code>EGL_ANDROID_native_fence_sync</code>。</p>
+
+<p class="note"><strong>注意</strong>:呈现给应用开发者的 OpenGL API 与在设备上实现的 OpenGL 不同。应用不能直接访问 GL 驱动程序层,且必须通过 API 提供的接口。</p>
+
+<h3 id="pre-rotation">预旋转</h3>
+
+<p>许多硬件叠加层不支持旋转(即使支持,也会耗费很多处理能力);解决方案是在缓冲区到达 SurfaceFlinger 之前进行预转换。Android 在 <code>ANativeWindow</code> 中支持查询提示 (<code>NATIVE_WINDOW_TRANSFORM_HINT</code>),以表示 SurfaceFlinger 应用于缓冲区的最可能的转换。GL 驱动程序可以使用此提示在缓冲区到达 SurfaceFlinger 之前预转换缓冲区,以便当缓冲区到达时,可以正确转换。</p>
+
+<p>例如,当接收到旋转 90 度的提示时,会生成一个矩阵并将其应用于缓冲区,以防止其从页面末尾运行。为了节省电量,请进行此预旋转。有关详请,请参见 <code>system/core/include/system/window.h</code> 中定义的 <code>ANativeWindow</code> 接口。</p>
+
+<h3 id="gralloc_hal">Gralloc HAL</h3>
+
+<p>图形内存分配器会分配图像生成器请求的内存。您可以在 <code>hardware/libhardware/include/hardware/gralloc.h</code> 中找到 HAL 的接口定义。</p>
+
+<h3 id="protected_buffers">受保护的缓冲区</h3>
+
+<p>Gralloc 使用标记 <code>GRALLOC_USAGE_PROTECTED</code> 允许仅通过受硬件保护的路径显示图形缓冲区。这些叠加平面是显示 DRM 内容的唯一途径(SurfaceFlinger 或 OpenGL ES 驱动程序无法访问受 DRM 保护的缓冲区)。</p>
+
+<p>受 DRM 保护的视频只能在叠加平面上呈现。支持受保护内容的视频播放器必须使用 SurfaceView 实现。在不受保护的硬件上运行的软件无法读取或写入缓冲区;受硬件保护的路径必须显示在 Hardware Composer 叠加层上(也就是说,如果 Hardware Composer 切换到 OpenGL ES 合成,受保护的视频将从显示设备中消失)。</p>
+
+<p>有关受保护内容的详细信息,请参阅 <a href="/devices/drm.html">DRM</a> 一文。</p>
+
+<h3 id="hardware_composer_hal">Hardware Composer HAL</h3>
+
+<p>SurfaceFlinger 使用 Hardware Composer HAL (HWC) 将 Surface 合成到屏幕。它可以抽象出叠加层和二维位块传送器等对象,并且有助于分载通常由 OpenGL 完成的一些工作。有关 HWC 的详细信息,请参阅<a href="/devices/graphics/implement-hwc.html">实现 Hardware Composer HAL</a> 一文。</p>
+
+<h3 id="vsync">VSYNC</h3>
+
+<p>VSYNC 可将某些事件同步到显示设备的刷新周期。应用始终在 VSYNC 边界上开始绘制,而 SurfaceFlinger 始终在 VSYNC 边界上进行合成。这样可以消除卡顿,并提升图形的视觉表现。有关 VSYNC 的详细信息,请参阅<a href="/devices/graphics/implement-vsync.html">实现 VSYNC</a> 一文。</p>
+
+<h3 id="vulkan">Vulkan</h3>
+
+<p>Vulkan 是用于高性能三维图形的低开销、跨平台 API。像 OpenGL ES 一样,Vulkan 会提供相应工具,以用于在应用中创建高品质的实时图形。Vulkan 的优势包括降低 CPU 开销和支持 <a href="https://www.khronos.org/spir">SPIR-V 二进制中间</a>语言。有关 Vulkan 的详细信息,请参阅<a href="/devices/graphics/implement-vulkan.html">实现 Vulkan</a> 一文。</p>
+
+<h3 id="virtual_displays">虚拟显示设备</h3>
+
+<p>Android 在 Hardware Composer v1.3 中添加了对虚拟显示设备的平台支持。虚拟显示设备合成类似于物理显示设备:在 prepare() 中描述输入层,SurfaceFlinger 进行 GPU 合成,然后在 set() 中将层和 GPU 帧缓冲区提供给 Hardware Composer。有关虚拟显示设备的详细信息,请参阅<a href="/devices/graphics/implement-vdisplays.html">实现虚拟显示设备</a>一文。</p>
+
+<h2 id="testing">测试</h2>
+
+<p>对于基准测试,请按阶段使用以下流程:</p>
+
+<ul>
+  <li>规格设计阶段。<em></em>在最初选定设备时(例如使用不成熟的驱动程序时),使用预定义(固定)的时钟和工作负载来测量每秒渲染的帧数 (fps)。这可以让我们清楚地了解硬件功能。</li>
+  <li>开发阶段。<em></em>在驱动程序成熟后,使用一组固定的用户操作来测量动画中的可见卡顿数量。</li>
+  <li>量产阶段。<em></em>当设备已准备好投放市场时,增加工作负载,直到卡顿增加。确定当前时钟设置是否可以跟得上负载。这可以帮助您确定在何处减慢时钟并减少功耗。</li>
+</ul>
+
+<p>为了在规格设计阶段便于推究设备性能,可使用 <code>platform/frameworks/native/cmds/flatland/</code> 下的 Flatland 工具。Flatland 依靠固定时钟,并显示可通过基于合成的工作负载实现的吞吐量。Flatland 使用 gralloc 缓冲区来模拟多窗口情景,用 GL 填充窗口,然后测量合成情况。</p>
+
+<p class="note"><strong>注意:</strong>Flatland 使用同步框架来测量时间,因此您的实现必须支持同步框架。</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/graphics/index.html b/zh-cn/devices/graphics/index.html
new file mode 100644
index 0000000..4d23d05
--- /dev/null
+++ b/zh-cn/devices/graphics/index.html
@@ -0,0 +1,117 @@
+<html devsite><head>
+    <title>图形</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 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.
+  -->
+
+<img style="float: right; margin: 0px 15px 15px 15px;" src="images/ape_fwk_hal_graphics.png" alt="Android 图形 HAL 图标"/>
+
+<p>Android 框架提供了各种用于 2D 和 3D 图形渲染的 API,可与制造商的图形驱动程序实现方法交互,因此,务必充分了解这些 API 如何在更高的级别工作。本页介绍了在其上构建这些驱动程序的图形硬件抽象层 (HAL)。</p>
+
+<p>应用开发者可通过两种方式将图像绘制到屏幕上:使用 Canvas 或 OpenGL。有关 Android 图形组件的详细说明,请参阅<a href="/devices/graphics/architecture.html">系统级图形架构</a>。</p>
+
+<p><a href="http://developer.android.com/reference/android/graphics/Canvas.html">android.graphics.Canvas</a> 是一个 2D 图形 API,并且是在开发者人群中最流行的图形 API。Canvas 运算会在 Android 中绘制所有原生和自定义 <a href="http://developer.android.com/reference/android/view/View.html">android.view.View</a>。在 Android 中,Canvas API 通过一个名为 OpenGLRenderer 的绘制库实现硬件加速,该绘制库将 Canvas 运算转换为 OpenGL 运算,以便它们可以在 GPU 上执行。</p>
+
+<p>从 Android 4.0 开始,硬件加速的 Canvas 默认情况下处于启用状态。因此,支持 OpenGL ES 2.0 的硬件 GPU 对于 Android 4.0 及更高版本的设备来说是强制要求。有关硬件加速绘制路径的工作原理及其行为与软件绘制路径行为之间的差异的说明,请参阅<a href="https://developer.android.com/guide/topics/graphics/hardware-accel.html">硬件加速指南</a>。</p>
+
+<p>除了 Canvas,开发者渲染图形的另一个主要方式是使用 OpenGL ES 直接渲染到 Surface。Android 在 <a href="http://developer.android.com/reference/android/opengl/package-summary.html">Android.opengl</a> 包中提供了 OpenGL ES 接口,开发者可以使用这些接口通过 SDK 或 <a href="https://developer.android.com/tools/sdk/ndk/index.html">Android NDK</a> 中提供的原生 API 调用其 GL 实现。</p>
+
+<p>Android 实现人员可以使用 <a href="testing.html">drawElements 质量计划</a>(也称为 deqp)来测试 OpenGL ES 功能。</p>
+
+<h2 id="android_graphics_components">Android 图形组件</h2>
+
+<p>无论开发者使用什么渲染 API,一切内容都会渲染到“Surface”。Surface 表示缓冲队列中的生产方,而缓冲队列通常会被 SurfaceFlinger 消耗。在 Android 平台上创建的每个窗口都由 Surface 提供支持。所有被渲染的可见 Surface 都被 SurfaceFlinger 合成到显示部分。</p>
+
+<p>下图显示了关键组件如何协同工作:</p>
+
+<img src="images/ape_fwk_graphics.png" alt="图像渲染组件"/>
+
+<p class="img-caption"><strong>图 1.</strong> Surface 如何被渲染</p>
+
+<p>主要组件如下所述:</p>
+
+<h3 id="image_stream_producers">图像流生产方</h3>
+
+<p>图像流生产方可以是生成图形缓冲区以供消耗的任何内容。例如 OpenGL ES、Canvas 2D 和 mediaserver 视频解码器。</p>
+
+<h3 id="image_stream_consumers">图像流消耗方</h3>
+
+<p>图像流的最常见消耗方是 SurfaceFlinger,该系统服务会消耗当前可见的 Surface,并使用窗口管理器中提供的信息将它们合成到显示部分。SurfaceFlinger 是可以修改显示部分内容的唯一服务。SurfaceFlinger 使用 OpenGL 和 Hardware Composer 来合成一组 Surface。</p>
+
+<p>其他 OpenGL ES 应用也可以消耗图像流,例如相机应用会消耗相机预览图像流。非 GL 应用也可以是消耗方,例如 ImageReader 类。</p>
+
+<h3 id="window_manager">窗口管理器</h3>
+
+<p>控制窗口的 Android 系统服务,它是视图容器。窗口总是由 Surface 提供支持。该服务会监督生命周期、输入和聚焦事件、屏幕方向、转换、动画、位置、变形、Z-Order 以及窗口的其他许多方面。窗口管理器会将所有窗口元数据发送到 SurfaceFlinger,以便 SurfaceFlinger 可以使用该数据在显示部分合成 Surface。</p>
+
+<h3 id="hardware_composer">硬件混合渲染器</h3>
+
+<p>显示子系统的硬件抽象实现。SurfaceFlinger 可以将某些合成工作委托给 Hardware Composer,以分担 OpenGL 和 GPU 上的工作量。SurfaceFlinger 只是充当另一个 OpenGL ES 客户端。因此,在 SurfaceFlinger 将一个或两个缓冲区合成到第三个缓冲区中的过程中,它会使用 OpenGL ES。这样使合成的功耗比通过 GPU 执行所有计算更低。</p>
+
+<p><a href="/devices/graphics/architecture.html#hwcomposer">Hardware Composer HAL</a> 则进行另一半的工作,并且是所有 Android 图形渲染的核心。Hardware Composer 必须支持事件,其中之一是 VSYNC(另一个是支持即插即用 HDMI 的热插拔)。</p>
+
+<h3 id="gralloc">Gralloc</h3>
+
+<p>需要使用图形内存分配器 (Gralloc) 来分配图像生产方请求的内存。有关详情,请参阅 <a href="/devices/graphics/architecture.html#gralloc_HAL">Gralloc HAL</a>。</p>
+
+<h2 id="data_flow">数据流</h2>
+
+<p>有关 Android 图形管道的描述,请参见下图:</p>
+
+<img src="images/graphics_pipeline.png" alt="图形数据流"/>
+
+<p class="img-caption"><strong>图 2.</strong> 流经 Android 的图形数据流</p>
+
+<p>左侧的对象是生成图形缓冲区的渲染器,如主屏幕、状态栏和系统界面。SurfaceFlinger 是合成器,而硬件混合渲染器是制作器。</p>
+
+<h3 id="bufferqueue">BufferQueue</h3>
+
+<p>BufferQueues 是 Android 图形组件之间的粘合剂。它们是一对队列,可以调解缓冲区从生产方到消耗方的固定周期。一旦生产方移交其缓冲区,SurfaceFlinger 便会负责将所有内容合成到显示部分。</p>
+
+<p>有关 BufferQueue 通信过程,请参见下图。</p>
+
+<img src="images/bufferqueue.png" alt="BufferQueue 通信过程"/>
+
+<p class="img-caption"><strong>图 3.</strong> BufferQueue 通信过程</p>
+
+<p>BufferQueue 包含将图像流生产方与图像流消耗方结合在一起的逻辑。图像生产方的一些示例包括由相机 HAL 或 OpenGL ES 游戏生成的相机预览。图像消耗方的一些示例包括 SurfaceFlinger 或显示 OpenGL ES 流的另一个应用,如显示相机取景器的相机应用。</p>
+
+<p>BufferQueue 是将缓冲区池与队列相结合的数据结构,它使用 Binder IPC 在进程之间传递缓冲区。生产方接口,或者您传递给想要生成图形缓冲区的某个人的内容,即是 IGraphicBufferProducer(<a href="http://developer.android.com/reference/android/graphics/SurfaceTexture.html">SurfaceTexture</a> 的一部分)。BufferQueue 通常用于渲染到 Surface,并且与 GL 消耗方及其他任务一起消耗内容。BufferQueue 可以在三种不同的模式下运行:</p>
+
+<p><em></em>类同步模式 - 默认情况下,BufferQueue 在类同步模式下运行,在该模式下,从生产方进入的每个缓冲区都在消耗方那退出。在此模式下不会舍弃任何缓冲区。如果生产方速度太快,创建缓冲区的速度比消耗缓冲区的速度更快,它将阻塞并等待可用的缓冲区。</p>
+
+<p><em></em>非阻塞模式 - BufferQueue 还可以在非阻塞模式下运行,在此类情况下,它会生成错误,而不是等待缓冲区。在此模式下也不会舍弃缓冲区。这有助于避免可能不了解图形框架的复杂依赖项的应用软件出现潜在死锁现象。</p>
+
+<p><em></em>舍弃模式 - 最后,BufferQueue 可以配置为丢弃旧缓冲区,而不是生成错误或进行等待。例如,如果对纹理视图执行 GL 渲染并尽快绘制,则必须丢弃缓冲区。</p>
+
+<p>为了执行这项工作的大部分环节,SurfaceFlinger 就像另一个 OpenGL ES 客户端一样工作。例如,当 SurfaceFlinger 正在积极地将一个缓冲区或两个缓冲区合成到第三个缓冲区中时,它使用的是 OpenGL ES。</p>
+
+<p>Hardware Composer HAL 执行另一半工作。该 HAL 充当所有 Android 图形渲染的中心点。</p>
+
+<h3 id="synchronization_framework">同步框架</h3>
+
+<p>由于 Android 图形不提供显式并行性,因此供应商一直都是在自己的驱动程序中实现自己的隐式同步。但是,Android 图形同步框架不再需要这么做。有关实现说明,请参阅<a href="/devices/graphics/implement-vsync.html#explicit_synchronization">显式同步</a>部分。</p>
+
+<p>同步框架明确描述了系统中不同异步操作之间的依赖关系。框架提供了一个简单 API,使组件在缓冲区被释放时发出信号。它还允许在从内核到用户空间的驱动程序之间以及用户空间进程本身之间传递同步基元。</p>
+
+<p>例如,应用可以将要在 GPU 中执行的工作加入队列。然后,GPU 开始绘制该图像。尽管图像尚未被绘制到内存中,但缓冲区指针仍然可以与指示 GPU 工作何时完成的栅栏一起传递到窗口合成器。然后,窗口合成器可以提前开始处理,并将工作移交给显示控制器。通过这种方式,CPU 工作可以提前完成。GPU 完成后,显示控制器就可以立即显示图像。</p>
+
+<p>同步框架还允许实现人员在自己的硬件组件中利用同步资源。最后,框架使实现人员可以查看图形管道,以帮助进行调试。</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/graphics/testing.html b/zh-cn/devices/graphics/testing.html
new file mode 100644
index 0000000..b411ba6
--- /dev/null
+++ b/zh-cn/devices/graphics/testing.html
@@ -0,0 +1,156 @@
+<html devsite><head>
+    <title>OpenGL ES 测试</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 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>AOSP 包含 drawElements 质量计划 (deqp) GPU 测试套件 (<a href="https://android.googlesource.com/platform/external/deqp">https://android.googlesource.com/platform/external/deqp</a>)。</p>
+
+<p>要采用最新提交的代码,请使用 <code>deqp-dev</code> 分支。要采用适用于特定 Android CTS 版本的代码,请使用 <code><em>release-code-name</em>-release</code> 分支(例如,如果是 Android 6.0,请使用 <code>marshmallow-release</code> 分支)。</p>
+
+<h2 id="deploying_deqp">部署 deqp</h2>
+
+<p>要将 deqp 测试套件部署到新环境中,请查看本部分的所有页面:</p>
+<ul>
+<li><a href="/devices/graphics/build-tests.html">编译测试程序</a>:讨论编译系统(例如 CMake)、目标和各种版本(Win32、Android、Linux)。</li>
+<li><a href="/devices/graphics/port-tests.html">移植测试框架</a>:说明如何调整基础可移植性库,实现测试框架平台集成界面以及移植执行服务。移植是可选的(具体取决于目标平台)。</li>
+<li><a href="/devices/graphics/run-tests.html">运行测试</a>:提供在 Linux 和 Windows 环境中运行 deqp 测试,命令行参数和 Android 软件包的相关说明。</li>
+<li><a href="/devices/graphics/automate-tests.html">自动执行测试</a>:涵盖测试自动化选项、命令行工具、CSV 和 XML 导出,以及转换为 JUnit。</li>
+<li><a href="/devices/graphics/test-groups.html">使用特殊测试组</a>:针对运行内存分配和长时间运行的压力测试提供相关建议。</li>
+<li><a href="/devices/graphics/cts-integration.html">与 Android CTS 集成</a>:说明测试的 <code>mustpass</code> 列表、重复运行以及映射 CTS 结果。</li>
+</ul>
+
+<h2 id="source_layout">源代码布局</h2>
+
+<p>deqp 测试模块和支持的库的源代码布局如下表所示(列出的内容并不全面,但突出显示了最重要的目录)。</p>
+
+<table>
+ <tbody><tr>
+   <th>目录</th>
+   <th>说明</th>
+ </tr>
+ <tr>
+    <td><code>android</code></td>
+    <td><p>Android 测试人员源代码和编译脚本</p></td>
+ </tr>
+ <tr>
+    <td><code>data</code></td>
+<td><p>测试数据文件</p>
+</td>
+ </tr>
+ <tr>
+    <td><code>modules</code></td>
+<td><p>测试模块源代码</p>
+</td>
+ </tr>
+ <tr>
+    <td><code>
+        modules/egl</code></td>
+<td><p>EGL 模块</p>
+</td>
+ </tr>
+ <tr>
+    <td><code>
+        modules/gles2</code></td>
+<td><p>GLES2 模块</p>
+</td>
+ </tr>
+ <tr>
+    <td><code>
+        modules/gles3</code></td>
+<td><p>GLES3 模块</p>
+</td>
+ </tr>
+ <tr>
+    <td><code>
+        modules/gles31</code></td>
+<td><p>GLES3.1 模块</p>
+</td>
+ </tr>
+  <tr>
+    <td><code>
+        modules/gles32</code></td>
+<td><p>GLES3.2 模块</p>
+</td>
+ </tr>
+ <tr>
+    <td><code>targets</code></td>
+<td><p>特定于目标的编译配置文件</p>
+</td>
+ </tr>
+ <tr>
+    <td><code>framework</code></td>
+<td><p>deqp 测试模块框架和实用工具</p>
+</td>
+ </tr>
+ <tr>
+    <td><code>
+        framework/delibs</code></td>
+<td><p>基础可移植性库和编译库</p>
+</td>
+ </tr>
+ <tr>
+    <td><code>
+        framework/platform</code></td>
+<td><p>平台端口</p>
+</td>
+ </tr>
+ <tr>
+    <td><code>
+        framework/qphelper</code></td>
+<td><p>测试程序集成库 (C)</p>
+</td>
+ </tr>
+ <tr>
+    <td><code>
+        framework/common</code></td>
+<td><p>Deqp 框架 (C++)</p>
+</td>
+ </tr>
+ <tr>
+    <td><code>
+        framework/opengl, framework/egl</code></td>
+<td><p>API 专用实用工具</p>
+</td>
+ </tr>
+ <tr>
+    <td><code>
+execserver</code></td>
+<td><p>设备端 ExecServer 源代码</p>
+</td>
+ </tr>
+ <tr>
+    <td><code>
+executor</code></td>
+<td><p>主机端测试执行器 shell 工具和实用工具</p>
+</td>
+ </tr>
+ <tr>
+    <td><code>
+external</code></td>
+<td><p>适用于外部库 libpng 和 zlib 的编译存根目录</p>
+</td>
+ </tr>
+</tbody></table>
+
+<h3 id="open-source_components">开放源代码组件</h3>
+
+<p>deqp 使用 <code>libpng</code> 和 <code>zlib</code>,您可以使用脚本 <a href="https://android.googlesource.com/platform/external/deqp/+/master/external/fetch_sources.py"><code>platform/external/deqp/external/fetch_sources.py</code></a> 或通过 <code>platform/external/[libpng,zlib]</code> 中的 git 获取它们。</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/input/getevent.html b/zh-cn/devices/input/getevent.html
new file mode 100644
index 0000000..e185e30
--- /dev/null
+++ b/zh-cn/devices/input/getevent.html
@@ -0,0 +1,115 @@
+<html devsite><head>
+    <title>Getevent</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 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><code>getevent</code> 工具可在设备上运行,并可提供关于输入设备和内核输入事件的实时转储的信息。</p>
+<p>此工具非常实用,可确保设备驱动程序报告各个输入设备的一系列预期功能并生成输入事件的所需信息流。</p>
+
+<h2 id="showing-device-capabilities">显示设备功能</h2>
+<p>使用带有 <code>adb</code> 命令的 <code>-p</code> 选项来查看设备报告的所有键和轴。</p>
+
+<pre class="devsite-terminal devsite-click-to-copy">adb shell su -- getevent -p</pre>
+
+<p>以下示例列出了特定键盘所支持的 Linux 键码和其他事件。</p>
+
+<pre>
+  name:     "Motorola Bluetooth Wireless Keyboard"
+  events:
+    KEY (0001): 0001  0002  0003  0004  0005  0006  0007  0008
+                0009  000a  000b  000c  000d  000e  000f  0010
+                0011  0012  0013  0014  0015  0016  0017  0018
+                0019  001a  001b  001c  001d  001e  001f  0020
+                0021  0022  0023  0024  0025  0026  0027  0028
+                0029  002a  002b  002c  002d  002e  002f  0030
+                0031  0032  0033  0034  0035  0036  0037  0038
+                0039  003a  003b  003c  003d  003e  003f  0040
+                0041  0042  0043  0044  0045  0046  0047  0048
+                0049  004a  004b  004c  004d  004e  004f  0050
+                0051  0052  0053  0055  0056  0057  0058  0059
+                005a  005b  005c  005d  005e  005f  0060  0061
+                0062  0063  0064  0066  0067  0068  0069  006a
+                006b  006c  006d  006e  006f  0071  0072  0073
+                0074  0075  0077  0079  007a  007b  007c  007d
+                007e  007f  0080  0081  0082  0083  0084  0085
+                0086  0087  0088  0089  008a  008c  008e  0090
+                0096  0098  009b  009c  009e  009f  00a1  00a3
+                00a4  00a5  00a6  00ab  00ac  00ad  00b0  00b1
+                00b2  00b3  00b4  00b7  00b8  00b9  00ba  00bb
+                00bc  00bd  00be  00bf  00c0  00c1  00c2  00d9
+                00f0  0110  0111  0112  01ba
+    REL (0002): 0000  0001  0008
+    ABS (0003): 0028  : value 223, min 0, max 255, fuzz 0, flat 0, resolution 0
+                0029  : value 0, min 0, max 255, fuzz 0, flat 0, resolution 0
+                002a  : value 0, min 0, max 255, fuzz 0, flat 0, resolution 0
+                002b  : value 0, min 0, max 255, fuzz 0, flat 0, resolution 0
+    MSC (0004): 0004
+    LED (0011): 0000  0001  0002  0003  0004
+  input props:
+    &lt;none&gt;
+</pre>
+
+<p>使用 <code>-i</code> 选项可获取更多信息,包括 HID 映射表和调试信息。</p>
+
+<p>使用 <code>-l</code> 选项可显示所有事件代码的文字标签。</p>
+<pre class="devsite-terminal devsite-click-to-copy">
+adb shell su -- getevent -lp /dev/input/event1
+</pre>
+<p>示例:</p>
+<pre>
+  name:     "Melfas MMSxxx Touchscreen"
+  events:
+    ABS (0003): ABS_MT_SLOT           : value 0, min 0, max 9, fuzz 0, flat 0, resolution 0
+                ABS_MT_TOUCH_MAJOR    : value 0, min 0, max 30, fuzz 0, flat 0, resolution 0
+                ABS_MT_POSITION_X     : value 0, min 0, max 720, fuzz 0, flat 0, resolution 0
+                ABS_MT_POSITION_Y     : value 0, min 0, max 1280, fuzz 0, flat 0, resolution 0
+                ABS_MT_TRACKING_ID    : value 0, min 0, max 65535, fuzz 0, flat 0, resolution 0
+                ABS_MT_PRESSURE       : value 0, min 0, max 255, fuzz 0, flat 0, resolution 0
+  input props:
+    INPUT_PROP_DIRECT
+</pre>
+<h2 id="showing-live-events">显示实时事件</h2>
+<p>以下示例显示了使用 Linux 多点触控输入协议“B”的触摸屏的双指多点触控手势。<code>-l</code> 选项可显示文字标签,而 <code>-t</code> 选项则可显示时间戳。</p>
+
+<pre class="devsite-terminal devsite-click-to-copy">
+adb shell su -- getevent -lt /dev/input/event1
+</pre>
+
+<p>示例:</p>
+<pre>
+[   78826.389007] EV_ABS       ABS_MT_TRACKING_ID   0000001f
+[   78826.389038] EV_ABS       ABS_MT_PRESSURE      000000ab
+[   78826.389038] EV_ABS       ABS_MT_POSITION_X    000000ab
+[   78826.389068] EV_ABS       ABS_MT_POSITION_Y    0000025b
+[   78826.389068] EV_ABS       ABS_MT_SLOT          00000001
+[   78826.389068] EV_ABS       ABS_MT_TRACKING_ID   00000020
+[   78826.389068] EV_ABS       ABS_MT_PRESSURE      000000b9
+[   78826.389099] EV_ABS       ABS_MT_POSITION_X    0000019e
+[   78826.389099] EV_ABS       ABS_MT_POSITION_Y    00000361
+[   78826.389099] EV_SYN       SYN_REPORT           00000000
+[   78826.468688] EV_ABS       ABS_MT_SLOT          00000000
+[   78826.468688] EV_ABS       ABS_MT_TRACKING_ID   ffffffff
+[   78826.468719] EV_ABS       ABS_MT_SLOT          00000001
+[   78826.468719] EV_ABS       ABS_MT_TRACKING_ID   ffffffff
+[   78826.468719] EV_SYN       SYN_REPORT           00000000
+</pre>
+<p class="note"><strong>注意</strong>:<code>getevent</code> 时间戳使用 CLOCK_MONOTONIC 时基中的 $SECONDS.$MICROSECONDS 格式。有关详情,请参阅 getevent.c。</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/input/index.html b/zh-cn/devices/input/index.html
new file mode 100644
index 0000000..f1612d9
--- /dev/null
+++ b/zh-cn/devices/input/index.html
@@ -0,0 +1,27 @@
+<html devsite><head>
+    <title>输入设备技术信息</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 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.
+  -->
+
+<img style="float: right; margin: 0px 135px 15px 15px;" src="images/ape_fwk_hal_input.png" alt="Android 输入 HAL 图标"/>
+
+<p>Android 输入子系统支持各种不同类型的设备,包括键盘、操纵杆、轨迹球、鼠标和触摸屏。本部分的文档介绍了如何为输入设备配置、校准、测试和编写驱动程序。</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/input/input-device-configuration-files.html b/zh-cn/devices/input/input-device-configuration-files.html
new file mode 100644
index 0000000..e84e2b3
--- /dev/null
+++ b/zh-cn/devices/input/input-device-configuration-files.html
@@ -0,0 +1,98 @@
+<html devsite><head>
+    <title>输入设备配置文件</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 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>输入设备配置文件(<code>.idc</code> 文件)包含特定设备的配置属性,这些属性会影响输入设备的行为。</p>
+<p>输入设备配置文件通常并非标准外围设备(例如 HID 键盘和鼠标)所必需的,因为默认的系统行为通常可确保它们开箱即用。另一方面,内置的嵌入式设备(尤其是触摸屏)几乎总是需要输入设备配置文件来指定其行为。</p>
+<h2 id="rationale">基本原理</h2>
+<p>根据关联的 Linux 内核输入设备驱动程序报告的事件类型和属性,Android 会自动检测和配置大多数输入设备功能。</p>
+<p>例如,如果输入设备支持 <code>EV_REL</code> 事件类型、代码 <code>REL_X</code> 和 <code>REL_Y</code> 以及 <code>EV_KEY</code> 事件类型和 <code>BTN_MOUSE</code>,则 Android 会将输入设备归类为鼠标。鼠标的默认行为是在屏幕上显示光标,光标跟踪鼠标的移动并在鼠标被点击时模拟触摸操作。虽然可以通过不同的方式配置鼠标,但是默认行为通常足以用于标准的鼠标外围设备。</p>
+<p>某些类别的输入设备更加模糊。例如,多点触摸屏和触摸板都至少支持 <code>EV_ABS</code> 事件类型以及代码 <code>ABS_MT_POSITION_X</code> 和 <code>ABS_MT_POSITION_Y</code>。不过,这些设备的主要用途千差万别,无法总能自动确定。此外,还需要其他信息才能了解触摸设备报告的压力和大小信息。因此,触摸设备(尤其是内置触摸屏)通常都需要 IDC 文件。</p>
+<h2 id="location">位置</h2>
+<p>输入设备配置文件由 USB 供应商、产品(及可选版本)ID 或输入设备名称定位。</p>
+<p>按顺序查阅以下路径。</p>
+<ul>
+<li><code>/system/usr/idc/Vendor_XXXX_Product_XXXX_Version_XXXX.idc</code></li>
+<li><code>/system/usr/idc/Vendor_XXXX_Product_XXXX.idc</code></li>
+<li><code>/system/usr/idc/DEVICE_NAME.idc</code></li>
+<li><code>/data/system/devices/idc/Vendor_XXXX_Product_XXXX_Version_XXXX.idc</code></li>
+<li><code>/data/system/devices/idc/Vendor_XXXX_Product_XXXX.idc</code></li>
+<li><code>/data/system/devices/idc/DEVICE_NAME.idc</code></li>
+</ul>
+<p>当构建包含设备名称的文件路径时,设备名称中除“0-9”、“a-z”、“A-Z”、“-”或“_”之外的所有字符将替换为“_”。</p>
+<h2 id="syntax">句法</h2>
+<p>输入设备配置文件是由属性分配和注释组成的纯文本文件。</p>
+<h3 id="properties">属性</h3>
+<p>属性分配均由属性名称、<code>=</code>、属性值和新行组成。例如:</p>
+<pre class="devsite-click-to-copy">
+property = value
+</pre>
+<p>属性名称为非空的文字文本标识符,不能包含空格。输入系统的每个组件都定义一组用于配置其功能的属性。</p>
+<p>属性值为非空字符串文字、整数或浮点数。不能包含空格或保留字符 <code>\</code> 或 <code>"</code>。</p>
+<p>属性名称和值区分大小写。</p>
+<h3 id="comments">注释</h3>
+<p>注释行以“#”开头,并持续到这一行的结束。例如:</p>
+<pre class="devsite-click-to-copy">
+# A comment!
+</pre>
+<p>空白行会被忽略。</p>
+<h3 id="example">示例</h3>
+<pre class="devsite-click-to-copy">
+# This is an example of an input device configuration file.
+# It might be used to describe the characteristics of a built-in touch screen.
+
+# This is an internal device, not an external peripheral attached to the USB
+# or Bluetooth bus.
+device.internal = 1
+
+# The device should behave as a touch screen, which uses the same orientation
+# as the built-in display.
+touch.deviceType = touchScreen
+touch.orientationAware = 1
+
+# Additional calibration properties...
+# etc...
+</pre>
+<h2 id="common-properties">通用属性</h2>
+<p>以下属性在所有输入设备类之间通用。</p>
+<p>如需了解每个类所使用的特殊属性,请参阅各个输入设备类的文档。</p>
+<h4 id="deviceinternal"><code>device.internal</code></h4>
+<p>定义:<code>device.internal</code> = <code>0</code> | <code>1</code><em></em></p>
+<p>指定输入设备属于内置组件,还是外部连接(很可能可拆卸)的外围设备。</p>
+<ul>
+<li>
+<p>如果值为 <code>0</code>,则该设备为外部设备。</p>
+</li>
+<li>
+<p>如果值为 <code>1</code>,则该设备为内部设备。</p>
+</li>
+<li>
+<p>如果该值未指定,则 USB (BUS_USB) 或蓝牙 (BUS_BLUETOOTH) 总线上的所有设备的默认值均为 <code>0</code>,否则,值为 <code>1</code>。</p>
+</li>
+</ul>
+<p>该属性决定有关唤醒事件的默认策略决定。</p>
+<p>内部输入设备一般不从休眠状态中唤醒显示屏,除非关键布局文件或硬编码的策略规则中明确进行了相应配置。这种区别可防止按键和触摸意外唤醒您口袋中的手机。通常只定义几个唤醒键。</p>
+<p>相反,外部输入设备通常会更主动地唤醒设备,因为它们在传输过程中被假定为关闭或未插入。例如,按下外部键盘上的任何一个键就能很好地说明用户希望唤醒设备并得到响应。</p>
+<p>务必确保所有内部输入设备 <code>device.internal</code> 属性的值都得到正确设置。</p>
+<h2 id="validation">验证</h2>
+<p>确保使用<a href="validate-keymaps.html">验证按键映射</a>工具验证您的输入设备配置文件。</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/input/key-character-map-files.html b/zh-cn/devices/input/key-character-map-files.html
new file mode 100644
index 0000000..212a24d
--- /dev/null
+++ b/zh-cn/devices/input/key-character-map-files.html
@@ -0,0 +1,334 @@
+<html devsite><head>
+    <title>按键字符映射文件</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 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>按键字符映射文件(<code>.kcm</code> 文件)负责将 Android 按键代码与修饰符的组合映射到 Unicode 字符。</p>
+<p>如果只是告诉系统该设备仅用于特殊用途(非全键盘),那么对于具有按键的所有内部(内置)输入设备,特定于设备的按键布局文件必不可少<em></em>。</p>
+<p>对于外部键盘,特定于设备的按键布局文件为<em></em>可选项,并且通常根本不需要。系统会提供适用于许多外部键盘的通用按键字符映射。</p>
+<p>如果没有提供特定于设备的按键布局文件,系统将选择默认按键布局文件。</p>
+<h2 id="location">位置</h2>
+<p>按键字符映射文件可以通过 USB 供应商、产品(和可选版本)ID 或输入设备名称进行定位。</p>
+<p>按上述顺序查阅以下路径。</p>
+<ul>
+<li><code>/system/usr/keychars/Vendor_XXXX_Product_XXXX_Version_XXXX.kcm</code></li>
+<li><code>/system/usr/keychars/Vendor_XXXX_Product_XXXX.kcm</code></li>
+<li><code>/system/usr/keychars/DEVICE_NAME.kcm</code></li>
+<li><code>/data/system/devices/keychars/Vendor_XXXX_Product_XXXX_Version_XXXX.kcm</code></li>
+<li><code>/data/system/devices/keychars/Vendor_XXXX_Product_XXXX.kcm</code></li>
+<li><code>/data/system/devices/keychars/DEVICE_NAME.kcm</code></li>
+<li><code>/system/usr/keychars/Generic.kcm</code></li>
+<li><code>/data/system/devices/keychars/Generic.kcm</code></li>
+<li><code>/system/usr/keychars/Virtual.kcm</code></li>
+<li><code>/data/system/devices/keychars/Virtual.kcm</code></li>
+</ul>
+<p>当构建包含设备名称的文件路径时,设备名称中除“0-9”、“a-z”、“A-Z”、“-”或“_”之外的所有字符都会被替换为“_”。</p>
+<h2 id="generic-key-character-map-file">通用按键字符映射文件</h2>
+<p>系统会提供一个名为 <code>Generic.kcm</code> 的特殊内置按键字符映射文件。此按键字符映射旨在支持各种标准外部键盘。</p>
+<p><em>请勿修改通用按键字符映射!</em></p>
+<h2 id="virtual-key-character-map-file">虚拟按键字符映射文件</h2>
+<p>系统会提供一个名为 <code>Virtual.kcm</code> 的特殊内置按键字符映射文件,供虚拟键盘设备使用。</p>
+<p>虚拟键盘设备属于合成输入设备,其 ID 为 -1(请见 <code>KeyCharacterMap.VIRTUAL_KEYBOARD</code>)。从 Android Honeycomb 3.0 开始,它在所有 Android 设备上都有提供。虚拟键盘设备的目的是提供一种已知的内置输入设备,它可用于通过 IME 或测试仪器将按键注入到应用中,即使设备没有内置键盘也是如此。</p>
+<p>假设虚拟键盘在所有设备上具有相同的完整 QWERTY 布局。这样一来,应用可以使用虚拟键盘设备注入按键,并始终得到相同的结果。</p>
+<p><em>请勿修改虚拟按键字符映射!</em></p>
+<h2 id="syntax">语法</h2>
+<p>按键字符映射文件是由键盘类型声明和一组按键声明组成的纯文本文件。</p>
+<h3 id="keyboard-type-declaration">键盘类型声明</h3>
+<p>键盘类型声明描述了键盘的整体行为。字符映射文件必须包含键盘类型声明。为了清楚起见,声明通常放置在文件的顶部。</p>
+<pre class="devsite-click-to-copy">
+type FULL
+</pre>
+<p>将识别以下键盘类型:</p>
+<ul>
+<li>
+<p><code>NUMERIC</code>:数字(12 键)键盘。</p>
+<p>数字键盘支持使用多次击键方式输入文本。可能需要多次敲击键,才能生成所需的字母或符号。</p>
+<p>这种类型的键盘通常设计为用拇指打字。</p>
+<p>对应于 <code>KeyCharacterMap.NUMERIC</code>。</p>
+</li>
+<li>
+<p><code>PREDICTIVE</code>:一种具有所有字母的键盘,但每个键有多个字母。</p>
+<p>这种类型的键盘通常设计为用拇指打字。</p>
+<p>对应于 <code>KeyCharacterMap.PREDICTIVE</code>。</p>
+</li>
+<li>
+<p><code>ALPHA</code>:一种具有所有字母的键盘,并且可能还带有一些数字。</p>
+<p>字母键盘支持文本直接输入,但由于尺寸小,因此布局可能会很紧凑。与 <code>FULL</code> 键盘相比,一些符号只能使用特殊的屏幕字符选择器才能输入。此外,为了提高打字速度和准确性,框架为字母键盘提供了特殊的功能,如自动首字母大写和切换/锁定 SHIFT 和 ALT 键。</p>
+<p>这种类型的键盘通常设计为用拇指打字。</p>
+</li>
+<li>
+<p><code>FULL</code>:一种 PC 式全键盘。</p>
+<p>全键盘的用法类似于 PC 的键盘。通过按键盘上的键可以直接输入所有符号,无需屏幕支持或诸如自动首字母大写等直观功能。</p>
+<p>这种类型的键盘通常设计为用双手打字。</p>
+</li>
+<li>
+<p><code>SPECIAL_FUNCTION</code>:一种仅用于执行系统控制功能(而非打字)的键盘。</p>
+<p>特殊功能键盘仅由非实际用于打字的非打印键(如 HOME 和 POWER )组成。</p>
+</li>
+</ul>
+<p><code>Generic.kcm</code> 和 <code>Virtual.kcm</code> 按键字符映射都是 <code>FULL</code> 键盘。</p>
+<h3 id="key-declarations">按键声明</h3>
+<p>按键声明包括关键字 <code>key</code>,后跟 Android 按键代码名称、左大括号、一组属性和行为以及一个右大括号。</p>
+<pre class="devsite-click-to-copy">
+key A {
+    label:                              'A'
+    base:                               'a'
+    shift, capslock:                    'A'
+    ctrl, alt, meta:                    none
+}
+</pre>
+<h4 id="properties">属性</h4>
+<p>每个按键属性都会建立从按键到行为的映射。为了使按键字符映射文件更加紧凑,可以将多个属性(用逗号分隔)映射到同一个行为。</p>
+<p>在上面的例子中,<code>label</code> 属性被分配了 <code>'A'</code> 行为。同样,<code>ctrl</code>、<code>alt</code> 和 <code>meta</code> 属性同时被分配了 <code>none</code> 行为。</p>
+<p>将识别以下属性:</p>
+<ul>
+<li>
+<p><code>label</code>:当按键包含一个字符时,指定物理打印在该按键上的标签。这是 <code>KeyCharacterMap.getDisplayLabel</code> 方法返回的值。</p>
+</li>
+<li>
+<p><code>number</code>:指定数字文本视图具有焦点时的行为(即应该输入的字符),例如用户在输入电话号码时。</p>
+<p>紧凑型键盘通常会将多个符号组合到一个按键上,这样可能会使用相同的键来输入 <code>'1'</code> 和 <code>'a'</code> 或者 <code>'#'</code> 和 <code>'q'</code>。对于这些键,应设置 <code>number</code> 属性,以指示在数字上下文中应输入的符号(如果有)。</p>
+<p>一些典型的“数字”符号为数字 <code>'0'</code> 到 <code>'9'</code>、<code>'#'</code>、<code>'+'</code>、<code>'('</code>、<code>')'</code>、<code>','</code> 和 <code>'.'</code>。</p>
+</li>
+<li>
+<p><code>base</code>:指定在没有按下修饰符时的行为(即应该输入的字符)。</p>
+</li>
+<li>
+<p>&lt;modifier&gt; 或 &lt;modifier1&gt;<code>+</code>&lt;modifier2&gt;<code>+</code>…:指定在按下按键并且所有指定的修饰符处于活动状态时的行为(即应该输入的字符)。</p>
+<p>例如,修饰符属性 <code>shift</code> 指定了在按下 LEFT SHIFT 或 RIGHT SHIFT 修饰符时会应用的行为。</p>
+<p>同样,修饰符属性 <code>rshift+ralt</code> 指定了在同时按下 RIGHT SHIFT 和 RIGHT ALT 修饰符时会应用的行为。</p>
+</li>
+</ul>
+<p>将在修饰符属性中识别以下修饰符:</p>
+<ul>
+<li><code>shift</code>:在按下 LEFT SHIFT 或 RIGHT SHIFT 修饰符时应用。</li>
+<li><code>lshift</code>:在按下 LEFT SHIFT 修饰符时应用。</li>
+<li><code>rshift</code>:在按下 RIGHT SHIFT 修饰符时应用。</li>
+<li><code>alt</code>:在按下 LEFT ALT 或 RIGHT ALT 修饰符时应用。</li>
+<li><code>lalt</code>:在按下 LEFT ALT 修饰符时应用。</li>
+<li><code>ralt</code>:在按下 RIGHT ALT 修饰符时应用。</li>
+<li><code>ctrl</code>:在按下 LEFT CONTROL 或 RIGHT CONTROL 修饰符时应用。</li>
+<li><code>lctrl</code>:在按下 LEFT CONTROL 修饰符时应用。</li>
+<li><code>rctrl</code>:在按下 RIGHT CONTROL 修饰符时应用。</li>
+<li><code>meta</code>:在按下 LEFT META 或 RIGHT META 修饰符时应用。</li>
+<li><code>lmeta</code>:在按下 LEFT META 修饰符时应用。</li>
+<li><code>rmeta</code>:在按下 RIGHT META 修饰符时应用。</li>
+<li><code>sym</code>:在按下 SYMBOL 修饰符时应用。</li>
+<li><code>fn</code>:在按下 FUNCTION 修饰符时应用。</li>
+<li><code>capslock</code>:在 CAPS LOCK 修饰符被锁定时应用。</li>
+<li><code>numlock</code>:在 NUM LOCK 修饰符被锁定时应用。</li>
+<li><code>scrolllock</code>:在 SCROLL LOCK 修饰符被锁定时应用。</li>
+</ul>
+<p>属性的列出顺序很重要。在将按键映射到行为时,系统会按顺序扫描所有相关属性,并返回找到的最后一个适用行为。</p>
+<p>因此,对于给定按键,后面指定的属性会替换前面指定的属性。</p>
+<h4 id="behaviors">行为</h4>
+<p>每个属性都会映射到一个行为。最常见的行为是输入字符,但还有其他行为。</p>
+<p>将识别以下行为:</p>
+<ul>
+<li>
+<p><code>none</code>:不输入字符。</p>
+<p>当没有指定字符时,此行为是默认行为。虽然指定 <code>none</code> 不是必需的,但它可以提高明确性。</p>
+</li>
+<li>
+<p><code>'X'</code>:输入指定的字符文字。</p>
+<p>此行为会使指定的字符输入到聚焦的文本视图中。字符文字可以是任何 ASCII 字符,也可以是以下转义序列之一:</p>
+<ul>
+<li><code>'\\'</code>:输入反斜杠字符。</li>
+<li><code>'\n'</code>:输入新行字符(用于 ENTER/RETURN)。</li>
+<li><code>'\t'</code>:输入 TAB 字符。</li>
+<li><code>'\''</code>:输入撇号字符。</li>
+<li><code>'\"'</code>:输入引号字符。</li>
+<li><code>'\uXXXX'</code>:按照 XXXX 格式输入以十六进制形式提供代码点的 Unicode 字符。</li>
+</ul>
+</li>
+<li>
+<p><code>fallback</code> &lt;Android 按键代码名称&gt;:如果应用未处理该按键,则执行默认操作。</p>
+<p>当应用本身不处理指定的按键时,此行为会导致系统模拟不同的按键。它用于支持并非所有应用都知道如何处理的新按键的默认行为,例如 ESCAPE 或数字小键盘按键(在未按下 numlock 时)。</p>
+<p>当执行回退行为时,应用将收到两个按键:一个用于原始键,另一个用于所选的回退键。如果应用在松开按键期间处理原始键,则后退键事件将被取消(<code>KeyEvent.isCanceled</code> 将返回 <code>true</code>)。</p>
+</li>
+</ul>
+<p>系统保留两个 Unicode 字符来执行特殊功能:</p>
+<ul>
+<li>
+<p><code>'\uef00'</code>:执行此行为时,文本视图将使用并删除光标前的四个字符,将其解释为十六进制数字,并插入相应的 Unicode 代码点。</p>
+</li>
+<li>
+<p><code>'\uef01'</code>:执行此行为时,文本视图显示包含杂项符号的字符选择器对话框。</p>
+</li>
+</ul>
+<p>系统将以下 Unicode 字符识别为组合变音静键字符:</p>
+<ul>
+<li><code>'\u0300'</code>:重音符号。</li>
+<li><code>'\u0301'</code>:尖音符号。</li>
+<li><code>'\u0302'</code>:抑扬音符号。</li>
+<li><code>'\u0303'</code>:腭化音符号。</li>
+<li><code>'\u0308'</code>:元音变音符号。</li>
+</ul>
+<p>如果在输入静键时后跟另一个字符,则该静键和后面的字符将组合在一起。例如,如果用户在输入重音符号静键时后跟字母“a”,那么输出结果为“à”。</p>
+<p>请参见 <code>KeyCharacterMap.getDeadChar</code>,了解有关静键处理的详细信息。</p>
+<h3 id="comments">注释</h3>
+<p>注释行以“#”开头,并持续到这一行的结束。示例如下:</p>
+<pre class="devsite-click-to-copy">
+# A comment!
+</pre>
+<p>空白行会被忽略。</p>
+<h3 id="how-key-combinations-are-mapped-to-behaviors">如何将按键组合映射到行为</h3>
+<p>当用户按下某个键时,系统会查找与该按键组合和当前按下的修饰符关联的行为。</p>
+<h4 id="shift-a">SHIFT + A</h4>
+<p>假设用户一起按下 A 和 SHIFT。系统会首先查找与 <code>KEYCODE_A</code> 关联的一组属性和行为。</p>
+<pre class="devsite-click-to-copy">
+key A {
+    label:                              'A'
+    base:                               'a'
+    shift, capslock:                    'A'
+    ctrl, alt, meta:                    none
+}
+</pre>
+<p>系统按从头到尾、从左到右的顺序扫描属性,但会忽略 <code>label</code> 和 <code>number</code> 这两个特殊属性。</p>
+<p>遇到的第一个属性是 <code>base</code>。无论按哪个修饰符,<code>base</code> 属性始终会应用于按键。它主要是指定按键的默认行为,除非它被后续属性所替换。由于 <code>base</code> 属性会应用于此按键,因此系统会记录其行为为 <code>'a'</code>(输入字符 <code>a</code>)的事实。</p>
+<p>系统继续扫描后续属性,如果其中出现任何比 <code>base</code> 更具体的属性,则会进行替换。这时,系统遇到也会应用于按键 SHIFT + A 的 <code>shift</code>。因此,系统决定忽略 <code>base</code> 属性的行为,并选择与 <code>shift</code> 属性关联的行为,即 <code>'A'</code>(输入字符 <code>A</code>)。</p>
+<p>系统继续扫描上述表格,但是没有其他属性会应用于此按键(CAPS LOCK 未锁定,CONTROL 键、ALT 键和 META 键均未按下)。</p>
+<p>因此,按键组合 SHIFT + A 生成的行为是 <code>'A'</code>。</p>
+<h4 id="control-a">CONTROL + A</h4>
+<p>现在考虑一下,如果用户一起按下 A 和 CONTROL 将会发生什么。</p>
+<p>如前所述,系统将扫描属性表。系统会注意到应用的 <code>base</code> 属性,但仍将继续扫描,直到它最终达到 <code>control</code> 属性。恰巧的是,<code>control</code> 属性出现在 <code>base</code> 之后,因此其行为会替换 <code>base</code> 行为。</p>
+<p>因此,CONTROL + A 组合键生成的行为是 <code>none</code>。</p>
+<h4 id="escape">ESCAPE</h4>
+<p>现在假设用户按下 ESCAPE。</p>
+<pre class="devsite-click-to-copy">
+key ESCAPE {
+    base:                               fallback BACK
+    alt, meta:                          fallback HOME
+    ctrl:                               fallback MENU
+}
+</pre>
+<p>这次系统获得行为 <code>fallback BACK</code>,这是一种回退行为。因为没有字符文字出现,所以不会输入字符。</p>
+<p>处理按键时,系统将首先向应用传递 <code>KEYCODE_ESCAPE</code>。如果应用未处理它,系统将再次尝试,但这次它将按照回退行为的要求向应用传递 <code>KEYCODE_BACK</code>。</p>
+<p>因此,识别和支持 <code>KEYCODE_ESCAPE</code> 的应用有机会按原样处理它,但是其他应用不能替代执行处理该键的回退操作,就像它是 <code>KEYCODE_BACK</code> 一样。</p>
+<h4 id="numpad_0-with-or-without-num-lock">带有或不带 NUM LOCK 的 NUMPAD_0</h4>
+<p>根据 NUM LOCK 键是否被锁定,数字小键盘键的解释大有不同。</p>
+<p>以下按键声明会确保,在按下 NUM LOCK 键时,<code>KEYCODE_NUMPAD_0</code> 输入 <code>0</code>。在未按下 NUM LOCK 键时,会照常将按键传递给应用,如果没有处理它,则会传递回退键 <code>KEYCODE_INSERT</code>。</p>
+<pre class="devsite-click-to-copy">
+key NUMPAD_0 {
+    label, number:                      '0'
+    base:                               fallback INSERT
+    numlock:                            '0'
+    ctrl, alt, meta:                    none
+}
+</pre>
+<p>如我们所见,回退键声明大大提高了与不能识别或直接支持 PC 式全键盘上存在的所有按键的旧应用的兼容性。</p>
+<h3 id="examples">示例</h3>
+<h4 id="full-keyboard">全键盘</h4>
+<pre class="devsite-click-to-copy">
+# This is an example of part of a key character map file for a full keyboard
+# include a few fallback behaviors for special keys that few applications
+# handle themselves.
+
+type FULL
+
+key C {
+    label:                              'C'
+    base:                               'c'
+    shift, capslock:                    'C'
+    alt:                                '\u00e7'
+    shift+alt:                          '\u00c7'
+    ctrl, meta:                         none
+}
+
+key SPACE {
+    label:                              ' '
+    base:                               ' '
+    ctrl:                               none
+    alt, meta:                          fallback SEARCH
+}
+
+key NUMPAD_9 {
+    label, number:                      '9'
+    base:                               fallback PAGE_UP
+    numlock:                            '9'
+    ctrl, alt, meta:                    none
+}
+</pre>
+<h4 id="alphanumeric-keyboard">字母数字键盘</h4>
+<pre class="devsite-click-to-copy">
+# This is an example of part of a key character map file for an alphanumeric
+# thumb keyboard.  Some keys are combined, such as `A` and `2`.  Here we
+# specify `number` labels to tell the system what to do when the user is
+# typing a number into a dial pad.
+#
+# Also note the special character '\uef01' mapped to ALT+SPACE.
+# Pressing this combination of keys invokes an on-screen character picker.
+
+type ALPHA
+
+key A {
+    label:                              'A'
+    number:                             '2'
+    base:                               'a'
+    shift, capslock:                    'A'
+    alt:                                '#'
+    shift+alt, capslock+alt:            none
+}
+
+key SPACE {
+    label:                              ' '
+    number:                             ' '
+    base:                               ' '
+    shift:                              ' '
+    alt:                                '\uef01'
+    shift+alt:                          '\uef01'
+}
+</pre>
+<h4 id="game-pad">游戏手柄</h4>
+<pre class="devsite-click-to-copy">
+# This is an example of part of a key character map file for a game pad.
+# It defines fallback actions that enable the user to navigate the user interface
+# by pressing buttons.
+
+type SPECIAL_FUNCTION
+
+key BUTTON_A {
+    base:                               fallback BACK
+}
+
+key BUTTON_X {
+    base:                               fallback DPAD_CENTER
+}
+
+key BUTTON_START {
+    base:                               fallback HOME
+}
+
+key BUTTON_SELECT {
+    base:                               fallback MENU
+}
+</pre>
+<h2 id="compatibility-note">兼容性说明</h2>
+<p>在 Android Honeycomb 3.0 之前,Android 按键字符映射是使用截然不同的语法进行指定,并在构建时被编译成二进制文件格式 (<code>.kcm.bin</code>)。</p>
+<p>虽然新格式使用相同的扩展名 <code>.kcm</code>,但语法完全不同(而且更强大)。</p>
+<p>从 Android Honeycomb 3.0 开始,所有 Android 按键字符映射文件必须使用本文档中描述的新语法和纯文本文件格式。旧语法不受支持,并且系统不会识别旧 <code>.kcm.bin</code> 文件。</p>
+<h2 id="language-note">语言说明</h2>
+<p>Android 目前不支持多语言键盘。此外,内置的通用按键字符映射采用美式英文键盘布局。</p>
+<p>如果是为其他语言设计键盘,我们建议原始设备制造商 (OEM) 为其键盘提供自定义按键字符映射。</p>
+<p>未来版本的 Android 可能会为多语言键盘或用户可选型键盘布局提供更好的支持。</p>
+<h2 id="validation">验证</h2>
+<p>请务必使用<a href="validate-keymaps.html">验证按键映射</a>工具验证您的按键字符映射文件。</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/input/key-layout-files.html b/zh-cn/devices/input/key-layout-files.html
new file mode 100644
index 0000000..f942ebc
--- /dev/null
+++ b/zh-cn/devices/input/key-layout-files.html
@@ -0,0 +1,232 @@
+<html devsite><head>
+    <title>按键布局文件</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 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>按键布局文件(<code>.kl</code> 文件)将 Linux 按键代码和坐标轴代码映射到 Android 按键代码和坐标轴代码,并指定相关的策略标记。设备专属按键布局文件:</p>
+<ul>
+<li>对具有按键(包括音量、电源和耳机媒体按键等特殊按键)的内部(内置)输入设备而言是必要文件。<em></em></li>
+<li>对其他输入设备而言是可选文件,而对特殊用途的键盘和操纵杆而言则是推荐文件。<em></em><em></em></li>
+</ul>
+<p>如果没有可用的设备专属按键布局文件,则系统将改选默认文件。</p>
+
+<h2 id="location">位置</h2>
+<p>按键布局文件由 USB 供应商、产品(可能还包括版本)ID 或输入设备名称来确定位置。系统会按顺序查阅以下路径:</p>
+<ul>
+<li><code>/system/usr/keylayout/Vendor_XXXX_Product_XXXX_Version_XXXX.kl</code></li>
+<li><code>/system/usr/keylayout/Vendor_XXXX_Product_XXXX.kl</code></li>
+<li><code>/system/usr/keylayout/DEVICE_NAME.kl</code></li>
+<li><code>/data/system/devices/keylayout/Vendor_XXXX_Product_XXXX_Version_XXXX.kl</code></li>
+<li><code>/data/system/devices/keylayout/Vendor_XXXX_Product_XXXX.kl</code></li>
+<li><code>/data/system/devices/keylayout/DEVICE_NAME.kl</code></li>
+<li><code>/system/usr/keylayout/Generic.kl</code></li>
+<li><code>/data/system/devices/keylayout/Generic.kl</code></li>
+</ul>
+<p>当构建包含设备名称的文件路径时,设备名称中除“0-9”、“a-z”、“A-Z”、“-”或“_”之外的所有字符将替换为“_”。</p>
+
+<h2 id="generic-key-layout-file">常规按键布局文件</h2>
+<p>系统提供了一个特殊的内置常规按键布局文件,名为 <code>Generic.kl</code>。此按键布局旨在支持各种标准外部键盘和操纵杆。<strong>请勿修改常规按键布局!</strong></p>
+
+<h2 id="syntax">语法</h2>
+<p>按键布局文件是由按键或坐标轴声明和标记组成的纯文本文件。</p>
+
+<h3 id="key-declarations">按键声明</h3>
+<p>按键声明包含关键字 <code>key</code>(后跟一个 Linux 按键代码编号和 Android 按键代码名称),或该关键字的用途(后跟 HID 用途和 Android 按键代码名称)。HID 用途由 32 位整数表示,其中高 16 位表示 HID 用途页面,低 16 位表示 HID 用途 ID。任何一项声明都可以后跟一组由空格分隔的可选策略标记。</p>
+<pre class="devsite-click-to-copy">
+key 1     ESCAPE
+key 114   VOLUME_DOWN
+key 16    Q                 VIRTUAL
+key usage 0x0c006F          BRIGHTNESS_UP
+</pre>
+<p>可识别以下策略标记:</p>
+<ul>
+<li><code>FUNCTION</code>:按键应解读为如同也按下了 FUNCTION 键。</li>
+<li><code>GESTURE</code>:按键由用户手势(例如手掌摸触摸屏)生成。</li>
+<li><code>VIRTUAL</code>:按键是与主触摸屏相邻的虚拟软键(电容式按钮)。这会导致启用特殊的去抖动逻辑(请参阅下文)。</li>
+</ul>
+
+<h3 id="axis-declarations">坐标轴声明</h3>
+<p>每个坐标轴声明都包含关键字 <code>axis</code>,后跟一个 Linux 坐标轴代码编号和限定符,用于控制坐标轴(包括至少一个 Android 坐标轴代码名称)的行为。</p>
+
+<h4 id="basic-axes">基本坐标轴</h4>
+<p>基本坐标轴仅会将 Linux 坐标轴代码映射到 Android 坐标轴代码名称。以下声明将 <code>ABS_X</code>(由 <code>0x00</code> 表示)映射到 <code>AXIS_X</code>(由 <code>X</code> 表示)。</p>
+<pre class="devsite-click-to-copy">
+axis 0x00 X
+</pre>
+<p>在上述示例中,如果 <code>ABS_X</code> 值为 <code>5</code>,则 <code>AXIS_X</code> 设置为 <code>5</code>。</p>
+
+<h4 id="split-axes">分轴</h4>
+<p>分轴将一个 Linux 坐标轴代码映射到两个 Android 坐标轴代码名称,以便小于或大于阈值的值在映射时可以分割到两个不同的坐标轴。当设备报告的单个物理轴对两个不同的互斥逻辑轴进行编码时,此映射非常有用。</p>
+<p>当 <code>ABS_Y</code> 轴的值(由 <code>0x01</code> 表示)小于 <code>0x7f</code> 时,以下声明会将其映射到 <code>AXIS_GAS</code>;当该值大于 <code>0x7f</code> 时,则会将其映射到 <code>AXIS_BRAKE</code>。</p>
+<pre class="devsite-click-to-copy">
+axis 0x01 split 0x7f GAS BRAKE</pre>
+<p>在上述示例中,如果 <code>ABS_Y</code> 的值为 <code>0x7d</code>,则 <code>AXIS_GAS</code> 设为 <code>2</code> (<code>0x7f - 0x7d</code>),并且 <code>AXIS_BRAKE</code> 设为 <code>0</code>。相反,如果 <code>ABS_Y</code> 的值为 <code>0x83</code>,则 <code>AXIS_GAS</code> 设为 <code>0</code>,并且 <code>AXIS_BRAKE</code> 设为 <code>4</code> (<code>0x83 - 0x7f</code>)。最后,如果 <code>ABS_Y</code> 的值等于 <code>0x7f</code> 的分值,则 <code>AXIS_GAS</code> 和 <code>AXIS_BRAKE</code> 均设为 <code>0</code>。</p>
+
+<h4 id="inverted-axes">反转坐标轴</h4>
+<p>反转坐标轴会反转坐标轴值的符号。以下声明将 <code>ABS_RZ</code>(由 <code>0x05</code> 表示)映射到 <code>AXIS_BRAKE</code>(由 <code>BRAKE</code> 表示),并通过求补来反转输出。</p>
+<pre class="devsite-click-to-copy">
+axis 0x05 invert BRAKE
+</pre>
+<p>在上述示例中,如果 <code>ABS_RZ</code> 的值为 <code>2</code>,则 <code>AXIS_BRAKE</code> 设置为 <code>-2</code>。</p>
+
+<h4 id="center-flat-position-option">中心平面位置选项</h4>
+<p>中心平面位置是坐标轴的中间位置,例如,当方向键处于其范围的正中间位置且用户未触摸它时。</p>
+<p>Linux 输入协议为输入设备驱动程序提供了一种方法来指定操纵杆坐标轴的中心平面位置,但并不是所有驱动程序都这样做,其中一些提供的值并不正确。要解决此问题,坐标轴声明可后跟 <code>flat</code> 选项,以指定该坐标轴的中心平面位置的值。</p>
+<pre class="devsite-click-to-copy">
+axis 0x03 Z flat 4096
+</pre>
+<p>在上述示例中,中心平面位置设置为 <code>4096</code>。
+</p>
+
+<h3 id="comments">注释</h3>
+<p>注释行以“#”开头,并持续到这一行的结束位置:</p>
+<pre class="devsite-click-to-copy">
+# A comment!
+</pre>
+<p>空白行会被忽略。</p>
+
+<h3 id="examples">示例</h3>
+
+<h4 id="keyboard">键盘</h4>
+<pre class="devsite-click-to-copy">
+# This is an example of a key layout file for a keyboard.
+
+key 1     ESCAPE
+key 2     1
+key 3     2
+key 4     3
+key 5     4
+key 6     5
+key 7     6
+key 8     7
+key 9     8
+key 10    9
+key 11    0
+key 12    MINUS
+key 13    EQUALS
+key 14    DEL
+
+# etc...
+</pre>
+
+<h4 id="system-controls">系统控件</h4>
+<pre class="devsite-click-to-copy">
+# This is an example of a key layout file for basic system controls,
+# such as volume and power keys which are typically implemented as GPIO pins
+# the device decodes into key presses.
+
+key 114   VOLUME_DOWN
+key 115   VOLUME_UP
+key 116   POWER
+</pre>
+
+<h4 id="capacitive-buttons">电容式按钮</h4>
+<pre class="devsite-click-to-copy">
+# This is an example of a key layout file for a touch device with capacitive buttons.
+
+key 139    MENU           VIRTUAL
+key 102    HOME           VIRTUAL
+key 158    BACK           VIRTUAL
+key 217    SEARCH         VIRTUAL
+</pre>
+
+<h4 id="headset-jack-media-controls">耳机插孔媒体控件</h4>
+<pre class="devsite-click-to-copy">
+# This is an example of a key layout file for headset mounted media controls.
+# A typical headset jack interface might have special control wires or detect known
+# resistive loads as corresponding to media functions or volume controls.
+# This file assumes that the driver decodes these signals and reports media
+# controls as key presses.
+
+key 163   MEDIA_NEXT
+key 165   MEDIA_PREVIOUS
+key 226   HEADSETHOOK
+</pre>
+
+<h4 id="joystick">操纵杆</h4>
+<pre class="devsite-click-to-copy">
+# This is an example of a key layout file for a joystick.
+
+# These are the buttons that the joystick supports, represented as keys.
+key 304   BUTTON_A
+key 305   BUTTON_B
+key 307   BUTTON_X
+key 308   BUTTON_Y
+key 310   BUTTON_L1
+key 311   BUTTON_R1
+key 314   BUTTON_SELECT
+key 315   BUTTON_START
+key 316   BUTTON_MODE
+key 317   BUTTON_THUMBL
+key 318   BUTTON_THUMBR
+
+# Left and right stick.
+# The reported value for flat is 128 in a range of -32767 to 32768, which is absurd.
+# This confuses applications that rely on the flat value because the joystick
+# actually settles in a flat range of +/- 4096 or so. We override it here.
+axis 0x00 X flat 4096
+axis 0x01 Y flat 4096
+axis 0x03 Z flat 4096
+axis 0x04 RZ flat 4096
+
+# Triggers.
+axis 0x02 LTRIGGER
+axis 0x05 RTRIGGER
+
+# Hat.
+axis 0x10 HAT_X
+axis 0x11 HAT_Y
+</pre>
+
+<h2 id="virtual-soft-keys">虚拟软键</h2>
+<p>在下列使用情形中,输入系统提供了特殊的功能来实现虚拟软键:</p>
+<ol>
+<li>如果虚拟软键以图形方式显示在屏幕上(例如在 Galaxy Nexus 上),则它们将由系统界面包中的导航栏组件实现。由于要在系统的高层中实现图形虚拟软键,因此不涉及按键布局文件,以下信息将不适用。</li>
+<li>如果虚拟软键作为属于主触摸屏一部分的扩展可触摸区域进行实现(例如在 Nexus One 上),则输入系统会使用虚拟按键映射文件将 X/Y 触摸坐标转换为 Linux 按键代码,然后使用按键布局文件将 Linux 按键代码转换为 Android 按键代码(有关虚拟按键映射文件的详细信息,请参阅<a href="touch-devices.html">触摸设备</a>)。触摸屏输入设备的按键布局文件必须指定相应的按键映射并使每个按键都包含 <code>VIRTUAL</code> 标记。</li>
+<li>如果虚拟软键作为独立于主触摸屏的电容式按钮进行实现(例如在 Nexus S 上),则内核设备驱动程序或固件负责将触摸转换为 Linux 按键代码,然后输入系统使用按键布局文件将其转换为 Android 按键代码。电容式按钮输入设备的按键布局文件必须指定相应的按键映射并使每个按键都包含 <code>VIRTUAL</code> 标记。</li>
+</ol>
+<p>如果虚拟软键位于触摸屏内或离触摸屏很近,则当用户在屏幕底部附近触摸或在屏幕上从上往下或从下往上滑动手指时,容易不小心按到按钮。为了避免出现这种情况,输入系统会应用一个短暂的去抖动,以便在最近触摸触摸屏之后的短时间内忽略虚拟软键按压(该延迟称为“虚拟键安静时间”)。<em></em></p>
+<p>要启用虚拟软键去抖动,请执行以下操作:</p>
+<ol>
+<li>为触摸屏或电容式按钮输入设备提供按键布局文件,并为每个按键设置 <code>VIRTUAL</code> 标记。
+<pre class="devsite-click-to-copy">
+key 139    MENU           VIRTUAL
+key 102    HOME           VIRTUAL
+key 158    BACK           VIRTUAL
+key 217    SEARCH         VIRTUAL
+</pre>
+</li>
+<li>在框架 <code>config.xml</code> 资源的资源叠加层中设置虚拟按键安静时间的值。
+<pre class="devsite-click-to-copy">
+&lt;!-- Specifies the amount of time to disable virtual keys after the screen
+is touched to filter out accidental virtual key presses due to swiping gestures
+or taps near the edge of the display. May be 0 to disable the feature.
+It is recommended that this value be no more than 250 ms.
+This feature should be disabled for most devices. --&gt;
+
+&lt;integer name="config_virtualKeyQuietTimeMillis"&gt;250&lt;/integer&gt;
+</pre>
+</li>
+</ol>
+
+<h2 id="validation">验证</h2>
+<p>您应使用<a href="validate-keymaps.html">验证按键映射</a>工具验证您的按键布局文件。</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/input/migration-guide.html b/zh-cn/devices/input/migration-guide.html
new file mode 100644
index 0000000..fee62cb
--- /dev/null
+++ b/zh-cn/devices/input/migration-guide.html
@@ -0,0 +1,41 @@
+<html devsite><head>
+    <title>迁移指南</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 The Android Open Source Project
+
+      Licensed under the Apache License, Version 2.0 (the "License");
+      you may not use this file except in compliance with the License.
+      You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      See the License for the specific language governing permissions and
+      limitations under the License.
+  -->
+
+<p>本文档介绍一些有助于迁移到新的 Android 版本的提示。</p>
+<h2 id="migrating-to-android-gingerbread-23">迁移到 Android Gingerbread 2.3</h2>
+<p>在 Gingerbread 中,我们新增了输入设备配置文件(在此版本中,又称为输入设备校准文件)的概念。</p>
+<p>务必为所有触摸屏提供输入设备配置文件。特别是有必要花时间提供触摸尺寸信息的校准参考。</p>
+<h2 id="migrating-to-android-honeycomb-30">迁移到 Android Honeycomb 3.0</h2>
+<p>在 Honeycomb 中,我们修改了按键字符映射文件格式,并开始更好地利用输入设备配置文件。此外,我们还新增了对 PC 式全键盘的支持,并引入了全新的“通用”按键映射,以取代旧的特定于模拟器的“qwerty”按键映射(从未用作通用型按键映射)。</p>
+<p>务必更新您的所有按键字符映射文件,以便使用新的语法。</p>
+<p>如果您的外围设备依赖于旧的“qwerty”按键映射,则您可能需要提供特定于设备的新按键映射,以模拟旧行为。您应该为通过 USB 产品 ID/供应商 ID 或设备名称标识的每种设备创建新的按键映射。</p>
+<p>为所有特殊功能输入设备提供按键字符映射文件尤为重要。这些文件应该只包含一个将键盘类型设置为 <code>SPECIAL_FUNCTION</code> 的行。</p>
+<p>可确保所有内置输入设备均正确配置的一个方法是运行 <a href="dumpsys.html">Dumpsys</a>,然后使用 <code>Generic.kcm</code> 查找配置不正确的设备。</p>
+<h2 id="migrating-to-android-honeycomb-32">迁移到 Android Honeycomb 3.2</h2>
+<p>在 Honeycomb 3.2 中,我们新增了对操纵杆的支持,并扩展了按键布局文件格式以支持操纵杆轴映射。</p>
+<h2 id="migrating-to-android-ice-cream-sandwich-40">迁移到 Android Ice Cream Sandwich 4.0</h2>
+<p>在 Ice Cream Sandwich 4.0 中,我们将触摸屏的设备驱动程序要求更改为遵循标准的 Linux 多点触控输入协议,并新增了对“B”协议的支持。我们还支持数字化仪平板电脑和基于触控笔的触屏设备。</p>
+<p>您可能需要更新输入设备驱动程序,以按照标准正确实现 Linux 多点触控输入协议。</p>
+<p>您还需要更新输入设备配置文件,因为某些更改后的属性更简单、更系统化。</p>
+<p>如需了解有关驱动程序要求的更多详细信息,请参阅<a href="touch-devices.html">触屏设备</a>。</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/input/overview.html b/zh-cn/devices/input/overview.html
new file mode 100644
index 0000000..885b68b
--- /dev/null
+++ b/zh-cn/devices/input/overview.html
@@ -0,0 +1,123 @@
+<html devsite><head>
+    <title>概览</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 The Android Open Source Project
+
+      Licensed under the Apache License, Version 2.0 (the "License");
+      you may not use this file except in compliance with the License.
+      You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      See the License for the specific language governing permissions and
+      limitations under the License.
+  -->
+
+<p>Android 输入子系统名义上是由遍历系统多个层的事件管道组成。</p>
+<h2 id="input-pipeline">输入管道</h2>
+<p>在最低层,物理输入设备会生成描述状态更改(例如按键按压和触摸接触点)的信号。设备固件以某种方式编码和传输这些信号,例如向系统发送 USB HID 报告或在 I2C 总线上产生中断。</p>
+<p>然后,信号由 Linux 内核中的设备驱动程序解码。Linux 内核为许多标准的外围设备提供驱动程序,特别是那些符合 HID 协议的外围设备。然而,原始设备制造商 (OEM) 通常必须为在低级别紧密集成到系统的嵌入式设备(如触摸屏)提供自定义驱动程序。</p>
+<p>输入设备驱动程序负责通过 Linux 输入协议将设备特定信号转换为标准输入事件格式。Linux 输入协议在 <code>linux/input.h</code> 内核头文件中定义了一组标准事件类型和代码。这样一来,内核之外的组件就不需要关注物理扫描代码、HID 用途、I2C 消息、GPIO 引脚等方面的详细信息。</p>
+<p>接下来,Android <code>EventHub</code> 组件通过打开与每个输入设备关联的 <code>evdev</code> 驱动程序从内核读取输入事件。然后,Android InputReader 组件根据设备类别解码输入事件,并生成 Android 输入事件流。在此过程中,Linux 输入协议事件代码将根据输入设备配置、键盘布局文件和各种映射表,转化为 Android 事件代码。</p>
+<p>最后,<code>InputReader</code> 将输入事件发送到 InputDispatcher,后者将这些事件转发到相应的窗口。</p>
+<h2 id="control-points">控制点</h2>
+<p>在输入管道中有几个阶段会影响对输入设备行为的控制。</p>
+<h3 id="driver-and-firmware-configuration">驱动程序和固件配置</h3>
+<p>输入设备驱动程序经常通过在寄存器中设置参数甚或上传固件本身来配置输入设备的行为。对于诸如触摸屏等嵌入式设备尤其如此,其中一大部分校准过程涉及到调整这些参数或修复固件,以提供所需的精度和响应能力并抑制噪声。</p>
+<p>驱动程序配置选项通常在内核板级支持包 (BSP) 中指定为模块参数,以便同一驱动程序可以支持多种不同的硬件实现。</p>
+<p>本文档旨在介绍驱动程序或固件配置,但在总体上提供了有关设备校准的指导。</p>
+<h3 id="board-configuration-properties">板配置属性</h3>
+<p>内核板级支持包 (BSP) 可以通过由 Android InputReader 组件使用的 SysFS 导出板配置属性,如虚拟键在触摸屏上的位置。</p>
+<p>有关不同设备如何使用板配置属性的详细信息,请参阅设备类别部分。</p>
+<h3 id="resource-overlays">资源叠加层</h3>
+<p>有几个输入行为是通过 <code>config.xml</code> 中的资源叠加层配置的,例如机盖开关的操作。</p>
+<p>以下是几个例子:</p>
+<ul>
+<li>
+<p><code>config_lidKeyboardAccessibility</code>:指定机盖开关对硬件键盘可访问还是隐藏的影响。</p>
+</li>
+<li>
+<p><code>config_lidNavigationAccessibility</code>:指定机盖开关对触控板可访问还是隐藏的影响。</p>
+</li>
+<li>
+<p><code>config_longPressOnPowerBehavior</code>:指定当用户按住电源按钮时应该发生的情况。</p>
+</li>
+<li>
+<p><code>config_lidOpenRotation</code>:指定机盖开关对屏幕方向的影响。</p>
+</li>
+</ul>
+<p>要详细了解每个配置选项,请参阅 <code>frameworks/base/core/res/res/values/config.xml</code> 中的文档。</p>
+<h3 id="key-maps">按键映射</h3>
+<p>Android <code>EventHub</code> 和 <code>InputReader</code> 组件使用按键映射来配置按键、操纵杆按钮和操纵杆轴从 Linux 事件代码到 Android 事件代码的映射。映射可能会因设备或语言的不同而不同。</p>
+<p>要详细了解不同设备如何使用按键映射,请参阅设备类别部分。</p>
+<h3 id="input-device-configuration-files">输入设备配置文件</h3>
+<p>Android <code>EventHub</code> 和 <code>InputReader</code> 组件使用输入设备配置文件来配置特殊设备特征,例如,如何报告触摸尺寸信息。</p>
+<p>要详细了解不同设备如何使用输入设备配置映射,请参阅设备类别部分。</p>
+<h2 id="understanding-hid-usages-and-event-codes">了解 HID 用途和事件代码</h2>
+<p>通常使用几个不同的标识符来指代键盘上的任何指定按键、游戏控制器上的按钮、操纵杆轴或其他控件。这些标识符之间的关系并非总是一样的:它们取决于一组映射表,其中一些映射是固定的,还有一些映射随设备特征、设备驱动程序、当前语言区域、系统配置、用户偏好设置和其他因素而变化。</p>
+<dl>
+<dt>物理扫描代码</dt>
+<dd>
+<p>物理扫描代码是与每个按键、按钮或其他控件相关联的设备特定标识符。由于物理扫描代码通常因设备而异,因此固件或设备驱动程序负责将其映射到标准标识符,例如 HID 用途或 Linux 按键代码。</p>
+<p>扫描代码主要用于键盘。其他设备通常使用 GPIO 引脚、I2C 消息或其他方式在低级别进行通信。因此,软件堆栈的上层依赖于设备驱动程序来确定发生的操作。</p>
+</dd>
+<dt>HID 用途</dt>
+<dd>
+<p>HID 用途是一种标准标识符,用于报告控件(如键盘按键、操纵杆轴、鼠标按钮或触摸接触点)的状态。大多数 USB 和蓝牙输入设备都符合 HID 规范,使得系统能够以统一的方式与它们进行连接。</p>
+<p>Android 框架依赖于 Linux 内核 HID 驱动程序来将 HID 用途代码转换为 Linux 按键代码和其他标识符。因此,主要是外设制造商关注 HID 用途。</p>
+</dd>
+<dt>Linux 按键代码</dt>
+<dd>
+<p>Linux 按键代码是用于按键或按钮的标准标识符。Linux 按键代码在 <code>linux/input.h</code> 头文件中使用以前缀 <code>KEY_</code> 或 <code>BTN_</code> 开头的常量进行定义。Linux 内核输入驱动程序负责将物理扫描代码、HID 用途和其他设备特定信号转换为 Linux 按键代码,并作为 <code>EV_KEY</code> 事件的一部分提供有关它们的信息。</p>
+<p>Android API 有时将与按键相关联的 Linux 按键代码称为其“扫描代码”。这在技术上是错误的,但是有助于在 API 中区分 Linux 按键代码和 Android 按键代码。</p>
+</dd>
+<dt>Linux 相对或绝对轴代码</dt>
+<dd>
+<p>Linux 相对或绝对轴代码是一种标准标识符,用于报告沿着某个轴的相对位移或绝对位置,例如鼠标沿其 X 轴的相对位移或者操纵杆沿其 X 轴的绝对位置。Linux 轴代码在 <code>linux/input.h</code> 头文件中使用以前缀 <code>REL_</code> 或 <code>ABS_</code> 开头的常量进行定义。Linux 内核输入驱动程序负责将 HID 用途和其他设备特定信号转换为 Linux 轴代码,并作为 <code>EV_REL</code> 和 <code>EV_ABS</code> 事件的一部分提供有关它们的信息。</p>
+</dd>
+<dt>Linux 开关代码</dt>
+<dd>
+<p>Linux 开关代码是用于报告设备上的开关(例如机盖开关)状态的标准标识符。Linux 开关代码在 <code>linux/input.h</code> 头文件中使用以前缀 <code>SW_</code> 开头的常量进行定义。Linux 内核输入驱动程序以 <code>EV_SW</code> 事件形式报告开关状态更改。</p>
+<p>Android 应用通常不会接收来自开关的事件,但系统可能会在内部使用它们来控制各种特定于设备的功能。</p>
+</dd>
+<dt>Android 按键代码</dt>
+<dd>
+<p>Android 按键代码是在 Android API 中定义的标准标识符,用于指示特定按键(如“主屏幕”)。Android 按键代码由 <code>android.view.KeyEvent</code> 类作为以前缀 <code>KEYCODE_</code> 开头的常量进行定义。</p>
+<p>按键布局指定了 Linux 按键代码如何映射到 Android 按键代码。可以使用不同的按键布局,具体取决于键盘型号、语言、国家/地区、布局或特殊功能。</p>
+<p>使用特定于设备和语言区域的按键字符映射将 Android 按键代码组合转换为字符代码。例如,当同时按下标识为 <code>KEYCODE_SHIFT</code> 和 <code>KEYCODE_A</code> 的按键时,系统将在按键字符映射中查找该组合并找到大写字母“A”,然后将其插入当前聚焦的文本微件中。</p>
+</dd>
+<dt>Android 轴代码</dt>
+<dd>
+<p>Android 轴代码是在 Android API 中定义的标准标识符,用于指示特定设备轴。Android 轴代码由 <code>android.view.MotionEvent</code> 类定义为以前缀 <code>AXIS_</code> 开头的常量。</p>
+<p>按键布局指定了 Linux 轴代码如何映射到 Android 轴代码。可能会使用不同的按键布局,具体取决于设备型号、语言、国家/地区、布局或特殊功能。</p>
+</dd>
+<dt>Android 元状态</dt>
+<dd>
+<p>Android 元状态是在 Android API 中定义的标准标识符,用于指示按哪些辅助键。Android 元状态由 <code>android.view.KeyEvent</code> 类定义为以前缀 <code>META_</code> 开头的常量。</p>
+<p>当前元状态由 Android InputReader 组件确定,该组件用于监控何时按下/释放辅助键(如 <code>KEYCODE_SHIFT_LEFT</code>)并设置/重置相应的元状态标记。</p>
+<p>辅助键和元状态之间的关系采用硬编码,但是按键布局可以改变辅助键本身的映射方式,这反过来又会影响元状态。</p>
+</dd>
+<dt>Android 按钮状态</dt>
+<dd>
+<p>Android 按钮状态是在 Android API 中定义的标准标识符,用于指示按下(鼠标或触控笔上的)哪些按钮。Android 按钮状态由 <code>android.view.MotionEvent</code> 类定义为以前缀 <code>BUTTON_</code> 开头的常量。</p>
+<p>当前的按钮状态由 Android InputReader 组件确定,该组件用于监控何时按下/释放(鼠标或触控笔上的)按钮并设置/重置相应的按钮状态标记。</p>
+<p>按钮和按钮状态之间的关系采用硬编码。</p>
+</dd>
+</dl>
+<h2 id="further-reading">延伸阅读</h2>
+<ol>
+<li><a href="http://www.kernel.org/doc/Documentation/input/event-codes.txt">Linux 输入事件代码</a></li>
+<li><a href="http://www.kernel.org/doc/Documentation/input/multi-touch-protocol.txt">Linux 多点触控协议</a></li>
+<li><a href="http://www.kernel.org/doc/Documentation/input/input.txt">Linux 输入驱动程序</a></li>
+<li><a href="http://www.kernel.org/doc/Documentation/input/ff.txt">Linux 强制反馈</a></li>
+<li><a href="http://www.usb.org/developers/hidpage">HID 信息,包括 HID 用途表</a></li>
+</ol>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/input/touch-devices.html b/zh-cn/devices/input/touch-devices.html
new file mode 100644
index 0000000..f434604
--- /dev/null
+++ b/zh-cn/devices/input/touch-devices.html
@@ -0,0 +1,869 @@
+<html devsite><head>
+    <title>触摸设备</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 The Android Open Source Project
+
+      Licensed under the Apache License, Version 2.0 (the "License");
+      you may not use this file except in compliance with the License.
+      You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      See the License for the specific language governing permissions and
+      limitations under the License.
+  -->
+
+<p>Android 支持各种触摸屏和触摸板,包括基于触控笔的数字化板。</p>
+<p>触摸屏是与显示屏相关联的触摸设备,使用户能够在屏幕上直接操纵内容。</p>
+<p>触摸板是不与显示屏相关联的触摸设备(如数字化板)。触摸板通常用于指控或绝对间接定位或基于手势的界面控制。</p>
+<p>触摸设备可能具有功能与鼠标按钮类似的按钮。</p>
+<p>有时可以使用各种不同的工具(如手指或触控笔)操作触摸设备,具体取决于底层的触摸传感器技术。</p>
+<p>触摸设备有时用于实现虚拟按键。例如,在某些 Android 设备上,触摸屏传感器区域延伸超出显示屏的边缘,作为触摸式键盘的一部分发挥双重作用。</p>
+<p>由于触摸设备种类繁多,Android 依赖于大量配置属性来描述每个设备的特征和期望的行为。</p>
+<h2 id="touch-device-classification">触摸设备分类</h2>
+<p>如果同时满足以下两个条件,则输入设备属于多点触控设备:<em></em></p>
+<ul>
+<li>
+<p>输入设备报告存在 <code>ABS_MT_POSITION_X</code> 和 <code>ABS_MT_POSITION_Y</code> 绝对轴。</p>
+</li>
+<li>
+<p>输入设备没有任何游戏手柄按钮。某些游戏手柄会使用与 MT 轴的代码重叠的代码来报告轴,而这一条件则消除了这种歧义。</p>
+</li>
+</ul>
+<p>如果同时满足以下两个条件,则输入设备属于单点触控设备:<em></em></p>
+<ul>
+<li>
+<p>输入设备不属于多点触控设备。输入设备要么属于单点触控设备,要么属于多点触控设备,而不会同时属于这两种类别。</p>
+</li>
+<li>
+<p>输入设备报告存在 <code>ABS_X</code> 和 <code>ABS_Y</code> 绝对轴以及 <code>BTN_TOUCH</code> 按键代码。</p>
+</li>
+</ul>
+<p>一旦输入设备属于触摸设备,则通过尝试加载设备的虚拟按键映射文件来确定是否存在虚拟按键。如果存在虚拟按键映射,则还会加载设备的按键布局文件。</p>
+<p>有关虚拟按键映射文件的位置和格式,请参阅下面的部分。</p>
+<p>接下来,系统会加载触摸设备的输入设备配置文件。</p>
+<p><strong>所有内置触摸设备都应具有输入设备配置文件。</strong>如果没有输入设备配置文件,则系统将选择适用于典型通用触摸外设(如外部 USB 或蓝牙 HID 触摸屏或触摸板)的默认配置。这些默认配置不适用于内置触摸屏,很可能会导致错误的行为。</p>
+<p>加载输入设备配置后,系统会将输入设备分类为触摸屏、触摸板或指控设备。<em></em><em></em><em></em></p>
+<ul>
+<li>
+<p><em></em>触摸屏设备用于直接操纵屏幕上的对象。由于用户直接触摸屏幕,因此系统不需要任何额外的感知性来指示被操纵的对象。</p>
+</li>
+<li>
+<p><em></em>触摸板设备用于向应用提供关于在给定传感器区域上进行触摸时的绝对定位信息。它可能对数字化板有用。</p>
+</li>
+<li>
+<p><em></em>指控设备用于使用光标间接操纵屏幕上的对象。手指被解释为多点触控指控手势。其他工具(如触控笔)则通过绝对位置来解释。</p>
+<p>有关详情,请参阅<a href="#indirect-multi-touch-pointer-gestures">间接多点触控指控手势</a>。</p>
+</li>
+</ul>
+<p>以下规则用于将输入设备分类为触摸屏、触摸板或指控设备。<em></em><em></em><em></em></p>
+<ul>
+<li>
+<p>如果设置了 <code>touch.deviceType</code> 属性,则将按照指示设置设备类型。</p>
+</li>
+<li>
+<p>如果输入设备报告存在 <code>INPUT_PROP_DIRECT</code> 输入属性(通过 <code>EVIOCGPROP</code> ioctl),则设备类型将设置为触摸屏。<em></em>该条件假设直接输入触摸设备已连接到同样处于连接状态的显示屏。</p>
+</li>
+<li>
+<p>如果输入设备报告存在 <code>INPUT_PROP_POINTER</code> 输入属性(通过 <code>EVIOCGPROP</code> ioctl),则设备类型将设置为指控设备。<em></em></p>
+</li>
+<li>
+<p>如果输入设备报告存在 <code>REL_X</code> 或 <code>REL_Y</code> 相对轴,则设备类型将设置为触摸板。<em></em>该条件消除了由鼠标和触摸板组成的输入设备存在的歧义。在这种情况下,触摸板不会用于控制指针,因为鼠标已经在控制它。</p>
+</li>
+<li>
+<p>否则,设备类型将被设置为指控设备。<em></em>该默认设置确保没有指定任何其他特殊用途的触摸板将用于控制指针。</p>
+</li>
+</ul>
+<h2 id="buttons">按钮</h2>
+<p>按钮是可供应用用来执行其他功能的“可选”控件。<em></em>触摸设备上的按钮与鼠标按钮类似,主要与“指针式”触摸设备或者触控笔配合使用。<em></em></p>
+<p>支持以下按钮:</p>
+<ul>
+<li>
+<p><code>BTN_LEFT</code>:映射到 <code>MotionEvent.BUTTON_PRIMARY</code>。</p>
+</li>
+<li>
+<p><code>BTN_RIGHT</code>:映射到 <code>MotionEvent.BUTTON_SECONDARY</code>。</p>
+</li>
+<li>
+<p><code>BTN_MIDDLE</code>:映射到 <code>MotionEvent.BUTTON_MIDDLE</code>。</p>
+</li>
+<li>
+<p><code>BTN_BACK</code> 和 <code>BTN_SIDE</code>:映射到 <code>MotionEvent.BUTTON_BACK</code>。按此按钮还可以合成按键(使用按键代码 <code>KeyEvent.KEYCODE_BACK</code>)。</p>
+</li>
+<li>
+<p><code>BTN_FORWARD</code> 和 <code>BTN_EXTRA</code>:映射到 <code>MotionEvent.BUTTON_FORWARD</code>。按此按钮还可以合成按键(使用按键代码 <code>KeyEvent.KEYCODE_FORWARD</code>)。</p>
+</li>
+<li>
+<p><code>BTN_STYLUS</code>:映射到 <code>MotionEvent.BUTTON_SECONDARY</code>。</p>
+</li>
+<li>
+<p><code>BTN_STYLUS2</code>:映射到 <code>MotionEvent.BUTTON_TERTIARY</code>。</p>
+</li>
+</ul>
+<h2 id="tools-and-tool-types">工具和工具类型</h2>
+<p>“工具”是指用于和触摸设备进行交互的手指、触控笔或其他装置。<em></em>有些触摸设备可以区分不同类型的工具。</p>
+<p>在 Android 的其他位置(和在 <code>MotionEvent</code> API 中一样),“工具”通常被称为“指针”。<em></em><em></em></p>
+<p>支持以下工具类型:</p>
+<ul>
+<li>
+<p><code>BTN_TOOL_FINGER</code> 和 <code>MT_TOOL_FINGER</code>:映射到 <code>MotionEvent.TOOL_TYPE_FINGER</code>。</p>
+</li>
+<li>
+<p><code>BTN_TOOL_PEN</code> 和 <code>MT_TOOL_PEN</code>:映射到 <code>MotionEvent.TOOL_TYPE_STYLUS</code>。</p>
+</li>
+<li>
+<p><code>BTN_TOOL_RUBBER</code>:映射到 <code>MotionEvent.TOOL_TYPE_ERASER</code>。</p>
+</li>
+<li>
+<p><code>BTN_TOOL_BRUSH</code>:映射到 <code>MotionEvent.TOOL_TYPE_STYLUS</code>。</p>
+</li>
+<li>
+<p><code>BTN_TOOL_PENCIL</code>:映射到 <code>MotionEvent.TOOL_TYPE_STYLUS</code>。</p>
+</li>
+<li>
+<p><code>BTN_TOOL_AIRBRUSH</code>:映射到 <code>MotionEvent.TOOL_TYPE_STYLUS</code>。</p>
+</li>
+<li>
+<p><code>BTN_TOOL_MOUSE</code>:映射到 <code>MotionEvent.TOOL_TYPE_MOUSE</code>。</p>
+</li>
+<li>
+<p><code>BTN_TOOL_LENS</code>:映射到 <code>MotionEvent.TOOL_TYPE_MOUSE</code>。</p>
+</li>
+<li>
+<p><code>BTN_TOOL_DOUBLETAP</code>、<code>BTN_TOOL_TRIPLETAP</code> 和 <code>BTN_TOOL_QUADTAP</code>:映射到 <code>MotionEvent.TOOL_TYPE_FINGER</code>。</p>
+</li>
+</ul>
+<h2 id="hovering-vs-touching-tools">悬停与触摸工具</h2>
+<p>工具可以与触摸设备接触,也可以在触摸设备的感应范围内悬停在设备的上方。并非所有触摸设备都能够感应到悬停在其上方的工具。那些可实现感应的触摸设备(如基于射频的触控笔数字化仪)通常能在工具进入其有限的感应范围后检测到该工具。</p>
+<p><code>InputReader</code> 组件会谨慎区分触摸工具和悬停工具。同样,触摸工具和悬停工具也会以不同的方式报告给应用。</p>
+<p>触摸工具将通过以下组件作为触摸事件报告给应用:<code>MotionEvent.ACTION_DOWN</code>、<code>MotionEvent.ACTION_MOVE</code>、<code>MotionEvent.ACTION_DOWN</code>、<code>MotionEvent.ACTION_POINTER_DOWN</code> 和 <code>MotionEvent.ACTION_POINTER_UP</code>。</p>
+<p>悬停工具将通过以下组件作为通用动作事件报告给应用:<code>MotionEvent.ACTION_HOVER_ENTER</code>、<code>MotionEvent.ACTION_HOVER_MOVE</code> 和 <code>MotionEvent.ACTION_HOVER_EXIT</code>。</p>
+<h2 id="touch-device-driver-requirements">触摸设备驱动程序要求</h2>
+<ol>
+<li>
+<p>触摸设备驱动程序应该仅注册它们实际支持的轴/按钮的轴/按键代码。如果注册多余的轴/按键代码,则可能会混淆设备分类算法或导致系统错误地检测设备的功能。</p>
+<p>例如,如果设备报告 <code>BTN_TOUCH</code> 按键代码,系统会假设 <code>BTN_TOUCH</code> 将始终用于指示该工具是实际触摸屏幕还是只在感应范围内悬停。</p>
+</li>
+<li>
+<p>单点触控设备使用以下 Linux 输入事件:</p>
+<ul>
+<li>
+<p><code>ABS_X</code>:(必需)报告工具的 X 坐标。<em></em></p>
+</li>
+<li>
+<p><code>ABS_Y</code>:(必需)报告工具的 Y 坐标。<em></em></p>
+</li>
+<li>
+<p><code>ABS_PRESSURE</code>:(可选)报告应用于工具尖端的物理压力或触摸点的信号强度。<em></em></p>
+</li>
+<li>
+<p><code>ABS_TOOL_WIDTH</code>:(可选)报告触摸点或工具本身的横截面积或宽度。<em></em></p>
+</li>
+<li>
+<p><code>ABS_DISTANCE</code>:(可选)报告工具与触摸设备表面之间的距离。<em></em></p>
+</li>
+<li>
+<p><code>ABS_TILT_X</code>:(可选)报告工具沿触摸设备表面 X 轴方向的倾斜度。<em></em></p>
+</li>
+<li>
+<p><code>ABS_TILT_Y</code>:(可选)报告工具沿触摸设备表面 Y 轴方向的倾斜度。<em></em></p>
+</li>
+<li>
+<p><code>BTN_TOUCH</code>:(必需)指示工具是否触摸到设备。<em></em></p>
+</li>
+<li>
+<p><code>BTN_LEFT</code>、<code>BTN_RIGHT</code>、<code>BTN_MIDDLE</code>、<code>BTN_BACK</code>、<code>BTN_SIDE</code>、<code>BTN_FORWARD</code>、<code>BTN_EXTRA</code>、<code>BTN_STYLUS</code>、<code>BTN_STYLUS2</code>:(可选)报告<a href="#buttons">按钮</a>状态。<em></em></p>
+</li>
+<li>
+<p><code>BTN_TOOL_FINGER</code>、<code>BTN_TOOL_PEN</code>、<code>BTN_TOOL_RUBBER</code>、<code>BTN_TOOL_BRUSH</code>、<code>BTN_TOOL_PENCIL</code>、<code>BTN_TOOL_AIRBRUSH</code>、<code>BTN_TOOL_MOUSE</code>、<code>BTN_TOOL_LENS</code>、<code>BTN_TOOL_DOUBLETAP</code>、<code>BTN_TOOL_TRIPLETAP</code>、<code>BTN_TOOL_QUADTAP</code>:(可选)报告<a href="#tools-and-tool-types">工具类型</a>。<em></em></p>
+</li>
+</ul>
+</li>
+<li>
+<p>多点触控设备使用以下 Linux 输入事件:</p>
+<ul>
+<li>
+<p><code>ABS_MT_POSITION_X</code>:(必需)报告工具的 X 坐标。<em></em></p>
+</li>
+<li>
+<p><code>ABS_MT_POSITION_Y</code>:(必需)报告工具的 Y 坐标。<em></em></p>
+</li>
+<li>
+<p><code>ABS_MT_PRESSURE</code>:(可选)报告应用于工具尖端的物理压力或触摸点的信号强度。<em></em></p>
+</li>
+<li>
+<p><code>ABS_MT_TOUCH_MAJOR</code>:(可选)报告触摸点的横截面积或触摸点间较长尺寸的长度。<em></em></p>
+</li>
+<li>
+<p><code>ABS_MT_TOUCH_MINOR</code>:(可选)报告触摸点间较短尺寸的长度。<em></em>如果 <code>ABS_MT_TOUCH_MAJOR</code> 报告区域测量,则不应使用此轴。</p>
+</li>
+<li>
+<p><code>ABS_MT_WIDTH_MAJOR</code>:(可选)报告工具本身的横截面积或工具本身较长尺寸的长度。<em></em>如果工具本身的尺寸未知,则不应使用此轴。</p>
+</li>
+<li>
+<p><code>ABS_MT_WIDTH_MINOR</code>:(可选)报告工具本身较短尺寸的长度。<em></em>如果 <code>ABS_MT_WIDTH_MAJOR</code> 报告区域测量或者工具本身的尺寸未知,则不应使用此轴。</p>
+</li>
+<li>
+<p><code>ABS_MT_ORIENTATION</code>:(可选)报告工具的方向。<em></em></p>
+</li>
+<li>
+<p><code>ABS_MT_DISTANCE</code>:(可选)报告工具与触摸设备表面之间的距离。<em></em></p>
+</li>
+<li>
+<p><code>ABS_MT_TOOL_TYPE</code>:(可选)将<a href="#tools-and-tool-types">工具类型</a>报告为 <code>MT_TOOL_FINGER</code> 或 <code>MT_TOOL_PEN</code>。<em></em></p>
+</li>
+<li>
+<p><code>ABS_MT_TRACKING_ID</code>:(可选)报告工具的跟踪 ID。<em></em>跟踪 ID 是一个任意的非负整数。当多个工具同时处于活动状态时,该 ID 用于独立地识别和跟踪各个工具。例如,当多个手指同时触摸设备时,会为每个手指分配一个不同的跟踪 ID,用于在手指保持接触期间识别手指。跟踪 ID 可在其关联的工具移出感应范围后重复使用。</p>
+</li>
+<li>
+<p><code>ABS_MT_SLOT</code>:(可选)在使用 Linux 多点触控协议“B”时,报告工具的槽位 ID。<em></em>有关详情,请参阅 Linux 多点触控协议文档。</p>
+</li>
+<li>
+<p><code>BTN_TOUCH</code>:(必需)指示工具是否触摸到设备。<em></em></p>
+</li>
+<li>
+<p><code>BTN_LEFT</code>、<code>BTN_RIGHT</code>、<code>BTN_MIDDLE</code>、<code>BTN_BACK</code>、<code>BTN_SIDE</code>、<code>BTN_FORWARD</code>、<code>BTN_EXTRA</code>、<code>BTN_STYLUS</code>、<code>BTN_STYLUS2</code>:(可选)报告<a href="#buttons">按钮</a>状态。<em></em></p>
+</li>
+<li>
+<p><code>BTN_TOOL_FINGER</code>、<code>BTN_TOOL_PEN</code>、<code>BTN_TOOL_RUBBER</code>、<code>BTN_TOOL_BRUSH</code>、<code>BTN_TOOL_PENCIL</code>、<code>BTN_TOOL_AIRBRUSH</code>、<code>BTN_TOOL_MOUSE</code>、<code>BTN_TOOL_LENS</code>、<code>BTN_TOOL_DOUBLETAP</code>、<code>BTN_TOOL_TRIPLETAP</code>、<code>BTN_TOOL_QUADTAP</code>:(可选)报告<a href="#tools-and-tool-types">工具类型</a>。<em></em></p>
+</li>
+</ul>
+</li>
+<li>
+<p>如果同时定义了单点触控协议轴和多点触控协议轴,则仅使用多点触控轴,并忽略单点触控轴。</p>
+</li>
+<li>
+<p><code>ABS_X</code>、<code>ABS_Y</code>、<code>ABS_MT_POSITION_X</code> 和 <code>ABS_MT_POSITION_Y</code> 轴的最小值和最大值用于在特定于设备的 Surface 单元内指定设备有效区域的范围。如果是触摸屏,有效区域是指触摸设备实际覆盖显示屏的部分。</p>
+<p>对于触摸屏,系统会自动插入报告的触摸位置(在 Surface 单元内),以通过以下公式计算得出采用显示像素表示的触摸位置:</p>
+<pre class="devsite-click-to-copy">
+displayX = (x - minX) * displayWidth / (maxX - minX + 1)
+displayY = (y - minY) * displayHeight / (maxY - minY + 1)
+</pre>
+<p>触摸屏可能会报告在报告的有效区域之外发起的触摸。</p>
+<p>在有效区域之外发起的触摸不会传递给应用,但可用于虚拟按键。</p>
+<p>在有效区域内发起的触摸或进入和退出显示区域的触摸会传递给应用。因此,如果触摸是在应用的范围内开始,然后移动到有效区域之外,则应用可能会收到显示坐标为负或超出显示范围的触摸事件。这属于正常现象。</p>
+<p>触摸设备不得限制有效区域的触摸坐标边界。如果触摸退出有效区域,则应将其报告为超出有效区域范围,或者根本不应报告。</p>
+<p>例如,如果用户的手指在触摸屏左上角附近触摸,则可能会报告 (minX, minY) 坐标。如果手指继续移动到有效区域之外,触摸屏应该开始报告分量小于 minX 和 minY 的坐标(如 (minX - 2, minY - 3)),或者完全停止报告触摸。换句话说,当用户的手指确实触摸到有效区域之外时,触摸屏不应该报告 (minX, minY)。<em></em></p>
+<p>如果将触摸坐标限制到显示屏边缘,则会在屏幕边缘周围产生人为硬边界,阻止系统顺畅地跟踪进入或退出显示区域边界的运动。</p>
+</li>
+<li>
+<p><code>ABS_PRESSURE</code> 或 <code>ABS_MT_PRESSURE</code> 报告的值(如果有报告)在工具触摸设备时必须为非零值;否则就为零,表示该工具处于悬停状态。</p>
+<p>报告压力信息为可选项,但强烈建议报告该信息。<em></em>应用可以使用压力信息来实现压敏绘图等效果。</p>
+</li>
+<li>
+<p><code>ABS_TOOL_WIDTH</code>、<code>ABS_MT_TOUCH_MAJOR</code>、<code>ABS_MT_TOUCH_MINOR</code>、<code>ABS_MT_WIDTH_MAJOR</code> 或 <code>ABS_MT_WIDTH_MINOR</code> 报告的值在工具触摸设备时应为非零值;否则就为零,但这不是必需的。例如,触摸设备可能能够测量手指触摸点的尺寸,但不能测量触控笔触摸点的尺寸。</p>
+<p>报告大小信息为可选项,但强烈建议报告。<em></em>应用可以使用压力信息来实现尺寸敏感绘图等效果。</p>
+</li>
+<li>
+<p><code>ABS_DISTANCE</code> 或 <code>ABS_MT_DISTANCE</code> 报告的值在工具触摸设备时应接近零。即使当工具处于直接接触时,距离仍可能为非零。报告的确切值取决于硬件测量距离的方式。</p>
+<p>报告距离信息为可选项,但建议用于触控笔设备。<em></em></p>
+</li>
+<li>
+<p>当工具垂直于设备时,<code>ABS_TILT_X</code> 和 <code>ABS_TILT_Y</code> 报告的值应为零。将非零倾斜作为工具保持在倾斜处的标志。</p>
+<p>假定沿 X 轴和 Y 轴的倾斜角度以与垂直方向的夹角计。中心点(完全垂直)由每个轴的 <code>(max + min) / 2</code> 指定。小于中心点的值表示向上或向左倾斜,大于中心点的值表示向下或向右倾斜。</p>
+<p><code>InputReader</code> 将 X 和 Y 倾斜分量转换成从 0 到 <code>PI / 2</code> 弧度的垂直倾斜角以及从 <code>-PI</code> 到 <code>PI</code> 弧度的平面定向角。该表示法将产生与描述手指触摸所用方向相符的方向的描述。</p>
+<p>报告倾斜信息为可选项,但建议用于触控笔设备。<em></em></p>
+</li>
+<li>
+<p>如果工具类型是由 <code>ABS_MT_TOOL_TYPE</code> 报告的,则会取代 <code>BTN_TOOL_*</code> 报告的任何工具类型信息。如果根本没有可用的工具类型信息,则工具类型将默认为 <code>MotionEvent.TOOL_TYPE_FINGER</code>。</p>
+</li>
+<li>
+<p>根据以下条件确定工具的活动状态:</p>
+<ul>
+<li>
+<p>当使用单点触控协议时,如果 <code>BTN_TOUCH</code> 或 <code>BTN_TOOL_*</code> 为 1,则表示工具处于活动状态。</p>
+<p>这个条件意味着 <code>InputReader</code> 至少需要获得一些关于工具性质的信息:工具是否正在触摸,或者至少知道工具的类型。如果没有可用的信息,则假定工具处于非活动状态(超出范围)。</p>
+</li>
+<li>
+<p>当使用多点触控协议“A”时,只要工具出现在最近的同步报告中,则表示其处于活动状态。当工具不再出现在同步报告中时,则表示工具不再存在。</p>
+</li>
+<li>
+<p>当使用多点触控协议“B”时,只要工具具有活动插槽,则表示其处于活动状态。当插槽被清除时,则表示工具不再存在。</p>
+</li>
+</ul>
+</li>
+<li>
+<p>根据以下条件确定工具悬停:</p>
+<ul>
+<li>
+<p>如果工具为 <code>BTN_TOOL_MOUSE</code> 或 <code>BTN_TOOL_LENS</code>,则该工具不会悬停,即使以下任一条件为真也不例外。</p>
+</li>
+<li>
+<p>如果工具处于活动状态,并且驱动程序报告的压力为零,则表示工具处于悬停状态。</p>
+</li>
+<li>
+<p>如果工具处于活动状态,而且驱动程序支持 <code>BTN_TOUCH</code> 按键代码,并且 <code>BTN_TOUCH</code> 的值为零,则表示工具处于悬停状态。</p>
+</li>
+</ul>
+</li>
+<li>
+<p><code>InputReader</code> 支持多点触控协议“A”和“B”。新驱动程序应该使用“B”协议,但是使用任一协议均可正常运作。</p>
+</li>
+<li>
+<p><strong>根据 Android Ice Cream Sandwich 4.0,可能需要更改触摸屏驱动程序,以符合 Linux 输入协议规范。</strong></p>
+<p>可能需要进行以下更改:</p>
+<ul>
+<li>
+<p>当一个工具变为非活动状态(“抬起”一根手指)时,它应该停止显示在后续的多点触控同步报告中。当所有工具变为非活动状态(“抬起”所有手指)时,驱动程序应发送一个空的同步报告数据包,如 <code>SYN_MT_REPORT</code> 后跟 <code>SYN_REPORT</code>。</p>
+<p>以前版本的 Android 通过发送压力值 0 来报告“抬起”事件。该旧行为与 Linux 输入协议规范不兼容,因此不再受支持。</p>
+</li>
+<li>
+<p>物理压力或信号强度信息应使用 <code>ABS_MT_PRESSURE</code> 进行报告。</p>
+<p>以前版本的 Android 从 <code>ABS_MT_TOUCH_MAJOR</code> 检索压力信息。该旧行为与 Linux 输入协议规范不兼容,因此不再受支持。</p>
+</li>
+<li>
+<p>触摸尺寸信息应使用 <code>ABS_MT_TOUCH_MAJOR</code> 进行报告。</p>
+<p>以前版本的 Android 从 <code>ABS_MT_TOOL_MAJOR</code> 检索尺寸信息。该旧行为与 Linux 输入协议规范不兼容,因此不再受支持。</p>
+</li>
+</ul>
+<p>触摸设备驱动程序不再需要 Android 系统专用的自定义设置。通过依靠标准的 Linux 输入协议,Android 可以使用未经修改的驱动程序来支持更多种类的触摸外设,如外部 HID 多点触控触摸屏。</p>
+</li>
+</ol>
+<h2 id="touch-device-operation">触摸设备操作</h2>
+<p>下面简要汇总了 Android 上的触摸设备操作。</p>
+<ol>
+<li>
+<p><code>EventHub</code> 从 <code>evdev</code> 驱动程序读取原始事件。</p>
+</li>
+<li>
+<p><code>InputReader</code> 消耗原始事件,并更新关于每个工具的位置和其他特征的内部状态。它还会跟踪按钮状态。</p>
+</li>
+<li>
+<p>如果按下或释放“后退”或“前进”按钮,<code>InputReader</code> 会向 <code>InputDispatcher</code> 发出按键事件通知。</p>
+</li>
+<li>
+<p><code>InputReader</code> 确定是否发生了虚拟按键的按压操作。如果是,它会向 <code>InputDispatcher</code> 发出按键事件通知。</p>
+</li>
+<li>
+<p><code>InputReader</code> 确定触摸行为是否在显示范围内发起的。如果是,它会向 <code>InputDispatcher</code> 发出触摸事件通知。</p>
+</li>
+<li>
+<p>如果没有触摸工具,但至少有一个悬停工具,则 <code>InputReader</code> 会向 <code>InputDispatcher</code> 发出悬停事件通知。</p>
+</li>
+<li>
+<p><em></em>如果触摸设备类型是指控设备,则 <code>InputReader</code> 会执行指针手势检测,相应地移动指针和相关点,并向 <code>InputDispatcher</code> 发出指针事件通知。</p>
+</li>
+<li>
+<p><code>InputDispatcher</code> 使用 <code>WindowManagerPolicy</code> 来确定是否应该调度这些事件,以及它们是否应该唤醒设备。然后,<code>InputDispatcher</code> 将事件传递给相应的应用。</p>
+</li>
+</ol>
+<h2 id="touch-device-configuration">触摸设备配置</h2>
+<p>触摸设备行为由设备的坐标轴、按钮、输入属性、输入设备配置、虚拟按键映射和按键布局确定。</p>
+<p>要详细了解参与键盘配置的文件,请参阅以下部分:</p>
+<ul>
+<li><a href="input-device-configuration-files.html">输入设备配置文件</a></li>
+<li><a href="#virtual-key-map-files">虚拟按键映射文件</a></li>
+</ul>
+<h3 id="properties">属性</h3>
+<p>系统依赖于许多输入设备配置属性来配置和校准触摸设备行为。</p>
+<p>原因之一是触摸设备的设备驱动程序通常使用特定于设备的单元来报告触摸特性。</p>
+<p>例如,许多触摸设备使用内部特定于设备的比例(例如由触摸触发的传感器节点的总数)来测量触摸接触面积。此原始尺寸值对应用来说没有意义,因为它们需要了解触摸设备传感器节点的物理尺寸和其他特性。</p>
+<p>系统使用在输入设备配置文件中编码的校准参数,将触摸设备报告的值解码、转换和标准化为应用可以理解的更简单的标准表示。</p>
+<h3 id="documentation-conventions">文档规范</h3>
+<p>对本文档而言,我们将使用以下规范来描述系统在校准过程中使用的值。</p>
+<h4 id="raw-axis-values">原始轴值</h4>
+<p>以下表达式表示触摸设备驱动程序作为 <code>EV_ABS</code> 事件报告的原始值。</p>
+<dl>
+<dt><code>raw.x</code></dt>
+<dd><code>ABS_X</code> 或 <code>ABS_MT_POSITION_X</code> 轴的值。</dd>
+<dt><code>raw.y</code></dt>
+<dd><code>ABS_Y</code> 或 <code>ABS_MT_POSITION_Y</code> 轴的值。</dd>
+<dt><code>raw.pressure</code></dt>
+<dd><code>ABS_PRESSURE</code> 或 <code>ABS_MT_PRESSURE</code> 轴的值,如果未提供,则为 0。</dd>
+<dt><code>raw.touchMajor</code></dt>
+<dd><code>ABS_MT_TOUCH_MAJOR</code> 轴的值,如果未提供,则为 0。</dd>
+<dt><code>raw.touchMinor</code></dt>
+<dd><code>ABS_MT_TOUCH_MINOR</code> 轴的值,如果未提供,则为 <code>raw.touchMajor</code>。</dd>
+<dt><code>raw.toolMajor</code></dt>
+<dd><code>ABS_TOOL_WIDTH</code> 或 <code>ABS_MT_WIDTH_MAJOR</code> 轴的值,如果未提供,则为 0。</dd>
+<dt><code>raw.toolMinor</code></dt>
+<dd><code>ABS_MT_WIDTH_MINOR</code> 轴的值,如果未提供,则为 <code>raw.toolMajor</code>。</dd>
+<dt><code>raw.orientation</code></dt>
+<dd><code>ABS_MT_ORIENTATION</code> 轴的值,如果未提供,则为 0。</dd>
+<dt><code>raw.distance</code></dt>
+<dd><code>ABS_DISTANCE</code> 或 <code>ABS_MT_DISTANCE</code> 轴的值,如果未提供,则为 0。</dd>
+<dt><code>raw.tiltX</code></dt>
+<dd><code>ABS_TILT_X</code> 轴的值,如果未提供,则为 0。</dd>
+<dt><code>raw.tiltY</code></dt>
+<dd><code>ABS_TILT_Y</code> 轴的值,如果未提供,则为 0。</dd>
+</dl>
+<h4 id="raw-axis-ranges">原始轴范围</h4>
+<p>以下表达式表示原始值的范围。通过为每个轴调用 <code>EVIOCGABS</code> ioctl 获得它们。</p>
+<dl>
+<dt><code>raw.*.min</code></dt>
+<dd>原始轴的最小值(含)。</dd>
+<dt><code>raw.*.max</code></dt>
+<dd>原始轴的最大值(含)。</dd>
+<dt><code>raw.*.range</code></dt>
+<dd>相当于 <code>raw.*.max - raw.*.min</code>。</dd>
+<dt><code>raw.*.fuzz</code></dt>
+<dd>原始轴的精度。例如,fuzz = 1 表示值精确到 +/- 1 个单位。</dd>
+<dt><code>raw.width</code></dt>
+<dd>触摸区域的宽度(含),相当于 <code>raw.x.range + 1</code>。</dd>
+<dt><code>raw.height</code></dt>
+<dd>触摸区域的高度(含),相当于 <code>raw.y.range + 1</code>。</dd>
+</dl>
+<h4 id="output-ranges">输出范围</h4>
+<p>以下表达式表示输出坐标系的特性。系统使用线性插值将触摸设备使用的 Surface 单元的触摸位置信息转换成将报告给应用的输出单元(如显示像素)。</p>
+<dl>
+<dt><code>output.width</code></dt>
+<dd>输出宽度。对于触摸屏(与显示屏相关联),输出宽度是显示屏宽度(以像素为单位)。对于触摸板(不与显示屏相关联),输出宽度等于 <code>raw.width</code>,表示不会插入值。</dd>
+<dt><code>output.height</code></dt>
+<dd>输出高度。对于触摸屏(与显示屏相关联),输出高度是显示屏高度(以像素为单位)。对于触摸板(不与显示屏相关联),输出高度等于 <code>raw.height</code>,表示不会插入值。</dd>
+<dt><code>output.diag</code></dt>
+<dd>输出坐标系的对角线长度,相当于 <code>sqrt(output.width ^2 + output.height ^2)</code>。</dd>
+</dl>
+<h3 id="basic-configuration">基础配置</h3>
+<p>触摸输入映射器在输入设备配置文件中使用许多配置属性来指定校准值。下表介绍了一些通用配置属性。在下面的部分中介绍了所有其他属性及其进行校准所用的字段。</p>
+<h4 id="touchdevicetype"><code>touch.deviceType</code></h4>
+<p><em></em>定义:<code>touch.deviceType</code> = <code>touchScreen</code> | <code>touchPad</code> | <code>pointer</code> | <code>default</code></p>
+<p>指定触摸设备类型。</p>
+<ul>
+<li>
+<p>如果值为 <code>touchScreen</code>,则触摸设备是与显示屏相关联的触摸屏。</p>
+</li>
+<li>
+<p>如果值为 <code>touchPad</code>,则触摸设备是不与显示屏相关联的触摸板。</p>
+</li>
+<li>
+<p>如果值为 <code>pointer</code>,则触摸设备是不与显示屏相关联的触摸板,并且其动作用于<a href="#indirect-multi-touch-pointer-gestures">间接多点触控指控手势</a>。</p>
+</li>
+<li>
+<p>如果值为 <code>default</code>,则系统将根据分类算法自动检测设备类型。</p>
+</li>
+</ul>
+<p>有关设备类型如何影响触摸设备的行为的详细信息,请参阅<a href="#touch-device-classification">分类</a>部分。</p>
+<p>在 Honeycomb 之前,所有触摸设备都被视为触摸屏。</p>
+<h4 id="touchorientationaware"><code>touch.orientationAware</code></h4>
+<p><em></em>定义:<code>touch.orientationAware</code> = <code>0</code> | <code>1</code></p>
+<p>指定触摸设备是否应对显示屏的方向更改做出响应。</p>
+<ul>
+<li>
+<p>如果值为 <code>1</code>,则只要显示屏的方向更改了,触摸设备报告的触摸位置就会旋转。</p>
+</li>
+<li>
+<p>如果值为 <code>0</code>,则触摸设备报告的触摸位置将不受显示屏方向更改的影响。</p>
+</li>
+</ul>
+<p>如果设备是触摸屏,则默认值为 <code>1</code>,否则为 <code>0</code>。</p>
+<p>系统会区分内部和外部触摸屏与显示部分。方向感知型内部触摸屏基于内部显示部分的方向进行旋转。方向感知型外部触摸屏基于外部显示部分的方向进行旋转。</p>
+<p>方向感知功能用于支持 Nexus One 等设备上的触摸屏旋转。例如,当设备从其自然方向顺时针旋转 90 度时,触摸的绝对位置将被重新映射,使得在触摸屏绝对坐标系左上角的触摸行为被报告为在显示屏旋转坐标系左上角的触摸行为。这样做是为了使用应用绘制其可见元素时所用的同一坐标系报告触摸行为。</p>
+<p>在 Honeycomb 之前,所有触摸设备都被视为具有方向感知功能。</p>
+<h4 id="touchgesturemode"><code>touch.gestureMode</code></h4>
+<p><em></em>定义:<code>touch.gestureMode</code> = <code>pointer</code> | <code>spots</code> | <code>default</code></p>
+<p>指定指控手势的表示模式。<em></em>仅在触摸设备为指控类型时,该配置属性才具有相关性。</p>
+<ul>
+<li>
+<p>如果值为 <code>pointer</code>,则触摸板手势将通过与鼠标指针相似的光标来表示。</p>
+</li>
+<li>
+<p>如果值为 <code>spots</code>,则触摸板手势由代表手势形心的锚点和代表各个手指位置的一组圆形斑点来表示。</p>
+</li>
+</ul>
+<p>如果设置了 <code>INPUT_PROP_SEMI_MT</code> 输入属性,则默认值为 <code>pointer</code>,否则为 <code>spots</code>。</p>
+<h3 id="x-and-y-fields"><code>X</code> 和 <code>Y</code> 字段</h3>
+<p>X 和 Y 字段给出了接触区域中心的位置信息。</p>
+<h4 id="calculation">计算</h4>
+<p>计算非常简单:来自触摸驱动程序的位置信息被线性插入输出坐标系。</p>
+<pre class="devsite-click-to-copy">
+xScale = output.width / raw.width
+yScale = output.height / raw.height
+
+If not orientation aware or screen rotation is 0 degrees:
+output.x = (raw.x - raw.x.min) * xScale
+output.y = (raw.y - raw.y.min) * yScale
+Else If rotation is 90 degrees:
+    output.x = (raw.y - raw.y.min) * yScale
+    output.y = (raw.x.max - raw.x) * xScale
+Else If rotation is 180 degrees:
+    output.x = (raw.x.max - raw.x) * xScale
+    output.y = (raw.y.max - raw.y) * yScale
+Else If rotation is 270 degrees:
+    output.x = (raw.y.max - raw.y) * yScale
+    output.y = (raw.x - raw.x.min) * xScale
+End If
+</pre>
+<h3 id="touchmajor-touchminor-toolmajor-toolminor-size-fields"><code>TouchMajor</code>、<code>TouchMinor</code>、<code>ToolMajor</code>、<code>ToolMinor</code>、<code>Size</code> 字段</h3>
+<p><code>TouchMajor</code> 和 <code>TouchMinor</code> 字段描述了在输出单元中接触区域的大致维度(单位为像素)。</p>
+<p><code>ToolMajor</code> 和 <code>ToolMinor</code> 字段描述了在输出单元中<a href="#tools-and-tool-types">工具</a>本身的大致维度(单位为像素)。</p>
+<p><code>Size</code> 字段描述了相对于触摸设备可以感知的最大可能触摸区域的标准化触摸区域尺寸。可能的最小标准化尺寸为 0.0(无接触或不可测量),可能的最大标准化尺寸为 1.0(传感器区域已经完全覆盖)。</p>
+<p>如果可以同时测量近似长度和宽度,则 <code>TouchMajor</code> 字段会指定接触区域的较长维度,<code>TouchMinor</code> 字段会指定接触区域的较短维度。如果只能测量接触区域的大致直径,则 <code>TouchMajor</code> 和 <code>TouchMinor</code> 字段将相等。</p>
+<p>同样,<code>ToolMajor</code> 字段会指定工具截断面的较长维度,<code>ToolMinor</code> 字段会指定工具截断面的较短维度。</p>
+<p>如果触摸尺寸不可测量,但工具尺寸可测量,则工具尺寸将设为等于触摸尺寸。相反,如果工具尺寸不可测量,但触摸尺寸可测量,则触摸尺寸将设为等于工具尺寸。</p>
+<p>触摸设备以各种方式测量或报告触摸尺寸和工具尺寸。目前的实现支持三种不同的测量方式:Surface 单元内的直径、面积和几何边界区域。</p>
+<h4 id="touchsizecalibration"><code>touch.size.calibration</code></h4>
+<p><em></em>定义:<code>touch.size.calibration</code> = <code>none</code> | <code>geometric</code> | <code>diameter</code> | <code>area</code> | <code>default</code></p>
+<p>指定触摸驱动程序报告触摸尺寸和工具尺寸时所用的测量类型。</p>
+<ul>
+<li>
+<p>如果值为 <code>none</code>,则尺寸设为零。</p>
+</li>
+<li>
+<p>如果值为 <code>geometric</code>,则假定以与位置相同的 Surface 单元指定尺寸,从而以相同的方式对尺寸进行缩放。</p>
+</li>
+<li>
+<p>如果值为 <code>diameter</code>,则假定尺寸与触摸或工具直径(宽度)成比例。</p>
+</li>
+<li>
+<p>如果值为 <code>area</code>,则假定尺寸与触摸或工具面积成比例。</p>
+</li>
+<li>
+<p>如果值为 <code>default</code>,那么在 <code>raw.touchMajor</code> 或 <code>raw.toolMajor</code> 轴提供值的情况下,系统将使用 <code>geometric</code> 校准,否则将使用 <code>none</code> 校准。</p>
+</li>
+</ul>
+<h4 id="touchsizescale"><code>touch.size.scale</code></h4>
+<p><em></em>定义:<code>touch.size.scale</code> = &lt;非负浮点数&gt;</p>
+<p>指定校准中使用的恒定比例因子。</p>
+<p>默认值为 <code>1.0</code>。</p>
+<h4 id="touchsizebias"><code>touch.size.bias</code></h4>
+<p><em></em>定义:<code>touch.size.bias</code> = &lt;非负浮点数&gt;</p>
+<p>指定校准中使用的恒定偏差值。</p>
+<p>默认值为 <code>0.0</code>。</p>
+<h4 id="touchsizeissummed"><code>touch.size.isSummed</code></h4>
+<p><em></em>定义:<code>touch.size.isSummed</code> = <code>0</code> | <code>1</code></p>
+<p>指定尺寸是报告为所有有效接触区域的尺寸总和,还是针对每个接触区域单独报告尺寸。</p>
+<ul>
+<li>
+<p>如果值为 <code>1</code>,则报告的尺寸需除以接触数量,然后才能使用。</p>
+</li>
+<li>
+<p>如果值为 <code>0</code>,则报告的尺寸将按原样使用。</p>
+</li>
+</ul>
+<p>默认值为 <code>0</code>。</p>
+<p>一些触摸设备(尤其是“Semi-MT”设备)无法区分多个接触点的单个维度,因此它们会报告表示其总面积或宽度的尺寸测量结果。对于此类设备,此属性只能设为 <code>1</code>。如果有疑问,请将此值设为 <code>0</code>。</p>
+<h4 id="calculation_1">计算</h4>
+<p><code>TouchMajor</code>、<code>TouchMinor</code>、<code>ToolMajor</code>、<code>ToolMinor</code> 和 <code>Size</code> 字段的计算方法取决于指定的校准参数。</p>
+<pre class="devsite-click-to-copy">
+If raw.touchMajor and raw.toolMajor are available:
+    touchMajor = raw.touchMajor
+    touchMinor = raw.touchMinor
+    toolMajor = raw.toolMajor
+    toolMinor = raw.toolMinor
+Else If raw.touchMajor is available:
+    toolMajor = touchMajor = raw.touchMajor
+    toolMinor = touchMinor = raw.touchMinor
+Else If raw.toolMajor is available:
+    touchMajor = toolMajor = raw.toolMajor
+    touchMinor = toolMinor = raw.toolMinor
+Else
+    touchMajor = toolMajor = 0
+    touchMinor = toolMinor = 0
+    size = 0
+End If
+
+size = avg(touchMajor, touchMinor)
+
+If touch.size.isSummed == 1:
+    touchMajor = touchMajor / numberOfActiveContacts
+    touchMinor = touchMinor / numberOfActiveContacts
+    toolMajor = toolMajor / numberOfActiveContacts
+    toolMinor = toolMinor / numberOfActiveContacts
+    size = size / numberOfActiveContacts
+End If
+
+If touch.size.calibration == "none":
+    touchMajor = toolMajor = 0
+    touchMinor = toolMinor = 0
+    size = 0
+Else If touch.size.calibration == "geometric":
+    outputScale = average(output.width / raw.width, output.height / raw.height)
+    touchMajor = touchMajor * outputScale
+    touchMinor = touchMinor * outputScale
+    toolMajor = toolMajor * outputScale
+    toolMinor = toolMinor * outputScale
+Else If touch.size.calibration == "area":
+    touchMajor = sqrt(touchMajor)
+    touchMinor = touchMajor
+    toolMajor = sqrt(toolMajor)
+    toolMinor = toolMajor
+Else If touch.size.calibration == "diameter":
+    touchMinor = touchMajor
+    toolMinor = toolMajor
+End If
+
+If touchMajor != 0:
+    output.touchMajor = touchMajor * touch.size.scale + touch.size.bias
+Else
+    output.touchMajor = 0
+End If
+
+If touchMinor != 0:
+    output.touchMinor = touchMinor * touch.size.scale + touch.size.bias
+Else
+    output.touchMinor = 0
+End If
+
+If toolMajor != 0:
+    output.toolMajor = toolMajor * touch.size.scale + touch.size.bias
+Else
+    output.toolMajor = 0
+End If
+
+If toolMinor != 0:
+    output.toolMinor = toolMinor * touch.size.scale + touch.size.bias
+Else
+    output.toolMinor = 0
+End If
+
+output.size = size
+</pre>
+<h3 id="pressure-field"><code>Pressure</code> 字段</h3>
+<p><code>Pressure</code> 字段描述了以介于 0.0(无接触)和 1.0(全力)之间的标准化值形式施加到触摸设备的近似物理压力。</p>
+<p>零压力表示工具处于悬停状态。</p>
+<h4 id="touchpressurecalibration"><code>touch.pressure.calibration</code></h4>
+<p><em></em>定义:<code>touch.pressure.calibration</code> = <code>none</code> | <code>physical</code> | <code>amplitude</code> | <code>default</code></p>
+<p>指定触摸驱动程序报告压力所用的测量类型。</p>
+<ul>
+<li>
+<p>如果值为 <code>none</code>,压力未知,因此触摸时设置为 1.0,悬停时为 0.0。</p>
+</li>
+<li>
+<p>如果值为 <code>physical</code>,则认为压力轴测量的是施加到触摸板的压力的实际物理强度。</p>
+</li>
+<li>
+<p>如果值为 <code>amplitude</code>,则认为压力轴测量的是信号幅度(与接触的尺寸和施加的压力有关)。</p>
+</li>
+<li>
+<p>如果值为 <code>default</code>,在压力轴可用的情况下,系统将使用 <code>physical</code> 校准,否则使用 <code>none</code>。</p>
+</li>
+</ul>
+<h4 id="touchpressurescale"><code>touch.pressure.scale</code></h4>
+<p><em></em>定义:<code>touch.pressure.scale</code> = &lt;非负浮点数&gt;</p>
+<p>指定校准中使用的恒定比例因子。</p>
+<p>默认值为 <code>1.0 / raw.pressure.max</code>。</p>
+<h4 id="calculation_2">计算</h4>
+<p><code>Pressure</code> 字段的计算方法取决于指定的校准参数。</p>
+<pre class="devsite-click-to-copy">If touch.pressure.calibration == "physical" or "amplitude":
+    output.pressure = raw.pressure * touch.pressure.scale
+Else
+    If hovering:
+        output.pressure = 0
+    Else
+        output.pressure = 1
+    End If
+End If
+</pre>
+<h3 id="orientation-and-tilt-fields"><code>Orientation</code> 和 <code>Tilt</code> 字段</h3>
+<p><code>Orientation</code> 字段以角度测量的形式描述了触摸和工具的方向。值 <code>0</code> 表示长轴垂直取向,<code>-PI/2</code> 表示长轴朝向左侧,<code>PI/2</code> 表示长轴朝向右侧。当存在触控笔工具时,方向范围可以是从 <code>-PI</code> 到 <code>PI</code> 的整个圆环范围。</p>
+<p><code>Tilt</code> 字段通过测量角度描述了工具的倾斜度。倾斜度为 <code>0</code> 表示工具垂直于表面。倾斜度为 <code>PI/2</code> 表示工具与表面平行。</p>
+<h4 id="touchorientationcalibration"><code>touch.orientation.calibration</code></h4>
+<p><em></em>定义:<code>touch.orientation.calibration</code> = <code>none</code> | <code>interpolated</code> | <code>vector</code> | <code>default</code></p>
+<p>指定触摸驱动程序报告方向时所用的测量类型。</p>
+<ul>
+<li>
+<p>如果值为 <code>none</code>,则方向未知,因此设为 0。</p>
+</li>
+<li>
+<p>如果值为 <code>interpolated</code>,则方向被线性插入,使得 <code>raw.orientation.min</code> 的原始值映射到 <code>-PI/2</code>,<code>raw.orientation.max</code> 的原始值映射到 <code>PI/2</code>。<code>(raw.orientation.min + raw.orientation.max) / 2</code> 的中心值映射到 <code>0</code>。</p>
+</li>
+<li>
+<p>如果值为 <code>vector</code>,则方向表示为包含两个带符号的 4 位字段的压缩向量。该表示用于 Atmel 基于对象的协议部分。当解码时,向量生成定向角和置信度。置信度用于缩放尺寸信息,除非它是几何图形。</p>
+</li>
+<li>
+<p>如果值为 <code>default</code>,那么在方向轴可用的情况下,系统将使用 <code>interpolated</code> 校准,否则使用 <code>none</code>。</p>
+</li>
+</ul>
+<h4 id="calculation_3">计算</h4>
+<p><code>Orientation</code> 和 <code>Tilt</code> 字段的计算方法取决于指定的校准参数和可用输入。</p>
+<pre class="devsite-click-to-copy">
+If touch.tiltX and touch.tiltY are available:
+    tiltXCenter = average(raw.tiltX.min, raw.tiltX.max)
+    tiltYCenter = average(raw.tiltY.min, raw.tiltY.max)
+    tiltXAngle = (raw.tiltX - tiltXCenter) * PI / 180
+    tiltYAngle = (raw.tiltY - tiltYCenter) * PI / 180
+    output.orientation = atan2(-sin(tiltXAngle), sinf(tiltYAngle))
+    output.tilt = acos(cos(tiltXAngle) * cos(tiltYAngle))
+Else If touch.orientation.calibration == "interpolated":
+    center = average(raw.orientation.min, raw.orientation.max)
+    output.orientation = PI / (raw.orientation.max - raw.orientation.min)
+    output.tilt = 0
+Else If touch.orientation.calibration == "vector":
+    c1 = (raw.orientation &amp; 0xF0) &gt;&gt; 4
+    c2 = raw.orientation &amp; 0x0F
+
+    If c1 != 0 or c2 != 0:
+        If c1 &gt;= 8 Then c1 = c1 - 16
+        If c2 &gt;= 8 Then c2 = c2 - 16
+        angle = atan2(c1, c2) / 2
+        confidence = sqrt(c1*c1 + c2*c2)
+
+        output.orientation = angle
+
+        If touch.size.calibration == "diameter" or "area":
+            scale = 1.0 + confidence / 16
+            output.touchMajor *= scale
+            output.touchMinor /= scale
+            output.toolMajor *= scale
+            output.toolMinor /= scale
+        End If
+    Else
+        output.orientation = 0
+    End If
+    output.tilt = 0
+Else
+    output.orientation = 0
+    output.tilt = 0
+End If
+
+If orientation aware:
+    If screen rotation is 90 degrees:
+        output.orientation = output.orientation - PI / 2
+    Else If screen rotation is 270 degrees:
+        output.orientation = output.orientation + PI / 2
+    End If
+End If
+</pre>
+<h3 id="distance-field"><code>Distance</code> 字段</h3>
+<p><code>Distance</code> 字段描述了工具和触摸设备表面之间的距离。值 0.0 表示直接接触,值越大,表示与表面之间的距离越远。</p>
+<h4 id="touchdistancecalibration"><code>touch.distance.calibration</code></h4>
+<p><em></em>定义:<code>touch.distance.calibration</code> = <code>none</code> | <code>scaled</code> | <code>default</code></p>
+<p>指定触摸驱动程序报告距离时所用的测量类型。</p>
+<ul>
+<li>
+<p>如果值为 <code>none</code>,则距离未知,因此设为 0。</p>
+</li>
+<li>
+<p>如果值为 <code>scaled</code>,则报告的距离将乘以恒定比例因子。</p>
+</li>
+<li>
+<p>如果值为 <code>default</code>,则在距离轴可用的情况下,系统将使用 <code>scaled</code> 校准,否则使用 <code>none</code>。</p>
+</li>
+</ul>
+<h4 id="touchdistancescale"><code>touch.distance.scale</code></h4>
+<p><em></em>定义:<code>touch.distance.scale</code> = &lt;非负浮点数&gt;</p>
+<p>指定校准中使用的恒定比例因子。</p>
+<p>默认值为 <code>1.0</code>。</p>
+<h4 id="calculation_4">计算</h4>
+<p><code>Distance</code> 字段的计算方法取决于指定的校准参数。</p>
+<pre class="devsite-click-to-copy">If touch.distance.calibration == "scaled":
+    output.distance = raw.distance * touch.distance.scale
+Else
+    output.distance = 0
+End If
+</pre>
+<h3 id="example">示例</h3>
+<pre class="devsite-click-to-copy">
+# Input device configuration file for a touch screen that supports pressure,
+# size and orientation.  The pressure and size scale factors were obtained
+# by measuring the characteristics of the device itself and deriving
+# useful approximations based on the resolution of the touch sensor and the
+# display.
+#
+# Note that these parameters are specific to a particular device model.
+# Different parameters will need to be used for other devices.
+
+# Basic Parameters
+touch.deviceType = touchScreen
+touch.orientationAware = 1
+
+# Size
+# Based on empirical measurements, we estimate the size of the contact
+# using size = sqrt(area) * 28 + 0.
+touch.size.calibration = area
+touch.size.scale = 28
+touch.size.bias = 0
+touch.size.isSummed = 0
+
+# Pressure
+# Driver reports signal strength as pressure.
+#
+# A normal index finger touch typically registers about 80 signal strength
+# units although we don't expect these values to be accurate.
+touch.pressure.calibration = amplitude
+touch.pressure.scale = 0.0125
+
+# Orientation
+touch.orientation.calibration = vector
+</pre>
+<h3 id="compatibility-notes">兼容性说明</h3>
+<p>触摸设备的配置属性在 Android Ice Cream Sandwich 4.0 中发生了重大变化。<strong>必须更新触摸设备的所有输入设备配置文件,才能使用新配置属性。</strong></p>
+<p>更旧的触摸设备<a href="#touch-device-driver-requirements">驱动程序</a>可能也需要更新。</p>
+<h2 id="virtual-key-map-files">虚拟按键映射文件</h2>
+<p>触摸设备经常用于实现虚拟按键。</p>
+<p>有几种方法可以做到这一点,具体取决于触摸控制器的功能。一些触摸控制器可以直接配置为通过设置固件寄存器来实现软键。其他时候,最好在软件中执行从触摸坐标到按键代码的映射。</p>
+<p>在软件中实现虚拟按键时,内核必须将名为 <code>virtualkeys.&lt;devicename&gt;</code> 的虚拟按键映射文件作为本机已加载属性导出。例如,如果触摸屏设备驱动程序将其名称报告为“touchyfeely”,则虚拟按键映射文件的路径必须为 <code>/sys/board_properties/virtualkeys.touchyfeely</code>。</p>
+<p>虚拟按键映射文件描述了触摸屏上虚拟按键的坐标和 Linux 按键代码。</p>
+<p>除了虚拟按键映射文件外,还必须有一个对应的按键布局文件和按键字符映射文件,以将 Linux 按键代码映射到 Android 按键代码,并指定键盘设备的类型(通常为 <code>SPECIAL_FUNCTION</code>)。</p>
+<h3 id="syntax">语法</h3>
+<p>虚拟按键映射文件是一个纯文本文件,由一系列用换行符或冒号分隔的虚拟按键布局描述组成。</p>
+<p>注释行以“#”开头,并持续到这一行的结束位置。</p>
+<p>每个虚拟按键用由 6 个冒号分隔的组件进行描述:</p>
+<ul>
+<li><code>0x01</code>:版本代码。必须始终为 <code>0x01</code>。</li>
+<li>&lt;Linux key code&gt;:虚拟按键的 Linux 按键代码。</li>
+<li>&lt;centerX&gt;:虚拟按键中心的 X 轴坐标(以像素为单位)。</li>
+<li>&lt;centerY&gt;:虚拟按键中心的 Y 轴坐标(以像素为单位)。</li>
+<li>&lt;width&gt;:虚拟按键的宽度(以像素为单位)。</li>
+<li>&lt;height&gt;:虚拟按键的高度(以像素为单位)。</li>
+</ul>
+<p>所有的坐标和尺寸都是根据显示坐标系指定的。</p>
+<p>下面是一个虚拟按键映射文件,全部写在一行上。</p>
+<pre class="devsite-click-to-copy">
+# All on one line
+0x01:158:55:835:90:55:0x01:139:172:835:125:55:0x01:102:298:835:115:55:0x01:217:412:835:95:55
+</pre>
+<p>相同的虚拟按键映射文件也可以写在多行上。</p>
+<pre class="devsite-click-to-copy">
+# One key per line
+0x01:158:55:835:90:55
+0x01:139:172:835:125:55
+0x01:102:298:835:115:55
+0x01:217:412:835:95:55
+</pre>
+<p>在上述示例中,触摸屏具有 480×800 的分辨率。因此,所有虚拟按键的 &lt;centerY&gt; 坐标为 835,位于略低于触摸屏可见区域的位置。</p>
+<p>第一个按键的 Linux 扫描代码为 <code>158</code> (<code>KEY_BACK</code>),centerX 为 <code>55</code>,centerY 为 <code>835</code>,width 为 <code>90</code>,height 为 <code>55</code>。</p>
+<h3 id="example_1">示例</h3>
+<p>虚拟按键映射文件:<code>/sys/board_properties/virtualkeys.touchyfeely</code>。</p>
+<pre class="devsite-click-to-copy">
+0x01:158:55:835:90:55
+0x01:139:172:835:125:55
+0x01:102:298:835:115:55
+0x01:217:412:835:95:55
+</pre>
+<p>按键布局文件:<code>/system/usr/keylayout/touchyfeely.kl</code>。</p>
+<pre class="devsite-click-to-copy">key 158 BACK
+key 139 MENU
+key 102 HOME
+key 217 SEARCH
+</pre>
+<p>按键字符映射文件:<code>/system/usr/keychars/touchyfeely.kcm</code>。</p>
+<pre class="devsite-click-to-copy">
+type SPECIAL_FUNCTION
+</pre>
+<h2 id="indirect-multi-touch-pointer-gestures">间接多点触控指控手势</h2>
+<p>在指控模式下,系统会解释以下手势:</p>
+<ol>
+<li>
+<p>单指点按:点击。</p>
+</li>
+<li>
+<p>单指移动:移动指针。</p>
+</li>
+<li>
+<p>单指移动加按下按钮:拖动指针。</p>
+</li>
+<li>
+<p>两个手指移动(两个手指沿相同的方向移动):沿着该方向拖动指针下方的区域。指针本身不动。</p>
+</li>
+<li>
+<p>两个手指移动(两个手指朝着彼此移动或者移向不同方向):平移/缩放/旋转指针周围的区域。指针本身不动。</p>
+</li>
+<li>
+<p>多个手指移动:自由手势。</p>
+</li>
+</ol>
+<h2 id="further-reading">延伸阅读</h2>
+<ol>
+<li><a href="http://www.kernel.org/doc/Documentation/input/multi-touch-protocol.txt">Linux 多点触控协议</a></li>
+<li><a href="http://lii-enac.fr/en/architecture/linux-input/multitouch-devices.html">ENAC 列出的在 Linux 上可用的多点触控设备</a></li>
+</ol>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/input/validate-keymaps.html b/zh-cn/devices/input/validate-keymaps.html
new file mode 100644
index 0000000..de11f09
--- /dev/null
+++ b/zh-cn/devices/input/validate-keymaps.html
@@ -0,0 +1,92 @@
+<html devsite><head>
+    <title>验证按键映射工具</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 The Android Open Source Project
+
+      Licensed under the Apache License, Version 2.0 (the "License");
+      you may not use this file except in compliance with the License.
+      You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      See the License for the specific language governing permissions and
+      limitations under the License.
+  -->
+
+<p>Android 框架有一个名为 <code>validatekeymaps</code> 的小工具,用于验证输入设备配置文件、按键布局文件、按键字符映射文件和虚拟按键定义文件的语法。</p>
+<h2 id="compilation">编译</h2>
+<p>要编译 <code>validatekeymaps</code>,请设置开发环境,下载 Android 源代码树,对其进行编译,然后运行以下命令:</p>
+<pre class="devsite-terminal devsite-click-to-copy">
+mmm frameworks/base/tools/validatekeymaps
+</pre>
+<p>该命令应该会将一个名为 validatekeymaps 的主机工具编译到 <code>out/host/&lt;os&gt;/bin</code> 目录中。</p>
+<h2 id="usage">使用</h2>
+<p>如果您通过运行 <code>envsetup.sh</code> 设置了开发环境,那么 <code>validatekeymaps</code> 工具应当已经位于您的路径中。您可以通过运行 <code>validatekeymaps</code> 进行验证。</p>
+<pre class="devsite-terminal devsite-click-to-copy">
+validatekeymaps
+</pre>
+<p>您应该会看到以下输出内容:</p>
+<pre>
+Keymap Validation Tool
+
+Usage:
+ validatekeymaps [*.kl] [*.kcm] [*.idc] [virtualkeys.*] [...]
+   Validates the specified key layouts, key character maps,
+   input device configurations, or virtual key definitions.
+</pre>
+<p>然后,您只需运行 <code>validatekeymaps</code>,并为其提供一个或多个要进行验证的文件的路径。</p>
+<pre class="devsite-terminal devsite-click-to-copy">
+validatekeymaps frameworks/base/data/keyboards/Generic.kl
+</pre>
+<p>示例:</p>
+<pre>
+Validating file 'frameworks/base/data/keyboards/Generic.kl'...
+No errors.
+
+Success.
+</pre>
+<p>如果出现错误…</p>
+<pre class="devsite-terminal devsite-click-to-copy">
+validatekeymaps Bad.kl
+</pre>
+<p>示例:</p>
+<pre>
+Validating file 'Bad.kl'...
+E/KeyLayoutMap(87688): Bad.kl:24: Expected keyword, got 'ke'.
+Error -22 parsing key layout file.
+
+Failed!
+</pre>
+<h2 id="automation">自动化</h2>
+<p><em></em>最好先在所有配置文件上运行 <code>validatekeymaps</code>,然后再将这些文件安装到设备中。</p>
+<p>通过使用脚本或 makefile,该过程可以作为编译系统的一部分轻松地自动执行。</p>
+<p>以下示例 Makefile 基于 <code>frameworks/base/data/keyboards/Android.mk</code> 的内容。</p>
+<pre class="devsite-click-to-copy">
+# This makefile performs build time validation of framework keymap files.
+
+LOCAL_PATH := $(call my-dir)
+
+# Validate all key maps.
+include $(CLEAR_VARS)
+
+validatekeymaps := $(HOST_OUT_EXECUTABLES)/validatekeymaps$(HOST_EXECUTABLE_SUFFIX)
+files := MyKeyboard.kl MyKeyboard.kcm MyTouchScreen.idc
+
+LOCAL_MODULE := validate_framework_keymaps
+LOCAL_MODULE_TAGS := optional
+LOCAL_REQUIRED_MODULES := validatekeymaps
+
+validate_framework_keymaps: $(files)
+    $(hide) $(validatekeymaps) $(files)
+
+include $(BUILD_PHONY_PACKAGE)
+</pre>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/media/framework-hardening.html b/zh-cn/devices/media/framework-hardening.html
new file mode 100644
index 0000000..03f3da9
--- /dev/null
+++ b/zh-cn/devices/media/framework-hardening.html
@@ -0,0 +1,107 @@
+<html devsite><head>
+    <title>媒体框架强化</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 The Android Open Source Project
+
+      Licensed under the Apache License, Version 2.0 (the "License");
+      you may not use this file except in compliance with the License.
+      You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      See the License for the specific language governing permissions and
+      limitations under the License.
+  -->
+
+<p>为了提高设备安全性,Android 7.0 将整体的 <code>mediaserver</code> 进程分解为多个进程,同时仅向各个进程提供所需的权限和功能。这些变更通过以下方式减少了媒体框架安全漏洞:</p>
+<ul>
+<li>将 AV 管道组件拆分为应用专用的沙盒进程。</li>
+<li>启用可更新的媒体组件(提取器、编解码器等)。</li>
+</ul>
+
+<p>这些变更还大大降低了大多数媒体相关安全漏洞的严重程度,确保最终用户的设备和数据安全,从而提高了最终用户的安全性。</p>
+
+<p>原始设备制造商 (OEM) 和 SoC 供应商需要更新他们的 HAL 和框架变更,使之与新架构兼容。具体来说,由于供应商提供的 Android 代码通常假定所有内容均在同一进程中运行,因此,供应商必须更新其代码以传递对于各进程均有意义的本机句柄 (<code>native_handle</code>)。有关媒体强化相关变更的参考实现,请参阅 <code>frameworks/av</code> 和 <code>frameworks/native</code>。</p>
+
+<h2 id="arch_changes">架构变更</h2>
+<p>旧版 Android 使用单个整体的 <code>mediaserver</code> 进程,该进程具有众多权限(相机访问权、音频访问权、视频驱动程序访问权、文件访问权、网络访问权等)。Android 7.0 将 <code>mediaserver</code> 进程拆分为几个新进程,这些进程要求的权限要少得多:</p>
+
+<p><img src="images/ape_media_split.png" alt="mediaserver 强化"/></p>
+<p class="img-caption"><strong>图 1. </strong> mediaserver 强化的架构变更</p>
+
+<p>采用这种新型架构之后,即使某个进程遭到入侵,恶意代码也无法获得之前 mediaserver 所拥有的全部权限。进程受 SElinux 和 seccomp 政策的限制。
+</p>
+
+<p class="note"><strong>注意</strong>:由于供应商依赖项的原因,有些编解码器仍在 <code>mediaserver</code> 中运行,因此会为 <code>mediaserver</code> 授予非必要的权限。具体来说,Widevine Classic 将继续在 Android 7.0 的 <code>mediaserver</code> 中运行。</p>
+
+<h3 id="mediaserver-changes">MediaServer 变更</h3>
+<p>在 Android 7.0 中,<code>mediaserver</code> 进程用于驱动播放和录制,例如在组件与进程之间传递和同步缓冲区。进程通过标准的 Binder 机制进行通信。</p>
+<p>在标准的本地文件播放会话中,应用将文件描述符 (FD) 传递到 <code>mediaserver</code>(通常通过 MediaPlayer Java API),而 <code>mediaserver</code> 将执行以下操作:</p>
+<ol>
+<li>将 FD 封装到已传递给提取器进程的 Binder DataSource 对象中,提取器进程利用该对象读取使用 Binder IPC 的文件。(mediaextractor 不获取 FD,而是通过对 <code>mediaserver</code> 执行 Binder 回调来获取数据。)</li>
+<li>检查文件,针对该文件类型创建适当的提取器(例如 MP3Extractor 或 MPEG4Extractor),然后将提取器的 Binder 接口返回到 <code>mediaserver</code> 进程。</li>
+<li>对提取器执行 Binder IPC 调用,以确定文件中的数据类型(例如 MP3 或 H.264 数据)。</li>
+<li>调用 <code>mediacodec</code> 进程来创建所需类型的编解码器;接收这些编解码器的 Binder 接口。</li>
+<li>对提取器执行重复的 Binder IPC 调用以读取编码的示例,使用 Binder IPC 将编码的数据发送到 <code>mediacodec</code> 进程进行解码,然后接收解码的数据。</li>
+</ol>
+<p>某些用例不涉及任何编解码器(例如分流播放,这种播放会将编码的数据直接发送到输出设备),或者编解码器可能会直接呈现解码的数据,而不是返回解码数据的缓冲区(视频播放)。</p>
+
+<h3 id="mediacodecservice_changes">MediaCodecService 变更</h3>
+<p>编码器和解码器位于编解码器服务中。由于供应商依赖项的原因,并非所有编解码器都位于编解码器进程中。在 Android 7.0 中:</p>
+<ul>
+<li>非安全解码器和软件编码器位于编解码器进程中。</li>
+<li>安全解码器和硬件编码器位于 <code>mediaserver</code>(未变更)中。</li>
+</ul>
+
+<p>应用(或 mediaserver)调用编解码器进程来创建所需类型的编解码器,然后调用该编解码器传递编码的数据并检索解码的数据(解码),或者传递解码的数据并检索编码的数据(编码)。传入编解码器以及从中传出的数据已经使用了共享内存,因此该进程未发生改变。</p>
+
+<h3 id="mediadrmserver_changes">MediaDrmServer 变更</h3>
+<p>在播放受 DRM 保护的内容(例如 Google Play 电影中的影片)时,会使用 DRM 服务器。该服务器会采用安全方式对加密的数据进行解密,因此可以访问证书和密钥存储以及其他敏感组件。由于供应商依赖关系,DRM 进程尚未应用于所有情况。</p>
+
+<h3 id="audioserver_changes">AudioServer 变更</h3>
+<p>AudioServer 进程负责托管音频相关组件,例如音频输入和输出、确定音频转接的 policymanager 服务,以及 FM 电台服务。要详细了解音频变更和实现指南,请参阅<a href="/devices/audio/implement.html">实现音频</a>。</p>
+
+<h3 id="cameraserver_changes">CameraServer 变更</h3>
+<p>CameraServer 负责控制相机,并且在录制视频时用于从相机获取视频帧,然后将其传递给 <code>mediaserver</code> 进行进一步处理。要详细了解 CameraServer 变更和实现指南,请参阅<a href="/devices/camera/versioning.html#hardening">相机框架强化</a>。</p>
+
+<h3 id="extractor_service_changes">ExtractorService 变更</h3>
+<p>提取器服务负责托管提取器,即可解析媒体框架支持的各种文件格式的组件。<em></em>提取器服务是所有服务中权限最少的,它无法读取 FD,因此通过调用 Binder 接口(由各个播放会话的 <code>mediaserver for</code> 向其提供)来访问文件。</p>
+<p>应用(或 <code>mediaserver</code>)调用提取器进程来获取 <code>IMediaExtractor</code>,调用该 <code>IMediaExtractor</code> 来获取文件中包含的曲目的 <code> IMediaSources</code>,然后调用 <code>IMediaSources</code> 来读取其中的数据。</p>
+<p>为了在进程之间传输数据,应用(或 <code>mediaserver</code>)将 reply-Parcel 中的数据添加为 Binder 事务的一部分或使用共享内存:</p>
+
+<ul>
+<li>使用<strong>共享内存</strong>需要进行额外的 Binder 调用来释放共享内存,但这样可以加快速度并降低大型缓冲区的功耗。
+</li>
+<li>使用 <strong>in-Parcel</strong> 需要执行额外的复制操作,但对于小于 64KB 的缓冲区来说,这样可以加快速度并降低功耗。</li>
+</ul>
+
+<h2 id="implementation">实现</h2>
+<p>为了支持将 <code>MediaDrm</code> 和 <code>MediaCrypto</code> 组件移动到新的 <code>mediadrmserver</code> 进程,供应商必须更改安全缓冲区的分配方法,以允许在进程之间共享缓冲区。</p>
+<p>在旧版 Android 中,安全缓冲区由 <code>OMX::allocateBuffer</code> 在 <code>mediaserver</code> 中分配,并在同一进程的解密过程中使用,如下图所示:</p>
+
+<p><img src="images/ape_media_buffer_alloc_pren.png"/></p>
+<p class="img-caption"><strong>图 2. </strong> Android 6.0 及更低版本中的 mediaserver 中的缓冲区分配。</p>
+
+<p>在 Android 7.0 中,缓冲区分配进程已变更为一种新机制,可在提供灵活性的同时最大限度地减少对现有实现的影响。通过使用新的 <code>mediadrmserver</code> 进程中的 <code>MediaDrm</code> 和 <code>MediaCrypto</code> 堆栈,缓冲区将以不同的方法进行分配,而供应商必须更新安全缓冲区句柄,以便当 <code>MediaCodec</code> 在 <code>MediaCrypto</code> 上调用解密操作时可以进行跨 binder 传输。</p>
+
+<p><img src="images/ape_media_buffer_alloc_n.png"/></p>
+<p class="img-caption"><strong>图 3. </strong> Android 7.0 及更高版本中的 mediaserver 中的缓冲区分配。</p>
+
+<h3 id="native_handles">使用本机句柄</h3>
+<p><code>OMX::allocateBuffer</code> 必须返回一个指向 <code>native_handle</code> 结构的指针,其中包含文件描述符 (FD) 和其他整数数据。<code>native_handle</code> 具有使用 FD 的所有优势,包括对序列化/反序列化的现有 binder 支持,可为当前不使用 FD 的供应商提供更多灵活性。</p>
+<p>使用 <code>native_handle_create()</code> 分配本机句柄。框架代码拥有已分配的 <code>native_handle</code> 结构的所有权,并负责在最初分配 <code>native_handle</code> 的进程以及对其进行反序列化的进程中释放资源。该框架依次使用 <code>native_handle_close()</code> 和 <code>native_handle_delete()</code> 释放本机句柄,然后使用 <code>Parcel::writeNativeHandle()/readNativeHandle()</code> 对 <code>native_handle</code> 进行序列化/反序列化。
+</p>
+<p>使用 FD 表示安全缓冲区的 SoC 供应商可以使用其 FD 来填充 <code>native_handle</code> 中的 FD。不使用 FD 的供应商可以使用 <code>native_buffer</code> 中的其他字段来表示安全缓冲区。</p>
+
+<h3 id="decrypt_location">设置解密位置</h3>
+<p>供应商必须更新在 <code>native_handle</code> 上运行的 OEMCrypto 解密方法,以执行任何必要的供应商特定操作,以使 <code>native_handle</code> 在新的进程空间中可用(变更通常包括对 OEMCrypto 库的更新)。</p>
+<p><code>allocateBuffer</code> 是一种标准 OMX 操作,Android 7.0 中包含用于查询此项支持的全新 OMX 扩展程序 (<code>OMX.google.android.index.allocateNativeHandle</code>),以及通知 OMX 实现应当使用本机句柄的 <code>OMX_SetParameter</code> 调用。</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/media/oem.html b/zh-cn/devices/media/oem.html
new file mode 100644
index 0000000..5a5e0db
--- /dev/null
+++ b/zh-cn/devices/media/oem.html
@@ -0,0 +1,132 @@
+<html devsite><head>
+    <title>媒体资源管理器的 OEM 依赖项</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 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>本文档旨在帮助原始设备制造商 (OEM) 正确实现对 Android 媒体资源管理器和相关 API 的支持。</p>
+
+<h2 id="1_max_concurrent_codec_instances">1. 最大并发编解码器实例数量</h2>
+
+<p><code>CodecCapabilities.getMaxSupportedInstances</code> 接口返回支持的并发编解码器实例的最大数量。</p>
+
+<p>CTS 测试 <code>testGetMaxSupportedInstances(android.media.cts.MediaCodecCapabilitiesTest)</code> 用于强制在 <code>/etc/media_codecs.xml</code> 中设置合适的最大值。</p>
+
+<p>示例如下:</p>
+
+<pre class="devsite-click-to-copy">
+...
+&lt;MediaCodecs&gt;
+    ...
+    &lt;Encoders&gt;
+        &lt;MediaCodec name="OMX.<em>&lt;vendor&gt;</em>.video.encoder.avc" type="video/avc" &gt;
+           ...
+            &lt;Limit name="concurrent-instances" max="13" /&gt;
+        &lt;/MediaCodec&gt;
+        ...
+    &lt;/Encoders&gt;
+    ...
+&lt;/MediaCodecs&gt;
+</pre>
+
+<p>OEM 可以使用此测试来生成可通过测试的并发限制。具体操作步骤如下:</p>
+
+  <ol>
+    <li>首先使用 cts-tradefed 运行测试。
+    </li><li>评估生成的失败消息。示例如下:<pre class="devsite-click-to-copy">
+There was 1 failure:
+1) testGetMaxSupportedInstances(android.media.cts.MediaCodecCapabilitiesTest)
+junit.framework.AssertionFailedError: In order to pass the test, please publish
+following codecs' concurrent instances limit in /etc/media_codecs.xml:
+&lt;MediaCodec name="OMX.<em>&lt;vendor&gt;</em>.video.encoder.mpeg4" type="video/mp4v-es" &gt;
+    &lt;Limit name="concurrent-instances" max="13" /&gt;
+&lt;/MediaCodec&gt;
+&lt;MediaCodec name="OMX.<em>&lt;vendor&gt;</em>.video.encoder.h263" type="video/3gpp" &gt;
+    &lt;Limit name="concurrent-instances" max="13" /&gt;
+&lt;/MediaCodec&gt;
+&lt;MediaCodec name="OMX.<em>&lt;vendor&gt;</em>.video.encoder.avc" type="video/avc" &gt;
+    &lt;Limit name="concurrent-instances" max="13" /&gt;
+&lt;/MediaCodec&gt;
+&lt;MediaCodec name="OMX.<em>&lt;vendor&gt;</em>.video.encoder.vp8" type="video/x-vnd.on2.vp8" &gt;
+    &lt;Limit name="concurrent-instances" max="13" /&gt;
+&lt;/MediaCodec&gt;
+&lt;MediaCodec name="OMX.<em>&lt;vendor&gt;</em>.video.decoder.avc" type="video/avc" &gt;
+    &lt;Limit name="concurrent-instances" max="13" /&gt;
+&lt;/MediaCodec&gt;
+&lt;MediaCodec name="OMX.<em>&lt;vendor&gt;</em>.video.decoder.avc.secure" type="video/avc" &gt;
+    &lt;Limit name="concurrent-instances" max="4" /&gt;
+&lt;/MediaCodec&gt;
+&lt;MediaCodec name="OMX.<em>&lt;vendor&gt;</em>.video.decoder.mpeg4" type="video/mp4v-es" &gt;
+    &lt;Limit name="concurrent-instances" max="12" /&gt;
+&lt;/MediaCodec&gt;
+&lt;MediaCodec name="OMX.<em>&lt;vendor&gt;</em>.video.decoder.h263" type="video/3gpp" &gt;
+    &lt;Limit name="concurrent-instances" max="12" /&gt;
+&lt;/MediaCodec&gt;
+&lt;MediaCodec name="OMX.<em>&lt;vendor&gt;</em>.video.decoder.vp8" type="video/x-vnd.on2.vp8" &gt;
+    &lt;Limit name="concurrent-instances" max="12" /&gt;
+&lt;/MediaCodec&gt;
+</pre>
+
+    </li><li>将测试失败消息中建议的 <code>concurrent-instances</code> 行添加到 <code>/etc/media_codecs.xml</code> 文件。
+
+    </li><li>重新运行测试以验证测试是否成功。
+  </li></ol>
+
+<h2 id="2_achievable_frame_rates_for_video_codecs">2. 视频编解码器可实现的帧速率</h2>
+<p><code>VideoCapabilities.getAchievableFrameRatesFor</code> 接口针对某个视频大小返回可实现的视频帧率的范围。此信息必须由 OEM 通过位于 <code>/etc/media_codecs_performance.xml</code> 的 XML 文件为每个设备提供。这些设置由 <code>com.android.cts.videoperf.VideoEncoderDecoderTest</code> 和 <code>android.media.cts.VideoDecoderPerfTest</code> CTS 测试进行测试。</p>
+
+<p>OEM 可以使用 CTS 测试来生成可通过测试的 XML 文件。具体操作步骤如下:</p>
+  <ol>
+    <li>首先使用 cts-tradefed 运行测试。鉴于 Android 性能的波动性,建议多次运行测试以获得更准确的最小值和最大值。
+    </li><li>使用提供的 <a href="https://android.googlesource.com/platform/cts/+/marshmallow-cts-dev/tools/cts-media/get_achievable_rates.py">get_achievable_rates.py</a> 脚本生成 XML 文件。
+    </li><li>将 XML 文件放置在以下位置:<code>/etc/media_codecs_performance.xml</code><br />通常通过将 XML 文件放置在设备项目 (device/<em>&lt;vendor&gt;</em>/<em>&lt;product&gt;</em>) 中并将 <code>PRODUCT_COPY_FILES</code> 行添加到 <code>device.mk</code> 来完成此过程,如下所示:<pre class="devsite-click-to-copy">
+PRODUCT_COPY_FILES += \
+...
+   device/moto/shamu/media_codecs.xml:system/etc/media_codecs.xml \
++    device/moto/shamu/media_codecs_performance.xml:system/etc/media_codecs_performance.xml
+</pre>
+    </li><li>重新运行性能测试以验证测试是否成功。
+  </li></ol>
+
+<h2 id="3_co-exist_of_secure_codec_and_non-secure_codec">3. 安全编解码器和非安全编解码器共存</h2>
+
+<ul>
+  <li>supports-secure-with-non-secure-codec - 如果安全编解码器实例和非安全编解码器实例不能同时共存,则应在 <code>media_codecs.xml</code> 文件中作为全局设置指明。
+<pre class="devsite-click-to-copy">
+&lt;MediaCodecs&gt;
+    &lt;Settings&gt;
+        &lt;Setting name="supports-secure-with-non-secure-codec" value="false" /&gt;
+    &lt;/Settings&gt;
+    &lt;Encoders&gt;
+…
+</pre>
+  </li><li>supports-multiple-secure-codecs - 如果不支持多个安全编解码器实例共存,则应在 <code>media_codecs.xml</code> 文件中作为全局设置指明。
+<pre class="devsite-click-to-copy">
+&lt;MediaCodecs&gt;
+    &lt;Settings&gt;
+        &lt;Setting name="supports-multiple-secure-codecs" value="false" /&gt;
+    &lt;/Settings&gt;
+    &lt;Encoders&gt;
+…
+</pre>
+  </li><li>请注意,默认情况下,两个设置都为 true,这意味着如果支持这些设置,则无需将设置行添加到 <code>media_codecs.xml</code>。
+  </li><li>如果这两个设置未正确设置,<code>ResourceManagerTest</code> CTS 测试可能会失败。
+</li></ul>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/media/soc.html b/zh-cn/devices/media/soc.html
new file mode 100644
index 0000000..50fc164
--- /dev/null
+++ b/zh-cn/devices/media/soc.html
@@ -0,0 +1,56 @@
+<html devsite><head>
+    <title>媒体资源管理器的 SoC 供应商依赖关系</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 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>本文档旨在帮助系统芯片供应商 (SoC) 正确实现对 Android 媒体资源管理器所需的优先级、运营率和钩子的支持。</p>
+
+<h2 id="1_omx_errorinsufficientresources">1. OMX_ErrorInsufficientResources</h2>
+
+<p>如果失败的原因是资源不足,则编解码器组件应返回 <code>GetHandle</code> 上的 <code>OMX_ErrorInsufficientResources</code>、<code>Init</code>、<code>UseBuffer</code>、<code>AllocateBuffer</code> 或状态转换。媒体资源管理器会将该错误代码用作指示符(意味着可能会从其他优先级较低的进程抢占媒体资源)。</p>
+
+<p>Android 兼容性测试套件 (CTS) 测试存在的目的是重复分配、配置和启动每一个编解码器,直到出现 <code>catching
+OMX_ErrorInsufficientResources</code>(通过)结果或任何其他错误(失败)。</p>
+
+<h2 id="2_omx_indexconfigpriority">2. OMX_IndexConfigPriority</h2>
+
+<p>通过此配置,应用可以说明所需的编解码器优先级。</p>
+
+<p>关联值为整数。值越高,优先级越低。
+目前仅支持两种级别:</p>
+
+<ul>
+  <li>0:实时优先级 - 指的是编解码器应该实时支持指定的性能配置(如帧速率)。该优先级只能用于媒体播放、捕获,而且在可提供的最佳性能不合适时,还可能用于实时通信场景。</li>
+  <li>1:非实时优先级(可提供的最佳性能)。这是默认值。</li>
+</ul>
+
+<p>建议供应商将此用作编解码器配置和资源规划提示,以便了解应用的实时要求。</p>
+
+<p>请勿假设实时优先级(除非优先级配置为 0)。</p>
+
+<h2 id="3_omx_indexconfigoperatingrate">3. OMX_IndexConfigOperatingRate</h2>
+
+<p>通过此配置,应用可以说明编解码器需要操作的视频的操作帧速率或音频的采样率。</p>
+
+<p>该配置的其中一种使用情况为高速/慢动作视频捕获;在这种情况下,视频编码器格式包含目标播放速率(如 30 帧/秒),但组件必须能够处理较高的操作捕获速率(如 240 帧/秒)。</p>
+
+<p>此速率应该用于资源规划和设置操作点。</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/sensors/hal-interface.html b/zh-cn/devices/sensors/hal-interface.html
new file mode 100644
index 0000000..8128fa1
--- /dev/null
+++ b/zh-cn/devices/sensors/hal-interface.html
@@ -0,0 +1,184 @@
+<html devsite><head>
+    <title>HAL 接口</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 The Android Open Source Project
+
+      Licensed under the Apache License, Version 2.0 (the "License");
+      you may not use this file except in compliance with the License.
+      You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      See the License for the specific language governing permissions and
+      limitations under the License.
+  -->
+
+<p><a href="/devices/halref/sensors_8h.html">sensors.h</a> 中声明的 HAL 接口表示 Android <a href="sensor-stack.html#framework">框架</a>与特定于硬件的软件之间的接口。HAL 实现必须定义 sensors.h 中声明的每个函数。主要函数如下:</p>
+<ul>
+  <li><code>get_sensors_list</code> - 返回所有传感器的列表。</li>
+  <li><code>activate</code> - 启动或停止传感器。</li>
+  <li><code>batch</code> - 设置传感器的参数,如采样率和最大报告延迟。</li>
+  <li><code>setDelay</code> - 仅用于 HAL 版本 1.0。设置指定传感器的采样率。</li>
+  <li><code>flush</code> - 刷写指定传感器的 FIFO 并在完成后报告刷写完成事件。</li>
+  <li><code>poll</code> - 返回可用的传感器事件。</li>
+</ul>
+<p>实现必须是线程安全的,并且允许从不同线程调用这些函数。</p>
+<p>该接口还定义了这些函数使用的几个类型。主要类型如下:</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>除了下面的部分,还可参阅 <a href="/devices/halref/sensors_8h.html">sensors.h</a> 详细了解这些类型。</p>
+<h2 id="get_sensors_list_list">get_sensors_list(list)</h2>
+<pre class="prettyprint">int (*get_sensors_list)(struct sensors_module_t* module, struct sensor_t
+  const** list);</pre>
+<p>该函数提供由 HAL 实现的传感器列表。要详细了解如何定义传感器,请参阅 <a href="#sensor_t">sensor_t</a>。</p>
+<p>传感器在列表中显示的顺序是将传感器报告给应用的顺序。通常,先显示基础传感器,然后显示复合传感器。</p>
+<p>如果几个传感器的传感器类型和唤醒属性相同,则列表中的第一个传感器称为“默认”传感器。该传感器由 <code>getDefaultSensor(int sensorType, bool wakeUp)</code> 返回。</p>
+<p>该函数返回列表中的传感器数量。</p>
+<h2 id="activate_sensor_true_false">activate(sensor, true/false)</h2>
+<pre class="prettyprint">int (*activate)(struct sensors_poll_device_t *dev, int sensor_handle, int
+  enabled);</pre>
+<p>激活或禁用传感器。</p>
+<p><code>sensor_handle</code> 是要激活/禁用的传感器的句柄。传感器的句柄由其 <a href="#sensor_t">sensor_t</a> 结构的 <code>handle</code> 字段定义。</p>
+<p><code>enabled</code> 设为 1 时启用传感器,设为 0 时则停用传感器。</p>
+<p>单次传感器在接收到事件后立即自动自行禁用,并且必须仍接受通过调用 <code>activate(...,
+  enabled=0)</code> 进行禁用。</p>
+<p>非唤醒传感器绝不会阻止 SOC 进入暂停模式;即 HAL 不应代表应用控制部分唤醒锁定。</p>
+<p>持续提交事件的唤醒传感器会阻止 SOC 进入暂停模式,但如果无需提交任何事件,则必须释放部分唤醒锁定。</p>
+<p>如果 <code>enabled</code> 为 1 且传感器已激活,则该函数是空操作且操作成功。</p>
+<p>如果 <code>enabled</code> 为 0 且传感器已禁用,则该函数是空操作且操作成功。</p>
+<p>如果操作成功了,则该函数返回 0;否则返回表示错误的负数。</p>
+<h2 id="batch_sensor_flags_sampling_period_maximum_report_latency">batch(sensor, flags, sampling period, maximum report latency)</h2>
+<pre class="prettyprint">
+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>设置传感器的参数,包括<a href="#sampling_period_ns">采样率</a>和<a href="#max_report_latency_ns">最大报告延迟</a>。该函数可在传感器被激活时调用,在这种情况下,它一定不能导致任何传感器测量丢失:从一个采样率转换到另一个采样率时不能导致丢失事件,而从较高最大报告延迟转换为较低最大报告延迟时也不能丢失事件。</p>
+<p><code>sensor_handle</code> 是要配置的传感器的句柄。</p>
+<p><code>flags</code> 当前未使用。</p>
+<p><code>sampling_period_ns</code> 是传感器运行时应采用的采样周期,以纳秒为单位。要了解详情,请参阅 <a href="#sampling_period_ns">sampling_period_ns</a>。</p>
+<p><code>max_report_latency_ns</code> 是事件在通过 HAL 报告之前可以延迟的最长时间,以纳秒为单位。要了解详情,请参阅 <a href="#max_report_latency_ns">max_report_latency_ns</a> 段落。</p>
+<p>如果操作成功了,则该函数返回 0;否则返回表示错误的负数。</p>
+<h3 id="sampling_period_ns">sampling_period_ns</h3>
+<p><code>sampling_period_ns</code> 参数的含义取决于指定传感器的报告模式:</p>
+<ul>
+  <li>连续模式:<code>sampling_period_ns</code> 是采样率,指的是生成事件的速率。</li>
+  <li>变化模式:<code>sampling_period_ns</code> 限制事件的采样率,表示事件的生成频率不会高于每 <code>sampling_period_ns</code> 纳秒一次。可能会有比 <code>sampling_period_ns</code> 长的周期,在这种情况下,如果测量值长时间不变化,则不会生成任何事件。要了解详情,请参阅<a href="report-modes.html#on-change">变化</a>报告模式。</li>
+  <li>单次模式:<code>sampling_period_ns</code> 会被忽略。该参数没有任何作用。</li>
+  <li>特殊模式:要详细了解 <code>sampling_period_ns</code> 如何用于特殊的传感器,请参阅具体的<a href="sensor-types.html">传感器类型说明</a>。</li>
+</ul>
+<p>要详细了解 <code>sampling_period_ns</code> 在不同模式下的影响,请参阅<a href="report-modes.html">报告模式</a>。</p>
+<p>对于连续和变化传感器:</p>
+<ul>
+  <li>如果 <code>sampling_period_ns</code> 小于 <code>sensor_t.minDelay</code>,则 HAL 实现必须静默将其钳位到 <code>max(sensor_t.minDelay, 1ms)</code>。Android 不支持以高于 1000Hz 的频率生成事件。</li>
+  <li>如果 <code>sampling_period_ns</code> 大于 <code>sensor_t.maxDelay</code>,则 HAL 实现必须静默将其截断为 <code>sensor_t.maxDelay</code>。</li>
+</ul>
+<p>物理传感器的运行速率和时钟精度有时会受到限制。因此,实际采样率与请求的频率可以不同,只要它满足下表中的要求即可。</p>
+<table>
+  <tbody><tr>
+    <th><p>如果请求的频率</p></th>
+    <th><p>那么实际频率必须</p></th>
+  </tr>
+  <tr>
+    <td><p>低于最小频率 (&lt;1/maxDelay)</p></td>
+    <td><p>在最小频率的 90%-110% 之间</p></td>
+  </tr>
+  <tr>
+    <td><p>在最小和最大频率之间</p></td>
+    <td><p>在请求频率的 90%-220% 之间</p></td>
+  </tr>
+  <tr>
+    <td><p>高于最大频率 (&gt;1/minDelay)</p></td>
+    <td><p>在最大频率的 90%-110% 之间</p>
+      <p>同时低于 1100Hz</p></td>
+  </tr>
+</tbody></table>
+<p>请注意,本约定仅对始终只有一个客户端的 HAL 层有效。而在 SDK 层,由于框架中会出现多路复用现象,应用可能会获得不同的速率。要了解详情,请参阅<a href="sensor-stack.html#framework">框架</a>。</p>
+<h3 id="max_report_latency_ns">max_report_latency_ns</h3>
+<p><code>max_report_latency_ns</code> 设置事件在 SoC 唤醒期间通过 HAL 报告之前可以延迟并存储在硬件 FIFO 中的最长时间,以纳秒为单位。</p>
+<p>值为零表示事件必须在测量完成后立即报告,一旦从该传感器发出的事件出现在 FIFO 中,就完全跳过 FIFO,或者将 FIFO 清空。</p>
+<p>例如,以 50Hz 激活的加速度计如果 <code>max_report_latency_ns=0</code>,则在 SoC 唤醒期间每秒触发中断 50 次。</p>
+<p>当 <code>max_report_latency_ns&gt;0</code> 时,在检测到传感器事件后无需立即报告。只要所有事件的延迟均不超过 max_report_latency_ns 纳秒,就可以暂时存储在硬件 FIFO 中并批量报告。也就是说,一次性记录并返回上一批之后的所有事件。这样一来,发送到 SoC 的中断数量会减少,并且在传感器捕获数据并进行批量处理时,SoC 可以切换到低电耗模式(闲置)。</p>
+<p>每个事件都具有相关联的时间戳。事件的报告时间有所延迟并不影响事件时间戳。时间戳必须准确且对应于事件实际发生的时间,而不是对应于事件的报告时间。</p>
+<p>允许传感器事件暂时存储在硬件 FIFO 中不会修改 <code>poll</code> 的行为:不同传感器的事件可交错;和往常一样,同一传感器的所有事件按时间排序。</p>
+<p>要详细了解传感器批量处理(包括暂停模式和非暂停模式中的行为),请参阅<a href="batching.html">批量处理</a>。</p>
+<h2 id="setdelay_sensor_sampling_period">setDelay(sensor, sampling period)</h2>
+<pre class="prettyprint">
+int (*setDelay)(
+     struct sensors_poll_device_t *dev,
+     int sensor_handle,
+     int64_t sampling_period_ns);
+</pre>
+<p>在 1.0 版本之后的 HAL 中,该函数已被弃用,并且无法再调用。改为调用 <code>batch</code> 函数来设置 <code>sampling_period_ns</code> 参数。</p>
+<p>在 1.0 版本的 HAL 中,使用 setDelay(而非 batch)来设置 <a href="#sampling_period_ns">sampling_period_ns</a>。</p>
+<h2 id="flush_sensor">flush(sensor)</h2>
+<pre class="prettyprint">int (*flush)(struct sensors_poll_device_1* dev, int sensor_handle);</pre>
+<p>将<a href="#metadata_flush_complete_events">刷写完成事件</a>添加到指定传感器的硬件 FIFO 的末尾并刷写 FIFO;这些事件会照常提交(即好像最大报告延迟已过期一样)并从 FIFO 中移除。</p>
+<p>刷写异步发生(即该函数必须立即返回)。如果实现将一个 FIFO 用于多个传感器,则刷写该 FIFO,并且仅为指定传感器添加刷写完成事件。</p>
+<p>如果指定传感器没有 FIFO(无法缓冲),或者如果 FIFO 在调用时为空,则 <code>flush</code> 仍必须操作成功并为该传感器发送刷写完成事件。这适用于除单次传感器以外的所有传感器。</p>
+<p>当调用 <code>flush</code> 时,即使该传感器的 FIFO 中已经存在刷写事件,也必须创建另一个刷写事件并将其添加到 FIFO 的末尾,并且必须刷写 FIFO。<code>flush</code> 调用的次数必须等于创建的刷写完成事件数。</p>
+<p><code>flush</code> 不适用于<a href="report-modes.html#one-shot">单次</a>传感器;如果 <code>sensor_handle</code> 指的是单次传感器,则 <code>flush</code> 必须返回 <code>-EINVAL</code>,并且不生成任何刷写完成元数据事件。</p>
+<p>如果操作成功了,则该函数返回 0;如果指定的传感器是单次传感器或未启用,则返回 <code>-EINVAL</code>;否则返回表示错误的负数。</p>
+<h2 id="poll">poll()</h2>
+<pre class="prettyprint">int (*poll)(struct sensors_poll_device_t *dev, sensors_event_t* data, int
+  count);</pre>
+<p>通过填充 <code>data</code> 参数返回传感器数据数组。该函数必须禁用,直到事件可用为止。如果操作成功了,则该函数返回读取的事件数,或者如果发生错误,则返回表示错误的负数。</p>
+<p><code>data</code> 中返回的事件数必须小于或等于 <code>count</code> 参数。该函数不应返回 0(没有任何事件)。</p>
+<h2 id="sequence_of_calls">调用的顺序</h2>
+<p>当设备启动时,调用 <code>get_sensors_list</code>。</p>
+<p>当传感器激活时,则先通过请求的参数调用 <code>batch</code> 函数,然后调用 <code>activate(..., enable=1)</code>。</p>
+<p>请注意,在 1_0 版本的 HAL 中,顺序是相反的,先调用 <code>activate</code>,然后调用 <code>set_delay</code>。</p>
+<p>当激活状态下的传感器的请求特性发生变化时,调用 <code>batch</code> 函数。</p>
+<p>即使是未激活传感器,也可以随时调用 <code>flush</code>(在这种情况下,必须返回 <code>-EINVAL</code>)</p>
+<p>当传感器禁用时,将调用 <code>activate(..., enable=0)</code>。</p>
+<p>在上述调用的同时,反复调用 <code>poll</code> 函数以请求数据。即使在没有激活任何传感器的情况下,仍可以调用 <code>poll</code>。</p>
+<h2 id="sensors_module_t">sensors_module_t</h2>
+<p><code>sensors_module_t</code> 是用于为传感器创建 Android 硬件模块的类型。HAL 的实现必须定义一个该类型的对象 <code>HAL_MODULE_INFO_SYM</code>,以提供 <a href="#get_sensors_list_list">get_sensors_list</a> 函数。要了解详情,请参阅 <a href="/devices/halref/sensors_8h.html">sensors.h</a> 中 <code>sensors_module_t</code> 的定义和 <code>hw_module_t</code> 的定义。</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> 包含上文定义的方法的剩余部分:<code>activate</code>、<code>batch</code>、<code>flush</code> 和 <code>poll</code>。其 <code>common</code> 字段(类型为 <a href="/devices/halref/structhw__device__t.html">hw_device_t</a>)定义 HAL 的版本号。</p>
+<h2 id="sensor_t">sensor_t</h2>
+<p><code>sensor_t</code> 表示 <a href="index.html">Android 传感器</a>。以下是 sensor_t 的一些重要字段:</p>
+<p><strong>name</strong>:表示传感器的用户可见字符串。该字符串通常包括底层传感器的部件名称、传感器的类型以及是否为唤醒传感器。例如,“LIS2HH12 Accelerometer”、“MAX21000 Uncalibrated Gyroscope”、“BMP280 Wake-up Barometer”、“MPU6515 Game Rotation Vector”。</p>
+<p><strong>handle</strong>:用于在注册到传感器或从传感器生成事件时表示传感器的整数。</p>
+<p><strong>type</strong>:传感器的类型。要详细了解传感器类型的解释,请参阅<a href="index.html">什么是 Android 传感器?</a>; 要了解官方传感器类型,请参阅<a href="sensor-types.html">传感器类型</a>。对于非官方传感器类型,<code>type</code> 必须以 <code>SENSOR_TYPE_DEVICE_PRIVATE_BASE</code> 开头。</p>
+<p><strong>stringType</strong>:传感器的类型(以字符串表示)。如果传感器为官方类型,则设置为 <code>SENSOR_STRING_TYPE_*</code>。如果传感器为制造商特定类型,<code>stringType</code> 必须以制造商的反向域名开头。例如,由 Fictional-Company 的 Cool-product 团队定义的传感器(例如 unicorn 检测器)可以使用 <code>stringType=”com.fictional_company.cool_product.unicorn_detector”</code>。<em></em><code>stringType</code> 用于唯一标识非官方传感器类型。要详细了解传感器类型和字符串类型,请参阅 <a href="/devices/halref/sensors_8h.html">sensors.h</a>。</p>
+<p><strong>requiredPermission</strong>:表示应用必须拥有的权限(查看传感器、注册到传感器和接收传感器数据)的字符串。空字符串表明应用不需要获取该传感器的任何访问权限。<a href="sensor-types.html#heart_rate">心率监测器</a>等传感器类型具有强制性的 <code>requiredPermission</code>。提供敏感用户信息(例如心率)的所有传感器必须受到权限保护。</p>
+<p><strong>flags</strong>:传感器的标记,用于定义传感器的报告模式以及传感器是否为唤醒传感器。例如,对于单次唤醒传感器,<code>flags = SENSOR_FLAG_ONE_SHOT_MODE | SENSOR_FLAG_WAKE_UP</code>。当前版本的 HAL 中未使用的标记的位必须等于 0。</p>
+<p><strong>maxRange</strong>:传感器可报告的最大值,与已报告值的单位相同。传感器必须能够报告 <code>[-maxRange; maxRange]</code> 范围内(未过载)的值。请注意,这意味着从常规意义上来说传感器的总范围是 <code>2*maxRange</code>。当传感器报告几条轴上的值时,该范围适用于每条轴。例如,“+/- 2g”加速度计会报告 <code>maxRange = 2*9.81 = 2g</code>。</p>
+<p><strong>resolution</strong>:传感器可测量出的最小差值。该字段通常基于 <code>maxRange</code> 和测量时的位数计算得来。</p>
+<p><strong>power</strong>:启用传感器的功耗成本,以毫安为单位。该字段值几乎始终大于底层传感器的相关数据表中报告的功耗。要了解详情,请参阅<a href="sensor-types.html#base_sensors_=_not_equal_to_physical_sensors">基础传感器不等于物理传感器</a>这篇文章;要详细了解如何测量传感器的功耗,请参阅<a href="power-use.html#power_measurement_process">功率测量过程</a>。如果传感器的功耗取决于设备是否正在移动,则 <code>power</code> 字段中报告的值是移动时的功耗。</p>
+<p><strong>minDelay</strong>:对于连续传感器,采样周期(以微秒为单位)对应于传感器支持的最快速率。要详细了解该值是如何使用的,请参阅 <a href="#sampling_period_ns">sampling_period_ns</a>。请注意,<code>minDelay</code> 以微秒为单位,而 <code>sampling_period_ns</code> 以纳秒为单位。对于变化和特殊报告模式传感器,除非另行指定,否则 <code>minDelay</code> 必须为 0。对于单次传感器,该值必须为 -1。</p>
+<p><strong>maxDelay</strong>:对于连续和变化传感器,采样周期(以微秒为单位)对应于传感器支持的最慢速率。要详细了解该值是如何使用的,请参阅 <a href="#sampling_period_ns">sampling_period_ns</a>。请注意,<code>maxDelay</code> 以毫秒为单位,而 <code>sampling_period_ns</code> 以纳秒为单位。对于特殊和单次传感器,<code>maxDelay</code> 必须为 0。</p>
+<p><strong>fifoReservedEventCount</strong>:硬件 FIFO 中为该传感器保留的事件数。如果该传感器有一个专用的 FIFO,则 <code>fifoReservedEventCount</code> 是该专用 FIFO 的大小。如果 FIFO 与其他传感器共享,则 <code>fifoReservedEventCount</code> 是为该传感器保留的 FIFO 部分的大小。对于大多数共享 FIFO 的系统以及没有硬件 FIFO 的系统,该值为 0。</p>
+<p><strong>fifoMaxEventCount</strong>:FIFO 中可为该传感器存储的最大事件数。该值总是大于或等于 <code>fifoReservedEventCount</code>。该值用于估计在假设不激活任何其他传感器的情况下,以特定速率注册到传感器时 FIFO 多快会被填满。对于没有硬件 FIFO 的系统,<code>fifoMaxEventCount</code> 为 0。要了解详情,请参阅<a href="batching.html">批量处理</a>。</p>
+<p>对于官方传感器类型的传感器,一些字段会被框架覆盖。例如,<a href="sensor-types.html#accelerometer">加速度计</a>传感器被强制使用连续报告模式,而<a href="sensor-types.html#heart_rate">心率</a>监测器被强制受 <code>SENSOR_PERMISSION_BODY_SENSORS</code> 权限的保护。</p>
+<h2 id="sensors_event_t">sensors_event_t</h2>
+<p>由 Android 传感器生成并通过 <a href="#poll">poll</a> 函数报告的传感器事件具有 <code>type sensors_event_t</code>。以下是 <code>sensors_event_t</code> 的一些重要字段:</p>
+<p><strong>version</strong>:必须是 <code>sizeof(struct sensors_event_t)</code></p>
+<p><strong>sensor</strong>:生成事件的传感器的句柄,由 <code>sensor_t.handle</code> 定义。</p>
+<p><strong>type</strong>:生成事件的传感器的传感器类型,由 <code>sensor_t.type</code> 定义。</p>
+<p><strong>timestamp</strong>:事件的时间戳,以纳秒为单位。这是事件(采取了步骤,或是进行了加速度计测量)发生的时间,而不是事件报告的时间。<code>timestamp</code> 必须与 <code>elapsedRealtimeNano</code> 时钟同步,并且对于连续传感器,抖动必须很小。有时需要进行时间戳过滤以满足 CDD 要求,因为仅使用 SoC 中断时间来设置时间戳会导致抖动过大,并且仅使用传感器芯片时间来设置时间戳可能会由于传感器时钟漂移而无法与 <code>elapsedRealtimeNano</code> 时钟同步。</p>
+<p><strong>数据和重叠字段</strong>:由传感器测量的值。这些字段的含义和单位特定于每种传感器类型。要了解数据字段的说明,请参阅 <a href="/devices/halref/sensors_8h.html">sensors.h</a> 和不同<a href="sensor-types.html">传感器类型</a>的定义。对于某些传感器,也可以通过 <code>status</code> 字段在数据中同时报告读数精度。该字段只能针对选定传感器类型通过管道传递,作为精度值出现在 SDK 层。对于这类传感器,其<a href="sensor-types.html">传感器类型</a>定义中会提及必须设置 status 字段。</p>
+<h3 id="metadata_flush_complete_events">元数据刷写完成事件</h3>
+<p>元数据事件的类型与常规传感器事件的类型相同:<code>sensors_event_meta_data_t = sensors_event_t</code>。元数据事件通过 poll 与其他传感器事件一起返回,且拥有如下字段:</p>
+<p><strong>version</strong>:必须是 <code>META_DATA_VERSION</code></p>
+<p><strong>type</strong>:必须是 <code>SENSOR_TYPE_META_DATA</code></p>
+<p><strong>sensor、reserved 和 timestamp</strong>:必须为 0</p>
+<p><strong>meta_data.what</strong>:包含该事件的元数据类型。目前有一个有效的元数据类型:<code>META_DATA_FLUSH_COMPLETE</code>。</p>
+<p><code>META_DATA_FLUSH_COMPLETE</code> 事件表示传感器 FIFO 刷写完成。当 <code>meta_data.what=META_DATA_FLUSH_COMPLETE</code> 时,必须将 <code>meta_data.sensor</code> 设置为已刷写的传感器的句柄。此类事件当且仅当对传感器调用 <code>flush</code> 时生成。要了解详情,请参阅有关 <a href="#flush_sensor">flush</a> 函数的部分。</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/sensors/index.html b/zh-cn/devices/sensors/index.html
new file mode 100644
index 0000000..6f67107
--- /dev/null
+++ b/zh-cn/devices/sensors/index.html
@@ -0,0 +1,117 @@
+<html devsite><head>
+    <title>传感器</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 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.
+  -->
+
+<img style="float: right; margin: 0px 15px 15px 15px;" src="images/ape_fwk_hal_sensors.png" alt="Android 传感器 HAL 图标"/>
+
+<p>Android 传感器使应用可以访问移动设备的底层物理传感器。它们是负责提供数据的虚拟设备,由传感器硬件抽象层 (HAL) <a href="/devices/halref/sensors_8h.html">sensor.h</a> 进行定义。</p>
+
+<h2 id="what_are_“android_sensors”">什么是 Android 传感器?</h2>
+<p>Android 传感器属于虚拟设备,可提供来自以下各种物理传感器的数据:加速度计、陀螺仪、磁力计、气压计、湿度传感器、压力传感器、光传感器、近程传感器和心率传感器。</p>
+<p>提供数据的物理设备的列表中不包括相机、指纹传感器、麦克风和触摸屏。这些设备有自己的报告机制;这种区别是随意的,但一般来说,Android 传感器提供较低带宽的数据。例如,“100 hz x 3 个通道”用于加速度计、“25 hz x 8 MP x 3 个通道”用于相机,或“44 kHz x 1 个通道”用于麦克风。</p>
+    <p>Android 不定义不同物理传感器如何连接到系统芯片 (SoC)。</p>
+    <ul>
+      <li>通常,传感器芯片通过<a href="sensor-stack.html#sensor_hub">传感器中枢</a>连接到 SoC,允许对数据进行一些低功耗的监控和数据处理。</li>
+      <li>通常,使用内部集成电路 (I2C) 或串行外设接口 (SPI) 作为传输机制。</li>
+      <li>为了降低功耗,一些架构具有层次性,在专用集成电路(简称 ASIC,如加速度计芯片上的运动检测)中进行极少的处理,而在微控制器(如传感器中枢中的步数检测)中进行更多处理。</li>
+      <li>设备制造商会根据精确度、功率、价格和封装大小特性来选择架构。有关详情,请参阅<a href="sensor-stack.html">传感器堆栈</a>。</li>
+      <li>批处理功能是功率优化的重要考虑因素。有关详情,请参阅<a href="batching.html">批处理</a>。</li>
+    </ul>
+    <p>每个 Android 传感器都有一个“类型”,表示传感器的行为及其提供的数据。</p>
+    <ul>
+      <li>官方 Android <a href="sensor-types.html">传感器类型</a>在 <a href="/devices/halref/sensors_8h.html">sensors.h</a> 中的 SENSOR_TYPE_ 名称下定义<ul>
+          <li>绝大多数传感器都具有官方传感器类型。</li>
+          <li>这些类型记录在 Android SDK 中。</li>
+	  <li>这些类型的传感器的行为在 Android 兼容性测试套件 (CTS) 中进行测试。</li>
+        </ul>
+      </li>
+      <li>如果制造商在 Android 设备上集成了一种新型传感器,则可以自行定义一个临时类型来引用它。
+        <ul>
+          <li>这些类型不会被记录,因此应用开发者不太可能使用它们,因为开发者不了解它们,或者知道它们很少存在(仅在该特定制造商制造的某些设备上)。</li>
+          <li>它们未经过 CTS 测试。</li>
+	  <li>一旦 Android 为这种传感器定义了官方传感器类型,那么制造商必须停止使用自己的临时类型,并改为使用官方类型。这样,该传感器将供更多应用开发者使用。</li>
+        </ul>
+      </li>
+      <li>设备上存在的所有传感器的列表由 HAL 实现报告。
+        <ul>
+          <li>可以存在几个相同类型的传感器。例如,两个近程传感器或两个加速度计。</li>
+          <li>绝大多数应用仅会请求给定类型的单个传感器。例如,请求默认加速度计的应用将获得列表中的第一个加速度计。</li>
+          <li>传感器通常由<a href="suspend-mode.html#wake-up_sensors">唤醒</a>和<a href="suspend-mode.html#non-wake-up_sensors">非唤醒</a>对定义,两个传感器共享同一类型,但其唤醒特性不同。</li>
+        </ul>
+      </li>
+    </ul>
+<p>Android 传感器提供的数据是一系列传感器事件。</p>
+      <p>每个<a href="hal-interface.html#sensors_event_t">事件</a>包含:</p>
+        <ul>
+          <li>生成该事件的传感器的句柄</li>
+          <li>检测到或测量事件时的时间戳</li>
+          <li>以及一些数据</li>
+        </ul>
+      <p>对所报告数据的解析取决于传感器类型。有关针对每种传感器类型报告什么数据的详细信息,请参见<a href="sensor-types.html">传感器类型</a>定义。</p>
+
+<h2 id="existing_documentation2">现有文档</h2>
+    <h3 id="targeted_at_developers">面向开发者</h3>
+    <ul>
+      <li>概览
+        <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 参考
+        <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 和教程网站
+        <ul>
+          <li>由于有时缺少传感器文档,因此开发者会前往 StackOverflow 等问答网站来寻找答案。</li>
+          <li>还存在一些教程网站,但不涉及最新功能,如批处理、大幅度动作传感器和游戏旋转矢量传感器。</li>
+          <li>这些网站的回答不一定总是正确,这就显示出哪些地方需要更多的文档来提供信息。</li>
+        </ul>
+      </li>
+    </ul>
+<h3 id="targeted_at_manufacturers_public">面向制造商</h3>
+    <ul>
+      <li> 概览
+        <ul>
+	  <li>此<a href="/devices/sensors/index.html">传感器</a>页面及其子页面。</li>
+        </ul>
+      </li>
+      <li>硬件抽象层 (HAL)
+        <ul>
+          <li> <a href="/devices/halref/sensors_8h_source.html">https://source.android.com/devices/halref/sensors_8h_source.html</a></li>
+          <li>也称为“sensors.h”</li>
+          <li>信息来源。开发新功能时要更新的第一份文档。</li>
+        </ul>
+      </li>
+      <li>Android CDD(兼容性定义文档)
+        <ul>
+          <li><a href="/compatibility/android-cdd.pdf">https://source.android.com/compatibility/android-cdd.pdf</a></li>
+          <li>查看有关传感器的部分。</li>
+          <li>CDD 的要求很宽松,因此满足 CDD 要求不足以确保传感器质量会很高。</li>
+        </ul>
+      </li>
+    </ul>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/sensors/interaction.html b/zh-cn/devices/sensors/interaction.html
new file mode 100644
index 0000000..dcef81e
--- /dev/null
+++ b/zh-cn/devices/sensors/interaction.html
@@ -0,0 +1,47 @@
+<html devsite><head>
+    <title>交互性</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 The Android Open Source Project
+
+      Licensed under the Apache License, Version 2.0 (the "License");
+      you may not use this file except in compliance with the License.
+      You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      See the License for the specific language governing permissions and
+      limitations under the License.
+  -->
+
+<p>从 Android 应用的角度来看,每个 Android 传感器都是一个独立的实体,这意味着不同传感器之间不存在交互性。</p>
+<ul>
+  <li>即使几个 Android 传感器可能共享同一个底层物理传感器,也是如此</li>
+  <li>例如:全部依靠同一个物理加速度计的计步器、大幅度动作感测器和加速度计必须能够同时工作</li>
+  <li>对于同一传感器的唤醒和非唤醒版本也是如此</li>
+</ul>
+<p>Android 传感器必须能够同时并且彼此独立工作。也就是说,一个 Android 传感器上的任何操作都不能影响其他传感器的行为。</p>
+<p>具体来说,在 HAL 级别:</p>
+<ul>
+  <li>激活传感器</li>
+  <li>停用传感器</li>
+  <li>更改传感器的采样率</li>
+  <li>更改传感器的最大报告延迟</li>
+</ul>
+<p>不能造成:</p>
+<ul>
+  <li>另一个激活的传感器停止工作</li>
+  <li>另一个激活的传感器改变采样率</li>
+  <li>另一个激活的传感器降低其测量的质量</li>
+  <li>另一个未激活的传感器开始传送事件</li>
+</ul>
+<p>上述任何操作也不能阻止在其他传感器上成功进行操作(激活、停用和更改参数)。例如,我们能否激活计步器与加速度计当前是否处于激活状态无关。</p>
+<p>另一个重要的示例是,以 5 Hz 频率激活的唤醒传感器必须以大约 5 Hz 频率生成事件,即使其非唤醒版本以 100 Hz 频率被激活也是如此。</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/sensors/power-use.html b/zh-cn/devices/sensors/power-use.html
new file mode 100644
index 0000000..ef72308
--- /dev/null
+++ b/zh-cn/devices/sensors/power-use.html
@@ -0,0 +1,42 @@
+<html devsite><head>
+    <title>耗电量</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 The Android Open Source Project
+
+      Licensed under the Apache License, Version 2.0 (the "License");
+      you may not use this file except in compliance with the License.
+      You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      See the License for the specific language governing permissions and
+      limitations under the License.
+  -->
+
+<h2 id="low_power_sensors">低功率传感器</h2>
+<p>某些传感器类型被定义为低功率传感器。低功率传感器必须以低功率运行,其处理在硬件中完成。这意味着它们不能要求运行 SoC。以下是一些低功率传感器类型:</p>
+<ul>
+  <li>地磁旋转矢量计</li>
+  <li>大幅运动感测器</li>
+  <li>计步器</li>
+  <li>步测器</li>
+  <li>倾斜探测器</li>
+</ul>
+<p>它们在<a href="sensor-types.html#composite_sensor_type_summary">复合传感器类型汇总</a>表中带有低功率 (<img src="images/battery_icon.png" width="20" height="20" alt="低功率传感器"/>) 图标。</p>
+<p>这些传感器类型不能在高功率下实现,因为它们的主要优势就是耗电量低。这些传感器预计会长期处于激活状态,很可能是全天候。对于低功率传感器,宁愿不实现,也不要在高功率下实现,否则会导致过度耗电。</p>
+<p>复合低功率传感器类型(如步测器)的处理过程必须在硬件中进行。</p>
+<p>有关具体的功率要求,请参阅 CDD,并应在 CTS 中进行测试来验证这些功率要求。</p>
+<h2 id="power_measurement_process">功率测量过程</h2>
+<p>功率是在电池处测量。对于以毫瓦为单位的值,我们使用电池的额定电压,这表示电压为 4 伏时,1 毫安的电流必须相应地计为 4 毫瓦。</p>
+<p>在 SoC 处于休眠状态时测量功率,并且在 SoC 休眠的几秒钟内计算平均值,以便将来自传感器芯片的周期性功率峰值考虑在内。</p>
+<p>对于单次唤醒传感器,在传感器未触发时测量功率(因此不会唤醒 SoC)。同样,对于其他传感器,会在传感器数据存储在硬件 FIFO 中时测量功率,因此 SoC 不会被唤醒。</p>
+<p>当没有传感器激活时,通常以增量形式测量功率。当有多个传感器激活时,功率增量不得大于各激活的传感器的功率之和。如果加速度计的电流为 0.5 毫安,步测器的电流也为 0.5 毫安,则同时激活两者所产生的电流必须小于 0.5 + 0.5 = 1 毫安。</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/sensors/report-modes.html b/zh-cn/devices/sensors/report-modes.html
new file mode 100644
index 0000000..2781dcf
--- /dev/null
+++ b/zh-cn/devices/sensors/report-modes.html
@@ -0,0 +1,42 @@
+<html devsite><head>
+    <title>报告模式</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 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>传感器可以不同的方式(称为报告模式)生成事件;每种传感器类型有且仅有一个与之关联的报告模式。共有 4 种报告模式。</p>
+<h2 id="continuous">连续模式</h2>
+<p>以传递给 <code>batch</code> 函数的 <a href="hal-interface.html#sampling_period_ns">sampling_period_ns</a> 参数所定义的恒定速率生成事件。使用连续报告模式的示例传感器有<a href="sensor-types.html#accelerometer">加速度计</a>和<a href="sensor-types.html#gyroscope">陀螺仪</a>。</p>
+<h2 id="on-change">变化模式</h2>
+<p>仅在测量值发生变化时生成事件。在 HAL 层激活传感器(在其上调用 <code>activate(..., enable=1)</code>)也会触发事件,也就是说在激活变化传感器时,HAL 必须立即返回事件。使用变化报告模式的示例传感器包括计步器、近程传感器和心率传感器类型。</p>
+<p>传递给 <code>batch</code> 函数的 <a href="hal-interface.html#sampling_period_ns">sampling_period_ns</a> 参数用于设置连续事件之间的最小时间间隔,也就是说不得在自上一事件后的 sampling_period_ns 纳秒内生成事件,即使值在这段时间内发生了变化也是如此。如果值发生变化,则必须在自上一事件的 <code>sampling_period_ns</code> 后立即生成事件。</p>
+<p>例如,假设:</p>
+<ul>
+  <li>我们使用 <code>sampling_period_ns = 10 * 10^9</code>(10 秒)激活计步器。</li>
+  <li>然后步行 55 秒,再站立 1 分钟。</li>
+  <li>在第一分钟,约每 10 秒生成一个事件(包括传感器激活时的 t=0 秒以及 t=60 秒),共有 7 个事件;在第二分钟,不生成任何事件,因为步数的值在 t=60 秒后没有发生变化。</li>
+</ul>
+<h2 id="one-shot">单次模式</h2>
+<p>一检测到事件,传感器便会自行禁用,然后通过 HAL 发送单个事件。顺序非常重要,可避免出现争用情况(在通过 HAL 报告事件之前,传感器必须处于禁用状态)。重新激活传感器之前,不会发送其他任何事件。<a href="sensor-types.html#significant_motion">显著运动</a>传感器就是这样一种传感器。</p>
+<p>单次传感器有时称为触发传感器。</p>
+<p>传递给 <code>batch</code> 函数的 <code>sampling_period_ns</code> 和 <code>max_report_latency_ns</code> 参数会被忽略。来自单次事件的事件不可存储在硬件 FIFO 中;这些事件在生成后必须立即报告。</p>
+<h2 id="special">特殊模式</h2>
+<p>有关何时生成事件的详细信息,请参阅各个<a href="sensor-types.html">传感器类型说明</a>。</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/sensors/sensor-stack.html b/zh-cn/devices/sensors/sensor-stack.html
new file mode 100644
index 0000000..0855f4e
--- /dev/null
+++ b/zh-cn/devices/sensors/sensor-stack.html
@@ -0,0 +1,91 @@
+<html devsite><head>
+    <title>传感器堆栈</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 The Android Open Source Project
+
+      Licensed under the Apache License, Version 2.0 (the "License");
+      you may not use this file except in compliance with the License.
+      You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      See the License for the specific language governing permissions and
+      limitations under the License.
+  -->
+
+<p>下图显示的是 Android 传感器堆栈。尽管某些传感器可以绕过传感器中枢(如果存在)进行通信,但各个组件仅可与其上方和下方紧邻的组件通信。控制系统从应用向下流向传感器,数据从传感器向上流向应用。</p>
+<img src="images/ape_fwk_sensors.png" alt="Android 传感器堆栈的层级和所有者"/>
+<p class="img-caption"><strong>图 1. </strong> Android 传感器堆栈层级以及各自的所有者</p>
+
+<h2 id="sdk">SDK</h2>
+<p>应用通过 <a href="http://developer.android.com/reference/android/hardware/SensorManager.html">Sensors SDK(软件开发套件)API</a> 访问传感器。SDK 包含用以列示可用传感器和注册到传感器的函数。</p>
+<p>在注册到传感器时,应用可指定自己的首选采样率和延迟要求。</p>
+<ul>
+  <li>例如,应用可注册到默认加速度计,以 100Hz 的频率请求事件,并允许事件报告有 1 秒延迟。</li>
+  <li>应用将以至少 100Hz 的频率从加速度计接收事件,且最多会延迟 1 秒。</li>
+</ul>
+<p>请参阅<a href="index.html#targeted_at_developers">开发者文档</a>,详细了解 SDK。</p>
+<h2 id="framework">框架</h2>
+<p>框架负责将多个应用关联到 <a href="hal-interface.html">HAL</a>。HAL 本身是单一客户端。如果框架级别没有发生这种多路复用,则在任何指定时间内只有一个应用可以访问各个传感器。</p>
+<ul>
+  <li>当第一个应用注册到传感器时,框架会向 HAL 发送请求以激活传感器。</li>
+  <li>当其他应用注册到相同的传感器时,框架会考虑每个应用的要求,并将更新的已请求参数发送到 HAL。<ul>
+      <li><a href="hal-interface.html#sampling_period_ns">采样率</a>将是请求的采样率的最大值,这意味着一些应用接收事件的频率会高于所请求的频率。</li>
+      <li><a href="hal-interface.html#max_report_latency_ns">最大报告延迟</a>将是请求的延迟的最小值。如果某个应用以 0 为最大报告延迟请求传感器,则所有应用将以连续模式从该传感器接收事件,即使某些应用以非零值的最大报告延迟请求传感器也是如此。请参阅<a href="batching.html">批处理</a>,了解详情。</li>
+    </ul>
+  </li>
+  <li>当注册到某个传感器的最后一个应用取消注册之后,框架会向 HAL 发送请求以停用该传感器,从而避免不必要的功耗。</li>
+</ul>
+<h3 id="impact_of_multiplexing">多路复用的影响</h3>
+<p>在框架中实现多路复用层的这一需求解释了一些设计决策。</p>
+<ul>
+  <li>当应用请求特定采样率时,不能保证事件不会以更快的频率到达。如果另一个应用以更快的频率请求同一传感器,则第一个应用也将以较快频率接收事件。</li>
+  <li>请求的最大报告延迟同样无法得到保证:应用可能以比请求的延迟短的多的延迟接收事件。</li>
+  <li>除了采样率和最大报告延迟之外,应用还无法配置传感器参数。
+    <ul>
+      <li>例如,假设某个物理传感器可同时在“高精确度”和“低电耗”模式下运行。</li>
+      <li>这两种模式中只有一种可以在 Android 设备上使用,因为否则一个应用可能请求高精确度模式,而另一个可能请求低电耗模式;框架根本无法同时满足这两个应用的要求。框架必须始终能够满足所有客户端的需要,因此同时使用两种模式是不可行的。</li>
+    </ul>
+  </li>
+  <li>没有将数据从应用向下发送至传感器或其驱动程序的机制。这样可以确保某个应用无法修改传感器的行为,从而不会对其他应用造成破坏。</li>
+</ul>
+<h3 id="sensor_fusion">传感器融合</h3>
+<p>Android 框架为部分复合传感器提供默认实现。如果一个设备上有<a href="sensor-types.html#gyroscope">陀螺仪</a>、<a href="sensor-types.html#accelerometer">加速度计</a>和<a href="sensor-types.html#magnetic_field_sensor">磁力计</a>,但没有<a href="sensor-types.html#rotation_vector">旋转矢量</a>、<a href="sensor-types.html#gravity">重力</a>和<a href="sensor-types.html#linear_acceleration">线性加速度</a>传感器,则框架会实现这些传感器,以便应用仍然可以使用它们。</p>
+<p>默认实现无法访问其他实现可以访问的所有数据,并且必须在 SoC 上运行,因此它不像其他实现那样精准和省电。设备制造商应尽可能定义自己的融合传感器(旋转矢量传感器、重力传感器和线性加速度传感器,以及<a href="sensor-types.html#game_rotation_vector">游戏旋转矢量</a>传感器等较新的复合传感器),而非依赖该默认实现。此外,设备制造商也可以要求传感器芯片供应商为其提供实现。</p>
+<p>默认的传感器融合实现没有相关的维护,且可能导致依赖它的设备无法通过 CTS 验证。</p>
+<h3 id="under_the_hood">深入了解</h3>
+<p>本部分作为背景信息提供,适用于 Android 开放源代码项目 (AOSP) 框架代码的维护人员,与硬件制造商无关。</p>
+<h4 id="jni">JNI</h4>
+<p>框架使用的是与 <a href="http://developer.android.com/reference/android/hardware/package-summary.html">android.hardware</a> 相关联的 Java 本机接口 (JNI)(位于 <code>frameworks/base/core/jni/</code> 目录中)。该代码会调用较低级别的原生代码,以获取对相应传感器硬件的访问权限。</p>
+<h4 id="native_framework">原生框架</h4>
+<p>原生框架在 <code>frameworks/native/</code> 中定义,提供相当于 <a href="http://developer.android.com/reference/android/hardware/package-summary.html">android.hardware</a> 文件包的原生内容。原生框架会调用 Binder IPC 代理,以获取对传感器专属服务的访问权限。</p>
+<h4 id="binder_ipc">Binder IPC</h4>
+<p>Binder IPC 代理用于促进跨越进程边界的通信。</p>
+<h2 id="hal">HAL</h2>
+<p>Sensors Hardware Abstraction Layer (HAL) API 是硬件驱动程序和 Android 框架之间的接口。它包含一个 HAL 接口 sensors.h 和一个我们称之为 sensors.cpp 的 HAL 实现。</p>
+<p>接口由 Android 和 AOSP 贡献者定义,并由设备制造商提供实现。</p>
+<p>传感器 HAL 接口位于 <code>hardware/libhardware/include/hardware</code> 中。请参阅 <a href="https://android.googlesource.com/platform/hardware/libhardware/+/master/include/hardware/sensors.h">sensors.h</a>,了解详情。</p>
+<h3 id="release_cycle">版本周期</h3>
+<p>HAL 实现通过设置 <code>your_poll_device.common.version</code> 指定实现的 HAL 接口版本。现有 HAL 接口版本在 sensors.h 中定义,相应功能与这些版本绑定在一起。</p>
+<p>Android 框架目前支持版本 1.0 和 1.3,不过版本 1.0 很快将不再受支持。本文档介绍了版本 1.3(所有设备均应升级到该版本)的行为。要详细了解如何升级到版本 1.3,请参阅 <a href="versioning.html">HAL 版本弃用</a>。</p>
+<h2 id="kernel_driver">内核驱动程序</h2>
+<p>传感器驱动程序可与物理设备进行交互。在某些情况下,HAL 实现和驱动程序是同一软件实体。在其他情况下,硬件集成者会要求传感器芯片制造商提供相应驱动程序,但是它们是用于编写 HAL 实现的驱动程序。</p>
+<p>在所有情况下,HAL 实现和内核驱动程序都由硬件制造商负责提供,Android 不提供首选编写方式。</p>
+<h2 id="sensor_hub">传感器中枢</h2>
+<p>设备的传感器堆栈可视需要添加传感器中枢。在 SoC 可以处于暂停模式时,传感器中枢对执行一些低功耗的低级计算任务非常有用。例如,计步功能或传感器融合功能可以在这些芯片上执行。此外,它也是实施传感器批处理以及为传感器事件添加硬件 FIFO 的理想位置。请参阅<a href="batching.html">批处理</a>,了解详情。</p>
+<p>传感器中枢的具体化方式取决于架构。它有时是一个单独的芯片,有时包含在与 SoC 相同的芯片上。传感器中枢的重要特征是,应该包含足够的内存来进行批处理,并消耗极少的电量以便能实现低功耗 Android 传感器。部分传感器中枢包含一个微控制器(用于通用计算)和硬件加速器(用于针对低电耗传感器实现极低功耗计算)。</p>
+<p>传感器中枢的架构方式以及与传感器和 SoC(I2C 总线、SPI 总线等)的通信方式并非由 Android 指定,但应该以最大程度减少整体功耗为目标。</p>
+<p>有一种方案似乎会对实现的简单性产生重大影响,即从传感器中枢到 SoC 设置两个中断行:一个用于唤醒中断(适用于唤醒传感器),另一个用于非唤醒中断(适用于非唤醒传感器)。</p>
+<h2 id="sensors">传感器</h2>
+<p>传感器是进行测量操作的物理 MEM 芯片。在很多情况下,同一个芯片上会有多个物理传感器。例如,一些芯片中包含加速度计、陀螺仪和磁力计(此类芯片通常称为 9 轴芯片,因为每个传感器基于 3 个轴提供数据)。</p>
+<p>此外,其中的部分芯片还包含用于执行常见计算任务(例如运动状态检测、步数检测以及 9 轴传感器融合)的逻辑。</p>
+<p>尽管 CDD 功率和精确度的要求与建议针对的是 Android 传感器而非物理传感器,但这些要求会影响物理传感器的选择。例如,游戏旋转矢量传感器的精确度要求会影响物理陀螺仪的精确度要求。设备制造商负责推算物理传感器的相关要求。</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/sensors/suspend-mode.html b/zh-cn/devices/sensors/suspend-mode.html
new file mode 100644
index 0000000..68040c7
--- /dev/null
+++ b/zh-cn/devices/sensors/suspend-mode.html
@@ -0,0 +1,37 @@
+<html devsite><head>
+    <title>挂起模式</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 The Android Open Source Project
+
+      Licensed under the Apache License, Version 2.0 (the "License");
+      you may not use this file except in compliance with the License.
+      You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      See the License for the specific language governing permissions and
+      limitations under the License.
+  -->
+
+<h2 id="soc_power_states">SoC 电源状态</h2>
+<p>系统芯片 (SoC) 的电源状态包括:开启、空闲和挂起。“开启”表示 SoC 正在运行。“空闲”表示一种中等耗电模式,在该模式下,SoC 已接通电源但不执行任何任务。“挂起”表示 SoC 未通电的低功耗模式。该模式下的设备功耗通常是“开启”模式的 1/100。</p>
+<h2 id="non-wake-up_sensors">非唤醒传感器</h2>
+<p>非唤醒传感器是不阻止 SoC 进入挂起模式,也不会将 SoC 唤醒以报告数据的传感器。尤其是,不允许驱动程序持有唤醒锁定。如果应用要在屏幕关闭时从非唤醒传感器那接收事件,则其有责任保留部分唤醒锁定。当 SoC 处于挂起模式时,传感器必须继续工作并生成事件,这些事件会放入硬件 FIFO 中。(有关详情,请参阅<a href="batching.html">批处理</a>。)当 SoC 唤醒时,FIFO 中的事件将传送到应用。如果 FIFO 太小而无法存储所有事件,则较旧的事件将丢失;最旧的数据将被删除以容纳最新的数据。在不存在 FIFO 的极端情况下,在 SoC 处于挂起模式时生成的所有事件都将丢失。一个例外情况是来自每个变化模式传感器的最新事件:最后一个事件<a href="batching.html#precautions_to_take_when_batching_non-wake-up_on-change_sensors">必须保存</a>在 FIFO 之外,以使其不会丢失。</p>
+<p>一旦 SoC 退出挂起模式,就会报告来自 FIFO 的所有事件,并且操作将恢复正常。</p>
+<p>使用非唤醒传感器的应用要么应持有唤醒锁定以确保系统不会挂起,在不需要传感器时取消注册传感器,要么会在 SoC 处于挂起模式期间丢失事件。</p>
+<h2 id="wake-up_sensors">唤醒传感器</h2>
+<p>与非唤醒传感器相反,唤醒传感器会确保其数据在传输时不依赖于 SoC 状态。当 SoC 唤醒时,唤醒传感器的行为就像非唤醒传感器。当 SoC 休眠时,唤醒传感器必须唤醒 SoC 以发送事件。它们仍必须让 SoC 进入挂起模式,但是当需要报告事件时,还必须唤醒 SoC。也就是说,在达到最大报告延迟时间或硬件 FIFO 已满之前,传感器必须唤醒 SoC 并传送事件。有关详情,请参阅<a href="batching.html">批处理</a>。</p>
+<p>为确保应用有时间在 SoC 返回休眠状态之前接收事件,每次报告事件时,驱动程序必须持有“超时唤醒锁定”200 毫秒。<em>也就是说,在唤醒中断后的 200 毫秒内,不允许 SoC 返回休眠状态。</em> 此要求将在未来的 Android 版本中消失,在此之前,我们需要该超时唤醒锁定。</p>
+<h2 id="how_to_define_wake-up_and_non-wake-up_sensors">如何定义唤醒和非唤醒传感器?</h2>
+<p>在 KitKat 及更早版本中,某个传感器是唤醒传感器还是非唤醒传感器由传感器类型确定:除<a href="sensor-types.html#proximity">近程</a>传感器和<a href="sensor-types.html#significant_motion">大幅度动作检测器</a>之外,大多数传感器都是非唤醒传感器。</p>
+<p>从 L 版本开始,给定传感器是否为唤醒传感器由传感器定义中的标记指定。大多数传感器均可由同一传感器的唤醒和非唤醒变体对来定义,在这种情况下,它们必须表现为两个独立的传感器,且彼此不进行交互。有关详情,请参阅<a href="interaction.html">交互性</a>。</p>
+<p>除非在传感器类型定义中另行指定,否则建议为<a href="sensor-types.html">传感器</a>类型中列出的每种传感器类型实现一个唤醒传感器和一个非唤醒传感器。在每个传感器类型定义中,查看 <code>SensorManager.getDefaultSensor(sensorType)</code> 将返回什么样的传感器(唤醒还是非唤醒)。它是大多数应用将使用的传感器。</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/storage/adoptable.html b/zh-cn/devices/storage/adoptable.html
new file mode 100644
index 0000000..430304a
--- /dev/null
+++ b/zh-cn/devices/storage/adoptable.html
@@ -0,0 +1,49 @@
+<html devsite><head>
+    <title>可合并的存储设备</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 The Android Open Source Project
+
+      Licensed under the Apache License, Version 2.0 (the "License");
+      you may not use this file except in compliance with the License.
+      You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      See the License for the specific language governing permissions and
+      limitations under the License.
+  -->
+
+<p>Android 一直都支持外部存储配件(如 SD 卡),但由于预期的无常性以及为<a href="/devices/storage/traditional.html">传统外部存储设备</a>只提供最低限度的数据保护,因此这些配件一直以来仅限于简单的文件存储。Android 6.0 推出了<a href="http://developer.android.com/about/versions/marshmallow/android-6.0.html#adoptable-storage">合并</a>外部存储媒介以充当内部存储设备的功能。</p>
+
+<p>当合并外部存储媒介时,系统将对其进行格式化和加密处理,以便一次仅与单个 Android 设备配合使用。由于该媒介与合并它的 Android 设备紧密关联,因此可以安全地为所有用户存储应用和私密数据。</p>
+
+<p>当用户将新的存储媒介(如 SD卡)插入到可合并的位置时,Android 会询问他们想要如何使用该媒介。他们可以选择合并该媒介,这样的话,系统会对该媒介进行格式化和加密处理,或者也可以继续按原样将其用于简单的文件存储。如果他们选择合并媒介,平台会询问是否将主要共享存储内容(通常装载在 <code>/sdcard</code> 上)迁移到新合并的媒介上,从而腾出宝贵的内部存储空间。不同于因使用 <a href="https://en.wikipedia.org/wiki/Master_boot_record">MBR</a> 而限制为 2TB 的传统存储设备,可合并的存储设备使用 <a href="https://en.wikipedia.org/wiki/GUID_Partition_Table">GPT</a>,因而文件存储限制约为 9ZB。</p>
+
+<p>只有当开发者通过 <code>android:installLocation</code> 属性指示提供支持时,才能将应用放置在合并的存储媒介上。新安装的受支持的应用将自动放置在具有最多可用空间的存储设备上,用户可以在“设置”应用中在存储设备之间移动支持的应用。<em></em>移动到已合并媒介的应用在媒介弹出时被记住,并在重新插入媒介时返回弹出前的状态。</p>
+
+<h2 id="security">安全性</h2>
+
+<p>平台为每个合并的设备随机生成加密密钥,该密钥存储在 Android 设备的内部存储设备上。这样可以有效地使得合并的媒介与内部存储设备一样安全。密钥与合并的设备(基于合并的分区 GUID)相关联。合并的设备使用通过 <code>aes-cbc-essiv:sha256</code> 算法和 128 位密钥大小配置的 <code>dm-crypt</code> 进行加密。</p>
+
+<p>合并设备的磁盘布局紧密对应内部数据分区,包括 SELinux 标签等。当在 Android 设备上支持多用户时,合并的存储设备也通过与内部存储设备相同的隔离级别支持多用户。</p>
+
+<p>由于合并的存储设备的内容与合并该设备的 Android 设备密切相关,加密密钥不应可以从父设备中进行提取,因此该存储设备无法装载到其他位置。</p>
+
+<h2 id="performance_and_stability">性能和稳定性</h2>
+
+<p>应该只考虑合并位于稳定位置(如电池盒内或防护盖后面的插槽)的外部存储媒介,以避免意外的数据丢失或损坏。尤其是,绝不应该考虑合并连接到手机或平板电脑的 USB 设备。一种常见的例外情况是连接到电视类设备的外部 U 盘,因为整个电视机通常安装在一个稳定的位置。</p>
+
+<p>当用户合并新的存储设备时,平台将运行基准测试,并将其性能与内部存储设备进行比较。如果所合并设备的速度明显慢于内部存储设备,则平台将警告用户体验可能会受到影响。此基准根据常用 Android 应用的实际 I/O 行为得出。目前,AOSP 实现只会在超出单个阈值时警告用户,但是设备制造商可以进一步做出调整,例如如果存储卡运行非常缓慢,则完全拒绝合并。</p>
+
+<p>合并的设备必须使用支持 POSIX 权限和扩展属性(如 <code>ext4</code> 或 <code>f2fs</code>)的文件系统进行格式化。为了获得最佳性能,建议基于闪存的存储设备使用 <code>f2fs</code> 文件系统。</p>
+
+<p>在执行周期性空闲维护时,平台将向合并的媒介发出 <code>FI_TRIM</code>(就像对待内部存储设备那样)。目前的 SD 卡规格不支持 <code>DISCARD</code> 命令;内核转而会使用 <code>ERASE</code> 命令,SD 卡固件可以选择使用该命令来满足优化目的。</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/storage/config-example.html b/zh-cn/devices/storage/config-example.html
new file mode 100644
index 0000000..02424e3
--- /dev/null
+++ b/zh-cn/devices/storage/config-example.html
@@ -0,0 +1,141 @@
+<html devsite><head>
+    <title>配置示例</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 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>下文提供了适用于各种设备类型的外部存储配置示例,其中仅包含配置文件的相关部分。
+</p><p>由于 Android 6.0 中发生了配置变化(例如移除 <code>storage_list.xml</code> 资源叠加层),因此配置示例分为两类。</p>
+
+<h2 id="android_5_x">Android 5.x 及更早版本</h2>
+<h3 id="android_5_x_physical">仅主要物理存储</h3>
+<p>这是 Nexus One 等具有单一外部存储设备(一种物理 SD 卡)的设备的典型配置。</p>
+<p>首先,原始物理设备必须装载在 <code>/mnt/media_rw</code>(仅系统和 FUSE 守护进程可以访问该位置)下。然后,当插入/移除媒体时,<code>vold</code> 将管理 <code>fuse_sdcard0</code> 服务。
+</p><h4>fstab.hardware</h4>
+<pre><code>[physical device node]  auto  vfat  defaults  voldmanaged=sdcard0:auto,noemulatedsd
+</code></pre>
+<h4>init.hardware.rc</h4>
+<pre><code>on init
+    mkdir /mnt/media_rw/sdcard0 0700 media_rw media_rw
+    mkdir /storage/sdcard0 0700 root root
+    export EXTERNAL_STORAGE /storage/sdcard0
+service fuse_sdcard0 /system/bin/sdcard -u 1023 -g 1023 -d /mnt/media_rw/sdcard0 /storage/sdcard0
+    class late_start
+    disabled
+</code></pre>
+<h4>storage_list.xml</h4>
+<pre><code>&lt;storage
+    android:mountPoint="/storage/sdcard0"
+    android:storageDescription="@string/storage_sd_card"
+    android:removable="true"
+    android:primary="true"
+    android:maxFileSize="4096" /&gt;
+</code></pre>
+<h3 id="android_5_x_emulated">仅主要模拟存储</h3>
+<p>这是 Nexus 4 等具有单一外部存储设备(由设备上的内部存储设备提供支持)的设备的典型配置。</p>
+<h4>init.hardware.rc</h4>
+<pre><code>on init
+    mkdir /mnt/shell/emulated 0700 shell shell
+    mkdir /storage/emulated 0555 root root
+    export EXTERNAL_STORAGE /storage/emulated/legacy
+    export EMULATED_STORAGE_SOURCE /mnt/shell/emulated
+    export EMULATED_STORAGE_TARGET /storage/emulated
+on fs
+    setprop ro.crypto.fuse_sdcard true
+service sdcard /system/bin/sdcard -u 1023 -g 1023 -l /data/media /mnt/shell/emulated
+    class late_start
+</code></pre>
+<h4>storage_list.xml</h4>
+<pre><code>&lt;storage
+    android:storageDescription="@string/storage_internal"
+    android:emulated="true"
+    android:mtpReserve="100" /&gt;
+</code></pre>
+<h3 id="android_5_x_both">模拟存储为主,物理存储为辅</h3>
+<p>这是 Xoom 等具有多个外部存储设备(其中主要设备由设备上的内部存储设备提供支持,辅助设备是物理 SD 卡)的设备的典型配置。</p>
+<p>首先,原始物理设备必须装载在 <code>/mnt/media_rw</code>(仅系统和 FUSE 守护进程可以访问该位置)下。然后,当插入/移除媒体时,<code>vold</code> 将管理 <code>fuse_sdcard1</code> 服务。</p>
+<h4>fstab.hardware</h4>
+<pre><code>[physical device node]  auto  vfat  defaults  voldmanaged=sdcard1:auto
+</code></pre>
+<h4>init.hardware.rc</h4>
+<pre><code>on init
+    mkdir /mnt/shell/emulated 0700 shell shell
+    mkdir /storage/emulated 0555 root root
+    mkdir /mnt/media_rw/sdcard1 0700 media_rw media_rw
+    mkdir /storage/sdcard1 0700 root root
+    export EXTERNAL_STORAGE /storage/emulated/legacy
+    export EMULATED_STORAGE_SOURCE /mnt/shell/emulated
+    export EMULATED_STORAGE_TARGET /storage/emulated
+    export SECONDARY_STORAGE /storage/sdcard1
+on fs
+    setprop ro.crypto.fuse_sdcard true
+service sdcard /system/bin/sdcard -u 1023 -g 1023 -l /data/media /mnt/shell/emulated
+    class late_start
+service fuse_sdcard1 /system/bin/sdcard -u 1023 -g 1023 -w 1023 -d /mnt/media_rw/sdcard1 /storage/sdcard1
+    class late_start
+    disabled
+</code></pre>
+<h4>storage_list.xml</h4>
+<pre><code>&lt;storage
+    android:storageDescription="@string/storage_internal"
+    android:emulated="true"
+    android:mtpReserve="100" /&gt;
+&lt;storage
+    android:mountPoint="/storage/sdcard1"
+    android:storageDescription="@string/storage_sd_card"
+    android:removable="true"
+    android:maxFileSize="4096" /&gt;
+</code></pre>
+
+<h2 id="android_6">Android 6.0</h2>
+<h3 id="android_6_physical">仅主要物理存储</h3>
+<p>这是原始 Android One 等具有单一外部存储设备(一种物理 SD 卡)的设备的典型配置。这种配置没有辅助共享存储空间,且设备不支持多用户。</p>
+<h4>fstab.device</h4>
+<pre><code>/devices/platform/mtk-msdc.1/mmc_host*         auto        auto       defaults
+voldmanaged=sdcard0:auto,encryptable=userdata,noemulatedsd
+</code></pre>
+<h4>init.device.rc</h4>
+<pre><code>on init
+    # By default, primary storage is physical
+    setprop ro.vold.primary_physical 1
+    </code></pre>
+<h3 id="android_6_emulated">仅主要模拟存储</h3>
+<p>这是 Nexus 6 等具有单一外部存储设备(由设备上的内部存储设备提供支持)的设备的典型配置。</p>
+<ul>
+  <li>主共享存储空间 (<code>/sdcard</code>) 在内部存储设备的顶部进行模拟。
+  </li><li>没有辅助 SD 卡存储设备。
+  </li><li>支持 USB OTG 存储设备。
+  </li><li>支持多用户。
+</li></ul>
+<h4>fstab.device</h4>
+<pre><code>/devices/*/xhci-hcd.0.auto/usb*             auto            auto    defaults
+                                                    voldmanaged=usb:auto</code></pre>
+<h3 id="android_6_both">模拟存储为主,物理存储为辅</h3>
+<p>这是 Xoom 等具有多个外部存储设备(其中主要设备由设备上的内部存储设备提供支持,辅助设备是物理 SD 卡)的设备的典型配置。</p>
+<ul>
+  <li>主共享存储空间 (<code>/sdcard</code>) 在内部存储设备的顶部进行模拟。
+  </li><li>辅助存储设备是可以采用的物理 SD 卡插槽。
+  </li><li>支持多用户。
+</li></ul>
+<h4>fstab.device</h4>
+<pre><code>/devices/platform/mtk-msdc.1/mmc_host*           auto      auto     defaults
+voldmanaged=sdcard1:auto,encryptable=userdata
+</code></pre>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/storage/config.html b/zh-cn/devices/storage/config.html
new file mode 100644
index 0000000..380f186
--- /dev/null
+++ b/zh-cn/devices/storage/config.html
@@ -0,0 +1,96 @@
+<html devsite><head>
+    <title>设备配置</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 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>外部存储由 <code>vold</code> init 服务和 <code>MountService</code> 系统服务共同管理。外部物理存储卷的装载由 <code>vold</code> 处理,它通过执行分阶段操作来准备好媒体,然后再将其提供给应用。</p>
+
+<h2 id="file_mappings">文件映射</h2>
+<p>对于 Android 4.2.2 及更早版本,特定于设备的 <code>vold.fstab</code> 配置文件定义从 sysfs 设备到文件系统装载点的映射,每行都遵循以下格式:</p>
+<pre><code>dev_mount &lt;label&gt; &lt;mount_point&gt; &lt;partition&gt; &lt;sysfs_path&gt; [flags]
+</code></pre>
+<ul>
+<li><code>label</code>:卷的标签。</li>
+<li><code>mount_point</code>:要装载卷的文件系统路径。</li>
+<li><code>partition</code>:分区编号(从 1 开始);如果是第一个可用分区,则为“auto”。</li>
+<li><code>sysfs_path</code>:可以提供此装载点的设备的一个或多个 sysfs 路径。这些路径用空格分开,且必须都以 <code>/</code> 开头。</li>
+<li><code>flags</code>:可选的逗号分隔标记列表,不能包含 <code>/</code>。可能的值包括 <code>nonremovable</code> 和 <code>encryptable</code>。</li>
+</ul>
+<p>对于 Android 4.3 及更高版本,init、vold 和 recovery 所使用的各种 fstab 文件在 <code>/fstab.&lt;device&gt;</code> 文件中进行统一。对于由 <code>vold</code> 管理的外部存储卷,条目应采用以下格式:</p>
+<pre><code>&lt;src&gt; &lt;mnt_point&gt; &lt;type&gt; &lt;mnt_flags&gt; &lt;fs_mgr_flags&gt;
+</code></pre>
+<ul>
+<li><code>src</code>:sysfs(通常在 /sys 下装载)下可以提供装载点的设备的路径。路径必须以 <code>/</code> 开头。</li>
+<li><code>mount_point</code>:要装载卷的文件系统路径。</li>
+<li><code>type</code>:卷上的文件系统类型。如果是外部卡,则通常为 <code>vfat</code>。</li>
+<li><code>mnt_flags</code>:<code>Vold</code> 会忽略此字段,应将其设置为 <code>defaults</code></li>
+<li><code>fs_mgr_flags</code>:<code>Vold</code> 会忽略此字段中不包含 <code>voldmanaged=</code> 标记的统一的 fstab 中的任何行。该标记必须后跟描述卡的标签,以及分区号或字词 <code>auto</code>。例如:<code>voldmanaged=sdcard:auto</code>。其他可能的标记有 <code>nonremovable</code>、<code>encryptable=sdcard</code>、<code>noemulatedsd</code> 和 <code>encryptable=userdata</code>。</li>
+</ul>
+
+<h2 id="configuration_details">配置详情</h2>
+<p>框架层以及以上的外部存储交互通过 <code>MountService</code> 进行处理。由于 Android 6.0 中进行了配置更改(例如移除了 storage_list.xml 资源叠加层),因此配置详情分为两类。
+
+</p><h3 id="android_5_x_and_earlier">Android 5.x 及更早版本</h3>特定于设备的 <code>storage_list.xml</code> 配置文件(通常通过 <code>frameworks/base</code> 叠加层提供)定义存储设备的属性和限制。<code>&lt;StorageList&gt;</code> 元素包含一个或多个 <code>&lt;storage&gt;</code> 元素,其中一个元素应被标记为主元素。<code>&lt;storage&gt;</code> 属性包括:<p></p>
+<ul>
+<li><code>mountPoint</code>:此装载的文件系统路径。</li>
+<li><code>storageDescription</code>:描述此装载的字符串资源。</li>
+<li><code>primary</code>:如果此装载是主要外部存储,则为 true。</li>
+<li><code>removable</code>:如果此装载包含可移动媒体(如物理 SD 卡),则为 true。</li>
+<li><code>emulated</code>:如果此装载由可能使用 FUSE 守护进程的内部存储模拟和支持,则为 true。</li>
+<li><code>mtp-reserve</code>:MTP 应为免费存储预留的存储 MB 数。仅在装载被标记为模拟时使用。</li>
+<li><code>allowMassStorage</code>:如果此装载可通过 USB 大容量存储设备共享,则为 true。</li>
+<li><code>maxFileSize</code>:最大文件大小(以 MB 为单位)。</li>
+</ul>
+<p>设备可以通过模拟由内部存储支持的文件系统(不区分大小写,无需权限)来提供外部存储。<code>system/core/sdcard</code> 中的 FUSE 守护进程提供一个可能的实现,可添加为特定于设备的 <code>init.rc</code> 服务:</p>
+<pre><code># virtual sdcard daemon running as media_rw (1023)
+service sdcard /system/bin/sdcard &lt;source_path&gt; &lt;dest_path&gt; 1023 1023
+    class late_start
+</code></pre>
+<p>其中,<code>source_path</code> 为提供支持的内部存储,<code>dest_path</code> 为目标装载点。</p>
+<p>配置特定于设备的 <code>init.rc</code> 脚本时,必须将 <code>EXTERNAL_STORAGE</code> 环境变量定义为主要外部存储的路径。<code>/sdcard</code> 路径也必须通过符号链接解析到同一位置。如果设备在平台更新之间调整外部存储的位置,则应创建符号链接,以便旧的路径继续发挥作用。</p>
+
+<h3 id="android_6_0">Android 6.0</h3>
+<p>目前,存储子系统的配置集中在特定于设备的 <code>fstab</code> 文件中,并且移除了一些历史静态配置文件/变量,以支持更多动态行为:</p>
+<ul>
+   <li><code>storage_list.xml</code> 资源叠加层已被移除,框架已不再使用该叠加层。现在,存储设备在被 <code>vold</code> 检测到时动态配置。
+   </li><li><code>EMULATED_STORAGE_SOURCE/TARGET</code> 环境变量已被移除,Zygote 已不再使用这些变量来配置特定于用户的装载点。相反,用户分离现在由特定于用户的 GID 强制执行,主要共享存储由 <code>vold</code> 在运行时装载到位。
+  <ul>
+     <li>开发者可以根据其使用情形继续动态或静态构建路径。在路径中包含 UUID 可识别每个卡,以便为开发者提供更清晰的位置。(例如,<code>/storage/ABCD-1234/report.txt</code> 明显是与 <code>/storage/DCBA-4321/report.txt</code> 不同的文件。)
+  </li></ul>
+   </li><li>硬编码的 FUSE 服务已从特定于设备的 <code>init.rc</code> 文件中移除,在需要时将从 <code>vold</code> 动态派生。
+</li></ul>
+<p>除了这些配置更改之外,Android 6.0 还包含可合并的存储设备的概念。对于 Android 6.0 设备,任何未被合并的物理媒体都被视为便携式设备。</p>
+
+<h4 id="adoptable_storage">可合并的存储设备</h4>
+<p>要在 <code>fstab</code> 中表示可合并的存储设备,请使用 <code>fs_mgr_flags</code> 字段中的 <code>encryptable=userdata</code> 属性。典型定义如下:</p>
+<pre><code>/devices/platform/mtk-msdc.1/mmc_host*           auto      auto     defaults
+voldmanaged=sdcard1:auto,encryptable=userdata
+</code></pre>
+<p>合并存储设备时,该平台会擦除内容并写入定义两个分区的 GUID 分区表:</p>
+<ul>
+   <li>一个较小的空 <code>android_meta</code> 分区,预留以备将来使用的。分区类型 GUID 为 19A710A2-B3CA-11E4-B026-10604B889DCF。</li><li>一个较大的 <code>android_ext</code> 分区,使用 dm-crypt 加密并使用 <code>ext4</code> 或 <code>f2fs</code>(取决于内核功能)格式化。分区类型 GUID 为 193D1EA4-B3CA-11E4-B075-10604B889DCF。</li></ul>
+<h4 id="portable_storage">便携式存储设备</h4>
+<p>在 <code>fstab</code> 中,具有 <code>voldmanaged</code> 属性的存储设备默认被视为便携式设备,除非定义了其他属性(如 <code>encryptable=userdata</code>)。例如,典型的 USB OTG 设备的定义如下:</p>
+<pre><code>/devices/*/xhci-hcd.0.auto/usb*             auto            auto    defaults
+                                                    voldmanaged=usb:auto
+</code></pre>
+<p>该平台在装载之前使用 <code>blkid</code> 检测文件系统类型,用户可以选择在文件系统不受支持时将媒体格式化。</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/storage/traditional.html b/zh-cn/devices/storage/traditional.html
new file mode 100644
index 0000000..216d4bc
--- /dev/null
+++ b/zh-cn/devices/storage/traditional.html
@@ -0,0 +1,50 @@
+<html devsite><head>
+    <title>传统存储设备</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 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.
+  -->
+
+<img style="float: right; margin: 0px 15px 15px 15px;" src="images/ape_fwk_hal_extstor.png" alt="Android 外部存储设备 HAL 图标"/>
+
+<p>Android 支持采用传统存储的设备,它被定义为具有不可变 POSIX 权限类和模式且不区分大小写的文件系统。传统存储设备的概念包括模拟和便携式存储设备。便携式存储设备指的是系统未<a href="/devices/storage/adoptable.html">合并</a>的任何外部存储设备,因此,未经格式化、加密或绑定到特定设备。由于传统的外部存储设备对存储的数据提供最低限度的保护,因此系统代码不应将敏感数据存储到外部存储设备中。具体来说,只能将配置和日志文件存储到可为其提供妥善保护的内部存储设备中。</p>
+
+<h2 id="multi-user-external-storage">多用户外部存储设备</h2>
+<p>从 Android 4.2 开始,设备可以支持多用户,且外部存储设备必须满足以下限制条件:</p>
+<ul>
+<li>每个用户都必须有各自的独立主要外部存储设备,且不得访问其他用户的主要外部存储设备。</li>
+<li><code>/sdcard</code> 路径必须根据运行进程的用户身份解析到特定于该用户的正确主要外部存储设备。</li>
+<li><code>Android/obb</code> 目录中较大的 OBB 文件的存储可作为优化在多个用户之间共享。</li>
+<li>次要外部存储设备不得让应用写入内容,除非在特定于软件包的目录中获得合成的权限。</li>
+</ul>
+<p>此功能的默认平台实现利用 Linux 内核命名空间,为每个 Zygote 所派生的进程创建独立的装载表,然后使用绑定装载向私有命名空间提供特定于用户的正确主要外部存储设备。</p>
+<p>启动时,系统会在 <code>EMULATED_STORAGE_SOURCE</code>(隐藏于应用中)装载一个模拟的外部存储设备 FUSE 守护进程。在 Zygote 派生之后,它会将特定于用户的相应子目录从 FUSE 守护进程下绑定装载到 <code>EMULATED_STORAGE_TARGET</code>,以便外部存储设备路径正确解析应用。由于应用缺少其他用户存储的可访问装载点,它们只能供启动的用户访问存储设备。</p>
+<p>该实现还使用共享的子树内核功能将装载事件从默认的根命名空间传播到应用命名空间中,从而确保 ASEC 容器和 OBB 装载等功能继续正常运行。它通过将 rootfs 装载为共享模式,然后在每个 Zygote 命名空间都创建好后重新将其装载为从属模式来实现。</p>
+
+<h2 id="multiple-external-storage-devices">多个外部存储设备</h2>
+<p>从 Android 4.4 开始,多个外部存储设备通过 <code>Context.getExternalFilesDirs()</code>、<code>Context.getExternalCacheDirs()</code> 和 <code>Context.getObbDirs()</code> 提供给开发者。</p>
+<p></p>通过这些 API 提供的外部存储设备必须是设备的半永久部件(如电池盒中的 SD 卡插槽)。开发者希望存储在这些位置的数据可供长期使用。因此,瞬态存储设备(如 USB 大容量存储驱动器)不应通过这些 API 提供。<p></p>
+<p><code>WRITE_EXTERNAL_STORAGE</code> 权限必须仅向在设备上的主要外部存储设备授予写入权限。不允许应用写入次要外部存储设备,除非在特定于软件包的目录中获得合成的权限。以这种方式限制写入可确保系统在应用被卸载时将文件清理干净。</p>
+
+<h2 id="support_usb_media">USB 媒体支持</h2>
+
+<p>Android 6.0 支持只需短时间内连接到设备的便携式存储设备,如 U 盘。当用户插入新的便携式设备时,该平台会显示一条通知,以让用户复制或管理相应设备上的内容。</p>
+
+<p>在 Android 6.0 中,任何未合并的设备均被视为便携式设备。由于便携式存储设备只能短时间连接到设备,因此 Android 平台会避免执行媒体扫描之类的繁重操作。第三方应用必须通过<a href="https://developer.android.com/guide/topics/providers/document-provider.html">存储访问框架</a>与便携式存储设备中的文件进行交互;出于隐私和安全考虑,明确禁止直接访问。</p>
+
+</body></html>
\ No newline at end of file
diff --git a/zh-cn/devices/tv/hdmi-cec.html b/zh-cn/devices/tv/hdmi-cec.html
new file mode 100644
index 0000000..8f7ab2e
--- /dev/null
+++ b/zh-cn/devices/tv/hdmi-cec.html
@@ -0,0 +1,262 @@
+<html devsite><head>
+    <title>HDMI-CEC 控制服务</title>
+    <meta name="project_path" value="/_project.yaml"/>
+    <meta name="book_path" value="/_book.yaml"/>
+  </head>
+  <body>
+  <!--
+      Copyright 2017 The Android Open Source Project
+
+      Licensed under the Apache License, Version 2.0 (the "License");
+      you may not use this file except in compliance with the License.
+      You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      See the License for the specific language governing permissions and
+      limitations under the License.
+  -->
+
+<h2 id="intro">简介</h2>
+
+<p>高清多媒体接口消费类电子产品控制 (HDMI-CEC) 标准允许多媒体消费类商品相互通信和交换信息。HDMI-CEC 支持很多功能(如遥控直通和系统音频控制),但最受欢迎的功能之一是单键播放。单键播放功能可以让媒体来源设备打开电视并自动切换其输入端口,因此您无需寻找电视遥控器,即可从 Chromecast 切换到蓝光播放器。</p>
+
+<p>大多数制造商都已采用 HDMI-CEC,因此它们的设备能够与其他公司的设备配合使用。不过,由于各个制造商实现 HDMI-CEC 标准的方式不同,因此设备之间并不总是可以实现顺畅协作,而且支持的功能也因设备而异。由于存在这种差异,消费者并不能放心地假定两个声称支持 CEC 的产品是完全兼容的。</p>
+
+<h2 id="solution">解决方法</h2>
+
+<p>随着 Android 电视输入框架 (TIF) 的推出,HDMI-CEC 可以将所有连接的设备汇集在一起,并最大限度地减少兼容性问题。Android 已经创建了一项名为 <code>HdmiControlService</code> 的系统服务来帮助缓解此类难题。</p>
+
+<p>通过提供 <code>HdmiControlService</code> 作为 Android 生态系统的一部分,Android 希望提供:</p>
+
+<ul>
+  <li>一个面向所有制造商的 HDMI-CEC 标准实现方案,以降低设备的不兼容性。以前,制造商必须开发自己的 HDMI-CEC 实现方案或使用第三方解决方案。</li>
+  <li>一项针对市场上已有的众多 HDMI-CEC 设备进行测试后反响良好的服务。Android 对从产品中发现的兼容性问题进行了认真而细致的研究,并从深谙该技术的设备实现人员处收集了实用的建议。CEC 服务旨在保持标准与对该标准做出的修改之间的良好平衡,以便它可以用于用户已经在使用的产品。</li>
+</ul>
+
+<h2 id="overall_design">整体设计</h2>
+
+<p><code>HdmiControlService</code> 与系统的其余部分(电视输入框架 (TIF)、音频服务和电源服务等)连接,以实现该标准指定的各种功能。</p>
+
+<p>以下示意图描绘了从自定义 CEC 控制器到更简单的 HDMI-CEC 硬件抽象层 (HAL) 实现的转换。</p>
+
+<img src="images/HDMI_Control_Service.png" alt="展示 HDMI-CEC 在 Android 5.0 之前和之后的版本中的实现方式的示意图"/>
+
+<p class="img-caption"><strong>图 1.</strong>  HDMI 控制服务替换</p>
+
+<h2 id="implementation">实现</h2>
+
+<p>请参阅以下示意图,详细了解 HDMI 控制服务。</p>
+
+<img src="images/HDMI_Control_Service_Flow.png" alt="展示 HDMI 控制服务详情的图片"/>
+
+<p class="img-caption"><strong>图 2.</strong>  HDMI 控制服务详情</p>
+
+<p>以下是正确的 Android HDMI-CEC 实现的关键因素:</p>
+
+<ul>
+  <li>管理器类 <code>HdmiControlManager</code> 向特权应用提供 API。TV Input Manager 服务和音频服务等系统服务可以直接获取该服务。</li>
+  <li>该服务旨在允许托管多种类型的逻辑设备。</li>
+  <li>HDMI-CEC 通过硬件抽象层 (HAL) 与硬件连接,以简化对设备之间协议和信号传输机制的差异的处理。设备制造商可以利用 HAL 定义来实现 HAL 层。</li>
+</ul>
+
+<p class="note"><strong>注意</strong>:设备制造商应将以下行添加到 <code>device.mk</code> 中的 <code>PRODUCT_COPY_FILES</code> 内。</p>
+
+<pre>
+PRODUCT_COPY_FILES += \
+frameworks/native/data/etc/android.hardware.hdmi.cec.xml:system/etc/permissions/android.hardware.hdmi.cec.xml
+</pre>
+
+<p>设备制造商需要在 <code>device.mk</code> 中设置 <code>ro.hdmi.device_type</code> 以使 <code>HdmiControlService</code> 正常工作,具体取决于您的设备是 HDMI 接收设备还是 HDMI 源设备。</p>
+
+<p>对于机顶盒 (OTT) 等 HDMI 源设备,请采用如下设置:</p>
+
+<pre>
+PRODUCT_PROPERTY_OVERRIDES += ro.hdmi.device_type=<strong>4</strong>
+</pre>
+
+<p>对于平板电视等 HDMI 接收设备,请采用如下设置:</p>
+
+<pre>
+PRODUCT_PROPERTY_OVERRIDES += ro.hdmi.device_type=<strong>0</strong></pre>
+<p></p>
+
+<ul>
+  <li>设备制造商提供的专有 CEC 控制器不能与 <code>HdmiControlService</code> 同时使用。必须将其停用或移除。在需要处理特定于制造商的命令时通常会用到此类控制器。应通过对该服务进行扩展/修改,将特定于制造商的命令处理程序合并到该服务中。上述工作由设备制造商负责,且并非由 Android 指定。请注意,针对特定于制造商的命令对该服务做出的任何更改均不得干扰标准命令的处理方式,否则将导致设备与 Android 不兼容。</li>
+  <li>对 HDMI-CEC 服务的访问受 <code>SignatureOrSystem</code> 保护级别的保护。只有系统组件或 <code>/system/priv-app</code> 中的应用才能访问该服务。这是为了防止该服务被恶意应用滥用。</li>
+</ul>
+
+<p>Android 支持类型 <code>TV/Display(0)</code> 和 <code>playback device(4)</code>,它们可向显示器发出单键播放命令。目前不支持其他类型(调谐器和录制器)。</p>
+
+<h2 id="hdmi-cec_hal_definition">HDMI-CEC HAL 定义</h2>
+
+<p>为使该服务发挥作用,必须按照 Android 提供的定义来实现 HDMI-CEC HAL。HDMI-CEC HAL 会抽象化硬件级别的差异,并通过 API 将原始操作(分配/读取/写入等)提供给上层。</p>
+
+<p>设备制造商必须支持的 API 调用如下:</p>
+
+<h3 id="tx_rx_events">TX/RX/事件</h3>
+<ul>
+  <li><code>send_message</code></li>
+  <li><code>register_event_callback</code></li>
+</ul>
+
+<h3 id="info">信息</h3>
+<ul>
+  <li><code>get_physical_address</code></li>
+  <li><code>get_version</code></li>
+  <li><code>get_vendor_id</code></li>
+  <li><code>get_port_info</code></li>
+</ul>
+
+<h3 id="logical_address">逻辑地址</h3>
+<ul>
+  <li><code>add_logical_address</code></li>
+  <li><code>clear_logical_address</code></li>
+</ul>
+
+<h3 id="status">状态</h3>
+<ul>
+  <li><code>is_connected set_option</code></li>
+  <li><code>set_audio_return_channel</code></li>
+</ul>
+
+<p>以下是关于 API 的 HDMI-CEC HAL 定义的摘录:</p>
+
+<pre>
+#ifndef ANDROID_INCLUDE_HARDWARE_HDMI_CEC_H
+#define ANDROID_INCLUDE_HARDWARE_HDMI_CEC_H
+
+...
+
+/*
+ * HDMI-CEC HAL interface definition.
+ */
+typedef struct hdmi_cec_device {
+    /**
+     * Common methods of the HDMI-CEC device.  This *must* be the first member of
+     * hdmi_cec_device as users of this structure will cast a hw_device_t to hdmi_cec_device
+     * pointer in contexts where it's known the hw_device_t references a hdmi_cec_device.
+     */
+    struct hw_device_t common;
+
+    /*
+     * (*add_logical_address)() passes the logical address that will be used
+     * in this system.
+     *
+     * HAL may use it to configure the hardware so that the CEC commands addressed
+     * the given logical address can be filtered in. This method can be called
+     * as many times as necessary in order to support multiple logical devices.
+     * addr should be in the range of valid logical addresses for the call
+     * to succeed.
+     *
+     * Returns 0 on success or -errno on error.
+     */
+    int (*add_logical_address)(const struct hdmi_cec_device* dev, cec_logical_address_t addr);
+
+    /*
+     * (*clear_logical_address)() tells HAL to reset all the logical addresses.
+     *
+     * It is used when the system doesn't need to process CEC command any more,
+     * hence to tell HAL to stop receiving commands from the CEC bus, and change
+     * the state back to the beginning.
+     */
+    void (*clear_logical_address)(const struct hdmi_cec_device* dev);
+
+    /*
+     * (*get_physical_address)() returns the CEC physical address. The
+     * address is written to addr.
+     *
+     * The physical address depends on the topology of the network formed
+     * by connected HDMI devices. It is therefore likely to change if the cable
+     * is plugged off and on again. It is advised to call get_physical_address
+     * to get the updated address when hot plug event takes place.
+     *
+     * Returns 0 on success or -errno on error.
+     */
+    int (*get_physical_address)(const struct hdmi_cec_device* dev, uint16_t* addr);
+
+    /*
+     * (*send_message)() transmits HDMI-CEC message to other HDMI device.
+     *
+     * The method should be designed to return in a certain amount of time not
+     * hanging forever, which can happen if CEC signal line is pulled low for
+     * some reason. HAL implementation should take the situation into account
+     * so as not to wait forever for the message to get sent out.
+     *
+     * It should try retransmission at least once as specified in the standard.
+     *
+     * Returns error code. See HDMI_RESULT_SUCCESS, HDMI_RESULT_NACK, and
+     * HDMI_RESULT_BUSY.
+     */
+    int (*send_message)(const struct hdmi_cec_device* dev, const cec_message_t*);
+
+    /*
+     * (*register_event_callback)() registers a callback that HDMI-CEC HAL
+     * can later use for incoming CEC messages or internal HDMI events.
+     * When calling from C++, use the argument arg to pass the calling object.
+     * It will be passed back when the callback is invoked so that the context
+     * can be retrieved.
+     */
+    void (*register_event_callback)(const struct hdmi_cec_device* dev,
+            event_callback_t callback, void* arg);
+
+    /*
+     * (*get_version)() returns the CEC version supported by underlying hardware.
+     */
+    void (*get_version)(const struct hdmi_cec_device* dev, int* version);
+
+    /*
+     * (*get_vendor_id)() returns the identifier of the vendor. It is
+     * the 24-bit unique company ID obtained from the IEEE Registration
+     * Authority Committee (RAC).
+     */
+    void (*get_vendor_id)(const struct hdmi_cec_device* dev, uint32_t* vendor_id);
+
+    /*
+     * (*get_port_info)() returns the hdmi port information of underlying hardware.
+     * info is the list of HDMI port information, and 'total' is the number of
+     * HDMI ports in the system.
+     */
+    void (*get_port_info)(const struct hdmi_cec_device* dev,
+            struct hdmi_port_info* list[], int* total);
+
+    /*
+     * (*set_option)() passes flags controlling the way HDMI-CEC service works down
+     * to HAL implementation. Those flags will be used in case the feature needs
+     * update in HAL itself, firmware or microcontroller.
+     */
+    void (*set_option)(const struct hdmi_cec_device* dev, int flag, int value);
+
+    /*
+     * (*set_audio_return_channel)() configures ARC circuit in the hardware logic
+     * to start or stop the feature. Flag can be either 1 to start the feature
+     * or 0 to stop it.
+     *
+     * Returns 0 on success or -errno on error.
+     */
+    void (*set_audio_return_channel)(const struct hdmi_cec_device* dev, int flag);
+
+    /*
+     * (*is_connected)() returns the connection status of the specified port.
+     * Returns HDMI_CONNECTED if a device is connected, otherwise HDMI_NOT_CONNECTED.
+     * The HAL should watch for +5V power signal to determine the status.
+     */
+    int (*is_connected)(const struct hdmi_cec_device* dev, int port);
+
+    /* Reserved for future use to maximum 16 functions. Must be NULL. */
+    void* reserved[16 - 11];
+} hdmi_cec_device_t;
+
+#endif /* ANDROID_INCLUDE_HARDWARE_HDMI_CEC_H */
+</pre>
+
+<p>借助 API,该服务可以利用硬件资源来发送/接收 HDMI-CEC 命令、配置必要的设置,并(可选)与底层平台(将在 Android 系统处于待机模式时负责 CEC 控制)上的微处理器进行通信。</p>
+
+<h2 id="testing">测试</h2>
+
+<p>设备制造商必须使用自己的工具测试 HDMI-CEC HAL 的 API,以确保它们可以提供预期的功能。</p>
+
+</body></html>
\ No newline at end of file