HAL'ler için AIDL

Android 11, Android'deki HAL'ler için AIDL kullanma olanağı sunarak Android'in bazı bölümlerini HIDL olmadan uygulamayı mümkün kılar. Mümkün olduğunda (yukarı akış HAL'leri HIDL kullanıyorsa HIDL kullanılmalıdır) HAL'leri yalnızca AIDL kullanacak şekilde geçirin.

system.img gibi çerçeve bileşenleri ile vendor.img gibi donanım bileşenleri arasında iletişim kurmak için AIDL kullanan HAL'ler, kararlı AIDL kullanmalıdır. Ancak bir bölüm içinde (ör. bir HAL'den diğerine) iletişim kurmak için kullanılacak IPC mekanizmasıyla ilgili bir kısıtlama yoktur.

Motivasyon

AIDL, HIDL'den daha uzun süredir kullanılmaktadır ve Android çerçeve bileşenleri arasında veya uygulamalarda olduğu gibi birçok başka yerde de kullanılır. AIDL artık kararlılık desteğine sahip olduğundan tek bir IPC çalışma zamanıyla tüm yığını uygulamak mümkündür. AIDL, HIDL'den daha iyi bir sürüm oluşturma sistemine de sahiptir. AIDL'nin bazı avantajları şunlardır:

  • Tek bir IPC dili kullanmak, öğrenilecek, hata ayıklanacak, optimize edilecek ve güvenliği sağlanacak tek bir şey olduğu anlamına gelir.
  • AIDL, arayüz sahipleri için yerinde sürüm oluşturmayı destekler:
    • Sahipler, arayüzlerin sonuna yöntemler veya parcelable'lara alanlar ekleyebilir. Bu sayede, yıllar içinde kodun sürümünü oluşturmak kolaylaşır ve yıllık maliyet de düşer (türler yerinde değiştirilebilir ve her arayüz sürümü için ek kitaplıklara gerek yoktur).
    • Uzantı arayüzleri, tür sisteminde değil çalışma zamanında eklenebilir. Bu nedenle, alt akış uzantılarını arayüzlerin daha yeni sürümlerine yeniden temel almaya gerek yoktur.
  • Sahibi kararlı hale getirmeyi seçtiğinde mevcut bir AIDL arayüzü doğrudan kullanılabilir. Daha önce, arayüzün tamamının HIDL'de oluşturulması gerekiyordu.

AIDL çalışma zamanına göre derleme

AIDL'nin üç farklı arka ucu vardır: Java, NDK ve CPP. Kararlı AIDL'yi kullanmak için her zaman libbinder öğesinin system/lib*/libbinder.so konumundaki sistem kopyasını kullanın ve /dev/binder üzerinde konuşun. vendor resmindeki kod için bu, libbinder (VNDK'dan) kullanılamaz demektir: Bu kitaplığın kararsız bir C++ API'si ve kararsız dahili bileşenleri vardır. Bunun yerine, yerel tedarikçi kodu AIDL'nin NDK arka ucunu kullanmalı, libbinder_ndk'ya (sistem libbinder.so tarafından desteklenir) ve aidl_interface girişleri tarafından oluşturulan NDK kitaplıklarına karşı bağlantı oluşturmalıdır. Tam modül adları için Modül adlandırma kuralları başlıklı makaleyi inceleyin.

AIDL HAL arayüzü yazma

Bir AIDL arayüzünün sistem ve satıcı arasında kullanılabilmesi için arayüzde iki değişiklik yapılması gerekir:

  • Her tür tanımı @VintfStability ile açıklama eklenmelidir.
  • aidl_interface beyanına stability: "vintf", eklenmelidir.

Bu değişiklikleri yalnızca arayüzün sahibi yapabilir.

Bu değişiklikleri yaptığınızda arayüzün çalışması için VINTF manifestinde olması gerekir. Bunu (ve ilgili gereksinimleri, örneğin yayınlanan arayüzlerin dondurulduğunu doğrulama) vts_treble_vintf_vendor_test Vendor Test Suite (VTS) testi ile test edin. NDK arka ucunda @VintfStability, C++ arka ucunda AIBinder_forceDowngradeToLocalStability veya Java arka ucunda android::Stability::forceDowngradeToLocalStability çağırarak bu koşullar olmadan bir android.os.Binder#forceDowngradeToSystemStability arayüzü kullanabilirsiniz.

Ayrıca, kodun taşınabilirliğini en üst düzeye çıkarmak ve gereksiz ek kitaplıklar gibi olası sorunları önlemek için CPP arka ucunu devre dışı bırakın.

Kodda CPP arka ucunun nasıl devre dışı bırakılacağı gösterilmektedir:

    aidl_interface: {
        ...
        backend: {
            cpp: {
                enabled: false,
            },
        },
    }

AIDL HAL arayüzlerini bulma

HAL'ler için AOSP kararlı AIDL arayüzleri, HIDL arayüzleriyle aynı temel dizinlerdeki aidl klasörlerinde bulunur:

  • hardware/interfaces, genellikle donanım tarafından sağlanan arayüzler içindir.
  • frameworks/hardware/interfaces, donanıma sağlanan üst düzey arayüzler içindir.
  • system/hardware/interfaces, donanıma sağlanan düşük seviyeli arayüzler içindir.

Uzantı arayüzlerini hardware/interfaces alt dizinlerine vendor veya hardware olarak yerleştirin.

Uzantı arayüzleri

Android, her sürümde bir dizi resmi AOSP arayüzü içerir. Android iş ortakları bu arayüzlere özellik eklemek istediğinde bunları doğrudan değiştirmemelidir. Aksi takdirde Android çalışma zamanları AOSP Android çalışma zamanıyla uyumsuz hale gelir. GSI görüntüsünün çalışmaya devam edebilmesi için bu arayüzleri değiştirmeyin.

Uzantılar iki farklı şekilde kaydedilebilir:

  • Çalışma zamanında; Ekli uzantı arayüzleri bölümüne bakın.
  • Bağımsız, dünya genelinde ve VINTF'de kayıtlı

Ancak bir uzantı nasıl kaydedilirse kaydedilsin, satıcıya özel (yani yukarı akış AOSP'nin parçası olmayan) bileşenler arayüzü kullandığında birleştirme çakışmaları mümkün değildir. Ancak yukarı akış AOSP bileşenlerinde aşağı akış değişiklikleri yapıldığında birleştirme çakışmaları oluşabilir ve şu stratejiler önerilir:

  • Arayüz eklemelerini bir sonraki sürümde AOSP'ye aktarın.
  • Bir sonraki sürümde daha fazla esneklik (birleştirme çakışmaları olmadan) sağlayan yukarı akış arayüzü eklemeleri.

Uzantı ayrıştırılabilir öğeleri: ParcelableHolder

ParcelableHolder, Parcelable arayüzünün bir örneğidir ve Parcelable'nin başka bir örneğini içerebilir.

ParcelableHolder'nın temel kullanım alanı, Parcelable'ı genişletilebilir hale getirmektir. Örneğin, cihaz uygulayıcıların AOSP tarafından tanımlanan Parcelable, AospDefinedParcelable özelliklerini değer katan özelliklerini de içerecek şekilde genişletebilmeyi beklediğini düşünün.

ParcelableHolder arayüzünü kullanarak Parcelable'ı katma değerli özelliklerinizle genişletin. ParcelableHolder arayüzü, Parcelable öğesinin bir örneğini içerir. Alanları doğrudan Parcelable öğesine eklemeye çalışırsanız hata oluşur:

parcelable AospDefinedParcelable {
  int a;
  String b;
  String x; // ERROR: added by a device implementer
  int[] y; // added by a device implementer
}

Önceki kodda görüldüğü gibi, cihaz uygulayıcısı tarafından eklenen alanlar, Android'in sonraki sürümlerinde Parcelable revize edildiğinde çakışma yaşayabileceğinden bu uygulama bozulur.

ParcelableHolder kullanarak, paketlenebilir bir öğenin sahibi, Parcelable örneğinde bir uzantı noktası tanımlayabilir:

parcelable AospDefinedParcelable {
  int a;
  String b;
  ParcelableHolder extension;
}

Ardından, cihaz uygulayıcıları uzantıları için kendi Parcelable örneklerini tanımlayabilir:

parcelable OemDefinedParcelable {
  String x;
  int[] y;
}

Yeni Parcelable örneği, ParcelableHolder alanı kullanılarak orijinal Parcelable örneğine eklenebilir:


// Java
AospDefinedParcelable ap = ...;
OemDefinedParcelable op = new OemDefinedParcelable();
op.x = ...;
op.y = ...;

ap.extension.setParcelable(op);

...

OemDefinedParcelable op = ap.extension.getParcelable(OemDefinedParcelable.class);

// C++
AospDefinedParcelable ap;
OemDefinedParcelable op;
std::shared_ptr<OemDefinedParcelable> op_ptr = make_shared<OemDefinedParcelable>();

ap.extension.setParcelable(op);
ap.extension.setParcelable(op_ptr);

...

std::shared_ptr<OemDefinedParcelable> op_ptr;

ap.extension.getParcelable(&op_ptr);

// NDK
AospDefinedParcelable ap;
OemDefinedParcelable op;
ap.extension.setParcelable(op);

...

std::optional<OemDefinedParcelable> op;
ap.extension.getParcelable(&op);

// Rust
let mut ap = AospDefinedParcelable { .. };
let op = Rc::new(OemDefinedParcelable { .. });

ap.extension.set_parcelable(Rc::clone(&op));

...

let op = ap.extension.get_parcelable::<OemDefinedParcelable>();

AIDL HAL sunucu örneği adları

AIDL HAL hizmetlerinin örnek adı, kural olarak $package.$type/$instance biçimindedir. Örneğin, titreşim cihazı HAL'ı android.hardware.vibrator.IVibrator/default olarak kaydedilir.

AIDL HAL sunucusu yazma

@VintfStability AIDL sunucuları, VINTF manifestinde bildirilmelidir. Örneğin:

    <hal format="aidl">
        <name>android.hardware.vibrator</name>
        <version>1</version>
        <fqname>IVibrator/default</fqname>
    </hal>

Aksi takdirde, AIDL hizmetini normal şekilde kaydetmeleri gerekir. VTS testleri çalıştırılırken, bildirilen tüm AIDL HAL'lerinin kullanılabilir olması beklenir.

AIDL istemcisi yazma

AIDL istemcileri, uyumluluk matrisinde kendilerini bildirmelidir. Örneğin:

    <hal format="aidl" optional="true">
        <name>android.hardware.vibrator</name>
        <version>1-2</version>
        <interface>
            <name>IVibrator</name>
            <instance>default</instance>
        </interface>
    </hal>

Mevcut bir HAL'yi HIDL'den AIDL'ye dönüştürme

HIDL arayüzünü AIDL'ye dönüştürmek için hidl2aidl aracını kullanın.

hidl2aidl özellikleri:

  • Belirli bir paket için HAL (.hal) dosyalarına dayalı AIDL (.aidl) dosyaları oluşturun.
  • Tüm arka uçlar etkinleştirilmiş olarak yeni oluşturulan AIDL paketi için derleme kuralları oluşturun.
  • HIDL türlerinden AIDL türlerine çeviri yapmak için Java, CPP ve NDK arka uçlarında çeviri yöntemleri oluşturun.
  • Gerekli bağımlılıkları içeren çeviri kitaplıkları için derleme kuralları oluşturun.
  • HIDL ve AIDL numaralandırıcılarının CPP ve NDK arka uçlarında aynı değerlere sahip olmasını sağlamak için statik onaylamalar oluşturun.

HAL dosyaları paketini AIDL dosyalarına dönüştürmek için aşağıdaki adımları uygulayın:

  1. system/tools/hidl/hidl2aidl konumundaki aracı oluşturun.

    Bu aracı en son kaynaktan oluşturmak en eksiksiz deneyimi sağlar. Önceki sürümlerdeki eski dallarda bulunan arayüzleri dönüştürmek için en son sürümü kullanabilirsiniz:

    m hidl2aidl
  2. Aracı, dönüştürülecek paketin ardından bir çıkış diziniyle birlikte çalıştırın.

    İsteğe bağlı olarak, oluşturulan tüm dosyaların en üstüne yeni bir lisans dosyasının içeriğini eklemek için -l bağımsız değişkenini kullanın. Doğru lisansı ve tarihi kullandığınızdan emin olun:

    hidl2aidl -o <output directory> -l <file with license> <package>

    Örneğin:

    hidl2aidl -o . -l my_license.txt android.hardware.nfc@1.2
  3. Oluşturulan dosyaları okuyun ve dönüştürmeyle ilgili sorunları düzeltin:

    • conversion.log, önce düzeltilmesi gereken işlenmemiş sorunlar içeriyor.
    • Oluşturulan AIDL dosyalarında işlem yapılması gereken uyarılar ve öneriler olabilir. Bu yorumlar // ile başlar.
    • Paketi temizleyin ve iyileştirin.
    • toString veya equals gibi gerekebilecek özellikler için @JavaDerive açıklamasını kontrol edin.
  4. Yalnızca ihtiyacınız olan hedefleri oluşturun:

    • Kullanılmayacak arka uçları devre dışı bırakın. CPP arka ucuna kıyasla NDK arka ucunu tercih edin. AIDL çalışma zamanına karşı derleme başlıklı makaleye bakın.
    • Çeviri kitaplıklarını veya oluşturulan kodlarından kullanılmayacak olanları kaldırın.
  5. AIDL ile HIDL arasındaki temel farklar başlıklı makaleye bakın:

    • AIDL'nin yerleşik Status ve istisnalarını kullanmak genellikle arayüzü iyileştirir ve arayüze özgü başka bir durum türüne olan ihtiyacı ortadan kaldırır.
    • Yöntemlerdeki AIDL arayüzü bağımsız değişkenleri, HIDL'de olduğu gibi varsayılan olarak @nullable değildir.

AIDL Donanım Soyutlama Katmanları için SEPolicy

Tedarikçi koduna görünür olan bir AIDL hizmet türünde hal_service_type özelliği bulunmalıdır. Aksi takdirde, sepolicy yapılandırması diğer AIDL hizmetleriyle aynıdır (HAL'ler için özel özellikler olsa da). Aşağıda, bir HAL hizmet bağlamının örnek tanımı verilmiştir:

    type hal_foo_service, service_manager_type, hal_service_type;

Platform tarafından tanımlanan çoğu hizmet için doğru türde bir hizmet bağlamı zaten eklenmiştir (örneğin, android.hardware.foo.IFoo/default zaten hal_foo_service olarak işaretlenmiştir). Ancak bir çerçeve istemcisi birden fazla örnek adını destekliyorsa cihaza özel service_contexts dosyalarına ek örnek adları eklenmelidir:

    android.hardware.foo.IFoo/custom_instance u:object_r:hal_foo_service:s0

Yeni bir HAL türü oluşturduğunuzda HAL özelliklerini eklemeniz gerekir. Belirli bir HAL özelliği birden fazla hizmet türüyle ilişkilendirilebilir (her birinin, az önce bahsedildiği gibi birden fazla örneği olabilir). foo adlı bir HAL için hal_attribute(foo). Bu makro, hal_foo_client ve hal_foo_server özelliklerini tanımlar. Belirli bir alan için hal_client_domain ve hal_server_domain makroları, bir alanı belirli bir HAL özelliğiyle ilişkilendirir. Örneğin, bu HAL'nin istemcisi olan sistem sunucusu hal_client_domain(system_server, hal_foo) politikasına karşılık gelir. Benzer şekilde, bir HAL sunucusu da şunları içerir: hal_server_domain(my_hal_domain, hal_foo).

Genellikle, belirli bir HAL özelliği için referans veya örnek HAL'ler olarak hal_foo_default gibi bir alan da oluşturun. Ancak bazı cihazlar kendi sunucuları için bu alanları kullanır. Birden fazla sunucu için alanları ayırt etmek yalnızca aynı arayüze hizmet veren ve uygulamalarında farklı bir izin grubuna ihtiyaç duyan birden fazla sunucu varsa önemlidir. Bu makroların hiçbirinde hal_foo bir sepolicy nesnesi değildir. Bunun yerine, bu makrolar bu jetonu kullanarak bir istemci-sunucu çiftiyle ilişkili özellikler grubunu ifade eder.

Ancak şu ana kadar hal_foo_service ve hal_foo (hal_attribute(foo) öğesinden gelen özellik çifti) ilişkilendirilmedi. Bir HAL özelliği, hal_attribute_service makrosu kullanılarak AIDL HAL hizmetleriyle ilişkilendirilir (HIDL HAL'leri hal_attribute_hwservice makrosunu kullanır). Örneğin, hal_attribute_service(hal_foo, hal_foo_service). Bu, hal_foo_client işlemlerinin HAL'yi alabileceği ve hal_foo_server işlemlerinin HAL'yi kaydedebileceği anlamına gelir. Bu kayıt kurallarının uygulanması bağlam yöneticisi (servicemanager) tarafından yapılır.

Hizmet adları her zaman HAL özellikleriyle eşleşmeyebilir. Örneğin: hal_attribute_service(hal_foo, hal_foo2_service). Genel olarak, bu hizmetlerin her zaman birlikte kullanıldığı anlamına geldiğinden hal_foo2_service simgesini kaldırabilir ve tüm hizmet bağlamları için hal_foo_service simgesini kullanabilirsiniz. HAL'ler birden fazla hal_attribute_service örneği ayarladığında bunun nedeni, orijinal HAL özelliği adının yeterince genel olmaması ve değiştirilememesidir.

Tüm bunları bir araya getirdiğimizde, örnek bir HAL şu şekilde görünür:

    public/attributes:
    // define hal_foo, hal_foo_client, hal_foo_server
    hal_attribute(foo)

    public/service.te
    // define hal_foo_service
    type hal_foo_service, hal_service_type, protected_service, service_manager_type

    public/hal_foo.te:
    // allow binder connection from client to server
    binder_call(hal_foo_client, hal_foo_server)
    // allow client to find the service, allow server to register the service
    hal_attribute_service(hal_foo, hal_foo_service)
    // allow binder communication from server to service_manager
    binder_use(hal_foo_server)

    private/service_contexts:
    // bind an AIDL service name to the selinux type
    android.hardware.foo.IFooXxxx/default u:object_r:hal_foo_service:s0

    private/<some_domain>.te:
    // let this domain use the hal service
    binder_use(some_domain)
    hal_client_domain(some_domain, hal_foo)

    vendor/<some_hal_server_domain>.te
    // let this domain serve the hal service
    hal_server_domain(some_hal_server_domain, hal_foo)

Eklenmiş uzantı arayüzleri

Uzantılar, hizmet yöneticisine doğrudan kaydedilmiş üst düzey bir arayüz veya bir alt arayüz olsun, herhangi bir bağlayıcı arayüze eklenebilir. Uzatma alırken uzatmanın türünün beklendiği gibi olduğunu onaylamanız gerekir. Uzantıları yalnızca bir bağlayıcıya hizmet veren süreçten ayarlayabilirsiniz.

Bir uzantı, mevcut bir HAL'ın işlevselliğini her değiştirdiğinde eklenmiş uzantıları kullanın. Tamamen yeni bir özellik gerektiğinde bu mekanizma gerekli değildir ve bir uzantı arayüzünü doğrudan hizmet yöneticisine kaydedebilirsiniz. Ekli uzantı arayüzleri, alt arayüzlere eklendiğinde en mantıklı sonucu verir. Çünkü bu hiyerarşiler derin veya çok örnekli olabilir. Başka bir hizmetin bağlayıcı arayüz hiyerarşisini yansıtmak için genel bir uzantı kullanmak, doğrudan eklenen uzantılarla eşdeğer özellikler sağlamak için kapsamlı bir muhasebe gerektirir.

Bir klasöre uzantı ayarlamak için aşağıdaki API'leri kullanın:

  • NDK arka ucu: AIBinder_setExtension
  • Java arka ucu: android.os.Binder.setExtension
  • CPP arka ucu: android::Binder::setExtension
  • Rust arka ucu: binder::Binder::set_extension

Bir bağlayıcıda uzatma almak için aşağıdaki API'leri kullanın:

  • NDK arka ucu: AIBinder_getExtension
  • Java arka ucu: android.os.IBinder.getExtension
  • CPP arka ucu: android::IBinder::getExtension
  • Rust arka ucu: binder::Binder::get_extension

Bu API'ler hakkında daha fazla bilgiyi ilgili arka uçtaki getExtension işlevinin belgelerinde bulabilirsiniz. Uzantıların nasıl kullanılacağına dair bir örneği hardware/interfaces/tests/extension/vibrator bölümünde bulabilirsiniz.

AIDL ile HIDL arasındaki temel farklar

AIDL HAL'leri veya AIDL HAL arayüzlerini kullanırken HIDL HAL'leri yazmaya kıyasla farklılıkların olduğunu unutmayın.

  • AIDL dilinin söz dizimi Java'ya daha yakındır. HIDL söz dizimi C++'a benzer.
  • Tüm AIDL arayüzlerinde yerleşik hata durumları bulunur. Özel durum türleri oluşturmak yerine arayüz dosyalarında sabit durum tamsayıları oluşturun ve CPP ile NDK arka uçlarında EX_SERVICE_SPECIFIC, Java arka ucunda ise ServiceSpecificException kullanın. Hata işleme bölümüne bakın.
  • AIDL, bağlayıcı nesneler gönderildiğinde iş parçacığı havuzlarını otomatik olarak başlatmaz. Bunları manuel olarak başlatmanız gerekir (bkz. İş parçacığı yönetimi).
  • AIDL, kontrol edilmemiş aktarım hatalarında işlemi durdurmaz (HIDL, kontrol edilmemiş hatalarda işlemi durdurur).Return
  • AIDL, dosya başına yalnızca bir tür bildirebilir.
  • AIDL bağımsız değişkenleri, çıkış parametresine ek olarak in, out veya inout olarak belirtilebilir (eşzamanlı geri çağırma yoktur).
  • AIDL, handle yerine fd öğesini temel tür olarak kullanır.
  • HIDL, uyumsuz değişiklikler için ana sürümleri, uyumlu değişiklikler için ise alt sürümleri kullanır. AIDL'de geriye dönük uyumlu değişiklikler yerinde yapılır. AIDL'de ana sürümlerle ilgili açık bir kavram yoktur. Bunun yerine, bu kavram paket adlarına dahil edilir. Örneğin, AIDL, bluetooth2 paket adını kullanabilir.
  • AIDL, varsayılan olarak gerçek zamanlı önceliği devralmaz. Gerçek zamanlı öncelik devralmayı etkinleştirmek için setInheritRt işlevi bağlayıcı başına kullanılmalıdır.

HAL'ler için testler

Bu bölümde, HAL'leri test etmeyle ilgili en iyi uygulamalar açıklanmaktadır. Bu uygulamalar, HAL'niz için entegrasyon testi VTS'de olmasa bile geçerlidir.

Android, beklenen HAL uygulamalarını doğrulamak için VTS'yi kullanır. VTS, Android'in eski tedarikçi uygulamalarıyla geriye dönük uyumlu olmasını sağlar. VTS'yi geçemeyen uygulamaların, gelecekteki işletim sistemi sürümleriyle çalışmasını engelleyebilecek bilinen uyumluluk sorunları vardır.

HAL'ler için VTS'nin iki ana bölümü vardır.

1. Cihazdaki HAL'lerin Android tarafından bilindiğini ve beklendiğini doğrulayın.

Android, yüklü tüm HAL'lerin statik ve doğru bir listesine sahip olmaya dayanır. Bu liste, VINTF Manifest'te ifade edilir. Özel ve platform genelinde yapılan testler, sistemin tamamındaki HAL katmanlarının bütünlüğünü birlikte doğrular. HAL'e özgü testler yazmadan önce bu testleri de çalıştırmanız gerekir. Bu testler, bir HAL'in tutarsız VINTF yapılandırmalarına sahip olup olmadığını belirleyebilir.

Bu test grubunu test/vts-testcase/hal/treble/vintf adresinde bulabilirsiniz. Bir satıcı HAL uygulaması üzerinde çalışıyorsanız bunu doğrulamak için vts_treble_vintf_vendor_test kullanın. Bu testi atest vts_treble_vintf_vendor_test komutuyla çalıştırabilirsiniz.

Bu testler aşağıdakileri doğrulamaktan sorumludur:

  • VINTF manifest dosyasında bildirilen her @VintfStability arayüzü, bilinen bir yayınlanmış sürümde dondurulur. Bu, arayüzün her iki tarafının da arayüzün söz konusu sürümünün tanımı konusunda anlaştığını doğrular. Bu, temel işlemler için gereklidir.
  • VINTF manifestinde belirtilen tüm HAL'ler söz konusu cihazda kullanılabilir. Bildirilmiş bir HAL hizmetini kullanmak için yeterli izne sahip olan tüm istemciler, bu hizmetleri istedikleri zaman alıp kullanabilmelidir.
  • VINTF manifestinde belirtilen tüm HAL'ler, manifestte belirttikleri arayüz sürümünü sunar.
  • Cihazda desteği sonlandırılmış HAL'ler kullanılmıyor. Android, FCM yaşam döngüsünde açıklandığı gibi HAL arayüzlerinin eski sürümlerine yönelik desteği sonlandırır.
  • Gerekli HAL'ler cihazda bulunmalıdır. Android'in düzgün çalışması için bazı HAL'ler gereklidir.

2. Her HAL'nin beklenen davranışını doğrulayın.

Her HAL arayüzünün, istemcilerinden beklenen davranışı doğrulamak için kendi VTS testleri vardır. Test senaryoları, beyan edilen her HAL arayüzü örneğine karşı çalıştırılır ve uygulanan arayüzün sürümüne göre belirli davranışlar zorunlu kılınır.

C++'ta, libaidlvintf_gtest_helper içindeki android::getAidlHalInstanceNames işleviyle sisteme yüklenen her bir HAL'in listesini alabilirsiniz. Rust'ta binder::get_declared_instances kullanın.

Bu testler, Android çerçevesinin kullandığı veya gelecekte kullanabileceği HAL uygulamasının her yönünü kapsamaya çalışır.

Bu testler, özelliklerin desteklenmesinin, hata işlemeyle ilgili durumların ve istemcinin hizmetten bekleyebileceği diğer davranışların doğrulanmasını içerir.

Donanım soyutlama katmanı geliştirme için VTS aşamaları

Android'in HAL arayüzleri oluşturulurken veya değiştirilirken VTS testlerinin (veya herhangi bir testin) güncel tutulması beklenir.

VTS testleri, Android Vendor API sürümleri için dondurulmadan önce tamamlanmalı ve satıcı uygulamalarını doğrulamaya hazır olmalıdır. Geliştiricilerin uygulamalarını oluşturabilmesi, bunları doğrulayabilmesi ve HAL arayüzü geliştiricilerine geri bildirim sağlayabilmesi için arayüzler dondurulmadan önce hazır olmalıdır.

Cuttlefish'te test etme

Donanım kullanılamadığında Android, HAL arayüzleri için geliştirme aracı olarak Cuttlefish'i kullanır. Bu sayede Android'in ölçeklenebilir entegrasyon testi yapılabilir.

hal_implementation_test Cuttlefish'in en yeni HAL arayüzü sürümlerini uyguladığını test ederek Android'in yeni arayüzleri işlemeye hazır olduğundan ve yeni donanım ve cihazlar kullanıma sunulur sunulmaz VTS testlerinin yeni tedarikçi uygulamalarını test etmeye hazır olduğundan emin olun.