Hot-Plug-Verwaltung

Die Displayfunktionen (z. B. Anzeigemodi und unterstützte HDR-Typen) können sich auf Geräten mit extern angeschlossenen Displays (über HDMI oder DisplayPort), z. B. Android TV-Set-Top-Boxen (STBs) und Over-the-Top-Geräten (OTT), dynamisch ändern. Diese Änderung kann durch ein HDMI-Hotplug-Signal ausgelöst 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 im Framework für Hotplugging und dynamische Displayfunktionen.

Auf dieser Seite wird die Verarbeitung von Display-Hotplugs und Änderungen der Displayfunktionen in der Composer HAL-Implementierung beschrieben. Außerdem wird erläutert, wie der zugehörige Framebuffer verwaltet und Race-Bedingungen in diesen Situationen verhindert werden können.

Anzeigefunktionen aktualisieren

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

Damit Android Änderungen an den Displayfunktionen richtig verarbeiten kann, muss der OEM den Composer HAL so implementieren, dass er onHotplug(display, connection=CONNECTED) verwendet, um das Framework über Änderungen an den Displayfunktionen zu informieren. Danach werden Änderungen an den Displayfunktionen unter Android so behandelt:

  1. Wenn eine Änderung der Anzeigefunktionen erkannt wird, erhält das Framework eine onHotplug(display, connection=CONNECTED)-Benachrichtigung.
  2. Nach Erhalt der Benachrichtigung löscht das Framework den Anzeigestatus und erstellt ihn mit den neuen Funktionen aus der HAL neu. Dazu werden die Methoden getActiveConfig, getDisplayConfigs, getDisplayAttribute, getColorModes, getHdrCapabilities und getDisplayCapabilities verwendet.
  3. Nachdem das Framework einen neuen Anzeigestatus erstellt hat, wird der onDisplayChanged-Callback an die Apps gesendet, die auf solche Ereignisse warten.

Das Framework weist die Framebuffer bei nachfolgenden onHotplug(display, connection=CONNECTED)-Ereignissen neu zu. Weitere Informationen zum richtigen Verwalten des Framebuffer-Arbeitsspeichers, um Fehler bei der Zuweisung neuer Framebuffer zu vermeiden, finden Sie unter Client-Framebuffer-Verwaltung.

Häufige Verbindungsszenarien verarbeiten

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

Das Android-Framework wurde für Mobilgeräte entwickelt und bietet daher keine integrierte Unterstützung für einen getrennten primären Bildschirm. Stattdessen muss das HAL das primäre Display durch ein Platzhalterdisplay ersetzen, wenn es mit dem Framework interagiert und das primäre Display physisch getrennt ist.

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

Szenario Handhabung
Beim Starten ist kein Display angeschlossen
  • Senden Sie ein onHotplug(display, connection=CONNECTED)-Signal vom Composer HAL an das Framework.
  • Ersetzen Sie den physischen Displaystatus im Composer-HAL durch einen Platzhalter-Displaystatus.
Der primäre Bildschirm ist physisch verbunden
Der primäre Bildschirm ist physisch getrennt
  • Senden Sie ein weiteres onHotplug(display, connection=CONNECTED)-Ereignis vom Composer HAL an das Framework.
  • Ersetzen Sie den physischen Displaystatus im Composer-HAL durch einen Platzhalter-Displaystatus. Die Platzhalteranzeige muss einen einzelnen Anzeigemodus haben, damit das Framework den onDisplayChanged-Callback an Apps sendet, da sich die unterstützten Modi geändert haben. Dieser Einzelanzeigemodus muss dem letzten aktiven Modus des physischen Displays vor dem Trennen entsprechen, damit Apps keine Konfigurationsänderungsereignisse empfangen.

Hinweise zu Verbindungen ohne HDMI

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

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

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

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

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

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

In diesem Abschnitt wird beschrieben, wie Race-Bedingungen auftreten können. Anschließend wird erläutert, wie Sie das Composer-HAL so implementieren, dass sequenzielle IDs verwendet werden, um solche Bedingungen zu verhindern.

Betrachten Sie die folgende Ereignisabfolge, wenn den neuen Displaykonfigurationen KEINE neuen, sequenziellen IDs zugewiesen werden, was zu einem 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 der Composer-HAL eine Änderung der Displaykonfigurationen und aktualisiert seinen internen Status auf eine neue Reihe von Displaykonfigurationen, wie unten dargestellt:

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

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

  6. Das HAL interpretiert, dass das Framework eine Konfigurationsänderung auf 2160 × 3840 bei 60 Hz angefordert hat, obwohl in Wirklichkeit 1080 × 1920 bei 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 sequenzieller IDs konfigurieren

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

  • Wenn das 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, ignoriert das Composer-HAL den Aufruf.

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

Sehen Sie sich die folgende Abfolge von Ereignissen an, wenn den neuen Displaykonfigurationen neue, fortlaufende IDs zugewiesen werden:

  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 Displaykonfigurationen verarbeitet wird, wird die nächste Gruppe von Konfigurations-IDs ab der nächsten nicht verwendeten Ganzzahl zugewiesen, wie unten dargestellt:

    • 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. Der Composer HAL sendet ein onHotplug-Ereignis an das Framework, um zu benachrichtigen, dass sich die unterstützten Modi geändert haben.

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

  6. Das 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. Dazu werden die Funktionen getDisplayConfigs und getDisplayAttribute verwendet, um den Composer-HAL aufzurufen. Mit diesen Funktionen ermittelt das Framework die neue ID (5) für die gewünschte Auflösung und Aktualisierungsrate von 1080 × 1920 und 60 Hz.

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

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

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

Wie im Beispiel oben gezeigt, wird durch die Verwendung sequenzieller ID-Zuweisungen verhindert, dass es zu einem Race Condition kommt, und die richtige Änderung der Displaykonfiguration wird aktualisiert.