Google se compromete a impulsar la igualdad racial para las comunidades afrodescendientes. Obtén información al respecto.
Se usó la API de Cloud Translation para traducir esta página.
Switch to English

Creación de la interfaz HAL

Debe usar HIDL para describir todos los indicadores de compilación utilizados para compilar condicionalmente el marco. Los indicadores de compilación relevantes deben agruparse e incluirse en un solo archivo .hal . El uso de HIDL para especificar elementos de configuración incluye los siguientes beneficios:

  • Con versión (para agregar nuevos elementos de configuración, los proveedores / OEM deben extender explícitamente la HAL)
  • Bien documentada
  • Control de acceso mediante SELinux
  • Verificación de cordura para los elementos de configuración a través de Vendor Test Suite (verificación de rango, verificación de interdependencia entre elementos, etc.)
  • API generadas automáticamente en C ++ y Java

Identificación de marcas de compilación utilizadas por el marco

Comience por identificar las configuraciones de compilación utilizadas para compilar condicionalmente el marco, luego abandone las configuraciones obsoletas para hacer el conjunto más pequeño. Por ejemplo, el siguiente conjunto de surfaceflinger de compilación se identifica para 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

Crear una interfaz HAL

Se accede a las configuraciones de compilación para un subsistema a través de una interfaz HAL, mientras que las interfaces para proporcionar valores de configuración se agrupan en el paquete HAL android.hardware.configstore (actualmente en la versión 1.0). Por ejemplo, para crear un archivo de interfaz HAL para surfaceflinger , en hardware/interfaces/configstore/1.0/ISurfaceFlingerConfigs.hal :

package android.hardware.configstore@1.0;

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

Después de crear el archivo .hal , ejecute hardware/interfaces/update-makefiles.sh para agregar el nuevo archivo .hal a los archivos Android.bp y Android.mk .

Agregar funciones para construir banderas

Para cada marca de compilación, agregue una nueva función a la interfaz. Por ejemplo, en 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);
};

Al agregar una función:

  • Sea conciso con los nombres. Evite convertir los nombres de las variables makefile en nombres de funciones y tenga en cuenta que los prefijos TARGET_ y BOARD_ ya no son necesarios.
  • Añadir comentarios. Ayude a los desarrolladores a comprender el propósito del elemento de configuración, cómo cambia el comportamiento del marco, los valores válidos y otra información relevante.

Los tipos de retorno de función pueden ser Optional[Bool|String|Int32|UInt32|Int64|UInt64] . Los tipos se definen en types.hal en el mismo directorio y envuelven los valores primitivos con un campo que indica si el valor está especificado por HAL; si no, se utiliza el valor predeterminado.

struct OptionalString {
    bool specified;
    string value;
};

Cuando sea apropiado, defina la enumeración que mejor represente el tipo de elemento de configuración y use esa enumeración como el tipo de retorno. En el ejemplo anterior, la enumeración NumBuffers se define para limitar el número de valores válidos. Al definir tales tipos de datos personalizados, agregue un campo o un valor de enumeración (por ejemplo, USE_DEFAULT ) para indicar si el valor está / no especificado por HAL.

No es obligatorio que un solo indicador de compilación se convierta en una sola función en HIDL. Los propietarios de módulos pueden agregar alternativamente indicadores de compilación estrechamente relacionados en una estructura y tener una función que devuelva esa estructura (hacerlo puede reducir el número de llamadas a funciones).

Por ejemplo, una opción para agregar dos hardware/interfaces/configstore/1.0/ISurfaceFlingerConfigs.hal compilación en una sola estructura en hardware/interfaces/configstore/1.0/ISurfaceFlingerConfigs.hal es:

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

Alternativas a una sola función HAL

Como alternativa al uso de una única función HAL para todos los indicadores de compilación, la interfaz HAL también proporciona funciones simples como getBoolean(string key) y getInteger(string key) . Los pares key=value reales se almacenan en archivos separados y el servicio HAL proporciona valores al leer / analizar esos archivos.

Si bien este enfoque es fácil de definir, no incluye los beneficios proporcionados por HIDL (control de versiones forzado, facilidad de documentación, control de acceso) y, por lo tanto, no se recomienda.

Interfaces únicas y múltiples

El diseño de la interfaz HAL para elementos de configuración presenta dos opciones:

  • Una única interfaz que cubre todos los elementos de configuración
  • Varias interfaces, cada una de las cuales cubre un conjunto de elementos de configuración relacionados

Una interfaz única es más fácil, pero puede volverse inmaterial a medida que se agregan más elementos de configuración al archivo único. Además, el control de acceso no es detallado, por lo que un proceso al que se le otorga acceso a la interfaz puede leer todos los elementos de configuración (no se puede otorgar acceso a un conjunto parcial de elementos de configuración). Alternativamente, si no se otorga acceso, los elementos de configuración no se pueden leer.

Debido a estos problemas, Android usa varias interfaces con una única interfaz HAL para un grupo de elementos de configuración relacionados. Por ejemplo, ISurfaceflingerConfigs para surfaceflinger configuración relacionados con IBluetoothConfigs e IBluetoothConfigs para elementos de configuración relacionados con Bluetooth.