Kullanıcı HAL Özellikleri

Mevcut birçok araç mimarisi, koltuk ayarları ve ayna ayarları gibi ergonomiyi kontrol eden bilgi-eğlence sisteminin dışında çoklu elektronik kontrol üniteleri (ECU) içerir. Mevcut donanım ve güç mimarilerine dayalı olarak, 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ı oluşturmak, değiştirmek, kaldırmak ve ilişkilendirmek için VHAL'da yeni bir dizi özellik tanıttı. Örneğin, bu yeni özellikler, bir sürücünün anahtarlık gibi harici bir aksesuarı Android Kullanıcısıyla eşleştirmesini sağlar. Ardından, sürücü araca yaklaştığında bir ECU uyanır ve anahtarlığı algılar. Bu ECU, HAL'a, bilgi-eğlence sisteminin hangi Android Kullanıcısının başlatması gerektiğini belirtir, bu da bir sürücünün Android Kullanıcısının yüklenmesini beklediği süreyi azaltır.

HAL Kullanıcısını Etkinleştir

Kullanıcı HAL özellikleri, android.car.user_hal_enabled sistem özelliğinin true olarak ayarlanması sağlanarak açıkça etkinleştirilmelidir. (Bu, manuel olarak ayarlanması gerekmemesi için car.mk dosyasında da yapılabilir.) UserHalService'i boşaltarak UserHalService user_hal_enabled=true öğesinin etkinleştirildiğini kontrol edin:

$ adb shell dumpsys car_service --hal UserHalService|grep enabled
user_hal_enabled=true

Ayrıca user_hal_enabled kullanarak da kontrol edebilirsiniz. adb shell getprop android.car.user_hal_enabled veya adb logcat CarServiceHelper *:s . Özellik devre dışı bırakılırsa, system_server başladığı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 etkinleştiren 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'ın bir özellik değişikliği olayı yayınlayarak yanıt verdiği bir istek ve yanıt protokolü kullanır.

Not: Kullanıcı HAL'ı desteklendiğinde, aşağıdaki özelliklerin tümü uygulanmalıdır.

HAL Özelliği Açıklama
INITIAL_USER_INFO
(OKUMA YAZMA)
Bu özellik, Android sistemi tarafından, cihaz önyüklendiğinde veya RAM'e Askıya Alma'dan (STR) kaldığında sistemin hangi Android Kullanıcısının başlayacağını belirlemek için çağrılır. Çağrıldığında, HAL aşağıdaki seçeneklerden biriyle yanıt vermelidir:
  • Android tarafından ayarlanan varsayılan davranış (son kullanılan Kullanıcıya geçmek veya bu ilk önyüklemeyse yeni bir Kullanıcı oluşturmak).
  • Mevcut bir Kullanıcıya geçin.
  • Yeni bir Kullanıcı oluşturun (ad, bayraklar, sistem yerel ayarı vb. isteğe bağlı özelliklerle birlikte) ve bu yeni Kullanıcıya geçin.

Not: HAL yanıt vermezse, varsayılan davranış, önyüklemeyi geciktiren bir zaman aşımı süresinden sonra (varsayılan olarak beş (5) saniye) yürütülür. HAL yanıt verirse, ancak Android sistemi eylemi gerçekleştiremezse (örneğin, maksimum Kullanıcı sayısına ulaşıldıysa), varsayılan davranış kullanılır.

Örneğin, varsayılan olarak Android sistemi, önyükleme sırasında son etkin 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 bu belirtilen Kullanıcıda çalışmaya başlar.

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. Anahtar, CarUserManager başlatıldı.
  • Miras. Anahtar, ActivityManager başlatıldı.
  • Araç. Bir Kullanıcı anahtarı istemek için HAL tarafından çağrılır.

Modern iş akışı, Android sisteminin ve harici ECU'nun senkronize edilmesini sağlamak için iki aşamalı bir tamamlama yaklaşımı kullanır. Android, anahtarı başlattığında:

  1. Kullanıcının değiştirilip değiştirilemeyeceğini belirlemek için HAL'ı kontrol edin.

    HAL, SUCCESS veya FAILURE ile yanıt verir, böylece Android devam edip etmeyeceğini bilir.

  2. Android Kullanıcı anahtarını tamamlayın.

    Android, anahtarın başarılı veya başarısız olduğunu belirtmek için HAL'a bir ANDROID_POST_SWITCH yanıtı gönderir.

HAL, ECU'ları senkronize etmek veya diğer HAL özelliklerini güncellemek için durumunu güncellemek için ANDROID_POST_SWITCH yanıtından sonraya kadar beklemelidir.

Örneğin, hareket halindeyken bir sürücü, bilgi-eğlence kullanıcı arayüzünde Android Kullanıcıları arasında geçiş yapmaya ç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 edecektir. Bu nedenle, koltukları kontrol eden ECU, anahtarı onaylamaz, HAL bir hata ile 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 (bu nedenle HAL, anahtarı engelleyemez). Yalnızca önyükleme sırasında (ilk kullanıcı geçişinden sonra) veya CarUserManager.switchUser() ActivityManager.switchUser() öğesini çağıran uygulamalar için çağrılır. Referans Settings ve SystemUI uygulamaları zaten ikincisini kullanıyor, ancak bir OEM, Kullanıcılar arasında geçiş yapmak için kendi Ayarlar uygulamalarını sağlıyorsa, OEM'lerin kullanımı değiştirmesi gerekir.

Örneğin, bir uygulama Kullanıcılar arasında geçiş yapmak için ActivityManager.switchUser() kullanıyorsa, bir Kullanıcı geçişinin gerçekleştiğini bildirmek için HAL'a tek yönlü bir çağrı gönderilir.

Araç iş akışı, Android sisteminden değil, HAL'den kaynaklanır:

  1. HAL, bir Kullanıcı anahtarı ister.
  2. Sistem, Android Kullanıcı geçişini tamamlar.
  3. Android, anahtarın başarılı veya başarısız olduğunu belirtmek için HAL'a bir ANDROID_POST_SWITCH yanıtı gönderir.

Örneğin , Bob, arabayı açmak için Alice'in anahtarlığını kullandı ve HAL, INITIAL_USER_INFO isteğine Alice'in Kullanıcı Kimliği ile yanıt verdi. Ardından, bir biyometrik sensör ECU, sürücüyü Bob olarak tanımladı, bu nedenle Kullanıcı HAL, kullanıcıları değiştirmek için bir SWITCH_USER isteği gönderdi.

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, SUCCESS veya FAILURE olarak yanıt verir. HAL bir hata ile yanıt verirse, Android sistemi Kullanıcıyı kaldırır.

Örneğin, bir sürücü, yeni bir Android Kullanıcısı oluşturmak için bir bilgi-eğlence kullanıcı arayüzü simgesine dokunur. Bu, HAL'e ve diğer araç alt sistemlerine 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ği ile ilişkilendirir.

REMOVE_USER
(Yalnızca YAZIN)
Android sistemi, bir Android Kullanıcısı kaldırıldıktan sonra ( CarUserManager.removeUser() API ile) bu özelliği çağırır.

Bu tek yönlü bir çağrıdır - HAL'den yanıt beklenmez.

Örneğin, bir sürücü, bilgi-eğlence kullanıcı arayüzünde mevcut bir Android Kullanıcısını kaldırmak için hafifçe vurur. 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ğıdakiler, Kullanıcı yaşam döngüsü durumlarıyla ilgisi olmayan ek özelliklerdir. Her biri, Kullanıcı HAL'ı desteklenmeden uygulanabilir.

HAL Özelliği Açıklama
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 bu aynı özelliği kullanın.

Örneğin, bir sürücü, aracı açmak için kullanılan anahtarlığı (KEY_123) mevcut aktif Android Kullanıcısı (USER_11) ile ilişkilendirmek için bir bilgi-eğlence UI simgesine dokunur.

yardımcı kitaplıklar

İstek ve yanıt mesajlarında kullanılan tüm nesneler ( UserInfo , InitialUserInfoRequest , InitialUSerInfoResponse vb. gibi) C++ struct kullanılarak yüksek düzeyde 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ğ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şturun)

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 aşağıda gösterildiği gibi genel iş akışı aynıdır:

iş akışı

Ş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 anahtarı 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ışı talebi ö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 anahtarı 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 talep et

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 talep et

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_ASSSOCIATION

Örnek ayarlayın (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
}