Puoi utilizzare il formato file APEX per pacchettizzare e installare moduli del sistema operativo Android di livello inferiore. Consente la compilazione e l'installazione indipendenti di componenti come servizi e librerie native, implementazioni HAL, firmware, file di configurazione e così via.
I file APEX del fornitore vengono installati automaticamente dal sistema di compilazione nella partizione /vendor
e attivati in fase di esecuzione da apexd
, proprio come i file APEX in altre
partizioni.
Casi d'uso
Modularizzazione delle immagini dei fornitori
Gli APEX facilitano il naturale raggruppamento e la modularizzazione delle caratteristiche le implementazioni delle immagini dei fornitori.
Quando le immagini del fornitore vengono create come combinazione di fornitori creati in modo indipendente APEX, i produttori di dispositivi possono selezionare e scegliere facilmente le implementazioni richieste dai fornitori sul loro dispositivo. I produttori possono anche creare una l'APEX del nuovo fornitore se nessuno degli APEX forniti soddisfa le sue esigenze o se hardware personalizzato completamente nuovo.
Ad esempio, un OEM potrebbe scegliere di comporre il proprio dispositivo con l'APEX di implementazione del Wi-Fi AOSP, l'APEX di implementazione del Bluetooth SoC e un APEX di implementazione della telefonia OEM personalizzato.
Senza APEX del fornitore, un'implementazione con così tante dipendenze tra i componenti del fornitore richiede un attento coordinamento e monitoraggio. Includendo tutti (inclusi file di configurazione e librerie aggiuntive) negli APEX con interfacce chiaramente definite in ogni punto di comunicazione tra funzionalità, i vari componenti diventano intercambiabili.
Iterazione dello sviluppatore
Gli APEX del fornitore aiutano gli sviluppatori a eseguire l'iterazione più velocemente durante lo sviluppo dei moduli del fornitore raggruppando un'intera implementazione della funzionalità, come l'HAL Wi-Fi, all'interno di un APEX del fornitore. Gli sviluppatori possono quindi creare ed eseguire il push dell'APEX del fornitore per testarlo delle modifiche, anziché ricreare l'intera immagine del fornitore.
In questo modo, il ciclo di iterazione degli sviluppatori viene semplificato e accelerato per gli sviluppatori che lavorano principalmente in un'area di funzionalità e vogliono eseguire l'iterazione solo su quella.
Anche il naturale raggruppamento di un'area di caratteristiche in un APEX semplifica il processo di creazione, push e test delle modifiche per quell'area delle caratteristiche. Ad esempio, la reinstallazione di un APEX aggiorna automaticamente eventuali file di configurazione o librerie inclusi nell'APEX.
Il raggruppamento di un'area di funzionalità in un APEX semplifica anche il debug o il ripristino quando viene osservato un comportamento anomalo del dispositivo. Ad esempio, se la telefonia non funziona correttamente in una nuova build, gli sviluppatori potrebbero provare a installare un APEX di implementazione della telefonia precedente su un dispositivo (senza dover eseguire il flashing di una build completa) e verificare se il comportamento corretto viene ripristinato.
Esempio di flusso di lavoro:
# 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 ...
Esempi
Nozioni di base
Consulta la pagina principale Formato file APEX per l'APEX generico informazioni, tra cui i requisiti dei dispositivi, i dettagli dei formati dei file e i passaggi per l'installazione.
In Android.bp
, l'impostazione della proprietà vendor: true
rende un modulo APEX un APEX del fornitore.
apex {
..
vendor: true,
..
}
Binari e librerie condivise
Un APEX include dipendenze trasitive all'interno del payload APEX, a meno che non abbiano interfacce stabili.
Le interfacce native stabili per le dipendenze APEX del fornitore includono cc_library
con
stubs
e LLNDK. Queste dipendenze sono escluse
la pacchettizzazione e le dipendenze vengono registrate nel manifest APEX. Il file manifest è
elaborati da linkerconfig
in modo che le dipendenze native esterne
disponibili in fase di runtime.
Nel seguente snippet, l'APEX contiene sia il file binario (my_service
) che i relativi
delle dipendenze non stabili (*.so
file).
apex {
..
vendor: true,
binaries: ["my_service"],
..
}
Nel seguente snippet, il file APEX contiene la libreria condivisamy_standalone_lib
e le eventuali dipendenze non stabili (come descritto sopra).
apex {
..
vendor: true,
native_shared_libs: ["my_standalone_lib"],
..
}
Riduci APEX
APEX potrebbe aumentare di dimensioni perché raggruppa dipendenze non stabili. I nostri suggerimenti
tramite link statici. Le librerie comuni come libc++.so
e libbase.so
possono essere collegate staticamente ai file binari HAL. Un'altra opzione è creare una dipendenza per fornire un'interfaccia stabile. La dipendenza non verrà inclusa in APEX.
Implementazioni HAL
Per definire un'implementazione HAL, fornisci i file binari e le librerie corrispondenti all'interno dell'APEX di un fornitore, come nei seguenti esempi:
Per incapsulare completamente l'implementazione HAL, l'APEX deve anche specificare qualsiasi frammenti VINTF e script di inizializzazione pertinenti.
Frammenti VINTF
I frammenti VINTF possono essere forniti dall'APEX di un fornitore quando i frammenti si trovano in
etc/vintf
dell'APEX.
Utilizza la proprietà prebuilts
per incorporare i frammenti VINTF nell'APEX.
apex {
..
vendor: true,
prebuilts: ["fragment.xml"],
..
}
prebuilt_etc {
name: "fragment.xml",
src: "fragment.xml",
sub_dir: "vintf",
}
API di query
Quando i frammenti VINTF vengono aggiunti ad APEX, utilizza le API libbinder_ndk
per ottenere le mappature delle interfacce HAL e dei nomi APEX.
AServiceManager_isUpdatableViaApex("com.android.foo.IFoo/default")
:true
se l'istanza HAL è definita in APEX.AServiceManager_getUpdatableApexName("com.android.foo.IFoo/default", ...)
: ottiene il nome APEX che definisce l'istanza HAL.AServiceManager_openDeclaredPassthroughHal("mapper", "instance", ...)
: utilizza questa opzione per aprire un HAL passthrough.
Script di inizializzazione
Gli APEX possono includere script di inizializzazione in due modi: (A) un file di testo precompilato all'interno del payload APEX o (B) un normale script di inizializzazione in /vendor/etc
. Puoi impostare entrambi
per lo stesso APEX.
Script di inizializzazione in APEX:
prebuilt_etc {
name: "myinit.rc",
src: "myinit.rc"
}
apex {
..
vendor: true,
prebuilts: ["myinit.rc"],
..
}
Gli script di inizializzazione negli APEX del fornitore possono avere definizioni di service
e
on <property or event>
.
Assicurati che una definizione service
indichi un file binario nello stesso APEX.
Ad esempio, com.android.foo
APEX può definire un servizio denominato foo-service
.
on foo-service /apex/com.android.foo/bin/foo
...
Fai attenzione quando usi istruzioni on
. Poiché gli script di inizializzazione negli APEX vengono
analizzati ed eseguiti dopo l'attivazione degli APEX, alcuni eventi o proprietà
non possono essere utilizzate. Utilizza apex.all.ready=true
per attivare le azioni il prima possibile.
Gli APEX di bootstrap possono utilizzare on init
, ma non
on early-init
.
Firmware
Esempio:
Incorpora il firmware nell'APEX di un fornitore con il tipo di modulo prebuilt_firmware
, come
.
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
moduli sono installati in <apex name>/etc/firmware
dell'APEX. ueventd
esegue la scansione delle directory /apex/*/etc/firmware
per trovare i moduli del firmware.
Il file_contexts
dell'APEX deve etichettare correttamente le eventuali voci del payload del firmware per garantire che questi file siano accessibili da ueventd
in fase di esecuzione. In genere, l'etichetta vendor_file
è sufficiente. Ad esempio:
(/.*)? u:object_r:vendor_file:s0
Moduli del kernel
Incorpora i moduli del kernel in un APEX del fornitore come moduli predefiniti, come segue.
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
..
}
Il file_contexts
dell'APEX deve etichettare qualsiasi voce di payload del modulo kernel
correttamente. Ad esempio:
/etc/modules(/.*)? u:object_r:vendor_kernel_modules:s0
I moduli del kernel devono essere installati in modo esplicito. Lo script di inizializzazione dell'esempio seguente
nella partizione del fornitore mostra l'installazione tramite insmod
:
my_init.rc
:
on early-boot
insmod /apex/myapex/etc/modules/my.ko
..
Overlay di risorse di runtime
Esempio:
Incorporano overlay di risorse di runtime nell'APEX di un fornitore
utilizzando la proprietà rros
.
runtime_resource_overlay {
name: "my_rro",
soc_specific: true,
}
apex {
..
vendor: true,
rros: ["my_rro"], // installed inside APEX as /overlay/my_rro.apk
..
}
Altri file di configurazione
Gli APEX del fornitore supportano vari altri file di configurazione che in genere si trovano sul la partizione è preconfigurata all'interno degli APEX del fornitore e se ne stanno aggiungendo altre.
Esempi:
- File XML di dichiarazione delle funzionalità
- I sensori includono XML integrato nell'APEX di un fornitore di sensori HAL
- File di configurazione di input
- Configurazioni del touchscreen come precompiute in un APEX del fornitore solo per la configurazione
APEX del fornitore di bootstrap
Alcuni servizi HAL come keymint
dovrebbero essere disponibili prima che gli APEX siano
è stata attivata. Questi HAL in genere impostano early_hal
nella definizione del servizio nello script di inizializzazione. Un altro esempio è la classe animation
, che di solito è iniziata
prima dell'evento post-fs-data
. Quando un servizio HAL precedente è impacchettato nell'APEX del fornitore, crea l'apex "vendorBootstrap": true
nel suo manifest APEX in modo che possa essere attivato in precedenza. Tieni presente che gli APEX di bootstrap possono essere attivati solo dalla posizione predefinita, ad esempio /vendor/apex
, non da /data/apex
.
Proprietà di sistema
Queste sono le proprietà di sistema che il framework legge per supportare gli APEX del fornitore:
input_device.config_file.apex=<apex name>
: se impostato, l'input di configurazione automatica (*.idc
,*.kl
e*.kcm
) viene eseguita la ricerca da directory/etc/usr
dell'APEX.ro.vulkan.apex=<apex name>
: se impostato, il driver Vulkan viene caricato da l'APEX. Poiché il driver Vulkan viene utilizzato dai primi HAL, imposta l'APEX Avvia APEX e configura lo spazio dei nomi del linker visibile.
Imposta le proprietà di sistema negli script di inizializzazione utilizzando il comando setprop
.
Funzionalità di sviluppo aggiuntive
Selezione di APEX all'avvio
Esempio:
Gli sviluppatori possono anche installare più versioni degli APEX dei fornitori che condividono
con lo stesso nome e la stessa chiave APEX, quindi scegli la versione da attivare durante ogni
utilizzando sysprop permanenti. Per determinati casi d'uso degli sviluppatori, questa operazione potrebbe essere più semplice rispetto all'installazione di una nuova copia di APEX utilizzando adb install
.
Esempi di casi d'uso:
- Installa 3 versioni dell'APEX del fornitore HAL Wi-Fi: i team QA possono eseguire test manuali o automatici utilizzando una versione, quindi riavviare in un'altra versione e eseguire nuovamente i test, per poi confrontare i risultati finali.
- Installa due versioni dell'APEX del fornitore HAL per la videocamera, attuale e sperimentale: i dogfood possono utilizzare la versione sperimentale senza scaricano e installano un file aggiuntivo in modo che possano tornare facilmente alla versione precedente.
Durante l'avvio, apexd
cerca i sysprop che seguono un formato specifico per
attivare la versione APEX corretta.
I formati previsti per la chiave della proprietà sono:
- Bootconfig
- Utilizzato per impostare il valore predefinito, in
BoardConfig.mk
. androidboot.vendor.apex.<apex name>
- Utilizzato per impostare il valore predefinito, in
- sysprop permanente
- Utilizzato per modificare il valore predefinito impostato su un dispositivo già avviato.
- Sostituisce il valore bootconfig, se presente.
persist.vendor.apex.<apex name>
Il valore della proprietà deve essere il nome file dell'APEX, che deve essere è stata attivata.
// 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 versione predefinita deve essere configurata anche utilizzando 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
Dopo l'avvio del dispositivo, modifica la versione attivata impostando la proprietà sysprop permanente:
$ adb root;
$ adb shell setprop \
persist.vendor.apex.com.oem.camera.hal \
com.oem.camera.hal.my_apex_experimental;
$ adb reboot;
Se il dispositivo supporta l'aggiornamento di bootconfig dopo il flashing (ad esempio tramite i comandi fastboot
oem
), la modifica della proprietà bootconfig per APEX installato su più dispositivi modifica anche la versione attivata all'avvio.
Per i dispositivi di riferimento virtuali basati su Cuttlefish,
puoi utilizzare il comando --extra_bootconfig_args
per impostare la proprietà bootconfig
direttamente durante l'avvio. Ad esempio:
launch_cvd --noresume \
--extra_bootconfig_args "androidboot.vendor.apex.com.oem.camera.hal:=com.oem.camera.hal.my_apex_experimental";