De nombreuses architectures de véhicule actuelles contiennent plusieurs unités de commande électronique à l'extérieur du système d'infoloisirs qui contrôlent l'ergonomie (siège, par exemple) et les réglages du miroir. Basé sur le matériel et la puissance actuels de nombreuses processeurs virtuels, de nombreuses unités de calcul de calcul est sous tension. Ces UCU peuvent interagir avec un système d'infoloisirs basé sur Android via le Couche d'abstraction matérielle du véhicule (VHAL).
À partir d'Android 11, Android Automotive OS (AAOS) a lancé un nouvel ensemble propriétés sur le VHAL pour créer, modifier, supprimer et associer des accessoires externes pour identifier les Utilisateurs. Par exemple, ces nouvelles propriétés permettent Un conducteur peut associer un accessoire externe, tel qu'une clé sans contact, à son utilisateur Android. Ensuite, lorsque le conducteur s'approche du véhicule, un ECU s'active et détecte la clé sans contact. Ce module ECU indique au HAL l'utilisateur Android à utiliser pour l'infoloisirs. démarre un démarrage, ce qui réduit le temps d'attente du pilote Utilisateur à charger.
Activer l'HAL pour les utilisateurs
Les propriétés HAL de l'utilisateur doivent être explicitement activées en veillant à ce que le système
la propriété android.car.user_hal_enabled
est définie sur true
.
(Vous pouvez également le faire dans le fichier car.mk
. Il n'est donc pas nécessaire qu'il soit
manuellement.) Vérifiez que user_hal_enabled=true
est activé en
vider le UserHalService
:
$ adb shell dumpsys car_service --hal UserHalService|grep enabled user_hal_enabled=true
Vous pouvez également vérifier user_hal_enabled
en utilisant adb shell
getprop android.car.user_hal_enabled
ou adb logcat
CarServiceHelper *:s
. Si la propriété est désactivée, un message de type
Les éléments suivants s'affichent au démarrage de system_server
:
I CarServiceHelper: Not using User HAL
Pour activer manuellement user_hal_enabled
, définissez le paramètre
Propriété système android.car.user_hal_enabled
et redémarrage
system_server
:
$ adb shell setprop android.car.user_hal_enabled true $ adb shell stop && adb shell start
Le résultat logcat
s'affiche comme suit:
I CarServiceHelper: User HAL enabled with timeout of 5000ms D CarServiceHelper: Got result from HAL: OK I CarServiceHelper: User HAL returned DEFAULT behavior
Propriétés HAL de l'utilisateur
Propriétés du cycle de vie des utilisateurs
Les propriétés suivantes fournissent les informations HAL pour le cycle de vie de l'utilisateur qui permettent de synchroniser le cycle de vie de l'utilisateur entre le système Android et une UCU externe. Ces propriétés utilisent un protocole de requête et de réponse, à laquelle le système Android envoie une requête en définissant une valeur de propriété. HAL répond en émettant un événement de modification de propriété.
Remarque:Lorsque l'HAL de l'utilisateur est compatible, toutes les options doivent être implémentées.
Propriété HAL | Description |
---|---|
INITIAL_USER_INFO (LIRE/ÉCRITURE) |
Cette propriété est appelée par le système Android pour déterminer
Utilisateur que le système démarre lorsque l'appareil démarre
Suspend-to-RAM (STR, Suspendre vers la RAM). Lorsqu'il est appelé, le HAL doit répondre avec l'une des
ces options:
<ph type="x-smartling-placeholder">
Remarque:Si le HAL ne répond pas, le comportement par défaut est s'exécuter après un délai d'inactivité (cinq secondes par défaut), ce qui retarde le démarrage. Si le HAL répond, mais que le système Android ne parvient pas à exécuter l'action (par exemple, si le nombre maximal d'utilisateurs a été atteint), le comportement par défaut est utilisé. Exemple:Par défaut, le système Android démarre au cours des l'utilisateur actif au démarrage. Si la clé sans contact d'un autre utilisateur est détectée, le processeur remplace la propriété HAL. Au démarrage, le système Android pour cet utilisateur. |
SWITCH_USER (LIRE/ÉCRITURE) |
Cette propriété est appelée lors du changement de l'utilisateur Android actif au premier plan.
La propriété peut être appelée par le système Android ou par le HAL pour
demander un changement d'utilisateur. Ces trois workflows sont les suivants: <ph type="x-smartling-placeholder">
Le workflow moderne utilise une approche de validation en deux phases pour garantir Le système Android et l'ECU externe sont synchronisés. Lorsqu'Android lance le changement:
Le HAL doit attendre après le Exemple:En mouvement, le conducteur tente de changer d'utilisateur Android dans l'interface d'infoloisirs. Cependant, comme le siège de voiture sont liés à l'utilisateur Android, le siège bouge Bouton bascule utilisateur. Ainsi, l’unité ECU contrôlant les sièges ne confirme pas le commutateur, le HAL répond par un échec et l'utilisateur Android n'est pas changé.
L'ancien workflow est un appel à sens unique envoyé après le changement d'utilisateur
(le HAL ne peut donc pas bloquer le commutateur). Il n'est appelé qu'au démarrage (après
changement d'utilisateur initial) ou pour les applications qui appellent
Exemple:Si une application utilise
Le workflow du véhicule provient du HAL, et non du système Android:
Exemple:Pierre a utilisé la clé sans contact d'Alice pour ouvrir la voiture
et le HAL a répondu à la requête |
CREATE_USER (LIRE/ÉCRITURE) |
Cette propriété est appelée par le système Android lorsqu'un nouvel utilisateur Android
(à l'aide de l'API CarUserManager.createUser() ).
Le HAL répond par Exemple:Un conducteur appuie sur une icône d'interface d'infoloisirs pour créer un utilisateur Android. Une requête est alors envoyée au HAL, des sous-systèmes du véhicule. Les ECU sont informées de l'utilisateur nouvellement créé. Autre les sous-systèmes et les ECU associent ensuite leur ID utilisateur interne à l’application Android ID utilisateur. |
REMOVE_USER (ÉCRITURE uniquement) |
Le système Android appelle cette propriété après qu'un utilisateur Android
(avec la méthode CarUserManager.removeUser() ).
Il s'agit d'un appel à sens unique. Aucune réponse n'est attendue de la part du HAL. Exemple:Un conducteur appuie pour supprimer un élément existant Utilisateur Android dans l'interface d'infoloisirs. Le HAL est informé et les autres les sous-systèmes des véhicules et les UCU sont informés de la suppression de l’utilisateur afin qu’ils peut supprimer son ID utilisateur interne. |
Autres propriétés
Vous trouverez ci-dessous des propriétés supplémentaires, sans rapport avec les états du cycle de vie des utilisateurs. Chacun d'eux peut être implémenté sans prendre en charge le HAL de l'utilisateur.
Propriété HAL | Description |
---|---|
USER_IDENTIFICATION_ASSOCIATION (LIRE/ÉCRITURE) |
Utilisez cette propriété pour associer n'importe quel utilisateur Android à une identification.
d'un mécanisme, tel qu'une clé sans contact ou un téléphone. Utiliser cette même propriété pour :
Associations get ou set .
Exemple:Un conducteur appuie sur une icône d'interface d'infoloisirs pour l'associer
La clé sans contact utilisée pour ouvrir le véhicule ( |
Bibliothèques d'aide
Tous les objets utilisés dans les messages de requête et de réponse (tels que
UserInfo
, InitialUserInfoRequest
InitialUSerInfoResponse
, etc.) disposent d'une représentation de haut niveau
avec struct
C++, mais la suppression doit être aplatie en
des objets VehiclePropValue
standards (voir les exemples ci-dessous). Pour plus de simplicité
de développement, une
C++
bibliothèque d'aide fournie dans AOSP pour convertir automatiquement l'HAL utilisateur
structs
en VehiclePropValue
(et inversement).
Exemples
INFO_UTILISATEUR_INITIAL
Exemple de requête (au premier démarrage)
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 }
Exemple de réponse (créer un administrateur)
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 }
CHANGER D'UTILISATEUR
Le nom réel des classes et des propriétés diffère légèrement, mais le le workflow global est le même, comme illustré ci-dessous:
Figure 1 : Workflow des propriétés HAL de l'utilisateur
Exemple de requête de workflow moderne
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) }
Exemple de réponse de workflow moderne
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 }
Exemple de réponse à un workflow moderne après un basculement
Cette réponse se produit généralement lorsqu'un basculement Android aboutit:
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) }
Workflow moderne après le basculement
Cette réponse se produit généralement en cas d'échec d'un commutateur 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) }
Exemple de requête d'ancien workflow
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) }
Exemple de requête de workflow de véhicule
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 }
Réponse de l'ancien workflow après le basculement
Cette réponse se produit généralement lorsqu'un basculement Android aboutit:
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) }
CRÉER_UTILISATEUR
Exemple de requête
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) }
Exemple de réponse
VehiclePropValue { // flattened from CreateUserResponse prop: 299896585 // CREATE_USER prop.values.int32Values: [0] = 42 // Request ID (must match request) [1] = 3 // CreateUserStatus::SUCCESS }
SUPPRIMER L'UTILISATEUR
Exemple de requête
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) }
USER_IDENTIFICATION_ASSOCIATION (ASSOCIATION_UTILISATEUR)
Exemple de jeu de clés (clé sans contact associée à l'utilisateur 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 }