Layanan dan transfer data

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:

  1. Membuat subclass hidl_death_recipient class/antarmuka HIDL (dalam C++ kode, bukan dalam HIDL).
  2. Ganti metode serviceDied().
  3. Buat instance objek subclass hidl_death_recipient.
  4. Panggil metode linkToDeath() pada layanan untuk memantau, dengan meneruskan objek antarmuka IDeathRecipient. 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 atau MQDescriptorUnsync. 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.
    Tidak ada jenis yang diizinkan untuk underflow (membaca dari antrean kosong gagal), dan setiap jenis hanya dapat memiliki satu penulis.

Untuk mengetahui detail selengkapnya tentang FMQ, lihat Antrean Pesan Cepat (FMQ).