Properti HAL pengguna

Banyak arsitektur kendaraan saat ini berisi beberapa unit kontrol elektronik (ECU) di luar sistem infotainmen yang mengontrol ergonomi, seperti setelan kursi dan penyesuaian spion. Berdasarkan arsitektur daya dan hardware saat ini, banyak ECU yang menyala sebelum sistem infotainmen berbasis Android dinyalakan. ECU ini dapat berinteraksi dengan sistem infotainmen berbasis Android melalui Vehicle hardware abstraction layer (VHAL).

Mulai Android 11, Android Automotive OS (AAOS) memperkenalkan serangkaian properti baru di VHAL untuk membuat, mengalihkan, menghapus, dan mengaitkan aksesori eksternal guna mengidentifikasi pengguna. Misalnya, properti baru ini memungkinkan pengemudi untuk menghubungkan aksesori eksternal, seperti fob kunci, ke pengguna Android mereka. Kemudian, saat pengemudi mendekati kendaraan, ECU akan aktif dan mendeteksi fob kunci. ECU ini menunjukkan kepada HAL pengguna Android mana yang harus memulai booting infotainment, yang mengurangi waktu pengemudi menunggu pengguna Android mereka dimuat.

Mengaktifkan HAL Pengguna

Properti HAL Pengguna harus diaktifkan secara eksplisit dengan memastikan properti sistem android.car.user_hal_enabled disetel ke true. (Anda dapat melakukannya di file car.mk, sehingga tidak perlu ditetapkan secara manual.) Pastikan 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 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, tetapkan 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 akan 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 proses pengguna

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

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

Properti HAL Deskripsi
INITIAL_USER_INFO
(baca/tulis)
Properti ini dipanggil oleh sistem Android untuk menentukan pengguna Android yang dimulai 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 booting pertama).
  • Beralih ke pengguna yang sudah ada.
  • Buat pengguna baru (dengan properti opsional nama, tanda, lokalitas sistem, dan sebagainya) dan beralih ke pengguna baru tersebut.

Catatan: Jika HAL tidak merespons, perilaku defaultnya adalah dieksekusi setelah periode waktu tunggu (lima detik secara default), yang menunda booting. Jika HAL membalas, tetapi sistem Android gagal menjalankan tindakan (misalnya, jika jumlah maksimum pengguna telah tercapai), perilaku default akan digunakan.

Contoh: Secara default, sistem Android dimulai pada pengguna aktif terakhir saat booting. Jika fob kunci untuk pengguna lain terdeteksi, ECU akan mengganti properti HAL dan, selama memulai, sistem Android akan beralih untuk memulai di pengguna yang ditentukan tersebut.

SWITCH_USER
(baca/tulis)
Properti ini dipanggil saat beralih pengguna Android latar depan yang aktif. Properti dapat dipanggil oleh sistem Android atau oleh HAL untuk meminta pengalihan pengguna. Ketiga alur kerja tersebut adalah:
  • Modern. Pengalihan dimulai dari CarUserManager.
  • Lama. Tombol diaktifkan mulai ActivityManager.
  • Kendaraan. Dipanggil oleh HAL untuk meminta pengalihan pengguna.

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

  1. Periksa HAL untuk menentukan apakah pengguna dapat dialihkan.

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

  2. Selesaikan pengalihan pengguna Android.

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

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

Contoh: Saat dalam perjalanan, pengemudi mencoba mengganti pengguna Android di UI infotainmen. Namun, karena setelan kursi mobil terikat dengan pengguna Android, kursi bergerak selama peralihan pengguna. Jadi, ECU yang mengontrol slot tidak mengonfirmasi peralihan, HAL merespons dengan kegagalan, dan pengguna Android tidak dialihkan.

Alur kerja Lama adalah panggilan satu arah yang dikirim setelah pengguna dialihkan (sehingga HAL tidak dapat memblokir tombol). Metode ini hanya dipanggil saat booting (setelah peralihan pengguna awal) atau untuk aplikasi yang memanggil ActivityManager.switchUser(), bukan CarUserManager.switchUser(). Aplikasi Settings dan SystemUI referensi sudah menggunakan yang terakhir, tetapi jika OEM menyediakan aplikasi Setelan mereka sendiri untuk beralih pengguna, OEM harus mengubah penggunaannya.

Contoh: Jika aplikasi menggunakan ActivityManager.switchUser() untuk beralih pengguna, panggilan satu arah akan dikirim ke HAL untuk menginformasikan bahwa pengalihan pengguna telah terjadi.

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

  1. HAL meminta pengalihan pengguna.
  2. Sistem menyelesaikan pengalihan pengguna Android.
  3. Android mengirimkan respons ANDROID_POST_SWITCH ke HAL untuk menunjukkan keberhasilan atau kegagalan tombol.

Contoh: Bob menggunakan fob kunci Alice untuk membuka mobil, lalu HAL membalas permintaan INITIAL_USER_INFO dengan ID pengguna Alice. Selanjutnya, ECU sensor biometrik mengidentifikasi pengemudi sebagai Bob, sehingga HAL Pengguna mengirim permintaan SWITCH_USER untuk beralih pengguna.

CREATE_USER
(baca/tulis)
Properti ini dipanggil oleh sistem Android saat pengguna Android baru dibuat (menggunakan CarUserManager.createUser() API).

HAL merespons dengan SUCCESS atau FAILURE. Jika HAL merespons dengan kegagalan, sistem Android akan menghapus pengguna.

Contoh: Pengemudi mengetuk ikon UI infotainmen untuk membuat pengguna Android baru. Tindakan ini akan mengirim permintaan ke HAL dan subsistem kendaraan lainnya. ECU diberi tahu tentang pengguna yang baru dibuat. Subsistem dan ECU lainnya kemudian mengaitkan ID pengguna internal mereka dengan ID pengguna Android.

REMOVE_USER
(hanya WRITE)
Sistem Android memanggil properti ini setelah pengguna Android dihapus (dengan metode CarUserManager.removeUser()).

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

Contoh: Pengemudi mengetuk untuk menghapus pengguna Android yang ada di UI infotainmen. HAL diberi tahu dan subsistem kendaraan dan ECU lainnya diberi tahu tentang penghapusan pengguna sehingga dapat menghapus ID pengguna internal mereka.

Properti tambahan

Berikut adalah properti tambahan, yang tidak terkait dengan status siklus proses pengguna. Masing-masing dapat diterapkan tanpa mendukung HAL Pengguna.

Properti HAL Deskripsi
USER_IDENTIFICATION_ASSOCIATION
(baca/tulis)
Gunakan properti ini untuk mengaitkan pengguna Android dengan mekanisme identifikasi, seperti fob kunci atau ponsel. Gunakan properti yang sama ini untuk pengaitan get atau set.

Contoh: Pengemudi mengetuk ikon UI infotainmen untuk mengaitkan kunci fob yang digunakan untuk membuka kendaraan (KEY_123) ke pengguna Android aktif saat ini (USER_11).

Library bantuan

Semua objek yang digunakan dalam pesan permintaan dan respons (seperti UserInfo, InitialUserInfoRequest, InitialUSerInfoResponse, dan sebagainya) memiliki representasi tingkat tinggi menggunakan struct C++, tetapi penghapusan harus diratakan menjadi objek VehiclePropValue standar (lihat contoh di bawah). Untuk memudahkan pengembangan, library helper C++ disediakan di AOSP untuk mengonversi structs User HAL secara otomatis menjadi VehiclePropValue (dan sebaliknya).

Contoh

Info IniTIAL_USER_INFO

Contoh permintaan (saat booting 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 respons (membuat pengguna Admin)

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
}

BERALIH_PENGGUNA

Nama sebenarnya dari class dan properti sedikit berbeda, tetapi alur kerja keseluruhannya sama, seperti yang diilustrasikan dalam gambar:

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-peralihan alur kerja modern

Respons ini biasanya terjadi saat tombol 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-peralihan alur kerja modern

Respons ini biasanya terjadi saat tombol 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
}

Respons pascaperalihan alur kerja lama

Respons ini biasanya terjadi saat tombol 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)
}

CREATE_USER

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 respons

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

REMOVE_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

Contoh setelan (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
}