Properti HAL Pengguna

Banyak arsitektur kendaraan saat ini berisi beberapa unit kontrol elektronik (ECU) di luar sistem infotainment yang mengontrol ergonomi, seperti pengaturan kursi dan penyesuaian kaca spion. Berdasarkan arsitektur perangkat keras dan daya saat ini, banyak ECU yang dihidupkan sebelum sistem infotainment berbasis Android dihidupkan. ECU ini dapat berinteraksi dengan sistem infotainment berbasis Android melalui Vehicle Hardware Abstraction Layer (VHAL) .

Mulai Android 11, Android Automotive OS (AAOS) memperkenalkan kumpulan properti baru di VHAL untuk membuat, mengalihkan, menghapus, dan mengaitkan aksesori eksternal untuk mengidentifikasi Pengguna. Misalnya, properti baru ini memungkinkan driver untuk memasangkan aksesori eksternal, seperti key fob, ke Pengguna Android mereka. Kemudian, ketika pengemudi mendekati kendaraan, ECU bangun dan mendeteksi key fob. ECU ini menunjukkan kepada HAL Pengguna Android mana yang infotainment harus memulai boot, yang mengurangi waktu pengemudi menunggu Pengguna Android mereka memuat.

Aktifkan HAL Pengguna

Properti HAL Pengguna harus diaktifkan secara eksplisit dengan memastikan properti sistem android.car.user_hal_enabled disetel ke true . (Ini juga dapat dilakukan di file car.mk , sehingga tidak perlu diatur secara manual.) Periksa apakah user_hal_enabled=true diaktifkan dengan membuang UserHalService :

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

Anda juga dapat memeriksa user_hal_enabled dengan menggunakan adb shell getprop android.car.user_hal_enabled atau adb logcat CarServiceHelper *:s . Jika properti dinonaktifkan, pesan seperti berikut akan ditampilkan saat system_server dimulai:

I CarServiceHelper: Not using User HAL

Untuk mengaktifkan user_hal_enabled secara manual, setel properti sistem android.car.user_hal_enabled dan mulai ulang system_server :

$ adb shell setprop android.car.user_hal_enabled true
$ adb shell stop && adb shell start

Output logcat muncul sebagai berikut:

I CarServiceHelper: User HAL enabled with timeout of 5000ms
D CarServiceHelper: Got result from HAL: OK
I CarServiceHelper: User HAL returned DEFAULT behavior

Properti HAL pengguna

Properti siklus hidup pengguna

Properti berikut menyediakan informasi HAL untuk status siklus hidup Pengguna, yang memungkinkan sinkronisasi siklus hidup Pengguna antara sistem Android dan ECU eksternal. Properti ini menggunakan protokol permintaan dan respons, di mana sistem Android membuat permintaan dengan menetapkan nilai properti dan HAL merespons dengan mengeluarkan peristiwa perubahan properti.

Catatan: Ketika HAL Pengguna didukung, semua properti berikut harus diterapkan.

Properti HAL Keterangan
INITIAL_USER_INFO
(BACA TULIS)
Properti ini dipanggil oleh sistem Android untuk menentukan Pengguna Android mana yang akan dijalankan sistem saat perangkat melakukan booting atau melanjutkan dari Suspend-to-RAM (STR). Saat dipanggil, HAL harus merespons dengan salah satu opsi berikut:
  • Perilaku default yang ditetapkan oleh Android (beralih ke Pengguna yang terakhir digunakan atau membuat Pengguna baru jika ini adalah boot pertama).
  • Beralih ke Pengguna yang ada.
  • Buat Pengguna baru (dengan properti opsional nama, bendera, lokal sistem, dan sebagainya) dan alihkan ke Pengguna baru itu.

Catatan: Jika HAL tidak merespons, perilaku default adalah mengeksekusi setelah periode waktu habis (secara default lima (5) detik), yang menunda boot. Jika HAL membalas, tetapi sistem Android gagal menjalankan tindakan (misalnya, jika jumlah Pengguna maksimum telah tercapai), perilaku default akan digunakan.

Misalnya, secara default, sistem Android dimulai di Pengguna aktif terakhir saat boot. Jika key fob untuk Pengguna yang berbeda terdeteksi, ECU akan menimpa properti HAL dan, selama pengaktifan, sistem Android beralih untuk memulai pada Pengguna yang ditentukan.

SWITCH_USER
(BACA TULIS)
Properti ini dipanggil saat mengalihkan Pengguna Android latar depan yang aktif. Properti dapat dipanggil oleh sistem Android atau oleh HAL untuk meminta sakelar Pengguna. Ketiga alur kerja tersebut adalah:
  • Modern. Beralih dimulai dari CarUserManager .
  • Warisan. Beralih mulai dari ActivityManager .
  • Kendaraan. Dipanggil oleh HAL untuk meminta sakelar Pengguna.

Alur kerja Modern menggunakan pendekatan komit dua fase untuk memastikan sistem Android dan ECU eksternal disinkronkan. Saat Android memulai peralihan:

  1. Periksa HAL untuk menentukan apakah Pengguna dapat dialihkan.

    HAL merespon dengan SUCCESS atau FAILURE , sehingga Android tahu apakah akan melanjutkan atau tidak.

  2. Selesaikan sakelar Pengguna Android.

    Android mengirimkan respons ANDROID_POST_SWITCH ke HAL untuk menunjukkan keberhasilan atau kegagalan sakelar.

HAL harus menunggu hingga setelah respons ANDROID_POST_SWITCH untuk memperbarui statusnya guna menyinkronkan ECU atau memperbarui properti HAL lainnya.

Misalnya, saat sedang bergerak, pengemudi mencoba mengalihkan Pengguna Android di UI infotainment. Namun, karena pengaturan kursi mobil terikat dengan Pengguna Android, kursi akan bergerak selama sakelar Pengguna. Dengan demikian, ECU yang mengontrol kursi tidak mengonfirmasi sakelar, HAL merespons dengan kegagalan, dan Pengguna Android tidak dialihkan.

Alur kerja Legacy adalah panggilan satu arah yang dikirim setelah Pengguna dialihkan (sehingga HAL tidak dapat memblokir sakelar). Itu hanya dipanggil saat boot (setelah peralihan pengguna awal) atau untuk aplikasi yang memanggil ActivityManager.switchUser() alih-alih CarUserManager.switchUser() . Settings referensi dan aplikasi SystemUI sudah menggunakan yang terakhir, tetapi jika OEM menyediakan aplikasi Pengaturan mereka sendiri untuk beralih Pengguna, OEM harus mengubah penggunaannya.

Misalnya, jika aplikasi menggunakan ActivityManager.switchUser() untuk mengalihkan Pengguna, maka panggilan satu arah dikirim ke HAL untuk menginformasikan bahwa peralihan Pengguna telah dilakukan.

Alur kerja Kendaraan berasal dari HAL, bukan dari sistem Android:

  1. HAL meminta sakelar Pengguna.
  2. Sistem menyelesaikan peralihan Pengguna Android.
  3. Android mengirimkan respons ANDROID_POST_SWITCH ke HAL untuk menunjukkan keberhasilan atau kegagalan sakelar.

Misalnya , Bob menggunakan key fob Alice untuk membuka mobil dan HAL membalas permintaan INITIAL_USER_INFO dengan ID Pengguna Alice. Selanjutnya, ECU sensor biometrik mengidentifikasi driver sebagai Bob, sehingga HAL Pengguna mengirim permintaan SWITCH_USER untuk mengganti pengguna.

CREATE_USER
(BACA TULIS)
Properti ini dipanggil oleh sistem Android saat Pengguna Android baru dibuat (menggunakan CarUserManager.createUser() API).

HAL merespon dengan SUCCESS atau FAILURE . Jika HAL merespons dengan kegagalan, sistem Android menghapus Pengguna.

Misalnya, pengemudi mengetuk ikon UI infotainment untuk membuat Pengguna Android baru. Ini mengirimkan permintaan ke HAL dan subsistem kendaraan lainnya. ECU diinformasikan tentang Pengguna yang baru dibuat. Subsistem dan ECU lain kemudian mengaitkan ID pengguna internal mereka dengan ID Pengguna Android.

REMOVE_USER
(TULIS saja)
Sistem Android memanggil properti ini setelah Pengguna Android dihapus (dengan CarUserManager.removeUser() API).

Ini adalah panggilan satu arah — tidak ada respons yang diharapkan dari HAL.

Misalnya, pengemudi mengetuk untuk menghapus Pengguna Android yang ada di UI infotainment. HAL diinformasikan dan subsistem kendaraan lain serta ECU diinformasikan tentang penghapusan Pengguna sehingga mereka dapat menghapus ID pengguna internal mereka.

Properti tambahan

Berikut ini adalah properti tambahan, yang tidak terkait dengan status siklus hidup Pengguna. Masing-masing dapat diimplementasikan tanpa mendukung HAL Pengguna.

Properti HAL Keterangan
USER_IDENTIFICATION_ASSOCIATION
(BACA TULIS)
Gunakan properti ini untuk mengaitkan Pengguna Android dengan mekanisme identifikasi, seperti key fob atau telepon. Gunakan properti yang sama ini untuk get atau set asosiasi.

Misalnya, pengemudi mengetuk ikon UI infotainment untuk mengaitkan key fob yang digunakan untuk membuka kendaraan (KEY_123) ke Pengguna Android aktif saat ini (USER_11).

Pustaka pembantu

Semua objek yang digunakan dalam pesan permintaan dan respons (seperti UserInfo , InitialUserInfoRequest , InitialUSerInfoResponse , dan seterusnya) memiliki representasi tingkat tinggi menggunakan C++ struct , tetapi penghapusan harus diratakan menjadi objek VehiclePropValue standar (lihat contoh di bawah). Untuk kemudahan pengembangan, pustaka pembantu C++ disediakan di AOSP untuk secara otomatis mengubah structs HAL Pengguna menjadi VehiclePropValue (dan sebaliknya).

Contoh

INITIAL_USER_INFO

Contoh permintaan (saat boot pertama)

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
}

Contoh respon (buat Admin User)

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

Nama sebenarnya dari kelas dan properti sedikit berbeda tetapi alur kerja keseluruhannya sama, seperti yang diilustrasikan di bawah ini:

alur kerja

Gambar 1. Alur Kerja Properti HAL Pengguna

Contoh permintaan alur kerja modern

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)
}

Contoh respons alur kerja modern

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
}

Contoh respons pasca-pengalihan alur kerja modern

Respons ini biasanya terjadi ketika sakelar Android berhasil:

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)
}

Respons pasca-pengalihan alur kerja modern

Respons ini biasanya terjadi saat sakelar Android gagal:

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)
}

Contoh permintaan alur kerja lama

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)
}

Contoh permintaan alur kerja kendaraan

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
}

Tanggapan pasca-pengalihan alur kerja lama

Respons ini biasanya terjadi ketika sakelar Android berhasil:

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)
}

BUAT PENGGUNA

Contoh permintaan

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)
}

Contoh tanggapan

VehiclePropValue { // flattened from CreateUserResponse
prop: 299896585 // CREATE_USER
prop.values.int32Values:
 [0] = 42        // Request ID (must match request)
 [1] = 3         // CreateUserStatus::SUCCESS
}

HAPUS_USER

Contoh permintaan

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

Setel contoh (fob kunci yang terkait dengan Pengguna 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
}