Arayüzler ve paketler

HIDL, davranışları tanımlamak için nesne yönelimli dillerde kullanılan soyut bir tür olan arayüzler etrafında oluşturulur. Her arayüz bir paketin parçasıdır.

Paketler

Paket adlarında package.subpackage gibi alt düzeyler olabilir. Yayınlanan HIDL paketlerinin kök dizini hardware/interfaces veya vendor/vendorName'dır (ör. Pixel cihazlar için vendor/google). Paket adı, kök dizin altında bir veya daha fazla alt dizin oluşturur. Bir paketi tanımlayan tüm dosyalar aynı dizindedir. Örneğin, package android.hardware.example.extension.light@2.0, hardware/interfaces/example/extension/light/2.0 altında bulunabilir.

Aşağıdaki tabloda paket ön ekleri ve konumları listelenmiştir:

Paket ön eki Konum Arayüz türleri
android.hardware.* hardware/interfaces/* HAL
android.frameworks.* frameworks/hardware/interfaces/* çerçeveler/ ilgili
android.system.* system/hardware/interfaces/* sistem/ ilgili
android.hidl.* system/libhidl/transport/* core

Paket dizini, .hal uzantılı dosyalar içeriyor. Her dosya, paketin ve dosyanın parçası olduğu sürümün adını belirten bir package ifadesi içermelidir. Mevcutsa types.hal dosyası bir arayüz tanımlamaz, bunun yerine paketteki her arayüzün erişebileceği veri türlerini tanımlar.

Arayüz tanımı

types.hal dışındaki tüm .hal dosyaları bir arayüz tanımlar. Arayüz genellikle aşağıdaki şekilde tanımlanır:

interface IBar extends IFoo { // IFoo is another interface
    // embedded types
    struct MyStruct {/*...*/};

    // interface methods
    create(int32_t id) generates (MyStruct s);
    close();
};

Açık bir extends beyanı olmayan bir arayüz, android.hidl.base@1.0::IBase'ten dolaylı olarak genişler (Java'daki java.lang.Object'ye benzer). IBase arayüzü, dolaylı olarak içe aktarılır ve kullanıcı tanımlı arayüzlerde yeniden tanımlanmaması veya başka şekilde kullanılmaması gereken çeşitli ayrılmış yöntemler tanımlar. Bu yöntemler şunlardır:

  • ping
  • interfaceChain
  • interfaceDescriptor
  • notifySyspropsChanged
  • linkToDeath
  • unlinkToDeath
  • setHALInstrumentation
  • getDebugInfo
  • debug
  • getHashChain

İçe aktarma işlemi

import ifadesi, başka bir paketteki paket arayüzlerine ve türlerine erişmek için kullanılan HIDL mekanizmasıdır. import ifadesi iki öğeyle ilgilidir:

  • Paket veya arayüz olabilen içe aktarma varlığı
  • Paket veya arayüz olabilen içe aktarılan öğe

İçe aktaran varlık, import ifadesinin konumuna göre belirlenir. İfade bir paketin types.hal içinde olduğunda, içe aktarılan öğe paketin tamamı tarafından görülebilir. Bu, paket düzeyinde bir içe aktarma işlemidir. İfade bir arayüz dosyasının içindeyse içe aktarıcı varlık arayüzün kendisidir; bu, arayüz düzeyinde bir içe aktarma işlemidir.

İçe aktarılan öğe, import anahtar kelimeden sonraki değere göre belirlenir. Değerin tam nitelikli bir ad olması gerekmez. Atlanan bir bileşen, geçerli paketteki bilgilerle otomatik olarak doldurulur. Tam nitelikli değerler için aşağıdaki içe aktarma durumları desteklenir:

  • Paketlerin tamamını içe aktarma. Değer bir paket adı ve sürümüyse (aşağıda açıklanan söz dizimi) paketin tamamı içe aktarıcı öğeye aktarılır.
  • Kısmi içe aktarma işlemleri. Değer:
    • Bir arayüz, paketin types.hal ve bu arayüz içe aktarıcı öğeye aktarılır.
    • types.hal içinde tanımlanan bir UDT, ardından yalnızca bu UDT içe aktaran öğeye aktarılır (types.hal'teki diğer türler içe aktarılmaz).
  • Yalnızca türleri içe aktarma Değer, yukarıda açıklanan kısmi içe aktarma söz dizimini kullanıyorsa ancak arayüz adı yerine types anahtar kelimesi kullanılıyorsa yalnızca belirtilen paketin types.hal bölümündeki UDT'ler içe aktarılır.

İçe aktaran varlık, aşağıdakilerin bir kombinasyonuna erişir:

  • İçe aktarılan paketin types.hal içinde tanımlanan ortak UDT'leri;
  • İçe aktarılan paketin arayüzleri (tüm paketi içe aktarmak için) veya belirtilen arayüz (kısmi içe aktarma için) çağrılmak, onlara tutamak aktarmak ve/veya onlardan devralmak için.

İçe aktarma ifadesi, içe aktarılan paketin veya arayüzün adını ve sürümünü sağlamak için tam nitelikli tür adını kullanır:

import android.hardware.nfc@1.0;            // import a whole package
import android.hardware.example@1.0::IQuux; // import an interface and types.hal
import android.hardware.example@1.0::types; // import just types.hal

Arabirim devralma

Bir arayüz, daha önce tanımlanmış bir arayüzün uzantısı olabilir. Uzantılar aşağıdaki üç türden biri olabilir:

  • Arayüz, API'sini değiştirmeden başka bir arayüze işlev ekleyebilir.
  • Paket, API'sini değiştirmeden başka bir pakete işlev ekleyebilir.
  • Arayüz, türleri bir paketten veya belirli bir arayüzden içe aktarabilir.

Bir arayüz yalnızca bir başka arayüzü genişletebilir (birden fazla miras alma olmaz). Sıfır olmayan küçük sürüm numarasına sahip bir paketteki her arayüz, paketin önceki sürümündeki bir arayüzü genişletmelidir. Örneğin, derivative paketinin 4.0 sürümündeki bir IBar arayüzü, original paketinin 1.2 sürümündeki bir IFoo arayüzünü temel alıyorsa (IFoo arayüzünü genişletiyorsa) ve original paketinin 1.3 sürümü oluşturulursa IBar 4.1 sürümü, IFoo 1.3 sürümünü genişletemez. Bunun yerine, IBar 4.1 sürümü, IFoo 1.2 sürümüne bağlı olan IBar 4.0 sürümünü genişletmelidir. IBar 5.0 sürümü, istenirse IFoo 1.3 sürümünü genişletebilir.

Arayüz uzantıları, oluşturulan koda kitaplık bağımlılığı veya HAL'ler arası dahil etme anlamına gelmez. Yalnızca veri yapısını ve yöntem tanımlarını HIDL düzeyinde içe aktarır. Bir HAL'deki her yöntem, ilgili HAL'de uygulanmalıdır.

Tedarikçi uzantıları

Bazı durumlarda tedarikçi uzantıları, genişlettikleri temel arayüzü temsil eden temel nesnenin alt sınıfı olarak uygulanır. Aynı nesne, temel HAL adı ve sürümü ile uzantının (tedarikçi) HAL adı ve sürümü altında kaydedilir.

Sürüm oluşturma

Paketler sürümlere sahiptir ve arayüzler, paketlerinin sürümüne sahiptir. Sürümler, ana.ara şeklinde iki tam sayı ile ifade edilir.

  • Büyük sürümler geriye dönük uyumlu değildir. Ana sürüm numarasını artırdığınızda alt sürüm numarası 0'a sıfırlanır.
  • Alt sürümler geriye dönük uyumludur. Alt sürüm numarasının artırılması, yeni sürümün önceki sürümle tamamen geriye dönük uyumlu olduğunu gösterir. Yeni veri yapıları ve yöntemler eklenebilir ancak mevcut veri yapıları veya yöntem imzaları değiştirilemez.

Bir HAL'in birden fazla ana veya küçük sürümü aynı anda bir cihazda bulunabilir. Ancak önceki bir alt sürüm arayüzüyle çalışan istemci kodu, aynı arayüzün sonraki alt sürümleriyle de çalıştığından büyük sürüm yerine alt sürüm tercih edilmelidir. Sürüm oluşturma ve tedarikçi uzantıları hakkında daha fazla bilgi için HIDL Sürüm Oluşturma başlıklı makaleyi inceleyin.

Arayüz düzeni özeti

Bu bölümde, HIDL arayüz paketinin (hardware/interfaces gibi) nasıl yönetileceği özetlenmiştir ve HIDL bölümünde sunulan bilgiler birleştirilmiştir. Bu makaleyi okumadan önce HIDL sürümlendirme, hidl-gen ile karma oluşturma kavramları, genel olarak HIDL ile çalışma ile ilgili ayrıntılar ve aşağıdaki tanımlar hakkında bilgi sahibi olduğunuzdan emin olun:

Terim Tanım
Uygulama İkili Arabirimi (ABI) Uygulama programlama arayüzü ve gerekli tüm ikili bağlantılar.
tam nitelikli ad (fqName) Bir hidl türünü ayırt etmek için kullanılan ad. Örnek: android.hardware.foo@1.0::IFoo.
paket HIDL arayüzü ve türleri içeren paket. Örnek: android.hardware.foo@1.0.
paket kökü HIDL arayüzlerini içeren kök paket. Örnek: HIDL arayüzüandroid.hardware, paket kökündeandroid.hardware.foo@1.0 bulunur.
paket kök yolu Android kaynak ağacında bir paket kökünün eşlendiği konum.

Daha fazla tanım için HIDL terminolojisine bakın.

Her dosya, paket kök haritalama ve tam nitelikli adından bulunabilir.

Paket kökleri, bağımsız değişken olarak hidl-gen için belirtilir-r android.hardware:hardware/interfaces. Örneğin, paket vendor.awesome.foo@1.0::IFoo ise ve hidl-gen -r vendor.awesome:some/device/independent/path/interfaces gönderiliyorsa arayüz dosyası $ANDROID_BUILD_TOP/some/device/independent/path/interfaces/foo/1.0/IFoo.hal içinde olmalıdır.

Uygulamada, awesome adlı bir tedarikçinin veya OEM'nin standart arayüzlerini vendor.awesome içine yerleştirmesi önerilir. Bir paket yolu seçildikten sonra, arayüzün ABI'sine yerleştirildiği için değiştirilmemelidir.

Paket yolu eşlemesi benzersiz olmalıdır

Örneğin, -rsome.package:$PATH_A ve -rsome.package:$PATH_B değerleriniz varsa tutarlı bir arayüz dizini için $PATH_A, $PATH_B değerine eşit olmalıdır (bu, arayüz sürümlerini belirlemeyi de çok daha kolaylaştırır).

Paket kökünde bir sürüm oluşturma dosyası olmalıdır

-r vendor.awesome:vendor/awesome/interfaces gibi bir paket yolu oluşturursanız hidl-gen'daki -Lhash seçeneği kullanılarak oluşturulan arayüz karma oluşturma işlemlerini içeren $ANDROID_BUILD_TOP/vendor/awesome/interfaces/current.txt dosyasını da oluşturmanız gerekir (bu konu hidl-gen ile karma oluşturma bölümünde ayrıntılı olarak ele alınmıştır).

Arabirimler, cihazdan bağımsız konumlara yerleştirilir.

Uygulamada, arayüzleri şubeler arasında paylaşmanızı öneririz. Bu sayede, farklı cihazlarda ve kullanım alanlarında kodun yeniden kullanımı ve test edilmesi en üst düzeye çıkarılır.