No Android 9 (e versões anteriores), o SurfaceFlinger e o DisplayManagerService
assumiam a existência de no máximo duas telas físicas com IDs fixados 0
e 1. Conforme descrito em
Identificadores
de exibição estáticos, o SurfaceFlinger agora usa
uma API Hardware Composer (HWC) para gerar IDs de exibição estáveis, o que permite
gerenciar um número arbitrário de telas físicas.
O framework pode procurar o token IBinder
para uma tela
física usando SurfaceControl#getPhysicalDisplayToken
depois de receber
o ID de exibição de 64 bits de SurfaceControl#getPhysicalDisplayIds
ou
de um evento hotplug DisplayEventReceiver
.
No Android 10, a tela interna principal é
TYPE_BUILT_IN
, e todas as telas secundárias são sinalizadas como
TYPE_HDMI
, independente do tipo de conexão. Portanto, outras
telas internas são tratadas como externas. Como solução alternativa,
o código específico do dispositivo pode fazer suposições sobre
DisplayAddress.Physical#getPort
se o HWC for conhecido e a lógica de alocação
de porta for previsível.
Implementação
Antes, as telas eram identificadas por IDs de 32 bits, em que 0 é a tela
interna, 1 é a tela externa, [2, INT32_MAX] são telas virtuais HWC e
-1 representa uma tela inválida ou uma tela virtual que não é HWC. Para
que o SurfaceFlinger e o DisplayManagerService
rastreiem mais de duas
telas e reconheçam telas vistas anteriormente, as telas precisam receber IDs estáveis
e persistentes.
Se o HWC oferecer suporte a IComposerClient.getDisplayIdentificationData
e fornecer dados de identificação de tela, o SurfaceFlinger analisará a estrutura EDID
e alocará IDs de tela estáveis de 64 bits para telas físicas e
virtuais do HWC. Os IDs são expressos usando um tipo de opção, em que o valor nulo
representa uma tela inválida ou uma tela virtual sem HwC. Sem o suporte ao HWC,
o SurfaceFlinger volta ao comportamento legado com no máximo duas telas
físicas.