输入路由

在 Android 9 及更低版本中,无法通过触摸与多个显示屏进行互动,因为显示屏和输入设备之间没有关联机制。例如,触摸屏显示屏可以提供 HDMI 视频输出(这将在 Android 上注册为显示屏)和用于触摸屏的 USB 输出(这将注册为输入设备)。如果以这种方式连接了多个设备,则无法确定哪个输入设备属于哪个显示屏。相同的问题也适用于具有多个内置显示屏的可折叠设备。

Android 10 添加了一种机制来指定哪些输入设备属于哪些显示屏。这种关联是通过端口号完成的,其中端口是指显示屏连接到的物理端口。

例如,如果 Android 设备有两个标记为 hdmi1hdmi2 的 HDMI 端口,则显示屏端口值可以为 12。即使将不同的显示屏(例如,不同的显示屏型号或制造商)连接到同一物理 HDMI 端口,端口值也保持不变。这使设备制造商能够提供组装和升级显示屏的说明。

关联在 /vendor/etc/input-port-associations.xml 中配置。例如:

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

在上面的示例中,display="0" 指定显示屏连接到的端口。input="usb-xhci-hcd.0.auto-1.1/input0" 指定输入设备连接到的端口。要确定与特定设备关联的端口,请使用以下终端命令,然后查看事件中心状态中这些设备的 location 属性。

adb shell dumpsys input

如果连接了许多设备,请点按特定设备以检查输入调度程序状态中的 RecentQueue 数组。然后,您可以识别生成最近事件的那些设备。然后,您可以在事件中心状态中找到相应的设备。

要确定分配给已连接显示屏的显示屏端口,请使用 adb shell dumpsys display,然后查找显示设备下每个显示屏的 DisplayDeviceInfoaddress 属性。或者,使用 adb shell dumpsys SurfaceFlinger --display-id 转储所有已连接显示屏的识别信息。另请参阅静态显示屏标识符

如果您为特定输入设备指定了关联,但系统中不存在相应的显示屏,则输入设备将被禁用,直到相应的显示屏出现。关联仅针对触摸设备执行。

动态多显示屏的路由

Android 10 使您能够设置静态多显示屏设备。动态关联尚未启用。但是,某些用例可以通过为并非始终存在的显示屏和输入面板提供路由信息,或者使用虚拟输入设备,然后为这些虚拟设备提供其他路由信息来解决。如果设备实现支持

  • 具有扩展坞的桌面式体验,则可以提供路由配置,以将来自连接到扩展坞的输入配件(通过端口唯一标识)的输入定向到外部显示屏(通过端口标识)。
  • 当连接到外部显示屏时,主屏幕充当输入源(例如触摸板),则可以提供路由配置,以将来自虚拟触摸面板(通过唯一的虚拟 ID 标识)的输入定向到外部显示屏(通过端口标识)。

实现

  • 对于物理设备,输入设备连接到的端口和显示屏连接到的端口用于将显示屏与触摸屏进行匹配。
  • 映射存储在 InputReaderConfiguration 中。
  • TouchInputMapper.mViewport 被设置为与为 InputDevice.location 指定的端口匹配的视口。
  • 如果在映射文件中指定了输入设备端口,并且当前没有具有匹配显示端口的视口,则该端口上的输入设备将被禁用。
  • 如果未为特定输入设备指定端口,则视口将根据现有规则设置。
  • 输入驱动程序中不需要内核更改。
  • 输入设备端口是使用 EVIOCGPHYS ioctl 确定的。