Processamento de hot-plug

Os recursos de exibição (como modos de exibição e tipos HDR com suporte) podem mudar dinamicamente em dispositivos com telas conectadas externamente (por HDMI ou DisplayPort), como conversores do Android TV (STB) e dispositivos over-the-top (OTT). Essa mudança pode acontecer como resultado de um sinal de conexão a quente HDMI, como quando o usuário muda 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 a conexão a quente e os recursos de exibição dinâmica.

Esta página descreve o processamento de conexões a quente de tela e mudanças nos recursos de exibição na implementação da HAL do Composer. Além disso, ela discute como gerenciar o framebuffer associado e evitar condições de corrida 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 iniciados pela HAL do Composer.

Antes que o Android possa processar mudanças nos recursos de exibição corretamente, o OEM precisa implementar a HAL do Composer para que ela use onHotplug(display, connection=CONNECTED) para notificar o framework sobre mudanças 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 onHotplug(display, connection=CONNECTED) notificação.
  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 onDisplayChanged callback para os apps que estão aguardando esses eventos.

O framework realoca os framebuffers em eventos subsequentes onHotplug(display, connection=CONNECTED). 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.

Processar cenários de conexão comuns

Esta seção aborda como processar corretamente vários cenários de conexão nas implementações quando a tela principal está 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 de posição nas interações com o framework no caso de uma tela principal ser desconectada fisicamente.

onHotplug(display, connection=DISCONNECTED)

Os cenários a seguir podem ocorrer em conversores 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 na tabela a seguir:

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 da HAL do Composer por um estado de exibição de marcador de posição.
A tela principal está conectada fisicamente
A tela principal está desconectada fisicamente
  • Envie outro evento onHotplug(display, connection=CONNECTED) da HAL do Composer para o framework.
  • Substitua o estado de exibição física dentro da HAL do Composer por um estado de exibição de marcador de posição. A tela de marcador de posição precisa ter um único modo de exibição para que o framework envie o onDisplayChanged callback para os apps (porque o conjunto de modos compatíveis mudou). Esse modo de exibição único 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 não HDMI

O Android TV só oferece suporte a estas resoluções:

  • 720x1280
  • 1080x1920
  • 2160x3840
  • 4320x7680

Quando um conversor 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 conversor ou dongle de 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 ao SurfaceFlinger e os recursos da tela não HDMI precisarão ser refletidos por getDisplayAttribute e outras APIs IComposerClient (como getHdrCapabilities).

Usar IDs de configuração sequenciais para evitar condições de corrida

As condições de corrida podem surgir 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 de 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 IDs sequenciais novos NÃO são atribuídos às novas configurações de exibição, causando uma disputa:

  1. Os IDs de configuração de exibição com suporte são:

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

  3. Simultaneamente, a HAL do Composer processa uma mudança de configurações de exibição e atualiza o estado interno para um novo conjunto de configurações de exibição, mostrado da seguinte maneira:

    • id=1, 2160 x 3840 60 Hz
    • id=2, 2160 x 3840 50 Hz
    • id=3, 1080 x 1920 60 Hz
    • id=4, 1080 x 1920 50 Hz
  4. A HAL do Composer envia um onHotplug evento para o framework, para notificar que o conjunto de modos compatíveis mudou.

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

  6. A HAL interpreta que o framework solicitou uma mudança de configuração para 2160 x 3840 60 Hz, embora na realidade 1080 x 1920 60 Hz tenha sido selecionado.

O processo que usa atribuições de ID não sequenciais termina aqui com uma interpretação incorreta da mudança de configuração selecionada.

Configurar a 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 a HAL do Composer atualiza as configurações de exibição com suporte, ela atribui IDs sequenciais novos à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 corrida, conforme mostrado na discussão a seguir.

Considere a seguinte sequência de eventos, quando IDs sequenciais novos são atribuídos às novas configurações de exibição:

  1. Os IDs de configuração de exibição com suporte são:

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

  3. Quando uma mudança de 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 usado, mostrado da seguinte maneira:

    • id=3, 2160 x 3840 60 Hz

    • id=4, 2160 x 3840 50 Hz

    • id=5, 1080 x 1920 60 Hz

    • id=6, 1080 x 1920 50 Hz

  4. A HAL do Composer envia um onHotplug evento para o framework, para notificar que o conjunto de modos compatíveis mudou.

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

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

  7. O framework recebe e processa o evento onHotplug da etapa 4. Ele chama a 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 selecionadas de 1080 x 1920 e 60 Hz.

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

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

  10. A HAL interpreta corretamente que o framework solicitou uma mudança de configuração para 1080 x 1920 60 Hz.

Como mostrado no exemplo anterior, o processo que usa atribuições de ID sequenciais verifica se a disputa é evitada e a mudança de configuração de exibição correta é atualizada.