HAL-Nutzereigenschaften

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. starten und so die Zeit verkürzen, die der Fahrer auf sein Android-Gerät wartet 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:
  • Das von Android festgelegte Standardverhalten (Wechsel zur zuletzt verwendeten Nutzer oder Erstellen eines neuen Nutzers, wenn dies der erste Startvorgang ist.
  • Wechseln Sie zu einem vorhandenen Nutzer.
  • Neuen Nutzer erstellen (mit den optionalen Attributen name, Flags, system usw.) und wechseln Sie zu diesem neuen Nutzer.

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 wurde, 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:
  • Modern Wechsel ab CarUserManager gestartet.
  • Alt: Wechsel ab ActivityManager gestartet.
  • Fahrzeug. Wird vom HAL aufgerufen, um einen Nutzerwechsel anzufordern.

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:

  1. Überprüfen Sie den HAL, um festzustellen, ob der User-Wechsel möglich ist.

    Der HAL antwortet mit SUCCESS oder FAILURE, sodass Android weiß, ob es fortfahren soll oder nicht.

  2. Schließen Sie den Wechsel des Android-Nutzers ab.

    Android sendet eine ANDROID_POST_SWITCH-Antwort an den HAL, wenn der Wechsel erfolgreich oder fehlgeschlagen ist.

Der HAL sollte bis nach ANDROID_POST_SWITCH warten Antwort zum Aktualisieren des Status zum Synchronisieren von ECUs oder zum Aktualisieren anderer HAL Eigenschaften.

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 sind, 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 ActivityManager.switchUser() statt CarUserManager.switchUser(). Die Referenz Die Apps „Settings“ und „SystemUI“ verwenden bereits den aber wenn ein OEM eigene Einstellungen für den Nutzerwechsel bereitstellt, OEMs sollten die Nutzung ändern.

Beispiel:Wenn in einer App ActivityManager.switchUser() bis wechselt, wird ein einseitiger Anruf an den HAL gesendet, um zu informieren, geschaltet wurde.

Der Fahrzeug-Workflow stammt vom HAL, nicht vom Android-System:

  1. Der HAL fordert einen Nutzerwechsel an.
  2. Das System hat den Android-Nutzerwechsel abgeschlossen.
  3. Android sendet eine ANDROID_POST_SWITCH-Antwort an den HAL, um anzugeben, ob ein Wechsel erfolgreich war oder nicht.

Beispiel:Bob hat Alices Schlüsselanhänger verwendet, um das Auto zu öffnen. und der HAL antwortete auf die INITIAL_USER_INFO-Anfrage mit Annes Nutzer-ID. Als Nächstes identifizierte eine biometrische Sensor-ECU den Fahrer als Bob. Nutzer-HAL hat eine SWITCH_USER-Anfrage zum Wechseln des Nutzers gesendet.

CREATE_USER
(LESEN/SCHREIBEN)
Diese Eigenschaft wird vom Android-System aufgerufen, wenn ein neuer Android-Nutzer (mit der CarUserManager.createUser() API) erstellt wurden.

Der HAL antwortet mit SUCCESS oder FAILURE. Wenn die HAL antwortet mit einem Fehler. Das Android-System entfernt den Nutzer.

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 SCHREIBEN)
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 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 das Symbol der Infotainment-Benutzeroberfläche, um es zu verknüpfen. den Schlüsselanhänger, mit dem das Fahrzeug (KEY_123) für den aktuellen aktiven Android-Nutzer geöffnet wurde (USER_11).

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, ist der gesamte Workflow derselbe:

Workflow

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 Reaktion auf einen modernen Workflow 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 Fahrzeug-Workflow-Anfrage

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
}