Mevcut birçok araç mimarisi, bilgi-eğlence sisteminin dışında koltuk ayarları ve ayna ayarları gibi ergonomiyi kontrol eden birden fazla elektronik kontrol birimi (ECU) içerir. Mevcut donanım ve güç mimarilerine bağlı olarak birçok ECU, Android tabanlı bilgi-eğlence sistemi açılmadan önce açılır. Bu ECU'lar, araç donanım soyutlama katmanı (VHAL) üzerinden Android tabanlı bir bilgi-eğlence sistemiyle arayüz oluşturabilir.
Android 11'den itibaren Android Automotive OS (AAOS), kullanıcıları tanımlamak için harici aksesuarlar oluşturmak, değiştirmek, kaldırmak ve ilişkilendirmek amacıyla VHAL'de yeni bir özellik grubu kullanıma sundu. Örneğin, bu yeni özellikler sayesinde sürücüler, anahtar fob gibi harici bir aksesuarı Android kullanıcılarıyla eşleyebilir. Ardından, sürücü araca yaklaştığında bir ECU uyanır ve anahtar kumandayı algılar. Bu ECU, HAL'e bilgi-eğlence sisteminin hangi Android kullanıcısını başlatması gerektiğini belirtir. Bu sayede sürücü, Android kullanıcısının yüklenmesini beklemek için daha az zaman harcar.
Kullanıcı HAL'sini etkinleştirme
Kullanıcı HAL mülkleri, android.car.user_hal_enabled
sistem mülkünün true
olarak ayarlanmasıyla açıkça etkinleştirilmelidir.
(Bunu car.mk
dosyasında yapabilirsiniz. Böylece manuel olarak ayarlanması gerekmez.) UserHalService
'yi dökerek user_hal_enabled=true
'nin etkinleştirildiğinden emin olun:
$ adb shell dumpsys car_service --hal UserHalService|grep enabled user_hal_enabled=true
user_hal_enabled
adresini adb shell
getprop android.car.user_hal_enabled
veya adb logcat
CarServiceHelper *:s
kullanarak da kontrol edebilirsiniz. Mülk devre dışı bırakılırsa system_server
başlatıldığında aşağıdakine benzer bir mesaj görüntülenir:
I CarServiceHelper: Not using User HAL
user_hal_enabled
'ü manuel olarak etkinleştirmek için android.car.user_hal_enabled
sistem özelliğini ayarlayın ve system_server
'yi yeniden başlatın:
$ adb shell setprop android.car.user_hal_enabled true $ adb shell stop && adb shell start
logcat
çıkışı aşağıdaki gibi görünür:
I CarServiceHelper: User HAL enabled with timeout of 5000ms D CarServiceHelper: Got result from HAL: OK I CarServiceHelper: User HAL returned DEFAULT behavior
Kullanıcı HAL özellikleri
Kullanıcı yaşam döngüsü özellikleri
Aşağıdaki özellikler, Android sistemi ile harici bir ECU arasında kullanıcı yaşam döngüsü senkronizasyonunu sağlayan kullanıcı yaşam döngüsü durumları için HAL bilgilerini sağlar. Bu mülklerde, Android sisteminin bir mülk değeri ayarlayarak istek gönderdiği ve HAL'in bir mülk değişikliği etkinliği yayınlayarak yanıt verdiği bir istek ve yanıt protokolü kullanılır.
Not: Kullanıcı HAL desteklendiğinde aşağıdaki özelliklerin tümü uygulanmalıdır.
HAL mülkü | Açıklama |
---|---|
INITIAL_USER_INFO (okuma/yazma) |
Android sistemi, cihaz önyüklendiğinde veya RAM'de askıya alma (STR) işleminden devam ettirildiğinde sistemin hangi Android kullanıcısını başlatacağını belirlemek için bu özelliği çağırır. HAL çağrıldığında aşağıdaki seçeneklerden biriyle yanıt vermelidir:
Not: HAL yanıt vermezse varsayılan davranış, bir zaman aşımı süresinden (varsayılan olarak beş saniye) sonra yürütme işlemini gerçekleştirmektir. Bu da önyüklemeyi geciktirir. HAL yanıt verirse ancak Android sistemi işlemi yürütemezse (ör. maksimum kullanıcı sayısına ulaşıldıysa) varsayılan davranış kullanılır. Örnek: Android sistemi varsayılan olarak, önyükleme sırasında son etkin kullanıcıda başlar. Farklı bir kullanıcı için uzaktan kumanda algılanırsa ECU, HAL özelliğini geçersiz kılar ve başlatma sırasında Android sistemi belirtilen kullanıcıda başlayacak şekilde geçiş yapar. |
SWITCH_USER (okuma/yazma) |
Bu mülk, etkin ön plan Android kullanıcısı değiştirilirken çağrılır.
Mülk, kullanıcı geçişi isteğinde bulunmak için Android sistemi veya HAL tarafından çağrılabilir. Üç iş akışı şunlardır:
Modern iş akışı, Android sisteminin ve harici ECU'nun senkronize olmasını sağlamak için iki aşamalı taahhüt yaklaşımı kullanır. Android, geçişi başlattığında:
HAL, ECU'ları senkronize etmek veya diğer HAL özelliklerini güncellemek için durumunu güncellemek üzere Örnek: Sürücünün, hareket halindeyken bilgi-eğlence sistemi kullanıcı arayüzünde Android kullanıcılarını değiştirmeye çalışması Bununla birlikte, araba koltuğu ayarları Android kullanıcısına bağlı olduğundan kullanıcı değişimi sırasında koltuk hareket eder. Bu nedenle, koltukları kontrol eden ECU geçişi onaylamıyor, HAL bir hata yanıtı veriyor ve Android kullanıcısı geçiş yapmıyor.
Eski iş akışı, kullanıcı geçiş yaptıktan sonra gönderilen tek yönlü bir çağrıdır (yani HAL, anahtarı engelleyemez). Yalnızca başlatma sırasında (ilk kullanıcı geçişinden sonra) veya
Örnek: Bir uygulama, kullanıcı değiştirmek için Araç iş akışı, Android sisteminden değil HAL'den kaynaklanır:
Örnek: Boran, arabayı açmak için Aslı'nın anahtar kumandası kullandı ve HAL, |
CREATE_USER (okuma/yazma) |
Bu mülk, yeni bir Android kullanıcısı oluşturulduğunda (CarUserManager.createUser() API kullanılarak) Android sistemi tarafından çağrılır.
HAL, Örnek: Bir sürücü, yeni bir Android kullanıcısı oluşturmak için bilgi-eğlence kullanıcı arayüzü simgesine dokunur. Bu işlem, HAL'ye ve araç alt sistemlerinin geri kalanına bir istek gönderir. ECU'lar yeni oluşturulan kullanıcı hakkında bilgilendirilir. Ardından diğer alt sistemler ve ECU'lar dahili kullanıcı kimliklerini Android kullanıcı kimliğiyle ilişkilendirir. |
REMOVE_USER (yalnızca KAYDET) |
Android sistemi, bir Android kullanıcısı kaldırıldığında (CarUserManager.removeUser() yöntemiyle) bu özelliği çağırır.
Bu tek yönlü bir aramadır. HAL'den herhangi bir yanıt beklenmemektedir. Örnek: Bir sürücü, bilgi-eğlence kullanıcı arayüzünde mevcut bir Android kullanıcısını kaldırmak için dokunuyor. HAL bilgilendirilir. Diğer araç alt sistemleri ve ECU'lar, dahili kullanıcı kimliklerini kaldırabilmeleri için kullanıcının kaldırılması konusunda bilgilendirilir. |
Ek özellikler
Aşağıdakiler, kullanıcı yaşam döngüsü durumlarıyla alakalı olmayan ek özelliklerdir. Her biri, kullanıcı HAL'ini desteklemeden uygulanabilir.
HAL mülkü | Açıklama |
---|---|
USER_IDENTIFICATION_ASSOCIATION (okuma/yazma) |
Herhangi bir Android kullanıcısını bir kimlik mekanizmasıyla (ör. anahtar fob veya telefon) ilişkilendirmek için bu mülkü kullanın. get veya set ilişkilendirmeleri için de aynı mülkü kullanın.
Örnek: Bir sürücü, aracı açmak için kullanılan anahtar fobisini ( |
Yardımcı kitaplıklar
İstek ve yanıt mesajlarında kullanılan tüm nesneler (UserInfo
, InitialUserInfoRequest
, InitialUSerInfoResponse
vb.) C++ struct
kullanarak üst düzey temsile sahiptir ancak kaldırma işleminin standart VehiclePropValue
nesneleri olarak birleştirilmesi gerekir (aşağıdaki örneklere bakın). Geliştirme sürecini kolaylaştırmak için AOSP'de, User HAL structs
'yi VehiclePropValue
'a (ve bunun tersini) otomatik olarak dönüştüren bir C++ yardımcı kitaplığı sağlanır.
Örnekler
INITIAL_USER_INFO
İstek örneği (ilk açılışta)
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 }
Yanıt örneği (Yönetici kullanıcı oluşturma)
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
Sınıfların ve özelliklerin gerçek adı biraz farklıdır ancak genel iş akışı, şekilde gösterildiği gibi aynıdır:
Şekil 1. Kullanıcı HAL özellikleri iş akışı.
Modern iş akışı isteği örneği
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) }
Modern iş akışı yanıtı örneği
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 }
Geçiş sonrası modern iş akışı yanıtı örneği
Bu yanıt genellikle bir Android geçişi başarılı olduğunda gerçekleşir:
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) }
Geçiş sonrası modern iş akışı yanıtı
Bu yanıt genellikle Android geçişi başarısız olduğunda ortaya çıkar:
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) }
Eski iş akışı isteği örneği
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) }
Araç iş akışı isteği örneği
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 }
Geçiş sonrası eski iş akışı yanıtı
Bu yanıt genellikle bir Android geçişi başarılı olduğunda gerçekleşir:
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) }
CREATE_USER
Örnek istek
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) }
Yanıt örneği
VehiclePropValue { // flattened from CreateUserResponse prop: 299896585 // CREATE_USER prop.values.int32Values: [0] = 42 // Request ID (must match request) [1] = 3 // CreateUserStatus::SUCCESS }
REMOVE_USER
Örnek istek
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
Örnek ayarlayın (Kullanıcı 10 ile ilişkili tuş birimi)
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 }