これらのディスプレイ固有の領域に加えられた更新を以下に示します。
Android 10 は、デフォルト以外のディスプレイで実行されるアプリのソフトウェア キーボードをサポートしています。
デフォルト以外のディスプレイで実行されているアプリ
入力方式エディター (IME) のソフトウェア キーボードを表示するディスプレイには、2 つの異なるモードがあります。ソフトウェア キーボードは次の場所に表示されます。
- フォーカスされたアプリが表示される同じディスプレイ。
- フォーカスされたアプリがデフォルト以外のディスプレイで実行されている間のデフォルトのディスプレイ。
システムは、フォーカスされたアプリが表示されるディスプレイの設定に基づいて、使用するモードを決定します。詳細については、次を参照してください。
-
DisplayWindowSettings#shouldShowImeLocked()
-
DisplayWindowSettings#setShouldShowImeLocked()
図 1.セカンダリ ディスプレイに表示される IME ソフトウェア キーボード (ターゲット アプリを含む)
システムは 1 つの 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
#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) を同時に表示するように構成できます (ディスプレイごとに最大 1 つ)。次の 2 つの図は、2 つのディスプレイでのマルチセッション IME の例を示しています。
図 2.マルチセッション IME の例
図 3.マルチセッション IME の例
ディスプレイごとのフォーカスのサポートは、この機能の前提条件です。そうでない場合、この機能を有効にすることはできません。セキュリティ上の制限により、ディスプレイごとのフォーカス制限により、この機能はデバイスの小さなサブセットに制限されていました。
Android 10 では、マルチセッション IME のサポートは、API のセットが異なり、機能が制限された個別のシステム サービスで実装されます。マルチセッション IME は、既存の IME と互換性がありません。マルチセッション サービスまたはシングルセッション サービスのいずれかを使用できますが、両方を使用することはできません。
Android 1.5 で Android IME API が導入さInputMethodService
InputMethodService
多くのパブリック API がすでにその仮定に大きく依存しています。ただし、マルチクライアント シナリオをサポートするように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
を参照してください。