Pembuatan versi antarmuka

HIDL mewajibkan setiap antarmuka yang ditulis dalam HIDL diberi versi. Setelah dipublikasikan, antarmuka HAL akan dibekukan dan perubahan lebih lanjut harus dilakukan pada versi baru antarmuka tersebut. Meskipun antarmuka yang dipublikasikan tidak dapat diubah, antarmuka tersebut dapat diperluas oleh antarmuka lain.

Struktur kode HIDL

Kode HIDL diatur dalam jenis, antarmuka, dan paket yang ditentukan pengguna:

  • Jenis yang ditentukan pengguna (UDT). HIDL menyediakan akses ke kumpulan jenis data primitif yang dapat digunakan untuk menyusun jenis yang lebih kompleks melalui struktur, gabungan, dan enumerasi. UDT diteruskan ke metode antarmuka, dan dapat ditentukan di tingkat paket (umum untuk semua antarmuka) atau secara lokal ke antarmuka.
  • Antarmuka. Sebagai elemen penyusun dasar HIDL, antarmuka terdiri dari UDT dan deklarasi metode. Antarmuka juga dapat mewarisi dari antarmuka lain.
  • Paket. Mengatur antarmuka HIDL terkait dan jenis data tempatnya beroperasi. Paket diidentifikasi dengan nama dan versi serta menyertakan hal berikut:
    • File definisi jenis data yang disebut types.hal.
    • Nol atau beberapa antarmuka, masing-masing dalam file .hal-nya sendiri.

File definisi jenis data 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; paket tersebut tidak dapat diubah. Modifikasi pada antarmuka dalam paket atau perubahan pada UDT-nya hanya dapat dilakukan dalam paket lain.

Di HIDL, pembuatan versi berlaku di tingkat paket, bukan di tingkat antarmuka, dan semua antarmuka dan UDT dalam paket memiliki versi yang sama. Versi paket mengikuti versi semantik tanpa komponen metadata build dan tingkat patch. Dalam paket tertentu, peningkatan versi minor menyiratkan bahwa versi baru paket kompatibel dengan versi lama dan peningkatan versi utama menyiratkan bahwa versi baru paket tidak kompatibel dengan versi lama.

Secara konseptual, paket dapat dikaitkan dengan paket lain dengan salah satu dari beberapa cara:

  • Sama sekali tidak.
  • Ekstensibilitas tingkat paket yang kompatibel dengan versi lama. Hal ini terjadi untuk uprev versi minor baru (revisi yang bertambah berikutnya) dari paket; paket baru memiliki nama dan versi utama yang sama dengan paket lama, tetapi versi minor yang lebih tinggi. Secara fungsional, paket baru adalah superset dari paket lama, yang berarti:
    • Antarmuka tingkat atas paket induk ada dalam paket baru, meskipun antarmuka mungkin memiliki metode baru, UDT lokal antarmuka baru (ekstensi tingkat antarmuka yang dijelaskan di bawah), dan UDT baru di types.hal.
    • Antarmuka baru juga dapat ditambahkan ke paket baru.
    • Semua jenis data paket induk ada dalam paket baru dan dapat ditangani oleh metode (mungkin diterapkan ulang) dari paket lama.
    • Jenis data baru juga dapat ditambahkan untuk digunakan oleh metode baru dari antarmuka yang sudah ada yang diupdate, atau oleh antarmuka baru.
  • Ekstensibilitas tingkat antarmuka yang kompatibel dengan versi lama. Paket baru juga dapat memperluas paket asli dengan terdiri dari antarmuka yang terpisah secara logis yang hanya menyediakan fungsi tambahan, dan bukan fungsi inti. Untuk tujuan ini, hal berikut mungkin diinginkan:
    • Antarmuka dalam paket baru memerlukan penggantian jenis data paket lama.
    • Antarmuka dalam paket baru dapat memperluas antarmuka dari satu atau beberapa paket lama.
  • Memperluas inkompatibilitas mundur asli. Ini adalah uprev versi utama paket dan tidak perlu ada korelasi antara keduanya. Jika ada, hal ini dapat dinyatakan dengan kombinasi jenis dari paket versi lama, dan pewarisan subset antarmuka paket lama.

Penyusunan antarmuka

Untuk antarmuka yang terstruktur dengan baik, menambahkan jenis fungsi baru yang bukan bagian dari desain asli harus memerlukan modifikasi pada antarmuka HIDL. Sebaliknya, jika Anda dapat atau berharap untuk membuat perubahan di kedua sisi antarmuka yang memperkenalkan fungsi baru tanpa mengubah antarmuka itu sendiri, antarmuka tersebut tidak terstruktur.

Treble mendukung komponen vendor dan sistem yang dikompilasi secara terpisah, dengan vendor.img di perangkat dan system.img dapat dikompilasi secara terpisah. Semua interaksi antara vendor.img dan system.img harus ditentukan secara eksplisit dan menyeluruh sehingga dapat terus berfungsi selama bertahun-tahun. Hal ini mencakup banyak platform API, tetapi platform utama adalah mekanisme IPC yang digunakan HIDL untuk komunikasi antarproses di batas system.img/vendor.img.

Persyaratan

Semua data yang diteruskan melalui HIDL harus ditentukan secara eksplisit. Untuk memastikan implementasi dan klien dapat terus bekerja sama meskipun dikompilasi secara terpisah atau dikembangkan secara independen, data harus mematuhi persyaratan berikut:

  • Dapat dijelaskan di HIDL secara langsung (menggunakan enum struct, dll.) dengan nama dan makna semantik.
  • Dapat dijelaskan oleh standar publik seperti ISO/IEC 7816.
  • Dapat dijelaskan oleh standar hardware atau tata letak fisik hardware.
  • Dapat berupa data buram (seperti kunci publik, ID, dll.) jika diperlukan.

Jika data buram digunakan, data tersebut hanya boleh dibaca oleh satu sisi antarmuka HIDL. Misalnya, jika kode vendor.img memberi komponen di system.img pesan string atau data vec<uint8_t>, data tersebut tidak dapat diuraikan oleh system.img itu sendiri; data tersebut 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 merupakan bagian dari antarmuka.

Panduan

Anda harus dapat menulis implementasi atau klien HAL hanya menggunakan file .hal (yaitu Anda tidak perlu melihat sumber Android atau standar publik). Sebaiknya tentukan perilaku yang diperlukan secara tepat. Pernyataan seperti "implementasi mungkin melakukan A atau B" mendorong implementasi untuk menjadi terjalin dengan klien yang mengembangkannya.

Tata letak kode HIDL

HIDL mencakup paket inti dan vendor.

Antarmuka HIDL inti adalah antarmuka yang ditentukan oleh Google. Paket yang menjadi bagiannya akan dimulai dengan android.hardware. dan diberi nama oleh subsistem, yang berpotensi 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; hal ini penting, karena versi paket memengaruhi penempatannya dalam hierarki sumber.

Semua paket inti ditempatkan di bagian hardware/interfaces/ dalam sistem build. Paket android.hardware.[name1].[name2]… pada versi $m.$n berada di 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 antara awalan paket android.hardware. dan jalur hardware/interfaces/.

Paket non-inti (vendor) adalah paket yang diproduksi oleh vendor SoC atau ODM. Awalan untuk paket non-inti adalah vendor.$(VENDOR).hardware. dengan $(VENDOR)merujuk ke vendor SoC atau OEM/ODM. Hal ini dipetakan ke jalur vendor/$(VENDOR)/interfaces dalam hierarki (pemetaan ini juga di-hardcode).

Nama jenis yang ditentukan pengguna yang sepenuhnya memenuhi syarat

Di HIDL, setiap UDT memiliki nama yang sepenuhnya memenuhi syarat yang terdiri dari nama UDT, nama paket tempat UDT ditentukan, dan versi paket. Nama yang sepenuhnya memenuhi syarat hanya digunakan saat instance jenis dideklarasikan dan bukan tempat jenis itu sendiri ditentukan. Misalnya, asumsikan paket android.hardware.nfc, versi 1.0 menentukan struct bernama NfcData. Di situs deklarasi (baik di types.hal atau dalam deklarasi antarmuka), deklarasi hanya menyatakan:

struct NfcData {
    vec<uint8_t> data;
};

Saat mendeklarasikan instance jenis ini (baik dalam struktur data maupun sebagai parameter metode), gunakan nama jenis yang sepenuhnya memenuhi syarat:

android.hardware.nfc@1.0::NfcData

Sintaksis umumnya adalah PACKAGE@VERSION::UDT, dengan:

  • PACKAGE adalah nama paket HIDL yang dipisahkan titik (misalnya, android.hardware.nfc).
  • VERSION adalah format versi utama.minor yang dipisahkan titik dari paket (mis., 1.0).
  • UDT adalah nama UDT HIDL yang dipisahkan titik. Karena HIDL mendukung UDT bertingkat dan antarmuka HIDL dapat berisi UDT (jenis deklarasi bertingkat), titik digunakan untuk mengakses nama.

Misalnya, jika deklarasi bertingkat berikut ditentukan dalam file jenis 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 di paket di atas, deklarasi bertingkat berada di antarmuka yang disebut 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 hanya dapat disebut sebagai Bar dalam cakupan deklarasi Foo. Pada tingkat paket atau antarmuka, Anda harus merujuk ke Bar melalui Foo: Foo.Bar, seperti dalam deklarasi metode doSomething di atas. Atau, Anda dapat mendeklarasikan metode secara lebih panjang sebagai:

// IQuux.hal
doSomething(android.hardware.example@1.0::IQuux.Foo f) generates (android.hardware.example@1.0::IQuux.Foo.Bar fb);

Nilai enumerasi yang sepenuhnya memenuhi syarat

Jika UDT adalah jenis enum, setiap nilai jenis enum memiliki nama yang sepenuhnya memenuhi syarat yang dimulai dengan nama yang sepenuhnya memenuhi syarat dari jenis enum, diikuti dengan titik dua, lalu diikuti dengan nama nilai enum. Misalnya, anggap paket android.hardware.nfc, versi 1.0 menentukan jenis enum NfcStatus:

enum NfcStatus {
    STATUS_OK,
    STATUS_FAILED
};

Saat merujuk ke STATUS_OK, nama yang sepenuhnya memenuhi syarat adalah:

android.hardware.nfc@1.0::NfcStatus:STATUS_OK

Sintaksis umumnya adalah PACKAGE@VERSION::UDT:VALUE, dengan:

  • PACKAGE@VERSION::UDT adalah nama yang sepenuhnya memenuhi syarat dan sama persis untuk jenis enum.
  • VALUE adalah nama nilai.

Aturan inferensi otomatis

Nama UDT yang sepenuhnya memenuhi syarat tidak perlu ditentukan. Nama UDT dapat menghapus hal berikut dengan aman:

  • Paket, misalnya @1.0::IFoo.Type
  • Paket dan versi, misalnya IFoo.Type

HIDL mencoba menyelesaikan nama menggunakan aturan interferensi otomatis (angka aturan yang lebih rendah berarti prioritas yang lebih tinggi).

Aturan 1

Jika tidak ada paket dan versi yang diberikan, pencarian nama lokal akan dicoba. 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, tetapi karena tidak ditentukan secara lokal, aturan 2 dan 3 akan digunakan. @1.0::NfcStatus menyediakan versi, sehingga aturan 1 tidak berlaku.

Aturan 2

Jika aturan 1 gagal dan komponen nama yang sepenuhnya memenuhi syarat tidak ada (paket, versi, atau paket dan versi), komponen akan diisi otomatis dengan informasi dari paket saat ini. Kemudian, compiler HIDL akan mencari di file saat ini (dan semua impor) untuk menemukan nama yang sepenuhnya memenuhi syarat dan diisi otomatis. Dengan menggunakan contoh di atas, asumsikan deklarasi ExtendedNfcData dibuat dalam paket yang sama (android.hardware.nfc) pada versi yang sama (1.0) seperti NfcData, sebagai berikut:

struct ExtendedNfcData {
    NfcData base;
    // … additional members
};

Compiler 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 diimpor dengan benar), nama tersebut digunakan untuk deklarasi.

Nama dalam paket saat ini hanya diimpor jika salah satu dari berikut ini bernilai benar:

  • File ini diimpor secara eksplisit dengan pernyataan import.
  • Ini ditentukan dalam types.hal dalam paket saat ini

Proses yang sama diikuti jika NfcData hanya memenuhi syarat 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), compiler 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 Ekstensi Tingkat Paket), dan definisinya hanya menentukan nama UDT:

struct ExtendedNfcData {
    NfcData base;
    // … additional members
};

Compiler mencari UDT bernama NfcData dan menemukannya di android.hardware.nfc pada versi 1.0, yang menghasilkan UDT android.hardware.nfc@1.0::NfcData yang sepenuhnya memenuhi syarat. Jika lebih dari satu kecocokan ditemukan untuk UDT tertentu yang memenuhi syarat sebagian, compiler HIDL akan menampilkan error.

Contoh

Dengan menggunakan aturan 2, jenis yang diimpor yang ditentukan dalam paket saat ini lebih disukai daripada jenis 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 sebagai android.hardware.bar@1.0::S, dan ditemukan di bar/1.0/types.hal (karena types.hal otomatis diimpor).
  • IFooCallback diinterpolasi sebagai android.hardware.bar@1.0::IFooCallback menggunakan aturan 2, tetapi tidak dapat ditemukan karena bar/1.0/IFooCallback.hal tidak diimpor secara otomatis (seperti types.hal). Oleh karena itu, aturan 3 me-resolve-nya ke android.hardware.foo@1.0::IFooCallback, yang diimpor melalui import android.hardware.foo@1.0;).

types.hal

Setiap paket HIDL berisi file types.hal yang berisi UDT yang dibagikan di antara semua antarmuka yang berpartisipasi dalam paket tersebut. Jenis HIDL selalu bersifat publik; terlepas dari apakah UDT dideklarasikan dalam types.hal atau dalam deklarasi antarmuka, jenis ini dapat diakses di luar cakupan tempatnya ditentukan. types.hal tidak dimaksudkan untuk menjelaskan API publik paket, tetapi 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 adalah impor implisit), pernyataan import ini berada di tingkat paket menurut definisi. 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;

Hal berikut akan diimpor:

  • android.hidl.base@1.0::IBase (secara implisit)
  • android.hardware.foo@1.0::types (secara implisit)
  • Semuanya di android.hardware.bar@1.0 (termasuk semua antarmuka dan types.hal-nya)
  • types.hal dari android.hardware.baz@1.0::types (antarmuka di android.hardware.baz@1.0 tidak diimpor)
  • IQux.hal dan types.hal dari android.hardware.qux@1.0
  • Quuz dari android.hardware.quuz@1.0 (dengan asumsi Quuz ditentukan dalam types.hal, seluruh file types.hal akan diuraikan, tetapi jenis selain Quuz tidak diimpor).

Pembuatan versi tingkat antarmuka

Setiap antarmuka dalam paket berada dalam filenya sendiri. Paket yang menjadi milik antarmuka dideklarasikan di bagian atas antarmuka menggunakan pernyataan package. Setelah deklarasi paket, nol atau beberapa impor tingkat antarmuka (sebagian atau seluruh paket) mungkin dicantumkan. Contoh:

package android.hardware.nfc@1.0;

Di HIDL, antarmuka dapat mewarisi dari antarmuka lain menggunakan kata kunci extends. Agar dapat memperluas antarmuka lain, antarmuka harus memiliki akses ke antarmuka tersebut melalui pernyataan import. Nama antarmuka yang diperluas (antarmuka dasar) mengikuti aturan untuk kualifikasi nama jenis yang dijelaskan di atas. Antarmuka hanya dapat mewarisi dari satu antarmuka; HIDL tidak mendukung beberapa pewarisan.

Contoh pembuatan versi uprev di bawah 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 Uprev

Untuk menentukan package@major.minor paket, A atau semua B harus benar:

Aturan A "Adalah versi minor awal": Semua versi minor sebelumnya, package@major.0, package@major.1, …, package@major.(minor-1) tidak boleh ditentukan.
ATAU
Aturan B

Semua hal berikut benar:

  1. "Versi minor sebelumnya valid": package@major.(minor-1) harus ditentukan dan mengikuti aturan A yang sama (tidak ada package@major.0 hingga package@major.(minor-2) yang ditentukan) atau aturan B (jika merupakan uprev dari @major.(minor-2));

    DAN

  2. "Mewarisi minimal satu antarmuka dengan nama yang sama": Ada antarmuka package@major.minor::IFoo yang memperluas package@major.(minor-1)::IFoo (jika paket sebelumnya memiliki antarmuka);

    DAN

  3. "Tidak ada antarmuka yang diwarisi dengan nama yang berbeda": Tidak boleh ada package@major.minor::IBar yang memperluas package@major.(minor-1)::IBaz, dengan IBar dan IBaz adalah dua nama yang berbeda. Jika ada antarmuka dengan nama yang sama, package@major.minor::IBar harus memperluas package@major.(minor-k)::IBar sehingga tidak ada IBar dengan k yang lebih kecil.

Karena aturan A:

  • Paket dapat dimulai dengan nomor versi minor apa pun (misalnya, android.hardware.biometrics.fingerprint dimulai dari @2.1.)
  • Persyaratan "android.hardware.foo@1.0 tidak ditentukan" berarti direktori hardware/interfaces/foo/1.0 bahkan tidak boleh ada.

Namun, aturan A tidak memengaruhi paket dengan nama paket yang sama, tetapi versi utama yang berbeda (misalnya, android.hardware.camera.device memiliki @1.0 dan @3.2 yang ditentukan; @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 antarmuka tidak mendeklarasikan jenis super secara eksplisit 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 uprev yang valid.

Antarmuka Uprev

Untuk mengupdate android.hardware.example@1.0 (ditentukan di atas) ke @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 dari versi 1.0 android.hardware.example di types.hal. Meskipun tidak ada UDT baru yang ditambahkan dalam paket versi 1.1, referensi ke UDT dalam versi 1.0 masih diperlukan, sehingga impor tingkat paket di types.hal. (Efek yang sama dapat dicapai dengan impor tingkat antarmuka di IQuux.hal.)

Di extends @1.0::IQuux dalam deklarasi IQuux, kita menentukan versi IQuux yang diwarisi (disambiguasi diperlukan karena IQuux digunakan untuk mendeklarasikan antarmuka dan mewarisi dari antarmuka). Karena deklarasi hanya nama yang mewarisi semua atribut paket dan versi di situs deklarasi, disambiguasi harus dalam nama antarmuka dasar; kita juga dapat menggunakan UDT yang sepenuhnya memenuhi syarat, tetapi hal itu akan berlebihan.

Antarmuka baru IQuux tidak mendeklarasikan ulang metode fromFooToBar() yang diwarisi dari @1.0::IQuux; antarmuka ini hanya mencantumkan metode baru yang ditambahkan fromBarToFoo(). Di HIDL, metode yang diwarisi tidak dapat dideklarasikan lagi di antarmuka turunan, sehingga antarmuka IQuux tidak dapat mendeklarasikan metode fromFooToBar() secara eksplisit.

Konvensi Uprev

Terkadang nama antarmuka harus mengganti nama antarmuka yang diperluas. Sebaiknya ekstensi enum, struct, dan union memiliki nama yang sama dengan yang diperluasnya kecuali jika cukup berbeda untuk menjamin 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 metode dapat memiliki nama semantik baru (misalnya fooWithLocation), metode tersebut lebih disukai. Jika tidak, nama tersebut harus disebut mirip dengan yang diperluas. 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 di tingkat paket; setelah dipublikasikan, paket tidak dapat diubah (kumpulan antarmuka dan UDT-nya tidak dapat diubah). Paket dapat terkait satu sama lain dengan beberapa cara, yang semuanya dapat dinyatakan melalui kombinasi pewarisan tingkat antarmuka dan pembuatan UDT menurut komposisi.

Namun, satu jenis hubungan ditentukan secara ketat dan harus diterapkan: Warisan yang kompatibel dengan versi lama tingkat paket. Dalam skenario ini, paket induk adalah paket yang diwarisi dan paket turunan adalah paket yang memperluas induk. Aturan pewarisan yang kompatibel dengan versi sebelumnya di tingkat paket adalah sebagai berikut:

  1. Semua antarmuka tingkat teratas dari paket induk diwarisi dari antarmuka dalam paket turunan.
  2. Antarmuka baru juga dapat ditambahkan ke paket baru (tidak ada batasan tentang hubungan dengan antarmuka lain dalam paket lain).
  3. Jenis data baru juga dapat ditambahkan untuk digunakan oleh metode baru dari antarmuka yang sudah diupdate, atau oleh antarmuka baru.

Aturan ini dapat diimplementasikan menggunakan pewarisan tingkat antarmuka HIDL dan komposisi UDT, tetapi memerlukan pengetahuan tingkat meta untuk mengetahui bahwa hubungan ini merupakan ekstensi paket yang kompatibel dengan versi sebelumnya. Pengetahuan ini disimpulkan sebagai berikut:

Jika paket memenuhi persyaratan ini, hidl-gen akan menerapkan aturan kompatibilitas mundur.