Crea l'interfaccia dell'HAL

Devi usare l'HIDL per descrivere tutti i flag di build utilizzati per la compilazione del framework. I flag di build pertinenti devono essere raggruppati e inclusi in un singolo file .hal. Utilizzo di HIDL per specificare gli elementi di configurazione include i seguenti vantaggi:

  • Con più versioni (per aggiungere nuovi elementi di configurazione, i fornitori/OEM devono estendere esplicitamente la HAL)
  • Ben documentato
  • Controllo dell'accesso con SELinux
  • Verifica l'integrità degli elementi di configurazione tramite Test fornitore Suite (controllo intervallo, controllo delle interdipendenze tra gli elementi e così via)
  • API generate automaticamente sia in C++ che in Java

Identificare i flag di build utilizzati dal framework

Inizia identificando le configurazioni di build utilizzate per compilare in modo condizionale abbandona le configurazioni obsolete per rimpicciolire il set. Ad esempio: viene identificato il seguente set di flag di build per surfaceflinger:

  • TARGET_USES_HWC2
  • TARGET_BOARD_PLATFORM
  • TARGET_DISABLE_TRIPLE_BUFFERING
  • TARGET_FORCE_HWC_FOR_VIRTUAL_DISPLAYS
  • NUM_FRAMEBUFFER_SURFACE_BUFFERS
  • TARGET_RUNNING_WITHOUT_SYNC_FRAMEWORK
  • VSYNC_EVENT_PHASE_OFFSET_NS
  • SF_VSYNC_EVENT_PHASE_OFFSET_NS
  • PRESENT_TIME_OFFSET_FROM_VSYNC_NS
  • MAX_VIRTUAL_DISPLAY_DIMENSION

Crea un'interfaccia HAL

Le configurazioni di build per un sottosistema sono accessibili tramite un'interfaccia HAL, mentre interfacce per fornire valori di configurazione sono raggruppate nel pacchetto HAL android.hardware.configstore (attualmente alla versione 1.0). Ad esempio, per creare un file di interfaccia HAL per surfaceflinger, in hardware/interfaces/configstore/1.0/ISurfaceFlingerConfigs.hal:

package android.hardware.configstore@1.0;

interface ISurfaceFlingerConfigs {
    // TO-BE-FILLED-BELOW
};

Dopo aver creato il file .hal, esegui hardware/interfaces/update-makefiles.sh per aggiungere il nuovo .hal file in Android.bp e Android.mk file.

Aggiungi funzioni per i flag di build

Per ogni flag di build, aggiungi una nuova funzione all'interfaccia. Ad esempio, nel hardware/interfaces/configstore/1.0/ISurfaceFlingerConfigs.hal:

interface ISurfaceFlingerConfigs {
    disableTripleBuffering() generates(OptionalBool ret);
    forceHwcForVirtualDisplays() generates(OptionalBool ret);
    enum NumBuffers: uint8_t {
        USE_DEFAULT = 0,
        TWO = 2,
        THREE = 3,
    };
    numFramebufferSurfaceBuffers() generates(NumBuffers ret);
    runWithoutSyncFramework() generates(OptionalBool ret);
    vsyncEventPhaseOffsetNs generates (OptionalUInt64 ret);
    presentTimeOffsetFromSyncNs generates (OptionalUInt64 ret);
    maxVirtualDisplayDimension() generates(OptionalInt32 ret);
};

Quando aggiungi una funzione:

  • Usa nomi concisi. Evita di convertire la variabile makefile in nomi di funzione e tieni presente che TARGET_ e I prefissi BOARD_ non sono più necessari.
  • Aggiungi commenti. Aiuta gli sviluppatori a comprendere lo scopo dell'elemento di configurazione, come cambia il comportamento del framework, valori validi e altre informazioni informazioni.

I tipi restituiti di funzione possono essere Optional[Bool|String|Int32|UInt32|Int64|UInt64]. I tipi sono definiti in types.hal nella stessa directory e aggrega i valori primitivi con un campo che indica se il valore è specificato dall'HAL; In caso contrario, il valore predefinito .

struct OptionalString {
    bool specified;
    string value;
};

Se appropriato, definisci l'enumerazione che rappresenta al meglio il tipo di dell'elemento di configurazione e utilizza questa enum come tipo restituito. Nell'esempio precedente, l'enum NumBuffers è definita per limitare il numero di istanze e i relativi valori. Quando definisci questi tipi di dati personalizzati, aggiungi un campo o un valore enum (ad ad esempio USE_DEFAULT) per indicare se il valore non è specificato dall'HAL.

Non è obbligatorio che un singolo flag di build diventi una singola funzione in HIDL I proprietari dei moduli possono aggregare flag di build strettamente correlati uno struct e avere una funzione che lo restituisce (in questo modo si può ridurre di chiamate di funzione).

Ad esempio, un'opzione per aggregare due flag di build in un singolo struct tra hardware/interfaces/configstore/1.0/ISurfaceFlingerConfigs.hal è:

 interface ISurfaceFlingerConfigs {
    // other functions here
    struct SyncConfigs {
        OptionalInt64 vsyncEventPhaseoffsetNs;
        OptionalInt64 presentTimeoffsetFromSyncNs;
    };
    getSyncConfigs() generates (SyncConfigs ret);
    // other functions here
};

Alternative a una singola funzione HAL

In alternativa all'utilizzo di una singola funzione HAL per tutti i flag di build, fornisce anche funzioni semplici come getBoolean(string key) e getInteger(string key). L'effettivo key=value coppie sono archiviate in file separati e nel servizio HAL fornisce valori leggendo/analizzando questi file.

Sebbene questo approccio sia facile da definire, non include i vantaggi fornite da HIDL (controllo delle versioni applicato, facilità di documentazione, controllo degli accessi) pertanto non è consigliato.

Una o più interfacce

Il design dell'interfaccia HAL per gli elementi di configurazione presenta due scelte:

  • Un'unica interfaccia che copre tutti gli elementi di configurazione
  • Più interfacce, ciascuna delle quali copre un insieme di configurazioni correlate articoli

Una singola interfaccia è più semplice, ma può diventare non gestibile se vengono aggiunti al singolo file. Inoltre, il controllo dell'accesso non è granulare, quindi un processo a cui viene concesso l'accesso all'interfaccia può tutti gli elementi di configurazione (l'accesso a un insieme parziale di elementi di configurazione concesso). In alternativa, se l'accesso non viene concesso, gli elementi di configurazione lette.

A causa di questi problemi, Android utilizza più interfacce con un singolo HAL per un gruppo di elementi di configurazione correlati. Ad esempio: ISurfaceflingerConfigs per surfaceflinger correlati e IBluetoothConfigs per le impostazioni Bluetooth di configurazione.