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'ini etkinleştirme
android.car.user_hal_enabled
sistem özelliğinin true
olarak ayarlanmasıyla User HAL özellikleri 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
adb shell
getprop android.car.user_hal_enabled
veya adb logcat
CarServiceHelper *:s
kullanarak da user_hal_enabled
'ü kontrol edebilirsiniz. Mülk devre dışıysa system_server
başladığında aşağıdaki gibi bir mesaj görüntülenir:
I CarServiceHelper: Not using User HAL
user_hal_enabled
özelliğini 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) |
Bu mülk, cihaz açıldığında veya RAM'de askıya alma (STR) durumundan devam ettiğinde sistemin hangi Android kullanıcısını başlatacağını belirlemek için Android sistemi tarafından çağrılı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 sonra (varsayılan olarak beş saniye) yürütmektir. 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ıya ait bir anahtar fob'u algılanırsa ECU, HAL mülkünü geçersiz kılar ve Android sistemi, başlatma sırasında belirtilen kullanıcıda başlatılacak şekilde geçer. |
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ı Ancak araba koltuğu ayarları Android kullanıcısına bağlı olduğundan, kullanıcı geçişi 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 aramadır (bu nedenle HAL geçişi engelleyemez). Yalnızca önyüklemede (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'e ve aracın diğer alt sistemlerine bir istek gönderir. ECU'lar yeni oluşturulan kullanıcı hakkında bilgilendirilir. 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 çağrıdır. HAL'den yanıt beklenmez. Ö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 ve diğer araç alt sistemleri ile ECU'lar, kullanıcının kaldırıldığı konusunda bilgilendirilir. Böylece, dahili kullanıcı kimliklerini kaldırabilirler. |
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
kullanılarak yüksek düzeyde temsil edilir ancak kaldırma işlemi, standart VehiclePropValue
nesnelerine düzleştirilmelidir (aşağıdaki örneklere bakın). Geliştirme sürecini kolaylaştırmak için AOSP'de, kullanıcı 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 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 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
İstek örneği
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
İstek örneği
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 ayarlama (10. kullanıcıyla ilişkilendirilmiş anahtar fob)
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 }