Właściwości HAL użytkownika

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:
  • Domyślne zachowanie skonfigurowane przez Androida (przechodzenie na ostatnio używane użytkownika lub utworzenie nowego użytkownika, jeśli jest to pierwsze uruchomienie).
  • Przełącz się na istniejącego użytkownika.
  • Utwórz nowego użytkownika (z opcjonalnymi właściwościami nazwy, flag, systemu język itd.) i przełącz się na tego nowego użytkownika.

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:
  • Nowoczesny. Rozpoczęto przejście od CarUserManager.
  • Starsza wersja. Rozpoczęto przejście od ActivityManager.
  • Pojazd. Wywoływane przez HAL w celu zażądania przeniesienia użytkowników.

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:

  1. Sprawdź listę HAL, aby określić, czy można przełączyć użytkownika.

    HAL odpowiada ciągiem SUCCESS lub FAILURE, dzięki czemu Android wie, czy kontynuować, czy nie.

  2. Zakończ proces przełączania użytkownika Androida.

    Android wysyła odpowiedź ANDROID_POST_SWITCH do HAL do wskazywania powodzenia lub niepowodzenia przełączenia.

HAL powinien poczekać do ANDROID_POST_SWITCH odpowiedź na zaktualizowanie swojego stanu w celu zsynchronizowania ECU lub zaktualizowania innej HAL usług.

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 ActivityManager.switchUser() zamiast CarUserManager.switchUser() Plik referencyjny Aplikacje Settings i SystemUI używają już jeśli jednak producent OEM dostarcza własne aplikacje Ustawienia do przełączania użytkowników, OEM powinni zmienić sposób użytkowania.

Przykład: jeśli aplikacja używa ActivityManager.switchUser() na użytkownika, do HAL wysyłane jest połączenie jednokierunkowe z informacją, że użytkownik miało miejsce.

Procedura dotycząca pojazdów pochodzi z listy HAL, a nie z systemu Android:

  1. HAL prosi o przeniesienie użytkowników.
  2. System kończy proces przełączania użytkownika Androida.
  3. Android wysyła do HAL odpowiedź ANDROID_POST_SWITCH, aby wskazać, powodzenie lub niepowodzenie przełączania.

Przykład: Robert użył kluczyka Alicji, aby otworzyć samochód a HAL odpowiedział na prośbę INITIAL_USER_INFO, podając: Identyfikator użytkownika Alicji. Następnie czujnik biometryczny ECU rozpoznał kierowcę jako Boba, HAL użytkownika wysłała żądanie SWITCH_USER, aby przełączyć użytkowników.

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 SUCCESS lub FAILURE. Jeśli HAL zgłasza błąd, system Android usuwa użytkownika.

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 (KEY_123) w kierunku aktualnego aktywnego użytkownika Androida (USER_11).

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:

Workflow

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
}