センサーHAL2

Sensors Hardware Abstraction Layer(HAL)は、Androidセンサーフレームワークと、加速度計やジャイロスコープなどのデバイスのセンサーとの間のインターフェースです。センサーHALは、フレームワークがセンサーを制御できるようにするために実装する必要のある機能を定義します。

Sensors HAL 2.0は、Android 10以降で、新規およびアップグレードされたデバイスで使用できます。 Sensors HAL2.0はSensorsHAL 1.0に基づいていますが、下位互換性を妨げるいくつかの重要な違いがあります。センサーHAL2.0は、高速メッセージキュー(FMQ)を使用して、センサーイベントをHALからAndroidセンサーフレームワークに送信します。

Sensors HAL 2.1は、Android 11以降で、新規およびアップグレードされたデバイスで使用できます。 Sensors HAL 2.1は、Sensors HAL 2.0のイテレーションであり、 HINGE_ANGLEセンサータイプを公開し、 HINGE_ANGLEタイプを受け入れるようにさまざまなメソッドを更新します。

HAL2.1インターフェース

Sensors HAL 2.1のドキュメントの主なソースは、 hardware / interfaces / Sensors / 2.1 /ISensors.halのHAL定義内にあります。このページとISensors.halの間に要件の競合がある場合は、 ISensors.halの要件を使用してください。

HAL2.0インターフェース

Sensors HAL 2.0のドキュメントの主なソースは、 hardware / interfaces / Sensors / 2.0 /ISensors.halのHAL定義内にあります。このページとISensors.halの間に要件の競合がある場合は、 ISensors.halの要件を使用してください。

センサーHAL2.0およびHAL2.1の実装

Sensors HAL 2.0または2.1を実装するには、オブジェクトがISensorsインターフェイスを拡張し、 2.0/ISensors.halまたは2.1/ISensors.halで定義されているすべての関数を実装する必要があります。

HALの初期化

センサーHALは、使用する前にAndroidセンサーフレームワークによって初期化される必要があります。フレームワークは、HAL 2.0のinitialize_2_1()関数とHAL 2.1のinitialize_2_1 initialize()関数を呼び出して、センサーHALに3つのパラメーター(2つのFMQ記述子とISensorsCallbackオブジェクトへの1つのポインター)を提供します。

HALは最初の記述子を使用して、センサーイベントをフレームワークに書き込むために使用されるイベントFMQを作成します。 HALは、2番目の記述子を使用して、HALがWAKE_UPセンサーイベントのウェイクロックを解放するときに同期するために使用されるウェイクロックFMQを作成します。 HALは、必要なコールバック関数を呼び出すことができるように、 ISensorsCallbackオブジェクトへのポインターを保存する必要があります。

initialize()またはinitialize_2_1()関数は、センサーHALを初期化するときに呼び出される最初の関数である必要があります。

利用可能なセンサーの公開

デバイスで使用可能なすべての静的センサーのリストを取得するには、HAL 2.0ではgetSensorsList_2_1() getSensorsList()を使用し、HAL 2.1ではgetSensorsList_2_1()関数を使用します。この関数は、センサーのリストを返します。各センサーは、ハンドルによって一意に識別されます。センサーHALをホストしているプロセスが再起動するときに、特定のセンサーのハンドルを変更してはなりません。ハンドルは、デバイスの再起動間、およびシステムサーバーの再起動間で変更される場合があります。

複数のセンサーが同じセンサータイプとウェイクアッププロパティを共有している場合、リストの最初のセンサーはデフォルトセンサーと呼ばれ、 getDefaultSensor(int sensorType, bool wakeUp)関数を利用するアプリに返されます。

センサーリストの安定性

Sensors HALの再起動後、 getSensorsList()またはgetSensorsList_2_1() )によって返されたデータが、再起動前に取得されたセンサーリストと比較して大幅な変更を示している場合、フレームワークはAndroidランタイムの再起動をトリガーします。センサーリストの重要な変更には、特定のハンドルを持つセンサーが欠落しているか、属性が変更されている場合、または新しいセンサーが導入されている場合が含まれます。 Androidランタイムの再起動はユーザーに混乱をもたらしますが、Androidフレームワークは、静的(非動的)センサーがアプリの存続期間中に変更されないというAndroid APIコントラクトを満たすことができなくなるため、これが必要になります。これにより、フレームワークがアプリによって行われたアクティブなセンサーリクエストを再確立できなくなる可能性もあります。したがって、HALベンダーは、回避可能なセンサーリストの変更を防ぐことをお勧めします。

安定したセンサーハンドルを確保するには、HALはデバイス内の特定の物理センサーをそのハンドルに決定論的にマッピングする必要があります。 Sensors HALインターフェースでは特定の実装が義務付けられていませんが、開発者はこの要件を満たすために利用できるいくつかのオプションを利用できます。

たとえば、センサーリストは、ベンダー、モデル、センサータイプなど、各センサーの固定属性の組み合わせを使用して並べ替えることができます。別のオプションは、デバイスの静的センサーのセットがハードウェアで固定されているという事実に依存しているため、HALは、 getSensorsList()またはgetSensorsList_2_1() )から戻る前に、予想されるすべてのセンサーが初期化を完了したことを知る必要があります。この予想されるセンサーのリストは、HALバイナリにコンパイルするか、ファイルシステムの構成ファイルに保存することができ、出現順序を使用して安定したハンドルを導出できます。最善の解決策はHALの特定の実装の詳細によって異なりますが、重要な要件は、センサーハンドルがHALの再起動時に変更されないことです。

センサーの構成

センサーをアクティブにする前に、 batch()関数を使用して、サンプリング期間と最大レポート待ち時間をセンサーに構成する必要があります。

センサーは、センサーデータを失うことなく、 batch()を使用していつでも再構成できる必要があります。

サンプリング期間

サンプリング期間は、構成されているセンサータイプに基づいて異なる意味を持ちます。

  • 連続:センサーイベントは連続レートで生成されます。
  • 変更時:イベントはサンプリング期間よりも速く生成されることはなく、測定値が変化しない場合は、サンプリング期間よりも遅いレートで生成される可能性があります。
  • ワンショット:サンプリング周期は無視されます。
  • 特別:詳細については、センサータイプを参照してください。

サンプリング期間とセンサーのレポートモード間の相互作用については、レポートモードを参照してください。

最大レポート待ち時間

最大レポート遅延は、SoCが起動している間にHALを介してイベントFMQに書き込まれる前に、イベントを遅延させてハードウェアFIFOに格納できる最大時間をナノ秒単位で設定します。

ゼロの値は、イベントが測定されたらすぐに報告する必要があることを意味します。FIFOを完全にスキップするか、センサーからの1つのイベントがFIFOに存在するとすぐにFIFOを空にします。

たとえば、50 Hzでアクティブ化され、最大レポート遅延がゼロの加速度計は、SoCが起動しているときに1秒間に50回割り込みをトリガーします。

最大レポート待ち時間がゼロより大きい場合、センサーイベントは検出されたらすぐにレポートする必要はありません。イベントが最大レポート待ち時間を超えて遅延しない限り、イベントをハードウェアFIFOに一時的に保存し、バッチでレポートすることができます。前のバッチ以降のすべてのイベントが記録され、一度に返されます。これにより、SoCに送信される割り込みの数が減り、センサーがデータをキャプチャしてバッチ処理している間、SoCを低電力モードに切り替えることができます。

各イベントにはタイムスタンプが関連付けられています。イベントが報告される時間を遅らせても、イベントのタイムスタンプに影響を与えてはなりません。タイムスタンプは正確であり、イベントが報告された時間ではなく、イベントが物理的に発生した時間に対応している必要があります。

最大レポート待ち時間がゼロ以外のセンサーイベントのレポートに関する追加情報と要件については、バッチ処理を参照してください。

センサーのアクティブ化

フレームワークは、 activate()関数を使用してセンサーを有効または無効にします。センサーをアクティブ化する前に、フレームワークは最初にbatch()を使用してセンサーを構成する必要があります。

センサーが非アクティブ化された後、そのセンサーからの追加のセンサーイベントをイベントFMQに書き込まないでください。

フラッシングセンサー

センサーがセンサーデータをバッチ処理するように構成されている場合、フレームワークは、 flush()を呼び出すことにより、バッチ処理されたセンサーイベントの即時フラッシュを強制できます。これにより、指定されたセンサーハンドルのバッチセンサーイベントがすぐにイベントFMQに書き込まれます。 Sensors HALは、 flush()の呼び出しの結果として書き込まれるセンサーイベントの最後にflushcompleteイベントを追加する必要があります。

フラッシュは非同期で行われます(つまり、この関数はすぐに戻る必要があります)。実装が複数のセンサーに単一のFIFOを使用する場合、そのFIFOはフラッシュされ、フラッシュ完了イベントは指定されたセンサーにのみ追加されます。

指定されたセンサーにFIFOがない場合(バッファリングが不可能)、または呼び出し時にFIFOが空であった場合でも、 flush()は成功し、そのセンサーのフラッシュ完了イベントを送信する必要があります。これは、ワンショットセンサー以外のすべてのセンサーに適用されます。

ワンショットセンサーに対してflush()が呼び出された場合、flush( flush()BAD_VALUEを返す必要があり、flushcompleteイベントを生成しないようにする必要があります。

FMQへのセンサーイベントの書き込み

イベントFMQは、センサーHALがセンサーイベントをAndroidセンサーフレームワークにプッシュするために使用されます。

イベントFMQは同期されたFMQです。つまり、使用可能なスペースよりも多くのイベントをFMQに書き込もうとすると、書き込みに失敗します。このような場合、HALは、現在のイベントのセットを2つの小さなイベントのグループとして書き込むか、十分なスペースが利用可能なときにすべてのイベントを一緒に書き込むかを決定する必要があります。

Sensors HALが必要な数のセンサーイベントをイベントFMQに書き込んだ場合、Sensors HALは、 EventQueueFlagBits::READ_AND_PROCESSビットをEventFMQのEventFlag::wake関数に書き込むことにより、イベントの準備ができたことをフレームワークに通知する必要があります。 EventFlagは、 EventFlag::createEventFlagとイベントFMQのgetEventFlagWord()関数を使用して、イベントFMQから作成できます。

センサーwriteBlocking / 2.1は、イベントFMQでのwriteと書き込みブロッキングの両方をサポートします。デフォルトの実装は、 writeを使用するためのリファレンスを提供します。 writeBlocking関数を使用する場合は、 readNotificationフラグをEventQueueFlagBits::EVENTS_READに設定する必要があります。これは、フレームワークがイベントFMQからイベントを読み取るときに設定されます。書き込み通知フラグは、 EventQueueFlagBits::READ_AND_PROCESSに設定する必要があります。これは、イベントがイベントFMQに書き込まれたことをフレームワークに通知します。

WAKE_UPイベント

WAKE_UPイベントは、アプリケーションプロセッサ(AP)をウェイクアップさせ、イベントを即座に処理するセンサーイベントです。 WAKE_UPイベントがイベントFMQに書き込まれるときは常に、センサーHALは、フレームワークがイベントを処理できるようになるまでシステムがスリープ状態を維持できるように、ウェイクロックを保護する必要があります。 WAKE_UPイベントを受信すると、フレームワークは独自のウェイクロックを保護し、センサーHALがウェイクロックを解放できるようにします。 Sensors HALがウェイクロックを解放するときに同期するには、ウェイクロックFMQを使用します。

センサーHALは、Wake Lock FMQを読み取って、フレームワークが処理したWAKE_UPイベントの数を判別する必要があります。 HALは、未処理のWAKE_UPイベントの総数がゼロの場合にのみ、 WAKE_UPイベントのウェイクロックを解放する必要があります。センサーイベントを処理した後、フレームワークはWAKE_UPイベントとしてマークされたイベントの数をカウントし、この数をWake LockFMQに書き戻します。

フレームワークは、Wake Lock FMQにデータを書き込むたびに、 WakeLockQueueFlagBits::DATA_WRITTEN書き込み通知をWakeLockFMQに設定します。

動的センサー

動的センサーは、物理的にはデバイスの一部ではありませんが、加速度計を備えたゲームパッドなど、デバイスへの入力として使用できるセンサーです。

動的センサーが接続されている場合、ISensorsCallbackのonDynamicSensorConnected関数はISensorsCallbackから呼び出す必要があります。これにより、新しい動的センサーのフレームワークに通知され、フレームワークを介してセンサーを制御し、センサーのイベントをクライアントが消費できるようになります。

同様に、動的センサーが切断された場合、ISensorsCallbackのonDynamicSensorDisconnected関数をISensorsCallbackて、フレームワークが使用できなくなったセンサーを削除できるようにする必要があります。

ダイレクトチャネル

ダイレクトチャネルは、AndroidセンサーフレームワークをバイパスするイベントFMQではなく、センサーイベントが特定のメモリに書き込まれる操作方法です。直接チャネルを登録するクライアントは、直接チャネルの作成に使用されたメモリからセンサーイベントを直接読み取る必要があり、フレームワークを介してセンサーイベントを受信しません。 configDirectReport()関数は、通常の操作のbatch()に似ており、直属の部下のチャネルを構成します。

registerDirectChannel()およびunregisterDirectChannel()関数は、新しい直接チャネルを作成または破棄します。

動作モード

setOperationMode()関数を使用すると、フレームワークがセンサーを構成して、フレームワークがセンサーデータをセンサーに挿入できるようになります。これは、特にフレームワークの下に存在するアルゴリズムのテストに役立ちます。

HAL 2.0のinjectSensorData()関数とHAL 2.0のinjectSensorsData_2_1()関数は、通常、操作パラメーターをセンサーHALにプッシュするために使用されます。この関数を使用して、センサーイベントを特定のセンサーに挿入することもできます。

検証

Sensors HALの実装を検証するには、センサーのCTSおよびVTSテストを実行します。

CTSテスト

センサーCTSテストは、自動CTSテストと手動CTSベリファイアアプリの両方に存在します。

自動テストは、 cts / tests / Sensor / src / android / hardware / ctsにあります。これらのテストは、センサーのアクティブ化、バッチ処理、センサーイベントレートなど、センサーの標準機能を検証します。

CTS Verifierテストは、 cts / apps / CtsVerifier / src / com / android / cts / verifier / sensorsにあります。これらのテストでは、テストオペレーターからの手動入力が必要であり、センサーが正確な値を報告することを確認します。

CTSテストに合格することは、テスト対象のデバイスがすべてのCDD要件を満たしていることを確認するために重要です。

VTSテスト

センサーHAL2.0のVTSテストは、ハードウェア/インターフェース/センサー/2.0/vtsにあります。センサーHAL2.1のVTSテストは、ハードウェア/インターフェース/センサー/2.1/vtsにあります。これらのテストは、Sensors HALが適切に実装され、 ISensors.halおよびISensorsCallback.hal内のすべての要件が適切に満たされていることを確認します。

2.0からSensorsHAL2.1へのアップグレード

2.0からSensorsHAL 2.1にアップグレードする場合、HAL実装には、HAL 2.1タイプとともに、 initialize_2_1()getSensorsList_2_1() 、およびinjectSensorsData_2_1()メソッドを含める必要があります。これらのメソッドは、上記のHAL2.0で概説されているのと同じ要件を満たす必要があります。

マイナーバージョンのHALは、以前のHALのすべての機能をサポートする必要があるため、2.1HALは2.0HALとしての初期化をサポートする必要があります。両方のHALバージョンをサポートする複雑さを回避するために、Multi-HAL2.1を使用することを強くお勧めします。

独自のSensors2.1 HALを実装する方法の例については、 Sensors.hを参照してください。

1.0からSensorsHAL2.0へのアップグレード

1.0からSensorsHAL 2.0にアップグレードする場合は、HALの実装が次の要件を満たしていることを確認してください。

HALの初期化

フレームワークとHALの間にFMQを確立するには、 initialize()関数をサポートする必要があります。

利用可能なセンサーの公開

Sensors HAL 2.0では、 getSensorsList()関数は、Sensors HALが再起動した場合でも、単一のデバイスの起動中に同じ値を返す必要があります。 getSensorsList()関数の新しい要件は、Sensors HALの再起動後も、単一のデバイスの起動中に同じ値を返す必要があることです。これにより、システムサーバーが再起動した場合に、フレームワークがセンサー接続の再確立を試みることができます。 getSensorsList()によって返される値は、デバイスが再起動を実行した後に変更される可能性があります。

FMQへのセンサーイベントの書き込み

センサーHAL2.0では、 poll()が呼び出されるのを待つ代わりに、センサーHALは、センサーイベントが使用可能な場合は常に、センサーイベントをイベントFMQにプロアクティブに書き込む必要があります。 HALは、フレームワーク内でFMQを読み取るために、 EventFlagに正しいビットを書き込む役割も果たします。

WAKE_UPイベント

poll() WAKE_UP 1.0 poll() 、フレームワークがすべてのWAKE_UPイベントを処理し、必要に応じて、ロックを解除します。 Sensors HAL 2.0では、フレームワークがFMQに書き込まれたイベントを処理したことをHALが認識しなくなったため、Wake Lock FMQを使用すると、フレームワークはWAKE_UPイベントを処理したときにHALと通信できます。

Sensors HAL 2.0では、 WAKE_UPイベント用にSensors HALによって保護されているウェイクロックは、 SensorsHAL_WAKEUPで開始する必要があります。

動的センサー

動的センサーは、Sensors HAL 1.0のpoll()関数を使用して返されました。 Sensors HAL 2.0では、動的センサー接続が変更されるたびに、 ISensorsCallbackonDynamicSensorsConnectedおよびonDynamicSensorsDisconnectedが呼び出される必要があります。これらのコールバックは、 initialize()関数を介して提供されるISensorsCallbackポインターの一部として使用できます。

動作モード

WAKE_UPセンサーのDATA_INJECTIONモードは、Sensors HAL2.0でサポートされている必要があります。

マルチHALサポート

Sensors HAL 2.0および2.1は、 SensorsMulti-HALフレームワークを使用したmulti-HALをサポートします。実装の詳細については、 Sensors HAL1.0からの移植を参照してください。