Google berkomitmen untuk mendorong terwujudnya keadilan ras bagi komunitas Kulit Hitam. Lihat caranya.

HIDL

Bahasa definisi antarmuka HAL atau HIDL (diucapkan "hide-l") adalah bahasa deskripsi antarmuka (IDL) untuk menentukan antarmuka antara HAL dan penggunanya. Ini memungkinkan menentukan jenis dan panggilan metode, dikumpulkan ke dalam antarmuka dan paket. Secara lebih luas, HIDL adalah sistem untuk berkomunikasi antara basis kode yang dapat dikompilasi secara independen. Mulai Android 10, HIDL tidak digunakan lagi dan Android bermigrasi untuk menggunakan AIDL di mana saja.

HIDL dimaksudkan untuk digunakan untuk komunikasi antar proses (IPC). Komunikasi antar proses yang disebut sebagai Binderized . Untuk perpustakaan yang harus dikaitkan dengan proses, sebuah modus passthrough juga tersedia (tidak didukung di Jawa).

HIDL menentukan struktur data dan tanda tangan metode, diatur dalam antarmuka (mirip dengan kelas) yang dikumpulkan ke dalam paket. Sintaks HIDL akan terlihat familier bagi programmer C++ dan Java, meskipun dengan rangkaian kata kunci yang berbeda. HIDL juga menggunakan anotasi gaya Java.

desain HIDL

Tujuan HIDL adalah agar kerangka kerja dapat diganti tanpa harus membangun kembali HAL. HAL akan dibangun oleh vendor atau pembuat SOC dan dimasukkan ke dalam /vendor partisi pada perangkat, memungkinkan kerangka, di partisi sendiri, untuk digantikan dengan OTA tanpa mengkompilasi ulang HAL.

Desain HIDL menyeimbangkan kekhawatiran berikut:

  • Interoperabilitas. Buat antarmuka yang andal dan dapat dioperasikan antara proses yang dapat dikompilasi dengan berbagai arsitektur, rantai alat, dan konfigurasi build. Antarmuka HIDL berversi dan tidak dapat diubah setelah dipublikasikan.
  • Efisiensi. HIDL mencoba meminimalkan jumlah operasi penyalinan. Data yang ditentukan HIDL dikirimkan ke kode C++ dalam struktur data tata letak standar C++ yang dapat digunakan tanpa membongkar. HIDL juga menyediakan antarmuka memori bersama dan, karena RPC secara inheren agak lambat, HIDL mendukung dua cara untuk mentransfer data tanpa menggunakan panggilan RPC: memori bersama dan Antrian Pesan Cepat (FMQ).
  • Intuitif. HIDL Menghindari berduri masalah kepemilikan memori dengan menggunakan hanya in parameter untuk RPC (lihat Android Interface Definition Language (AIDL) ); nilai yang tidak dapat dikembalikan secara efisien dari metode dikembalikan melalui fungsi panggilan balik. Baik meneruskan data ke HIDL untuk transfer atau menerima data dari HIDL tidak mengubah kepemilikan data—kepemilikan selalu tetap dengan fungsi panggilan. Data perlu bertahan hanya selama fungsi yang dipanggil dan dapat dimusnahkan segera setelah fungsi yang dipanggil kembali.

Menggunakan mode passthrough

Untuk memperbarui perangkat yang menjalankan Android versi sebelumnya ke Android O, Anda dapat menggabungkan HAL konvensional (dan lama) dalam antarmuka HIDL baru yang melayani HAL dalam mode binderized dan proses yang sama (passthrough). Pembungkusan ini transparan untuk kerangka kerja HAL dan Android.

Mode passthrough hanya tersedia untuk klien dan implementasi C++. Perangkat yang menjalankan Android versi sebelumnya tidak memiliki HAL yang ditulis dalam Java, sehingga Java HAL secara inheren diikat.

Ketika .hal file dikompilasi, hidl-gen menghasilkan passthrough file header tambahan BsFoo.h selain header digunakan untuk komunikasi pengikat; ini mendefinisikan sundulan fungsi menjadi dlopen ed. Saat HAL passthrough berjalan dalam proses yang sama saat mereka dipanggil, dalam banyak kasus metode passthrough dipanggil oleh panggilan fungsi langsung (utas yang sama). oneway metode menjalankan di thread mereka sendiri karena mereka tidak dimaksudkan untuk menunggu HAL untuk memproses mereka (cara ini setiap HAL yang menggunakan oneway metode dalam mode passthrough harus benang-aman).

Mengingat IFoo.hal , BsFoo.h membungkus metode HIDL yang dihasilkan untuk memberikan fitur tambahan (seperti membuat oneway transaksi berjalan di thread lain). File ini mirip dengan BpFoo.h , namun bukan lewat panggilan IPC menggunakan pengikat, fungsi yang diinginkan secara langsung dipanggil. Implementasi masa depan HAL dapat memberikan beberapa implementasi, seperti FooFast HAL dan FooAccurate HAL. Dalam kasus tersebut, file untuk setiap pelaksanaan tambahan akan dibuat (misalnya, PTFooFast.cpp dan PTFooAccurate.cpp ).

Pengikat passthrough HAL

Anda dapat mengikat implementasi HAL yang mendukung mode passthrough. Mengingat HAL antarmuka abcd@MN::IFoo , dua paket diciptakan:

  • abcd@MN::IFoo-impl . Berisi pelaksanaan HAL dan paparan berfungsi IFoo* HIDL_FETCH_IFoo(const char* name) . Pada perangkat warisan, paket ini adalah dlopen ed dan pelaksanaannya instantiated menggunakan HIDL_FETCH_IFoo . Anda dapat menghasilkan kode dasar menggunakan hidl-gen dan -Lc++-impl dan -Landroidbp-impl .
  • abcd@MN::IFoo-service . Membuka HAL passthrough dan mendaftarkan dirinya sebagai layanan binder, memungkinkan implementasi HAL yang sama untuk digunakan baik sebagai passthrough dan binder.

Mengingat jenis IFoo , Anda dapat menghubungi sp<IFoo> IFoo::getService(string name, bool getStub) untuk mendapatkan akses ke sebuah contoh dari IFoo . Jika getStub benar, getService upaya untuk membuka HAL-satunya dalam mode passthrough. Jika getStub adalah palsu, getService upaya untuk mencari layanan binderized; jika gagal, ia kemudian mencoba menemukan layanan passthrough. The getStub parameter tidak boleh digunakan kecuali dalam defaultPassthroughServiceImplementation . (Perangkat yang diluncurkan dengan Android O adalah perangkat yang sepenuhnya terikat, jadi membuka layanan dalam mode passthrough tidak diizinkan.)

tata bahasa HIDL

Secara desain, bahasa HIDL mirip dengan C (tetapi tidak menggunakan preprosesor C). Semua tanda baca tidak dijelaskan di bawah ini (selain dari penggunaan jelas = dan | ) merupakan bagian dari tata bahasa.

Catatan: Untuk rincian tentang gaya kode HIDL, lihat Kode Style Guide .

  • /** */ menunjukkan komentar dokumentasi. Ini dapat diterapkan hanya untuk tipe, metode, bidang, dan deklarasi nilai enum.
  • /* */ Menunjukkan komentar multiline.
  • // menunjukkan komentar untuk mengakhiri baris. Selain // , baris yang sama seperti spasi lainnya.
  • Pada contoh tata bahasa di bawah ini, teks dari // ke akhir baris bukan bagian dari tata bahasa tetapi bukan komentar pada tata bahasa.
  • [empty] berarti bahwa istilah mungkin kosong.
  • ? mengikuti literal atau istilah berarti opsional.
  • ... menunjukkan urutan mengandung nol atau lebih item dengan memisahkan tanda baca seperti yang ditunjukkan. Tidak ada argumen variadik dalam HIDL.
  • Koma memisahkan elemen urutan.
  • Titik koma mengakhiri setiap elemen, termasuk elemen terakhir.
  • UPPERCASE adalah nonterminal.
  • italics adalah keluarga tanda seperti integer atau identifier (aturan standar C parsing).
  • constexpr adalah konstan ekspresi C gaya (seperti 1 + 1 dan 1L << 3 ).
  • import_name adalah paket atau antarmuka nama, kualifikasi seperti yang dijelaskan dalam HIDL Versi .
  • Huruf kecil words yang token literal.

Contoh:

ROOT =
    PACKAGE IMPORTS PREAMBLE { ITEM ITEM ... }  // not for types.hal
  | PACKAGE IMPORTS ITEM ITEM...  // only for types.hal; no method definitions

ITEM =
    ANNOTATIONS? oneway? identifier(FIELD, FIELD ...) GENERATES?;
  |  safe_union identifier { UFIELD; UFIELD; ...};
  |  struct identifier { SFIELD; SFIELD; ...};  // Note - no forward declarations
  |  union identifier { UFIELD; UFIELD; ...};
  |  enum identifier: TYPE { ENUM_ENTRY, ENUM_ENTRY ... }; // TYPE = enum or scalar
  |  typedef TYPE identifier;

VERSION = integer.integer;

PACKAGE = package android.hardware.identifier[.identifier[...]]@VERSION;

PREAMBLE = interface identifier EXTENDS

EXTENDS = <empty> | extends import_name  // must be interface, not package

GENERATES = generates (FIELD, FIELD ...)

// allows the Binder interface to be used as a type
// (similar to typedef'ing the final identifier)
IMPORTS =
   [empty]
  |  IMPORTS import import_name;

TYPE =
  uint8_t | int8_t | uint16_t | int16_t | uint32_t | int32_t | uint64_t | int64_t |
 float | double | bool | string
|  identifier  // must be defined as a typedef, struct, union, enum or import
               // including those defined later in the file
|  memory
|  pointer
|  vec<TYPE>
|  bitfield<TYPE>  // TYPE is user-defined enum
|  fmq_sync<TYPE>
|  fmq_unsync<TYPE>
|  TYPE[SIZE]

FIELD =
   TYPE identifier

UFIELD =
   TYPE identifier
  |  safe_union identifier { FIELD; FIELD; ...} identifier;
  |  struct identifier { FIELD; FIELD; ...} identifier;
  |  union identifier { FIELD; FIELD; ...} identifier;

SFIELD =
   TYPE identifier
  |  safe_union identifier { FIELD; FIELD; ...};
  |  struct identifier { FIELD; FIELD; ...};
  |  union identifier { FIELD; FIELD; ...};
  |  safe_union identifier { FIELD; FIELD; ...} identifier;
  |  struct identifier { FIELD; FIELD; ...} identifier;
  |  union identifier { FIELD; FIELD; ...} identifier;

SIZE =  // Must be greater than zero
     constexpr

ANNOTATIONS =
     [empty]
  |  ANNOTATIONS ANNOTATION

ANNOTATION =
  |  @identifier
  |  @identifier(VALUE)
  |  @identifier(ANNO_ENTRY, ANNO_ENTRY  ...)

ANNO_ENTRY =
     identifier=VALUE

VALUE =
     "any text including \" and other escapes"
  |  constexpr
  |  {VALUE, VALUE ...}  // only in annotations

ENUM_ENTRY =
     identifier
  |  identifier = constexpr

Terminologi

Bagian ini menggunakan istilah terkait HIDL berikut:

terikat Menunjukkan HIDL sedang digunakan untuk panggilan prosedur jarak jauh antar proses, diimplementasikan melalui mekanisme seperti Binder. Lihat juga passthrough.
panggilan balik, asinkron Antarmuka dilayani oleh pengguna HAL, diteruskan ke HAL (melalui metode HIDL), dan dipanggil oleh HAL untuk mengembalikan data kapan saja.
panggilan balik, sinkron Mengembalikan data dari implementasi metode HIDL server ke klien. Tidak digunakan untuk metode yang mengembalikan void atau nilai primitif tunggal.
klien Proses yang memanggil metode antarmuka tertentu. Proses HAL atau kerangka kerja dapat menjadi klien dari satu antarmuka dan server dari yang lain. Lihat juga passthrough.
meluas Menunjukkan antarmuka yang menambahkan metode dan/atau tipe ke antarmuka lain. Sebuah antarmuka hanya dapat memperluas satu antarmuka lainnya. Dapat digunakan untuk peningkatan versi minor dalam nama paket yang sama atau untuk paket baru (misalnya ekstensi vendor) untuk membangun paket yang lebih lama.
menghasilkan Menunjukkan metode antarmuka yang mengembalikan nilai ke klien. Untuk mengembalikan satu nilai non-primitif, atau lebih dari satu nilai, fungsi panggilan balik sinkron dibuat.
antarmuka Kumpulan metode dan jenis. Diterjemahkan ke dalam kelas dalam C++ atau Java. Semua metode dalam antarmuka dipanggil ke arah yang sama: proses klien memanggil metode yang diimplementasikan oleh proses server.
satu arah Ketika diterapkan ke metode HIDL, menunjukkan metode tidak mengembalikan nilai dan tidak memblokir.
kemasan Kumpulan antarmuka dan tipe data yang berbagi versi.
melewati Mode HIDL di mana server shared library, dlopen ed oleh klien. Dalam mode passthrough, klien dan server adalah proses yang sama tetapi basis kode yang terpisah. Digunakan hanya untuk membawa basis kode lama ke dalam model HIDL. Lihat juga Binderized.
server Proses yang mengimplementasikan metode antarmuka. Lihat juga passthrough.
mengangkut Infrastruktur HIDL yang memindahkan data antara server dan klien.
Versi: kapan Versi paket. Terdiri dari dua bilangan bulat, mayor dan minor. Peningkatan versi minor dapat menambahkan (tetapi tidak mengubah) jenis dan metode.