Os recursos de exibição, como modos de exibição e tipos HDR com suporte, podem mudar dinamicamente em dispositivos com telas conectadas externamente (com HDMI ou DisplayPort), como conversores do Android TV (STBs) e dispositivos over-the-top (OTT). Essa mudança pode acontecer como resultado de um sinal de hotplug HDMI, como quando o usuário alterna de uma tela para outra ou inicializa o dispositivo sem uma tela conectada. O Android 12 e versões mais recentes incluem mudanças no framework para processar recursos de exibição dinâmica e de adição de componentes.
Esta página descreve o processamento de hotplugs de exibição e mudanças nos recursos de exibição na implementação da HAL do Composer. Além disso, discute como gerenciar o framebuffer associado e evitar disputas nessas situações.
Atualizar recursos de exibição
Esta seção descreve como o framework do Android processa mudanças nos recursos de exibição iniciadas pela HAL do Composer.
Antes que o Android possa processar as mudanças nos recursos de exibição corretamente, o OEM precisa
implementar o HAL do Composer para usar onHotplug(display, connection=CONNECTED)
e notificar o framework sobre qualquer mudança nos recursos de exibição. Depois que isso for
implementado, o Android vai processar as mudanças nos recursos de exibição da seguinte maneira:
- Ao detectar uma mudança nos recursos de exibição, o framework recebe uma
notificação
onHotplug(display, connection=CONNECTED)
. - Ao receber a notificação, o framework descarta o estado de exibição e
o recria com os novos recursos da HAL usando os métodos
getActiveConfig
,getDisplayConfigs
,getDisplayAttribute
,getColorModes
,getHdrCapabilities
egetDisplayCapabilities
. - Depois que o framework recria um novo estado de exibição, ele envia o
callback
onDisplayChanged
para os apps que estão detectando esses eventos.
O framework realoca os framebuffers em eventos onHotplug(display, connection=CONNECTED)
posteriores. Consulte Gerenciamento de framebuffer do cliente
para mais informações sobre como gerenciar corretamente a memória do framebuffer para evitar
falhas durante a alocação de novos framebuffers.
Lidar com cenários de conexão comuns
Esta seção aborda como lidar corretamente com vários cenários de conexão nas implementações quando a tela principal estiver conectada e desconectada.
Como foi criado para dispositivos móveis, o framework do Android não tem suporte integrado para uma tela principal desconectada. Em vez disso, a HAL precisa substituir a tela principal por uma tela de marcador nas interações com o framework, caso uma tela principal seja desconectada fisicamente.
Os cenários a seguir podem ocorrer em decodificadores e dongles de TV que têm telas conectadas externamente que podem ser desconectadas. Para implementar o suporte a esses cenários, use as informações da tabela abaixo:
Cenário | Manuseio |
---|---|
Nenhuma tela conectada no momento da inicialização |
|
A tela principal está fisicamente conectada |
|
A tela principal está fisicamente desconectada |
|
Considerações sobre conexões que não são HDMI
O Android TV só é compatível com as seguintes resoluções:
- 720 x 1.280
- 1080x1920
- 2160x3840
- 4.320 x 7.680
Quando um decodificador STB ou dongle de TV tenta mostrar uma resolução sem suporte, como 480i em uma conexão CVBS, uma mensagem de erro é apresentada ao usuário.
Se o STB ou dongle da TV tiver conexões HDMI e não HDMI, a conexão HDMI
será a tela principal, e a conexão não HDMI ficará
inativa. Como resultado, se a conexão HDMI for desconectada enquanto a conexão
não HDMI ainda estiver conectada, um evento será enviado para o SurfaceFlinger, e os
recursos da tela não HDMI precisarão ser refletidos pelo getDisplayAttribute
e outras APIs iComposerClient
(como getHdrCapabilities
).
Usar IDs de configuração sequenciais para evitar disputas
Pode haver disputas se a HAL do Composer atualizar as configurações de exibição
com suporte simultaneamente com o framework chamando setActiveConfig
ou setActiveConfigWithConstraints
.
A solução é implementar a HAL do Composer para usar IDs sequenciais e evitar esse
problema.
Esta seção descreve como as condições de corrida podem ocorrer, seguida por detalhes sobre como implementar a HAL do Composer para que ela use IDs sequenciais para evitar essas condições.
Considere a seguinte sequência de eventos, quando novos IDs sequenciais NÃO são atribuídos às novas configurações de exibição, causando uma condição de disputa:
Os IDs de configuração de exibição compatíveis são:
- id=1, 1080x1920 60 Hz
- id=2, 1080x1920 50 Hz
O framework chama
setActiveConfig(display, config=1)
.Ao mesmo tempo, o HAL do Composer processa uma mudança nas configurações de exibição e atualiza o estado interno para um novo conjunto de configurações de exibição, conforme mostrado abaixo:
- id=1, 2160x3840 60 Hz
- id=2, 2160x3840 50 Hz
- id=3, 1080x1920 60 Hz
- id=4, 1080x1920 50 Hz
O HAL do Composer envia um evento
onHotplug
para o framework, para notificar que o conjunto de modos com suporte foi alterado.A HAL do Composer recebe
setActiveConfig(display, config=1)
(da etapa 2).O HAL interpreta que o framework solicitou uma mudança de configuração para 2160x3840 60 Hz, embora na realidade 1080x1920 60 Hz fosse o desejado.
O processo que usa atribuições de ID não sequenciais termina aqui com uma interpretação incorreta da mudança de configuração desejada.
Configurar o HAL do Composer para usar IDs sequenciais
Para evitar essas condições de corrida, o OEM precisa implementar a HAL do Composer da seguinte maneira:
- Quando o HAL do compositor atualiza as configurações de exibição com suporte, ele atribui novos IDs sequenciais às novas configurações de exibição.
- Quando o framework chama
setActiveConfig
ousetActiveConfigWithConstraints
com um ID de configuração inválido, a HAL do Composer ignora a chamada.
Essas etapas servem para evitar condições de disputa, conforme mostrado na discussão a seguir.
Considere a seguinte sequência de eventos, quando novos IDs sequenciais são atribuídos às novas configurações de exibição:
Os IDs de configuração de exibição compatíveis são:
- id=1, 1080x1920 60 Hz
- id=2, 1.080 x 1.920 50 Hz
O framework chama
setActiveConfig(display, config=1)
.Quando uma mudança nas configurações de exibição é processada, o próximo conjunto de IDs de configuração é atribuído a partir do próximo número inteiro não utilizado, conforme mostrado abaixo:
id=3, 2160x3840 60 Hz
id=4, 2.160 x 3.840 50 Hz
id=5, 1080x1920 60 Hz
id=6, 1080x1920 50 Hz
O HAL do Composer envia um evento
onHotplug
para o framework, para notificar que o conjunto de modos com suporte mudou.A HAL do Composer recebe
setActiveConfig(display, config=1)
(da etapa 2).O HAL do Composer ignora a chamada porque o ID não é mais válido.
O framework recebe e processa o evento
onHotplug
a partir da etapa 4. Ele chama o HAL do Composer usando as funçõesgetDisplayConfigs
egetDisplayAttribute
. Com essas funções, o framework identifica o novo ID (5) para a resolução e a taxa de atualização desejadas de 1080x1920 e 60 Hz.O framework envia outro evento
setActiveConfig
com um ID atualizado de 5.A HAL do Composer recebe
setActiveConfig(display, config=5)
da etapa 5.A HAL interpreta corretamente que o framework solicitou uma mudança de configuração para 1.080 x 1.920 60 Hz.
Como mostrado no exemplo acima, o processo que usa atribuições de ID sequenciais evita que a disputa ocorra e a mudança correta da configuração de exibição seja atualizada.