HAL'ler için AIDL

Android 11, Android'de HAL'ler için AIDL kullanma özelliğini kullanıma sunar. Bu sayede Android'in bazı kısımlarını HIDL olmadan uygulamak mümkün olur. Mümkün olduğunda HAL'leri yalnızca AIDL kullanmaya geçirin (yukarı yönlü HAL'ler HIDL kullandığında HIDL kullanılmalıdır).

system.img'teki gibi çerçeve bileşenleri ile vendor.img'teki 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ı konusunda herhangi 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 gibi diğer birçok yerde kullanılır. AIDL'de kararlılık desteği bulunduğundan, tek bir IPC çalışma zamanında tüm yığının uygulanması mümkündür. AIDL, HIDL'den daha iyi bir sürüm sistemi de sunar.

  • Tek bir IPC dili kullanmak, öğrenmeniz, hata ayıklamanız, optimize etmeniz ve güvence altına almanız gereken tek bir şey olduğu anlamına gelir.
  • AIDL, bir arayüzün sahipleri için yerinde sürüm oluşturmayı destekler:
    • Sahipler, arayüzlerin sonuna yöntem veya paketlenebilir öğelere alan ekleyebilir. Bu sayede, yıllar içinde kod sürümünü oluşturmak daha kolay olur ve yıllık maliyet daha düşük olur (türler yerinde değiştirilebilir ve her arayüz sürümü için ek kitaplıklara gerek yoktur).
    • Uzatma arayüzleri, tür sisteminde değil de çalışma zamanında eklenebilir. Bu nedenle, yayın uzantılarını arayüzlerin daha yeni sürümlerine yeniden temellendirmeye gerek yoktur.
  • Mevcut bir AIDL arayüzü, sahibi tarafından sabitlendiğinde 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, CPP. Sabit AIDL'yi kullanmak için her zaman system/lib*/libbinder.so adresindeki libbinder'in sistem kopyasını kullanmalı ve /dev/binder üzerinde konuşmalısınız. Tedarikçi firma resmindeki kod için bu, libbinder (VNDK'dan) kullanılamayacağı anlamına gelir: Bu kitaplıkta 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 (libbinder.so sistemi tarafından desteklenir) ile bağlantı kurmalı ve aidl_interface girişleri tarafından oluşturulan NDK kitaplıklarıyla bağlantı kurmalıdır. Modül adlarının tam listesi için modül adlandırma kurallarına bakın.

AIDL HAL arayüzü yazma

Sistem ile tedarikçi firma arasında kullanılacak bir AIDL arayüzünde iki değişiklik yapılması gerekir:

  • Her tür tanımı @VintfStability ile ek açıklamaya tabi tutulmalıdır.
  • aidl_interface beyanında stability: "vintf", bulunmalıdır.

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. Bu koşulu (ve yayınlanmış arayüzlerin dondurulduğunu doğrulama gibi ilgili koşulları) VTS testini vts_treble_vintf_vendor_test kullanarak test edin. Bir bağlayıcı nesnesi başka bir sürece gönderilmeden önce NDK arka ucunda AIBinder_forceDowngradeToLocalStability, C++ arka ucunda android::Stability::forceDowngradeToLocalStability veya Java arka ucunda android.os.Binder#forceDowngradeToSystemStability çağrısını yaparak @VintfStability arayüzünü bu şartlar olmadan kullanabilirsiniz. Tüm uygulamalar sistem bağlamında çalıştığından, bir hizmeti tedarikçi firma kararlılığına indirgeme işlemi Java'da desteklenmez.

Ayrıca, kod 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.

Üç arka uç (Java, NDK ve CPP) olduğundan aşağıdaki kod örneğinde backends kullanımının doğru olduğunu unutmayın. Aşağıdaki kodda, CPP arka ucuna özel olarak nasıl erişileceği ve bu arka uç devre dışı bırakılacağı açıklanmaktadır.

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

AIDL HAL arayüzlerini bulma

HAL'ler için AOSP kararlı AIDL arayüzleri, HIDL arayüzleriyle aynı ana dizinlerde (aidl klasörlerinde) bulunur.

  • hardware/interfaces: Genellikle donanım tarafından sağlanan arayüzler için
  • frameworks/hardware/interfaces: Donanıma sağlanan üst düzey arayüzler için
  • system/hardware/interfaces: Donanıma sağlanan düşük düzeyli arayüzler için

Uzantı arayüzlerini vendor veya hardware içindeki diğer hardware/interfaces alt dizinlerine yerleştirmeniz gerekir.

Uzantı arayüzleri

Android'in her sürümünde resmi AOSP arayüzleri bulunur. Android iş ortakları bu arayüzlere işlev eklemek istediğinde bunları doğrudan değiştirmemelidir. Aksi takdirde, Android çalışma zamanlarının AOSP Android çalışma zamanıyla uyumlu olmadığı anlamına gelir. GMS cihazlarda, bu arayüzlerin değiştirilmemesinden GSI resminin çalışmaya devam edebilmesi de sağlanır.

Uzantılar iki farklı şekilde kaydedilebilir:

  • çalıştırırken ekli uzantılar bölümüne bakın.
  • bağımsız, dünya genelinde ve VINTF'de kayıtlı olmalıdır.

Ancak bir uzantı kaydedildiğinde, tedarikçiye özgü (yani yayın öncesi AOSP'nin bir parçası olmayan) bileşenler arayüzü kullandığında birleştirme çakışması olasılığı yoktur. Ancak, yayın öncesi AOSP bileşenlerinde yayın sonrası değişiklikler yapıldığında birleştirme çakışmaları yaşanabilir. Bu durumda aşağıdaki stratejiler önerilir:

  • Arayüz eklemeleri sonraki sürümde AOSP'ye aktarılabilir.
  • Birleştirme çakışması olmadan daha fazla esneklik sağlayan arayüz eklemeleri, sonraki sürüme aktarılabilir.

Uzantı paketlenebilirleri: ParcelableHolder

ParcelableHolder, başka bir Parcelable içerebilen bir Parcelable öğesidir. ParcelableHolder'ün ana kullanım alanı, Parcelable'u genişletilebilir hale getirmektir. Örneğin, cihaz uygulayıcılarının AOSP tarafından tanımlanan bir Parcelable, AospDefinedParcelable öğesini katma değerli özelliklerini içerecek şekilde genişletebilmeyi beklediği resim.

Daha önce ParcelableHolder olmadan cihaz uygulayıcıları, daha fazla alan eklemek hata olacağından AOSP tarafından tanımlanan kararlı bir AIDL arayüzünü değiştiremiyordu:

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 üzerinde düzeltme yapıldığında çakışabileceği için bu uygulama geçersizdir.

ParcelableHolder özelliğini kullanarak, bölünebilir bir öğenin sahibi Parcelable içinde bir uzantı noktası tanımlayabilir.

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

Ardından cihaz uygulayıcıları, uzantılarının kendi Parcelable'lerini tanımlayabilir.

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

Son olarak, yeni Parcelable, ParcelableHolder alanıyla orijinal Parcelable'e 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 örnek adı

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

AIDL HAL sunucusu yazma

@VintfStability AIDL sunucuları VINTF manifestinde beyan edilmelidir. Örneğin:

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

Aksi takdirde, AIDL hizmetini normal şekilde kaydetmelidirler. VTS testleri çalıştırıldığında, bildirilen tüm AIDL HAL'lerin kullanılabilir olması beklenir.

AIDL istemcisi yazma

AIDL istemcileri kendilerini uyumluluk matrisinde beyan etmelidir. Örneğin, aşağıdaki gibi:

    <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'i 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:

  • Belirtilen paketin .hal dosyalarına göre .aidl dosyası oluşturma
  • Yeni oluşturulan AIDL paketi için tüm arka uçların etkin olduğu derleme kuralları oluşturun
  • HIDL türlerinden AIDL türlerine çevirmek için Java, CPP ve NDK arka uçlarında çeviri yöntemleri oluşturun
  • Gerekli bağımlılıkları olan çeviri kitaplıkları için derleme kuralları oluşturma
  • HIDL ve AIDL dizeleyicilerinin CPP ve NDK arka uçlarında aynı değerlere sahip olmasını sağlamak için statik iddialar oluşturun

Bir .hal dosyası paketini .aidl dosyalarına dönüştürmek için aşağıdaki adımları uygulayın:

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

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

    m hidl2aidl
  2. Aracı, çıkış dizini ve ardından dönüştürülecek paketle birlikte çalıştırın.

    İsteğe bağlı olarak, yeni bir lisans dosyasının içeriğini oluşturulan tüm dosyaların en üstüne 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>

    Örnek:

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

    • conversion.log, önce düzeltilmesi gereken, ele alınmamış sorunları içerir.
    • Oluşturulan .aidl dosyalarında işlem gerektirebilecek uyarılar ve öneriler bulunabilir. Bu yorumlar // ile başlar.
    • Bu fırsatı değerlendirerek pakette temizlik yapın ve iyileştirmeler yapın.
    • toString veya equals gibi ihtiyaç duyulabilecek özellikler için @JavaDerive ek 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 ucu yerine NDK arka ucunu tercih edin. Çalışma zamanı seçin başlıklı makaleyi inceleyin.
    • Çeviri kitaplıklarını veya oluşturulan kodlarından kullanılmayacak olanları kaldırın.
  5. Başlıca AIDL/HIDL farkları başlıklı makaleyi inceleyin.

    • AIDL'in 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 HAL'ler için SEPolicy

Tedarikçi kodu tarafından görülebilen bir AIDL hizmet türü, hal_service_type özelliğine sahip olmalıdır. Aksi takdirde, sepolicy yapılandırması diğer tüm AIDL hizmetleriyle aynıdır (HAL'ler için özel özellikler olsa da). Aşağıda, HAL hizmet bağlamının örnek bir 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üre sahip 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ı destekliyorsa cihaza özgü 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ştururken HAL özellikleri eklenmelidir. Belirli bir HAL özelliği birden fazla hizmet türüyle ilişkilendirilebilir (az önce bahsettiğimiz gibi bunların her biri birden fazla örneği olabilir). HAL için foo, hal_attribute(foo) değerine sahibiz. Bu makro, hal_foo_client ve hal_foo_server özelliklerini tanımlar. hal_client_domain ve hal_server_domain makroları, belirli bir alan için alanı belirli bir HAL özelliğiyle ilişkilendirir. Örneğin, sistem sunucusunun bu HAL'in istemcisi olması hal_client_domain(system_server, hal_foo) politikasına karşılık gelir. HAL sunucusu da benzer şekilde hal_server_domain(my_hal_domain, hal_foo) içerir. Genellikle belirli bir HAL özelliği için referans veya örnek HAL'ler olarak hal_foo_default gibi bir alan da oluştururuz. Ancak bazı cihazlar kendi sunucuları için bu alanları kullanır. Birden fazla sunucu için alanları ayırt etmek yalnızca aynı arayüzü sunan ve uygulamalarında farklı bir izin grubuna ihtiyaç duyan birden fazla sunucumuz varsa önemlidir. Bu makroların hiçbirinde hal_foo aslında bir sepolicy nesnesi değildir. Bunun yerine bu jeton, istemci sunucusu çiftiyle ilişkili özellik grubunu belirtmek için bu makrolar tarafından kullanılır.

Ancak şu ana kadar hal_foo_service ve hal_foo'i (hal_attribute(foo)'deki özellik çifti) ilişkilendirmedik. HAL özelliği, hal_attribute_service makrosu kullanılarak AIDL HAL hizmetleriyle ilişkilendirilir (HIDL HAL'ler hal_attribute_hwservice makrosunu kullanır). Örneğin, hal_attribute_service(hal_foo, hal_foo_service). Bu, hal_foo_client işlemlerinin HAL'i alabileceği ve hal_foo_server işlemlerinin HAL'i kaydedebileceği anlamına gelir. Bu kayıt kurallarının uygulanması bağlam yöneticisi (servicemanager) tarafından yapılır. Hizmet adlarının her zaman HAL özelliklerine karşılık gelmediğini unutmayın. Örneğin, şunu görebiliriz: hal_attribute_service(hal_foo, hal_foo2_service). Ancak genel olarak, hizmetlerin her zaman birlikte kullanıldığı anlamına geldiğinden hal_foo2_service ifadesini kaldırıp tüm hizmet bağlamlarımız için hal_foo_service ifadesini kullanabiliriz. Birden fazla hal_attribute_service ayarlayan HAL'lerin çoğu, orijinal HAL özellik adının yeterince genel olmaması ve değiştirilememesi nedeniyledir.

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)

Ekli uzantı arayüzleri

Doğrudan hizmet yöneticisine kayıtlı üst düzey bir arayüz veya alt arayüz olsun, herhangi bir bağlayıcı arayüzüne uzantı eklenebilir. Uzatma alırken, uzantının türünü doğrulamanız gerekir. Uzantılar yalnızca bir bağlayıcı sunan işlemden ayarlanabilir.

Ekli uzantılar, bir uzantı mevcut HAL'in işlevini değiştirdiğinde kullanılmalıdır. Tamamen yeni bir işlev gerektiğinde bu mekanizmanın kullanılmasına gerek yoktur ve doğrudan hizmet yöneticisine bir uzantı arayüzü kaydedilebilir. Ekli uzantı arayüzleri, bu hiyerarşiler derin veya çok örnekli olabileceğinden alt arayüzlere eklendiğinde en iyi sonucu verir. Başka bir hizmetin bağlayıcı arayüzü hiyerarşisini yansıtmak için genel bir uzantı kullanmak, doğrudan bağlı uzantılara eşdeğer işlevler sunmak için kapsamlı bir muhasebe gerektirir.

Binder'da uzantı ayarlamak için aşağıdaki API'leri kullanın:

  • NDK arka ucunda: AIBinder_setExtension
  • Java arka ucunda: android.os.Binder.setExtension
  • CSS arka ucunda: android::Binder::setExtension
  • Rust arka ucunda: binder::Binder::set_extension

Bir ciltleyici için ek süre almak üzere aşağıdaki API'leri kullanın:

  • NDK arka ucunda: AIBinder_getExtension
  • Java arka ucunda: android.os.IBinder.getExtension
  • CSS arka ucunda: android::IBinder::getExtension
  • Rust arka ucunda: binder::Binder::get_extension

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

AIDL ile HIDL arasındaki önemli farklar

AIDL HAL'leri veya AIDL HAL arayüzleri kullanırken HIDL HAL'leri yazmaya kıyasla farklılıklara dikkat edin.

  • AIDL dilinin söz dizimi Java'ya daha yakındır. HIDL söz dizimi C++'ya benzer.
  • Tüm AIDL arayüzlerinde yerleşik hata durumları vardır. Özel durum türleri oluşturmak yerine arayüz dosyalarında sabit durum int'leri oluşturun ve CPP/NDK arka uçlarında EX_SERVICE_SPECIFIC, Java arka ucunda ise ServiceSpecificException kullanın. Hata İşleme bölümüne bakın.
  • AIDL, bağlayıcı nesneleri gönderildiğinde iş parçacığı havuzlarını otomatik olarak başlatmaz. Bunlar manuel olarak başlatılmalıdır (mesaj dizisi yönetimine bakın).
  • AIDL, işaretlenmemiş aktarım hatalarında işlemi iptal etmez (HIDL, işaretlenmemiş hatalarda işlemi iptal eder).Return
  • AIDL, dosya başına yalnızca bir tür tanımlayabilir.
  • AIDL bağımsız değişkenleri, çıkış parametresine ek olarak in/out/inout olarak belirtilebilir ("eşzamanlı geri çağırma" yoktur).
  • AIDL, asıl tür olarak tutamak yerine fd kullanır.
  • HIDL, uyumsuz değişiklikler için ana sürümleri, uyumlu değişiklikler için ise küçük sürümleri kullanır. AIDL'de geriye dönük uyumlu değişiklikler yerinde yapılır. AIDL'de ana sürüm kavramı açıkça belirtilmez. Bunun yerine, ana sürümler 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 devralınmasını etkinleştirmek için setInheritRt işlevi bağlayıcı başına kullanılmalıdır.

HAL'ler için Tedarikçi Test Paketi (VTS) Testleri

Android, beklenen HAL uygulamalarını doğrulamak için Satıcı Testi Paketi'ni (VTS) kullanır. VTS, Android'in eski tedarikçi uygulamalarıyla geriye dönük uyumlu olmasını sağlar. VTS'de başarısız olan uygulamalarda, işletim sisteminin gelecekteki 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.

Bu test grubunu test/vts-testcase/hal/treble/vintf adresinde bulabilirsiniz. Aşağıdakilerin doğrulanmasından sorumludur:

  • VINTF manifestinde tanımlanan 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 ilgili sürümünün tam tanımı konusunda anlaşmasına olanak tanır. Bu, temel işlevler için gereklidir.
  • VINTF manifestinde tanımlanan tüm HAL'ler söz konusu cihazda kullanılabilir. Beyan edilen bir HAL hizmetini kullanmak için yeterli izinlere sahip olan tüm istemciler, bu hizmetleri istedikleri zaman alıp kullanabilmelidir.
  • VINTF manifestinde beyan edilen tüm HAL'ler, manifestte beyan ettikleri arayüz sürümünü sunar.
  • Cihazlarda desteği sonlandırılmış HAL'ler sunulmuyor. Android, FCM Yaşam Döngüsü bölümünde açıklandığı gibi HAL arayüzlerinin eski sürümleri için desteği sonlandırıyor.
  • Gerekli HAL'ler cihazda mevcut olmalıdır. Android'in düzgün çalışması için bazı HAL'ler gereklidir.

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

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

Bu testler, HAL uygulamasının Android çerçevesinin dayandığı veya gelecekte dayayabileceği her yönünü kapsayacak şekilde tasarlanmıştır.

Bu testler, özelliklerin desteklenmesi, hata işleme ve istemcinin hizmetten beklediği diğer tüm davranışların doğrulanmasını içerir.

HAL Geliştirme İçin VTS Dönüm Noktaları

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

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

Mürekkep balığında VTS

Donanım kullanılamadığında Android, HAL arayüzleri için geliştirme aracı olarak Cuttlefish'i kullanır. Bu sayede Android için ölçeklenebilir VTS ve entegrasyon testi yapılabilir. hal_implementation_test, Android'in yeni arayüzleri işlemeye hazır olduğundan ve VTS testlerinin yeni donanım ve cihazlar kullanıma sunulduğunda yeni satıcı uygulamalarını test etmeye hazır olduğundan emin olmak için Cuttlefish'in en son HAL arayüzü sürümlerinin uygulandığını test eder.