HIDL mengharuskan setiap antarmuka yang ditulis dalam HIDL dibuat versinya. Setelah antarmuka HAL diterbitkan, antarmuka tersebut dibekukan dan perubahan lebih lanjut harus dilakukan pada versi baru antarmuka tersebut. Meskipun antarmuka tertentu yang diterbitkan tidak dapat diubah, antarmuka tersebut dapat diperluas dengan antarmuka lain.
Struktur kode HIDL
Kode HIDL disusun dalam tipe, antarmuka, dan paket yang ditentukan pengguna:
- Tipe yang ditentukan pengguna (UDT) . HIDL menyediakan akses ke sekumpulan tipe data primitif yang dapat digunakan untuk menyusun tipe data yang lebih kompleks melalui struktur, gabungan, dan enumerasi. UDT diteruskan ke metode antarmuka, dan dapat didefinisikan pada tingkat paket (umum untuk semua antarmuka) atau secara lokal ke antarmuka.
- Antarmuka . Sebagai blok penyusun dasar HIDL, antarmuka terdiri dari UDT dan deklarasi metode. Antarmuka juga dapat mewarisi dari antarmuka lain.
- Paket . Mengatur antarmuka HIDL terkait dan tipe data yang digunakannya. Sebuah paket diidentifikasi berdasarkan nama dan versi dan mencakup hal-hal berikut:
- File definisi tipe data
types.hal
. - Tidak ada atau lebih antarmuka, masing-masing dalam file
.hal
sendiri.
- File definisi tipe data
File definisi tipe types.hal
hanya berisi UDT (semua UDT tingkat paket disimpan dalam satu file). Representasi dalam bahasa target tersedia untuk semua antarmuka dalam paket.
Filosofi pembuatan versi
Paket HIDL (seperti android.hardware.nfc
), setelah dipublikasikan untuk versi tertentu (seperti 1.0
), tidak dapat diubah; itu tidak dapat diubah. Modifikasi antarmuka dalam paket atau perubahan apa pun pada UDT hanya dapat dilakukan di paket lain .
Dalam HIDL, pembuatan versi berlaku pada tingkat paket, bukan pada tingkat antarmuka, dan semua antarmuka dan UDT dalam suatu paket berbagi versi yang sama. Versi paket mengikuti pembuatan versi semantik tanpa komponen level patch dan metadata build. Dalam suatu paket tertentu, perubahan versi minor berarti bahwa versi baru dari paket tersebut kompatibel dengan paket yang lama, dan perubahan versi mayor berarti bahwa versi baru dari paket tersebut tidak kompatibel dengan paket yang lama.
Secara konseptual, sebuah paket dapat berhubungan dengan paket lain melalui salah satu dari beberapa cara berikut:
- Sama sekali tidak .
- Ekstensibilitas kompatibel ke belakang tingkat paket . Hal ini terjadi untuk peningkatan versi kecil yang baru (revisi tambahan berikutnya) dari sebuah paket; paket baru memiliki nama dan versi mayor yang sama dengan paket lama, tetapi versi minornya lebih tinggi. Secara fungsional paket baru merupakan superset dari paket lama, artinya :
- Antarmuka tingkat atas dari paket induk ada dalam paket baru, meskipun antarmuka tersebut mungkin memiliki metode baru, UDT antarmuka-lokal baru (ekstensi tingkat antarmuka dijelaskan di bawah), dan UDT baru di
types.hal
. - Antarmuka baru juga dapat ditambahkan ke paket baru.
- Semua tipe data dari paket induk ada dalam paket baru dan dapat ditangani dengan metode (yang mungkin diimplementasikan kembali) dari paket lama.
- Tipe data baru juga dapat ditambahkan untuk digunakan dengan metode baru pada antarmuka yang sudah ada, atau dengan antarmuka baru.
- Antarmuka tingkat atas dari paket induk ada dalam paket baru, meskipun antarmuka tersebut mungkin memiliki metode baru, UDT antarmuka-lokal baru (ekstensi tingkat antarmuka dijelaskan di bawah), dan UDT baru di
- Ekstensibilitas kompatibel ke belakang tingkat antarmuka . Paket baru juga dapat memperluas paket asli dengan terdiri dari antarmuka yang terpisah secara logis yang hanya menyediakan fungsionalitas tambahan, dan bukan antarmuka inti. Untuk tujuan ini, hal-hal berikut mungkin diperlukan:
- Antarmuka dalam paket baru memerlukan bantuan tipe data paket lama.
- Antarmuka dalam paket baru dapat memperluas antarmuka dari satu atau lebih paket lama.
- Perluas ketidakcocokan ke belakang yang asli . Ini adalah peningkatan versi utama dari paket tersebut dan tidak perlu ada korelasi apa pun di antara keduanya. Sejauh yang ada, hal ini dapat diekspresikan dengan kombinasi tipe dari versi paket yang lebih lama, dan pewarisan subset antarmuka paket lama.
Penataan antarmuka
Untuk antarmuka yang terstruktur dengan baik, penambahan jenis fungsionalitas baru yang bukan bagian dari desain asli memerlukan modifikasi pada antarmuka HIDL. Sebaliknya, jika Anda dapat atau mengharapkan untuk membuat perubahan pada kedua sisi antarmuka yang memperkenalkan fungsionalitas baru tanpa mengubah antarmuka itu sendiri, maka antarmuka tersebut tidak terstruktur.
Treble mendukung vendor dan komponen sistem yang dikompilasi secara terpisah di mana vendor.img
pada perangkat dan system.img
dapat dikompilasi secara terpisah. Semua interaksi antara vendor.img
dan system.img
harus didefinisikan secara eksplisit dan menyeluruh sehingga dapat terus berfungsi selama bertahun-tahun. Ini mencakup banyak permukaan API, tetapi permukaan utamanya adalah mekanisme IPC yang digunakan HIDL untuk komunikasi antarproses pada batas system.img
/ vendor.img
.
Persyaratan
Semua data yang melewati HIDL harus didefinisikan secara eksplisit. Untuk memastikan implementasi dan klien dapat terus bekerja sama meskipun dikompilasi secara terpisah atau dikembangkan secara mandiri, data harus mematuhi persyaratan berikut:
- Dapat dijelaskan dalam HIDL secara langsung (menggunakan struct enums, dll.) dengan nama dan makna semantik.
- Dapat dijelaskan dengan standar publik seperti ISO/IEC 7816.
- Dapat digambarkan dengan standar perangkat keras atau tata letak fisik perangkat keras.
- Dapat berupa data buram (seperti kunci publik, id, dll.) jika diperlukan.
Jika data buram digunakan, data tersebut harus dibaca hanya oleh satu sisi antarmuka HIDL. Misalnya, jika kode vendor.img
memberikan pesan string atau data vec<uint8_t>
kepada komponen di system.img
, data tersebut tidak dapat diurai oleh system.img
itu sendiri; itu hanya dapat diteruskan kembali ke vendor.img
untuk ditafsirkan. Saat meneruskan nilai dari vendor.img
ke kode vendor di system.img
atau ke perangkat lain, format data dan cara menafsirkannya harus dijelaskan dengan tepat dan masih menjadi bagian dari antarmuka .
Pedoman
Anda seharusnya bisa menulis implementasi atau klien HAL hanya dengan menggunakan file .hal (yaitu Anda tidak perlu melihat sumber Android atau standar publik). Kami merekomendasikan untuk menentukan perilaku yang diperlukan secara tepat. Pernyataan seperti "sebuah implementasi dapat menghasilkan A atau B" mendorong implementasi untuk menjadi terjalin dengan klien yang mengembangkannya.
Tata letak kode HIDL
HIDL mencakup paket inti dan vendor.
Antarmuka inti HIDL adalah antarmuka yang ditentukan oleh Google. Paket-paket milik mereka dimulai dengan android.hardware.
dan diberi nama berdasarkan subsistem, kemungkinan dengan tingkat penamaan bertingkat. Misalnya, paket NFC diberi nama android.hardware.nfc
dan paket kamera diberi nama android.hardware.camera
. Secara umum, paket inti memiliki nama android.hardware.
[ name1
].[ name2
]…. Paket HIDL memiliki versi selain namanya. Misalnya, paket android.hardware.camera
mungkin berada pada versi 3.4
; ini penting, karena versi suatu paket mempengaruhi penempatannya di pohon sumber.
Semua paket inti ditempatkan di bawah hardware/interfaces/
dalam sistem pembangunan. Paket android.hardware.
[ name1
].[ name2
]… pada versi $m.$n
berada di bawah hardware/interfaces/name1/name2/
… /$m.$n/
; paket android.hardware.camera
versi 3.4
ada di direktori hardware/interfaces/camera/3.4/.
Pemetaan hard-code ada di antara awalan paket android.hardware.
dan jalur hardware/interfaces/
.
Paket non-inti (vendor) adalah yang diproduksi oleh vendor SoC atau ODM. Awalan untuk paket non-inti adalah vendor.$(VENDOR).hardware.
di mana $(VENDOR)
mengacu pada vendor SoC atau OEM/ODM. Ini memetakan ke jalur vendor/$(VENDOR)/interfaces
di pohon (pemetaan ini juga dikodekan secara keras).
Nama jenis yang ditentukan pengguna sepenuhnya memenuhi syarat
Di HIDL, setiap UDT memiliki nama yang sepenuhnya memenuhi syarat yang terdiri dari nama UDT, nama paket dimana UDT didefinisikan, dan versi paket. Nama yang sepenuhnya memenuhi syarat hanya digunakan ketika instance dari tipe tersebut dideklarasikan dan bukan ketika tipe itu sendiri didefinisikan. Misalnya, asumsikan paket android.hardware.nfc,
versi 1.0
mendefinisikan sebuah struct bernama NfcData
. Di tempat deklarasi (baik dalam types.hal
atau dalam deklarasi antarmuka), deklarasi tersebut hanya menyatakan:
struct NfcData { vec<uint8_t> data; };
Saat mendeklarasikan instance tipe ini (baik dalam struktur data atau sebagai parameter metode), gunakan nama tipe yang sepenuhnya memenuhi syarat:
android.hardware.nfc@1.0::NfcData
Sintaks umumnya adalah PACKAGE @ VERSION :: UDT
, dimana:
-
PACKAGE
adalah nama paket HIDL yang dipisahkan titik (misalnya,android.hardware.nfc
). -
VERSION
adalah format paket versi mayor.minor yang dipisahkan titik (misalnya,1.0
). -
UDT
adalah nama UDT HIDL yang dipisahkan titik. Karena HIDL mendukung UDT bersarang dan antarmuka HIDL dapat berisi UDT (sejenis deklarasi bersarang), titik digunakan untuk mengakses nama.
Misalnya, jika deklarasi bertingkat berikut didefinisikan dalam file tipe umum dalam paket android.hardware.example
versi 1.0
:
// types.hal package android.hardware.example@1.0; struct Foo { struct Bar { // … }; Bar cheers; };
Nama yang sepenuhnya memenuhi syarat untuk Bar
adalah android.hardware.example@1.0::Foo.Bar
. Jika, selain berada dalam paket di atas, deklarasi bersarang berada dalam antarmuka bernama IQuux
:
// IQuux.hal package android.hardware.example@1.0; interface IQuux { struct Foo { struct Bar { // … }; Bar cheers; }; doSomething(Foo f) generates (Foo.Bar fb); };
Nama yang sepenuhnya memenuhi syarat untuk Bar
adalah android.hardware.example@1.0::IQuux.Foo.Bar
.
Dalam kedua kasus tersebut, Bar
dapat disebut sebagai Bar
hanya dalam lingkup deklarasi Foo
. Pada tingkat paket atau antarmuka, Anda harus merujuk ke Bar
melalui Foo
: Foo.Bar
, seperti pada deklarasi metode doSomething
di atas. Alternatifnya, Anda dapat mendeklarasikan metode ini dengan lebih jelas seperti:
// IQuux.hal doSomething(android.hardware.example@1.0::IQuux.Foo f) generates (android.hardware.example@1.0::IQuux.Foo.Bar fb);
Nilai pencacahan yang memenuhi syarat sepenuhnya
Jika UDT adalah tipe enum, maka setiap nilai dari tipe enum memiliki nama yang sepenuhnya memenuhi syarat yang dimulai dengan nama tipe enum yang sepenuhnya memenuhi syarat, diikuti dengan titik dua, lalu diikuti dengan nama nilai enum. Misalnya, asumsikan paket android.hardware.nfc,
versi 1.0
mendefinisikan tipe enum NfcStatus
:
enum NfcStatus { STATUS_OK, STATUS_FAILED };
Saat mengacu pada STATUS_OK
, nama yang sepenuhnya memenuhi syarat adalah:
android.hardware.nfc@1.0::NfcStatus:STATUS_OK
Sintaks umumnya adalah PACKAGE @ VERSION :: UDT : VALUE
, dimana:
-
PACKAGE @ VERSION :: UDT
adalah nama yang sepenuhnya memenuhi syarat untuk tipe enum. -
VALUE
adalah nama nilainya.
Aturan inferensi otomatis
Nama UDT yang sepenuhnya memenuhi syarat tidak perlu disebutkan. Nama UDT dapat dengan aman menghilangkan hal berikut:
- Paketnya, misal
@1.0::IFoo.Type
- Baik paket maupun versinya, misal
IFoo.Type
HIDL mencoba melengkapi nama menggunakan aturan interferensi otomatis (nomor aturan yang lebih rendah berarti prioritas yang lebih tinggi).
Aturan 1
Jika tidak ada paket dan versi yang disediakan, pencarian nama lokal akan dilakukan. Contoh:
interface Nfc { typedef string NfcErrorMessage; send(NfcData d) generates (@1.0::NfcStatus s, NfcErrorMessage m); };
NfcErrorMessage
dicari secara lokal, dan typedef
di atasnya ditemukan. NfcData
juga dicari secara lokal, namun karena tidak ditentukan secara lokal, aturan 2 dan 3 digunakan. @1.0::NfcStatus
menyediakan versi, jadi aturan 1 tidak berlaku.
Aturan 2
Jika aturan 1 gagal dan komponen dengan nama yang sepenuhnya memenuhi syarat tidak ada (paket, versi, atau paket dan versi), komponen tersebut diisi otomatis dengan informasi dari paket saat ini. Kompiler HIDL kemudian mencari file saat ini (dan semua impor) untuk menemukan nama yang sepenuhnya memenuhi syarat yang diisi otomatis. Dengan menggunakan contoh di atas, asumsikan deklarasi ExtendedNfcData
dibuat dalam paket yang sama ( android.hardware.nfc
) pada versi yang sama ( 1.0
) dengan NfcData
, sebagai berikut:
struct ExtendedNfcData { NfcData base; // … additional members };
Kompiler HIDL mengisi nama paket dan nama versi dari paket saat ini untuk menghasilkan nama UDT yang sepenuhnya memenuhi syarat android.hardware.nfc@1.0::NfcData
. Karena nama tersebut ada dalam paket saat ini (dengan asumsi nama tersebut diimpor dengan benar), maka nama tersebut digunakan untuk deklarasi.
Nama dalam paket saat ini diimpor hanya jika salah satu dari yang berikut ini benar:
- Itu diimpor secara eksplisit dengan pernyataan
import
. - Itu didefinisikan di
types.hal
dalam paket saat ini
Proses yang sama diikuti jika NfcData
memenuhi syarat hanya berdasarkan nomor versi:
struct ExtendedNfcData { // autofill the current package name (android.hardware.nfc) @1.0::NfcData base; // … additional members };
Aturan 3
Jika aturan 2 gagal menghasilkan kecocokan (UDT tidak ditentukan dalam paket saat ini), kompiler HIDL akan memindai kecocokan dalam semua paket yang diimpor. Dengan menggunakan contoh di atas, asumsikan ExtendedNfcData
dideklarasikan dalam versi 1.1
paket android.hardware.nfc
, 1.1
mengimpor 1.0
sebagaimana mestinya (lihat Package-Level Extensions ), dan definisinya hanya menetapkan nama UDT:
struct ExtendedNfcData { NfcData base; // … additional members };
Kompiler mencari UDT apa pun yang bernama NfcData
dan menemukannya di android.hardware.nfc
pada versi 1.0
, sehingga menghasilkan UDT android.hardware.nfc@1.0::NfcData
yang sepenuhnya memenuhi syarat. Jika lebih dari satu kecocokan ditemukan untuk UDT yang memenuhi syarat sebagian, kompiler HIDL akan memunculkan kesalahan.
Contoh
Dengan menggunakan aturan 2, tipe yang diimpor yang ditentukan dalam paket saat ini lebih disukai daripada tipe yang diimpor dari paket lain:
// hardware/interfaces/foo/1.0/types.hal package android.hardware.foo@1.0; struct S {}; // hardware/interfaces/foo/1.0/IFooCallback.hal package android.hardware.foo@1.0; interface IFooCallback {}; // hardware/interfaces/bar/1.0/types.hal package android.hardware.bar@1.0; typedef string S; // hardware/interfaces/bar/1.0/IFooCallback.hal package android.hardware.bar@1.0; interface IFooCallback {}; // hardware/interfaces/bar/1.0/IBar.hal package android.hardware.bar@1.0; import android.hardware.foo@1.0; interface IBar { baz1(S s); // android.hardware.bar@1.0::S baz2(IFooCallback s); // android.hardware.foo@1.0::IFooCallback };
-
S
diinterpolasi sebagaiandroid.hardware.bar@1.0::S
, dan ditemukan dibar/1.0/types.hal
(karenatypes.hal
diimpor secara otomatis). -
IFooCallback
diinterpolasi sebagaiandroid.hardware.bar@1.0::IFooCallback
menggunakan aturan 2, tetapi tidak dapat ditemukan karenabar/1.0/IFooCallback.hal
tidak diimpor secara otomatis (seperti halnyatypes.hal
). Jadi, aturan 3 menyelesaikannya menjadiandroid.hardware.foo@1.0::IFooCallback
, yang diimpor melaluiimport android.hardware.foo@1.0;
).
jenis.hal
Setiap paket HIDL berisi file types.hal
yang berisi UDT yang dibagikan di antara semua antarmuka yang berpartisipasi dalam paket itu. Tipe HIDL selalu bersifat publik; terlepas dari apakah UDT dideklarasikan dalam types.hal
atau dalam deklarasi antarmuka, tipe ini dapat diakses di luar cakupan di mana UDT didefinisikan. types.hal
tidak dimaksudkan untuk mendeskripsikan API publik suatu paket, melainkan untuk menghosting UDT yang digunakan oleh semua antarmuka dalam paket. Karena sifat HIDL, semua UDT adalah bagian dari antarmuka.
types.hal
terdiri dari UDT dan pernyataan import
. Karena types.hal
tersedia untuk setiap antarmuka paket (ini merupakan impor implisit), pernyataan import
ini menurut definisi adalah tingkat paket. UDT di types.hal
juga dapat menggabungkan UDT dan antarmuka yang diimpor.
Misalnya, untuk IFoo.hal
:
package android.hardware.foo@1.0; // whole package import import android.hardware.bar@1.0; // types only import import android.hardware.baz@1.0::types; // partial imports import android.hardware.qux@1.0::IQux.Quux; // partial imports import android.hardware.quuz@1.0::Quuz;
Berikut ini yang diimpor:
-
android.hidl.base@1.0::IBase
(secara implisit) -
android.hardware.foo@1.0::types
(secara implisit) - Segala sesuatu di
android.hardware.bar@1.0
(termasuk semua antarmuka dantypes.hal
) -
types.hal
dariandroid.hardware.baz@1.0::types
(antarmuka diandroid.hardware.baz@1.0
tidak diimpor) -
IQux.hal
dantypes.hal
dariandroid.hardware.qux@1.0
-
Quuz
dariandroid.hardware.quuz@1.0
(dengan asumsiQuuz
didefinisikan dalamtypes.hal
, seluruh filetypes.hal
diurai, namun tipe selainQuuz
tidak diimpor).
Pembuatan versi tingkat antarmuka
Setiap antarmuka dalam suatu paket berada di filenya sendiri. Paket milik antarmuka dideklarasikan di bagian atas antarmuka menggunakan pernyataan package
. Setelah deklarasi paket, tidak ada atau lebih impor tingkat antarmuka (paket sebagian atau keseluruhan) yang dapat dicantumkan. Misalnya:
package android.hardware.nfc@1.0;
Di HIDL, antarmuka dapat mewarisi dari antarmuka lain menggunakan kata kunci extends
. Agar sebuah antarmuka dapat memperluas antarmuka lain, ia harus memiliki akses ke antarmuka tersebut melalui pernyataan import
. Nama antarmuka yang diperluas (antarmuka dasar) mengikuti aturan kualifikasi nama tipe yang dijelaskan di atas. Sebuah antarmuka hanya dapat mewarisi satu antarmuka; HIDL tidak mendukung pewarisan berganda.
Contoh pembuatan versi uprev di bawah ini menggunakan paket berikut:
// types.hal package android.hardware.example@1.0 struct Foo { struct Bar { vec<uint32_t> val; }; }; // IQuux.hal package android.hardware.example@1.0 interface IQuux { fromFooToBar(Foo f) generates (Foo.Bar b); }
Aturan kenaikan
Untuk mendefinisikan sebuah paket package@major.minor
, A atau seluruh B harus benar:
Aturan A | "Merupakan versi minor awal": Semua versi minor sebelumnya, package@major.0 , package@major.1 , …, package@major.(minor-1) tidak boleh ditentukan. |
---|
Aturan B | Semua hal berikut ini benar:
|
---|
Karena aturan A:
- Paket dapat dimulai dengan nomor versi minor apa pun (misalnya,
android.hardware.biometrics.fingerprint
dimulai pada@2.1
.) - Persyaratan "
android.hardware.foo@1.0
tidak ditentukan" berarti direktorihardware/interfaces/foo/1.0
seharusnya tidak ada.
Namun, aturan A tidak memengaruhi paket dengan nama paket yang sama tetapi versi utama yang berbeda (misalnya, android.hardware.camera.device
telah menetapkan @1.0
dan @3.2
; @3.2
tidak perlu berinteraksi dengan @1.0
.) Oleh karena itu, @3.2::IExtFoo
dapat memperluas @1.0::IFoo
.
Asalkan nama paketnya berbeda, package@major.minor::IBar
dapat diperluas dari antarmuka dengan nama yang berbeda (misalnya, android.hardware.bar@1.0::IBar
dapat memperluas android.hardware.baz@2.2::IBaz
). Jika suatu antarmuka tidak secara eksplisit mendeklarasikan tipe super dengan kata kunci extend
, antarmuka tersebut akan memperluas android.hidl.base@1.0::IBase
(kecuali IBase
itu sendiri).
B.2 dan B.3 harus diikuti secara bersamaan. Misalnya, meskipun android.hardware.foo@1.1::IFoo
memperluas android.hardware.foo@1.0::IFoo
untuk meneruskan aturan B.2, jika android.hardware.foo@1.1::IExtBar
memperluas android.hardware.foo@1.0::IBar
, ini masih bukan peningkatan yang valid.
Meningkatkan antarmuka
Untuk meningkatkan android.hardware.example@1.0
(didefinisikan di atas) menjadi @1.1
:
// types.hal package android.hardware.example@1.1; import android.hardware.example@1.0; // IQuux.hal package android.hardware.example@1.1 interface IQuux extends @1.0::IQuux { fromBarToFoo(Foo.Bar b) generates (Foo f); }
Ini adalah import
tingkat paket android.hardware.example
versi 1.0
di types.hal
. Meskipun tidak ada UDT baru yang ditambahkan dalam paket versi 1.1
, referensi ke UDT dalam versi 1.0
masih diperlukan, oleh karena itu impor tingkat paket dalam types.hal
. (Efek yang sama dapat dicapai dengan impor tingkat antarmuka di IQuux.hal
.)
Dalam extends @1.0::IQuux
dalam deklarasi IQuux
, kami menentukan versi IQuux
yang diwarisi (disambiguasi diperlukan karena IQuux
digunakan untuk mendeklarasikan antarmuka dan mewarisi dari antarmuka). Karena deklarasi hanyalah nama yang mewarisi semua atribut paket dan versi di tempat deklarasi, disambiguasinya harus dalam nama antarmuka dasar; kami juga dapat menggunakan UDT yang memenuhi syarat sepenuhnya, namun hal tersebut akan menjadi mubazir.
Antarmuka baru IQuux
tidak mendeklarasikan ulang metode fromFooToBar()
yang diwarisi dari @1.0::IQuux
; itu hanya mencantumkan metode baru yang ditambahkannya fromBarToFoo()
. Di HIDL, metode yang diwariskan tidak boleh dideklarasikan lagi di antarmuka anak, sehingga antarmuka IQuux
tidak dapat mendeklarasikan metode fromFooToBar()
secara eksplisit.
Konvensi peningkatan
Terkadang nama antarmuka harus mengganti nama antarmuka perluasan. Kami merekomendasikan bahwa ekstensi enum, struct, dan gabungan memiliki nama yang sama dengan perluasannya kecuali jika keduanya cukup berbeda untuk memerlukan nama baru. Contoh:
// in parent hal file enum Brightness : uint32_t { NONE, WHITE }; // in child hal file extending the existing set with additional similar values enum Brightness : @1.0::Brightness { AUTOMATIC }; // extending the existing set with values that require a new, more descriptive name: enum Color : @1.0::Brightness { HW_GREEN, RAINBOW };
Jika suatu metode dapat memiliki nama semantik baru (misalnya fooWithLocation
) maka itu lebih disukai. Jika tidak, nama tersebut harus serupa dengan perluasannya. Misalnya, metode foo_1_1
di @1.1::IFoo
dapat menggantikan fungsi metode foo
di @1.0::IFoo
jika tidak ada nama alternatif yang lebih baik.
Pembuatan versi tingkat paket
Pembuatan versi HIDL terjadi pada tingkat paket; setelah sebuah paket dipublikasikan, paket tersebut tidak dapat diubah (rangkaian antarmuka dan UDTnya tidak dapat diubah). Paket-paket dapat berhubungan satu sama lain dalam beberapa cara, yang semuanya dapat diekspresikan melalui kombinasi pewarisan tingkat antarmuka dan pembuatan UDT berdasarkan komposisi.
Namun, ada satu jenis hubungan yang didefinisikan secara ketat dan harus ditegakkan: Warisan kompatibel ke belakang tingkat paket . Dalam skenario ini, paket induk adalah paket yang diwarisi dan paket anak adalah paket yang memperluas induknya. Aturan pewarisan kompatibel ke belakang tingkat paket adalah sebagai berikut:
- Semua antarmuka tingkat atas dari paket induk diwarisi dari antarmuka dalam paket anak.
- Antarmuka baru juga dapat ditambahkan ke paket baru (tidak ada batasan tentang hubungan ke antarmuka lain di paket lain).
- Tipe data baru juga dapat ditambahkan untuk digunakan dengan metode baru pada antarmuka yang sudah ada, atau dengan antarmuka baru.
Aturan-aturan ini dapat diimplementasikan menggunakan pewarisan tingkat antarmuka HIDL dan komposisi UDT, namun memerlukan pengetahuan tingkat meta untuk mengetahui hubungan ini merupakan ekstensi paket yang kompatibel ke belakang. Pengetahuan ini disimpulkan sebagai berikut:
Jika sebuah paket memenuhi persyaratan ini, hidl-gen
menerapkan aturan kompatibilitas mundur.