Häufig gestellte Fragen

Hat Google A/B-OTAs auf Geräten verwendet?

Ja. Der Marketingname für A/B-Updates ist nahtlose Updates. Die Pixel- und Pixel XL Smartphones vom Oktober 2016 wurden mit A/B ausgeliefert und alle Chromebooks verwenden dieselbe update_engine Implementierung von A/B. Die erforderliche Plattformcode-Implementierung ist in Android 7.1 und höher öffentlich.

Warum sind A/B-OTAs besser?

A/B-OTAs bieten eine bessere Nutzererfahrung bei der Installation von Updates. Messungen von monatlichen Sicherheitsupdates zeigen, dass sich diese Funktion bereits bewährt hat: Im Mai 2017 hatten 95% der Pixel Nutzer nach einem Monat das neueste Sicherheitsupdate installiert, verglichen mit 87% der Nexus-Nutzer. Außerdem aktualisieren Pixel-Nutzer früher als Nexus-Nutzer. Wenn bei einem OTA-Update Blöcke nicht aktualisiert werden können, führt das nicht mehr dazu, dass sich das Gerät nicht mehr starten lässt. Bis das neue System-Image erfolgreich gestartet wurde, kann Android auf das vorherige funktionierende System-Image zurückgreifen.

Was ist system_other?

Anwendungen werden in APK-Dateien gespeichert, die eigentlich ZIP-Archive sind. Jede APK-Datei enthält eine oder mehrere DEX-Dateien mit portierbarem Dalvik-Bytecode. Eine ODEX-Datei (optimierte DEX-Datei) ist von der APK-Datei getrennt und kann gerätespezifischen Maschinencode enthalten. Wenn eine ODEX-Datei verfügbar ist, kann Android Anwendungen mit Ahead-of-Time-Kompilierungsgeschwindigkeit ausführen ohne jedes Mal auf die Kompilierung des Codes warten zu müssen, wenn die Anwendung gestartet wird. Eine ODEX-Datei ist nicht unbedingt erforderlich: Android kann den DEX-Code direkt über die Interpretation oder die Just-in-Time-Kompilierung (JIT) ausführen. Eine ODEX-Datei bietet jedoch die beste Kombination aus Start- und Laufzeitgeschwindigkeit, wenn Speicherplatz verfügbar ist.

Beispiel: Für die Datei „installed-files.txt“ eines Nexus 6P mit Android 7.1 und einer Gesamtgröße des System Image von 2628 MiB (2755792836 Byte) sieht die Aufschlüsselung der größten Beiträge zur Gesamtgröße des System-Image nach Dateityp so aus:

.odex 1391770312 Byte 50,5%
.apk 846878259 Byte 30,7%
.so (nativer C/C++-Code) 202162479 Byte 7,3%
.oat-Dateien/.art-Images 163892188 Byte 5,9%
Schriftarten 38952361 Byte 1,4%
ICU-Locale-Daten 27468687 Byte 0,9%

Diese Zahlen sind auch für andere Geräte ähnlich. Auf Nexus-/Pixel-Geräten nehmen ODEX-Dateien etwa die Hälfte der Systempartition ein. Das bedeutete, dass wir weiterhin ext4 verwenden konnten, die ODEX-Dateien aber im Werk auf die B-Partition schreiben und sie dann beim ersten Start nach /data kopieren konnten. Der tatsächlich mit ext4 A/B verwendete Speicherplatz ist identisch mit SquashFS A/B, da wir bei Verwendung von SquashFS die voroptimierten ODEX-Dateien auf system_a anstelle von system_b ausgeliefert hätten.

Bedeutet das Kopieren von ODEX-Dateien nach /data nicht, dass der auf /system gesparte Speicherplatz auf /data verloren geht?

Nicht ganz. Auf Pixel-Geräten wird der größte Teil des von ODEX-Dateien belegten Speicherplatzes für Apps verwendet, die sich in der Regel auf /data befinden. Diese Apps erhalten Google Play-Updates, sodass die APK- und ODEX-Dateien im System-Image die meiste Zeit der Lebensdauer des Geräts nicht verwendet werden. Solche Dateien können vollständig ausgeschlossen und durch kleine, profildatenbasierte ODEX-Dateien ersetzt werden, wenn der Nutzer die jeweilige App verwendet .So wird kein Speicherplatz für Apps benötigt, die der Nutzer nicht verwendet. Weitere Informationen finden Sie im Vortrag „The Evolution of Art“ auf der Google I/O 2016.

Der Vergleich ist aus mehreren Gründen schwierig:

  • Bei Apps, die über Google Play aktualisiert werden, befinden sich die ODEX-Dateien immer auf /data, sobald sie das erste Update erhalten.
  • Für Apps, die der Nutzer nicht ausführt, ist keine ODEX-Datei erforderlich.
  • Bei der profildatenbasierten Kompilierung werden kleinere ODEX-Dateien als bei der Ahead-of-Time-Kompilierung generiert da nur leistungskritischer Code optimiert wird.

Weitere Informationen zu den Optimierungsoptionen für OEMs finden Sie unter ART konfigurieren.

Gibt es nicht zwei Kopien der ODEX-Dateien auf /data?

Es ist etwas komplizierter. Nachdem das neue System-Image geschrieben wurde, wird die neue Version von dex2oat für die neuen DEX-Dateien ausgeführt, um die neuen ODEX-Dateien zu generieren. Dies geschieht, während das alte System noch ausgeführt wird, sodass sich die alten und neuen ODEX-Dateien gleichzeitig auf /data befinden.

Der Code in OtaDexoptService (frameworks/base/+/android17-release/services/core/java/com/android/server/pm/OtaDexoptService.java) ruft getAvailableSpace auf, bevor jedes Paket optimiert wird, um eine Überfüllung von /data zu vermeiden. Beachten Sie, dass verfügbar hier immer noch konservativ ist: Es ist der Speicherplatz, der vor Erreichen des üblichen Schwellenwerts für wenig Speicherplatz im System verbleibt (gemessen sowohl in Prozent als auch in Byte). Wenn /data voll ist, gibt es also nicht zwei Kopien jeder ODEX-Datei. Derselbe Code hat auch einen BULK_DELETE_THRESHOLD .Wenn das Gerät sich dem Füllen des verfügbaren Speicherplatzes nähert (wie gerade beschrieben), werden die ODEX-Dateien von Apps entfernt, die nicht verwendet werden. Auch in diesem Fall gibt es nicht zwei Kopien jeder ODEX-Datei.

Im schlimmsten Fall, in dem /data vollständig voll ist, wartet das Update, bis das Gerät in das neue System neu gestartet wurde und die ODEX-Dateien des alten Systems nicht mehr benötigt. Das wird vom PackageManager verarbeitet: (frameworks/base/+/android17-release/services/core/java/com/android/server/pm/PackageManagerService.java#7215). Nachdem das neue System erfolgreich gestartet wurde, kann installd (frameworks/native/+/android17-release/cmds/installd/dexopt.cpp#2422) die ODEX-Dateien entfernen, die vom alten System verwendet wurden, und das Gerät wieder in den stabilen Zustand versetzen, in dem nur eine Kopie vorhanden ist.

Es ist also möglich, dass /data zwei Kopien aller ODEX-Dateien enthält .Das ist jedoch (a) nur vorübergehend und (b) tritt nur auf, wenn Sie ohnehin viel freien Speicherplatz auf /data hatten. Außer während eines Updates gibt es nur eine Kopie. Außerdem wird /data im Rahmen der allgemeinen Robustheitsfunktionen von ART ohnehin nie mit ODEX-Dateien gefüllt, da dies auch bei einem Nicht-A/B-System ein Problem wäre.

Erhöht all dieses Schreiben und Kopieren den Verschleiß des Flash-Speichers?

Nur ein kleiner Teil des Flash-Speichers wird neu geschrieben: Bei einem vollständigen Pixel-Systemupdate werden etwa 2,3 GiB geschrieben. Apps werden auch neu kompiliert, aber das gilt auch für Nicht-A/B-Systeme. Bei herkömmlichen blockbasierten vollständigen OTAs wurde eine ähnliche Datenmenge geschrieben, sodass die Verschleißraten des Flash-Speichers ähnlich sein sollten.

Verlängert das Flashen von zwei Systempartitionen die Flashing-Zeit im Werk?

Nein. Die Größe des System-Image von Pixel hat sich nicht erhöht. Der Speicherplatz wurde lediglich auf zwei Partitionen aufgeteilt.

Verlangsamt das Beibehalten von ODEX-Dateien auf B den Neustart nach dem Zurücksetzen auf die Werkseinstellungen?

Ja. Wenn Sie ein Gerät tatsächlich verwendet, ein OTA-Update installiert und es auf die Werkseinstellungen zurückgesetzt haben, ist der erste Neustart langsamer als sonst (1 Minute 40 Sekunden im Vergleich zu 40 Sekunden auf einem Pixel XL), da die ODEX-Dateien nach dem ersten OTA-Update von B verloren gegangen sind und daher nicht nach /data kopiert werden können. Das ist der Kompromiss.

Das Zurücksetzen auf die Werkseinstellungen sollte im Vergleich zum regulären Start ein seltener Vorgang sein, daher ist die benötigte Zeit weniger wichtig. Das betrifft keine Nutzer oder Rezensenten, die ihr Gerät direkt vom Werk erhalten, da in diesem Fall die B-Partition verfügbar ist. Durch die Verwendung des JIT-Compilers müssen wir nicht alles neu kompilieren, daher ist es nicht so schlimm, wie Sie vielleicht denken. Es ist auch möglich, Apps als Ahead-of-Time-Kompilierung erforderlich zu kennzeichnen, indem Sie coreApp="true" im Manifest verwenden: (frameworks/base/+/android17-release/packages/SystemUI/AndroidManifest.xml#23). Das wird derzeit von system_server verwendet, da JIT aus Sicherheitsgründen nicht zulässig ist.

Verlangsamt das Beibehalten von ODEX-Dateien auf /data anstelle von /system den Neustart nach einem OTA-Update?

Nein. Wie oben erläutert, wird das neue dex2oat ausgeführt, während das alte System-Image noch ausgeführt wird, um die Dateien zu generieren, die für das neue System benötigt werden. Das Update gilt erst als verfügbar, wenn diese Arbeit abgeschlossen ist.

Sollten wir ein 32-GiB-A/B-Gerät ausliefern? 16GiB? 8GiB?

32 GiB funktionieren gut, wie sich beim Pixel gezeigt hat. 320 MiB von 16 GiB bedeuten eine Reduzierung von 2%. Ebenso bedeuten 320 MiB von 8 GiB eine Reduzierung von 4%. A/B wäre natürlich nicht die empfohlene Wahl für Geräte mit 4 GiB, da der Overhead von 320 MiB fast 10% des insgesamt verfügbaren Speicherplatzes beträgt.

Sind für AVB 2.0 A/B-OTAs erforderlich?

Nein. Für Android Bootmodus mit Verifikation waren schon immer blockbasierte Updates erforderlich, aber nicht unbedingt A/B-Updates.

Sind für A/B-OTAs AVB 2.0 erforderlich?

Nein.

Untergraben A/B-OTAs den Rollback-Schutz von AVB 2.0?

Nein. Hier gibt es einige Verwirrung, denn wenn ein A/B-System nicht in das neue System Image starten kann, wird es (nach einer bestimmten Anzahl von Wiederholungen, die von Ihrem Bootloader festgelegt werden) automatisch auf das „vorherige“ System-Image zurückgesetzt. Der entscheidende Punkt ist jedoch, dass das "vorherige" im Sinne von A/B eigentlich immer noch das "aktuelle" System-Image ist. Sobald das Gerät ein neues Image erfolgreich startet, wird der Rollback-Schutz aktiviert und verhindert, dass Sie zurückkehren können. Bis Sie das neue Image jedoch tatsächlich erfolgreich gestartet haben, wird es vom Rollback-Schutz nicht als aktuelles System-Image betrachtet.

Ist es nicht langsam, ein Update zu installieren, während das System ausgeführt wird?

Bei Nicht-A/B-Updates ist das Ziel, das Update so schnell wie möglich zu installieren, da der Nutzer wartet und sein Gerät nicht verwenden kann, während das Update angewendet wird. Bei A/B-Updates ist das Gegenteil der Fall. Da der Nutzer sein Gerät weiterhin verwendet, ist das Ziel, die Auswirkungen so gering wie möglich zu halten. Daher wird das Update bewusst langsam durchgeführt. Über die Logik im Java-Systemupdate-Client (bei Google ist das GmsCore, das Kernpaket von GMS) versucht Android auch, eine Zeit auszuwählen, in der die Nutzer ihre Geräte überhaupt nicht verwenden. Die Plattform unterstützt das Anhalten und Fortsetzen des Updates. Der Client kann das Update anhalten, wenn der Nutzer das Gerät verwendet, und es fortsetzen, wenn das Gerät wieder inaktiv ist.

Bei einem OTA-Update gibt es zwei Phasen, die in der Benutzeroberfläche deutlich als Schritt 1 von 2 und Schritt 2 von 2 unter der Fortschrittsanzeige dargestellt werden. Schritt 1 entspricht dem Schreiben der Datenblöcke, während in Schritt 2 die DEX-Dateien vorkompiliert werden. Diese beiden Phasen unterscheiden sich erheblich in Bezug auf die Auswirkungen auf die Leistung. Die erste Phase ist eine einfache Ein-/Ausgabe. Dafür sind nur wenige Ressourcen (RAM, CPU, Ein-/Ausgabe) erforderlich, da nur langsam Blöcke kopiert werden.

In der zweiten Phase wird dex2oat ausgeführt, um das neue System-Image vorkompilieren. Die Anforderungen sind hier natürlich weniger klar begrenzt, da tatsächliche Apps kompiliert werden. Außerdem ist die Kompilierung einer großen und komplexen App viel aufwendiger als die einer kleinen und einfachen App. In Phase 1 gibt es keine Festplattenblöcke, die größer oder komplexer als andere sind.

Der Vorgang ähnelt dem, wenn Google Play im Hintergrund ein App-Update installiert, bevor die 5 Apps aktualisiert Benachrichtigung angezeigt wird, wie es seit Jahren der Fall ist.

Was ist, wenn ein Nutzer tatsächlich auf das Update wartet?

Die aktuelle Implementierung in GmsCore unterscheidet nicht zwischen Hintergrundupdates und vom Nutzer initiierten Updates, dies kann sich aber in Zukunft ändern. Wenn der Nutzer ausdrücklich die Installation des Updates angefordert hat oder den Bildschirm mit dem Fortschritt des Updates beobachtet, priorisieren wir die Updatearbeit, da wir davon ausgehen, dass er aktiv auf den Abschluss wartet.

Was passiert, wenn ein Update nicht angewendet werden kann?

Bei Nicht-A/B-Updates führte ein fehlgeschlagenes Update in der Regel dazu, dass der Nutzer ein unbrauchbares Gerät hatte. Die einzige Ausnahme war, wenn der Fehler auftrat, bevor eine Anwendung überhaupt gestartet wurde (z. B. weil das Paket nicht verifiziert werden konnte). Bei A/B-Updates hat ein fehlgeschlagenes Update keine Auswirkungen auf das aktuell ausgeführte System. Das Update kann einfach später noch einmal versucht werden.