aboutsummaryrefslogtreecommitdiff
path: root/en/devices
diff options
context:
space:
mode:
authorAndroid Partner Docs <noreply@android.com>2017-11-13 11:09:31 -0800
committerClay Murphy <claym@google.com>2017-11-13 14:23:17 -0800
commit04afcc4f4865ec1e526e8ff4493ea340247e94f3 (patch)
tree21a24b7e87037c9d9364de151db069551e798d8a /en/devices
parent6700a72c3945b934469746e0a7d040aea8abd9ff (diff)
downloadsource.android.com-04afcc4f4865ec1e526e8ff4493ea340247e94f3.tar.gz
Docs: Changes to source.android.com
- 175558266 Add left nav to advisory by Danielle Roberts <daroberts@google.com> - 175554955 Fix malformed reference to AOSP by Clay Murphy <claym@google.com> - 175550240 Devsite localized content from translation request 7a0693... by Android Partner Docs <noreply@android.com> - 175549114 Typo fix (ASOP -> AOSP) by Christina Nguyen <cqn@google.com> - 175293154 Devsite localized content from translation request 372f6d... by Android Partner Docs <noreply@android.com> - 175248838 Devsite localized content from translation request 29d8af... by Android Partner Docs <noreply@android.com> - 175218477 Clarify information about update_verifier and care_map.txt. by Christina Nguyen <cqn@google.com> - 175207560 Adding android common kernel details by Heidi von Markham <hvm@google.com> - 175185286 Add November Security bulletins to home page by Danielle Roberts <daroberts@google.com> - 175055180 Add AOSP links to Android and Pixel security bulletins by Danielle Roberts <daroberts@google.com> - 175042468 updated researcher acknowledgments by Android Partner Docs <noreply@android.com> - 175015511 Devsite localized content from translation request 9104ad... by Android Partner Docs <noreply@android.com> - 175015506 Devsite localized content from translation request bd87ac... by Android Partner Docs <noreply@android.com> - 174885954 Update build numbers for Nov 2017 EMR releases by Android Partner Docs <noreply@android.com> - 174874043 Devsite localized content from translation request 76c64c... by Android Partner Docs <noreply@android.com> - 174773244 Update build numbers for Nov 2017 releases by Android Partner Docs <noreply@android.com> - 174726959 Add FunctionFS support to Architecture section of Site Up... by Clay Murphy <claym@google.com> - 174724840 November Pixel/ Nexus & Android security bulletins by Danielle Roberts <daroberts@google.com> - 174719013 Updating link for reporting security vulns on Android by Android Partner Docs <noreply@android.com> - 174704161 Devsite localized content from translation request 937e48... by Android Partner Docs <noreply@android.com> - 174704153 Devsite localized content from translation request 9112c5... by Android Partner Docs <noreply@android.com> - 174528053 Devsite localized content from translation request 6e449c... by Android Partner Docs <noreply@android.com> - 174487952 Add outstanding updates to home page and Site Updates by Clay Murphy <claym@google.com> - 174475927 Add description how to build userspace HAL for neonkey by Android Partner Docs <noreply@android.com> - 174380489 Devsite localized content from translation request 841fb1... by Android Partner Docs <noreply@android.com> - 174380480 Devsite localized content from translation request 9eb492... by Android Partner Docs <noreply@android.com> - 174380476 Devsite localized content from translation request 04daa4... by Android Partner Docs <noreply@android.com> - 174248031 Update documentation to talk about retry vs. no-retry APIs. by Android Partner Docs <noreply@android.com> - 174202686 Update CTS/CTS-Verifier download links for CTS-Nov-2017 R... by Android Partner Docs <noreply@android.com> - 174116481 Devsite localized content from translation request 9299f0... by Android Partner Docs <noreply@android.com> - 174116372 Devsite localized content from translation request 6491d8... by Android Partner Docs <noreply@android.com> - 174099937 Include Nougat MR1 and Oreo branch information in release... by Android Partner Docs <noreply@android.com> - 174083954 Fixed some formatting and grammatical issues. by Christina Nguyen <cqn@google.com> - 174079046 Add devsite-click-to-copy and devsite-terminal classes by Christina Nguyen <cqn@google.com> - 174066120 Fix some terminal and click-to-copy classes by Christina Nguyen <cqn@google.com> - 173967954 Remove optional "function" keyword as discussed in b/6788... by Christina Nguyen <cqn@google.com> - 173952142 Escape a character so that Gerrit reads HTML properly. by Christina Nguyen <cqn@google.com> - 173951380 Update overview page and separated out non-a/b device upd... by Christina Nguyen <cqn@google.com> PiperOrigin-RevId: 175558266 Change-Id: I413bc55681f23979b36d84ded9b012486988421b
Diffstat (limited to 'en/devices')
-rw-r--r--en/devices/_toc-interfaces.yaml2
-rw-r--r--en/devices/_toc-tech.yaml18
-rw-r--r--en/devices/architecture/dto/partitions.html16
-rw-r--r--en/devices/architecture/hidl/services.html14
-rw-r--r--en/devices/architecture/images/android-diffs.pngbin0 -> 67212 bytes
-rw-r--r--en/devices/architecture/images/kernel_branch_hierarchy_44.pngbin0 -> 83197 bytes
-rw-r--r--en/devices/architecture/images/kernel_lts_diff.pngbin0 -> 20146 bytes
-rw-r--r--en/devices/architecture/kernel/android-common.html170
-rw-r--r--en/devices/tech/admin/enterprise-telephony.html15
-rw-r--r--en/devices/tech/config/perms-whitelist.html14
-rw-r--r--en/devices/tech/debug/index.html2
-rw-r--r--en/devices/tech/ota/ab_updates.html1600
-rw-r--r--en/devices/tech/ota/index.html162
-rw-r--r--en/devices/tech/ota/nonab_updates.html195
14 files changed, 1324 insertions, 884 deletions
diff --git a/en/devices/_toc-interfaces.yaml b/en/devices/_toc-interfaces.yaml
index 5a78a719..a7958fc3 100644
--- a/en/devices/_toc-interfaces.yaml
+++ b/en/devices/_toc-interfaces.yaml
@@ -17,6 +17,8 @@ toc:
path: /devices/architecture/kernel/
- title: Stable Releases & Updates
path: /devices/architecture/kernel/releases
+ - title: Android Common Kernels
+ path: /devices/architecture/kernel/android-common
- title: Modular Kernel Requirements
path: /devices/architecture/kernel/modular-kernels
- title: Interface Requirements
diff --git a/en/devices/_toc-tech.yaml b/en/devices/_toc-tech.yaml
index 22d8fa9a..dd7e48a2 100644
--- a/en/devices/_toc-tech.yaml
+++ b/en/devices/_toc-tech.yaml
@@ -169,20 +169,22 @@ toc:
path: /devices/tech/ota/
- title: OTA Tools
path: /devices/tech/ota/tools
- - title: Block-Based OTA
- path: /devices/tech/ota/block
- - title: Inside OTA Packages
- path: /devices/tech/ota/inside_packages
- - title: Device-Specific Code
- path: /devices/tech/ota/device_code
- - title: Reducing OTA Size
- path: /devices/tech/ota/reduce_size
- title: Signing Builds for Release
path: /devices/tech/ota/sign_builds
+ - title: Reducing OTA Size
+ path: /devices/tech/ota/reduce_size
- title: A/B System Updates
path: /devices/tech/ota/ab_updates
- title: Implementing A/B Updates
path: /devices/tech/ota/ab_implement
+ - title: Non-A/B System Updates
+ path: /devices/tech/ota/nonab_updates
+ - title: Block-Based OTA
+ path: /devices/tech/ota/block
+ - title: Inside OTA Packages
+ path: /devices/tech/ota/inside_packages
+ - title: Device-Specific Code
+ path: /devices/tech/ota/device_code
- title: Performance
section:
- title: Overview
diff --git a/en/devices/architecture/dto/partitions.html b/en/devices/architecture/dto/partitions.html
index bcbea204..d18cda84 100644
--- a/en/devices/architecture/dto/partitions.html
+++ b/en/devices/architecture/dto/partitions.html
@@ -150,8 +150,8 @@ several commands, including <code>create</code>, <code>cfg_create</code>, and
<h3 id=create>create</h3>
<p>Use the <code>create</code> command to create a
<code>dtb</code>/<code>dtbo</code> image:</p>
-<pre class="prettyprint">
-$mkdtimg create &lt;image_filename&gt; (&lt;global-option&gt;...) \
+<pre class="devsite-click-to-copy">
+<code class="devsite-terminal">mkdtimg create &lt;image_filename&gt; (&lt;global-option&gt;...) \</code>
&lt;ftb1_filename&gt; (&lt;entry1_option&gt;...) \
&lt;ftb2_filename&gt; (&lt;entry2_option&gt;...) \
...
@@ -184,7 +184,7 @@ value of <code>page_size</code> in <code>dt_table_header</code> is 2048; use
value.</p>
<p>Example:</p>
-<pre class="prettyprint">
+<pre class="devsite-click-to-copy">
[board1.dts]
/dts-v1/;
/plugin/;
@@ -203,7 +203,7 @@ value.</p>
};
-$mkdtimg create dtbo.img --id=/:board_id --custom0=0xabc \
+<code class="devsite-terminal">mkdtimg create dtbo.img --id=/:board_id --custom0=0xabc \</code>
board1.dtbo \
board2.dtbo --id=0x6800 \
board3.dtbo --id=0x6801 --custom0=0x123
@@ -243,7 +243,7 @@ with one or more space characters (these options are the same as
lines beginning with <code>#</code> are ignored.</p>
<p>Example:</p>
-<pre class="prettyprint">
+<pre class="devsite-click-to-copy">
[dtboimg.cfg]
# global options
id=/:board_id
@@ -260,7 +260,7 @@ board2.dtbo
custom0=0x123 # override the value of custom0 in global options
-$mkdtimg cfg_create dtbo.img dtboimg.cfg
+<code class="devsite-terminal">mkdtimg cfg_create dtbo.img dtboimg.cfg</code>
</pre>
<p><code>mkdtimg</code> does not handle alignment for
@@ -278,8 +278,8 @@ useful when using different hardware with identical DTs.</p>
<h3 id=dump>dump</h3>
<p>For <code>dtb</code>/<code>dtbo</code> images, use the <code>dump</code>
command to print the information in the image. Example:</p>
-<pre class="prettyprint">
-$mkdtimg dump dtbo.img
+<pre class="devsite-click-to-copy">
+<code class="devsite-terminal">mkdtimg dump dtbo.img</code>
dt_table_header:
magic = d7b7ab1e
total_size = 1300
diff --git a/en/devices/architecture/hidl/services.html b/en/devices/architecture/hidl/services.html
index 647555b7..75933ec9 100644
--- a/en/devices/architecture/hidl/services.html
+++ b/en/devices/architecture/hidl/services.html
@@ -51,8 +51,12 @@ into the server.</p>
version, calling <code>getService</code> on the desired HAL class:</p>
<pre class="prettyprint">
+// C++
sp&lt;V1_1::IFooService&gt; service = V1_1::IFooService::getService();
sp&lt;V1_1::IFooService&gt; alternateService = 1_1::IFooService::getService("another_foo_service");
+// Java
+V1_1.IFooService; service = V1_1.IFooService.getService(true /* retry */);
+V1_1.IFooService; alternateService = 1_1.IFooService.getService("another", true /* retry */);
</pre>
<p>Each version of a HIDL interface is treated as a separate interface. Thus,
@@ -69,6 +73,16 @@ returned interface. For an interface <code>IFoo</code> in package
<code>android.hardware.foo</code> in the device manifest if the entry exists;
and if the transport method is not available, nullptr is returned.</p>
+<p> In some cases, it may be necessary to continue immediately even without
+getting the service. This can happen (for instance) when a client wants to
+manage service notifications itself or in a diagnostic program (such as
+<code>atrace</code>) which needs to get all hwservices and retrieve them. In
+this case, additional APIs are provided such as <code>tryGetService</code> in C++ or
+<code>getService("instance-name", false)</code> in Java. The legacy API
+<code>getService</code> provided in Java also must be used with service
+notifications. Using this API does not avoid the race condition where a server
+registers itself after the client requests it with one of these no-retry APIs.</p>
+
<h2 id=death>Service death notifications</h2>
<p>Clients who want to be notified when a service dies can receive death
notifications delivered by the framework. To receive notifications, the client
diff --git a/en/devices/architecture/images/android-diffs.png b/en/devices/architecture/images/android-diffs.png
new file mode 100644
index 00000000..312718cb
--- /dev/null
+++ b/en/devices/architecture/images/android-diffs.png
Binary files differ
diff --git a/en/devices/architecture/images/kernel_branch_hierarchy_44.png b/en/devices/architecture/images/kernel_branch_hierarchy_44.png
new file mode 100644
index 00000000..ab749e87
--- /dev/null
+++ b/en/devices/architecture/images/kernel_branch_hierarchy_44.png
Binary files differ
diff --git a/en/devices/architecture/images/kernel_lts_diff.png b/en/devices/architecture/images/kernel_lts_diff.png
new file mode 100644
index 00000000..cbd9fafa
--- /dev/null
+++ b/en/devices/architecture/images/kernel_lts_diff.png
Binary files differ
diff --git a/en/devices/architecture/kernel/android-common.html b/en/devices/architecture/kernel/android-common.html
new file mode 100644
index 00000000..13175576
--- /dev/null
+++ b/en/devices/architecture/kernel/android-common.html
@@ -0,0 +1,170 @@
+<html devsite>
+ <head>
+ <title>Android Common Kernels</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
+<a href="https://android.googlesource.com/kernel/common/" class="external">AOSP
+common kernels</a> are downstream of Long Term Supported (LTS) kernels and
+include patches of interest to the Android community that have not been merged
+into LTS. These patches can include:</p>
+
+<ul>
+<li>Features tailored for Android needs (e.g. interactive <code>cpufreq</code>
+governor).</li>
+<li>Features rejected by upstream due to implementation concerns (e.g. MTP/PTP,
+paranoid networking).</li>
+<li>Features ready for Android devices but still under development upstream
+(e.g. Energy Aware Scheduling/EAS).</li>
+<li>Vendor/OEM features that are useful for others (e.g. <code>sdcardfs</code>).
+</li>
+</ul>
+
+<h2 id="list-of-kernels">List of common kernels</h2>
+<p>To view a list of Android common kernels, refer to
+<a href="https://android.googlesource.com/kernel/common/" class=external>https://android.googlesource.com/kernel/common/</a>
+(shown below).</p>
+<p><img src="../images/android-diffs.png"></p>
+<p class="img-caption"><strong>Figure 1.</strong> List of Android common
+kernels.</p>
+
+<h3 id="differences-lts">Differences from LTS</h3>
+<p>When compared to LTS (4.4.40), the Android common kernel has 679 changes,
+56172 insertions, and 3340 deletions (as of February 2017).</p>
+
+<p><img src="../images/kernel_lts_diff.png"></p>
+<p class="img-caption"><strong>Figure 2.</strong> Android-specific code over
+time.</p>
+
+<p>The largest features include:</p>
+<ul>
+<li>13.8% SoC (arch/arm64, arch/x86)</li>
+<li>9.2% USB (drivers/usb)</li>
+<li>8.2% Energy Aware Scheduling (kernel/sched)</li>
+<li>8.2% Atomic Display Framework (drivers/video/adf)</li>
+<li>8.0% networking (net/netfilter)</li>
+<li>6.2% sdcardfs (fs/sdcardfs)</li>
+<li>5.0% Verity (drivers/md)</li>
+<li>3.7% Input (drivers/input/misc)</li>
+<li>3.3% FIQ Debugger (drivers/staging/android/fiq_debugger)</li>
+<li>2.4% Cpufreq (drivers/cpufreq)</li>
+<li>2.2% Goldfish Emulator (drivers/platform/goldfish)</li>
+</ul>
+
+<h2 id="requirements">Requirements</h2>
+<p>All AOSP common kernels must provide the following:</p>
+<ul>
+<li>Method for downstream partners to get timely updates that include all
+LTS patches.</li>
+<li>Mechanism to guarantee that new feature development does not interfere with
+merging from AOSP common (even for previous Android releases).</li>
+<li>Method for downstream partners to easily identify security patches that are
+part of an <a href="/security/bulletin/">Android Security Bulletin (ASB)</a>.
+This satisfies carriers who require a full requalification if OEMs attempt to
+include patches beyond those listed in the bulletin.</li>
+</ul>
+<p>In addition, regular testing must be performed on AOSP common kernels and
+branches must be tagged when passing.</p>
+
+<h3 id="lts-merges">LTS merges</h3>
+<p>To ensure downstream partners can get timely updates that include all LTS
+patches, android-<var>X</var>.<var>Y</var> gets regular merges from LTS and is
+validated via automated VTS, CTS, and build/boot tests.</p>
+
+<h3 id="android-dessert-branches">Android-dessert branches</h3>
+<p>To guarantee that new feature development does not interfere with merging
+from the AOSP common kernel (even for previous Android releases),
+android-<var>X</var>.<var>Y</var>-<var>androidRel</var> is cloned from
+android-<var>X</var>.<var>Y</var> prior to the initial dessert release, gets regular
+merges from LTS, and is tested against the associated Android release. For
+example, the android-4.4-n branch gets merges from the LTS 4.4.y branch. </p>
+
+<h3 id="android-release-branches">Android-release branches</h3>
+<p>To ensure downstream partners can easily identify security patches that are
+part of an ASB,
+android-<var>X</var>.<var>Y</var>-<var>androidRel</var>-<var>type</var> is
+cloned from android-<var>X</var>.<var>Y</var>-<var>androidRel</var> at the time
+of the Android release and gets only the patches listed in the bulletin.</p>
+
+<p>After the patches associated with a bulletin are confirmed to be merged
+into a release branch, the branch is tagged with the ASB level. For example, the
+tag <strong>ASB-2017-10-05</strong> indicates the release branch contains
+patches from the Android Security Bulletin for October 5th, 2017. Parent
+branches contain those security patches, so if the android-4.4-o-release branch
+is tagged with <strong>ASB-2017-10-01</strong>, android-4.4-o and android-4.4
+are also up-to-date with that bulletin. Example:</p>
+<ul>
+<li>Before releasing Android N MR1, <strong>android-4.4-n-mr1</strong> is cloned
+from <strong>android-4.4-n</strong>.</li>
+<li>Only patches listed in ASBs are merged, allowing OEMs (who have strict
+requirements from carriers to avoid full qualification on security updates) to
+find the patches listed in the bulletin.</li>
+<li><strong>android-4.4-n-mr2</strong> will be
+<strong>android-4.4-n-mr1</strong> plus LTS patches that were merged between the
+releases.</li>
+<li>Each month when the ASB is released publicly, the release branches are
+updated with any patches cited in the bulletin that are upstream
+(device-specific patches cited in the bulletin are not applied to the common
+kernels).</li>
+</ul>
+
+<h3 id="regular-testing">Regular testing</h3>
+<p>Regular testing is performed on all on AOSP common kernels and test results
+are available to the public. Specifically:</p>
+<ul>
+<li>After LTS updates or other patches are merged, VTS and a subset of CTS
+is run and results are made available at
+<a href="https://qa-reports.linaro.org/lkft" class="external">https://qa-reports.linaro.org/lkft</a>.
+</li>
+<li>To continually test for build/boot breaks in a variety of architectures and
+builds, <code>kernelci</code> is run and results are made available at
+<a href="https://kernelci.org/job/android/" class="external">https://kernelci.org/job/android</a>.
+</li>
+</ul>
+
+<h3 id="branch-hierarchy">Branch hierarchy (android-4.4)</h3>
+<p>The branch hierarchy for the android-4.4 kernel uses the following structure:
+</p>
+
+<p><img src="../images/kernel_branch_hierarchy_44.png"></p>
+<p class="img-caption"><strong>Figure 3.</strong> Branch hierarchy for the
+android-4.4 kernel.</p>
+
+<h2 id="guidelines">Guidelines</h2>
+<p>Android implementations should use the following kernel guidelines:</p>
+<ul>
+<li>Use the new AOSP common kernels as upstream merge sources.<ul>
+<li>To get patches from LTS, merge from android-<var>X</var>.<var>Y</var>.<ul>
+<li>Merge regularly during development phase.</li>
+<li>When updating device to a new Android release, merge either from the
+android-<var>X</var>.<var>Y</var> branch or the release branch for the target
+release (e.g. for an update to Nougat MR2, merge from the android-4.4-n-mr2
+branch).</li>
+</ul>
+<li>When constrained by the carrier for a security release, merge from release
+branches for security updates.</li>
+</ul>
+<li>Send fixes upstream to mainline, LTS, or AOSP common.</li>
+</ul>
+
+ </body>
+</html>
diff --git a/en/devices/tech/admin/enterprise-telephony.html b/en/devices/tech/admin/enterprise-telephony.html
index 39a870c2..aee11f3a 100644
--- a/en/devices/tech/admin/enterprise-telephony.html
+++ b/en/devices/tech/admin/enterprise-telephony.html
@@ -75,19 +75,20 @@ for contacts in their Dialer Contacts and SMS/MMS Messaging apps.</p>
<p>
Cross profile contact search should be implemented using the Enterprise Contacts
-API (<code>ContactsContract.Contacts.ENTERPRISE_CONTENT_FILTER_URI</code> etc.)
-see <a
-href="http://developer.android.com/preview/features/afw.html#contacts">http://developer.android.com/preview/features/afw.html#contacts</a>
+API (<code>ContactsContract.Contacts.ENTERPRISE_CONTENT_FILTER_URI</code> etc.), which can be found
+in the <a
+href="http://developer.android.com/preview/features/afw.html#contacts">EMM developer's overview</a>
+on the Android EMM Developers site.
</p>
<h3 id="work-profile-contact-badging">Work profile contact badging</h3>
<p>
Work profile contact badging can be implemented by checking
-<code>ContactsContract.Directory.isEntepriseDirectoryId() </code>if available or
-<a
-href="http://developer.android.com/reference/android/provider/ContactsContract.Contacts.html#isEnterpriseContactId(long)">http://developer.android.com/reference/android/provider/ContactsContract.Contacts.html#isEnterpriseContactId(long)</a>
-<code> </code>
+<code>ContactsContract.Directory.isEntepriseDirectoryId()</code> if available or
+<code><a
+href="http://developer.android.com/reference/android/provider/ContactsContract.Contacts.html#isEnterpriseContactId(long)">isEnterpriseContactId</a></code>
+.
</p>
<h3 id="managed-profile-aware-connectionservice">Managed Profile Aware
diff --git a/en/devices/tech/config/perms-whitelist.html b/en/devices/tech/config/perms-whitelist.html
index 79f03263..0ec1f21c 100644
--- a/en/devices/tech/config/perms-whitelist.html
+++ b/en/devices/tech/config/perms-whitelist.html
@@ -76,8 +76,7 @@
</p>
<pre
- class="prettyprint">development/tools/privapp_permissions/privapp_permissions.py
- </pre>
+ class="prettyprint">development/tools/privapp_permissions/privapp_permissions.py</pre>
<p>
To generate an initial version of device-specific
@@ -86,15 +85,16 @@
</p>
<ol>
<li>Build a system image, as follows:<br>
- <pre>$ . build/envsetup.sh
-$ lunch product_name
-$ make -j</pre>
+ <pre class="devsite-click-to-copy">
+<code class="devsite-terminal">. build/envsetup.sh</code>
+<code class="devsite-terminal">lunch product_name</code>
+<code class="devsite-terminal">make -j</code></pre>
</li>
<li>Run the following tool to generate a <code>privapp-permissions.xml
</code>file that lists all signature|privileged permissions that are required to
- be whitelisted.<br>
- <pre>$ development/tools/privapp_permissions/privapp_permissions.py</pre><br>
+ be whitelisted.<br />
+ <pre class="devsite-terminal devsite-click-to-copy">development/tools/privapp_permissions/privapp_permissions.py</pre>
This tool prints XML content that can be used as a single file or split into
multiple files in <code>/etc/permissions</code>.<br><br>
diff --git a/en/devices/tech/debug/index.html b/en/devices/tech/debug/index.html
index 67b2fee2..1c493637 100644
--- a/en/devices/tech/debug/index.html
+++ b/en/devices/tech/debug/index.html
@@ -159,7 +159,7 @@ directly without taking up anywhere near as much space as an unstripped version.
<p>You can also <code>stack</code> an entire tombstone. Example:</p>
<pre class="devsite-terminal devsite-click-to-copy">
-stack < FS/data/tombstones/tombstone_05</code>
+stack &lt; FS/data/tombstones/tombstone_05</code>
</pre>
<p>This is useful if you've just unzipped a bugreport in the current directory.
For more information about diagnosing native crashes and tombstones, see
diff --git a/en/devices/tech/ota/ab_updates.html b/en/devices/tech/ota/ab_updates.html
index c63f6714..5dc04c2a 100644
--- a/en/devices/tech/ota/ab_updates.html
+++ b/en/devices/tech/ota/ab_updates.html
@@ -21,730 +21,882 @@
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 provide the following benefits:</p>
-
-<ul>
-<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>Updates can be streamed to A/B devices, removing the need to download the
-package before installing it. Streaming means it's not necessary for the
-user to have enough free space to store the update package on <code>/data</code>
-or <code>/cache</code>.
-<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>
-
-<h2 id=overview>About A/B system updates</h2>
-
-<p>A/B system updates affect the following:</p>
-
-<ul>
-<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>
-
-<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>
-
-<h3 id="update-engine">Update engine daemon</h3>
-
-<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>
-
-<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>
-
-<h3 id="bootloader-interactions">Bootloader interactions</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. 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.
- </li>
- <li>
- <strong>Update in progress</strong>: The system is running from slot B, so
- slot B is the bootable, successful, and active slot. Slot A was marked as
- unbootable since the contents of slot A are being updated but not yet
- completed. A reboot in this state should continue booting from slot B.
- </li>
- <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.
- </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.
- </li>
-</ul>
-
-<h3 id="streaming-updates">Streaming update support</h3>
-<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
-added 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>To enable streaming updates in Android 7.1, cherrypick the following
-patches:</p>
-<ul>
-<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>These patches are required to support streaming A/B updates in 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,
-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 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>After a payload is available, the update process is 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>
-
-<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>
-
-<h3 id="post-installation">Post-installation</h3>
-
-<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>For post-installation to succeed, the old kernel must be able to:</p>
-
-<ul>
-<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>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>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>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=faq>Frequently asked questions</h2>
-
-<h3>Has Google used A/B OTAs on any devices?</h3>
-
-<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>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>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 width="33%">A/B</th>
- <th width="33%">Non-A/B</th>
- </tr>
- <tr>
- <td>Bootloader</td>
- <td>50*2</td>
- <td>50</td>
- </tr>
- <tr>
- <td>Boot</td>
- <td>32*2</td>
- <td>32</td>
- </tr>
- <tr>
- <td>Recovery</td>
- <td>0</td>
- <td>32</td>
- </tr>
- <tr>
- <td>Cache</td>
- <td>0</td>
- <td>100</td>
- </tr>
- <tr>
- <td>Radio</td>
- <td>70*2</td>
- <td>70</td>
- </tr>
- <tr>
- <td>Vendor</td>
- <td>300*2</td>
- <td>300</td>
- </tr>
- <tr>
- <td>System</td>
- <td>2048*2</td>
- <td>4096</td>
- </tr>
- <tr>
- <td><strong>Total</strong></td>
- <td><strong>5000</strong></td>
- <td><strong>4680</strong></td>
- </tr>
- </tbody>
-</table>
-
-<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>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>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>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
- number of spare CPU cycles, so reading fewer bytes from flash but needing
- more CPU for I/O was a potential bottleneck.</li>
- <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.</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
-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
-.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
-space is available.</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>
-<tbody>
-<tr>
-<td>.odex</td>
-<td>1391770312 bytes</td>
-<td>50.5%</td>
-</tr>
-<tr>
-<td>.apk</td>
-<td>846878259 bytes</td>
-<td>30.7%</td>
-</tr>
-<tr>
-<td>.so (native C/C++ code)</td>
-<td>202162479 bytes</td>
-<td>7.3%</td>
-</tr>
-<tr>
-<td>.oat files/.art images</td>
-<td>163892188 bytes</td>
-<td>5.9%</td>
-</tr>
-<tr>
-<td>Fonts</td>
-<td>38952361 bytes</td>
-<td>1.4%</td>
-</tr>
-<tr>
-<td>icu locale data</td>
-<td>27468687 bytes</td>
-<td>0.9%</td>
-</tr>
-</tbody>
-</table>
-
-<p>These figures are similar for other devices too, so on Nexus/Pixel
-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 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 the space saved on /system is
-lost on /data?</h3>
-
-<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>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 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>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>
-
-<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" 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.
-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>
-
-<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, 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>
-
-<p>Only a small portion of flash is rewritten: a full Pixel system update
-writes about 2.3GiB. (Apps are also recompiled, but that's true of non-A/B
-too.) Traditionally, block-based full OTAs wrote a similar amount of data, so
-flash wear rates should be similar.</p>
-
-<h3>Does flashing two system partitions increase factory flashing time?</h3>
-
-<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>
-
-<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 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>
-
-<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
-update isn't considered available until that work has been done.</p>
-
-<h3>Can (should) we ship a 32GiB A/B device? 16GiB? 8GiB?</h3>
-
-<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
-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>
-
-<h3>Do A/B OTAs require AVB2.0?</h3>
-
-<p>No.</p>
-
-<h3>Do A/B OTAs break AVB2.0's rollback protection?</h3>
-
-<p>No. There's some confusion here because if an A/B system fails to boot into
-the new system image it will (after some number of retries determined by your
-bootloader) automatically revert to the "previous" system image. The key point
-here though is that "previous" in the A/B sense is actually still the "current"
-system image. As soon as the device successfully boots a new image, rollback
-protection kicks in and ensures that you can't go back. But until you've
-actually successfully booted the new image, rollback protection doesn't
-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>
-
-<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. 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
-corresponds with writing the data blocks, while step 2 is pre-compiling the
-.dex files. These two phases are quite different in terms of performance
-impact. The first phase is simple I/O. This requires little in the way of
-resources (RAM, CPU, I/O) because it's just slowly copying blocks around.</p>
-
-<p>The second phase runs dex2oat to precompile the new system image. This
-obviously has less clear bounds on its requirements because it compiles actual
-apps. And there's obviously much more work involved in compiling a large and
-complex app than a small and simple app; whereas in phase 1 there are no disk
-blocks that are larger or more complex than others.</p>
-
-<p>The process is similar to when Google Play installs an app update in the
-background before showing the <em>5 apps updated</em> notification, as has been
-done for years.</p>
-
-<h3>What if a user is actually waiting for the update?</h3>
-
-<p>The current implementation in GmsCore doesn't distinguish between background
-updates and user-initiated updates but may do so in the future. In the case
-where the user explicitly asked for the update to be installed or is watching
-the update progress screen, we'll prioritize the update work on the assumption
-that they're actively waiting for it to finish.</p>
-
-<h3>What happens if there's a failure to apply an update?</h3>
-
-<p>With non-A/B updates, if an update failed to apply, the user was usually
-left with an unusable device. The only exception was if the failure occurred
-before an application had even started (because the package failed to verify,
-say). With A/B updates, a failure to apply an update does not affect the
-currently running system. The update can simply be retried later.</p>
-
-<h3>What does GmsCore do?</h3>
-
-<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
-<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>:
-<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>
-
-<p>As of 2017-03-15, we have the following information:</p>
-<table class="style0">
-<tbody>
-<tr>
-<td></td>
-<td><strong>Android 7.x Release</strong></td>
-<td><strong>Android 8.x Release</strong></td>
-</tr>
-<tr>
-<td><strong>Qualcomm</strong></td>
-<td>Depending on OEM requests </td>
-<td>All chipsets will get support</td>
-</tr>
-<tr>
-<td><strong>Mediatek</strong></td>
-<td>Depending on OEM requests</td>
-<td>All chipsets will get support</td>
-</tr>
-</tbody>
-</table>
-
-<p>For details on schedules, check with your SoC contacts. For SoCs not listed
-above, reach out to your SoC directly.</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 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 provide the following benefits:</p>
+
+ <ul>
+ <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>
+ Updates can be streamed to A/B devices, removing the need to download
+ the package before installing it. Streaming means it's not necessary
+ for the user to have enough free space to store the update package on
+ <code>/data</code> or <code>/cache</code>.
+ </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>
+
+ <h2 id="overview">About A/B system updates</h2>
+
+ <p>A/B system updates affect the following:</p>
+
+ <ul>
+ <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>
+
+ <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>
+
+ <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>
+
+ <h3 id="update-engine">Update engine daemon</h3>
+
+ <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>
+
+ <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>
+
+ <h3 id="bootloader-interactions">Bootloader interactions</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. 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.
+ </li>
+ <li>
+ <strong>Update in progress</strong>: The system is running from
+ slot B, so slot B is the bootable, successful, and active slot.
+ Slot A was marked as unbootable since the contents of slot A are
+ being updated but not yet completed. A reboot in this state should
+ continue booting from slot B.
+ </li>
+ <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.
+ </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, <code>update_verifier</code>,
+ should mark slot A as successful after some checks are made.
+ </li>
+ </ul>
+
+ <h3 id="streaming-updates">Streaming update support</h3>
+
+ <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 added 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>To enable streaming updates in Android 7.1, cherrypick the following
+ patches:</p>
+
+ <ul>
+ <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 unit test for TerminateTransfer between ranges</a>
+ </li>
+ <li>
+ <a href="https://android-review.googlesource.com/333627" class="external">
+ Cleanup the RetryTimeoutCallback()</a>
+ </li>
+ </ul>
+
+ <p>
+ These patches are required to support streaming A/B updates in
+ Android 7.1 and later 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, 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 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>After a payload is available, the update process is 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>
+ <td>9</td>
+ <td>
+ After the system successfully boots far enough into the new slot
+ and finishes the post-reboot checks, the now current slot
+ (formerly the "target slot") is marked as successful by calling
+ <code>markBootSuccessful()</code>.
+ </td>
+ <tr>
+ </table>
+
+ <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>
+
+ <h3 id="post-installation">Post-installation</h3>
+
+ <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>
+ For post-installation to succeed, the old kernel must be able to:
+ </p>
+
+ <ul>
+ <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>
+ 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>
+ 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>
+ 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>
+
+ <h3 id="after_reboot">After reboot</h3>
+
+ <p>
+ After rebooting, <code>update_verifier</code> triggers the integrity
+ check using dm-verity. This check starts before zygote to avoid Java
+ services making any irreversible changes that would prevent a safe
+ rollback. During this process, bootloader and kernel may also
+ trigger a reboot if verified boot or dm-verity detect any
+ corruption. After the check completes, <code>update_verifier</code>
+ marks the boot successful.
+ </p>
+
+ <p>
+ <code>update_verifier</code> will read only the blocks listed in
+ <code>/data/ota_package/care_map.txt</code>, which is included in an
+ A/B OTA package when using the AOSP code. The Java system update
+ client, such as GmsCore, extracts <code>care_map.txt</code>, sets up
+ the access permission before rebooting the device, and deletes the
+ extracted file after the system successfully boots into the new
+ version.
+ </p>
+
+ <h2 id="faq">Frequently asked questions</h2>
+
+ <h3>Has Google used A/B OTAs on any devices?</h3>
+
+ <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>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>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 width="33%">A/B</th>
+ <th width="33%">Non-A/B</th>
+ </tr>
+ <tr>
+ <td>Bootloader</td>
+ <td>50*2</td>
+ <td>50</td>
+ </tr>
+ <tr>
+ <td>Boot</td>
+ <td>32*2</td>
+ <td>32</td>
+ </tr>
+ <tr>
+ <td>Recovery</td>
+ <td>0</td>
+ <td>32</td>
+ </tr>
+ <tr>
+ <td>Cache</td>
+ <td>0</td>
+ <td>100</td>
+ </tr>
+ <tr>
+ <td>Radio</td>
+ <td>70*2</td>
+ <td>70</td>
+ </tr>
+ <tr>
+ <td>Vendor</td>
+ <td>300*2</td>
+ <td>300</td>
+ </tr>
+ <tr>
+ <td>System</td>
+ <td>2048*2</td>
+ <td>4096</td>
+ </tr>
+ <tr>
+ <td><strong>Total</strong></td>
+ <td><strong>5000</strong></td>
+ <td><strong>4680</strong></td>
+ </tr>
+ </tbody>
+ </table>
+
+ <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>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>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>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
+ number of spare CPU cycles, so reading fewer bytes from flash but needing
+ more CPU for I/O was a potential bottleneck.</li>
+ <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.</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
+ 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
+ .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
+ space is available.</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>
+ <tbody>
+ <tr>
+ <td>.odex</td>
+ <td>1391770312 bytes</td>
+ <td>50.5%</td>
+ </tr>
+ <tr>
+ <td>.apk</td>
+ <td>846878259 bytes</td>
+ <td>30.7%</td>
+ </tr>
+ <tr>
+ <td>.so (native C/C++ code)</td>
+ <td>202162479 bytes</td>
+ <td>7.3%</td>
+ </tr>
+ <tr>
+ <td>.oat files/.art images</td>
+ <td>163892188 bytes</td>
+ <td>5.9%</td>
+ </tr>
+ <tr>
+ <td>Fonts</td>
+ <td>38952361 bytes</td>
+ <td>1.4%</td>
+ </tr>
+ <tr>
+ <td>icu locale data</td>
+ <td>27468687 bytes</td>
+ <td>0.9%</td>
+ </tr>
+ </tbody>
+ </table>
+
+ <p>These figures are similar for other devices too, so on Nexus/Pixel
+ 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 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 the space saved on /system is
+ lost on /data?</h3>
+
+ <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>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 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>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>
+
+ <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" 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.
+ 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>
+
+ <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, 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>
+
+ <p>Only a small portion of flash is rewritten: a full Pixel system update
+ writes about 2.3GiB. (Apps are also recompiled, but that's true of non-A/B
+ too.) Traditionally, block-based full OTAs wrote a similar amount of data, so
+ flash wear rates should be similar.</p>
+
+ <h3>Does flashing two system partitions increase factory flashing time?</h3>
+
+ <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>
+
+ <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 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>
+
+ <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
+ update isn't considered available until that work has been done.</p>
+
+ <h3>Can (should) we ship a 32GiB A/B device? 16GiB? 8GiB?</h3>
+
+ <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
+ 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>
+
+ <h3>Do A/B OTAs require AVB2.0?</h3>
+
+ <p>No.</p>
+
+ <h3>Do A/B OTAs break AVB2.0's rollback protection?</h3>
+
+ <p>No. There's some confusion here because if an A/B system fails to boot into
+ the new system image it will (after some number of retries determined by your
+ bootloader) automatically revert to the "previous" system image. The key point
+ here though is that "previous" in the A/B sense is actually still the "current"
+ system image. As soon as the device successfully boots a new image, rollback
+ protection kicks in and ensures that you can't go back. But until you've
+ actually successfully booted the new image, rollback protection doesn't
+ 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>
+
+ <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. 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
+ corresponds with writing the data blocks, while step 2 is pre-compiling the
+ .dex files. These two phases are quite different in terms of performance
+ impact. The first phase is simple I/O. This requires little in the way of
+ resources (RAM, CPU, I/O) because it's just slowly copying blocks around.</p>
+
+ <p>The second phase runs dex2oat to precompile the new system image. This
+ obviously has less clear bounds on its requirements because it compiles actual
+ apps. And there's obviously much more work involved in compiling a large and
+ complex app than a small and simple app; whereas in phase 1 there are no disk
+ blocks that are larger or more complex than others.</p>
+
+ <p>The process is similar to when Google Play installs an app update in the
+ background before showing the <em>5 apps updated</em> notification, as has been
+ done for years.</p>
+
+ <h3>What if a user is actually waiting for the update?</h3>
+
+ <p>The current implementation in GmsCore doesn't distinguish between background
+ updates and user-initiated updates but may do so in the future. In the case
+ where the user explicitly asked for the update to be installed or is watching
+ the update progress screen, we'll prioritize the update work on the assumption
+ that they're actively waiting for it to finish.</p>
+
+ <h3>What happens if there's a failure to apply an update?</h3>
+
+ <p>With non-A/B updates, if an update failed to apply, the user was usually
+ left with an unusable device. The only exception was if the failure occurred
+ before an application had even started (because the package failed to verify,
+ say). With A/B updates, a failure to apply an update does not affect the
+ currently running system. The update can simply be retried later.</p>
+
+ <h3>What does GmsCore do?</h3>
+
+ <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
+ <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>:
+ <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>
+
+ <p>As of 2017-03-15, we have the following information:</p>
+ <table class="style0">
+ <tbody>
+ <tr>
+ <td></td>
+ <td><strong>Android 7.x Release</strong></td>
+ <td><strong>Android 8.x Release</strong></td>
+ </tr>
+ <tr>
+ <td><strong>Qualcomm</strong></td>
+ <td>Depending on OEM requests </td>
+ <td>All chipsets will get support</td>
+ </tr>
+ <tr>
+ <td><strong>Mediatek</strong></td>
+ <td>Depending on OEM requests</td>
+ <td>All chipsets will get support</td>
+ </tr>
+ </tbody>
+ </table>
+
+ <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/index.html b/en/devices/tech/ota/index.html
index 234ff2de..58737b5c 100644
--- a/en/devices/tech/ota/index.html
+++ b/en/devices/tech/ota/index.html
@@ -23,138 +23,42 @@
-<p>Android devices in the field can receive and install over-the-air (OTA)
-updates to the system and application software. Devices have a special
-recovery partition with the software needed to unpack a downloaded update
-package and apply it to the rest of the system.</p>
-<p>This section describes the structure of these packages and the tools
-provided to build them. It is intended for developers who want to
-make the OTA update system work on new Android devices and those who are
-building update packages for use with released devices. OTA updates are
-designed to upgrade the underlying operating system and the read-only apps
-installed on the system partition; these updates do <i>not</i> affect
-applications installed by the user from Google Play.
-</p>
-<p>This section describes the OTA system as of the Android 5.x release. For
-help porting OTA-related code from older releases, see <a href="#migrating">
-Migrating from previous releases</a>.
-</p>
+ <p>
+ Android devices in the field can receive and install over-the-air (OTA)
+ updates to the system and application software. This section describes
+ the structure of the update packages and the tools provided to build
+ them. It is intended for developers who want to make the OTA update
+ system work on new Android devices and those who are building update
+ packages for use with released devices. OTA updates are designed to
+ upgrade the underlying operating system and the read-only apps installed
+ on the system partition; these updates do <em>not</em> affect
+ applications installed by the user from Google Play.
+ </p>
-<h2 id="android-device-layout">Android device layout</h2>
-<p>The flash space on an Android device typically contains the following
-partitions.</p>
+ <h2 id="ab_updates">A/B updates</h2>
-<dl>
-<dt>boot</dt>
-<dd>Contains the Linux kernel and a minimal root filesystem (loaded into a RAM
-disk). It mounts system and other partitions and starts the runtime located on
-the system partition.</dd>
-<dt>system</dt>
-<dd>Contains system applications and libraries that have source code available
-on Android Open Source Project (AOSP). During normal operation, this partition
-is mounted read-only; its contents change only during an OTA update.</dd>
-<dt>vendor</dt>
-<dd>Contains system applications and libraries that do <em>not</em> have
-source code available on Android Open Source Project (AOSP). During normal
-operation, this partition is mounted read-only; its contents change only
-during an OTA update.</dd>
-<dt>userdata</dt>
-<dd>Stores the data saved by applications installed by the user, etc. This
-partition is not normally touched by the OTA update process.</dd>
-<dt>cache</dt>
-<dd>Temporary holding area used by a few applications (accessing this
-partition requires special app permissions) and for storage of downloaded OTA
-update packages. Other programs use this space with the expectation that files
-can disappear at any time. Some OTA package installations may result in this
-partition being wiped completely.</dd>
-<dt>recovery</dt>
-<dd>Contains a second complete Linux system, including a kernel and the
-special recovery binary that reads a package and uses its contents to update
-the other partitions.</dd>
-<dt>misc</dt>
-<dd>Tiny partition used by recovery to stash some information away about what
-it's doing in case the device is restarted while the OTA package is being
-applied.</dd></dl>
+ <p>
+ Modern A/B devices have two copies of each partition, A and B. Devices
+ apply the update to the currently unused partition while the system is
+ running but idle. A/B devices do not need space to download the update
+ package because they can apply the update as they read it from the
+ network. This is called <em>streaming A/B</em>. A/B updates are also
+ know as <em>seamless updates</em>. For more information about OTA
+ updates for A/B devices, see
+ <a href="/devices/tech/ota/ab_updates.html">A/B (Seamless) System
+ Update
+ </a>.
+ </p>
-<h2 id="life-ota-update">Life of an OTA update</h2>
-<p>A typical OTA update contains the following steps:</p>
-<ol>
-<li>Device performs regular check in with OTA servers and is notified of the
-availability of an update, including the URL of the update package and a
-description string to show the user.</li>
-<li>Update downloads to a cache or data partition, and its cryptographic
-signature is verified against the certificates in
-<code>/system/etc/security/otacerts.zip</code>. User is prompted to install the
-update.</li>
-<li>Device reboots into recovery mode, in which the kernel and system in the
-recovery partition are booted instead of the kernel in the boot partition.</li>
-<li>Recovery binary is started by init. It finds command-line arguments in
-<code>/cache/recovery/command</code> that point it to the downloaded package.
-</li>
-<li>Recovery verifies the cryptographic signature of the package against the
-public keys in <code>/res/keys</code> (part of the RAM disk contained in the
-recovery partition).</li>
-<li>Data is pulled from the package and used to update the boot, system,
-and/or vendor partitions as necessary. One of the new files left on the system
-partition contains the contents of the new recovery partition.</li>
-<li>Device reboots normally. <ol style="list-style-type:lower-alpha">
-<li>The newly updated boot partition is loaded, and it mounts and starts
-executing binaries in the newly updated system partition.</li>
-<li>As part of normal startup, the system checks the contents of the recovery
-partition against the desired contents (which were previously stored as a file
-in <code>/system</code>). They are different, so the recovery partition is
-reflashed with the desired contents. (On subsequent boots, the recovery
-partition already contains the new contents, so no reflash is necessary.)</li>
-</ol></li>
-</ol>
-<p>The system update is complete!</p>
+ <h2 id="nonab_updates">Non-A/B updates</h2>
-<h2 id="migrating">Migrating from previous releases</h2>
-
-<p>When migrating from Android 2.3/3.0/4.0 release, the major change is the
-conversion of all the device-specific functionality from a set of C functions
-with predefined names to C++ objects. The following table lists the old
-functions and the new methods that serve a roughly equivalent purpose:</p>
-
-<table>
-<tbody>
-<tr>
-<th>C function</th>
-<th>C++ method</th>
-</tr>
-<tr>
-<td>device_recovery_start()</td>
-<td>Device::RecoveryStart()</td>
-</tr>
-<tr>
-<td>device_toggle_display()<br>
-device_reboot_now()<br>
-</td>
-<td>RecoveryUI::CheckKey()<br>
-(also RecoveryUI::IsKeyPressed())<br>
-</td>
-</tr>
-<tr>
-<td>device_handle_key()</td>
-<td>Device::HandleMenuKey()</td>
-</tr>
-<tr>
-<td>device_perform_action()</td>
-<td>Device::InvokeMenuItem()</td>
-</tr>
-<tr>
-<td>device_wipe_data()</td>
-<td>Device::WipeData()</td>
-</tr>
-<tr>
-<td>device_ui_init()</td>
-<td>ScreenRecoveryUI::Init()</td>
-</tr>
-</tbody>
-</table>
-
-<p>Conversion of old functions to new methods should be reasonably
-straightforward. Don't forget to add the new <code>make_device()</code>
-function to create and return an instance of your new Device subclass.</p>
+ <p>
+ Older devices have a special recovery partition containing the software
+ needed to unpack a downloaded update package and apply the update to
+ the other partitions. For more information, see
+ <a href="/devices/tech/ota/nonab_updates.html">Non-A/B System Updates
+ </a>.
+ </p>
+
</body>
</html>
diff --git a/en/devices/tech/ota/nonab_updates.html b/en/devices/tech/ota/nonab_updates.html
new file mode 100644
index 00000000..627fa263
--- /dev/null
+++ b/en/devices/tech/ota/nonab_updates.html
@@ -0,0 +1,195 @@
+<html devsite>
+ <head>
+ <title>Non-A/B System 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>On older Android devices without A/B partitions, the flash space
+ typically contains the following partitions:
+ </p>
+
+ <dl>
+ <dt>boot</dt>
+ <dd>
+ Contains the Linux kernel and a minimal root filesystem (loaded into
+ a RAM disk). It mounts system and other partitions and starts the
+ runtime located on the system partition.
+ </dd>
+
+ <dt>system</dt>
+ <dd>
+ Contains system applications and libraries that have source code
+ available on Android Open Source Project (AOSP). During normal
+ operation, this partition is mounted read-only; its contents change
+ only during an OTA update.
+ </dd>
+
+ <dt>vendor</dt>
+ <dd>
+ Contains system applications and libraries that do <em>not</em> have
+ source code available on Android Open Source Project (AOSP). During
+ normal operation, this partition is mounted read-only; its contents
+ change only during an OTA update.
+ </dd>
+
+ <dt>userdata</dt>
+ <dd>
+ Stores the data saved by applications installed by the user, etc. This
+ partition is not normally touched by the OTA update process.
+ </dd>
+
+ <dt>cache</dt>
+ <dd>
+ Temporary holding area used by a few applications (accessing this
+ partition requires special app permissions) and for storage of
+ downloaded OTA update packages. Other programs use this space with the
+ expectation that files can disappear at any time. Some OTA package
+ installations may result in this partition being wiped completely.
+ </dd>
+
+ <dt>recovery</dt>
+ <dd>
+ Contains a second complete Linux system, including a kernel and the
+ special recovery binary that reads a package and uses its contents to
+ update the other partitions.
+ </dd>
+
+ <dt>misc</dt>
+ <dd>
+ Tiny partition used by recovery to stash some information away about
+ what it is doing in case the device is restarted while the OTA package
+ is being applied.
+ </dd>
+ </dl>
+
+ <h2 id="life-ota-update">Life of an OTA update</h2>
+
+ <p>A typical OTA update contains the following steps:</p>
+
+ <ol>
+ <li>
+ Device performs regular check in with OTA servers and is notified of
+ the availability of an update, including the URL of the update
+ package and a description string to show the user.
+ </li>
+ <li>
+ Update downloads to a cache or data partition, and its cryptographic
+ signature is verified against the certificates in
+ <code>/system/etc/security/otacerts.zip</code>. User is prompted to
+ install the update.
+ </li>
+ <li>
+ Device reboots into recovery mode, in which the kernel and system in
+ the recovery partition are booted instead of the kernel in the boot
+ partition.
+ </li>
+ <li>
+ Recovery binary is started by init. It finds command-line arguments
+ in <code>/cache/recovery/command</code> that point it to the
+ downloaded package.
+ </li>
+ <li>
+ Recovery verifies the cryptographic signature of the package against
+ the public keys in <code>/res/keys</code> (part of the RAM disk
+ contained in the recovery partition).
+ </li>
+ <li>
+ Data is pulled from the package and used to update the boot, system,
+ and/or vendor partitions as necessary. One of the new files left on
+ the system partition contains the contents of the new recovery partition.
+ </li>
+ <li>Device reboots normally.
+ <ol style="list-style-type:lower-alpha">
+ <li>
+ The newly updated boot partition is loaded, and it mounts and
+ starts executing binaries in the newly updated system partition.
+ </li>
+ <li>
+ As part of normal startup, the system checks the contents of the
+ recovery partition against the desired contents (which were
+ previously stored as a file in <code>/system</code>). They are
+ different, so the recovery partition is reflashed with the
+ desired contents. (On subsequent boots, the recovery partition
+ already contains the new contents, so no reflash is necessary.)
+ </li>
+ </ol>
+ </li>
+ </ol>
+
+ <p>The system update is complete!</p>
+
+ <h2 id="migrating">Migrating from previous releases</h2>
+
+ <p>
+ When migrating from Android 2.3/3.0/4.0 release, the major change is
+ the conversion of all the device-specific functionality from a set of
+ C functions with predefined names to C++ objects. The following table
+ lists the old functions and the new methods that serve a roughly equivalent purpose:
+ </p>
+
+ <table>
+ <tr>
+ <th>C function</th>
+ <th>C++ method</th>
+ </tr>
+
+ <tr>
+ <td>device_recovery_start()</td>
+ <td>Device::RecoveryStart()</td>
+ </tr>
+
+ <tr>
+ <td>device_toggle_display()<br />
+ device_reboot_now()<br />
+ </td>
+ <td>RecoveryUI::CheckKey()<br />
+ (also RecoveryUI::IsKeyPressed())<br />
+ </td>
+ </tr>
+
+ <tr>
+ <td>device_handle_key()</td>
+ <td>Device::HandleMenuKey()</td>
+ </tr>
+
+ <tr>
+ <td>device_perform_action()</td>
+ <td>Device::InvokeMenuItem()</td>
+ </tr>
+
+ <tr>
+ <td>device_wipe_data()</td>
+ <td>Device::WipeData()</td>
+ </tr>
+
+ <tr>
+ <td>device_ui_init()</td>
+ <td>ScreenRecoveryUI::Init()</td>
+ </tr>
+ </table>
+
+ <p>
+ Conversion of old functions to new methods should be reasonably
+ straightforward. Don't forget to add the new <code>make_device()</code>
+ function to create and return an instance of your new Device subclass.
+ </p>
+
+ </body>
+</html> \ No newline at end of file