Auf dieser Seite werden verschiedene Mechanismen vorgestellt, mit denen Android-OEMs ein gemeinsames Systemimage (Shared System Image, SSI) für verschiedene Produktlinien verwenden können. Außerdem wird ein Verfahren vorgeschlagen, mit dem ein SSI, das einem OEM gehört, auf einem generischen Systemimage (Generic System Image, GSI) basiert, das auf AOSP basiert.
Hintergrund
Das Framework des Open-Source-Projekts für Android (Android Open Source Project, AOSP) entspricht der Mainline-Architektur, um die Abwärtskompatibilität mit älteren Anbieterimplementierungen aufrechtzuerhalten. So kann beispielsweise ein generisches Systemimage (Generic System Image, GSI), das aus Android 10-AOSP-Quellen erstellt wurde, auf jedem Treble-kompatiblen Gerät mit Android 8 oder höher ausgeführt werden.
Mainline erreicht dies, indem Android in zwei separate Teile unterteilt wird: die hardwarespezifische Anbieterimplementierung und das generische Android-Betriebssystem-Framework. Jede Komponente wird in einer separaten Partition installiert: die Anbieterpartition für hardwarespezifische Software und die Systempartition für das generische Betriebssystem. Zwischen ihnen wird eine versionierte Schnittstelle, die sogenannte Vendorschnittstelle (VINTF), erzwungen. Mit diesem Partitionierungssystem können OEMs die Systempartition ändern, ohne die Anbieterpartition zu berühren, und umgekehrt.
In der Vergangenheit haben SoC-Anbieter und OEMs die auf Verbrauchergeräten ausgelieferte Android-Framework-Version stark modifiziert (weitere Informationen finden Sie unter Life of an Android Release). Da diese Framework-Erweiterungen selten mit Blick auf die Abwärtskompatibilität entwickelt wurden, haben gerätespezifische Änderungen die Komplexität und die finanziellen Kosten nachfolgender Betriebssystem-Upgrades erheblich erhöht. In Android 10 (API-Level 29) und niedriger fehlte dem Ökosystem eine klare, standardisierte Architektur, mit der Partner modulare Erweiterungen für das Android-Framework entwickeln konnten.
Auf dieser Seite wird beschrieben, wie SoC-Anbieter und OEMs ein gemeinsames System-Image (Shared System Image, SSI) erstellen können. Ein SSI ist ein einheitliches Framework-Image, das aus Android-Betriebssystemquellen erstellt wird und auf mehreren Geräten wiederverwendet werden kann. Durch die Aufrechterhaltung einer sauberen Abwärtskompatibilität mit Anbieterimplementierungen durch diese partitionierte Architektur senkt ein SSI die Kosten und Komplexität von Android-Betriebssystem-Upgrades erheblich.
Implementierungsdetails finden Sie unter Empfohlene Schritte für GSI-basiertes SSI. Die Schritte sind modular. Je nach Architektur können Sie bestimmte Phasen (z. B. Schritt 1: generic_system.mk für OEM-System-Image (OEM-GSI) übernehmen) anstelle aller Phasen implementieren.
SSI – Übersicht
Bei SSI werden produktspezifische Softwarekomponenten und OEM-Erweiterungen in einer neuen /product-Partition platziert. Die Komponenten in der Partition /product verwenden eine genau definierte, stabile Schnittstelle für die Interaktion mit Komponenten in der Partition /system. OEMs können entweder ein SSI erstellen oder eine kleine Anzahl von SSIs für die Verwendung in mehreren Geräte-SKUs haben. Wenn eine neue Version des Android-Betriebssystems veröffentlicht wird, müssen OEMs ihre SSIs nur einmal auf die neueste Android-Version aktualisieren. Sie können die SSIs wiederverwenden, um mehrere Geräte zu aktualisieren, ohne die /product-Partition zu aktualisieren.
OEMs und SoC-Anbieter können SSIs erstellen, die benutzerdefinierte Funktionen und Änderungen enthalten. Die auf dieser Seite beschriebenen Mechanismen und Best Practices sollen OEMs dabei helfen, folgende wichtige Ziele zu erreichen:
- Die SSI für mehrere Geräte-SKUs wiederverwenden.
- Aktualisieren Sie das Android-System mit den modularen Erweiterungen, um Betriebssystem-Upgrades zu vereinfachen.
Die grundlegende Idee, produktspezifische Komponenten in die Produktpartition zu trennen, ähnelt der Trennung von SoC-spezifischen Komponenten in die Anbieterpartition durch Mainline. Eine Produktschnittstelle (ähnlich VINTF) ermöglicht die Kommunikation zwischen SSI und der Produktpartition. In Bezug auf SSI beschreibt der Begriff Komponenten alle Ressourcen, Binärdateien, Texte und Bibliotheken, die in Images installiert werden, aus denen Partitionen werden.
Partitionen um SSI
Abbildung 1 zeigt Partitionen um SSI sowie die versionierten Schnittstellen über die Partitionen und Richtlinien für die Schnittstellen hinweg. In diesem Abschnitt werden die einzelnen Partitionen und Schnittstellen im Detail erläutert.
Abbildung 1. Partitionen und Schnittstellen rund um SSI.
Images und Partitionen
In diesem Abschnitt wird zwischen den Begriffen Image und Partition unterschieden.
- Ein Image ist ein konzeptionelles Softwareelement, das unabhängig aktualisiert werden kann.
- Eine Partition ist ein physischer Speicherort, der unabhängig aktualisiert werden kann.
Die Abschnitte in Abbildung 1 sind so definiert:
SSI:Ein Image, das für einen OEM üblich ist und auf mehreren Geräten vorhanden sein kann. Es enthält keine hardwarespezifischen oder produktspezifischen Komponenten. Alle Inhalte in einem bestimmten SSI werden per Definition auf allen Geräten geteilt, die dieses SSI verwenden. Das SSI besteht entweder aus einem einzelnen
/system-Image oder aus den Partitionen/systemund/system_ext.Produkt-Image:Eine Sammlung von produkt- oder gerätespezifischen Komponenten, die OEM-Anpassungen und Erweiterungen des Android-Betriebssystems darstellen. SoC-spezifische Komponenten gehören in die Partition
/vendor. SoC-Anbieter können die Partition/productauch für geeignete Komponenten wie SoC-unabhängige Komponenten verwenden. Wenn ein SoC-Anbieter beispielsweise eine SoC-unabhängige Komponente für seine OEM-Kunden bereitstellt (die optional mit dem Produkt ausgeliefert werden kann), kann der SoC-Anbieter diese Komponente im Produkt-Image platzieren. Der Speicherort einer Komponente wird durch ihren Zweck und nicht durch ihren Eigentümer bestimmt.Anbieter-Image:Eine Sammlung von SoC-spezifischen Komponenten.
ODM-Image:Eine Sammlung von platinenspezifischen Komponenten, die nicht vom SoC bereitgestellt werden. In der Regel gehört das Anbieter-Image dem SoC-Anbieter, während das ODM-Image dem Gerätehersteller gehört. Wenn es keine separate
/odm-Partition gibt, werden die Bilder des SoC-Anbieters und des ODM in der/vendor-Partition zusammengeführt.
Die Partition „/system_ext“
Die Partition /system_ext ist optional. Verwenden Sie diese Partition für alle benutzerdefinierten Funktionen und Erweiterungen, die eng mit AOSP-basierten Komponenten verknüpft sind. Diese Partition wird als OEM-spezifische Erweiterung der Partition /system betrachtet, ohne dass eine Schnittstelle zwischen den beiden Partitionen definiert ist.
Komponenten in der Partition /system_ext können private API-Aufrufe in die Partition /system ausführen und Komponenten in der Partition /system können private API-Aufrufe in die Partition /system_ext ausführen.
Da die beiden Partitionen eng miteinander verbunden sind, werden beide Partitionen zusammen aktualisiert, wenn eine neue Android-Version veröffentlicht wird. Eine /system_ext-Partition, die für die vorherige Android-Version erstellt wurde, muss nicht mit der /system-Partition in der nächsten Android-Version kompatibel sein.
Wenn Sie ein Modul in der Partition /system_ext installieren möchten, fügen Sie der Datei Android.bp system_ext_specific:
true hinzu. Auf Geräten ohne /system_ext-Partition werden solche Module im Unterverzeichnis ./system_ext der /system-Partition installiert.
Verlauf:Das ursprüngliche Designziel der /system_ext-Partition war, alle OEM-spezifischen Komponenten, unabhängig davon, ob sie häufig verwendet werden, in der /product-Partition zu platzieren. Es war jedoch nicht möglich, alle Komponenten auf einmal zu verschieben, insbesondere wenn einige Komponenten eine enge Kopplung mit der /system-Partition aufwiesen. Um eine eng gekoppelte Komponente in die /product-Partition zu verschieben, musste die Produktschnittstelle erweitert werden. Dies erforderte oft eine umfangreiche Umgestaltung der Komponente selbst, was viel Zeit und Aufwand in Anspruch nahm. Die /system_ext-Partition wurde ursprünglich als temporärer Speicherort für Komponenten eingerichtet, die noch nicht in die /product-Partition verschoben werden konnten. Ziel der SSI war es, die /system_ext-Partition schließlich zu eliminieren.
Die Partition /system_ext ist jedoch nützlich, um die Partition /system so nah wie möglich an AOSP zu halten. Bei SSI wird der größte Teil des Aufwands für das Upgrade auf die Komponenten in den Partitionen /system und /system_ext verwendet. Wenn das System-Image aus Quellen erstellt wird, die denen in AOSP so ähnlich wie möglich sind, können Sie sich bei der Aktualisierung auf das system_ext-Image konzentrieren.
Schnittstellen zwischen Bildern
Es gibt zwei Hauptschnittstellen für Händler- und Produktbilder im Zusammenhang mit SSI:
Vendor Interface (VINTF):VINTF ist die Schnittstelle zu den Komponenten, die sich in den Anbieter- und ODM-Images befinden. Komponenten in den Produkt- und System-Images können nur über diese Schnittstelle mit den Anbieter- und ODM-Images interagieren. Ein Anbieter-Image kann beispielsweise nicht von einem privaten Teil des System-Images abhängen und umgekehrt. Dies ist in der Treble-Architektur (jetzt Teil der umfassenderen Mainline-Architektur) definiert, die die Images in System- und Anbieterpartitionen aufteilt. Die Schnittstelle wird mit den folgenden Mechanismen beschrieben:
- HIDL (Passthrough-HAL ist nur für
system- undsystem_ext-Module verfügbar) - Stabile AIDL
- Konfigurationen
- System Properties API
- API für Konfigurationsdateischema
- VNDK
- Android SDK APIs
- Java SDK-Bibliothek
- HIDL (Passthrough-HAL ist nur für
Produktschnittstellen:Die Produktschnittstelle ist die Schnittstelle zwischen SSI und dem Produktbild. Durch die Definition einer stabilen Schnittstelle werden die Produktkomponenten von den Systemkomponenten in einem SSI entkoppelt.
SSI aktivieren
In diesem Abschnitt wird erläutert, wie Sie SSI in Android 11 und höher unterstützen.
Komponenten entbündeln
Damit die /product-Partition von den Systemkomponenten entkoppelt werden kann, muss sie dieselbe Erzwingungsrichtlinie wie die /vendor-Partition haben, die bereits mit Mainline entkoppelt wurde./product
- Integrierte Schnittstellen:Die integrierten Module in der
/product-Partition müssen von den anderen Partitionen entkoppelt werden. Die einzigen zulässigen Abhängigkeiten der Produktmodule sind einige VNDK-Bibliotheken (einschließlich LLNDK) aus der/system-Partition. JNI-Bibliotheken, von denen die Produkt-Apps abhängen, müssen NDK-Bibliotheken sein. - Java-Schnittstellen:Die Java-Module (Apps) in der Partition
/productkönnen keine verborgenen APIs verwenden, da diese instabil sind. Diese Module dürfen nur öffentliche APIs und System-APIs aus der Partition/systemsowie Java SDK-Bibliotheken in der Partition/systemoder/system_extverwenden. Sie können Java-SDK-Bibliotheken für benutzerdefinierte APIs definieren.
Produktschnittstellen erzwingen
Damit die /product-Partition entkoppelt wird, können OEMs auf ihren Geräten die Produktschnittstellen erzwingen, indem sie PRODUCT_PRODUCT_VNDK_VERSION:= current für integrierte Module und PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE:= true für Java-Module festlegen. Diese Variablen werden automatisch festgelegt, wenn die PRODUCT_SHIPPING_API_LEVEL des Geräts größer oder gleich 30 ist. Weitere Informationen finden Sie unter Schnittstellen für Produktpartitionen erzwingen.
Vorgeschlagene Schritte für GSI-basiertes SSI
Abbildung 2: Vorgeschlagene Partitionen für GSI-basiertes SSI.
Ein generisches Systemimage (GSI) ist das Systemimage, das direkt aus AOSP erstellt wird. Es wird für die Compliance-Tests (z. B. CTS-on-GSI) und als Referenzplattform verwendet, mit der App-Entwickler die Kompatibilität ihrer Apps testen können, wenn sie kein echtes Gerät mit der erforderlichen Android-Version haben.
OEMs können auch GSI verwenden, um ihr SSI zu erstellen. Wie unter Images und Partitionen beschrieben, besteht SSI aus dem Systemimage für die AOSP-definierten Komponenten und dem system_ext-Image für die OEM-definierten Komponenten. Wenn GSI als system-Image verwendet wird, kann sich der OEM auf das system_ext-Image für das Upgrade konzentrieren.
In diesem Abschnitt finden OEMs eine Anleitung dazu, wie sie ihre Anpassungen in die Partitionen /system_ext und /product modularisieren können, wenn sie ein AOSP- oder Near-AOSP-Systemimage verwenden. Wenn OEMs das Systemimage aus AOSP-Quellen erstellen, können sie das von ihnen erstellte Systemimage durch das von AOSP bereitgestellte GSI ersetzen. OEMs müssen den letzten Schritt (GSI unverändert verwenden) jedoch nicht sofort ausführen.
Schritt 1: „generic_system.mk“ für das OEM‑Systemimage (OEM‑GSI) übernehmen
Durch die Übernahme von generic_system.mk (das in Android 11 mainline_system.mk hieß und in AOSP in generic_system.mk umbenannt wurde) enthält das Systemimage (OEM-GSI) alle Dateien, die das AOSP-GSI hat. Diese Dateien können von OEMs geändert werden, sodass die OEM-GSI zusätzlich zu den AOSP-GSI-Dateien die proprietären OEM-Dateien enthalten kann.
Abbildung 3: Übernehmen Sie generic_system.mk für das Systemimage des OEM.
Schritt 2: OEM-GSI mit derselben Dateiliste wie das AOSP-GSI erstellen
Das OEM-GSI darf in dieser Phase keine zusätzlichen Dateien enthalten. Verschieben Sie daher OEM-eigene Dateien auf die Partitionen system_ext oder product.
Abbildung 4: Verschieben Sie hinzugefügte Dateien aus dem OEM-GSI.
Schritt 3: Zulassungsliste definieren, um die geänderten Dateien im OEM-GSI zu beschränken
Um die geänderten Dateien zu prüfen, können OEMs das Tool compare_images verwenden und das AOSP-GSI mit dem OEM-GSI vergleichen. Rufen Sie das AOSP-GSI über das AOSP-Lunch-Ziel generic_system_* ab.
Wenn Sie das compare_images-Tool regelmäßig mit dem Parameter allowlist ausführen, können Sie die Unterschiede außerhalb der Zulassungsliste im Blick behalten. So werden zusätzliche Änderungen am OEM-GSI verhindert.
Abbildung 5: Definieren Sie eine Zulassungsliste, um die Liste der geänderten Dateien im OEM-GSI zu reduzieren.
Schritt 4: OEM-GSI mit denselben Binärdateien wie das AOSP-GSI erstellen
Durch das Bereinigen der Zulassungsliste können OEMs das AOSP-GSI als System-Image für ihre eigenen Produkte verwenden. Um die Zulassungsliste zu bereinigen, können OEMs entweder ihre Änderungen im OEM-GSI aufgeben oder ihre Änderungen in AOSP einbringen, damit das AOSP-GSI ihre Änderungen enthält.
Abbildung 6. Die OEM-GSI muss dieselben Binärdateien wie die AOSP-GSI haben.
SSI definieren
OEMs können die folgenden Richtlinien verwenden, um ihre SSI zu definieren.
Die Partition „/system“ zur Build-Zeit schützen
Um produktspezifische Änderungen in der /system-Partition zu vermeiden und das OEM-GSI zu definieren, können OEMs ein Makefile-Makro namens require-artifacts-in-path verwenden, um die Deklaration von Systemmodulen nach dem Aufrufen des Makros zu verhindern. Ein Beispiel finden Sie unter Schritt 1: Makefile erstellen und Prüfung des Artefaktpfads aktivieren.
OEMs können eine Liste definieren, damit produktspezifische Module vorübergehend in der Partition /system installiert werden können. Die Liste muss jedoch leer sein, damit das OEM-GSI für alle Produkte des OEM gilt. In diesem Prozess wird das OEM-GSI definiert. Er kann unabhängig von den Schritten für das AOSP-GSI sein.
/system_ext-Partition gemeinsam nutzen
Die /system_ext-Partition kann sich zwischen Geräten unterscheiden, da sie gerätespezifische, systemgebundene Module enthalten kann. Da das SSI aus /system- und /system_ext-Partitionen besteht, verhindern die Unterschiede in der /system_ext-Partition, dass OEMs ein SSI definieren können. OEMs können ihr eigenes SSI haben und es auf mehreren Geräten freigeben, indem sie alle Unterschiede entfernen und die /system_ext-Partition gemeinsam nutzen.
In diesem Abschnitt finden Sie Empfehlungen zur Verwendung der /system_ext-Partition.
Ausgeblendete APIs in der Systempartition verfügbar machen
Viele produktspezifische Apps können nicht in der Produktpartition installiert werden, da sie verborgene APIs verwenden, die in der Produktpartition nicht zulässig sind. Wenn Sie gerätespezifische Apps in die Produktpartition verschieben möchten, müssen Sie die Verwendung verborgener APIs entfernen.
Die bevorzugte Methode zum Entfernen verborgener APIs aus den Apps besteht darin, alternative öffentliche oder System-APIs zu finden, um sie zu ersetzen. Wenn es keine APIs gibt, die die ausgeblendeten APIs ersetzen, können OEMs zum AOSP beitragen, um die neuen System-APIs für ihre Geräte zu definieren.
Alternativ können OEMs benutzerdefinierte APIs definieren, indem sie ihre eigene Java SDK-Bibliothek in der Partition /system_ext erstellen. Diese Bibliothek kann verborgene APIs in der Systempartition verwenden und die APIs für die Apps in der Produkt- oder Anbieterpartition bereitstellen. OEMs müssen die produktbezogenen APIs einfrieren, um die Abwärtskompatibilität zu gewährleisten.
SKU-spezifische App-Deaktivierung ersetzen
In Android 16 wurde der Legacy-Mechanismus zum selektiven Deaktivieren von APKs basierend auf der Hardware-SKU mithilfe von Framework-Ressourcen-Overlays (config_disableApksUnlessMatchedSku_apk_list und config_disableApkUnlessMatchedSku_skus_list) verworfen und entfernt. Weitere Informationen finden Sie unter aosp/3444399.
Die empfohlene Alternative ist die Verwendung der install-in-user-type-Systemkonfiguration in artikelnummernspezifischen Verzeichnissen. So wird verhindert, dass das Paket für Nutzer mit einer bestimmten Artikelnummer installiert wird, anstatt es erst nach der Installation zu deaktivieren.
Fügen Sie alle APKs (die Obermenge aller potenziellen Apps für alle SKUs in Ihrem Systemimage) in das Image ein, in der Regel in die Partition
/product.Prüfe, ob die Geräte-SKU in der Systemproperty
ro.boot.hardware.skurichtig festgelegt ist. Diese wird vom System verwendet, um die Geräte-SKU beim Booten zu identifizieren.Erstellen Sie SKU-spezifische sysconfig-Unterverzeichnisse unter
/product/etc/sysconfig/mit der Namenskonventionsku_<SKU_NAME>. Das System lädt Konfigurationen automatisch aus dem Verzeichnis, das der Eigenschaftro.boot.hardware.skuentspricht. Beispielpfad:/product/etc/sysconfig/sku_basic_model/.Konfigurieren Sie die Verhinderung der App-Installation. Erstellen Sie im SKU-spezifischen Verzeichnis eine XML-Konfigurationsdatei (z. B.
disabled_apps.xml) und verwenden Sie das<do-not-install-in>-Tag, um bestimmte Pakete auszuschließen.
XML-Beispiel (/product/etc/sysconfig/sku_basic_model/disabled_apps.xml):
<?xml version="1.0" encoding="utf-8"?>
<config>
<!-- Prevents this package from being installed for ANY user on this SKU -->
<install-in-user-type package="com.example.premium.feature.app" >
<do-not-install-in user-type="FULL" />
<do-not-install-in user-type="SYSTEM" />
</install-in-user-type>
</config>
Hier ein Vergleich der beiden Methoden:
| Funktion | Android 15 und niedriger | Android 16 und höher |
|---|---|---|
| Konfigurationsmethode | Framework-Ressourcen-Overlays | XML-Dateien für die Systemkonfiguration |
| Logikspeicherort | config.xml (Ressourcen-Overlay) |
/product/etc/sysconfig/sku_<name>/ |
| Ergebnis | App mit PackageManager deaktivieren | Verhindert die Installation von Apps für den Nutzer |
| Robustheit | Kann von Systemdiensten wieder aktiviert werden | Das Paket wird für den Nutzer nie installiert. |
Für Fälle, die eine detailliertere Steuerung erfordern (d. h. das Deaktivieren einer App, die normalerweise standardmäßig für alle SKUs installiert ist), unterstützt Android auch die Tags disabled-in-sku und enabled-in-sku-override in der Systemkonfiguration:
Mit
<disabled-in-sku package="com.example.app" />wird die App global deaktiviert.Mit
<enabled-in-sku-override package="com.example.app" />wird die App für eine bestimmte SKU wieder aktiviert, wenn sie im entsprechendensku_<name>-Verzeichnis platziert wird.
RRO definieren, anstatt statisches Ressourcen-Overlay zu verwenden
Ein statisches Ressourcen-Overlay manipuliert die überlagerten Pakete. Dies kann jedoch die Definition eines SSI beeinträchtigen. Achten Sie daher darauf, dass die Eigenschaften für RRO aktiviert und richtig festgelegt sind. Wenn OEMs die Attribute wie unten beschrieben festlegen, können alle automatisch generierten Overlays als RROs verwendet werden.
PRODUCT_ENFORCE_RRO_TARGETS := *
PRODUCT_ENFORCE_RRO_EXCLUDED_OVERLAYS := # leave it empty
Wenn eine detaillierte Konfiguration erforderlich ist, definieren Sie ein RRO manuell, anstatt sich auf ein automatisch generiertes zu verlassen. Ausführliche Informationen finden Sie unter Werte von App-Ressourcen zur Laufzeit ändern. OEMs können auch bedingte RROs definieren, die von den Systemeigenschaften abhängen, indem sie die Attribute android:requiredSystemPropertyName und android:requiredSystemPropertyValue verwenden.
FAQ
Nachfolgend finden Sie häufig gestellte Fragen zu SSI.
Kann ich mehrere SSIs definieren?
Das hängt von der Häufigkeit und den Merkmalen der Geräte (oder Gerätegruppe) ab.
OEMs können versuchen, die system_ext-Partition gemeinsam zu nutzen, wie unter system_ext-Partition gemeinsam nutzen beschrieben. Wenn sich eine Gerätegruppe in vielen Punkten unterscheidet, ist es besser, mehrere SSIs zu definieren.
Kann ich Module aus generic_system.mk entfernen, die mit meiner Implementierung in Konflikt stehen?
Nein. GSI hat eine Mindestanzahl an bootfähigen und testbaren Modulen. Wenn Sie der Meinung sind, dass ein Modul nicht unbedingt erforderlich ist, reichen Sie einen Fehlerbericht ein, um die Datei generic_system.mk zu aktualisieren.