Android 8 merancang ulang Android OS untuk mendefinisikan antarmuka yang jelas antara
platform Android yang tidak bergantung pada perangkat, serta kode khusus perangkat dan vendor.
Android sudah mendefinisikan banyak antarmuka seperti itu dalam bentuk antarmuka HAL,
ditentukan sebagai header C di hardware/libhardware
. HIDL menggantikan
Antarmuka HAL dengan antarmuka berversi stabil, yang bisa berupa
antarmuka HIDL sisi server di C++ (dijelaskan di bawah) atau
Java telah selesai.
Halaman di bagian ini menjelaskan
implementasi C++ antarmuka HIDL,
termasuk detail tentang file yang dibuat secara otomatis dari .hal
HIDL
oleh compiler hidl-gen
, cara file ini dikemas, dan
cara mengintegrasikan file-file ini
dengan kode C++ yang menggunakannya.
Implementasi klien dan server
Antarmuka HIDL memiliki implementasi klien dan server:
- Klien antarmuka HIDL adalah kode yang menggunakan antarmuka pengguna dengan memanggil metode di dalamnya.
- Server adalah implementasi antarmuka HIDL yang menerima panggilan dari klien dan mengembalikan hasilnya (jika perlu).
Dalam transisi dari libhardware
HAL ke HIDL HAL,
menjadi server dan proses yang memanggil HAL menjadi
klien. Implementasi default dapat berfungsi sebagai passthrough dan binderized
HAL, dan dapat berubah dari waktu ke waktu:
Gambar 1. Perkembangan pengembangan untuk HAL lama.
Membuat klien HAL
Mulailah dengan menyertakan library HAL di makefile:
- Membuat:
LOCAL_SHARED_LIBRARIES += android.hardware.nfc@1.0
- Soong:
shared_libs: [ …, android.hardware.nfc@1.0 ]
Selanjutnya, sertakan file {i>header<i} HAL:
#include <android/hardware/nfc/1.0/IFoo.h> … // in code: sp<IFoo> client = IFoo::getService(); client->doThing();
Membuat server HAL
Untuk membuat implementasi HAL, Anda harus memiliki file .hal
yang mewakili HAL Anda dan telah membuat {i>
makefile<i} untuk HAL Anda menggunakan
-Lmakefile
atau -Landroidbp
di hidl-gen
(./hardware/interfaces/update-makefiles.sh
melakukan hal ini untuk
file HAL dan merupakan referensi yang baik). Saat mentransfer melalui HAL dari
libhardware
, Anda dapat melakukan banyak hal ini dengan mudah menggunakan c2hal.
Untuk membuat file yang diperlukan guna mengimplementasikan HAL Anda:
PACKAGE=android.hardware.nfc@1.0 LOC=hardware/interfaces/nfc/1.0/default/ m -j hidl-gen hidl-gen -o $LOC -Lc++-impl -randroid.hardware:hardware/interfaces \ -randroid.hidl:system/libhidl/transport $PACKAGE hidl-gen -o $LOC -Landroidbp-impl -randroid.hardware:hardware/interfaces \ -randroid.hidl:system/libhidl/transport $PACKAGE
Agar HAL bekerja dalam mode {i>passthrough<i}, Anda harus memiliki
fungsi HIDL_FETCH_IModuleName
yang berada di
/(system|vendor|...)/lib(64)?/hw/android.hardware.package@3.0-impl(OPTIONAL_IDENTIFIER).so
dengan OPTIONAL_IDENTIFIER adalah string yang mengidentifikasi passthrough
terlepas dari implementasi layanan. Persyaratan mode passthrough dipenuhi secara otomatis oleh
di atas, yang juga membuat error android.hardware.nfc@1.0-impl
target, tetapi ekstensi apa pun dapat digunakan. Misalnya
android.hardware.nfc@1.0-impl-foo
menggunakan -foo
untuk
membedakan dirinya sendiri.
Jika HAL adalah versi minor atau perluasan dari versi lain
HAL, HAL dasar harus digunakan
untuk menamai biner ini. Contohnya,
Penerapan android.hardware.graphics.mapper@2.1
harus
masih dalam biner
yang disebut
android.hardware.graphics.mapper@2.0-impl(OPTIONAL_IDENTIFIER)
.
Biasanya, OPTIONAL_IDENTIFIER di sini akan mencakup HAL yang sebenarnya
. Dengan menamai biner seperti ini,
klien 2,0 dapat mengambilnya secara langsung,
dan 2.1 klien dapat
mengganggu implementasinya.
Selanjutnya, isi stub dengan fungsi dan siapkan daemon. Contoh kode daemon (mendukung passthrough):
#include <hidl/LegacySupport.h> int main(int /* argc */, char* /* argv */ []) { return defaultPassthroughServiceImplementation<INfc>("nfc"); }
defaultPassthroughServiceImplementation
panggilan
dlopen()
untuk library -impl
yang disediakan dan menyediakannya sebagai
layanan binderized. Contoh kode daemon (untuk layanan binderized murni):
int main(int /* argc */, char* /* argv */ []) { // This function must be called before you join to ensure the proper // number of threads are created. The threadpool never exceeds // size one because of this call. ::android::hardware::configureRpcThreadpool(1 /*threads*/, true /*willJoin*/); sp<INfc> nfc = new Nfc(); const status_t status = nfc->registerAsService(); if (status != ::android::OK) { return 1; // or handle error } // Adds this thread to the threadpool, resulting in one total // thread in the threadpool. We could also do other things, but // would have to specify 'false' to willJoin in configureRpcThreadpool. ::android::hardware::joinRpcThreadpool(); return 1; // joinRpcThreadpool should never return }
Daemon ini biasanya berada di $PACKAGE + "-service-suffix"
(untuk
misalnya, android.hardware.nfc@1.0-service
), tetapi bisa juga di mana saja.
Sepolicy untuk kebijakan
kelas HAL adalah atribut hal_<module>
(misalnya,
hal_nfc)
. Atribut ini harus diterapkan ke daemon yang menjalankan
HAL tertentu (jika proses yang sama melayani beberapa HAL, beberapa atribut
yang dapat diterapkan).