Обновления, внесенные в эти области отображения, представлены ниже:
- Приложения, работающие на дисплее, отличном от стандартного
- Поддержка редактора многосессионного метода ввода
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
, он сначала отвязывает текущую службу метода ввода, а затем повторно привязывает службу для повторного подключения нового 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
для поддержки многоклиентского сценария является сложной задачей, поскольку:
- Это привело бы к неприемлемой сложности
InputMethodService
, которую и без того сложно поддерживать. - Разработчикам IME по-прежнему необходимо обновить свою реализацию, чтобы иметь возможность поддерживать параллельные запросы от нескольких целевых клиентов IME, что может потребовать нетривиального редизайна с их стороны (например, декодера ввода и базы данных истории ввода).
- Ожидается, что фактические варианты использования для клиентов с несколькими IME будут быстро развиваться, поэтому новый протокол нестабилен и не готов к использованию в качестве общедоступных API.
Как и в случае с односессионным (обычным) IME, управление отображением IME на отдельных дисплеях осуществляется с помощью DisplayWindowSettings
.
Образец многосеансового IME находится по адресу development/samples/MultiClientInputMethod
.
Чтобы протестировать многосеансовый 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
.