Manuseio de hotplug

Os recursos de exibição (como modos de exibição e tipos de HDR compatíveis) podem mudar dinamicamente em dispositivos que possuem monitores conectados externamente (com HDMI ou DisplayPort), como decodificadores de Android TV (STBs) e over-the-top (OTT) dispositivos. Essa alteração pode ocorrer como resultado de um sinal hotplug HDMI, como quando o usuário alterna de um monitor para outro ou inicializa o dispositivo sem um monitor conectado. O Android 12 e versões posteriores incluem 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 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 forma 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 trata 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 notificação onHotplug(display, connection=CONNECTED) .
  2. Ao receber a notificação, a estrutura elimina seu 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 a estrutura recria um novo estado de exibição, ela envia o retorno de chamada onDisplayChanged para os aplicativos que estão escutando esses eventos.

A estrutura realoca os framebuffers em eventos 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 está conectado e desconectado.

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

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

Cenário Manuseio
Nenhum monitor conectado no momento da inicialização
  • Envie um sinal onHotplug(display, connection=CONNECTED) do Composer HAL para a estrutura.
  • Substitua o estado de exibição físico dentro do Composer HAL por um estado de exibição de espaço reservado.
O monitor principal está fisicamente conectado
A tela principal está fisicamente desconectada
  • Envie outro evento onHotplug(display, connection=CONNECTED) do Composer HAL para a estrutura.
  • Substitua o estado de exibição físico dentro do Composer HAL por um estado de exibição de espaço reservado. A exibição do espaço reservado deve ter um modo de exibição único, para que a estrutura envie o retorno de chamada onDisplayChanged para aplicativos (porque o conjunto de modos suportados foi alterado). Este modo de exibição único 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 estrutura chamando 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, seguida por 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:

    • identificação = 1 , 1080x1920 60 Hz
    • identificação = 2 , 1080x1920 50 Hz
  2. A estrutura chama setActiveConfig(display, config=1) .

  3. Ao mesmo tempo, 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:

    • identificação = 1 , 2160x3840 60Hz
    • identificação = 2 , 2160x3840 50Hz
    • identificação = 3 , 1080x1920 60 Hz
    • identificação = 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 a estrutura solicitou uma alteração de configuração para 2160x3840 60 Hz , embora na realidade fosse desejado 1080x1920 60 Hz .

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

Configure 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:

    • identificação = 1 , 1080x1920 60 Hz
    • identificação = 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 número inteiro não utilizado, mostrado a seguir:

    • identificação = 3 , 2160x3840 60 Hz

    • identificação = 4 , 2160x3840 50 Hz

    • identificação = 5 , 1080x1920 60 Hz

    • identificação = 6 , 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 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. Ela 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 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 sequenciais garante que a condição de corrida seja evitada e a alteração correta da configuração de exibição seja atualizada.