下面提供了对这些显示特定区域所做的更新:
Android 10 支持在非默认显示器上运行的应用程序的软件键盘。
在非默认显示器上运行的应用程序
在哪个显示器显示输入法编辑器 (IME) 的软件键盘方面,有两种不同的模式。软件键盘显示在:
- 显示焦点应用程序的显示器相同。
- 焦点应用程序在非默认显示器上运行时的默认显示。
系统根据显示焦点应用程序的显示器的设置来确定使用哪种模式。有关详细信息,请参阅:
-
DisplayWindowSettings#shouldShowImeLocked()
-
DisplayWindowSettings#setShouldShowImeLocked()
图 1.显示在辅助显示屏上的 IME 软件键盘,包括目标应用程序
该系统使用单个 IME,但可以在显示之间切换以跟随用户的焦点。 Android 10 自动要求所有第一方和第三方 IME 在创建时根据新的显示尺寸修改布局和调整大小。
如果显示器 A 上存在活动连接,并且输入字段请求显示器 B 上的输入焦点,则将发生以下流程:
- 新的输入连接来自显示器 B 上的输入字段。
-
InputMethodManagerService
检查连接是否应该被批准。 - 为 IME 选择了一个显示器。如果显示器 B 支持显示 IME 并且允许显示它,则使用 B。否则,选择主设备显示器。
- 如果所选显示器不是来自显示器 A,则重新建立连接。
InputMethodService
被销毁,然后再次创建。
安全限制
系统不会在不属于系统的虚拟显示器上显示 IME。这是出于安全考虑,恶意应用程序可能会创建具有启用的系统装饰支持的虚拟显示,并从表面读取用户敏感信息,例如键入预测和自定义背景。
执行
在 Android 9(及更低版本)中,IME 仅在默认屏幕上可用,如屏幕输入法中所述。在 Android 10(及更高版本)中,用户可以通过切换焦点在不同显示器上的不同输入文本字段之间切换,并且 IME 窗口会移动到辅助显示器。
WindowManager
中的实现跟踪输入法窗口(绘制软键盘的 IME 窗口)和输入法目标(IME 输入所在的窗口)以管理 IME 状态。
对于InputMethodManagerService
(IMMS),没有其他内置机制可以将显示更改传播到InputMethodService
(IMS) 并在将焦点移动到另一个显示器时在运行时重新配置键盘布局。
为了实现 IME 窗口在显示器之间的切换,Android 10 实现了以下功能:
- IME 和输入目标窗口现在在
DisplayContent#mInputMethodWindow
和DisplayContent#mInputMethodTarget
中按显示器进行跟踪,以便 WindowManager (WM) 可以独立于每个显示器管理 IME 焦点状态。 - 在 IMMS 端,当通过
ViewRootImpl#handleWindowFocusChanged -> InputMethodManager#onPostWindowFocus -> IMMS#startInputOrWindowGainedFocus
接收到来自外部显示器的应用程序客户端的焦点请求时,它首先解除绑定当前输入法服务,然后重新绑定服务以重新附加新的 IMEonServiceConnected()
中外部显示的窗口令牌。 - 在IMS端,收到
IMS#attachToken
后,会出现如下流程:- 调用
ContextImpl#updateDisplay
以更新服务上下文在InputMethodService#attachToken()
中的显示。这会调用ViewGroup#addView()
来修改键盘布局并适应目标显示并检查当前上下文。 - 调用
DisplayContent#setInputMethodWindowLocked()
后,该实现使用WindowProcessController
向 IME 进程发送进程级显示配置更改,以覆盖资源和显示指标。 -
InputMethodService
客户端在onConfigurationChanged()
和ViewGroup#addView()
调用后获得正确的配置和正确的显示指标以重新初始化输入视图。
- 调用
多会话输入法编辑器支持
具有多个显示器的设备实现预计将被多个用户同时使用以提供适当的输入源,可以配置为同时显示多个输入法编辑器 (IME),每个显示器最多一个。以下两个图显示了两个显示器上的示例多会话 IME:
图 2.示例多会话 IME
图 3.示例多会话 IME
支持Per-display focus是此功能的先决条件。如果不是,则无法启用此功能。由于安全限制,每个显示器的焦点限制将此功能限制在一小部分设备上。
在 Android 10 中,对多会话 IME 的支持是通过具有不同 API 集和缩减功能的单独系统服务实现的。多会话 IME 与现有 IME 不兼容。可以使用多会话或单会话服务,但不能同时使用两者。
不可能使用在InputMethodService
类之上构建的现有 Android IME,因为在 Android IME API 被引入 Android 1.5 之前就假设可以同时关注单个 IME 客户端,并且InputMethodService
中的许多公共 API 已经已经在很大程度上依赖于该假设。但是,更新InputMethodService
类以支持多客户端场景具有挑战性,因为:
- 这样做会给
InputMethodService
带来不可接受的复杂性,而这已经很难维护了。 - IME 开发人员仍然需要更新他们的实现,以便能够支持来自多个集中 IME 客户端的并行请求,这可能需要在他们这边进行重大的重新设计(例如输入解码器和键入历史数据库)。
- 多 IME 客户端的实际用例预计会迅速发展,因此新协议不稳定,还没有准备好作为公共 API 公开。
与单会话(常规)IME 一样,控制在单个显示器上显示 IME 是使用DisplayWindowSettings
执行的。
在development/samples/MultiClientInputMethod
中有一个示例多会话 IME。
要测试多会话 IME:
- 将
config_perDisplayFocusEnabled
设置为true
。 - 运行这些命令:
-
$ make -j MultiClientInputMethod
-
$ adb install -r $OUT/system/priv-app/MultiClientInputMethod/MultiClientInputMethod.apk
-
$ adb root
-
$ adb shell setprop persist.debug.multi_client_ime \
com.example.android.multiclientinputmethod/.MultiClientInputMethod -
$ adb reboot
-
- 尝试多种文本输入方案。
执行
有关实施细节,请参阅MultiClientInputMethodManagerService
。