Gerenciamento de hotplug

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:

  1. Ao detectar uma mudança nos recursos de exibição, o framework recebe uma notificação onHotplug(display, connection=CONNECTED).
  2. 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 e getDisplayCapabilities.
  3. 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
  • Envie um sinal onHotplug(display, connection=CONNECTED) da HAL do Composer para o framework.
  • Substitua o estado de exibição física dentro do HAL do Composer por um estado de exibição de marcador de posição.
A tela principal está fisicamente conectada
A tela principal está fisicamente desconectada
  • Envie outro evento onHotplug(display, connection=CONNECTED) da HAL do Composer para o framework.
  • Substitua o estado de exibição física dentro do HAL do Composer por um estado de exibição de marcador de posição. A exibição do marcador precisa ter um único modo de exibição para que o framework envie o callback onDisplayChanged aos apps, porque o conjunto de modos compatíveis mudou. Esse modo de tela única precisa corresponder ao último modo ativo da tela física antes da desconexão para que os apps não recebam eventos de mudança de configuração.

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:

  1. Os IDs de configuração de exibição compatíveis são:

    • id=1, 1080x1920 60 Hz
    • id=2, 1080x1920 50 Hz
  2. O framework chama setActiveConfig(display, config=1).

  3. 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
  4. O HAL do Composer envia um evento onHotplug para o framework, para notificar que o conjunto de modos com suporte foi alterado.

  5. A HAL do Composer recebe setActiveConfig(display, config=1) (da etapa 2).

  6. 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 ou setActiveConfigWithConstraints 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:

  1. 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
  2. O framework chama setActiveConfig(display, config=1).

  3. 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

  4. O HAL do Composer envia um evento onHotplug para o framework, para notificar que o conjunto de modos com suporte mudou.

  5. A HAL do Composer recebe setActiveConfig(display, config=1) (da etapa 2).

  6. O HAL do Composer ignora a chamada porque o ID não é mais válido.

  7. O framework recebe e processa o evento onHotplug a partir da etapa 4. Ele chama o HAL do Composer usando as funções getDisplayConfigs e getDisplayAttribute. 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.

  8. O framework envia outro evento setActiveConfig com um ID atualizado de 5.

  9. A HAL do Composer recebe setActiveConfig(display, config=5) da etapa 5.

  10. 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.