センサー Multi-HAL は、センサー HAL と他のセンサー HAL の併用を可能にするフレームワークです。センサー Multi-HAL は、動的ライブラリとして保存されたセンサーサブ HAL をベンダー パーティションに動的に読み込んで、イベントのポストと wake lock の取得および解放を処理できるコールバック オブジェクトを提供します。センサーサブ HAL は、ベンダー パーティションの共有オブジェクトに組み込まれ、マルチ HAL フレームワークで使用されるセンサー HAL です。これらのサブ HAL は、相互にまたはプロセスのメイン関数を含むマルチ HAL コードに依存しません。
Android 11 以降を搭載するデバイスで利用可能なセンサー Multi-HAL 2.1 は、センサー Multi-HAL 2.0 の後継です。この HAL は、ヒンジ角度センサーのタイプを公開できるサブ HAL の読み込みをサポートしています。このセンサータイプをサポートするには、サブ HAL で 2.1 SubHal ヘッダーで定義されているサブ HAL API を使用する必要があります。
センサー AIDL HAL を使用する Android 13 以降を搭載したデバイスでは、Multi-HAL shim レイヤを使用して Multi-HAL 機能を有効にできます。実装の詳細については、センサー AIDL HAL でのセンサー Multi-HAL の使用をご覧ください。
センサー Multi-HAL 2 とセンサー HAL 2 の相違点
センサー Multi-HAL 2(Android 10 以降を搭載しているデバイスで利用可能)では、センサー HAL 2 の上に複数の抽象化が導入され、HAL API を簡単に操作できるようになりました。センサー Multi-HAL 2 には、HalProxy クラスが導入されており、センサー HAL 2 インターフェースと V2_1/SubHal
(または V2_0/SubHal
)インターフェースの実装を処理し、HalProxy
がサブ HAL を操作できるようにします。
ISensorsSubHal
インターフェースは、2.1/ISensors.hal
(または 2.0/ISensors.hal
)インターフェースとは次の点で異なります。
- 初期化メソッドは、2 つの FMQ と
ISensorsCallback
ではなくIHalProxyCallback
クラスを渡します。 - サブ HAL は、バグレポートにデバッグ情報を表示するデバッグ関数を実装する必要があります。
- 読み込まれたサブ HAL を他のサブ HAL と区別できるように、サブ HAL は名前関数を実装する必要があります。
センサー Multi-HAL 2 とセンサー HAL 2 の主な相違点は、初期化関数にあります。IHalProxyCallback
インターフェースには、FMQ の代わりに、センサー イベントをセンサー フレームワークにポストするメソッドと、wake lock を作成するメソッドの 2 つのメソッドが用意されています。センサー Multi-HAL は内部で FMQ とのすべてのインタラクションを管理し、すべてのサブ HAL のセンサー イベントをタイムリーに配信できるようにします。サブ HAL で createScopedWakelock
メソッドを使用して wake lock をタイムアウトする際の負荷をセンサー Multi-HAL に委任し、センサー Multi-HAL 全体で wake lock の使用を 1 つの共通の wake lock に一元化することが強く推奨されます。これにより、ロックとロック解除の呼び出しが最小限に抑えられます。
センサー Multi-HAL 2 には、いくつかの安全機能も内蔵されています。こうした機能により、センサー FMQ に空きがなくなった状況や、Android センサー フレームワークが再起動されてセンサーの状態をリセットする必要がある状況に対処します。さらに、イベントが HalProxy
クラスにポストされても、センサー フレームワークで直ちにイベントを受け入れることができない場合、センサー Multi-HAL はイベントをバックグラウンド スレッドに移動して、イベントがポストされるのを待機しながら、すべてのサブ HAL で処理を続行できます。
ソースコードとリファレンス実装
すべてのセンサー Multi-HAL コードは hardware/interfaces/sensors/common/default/2.X/multihal/
で入手できます。以下のリソースをご覧ください。
HalProxy.h
:HalProxy
オブジェクトはセンサー Multi-HAL によってインスタンス化され、サブ HAL からセンサー フレームワークにデータを渡す作業を処理します。HalProxy.cpp
:HalProxy
の実装には、サブ HAL とセンサー フレームワーク間の通信を多重化する際に必要なすべてのロジックが含まれています。SubHal.h
:ISensorsSubHal
インターフェースは、HalProxy
との互換性を持つサブ HAL に必要なインターフェースを定義します。サブ HAL は初期化メソッドを実装して、postEvents
とcreateScopedWakelock
に対してHalProxyCallback
オブジェクトを使用できるようにします。Multi-HAL 2.0 の実装では、
SubHal.h
のバージョン 2.0 を使用します。hardware/interfaces/sensors/common/default/2.X/multihal/tests/
: これらの単体テストでは、HalProxy
の実装を検証します。hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/
: このサンプルのサブ HAL の実装では、疑似センサーを使用して偽のデータを生成します。デバイス上で複数のサブ HAL がどのように動作するかをテストする場合に有用です。
実装
このセクションでは、次の状況でセンサー Multi-HAL を実装する方法について説明します。
- センサー AIDL HAL でのセンサー Multi-HAL の使用
- センサー Multi-HAL 2.1 の実装
- センサー Multi-HAL 2.0 から Multi-HAL 2.1 への移植
- センサー HAL 2.0 からの移植
- センサー HAL 1.0 からの移植
- センサー Multi-HAL 1.0 からの移植
センサー AIDL HAL でセンサー Multi-HAL を使用する
センサー AIDL HAL で Multi-HAL 機能を有効にするには、hardware/interfaces/sensors/aidl/default/multihal/ にある、AIDL Multi-HAL shim レイヤ モジュールをインポートします。このモジュールは、AIDL センサーと HIDL センサーの HAL 定義タイプ間の変換を処理し、センサー Multi-HAL 2.1 の実装で説明されているマルチ HAL インターフェースのラッパーを定義しています。AIDL マルチ HAL shim レイヤは、センサー Multi-HAL 2.1 を実装しているデバイスと互換性があります。
AIDL マルチ HAL shim レイヤでは、センサー AIDL HAL でセンサータイプとしてヘッド トラッカーと軸制限付き IMU を公開できます。AIDL HAL インターフェースで定義されたこれらのセンサータイプを使用するには、getSensorsList_2_1()
実装の SensorInfo
構造体の type
フィールドを設定します。AIDL センサーと HIDL センサーの HAL の整数を使用しているセンサータイプ フィールドは重複していないため、このようにしても安全です。
センサー Multi-HAL 2.1 を実装する
センサー Multi-HAL 2.1 を新しいデバイスに実装する手順は次のとおりです。
SubHal.h
で説明したように、ISensorsSubHal
インターフェースを実装します。SubHal.h
にsensorsHalGetSubHal_2_1
メソッドを実装します。新しく実装されたサブ HAL をビルドするため、
cc_library_shared
ターゲットを追加します。ターゲットを追加する場合は次の作業を行います。- ターゲットがデバイスのベンダー パーティションのどこかにプッシュされていることを確認します。
/vendor/etc/sensors/hals.conf
にある構成ファイルで、新しい行にライブラリへのパスを追加します。必要に応じて、hals.conf
ファイルを作成します。
サブ HAL ライブラリをビルドするための
Android.bp
エントリの例については、hardware/interfaces/sensors/common/default/2.X/multihal/tests/Android.bp
をご覧ください。manifest.xml
ファイルからandroid.hardware.sensors
エントリをすべて削除します。このファイルには、デバイスでサポートされている HAL のリストが含まれています。device.mk
ファイルからandroid.hardware.sensors
サービスとservice.rc
ファイルをすべて削除し、android.hardware.sensors@2.1-service.multihal
とandroid.hardware.sensors@2.1-service.multihal.rc
をPRODUCT_PACKAGES
に追加します。
起動時に HalProxy
が開始され、新しく実装されたサブ HAL を探して、sensorsHalGetSubHal_2_1
を呼び出すことによって初期化します。
センサー Multi-HAL 2.0 から Multi-HAL 2.1 に移植する
Multi-HAL 2.0 から Multi-HAL 2.1 に移植するには、SubHal
インターフェースを実装し、サブ HAL を再コンパイルします。
2.0 と 2.1 の SubHal
インターフェースの違いは次のとおりです。
IHalProxyCallback
は、ISensors.hal
仕様のバージョン 2.1 で作成されたタイプを使用します。initialize()
関数は、2.0SubHal
インターフェースのコードではなく、新しいIHalProxyCallback
を渡します。- これらのメソッドは、
ISensors.hal
仕様のバージョン 2.1 で追加された新しいタイプを使用することから、サブ HAL では、getSensorsList
とinjectSensorData
ではなく、getSensorsList_2_1
とinjectSensorData_2_1
を実装する必要があります。 - サブ HAL は、マルチ HAL でバージョン 2.1 サブ HAL として扱われるために、
sensorsHalGetSubHal
ではなくsensorsHalGetSubHal_2_1
を公開する必要があります。
センサー HAL 2.0 から移植する
センサー HAL 2.0 からセンサー Multi-HAL 2.0 にアップグレードする場合は、HAL 実装が次の要件を満たしていることを確認してください。
HAL を初期化する
センサー HAL 2.0 には、センサー サービスが FMQ と動的センサー コールバックを渡すことのできる初期化関数が用意されています。センサー Multi-HAL 2.0 では、initialize()
関数が 1 つのコールバックを渡します。このコールバックは、センサー イベントのポスト、wake lock の取得、動的センサー接続と接続解除の通知に使用する必要があります。
Multi-HAL 実装にセンサー イベントをポストする
センサー イベントが利用可能な場合、サブ HAL は FMQ を介してセンサー イベントをポストする代わりに IHalProxyCallback
にセンサー イベントを書き込む必要があります。
WAKE_UP イベント
センサー HAL 2.0 では、HAL で実装の wake lock を管理できます。センサー Multi-HAL 2.0 では、サブ HAL は Multi-HAL 実装による wake lock の管理を可能にするとともに、createScopedWakelock
を呼び出すことで wake lock を取得するようリクエストできます。Multi-HAL 実装にウェイクアップ イベントをポストする場合は、ロックされた範囲の wake lock を取得して postEvents
に渡す必要があります。
動的センサー
センサー Multi-HAL 2.0 では、動的センサー接続が変更されるたびに、IHalProxyCallback
の onDynamicSensorsConnected
と onDynamicSensorsDisconnected
を呼び出す必要があります。これらのコールバックは、initialize()
関数によって提供される IHalProxyCallback
ポインタの一部として使用できます。
センサー HAL 1.0 から移植する
センサー HAL 1.0 からセンサー Multi-HAL 2.0 にアップグレードする場合は、HAL 実装が次の要件を満たしていることを確認してください。
HAL を初期化する
サブ HAL と Multi-HAL 実装の間でコールバックを確立するには、initialize()
関数がサポートされている必要があります。
使用可能なセンサーを公開する
センサー Multi-HAL 2.0 で getSensorsList()
関数は、単一デバイスの起動中(センサー HAL の再起動後も)同じ値を返す必要があります。これにより、システム サーバーが再起動されると、フレームワークはセンサー接続の再確立を試行できます。getSensorsList()
が返す値は、デバイスの再起動後に変更される可能性があります。
Multi-HAL 実装にセンサー イベントをポストする
センサー HAL 2.0 では、poll()
が呼び出されるのを待つのではなく、センサー イベントが発生するたびに、サブ HAL がセンサー イベントを IHalProxyCallback
に前もって書き込む必要があります。
WAKE_UP イベント
センサー HAL 1.0 では、HAL で実装の wake lock を管理できます。センサー Multi-HAL 2.0 では、サブ HAL は Multi-HAL 実装による wake lock の管理を可能にするとともに、createScopedWakelock
を呼び出すことで wake lock を取得するようリクエストできます。Multi-HAL 実装にウェイクアップ イベントをポストする場合は、ロックされた範囲の wake lock を取得して postEvents
に渡す必要があります。
動的センサー
センサー HAL 1.0 では、動的センサーは poll()
関数を介して返されます。センサー Multi-HAL 2.0 では、動的センサー接続が変更されるたびに、IHalProxyCallback
の onDynamicSensorsConnected
と onDynamicSensorsDisconnected
を呼び出す必要があります。これらのコールバックは、initialize()
関数によって提供される IHalProxyCallback
ポインタの一部として使用できます。
センサー Multi-HAL 1.0 から移植する
センサー Multi-HAL 1.0 から既存の実装を移植する手順は次のとおりです。
- センサー HAL 構成が
/vendor/etc/sensors/hals.conf
に配置されていることを確認します。これには、/system/etc/sensors/hals.conf
にあるファイルの移動が必要になる場合があります。 hardware/hardware.h
とhardware/sensors.h
への参照は HAL 2.0 でサポートされていないため削除します。- センサー HAL 1.0 からの移植の説明に従ってサブ HAL を移植します。
- センサー Mutli-HAL 2.0 の実装セクションの手順 3 と 4 に従って、指定された HAL としてセンサー Multi-HAL 2.0 を設定します。
検証
VTS を実行する
のサブ HAL をセンサー Multi-HAL 2.1 に統合したら、ベンダー テストスイート(VTS)を使用して、センサー HAL インターフェースによって設定された要件をサブ HAL 実装がすべて満たしていることを確認します。
ホストマシン上で VTS がセットアップされている場合にセンサー VTS テストのみを実行するには、次のコマンドを実行します。
vts-tradefed run commandAndExit vts \
--skip-all-system-status-check \
--primary-abi-only \
--skip-preconditions \
--module VtsHalSensorsV2_0Target && \
vts-tradefed run commandAndExit vts \
--skip-all-system-status-check \
--primary-abi-only \
--skip-preconditions \
--module VtsHalSensorsV2_1Target
AIDL Multi-HAL shim レイヤを実行している場合は、VtsAidlHalSensorsTargetTest
を実行します。
vts-tradefed run commandAndExit vts \
--skip-all-system-status-check \
--primary-abi-only \
--skip-preconditions \
--module VtsAidlHalSensorsTargetTest
単体テストを実行する
HalProxy_test.cpp
の単体テストでは、単体テストでインスタンス化され、動的に読み込まれていない疑似サブ HAL を使用して HalProxy
をテストします。新しいサブ HAL を作成する際は、新しいサブ HAL が適切に実装されていることを検証する単体テストの追加方法に関するガイドとして、これらのテストが機能する必要があります。
テストを実施するには、次のコマンドを実行します。
cd $ANDROID_BUILD_TOP/hardware/interfaces/sensors/common/default/2.X/multihal/tests
atest
疑似サブ HAL を使用してテストする
疑似サブ HAL は、ISensorsSubHal
インターフェースのダミー実装です。サブ HAL は、さまざまなセンサーリストを公開します。センサーが有効になると、特定のセンサー リクエストで指定された間隔に基づいて、自動的に生成されたセンサー イベントを HalProxy
に定期的にポストします。
疑似サブ HAL を使用すると、システムに読み込まれた他のサブ HAL と、完全なマルチ HAL コードがどのように連携して動作するかをテストでき、センサー Multi-HAL のコードのさまざまな側面を明確にできます。
hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/
で 2 つの疑似サブ HAL を利用できます。
疑似サブ HAL をビルドして、デバイスに push する手順は次のとおりです。
次のコマンドを実行して、3 つの異なる疑似サブ HAL をビルドしてデバイスに push します。
$ANDROID_BUILD_TOP/hardware/interfaces/sensors/common/default/2.X/multihal/tests/
mma
adb push \ $ANDROID_BUILD_TOP/out/target/product/<device>/symbols/vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config1.so \ /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config1.so
adb push \ $ANDROID_BUILD_TOP/out/target/product/<device>/symbols/vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config2.so \ /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config2.so
adb push \ $ANDROID_BUILD_TOP/out/target/product/<device>/symbols/vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config3.so \ /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config3.so
疑似サブ HAL のパスを指定して、
/vendor/etc/sensors/hals.conf
のセンサー HAL 構成を更新します。/vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config1.so /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config2.so /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config3.so
HalProxy
を再起動して、構成にリストされている新しいサブ HAL を読み込みます。adb shell stop
adb shell start
デバッグ
デベロッパーは lshal
コマンドを使用してフレームワークをデバッグできます。センサー HAL のデバッグ出力をリクエストするには、次のコマンドを実行します。
adb root
adb shell lshal debug android.hardware.sensors@2.1::ISensors/default
HalProxy
の現在の状態に関する情報とサブ HAL は、ターミナルに出力されます。HalProxy
オブジェクトと疑似サブ HAL のコマンド出力の例を以下に示します。
Internal values:
Threads are running: true
Wakelock timeout start time: 200 ms ago
Wakelock timeout reset time: 73208 ms ago
Wakelock ref count: 0
# of events on pending write queue: 0
# of non-dynamic sensors across all subhals: 8
# of dynamic sensors across all subhals: 0
SubHals (2):
Name: FakeSubHal-OnChange
Debug dump:
Available sensors:
Name: Ambient Temp Sensor
Min delay: 40000
Flags: 2
Name: Light Sensor
Min delay: 200000
Flags: 2
Name: Proximity Sensor
Min delay: 200000
Flags: 3
Name: Relative Humidity Sensor
Min delay: 40000
Flags: 2
Name: FakeSubHal-OnChange
Debug dump:
Available sensors:
Name: Ambient Temp Sensor
Min delay: 40000
Flags: 2
Name: Light Sensor
Min delay: 200000
Flags: 2
Name: Proximity Sensor
Min delay: 200000
Flags: 3
Name: Relative Humidity Sensor
Min delay: 40000
Flags: 2
# of events on pending write queue
に対して指定した数値が大きい場合(1,000 以上)は、センサー フレームワークへの書き込みが保留状態になっているイベントが多数存在することを示しています。これは、センサー サービスでデッドロックやクラッシュが発生してセンサー イベントを処理していない、または最近多数のセンサー イベントがサブ HAL からポストされたことを意味します。
wake lock 参照の数が 0
より大きい場合は、HalProxy
が wake lock を取得したことを意味します。これは、ScopedWakelock
が意図的に保持されている場合、またはウェイクアップ イベントが HalProxy
に送信され、センサー フレームワークによって処理されていない場合に限り、0
より大きくする必要があります。
HalProxy
のデバッグ メソッドに渡されるファイル記述子は各サブ HAL に渡されるため、デベロッパーは ISensorsSubHal
メソッドの一部としてデバッグ メソッドを実装する必要があります。