Google berkomitmen untuk mendorong terwujudnya keadilan ras bagi komunitas Kulit Hitam. Lihat caranya.
Halaman ini diterjemahkan oleh Cloud Translation API.
Switch to English

Pembuatan Versi

HIDL mengharuskan setiap antarmuka yang ditulis dalam HIDL diversi. Setelah antarmuka HAL diterbitkan, itu dibekukan dan perubahan lebih lanjut harus dilakukan ke versi baru dari antarmuka itu. Meskipun antarmuka yang diterbitkan tidak dapat dimodifikasi, itu dapat diperpanjang dengan antarmuka lain.

Struktur kode HIDL

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

  • Jenis yang ditentukan pengguna (UDT) . HIDL menyediakan akses ke sekumpulan tipe data primitif yang dapat digunakan untuk membuat tipe yang lebih kompleks melalui struktur, unions, dan enumeration. UDT diteruskan ke metode antarmuka, dan dapat didefinisikan pada tingkat paket (umum untuk semua antarmuka) atau secara lokal ke antarmuka.
  • Antarmuka . Sebagai blok bangunan dasar HIDL, antarmuka terdiri dari UDT dan deklarasi metode. Antarmuka juga dapat diturunkan dari antarmuka lain.
  • Paket . Mengatur antarmuka HIDL terkait dan tipe data tempat mereka beroperasi. Paket diidentifikasi dengan nama dan versi dan mencakup berikut ini:
    • File definisi tipe data disebut types.hal .
    • Nol atau lebih antarmuka, masing-masing dalam file .hal mereka sendiri.

File definisi tipe 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; itu tidak bisa diubah. Modifikasi antarmuka dalam paket atau perubahan apa pun pada UDT-nya hanya dapat dilakukan di paket lain .

Di HIDL, pembuatan versi berlaku pada tingkat paket, bukan pada tingkat antarmuka, dan semua antarmuka dan UDT dalam sebuah paket memiliki versi yang sama. Versi paket mengikuti pembuatan versi semantik tanpa level patch dan komponen build-metadata. Di dalam paket tertentu, tonjolan versi kecil menyiratkan bahwa versi baru dari paket itu kompatibel dengan paket lama dan versi utama menyiratkan versi baru paket tidak kompatibel dengan versi lama.

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

  • Tidak sama sekali .
  • Ekstensibilitas kompatibel mundur tingkat paket . Ini terjadi untuk uprev versi minor baru (revisi bertahap berikutnya) dari sebuah paket; paket baru memiliki nama dan versi mayor yang sama dengan paket lama, tetapi versi minor yang lebih tinggi. Secara fungsional, paket baru merupakan superset dari paket lama, artinya:
    • Antarmuka tingkat atas dari paket induk ada dalam paket baru, meskipun antarmuka mungkin memiliki metode baru, UDT lokal antarmuka 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 di paket baru dan bisa ditangani oleh metode (mungkin diimplementasikan kembali) dari paket lama.
    • Tipe data baru juga dapat ditambahkan untuk digunakan baik dengan metode baru dari antarmuka yang ada, atau dengan antarmuka baru.
  • Ekstensibilitas kompatibel-mundur tingkat antarmuka . Paket baru juga dapat memperluas paket asli dengan terdiri dari antarmuka yang terpisah secara logis yang hanya menyediakan fungsionalitas tambahan, dan bukan yang inti. Untuk tujuan ini, yang berikut mungkin diinginkan:
    • Antarmuka dalam paket baru membutuhkan bantuan ke tipe data dari paket lama.
    • Antarmuka dalam paket baru dapat memperluas antarmuka dari satu atau lebih paket lama.
  • Perpanjang ketidakcocokan ke belakang asli . Ini adalah uprev versi mayor dari paket dan tidak perlu ada korelasi antara keduanya. Sejauh yang ada, itu dapat diekspresikan dengan kombinasi tipe dari versi paket yang lebih lama, dan pewarisan subset dari antarmuka paket lama.

Antarmuka penataan

Untuk antarmuka yang terstruktur dengan baik, menambahkan jenis fungsionalitas baru yang bukan bagian dari desain asli memerlukan modifikasi pada antarmuka HIDL. Sebaliknya, jika Anda dapat atau mengharapkan untuk membuat perubahan di kedua sisi antarmuka yang memperkenalkan fungsionalitas baru tanpa mengubah antarmuka itu sendiri, maka antarmuka 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 mereka 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 bahkan ketika disusun secara terpisah atau dikembangkan secara independen, data harus mematuhi persyaratan berikut:

  • Dapat dijelaskan dalam HIDL secara langsung (menggunakan enum struct, dll.) Dengan nama dan arti semantik.
  • Dapat dijelaskan oleh standar publik seperti ISO / IEC 7816.
  • Dapat dijelaskan dengan standar perangkat keras atau tata letak fisik perangkat keras.
  • Dapat berupa data buram (seperti kunci publik, id, dll.) Jika perlu.

Jika data buram digunakan, data tersebut harus dibaca hanya di satu sisi antarmuka HIDL. Misalnya, jika kode vendor.img memberikan sebuah komponen pada system.img sebuah pesan string atau vec<uint8_t> data, data tersebut tidak dapat diurai oleh system.img itu sendiri; itu hanya dapat dikirimkan 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 harus dapat menulis implementasi atau klien HAL hanya dengan menggunakan file .hal (yaitu, Anda tidak perlu melihat sumber Android atau standar publik). Kami menyarankan Anda untuk menentukan perilaku yang dibutuhkan secara tepat. Pernyataan seperti "implementasi dapat dilakukan A atau B" mendorong implementasi menjadi terkait dengan klien yang dikembangkan.

Tata letak kode HIDL

HIDL mencakup paket inti dan vendor.

Antarmuka HIDL inti adalah yang ditentukan oleh Google. Paket milik mereka dimulai dengan android.hardware. dan diberi nama oleh subsistem, berpotensi dengan tingkat penamaan yang bertingkat. Misalnya, paket NFC dinamai android.hardware.nfc dan paket kamera adalah 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 ada di versi 3.4 ; ini penting, karena versi paket memengaruhi 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/ hardware/interfaces/name1/name2/ /$m.$n/ 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 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 vendor/$(VENDOR)/interfaces jalur vendor/$(VENDOR)/interfaces di pohon (pemetaan ini juga memiliki kode 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 tempat UDT ditentukan, dan versi paket. Nama yang sepenuhnya memenuhi syarat hanya digunakan jika contoh dari tipe dideklarasikan dan bukan di mana tipe itu sendiri ditentukan. Misalnya, asumsikan paket android.hardware.nfc, versi 1.0 mendefinisikan sebuah struct bernama NfcData . Di situs deklarasi (baik di 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 memenuhi syarat:

android.hardware.nfc@1.0::NfcData

Sintaks umumnya adalah PACKAGE @ VERSION :: UDT , di mana:

  • PACKAGE adalah name dot-dipisahkan dari sebuah package HIDL (misalnya, android.hardware.nfc ).
  • VERSION adalah format versi mayor.minor yang dipisahkan titik dari paket (misalnya, 1.0 ).
  • UDT adalah nama yang dipisahkan titik dari HIDL UDT. Karena HIDL mendukung UDT bersarang dan antarmuka HIDL dapat berisi UDT (jenis deklarasi bersarang), titik digunakan untuk mengakses nama.

Misalnya, jika deklarasi bersarang berikut ditentukan 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 dalam paket di atas, deklarasi bersarang ada dalam 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 dapat disebut sebagai Bar hanya dalam lingkup deklarasi Foo . Pada tingkat paket atau antarmuka, Anda harus merujuk ke Bar melalui Foo : Foo.Bar , seperti dalam deklarasi metode doSomething atas. Atau, Anda dapat mendeklarasikan metode ini secara lebih verbal sebagai:

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

Nilai pencacahan yang sepenuhnya memenuhi syarat

Jika UDT adalah jenis enum, maka setiap nilai jenis enum memiliki nama yang sepenuhnya memenuhi syarat yang dimulai dengan nama jenis 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 , di mana:

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

Aturan inferensi otomatis

Nama UDT yang sepenuhnya memenuhi syarat tidak perlu ditentukan. Nama UDT dapat dengan aman menghilangkan berikut ini:

  • Paketnya, misalnya @1.0::IFoo.Type
  • Baik paket maupun versinya, misalnya IFoo.Type

HIDL mencoba melengkapi nama menggunakan aturan interferensi otomatis (nomor aturan lebih rendah berarti prioritas lebih tinggi).

Aturan 1

Jika tidak ada paket dan versi yang disediakan, 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 didefinisikan 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 dari nama yang sepenuhnya memenuhi syarat hilang (paket, versi, atau paket dan versi), komponen tersebut akan diisi otomatis dengan informasi dari paket saat ini. Kompiler HIDL kemudian mencari di file saat ini (dan semua impor) untuk menemukan nama memenuhi syarat yang diisi otomatis. 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
};

Kompilator 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 ada di paket saat ini (dengan asumsi itu diimpor dengan benar), itu digunakan untuk deklarasi.

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

  • Itu diimpor secara eksplisit dengan pernyataan import .
  • Ini didefinisikan dalam types.hal dalam paket saat ini

Proses yang sama diikuti jika NfcData hanya memenuhi syarat dengan 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), kompilator HIDL 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 impor 1.0 sebagaimana mestinya (lihat Ekstensi Tingkat Paket ), dan definisi tersebut hanya menetapkan nama UDT:

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

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

Contoh

Menggunakan aturan 2, jenis impor 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 diimpor secara otomatis).
  • 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 ). Jadi, aturan 3 menyelesaikannya 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 berisi UDT yang dibagikan 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, tipe ini dapat diakses di luar cakupan tempat mereka didefinisikan. types.hal tidak dimaksudkan untuk mendeskripsikan API publik suatu paket, melainkan untuk menghosting UDT yang digunakan oleh semua antarmuka dalam paket tersebut. 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 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;

Yang berikut ini 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 dan types.hal - types.hal )
  • 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 didefinisikan di types.hal , seluruh file types.hal diurai, tetapi jenis selain Quuz tidak diimpor).

Pembuatan versi tingkat antarmuka

Setiap antarmuka dalam sebuah paket berada di filenya sendiri. Paket yang dimiliki antarmuka dideklarasikan di bagian atas antarmuka menggunakan pernyataan package . Setelah deklarasi paket, nol atau lebih impor tingkat antarmuka (sebagian atau seluruh paket) dapat dicantumkan. Contoh:

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 sana melalui pernyataan import . Nama antarmuka yang diperluas (antarmuka dasar) mengikuti aturan untuk kualifikasi nama jenis yang dijelaskan di atas. Sebuah antarmuka hanya dapat mewarisi dari satu antarmuka; HIDL tidak mendukung multiple inheritance.

Contoh 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 uprev

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

Aturan A "Apakah awal versi minor": Semua versi sebelumnya minor, package@major.0 , package@major.1 , ..., package@major.(minor-1) Tidak harus didefinisikan.
ATAU
Aturan B

Semua hal berikut ini 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 itu adalah uprev dari @major.(minor-2) );

    DAN

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

    DAN

  3. "Tidak ada antarmuka yang diwariskan dengan nama berbeda": Tidak boleh ada package@major.minor::IBar yang memperluas package@major.(minor-1)::IBaz , di mana 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 pada @2.1 .)
  • Persyaratan " android.hardware.foo@1.0 tidak ditentukan" berarti direktori hardware/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 memiliki definisi @1.0 dan @3.2 ; @3.2 tidak perlu berinteraksi dengan @1.0 .) Karenanya, @3.2::IExtFoo dapat memperpanjang @1.0::IFoo .

Asalkan nama paket berbeda, package@major.minor::IBar dapat diperluas dari antarmuka dengan nama berbeda (misalnya, android.hardware.bar@1.0::IBar dapat memperpanjang android.hardware.baz@2.2::IBaz ). Jika sebuah antarmuka tidak secara eksplisit mendeklarasikan tipe super dengan kata kunci extend , itu akan memperpanjang android.hidl.base@1.0::IBase (kecuali IBase itu sendiri).

B.2 dan B.3 harus diikuti pada waktu yang 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 yang meningkat

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

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

Antarmuka baru IQuux tidak mendeklarasikan ulang metode fromFooToBar() yang diwarisi dari @1.0::IQuux ; itu hanya mencantumkan metode baru yang ditambahkannya fromBarToFoo() . Dalam HIDL, metode yang diwariskan tidak boleh dideklarasikan lagi di antarmuka anak, sehingga antarmuka IQuux tidak dapat mendeklarasikan metode fromFooToBar() secara eksplisit.

Konvensi uprev

Terkadang nama antarmuka harus mengganti nama antarmuka perluasan. Kami merekomendasikan bahwa ekstensi enum, struct, dan unions memiliki nama yang sama dengan yang mereka perpanjang kecuali mereka 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 suatu metode dapat memiliki nama semantik baru (misalnya fooWithLocation ) maka itu lebih disukai. Jika tidak, itu harus diberi nama yang mirip dengan apa yang diperluas. Misalnya, metode foo_1_1 di @1.1::IFoo dapat menggantikan fungsionalitas 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 sebuah paket diterbitkan, itu tidak dapat diubah (kumpulan antarmuka dan UDT-nya tidak dapat diubah). Paket dapat berhubungan satu sama lain dalam beberapa cara, yang semuanya dapat diekspresikan melalui kombinasi pewarisan tingkat antarmuka dan pembuatan UDT berdasarkan komposisi.

Namun, satu jenis hubungan ditentukan secara ketat dan harus diterapkan: Warisan kompatibel mundur tingkat paket . Dalam skenario ini, paket orangtua adalah paket yang diwarisi dari dan paket anak adalah salah satu memperluas orangtua. Aturan pewarisan yang kompatibel dengan mundur tingkat paket adalah sebagai berikut:

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

Aturan ini dapat diterapkan 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 sebuah paket memenuhi persyaratan ini, hidl-gen memberlakukan aturan kompatibilitas mundur.