Pembuatan versi antarmuka

HIDL mengharuskan setiap antarmuka yang ditulis dalam HIDL dibuat versinya. Setelah HAL dipublikasikan, dibekukan, dan perubahan lebih lanjut harus dilakukan versi baru dari antarmuka itu. Meskipun antarmuka tertentu yang dipublikasikan tidak dapat dimodifikasi, dapat diperluas oleh antarmuka lain.

Struktur kode HIDL

Kode HiDL diatur dalam ditentukan pengguna tipe, antarmuka, dan paket:

  • Jenis yang ditentukan pengguna (UDT). HIDL menyediakan akses ke serangkaian tipe data primitif yang dapat digunakan untuk membuat tipe yang lebih kompleks melalui struktur, serikat buruh, dan enumerasi. UDT diteruskan ke metode antarmuka, dan dapat didefinisikan pada tingkat paket (umum untuk semua antarmuka) atau secara lokal ke antarmuka.
  • Antarmuka. Sebagai elemen penyusun dasar HIDL, antarmuka terdiri dari deklarasi UDT dan metode. Antarmuka juga dapat mewarisi dari antarmuka lain.
  • Paket. Mengatur antarmuka HIDL dan data yang terkait jenis tempat mereka beroperasi. Sebuah paket diidentifikasi dengan nama dan versi dan mencakup hal berikut:
    • File definisi jenis data bernama 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 target bahasa tersedia untuk semua antarmuka dalam paket.

Filosofi pembuatan versi

Paket HIDL (seperti android.hardware.nfc), setelah yang dipublikasikan untuk versi tertentu (seperti 1.0), tidak dapat diubah; ini tidak dapat diubah. Modifikasi antarmuka dalam paket atau perubahan pada UDT-nya hanya dapat dilakukan di paket lain.

Dalam HIDL, pembuatan versi berlaku di tingkat paket, bukan di tingkat antarmuka, dan semua antarmuka dan UDT dalam satu paket memiliki versi yang sama. Package (Paket) versi mengikuti semantik pembuatan versi tanpa level patch dan komponen metadata build. Dalam paket tertentu, bump versi minor menyiratkan versi baru paket tersebut kompatibel dengan versi lama dan paket utama version bump menyiratkan bahwa versi baru paket bukan agar kompatibel dengan paket lama.

Secara konseptual, sebuah paket dapat berhubungan dengan paket lain melalui salah satu dari beberapa cara berikut:

  • Sama sekali tidak menghargai.
  • Ekstensi yang kompatibel dengan versi lama tingkat paket. Ini terjadi peningkatan versi minor baru (revisi yang bertambah berikutnya) dari suatu 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 paket, artinya:
    • Antarmuka tingkat atas dari paket induk ada dalam paket baru, meskipun antarmuka mungkin memiliki metode baru, UDT antarmuka-lokal baru ( ekstensi tingkat antarmuka yang 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 baik oleh metode pembaruan yang baru antarmuka yang ada, atau oleh antarmuka baru.
  • Ekstensi yang kompatibel dengan versi sebelumnya dan kompatibel dengan versi sebelumnya. Yang baru juga dapat memperluas paket asli dengan memisahkan antarmuka yang hanya menyediakan fungsi tambahan, dan bukan inti. Untuk tujuan ini, hal berikut mungkin diinginkan:
    • Antarmuka dalam paket baru memerlukan bantuan untuk tipe data lama paket.
    • Antarmuka dalam paket baru dapat memperluas antarmuka dari satu atau beberapa paket.
  • Memperluas inkompatibilitas mundur asli. Ini adalah peningkatan versi utama dari paket dan tidak perlu ada korelasi antara keduanya. Jika ada, hal itu bisa dinyatakan dengan kombinasi tipe dari paket versi lama, dan pewarisan subset dari antarmuka paket lama.

Struktur antarmuka

Untuk antarmuka yang terstruktur dengan baik, menambahkan tipe fungsi baru yang bukan bagian dari desain asli yang harus memerlukan modifikasi pada HIDL dalam antarmuka berbasis web yang sederhana. Sebaliknya, jika Anda dapat atau berharap untuk membuat perubahan di kedua sisi antarmuka yang memperkenalkan fungsionalitas baru tanpa mengubah antarmuka itu sendiri, maka antarmukanya tidak terstruktur.

Treble mendukung vendor dan komponen sistem yang dikompilasi secara terpisah di mana vendor.img di 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 bekerja selama bertahun-tahun. Hal ini mencakup banyak platform API, tetapi adalah mekanisme IPC yang digunakan HIDL untuk komunikasi antarproses pada system.img/vendor.img batas.

Persyaratan

Semua data yang diteruskan melalui HIDL harus ditentukan secara eksplisit. Untuk memastikan dan klien dapat terus bekerja sama bahkan ketika dikompilasi secara terpisah atau dikembangkan sendiri, data harus mematuhi persyaratan:

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

Jika data buram digunakan, data harus dibaca hanya di satu sisi HIDL dalam antarmuka berbasis web yang sederhana. Misalnya, jika kode vendor.img memberikan komponen pada system.img pesan string atau vec<uint8_t> data, data tersebut tidak dapat diuraikan oleh system.img itu sendiri; perangkat itu bisa hanya diteruskan kembali ke vendor.img untuk ditafsirkan. Jika meneruskan nilai dari vendor.img ke kode vendor di system.img atau ke perangkat lain, format data dan caranya harus diinterpretasikan dengan tepat dan masih merupakan bagian dari antarmuka.

Panduan

Anda seharusnya dapat menulis implementasi atau klien HAL hanya dengan file .hal (misalnya, Anda tidak perlu melihat sumber Android atau standar). Sebaiknya tentukan perilaku yang diperlukan secara persis. Pernyataan seperti sebagai "implementasi mungkin melakukan A atau B" mendorong implementasi untuk menjadi terkait dengan klien yang sedang dikembangkan bersama mereka.

Tata letak kode HIDL

HIDL mencakup paket inti dan vendor.

Antarmuka HIDL inti adalah antarmuka yang ditentukan oleh Google. Paket-paket yang dimilikinya dimulai dengan android.hardware. dan diberi nama berdasarkan subsistem, mungkin dengan tingkat penamaan yang bersarang. Misalnya, paket NFC diberi nama android.hardware.nfc dan paket kameranya 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 dalam versi 3.4; ini adalah penting, karena versi paket mempengaruhi penempatannya dalam hierarki sumber.

Semua paket inti ditempatkan di hardware/interfaces/ dalam sistem build. Paket android.hardware.[name1].[name2]... pada versi $m.$n di bawah hardware/interfaces/name1/name2/.../$m.$n/; paket android.hardware.camera versi 3.4 ada di direktori hardware/interfaces/camera/3.4/. Terdapat pemetaan hard code antara awalan paket android.hardware. dan jalur hardware/interfaces/.

Paket non-inti (vendor) adalah paket yang dihasilkan oleh vendor SoC atau ODM. Tujuan awalan untuk paket non-inti adalah vendor.$(VENDOR).hardware. dengan $(VENDOR)merujuk pada vendor SoC atau OEM/ODM. Ini memetakan ke jalur vendor/$(VENDOR)/interfaces di hierarki (pemetaan ini juga hard code).

Nama jenis buatan pengguna yang sepenuhnya memenuhi syarat

Di HIDL, setiap UDT memiliki nama yang sepenuhnya memenuhi syarat yang terdiri dari nama UDT, nama paket di mana UDT didefinisikan, dan versi paketnya. Tujuan nama yang sepenuhnya memenuhi syarat hanya digunakan ketika {i>instance<i} dari jenis tersebut dinyatakan dan bukan di mana jenis itu sendiri didefinisikan. Misalnya, asumsikan paket android.hardware.nfc, versi 1.0 menentukan struct bernama NfcData. Di lokasi pernyataan (baik di types.hal atau dalam deklarasi antarmuka), deklarasi tersebut hanya menyatakan:

struct NfcData {
    vec<uint8_t> data;
};

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

android.hardware.nfc@1.0::NfcData

{i>Syntax<i} umumnya adalah PACKAGE@VERSION::UDT, dengan:

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

Misalnya, jika deklarasi bertingkat berikut ditentukan dalam mengetik file dalam paket versi android.hardware.example 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 bersarang 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 paket atau tingkat 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, maka setiap nilai jenis enum memiliki nama yang sepenuhnya memenuhi syarat, yang dimulai dengan nama yang sepenuhnya memenuhi syarat dari jenis enum, diikuti oleh titik dua, lalu diikuti dengan nama nilai enum. Misalnya, menggunakan 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

{i>Syntax<i} umumnya adalah PACKAGE@VERSION::UDT:VALUE, dalam hal ini:

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

Aturan inferensi otomatis

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

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

HIDL mencoba melengkapi nama menggunakan aturan gangguan otomatis (aturan lebih rendah angka 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. NfcData juga dicari secara lokal, tetapi seperti tidak ditentukan secara lokal, aturan 2 dan 3 akan digunakan. @1.0::NfcStatus menyediakan versi, jadi 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 itu diisi otomatis dengan informasi dari paket saat ini. Kompilator HIDL kemudian mencari di file saat ini (dan semua impor) untuk menemukan nama yang sepenuhnya memenuhi syarat yang diisi otomatis. Menggunakan contoh di atas, asumsikan deklarasi ExtendedNfcData dibuat dalam paket yang sama (android.hardware.nfc) pada versi (1.0) sebagai NfcData, sebagai berikut:

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

Kompilator HIDL mengisikan 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), paket ini digunakan untuk deklarasi.

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

  • Kolom ini diimpor secara eksplisit dengan pernyataan import.
  • Hal ini ditentukan di types.hal dalam paket saat ini

Proses yang sama diikuti jika NfcData hanya memenuhi syarat oleh 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 ), compiler HIDL memindai kecocokan dalam semua paket yang diimpor. Menggunakan contoh di atas, asumsikan ExtendedNfcData dideklarasikan di versi 1.1 dari 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 menemukan satu di android.hardware.nfc pada versi 1.0, sehingga menghasilkan UDT yang sepenuhnya memenuhi syarat dari android.hardware.nfc@1.0::NfcData. Jika lebih ditemukan lebih dari satu kecocokan untuk UDT yang memenuhi syarat sebagian, kompilator HIDL menampilkan error.

Contoh

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 diinterpolasikan sebagai android.hardware.bar@1.0::S, dan ditemukan di bar/1.0/types.hal (karena types.hal otomatis diimpor).
  • IFooCallback diinterpolasikan sebagai android.hardware.bar@1.0::IFooCallback menggunakan aturan 2, tetapi tidak dapat ditemukan karena bar/1.0/IFooCallback.hal tidak diimpor secara otomatis (sebagaimana types.hal). Jadi, aturan 3 menentukannya menjadi 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 digunakan bersama di antara semua antarmuka yang berpartisipasi dalam paket itu. Jenis HIDL selalu publik; terlepas dari apakah UDT dideklarasikan di types.hal atau dalam deklarasi antarmuka, jenis ini dapat diakses di luar cakupan tempat mereka didefinisikan. types.hal tidak dimaksudkan untuk menjelaskan API publik dari suatu paket, melainkan untuk menghosting UDT digunakan oleh semua antarmuka dalam paket. Karena sifat HIDL, semua UDT merupakan bagian dari antarmuka.

types.hal terdiri dari UDT dan pernyataan import. Karena types.hal tersedia untuk setiap antarmuka (ini adalah impor implisit), pernyataan import ini level paket menurut definisi. UDT di types.hal juga dapat menyertakan UDT, dan antarmuka yang telah 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)
  • Semua yang ada 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 diuraikan, tetapi jenis selain Quuz tidak diimpor).

Pembuatan versi tingkat antarmuka

Setiap antarmuka dalam sebuah paket berada dalam filenya sendiri. Kemasan milik antarmuka, dideklarasikan di bagian atas antarmuka menggunakan atribut Pernyataan package. Setelah deklarasi paket, nol atau beberapa impor tingkat antarmuka (sebagian atau seluruh paket) mungkin dicantumkan. Contoh:

package android.hardware.nfc@1.0;

Dalam HIDL, antarmuka dapat mewarisi dari antarmuka lain menggunakan Kata kunci extends. Agar antarmuka dapat memperluas antarmuka lain, antarmuka itu harus memiliki akses ke aset tersebut melalui pernyataan import. Nama antarmuka yang diperluas (antarmuka dasar) mengikuti aturan untuk type-name kualifikasi yang dijelaskan di atas. Sebuah antarmuka hanya dapat mewarisi dari satu antarmuka; HIDL tidak mendukung lebih dari satu pewarisan.

Contoh pembuatan versi peningkatan 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 peningkatan

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

Aturan A "Is a start minor version": 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 satu pun dari package@major.0 sampai package@major.(minor-2) ditentukan) atau aturan B (jika merupakan peningkatan dari @major.(minor-2));

    DAN,

  2. "Warisi setidaknya satu antarmuka dengan nama yang sama": Ada sebuah 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 pukul @2.1.)
  • Persyaratan "android.hardware.foo@1.0 tidak ditentukan" berarti direktori hardware/interfaces/foo/1.0 pun seharusnya tidak ada.

Namun, aturan A tidak mempengaruhi paket dengan nama paket yang sama tetapi versi utama yang berbeda (misalnya, android.hardware.camera.device memiliki @1.0 dan @3.2 ditentukan; @3.2 tidak perlu berinteraksi dengan @1.0.) Oleh karena itu, @3.2::IExtFoo dapat diperluas @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 perluas android.hardware.baz@2.2::IBaz). Jika antarmuka tidak secara eksplisit mendeklarasikan jenis super dengan kata kunci extend, 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 lulus aturan B.2, jika android.hardware.foo@1.1::IExtBar diperluas android.hardware.foo@1.0::IBar, ini masih bukan peningkatan yang valid.

Antarmuka peningkatan

Untuk meningkatkan android.hardware.example@1.0 (ditentukan 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 level paket dari versi 1.0 android.hardware.example di types.hal. Meskipun tidak ada hal baru UDT ditambahkan dalam versi 1.1 paket, 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 sedang diwariskan (disambiguasi diperlukan karena IQuux digunakan untuk mendeklarasikan antarmuka dan mewarisi dari antarmuka). Ketika deklarasi bersifat nama yang mewarisi semua atribut paket dan versi di situs deklarasi, disambiguasi harus atas nama antarmuka dasar; kami bisa saja menggunakan UDT yang sepenuhnya memenuhi syarat, tapi itu seharusnya redundan.

Antarmuka baru IQuux tidak mendeklarasikan ulang metode fromFooToBar() yang diwarisi dari @1.0::IQuux; cukup mencantumkan metode baru yang ditambahkan fromBarToFoo(). Dalam HIDL, diwariskan metode tidak dapat dideklarasikan lagi dalam antarmuka turunan, sehingga antarmuka IQuux tidak dapat mendeklarasikan fromFooToBar() metode secara eksplisit.

Konvensi peningkatan

Terkadang nama antarmuka harus mengganti nama antarmuka yang diperluas. Saran dari kami bahwa ekstensi enum, {i>struct<i}, dan {i>union<i} memiliki nama yang sama dengan ekstensi kecuali jika keduanya 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 };

Apakah sebuah metode dapat memiliki nama semantik baru (misalnya fooWithLocation) maka pilihan tersebut. Jika tidak, seharusnya dinamai mirip dengan apa yang diperluas. Misalnya, metode foo_1_1 di @1.1::IFoo dapat menggantikan fungsi dari metode foo di @1.0::IFoo jika tidak ada nama alternatif.

Pembuatan versi tingkat paket

Pembuatan versi HIDL terjadi di level paket; setelah paket dipublikasikan, tidak dapat diubah (kumpulan antarmuka dan UDT-nya tidak dapat diubah). Paket dapat berhubungan satu sama lain dalam beberapa cara, yang semuanya dapat diungkapkan melalui kombinasi pewarisan tingkat antarmuka dan pembuatan UDT berdasarkan komposisi.

Namun, satu jenis hubungan ditentukan dengan ketat dan harus ditegakkan: Pewarisan yang kompatibel dengan versi lama di tingkat paket. Dalam skenario ini, paket parent dari paket yang diwarisi dan paket child adalah paket yang memperluas induk. Tingkat paket aturan pewarisan yang kompatibel dengan versi lama adalah sebagai berikut:

  1. Semua antarmuka tingkat atas dari paket induk diwarisi dari antarmuka di paket turunan.
  2. Antarmuka baru juga dapat ditambahkan ke paket baru (tidak ada pembatasan tentang hubungan dengan antarmuka lain dalam paket lain).
  3. Tipe data baru juga dapat ditambahkan untuk digunakan baik oleh metode pembaruan yang baru antarmuka yang ada, atau oleh antarmuka baru.

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

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