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 aufgrund eines HDMI-Hotplug-Signals erfolgen, z. B. wenn der Nutzer von einem Bildschirm zu einem anderen wechselt oder das Gerät ohne angeschlossenen Bildschirm 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 Composer HAL-Implementierung beschrieben. Außerdem wird erläutert, wie Sie den zugehörigen Framebuffer verwalten und Race-Bedingungen in diesen Situationen verhindern.
Displayfunktionen aktualisieren
In diesem Abschnitt wird beschrieben, wie das Android-Framework Änderungen an den Displayfunktionen verarbeitet, die von der Composer HAL initiiert wurden.
Bevor Android Änderungen an den Anzeigefunktionen ordnungsgemäß verarbeiten kann, muss der OEM Composer-HAL so implementieren, dass er onHotplug(display, connection=CONNECTED)
verwendet, um das Framework über Änderungen an den Anzeigefunktionen zu informieren. Nach der Implementierung werden Änderungen an den Displayfunktionen von Android so verarbeitet:
- Wenn eine Änderung der Anzeigefunktionen erkannt wird, erhält das Framework eine
onHotplug(display, connection=CONNECTED)
-Benachrichtigung. - 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
undgetDisplayCapabilities
verwendet. - Nachdem das Framework einen neuen Anzeigezustand neu erstellt hat, wird der
onDisplayChanged
-Callback an die Apps gesendet, die solche Ereignisse beobachten.
Das Framework weist die Framebuffer bei nachfolgenden onHotplug(display, connection=CONNECTED)
-Ereignissen neu zu. Weitere Informationen zum ordnungsgemäßen Verwalten des Framebuffer-Speichers, um Fehler bei der Zuweisung neuer Framebuffer zu vermeiden, finden Sie unter Client-Framebuffer-Verwaltung.
Häufige Verbindungsszenarien verarbeiten
In diesem Abschnitt erfahren Sie, wie Sie verschiedene Verbindungsszenarien in Ihren Implementierungen richtig handhaben, 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 der HAL den primären Bildschirm in seinen Interaktionen mit dem Framework durch einen Platzhalter ersetzen, wenn die primäre Anzeige 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 |
|
Primäres Display ist physisch verbunden |
|
Das primäre Display ist physisch getrennt |
|
Nicht HDMI-Verbindungen
Android TV unterstützt nur die folgenden Auflösungen:
- 720 x 1280
- 1.080 × 1.920
- 2160 x 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 Nicht-HDMI-Verbindungen hat, ist die HDMI-Verbindung der primäre Bildschirm und die Nicht-HDMI-Verbindung ist inaktiv. Wenn die HDMI-Verbindung getrennt wird, während die Nicht-HDMI-Verbindung weiterhin besteht, wird ein Ereignis an SurfaceFlinger gesendet und die Funktionen des Nicht-HDMI-Bildschirms müssen über die 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 der Composer-HAL die unterstützten Anzeigekonfigurationen 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, fortlaufenden IDs zugewiesen werden, was zu einer Race-Condition führt:
Folgende Displaykonfigurations-IDs werden unterstützt:
- id=1, 1080 × 1920, 60 Hz
- id=2, 1080 × 1920, 50 Hz
Das Framework ruft
setActiveConfig(display, config=1)
auf.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
Composer HAL sendet ein
onHotplug
-Ereignis an das Framework, um zu informieren, dass sich der Satz der unterstützten Modi geändert hat.Der Composer-HAL empfängt
setActiveConfig(display, config=1)
(aus Schritt 2).Der HAL geht davon aus, dass das Framework eine Konfigurationsänderung auf 2160 × 3840 60 Hz angefordert hat, obwohl in Wirklichkeit 1080 × 1920 60 Hz gewünscht ist.
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
odersetActiveConfigWithConstraints
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:
Folgende Displaykonfigurations-IDs werden unterstützt:
- id=1, 1080 × 1920, 60 Hz
- id=2, 1080 × 1920, 50 Hz
Das Framework ruft
setActiveConfig(display, config=1)
auf.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, 2.160 × 3.840, 60 Hz
id=4, 2160 × 3840, 50 Hz
id=5, 1.080 × 1.920, 60 Hz
id=6, 1080 × 1920, 50 Hz
Die Composer HAL sendet ein
onHotplug
-Ereignis an das Framework, um zu informieren, dass sich die unterstützten Modi geändert haben.Die Composer HAL empfängt
setActiveConfig(display, config=1)
(aus Schritt 2).Der Composer HAL ignoriert den Aufruf, da die ID nicht mehr gültig ist.
Das Framework empfängt und verarbeitet das
onHotplug
-Ereignis aus Schritt 4. Er ruft die Composer HAL mit den FunktionengetDisplayConfigs
undgetDisplayAttribute
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.Das Framework sendet ein weiteres
setActiveConfig
-Ereignis mit der aktualisierten ID 5.Die Composer HAL empfängt
setActiveConfig(display, config=5)
aus Schritt 5.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.