Manuseio de hotplug

Os recursos de exibição (como modos de exibição e tipos de HDR compatíveis) podem mudar dinamicamente em dispositivos com monitores conectados externamente (com HDMI ou DisplayPort), como decodificadores de TV Android (STBs) e over-the-top (OTT) dispositivos. Essa alteração pode ocorrer como resultado de um sinal HDMI hotplug, como quando o usuário alterna de um monitor para outro ou inicializa o dispositivo sem um monitor conectado. O Android 12 e superior inclui alterações na estrutura para lidar com hotplugging e recursos de exibição dinâmica.

Esta página descreve o tratamento de hotplugs de exibição e alterações nos recursos de exibição na implementação do Composer HAL. Além disso, 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 a estrutura do Android lida com as alterações nos recursos de exibição iniciadas pelo Composer HAL.

Antes que o Android possa lidar adequadamente com as alterações nos recursos de exibição, o OEM deve implementar o Composer HAL de modo que ele use onHotplug(display, connection=CONNECTED) para notificar a estrutura sobre quaisquer alterações nos recursos de exibição. Depois de implementado, o Android lida com as alterações nos recursos de exibição da seguinte maneira:

  1. Ao detectar uma alteração nos recursos de exibição, a estrutura recebe uma onHotplug(display, connection=CONNECTED) .
  2. Ao receber a notificação, a estrutura descarta seu estado de exibição e o recria com os novos recursos do HAL usando os getActiveConfig , getDisplayConfigs , getDisplayAttribute , getColorModes , getHdrCapabilities e getDisplayCapabilities .
  3. Depois que a estrutura recria um novo estado de exibição, ela envia o retorno de chamada onDisplayChanged para os aplicativos que estão ouvindo esses eventos.

A estrutura realoca os framebuffers nos onHotplug(display, connection=CONNECTED) subsequentes. Consulte Gerenciamento de framebuffer do cliente para obter mais informações sobre como gerenciar adequadamente 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 adequadamente com vários cenários de conexão em suas implementações quando o monitor principal é conectado e desconectado.

Tendo sido criado para dispositivos móveis, a estrutura do Android não possui suporte integrado para um monitor primário desconectado. Em vez disso, o HAL deve substituir a exibição principal por uma exibição de espaço reservado em suas interações com a estrutura no caso de uma exibição principal ser fisicamente desconectada.

Os seguintes cenários podem ocorrer em STBs e dongles de TV que possuem monitores conectados externamente que podem ser desconectados. Para implementar o suporte para esses cenários, use as informações da tabela abaixo:

Cenário Manipulação
Nenhum monitor conectado no momento da inicialização
  • Envie um onHotplug(display, connection=CONNECTED) do Composer HAL para a estrutura.
  • Substitua o estado de exibição física dentro do Composer HAL por um estado de exibição de espaço reservado.
O monitor principal está fisicamente conectado
O monitor principal está fisicamente desconectado
  • Envie outro onHotplug(display, connection=CONNECTED) do Composer HAL para a estrutura.
  • Substitua o estado de exibição física dentro do Composer HAL por um estado de exibição de espaço reservado. A exibição do espaço reservado deve ter um único modo de exibição, para que a estrutura envie o retorno de chamada onDisplayChanged aos aplicativos (porque o conjunto de modos com suporte foi alterado). Esse modo de exibição única deve corresponder ao último modo ativo da exibição física antes da desconexão, para que os aplicativos não recebam eventos de alteração de configuração .

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

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

Esta seção descreve como as condições de corrida podem ocorrer, seguidas de detalhes sobre como implementar o Composer HAL para que ele use IDs sequenciais para evitar tais 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 corrida:

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

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

  3. Simultaneamente, o Composer HAL processa uma alteração nas configurações de exibição e atualiza seu estado interno para um novo conjunto de configurações de exibição, mostrado a seguir:

    • id=1 , 2160x3840 60 Hz
    • id=2 , 2160x3840 50 Hz
    • id=3 , 1080x1920 60 Hz
    • id=4 , 1080x1920 50 Hz
  4. O Composer HAL envia um evento onHotplug para a estrutura, para notificar que o conjunto de modos suportados foi alterado.

  5. O Composer HAL 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 desejado.

O processo que usa atribuições de ID não sequencial termina aqui com uma interpretação incorreta da alteração de configuração desejada.

Configurar o Composer HAL para usar IDs sequenciais

Para evitar tais condições de corrida, o OEM deve implementar o Composer HAL da seguinte forma:

  • Quando o Composer HAL atualiza as configurações de exibição suportadas, ele atribui novos IDs sequenciais às novas configurações de exibição.
  • Quando a estrutura chama setActiveConfig ou setActiveConfigWithConstraints com um ID de configuração inválido, o Composer HAL 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 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. A estrutura chama setActiveConfig(display, config=1) .

  3. Quando uma alteração nas configurações de exibição é processada, o próximo conjunto de IDs de configuração é atribuído a partir do próximo inteiro não utilizado, 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 Composer HAL envia um evento onHotplug para o framework, para notificar que o conjunto de modos suportados mudou.

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

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

  7. A estrutura recebe e processa o evento onHotplug da etapa 4. Ele chama o Composer HAL usando as funções getDisplayConfigs e getDisplayAttribute . Com essas funções o framework identifica o novo ID (5) para a resolução desejada e taxa de atualização de 1080x1920 e 60 Hz.

  8. A estrutura envia outro evento setActiveConfig com um ID atualizado de 5.

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

  10. O HAL interpreta corretamente que a estrutura solicitou uma alteração de configuração para 1080x1920 60 Hz.

Conforme mostrado no exemplo acima, o processo que usa atribuições de ID sequencial garante que a condição de corrida seja evitada e que a alteração de configuração de exibição correta seja atualizada.