Mevcut araç mimarilerinin çoğu, bilgi-eğlence sisteminin dışında, koltuk ayarları ve ayna ayarları gibi ergonomiyi kontrol eden birden fazla elektronik kontrol ünitesi (ECU) içerir. Mevcut donanım ve güç mimarilerine dayanarak, birçok ECU, Android tabanlı bilgi-eğlence sistemine güç verilmeden önce açılır. Bu ECU'lar , Araç donanımı soyutlama katmanı (VHAL) aracılığıyla Android tabanlı bir bilgi-eğlence sistemi ile arayüz oluşturabilir.
Android 11'den başlayarak, Android Automotive OS (AAOS), Kullanıcıları tanımlamak için harici aksesuarların oluşturulması, değiştirilmesi, kaldırılması ve ilişkilendirilmesi için VHAL'de yeni bir dizi özellik sundu. Örneğin, bu yeni özellikler, bir sürücünün anahtarlık gibi harici bir aksesuarı Android Kullanıcısına eşleştirmesine olanak tanır. Ardından sürücü araca yaklaştığında ECU uyanır ve anahtarlığı algılar. Bu ECU, HAL'ye bilgi-eğlence sisteminin hangi Android Kullanıcısına önyükleme başlatması gerektiğini belirtir, bu da sürücünün Android Kullanıcısının yüklenmesini beklediği süreyi azaltır.
Kullanıcı HAL'sini Etkinleştir
Kullanıcı HAL özelliklerinin, android.car.user_hal_enabled
sistem özelliğinin true
olarak ayarlanması sağlanarak açıkça etkinleştirilmesi gerekir. (Bu aynı zamanda car.mk
dosyasında da yapılabilir, böylece manuel olarak ayarlanmasına gerek kalmaz.) UserHalService
dosyasının dökümünü alarak user_hal_enabled=true
öğesinin etkinleştirilip etkinleştirilmediğini kontrol edin:
$ adb shell dumpsys car_service --hal UserHalService|grep enabled user_hal_enabled=true
Ayrıca user_hal_enabled
adb shell getprop android.car.user_hal_enabled
veya adb logcat CarServiceHelper *:s
kullanarak da kontrol edebilirsiniz. Özellik 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
yeniden başlatın:
$ adb shell setprop android.car.user_hal_enabled true $ adb shell stop && adb shell start
logcat
çıktısı 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 özellikler, Android sisteminin bir özellik değeri ayarlayarak istekte bulunduğu ve HAL'nin bir özellik değişikliği olayı düzenleyerek yanıt verdiği bir istek ve yanıt protokolünü kullanır.
Not: Kullanıcı HAL desteklendiğinde aşağıdaki özelliklerin tümü uygulanmalıdır.
HAL özelliği | Tanım |
---|---|
INITIAL_USER_INFO (OKUMA YAZMA) | Bu özellik, cihaz RAM'e Askıya Alma'dan (STR) önyükleme yaptığında veya devam ettirildiğ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ış, önyüklemeyi geciktiren bir zaman aşımı süresinden sonra (varsayılan olarak beş saniye) yürütülür. HAL yanıt verirse ancak Android sistemi eylemi yürütemezse (örneğin, maksimum Kullanıcı sayısına ulaşıldıysa), varsayılan davranış kullanılır. Örnek: Varsayılan olarak Android sistemi, önyükleme sırasında son aktif Kullanıcıda başlar. Farklı bir Kullanıcı için bir anahtarlık algılanırsa ECU, HAL özelliğini geçersiz kılar ve başlatma sırasında Android sistemi, belirtilen Kullanıcıda başlatılacak şekilde geçiş yapar. |
SWITCH_USER (OKUMA YAZMA) | Bu özellik, etkin ön plan Android Kullanıcısı değiştirilirken çağrılır. Özellik, bir Kullanıcı anahtarı istemek için Android sistemi veya HAL tarafından çağrılabilir. Üç iş akışı şunlardır:
Modern iş akışı, Android sistemi ile harici ECU'nun senkronize olmasını sağlamak için iki aşamalı bir 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 amacıyla durumunu güncellemek için Örnek: Hareket halindeyken bir sürücü bilgi-eğlence sistemi kullanıcı arayüzünde Android Kullanıcılarını değiştirmeye çalışır. 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. Böylece koltukları kontrol eden ECU anahtarı onaylamaz, HAL bir arızayla yanıt verir ve Android Kullanıcısı değiştirilmez. Eski iş akışı, Kullanıcı değiştirildikten sonra gönderilen tek yönlü bir çağrıdır (böylece HAL, anahtarı engelleyemez). Yalnızca önyükleme sırasında (ilk kullanıcı geçişinden sonra) veya Örnek: Bir uygulama, Kullanıcıları değiştirmek için Araç iş akışı Android sisteminden değil HAL'den kaynaklanır:
Örnek: Bob, arabayı açmak için Alice'in anahtarlığını kullandı ve HAL, |
CREATE_USER (OKUMA YAZMA) | Bu özellik, 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 sistemi kullanıcı arayüzü simgesine dokunuyor. Bu, HAL'e ve araç alt sistemlerinin geri kalanına bir istek gönderir. ECU'lar yeni oluşturulan Kullanıcı hakkında bilgilendirilir. Diğer alt sistemler ve ECU'lar daha sonra dahili kullanıcı kimliklerini Android Kullanıcı Kimliğiyle ilişkilendirir. |
REMOVE_USER (Yalnızca YAZIN) | Android sistemi, bir Android Kullanıcısı kaldırıldıktan sonra ( CarUserManager.removeUser() yöntemiyle) bu özelliği çağırır.Bu tek yönlü bir çağrıdır; HAL'den herhangi bir yanıt beklenmemektedir. Örnek: Bir sürücü, bilgi-eğlence sistemi kullanıcı arayüzünde mevcut bir Android Kullanıcısını kaldırmak için dokunur. HAL bilgilendirilir ve 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ğıda Kullanıcı yaşam döngüsü durumlarıyla ilgisi olmayan ek özellikler yer almaktadır. Her biri Kullanıcı HAL'sini desteklemeden uygulanabilir.
HAL Özelliği | Tanım |
---|---|
USER_IDENTIFICATION_ASSOCIATION (OKUMA YAZMA) | Herhangi bir Android Kullanıcısını anahtarlık veya telefon gibi bir tanımlama mekanizmasıyla ilişkilendirmek için bu özelliği kullanın. İlişkilendirmeleri get veya set için aynı özelliği kullanın. Örnek: Bir sürücü, aracı açmak için kullanılan anahtarlığı ( |
Yardımcı kütüphaneler
İstek ve yanıt mesajlarında kullanılan tüm nesneler ( UserInfo
, InitialUserInfoRequest
, InitialUSerInfoResponse
vb. gibi) C++ struct
kullanılarak yüksek düzeyde bir temsile sahiptir, ancak kaldırma işlemi standart VehiclePropValue
nesnelerine düzleştirilmelidir (aşağıdaki örneklere bakın). Geliştirme kolaylığı için, Kullanıcı HAL structs
otomatik olarak bir VehiclePropValue
(ve tersi) dönüştürmek için AOSP'de bir C++ yardımcı kitaplığı sağlanmıştır.
Örnekler
INITIAL_USER_INFO
Örnek isteyin (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ştur)
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 }
KULLANICI DEĞİŞTİR
Sınıfların ve özelliklerin gerçek adı biraz farklıdır ancak genel iş akışı aşağıda gösterildiği gibi aynıdır:
Şekil 1. Kullanıcı HAL Özellikleri İş 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 }
Modern iş akışı geçiş sonrası yanıt örneği
Bu yanıt genellikle bir Android geçişi başarılı 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] = 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) }
Modern iş akışı geçiş sonrası yanıt
Bu yanıt genellikle bir Android anahtarı 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 }
Eski iş akışı geçiş sonrası yanıtı
Bu yanıt genellikle bir Android geçişi başarılı olduğunda ortaya çıkar:
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) }
KULLANICI OLUŞTUR
Örnek isteyin
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 isteyin
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 ayarla (Kullanıcı 10 ile ilişkili anahtarlık)
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 }