Manejo de conexiones en caliente

Las capacidades de visualización (como los modos de visualización y los tipos de HDR compatibles) pueden cambiar de forma dinámica 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 producirse 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 las versiones posteriores incluyen cambios en el framework para controlar las capacidades de conexión en caliente y pantalla dinámica.

En esta página, se describe el manejo de las conexiones en caliente de pantallas y los cambios en las capacidades de visualización en la implementación de la 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.

Cómo actualizar las capacidades de visualización

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

Antes de que Android pueda controlar correctamente los cambios en las capacidades de visualización, el OEM debe implementar la HAL de Composer de forma que use onHotplug(display, connection=CONNECTED) para notificar al framework sobre los cambios en las capacidades de visualización. Una vez implementado, 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 vuelve a crear con las nuevas capacidades de la HAL mediante los métodos getActiveConfig, getDisplayConfigs, getDisplayAttribute, getColorModes, getHdrCapabilities y getDisplayCapabilities.
  3. Después de que el framework recrea un nuevo estado de pantalla, envía la devolución de llamada onDisplayChanged a las apps que escuchan esos eventos.

El framework reasigna los búferes de fotogramas 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 manejar correctamente varias situaciones de conexión en tus implementaciones cuando la pantalla principal está conectada y desconectada.

El framework de Android se creó para dispositivos móviles y no tiene compatibilidad integrada con una pantalla principal desconectada. En cambio, la HAL debe reemplazar la pantalla principal por una pantalla de marcador de posición en sus interacciones con el framework en caso de que una pantalla principal se desconecte 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 una pantalla conectada en el momento del inicio
  • Envía una señal onHotplug(display, connection=CONNECTED) desde la HAL de Composer al framework.
  • Reemplaza el estado de visualización física dentro de la HAL de Composer por un estado de visualización de marcador de posición.
La pantalla principal está conectada físicamente
La pantalla principal está desconectada físicamente
  • Envía otro evento onHotplug(display, connection=CONNECTED) desde la HAL del compositor al framework.
  • Reemplaza el estado de visualización física dentro de la HAL de Composer por un estado de visualización 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, para que las apps no reciban eventos de cambio de configuración.

Consideraciones sobre conexiones sin HDMI

Android TV solo admite las siguientes resoluciones:

  • 720 × 1280
  • 1080 × 1920
  • 2,160 x 3,840
  • 4,320 x 7,680

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 adaptador de STB o TV tiene conexiones HDMI y no HDMI, la conexión HDMI es la pantalla principal y la conexión que no es HDMI estará inactiva. Como resultado, si la conexión HDMI se desconecta mientras la conexión no 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 la HAL de Composer actualiza los parámetros de configuración de pantalla compatibles de forma simultánea con el framework que llama a setActiveConfig o setActiveConfigWithConstraints. La solución es implementar la HAL de Composer para usar IDs secuenciales y evitar este problema.

En esta sección, se describe cómo podrían ocurrir las condiciones de carrera, seguido de detalles sobre cómo implementar la HAL de Composer para que use IDs secuenciales a fin de evitar esas condiciones.

Considera la siguiente secuencia de eventos cuando NO se asignan IDs secuenciales nuevos a los parámetros de configuración de pantalla nuevos, lo que causa una condición de carrera:

  1. Los IDs de configuración de visualización compatibles 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. Al mismo tiempo, la HAL de Composer procesa un cambio de configuración de pantalla y actualiza su estado interno a un nuevo conjunto de parámetros de configuración de pantalla, que se muestran de la siguiente manera:

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

  5. La HAL del compositor recibe setActiveConfig(display, config=1) (del paso 2).

  6. La HAL interpreta que el framework solicitó un cambio de configuración a 2160x3840 60 Hz, aunque, en realidad, se deseaba 1080x1920 60 Hz.

El proceso con asignaciones de ID no secuenciales finaliza aquí con una mala interpretación del cambio de configuración deseado.

Cómo configurar la HAL del compositor para que use IDs secuenciales

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

  • Cuando la HAL del Composer actualiza los parámetros de configuración de la pantalla compatibles, les asigna nuevos IDs secuenciales a los nuevos parámetros de configuración de pantalla.
  • Cuando el framework llama a setActiveConfig o setActiveConfigWithConstraints con un ID de configuración no válido, la 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 visualización compatibles 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 la configuración de la pantalla, el siguiente conjunto de IDs de configuración se asigna a partir del siguiente número entero sin utilizar, como se muestra a continuación:

    • id=3, 2160 x 3840, 60 Hz

    • id=4, 2160 x 3840, 50 Hz

    • id=5, 1,080 × 1,920, 60 Hz

    • id=6, 1,080 × 1,920, 50 Hz

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

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

  6. La HAL del compositor 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 una 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. La HAL de Composer recibe setActiveConfig(display, config=5) del paso 5.

  10. La HAL interpreta correctamente que el framework solicitó un cambio de configuración a 1,080 × 1,920, 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.