Google is committed to advancing racial equity for Black communities. See how.
Questa pagina è stata tradotta dall'API Cloud Translation.
Switch to English

AIDL per gli HAL

Android 11 introduce la possibilità di utilizzare AIDL per HAL in Android. Ciò rende possibile implementare parti di Android senza HIDL. Si consiglia vivamente di trasferire gli HAL in modo da utilizzare esclusivamente AIDL ove possibile (quando gli HAL a monte utilizzano HIDL, deve essere utilizzato HIDL).

Gli HAL che utilizzano AIDL per comunicare tra componenti del framework, come quelli in system.img , e componenti hardware, come quelli in vendor.img , devono utilizzare Stable AIDL. Tuttavia, per comunicare all'interno di una partizione, ad esempio, da un HAL a un altro, non ci sono restrizioni sul meccanismo IPC utilizzato.

Motivazione

AIDL esiste da più tempo di HIDL e viene utilizzato in molti altri luoghi, ad esempio tra i componenti del framework Android o nelle app. Ora che AIDL ha il supporto della stabilità, è possibile implementare un intero stack con un unico runtime IPC. AIDL ha anche un sistema di controllo delle versioni migliore di HIDL.

  • Usare un unico linguaggio IPC significa avere solo una cosa da imparare, eseguire il debug, ottimizzare e proteggere.
  • AIDL supporta il controllo delle versioni sul posto per i proprietari di un'interfaccia
    • I proprietari possono aggiungere metodi alla fine delle interfacce o campi ai lotti. Ciò significa che è più facile modificare il codice nel corso degli anni e anche il costo anno su anno è inferiore (i tipi possono essere modificati sul posto e non sono necessarie librerie aggiuntive per ogni versione dell'interfaccia).
    • Le interfacce di estensione possono essere collegate in fase di esecuzione piuttosto che nel sistema di tipi, quindi non è necessario riassegnare le estensioni a valle alle versioni più recenti delle interfacce.
  • Le interfacce AIDL esistenti possono essere utilizzate direttamente quando il proprietario decide di stabilizzarle. Prima, era necessario creare un'intera copia dell'interfaccia in HIDL.

Scrivere un'interfaccia HAL AIDL

Affinché un'interfaccia AIDL possa essere utilizzata tra il sistema e il fornitore, l'interfaccia richiede due modifiche:

  • Ogni definizione di tipo deve essere annotata con @VintfStability
  • La dichiarazione aidl_interface deve includere la stability: "vintf",

Solo il proprietario di un'interfaccia può apportare queste modifiche.

Inoltre, per la massima portabilità del codice e per evitare potenziali problemi come librerie aggiuntive non necessarie, si consiglia di disabilitare il backend CPP.

    aidl_interface: {
        ...
        backends: {
            cpp: {
                enabled: false,
            },
        },
    }

Trovare le interfacce HAL di AIDL

Le interfacce AIDL stabili AOSP per HAL si trovano nelle stesse directory di base delle interfacce HIDL, nelle cartelle aidl .

  • hardware / interfacce
  • framework / hardware / interfacce
  • sistema / hardware / interfacce

È necessario inserire le interfacce di estensione in altre sottodirectory di hardware/interfaces del vendor o hardware . Si consiglia vivamente di mantenere le interfacce coerenti tra tutti i dispositivi. Gli interni possono registrarsi in due modi diversi:

  • in fase di esecuzione, vedere le estensioni allegate
  • autonomo, registrato a livello globale e in VINTF

Costruire contro il runtime AIDL

AIDL ha tre diversi backend: Java, NDK, CPP. Per usare Stable AIDL, devi sempre usare la copia di sistema di libbinder in system/lib*/libbinder.so e parlare su /dev/binder . Per il codice sull'immagine del fornitore, ciò significa che libbinder (dal VNDK) non può essere utilizzato: questa libreria ha un'API C ++ instabile e interni instabili. Invece, il codice del fornitore nativo deve utilizzare il backend NDK di AIDL, collegarsi a libbinder_ndk (che è supportato dal sistema libbinder.so ) e collegare alle librerie -ndk_platform create dalle voci aidl_interface .

Nomi delle istanze del server AIDL HAL

Per convenzione, i servizi AIDL HAL hanno un nome istanza nel formato $package.$type/$instance . Ad esempio, un'istanza del vibratore HAL è registrata come android.hardware.vibrator.IVibrator/default .

Scrivere un server HAL AIDL

I server AIDL devono essere dichiarati nel manifest VINTF, ad esempio in questo modo:

    <hal format="aidl">
        <name>android.hardware.vibrator</name>
        <version>1</version>
        <fqname>IVibrator/default</fqname>
    </hal>

In caso contrario, dovrebbero registrare normalmente un servizio AIDL. Quando si eseguono test VTS, è previsto che siano disponibili tutti gli HAL AIDL dichiarati.

Scrivere un client AIDL

I client AIDL devono dichiararsi nella matrice di compatibilità, ad esempio in questo modo:

    <hal format="aidl" optional="true">
        <name>android.hardware.vibrator</name>
        <version>1-2</version>
        <interface>
            <name>IVibrator</name>
            <instance>default</instance>
        </interface>
    </hal>

Conversione di un HAL esistente da HIDL ad AIDL

Usa lo strumento hidl2aidl per convertire un'interfaccia HIDL in AIDL. Segui questi passaggi per convertire un pacchetto di file .hal in file .aidl:

  1. system/tools/hidl/hidl2aidl lo strumento che si trova in system/tools/hidl/hidl2aidl .

    m hidl2aidl
    
  2. Eseguire lo strumento con una directory di output seguita dal pacchetto da convertire.

    hidl2aidl -o <output directory> <package>
    

    Per esempio:

    hidl2aidl -o . android.hardware.nfc@1.2
    
  3. Leggi i file generati e risolvi eventuali problemi con la conversione.

    • conversion.log contiene eventuali problemi non gestiti che dovrebbero essere risolti per primi.
    • I file .aidl generati potrebbero contenere avvisi e suggerimenti che potrebbero richiedere un'azione. Questi commenti iniziano con // .
    • Cogli l'occasione per ripulire e apportare miglioramenti al pacchetto.

Sepolicy per AIDL HALs

Un tipo di servizio AIDL visibile al codice del fornitore deve avere l'attributo vendor_service . Altrimenti, la configurazione sepolicy è la stessa di qualsiasi altro servizio AIDL.

    type hal_power_service, service_manager_type, vendor_service;

Per la maggior parte dei servizi definiti dalla piattaforma, viene già aggiunto un contesto del servizio con il tipo corretto (ad esempio, android.hardware.power.IPower/default è già contrassegnato come hal_power_service ). Tuttavia, se un client framework supporta più nomi di istanza, è necessario aggiungere altri nomi di istanza nei file service_contexts specifici del dispositivo.

    android.hardware.power.IPower/custom_instance u:object_r:hal_power_service:s0

Interfacce di estensione collegate

Un'estensione può essere collegata a qualsiasi interfaccia del raccoglitore, sia che si tratti di un'interfaccia di primo livello registrata direttamente con il gestore del servizio o di una sotto-interfaccia. Quando si ottiene un'estensione, è necessario confermare che il tipo di estensione sia quello previsto. Le estensioni possono essere impostate solo dal processo che serve un raccoglitore.

Le estensioni allegate devono essere utilizzate ogni volta che un'estensione modifica la funzionalità di un HAL esistente. Quando è necessaria una funzionalità completamente nuova, non è necessario utilizzare questo meccanismo e un'interfaccia di estensione può essere registrata direttamente con il gestore del servizio.

Per impostare un'estensione nel raccoglitore, utilizza le seguenti API:

  • Nel backend NDK: AIBinder_setExtension
  • Nel back-end Java: android.os.Binder.setExtension
  • Nel backend CPP: android::Binder::setExtension

Per ottenere un'estensione su un raccoglitore, utilizza le seguenti API:

  • Nel backend NDK: AIBinder_getExtension
  • Nel back-end Java: android.os.IBinder.getExtension
  • Nel backend CPP: android::IBinder::getExtension

È possibile trovare ulteriori informazioni per queste API nella documentazione della funzione getExtension nel backend corrispondente. Un esempio di come utilizzare le estensioni può essere trovato in hardware / interfaces / test / extension / vibrator .

Principali differenze AIDL / HIDL

Quando si utilizzano gli HAL AIDL o le interfacce HAL AIDL, prestare attenzione alle differenze rispetto alla scrittura di HAL HIDL.

  • La sintassi del linguaggio AIDL è più vicina a Java. La sintassi HIDL è simile a C ++.
  • Tutte le interfacce AIDL hanno stati di errore incorporati. Invece di creare tipi di stato personalizzati, creare int di stato costanti nei file di interfaccia e utilizzare EX_SERVICE_SPECIFIC nei backend CPP / NDK e ServiceSpecificException nel backend Java.
  • AIDL non si interrompe in caso di errori di trasporto non controllati (il Return HIDL si interrompe in caso di errori non controllati).
  • AIDL può dichiarare un solo tipo per file.
  • Gli argomenti AIDL possono essere specificati come in / out / inout oltre al parametro di output (non ci sono "callback sincroni").
  • AIDL utilizza un fd come tipo primitivo invece di handle.
  • HIDL utilizza versioni principali per modifiche incompatibili e versioni secondarie per modifiche compatibili. In AIDL vengono apportate modifiche compatibili con le versioni precedenti. AIDL non ha un concetto esplicito delle versioni principali e invece questo è incorporato nei nomi dei pacchetti. Ad esempio, AIDL potrebbe utilizzare il nome del pacchetto bluetooth2 .