傳感器多 HAL

Sensors Multi-HAL 是一個框架,允許傳感器 HAL 與其他傳感器 HAL 一起運行。 Sensors Multi-HAL 動態加載存儲為供應商分區上的動態庫的傳感器子 HAL,並為它們提供一個回調對象,該對象可以處理髮布事件以及獲取和釋放喚醒鎖。傳感器子 HAL 是內置在供應商分區上的共享對像中並由多 HAL 框架使用的傳感器 HAL。這些子 HAL 不相互依賴,也不依賴於包含進程主要功能的多 HAL 代碼。

Sensors Multi-HAL 2.1 可在運行 Android 11 或更高版本的設備上使用,是 Sensors Multi-HAL 2.0 的迭代,支持加載可暴露鉸鏈角度傳感器類型的子 HAL。要支持這種傳感器類型,sub-HAL 必須使用2.1 SubHal 標頭中定義的 sub-HAL API。

Sensors Multi-HAL 2 和 Sensors HAL 2 之間的區別

Sensors Multi-HAL 2 可在運行 Android 10 或更高版本的設備上使用,它在Sensors HAL 2之上引入了幾個抽象,以便更容易與 HAL API 交互。 Sensors Multi-HAL 2 引入了HalProxy類來處理實現 Sensors HAL 2 接口和V2_1/SubHal (或V2_0/SubHal )接口以允許HalProxy與子 HAL 交互。

ISensorsSubHal接口與2.1/ISensors.hal (或2.0/ISensors.hal )接口在以下方面有所不同:

  • 初始化方法傳遞一個IHalProxyCallback類而不是兩個 FMQ 和ISensorsCallback
  • Sub-HAL 必須實現調試功能,以便在錯誤報告中提供調試信息。
  • Sub-HAL 必須實現名稱功能,以便加載的 sub-HAL 可以與其他 sub-HAL 區分開來。

Sensors Multi-HAL 2 和 Sensors HAL 2 之間的主要區別在於初始化功能。 IHalProxyCallback接口不提供 FMQ,而是提供了兩種方法,一種將傳感器事件發佈到傳感器框架的方法,另一種創建喚醒鎖的方法。在後台,Sensors Multi-HAL 管理與 FMQ 的所有交互,以確保及時為所有 sub-HAL 傳遞傳感器事件。強烈建議子 HAL 使用createScopedWakelock方法將喚醒鎖超時的負擔委託給 Sensors Multi-HAL,並將喚醒鎖的使用集中到整個 Sensors Multi-HAL 的一個通用喚醒鎖上,從而最大限度地減少鎖定和解鎖來電。

Sensors Multi-HAL 2 還具有一些內置的安全功能。它處理傳感器 FMQ 已滿或 Android 傳感器框架重新啟動並且需要重置傳感器狀態的情況。此外,當事件發佈到HalProxy類但傳感器框架無法立即接受事件時,Sensors Multi-HAL 可以將事件移動到後台線程,以允許在等待事件的同時跨所有子 HAL 繼續工作要張貼。

源代碼和參考實現

所有 Sensors Multi-HAL 代碼都在hardware/interfaces/sensors/common/default/2.X/multihal/中可用。以下是一些資源的指針。

執行

本節介紹如何在以下情況下實施 Sensors Multi-HAL:

實施傳感器 Multi-HAL 2.1

要在新設備上實施 Sensors Multi-HAL 2.1,請執行以下步驟:

  1. 實現ISensorsSubHal接口,如SubHal.h中所述。
  2. SubHal.h中實現sensorsHalGetSubHal_2_1方法。
  3. 添加一個cc_library_shared目標來構建新實現的子 HAL。添加目標時:

    1. 確保將目標推送到設備供應商分區上的某個位置。
    2. 在位於/vendor/etc/sensors/hals.conf的配置文件中,將庫的路徑添加到新行。如有必要,創建hals.conf文件。

    有關構建子 HAL 庫的示例Android.bp條目,請參閱hardware/interfaces/sensors/common/default/2.X/multihal/tests/Android.bp

  4. manifest.xml文件中刪除所有android.hardware.sensors條目,該文件包含設備上支持的 HAL 列表。

  5. device.mk文件中刪除所有android.hardware.sensors服務和service.rc文件,並將android.hardware.sensors@2.1-service.multihalandroid.hardware.sensors@2.1-service.multihal.rc添加到PRODUCT_PACKAGES中。

在啟動時, HalProxy啟動,查找新實現的子 HAL,並通過調用sensorsHalGetSubHal_2_1對其進行初始化。

從 Sensors Multi-HAL 2.0 移植到 Multi-HAL 2.1

要從 Multi-HAL 2.0 移植到 Multi-HAL 2.1,請實現SubHal接口並重新編譯您的 sub-HAL。

這些是 2.0 和 2.1 SubHal接口之間的區別:

  • IHalProxyCallback使用在ISensors.hal規範的 2.1 版中創建的類型。
  • initialize()函數傳遞一個新的IHalProxyCallback而不是來自 2.0 SubHal接口的那個
  • Sub-HAL 必須實現getSensorsList_2_1injectSensorData_2_1而不是getSensorsListinjectSensorData ,因為這些方法使用ISensors.hal規範 2.1 版中添加的新類型。
  • Sub-HAL 必須公開sensorsHalGetSubHal_2_1而不是sensorsHalGetSubHal ,以便 Multi-HAL 將它們視為 2.1 版 sub-HAL。

從 Sensors HAL 2.0 移植

Sensors HAL 2.0升級到 Sensors Multi-HAL 2.0 時,請確保 HAL 實現滿足以下要求。

初始化 HAL

Sensors HAL 2.0 具有允許傳感器服務傳遞 FMQ 和動態傳感器回調的初始化函數。在 Sensors Multi-HAL 2.0 中, initialize()函數傳遞一個必須用於發布傳感器事件、獲取喚醒鎖以及通知動態傳感器連接和斷開的回調。

將傳感器事件發佈到 Multi-HAL 實現

當傳感器事件可用時,子 HAL 必須將傳感器事件寫入IHalProxyCallback ,而不是通過 FMQ 發布傳感器事件。

WAKE_UP 事件

在 Sensors HAL 2.0 中,HAL 可以為其實現管理喚醒鎖。在 Sensors Multi-HAL 2.0 中,子 HAL 允許 Multi-HAL 實現管理喚醒鎖,並且可以通過調用createScopedWakelock來請求獲取喚醒鎖。將喚醒事件發佈到 Multi-HAL 實現時,必須獲取鎖定範圍的喚醒鎖並將其傳遞給postEvents

動態傳感器

Sensors Multi-HAL 2.0 要求在動態傳感器連接發生變化時調用IHalProxyCallback中的onDynamicSensorsConnectedonDynamicSensorsDisconnected 。這些回調作為通過initialize()函數提供的IHalProxyCallback指針的一部分提供。

從 Sensors HAL 1.0 移植

Sensors HAL 1.0升級到 Sensors Multi-HAL 2.0 時,請確保 HAL 實現滿足以下要求。

初始化 HAL

必須支持initialize()函數才能在 sub-HAL 和 Multi-HAL 實現之間建立回調。

暴露可用的傳感器

在 Sensors Multi-HAL 2.0 中, getSensorsList()函數必須在單個設備啟動期間返回相同的值,即使在傳感器 HAL 重新啟動時也是如此。這允許框架在系統服務器重新啟動時嘗試重新建立傳感器連接。 getSensorsList()返回的值可以在設備執行重啟後更改。

將傳感器事件發佈到 Multi-HAL 實現

在 Sensors HAL 2.0 中,子 HAL 必須在傳感器事件可用時主動將傳感器事件寫入IHalProxyCallback ,而不是等待調用poll()

WAKE_UP 事件

在 Sensors HAL 1.0 中,HAL 可以為其實現管理喚醒鎖。在 Sensors Multi-HAL 2.0 中,子 HAL 允許 Multi-HAL 實現管理喚醒鎖,並且可以通過調用createScopedWakelock來請求獲取喚醒鎖。將喚醒事件發佈到 Multi-HAL 實現時,必須獲取鎖定範圍的喚醒鎖並將其傳遞給postEvents

動態傳感器

在 Sensors HAL 1.0 中,動態傳感器通過poll()函數返回。 Sensors Multi-HAL 2.0 要求在動態傳感器連接發生變化時調用IHalProxyCallback中的onDynamicSensorsConnectedonDynamicSensorsDisconnected 。這些回調作為通過initialize()函數提供的IHalProxyCallback指針的一部分提供。

從 Sensors Multi-HAL 1.0 移植

要從Sensors Multi-HAL 1.0移植現有實施,請執行以下步驟。

  1. 確保傳感器 HAL 配置位於/vendor/etc/sensors/hals.conf.這可能涉及移動位於/system/etc/sensors/hals.conf的文件。
  2. 刪除對hardware/hardware.hhardware/sensors.h的所有引用,因為 HAL 2.0 不支持這些引用。
  3. 從 Sensors Hal 1.0 移植中所述移植sub-HAL。
  4. 按照實施 Sensors Mutli-HAL 2.0部分中的步驟 3 和 4 將 Sensors Multi-HAL 2.0 設置為指定的 HAL。

驗證

運行 VTS

當您將一個或多個 sub-HAL 與 Sensors Multi-Hal 2.1 集成後,請使用供應商測試套件 (VTS)確保您的 sub-HAL 實現滿足 Sensors 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

運行單元測試

HalProxy_test.cpp中的單元測試使用在單元測試中實例化且未動態加載的假子 HAL 測試HalProxy 。創建新的 sub-HAL 時,這些測試應作為指導,指導如何添加單元測試以驗證新的 sub-HAL 是否已正確實施。

要運行測試,請執行以下命令:

cd $ANDROID_BUILD_TOP/hardware/interfaces/sensors/common/default/2.X/multihal/tests
atest

使用偽造的 sub-HAL 進行測試

假子 HAL 是ISensorsSubHal接口的虛擬實現。 sub-HAL 公開了不同的傳感器列表。當傳感器被激活時,它們會根據給定傳感器請求中指定的間隔定期將自動生成的傳感器事件發佈到HalProxy

偽造的 sub-HAL 可用於測試完整的 Multi-HAL 代碼如何與加載到系統中的其他 sub-HAL 一起工作,並強調 Sensors Multi-HAL 代碼的各個方面。

hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/中提供了兩個假子 HAL。

要構建虛假子 HAL 並將其推送到設備,請執行以下步驟:

  1. 運行以下命令來構建三個不同的假子 HAL 並將其推送到設備:

    $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
    
  2. 使用假子 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
    
  3. 重新啟動HalProxy並加載配置中列出的新子 HAL。

    adb shell stop
    adb shell start
    

調試

開發者可以使用lshal命令調試框架。要請求 Sensors 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指定的數量很大(1000 或更多),這表明有許多事件等待寫入傳感器框架。這表明傳感器服務已死鎖或已崩潰並且未處理傳感器事件,或者最近從子 HAL 發布了大量傳感器事件。

如果喚醒鎖引用計數大於0 ,這意味著HalProxy獲得了喚醒鎖。僅當有意保持ScopedWakelock或喚醒事件已發送到HalProxy且傳感器框架尚未處理時,該值才應大於0

傳遞給HalProxy調試方法的文件描述符會傳遞給每個子 HAL,因此開發人員必須將調試方法實現為ISensorsSubHal接口的一部分。