Arayüz sürümü oluşturma

HIDL, HIDL'de yazılan her arayüzün sürümlendirilmesini gerektirir. Bir HAL arayüzü yayınlandıktan sonra dondurulur ve daha fazla değişiklik, bu arayüzün yeni bir sürümünde yapılmalıdır. Yayınlanan bir arayüz değiştirilemez ancak başka bir arayüz tarafından genişletilebilir.

HIDL kod yapısı

HIDL kodu, kullanıcı tanımlı türlerde, arayüzlerde ve paketlerde düzenlenir:

  • Kullanıcı tanımlı türler (UDT'ler). HIDL, yapılar, birleştirme işlemleri ve listeleme işlemleri aracılığıyla daha karmaşık türler oluşturmak için kullanılabilecek bir dizi ilkel veri türüne erişim sağlar. UDT'ler arayüz yöntemlerine iletilir ve paket düzeyinde (tüm arayüzlere ortak) veya yerel olarak bir arayüzde tanımlanabilir.
  • Arayüzler. HIDL'nin temel yapı taşları olan arayüzler, UDT ve yöntem beyanlarından oluşur. Arayüzler başka bir arayüzden de miras alabilir.
  • Paketler. İlgili HIDL arayüzlerini ve çalıştıkları veri türlerini düzenler. Paketler bir ad ve sürümle tanımlanır ve şunları içerir:
    • types.hal adlı veri türü tanımı dosyası.
    • Her biri kendi .hal dosyasında bulunan sıfır veya daha fazla arayüz.

Veri türü tanımı dosyası types.hal yalnızca UDT'leri içerir (paket düzeyindeki tüm UDT'ler tek bir dosyada tutulur). Hedef dilde yapılan gösterimler, paketteki tüm arayüzler tarafından kullanılabilir.

Sürüm oluşturma felsefesi

Belirli bir sürüm (1.0 gibi) için yayınlanmış bir HIDL paketi (android.hardware.nfc gibi), değiştirilemez. Paketteki arayüzlerde veya UDT'lerinde yapılan değişiklikler yalnızca başka bir pakette yapılabilir.

HIDL'de sürümlendirme, arayüz düzeyinde değil paket düzeyinde uygulanır ve bir paketteki tüm arayüzler ve UDT'ler aynı sürümü paylaşır. Paket sürümleri, yama düzeyi ve derleme meta verisi bileşenleri olmadan anlamsal sürümlendirmeyi izler. Belirli bir pakette ara sürüm artışı, paketin yeni sürümünün eski paketle geriye dönük uyumlu olduğunu, büyük sürüm artışı ise paketin yeni sürümünün eski paketle geriye dönük uyumlu olmadığını gösterir.

Bir paket, kavramsal olarak başka bir paketle aşağıdaki yöntemlerden biriyle ilişkilendirilebilir:

  • Hiç.
  • Paket düzeyinde geriye dönük uyumlu genişletilebilirlik. Bu durum, bir paketin yeni küçük sürüm yükseltmelerinde (sonraki artımlı düzeltme) görülür. Yeni paket, eski paketle aynı ada ve büyük sürüme sahiptir ancak küçük sürümü daha yüksektir. İşlevsel olarak yeni paket, eski paketin üst kümesidir. Yani:
    • Üst paketin üst düzey arayüzleri yeni pakette bulunur ancak arayüzlerde yeni yöntemler, yeni arayüz yerel UDT'ler (aşağıda açıklanan arayüz düzeyinde uzantı) ve types.hal içinde yeni UDT'ler olabilir.
    • Yeni pakete yeni arayüzler de eklenebilir.
    • Üst paketin tüm veri türleri yeni pakette bulunur ve eski paketteki (muhtemelen yeniden uygulanmış) yöntemler tarafından işlenebilir.
    • Yeni veri türleri, mevcut arayüzlerin güncellenmiş sürümlerindeki yeni yöntemler veya yeni arayüzler tarafından kullanılmak üzere de eklenebilir.
  • Arayüz düzeyinde geriye dönük uyumlu genişletilebilirlik. Yeni paket, temel işlevi değil yalnızca ek işlev sağlayan mantıksal olarak ayrı arayüzlerden oluşarak orijinal paketi de genişletebilir. Bu amaçla aşağıdakiler istenebilir:
    • Yeni paketteki arayüzlerin eski paketin veri türlerine başvurması gerekir.
    • Yeni paketteki arayüzler, bir veya daha fazla eski paketin arayüzlerini genişletebilir.
  • Orijinal geriye dönük uyumsuzluğu genişletin. Bu, paketin büyük sürüm bir ön sürümüdür ve ikisi arasında herhangi bir ilişki olması gerekmez. Varsa paketin eski sürümünden türlerin bir kombinasyonu ve eski paket arayüzlerinin bir alt kümesinin devralınmasıyla ifade edilebilir.

Arayüz yapılandırması

İyi yapılandırılmış bir arayüzde, orijinal tasarımın parçası olmayan yeni işlev türleri eklemek için HIDL arayüzünde bir değişiklik yapılması gerekir. Buna karşılık, arayüzün kendisini değiştirmeden arayüzün her iki tarafında da yeni işlevler sunan bir değişiklik yapabiliyorsanız veya yapmayı bekliyorsanız arayüz yapılandırılmış değildir.

Treble, bir cihazdaki vendor.img ve system.img'ın ayrı ayrı derlenebildiği, ayrı olarak derlenmiş tedarikçi ve sistem bileşenlerini destekler. vendor.img ile system.img arasındaki tüm etkileşimler, uzun yıllar boyunca çalışmaya devam edebilmeleri için açıkça ve ayrıntılı bir şekilde tanımlanmalıdır. Birçok API yüzeyi buna dahildir ancak en önemli yüzey, HIDL'nin system.img/vendor.img sınırında işlemler arası iletişim için kullandığı IPC mekanizmasıdır.

Şartlar

HIDL üzerinden iletilen tüm veriler açıkça tanımlanmalıdır. Bir uygulamanın ve istemcinin ayrı ayrı derlendiğinde veya ayrı olarak geliştirildiğinde bile birlikte çalışmaya devam edebilmesi için verilerin aşağıdaki şartlara uyması gerekir:

  • Anlamlı adlar ve anlamlarla doğrudan HIDL'de (structs enums vb. kullanılarak) açıklanabilir.
  • ISO/IEC 7816 gibi herkese açık bir standartla açıklanabilir.
  • Donanım standardı veya donanımın fiziksel düzeni ile açıklanabilir.
  • Gerekirse opak veriler (ör. herkese açık anahtarlar, kimlikler vb.) olabilir.

Saydam olmayan veriler kullanılıyorsa yalnızca HIDL arayüzünün bir tarafı tarafından okunmalıdır. Örneğin, vendor.img kodu system.img'daki bir bileşene dize mesajı veya vec<uint8_t> verileri verirse bu veriler system.img tarafından ayrıştırılamaz; yalnızca yorumlanması için vendor.img'e geri gönderilebilir. vendor.img'dan system.img'deki tedarikçi koduna veya başka bir cihaza bir değer aktarılırken verilerin biçimi ve nasıl yorumlanacağı tam olarak açıklanmalıdır ve arayüzün bir parçası olmaya devam eder.

Kurallar

Yalnızca .hal dosyalarını kullanarak bir HAL uygulaması veya istemcisi yazabilmeniz gerekir (yani Android kaynağına veya herkese açık standartlara bakmanız gerekmez). Gerekli davranışı tam olarak belirtmenizi öneririz. "Bir uygulama A veya B yapabilir" gibi ifadeler, uygulamaların geliştirildikleri müşterilerle iç içe geçmesini teşvik eder.

HIDL kod düzeni

HIDL, temel ve tedarikçi paketlerini içerir.

Temel HIDL arayüzleri, Google tarafından belirtilen arayüzlerdir. Bu alt sistemlere ait paketler android.hardware. ile başlar ve alt sisteme göre adlandırılır. Bu adlandırma, iç içe yerleştirilmiş adlandırma düzeyleri içerebilir. Örneğin, NFC paketi android.hardware.nfc, kamera paketi ise android.hardware.camera olarak adlandırılır. Genel olarak, temel paketlerin adı android.hardware.[name1].[name2] şeklindedir. HIDL paketlerinin adlarına ek olarak bir sürümü de vardır. Örneğin, android.hardware.camera paketi 3.4 sürümünde olabilir. Bir paketin sürümü, kaynak ağacındaki yerleşimini etkilediği için bu önemlidir.

Tüm temel paketler, derleme sisteminde hardware/interfaces/ altına yerleştirilir. $m.$n sürümüne sahip android.hardware.[name1].[name2]… paketi hardware/interfaces/name1/name2//$m.$n/ altındadır; 3.4 sürümüne sahip android.hardware.camera paketi ise hardware/interfaces/camera/3.4/. dizinindedir. android.hardware. paket ön ekiyle hardware/interfaces/ yolu arasında sabit kodlu bir eşleme vardır.

Temel olmayan (tedarikçi) paketler, SoC tedarikçisi veya ODM tarafından üretilen paketlerdir. Temel olmayan paketlerin ön eki vendor.$(VENDOR).hardware.'tür. Burada $(VENDOR), bir SoC satıcısını veya OEM/ODM'yi ifade eder. Bu, ağaçtaki vendor/$(VENDOR)/interfaces yoluna eşlenir (bu eşleme de sabit kodludur).

Tam nitelikli kullanıcı tanımlı tür adları

HIDL'de her UDT'nin, UDT adından, UDT'nin tanımlandığı paket adından ve paket sürümünden oluşan tam nitelikli bir adı vardır. Tam nitelikli ad, yalnızca türün örnekleri tanımlanırken kullanılır ve türün tanımlandığı yerde kullanılmaz. Örneğin, android.hardware.nfc, paketinin 1.0 sürümünde NfcData adlı bir yapının tanımlandığını varsayalım. Beyan, beyanın yapıldığı yerde (types.hal içinde veya bir arayüzün beyanında) şunu belirtir:

struct NfcData {
    vec<uint8_t> data;
};

Bu türden bir örnek tanımlarken (veri yapısı içinde veya yöntem parametresi olarak) tam nitelikli tür adını kullanın:

android.hardware.nfc@1.0::NfcData

Genel söz dizimi şu şekildedir: PACKAGE@VERSION::UDT. Burada:

  • PACKAGE, HIDL paketinin noktayla ayrılmış adıdır (ör. android.hardware.nfc).
  • VERSION, paketin noktayla ayrılmış ana.altsürüm biçimidir (ör. 1.0).
  • UDT, HIDL UDT'nin noktayla ayrılmış adıdır. HIDL, iç içe yerleştirilmiş UDT'leri desteklediğinden ve HIDL arayüzleri UDT'ler (iç içe yerleştirilmiş bir beyan türü) içerebildiğinden, adlara erişmek için noktalar kullanılır.

Örneğin, android.hardware.example sürümü 1.0 paketindeki ortak tür dosyası için aşağıdaki iç içe yerleştirilmiş beyan tanımlandıysa:

// types.hal
package android.hardware.example@1.0;
struct Foo {
    struct Bar {
        // …
    };
    Bar cheers;
};

Bar için tam nitelikli ad android.hardware.example@1.0::Foo.Bar'dur. İç içe yerleştirilmiş beyan, yukarıdaki paketin yanı sıra IQuux adlı bir arayüzdeyse:

// IQuux.hal
package android.hardware.example@1.0;
interface IQuux {
    struct Foo {
        struct Bar {
            // …
        };
        Bar cheers;
    };
    doSomething(Foo f) generates (Foo.Bar fb);
};

Bar için tam nitelikli ad android.hardware.example@1.0::IQuux.Foo.Bar'dur.

Her iki durumda da Bar, yalnızca Foo tanımının kapsamında Bar olarak atıfta bulunulabilir. Paket veya arayüz düzeyinde, yukarıdaki doSomething yönteminin beyanında olduğu gibi Bar'e Foo:Foo.Bar aracılığıyla başvurmanız gerekir. Alternatif olarak, yöntemi daha ayrıntılı bir şekilde şu şekilde de tanımlayabilirsiniz:

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

Tam nitelikli sıralama değerleri

Bir UDT bir enum türüyse enum türünün her değerinin, enum türünün tam nitelikli adıyla başlayan, ardından iki nokta işareti ve enum değerinin adıyla devam eden tam nitelikli bir adı vardır. Örneğin, android.hardware.nfc, paketinin 1.0 sürümünde NfcStatus bir enum türü tanımlandığını varsayalım:

enum NfcStatus {
    STATUS_OK,
    STATUS_FAILED
};

STATUS_OK için tam nitelikli ad:

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

Genel söz dizimi PACKAGE@VERSION::UDT:VALUE şeklindedir. Burada:

  • PACKAGE@VERSION::UDT, enum türünün tam nitelikli adıyla aynıdır.
  • VALUE, değerin adıdır.

Otomatik çıkarım kuralları

Tam nitelikli bir UDT adının belirtilmesi gerekmez. UDT adında aşağıdakiler güvenli bir şekilde atlanabilir:

  • Paket, ör. @1.0::IFoo.Type
  • Hem paket hem de sürüm (ör. IFoo.Type

HIDL, otomatik girişim kurallarını kullanarak adı tamamlamaya çalışır (düşük kural numarası, daha yüksek öncelik anlamına gelir).

1. Kural

Paket ve sürüm sağlanmazsa yerel ad araması yapılır. Örnek:

interface Nfc {
    typedef string NfcErrorMessage;
    send(NfcData d) generates (@1.0::NfcStatus s, NfcErrorMessage m);
};

NfcErrorMessage yerel olarak aranır ve yukarıdaki typedef bulunur. NfcData da yerel olarak aranır ancak yerel olarak tanımlanmadığı için 2. ve 3. kurallar kullanılır. @1.0::NfcStatus, bir sürüm sağladığından 1. kural geçerli değildir.

2. Kural

1. kural geçersizse ve tam nitelikli adın bir bileşeni eksikse (paket, sürüm veya paket ve sürüm) bileşen, mevcut paketteki bilgilerle otomatik olarak doldurulur. Ardından HIDL derleyici, otomatik olarak doldurulan tam nitelikli adı bulmak için geçerli dosyaya (ve tüm içe aktarma işlemlerine) bakar. Yukarıdaki örneği kullanarak, ExtendedNfcData beyanının NfcData ile aynı pakette (android.hardware.nfc) ve aynı sürümde (1.0) aşağıdaki gibi yapıldığını varsayalım:

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

HIDL derleyicisi, tam nitelikli UDT adını android.hardware.nfc@1.0::NfcData oluşturmak için mevcut paketteki paket adını ve sürüm adını doldurur. Ad, geçerli pakette bulunduğundan (doğru şekilde içe aktarıldığı varsayılarak) beyan için kullanılır.

Mevcut paketteki bir ad yalnızca aşağıdakilerden biri doğruysa içe aktarılır:

  • import ifadesiyle açıkça içe aktarılır.
  • Mevcut pakette types.hal içinde tanımlanmıştır

NfcData yalnızca sürüm numarasına göre uygunsa aynı süreç uygulanır:

struct ExtendedNfcData {
    // autofill the current package name (android.hardware.nfc)
    @1.0::NfcData base;
    // … additional members
};

3. Kural

2. kural eşleşme sağlamazsa (UDT mevcut pakette tanımlanmamışsa) HIDL derleyicisi, içe aktarılan tüm paketlerde eşleşme arar. Yukarıdaki örneği kullanarak ExtendedNfcData'ün android.hardware.nfc paketinin 1.1 sürümünde tanımlandığını, 1.1'ün 1.0'ı gerektiği gibi içe aktardığını (Paket Seviyesinde Uzantılar bölümüne bakın) ve tanımın yalnızca UDT adını belirttiğini varsayalım:

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

Derleyici, NfcData adlı bir UDT arar ve android.hardware.nfc sürüm 1.0'de bir tane bulur. Bu, android.hardware.nfc@1.0::NfcData adlı tam nitelikli bir UDT ile sonuçlanır. Belirli bir kısmen nitelikli UDT için birden fazla eşleşme bulunursa HIDL derleyicisi hata verir.

Örnek

2. kural kullanılarak, mevcut pakette tanımlanan içe aktarılan tür, başka bir paketten içe aktarılan türe tercih edilir:

// 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, android.hardware.bar@1.0::S olarak doldurulur ve types.hal otomatik olarak içe aktarıldığı için bar/1.0/types.hal içinde bulunur.
  • IFooCallback, 2. kural kullanılarak android.hardware.bar@1.0::IFooCallback olarak doldurulur ancak bar/1.0/IFooCallback.hal otomatik olarak içe aktarılmadığı için (types.hal gibi) bulunamaz. Bu nedenle 3. kural, import android.hardware.foo@1.0; aracılığıyla içe aktarılan android.hardware.foo@1.0::IFooCallback olarak çözümler.

types.hal

Her HIDL paketi, söz konusu pakete katılan tüm arayüzler arasında paylaşılan UDT'leri içeren bir types.hal dosyası içerir. HIDL türleri her zaman herkese açıktır. Bir UDT'nin types.hal içinde mi yoksa bir arayüz tanımında mı tanımlandığına bakılmaksızın bu türlere, tanımlandıkları kapsamın dışından erişilebilir. types.hal, bir paketin herkese açık API'sini açıklamak için değil, paketteki tüm arayüzler tarafından kullanılan UDT'leri barındırmak için tasarlanmıştır. HIDL'nin yapısı nedeniyle tüm UDT'ler arayüzün bir parçasıdır.

types.hal, UDT'lerden ve import ifadelerinden oluşur. types.hal, paketin her arayüzüne sunulduğundan (örtülü bir içe aktarma işlemidir) bu import ifadeleri, tanımı gereği paket düzeyindedir. types.hal içindeki UDT'ler, bu şekilde içe aktarılan UDT'leri ve arayüzleri de içerebilir.

Örneğin, IFoo.hal için:

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;

Aşağıdakiler içe aktarılır:

  • android.hidl.base@1.0::IBase (dolaylı olarak)
  • android.hardware.foo@1.0::types (dolaylı olarak)
  • android.hardware.bar@1.0'teki her şey (tüm arayüzler ve types.hal dahil)
  • android.hardware.baz@1.0::types tarihinde types.hal (android.hardware.baz@1.0 içindeki arayüzler içe aktarılmaz)
  • android.hardware.qux@1.0'den IQux.hal ve types.hal
  • android.hardware.quuz@1.0 kaynağından Quuz (Quuz'nin types.hal içinde tanımlandığı varsayılırsa types.hal dosyasının tamamı ayrıştırılır ancak Quuz dışındaki türler içe aktarılmaz).

Arayüz düzeyinde sürüm oluşturma

Bir paketteki her arayüz kendi dosyasında bulunur. Arayüzün ait olduğu paket, package ifadesi kullanılarak arayüzün üst kısmında tanımlanır. Paket beyanının ardından, sıfır veya daha fazla arayüz düzeyinde içe aktarma (kısmi veya paketin tamamı) listelenebilir. Örnek:

package android.hardware.nfc@1.0;

HIDL'de arayüzler, extends anahtar kelimesini kullanarak diğer arayüzlerden miras alabilir. Bir arayüzün başka bir arayüzü genişletebilmesi için import ifadesi aracılığıyla bu arayüze erişmesi gerekir. Genişletilen arayüzün (temel arayüz) adı, yukarıda açıklanan tür adı niteliklendirme kurallarına uyar. Bir arayüz yalnızca bir arayüzden miras alabilir. HIDL birden fazla miras almayı desteklemez.

Aşağıdaki uprev sürümlendirme örnekleri aşağıdaki paketi kullanır:

// 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);
}

Uprev kuralları

package@major.minor paketini tanımlamak için A veya B'nin tamamı doğru olmalıdır:

A Kuralı "Başlangıç alt sürümü mü?": Önceki tüm alt sürümler (package@major.0, package@major.1, …, package@major.(minor-1)) tanımlanmamalıdır.
VEYA
B Kuralı

Aşağıdakilerin tümü doğrudur:

  1. "Önceki küçük sürüm geçerli": package@major.(minor-1) tanımlanmış olmalı ve aynı A kuralını (package@major.0 ile package@major.(minor-2) arasında hiçbiri tanımlanmamışsa) veya B kuralını (@major.(minor-2)'ten önceki bir sürümse) izlemelidir;

    VE

  2. "Aynı ada sahip en az bir arayüzü devralın": package@major.(minor-1)::IFoo'ü genişleten bir package@major.minor::IFoo arayüzü vardır (önceki pakette bir arayüz varsa);

    VE

  3. "Farklı ada sahip devralınan arayüz yok": IBar ve IBaz iki farklı ad olmak kaydıyla package@major.(minor-1)::IBaz'yi genişleten package@major.minor::IBar bulunmamalıdır. Aynı ada sahip bir arayüz varsa package@major.minor::IBar, package@major.(minor-k)::IBar'u, k değeri daha küçük bir IBar bulunmayacak şekilde genişletmelidir.

A kuralı nedeniyle:

  • Paket, herhangi bir küçük sürüm numarasıyla başlayabilir (örneğin, android.hardware.biometrics.fingerprint @2.1 ile başlar).
  • "android.hardware.foo@1.0 tanımlanmadı" koşulu, hardware/interfaces/foo/1.0 dizininin hiç mevcut olmaması gerektiği anlamına gelir.

Ancak A kuralı, aynı paket adına sahip ancak farklı bir büyük sürüme sahip bir paketi etkilemez (örneğin, android.hardware.camera.device hem @1.0 hem de @3.2'i tanımlamıştır; @3.2'in @1.0 ile etkileşim kurması gerekmez). Bu nedenle @3.2::IExtFoo, @1.0::IFoo'i genişletebilir.

Paket adı farklı olduğunda package@major.minor::IBar, farklı ada sahip bir arayüzden genişleyebilir (örneğin, android.hardware.bar@1.0::IBar, android.hardware.baz@2.2::IBaz'yi genişletebilir). Bir arayüz, extend anahtar kelimesiyle açıkça bir süper tür tanımlamazsa android.hidl.base@1.0::IBase'yi genişletir (IBase hariç).

B.2 ve B.3 aynı anda uygulanmalıdır. Örneğin, B.2 kuralını karşılamak için android.hardware.foo@1.1::IFoo, android.hardware.foo@1.0::IFoo'yi genişletse bile android.hardware.foo@1.1::IExtBar, android.hardware.foo@1.0::IBar'ı genişletiyorsa bu yine de geçerli bir uprev değildir.

Uprev arayüzleri

android.hardware.example@1.0'ü (yukarıda tanımlanmıştır) @1.1 olarak güncellemek için:

// 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);
}

Bu, types.hal'daki android.hardware.example'nin 1.0 sürümünün paket düzeyinde bir import'sidir. Paketin 1.1 sürümüne yeni UDT eklenmemiştir ancak 1.0 sürümündeki UDT'lere referanslara hâlâ ihtiyaç vardır. Bu nedenle types.hal sürümünde paket düzeyinde içe aktarma işlemi gerçekleştirilmiştir. (IQuux.hal'te arayüz düzeyinde bir içe aktarma işlemiyle de aynı etki elde edilebilir.)

IQuux beyanında extends @1.0::IQuux içinde, devralınan IQuux sürümünü belirttik (IQuux bir arayüzü beyan etmek ve bir arayüzden devralmak için kullanıldığı için netleştirme gereklidir). Beyanlar, beyanın yapıldığı sitedeki tüm paket ve sürüm özelliklerini devralan adlar olduğundan, anlamlandırma, temel arayüzün adında olmalıdır. Tam nitelikli UDT'yi de kullanabilirdik ancak bu gereksiz olurdu.

Yeni arayüz IQuux, @1.0::IQuux sınıfından devraldığı fromFooToBar() yöntemini yeniden tanımlamaz. Yalnızca eklediği yeni yöntemi fromBarToFoo() listeler. HIDL'de devralınan yöntemler alt arayüzlerde tekrar beyan edilemez. Bu nedenle IQuux arayüzü, fromFooToBar() yöntemini açıkça beyan edemez.

Uprev kuralları

Bazen arayüz adları, genişleyen arayüzü yeniden adlandırmalıdır. Yeni bir ad gerektirecek kadar farklı olmadıkları sürece enum uzantılarının, yapıların ve birliklerin, genişlettikleri öğeyle aynı ada sahip olmasını öneririz. Örnekler:

// 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 };

Bir yöntemin yeni bir semantik adı varsa (örneğin, fooWithLocation) bu tercih edilir. Aksi takdirde, genişlettiği öğeye benzer şekilde adlandırılmalıdır. Örneğin, daha iyi bir alternatif ad yoksa @1.1::IFoo içindeki foo_1_1 yöntemi, @1.0::IFoo içindeki foo yönteminin işlevini değiştirebilir.

Paket düzeyinde sürüm oluşturma

HIDL sürümlendirmesi paket düzeyinde gerçekleşir; bir paket yayınlandıktan sonra değiştirilemez (arayüz ve UDT kümesi değiştirilemez). Paketler birbirleriyle çeşitli şekillerde ilişkilendirilebilir. Bu ilişkilendirmelerin tümü, arayüz düzeyinde devralma ve UDT'lerin bileşime göre oluşturulmasının bir kombinasyonuyla ifade edilebilir.

Ancak bir ilişki türü kesinlikle tanımlanır ve zorunlu kılınmalıdır: Paket düzeyinde geriye dönük uyumlu miras alma. Bu senaryoda, üst paket, devralınan pakettir ve alt paket, üst paketi genişleten pakettir. Paket düzeyinde geriye dönük uyumlu devralma kuralları aşağıdaki gibidir:

  1. Üst paketin tüm üst düzey arayüzleri, alt paketteki arayüzler tarafından devralınır.
  2. Yeni pakete yeni arayüzler de eklenebilir (diğer paketlerdeki diğer arayüzler arasındaki ilişkilerle ilgili herhangi bir kısıtlama yoktur).
  3. Yeni veri türleri, mevcut arayüzlerin güncellenmiş sürümlerindeki yeni yöntemler veya yeni arayüzler tarafından kullanılmak üzere de eklenebilir.

Bu kurallar, HIDL arayüz düzeyinde devralma ve UDT derlemesi kullanılarak uygulanabilir ancak bu ilişkilerin geriye dönük uyumlu bir paket uzantısı oluşturduğunu bilmek için meta düzeyinde bilgi gerekir. Bu bilgiler aşağıdaki şekilde çıkarılır:

Bir paket bu koşulu karşılıyorsa hidl-gen geriye dönük uyumluluk kurallarını uygular.