Android News – APEX in Android Q

Die Implementierung von APEX ist wahrscheinlich das größte Problem, mit dem Google seit der Einführung von Project Treble konfrontiert war. Was ist APEX und wie wird seine Einführung Android verändern? Die Idee hinter APEX an sich ist in alltäglichen GNU/Linux-Distributionen bereits weit verbreitet: Paket-Updates für bestimmte Abschnitte der Linux-Bibliothek. Aber das ist etwas, was Google selbst noch nie versucht hat, da Android eine ro-Partition (read-only) verwendet, auf der alle Systembibliotheken und Frameworks gespeichert sind, im Vergleich zu den üblichen rw-Partitionen (read-write), die in den meisten Linux-Distributionen verwendet werden. Das macht den Standard-Aktualisierungsprozess ungeeignet.

Bibliotheken sind vorkompilierter Code, der in anderen Programmen verwendet werden kann. Häufig verwendete Methoden können in Bibliotheken für den Aufruf von Android-Apps umgewandelt werden, wodurch die Größe der APKs reduziert wird, da derselbe Code nicht erneut über mehrere Apps hinweg implementiert werden muss. Viele vorinstallierte Systembibliotheken finden Sie in den Verzeichnissen /system/lib und /system/lib64. Android-Systembibliotheken werden in der Regel nicht einzeln aktualisiert – sondern im Rahmen von Upgrades von Android-Plattformen über ein OTA-Update. Andererseits können Bibliotheken in Linux-Distributionen bereits seit langem individuell aktualisiert werden. Mit der Einführung von APEX könnte dies auch für Systembibliotheken in Android realisiert werden.

Der Hauptvorteil dabei ist, dass App-Entwickler die Vorteile aktualisierter Bibliotheken nutzen können, ohne darauf zu warten, dass ein OEM ein vollständiges System-Upgrade durchführt. Lasst uns also, für eine besseres Verständnis, in die technischen Details darüber eintauchen, wie APEX funktioniert.

Wie wird APEX die Art und Weise verändern, in der Bibliotheken aktualisiert werden?

APEX ist ein Ökosystem, das Google gezwungen hat, oder besser gesagt zwingt, die Art und Weise zu überdenken, wie Android alle Bibliotheken und Dateien von einer nicht dem Standard entsprechenden Partition lädt, die sich von /system unterscheidet. Zuerst müssen wir dazu den Unterschied zwischen einer gemeinsamen Bibliothek und einer statischen Bibliothek untersuchen.

Eine Shared Library ist eine Bibliothek (normalerweise eine Datei namens libkind.so), die nicht den gesamten Code enthält, der für die Ausführung in sich selbst benötigt wird, sondern mit anderen Bibliotheken „verknüpft“ ist, die den Code tatsächlich bereitstellen, während eine statische Bibliothek, wie Ihr euch vorstellen können, eine Bibliothek ist, die von keiner anderen Bibliothek abhängt und alles statisch in der Datei enthält.

Android hat den Bibliothekspfad – in der Linux-Welt als LD_LIBRARY_PATH bekannt – historisch mit einer einzigen Datei namens ld.config.txt konfiguriert, um die zulässigen Suchpfade für die gemeinsamen Bibliotheken zu konfigurieren, die entweder von einer binären oder einer anderen Bibliothek benötigt werden. Diese Pfade sind in der Konfiguration fest programmiert und nicht erweiterbar. Dieses Layout, einschließlich der schreibgeschützten Systempartition, führt zu nicht aktualisierbaren Bibliotheken, es sei denn, der Benutzer installiert ein OTA-Android-Update. Google behebt dieses Problem nun allem Anschein nach, und erlaubt es, den Suchpfad zu erweitern, indem die einzelnen APEX-Pakete ihre eigene ld.config.txt bereitstellen, die die zusätzlichen, und aktualisierten Bibliothekspfade enthält.

Während dieser Schritt eines der Hauptprobleme behebt, gab es dadurch jedoch noch einige andere ernsthafte Probleme zu lösen. Zuerst einmal: die ABI (Application Binary Interface) Stabilität. Bibliotheken sollten immer einen stabilen Satz von Schnittstellen exportieren, damit andere Anwendungen und Bibliotheken auch mit der aktualisierten Bibliothek mit dem gleichen Protokoll weiterarbeiten können. Google arbeitet aktiv daran, indem es versucht, eine stabile C-Schnittstelle zwischen APEXed-Bibliotheken zu schaffen.

Aber eine APEX ist nicht nur auf Bibliotheken und Binärdateien beschränkt. Tatsächlich kann es Konfigurationsdateien, Zeitzonen-Updates und einige Java-Frameworks enthalten.

Hier sind einige Beispiele für die aktuellen APEX-Pakete von AOSP:

  • com.android.runtime: ART und bionische Laufzeit (Binärdateien und Bibliotheken)
  • com.android.tzdata: TimeZone- und ICU-Daten (Bibliotheken und Konfigurationsdaten)
  • com.android.resolv: Bibliothek, die von Android zum Auflösen von netzwerkbezogenen Anfragen verwendet wird (Bibliotheken).
  • com.android.conscrypt: Ein Java Security Provider (Java Framework)

Wie wird ein APEX-Paket installiert und strukturiert?

Ein APEX-Paket ist ein einfaches Zip-Archiv, ähnlich einer APK, das von unserer praktischen ADB – zu diesem Zeitpunkt in der Entwicklung – und später vom Benutzer selbst über einen Paketmanager, wie GooglePlay oder manuell über den Android-Paketinstaller, installiert werden kann.

Das ZIP-Layout sieht wie folgt aus:

apex-android-q-1

Lasst uns dort noch tiefer eintauchen. Die Datei apex_manifest.json gibt den Paketnamen und die Version an.

apex-android-q-2

Die apex_payload.img ist ein Mikro-Dateisystem-Image – formatiert als EXT4.

apex-android-q-10

Die anderen Dateien sind Teil des Verifizierungsprozesses, der zur Installation des Pakets verwendet wird. Schauen wir es uns daher auch noch einmal an. Das Vorhandensein von AndroidManifest.xml, auch wenn es hauptsächlich in Anwendungen verwendet wird, hilft uns zu verstehen, dass der Großteil der für eine Standard-APK-Installation verwendeten Implementierung auch für diese Pakete wiederverwendet wird. Tatsächlich wird nur die Erweiterung geprüft, um zwischen ihnen zu unterscheiden.

Das META-INF/-Verzeichnis hat das Paketzertifikat und verwendet den gleichen Mechanismus wie normale APKs. Diese Pakete werden also zur Laufzeit von einem privaten/öffentlichen Schlüsselpaar verifiziert, bevor der Benutzer ein Update installieren darf. Aber das war für Google nicht genug, also haben sie 2 weitere Sicherheitsebenen hinzugefügt. Sie verwenden dm-verity, um die Integrität des Images zu überprüfen, und AVB (Android Verified Boot) Verifikationen, um sicherzustellen, dass das Image von einer vertrauenswürdigen Quelle stammt. Im schlimmsten Fall wird das APEX-Paket abgelehnt.

Wenn alle Verifizierungsschritte erfolgreich sind, wird das Image als gültig markiert und ersetzt beim nächsten Neustart die Systemvariante.

Wie wird ein Image beim Booten installiert?

Beginnen wir mit einem Blick auf die APEXes, die derzeit auf meinem Gerät – einem Emulator – installiert sind.

apex-android-q-9

Wie wir sehen können, sind die vorinstallierten Pakete in /system/apex/ gespeichert und alle befinden sich derzeit auf Versionsnummer 1. Aber was passiert, wenn ein APEX aktiviert wird? Wir werden wieder com.android.tzdata als Beispiel verwenden.

apex-android-q-5

Lasst uns das Gerät neu starten und den Logcat analysieren.

apex-android-q-8

Die ersten beiden Zeilen liefern genügend Informationen, um den Ursprung des Pakets und den Installationsort zu verstehen: /apex/, ein neues Verzeichnis, das in Android Q eingeführt wurde und das zum Speichern der aktivierten Pakete verwendet wird.

apex-android-q-7

Nachdem das Paket erfolgreich mit AVB verifiziert wurde und der öffentliche Schlüssel übereinstimmt, wird die APEX mittels einer loop nach /dev/block/loop0 gemountet, wodurch das EXT4-Dateisystem für das System zugänglich wird. Eine loop ist ein Pseudo-Gerät, das eine Datei als Block zugänglich macht und den Inhalt dieser Datei als Mount-Punkt zugänglich macht.

An dieser Stelle wird die APEX aufgrund des Suffixes @1, welches die Paketversion angibt, noch nicht verwendet. Um das System schließlich darüber zu informieren, dass unser Paket erfolgreich aktiviert wurde, wird es an /apex/com.android.tzdata angebunden, wo Android aktiv erwartet, dass tzdata exitiert. Ein Bind-Mount überlagert ein bestehendes Verzeichnis oder eine bestehende Datei an einem anderen Punkt.

Die APEX-Implementierung ist vollständig in einem einzigen Repository unter AOSP enthalten. Das Verzeichnis apexd (APEX daemon) hat den Code, der auf Android läuft. Das Apexer-Verzeichnis enthält den Code, der vom Build-System verwendet wird, um die APEX-Pakete zu erstellen.

Was ist der Zweck?

An diesem Punkt kann ich nur noch spekulieren. Meine beste Vermutung ist, dass Google versucht, einen Kernsatz von APEX-Paketen zu erstellen, die von Google aktualisiert werden können, um möglicherweise einen einheitlichen Basiskern von Android zu erstellen, der zwischen Anbietern geteilt wird, wodurch es ermöglicht wird, dass die Anbieter nur noch Updates für das „System“ durchführen, und ansonsten Updates für einzelne Pakete verwendet werden.

Werden alle Geräte APEX unterstützen?

Nein. Zum Beispiel erfordert apexd, dass /data/apex direkt nach dem Start verfügbar ist, um alle Android-Module zu aktualisieren. Mit FDE (Full-disk Encryption) wird /data/apex verschlüsselt, bis das Gerät vom Benutzer entsperrt wird, was APEX grundsätzlich nutzlos macht, da nur die System-APEX-Varianten beim Booten geladen werden. Ansonsten sollten alle Geräte APEX unterstützen, aber sie benötigen ein paar Kernel-Patches – viele davon sind Fixes, die von Google beim Arbeiten mit Loop-Geräten gefunden wurden.

Advertisements

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden /  Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden /  Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden /  Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden /  Ändern )

Verbinde mit %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Create a website or blog at WordPress.com

Nach oben ↑

%d Bloggern gefällt das: