입력 방식 편집기(IME) 지원

이러한 디스플레이 관련 영역에 적용된 업데이트는 아래와 같습니다.

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#mInputMethodWindowDisplayContent#mInputMethodTarget에서 디스플레이별로 추적됩니다. 이는 WindowManager(WM)가 각 디스플레이와 상관없이 IME 포커스 상태를 관리할 수 있도록 하기 위함입니다.
  • IMMS 측에서는 외부 디스플레이에서 발생한 앱 클라이언트의 포커스 요청이 ViewRootImpl#handleWindowFocusChanged -> InputMethodManager#onPostWindowFocus -> IMMS#startInputOrWindowGainedFocus를 통해 수신되는 경우 먼저 현재의 입력 방법 서비스를 바인딩 해제한 다음 서비스를 다시 바인딩하여 onServiceConnected()의 외부 디스플레이에 새 IME 창 토큰을 다시 연결합니다.
  • IMS 측에서는 IMS#attachToken이 수신된 후에 다음과 같은 흐름이 발생합니다.
    • ContextImpl#updateDisplay가 호출되어 InputMethodService#attachToken()의 서비스 컨텍스트 디스플레이를 업데이트합니다. 그러면 ViewGroup#addView()가 호출되어 키보드의 레이아웃을 수정하고 현재 컨텍스트를 확인 중인 타겟 디스플레이에 맞게 조정됩니다.
    • DisplayContent#setInputMethodWindowLocked()가 호출되면 구현은 WindowProcessController를 사용하여 프로세스 수준의 디스플레이 구성 변경사항을 IME 프로세스로 전송하고 리소스와 디스플레이 측정항목을 재정의합니다.
    • InputMethodService 클라이언트는 입력 보기를 다시 초기화하기 위한 onConfigurationChanged()ViewGroup#addView() 호출 이후에 올바른 디스플레이 측정항목이 포함된 올바른 구성을 가져옵니다.

멀티 세션 입력 방식 편집기(IME) 지원

멀티 사용자가 동시에 사용하여 적절한 입력 소스를 제공할 것으로 기대되는 여러 디스플레이가 포함된 기기 구현은 여러 입력 방식 편집기(IME)를 동시에 표시하도록 구성할 수 있습니다(디스플레이당 최대 1개). 아래의 두 그림은 두 디스플레이의 멀티 세션 IME 샘플을 보여줍니다.

그림 2. 멀티 세션 IME 샘플

그림 3. 멀티 세션 IME 샘플

디스플레이별 포커스가 지원되어야 이 기능을 사용할 수 있습니다. 지원되지 않는 경우에는 이 기능을 사용 설정할 수 없습니다. 보안 제한사항을 이유로 디스플레이별 포커스 제한사항은 이 기능을 기기의 소규모 집합으로 제한합니다.

Android 10에서는 멀티 세션 IME 지원이 여러 API 모음과 축소된 기능을 보유한 별도의 시스템 서비스로 구현됩니다. 멀티 세션 IME는 기존 IME와 호환되지 않습니다. 멀티 세션 또는 단일 세션 서비스 중 하나를 사용할 수는 있지만 둘 다 사용할 수는 없습니다.

InputMethodService 클래스 상단에 빌드된 기존 Android IME는 사용할 수 없습니다. 이는 동시에 단일 IME 클라이언트에 포커스를 맞출 수 있다는 가정이 Android 1.5에 Android IME API가 도입되기 전에 이루어졌고 InputMethodService의 수많은 공개 API가 이미 이러한 가정에 크게 의존했기 때문입니다. 하지만 InputMethodService 클래스가 멀티 클라이언트 시나리오를 지원하도록 업데이트하기는 쉽지 않습니다. 이유는 다음과 같습니다.

  1. 업데이트할 경우 이미 유지가 어려운 InputMethodService에 용납할 수 없을 정도의 복잡성이 발생합니다.
  2. IME 개발자는 계속해서 구현을 업데이트해야만 포커스가 맞춰진 여러 IME 클라이언트의 동시 요청을 지원할 수 있습니다. 이를 위해서는 클라이언트 측의 상당한 재설계가 요구될 수 있습니다(예: 입력 디코더 및 입력 내역 데이터베이스).
  3. 다중 IME 클라이언트와 관련된 실질적인 사용 사례는 급속하게 진화될 것으로 예상됩니다. 따라서 새로운 프로토콜이 불안정하며 공개 API로 노출될 준비가 되지 않았습니다.

단일 세션(일반) IME와 마찬가지로 IME를 개별 디스플레이에 표시하기 위한 제어 작업 역시 DisplayWindowSettings를 사용하여 실행됩니다.

development/samples/MultiClientInputMethod에서 멀티 세션 IME 샘플을 찾아볼 수 있습니다.

멀티 세션 IME를 테스트하는 방법은 다음과 같습니다.

  1. config_perDisplayFocusEnabledtrue로 설정합니다.
  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를 참고하세요.