aboutsummaryrefslogtreecommitdiff
path: root/en/devices/tech/ota/ab/ab_faqs.html
blob: ff978c362afe346d917e7a2c581916a1b83856cb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
<html devsite>
  <head>
    <title>Frequently Asked Questions</title>
    <meta name="project_path" value="/_project.yaml" />
    <meta name="book_path" value="/_book.yaml" />
  </head>
  <body>
  <!--
      Copyright 2018 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.
  -->


      <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>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>