Manejo de conexión 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, por ejemplo, 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 la conexión directa y las capacidades de visualización dinámica.

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

Actualiza las capacidades de visualización

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

Para que Android pueda controlar los cambios en las capacidades de pantalla de forma adecuada, el OEM debe implementar el HAL de Composer de modo que use onHotplug(display, connection=CONNECTED) para notificar al framework cualquier cambio en las capacidades de pantalla. Una vez que se implemente, Android controlará los cambios en las capacidades de pantalla de la siguiente manera:

  1. Cuando se detecta un cambio en las capacidades de pantalla, el framework recibe una notificación de 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 del HAL usando 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 están escuchando esos eventos.

El framework reasigna los búferes de fotogramas en los 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 y evitar errores durante la asignación de nuevos búferes de fotogramas.

Cómo controlar situaciones de conexión comunes

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

Dado que se creó para dispositivos móviles, el framework de Android no tiene compatibilidad integrada con una pantalla principal desconectada. En cambio, 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 se desconecte físicamente una pantalla principal.

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

Situación Manipulación
No hay una pantalla conectada durante el inicio
  • Envía un indicador onHotplug(display, connection=CONNECTED) desde la HAL del compositor al framework.
  • Reemplaza el estado de 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á desconectada físicamente
  • Envía otro evento onHotplug(display, connection=CONNECTED) desde la HAL de Composer al framework.
  • Reemplaza el estado de pantalla física dentro del HAL de Composer por un estado de pantalla de marcador de posición. La pantalla de marcador de posición debe tener un solo modo de visualización para que el framework envíe la devolución de llamada onDisplayChanged a las apps (porque cambió el conjunto de modos admitidos). Este modo de visualización único 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 la conexión que no es HDMI

Android TV solo admite las siguientes resoluciones:

  • 720 x 1280
  • 1080 x 1920
  • 2160 x 3840
  • 4320 x 7680

Cuando un dongle de TV o un STB intentan mostrar una resolución no admitida, como 480i a través de una conexión CVBS, se le presenta al usuario un mensaje de error.

Si el STB o el adaptador para 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 no HDMI sigue activa, se envía un evento a SurfaceFlinger y las capacidades de la pantalla no 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 admitidas 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 y, luego, se brindan detalles para implementar el HAL de Composer de modo que use IDs secuenciales para 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 provoca una condición de carrera:

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

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

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

    • id=1, 2160 x 3840, 60 Hz
    • id=2, 2160 x 3840, 50 Hz
    • id=3, 1080 x 1920 a 60 Hz
    • id=4, 1080 x 1920, 50 Hz
  4. El 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. El 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 la HAL de Composer para que use IDs secuenciales

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

  • Cuando el HAL de Composer actualiza las configuraciones de pantalla admitidas, asigna IDs nuevos y 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.

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

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

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

  3. Cuando se procesa un cambio en las configuraciones de pantalla, el siguiente conjunto de IDs de configuración se asigna 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 a 60 Hz

    • id=6, 1080 x 1920, 50 Hz

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

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

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

  7. El framework recibe y procesa el evento onHotplug del paso 4. Llama al HAL de Composer con 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 1,080 x 1,920 y 60 Hz.

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

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

  10. El 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 evite la condición de carrera y que se actualice el cambio de configuración de pantalla correcto.