Hot-Plug-Verwaltung

Displayfunktionen wie Displaymodi und unterstützte HDR-Typen können sich auf Geräten mit extern angeschlossenen Displays (über HDMI oder DisplayPort) dynamisch ändern, z. B. auf Android TV-Set-Top-Boxen (STBs) und Over-the-Top-Geräten (OTT). Diese Änderung kann durch ein HDMI-Hotplug-Signal verursacht werden, z. B. wenn der Nutzer von einem Display zu einem anderen wechselt oder das Gerät ohne angeschlossenes Display startet. Android 12 und höher enthalten Änderungen am Framework, um Hotplugging und dynamische Displayfunktionen zu verarbeiten.

Auf dieser Seite wird die Verarbeitung von Hotplugs für Displays und Änderungen an den Displayfunktionen in der HAL-Implementierung von Composer beschrieben. Außerdem wird beschrieben, wie Sie den zugehörigen Framebuffer verwalten und in diesen Situationen Race-Bedingungen verhindern.

Displayfunktionen aktualisieren

In diesem Abschnitt wird beschrieben, wie das Android-Framework Änderungen an den Displayfunktionen verarbeitet, die von der Composer HAL initiiert wurden.

Damit Android Änderungen an den Displayfunktionen richtig verarbeiten kann, muss der OEM die Composer HAL so implementieren, dass das Framework über onHotplug(display, connection=CONNECTED) über alle Änderungen an den Displayfunktionen informiert wird. Nach der Implementierung werden Änderungen an den Displayfunktionen von Android so verarbeitet:

  1. Wenn eine Änderung der Anzeigefunktionen erkannt wird, erhält das Framework eine onHotplug(display, connection=CONNECTED)-Benachrichtigung.
  2. Wenn das Framework die Benachrichtigung erhält, setzt es den Displaystatus zurück und erstellt ihn mit den neuen Funktionen der HAL neu. Dazu werden die Methoden getActiveConfig, getDisplayConfigs, getDisplayAttribute, getColorModes, getHdrCapabilities und getDisplayCapabilities verwendet.
  3. Nachdem das Framework einen neuen Displaystatus erstellt hat, sendet es den onDisplayChanged-Callback an die Apps, die auf solche Ereignisse warten.

Das Framework weist die Framebuffer bei nachfolgenden onHotplug(display, connection=CONNECTED)-Ereignissen neu zu. Weitere Informationen zur ordnungsgemäßen Verwaltung des Framebuffer-Speichers, um Fehler bei der Zuweisung neuer Framebuffer zu vermeiden, finden Sie unter Client-Framebuffer-Verwaltung.

Umgang mit häufigen Verbindungsszenarien

In diesem Abschnitt erfahren Sie, wie Sie verschiedene Verbindungsszenarien in Ihren Implementierungen richtig behandeln, wenn das primäre Display verbunden und getrennt ist.

Da das Android-Framework für Mobilgeräte entwickelt wurde, unterstützt es kein getrenntes primäres Display. Stattdessen muss die HAL das primäre Display bei Interaktionen mit dem Framework durch ein Platzhalterdisplay ersetzen, wenn ein primäres Display physisch getrennt ist.

Die folgenden Szenarien können bei Set-Top-Boxen und TV-Dongles auftreten, die extern angeschlossene Displays haben, die getrennt werden können. Verwenden Sie die Informationen in der folgenden Tabelle, um Unterstützung für diese Szenarien zu implementieren:

Szenario Handhabung
Kein angeschlossener Bildschirm beim Starten
  • Senden Sie ein onHotplug(display, connection=CONNECTED)-Signal von der Composer HAL an das Framework.
  • Ersetzen Sie den physischen Displaystatus in der Composer HAL durch einen Platzhalter-Displaystatus.
Primäres Display ist physisch verbunden
Das primäre Display ist physisch getrennt
  • Senden Sie ein weiteres onHotplug(display, connection=CONNECTED)-Ereignis von der Composer HAL an das Framework.
  • Ersetzen Sie den physischen Displaystatus in der Composer HAL durch einen Platzhalter-Displaystatus. Das Platzhalter-Display muss einen einzelnen Anzeigemodus haben, damit das Framework den onDisplayChanged-Callback an die Apps sendet, weil sich die unterstützten Modi geändert haben. Dieser Modus für ein einzelnes Display muss mit dem zuletzt aktiven Modus des physischen Displays vor der Trennung übereinstimmen, damit Apps keine Ereignisse zur Konfigurationsänderung erhalten.

Nicht HDMI-Verbindungen

Android TV unterstützt nur die folgenden Auflösungen:

  • 720 x 1280
  • 1.080 × 1.920
  • 2160 × 3840
  • 4320 × 7680

Wenn ein STB oder TV-Dongle versucht, eine nicht unterstützte Auflösung wie 480i über eine CVBS-Verbindung anzuzeigen, wird dem Nutzer eine Fehlermeldung angezeigt.

Wenn der STB oder TV-Dongle sowohl HDMI- als auch andere Anschlüsse hat, ist die HDMI-Verbindung das primäre Display und die andere Verbindung inaktiv. Wenn also die HDMI-Verbindung getrennt wird, während die andere Verbindung noch verbunden ist, wird ein Ereignis an SurfaceFlinger gesendet und die Funktionen des anderen Displays müssen über getDisplayAttribute und andere iComposerClient APIs (z. B. getHdrCapabilities) berücksichtigt werden.

Sequenzielle Konfigurations-IDs verwenden, um Race-Bedingungen zu verhindern

Race-Bedingungen können auftreten, wenn die Composer HAL die unterstützten Displaykonfigurationen gleichzeitig mit dem Framework aktualisiert, das setActiveConfig oder setActiveConfigWithConstraints aufruft. Die Lösung besteht darin, Composer HAL zu implementieren, um sequenzielle IDs zu verwenden und dieses Problem zu vermeiden.

In diesem Abschnitt wird beschrieben, wie es zu Race-Bedingungen kommen kann. Anschließend folgen Details dazu, wie Sie Composer HAL so implementieren, dass solche Bedingungen mithilfe von sequenziellen IDs verhindert werden.

Betrachten Sie die folgende Abfolge von Ereignissen, wenn den neuen Anzeigenkonfigurationen KEINE neuen, sequenziellen IDs zugewiesen werden, was zu einer Race-Condition führt:

  1. Folgende Displaykonfigurations-IDs werden unterstützt:

    • id=1, 1080 × 1920, 60 Hz
    • id=2, 1080 × 1920, 50 Hz
  2. Das Framework ruft setActiveConfig(display, config=1) auf.

  3. Gleichzeitig verarbeitet die Composer HAL eine Änderung der Displaykonfigurationen und aktualisiert ihren internen Status auf eine neue Gruppe von Displaykonfigurationen, wie hier dargestellt:

    • id=1, 2160 x 3840, 60 Hz
    • id=2, 2160 × 3840, 50 Hz
    • id=3, 1080 x 1920, 60 Hz
    • id=4, 1080 × 1920, 50 Hz
  4. Composer HAL sendet ein onHotplug-Ereignis an das Framework, um zu informieren, dass sich die unterstützten Modi geändert haben.

  5. Die Composer HAL empfängt setActiveConfig(display, config=1) (aus Schritt 2).

  6. Die HAL interpretiert, dass das Framework eine Konfigurationsänderung auf 2160 × 3840 60 Hz angefordert hat, obwohl in Wirklichkeit 1080 × 1920 60 Hz gewünscht war.

Der Prozess mit nicht sequenziellen ID-Zuweisungen endet hier mit einer Fehlinterpretation der gewünschten Konfigurationsänderung.

Composer HAL für die Verwendung von sequenziellen IDs konfigurieren

Um solche Race-Bedingungen zu vermeiden, muss der OEM die Composer HAL so implementieren:

  • Wenn die Composer HAL die unterstützten Displaykonfigurationen aktualisiert, werden den neuen Displaykonfigurationen neue, fortlaufende IDs zugewiesen.
  • Wenn das Framework setActiveConfig oder setActiveConfigWithConstraints mit einer ungültigen Konfigurations-ID aufruft, wird der Aufruf von der Composer HAL ignoriert.

Diese Schritte dienen dazu, Race-Bedingungen zu verhindern, wie in der folgenden Diskussion gezeigt.

Angenommen, den neuen Anzeigenkonfigurationen werden neue, fortlaufende IDs zugewiesen. Hier ist die Abfolge der Ereignisse:

  1. Folgende Displaykonfigurations-IDs werden unterstützt:

    • id=1, 1080 × 1920, 60 Hz
    • id=2, 1080 × 1920, 50 Hz
  2. Das Framework ruft setActiveConfig(display, config=1) auf.

  3. Wenn eine Änderung der Anzeigekonfigurationen verarbeitet wird, werden die nächsten Konfigurations-IDs ab der nächsten nicht verwendeten Ganzzahl zugewiesen. Das sieht so aus:

    • id=3, 2160 × 3840, 60 Hz

    • id=4, 2160 × 3840, 50 Hz

    • id=5, 1080 × 1920, 60 Hz

    • id=6, 1080 × 1920, 50 Hz

  4. Die Composer HAL sendet ein onHotplug-Ereignis an das Framework, um zu informieren, dass sich die unterstützten Modi geändert haben.

  5. Die Composer HAL empfängt setActiveConfig(display, config=1) (aus Schritt 2).

  6. Der Composer HAL ignoriert den Aufruf, da die ID nicht mehr gültig ist.

  7. Das Framework empfängt und verarbeitet das onHotplug-Ereignis aus Schritt 4. Er ruft die Composer HAL mit den Funktionen getDisplayConfigs und getDisplayAttribute auf. Mit diesen Funktionen identifiziert das Framework die neue ID (5) für die gewünschte Auflösung und Bildwiederholrate von 1080 × 1920 und 60 Hz.

  8. Das Framework sendet ein weiteres setActiveConfig-Ereignis mit der aktualisierten ID 5.

  9. Die Composer HAL empfängt setActiveConfig(display, config=5) aus Schritt 5.

  10. Die HAL interpretiert richtig, dass das Framework eine Konfigurationsänderung auf 1080 × 1920 60 Hz angefordert hat.

Wie im Beispiel oben gezeigt, wird durch den Prozess mit sequenziellen ID-Zuweisungen verhindert, dass es zu einer Race-Bedingung kommt, und die richtige Änderung der Anzeigekonfiguration wird aktualisiert.