傳感器多 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。為了支援此感測器類型,子 HAL 必須使用2.1 SubHal 標頭中定義的子 HAL API。

對於運行 Android 13 或更高版本並使用Sensors AIDL HAL 的設備,您可以使用多 HAL shim 層來允許多 HAL 功能。有關實現詳細信息,請參閱將感測器 Multi-HAL 與感測器 AIDL HAL 結合使用

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
  • 子 HAL 必須實作偵錯功能,以便在錯誤報告中提供偵錯資訊。
  • 子 HAL 必須實作名稱函數,以便載入的子 HAL 可以與其他子 HAL 區分開。

Sensors Multi-HAL 2 和 Sensors HAL 2 之間的主要差異在於初始化函數。 IHalProxyCallback介面不提供 FMQ,而是提供兩種方法,一種將感測器事件發佈到感測器框架的方法,一種創建喚醒鎖定的方法。在底層,Sensors Multi-HAL 管理與 FMQ 的所有交互,以確保及時傳遞所有子 HAL 的感測器事件。強烈建議子 HAL 使用createScopedWakelock方法將超時喚醒鎖的負擔委託給 Sensors Multi-HAL,並將喚醒鎖的使用集中到整個 Sensors Multi-HAL 的一個公共喚醒鎖,從而最大限度地減少鎖定和解鎖來電。

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

源碼及參考實現

所有感測器 Multi-HAL 程式碼可在hardware/interfaces/sensors/common/default/2.X/multihal/中找到。以下是一些資源的指標。

執行

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

將感測器 Multi-HAL 與感測器 AIDL HAL 結合使用

若要允許感測器 AIDL HAL 具有多 HAL 功能,請匯入 AIDL Multi-HAL shim 層模組,該模組位於hardware/interfaces/sensors/aidl/default/multihal/中。此模組處理 AIDL 和 HIDL 感測器 HAL 定義類型之間的轉換,並定義圍繞實現感測器 Multi-HAL 2.1中所述的 multi-HAL 介面的包裝器。 AIDL multi-HAL shim 層與實作 Sensors Multi-HAL 2.1 的裝置相容。

AIDL 多 HAL 墊片層可讓您在感測器 AIDL HAL 中公開頭部追蹤器和限軸 IMU 感測器類型。若要使用 AIDL HAL 介面定義的這些感測器類型,請在getSensorsList_2_1()實作的SensorInfo結構中設定type欄位。這是安全的,因為 AIDL 和 HIDL 感測器 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對其進行初始化。

從感測器 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()函數傳遞一個新的IHalProxyCallback ,而不是 2.0 SubHal介面中的 IHalProxyCallback
  • 子 HAL 必須實作getSensorsList_2_1injectSensorData_2_1 ,而不是getSensorsListinjectSensorData ,因為這些方法使用ISensors.hal規格 2.1 版中新增的新類型。
  • 子 HAL 必須揭露sensorsHalGetSubHal_2_1而非sensorsHalGetSubHal ,以便 Multi-HAL 將它們視為 2.1 版子 HAL。

感測器 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指標的一部分來使用。

感測器 HAL 1.0 的端口

Sensors HAL 1.0升級到 Sensors Multi-HAL 2.0 時,請確保 HAL 實現符合下列要求。

初始化 HAL

必須支援initialize()函數才能在子HAL 和Multi-HAL 實作之間建立回呼。

公開可用的感測器

在 Sensors Multi-HAL 2.0 中, getSensorsList()函數必須在單一裝置啟動期間傳回相同的值,即使跨感測器 HAL 重新啟動也是如此。這允許框架在系統伺服器重新啟動時嘗試重新建立感測器連接。設備重新啟動後, getSensorsList()傳回的值可能會改變。

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

在感測器 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指標的一部分來使用。

感測器 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. 按照從感測器 Hal 1.0 移植中所述移植子 HAL。
  4. 依照實作 Sensors Mutli-HAL 2.0部分中的步驟 3 和 4,將 Sensors Multi-HAL 2.0 設定為指定的 HAL。

驗證

運行VTS

當您將一個或多個子 HAL 與 Sensors Multi-Hal 2.1 整合後,請使用供應商測試套件 (VTS)確保您的子 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

如果您正在執行 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 可用於測試完整的 Multi-HAL 程式碼如何與載入到系統中的其他子 HAL 一起工作,並強調感測器 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指令來除錯框架。若要請求感測器 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的 debug 方法的檔案描述子會傳遞給每個子 HAL,因此開發人員必須將 debug 方法實作為ISensorsSubHal介面的一部分。