Input method editor support

Updates made to these display-specific areas are provided below:

Android 10 supports software keyboard for apps running on a non-default display.

Apps running on a non-default display

In terms of which display shows the software keyboard of the Input Method Editor (IME), there are different modes. The software keyboard is shown on the:

  • Same display on which the focused app appears.
  • Default display while the focused app is running on a non-default display.
  • No display at all.

The system determines which mode to use based on the settings of the display on which the focused app appears. For more details, see:

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

Figure 1. IME software keyboard as it appears on secondary display, including target app

The system uses a single IME, but can shift between displays to follow user focus. Android 10 automatically expects all first- and third-party IMEs to revise the layout and resize according to the new display size when created.

If there's an active connection on display A, and an input field requests input focus on display B, then the following flow occurs:

  1. A new input connection comes from the input field on display B.
  2. InputMethodManagerService checks if the connection should be approved.
  3. A display is selected for the IME. If display B supports showing the IME and is allowed to show it, then B is used. Otherwise, the primary device display is selected.
  4. If the selected display is not from display A, then the connection is re-established. InputMethodService is destroyed and then created again.

Security restriction

The system won't show an IME on virtual displays that aren't owned by the system. This is due to a security concern that a malicious app could create a virtual display with enabled system decorations support and read user-sensitive information from the surface, such as typing predictions and custom backgrounds.

Implementation

In Android 9 (and lower), the IME was only available on the default screen, as described in On-Screen Input methods. In Android 10 (and higher), a user can switch between different input text fields on different displays by switching focus, and the IME window moves to the secondary displays.

The implementation in WindowManager tracks the input method window (the IME window where the soft keyboard is drawn) and the input method target (the window where the IME input goes) to manage the IME state.

For InputMethodManagerService (IMMS), no other built-in mechanism can propagate the display change to InputMethodService (IMS) and reconfigure the keyboard layout at runtime when moving focus to another display.

To achieve the IME window switch between displays, Android 10 implements the following:

  • The IME and input target window are now tracked per display in DisplayContent#mInputMethodWindow and DisplayContent#mInputMethodTarget, so that the WindowManager (WM) can manage the IME focus state independently of each display.
  • On the IMMS side, when an app client's focus request from the external display is received through ViewRootImpl#handleWindowFocusChanged -> InputMethodManager#onPostWindowFocus -> IMMS#startInputOrWindowGainedFocus, it first unbinds the current input method service and then rebinds the service to reattach the new IME window token for the external display in onServiceConnected().
  • On the IMS side, after the IMS#attachToken is received, the following flow occurs:
    • ContextImpl#updateDisplay is called to update the service context's display in InputMethodService#attachToken(). This calls ViewGroup#addView() to revise the layout of the keyboard and adapt to the target display checking the current context.
    • After DisplayContent#setInputMethodWindowLocked() is called, the implementation sends process-level display configuration changes using the WindowProcessController to IME process to override resources and display metrics.
    • The InputMethodService client gets the correct configuration with the correct display metrics after onConfigurationChanged() and the ViewGroup#addView() call to reinitialize the input view.