Halaman ini menjelaskan cara mendaftar dan menemukan layanan, serta cara mengirim
data ke layanan dengan memanggil metode yang ditentukan dalam antarmuka di .hal
.
Mendaftar layanan
Server antarmuka HIDL (objek yang mengimplementasikan antarmuka) dapat didaftarkan sebagai layanan bernama. Nama yang terdaftar tidak perlu terkait dengan antarmuka atau nama paket. Jika tidak ada nama yang ditentukan, nama "default" digunakan; ini seharusnya digunakan untuk HAL yang tidak perlu mendaftarkan dua implementasi dalam antarmuka berbasis web yang sederhana. Misalnya, panggilan C++ untuk pendaftaran layanan yang didefinisikan dalam setiap antarmukanya adalah:
status_t status = myFoo->registerAsService(); status_t anotherStatus = anotherFoo->registerAsService("another_foo_service"); // if needed
Versi antarmuka HIDL disertakan dalam antarmuka itu sendiri. Penting
yang dikaitkan dengan pendaftaran layanan secara otomatis dan dapat diambil melalui
panggilan metode (android::hardware::IInterface::getInterfaceVersion()
)
di setiap antarmuka HIDL. Objek server tidak perlu didaftarkan dan dapat diteruskan
melalui parameter metode HIDL ke proses lain yang melakukan panggilan metode HIDL
ke server.
Menemukan layanan
Permintaan oleh kode klien dibuat untuk antarmuka tertentu berdasarkan nama dan oleh
versi, memanggil getService
pada class HAL yang diinginkan:
// C++ sp<V1_1::IFooService> service = V1_1::IFooService::getService(); sp<V1_1::IFooService> alternateService = V1_1::IFooService::getService("another_foo_service"); // Java V1_1.IFooService service = V1_1.IFooService.getService(true /* retry */); V1_1.IFooService alternateService = V1_1.IFooService.getService("another", true /* retry */);
Setiap versi antarmuka HIDL diperlakukan sebagai antarmuka terpisah. Dengan demikian,
IFooService
versi 1.1 dan IFooService
versi 2.2
keduanya bisa didaftarkan sebagai "foo_service" dan
getService("foo_service")
di salah satu antarmuka membuat
untuk antarmuka tersebut. Inilah sebabnya, dalam kebanyakan kasus, tidak ada parameter nama yang membutuhkan
disediakan untuk pendaftaran atau penemuan (artinya nama "default").
Objek Antarmuka Vendor juga berperan
dalam metode transport
antarmuka yang ditampilkan. Untuk antarmuka IFoo
dalam paket
android.hardware.foo@1.0
, antarmuka yang ditampilkan oleh
IFoo::getService
selalu menggunakan metode transpor yang dideklarasikan untuk
android.hardware.foo
dalam manifes perangkat jika entri ada;
dan jika metode transport tidak tersedia, nullptr akan ditampilkan.
Pada beberapa kasus, Anda mungkin perlu
melanjutkan segera bahkan tanpa
mendapatkan layanan. Hal ini bisa terjadi (misalnya) ketika klien ingin
mengelola notifikasi layanan itu sendiri atau dalam program diagnostik (seperti
atrace
) yang perlu mendapatkan semua hwservice dan mengambilnya. Di beberapa
dalam hal ini, API tambahan disediakan seperti tryGetService
di C++ atau
getService("instance-name", false)
di Java. API lama
getService
yang disediakan di Java juga harus digunakan dengan layanan
notifikasi. Menggunakan API ini tidak menghindari kondisi race di mana server
mendaftarkan dirinya sendiri setelah klien memintanya dengan salah satu API yang tidak perlu dicoba lagi.
Notifikasi penghentian layanan
Klien yang ingin diberi tahu saat layanan meninggal dapat menerima kematian notifikasi yang disampaikan oleh framework. Untuk menerima notifikasi, klien harus:
- Membuat subclass
hidl_death_recipient
class/antarmuka HIDL (dalam C++ kode, bukan dalam HIDL). - Ganti metode
serviceDied()
. - Buat instance objek subclass
hidl_death_recipient
. - Panggil metode
linkToDeath()
pada layanan untuk memantau, dengan meneruskan objek antarmukaIDeathRecipient
. Perhatikan bahwa tidak mengambil kepemilikan penerima kematian atau proxy yang menjadi tempat dipanggil.
Contoh kode semu (C++ dan Java serupa):
class IMyDeathReceiver : hidl_death_recipient { virtual void serviceDied(uint64_t cookie, wp<IBase>& service) override { log("RIP service %d!", cookie); // Cookie should be 42 } }; .... IMyDeathReceiver deathReceiver = new IMyDeathReceiver(); m_importantService->linkToDeath(deathReceiver, 42);
Penerima kematian yang sama dapat didaftarkan di beberapa layanan yang berbeda.
Transfer data
Data dapat dikirim ke layanan dengan memanggil metode yang ditentukan dalam antarmuka
.hal
file. Ada dua jenis metode:
- Metode pemblokiran akan menunggu hingga server menghasilkan hasil pengujian tersebut.
- Metode Satu Arah mengirim data hanya dalam satu arah dan tidak diblokir. Jika jumlah data yang berlangsung di panggilan RPC melebihi penerapan aktif, panggilan mungkin memblokir atau mengembalikan indikasi kesalahan (perilaku belum ditentukan).
Metode yang tidak menampilkan nilai tetapi tidak dideklarasikan sebagai
oneway
masih memblokir.
Semua metode yang dideklarasikan dalam antarmuka HIDL dipanggil dalam satu arah, dari HAL atau ke HAL. Antarmuka tidak menentukan arah pemanggilannya. Arsitektur yang memerlukan panggilan untuk berasal dari HAL harus menyediakan dua (atau lebih) antarmuka dalam paket HAL dan menyediakan antarmuka yang sesuai dari setiap proses. Kata client dan server digunakan sesuai dengan arah panggilan antarmuka (yaitu HAL bisa menjadi server dari satu antarmuka dan klien dari antarmuka ).
Callback
Kata callback mengacu pada dua konsep yang berbeda, yang dibedakan berdasarkan callback sinkron dan callback asinkron.
Callback sinkron digunakan dalam beberapa metode HIDL yang menampilkan layanan otomatis dan data skalabel. Metode HIDL yang mengembalikan lebih dari satu nilai (atau mengembalikan satu nilai jenis non-primitif) menampilkan hasilnya melalui fungsi callback. Jika hanya satu dikembalikan dan ini adalah tipe primitif, callback tidak digunakan dan yang ditampilkan dari metode tersebut. Server mengimplementasikan metode HIDL dan klien mengimplementasikan callback.
Callback asinkron memungkinkan server antarmuka HIDL untuk
melakukan panggilan. Hal ini dilakukan dengan meneruskan instance antarmuka kedua
melewati antarmuka pertama. Klien antarmuka pertama
harus bertindak sebagai
dari server kedua. Server antarmuka pertama bisa memanggil metode di
objek antarmuka kedua. Misalnya, implementasi HAL bisa
mengirimkan informasi
secara asinkron kembali ke proses yang menggunakannya dengan memanggil metode pada
objek antarmuka yang dibuat dan
disajikan oleh proses tersebut. Metode dalam antarmuka yang digunakan
untuk callback asinkron mungkin memblokir (dan mungkin menampilkan nilai ke pemanggil)
atau oneway
. Untuk contoh, lihat "Callback asinkron" inci
HIDL C++.
Untuk menyederhanakan kepemilikan memori, panggilan metode dan callback hanya
Parameter in
dan tidak mendukung out
atau
Parameter inout
.
Batas per transaksi
Batas per transaksi tidak dikenakan pada jumlah data yang dikirim di HIDL
metode dan callback. Namun, panggilan yang melebihi 4 KB per transaksi
dianggap berlebihan. Jika ini terlihat, merancang ulang antarmuka HIDL yang diberikan
yang disarankan. Keterbatasan lain adalah sumber
daya yang tersedia untuk HIDL
infrastruktur Anda untuk menangani
beberapa transaksi secara simultan. Beberapa
transaksi dapat berlangsung secara bersamaan
karena beberapa thread atau
proses yang mengirim panggilan ke satu proses atau beberapa panggilan oneway
yang
tidak ditangani dengan
cepat oleh proses penerimaan. Total ruang maksimum
tersedia untuk semua transaksi serentak sebesar 1 MB secara default.
Dalam antarmuka yang dirancang dengan baik, melebihi batasan sumber daya seharusnya tidak terjadi; jika ya, panggilan yang melampauinya dapat memblokir hingga sumber daya yang tersedia atau menandakan {i>error <i}transport. Setiap kejadian yang melebihi batas per transaksi atau kelebihan sumber daya implementasi HIDL dengan transaksi agregat yang sedang berlangsung akan dicatat untuk memfasilitasi proses debug.
Implementasi metode
HIDL menghasilkan file {i>header<i} yang mendeklarasikan jenis, metode, dan callback dalam bahasa target (C++ atau Java). Prototipe fidelitas rendah yang didefinisikan oleh HIDL metode dan callback adalah sama untuk kode klien dan server. HIDL menyediakan implementasi proxy untuk metode pada sisi pemanggil yang mengatur data untuk transpor IPC, dan stub kode pada sisi tujuan panggilan yang meneruskan data ke implementasi developer dari metode tersebut.
Pemanggil fungsi (metode atau callback HIDL) memiliki kepemilikan data struktur yang diteruskan ke fungsi, dan mempertahankan kepemilikan setelah panggilan; inci semua kasus yang tidak perlu mengosongkan atau melepaskan penyimpanan.
- Di C++, data mungkin bersifat hanya-baca (upaya untuk menulisnya dapat menyebabkan kesalahan segmentasi) dan berlaku selama durasi panggilan. Klien dapat menyalin secara mendalam data untuk menyebarkannya di luar panggilan.
- Di Java, kode menerima salinan lokal data (objek Java normal), yang mungkin disimpan dan dimodifikasi atau diizinkan untuk dikumpulkan sampahnya.
Transfer data non-RPC
HIDL memiliki dua cara untuk mentransfer data tanpa menggunakan panggilan RPC: dan Fast Message Queue (FMQ), keduanya hanya didukung di C++.
- Memori bersama. Jenis HIDL bawaan
memory
digunakan untuk meneruskan objek yang mewakili memori bersama yang telah dialokasikan. Dapat digunakan dalam proses penerimaan untuk memetakan memori bersama. - Antrean Pesan Cepat (FMQ). HIDL menyediakan pesan dengan template
jenis antrean yang mengimplementasikan
penerusan pesan tanpa tunggu. Mesin ini tidak menggunakan {i>kernel<i}
atau penjadwal dalam mode passthrough atau binderized (komunikasi antar-perangkat tidak
memiliki properti ini). Biasanya, HAL mengatur
akhir antrian,
membuat objek yang dapat diteruskan melalui RPC melalui parameter
Jenis HIDL
MQDescriptorSync
atauMQDescriptorUnsync
. Ini dapat digunakan oleh proses penerima untuk mengatur ujung lain dari antrean.- Antrean sinkronisasi tidak diizinkan untuk kelebihan beban, dan hanya dapat memiliki satu pembaca.
- Antrean Batalkan sinkronisasi diizinkan untuk tambahan, dan dapat memiliki banyak pembaca, yang masing-masing harus membaca data tepat waktu atau kehilangan data.
Untuk mengetahui detail selengkapnya tentang FMQ, lihat Antrean Pesan Cepat (FMQ).