Propriétés HAL de l'utilisateur

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">
    </ph>
  • Comportement par défaut défini par Android (passage au dernier utilisateur ou en créant un utilisateur s'il s'agit du premier démarrage).
  • Passez à un utilisateur existant.
  • Créer un nouvel utilisateur (avec les propriétés facultatives de nom, d'indicateurs, de système paramètres régionaux, etc.) et passer à ce nouvel utilisateur.

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">
    </ph>
  • Moderne. Migration lancée à partir de CarUserManager.
  • Ancienne : Migration lancée à partir de ActivityManager.
  • Véhicule. Appelé par le HAL pour demander un changement d'utilisateur.

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:

  1. Vérifiez le HAL pour déterminer s'il est possible de changer d'utilisateur.

    Le HAL répond par SUCCESS ou FAILURE, de sorte que : Android sait si vous devez continuer ou non.

  2. Effectuez le changement d'utilisateur Android.

    Android envoie une réponse ANDROID_POST_SWITCH au HAL pour indiquer la réussite ou l'échec du commutateur.

Le HAL doit attendre après le ANDROID_POST_SWITCH réponse pour mettre à jour son état afin de synchroniser les ECU ou de mettre à jour d'autres HAL propriétés.

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 ActivityManager.switchUser() au lieu de CarUserManager.switchUser() La référence Les applications Settings et SystemUI utilisent déjà le mais si un OEM fournit ses propres applications de paramétrage pour changer d'utilisateur, Les OEM doivent modifier l'utilisation.

Exemple:Si une application utilise ActivityManager.switchUser() jusqu'à change d'utilisateur, un appel à sens unique est envoyé au HAL pour informer le changement a eu lieu.

Le workflow du véhicule provient du HAL, et non du système Android:

  1. Le HAL demande un changement d'utilisateur.
  2. Le système effectue le changement d'utilisateur Android.
  3. Android envoie une réponse ANDROID_POST_SWITCH au HAL pour indiquer la réussite ou l'échec du commutateur.

Exemple:Pierre a utilisé la clé sans contact d'Alice pour ouvrir la voiture et le HAL a répondu à la requête INITIAL_USER_INFO avec l’identifiant utilisateur d’Alice. Ensuite, un ECU à capteur biométrique a identifié le conducteur comme Bob, donc le HAL de l'utilisateur a envoyé une requête SWITCH_USER pour changer d'utilisateur.

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 SUCCESS ou FAILURE. Si le HAL répond par un échec, le système Android supprime l'utilisateur.

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 (KEY_123) pour l'utilisateur Android actif actuel (USER_11).

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:

Workflow

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
}