入力

Android 入力 HAL アイコン

Android の入力サブシステムは、通常、システムの複数のレイヤを走査するイベント パイプラインで構成されます。

入力パイプライン

最下層では、物理的な入力デバイスが、キーの押下やタッチ接触点などの状態変化を表す信号を生成します。デバイスのファームウェアは、USB HID レポートをシステムに送信するか、I2C バスで割り込みを生成するなど、なんらかの方法でこれらの信号をエンコードして送信します。

こうした信号は、Linux カーネルのデバイス ドライバでデコードされます。Linux カーネルは、多くの標準周辺機器、特に HID プロトコルに準拠した周辺機器用のドライバを提供します。一方、OEM は通常、システムに低レベルで緊密に統合された組み込みデバイス(タッチ スクリーンなど)のカスタム ドライバを提供する必要があります。

入力デバイス ドライバは、Linux 入力プロトコルを使用して、デバイス固有の信号を標準の入力イベント形式に変換します。Linux の入力プロトコルは、linux/input.h カーネル ヘッダー ファイル内のイベントタイプとコードの標準セットを定義します。このようにすることで、カーネル外のコンポーネントで、物理スキャンコード、HID 使用状況(HID usage)、I2C メッセージ、GPIO ピンなどの詳細を考慮する必要がなくなります。

次に、Android EventHub コンポーネントが、各入力デバイスに関連付けられている evdev ドライバを開き、カーネルから入力イベントを読み取ります。そして Android InputReader コンポーネントが、デバイスクラスに従って入力イベントをデコードし、Android 入力イベントのストリームを生成します。このプロセスの中で、入力デバイスの設定、キーボード レイアウト ファイル、さまざまなマッピング テーブルに基づいて、Linux 入力プロトコルのイベントコードが Android イベントコードに変換されます。

最後に、InputReader が入力イベントを InputDispatcher に送信し、InputDispatcher がこれらのイベントを適切なウィンドウに転送します。

コントロール ポイント

入力パイプラインには、入力デバイスの動作の制御に影響を与えるいくつかの段階があります。

ドライバとファームウェアの設定

入力デバイス ドライバは、多くの場合、パラメータをレジスタに設定するか、ファームウェア自体をアップロードすることで、入力デバイスの動作を設定します。特に、タッチ スクリーンなどの埋め込み型デバイスの場合が当てはまります。これらのデバイスで期待される精度と応答性を実現してノイズを抑えるには、調整プロセスの大部分をパラメータの調整やファームウェアの修正にあてる必要があります。

通常は、同じドライバが複数の異なるハードウェア実装をサポートできるように、ドライバ設定オプションがカーネル ボード サポート パッケージ(BSP)のモジュール パラメータとして指定されます。

このドキュメントでは、ドライバやファームウェアの設定について説明することを目的としていますが、一般的なデバイス調整に関するガイダンスも提供します。

ボード設定プロパティ

カーネル ボード サポート パッケージ(BSP)は、タッチ スクリーン上の仮想キーの配置など、Android InputReader コンポーネントで使用されるボード設定プロパティを SysFS 経由でエクスポートできます。

ボード設定プロパティを使用するデバイスの詳細については、デバイスクラス セクションをご覧ください。

リソース オーバーレイ

カバースイッチの操作など、いくつかの入力動作は、config.xml のリソース オーバーレイを使用して設定されます。

いくつか例を示します。

  • config_lidKeyboardAccessibility : カバースイッチの効果として、ハードウェア キーボードがアクセス可能か非表示かを指定します。

  • config_lidNavigationAccessibility : カバースイッチの効果として、トラックパッドがアクセス可能か非表示かを指定します。

  • config_longPressOnPowerBehavior : ユーザーが電源ボタンを押し続けたときの動作を指定します。

  • config_lidOpenRotation : 画面の向きに対するカバースイッチの効果を指定します。

各設定オプションの詳細については、frameworks/base/core/res/res/values/config.xml のドキュメントをご覧ください。

キーマップ

Android EventHub および InputReader コンポーネントでは、Linux イベントコードからキー、ジョイスティック ボタン、ジョイスティック軸の Android イベントコードへのマッピングを設定する際に、キーマップを使用します。マッピングはデバイスや言語に依存します。

キーマップを使用する際のデバイスごとに相違点については、デバイスクラスのセクションをご覧ください。

入力デバイス設定ファイル

Android EventHub および InputReader コンポーネントでは、タッチサイズ情報のレポート方法など、特殊なデバイス特性を設定する際に、入力デバイス設定ファイルを使用します。

入力デバイス設定マップを使用する際のデバイスごとの相違点については、デバイスクラスのセクションをご覧ください。

HID 使用状況とイベントコードについて

キーボードの任意のキー、ゲーム コントローラのボタン、ジョイスティックの軸、その他のコントロールを参照する際には、通常、複数の識別子が使用されます。これらの識別子の関係は常に同じではなく、マッピング テーブルでの組み合わせに依存します。マッピング テーブルには固定のものもありますが、デバイスの特性、デバイス ドライバ、現在のロケール、システム構成、ユーザーの好みやその他の要因によって変わるものもあります。

物理スキャンコード

物理スキャンコードは、キー、ボタン、その他コントロールなどに関連付けられたデバイス固有の識別子です。通常、物理スキャンコードはデバイスによって異なるため、ファームウェアやデバイス ドライバによって HID 使用状況や Linux キーコードなどの標準識別子にマッピングされます。

スキャンコードは主にキーボードを対象とし、他のデバイスでは、GPIO ピン、I2C メッセージなどを使用した低レベルでの通信が通常は行なわれます。そのため、ソフトウェア スタックの上位レイヤは、デバイス ドライバを経由して状態を把握します。

HID 使用状況

HID 使用状況は、キーボードのキー、ジョイスティックの軸、マウスボタン、指で接触される点などのコントロールの状態をレポートするために使用される標準の識別子です。USB 入力デバイスと Bluetooth 入力デバイスの大半は HID 仕様に準拠しており、システムとのインターフェースが統一されています。

Android フレームワークでは、Linux カーネルの HID ドライバを使用して、HID 使用状況コードを Linux キーコードなどの識別子に変換します。したがって、HID 使用状況を扱うのは、通常は周辺機器メーカーになります。

Linux キーコード

Linux キーコードは、キーまたはボタンの標準の識別子です。Linux キーコードは、KEY_ または BTN_ のプレフィックスで始まる定数を使用して、linux/input.h ヘッダー ファイルで定義されます。Linux カーネル入力ドライバは、物理スキャンコード、HID 使用状況などのデバイス固有の信号を Linux キーコードに変換し、それらに関する情報を EV_KEY イベントの一部として提供します。

Android API では、キーに関連付けられている Linux キーコードを「スキャンコード」と呼ぶ場合があります。技術的には正しくありませんが、Linux キーコードと API の Android キーコードを区別する際に使われます。

Linux 相対軸コードまたは絶対軸コード

Linux 相対軸コードまたは絶対軸コードは、X 軸に沿ったマウスの相対的な動きや X 軸に沿ったジョイスティックの絶対的な位置など、軸に沿った相対的な動きや絶対位置をレポートするための標準識別子です。Linux 軸コードは、REL_ または ABS_ のプレフィックスで始まる定数を使用して、linux/input.h ヘッダー ファイルで定義されます。Linux カーネル入力ドライバは、HID 使用状況やその他のデバイス固有の信号を Linux 軸コードに変換し、それらの情報を EV_REL イベントおよび EV_ABS イベントの一部として提供します。

Linux スイッチコード

Linux スイッチコードは、カバースイッチなどのデバイス上のスイッチの状態をレポートするための標準識別子です。Linux スイッチコードは、SW_ のプリフィックスで始まる定数を使用して、linux/input.h ヘッダー ファイルで定義されます。Linux カーネル入力ドライバは、スイッチ状態の変化を EV_SW イベントとしてレポートします。

Android アプリケーションは通常スイッチからのイベントを受信しませんが、内部でこれらを使用してさまざまなデバイス固有の機能を制御します。

Android キーコード

Android キーコードは、特定のキー(「HOME」など)を示すために Android API で定義された標準識別子です。Android キーコードは、android.view.KeyEvent クラスによって、KEYCODE_ のプリフィックスで始まる定数として定義されます。

キーレイアウトでは、Linux キーコードを Android キーコードにマッピングする方法を指定します。キーボードのモデル、言語、国、レイアウト、特別な機能に応じて、異なるキーレイアウトを使用できます。

Android キーコードの組み合わせは、デバイスとロケールごとに異なるキー文字マップを使用して文字コードに変換されます。たとえば、KEYCODE_SHIFTKEYCODE_A のキーが同時に押されると、キー文字マップの組み合わせが検索され、大文字の「A」が見つけられます。そして、フォーカスされているテキスト ウィジェットに「A」が挿入されます。

Android 軸コード

Android 軸コードは、Android API で定義され、特定のデバイス軸を示す標準識別子です。Android 軸コードは、android.view.MotionEvent クラスによって、AXIS_ のプリフィックスで始まる定数として定義されます。

キーレイアウトでは、Linux 軸コードを Android 軸コードにマッピングする方法を指定します。デバイスのモデル、言語、国、レイアウト、特別な機能に応じて、異なるキーレイアウトを使用できます。

Android メタ状態

Android メタ状態は、Android API で定義され、どの修飾キーが押されたかを示す標準識別子です。Android メタ状態は、android.view.KeyEvent クラスによって、META_ のプリフィックスで始まる定数として定義されます。

メタ状態は、Android InputReader コンポーネントによって決まります。このコンポーネントは、修飾キー(KEYCODE_SHIFT_LEFT など)が押されるタイミング、または離されたタイミングをモニタリングし、適切なメタ状態フラグを設定またはリセットします。

修飾キーとメタ状態の関係はハードコードされていますが、キーレイアウトによって修飾キー自体のマッピング方法が変更されることがあり、その場合はメタ状態に影響します。

Android ボタン状態

Android ボタン状態は、Android API で定義され、マウスやタッチペンのどのボタンが押されたかを示す標準識別子です。Android ボタン状態は、android.view.MotionEvent クラスによって、BUTTON_ プリフィックスで始まる定数として定義されます。

ボタン状態は、Android InputReader コンポーネントによって決まります。このコンポーネントは、マウスやタッチペンのボタンが押されるタイミング、または離されたタイミングをモニタリングし、適切なボタン状態フラグを設定またはリセットします。

なお、ボタンとボタン状態の関係はハードコードされています。

関連情報

  1. Linux 入力イベントコード
  2. Linux マルチタッチ プロトコル
  3. Linux 入力ドライバ
  4. Linux フォース フィードバック
  5. HID に関する情報(HID 使用状況の表を含む)