Anbieter APEX

Sie können das APEX-Dateiformat verwenden, um ein Paket zu verpacken und untergeordnete Android-Betriebssystemmodule installieren. Sie ermöglicht unabhängige Erstellung und Installation von Komponenten wie nativen Diensten und Bibliotheken, HAL Implementierungen, Firmware, Konfigurationsdateien usw.

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

Anwendungsfälle

Modularisierung von Anbieterbildern

APEX erleichtert die natürliche Bündelung und Modularisierung von Funktionen Implementierungen von Anbieter-Images.

Wenn Anbieter-Images als Kombination aus unabhängigen Anbietern erstellt werden APEX: Gerätehersteller können ganz einfach die gewünschten welche Implementierungen auf ihrem Gerät erwünscht sind. Hersteller können sogar einem neuen Anbieter-APEX, wenn keiner der bereitgestellten APEXs den Anforderungen entspricht oder brandneue Hardware.

Beispielsweise kann ein OEM sein Gerät mit AOSP-WLAN zusammensetzen. APEX-Implementierung, SoC-Bluetooth-Implementierung APEX und ein benutzerdefinierter OEM Telefonieimplementierung APEX.

Eine Implementierung mit so vielen Abhängigkeiten zwischen die Komponenten eines Anbieters erfordern eine sorgfältige Koordination und Nachverfolgung. Durch das Einbinden aller Komponenten (einschließlich Konfigurationsdateien und zusätzlichen Bibliotheken) in APEXes mit klar definierte Schnittstellen an jedem Punkt der funktionsübergreifenden Kommunikation, Komponenten austauschbar werden.

Entwickleriteration

Mit Vendor APEX können Entwickler bei der Entwicklung von Anbietermodulen schneller iterieren, indem sie Bündeln einer vollständigen Funktionsimplementierung wie WLAN-HAL in einem Anbieter Apex. Entwickler können das Anbieter-APEX dann individuell erstellen und per Push zum Testen übertragen. anstatt das gesamte Anbieter-Image neu zu erstellen.

Dies vereinfacht und beschleunigt den Iterationszyklus für Entwickler, die arbeiten hauptsächlich an einem Funktionsbereich und möchten nur diesen iterieren. Bereich.

Die natürliche Bündelung eines Elementbereichs in einem APEX vereinfacht ebenfalls den Prozess. des Erstellens, Übertragens und Testens von Änderungen für diesen Funktionsbereich. Beispiel: Bei der Neuinstallation eines APEX werden alle gebündelten Bibliotheks- oder Konfigurationsdateien automatisch aktualisiert. die im APEX enthalten sind.

Das Bündeln eines Funktionsbereichs in einem APEX vereinfacht außerdem das Debugging oder das Zurücksetzen, wenn wird ein unerwünschtes Geräteverhalten beobachtet. Wenn die Telefoniefunktion in können Entwickler versuchen, eine ältere Telefonielösung zu installieren, Implementierung von APEX auf einem Gerät (ohne einen vollständigen Build flashen zu müssen) und um zu sehen, ob das Verhalten wieder funktioniert.

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

Grundlegende Informationen

Informationen zu generischem APEX finden Sie auf der Hauptseite des APEX-Dateiformats Informationen, einschließlich Geräteanforderungen, Details zum Dateiformat und Installationsschritten.

Wenn Sie in Android.bp das Attribut vendor: true festlegen, wird ein APEX-Modul zu einem Anbieter APEX.

apex {
  ..
  vendor: true,
  ..
}

Binärdateien und gemeinsam genutzte Bibliotheken

Ein APEX enthält transitive Abhängigkeiten in der APEX-Nutzlast, es sei denn, sie stabile Oberflächen haben.

Zu den stabilen nativen Schnittstellen für APEX-Abhängigkeiten des Anbieters gehören unter anderem cc_library mit stubs, ndk_library oder llndk_library. Diese Abhängigkeiten sind von der Paketerstellung und Abhängigkeiten werden im APEX-Manifest aufgezeichnet. Das Manifest ist von linkerconfig verarbeitet, sodass die externen nativen Abhängigkeiten zur Laufzeit verfügbar.

Im Gegensatz zu APEX in der Partition /system sind Anbieter-APEX in der Regel an eine bestimmte VNDK-Version. VNDK-Bibliotheken garantieren die ABI-Stabilität im damit wir VNDK-Bibliotheken als stabil behandeln und die Größe des Anbieters APEXes durch Ausschließen aus den APEXes mithilfe der use_vndk_as_stable Property.

Im folgenden Snippet enthält das APEX sowohl das Binärprogramm (my_service) als auch seine instabilen Abhängigkeiten (*.so-Dateien). Es enthält keine VNDK-Bibliotheken, auch wenn my_service mit VNDK-Bibliotheken wie libbase erstellt wird. Stattdessen können Sie Laufzeit my_service verwendet libbase aus VNDK-Bibliotheken, die vom System.

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

Im Snippet unten enthält das APEX die gemeinsam genutzte Bibliothek. my_standalone_libund alle zugehörigen instabilen Abhängigkeiten (wie oben beschrieben) werden erkannt.

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

HAL-Implementierungen

Um eine HAL-Implementierung zu definieren, stellen Sie die entsprechenden Binärdateien und Bibliotheken bereit in einem Anbieter-APEX ähnlich den folgenden Beispielen:

Um die HAL-Implementierung vollständig zu kapseln, sollte APEX auch alle relevante VINTF-Fragmente und Init-Skripts.

VINTF-Fragmente

VINTF-Fragmente können von einem Anbieter-APEX bereitgestellt werden, wenn sich die Fragmente etc/vintf des APEX.

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

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

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

Initialisierungsskripte

APEX-Dateien können init-Skripts auf zwei Arten eingefügt werden: (A) als vordefinierte Textdatei im APEX-Nutzlast oder (B) ein reguläres Initialisierungsskript in /vendor/etc. Sie können sowohl für dasselbe APEX.

Initialisierungsskript in APEX:

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

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

Init-Skripts in APEX-Dateien dürfen nur service Definitionen haben. Initialisierungsskripte in Anbieter-APEXes können auch on <property>-Anweisungen haben.

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

Firmware

Beispiel:

Betten Sie die Firmware mit dem Modultyp prebuilt_firmware in ein APEX des Anbieters ein: 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 sind in <apex name>/etc/firmware installiert des APEX-Verzeichnisses. ueventd scannt /apex/*/etc/firmware Verzeichnisse nach Firmware-Module zu finden.

Die file_contexts des APEX sollte alle Firmware-Nutzlasteinträge kennzeichnen. um sicherzustellen, dass ueventd zur Laufzeit auf diese Dateien zugreifen kann; Normalerweise reicht das Label vendor_file aus. Beispiel:

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

Kernelmodule

Betten Sie Kernelmodule wie im Folgenden beschrieben als vordefinierte Module in eine Anbieter-APEX ein.

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
  ..
}

Der file_contexts des APEX sollte alle Nutzlasteinträge des Kernelmoduls mit einem Label versehen ordnungsgemäß funktioniert. Beispiel:

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

Kernelmodule müssen explizit installiert werden. Beispiel für ein init-Script in der Anbieterpartition zeigt die Installation über insmod an:

my_init.rc:

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

Laufzeitressourcen-Overlays

Beispiel:

Overlays für Laufzeitressourcen in einen Anbieter-APEX einbetten mithilfe der Eigenschaft rros.

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 unterstützen verschiedene andere Konfigurationsdateien, die in der Regel beim Anbieter zu finden sind als vorgefertigte Daten in Anbieter-APEXs partitionieren und es kommen weitere hinzu.

Beispiele:

Zusätzliche Entwicklungsfunktionen

APEX-Auswahl beim Start

Beispiel:

Entwickler können auch mehrere Versionen von Anbieter-APEX installieren, die den gleichen denselben APEX-Namen und -Schlüssel und wählen Sie aus, welche Version jeweils aktiviert wird. mit persistenten Sysprops. Bei bestimmten Anwendungsfällen für Entwickler einfacher als die Installation einer neuen APEX-Kopie mit adb install.

Beispiele für Anwendungsfälle:

  • 3 Versionen des WLAN-HAL-Anbieters APEX installieren: QA-Teams können manuelle oder automatische Tests mit einer Version, führen Sie einen Neustart mit einer anderen Version durch und die Tests erneut ausführen und die Endergebnisse vergleichen.
  • Installieren Sie zwei Versionen des Kamera-HAL-Anbieters APEX, aktuell und experimentell:Dogfooder können die experimentelle Version ohne eine zusätzliche Datei herunterladen und installieren, damit sie einfach zurückwechseln können.

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

Für den Attributschlüssel werden folgende Formate erwartet:

  • Bootconfig
    • Wird zum Festlegen des Standardwerts in BoardConfig.mk verwendet.
    • androidboot.vendor.apex.<apex name>
  • Persistente Sysprop
    • Wird zum Ändern des Standardwerts auf einem bereits gestarteten Gerät verwendet.
    • Überschreibt den bootconfig-Wert, falls vorhanden.
    • persist.vendor.apex.<apex name>

Der Wert der Eigenschaft sollte der Dateiname des APEX sein. Dieser sollte aktiviert.

// 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 bootconfig in BoardConfig.mk:

# 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

Ändere nach dem Hochfahren des Geräts die aktivierte Version, indem du die persistentes Sysprop:

$ 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 die Aktualisierung von Bootconfig nach dem Flashen unterstützt (z. B. über fastboot oem-Befehle), muss das Attribut „bootconfig“ für die Mehrfachinstallation Außerdem ändert APEX die beim Hochfahren aktivierte Version.

Für virtuelle Referenzgeräte basierend auf Sepia: können Sie mit dem Befehl --extra_bootconfig_args das Attribut bootconfig festlegen direkt während der Markteinführung. Beispiel:

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