Roteamento de entrada

No Android 9 e versões anteriores, não era possível interagir com várias telas por toque, porque não havia um mecanismo de associação entre telas e dispositivos de entrada. Por exemplo, uma tela touch pode fornecer uma saída de vídeo HDMI (que seria registrada como uma tela no Android) e uma saída USB para tela touch (que seria registrada como um dispositivo de entrada). Se vários dispositivos fossem conectados dessa maneira, não seria possível determinar qual dispositivo de entrada pertence a qual tela. O mesmo problema se aplica a dispositivos dobráveis com várias telas integradas.

O Android 10 adicionou um mecanismo para especificar a qual tela cada dispositivo de entrada pertence. A associação é feita por números de porta, em que port se refere à porta física a que uma tela está conectada.

Por exemplo, se um dispositivo Android tiver duas portas HDMI rotuladas como hdmi1 e hdmi2, os valores da porta de exibição poderão ser 1 e 2. Os valores da porta permanecem os mesmos mesmo quando uma tela diferente (como um modelo ou fabricante diferente) é conectada à mesma porta HDMI física. Isso permite que os fabricantes de dispositivos forneçam instruções para montar e atualizar telas.

A associação é configurada em /vendor/etc/input-port-associations.xml. Exemplo:

<ports>
    <port display="0" input="usb-xhci-hcd.0.auto-1.1/input0" />
    <port display="1" input="usb-xhci-hcd.0.auto-1.2/input0" />
</ports>

No exemplo acima, display="0" especifica a porta a que o display está conectado. input="usb-xhci-hcd.0.auto-1.1/input0" especifica a porta a que o dispositivo de entrada está conectado. Para determinar as portas associadas a dispositivos específicos, use o seguinte comando do terminal e analise a propriedade location desses dispositivos no estado do Hub de eventos.

adb shell dumpsys input

Se muitos dispositivos estiverem conectados, toque em um específico para examinar a matriz RecentQueue no estado do Input Dispatcher. Em seguida, identifique os dispositivos que geraram o evento mais recente. Em seguida, encontre o dispositivo correspondente no estado do Hub de Eventos.

Para determinar as portas de exibição atribuídas aos monitores conectados, use adb shell dumpsys display e procure a propriedade address de DisplayDeviceInfo para cada monitor em "Dispositivos de exibição". Como alternativa, use adb shell dumpsys SurfaceFlinger --display-id para despejar informações de identificação de todas as telas conectadas. Consulte também Identificadores de exibição estática.

Se você especificar uma associação para um dispositivo de entrada específico e a tela correspondente não estiver presente no sistema, o dispositivo de entrada será desativado até que a tela respectiva apareça. A associação é feita apenas para dispositivos sensíveis ao toque.

Roteamento para várias telas dinâmicas

O Android 10 permite configurar dispositivos estáticos com várias telas. As associações dinâmicas ainda não estão ativadas. No entanto, alguns casos de uso podem ser resolvidos fornecendo informações de roteamento para telas e painéis de entrada que nem sempre estão presentes ou usando dispositivos de entrada virtuais e fornecendo informações de roteamento adicionais para esses dispositivos virtuais. Se uma implementação de dispositivo for compatível com:

  • Experiência semelhante à de um computador desktop com uma estação de encaixe. Nesse caso, uma configuração de roteamento pode ser fornecida para direcionar a entrada do acessório conectado à estação (identificado exclusivamente por porta) para a tela externa (identificada por porta).
  • A tela principal funciona como uma fonte de entrada (como um touchpad) quando conectada ao monitor externo. Assim, uma configuração de roteamento pode ser fornecida para direcionar a entrada do painel de toque virtual (identificado por um ID virtual exclusivo) ao monitor externo (identificado por uma porta).

Implementação

  • Para dispositivos físicos, a porta a que o dispositivo de entrada e a tela estão conectados são usadas para corresponder às telas sensíveis ao toque.
  • Os mapeamentos são armazenados em InputReaderConfiguration.
  • TouchInputMapper.mViewport é definido como a janela de visualização que corresponde à porta especificada para InputDevice.location.
  • Se uma porta de dispositivo de entrada for especificada no arquivo de mapeamento e não houver uma janela de visualização com uma porta de exibição correspondente, o dispositivo de entrada nessa porta será desativado.
  • Se uma porta não for especificada para um dispositivo de entrada específico, a janela de visualização será definida de acordo com as regras atuais.
  • Não é necessário fazer mudanças no kernel nos drivers de entrada.
  • As portas do dispositivo de entrada são determinadas usando o ioctl EVIOCGPHYS.