Häufig gestellte Fragen

Hat Google A/B-Over-the-air-Updates auf Geräten verwendet?

Ja. Der Marketingname für A/B-Updates lautet nahtlose Updates. Google Pixel und Google Pixel XL ab Oktober 2016 werden 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 zugänglich.

Warum sind A/B-OTAs besser?

A/B-Over-the-air-Updates bieten eine bessere Nutzerfreundlichkeit bei der Installation von Updates. Messungen bei monatlichen Sicherheitsupdates zeigen, dass diese Funktion bereits ein Erfolg ist: Im Mai 2017 hatten 95% der Pixel-Nutzer nach einem Monat das neueste Sicherheitsupdate installiert, verglichen mit 87% der Nexus-Nutzer. Außerdem installieren Pixel-Nutzer Updates schneller als Nexus-Nutzer. Wenn bei einem Over-the-air-Update (OTA) Blöcke nicht aktualisiert werden können, führt das nicht mehr dazu, dass das Gerät nicht startet. 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 portablem Dalvik-Bytecode. Eine .odex-Datei (optimierte .dex-Datei) ist unabhängig von der .apk-Datei und kann gerätespezifischen Maschinencode enthalten. Wenn eine .odex-Datei verfügbar ist, kann Android Anwendungen mit der Geschwindigkeit ausführen, die durch die Vorabkompilierung erreicht wird, ohne jedes Mal warten zu müssen, bis der Code kompiliert wurde. Eine .odex-Datei ist nicht unbedingt erforderlich: Android kann den .dex-Code direkt über Interpretation oder JIT-Kompilierung (Just-In-Time) ausführen. Eine .odex-Datei bietet jedoch die beste Kombination aus Start- und Laufzeitgeschwindigkeit, wenn Speicherplatz verfügbar ist.

Beispiel: In der Datei „installed-files.txt“ eines Nexus 6P mit Android 7.1 und einer Gesamtsystem-Imagegröße von 2.628 MiB (2.755.792.836 Byte) sehen Sie die größten Dateitypen, die zur Gesamtgröße des System-Images beitragen:

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

Diese Werte sind auch für andere Geräte ähnlich. Auf Nexus-/Pixel-Geräten belegen .odex-Dateien etwa die Hälfte der Systempartition. So konnten wir ext4 weiterhin verwenden, die .odex-Dateien aber in der B-Partition in der Fabrik schreiben und sie dann beim ersten Start auf /data kopieren. Der tatsächliche Speicherplatz, der mit ext4 A/B verwendet wird, ist mit SquashFS A/B identisch. Wenn wir SquashFS verwendet hätten, hätten wir die vorab optimierten .odex-Dateien auf system_a anstelle von system_b bereitgestellt.

Bedeutet das Kopieren von .odex-Dateien in /data, dass der in /system gespeicherte Speicherplatz in /data verloren geht?

Nicht ganz. Auf Pixel wird der Großteil des Speicherplatzes, der von .odex-Dateien belegt wird, von Apps belegt, die sich normalerweise auf /data befinden. Diese Apps erhalten Google Play-Updates, sodass die .apk- und .odex-Dateien im System-Image während der gesamten Lebensdauer des Geräts größtenteils nicht verwendet werden. Solche Dateien können vollständig ausgeschlossen und durch kleine, profilbasierte .odex-Dateien ersetzt werden, wenn der Nutzer die einzelnen Apps tatsächlich verwendet. So wird kein Speicherplatz für Apps belegt, die der Nutzer nicht verwendet. Weitere Informationen finden Sie im Vortrag The Evolution of Art (Die Entwicklung der Kunst) auf der Google I/O 2016.

Der Vergleich ist aus mehreren Gründen schwierig:

  • Bei Apps, die von Google Play aktualisiert werden, waren die .odex-Dateien immer auf /data verfügbar, sobald sie ihr erstes Update erhalten haben.
  • Für Apps, die der Nutzer nicht ausführt, ist keine .odex-Datei erforderlich.
  • Bei der profilbasierten Kompilierung werden kleinere .odex-Dateien generiert als bei der Vorabkompilierung, da bei der ersten 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 unter /data?

Es ist etwas komplizierter: Nachdem das neue System-Image geschrieben wurde, wird die neue Version von dex2oat auf die neuen .dex-Dateien angewendet, um die neuen .odex-Dateien zu generieren. Das geschieht, während das alte System noch ausgeführt wird. Daher befinden sich die alten und neuen .odex-Dateien gleichzeitig auf /data.

Der Code in OtaDexoptService (frameworks/base/+/main/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. Hinweis: Der Wert verfügbar ist hier noch konservativ: Es ist der verbleibende Speicherplatz vor Erreichen des üblichen Grenzwerts für wenig Speicherplatz (gemessen als Prozentsatz und in Byte). Wenn /data voll ist, gibt es also nicht zwei Kopien jeder .odex-Datei. Derselbe Code enthält auch einen BULK_DELETE_THRESHOLD: Wenn der verfügbare Speicherplatz auf dem Gerät (wie oben beschrieben) fast aufgebraucht ist, werden die .odex-Dateien der nicht verwendeten Apps entfernt. Das ist ein weiterer Fall ohne zwei Kopien jeder .odex-Datei.

Im schlimmsten Fall, wenn /data vollständig belegt ist, wartet das Update, bis das Gerät neu mit dem neuen System gestartet wurde und die .odex-Dateien des alten Systems nicht mehr benötigt werden. Der PackageManager übernimmt das: (frameworks/base/+/main/services/core/java/com/android/server/pm/PackageManagerService.java#7215). Nachdem das neue System erfolgreich gestartet wurde, kann installd (frameworks/native/+/main/cmds/installd/dexopt.cpp#2422) die .odex-Dateien entfernen, die vom alten System verwendet wurden. Das Gerät kehrt dann in den stabilen Zustand zurück, in dem nur eine Kopie vorhanden ist.

Es ist also möglich, dass /data zwei Kopien aller .odex-Dateien enthält. Dies ist jedoch (a) nur vorübergehend und (b) tritt nur auf, wenn auf /data ohnehin viel freier Speicherplatz vorhanden ist. Außer bei einem Update gibt es nur eine Kopie. Außerdem wird /data im Rahmen der allgemeinen Robustheitsfunktionen von ART niemals mit .odex-Dateien gefüllt, da dies auch bei einem nicht A/B-System ein Problem wäre.

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

Es wird nur ein kleiner Teil des Flash-Speichers überschrieben: Bei einem vollständigen Systemupdate von Pixel werden etwa 2,3 GiB geschrieben. Auch Apps werden neu kompiliert, was aber auch bei nicht A/B-Tests der Fall ist. Traditionell haben blockbasierte vollständige OTAs eine ähnliche Datenmenge geschrieben, sodass die Flash-Abnutzungsraten ähnlich sein sollten.

Erhöht das Flashen von zwei Systempartitionen die Zeit für das Zurücksetzen auf die Werkseinstellungen?

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

Verlangsamt das Belassen von .odex-Dateien auf B den Neustart nach dem Zurücksetzen auf die Werkseinstellungen?

Ja. Wenn Sie ein Gerät verwendet, ein Over-the-air-Update durchgeführt und es auf die Werkseinstellungen zurückgesetzt haben, ist der erste Neustart langsamer als sonst (1 Min. 40 Sek. gegenüber 40 Sek. auf Pixel XL), da die .odex-Dateien nach dem ersten Over-the-air-Update auf B verloren gegangen sind und daher nicht auf /data kopiert werden können. Das ist der Kompromiss.

Das Zurücksetzen auf die Werkseinstellungen sollte im Vergleich zum normalen Starten seltener vorkommen, sodass die Dauer weniger wichtig ist. Dies gilt nicht für Nutzer oder Rezensenten, die ihr Gerät direkt vom Hersteller erhalten, da in diesem Fall die B-Partition verfügbar ist. Da wir den JIT-Compiler verwenden, müssen wir nicht alles neu kompilieren. Das ist also gar nicht so schlimm, wie es sich anhört. Es ist auch möglich, Apps mithilfe von coreApp="true" im Manifest als solche zu kennzeichnen, für die eine Vorabkompilierung erforderlich ist: (frameworks/base/+/main/packages/SystemUI/AndroidManifest.xml#23). Diese Option wird derzeit von system_server verwendet, da JIT-Kompilierung aus Sicherheitsgründen nicht zulässig ist.

Verlangsamt es den Neustart nach einem OTA-Update, wenn .odex-Dateien unter /data statt unter /system gespeichert werden?

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

Können (sollten) wir ein 32-GB-A/B-Gerät versenden? 16 GiB? 8 GiB?

32 GiB funktionieren gut, wie sich bei Pixel gezeigt hat. 320 MiB von 16 GiB bedeuten eine Reduzierung von 2%. Bei 320 MiB von 8 GiB entspricht dies einer Reduzierung von 4%. Auf Geräten mit 4 GiB wäre A/B natürlich nicht die empfohlene Option, da der Overhead von 320 MiB fast 10% des gesamten verfügbaren Speicherplatzes ausmacht.

Erfordert AVB2.0 A/B-Over-the-air-Updates?

Nein. Für den bestätigten Start von Android waren schon immer blockbasierte Updates erforderlich, aber nicht unbedingt A/B-Updates.

Ist AVB2.0 für A/B-Over-the-air-Updates erforderlich?

Nein.

Beeinträchtigen A/B-Over-the-air-Updates den Rollback-Schutz von AVB2.0?

Nein. Hier gibt es etwas Verwirrung, denn wenn ein A/B-System nicht in das neue System-Image bootet, wird es (nach einer vom Bootloader festgelegten Anzahl von Wiederholungen) automatisch auf das „vorherige“ System-Image zurückgesetzt. Der entscheidende Punkt ist jedoch, dass „vorherig“ im A/B-Test-Kontext eigentlich das „aktuelle“ Systemimage ist. Sobald das Gerät ein neues Image gestartet hat, wird der Rollback-Schutz aktiviert und verhindert, dass Sie zu einem vorherigen Image zurückkehren können. Solange Sie das neue Image jedoch nicht erfolgreich gestartet haben, wird es vom Rollback-Schutz nicht als aktuelles System-Image betrachtet.

Ist es nicht langsam, wenn ein Update installiert wird, während das System läuft?

Bei nicht A/B-Updates besteht das Ziel darin, das Update so schnell wie möglich zu installieren, da der Nutzer wartet und sein Gerät während der Anwendung des Updates nicht verwenden kann. Bei A/B-Updates ist das Gegenteil der Fall: Da der Nutzer sein Gerät weiterhin verwendet, soll das Update so wenig wie möglich beeinträchtigen. Daher wird es bewusst langsam durchgeführt. Über die Logik im Java-Systemupdate-Client (bei Google GmsCore, das von GMS bereitgestellte Kernpaket) versucht Android auch, einen Zeitpunkt auszuwählen, zu dem die Nutzer ihre Geräte nicht verwenden. Die Plattform unterstützt das Pausieren und Fortsetzen des Updates. Der Kunde kann das Update pausieren, wenn der Nutzer das Gerät verwendet, und fortsetzen, wenn das Gerät wieder inaktiv ist.

Es gibt zwei Phasen bei der Durchführung einer Over-the-air-Aktualisierung, die in der Benutzeroberfläche deutlich als Schritt 1 von 2 und Schritt 2 von 2 unter der Fortschrittsanzeige angezeigt werden. Schritt 1 entspricht dem Schreiben der Datenblöcke, während Schritt 2 der Vorkompilierung der .dex-Dateien entspricht. Diese beiden Phasen unterscheiden sich hinsichtlich der Auswirkungen auf die Leistung erheblich. Die erste Phase ist die einfache E/A. Dies erfordert nur wenig Ressourcen (RAM, CPU, E/A), da nur langsam Blöcke kopiert werden.

In der zweiten Phase wird dex2oat ausgeführt, um das neue System-Image vorab zu kompilieren. Die Anforderungen sind hier natürlich weniger klar definiert, da es sich um die Kompilierung tatsächlicher Apps handelt. Außerdem ist das Kompilieren einer großen und komplexen App natürlich viel aufwendiger als das einer kleinen und einfachen App. In Phase 1 gibt es jedoch keine größeren oder komplexeren Laufwerksblöcke als andere.

Das Verfahren ähnelt dem, wenn Google Play ein App-Update im Hintergrund installiert, bevor die Benachrichtigung 5 Apps aktualisiert angezeigt wird. Das ist seit Jahren so.

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 jedoch in Zukunft ändern. Wenn der Nutzer ausdrücklich darum gebeten hat, das Update zu installieren, oder den Fortschrittsbildschirm des Updates beobachtet, priorisieren wir die Update-Arbeiten unter der Annahme, dass er aktiv auf den Abschluss wartet.

Was passiert, wenn ein Update nicht angewendet werden kann?

Bei nicht A/B-Updates konnte das Gerät in der Regel nicht mehr verwendet werden, wenn ein Update fehlgeschlagen war. Die einzige Ausnahme war, wenn der Fehler auftrat, bevor eine Anwendung gestartet wurde (z. B. weil die Überprüfung des Pakets fehlgeschlagen ist). Bei A/B-Updates wirkt sich ein fehlgeschlagenes Update nicht auf das derzeit laufende System aus. Das Update kann später einfach noch einmal versucht werden.