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

Обновления, внесенные в эти области отображения, представлены ниже:

Android 10 поддерживает программную клавиатуру для приложений, работающих не на дисплее по умолчанию.

Приложения, работающие на дисплее, отличном от стандартного

С точки зрения того, на каком дисплее отображается программная клавиатура редактора метода ввода (IME), существует два разных режима. Программная клавиатура показана на:

  • Тот же дисплей, на котором отображается целевое приложение.
  • Отображение по умолчанию , когда целевое приложение работает на дисплее, отличном от экрана по умолчанию.

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

  • DisplayWindowSettings#shouldShowImeLocked()
  • DisplayWindowSettings#setShouldShowImeLocked()

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

Поддержка редактора многосессионного метода ввода

Реализации устройств с несколькими дисплеями, которые, как ожидается, будут одновременно использоваться несколькими пользователями для обеспечения соответствующих источников ввода, могут быть настроены для одновременного отображения нескольких редакторов методов ввода (IME), не более одного на каждый дисплей. На следующих двух рисунках показан пример многосеансового IME на двух дисплеях:

Рис. 2. Пример многосеансового IME

Рис. 3. Пример многосеансового IME

Поддержка фокусировки на каждом дисплее является необходимым условием для этой функции. В противном случае эта функция не может быть включена. Из-за ограничений безопасности ограничение фокуса для каждого дисплея ограничивало эту функцию небольшим подмножеством устройств.

В Android 10 поддержка многосессионных IME реализована с помощью отдельных системных служб с другим набором API и ограниченной функциональностью. Многосеансовый IME несовместим с существующими IME. Можно использовать либо многосеансовый, либо односеансовый сервис, но не оба одновременно.

Невозможно использовать существующие IME Android, созданные поверх класса InputMethodService , потому что предположение, что один клиент IME может быть сфокусирован одновременно, было сделано до того, как API Android IME были представлены в Android 1.5, и многие общедоступные API в InputMethodService имеют уже сильно полагался на это предположение. Однако обновление класса InputMethodService для поддержки многоклиентского сценария является сложной задачей, поскольку:

  1. Это привело бы к неприемлемой сложности InputMethodService , которую и без того сложно поддерживать.
  2. Разработчикам IME по-прежнему необходимо обновить свою реализацию, чтобы иметь возможность поддерживать параллельные запросы от нескольких целевых клиентов IME, что может потребовать нетривиального редизайна с их стороны (например, декодера ввода и базы данных истории ввода).
  3. Ожидается, что фактические варианты использования для клиентов с несколькими IME будут быстро развиваться, поэтому новый протокол нестабилен и не готов к использованию в качестве общедоступных API.

Как и в случае с односессионным (обычным) IME, управление отображением IME на отдельных дисплеях осуществляется с помощью DisplayWindowSettings .

Образец многосеансового IME находится по адресу development/samples/MultiClientInputMethod .

Чтобы протестировать многосеансовый IME:

  1. Установите для config_perDisplayFocusEnabled значение true .
  2. Запустите эти команды:
    1. $ make -j MultiClientInputMethod
    2. $ adb install -r $OUT/system/priv-app/MultiClientInputMethod/MultiClientInputMethod.apk
    3. $ adb root
    4. $ adb shell setprop persist.debug.multi_client_ime \
      com.example.android.multiclientinputmethod/.MultiClientInputMethod
    5. $ adb reboot
  3. Попробуйте несколько сценариев ввода текста.

Реализация

Дополнительные сведения о реализации см. в разделе MultiClientInputMethodManagerService .