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 (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 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 adição de componentes e recursos de exibição dinâmica.

Nesta página, descrevemos o processamento de adições de componentes a quente e mudanças nas capacidades de exibição na implementação da HAL do Composer. Além disso, ele discute como gerenciar o framebuffer associado e evitar condições de disputa nessas situações.

Atualizar recursos de exibição

Esta seção descreve como o framework Android lida com mudanças nas capacidades de exibição iniciadas pelo Composer HAL.

Antes que o Android possa processar corretamente as mudanças nos recursos de exibição, 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 forma:

  1. Ao detectar uma mudança nas capacidades 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 do 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 aos apps que estão detectando esses eventos.

O framework realoca os framebuffers em eventos onHotplug(display, connection=CONNECTED) subsequentes. Consulte Gerenciamento de framebuffer do cliente para mais informações sobre como gerenciar corretamente a memória do framebuffer e evitar falhas durante a alocação de novos framebuffers.

Lidar com cenários comuns de conexão

Esta seção aborda como processar corretamente vários cenários de conexão nas suas implementações quando a tela principal está conectada e desconectada.

Como foi criado para dispositivos móveis, o framework Android não tem suporte integrado para uma tela principal desconectada. Em vez disso, a HAL precisa substituir a tela principal por uma tela substituta nas interações com o framework quando uma tela principal é desconectada fisicamente.

Os seguintes cenários podem ocorrer em STBs 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 abaixo:

Cenário Manuseio
Nenhuma tela conectada no momento da inicialização
  • Envie um indicador onHotplug(display, connection=CONNECTED) da HAL do Composer para o framework.
  • Substitua o estado de exibição física no HAL do Composer por um marcador de posição.
A tela principal está conectada fisicamente
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 no HAL do Composer por um estado de exibição de marcador de posição. O marcador de posição precisa ter um único modo de exibição para que o framework envie o callback onDisplayChanged aos apps, já que 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ó é compatível com as seguintes resoluções:

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

Quando um 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 o 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.

Use IDs de configuração sequenciais para evitar disputas

Condições de corrida podem surgir se a HAL do Composer atualizar as configurações de tela compatíveis simultaneamente com a chamada do framework setActiveConfig ou setActiveConfigWithConstraints. A solução é implementar o Composer HAL para usar IDs sequenciais e evitar esse problema.

Nesta seção, descrevemos como as condições de disputa podem ocorrer e fornecemos detalhes sobre como implementar a HAL do Composer para que ela use IDs sequenciais e evite essas condições.

Considere a seguinte sequência de eventos, quando IDs novos e 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. A HAL do compositor envia um evento onHotplug ao framework para notificar que o conjunto de modos compatíveis mudou.

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

  6. A HAL interpreta que o framework solicitou uma mudança de configuração para 2160x3840 60 Hz, embora na realidade o desejado fosse 1080x1920 60 Hz.

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 a HAL do Composer para usar IDs sequenciais

Para evitar essas condições de disputa, o OEM precisa implementar a HAL do Composer da seguinte maneira:

  • Quando o HAL do Composer atualiza as configurações de tela compatíveis, ele atribui IDs novos e sequenciais às novas configurações.
  • Quando o framework chama setActiveConfig ou setActiveConfigWithConstraints com um ID de configuração inválido, a HAL do Composer ignora a chamada.

Essas etapas evitam disputas, como 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, 1080x1920 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, conforme mostrado a seguir:

    • id=3, 2160x3840 60 Hz

    • id=4, 2160x3840 50 Hz

    • id=5, 1080x1920 60 Hz

    • id=6, 1080x1920 50 Hz

  4. O HAL do Composer envia um evento onHotplug ao framework para notificar que o conjunto de modos compatíveis 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 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 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 1080 x 1920 a 60 Hz.

Como mostrado no exemplo acima, o processo que usa atribuições de ID sequenciais garante que a condição de disputa seja evitada e que a mudança correta na configuração de exibição seja atualizada.