許多現有車輛架構都包含多個電子控制單元 (ECU) 是控管人體工學的資訊娛樂系統以外,例如:座位 調整設定和鏡像取決於目前的硬體和電源 開發了 Android 式資訊娛樂系統 已開機。這些 ECU 具有 Android 資訊娛樂系統 將透過 YAML 檔案 車輛硬體抽象層 (VHAL)。
從 Android 11 開始,Android Automotive OS (AAOS) 導入了一組全新的 VHAL 上的屬性建立、切換、移除和關聯 用來識別使用者的外部配件舉例來說 驅動程式,可將外部配件 (例如鍵盤遙控) 與 Android 使用者配對。 之後駕駛人靠近車輛時,ECU 便會喚醒並偵測遙控鑰匙。 這個 ECU 會向 Android 使用者指示 HAL 應提供資訊娛樂 藉此縮短驅動程式等待 Android 應用程式的時間 要載入的使用者。
啟用使用者 HAL
您必須確保系統能明確啟用使用者 HAL 屬性
屬性 android.car.user_hal_enabled
已設為 true
。
(您也可以在 car.mk
檔案中進行這項操作,因此不需要
手動設定)。檢查 user_hal_enabled=true
是否已啟用
轉儲 UserHalService
:
$ adb shell dumpsys car_service --hal UserHalService|grep enabled user_hal_enabled=true
您也可以使用 adb shell
getprop android.car.user_hal_enabled
或 adb logcat
CarServiceHelper *:s
檢查 user_hal_enabled
。如果屬性已停用,系統會顯示一則訊息,例如
system_server
開始時會顯示以下內容:
I CarServiceHelper: Not using User HAL
如要手動啟用 user_hal_enabled
,請將
android.car.user_hal_enabled
系統屬性並重新啟動
system_server
:
$ adb shell setprop android.car.user_hal_enabled true $ adb shell stop && adb shell start
logcat
輸出內容如下所示:
I CarServiceHelper: User HAL enabled with timeout of 5000ms D CarServiceHelper: Got result from HAL: OK I CarServiceHelper: User HAL returned DEFAULT behavior
使用者 HAL 屬性
使用者生命週期屬性
下列屬性可提供使用者生命週期的 HAL 資訊 狀態,啟用 Android 系統之間的使用者生命週期同步處理功能 以及外部 ECU。這些屬性在 Android 系統會透過設定屬性值和 HAL 會透過發出屬性變更事件來回應。
注意:系統支援使用者 HAL 時,所有下列項目 。
HAL 屬性 | 說明 |
---|---|
INITIAL_USER_INFO (讀取/寫入) |
Android 系統會呼叫這個屬性,判斷哪個 Android 裝置
使用者啟動或重新啟用裝置時,系統會啟動
暫停對 RAM (STR)。呼叫時,HAL 必須以下列任一值回應:
這些選項:
注意:如果 HAL 沒有回應,預設行為是 在逾時期限 (預設為五秒) 後執行,這會延遲啟動。 如果 HAL 確實回覆,但 Android 系統無法執行動作 (例如 如果已達到使用者數量上限,系統就會採用預設行為。 範例:根據預設,Android 系統的起始時間為 啟動期間的活躍使用者。如果偵測到其他使用者的遙控車鑰,ECU 會覆寫 HAL 屬性,並且在啟動期間,Android 系統會切換為 指定的授權中。 |
SWITCH_USER (讀取/寫入) |
切換有效的前景 Android 使用者時,系統會呼叫這個屬性。
這個屬性可由 Android 系統或 HAL 呼叫,
要求切換使用者。這三項工作流程如下:
現代工作流程採用兩階段修訂方法, Android 系統和外部 ECU 會保持同步。Android 啟動轉移作業時:
HAL 應等到 例如:駕駛人在移動時 在資訊娛樂使用者介面中切換 Android 使用者。但由於兒童安全座椅 設定會與 Android 使用者相連結,那你在 使用者切換。因此,負責控管座位的 ECU 無法確認切換開關。 HAL 會回應「失敗」,且 Android 使用者未切換。
舊版工作流程是指使用者切換後傳送的單向呼叫
(因此 HAL 無法阻擋切換)。只會在
初始使用者切換) 或呼叫
範例:如果應用程式使用
車輛工作流程源自 HAL,而非 Android 系統:
範例:白先生使用 Alice 的遙控車打開汽車
HAL 透過以下方式回覆「 |
CREATE_USER (讀取/寫入) |
Android 系統會在新的 Android 使用者
(透過 CarUserManager.createUser() API 建立)。
HAL 會以 範例:駕駛人輕觸資訊娛樂 UI 圖示, 建立新的 Android 使用者這會將要求傳送給 HAL 和其他 例如車輛子系統ECU 會通知新建立的使用者。其他 接著,子系統和 ECU 便會將其內部使用者 ID 與 Android 使用者 ID。 |
REMOVE_USER (僅限寫入) |
Android 系統會在 Android 使用者
移除 (使用 CarUserManager.removeUser() 方法)。
此為單向呼叫,但 HAL 不會有任何回應。 範例:駕駛人輕觸以移除現有項目 資訊娛樂 UI 中的 Android 使用者。HAL 掌握了充分資訊 使用者將收到車輛子系統和 ECU 相關通知, 才能移除其內部使用者 ID |
其他屬性
以下是與使用者生命週期狀態無關的額外屬性。 每個項目都可以實作,但不支援使用者 HAL。
HAL 屬性 | 說明 |
---|---|
USER_IDENTIFICATION_ASSOCIATION (讀取/寫入) |
請使用這個屬性,將任何 Android 使用者與身分識別資訊建立關聯
例如鑰匙或手機使用相同資源
get 或 set 關聯。
範例:一位駕駛人輕觸資訊娛樂 UI 圖示,以便建立關聯
用來打開車輛的鑰匙 ( |
輔助程式庫
請求和回應訊息中使用的所有物件 (例如
UserInfo
、InitialUserInfoRequest
、
InitialUSerInfoResponse
等) 具有較高等級的表示法
使用 C++ struct
,但移除物件必須分割為
標準 VehiclePropValue
物件 (請參閱以下範例)。便利
C++
Android 開放原始碼計畫提供輔助程式庫,可自動轉換使用者 HAL
將 structs
轉換為 VehiclePropValue
(反之亦然)。
範例
INITIAL_USER_INFO
要求範例 (首次啟動時)
VehiclePropValue { // flattened from InitialUserInfoRequest prop: 299896583 // INITIAL_USER_INFO prop.values.int32Values: [0] = 1 // Request ID [1] = 1 // InitialUserInfoRequestType.FIRST_BOOT [2] = 0 // user id of current user [3] = 1 // flags of current user (SYSTEM) [4] = 1 // number of existing users [5] = 0 // existingUser[0].id [6] = 1 // existingUser[0].flags }
回應範例 (建立管理員使用者)
VehiclePropValue { // flattened from InitialUserInfoResponse prop: 299896583 // INITIAL_USER_INFO prop.values.int32Values: [0] = 1 // Request ID (must match request) [1] = 2 // InitialUserInfoResponseAction.CREATE [2] = -10000 // user id (not used on CREATE) [3] = 8 // user flags (ADMIN) prop.values.stringValue: "en-US||Car Owner" // User locale and User name }
SWITCH_使用者
類別和屬性的實際名稱略有不同 整體工作流程保持不變,如下圖所示:
圖 1. 使用者 HAL 屬性工作流程
現代化工作流程要求示例
VehiclePropValue { // flattened from SwitchUserRequest prop: 299896585 // SWITCH_USER prop.values.int32Values: [0] = 42 // Request ID [1] = 2 // SwitchUserMessageType::ANDROID_SWITCH ("modern") [2,3] = 11,0 // target user id (11) and flags (none in this case) [4,5] = 10,8 // current user id (10) and flags (ADMIN) [6] = 3 // number of existing users (0, 10, 11) [7,8] = 0,1 // existingUser[0] (id=0, flags=SYSTEM) [9,10] = 10,8 // existingUser[1] (id=10, flags=ADMIN) [11,12] = 11,0 // existingUser[2] (id=11, flags=NONE) }
現代化工作流程回應範例
VehiclePropValue { // flattened from SwitchUserResponse prop: 299896584 // SWITCH_USER prop.values.int32Values: [0] = 42 // Request ID (must match request) [1] = 3 // SwitchUserMessageType::VEHICLE_RESPONSE [2] = 1 // SwitchUserStatus::SUCCESS }
現代化工作流程換機後的應變示例
此回應通常會在 Android 切換成功時發生:
VehiclePropValue { // flattened from SwitchUserRequest prop: 299896584 // SWITCH_USER prop.values.int32Values: [0] = 42 // Request ID (must match "pre"-SWITCH_USER request ) [1] = 5 // SwitchUserMessageType::ANDROID_POST_SWITCH [2,3] = 11,0 // target user id (11) and flags (none in this case) [4,5] = 11,0 // current user id (11) and flags (none in this case) [6] = 3 // number of existing users (0, 10, 11) [7,8] = 0,1 // existingUser[0] (id=0, flags=SYSTEM) [9,10] = 10,8 // existingUser[1] (id=10, flags=ADMIN) [11,12] = 11,0 // existingUser[2] (id=11, flags=NONE) }
現代化工作流程切換後的應變措施
這類回應通常會在 Android 切換失敗時發生:
VehiclePropValue { // flattened from SwitchUserRequest prop: 299896584 // SWITCH_USER prop.values.int32Values: [0] = 42 // Request ID (must match "pre"-SWITCH_USER request ) [1] = 5 // SwitchUserMessageType::ANDROID_POST_SWITCH [2,3] = 11,0 // target user id (11) and flags (none in this case) [4,5] = 10,8 // current user id (10) and flags (ADMIN) [6] = 3 // number of existing users (0, 10, 11) [7,8] = 0,1 // existingUser[0] (id=0, flags=SYSTEM) [9,10] = 10,8 // existingUser[1] (id=10, flags=ADMIN) [11,12] = 11,0 // existingUser[2] (id=11, flags=NONE) }
舊版工作流程要求示例
VehiclePropValue { // flattened from SwitchUserRequest prop: 299896584 // SWITCH_USER prop.values.int32Values: [0] = 2 // Request ID [1] = 1 // SwitchUserMessageType::LEGACY_ANDROID_SWITCH [2,3] = 10,8 // target user id (10) and flags (ADMIN) [4,5] = 0,1 // current user id (0) and flags (SYSTEM) [6] = 3 // number of existing users (0, 10, 11) [7,8] = 0,1 // existingUser[0] (id=0, flags=SYSTEM) [9,10] = 10,8 // existingUser[1] (id=10, flags=ADMIN) [11,12] = 11,0 // existingUser[2] (id=11, flags=NONE) }
車輛工作流程要求示例
VehiclePropValue { // flattened from SwitchUserRequest prop: 299896584 // SWITCH_USER prop.values.int32Values: [0] = -108 // Request ID (must be negative) [1] = 4 // SwitchUserMessageType::VEHICLE_REQUEST [2] = 11 // target user id }
舊版工作流程換機後的應變
此回應通常會在 Android 切換成功時發生:
VehiclePropValue { // flattened from SwitchUserRequest prop: 299896584 // SWITCH_USER prop.values.int32Values: [0] = -108 // Request ID (must match from vehicle request ) [1] = 5 // SwitchUserMessageType::ANDROID_POST_SWITCH [2,3] = 11,0 // target user id (11) and flags (none in this case) [4,5] = 11,0 // current user id (11) and flags (none in this case) [6] = 3 // number of existing users (0, 10, 11) [7,8] = 0,1 // existingUser[0] (id=0, flags=SYSTEM) [9,10] = 10,8 // existingUser[1] (id=10, flags=ADMIN) [11,12] = 11,0 // existingUser[2] (id=11, flags=NONE) }
建立使用者
要求範例
VehiclePropValue { // flattened from CreateUserRequest prop: 299896585 // CREATE_USER prop.values.int32Values: [0] = 42 // Request ID [1,2] = 11,6 // Android id of the created user and flags (id=11, flags=GUEST, EPHEMERAL) [3,4] = 10,0 // current user id (10) and flags (none in this case) [5] = 3 // number of existing users (0, 10, 11) [6,7] = 0,1 // existingUser[0] (id=0, flags=SYSTEM) [8,9] = 10,8 // existingUser[1] (id=10, flags=ADMIN) [10,11] = 11,6 // newUser[2] (id=11, flags=GUEST,EPHEMERAL) }
回應範例
VehiclePropValue { // flattened from CreateUserResponse prop: 299896585 // CREATE_USER prop.values.int32Values: [0] = 42 // Request ID (must match request) [1] = 3 // CreateUserStatus::SUCCESS }
REMOVE_USER
要求範例
VehiclePropValue { // flattened from RemoveUserRequest prop: 299896586 // REMOVE_USER prop.values.int32Values: [0] = 42 // Request ID [1,2] = 11,0 // Android id of the removed user and flags (none in this case) [3,4] = 10,0 // current user id (10) and flags (none in this case) [5] = 2 // number of existing users (0, 10) [6,7] = 0,1 // existingUser[0] (id=0, flags=SYSTEM) [8,9] = 10,8 // existingUser[1] (id=10, flags=ADMIN) }
使用者 ID
設定範例 (與使用者 10 相關聯的索引鍵)
VehiclePropValue { // flattened from UserIdentificationSetRequest prop: 299896587 // USER_IDENTIFICATION_ASSOCIATION prop.values.int32Values: [0] = 43 // Request ID [1,2] = 10,0 // Android id (10) and flags (none in this case) [3] = 1 // number of associations being set [4] = 1 // 1st type: UserIdentificationAssociationType::KEY_FOB [5] = 1 // 1st value: UserIdentificationAssociationSetValue::ASSOCIATE_CURRENT_USER }