Manejo de conexiones en caliente

Las capacidades de visualización (como los modos de visualización y los tipos de HDR compatibles) pueden cambiar dinámicamente en dispositivos que tienen pantallas conectadas de forma externa (con HDMI o DisplayPort), como decodificadores de Android TV (STB) y dispositivos de transmisión libre (OTT). Este cambio puede ocurrir como resultado de una señal de conexión en caliente HDMI, como cuando el usuario cambia de una pantalla a otra o inicia el dispositivo sin una pantalla conectada. Android 12 y versiones posteriores incluyen cambios en el framework para controlar las capacidades de conexión directa y visualización dinámica.

En esta página, se describe el manejo de las conexiones directas de la pantalla y los cambios en las capacidades de la pantalla en la implementación de HAL de Composer. Además, se explica cómo administrar el búfer de fotogramas asociado y evitar las condiciones de carrera en estas situaciones.

Actualiza las capacidades de la pantalla

En esta sección, se describe cómo el framework de Android controla los cambios en las capacidades de visualización que inicia el HAL de Composer.

Antes de que Android pueda controlar los cambios en las capacidades de visualización de forma correcta, el OEM debe implementar el HAL de Composer de modo que use onHotplug(display, connection=CONNECTED) para notificar al framework sobre cualquier cambio en las capacidades de visualización. Después de que se implemente, Android controla los cambios en las capacidades de visualización de la siguiente manera:

  1. Cuando se detecta un cambio en las capacidades de visualización, el framework recibe una notificación onHotplug(display, connection=CONNECTED).
  2. Cuando recibe la notificación, el framework descarta su estado de visualización y lo recrea con las nuevas funciones del HAL mediante los métodos getActiveConfig, getDisplayConfigs, getDisplayAttribute, getColorModes, getHdrCapabilities y getDisplayCapabilities.
  3. Después de que el framework recrea un nuevo estado de visualización, envía la devolución de llamada onDisplayChanged a las apps que escuchan esos eventos.

El framework reasignará los búferes de trama en eventos onHotplug(display, connection=CONNECTED) posteriores. Consulta Administración del búfer de fotogramas del cliente para obtener más información sobre cómo administrar correctamente la memoria del búfer de fotogramas para evitar fallas durante la asignación de búferes de fotogramas nuevos.

Cómo controlar situaciones de conexión comunes

En esta sección, se explica cómo controlar correctamente varias situaciones de conexión en tus implementaciones cuando la pantalla principal está conectada y desconectada.

Como se compiló para dispositivos móviles, el framework de Android no tiene compatibilidad integrada con una pantalla principal desconectada. En su lugar, el HAL debe reemplazar la pantalla principal por una pantalla de marcador de posición en sus interacciones con el framework en el caso de que una pantalla principal esté desconectada físicamente.

Las siguientes situaciones pueden ocurrir en llaves de TV y STB que tienen pantallas conectadas de forma externa que se pueden desconectar. Para implementar la compatibilidad en estas situaciones, usa la información de la siguiente tabla:

Situación Manipulación
No hay pantalla conectada durante el inicio
  • Envía un indicador onHotplug(display, connection=CONNECTED) desde la HAL de Composer al framework.
  • Reemplaza el estado de la pantalla física dentro del HAL de Composer por un estado de pantalla de marcador de posición.
La pantalla principal está conectada físicamente
La pantalla principal está físicamente desconectada
  • Envía otro evento onHotplug(display, connection=CONNECTED) desde la HAL del compositor al framework.
  • Reemplaza el estado de la pantalla física dentro del HAL de Composer por un estado de pantalla de marcador de posición. La pantalla del marcador de posición debe tener un solo modo de visualización, de modo que el framework envíe la devolución de llamada onDisplayChanged a las apps (porque cambió el conjunto de modos compatibles). Este modo de pantalla única debe coincidir con el último modo activo de la pantalla física antes de la desconexión, de modo que las apps no reciban eventos de cambio de configuración.

Consideraciones sobre las conexiones que no son HDMI

Android TV solo admite las siguientes resoluciones:

  • 720 × 1280
  • 1080 × 1920
  • 2,160 × 3,840
  • 4320 × 7680

Cuando una llave de STB o TV intenta mostrar una resolución no compatible, como 480i con una conexión CVBS, se muestra un mensaje de error al usuario.

Si el decodificador o la llave de TV tienen conexiones HDMI y no HDMI, la conexión HDMI es la pantalla principal y la conexión no HDMI está inactiva. Como resultado, si se desconecta la conexión HDMI mientras la conexión que no es HDMI sigue conectada, se envía un evento a SurfaceFlinger y las capacidades de la pantalla que no es HDMI deben reflejarse a través de getDisplayAttribute y otras APIs de iComposerClient (como getHdrCapabilities).

Usa IDs de configuración secuenciales para evitar condiciones de carrera

Pueden surgir condiciones de carrera si el HAL de Composer actualiza las configuraciones de pantalla compatibles de forma simultánea con el framework que llama a setActiveConfig o setActiveConfigWithConstraints. La solución es implementar el HAL de Composer para usar IDs secuenciales y evitar este problema.

En esta sección, se describe cómo pueden ocurrir las condiciones de carrera, seguidas de detalles sobre cómo implementar el HAL de Composer para que use IDs secuenciales y evite esas condiciones.

Considera la siguiente secuencia de eventos, cuando los IDs secuenciales nuevos NO se asignan a las nuevas configuraciones de visualización, lo que genera una condición de carrera:

  1. Los IDs de configuración de la pantalla admitidos son los siguientes:

    • id=1, 1,080 × 1,920, 60 Hz
    • id=2, 1080 × 1920, 50 Hz
  2. El framework llama a setActiveConfig(display, config=1).

  3. De manera simultánea, el HAL de Composer procesa un cambio de configuración de visualización y actualiza su estado interno a un nuevo conjunto de configuraciones de visualización, como se muestra a continuación:

    • id=1, 2160 x 3840 60 Hz
    • id=2, 2160 x 3840 50 Hz
    • id=3, 1080 × 1920, 60 Hz
    • id=4, 1080 × 1920 50 Hz
  4. El HAL de Composer envía un evento onHotplug al framework para notificar que cambió el conjunto de modos compatibles.

  5. El HAL de Composer recibe setActiveConfig(display, config=1) (del paso 2).

  6. El sistema HAL interpreta que el framework solicitó un cambio de configuración a 2160 x 3840 a 60 Hz, aunque en realidad se deseaba 1080 x 1920 a 60 Hz.

El proceso que usa asignaciones de ID no secuenciales termina aquí con una interpretación errónea del cambio de configuración deseado.

Configura el HAL de Composer para usar IDs secuenciales

Para evitar esas condiciones de carrera, el OEM debe implementar el HAL de Composer de la siguiente manera:

  • Cuando el HAL de Composer actualiza las configuraciones de pantalla compatibles, asigna nuevos IDs secuenciales a las nuevas configuraciones de pantalla.
  • Cuando el framework llama a setActiveConfig o setActiveConfigWithConstraints con un ID de configuración no válido, el HAL de Composer ignora la llamada.

Estos pasos sirven para evitar condiciones de carrera, como se muestra en el siguiente análisis.

Considera la siguiente secuencia de eventos cuando se asignan IDs secuenciales nuevos a los nuevos parámetros de configuración de pantalla:

  1. Los IDs de configuración de la pantalla admitidos son los siguientes:

    • id=1, 1,080 × 1,920, 60 Hz
    • id=2, 1080 × 1920, 50 Hz
  2. El framework llama a setActiveConfig(display, config=1).

  3. Cuando se procesa un cambio de configuración de visualización, se asigna el siguiente conjunto de IDs de configuración a partir del siguiente número entero sin usar, como se muestra a continuación:

    • id=3, 2160 x 3840 60 Hz

    • id=4, 2160 x 3840 50 Hz

    • id=5, 1080 × 1920 60 Hz

    • id=6, 1080 × 1920 50 Hz

  4. El HAL de Composer envía un evento onHotplug al framework para notificar que cambió el conjunto de modos compatibles.

  5. El HAL de Composer recibe setActiveConfig(display, config=1) (del paso 2).

  6. El HAL de Composer ignora la llamada porque el ID ya no es válido.

  7. El framework recibe y procesa el evento onHotplug del paso 4. Llama a la HAL de Composer mediante las funciones getDisplayConfigs y getDisplayAttribute. Con estas funciones, el framework identifica el nuevo ID (5) para la resolución y la frecuencia de actualización deseadas de 1080 x 1920 y 60 Hz.

  8. El framework envía otro evento setActiveConfig con un ID actualizado de 5.

  9. El HAL de Composer recibe setActiveConfig(display, config=5) del paso 5.

  10. El sistema HAL interpreta correctamente que el framework solicitó un cambio de configuración a 1080 x 1920 a 60 Hz.

Como se muestra en el ejemplo anterior, el proceso que usa asignaciones de ID secuenciales garantiza que se prevenga la condición de carrera y se actualice el cambio correcto en la configuración de visualización.