VHAL介面

AIDL VHAL 在android.hardware.automotive.vehicle namespace中定義。 VHAL 介面在IVehicle.aidl中定義。除非指定,否則所有方法都必須實作。

方法
VehiclePropConfigs getAllPropConfigs()
傳回此車輛 HAL 支援的所有屬性配置的清單。
VehiclePropConfigs getPropConfigs(in int[] props)
傳回給定屬性 ID 的屬性配置清單。
void getValues(IVehicleCallback callback, in GetValueRequests requests)
非同步取得車輛屬性值。非同步處理一批GetValueRequest 。結果透過回調的onGetValues方法傳遞。
void setValues(IVehicleCallback callback, in SetValueRequests requests)
異步設定車輛屬性值。非同步處理一批SetValueRequest 。結果透過回調的onSetValues方法傳遞。
void subscribe(in IVehicleCallback callback, in SubscribeOptions[] options, int maxSharedMemoryFileCount)
訂閱具有指定選項的屬性事件。訂閱選項包括屬性 ID、屬性區域 ID 和以 Hz 為單位的取樣率(對於連續屬性)。未使用maxSharedMemoryFileCount
void unsubscribe(in IVehicleCallback callback, in int[] propIds)
取消訂閱先前訂閱的指定屬性的屬性事件。
returnSharedMemory(in IVehicleCallback callback, long sharedMemoryId)
不使用並且可以作為無操作來實現。

回調在IVehicleCallback.aidl中定義並包含這些方法。

方法
oneway void onGetValues(in GetValueResults responses)
getValues函數的回呼以傳遞獲取值結果。當一些要取得的值準備就緒時調用。
oneway void onSetValues(in SetValueResults responses)
setValues函數的回調以提供設定值結果。當 VHAL 完成處理一些屬性設定請求時呼叫。
oneway void onPropertyEvent(in VehiclePropValues propValues, int sharedMemoryFileCount)
用於報告屬性更新事件的回呼。
CONTINUOUS屬性,屬性事件根據訂閱取樣率(以 Hz 為單位)或車輛匯流排訊息頻率發生。如果屬性的狀態發生更改,也可能會發生屬性事件。例如,從不可用到可用。
對於ON_CHANGE屬性,當屬性的值或屬性的狀態改變時,就會發生屬性事件。
SharedMemoryFileCount始終為0
oneway void onPropertySetError(in VehiclePropErrors errors)
用於報告沒有相應設定請求的非同步屬性設定錯誤的回調。如果我們知道錯誤是針對哪個 set 請求,則必須使用帶有錯誤結果的onSetValues而不是 this。

有關更多信息,請參閱IVehicle.aidlIVehicleCallback.aidl

VHAL 實作由位於VtsHalAutomotiveVehicle_TargetTest.cpp的 VHAL VTS 進行驗證。測試驗證基本方法實作正確,支援的屬性配置正確。

車輛財產價值

使用VehiclePropValue結構來描述每個屬性的值,該結構具有以下欄位:

場地描述
timestamp表示事件發生時間並與SystemClock.elapsedRealtimeNano()時鐘同步的時間戳記。
prop該值的屬性 ID。
areaid該值的區域 ID。此區域必須是區域 ID 配置中列出的支援區域之一,或全域屬性為0
value包含實際屬性值的資料結構。根據屬性類型,該欄位中的一個或多個欄位用於儲存實際值。例如, value.int32Values中的第一個元素用於 Int32 類型屬性。詳細資訊請參閱屬性配置

非同步 getValue 和 setValue

getValuessetValues操作是非同步執行的,這表示該函數可能會在實際的 get 或 set 操作完成之前傳回。操作結果(例如, getValues的屬性值和setValues的成功或錯誤狀態)透過作為參數傳遞的回調傳遞。

實作不得阻塞處理請求的綁定器執行緒中的結果。相反,我們建議您將請求儲存在請求佇列中,並使用單獨的處理程序執行緒非同步處理請求。有關詳細信息,請參閱參考實作

圖 1.非同步流程。

大包裹

所有名為XXXs的結構(例如VehiclePropConfigsSetValueRequestsVehiclePropValues都稱為LargeParcelable (或StableLargeParcelable )。每個都代表一個值列表,用於跨綁定器邊界傳遞可能超出綁定器限制( LargeParcelable庫實現中的 4KB)的大數據。每個都有相似的結構定義,其中包含以下欄位。

指導描述
payloads當值大小符合活頁夾記憶體限制時的值列表,或空列表。
sharedMemoryFd如果值清單太大,則指向儲存序列化有效負載的共享記憶體檔案的可為空檔案描述符。

例如, VehiclePropConfigs定義為:

parcelable VehiclePropConfigs {
    // The list of vehicle property configs if they fit the binder memory
    // limitation.
    VehiclePropConfig[] payloads;
    // Shared memory file to store configs if they exceed binder memory
    // limitation. Created by VHAL, readable only at client. Client could keep
    // the fd opened or keep the FD mapped to access configs.
    @nullable ParcelFileDescriptor sharedMemoryFd;
}

VehiclePropConfigs包含非空有效負載或非空sharedMemoryFd

  • 如果payloads不為空,它會儲存實際資料的列表,即屬性配置。
  • 如果sharedMemoryFd不為null,則它包含一個共享記憶體文件,該文件儲存VehiclePropConfigs的序列化結構。結構使用writeToParcel函數來序列化 Parcel。

作為 VHAL 的 Java 用戶端,Car Service 處理LargeParcelable的序列化和反序列化。對於 VHAL 實作和本機客戶端,應該使用LargeParcelable函式庫或ParcelableUtils.h中的函式庫的有用包裝類別來序列化和反序列化LargeParcelable

例如,本機用戶端解析從綁定器接收到的getValues請求如下:

// 'requests' are from the binder.
GetValueRequests requests;
expected, ScopedAStatus> deserializedResults = fromStableLargeParcelable(requests);
if (deserializedResults.ok()) {
    const std::vector& getValueRequests = deserializedResults.value().getObject()->payloads;
    // Use the getValueRequests.
  } else {
    // handle error.
}

透過綁定器發送getValues結果的範例 VHAL 實作如下所示:

std::vector results = getResults();
GetValueResults parcelableResults;
ScopedAStatus status = vectorToStableLargeParcelable(std::move(results), &parcelableResults);
if (status.isOk()) {
    // Send parcelableResults through callback.
} else {
    // Handle error.
}