Anbieter APEX

Sie können das APEX-Dateiformat verwenden, um Android-Betriebssystemmodule auf niedrigerer Ebene zu verpacken und zu installieren. Es ermöglicht das unabhängige Erstellen und Installieren von Komponenten wie nativen Diensten und Bibliotheken, HAL-Implementierungen, Firmware und Konfigurationsdateien.

Anbieter-APEX-Dateien werden vom Build-System automatisch in der Partition /vendor installiert und zur Laufzeit von apexd aktiviert, genau wie APEX-Dateien in anderen Partitionen.

Anwendungsfälle

Modularisierung von Anbieter-Images

APEX-Dateien erleichtern die natürliche Bündelung und Modularisierung von Feature-Implementierungen in Anbieter-Images.

Wenn Anbieter-Images als Kombination aus unabhängig erstellten Anbieter-APEX-Dateien erstellt werden, können Gerätehersteller ganz einfach die spezifischen Anbieter-Implementierungen auswählen, die sie auf ihrem Gerät verwenden möchten. Hersteller können sogar eine neue Anbieter-APEX-Datei erstellen, wenn keine der bereitgestellten APEX-Dateien ihren Anforderungen entspricht oder wenn sie eine brandneue benutzerdefinierte Hardware haben.

Ein OEM kann beispielsweise sein Gerät mit der AOSP-WLAN-Implementierungs-APEX-Datei, der SoC-Bluetooth-Implementierungs-APEX-Datei und einer benutzerdefinierten OEM-Telefonie-Implementierungs-APEX-Datei zusammenstellen.

Ohne Anbieter-APEX-Dateien erfordert eine Implementierung mit so vielen Abhängigkeiten zwischen Anbieterkomponenten eine sorgfältige Koordination und Nachverfolgung. Wenn alle Komponenten (einschließlich Konfigurationsdateien und zusätzlichen Bibliotheken) in APEX-Dateien mit klar definierten Schnittstellen an jedem Punkt der funktionsübergreifenden Kommunikation verpackt werden, sind die verschiedenen Komponenten austauschbar.

Entwickleriteration

Anbieter-APEX-Dateien helfen Entwicklern, bei der Entwicklung von Anbietermodulen schneller zu iterieren, indem sie eine vollständige Feature-Implementierung wie die WLAN-HAL in einer Anbieter-APEX-Datei bündeln. Entwickler können dann die Anbieter-APEX-Datei erstellen und einzeln per Push übertragen, um Änderungen zu testen, anstatt das gesamte Anbieter-Image neu zu erstellen.

Dies vereinfacht und beschleunigt den Entwickleriterationszyklus für Entwickler, die hauptsächlich in einem Feature-Bereich arbeiten und nur diesen Bereich iterieren möchten.

Die natürliche Bündelung eines Feature-Bereichs in einer APEX-Datei vereinfacht auch das Erstellen, Übertragen und Testen von Änderungen für diesen Bereich. Wenn Sie beispielsweise eine APEX-Datei neu installieren, werden alle gebündelten Bibliotheks- oder Konfigurationsdateien, die in der APEX-Datei enthalten sind, automatisch aktualisiert.

Das Bündeln eines Feature-Bereichs in einer APEX-Datei vereinfacht auch das Debugging oder das Zurücksetzen, wenn ein schlechtes Geräteverhalten beobachtet wird. Wenn beispielsweise die Telefonie in einem neuen Build schlecht funktioniert, können Entwickler versuchen, eine ältere Telefonie-Implementierungs-APEX-Datei auf einem Gerät zu installieren (ohne einen vollständigen Build flashen zu müssen) und zu prüfen, ob das gute Verhalten wiederhergestellt wird.

Beispielworkflow:

# Build the entire device and flash. OR, obtain an already-flashed device.
source build/envsetup.sh && lunch oem_device-userdebug
m
fastboot flashall -w

# Test the device.
... testing ...

# Check previous behavior using a vendor APEX from one week ago, downloaded from
# your continuous integration build.
... download command ...
adb install <path to downloaded APEX>
adb reboot
... testing ...

# Edit and rebuild just the APEX to change and test behavior.
... edit APEX source contents ...
m <apex module name>
adb install out/<path to built APEX>
adb reboot
... testing ...

Beispiele

Grundlagen

Auf der Hauptseite zum APEX-Dateiformat finden Sie allgemeine Informationen zu APEX Dateien, einschließlich Geräteanforderungen, Details zum Dateiformat und Installationsschritten.

Wenn Sie in Android.bp die Property vendor: true festlegen, wird ein APEX-Modul zu einer Anbieter-APEX-Datei.

apex {
  ..
  vendor: true,
  ..
}

Binärdateien und gemeinsam genutzte Bibliotheken

Eine APEX-Datei enthält transitive Abhängigkeiten in der APEX-Nutzlast, es sei denn, sie haben stabile Schnittstellen.

Zu den stabilen nativen Schnittstellen für Anbieter-APEX-Abhängigkeiten gehören cc_library mit stubs und LLNDK-Bibliotheken. Diese Abhängigkeiten werden nicht verpackt und die Abhängigkeiten werden im APEX-Manifest aufgezeichnet. Das Manifest wird von linkerconfig verarbeitet, sodass die externen nativen Abhängigkeiten zur Laufzeit verfügbar sind.

Im folgenden Snippet enthält die APEX-Datei sowohl die Binärdatei (my_service) als auch ihre nicht stabilen Abhängigkeiten (*.so-Dateien).

apex {
  ..
  vendor: true,
  binaries: ["my_service"],
  ..
}

Im folgenden Snippet enthält die APEX-Datei die gemeinsam genutzte Bibliothek my_standalone_lib und alle ihre nicht stabilen Abhängigkeiten (wie oben beschrieben).

apex {
  ..
  vendor: true,
  native_shared_libs: ["my_standalone_lib"],
  ..
}

APEX-Datei verkleinern

APEX-Dateien können größer werden, da sie nicht stabile Abhängigkeiten bündeln. Wir empfehlen die Verwendung der statischen Verknüpfung. Häufig verwendete Bibliotheken wie libc++.so und libbase.so können statisch mit HAL-Binärdateien verknüpft werden. Eine Abhängigkeit zu erstellen, um eine stabile Schnittstelle bereitzustellen, kann eine weitere Option sein. Die Abhängigkeit wird nicht in der APEX-Datei gebündelt.

HAL-Implementierungen

Um eine HAL-Implementierung zu definieren, geben Sie die entsprechenden Binärdateien und Bibliotheken in einer Anbieter-APEX-Datei an, ähnlich den folgenden Beispielen:

Um die HAL-Implementierung vollständig zu kapseln, sollten in der APEX-Datei auch alle relevanten VINTF-Fragmente und Init-Skripts angegeben werden.

VINTF-Fragmente

VINTF-Fragmente können aus einer Anbieter-APEX-Datei bereitgestellt werden, wenn sie sich in etc/vintf der APEX-Datei befinden.

Verwenden Sie die Property prebuilts, um die VINTF-Fragmente in die APEX-Datei einzubetten.

apex {
  ..
  vendor: true,
  prebuilts: ["fragment.xml"],
  ..
}

prebuilt_etc {
  name: "fragment.xml",
  src: "fragment.xml",
  sub_dir: "vintf",
}

Abfrage-APIs

Wenn VINTF-Fragmente zu APEX-Dateien hinzugefügt werden, verwenden Sie libbinder_ndk-APIs, um die Zuordnungen von HAL-Schnittstellen und APEX-Namen abzurufen.

  • AServiceManager_isUpdatableViaApex("com.android.foo.IFoo/default") : true wenn die HAL-Instanz in der APEX-Datei definiert ist.
  • AServiceManager_getUpdatableApexName("com.android.foo.IFoo/default", ...) : Ruft den APEX-Namen ab, der die HAL-Instanz definiert.
  • AServiceManager_openDeclaredPassthroughHal("mapper", "instance", ...) : Verwenden Sie diesen Befehl, um eine Passthrough-HAL zu öffnen.

Init-Skripts

APEX-Dateien können Init-Skripts auf zwei Arten enthalten: (A) als vorgefertigte Textdatei in der APEX-Nutzlast oder (B) als reguläres Init-Skript in /vendor/etc. Sie können beides für dieselbe APEX-Datei festlegen.

Init-Skript in der APEX-Datei:

prebuilt_etc {
  name: "myinit.rc",
  src: "myinit.rc"
}

apex {
  ..
  vendor: true,
  prebuilts: ["myinit.rc"],
  ..
}

Init-Skripts in Anbieter-APEX-Dateien können service Definitionen und on <property or event> Anweisungen enthalten.

Achten Sie darauf, dass eine service-Definition auf eine Binärdatei in derselben APEX-Datei verweist. Die APEX-Datei com.android.foo kann beispielsweise einen Dienst namens foo-service definieren.

on foo-service /apex/com.android.foo/bin/foo
  ...

Seien Sie vorsichtig bei der Verwendung von on-Anweisungen. Da Init-Skripts in APEX-Dateien nach der Aktivierung von APEX-Dateien geparst und ausgeführt werden, können einige Ereignisse oder Properties nicht verwendet werden. Verwenden Sie apex.all.ready=true, um Aktionen so früh wie möglich auszulösen. Bootstrap-APEX-Dateien können on init verwenden, aber nicht on early-init.

Firmware

Beispiel :

Betten Sie die Firmware mit dem Modultyp prebuilt_firmware in eine Anbieter-APEX-Datei ein, wie folgt:

prebuilt_firmware {
  name: "my.bin",
  src: "path_to_prebuilt_firmware",
  vendor: true,
}

apex {
  ..
  vendor: true,
  prebuilts: ["my.bin"],  // installed inside APEX as /etc/firmware/my.bin
  ..
}

prebuilt_firmware-Module werden im <apex name>/etc/firmware -Verzeichnis der APEX-Datei installiert. ueventd scannt die Verzeichnisse /apex/*/etc/firmware nach Firmwaremodulen.

Die file_contexts der APEX-Datei sollten alle Einträge der Firmware-Nutzlast ordnungsgemäß kennzeichnen, damit diese Dateien zur Laufzeit von ueventd aufgerufen werden können. In der Regel reicht die Kennzeichnung vendor_file aus. Beispiel:

(/.*)? u:object_r:vendor_file:s0

Kernelmodule

Betten Sie Kernelmodule als vorgefertigte Module in eine Anbieter-APEX-Datei ein, wie folgt:

prebuilt_etc {
  name: "my.ko",
  src: "my.ko",
  vendor: true,
  sub_dir: "modules"
}

apex {
  ..
  vendor: true,
  prebuilts: ["my.ko"],  // installed inside APEX as /etc/modules/my.ko
  ..
}

Die file_contexts der APEX-Datei sollten alle Einträge der Kernelmodul-Nutzlast ordnungsgemäß kennzeichnen. Beispiel:

/etc/modules(/.*)? u:object_r:vendor_kernel_modules:s0

Kernelmodule müssen explizit installiert werden. Das folgende Beispiel für ein Init-Skript in der Anbieterpartition zeigt die Installation über insmod:

my_init.rc:

on early-boot
  insmod /apex/myapex/etc/modules/my.ko
  ..

Laufzeit-Ressourcen-Overlays

Beispiel :

Betten Sie Laufzeit-Ressourcen-Overlays mit der rros Property in eine Anbieter-APEX-Datei ein.

runtime_resource_overlay {
    name: "my_rro",
    soc_specific: true,
}


apex {
  ..
  vendor: true,
  rros: ["my_rro"],  // installed inside APEX as /overlay/my_rro.apk
  ..
}

Andere Konfigurationsdateien

Anbieter-APEX-Dateien unterstützen verschiedene andere Konfigurationsdateien, die sich normalerweise in der Anbieterpartition befinden, als vorgefertigte Dateien in Anbieter-APEX-Dateien. Weitere werden hinzugefügt.

Beispiele :

Bootstrap-Anbieter-APEX-Dateien

Einige HAL-Dienste wie keymint sollten verfügbar sein, bevor APEX-Dateien aktiviert werden. Diese HALs legen in der Regel early_hal in ihrer Dienstdefinition im Init-Skript fest. Ein weiteres Beispiel ist die Klasse animation, die in der Regel früher als das Ereignis post-fs-data gestartet wird. Wenn ein solcher früher HAL-Dienst in einer Anbieter-APEX-Datei verpackt ist, legen Sie im APEX Manifest "vendorBootstrap": true fest, damit er früher aktiviert werden kann. Bootstrap-APEX-Dateien können nur vom vorgefertigten Speicherort wie /vendor/apex und nicht von /data/apex aktiviert werden.

Systemeigenschaften

Dies sind die Systemeigenschaften, die das Framework liest, um Anbieter-APEX-Dateien zu unterstützen:

  • input_device.config_file.apex=<apex name> : Wenn diese Property festgelegt ist, werden die Eingabekonfigurationsdateien (*.idc, *.kl, und *.kcm) im Verzeichnis /etc/usr der APEX-Datei gesucht.
  • ro.vulkan.apex=<apex name> : Wenn diese Property festgelegt ist, wird der Vulkan-Treiber aus der APEX-Datei geladen. Da der Vulkan-Treiber von frühen HALs verwendet wird, legen Sie die APEX Bootstrap-APEX-Datei fest und konfigurieren Sie, dass der Linker-Namespace sichtbar ist.

Legen Sie die Systemeigenschaften in Init-Skripts mit dem setprop Befehl fest.

Zusätzliche Funktionen

APEX-Auswahl beim Start

Beispiel :

Anbieter-APEX-Dateien können optional während des Starts aktiviert werden. Wenn Sie mit der Systemeigenschaft ro.vendor.apex.<apex name> einen Dateinamen angeben, wird nur die APEX-Datei mit dem entsprechenden Dateinamen für <apex name> aktiviert. Die APEX-Datei mit <apex name> wird ignoriert (nicht aktiviert), wenn diese Systemeigenschaft auf none gesetzt ist. Mit dieser Funktion können Sie mehrere Kopien einer APEX-Datei mit demselben Namen installieren. Wenn mehrere Versionen derselben APEX-Datei vorhanden sind, sollten sie denselben Schlüssel verwenden.

Anwendungsbeispiele:

  • Drei Versionen der Anbieter-APEX-Datei für die WLAN-HAL installieren:QA-Teams können manuelle oder automatisierte Tests mit einer Version ausführen, dann in eine andere Version neu starten und die Tests noch einmal ausführen und schließlich die Endergebnisse vergleichen.
  • Zwei Versionen der Anbieter-APEX-Datei für die Kamera-HAL installieren: current und experimental: Dogfooder können die experimentelle Version verwenden, ohne eine zusätzliche Datei herunterladen und installieren zu müssen, und so ganz einfach wieder zur vorherigen Version zurückkehren.

Beim Start sucht apexd nach Sysprops in einem bestimmten Format, um die richtige APEX-Version zu aktivieren.

Die erwarteten Formate für den Attributschlüssel sind:

  • Startkonfiguration
    • Wird verwendet, um den Standardwert in BoardConfig.mk festzulegen.
    • androidboot.vendor.apex.<apex name>
  • Permanente Systemeigenschaft
    • Wird verwendet, um den Standardwert zu ändern, der auf einem bereits gestarteten Gerät festgelegt ist.
    • Überschreibt den Wert der Startkonfiguration, falls vorhanden.
    • persist.vendor.apex.<apex name>

Der Wert der Property sollte der Dateiname der APEX-Datei sein, die aktiviert werden soll, oder none, um die APEX-Datei zu deaktivieren.

// Default version.
apex {
  name: "com.oem.camera.hal.my_apex_default",
  vendor: true,
  ..
}

// Non-default version.
apex {
  name: "com.oem.camera.hal.my_apex_experimental",
  vendor: true,
  ..
}

Die Standardversion sollte auch mit der Startkonfiguration in BoardConfig.mk konfiguriert werden:

# Example for APEX "com.oem.camera.hal" with the default above:
BOARD_BOOTCONFIG += \
    androidboot.vendor.apex.com.oem.camera.hal=com.oem.camera.hal.my_apex_default

Nach dem Start des Geräts können Sie die aktivierte Version ändern, indem Sie die permanente Systemeigenschaft festlegen:

$ adb root;
$ adb shell setprop \
    persist.vendor.apex.com.oem.camera.hal \
    com.oem.camera.hal.my_apex_experimental;
$ adb reboot;

Wenn das Gerät das Aktualisieren der Startkonfiguration nach dem Flashen unterstützt (z. B. über fastboot oem Befehle), ändert das Ändern der Startkonfigurations-Property für die mehrfach installierte APEX-Datei auch die Version, die beim Start aktiviert wird.

Für virtuelle Referenzgeräte, die auf Cuttlefish basieren, können Sie den Befehl --extra_bootconfig_args verwenden, um die Startkonfigurations-Property direkt beim Start festzulegen. Beispiel:

launch_cvd --noresume \
  --extra_bootconfig_args "androidboot.vendor.apex.com.oem.camera.hal:=com.oem.camera.hal.my_apex_experimental";