感應器多 HAL

感應器 Multi-HAL 是一種架構 其他感應器 HAL感應器 Multi-HAL 可動態載入感應器 sub-HAL 並儲存為廠商分區上的動態程式庫 物件,能夠處理張貼事件,並取得及釋放 Wake Lock。 感應器 HAL 是一種感應器 HAL,內建於 並由 Multi-HAL 架構使用,這些子 HAL 則不需要 依附另一個程式碼,或仰賴包含主要函式的 Multi-HAL 程式碼 整個程序。

感應器 Multi-HAL 2.1,適用於搭載 Android 的裝置 11 以上,則為 感應器多 HAL 2.0 疊代,可載入可載入的子 HAL 公開 轉軸角度 感應器類型。如要支援此感應器類型,子 HAL 必須使用 2.1 子 HAL 標頭中定義的子 HAL API。

如果裝置搭載 Android 13 以上版本,且使用 Sensors AIDL HAL,您可以使用多 HAL 修補層,啟用多 HAL 功能。如需實作詳細資訊,請參閱「使用 Sensors Multi-HAL 搭配 Sensors AIDL HAL」。

Sensors Multi-HAL 2 和 Sensors HAL 2 的差異

感應器 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) 存取 API

  • 初始化方法會傳遞 IHalProxyCallback 而不是兩個 FMQ 和 ISensorsCallback
  • Sub-HAL 必須實作偵錯函式才能提供偵錯 回報相關資訊
  • Sub-HAL 必須實作名稱函式,以便載入所載入的 sub-HAL 與其他子 HAL 區隔開來

Sensors Multi-HAL 2 和 Sensors HAL 2 的主要差異在於初始化函式。與其提供 FMQ 值,IHalProxyCallback 介面提供兩種方法,一種將感應器事件發布至感應器的方法 以及建立 Wake Lock 的方法實際上 多 HAL 負責管理與 FMQ 的所有互動,確保 所有子 HAL 的感應器事件強烈建議子 HAL 使用 createScopedWakelock 方法,將喚醒鎖定逾時的負擔委派給 Sensors Multi-HAL,並將喚醒鎖定用途集中到整個 Sensors Multi-HAL 的一個常見喚醒鎖定,以便減少鎖定和解鎖的呼叫。

此外,若感應器搭載 Multi-HAL 2,還內建部分安全功能,處理 感應器 FMQ 已滿或 Android 感應器架構為何 並且必須重設感應器狀態。此外,當事件發布至 HalProxy 類別,但感應器架構無法立即接受事件時,Sensors Multi-HAL 可以將事件移至背景執行緒,讓所有子 HAL 在等待事件發布時繼續執行工作。

原始碼和參考實作

所有感應器多 HAL 程式碼都可供使用 hardware/interfaces/sensors/common/default/2.X/multihal/。 以下是部分資源的指標。

實作

本節說明如何在下列情況下實作 Sensors Multi-HAL:

將感應器多 HAL 與感應器 AIDL HAL 搭配使用

如要允許使用感應器 AIDL HAL 的多 HAL 功能,請匯入 AIDL 多 HAL 輔助層模組位於 hardware/interfaces/sensors/aidl/default/multihal/。 這個模組會處理 AIDL 和 HIDL 感應器 HAL 定義類型之間的轉換,並在 實作感應器多重 HAL 2.1 中所述的多重 HAL 介面周圍定義包裝函式。AIDL 多重 HAL 墊片層與實作 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. 實作 sensorsHalGetSubHal_2_1 SubHal.h 中的方法。
  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. 從以下位置移除所有「android.hardware.sensors」服務和 service.rc 個檔案: device.mk 檔案並新增 android.hardware.sensors@2.1-service.multihalandroid.hardware.sensors@2.1-service.multihal.rcPRODUCT_PACKAGES

在啟動時,HalProxy 會啟動並尋找新實作的子 HAL,然後呼叫 sensorsHalGetSubHal_2_1 來初始化。

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

如要從 Multi-HAL 2.0 移植至 Multi-HAL 2.1,請實作 SubHal 介面,並重新編譯子 HAL。

以下是 2.0 和 2.1 版 SubHal 介面之間的差異:

  • IHalProxyCallback 會使用您在 2.1 版的 ISensors.hal 規格。
  • initialize() 函式會傳遞新的 IHalProxyCallback,而非 2.0 SubHal 介面中的 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。

來自感應器 HAL 2.0 的連接埠

Sensors HAL 升級至 Multi-HAL 2.0 版本時 2.0,確認 HAL 導入必須符合下列規定。

初始化 HAL

HAL 2.0 感應器具有初始化函式,可讓感應器服務 傳遞 FMQ 和動態感應器回呼。在 Sensors Multi-HAL 2.0 中,initialize() 函式會傳遞單一回呼,該回呼必須用於發布感應器事件、取得喚醒鎖定,以及通知動態感應器連線和中斷連線。

將感應器事件張貼至 Multi-HAL 實作

Sub-HAL 必須寫入感應器,而不是透過 FMQ 發布感應器事件 傳送給 IHalProxyCallback 就會傳回相關資訊

WAKE_UP 事件

在 Sensors HAL 2.0 中,HAL 可管理喚醒鎖定功能的實作方式。在 Sensors Multi-HAL 2.0 中,子 HAL 可讓 Multi-HAL 實作項目管理喚醒鎖定,並可透過叫用 createScopedWakelock 要求取得喚醒鎖定。必須取得鎖定的範圍 Wake Lock,並在發生下列情況時傳遞至 postEvents 將喚醒事件發布到 Multi-HAL 實作。

動態感應器

感應器支援 Multi-HAL 2.0 需要 onDynamicSensorsConnectedonDynamicSensorsDisconnected 英寸 IHalProxyCallback 。這些回呼 可做為 IHalProxyCallback 指標的一部分,由 initialize() 函式。

從 Sensors HAL 1.0 移植

Sensors HAL 升級至 Multi-HAL 2.0 版本時 1.0,確認 HAL 導入必須符合下列規定。

初始化 HAL

必須支援 initialize() 函式,才能在子 HAL 和多 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 要求取得喚醒鎖定。必須取得鎖定的範圍 Wake Lock,並在發生下列情況時傳遞至 postEvents 將喚醒事件發布到 Multi-HAL 實作。

動態感應器

在感應器 HAL 1.0 中,動態感應器會透過 poll() 函式傳回。 根據 Sensors Multi-HAL 2.0 的規定,每當動態感應器連線發生變更時,就會呼叫 IHalProxyCallback 中的 onDynamicSensorsConnectedonDynamicSensorsDisconnected。這些回呼 可做為 IHalProxyCallback 指標的一部分,由 initialize() 函式。

從 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 移植」一文所述,移植子 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 多 HAL 墊片層,請執行 VtsAidlHalSensorsTargetTest

vts-tradefed run commandAndExit vts \
    --skip-all-system-status-check \
    --primary-abi-only \
    --skip-preconditions \
    --module VtsAidlHalSensorsTargetTest

執行單元測試

HalProxy_test.cpp 中的單元測試 HalProxy 會使用假造的 subHAL, 會在單元測試中例項化,不會動態載入。建立新的子 HAL 時,這些測試應可做為指南,說明如何新增單元測試,驗證新子 HAL 是否已正確實作。

如要執行測試,請執行下列指令:

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

使用假的 sub-HAL 進行測試

假 sub-HAL 是 ISensorsSubHal 介面的虛擬實作。 子 HAL 會公開不同的感應器清單。感應器啟動後 他們會定期將自動產生的感應器事件發布至HalProxy 取值範圍

利用假的 sub-HAL 測試完整的 Multi-HAL 程式碼如何運作 又會載入系統的其他子 HAL 感應器多 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 發布。

如果 Wake Lock 參照計數大於 0,表示 HalProxy 已取得 Wake Lock。如果 ScopedWakelock 的值,這個值必須大於 0 系統刻意保留,或如果喚醒事件傳送至 HalProxy,且 但並未經過感應器架構處理

傳遞至 HalProxy 偵錯方法的檔案描述元會傳遞至每個子 HAL,因此開發人員必須將偵錯方法實作為 ISensorsSubHal 介面的一部分。