Vous pouvez utiliser le format de fichier ApEX pour empaqueter et installer des modules d'OS Android de niveau inférieur. Il permet de créer et d'installer indépendamment des composants tels que des services et des bibliothèques natives, des implémentations HAL, des micrologiciels, des fichiers de configuration, etc.
Les apex du fournisseur sont installés automatiquement par le système de compilation dans le /vendor
.
partition et activée au moment de l'exécution par apexd
, comme les apex dans d'autres
des partitions.
Cas d'utilisation
Modularisation des images des fournisseurs
Les APEX facilitent le regroupement et la modularisation naturels des implémentations de fonctionnalités sur les images du fournisseur.
Lorsque les images des fournisseurs sont créées de manière indépendante APEX, les fabricants d’appareils peuvent facilement choisir les besoins spécifiques les implémentations des fournisseurs voulaient sur leur appareil. Les fabricants peuvent même créer un nouvel APEX de fournisseur si aucun des APEX fournis ne répond à leurs besoins ou s'ils disposent d'un tout nouveau matériel personnalisé.
Par exemple, un OEM peut choisir de composer son appareil avec le Wi-Fi AOSP l'apex d'implémentation Bluetooth pour le SoC, et un OEM personnalisé APEX pour l'implémentation des services de téléphonie.
Sans APEX du fournisseur, une implémentation avec autant de dépendances entre les composants du fournisseur nécessite une coordination et un suivi minutieux. En encapsulant tout (y compris les fichiers de configuration et les bibliothèques supplémentaires) dans les APEX avec des interfaces clairement définies à tout point de communication entre les fonctionnalités, les différents composants deviennent interchangeables.
Itération du développeur
Les APEX du fournisseur aident les développeurs à itérer plus rapidement lors du développement de modules de fournisseurs en regroupant l'implémentation complète d'une fonctionnalité, comme le HAL Wi-Fi, dans un APEX du fournisseur. Les développeurs peuvent ensuite créer et transférer individuellement l'APEX du fournisseur pour tester les modifications, au lieu de recréer l'image complète du fournisseur.
Cela simplifie et accélère le cycle d'itération des développeurs qui travaillent principalement dans un seul domaine de fonctionnalités et ne souhaitent itérer que sur ce domaine.
Le regroupement naturel d'une zone de caractéristiques dans un apex simplifie également le processus. pour créer, transmettre et tester des modifications pour ce domaine. Par exemple : la réinstallation d’un APEX met automatiquement à jour tout fichier de bibliothèque ou fichier de configuration groupé de l'apex.
Le regroupement d'une zone de fonctionnalité dans un APEX simplifie également le débogage ou le rétablissement lorsqu'un mauvais comportement de l'appareil est observé. Par exemple, si la téléphonie ne fonctionne pas bien un nouveau build, les développeurs peuvent alors essayer d'installer une ancienne implémenter APEX sur un appareil (sans qu'il soit nécessaire de flasher un build complet) et pour voir si le bon comportement est rétabli.
Exemple de workflow:
# 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 ...
Exemples
Principes de base
Consultez la page principale APEX File Format (Format de fichier apex) pour trouver les valeurs génériques. y compris la configuration requise pour l'appareil, les détails sur le format des fichiers et la procédure d'installation.
Dans Android.bp
, la définition de la propriété vendor: true
fait d'un module APEX un
du fournisseur APEX.
apex {
..
vendor: true,
..
}
Binaires et bibliothèques partagées
Un APEX inclut des dépendances transitives dans la charge utile APEX, sauf s'il dispose d'interfaces stables.
Les interfaces natives stables pour les dépendances APEX des fournisseurs incluent cc_library
avec
stubs
et LLNDK. Ces dépendances sont exclues de
le packaging et les dépendances sont enregistrés dans le fichier manifeste APEX. Le fichier manifeste est
traités par linkerconfig
afin que les dépendances natives externes soient
disponibles au moment de l'exécution.
Dans l'extrait de code suivant, APEX contient à la fois le binaire (my_service
) et son
dépendances non stables (fichiers *.so
).
apex {
..
vendor: true,
binaries: ["my_service"],
..
}
Dans l'extrait de code suivant, l'APEX contient la bibliothèque partagée my_standalone_lib
et toutes ses dépendances non stables (comme décrit ci-dessus).
apex {
..
vendor: true,
native_shared_libs: ["my_standalone_lib"],
..
}
Réduire APEX
APEX peut être plus volumineux, car il regroupe les dépendances instables. Nous vous recommandons d'utiliser l'association statique. Les bibliothèques courantes telles que libc++.so
et libbase.so
peuvent être liées de manière statique aux binaires HAL. Une autre option consiste à créer une dépendance pour fournir une interface stable. La dépendance ne sera pas regroupée dans l'apex.
Implémentations HAL
Pour définir une implémentation HAL, fournissez les binaires et les bibliothèques correspondants dans un APEX de fournisseur, comme dans les exemples suivants:
Pour encapsuler entièrement l'implémentation HAL, l'apex doit également spécifier les fragments VINTF et les scripts d'initialisation pertinents.
Fragments VINTF
Les fragments VINTF peuvent être diffusés à partir d'un APEX du fournisseur lorsque les fragments se trouvent dans etc/vintf
de l'APEX.
Utilisez la propriété prebuilts
pour intégrer les fragments VINTF dans l'apex.
apex {
..
vendor: true,
prebuilts: ["fragment.xml"],
..
}
prebuilt_etc {
name: "fragment.xml",
src: "fragment.xml",
sub_dir: "vintf",
}
API de requête
Lorsque des fragments VINTF sont ajoutés à APEX, utilisez les API libbinder_ndk
pour obtenir les mappages des interfaces HAL et des noms APEX.
AServiceManager_isUpdatableViaApex("com.android.foo.IFoo/default")
:true
si l'instance HAL est définie dans APEX.AServiceManager_getUpdatableApexName("com.android.foo.IFoo/default", ...)
: obtient le nom APEX qui définit l'instance HAL.AServiceManager_openDeclaredPassthroughHal("mapper", "instance", ...)
: utilisez-le pour ouvrir une couche HAL passthrough.
Scripts d'initialisation
Les apex peuvent inclure des scripts d'initialisation de deux manières: (A) dans un fichier texte prédéfini
charge utile APEX, ou (B) un script d'initialisation standard dans /vendor/etc
. Vous pouvez définir à la fois
pour le même APEX.
Script d'initialisation dans APEX:
prebuilt_etc {
name: "myinit.rc",
src: "myinit.rc"
}
apex {
..
vendor: true,
prebuilts: ["myinit.rc"],
..
}
Les scripts d'initialisation dans les APEX de fournisseurs peuvent comporter des définitions service
et des directives on <property or event>
.
Assurez-vous qu'une définition service
pointe un binaire dans le même Apex.
Par exemple, l'apex com.android.foo
peut définir un service nommé foo-service
.
on foo-service /apex/com.android.foo/bin/foo
...
Soyez prudent lorsque vous utilisez des directives on
. Étant donné que les scripts d'initialisation
dans les APEX sont
analysés et exécutés après l'activation des APEX, certains événements ou propriétés
ne peuvent pas être utilisées. Utilisez apex.all.ready=true
pour déclencher des actions dès que possible.
Les APEX d'amorçage peuvent utiliser on init
, mais pas on early-init
.
Micrologiciel
Exemple :
Intégrez le micrologiciel dans un APEX du fournisseur avec le type de module prebuilt_firmware
, comme suit.
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
..
}
Les modules prebuilt_firmware
sont installés dans le répertoire <apex name>/etc/firmware
de l'APEX. ueventd
analyse les répertoires /apex/*/etc/firmware
pour trouver les modules de micrologiciels.
Le file_contexts
de l'apex doit étiqueter toutes les entrées de charge utile du micrologiciel
correctement pour s'assurer que ces fichiers sont accessibles par ueventd
lors de l'exécution.
l'étiquette vendor_file
suffit généralement. Exemple :
(/.*)? u:object_r:vendor_file:s0
Modules du noyau
Intégrez les modules du noyau dans un système APEX de fournisseur en tant que modules prédéfinis, comme suit.
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
..
}
Le file_contexts
de l'apex doit étiqueter toutes les entrées de charge utile de module du noyau
correctement. Exemple :
/etc/modules(/.*)? u:object_r:vendor_kernel_modules:s0
Les modules kernel doivent être installés explicitement. L'exemple de script d'initialisation suivant dans la partition du fournisseur montre l'installation via insmod
:
my_init.rc
:
on early-boot
insmod /apex/myapex/etc/modules/my.ko
..
Superpositions de ressources d'exécution
Exemple :
Intégrez des superpositions de ressources d'exécution dans un APEX de fournisseur.
à l'aide de la propriété rros
.
runtime_resource_overlay {
name: "my_rro",
soc_specific: true,
}
apex {
..
vendor: true,
rros: ["my_rro"], // installed inside APEX as /overlay/my_rro.apk
..
}
Autres fichiers de configuration
Les apex de fournisseur prennent en charge divers autres fichiers de configuration généralement disponibles sur le fournisseur partition en tant que composants prédéfinis dans les APR des fournisseurs, et d'autres sont en cours d'ajout.
Exemples :
- Fichiers XML de déclaration de fonctionnalités
- Les capteurs comportent des fichiers XML prédéfinis dans un APEX de fournisseur HAL de capteur.
- Fichiers de configuration d'entrée
- Configurations d'écran tactile en tant que composants prédéfinis dans un APEX de fournisseur de configuration uniquement
APEX de fournisseurs d'amorçage
Certains services HAL tels que keymint
doivent être disponibles avant l'activation des APEX. Ces HAL définissent généralement early_hal
dans leur définition de service dans le
script init. Un autre exemple est la classe animation
, qui est généralement démarrée avant l'événement post-fs-data
. Lorsqu'un tel service HAL précoce est empaqueté dans l'APEX du fournisseur, définissez l'apex sur "vendorBootstrap": true
dans son fichier manifeste APEX afin qu'il puisse être activé plus tôt. Notez que les
apex d’amorçage peuvent être
activé uniquement à partir de l'emplacement prédéfini comme /vendor/apex
, et non depuis
/data/apex
Propriétés système
Il s'agit des propriétés système lues par le framework pour permettre au fournisseur APERÇU:
input_device.config_file.apex=<apex name>
: lorsque ce paramètre est défini, les fichiers de configuration d'entrée (*.idc
,*.kl
et*.kcm
) sont recherchés à partir du répertoire/etc/usr
de l'APEX.ro.vulkan.apex=<apex name>
: lorsque cette valeur est définie, le pilote Vulkan est chargé à partir de l'APEX. Étant donné que le pilote Vulkan est utilisé par les premières HAL, assurez-vous que l'apex Amorcer APEX et configurer cet espace de noms de l'éditeur de liens visible.
Définissez les propriétés système dans les scripts d'initialisation à l'aide de la commande setprop
.
Fonctionnalités de développement supplémentaires
Sélection de l'apex au démarrage
Exemple :
Les développeurs peuvent également installer plusieurs versions d'APEX de fournisseurs qui partagent le
le même nom et la même clé d'apex, puis de choisir la version à activer lors de chaque
à l'aide de Sysprops persistants. Pour certains cas d'utilisation des développeurs, cela peut être plus simple que d'installer une nouvelle copie de l'APEX à l'aide de adb install
.
Exemples de cas d'utilisation :
- Installez trois versions de l'APEX du fournisseur HAL Wi-Fi : les équipes de contrôle qualité peuvent exécuter des tests manuels ou automatisés à l'aide d'une version, puis redémarrer dans une autre version et réexécuter les tests, puis comparer les résultats finaux.
- Installez deux versions du fournisseur HAL de la caméra APEX, current et expérimental:les dogfoodeurs peuvent utiliser la version expérimentale sans télécharger et installer un fichier supplémentaire, afin de pouvoir facilement revenir en arrière.
Lors du démarrage, apexd
recherche sysprops suivant un format spécifique pour
activer la bonne version d’APEX.
Les formats attendus pour la clé de propriété sont les suivants:
- Bootconfig
- Permet de définir la valeur par défaut, dans
BoardConfig.mk
. androidboot.vendor.apex.<apex name>
- Permet de définir la valeur par défaut, dans
- Système persistant "sysprop"
- Permet de modifier la valeur par défaut définie sur un appareil déjà démarré.
- Remplace la valeur de bootconfig, le cas échéant.
persist.vendor.apex.<apex name>
La valeur de la propriété doit être le nom de fichier de l'APEX à activer.
// 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,
..
}
La version par défaut doit également être configurée à l'aide de bootconfig dans 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
Une fois l'appareil démarré, modifiez la version activée en définissant la propriété système persistante :
$ adb root;
$ adb shell setprop \
persist.vendor.apex.com.oem.camera.hal \
com.oem.camera.hal.my_apex_experimental;
$ adb reboot;
Si l'appareil prend en charge la mise à jour de bootconfig après le flashage (par exemple, via des commandes fastboot
oem
), la modification de la propriété bootconfig pour l'APEX multi-installé modifie également la version activée au démarrage.
Pour les appareils de référence virtuels basés sur Cuttlefish,
vous pouvez utiliser la commande --extra_bootconfig_args
pour définir la propriété bootconfig
directement lors du lancement. Exemple :
launch_cvd --noresume \
--extra_bootconfig_args "androidboot.vendor.apex.com.oem.camera.hal:=com.oem.camera.hal.my_apex_experimental";