Wiele współczesnych architektur pojazdów zawiera wiele elektronicznych jednostek sterujących poza systemem multimedialnym, który kontroluje ergonomię, np. fotela ustawienia i opcje odbicia lustrzanego. Na podstawie obecnego sprzętu i mocy i w innych architekturach wiele urządzeń ECU jest zasilanych przed systemem multimedialnym opartym na Androidzie. jest naładowany. Jednostki ECU mogą łączyć się z systemem multimedialnym opartym na Androidzie za pomocą Warstwa abstrakcji sprzętowej pojazdu (VHAL).
Począwszy od Androida 11 w systemie operacyjnym Android Automotive (AAOS) wprowadzono nowy zestaw właściwości w VHAL do tworzenia, przełączania, usuwania i wiązania akcesoriów zewnętrznych do identyfikacji Użytkowników. Te nowe usługi pozwalają na przykład kierowcy do powiązania akcesorium zewnętrznego, np. kluczyka, z użytkownikiem Androida. Następnie, gdy kierowca zbliży się do pojazdu, urządzenie ECU wybudza się i wykrywa kluczyk. Ten moduł ECU wskazuje HAL, którego użytkownika Androida powinien używać system multimedialny uruchamiają się, co skraca czas oczekiwania kierowcy na Androida; Wczytywanie użytkownika.
Włącz HAL użytkownika
Właściwości HAL użytkownika muszą być wyraźnie włączone przez zapewnienie, że system
właściwość android.car.user_hal_enabled
ma wartość true
.
(Można to również zrobić w pliku car.mk
, więc nie trzeba tego robić
ręcznie). Sprawdź, czy usługa user_hal_enabled=true
jest włączona przez
zrzucając UserHalService
:
$ adb shell dumpsys car_service --hal UserHalService|grep enabled user_hal_enabled=true
user_hal_enabled
możesz też sprawdzić, używając adb shell
getprop android.car.user_hal_enabled
lub adb logcat
CarServiceHelper *:s
. Jeśli usługa jest wyłączona, pojawi się komunikat taki jak
po uruchomieniu system_server
wyświetla się następujący komunikat:
I CarServiceHelper: Not using User HAL
Aby ręcznie włączyć funkcję user_hal_enabled
, ustaw wartość
android.car.user_hal_enabled
właściwość systemowa i uruchom ponownie
system_server
:
$ adb shell setprop android.car.user_hal_enabled true $ adb shell stop && adb shell start
Dane wyjściowe funkcji logcat
będą wyglądać tak:
I CarServiceHelper: User HAL enabled with timeout of 5000ms D CarServiceHelper: Got result from HAL: OK I CarServiceHelper: User HAL returned DEFAULT behavior
Właściwości HAL użytkownika
Właściwości cyklu życia użytkownika
Poniższe właściwości dostarczają informacji o HAL dotyczących cyklu życia użytkownika które umożliwiają synchronizację cyklu życia użytkownika między systemem Android i zewnętrznej jednostki ECU. Usługi te korzystają z protokołu żądań i odpowiedzi do których system Android wysyła żądanie, ustawiając wartość właściwości, a funkcja HAL odpowiada, wysyłając zdarzenie zmiany usługi.
Uwaga: jeśli HAL użytkownika jest obsługiwana, wszystkie te .
usługa HAL | Opis |
---|---|
INITIAL_USER_INFO (ODCZYT/ZAPIS) |
Jest ona wywoływana przez system Android w celu określenia,
Użytkownik uruchamia system po uruchomieniu urządzenia lub wznowieniu działania urządzenia
Zawieszenie w pamięci RAM (STR). Po wywołaniu HAL musi odpowiedzieć z użyciem jednego z tych elementów:
następujące opcje:
Uwaga: jeśli HAL nie odpowiada, domyślnym działaniem jest są wykonywane po upłynięciu czasu oczekiwania (domyślnie co pięć sekund), co opóźnia rozruch. Jeśli HAL odpowiada, ale system Android nie wykonuje działania (na przykład jeśli została osiągnięta maksymalna liczba użytkowników, używane jest działanie domyślne. Przykład: domyślnie system Android rozpoczyna działanie w ciągu ostatniego użytkownik jest aktywny po uruchomieniu programu. Jeśli zostanie wykryty pilot dla innego użytkownika, zastępuje właściwość HAL, a podczas uruchamiania system Android w ramach tego konkretnego Użytkownika. |
SWITCH_USER (ODCZYT/ZAPIS) |
Ta właściwość jest wywoływana podczas przełączania aktywnego użytkownika Androida na pierwszym planie.
Właściwość może zostać wywołana przez system Android lub przez HAL do
zażądać przeniesienia użytkowników. Te 3 przepływy pracy to:
W nowoczesnym przepływie pracy stosowane jest dwufazowe podejście do zatwierdzania, System Android i zewnętrzna jednostka ECU są zsynchronizowane. Gdy Android zainicjuje przełączenie:
HAL powinien poczekać do Przykład: podczas jazdy kierowca próbuje przełączać użytkowników Androida w interfejsie systemu multimedialnego. Ponieważ foteliek samochodowy są powiązane z użytkownikiem Androida, fotel przesuwa się w czasie Przełącznik użytkowników. Dlatego sterowanie fotelami przez ECU nie potwierdza zmiany. HAL zgłasza błąd, a użytkownik Androida nie przełącza się.
Starsza wersja przepływu pracy to połączenie jednokierunkowe wysyłane po przełączeniu konta użytkownika.
(aby HAL nie mógł zablokować przełącznika). Jest wywoływane tylko przy uruchamianiu (po
i aplikacji, które nawiązują połączenie
Przykład: jeśli aplikacja używa
Procedura dotycząca pojazdów pochodzi z listy HAL, a nie z systemu Android:
Przykład: Robert użył kluczyka Alicji, aby otworzyć samochód
a HAL odpowiedział na prośbę |
CREATE_USER (ODCZYT/ZAPIS) |
Ta właściwość jest wywoływana przez system Android, gdy nowy użytkownik
(przy użyciu interfejsu API CarUserManager.createUser() ).
HAL odpowiada parametrowi Przykład: kierowca klika ikonę interfejsu informacyjno-rozrywkowego, utworzyć nowego użytkownika Androida. Spowoduje to wysłanie żądania do HAL i pozostałych podsystemów pojazdów. Jednostki ECU są powiadamiane o nowo utworzonym użytkowniku. Inny powód wiążą swój wewnętrzny identyfikator użytkownika z systemem Android. Identyfikator użytkownika. |
REMOVE_USER (tylko ZAPIS) |
System Android wywołuje tę właściwość, gdy użytkownik Androida
usunięto (metodą CarUserManager.removeUser() ).
Jest to połączenie jednokierunkowe – HAL nie oczekuje na odpowiedź. Przykład: kierowca klika, by usunąć istniejący pojazd. Użytkownik Androida w interfejsie multimedialnym. Poinformowanie HAL, podsystemy pojazdów i moduły ECU są informowane o usunięciu usługi przez użytkownika, może usunąć swój wewnętrzny identyfikator użytkownika. |
Dodatkowe właściwości
Poniżej znajdują się dodatkowe usługi, które nie są związane ze stanami cyklu życia użytkownika. Każdą z tych opcji można wdrożyć bez obsługi HAL użytkownika.
Usługa HAL | Opis |
---|---|
USER_IDENTIFICATION_ASSOCIATION (ODCZYT/ZAPIS) |
Używaj tej usługi do powiązania dowolnego użytkownika Androida z identyfikatorem
takich jak pilot lub telefon. Użyj tej samej usługi do:
Powiązania get lub set .
Przykład: kierowca klika ikonę interfejsu multimedialnego, aby powiązać
pilot używany do otwierania pojazdu ( |
Biblioteki pomocnicze
Wszystkie obiekty używane w wiadomościach z żądaniami i odpowiedziami (takie jak
UserInfo
, InitialUserInfoRequest
,
InitialUSerInfoResponse
itp.) są reprezentowane na całym świecie.
przy użyciu języka C++ struct
, ale usunięcie należy spłaszczyć do
standardowych obiektów VehiclePropValue
(zobacz przykłady poniżej). Dla ułatwienia
rozwoju,
C++
biblioteka pomocnicza jest udostępniana w AOSP w celu automatycznej konwersji HAL użytkownika
structs
do VehiclePropValue
(i odwrotnie).
Przykłady
INITIAL_USER_INFO
Przykład żądania (przy pierwszym uruchomieniu)
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 }
Przykładowa odpowiedź (utwórz administratora)
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_USER
Rzeczywista nazwa klas i właściwości nieco się różni, ale atrybut ogólny przepływ pracy jest taki sam, jak na ilustracji poniżej:
Rysunek 1. Przepływ pracy związany z usługami HAL użytkownika
Przykład żądania nowoczesnego przepływu pracy
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) }
Przykładowa odpowiedź z nowoczesnym przepływem pracy
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 }
Przykładowa odpowiedź z nowoczesnym przepływem pracy po przełączeniu
Ta odpowiedź zwykle występuje wtedy, gdy po przełączeniu się na Androida:
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) }
Nowoczesny przepływ pracy – odpowiedź po przełączeniu
Ta odpowiedź zwykle występuje wtedy, gdy nie uda się przełączyć na Androida:
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) }
Przykład żądania starszego przepływu pracy
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) }
Przykład żądania przepływu pracy dotyczącego pojazdu
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 }
Odpowiedź ze starszej wersji przepływu pracy po przełączeniu
Ta odpowiedź zwykle występuje wtedy, gdy po przełączeniu się na Androida:
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) }
UTWÓRZ_UŻYTKOWNIKA
Przykład żądania
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) }
Przykładowa odpowiedź
VehiclePropValue { // flattened from CreateUserResponse prop: 299896585 // CREATE_USER prop.values.int32Values: [0] = 42 // Request ID (must match request) [1] = 3 // CreateUserStatus::SUCCESS }
REMOVE_USER
Przykład żądania
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) }
Identyfikator_IDENTIFICATION_ASSOCIATION
Przykład (kluczyk powiązany z Użytkownikiem 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 }