输入法编辑器支持

下面提供了对这些特定于显示区域的更新

Android 10 支持在非默认显示屏上运行的应用使用软件键盘

在非默认显示屏上运行的应用

就哪个显示屏显示输入法编辑器 (IME) 的软件键盘而言,有不同的模式。软件键盘显示在

  • 同一显示屏上,聚焦的应用出现在该显示屏上。
  • 默认显示屏上,而聚焦的应用在非默认显示屏上运行。
  • 根本没有显示屏上。

系统会根据聚焦的应用出现的显示屏的设置,确定要使用哪种模式。如需了解详情,请参阅

  • WindowManager#setDisplayImePolicy()
  • WindowManager#getDisplayImePolicy()

图 1. IME 软件键盘(因为它出现在辅助显示屏上,包括目标应用)

系统使用单个 IME,但可以在显示屏之间切换以跟随用户焦点。Android 10 会自动期望所有第一方和第三方 IME 在创建时根据新的显示屏尺寸修订布局并调整大小。

如果显示屏 A 上有活动连接,并且输入字段在显示屏 B 上请求输入焦点,则会发生以下流程

  1. 来自显示屏 B 上的输入字段的新输入连接。
  2. InputMethodManagerService 检查是否应批准连接。
  3. 为 IME 选择显示屏。如果显示屏 B 支持显示 IME 且被允许显示,则使用 B。否则,选择主设备显示屏。
  4. 如果所选显示屏不是来自显示屏 A,则重新建立连接。InputMethodService 会被销毁,然后再次创建。

安全限制

系统不会在并非系统拥有的虚拟显示屏上显示 IME。这是出于安全考虑,因为恶意应用可能会创建启用系统装饰支持的虚拟显示屏,并从界面读取用户敏感信息,例如输入预测和自定义背景。

实现

在 Android 9(及更低版本)中,IME 仅在默认屏幕上可用,如屏幕输入法中所述。在 Android 10(及更高版本)中,用户可以通过切换焦点在不同显示屏上的不同输入文本字段之间切换,并且 IME 窗口会移动到辅助显示屏。

WindowManager 中的实现会跟踪输入法窗口(绘制软件键盘的 IME 窗口)和输入法目标(IME 输入的目标窗口)以管理 IME 状态。

对于 InputMethodManagerService (IMMS),当焦点移动到另一个显示屏时,没有其他内置机制可以将显示屏更改传播到 InputMethodService (IMS) 并在运行时重新配置键盘布局。

为了实现显示屏之间的 IME 窗口切换,Android 10 实现了以下功能

  • IME 和输入目标窗口现在在 DisplayContent#mInputMethodWindowDisplayContent#mInputMethodTarget 中按显示屏进行跟踪,以便 WindowManager (WM) 可以独立于每个显示屏管理 IME 焦点状态。
  • 在 IMMS 端,当应用客户端从外部显示器收到的焦点请求通过 ViewRootImpl#handleWindowFocusChanged -> InputMethodManager#onPostWindowFocus -> IMMS#startInputOrWindowGainedFocus 接收时,它首先解绑当前的输入法服务,然后在 onServiceConnected() 中重新绑定服务,以重新附加外部显示器的新 IME 窗口令牌。
  • 在 IMS 端,在收到 IMS#attachToken 后,会发生以下流程
    • 调用 ContextImpl#updateDisplay 以在 InputMethodService#attachToken() 中更新服务上下文的显示。 这会调用 ViewGroup#addView() 以修改键盘布局并适应目标显示器,同时检查当前上下文。
    • 在调用 DisplayContent#setInputMethodWindowLocked() 后,实现使用 WindowProcessController 向 IME 进程发送进程级显示配置更改,以覆盖资源和显示指标。
    • onConfigurationChanged()ViewGroup#addView() 调用重新初始化输入视图后,InputMethodService 客户端会获得具有正确显示指标的正确配置。