Поддержка редактора метода ввода

Ниже приведены изменения, внесенные в эти разделы.

В Android 10 поддерживается виртуальная клавиатура для приложений, запущенных на дополнительном экране.

Приложения, запущенные не на экране по умолчанию

В зависимости от режима работы виртуальная клавиатура редактора метода ввода (IME) может показываться на разных дисплеях. Виртуальная клавиатура показывается на:

  • Тот же дисплей, на котором отображается активное приложение.
  • По умолчанию – экран по умолчанию, когда приложение, на котором сфокусировано внимание, запущено на другом экране.
  • Нет.

Система определяет, какой режим использовать, на основе настроек дисплея, на котором отображается приложение. Подробная информация приведена в следующих статьях:

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

Рисунок 1. Экранная клавиатура IME, которая показывается на дополнительном дисплее, включая целевое приложение

Система использует один IME, но может переключаться между экранами, чтобы следовать за выбранным элементом пользователя. В Android 10 все встроенные и сторонние редакторы методов ввода должны автоматически изменять макет и размер в соответствии с новым размером экрана при создании.

Если на дисплее A есть активное подключение, а поле ввода запрашивает фокус ввода на дисплее B, происходит следующее:

  1. Новое входное подключение поступает из поля ввода на дисплее B.
  2. InputMethodManagerService проверяет, нужно ли одобрить подключение.
  3. Для метода ввода выбран экран. Если дисплей Б поддерживает показ IME и ему разрешено это делать, то используется дисплей Б. В противном случае будет выбран основной экран устройства.
  4. Если выбранный дисплей не относится к дисплею A, подключение устанавливается заново. InputMethodService удаляется и создается заново.

Ограничение безопасности

Система не будет показывать редактор метода ввода на виртуальных дисплеях, которые ей не принадлежат. Это связано с тем, что вредоносное приложение может создать виртуальный экран с включенной поддержкой системных элементов оформления и считывать с него конфиденциальную информацию пользователя, например подсказки при вводе текста и пользовательские фоны.

Реализация

В Android 9 и более ранних версиях редактор метода ввода был доступен только на экране по умолчанию, как описано в разделе Экранные методы ввода. В Android 10 и более поздних версиях пользователь может переключаться между текстовыми полями на разных экранах, меняя фокус. При этом окно редактора метода ввода перемещается на дополнительный экран.

Реализация в WindowManager отслеживает окно способа ввода (окно IME, в котором отрисовывается экранная клавиатура) и целевое окно способа ввода (окно, в которое поступает ввод IME), чтобы управлять состоянием IME.

Для InputMethodManagerService (IMMS) нет встроенного механизма, который мог бы передать изменение отображения в InputMethodService (IMS) и перенастроить раскладку клавиатуры во время выполнения при переходе фокуса на другой экран.

Чтобы окно IME можно было переключать между экранами, в Android 10 реализованы следующие функции:

  • Редактор метода ввода и целевое окно ввода теперь отслеживаются для каждого экрана в DisplayContent#mInputMethodWindow и DisplayContent#mInputMethodTarget, чтобы WindowManager (WM) мог управлять состоянием фокуса редактора метода ввода независимо от каждого экрана.
  • Когда запрос фокуса от клиента приложения с внешнего дисплея поступает через ViewRootImpl#handleWindowFocusChanged -> InputMethodManager#onPostWindowFocus -> IMMS#startInputOrWindowGainedFocus, IMMS сначала отменяет привязку текущего сервиса метода ввода, а затем повторно привязывает сервис, чтобы прикрепить новый токен окна IME для внешнего дисплея в onServiceConnected().
  • После получения IMS#attachToken в IMS происходит следующее:
    • ContextImpl#updateDisplay вызывается для обновления контекста сервиса, отображаемого в InputMethodService#attachToken(). Это вызывает метод ViewGroup#addView(), который изменяет макет клавиатуры и адаптирует его к целевому экрану, проверяя текущий контекст.
    • После вызова DisplayContent#setInputMethodWindowLocked() реализация отправляет изменения конфигурации дисплея на уровне процесса с помощью WindowProcessController в процесс IME, чтобы переопределить ресурсы и показатели дисплея.
    • Клиент InputMethodService получает правильную конфигурацию с правильными показателями отображения после вызова onConfigurationChanged() и ViewGroup#addView() для повторной инициализации представления ввода.