Le funzionalità di visualizzazione (come le modalità di visualizzazione e i tipi di HDR supportati) possono cambiare dinamicamente sui dispositivi con display collegati esternamente (con HDMI o DisplayPort), come i set-top box (STB) Android TV e i dispositivi over-the-top (OTT). Questa modifica può verificarsi a seguito di un segnale hotplug HDMI, ad esempio quando l'utente passa da un display all'altro o avvia il dispositivo senza un display collegato. Android 12 e versioni successive includono modifiche al framework per gestire l'hotplugging e le funzionalità di visualizzazione dinamica.
Questa pagina descrive la gestione degli hotplug del display e delle modifiche alle funzionalità del display nell'implementazione di Composer HAL. Inoltre, spiega come gestire il framebuffer associato e prevenire le race condition in queste situazioni.
Aggiornare le funzionalità di visualizzazione
Questa sezione descrive come il framework Android gestisce le modifiche alle funzionalità di visualizzazione avviate da Composer HAL.
Prima che Android possa gestire correttamente le modifiche alle funzionalità di visualizzazione, l'OEM deve
implementare Composer HAL in modo che utilizzi onHotplug(display, connection=CONNECTED)
per comunicare al framework eventuali modifiche alle funzionalità di visualizzazione. Una volta
implementate, Android gestisce le modifiche alle funzionalità di visualizzazione nel seguente modo:
- Quando rileva una modifica delle funzionalità di visualizzazione, il framework riceve una notifica
onHotplug(display, connection=CONNECTED)
. - Alla ricezione della notifica, il framework abbandona il suo stato di visualizzazione e
lo ricrea con le nuove funzionalità dell'HAL utilizzando i metodi
getActiveConfig
,getDisplayConfigs
,getDisplayAttribute
,getColorModes
,getHdrCapabilities
egetDisplayCapabilities
. - Dopo che il framework ricrea un nuovo stato di visualizzazione, invia il callback
onDisplayChanged
alle app che sono in ascolto di questi eventi.
Il framework rialloca i frame buffer negli eventi onHotplug(display, connection=CONNECTED)
successivi. Per ulteriori informazioni su come gestire correttamente la memoria del framebuffer per evitare errori durante l'allocazione di nuovi framebuffer, consulta la sezione Gestione del framebuffer client.
Gestire scenari di connessione comuni
Questa sezione illustra come gestire correttamente vari scenari di connessione nelle implementazioni quando il display principale è connesso e disconnesso.
Essendo stato creato per i dispositivi mobili, il framework Android non supporta un display principale disconnesso. Al contrario, l'HAL deve sostituire il display principale con un display segnaposto nelle sue interazioni con il framework nel caso in cui un display principale sia fisicamente scollegato.
I seguenti scenari possono verificarsi in STB e dongle TV con display collegati esternamente che possono essere scollegati. Per implementare il supporto per questi scenari, utilizza le informazioni nella tabella seguente:
Scenario | Prescrizioni d'uso |
---|---|
Nessun display connesso all'avvio |
|
Il display principale è collegato fisicamente |
|
Il display principale è fisicamente disconnesso |
|
Considerazioni sulla connessione non HDMI
Android TV supporta solo le seguenti risoluzioni:
- 720x1280
- 1080x1920
- 2160x3840
- 4320x7680
Quando un set-top box o un dongle TV tenta di visualizzare una risoluzione non supportata, ad esempio 480i su una connessione CVBS, all'utente viene mostrato un messaggio di errore.
Se il set-top box o il dongle TV dispone di connessioni HDMI e non HDMI, la connessione HDMI è il display principale e la connessione non HDMI è inattiva. Di conseguenza, se la connessione HDMI viene disconnessa mentre la connessione non HDMI è ancora attiva, viene inviato un evento a SurfaceFlinger e le funzionalità del display non HDMI devono essere riflesse tramite getDisplayAttribute
e altre API iComposerClient
(come getHdrCapabilities
).
Utilizza ID configurazione sequenziali per evitare le condizioni di competizione
Possono verificarsi condizioni di competizione se l'HAL Composer aggiorna le configurazioni del display supportate contemporaneamente al framework che chiama setActiveConfig
o setActiveConfigWithConstraints
.
La soluzione consiste nell'implementare Composer HAL per utilizzare ID sequenziali ed evitare questo problema.
Questa sezione descrive come possono verificarsi le condizioni di competizione, seguita dai dettagli su come implementare l'HAL Composer in modo che utilizzi ID sequenziali per evitare tali condizioni.
Considera la seguente sequenza di eventi, quando ai nuovi ID sequenziali NON vengono assegnate le nuove configurazioni di visualizzazione, causando una condizione di competizione:
Gli ID configurazione display supportati sono:
- id=1, 1080x1920 60 Hz
- id=2, 1080x1920 50 Hz
Il framework chiama
setActiveConfig(display, config=1)
.Contemporaneamente, Composer HAL elabora una modifica delle configurazioni del display e aggiorna il suo stato interno a un nuovo insieme di configurazioni del display, come mostrato di seguito:
- id=1, 2160x3840 60 Hz
- id=2, 2160x3840 50 Hz
- id=3, 1080x1920 60 Hz
- id=4, 1080x1920 50 Hz
Composer HAL invia un evento
onHotplug
al framework per comunicare che il set di modalità supportate è cambiato.Composer HAL riceve
setActiveConfig(display, config=1)
(dal passaggio 2).L'HAL interpreta che il framework ha richiesto una modifica della configurazione a 2160x3840 60 Hz, anche se in realtà era desiderata la risoluzione 1080x1920 60 Hz.
Il processo che utilizza assegnazioni di ID non sequenziali termina qui con un'interpretazione errata della modifica di configurazione desiderata.
Configurare Composer HAL per l'utilizzo di ID sequenziali
Per evitare queste race condition, l'OEM deve implementare l'HAL Composer come segue:
- Quando l'HAL Composer aggiorna le configurazioni di visualizzazione supportate, assegna nuovi ID sequenziali alle nuove configurazioni di visualizzazione.
- Quando il framework chiama
setActiveConfig
osetActiveConfigWithConstraints
con un ID configurazione non valido, l'HAL Composer ignora la chiamata.
Questi passaggi servono a prevenire le race condition, come mostrato nella seguente discussione.
Considera la seguente sequenza di eventi quando vengono assegnati nuovi ID sequenziali alle nuove configurazioni di visualizzazione:
Gli ID configurazione display supportati sono:
- id=1, 1080x1920 60 Hz
- id=2, 1080x1920 50 Hz
Il framework chiama
setActiveConfig(display, config=1)
.Quando viene elaborata una modifica delle configurazioni di visualizzazione, il successivo insieme di ID configurazione viene assegnato a partire dal successivo numero intero non utilizzato, come mostrato di seguito:
id=3, 2160x3840 60 Hz
id=4, 2160x3840 50 Hz
id=5, 1080x1920 60 Hz
id=6, 1080x1920 50 Hz
Composer HAL invia un evento
onHotplug
al framework per comunicare che il set di modalità supportate è cambiato.L'HAL di Composer riceve
setActiveConfig(display, config=1)
(dal passaggio 2).Composer HAL ignora la chiamata perché l'ID non è più valido.
Il framework riceve ed elabora l'evento
onHotplug
del passaggio 4. Chiama l'HAL di Composer utilizzando le funzionigetDisplayConfigs
egetDisplayAttribute
. Con queste funzioni, il framework identifica il nuovo ID (5) per la risoluzione e la frequenza di aggiornamento desiderate di 1080x1920 e 60 Hz.Il framework invia un altro evento
setActiveConfig
con un ID aggiornato di 5.L'HAL di Composer riceve
setActiveConfig(display, config=5)
dal passaggio 5.L'HAL interpreta correttamente che il framework ha richiesto una modifica della configurazione a 1080 x 1920 a 60 Hz.
Come mostrato nell'esempio precedente, il processo che utilizza assegnazioni di ID sequenziali garantisce che la race condition venga impedita e che la configurazione di visualizzazione corretta venga aggiornata.