Sensors AIDL HAL

感應器硬體抽象層 (HAL) 是 Android 感應器架構與裝置感應器 (例如加速計或陀螺儀) 之間的介面。感應器 HAL 定義必須實作的函式,讓架構控管感應器。

Android 13 以上版本的新裝置和升級裝置,都可使用感應器 AIDL HAL。感應器 AIDL HAL 以 Sensors HAL 2.1 為基礎,使用 AIDL HAL 介面,並公開頭部追蹤器和有限軸 IMU 感應器類型。

AIDL HAL 介面

感應器 AIDL HAL 的主要文件來源位於 hardware/interfaces/sensors/aidl/android/hardware/sensors/ISensors.aidl 的 HAL 定義中。

實作感應器 AIDL HAL

如要實作 Sensors AIDL HAL,物件必須擴充 ISensors 介面,並實作 hardware/interfaces/sensors/aidl/android/hardware/sensors/ISensors.aidl 中定義的所有函式。

初始化 HAL

Android 感應器架構必須先初始化感應器 HAL,才能使用感應器 HAL。架構會呼叫 initialize() 函式,將三個參數提供給感應器 HAL:兩個 FMQ 描述元和一個指向 ISensorsCallback 物件的指標。

HAL 會使用第一個描述元建立 Event FMQ,用於將感應器事件寫入架構。HAL 會使用第二個描述元建立 Wake Lock FMQ,用於在 HAL 為 WAKE_UP感應器事件釋放喚醒鎖定時進行同步。HAL 必須儲存 ISensorsCallback 物件的指標,以便叫用任何必要的回呼函式。

初始化感應器 HAL 時,必須先呼叫 initialize() 函式。

公開可用的感應器

如要取得裝置中所有可用靜態感應器的清單,請使用 getSensorsList() 函式。這個函式會傳回感應器清單,每個感應器都有專屬的控制代碼。當代管感應器 HAL 的程序重新啟動時,特定感應器的控制代碼不得變更。帳號代碼可能會在裝置重新啟動時,以及系統伺服器重新啟動時變更。

如果多個感應器共用相同的感應器類型和喚醒屬性,則清單中的第一個感應器會稱為「預設」感應器,並傳回給使用 getDefaultSensor(int sensorType, bool wakeUp) 函式的應用程式。

感應器清單的穩定性

感應器 HAL 重新啟動後,如果 getSensorsList() 傳回的資料與重新啟動前擷取的感應器清單相比,顯示有重大變更,架構就會觸發 Android 執行階段重新啟動。感應器清單的重大變更包括:缺少特定控制代碼的感應器或感應器屬性已變更,或是導入新的感應器。雖然重新啟動 Android 執行階段會干擾使用者,但這是必要步驟,因為 Android 架構無法再滿足 Android API 合約,也就是靜態 (非動態) 感應器在應用程式生命週期內不會變更。這也可能導致架構無法重新建立應用程式發出的有效感應器要求。因此,建議 HAL 供應商避免不必要的感應器清單變更。

為確保感應器控制代碼穩定,HAL 必須將裝置中的特定實體感應器確定性地對應至其控制代碼。雖然感應器 HAL 介面並未強制規定具體實作方式,但開發人員可選擇多種做法來滿足這項需求。

舉例來說,感應器清單可依每個感應器的固定屬性 (例如供應商、型號和感應器類型) 組合排序。另一種做法是依據裝置的靜態感應器組固定在硬體中的事實,因此 HAL 需要知道所有預期感應器何時完成初始化,才能從 getSensorsList() 傳回。這份預期感應器清單可以編譯成 HAL 二進位檔,或儲存在檔案系統的設定檔中,而出現順序可用於衍生穩定控制代碼。雖然最佳解決方案取決於 HAL 的具體實作詳細資料,但主要要求是感應器控制代碼在 HAL 重新啟動時不得變更。

設定感應器

啟用感應器前,必須先使用 batch() 函式設定感應器的取樣週期和最長回報延遲時間。

感應器必須能夠隨時使用 batch() 重新設定,且不會遺失感應器資料。

取樣週期

取樣週期會因設定的感應器類型而異:

  • 連續:感應器事件會以連續速率產生。
  • 變更時:產生的事件不會快於取樣週期,如果測量值沒有變化,產生的事件可能會慢於取樣週期。
  • 單次:系統會忽略取樣週期。
  • 特殊:詳情請參閱「感應器類型」。

如要瞭解取樣週期和感應器回報模式之間的互動,請參閱「回報模式」。

回報延遲時間上限

回報延遲時間上限會設定事件可延遲並儲存在硬體 FIFO 中的時間上限 (以奈秒為單位),之後事件會透過 HAL 寫入 Event FMQ,而 SoC 處於喚醒狀態。

如果值為零,表示系統必須在測量事件後立即回報,方法是完全略過 FIFO,或是在 FIFO 中出現感應器事件時立即清空 FIFO。

舉例來說,如果加速計以 50 Hz 啟動,且回報延遲時間上限為零,則 SoC 處於喚醒狀態時,每秒會觸發 50 次中斷。

如果最大回報延遲時間大於零,感應器事件就不必在偵測到時立即回報。只要沒有任何事件延遲超過最長回報延遲時間,事件就能暫時儲存在硬體 FIFO 中,並以批次形式回報。系統會記錄並立即傳回前一批次之後的所有事件。這可減少傳送至 SoC 的中斷次數,並讓 SoC 在感應器擷取及批次處理資料時,切換至低功耗模式。

每個事件都有相關聯的時間戳記。延遲回報事件的時間不得影響事件時間戳記。時間戳記必須準確,且對應事件實際發生的時間,而非回報時間。

如要進一步瞭解如何回報感應器事件,以及回報最大回報延遲時間不為零的感應器事件時須遵守的規定,請參閱「批次處理」一節。

啟用感應器

架構會使用 activate() 函式啟用及停用感應器。啟用感應器前,架構必須先使用 batch() 設定感應器。

感應器停用後,不得將該感應器的其他感應器事件寫入事件 FMQ。

沖水感應器

如果感應器設定為批次處理感應器資料,架構可以呼叫 flush(),強制立即排清批次處理的感應器事件。這會導致指定感應器控制代碼的批次感應器事件立即寫入事件 FMQ。感應器 HAL 必須在因呼叫 flush() 而寫入的感應器事件結尾,附加清除完成事件。

清除作業會以非同步方式進行 (也就是說,這個函式必須立即傳回)。如果實作方式是為多個感應器使用單一 FIFO,系統只會針對指定感應器排空該 FIFO,並新增排空完成事件。

如果指定的感應器沒有 FIFO (無法緩衝),或呼叫時 FIFO 為空,flush() 仍須成功,並為該感應器傳送清除完成事件。這項設定適用於所有感應器,但單次感應器除外。

如果為單次感應器呼叫 flush(),則 flush() 必須傳回 BAD_VALUE,且不得產生清除完成事件。

將感應器事件寫入 FMQ

感應器 HAL 會使用事件 FMQ,將感應器事件推送至 Android 感應器架構。

事件 FMQ 是同步 FMQ,也就是說,如果嘗試寫入 FMQ 的事件數量超過可用空間,寫入作業就會失敗。在這種情況下,HAL 應判斷是否要將目前的事件集寫入為兩組較小的事件,或是在有足夠空間時一起寫入所有事件。

當感應器 HAL 將所需數量的感應器事件寫入 Event FMQ 時,感應器 HAL 必須將 EventQueueFlagBits::READ_AND_PROCESS 位元寫入 Event FMQ 的 EventFlag::wake 函式,通知架構事件已準備就緒。您可以使用 EventFlag::createEventFlag 和 Event FMQ 的 getEventFlagWord() 函式,從 Event FMQ 建立 EventFlag。

感應器 AIDL HAL 支援 Event FMQ 上的 writewriteBlocking。 預設實作會提供使用 write 的參照。如果使用 writeBlocking 函式,readNotification 旗標必須設為 EventQueueFlagBits::EVENTS_READ,架構從 Event FMQ 讀取事件時會設定這個旗標。寫入通知旗標必須設為 EventQueueFlagBits::READ_AND_PROCESS,通知架構事件已寫入 Event FMQ。

WAKE_UP 事件

WAKE_UP 事件是感應器事件,會導致應用程式處理器 (AP) 喚醒並立即處理事件。每當 WAKE_UP 事件寫入 Event FMQ 時,感應器 HAL 必須取得喚醒鎖定,確保系統保持喚醒狀態,直到架構可以處理該事件為止。收到 WAKE_UP 事件後,架構會確保自己的喚醒鎖定,讓感應器 HAL 釋放喚醒鎖定。如要在感應器 HAL 釋放喚醒鎖定時進行同步,請使用 Wake Lock FMQ。

感應器 HAL 必須讀取 Wake Lock FMQ,才能判斷架構處理的事件數量。WAKE_UP如果未處理的 WAKE_UP 事件總數為零,HAL 應只針對 WAKE_UP 事件釋放 Wake Lock。處理感應器事件後,架構會計算標示為 WAKE_UP 事件的事件數量,並將此數字寫回 Wake Lock FMQ。

每當架構將資料寫入 Wake Lock FMQ 時,都會在 Wake Lock FMQ 上設定 WakeLockQueueFlagBits::DATA_WRITTEN 寫入通知。

動態感應器

動態感應器並非裝置的實體元件,但可做為裝置的輸入內容,例如具有加速計的遊戲手把。

連線動態感應器時,必須從 Sensors HAL 呼叫 ISensorsCallback 中的 onDynamicSensorConnected 函式。這會將新的動態感應器通知架構,並允許透過架構控制感應器,以及讓用戶端使用感應器的事件。

同樣地,動態感應器中斷連線時,必須呼叫 ISensorsCallback 中的 onDynamicSensorDisconnected 函式,架構才能移除不再可用的感應器。

直接管道

直接管道是一種運作方法,可將感應器事件寫入特定記憶體,而非寫入事件 FMQ,藉此略過 Android Sensors Framework。註冊直接管道的用戶端必須直接從用於建立直接管道的記憶體讀取感應器事件,且不會透過架構接收感應器事件。configDirectReport() 函式與 batch() 類似,可正常運作並設定直接回報管道。

registerDirectChannel()unregisterDirectChannel() 函式會建立或終止新的直接管道。

運作模式

setOperationMode() 函式可讓框架設定感應器,以便將感應器資料插入感應器。這項功能有助於測試,特別是架構下方的演算法。

injectSensorData() 函式通常用於將作業參數推送至感應器 HAL。這項函式也可用於將感應器事件插入特定感應器。

驗證

如要驗證感應器 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 測試

感應器 AIDL HAL 的 VTS 測試位於 hardware/interfaces/sensors/aidl/vts/。這些測試可確保感應器 HAL 實作正確無誤,且符合 ISensors.aidlISensorsCallback.aidl 中的所有規定。

初始化 HAL

必須支援 initialize() 函式,才能在架構和 HAL 之間建立 FMQ。

公開可用的感應器

在感應器 AIDL HAL 中,getSensorsList() 函式必須在單一裝置啟動期間傳回相同值,即使感應器 HAL 重新啟動也一樣。getSensorsList() 函式的新規定是,即使在感應器 HAL 重新啟動後,也必須在單一裝置啟動期間傳回相同的值。這樣一來,如果系統伺服器重新啟動,架構就能嘗試重新建立感應器連線。裝置重新啟動後,getSensorsList() 傳回的值可能會變更。

將感應器事件寫入 FMQ

在 Sensors AIDL HAL 中,Sensors HAL 必須在感應器事件可用時,主動將感應器事件寫入 Event FMQ,而不是等待呼叫 poll()。HAL 也負責將正確位元寫入 EventFlag,在架構內觸發 FMQ 讀取作業。

WAKE_UP 事件

在 Sensors HAL 1.0 中,HAL 可以在將 WAKE_UP 發布至 poll() 後,於後續對 poll() 的任何呼叫中,釋放任何事件的喚醒鎖定,因為這表示架構已處理所有感應器事件,並已視需要取得喚醒鎖定。WAKE_UP因為在 Sensors AIDL HAL 中,架構處理寫入 FMQ 的事件時,HAL 不會再收到通知,因此 Wake Lock FMQ 可讓架構在處理 WAKE_UP 事件時與 HAL 通訊。

在 Sensors AIDL HAL 中,Sensors HAL 為 WAKE_UP 事件確保的 Wake Lock 必須以 SensorsHAL_WAKEUP 開頭。

動態感應器

動態感應器是透過 Sensors HAL 1.0 中的 poll() 函式傳回。感應器 AIDL HAL 要求在動態感應器連線變更時,一律呼叫 ISensorsCallback 中的 onDynamicSensorsConnectedonDynamicSensorsDisconnected。這些回呼函式會透過 initialize() 函式提供,做為 ISensorsCallback 指標的一部分。

運作模式

必須支援 WAKE_UP 感應器的 DATA_INJECTION 模式。

支援多個 HAL

感應器 AIDL HAL 支援使用感應器多重 HAL 架構的多重 HAL。如需實作詳細資料,請參閱「從感應器 HAL 2.1 移植」。