Gestion des hotplugs

Les fonctionnalités d'affichage (telles que les modes d'affichage et les types HDR compatibles) peuvent changer de manière dynamique sur les appareils dotés d'un écran connecté en externe (avec HDMI ou DisplayPort), tels que les boîtiers décodeurs Android TV et les appareils de distribution par contournement (OTT, over-the-top). Cette modification peut se produire à la suite d'un signal de prise électrique HDMI, par exemple lorsque l'utilisateur passe d'un écran à un autre ou démarre l'appareil sans écran connecté. Android 12 et les versions ultérieures incluent des modifications dans le framework pour gérer le plug-in à chaud et les fonctionnalités d'affichage dynamique.

Cette page décrit la gestion des plug-ins d'affichage et des modifications apportées aux fonctionnalités d'affichage dans la mise en œuvre HAL de Composer. Il explique également comment gérer le framebuffer associé et empêcher les conditions de concurrence dans ces situations.

.

Mettre à jour les fonctionnalités d'affichage

Cette section décrit comment le framework Android gère les modifications des fonctionnalités d'affichage initiées par l'HAL Composer.

Pour qu'Android puisse gérer correctement les modifications des fonctionnalités d'affichage, l'OEM doit implémenter l'HAL Composer de sorte qu'il utilise onHotplug(display, connection=CONNECTED) pour signaler au framework toute modification des fonctionnalités d'affichage. Une fois cela implémenté, Android gère les modifications apportées aux fonctionnalités d'affichage comme suit:

  1. Lorsqu'il détecte une modification des fonctionnalités d'affichage, le framework reçoit une notification onHotplug(display, connection=CONNECTED).
  2. À la réception de la notification, le framework supprime son état d'affichage et le recrée avec les nouvelles fonctionnalités du HAL à l'aide des méthodes getActiveConfig, getDisplayConfigs, getDisplayAttribute, getColorModes, getHdrCapabilities et getDisplayCapabilities.
  3. Une fois que le framework a recréé un nouvel état d'affichage, il envoie le rappel onDisplayChanged aux applications qui écoutent de tels événements.

Le framework réalloue les tampons de frames lors des événements onHotplug(display, connection=CONNECTED) suivants. Consultez la section Gestion des tampons de frames client pour savoir comment gérer correctement la mémoire du tampon de frame afin d'éviter les échecs lors de l'allocation de nouveaux tampons de frames.

Gérer les scénarios de connexion courants

Cette section explique comment gérer correctement différents scénarios de connexion dans vos mises en œuvre lorsque l'écran principal est connecté et déconnecté.

Ayant été conçu pour les appareils mobiles, le framework Android n'est pas compatible avec un écran principal déconnecté. Au lieu de cela, le HAL doit remplacer l'écran principal par un écran d'espace réservé dans ses interactions avec le framework au cas où un écran principal serait déconnecté physiquement.

Les scénarios suivants peuvent se produire dans les STB et les dongles TV dotés d'écrans connectés en externe qui peuvent être déconnectés. Pour prendre en charge ces scénarios, utilisez les informations du tableau ci-dessous:

Scénario Manipulation
Aucun écran connecté au démarrage
  • Envoyer un signal onHotplug(display, connection=CONNECTED) à partir du HAL de Composer vers le framework.
  • Remplacez l'état d'affichage physique dans le HAL de Composer par un état d'affichage d'espace réservé.
L'écran principal est connecté physiquement
L'écran principal est déconnecté physiquement
  • Envoyez un autre événement onHotplug(display, connection=CONNECTED) du HAL de Composer au framework.
  • Remplacez l'état d'affichage physique dans le HAL de Composer par un état d'affichage d'espace réservé. L'affichage de l'espace réservé doit avoir un seul mode d'affichage, afin que le framework envoie le rappel onDisplayChanged aux applications (car l'ensemble des modes compatibles a changé). Ce mode d'affichage unique doit correspondre au dernier mode actif de l'écran physique avant la déconnexion, afin que les applications ne reçoivent pas d'événements de modification de la configuration.

Remarques concernant les connexions non-HDMI

Android TV n'est compatible qu'avec les résolutions suivantes:

  • 720x1280
  • 1080x1920
  • 2160x3840
  • 4320x7680

Lorsqu'un décodeur TV ou un dongle TV tente d'afficher une résolution non compatible, telle que 480i via une connexion CVBS, un message d'erreur s'affiche.

Si le STB ou le dongle TV dispose à la fois de connexions HDMI et non HDMI, la connexion HDMI est l'écran principal et la connexion non HDMI est inactive. Par conséquent, si la connexion HDMI est déconnectée alors que la connexion non HDMI est toujours connectée, un événement est envoyé à SurfaceFlinger, et les fonctionnalités de l'écran non HDMI doivent être reflétées via getDisplayAttribute et d'autres API iComposerClient (telles que getHdrCapabilities).

Utiliser des ID de configuration séquentiels pour empêcher les conditions de concurrence

Des conditions de concurrence peuvent se produire si le HAL de Composer met à jour les configurations d'affichage compatibles en même temps que le framework qui appelle setActiveConfig ou setActiveConfigWithConstraints. La solution consiste à implémenter le HAL de Composer pour utiliser des ID séquentiels et éviter ce problème.

Cette section décrit comment les conditions de concurrence peuvent se produire, puis décrit comment implémenter la HAL dans Composer afin d'utiliser des ID séquentiels pour éviter de telles conditions.

Considérez la séquence d'événements suivante, lorsque de nouveaux ID séquentiels ne sont PAS attribués aux nouvelles configurations d'affichage, ce qui entraîne une condition de concurrence:

  1. Les ID de configuration d'affichage acceptés sont les suivants:

    • id=1, 1 080 x 1 920, 60 Hz
    • id=2, 1 080 x 1 920, 50 Hz
  2. Le framework appelle setActiveConfig(display, config=1).

  3. Simultanément, le HAL de Composer traite une modification des configurations d'affichage et met à jour son état interne vers un nouvel ensemble de configurations d'affichage, comme suit:

    • id=1, 2 160 x 3 840, 60 Hz
    • id=2, 2 160 x 3 840, 50 Hz
    • id=3, 1 080 x 1 920, 60 Hz
    • id=4, 1 080 x 1 920, 50 Hz
  4. L'HAL de Composer envoie un événement onHotplug au framework pour avertir que l'ensemble des modes compatibles a été modifié.

  5. Le HAL de Composer reçoit des setActiveConfig(display, config=1) (de l'étape 2).

  6. Le HAL interprète que le framework a demandé une modification de configuration vers 2 160 x 3 840 60 Hz, alors qu'en réalité, 1 080 x 1 920 60 Hz était souhaité.

Le processus d'attribution d'ID non séquentielle se termine ici par une mauvaise interprétation de la modification de configuration souhaitée.

Configurer l'HAL de Composer pour utiliser des ID séquentiels

Pour éviter de telles conditions de concurrence, l'OEM doit implémenter le HAL Composer comme suit:

  • Lorsque le HAL de Composer met à jour les configurations d'affichage compatibles, il attribue de nouveaux ID séquentiels aux nouvelles configurations d'affichage.
  • Lorsque le framework appelle setActiveConfig ou setActiveConfigWithConstraints avec un ID de configuration non valide, le HAL de Composer ignore l'appel.

Ces étapes servent à éviter les conditions de concurrence, comme indiqué dans la discussion suivante.

Considérez la séquence d'événements suivante, lorsque de nouveaux ID séquentiels sont attribués aux nouvelles configurations d'affichage:

  1. Les ID de configuration d'affichage acceptés sont les suivants:

    • id=1, 1 080 x 1 920, 60 Hz
    • id=2, 1 080 x 1 920, 50 Hz
  2. Le framework appelle setActiveConfig(display, config=1).

  3. Lorsqu'une modification des configurations d'affichage est traitée, l'ensemble suivant d'ID de configuration est attribué à partir du prochain entier inutilisé, comme indiqué ci-dessous:

    • id=3, 2 160 x 3 840, 60 Hz

    • id=4, 2 160 x 3 840, 50 Hz

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

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

  4. Le HAL de Composer envoie un événement onHotplug au framework pour avertir que l'ensemble des modes compatibles a été modifié.

  5. Le HAL de Composer reçoit des setActiveConfig(display, config=1) (de l'étape 2).

  6. Le HAL de Composer ignore l'appel, car l'ID n'est plus valide.

  7. Le framework reçoit et traite l'événement onHotplug de l'étape 4. Elle appelle le HAL de Composer à l'aide des fonctions getDisplayConfigs et getDisplayAttribute. Avec ces fonctions, le framework identifie le nouvel identifiant (5) pour la résolution et la fréquence d'actualisation souhaitées de 1 080 x 1 920 et 60 Hz.

  8. Le framework envoie un autre événement setActiveConfig avec un ID mis à jour de 5.

  9. Le HAL de Composer reçoit des setActiveConfig(display, config=5) de l'étape 5.

  10. Le HAL interprète correctement que le framework a demandé une modification de configuration vers 1 080 x 1 920 60 Hz.

Comme le montre l'exemple ci-dessus, le processus utilisant des attributions d'ID séquentielles garantit que la condition de concurrence est évitée et que la modification correcte de la configuration d'affichage est mise à jour.