Cómo implementar la HAL USB

La versión de Android 8.0 traslada el control de los comandos USB de las secuencias de comandos init a un daemon USB nativo para mejorar la configuración y la confiabilidad del código. Para la configuración de la función de gadget, se usan secuencias de comandos init (activadores de propiedades) para realizar operaciones de gadgets específicas del dispositivo.

En versiones anteriores, estas configuraciones específicas del dispositivo se lograban a través de secuencias de comandos init específicas del dispositivo (con activadores de propiedades). El cambio a un diseño de capa de abstracción de hardware (HAL) da como resultado una implementación mucho más limpia que resuelve estos problemas:

  1. Las operaciones, como las escrituras en los nodos sysfs del kernel, podrían fallar, pero no propagarse al código de los frameworks que establece el activador de la propiedad. Como resultado, los frameworks suponen de forma incorrecta que las operaciones se realizaron correctamente, a pesar de que fallaron de forma silenciosa.
  2. Las secuencias de comandos init tienen una cantidad limitada de operaciones que pueden ejecutarse.

La versión de Android 12 agrega compatibilidad con la HAL de dispositivos USB para los modelos de control de red (NCM) y las llamadas a la API que muestran el número de versión de la HAL y la velocidad del USB. Para obtener más información sobre las llamadas a la API disponibles a través del HAL de USB, consulta el resumen del paquete android.hardware.usb.

HAL y Treble

Las secuencias de comandos init específicas del dispositivo se usaron como sustitución de las capas de HAL para realizar operaciones USB específicas del dispositivo. USB (a través de ADB) es una interfaz principal para depurar problemas del sistema. Tener un daemon nativo para realizar la configuración USB elimina la dependencia del código del framework, de modo que, incluso si el framework falla, el USB debería estar en ejecución.

En el modelo de Treble que también se introdujo en Android 8.0, todos los HAL están aislados de los servicios del sistema y deben ejecutarse en sus propios daemons nativos. De esta manera, se elimina el requisito de tener un daemon USB exclusivo, ya que la capa de HAL también funciona como un daemon USB.

La implementación predeterminada de HAL se encarga de todos los dispositivos anteriores a Android 8.0. Por lo tanto, no habría ningún trabajo específico del dispositivo para los dispositivos anteriores a Android 8.0. Android 8.0 usa la interfaz de HAL para consultar el estado de los puertos USB y realizar intercambios de roles de datos y de energía.

Implementación

Se debe implementar la nueva interfaz de HAL de USB en todos los dispositivos que se lancen con Android 8.0. La implementación predeterminada debe controlar los dispositivos anteriores a Android 8.0. La implementación predeterminada es suficiente si el dispositivo usa la clase dual_role_usb para informar el estado del puerto tipo C. Es posible que se requieran cambios triviales en las secuencias de comandos USB específicas del dispositivo para transferir la propiedad de los nodos typc-c al sistema.