Viele aktuelle Fahrzeugarchitekturen enthalten mehrere elektronische Steuereinheiten (ECUs) außerhalb des Infotainmentsystems mit Steuerung der Ergonomie, z. B. des Sitzes Einstellungen und Spiegelanpassungen. Basierend auf der aktuellen Hardware und Leistung Architekturen werden viele ECUs vor dem Android-basierten Infotainmentsystem eingeschaltet. eingeschaltet ist. Diese ECUs können mit einem Android-basierten Infotainmentsystem verbunden werden. über das Fahrzeughardware-Abstraktionsschicht (Vehicle Hardware Abstraktionsschicht, VHAL):
Ab Android 11 wurden mit Android Automotive OS (AAOS) neue Eigenschaften auf der VHAL zum Erstellen, Wechseln, Entfernen und Verknüpfen externes Zubehör zur Identifizierung von Nutzern verwenden. Diese neuen Properties ermöglichen beispielsweise einen Fahrer, der ein externes Zubehör, z. B. einen Schlüsselanhänger, mit seinem Android-Nutzer koppelt. Sobald sich der Fahrer dem Fahrzeug nähert, wacht eine ECU auf und erkennt den Schlüsselanhänger. Diese ECU gibt dem HAL an, welchen Android-Nutzer das Infotainment verwenden soll. einen Systemstart zu starten, wodurch Fahrer schneller auf ihr Android-Gerät warten müssen. Zu ladender Nutzer.
Nutzer-HAL aktivieren
Die User-HAL-Eigenschaften müssen explizit aktiviert werden, indem sichergestellt wird, dass das System
Eigenschaft android.car.user_hal_enabled
auf true
gesetzt ist.
Dies kann auch in der Datei car.mk
erfolgen.
manuell eingestellt werden.) Prüfen Sie, ob user_hal_enabled=true
aktiviert ist, indem Sie
UserHalService
speichern:
$ adb shell dumpsys car_service --hal UserHalService|grep enabled user_hal_enabled=true
Sie können user_hal_enabled
auch mit adb shell
getprop android.car.user_hal_enabled
oder adb logcat
CarServiceHelper *:s
prüfen. Wenn die Unterkunft deaktiviert ist, wird eine Meldung wie die
Folgendes wird angezeigt, wenn system_server
startet:
I CarServiceHelper: Not using User HAL
Um user_hal_enabled
manuell zu aktivieren, legen Sie den
android.car.user_hal_enabled
-Systemeigenschaft und Neustart
system_server
:
$ adb shell setprop android.car.user_hal_enabled true $ adb shell stop && adb shell start
Die Ausgabe von logcat
sieht so aus:
I CarServiceHelper: User HAL enabled with timeout of 5000ms D CarServiceHelper: Got result from HAL: OK I CarServiceHelper: User HAL returned DEFAULT behavior
HAL-Nutzereigenschaften
Nutzerlebenszyklus-Attribute
Die folgenden Eigenschaften enthalten die HAL-Informationen für den Nutzerlebenszyklus Status, die die Synchronisierung des Nutzerlebenszyklus zwischen dem Android-System und eine externe ECU. Diese Eigenschaften verwenden ein Anfrage- und Antwortprotokoll, die das Android-System durch Festlegen eines Eigenschaftswerts und des HAL reagiert, indem er ein Eigenschaftsänderungsereignis ausgibt.
Hinweis:Wenn Nutzer-HAL unterstützt wird, werden alle der folgenden müssen implementiert werden.
HAL-Eigenschaft | Beschreibung |
---|---|
INITIAL_USER_INFO (LESEN/SCHREIBEN) |
Diese Eigenschaft wird vom Android-System aufgerufen, um zu bestimmen,
Nutzer, die das System starten, wenn das Gerät gestartet oder fortgesetzt wird
Sperren von RAM. Wenn der HAL aufgerufen wird, muss er mit einer der folgenden Adressen antworten:
diese Optionen:
<ph type="x-smartling-placeholder">
Hinweis:Wenn der HAL nicht reagiert, ist das Standardverhalten nach einem Zeitlimit (standardmäßig fünf Sekunden) ausgeführt werden, wodurch der Bootvorgang verzögert wird. Wenn der HAL antwortet, das Android-System die Aktion aber nicht ausführen kann (z. B. Wenn die maximale Anzahl von Nutzern erreicht ist, wird das Standardverhalten verwendet. Beispiel:Standardmäßig startet das Android-System in den letzten aktiven Nutzer. Wird ein Schlüsselanhänger für einen anderen Nutzer erkannt, überschreibt die HAL-Eigenschaft und das Android-System wechselt beim Start in diesem angegebenen Nutzer. |
SWITCH_USER (LESEN/SCHREIBEN) |
Diese Eigenschaft wird aufgerufen, wenn der aktive Android-Nutzer im Vordergrund gewechselt wird.
Die Eigenschaft kann entweder vom Android-System oder vom HAL aufgerufen werden, um
Fordern Sie einen Nutzerwechsel an. Die drei Workflows sind: <ph type="x-smartling-placeholder">
Beim modernen Workflow wird ein zweiphasiger Commit-Ansatz verwendet, um sicherzustellen, Das Android-System und die externe ECU sind synchronisiert. Wenn Android den Wechsel initiiert:
Der HAL sollte bis nach Beispiel:Während der Fahrt versucht ein Fahrer, Android-Nutzer in der Infotainment-Benutzeroberfläche wechseln Da Autositze jedoch mit dem Android-Nutzer verknüpft ist, bewegt sich der Sitz Nutzerwechsel. Daher bestätigt die ECU, die die Sitze steuert, den Wechsel nicht, Der HAL antwortet mit einem Fehler und der Android-Nutzer wird nicht gewechselt.
Der Legacy-Workflow ist ein einseitiger Aufruf, der gesendet wird, nachdem der Nutzer gewechselt wurde.
(damit der HAL den Switch nicht blockieren kann). Es wird erst beim Booten aufgerufen (nach dem
oder für Apps, bei denen
Beispiel:Wenn in einer App
Der Fahrzeug-Workflow stammt vom HAL, nicht vom Android-System:
Beispiel:Bernd hat Alices Schlüsselanhänger verwendet, um das Auto zu öffnen.
und der HAL antwortete auf die |
CREATE_USER (LESEN/SCHREIBEN) |
Diese Eigenschaft wird vom Android-System aufgerufen, wenn ein neuer Android-Nutzer
(mit der CarUserManager.createUser() API) erstellt wurde.
Der HAL antwortet mit Beispiel:Ein Fahrer tippt auf das Symbol der Infotainment-Benutzeroberfläche, einen neuen Android-Nutzer zu erstellen. Dadurch wird eine Anfrage an den HAL und den Rest der Fahrzeug-Subsysteme. ECUs werden über den neu erstellten User informiert. Sonstiges und ECUs verknüpfen dann ihre interne Nutzer-ID mit dem User-ID. |
REMOVE_USER (nur Schreibzugriff) |
Das Android-System ruft diese Eigenschaft auf, nachdem ein Android-Nutzer
entfernt (mit der Methode CarUserManager.removeUser() ).
Dies ist ein Einwegaufruf. Es wird keine Antwort vom HAL erwartet. Beispiel:Ein Fahrer tippt, um einen vorhandenen zu entfernen. Android-Nutzer auf der Infotainment-Benutzeroberfläche. Der HAL wird informiert und andere werden die Subsysteme des Fahrzeugs und die ECUs über das Entfernen des Nutzers informiert, seine interne Nutzer-ID entfernen. |
Zusätzliche Attribute
Im Folgenden finden Sie zusätzliche Attribute, die sich nicht auf den Status des Nutzerlebenszyklus beziehen. Jedes kann ohne Unterstützung des Benutzer-HAL implementiert werden.
HAL-Eigenschaft | Beschreibung |
---|---|
USER_IDENTIFICATION_ASSOCIATION (LESEN/SCHREIBEN) |
Verwenden Sie diese Eigenschaft, um jeden Android-Nutzer einer Identifizierung zuzuordnen.
wie Schlüsselanhänger oder Telefon. Verwenden Sie diese Eigenschaft für
Verknüpfungen mit get oder set .
Beispiel:Ein Fahrer tippt auf ein Symbol für die Infotainment-Benutzeroberfläche, um es zu verknüpfen.
den Schlüsselanhänger, mit dem das Fahrzeug ( |
Hilfsbibliotheken
Alle in den Anfrage- und Antwortnachrichten verwendeten Objekte (z. B.
UserInfo
, InitialUserInfoRequest
,
InitialUSerInfoResponse
usw.) haben eine allgemeine Darstellung
mit C++ struct
, aber das Entfernen muss auf vereinfacht
VehiclePropValue
-Standardobjekte (siehe Beispiele unten) Einfacher geht's nicht
der Entwicklung, ein
C++
Hilfsbibliothek wird in AOSP bereitgestellt, um Nutzer-HAL automatisch zu konvertieren
structs
in VehiclePropValue
(und umgekehrt).
Beispiele
INITIAL_USER_INFO
Anfragebeispiel (beim ersten Start)
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 }
Antwortbeispiel (Administrator erstellen)
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 }
NUTZER_WECHSELN
Der tatsächliche Name der Klassen und Eigenschaften kann leicht abweichen, der gesamte Workflow bleibt der gleiche, wie unten dargestellt:
Abbildung 1: Workflow für Nutzer-HAL-Eigenschaften
Beispiel für eine moderne Workflow-Anfrage
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) }
Beispiel für eine moderne Workflow-Antwort
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 }
Beispiel für die Reaktion eines modernen Workflows nach dem Wechsel
Diese Antwort wird normalerweise angezeigt, wenn ein Android-Wechsel erfolgreich war:
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) }
Reaktion auf moderne Workflows nach dem Wechsel
Diese Antwort tritt normalerweise auf, wenn ein Android-Wechsel fehlschlägt:
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) }
Beispiel für Legacy-Workflow-Anfrage
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) }
Beispiel für eine Anfrage mit Fahrzeug-Workflows
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 }
Antwort des alten Workflows nach dem Wechsel
Diese Antwort wird normalerweise angezeigt, wenn ein Android-Wechsel erfolgreich war:
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) }
NUTZER_ERSTELLEN
Anfragebeispiel
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) }
Antwortbeispiel
VehiclePropValue { // flattened from CreateUserResponse prop: 299896585 // CREATE_USER prop.values.int32Values: [0] = 42 // Request ID (must match request) [1] = 3 // CreateUserStatus::SUCCESS }
NUTZER_ENTFERNEN
Anfragebeispiel
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
Beispiel festlegen (Schlüsselanhänger, der mit Nutzer 10 verknüpft ist)
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 }