HAL'ler için AIDL

Android 11, Android'de HAL'ler için AIDL kullanma özelliğini sunar. Bu, Android'in bazı bölümlerini HIDL olmadan uygulamayı mümkün kılar. HAL'leri mümkün olduğunda yalnızca AIDL kullanacak şekilde geçiş yapın (yukarı akış HAL'leri HIDL kullandığında, HIDL kullanılmalıdır).

AIDL kullanarak HAL'lere gibi olanlar gibi çerçeve bileşenleri arasında iletişim kurmak üzere system.img , ve böyle gibi donanım bileşenleri, vendor.img Kararlı AIDL kullanmalıdır. Ancak, bir bölüm içinde, örneğin bir HAL'den diğerine iletişim kurmak için, kullanılacak IPC mekanizmasında herhangi bir kısıtlama yoktur.

Motivasyon

AIDL, HIDL'den daha uzun süredir var ve Android çerçeve bileşenleri veya uygulamalar gibi birçok başka yerde kullanılıyor. AIDL artık kararlılık desteğine sahip olduğundan, tek bir IPC çalışma zamanı ile tüm yığını uygulamak mümkündür. AIDL ayrıca HIDL'den daha iyi bir sürüm oluşturma sistemine sahiptir.

  • Tek bir IPC dili kullanmak, öğrenilecek, hata ayıklanacak, optimize edilecek ve güvenli hale getirilecek tek bir şeye sahip olmak anlamına gelir.
  • AIDL, bir arabirimin sahipleri için yerinde sürüm oluşturmayı destekler:
    • Sahipler, arayüzlerin sonuna yöntemler veya parsellenebilirlere alanlar ekleyebilir. Bu, yıllar içinde kodun sürümlendirilmesinin daha kolay olduğu ve ayrıca yıldan yıla maliyetin daha düşük olduğu anlamına gelir (türler yerinde değiştirilebilir ve her arayüz sürümü için fazladan kitaplığa gerek yoktur).
    • Uzantı arabirimleri, tür sistemi yerine çalışma zamanında eklenebilir, bu nedenle aşağı akış uzantılarını daha yeni arabirim sürümlerine yeniden temellendirmeye gerek yoktur.
  • Mevcut bir AIDL arayüzü, sahibi onu stabilize etmeyi seçtiğinde doğrudan kullanılabilir. Daha önce, arayüzün tam bir kopyasının HIDL'de oluşturulması gerekiyordu.

AIDL HAL arabirimi yazma

Sistem ve satıcı arasında kullanılacak bir AIDL arabirimi için arabirimde iki değişiklik gerekir:

  • Her tür tanımı ile açıklamalı olmalıdır @VintfStability .
  • aidl_interface bildirimi içermelidir stability: "vintf", .

Bu değişiklikleri yalnızca bir arabirimin sahibi yapabilir.

Bu değişiklikleri yaparken, arayüz olmalıdır VINTF bildiriminde çalışmaları için. VTS testi kullanarak bu (örneğin serbest arayüzleri donmuş olduğunu doğrulama olarak ve ilgili gereksinimleri,) test vts_treble_vintf_vendor_test . Bir kullanabilirsiniz @VintfStability ya çağırarak bu gereksinimleri olmadan arayüzü AIBinder_forceDowngradeToLocalStability NDK arka uç, android::Stability::forceDowngradeToLocalStability C ++ arka uç veya içinde android.os.Binder#forceDowngradeToSystemStability bir bağlayıcı nesne üzerinde Java arka uç 's Önce gönderilen başka bir sürece. Tüm uygulamalar bir sistem bağlamında çalıştığından, bir hizmeti satıcı kararlılığına düşürmek Java'da desteklenmez.

Ek olarak, maksimum kod taşınabilirliği için ve gereksiz ek kitaplıklar gibi olası sorunlardan kaçınmak için CPP arka ucunu devre dışı bırakın.

Kullanımı Not backends , üç arka uçları (Java, NDK ve ABM) olarak orada kod örneği aşağıda doğrudur. Aşağıdaki kod, devre dışı bırakmak için özel olarak CPP arka ucunun nasıl seçileceğini anlatır.

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

AIDL HAL arabirimlerini bulma

HAL'lere için AOSP Kararlı AIDL arayüzleri içinde, HIDL arayüzleri ile aynı baz dizinleri vardır aidl klasörler.

  • donanım/arayüzler
  • çerçeveler/donanım/arayüzler
  • sistem/donanım/arayüzler

Diğer içine uzatma arayüzleri koymalıyız hardware/interfaces içinde alt dizinleri vendor veya hardware .

Uzantı Arayüzleri

Android, her sürümde bir dizi resmi AOSP arayüzüne sahiptir. Android iş ortakları bu arayüzlere işlevsellik eklemek istediklerinde, bunları doğrudan değiştirmemelidirler çünkü bu, Android çalışma zamanlarının AOSP Android çalışma zamanı ile uyumlu olmadığı anlamına gelir. GMS cihazları için, bu arayüzleri değiştirmekten kaçınmak, GSI görüntüsünün çalışmaya devam etmesini de sağlar.

Uzantılar iki farklı şekilde kaydedilebilir:

  • zamanında, bkz uzantıları ekli .
  • bağımsız, küresel olarak ve VINTF'de kayıtlı.

Ancak bir uzantı kaydedilir, satıcıya özel (yani yukarı akış AOSP'nin bir parçası olmayan) bileşenler arabirimi kullandığında, birleştirme çakışması olasılığı yoktur. Ancak, yukarı akış AOSP bileşenlerinde aşağı akış değişiklikleri yapıldığında, birleştirme çakışmaları ortaya çıkabilir ve aşağıdaki stratejiler önerilir:

  • arayüz eklemeleri bir sonraki sürümde AOSP'ye yüklenebilir
  • birleştirme çakışmaları olmadan daha fazla esneklik sağlayan arayüz eklemeleri, bir sonraki sürümde yukarı akışa alınabilir

AIDL çalışma zamanına karşı oluşturma

AIDL'nin üç farklı arka ucu vardır: Java, NDK, CPP. Kararlı AIDL kullanmak için, her zaman en libbinder sistem kopyasını kullanmalısınız system/lib*/libbinder.so üzerinde ve konuşma /dev/binder . Satıcı görüntü kod, bu araçlarının libbinder (VNDK dan) kullanılamaz Bu kütüphane, bir kararsız C ++ API ve kararsız iç bölümü vardır. Bunun yerine, yerli satıcı kodu NDK AIDL ait arka uç karşı bağlantıyı kullanmalısınız libbinder_ndk (sistem tarafından desteklenmektedir libbinder.so karşı) ve bağlantı -ndk_platform yarattığı kütüphaneler aidl_interface girdileri.

AIDL HAL sunucu örneği adları

Geleneksel olarak, AIDL HAL hizmetleri biçimi örnek adını sahip $package.$type/$instance . Örneğin, vibratör HAL bir örneği olarak tescil edilmiştir android.hardware.vibrator.IVibrator/default .

AIDL HAL sunucusu yazma

@VintfStability AIDL sunucuları bu gibi örneğin VINTF manifest'te beyan edilmelidir:

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

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

AIDL istemcisi yazma

AIDL istemcileri kendilerini uyumluluk matrisinde beyan etmelidir, örneğin şu şekilde:

    <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

Kullanım hidl2aidl AIDL bir HIDL arayüzü dönüştürmek için aracı.

hidl2aidl özellikleri:

  • Oluşturmak .aidl dayalı dosyaları .hal verilen paket için dosyaları
  • Tüm arka uçların etkinleştirildiği 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ıklara sahip ç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

Bir .hal dosyası paketini .aidl dosyalarına dönüştürmek için şu adımları izleyin:

  1. Bulunan aracını kurmak system/tools/hidl/hidl2aidl .

    Bu aracı en son kaynaktan oluşturmak, en eksiksiz deneyimi sağlar. Önceki sürümlerden daha eski dallardaki arabirimleri dönüştürmek için en son sürümü kullanabilirsiniz.

    m hidl2aidl
    
  2. Aracı bir çıktı dizini ve ardından dönüştürülecek paket ile çalıştırın.

    hidl2aidl -o <output directory> <package>
    

    Örneğin:

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

    • conversion.log ilk düzeltmek için herhangi bir işlenmeyen konuları içermektedir.
    • Oluşturulan .aidl dosyalar kudreti ihtiyacı eylem olduğu uyarı ve önerilerde bulunabilir. Bu yorumlar ile başlayan // .
    • Paketi temizleme ve iyileştirmeler yapma fırsatını yakalayın.
  4. Yalnızca ihtiyacınız olan hedefleri oluşturun.

    • Kullanılmayacak arka uçları devre dışı bırakın. CPP arka uç üzerinde NDK arka uç tercih Görmekten, çalışma zamanını seçerken .
    • Çeviri kitaplıklarını veya bunların oluşturulup kullanılmayacak kodlarından herhangi birini kaldırın.

AIDL HAL'leri için Sepolicy

Satıcı koduna görülebilir bir AIDL hizmet türü olmalıdır vendor_service niteliği. Aksi takdirde, sepolicy yapılandırması diğer AIDL hizmetleriyle aynıdır.

    type hal_power_service, service_manager_type, vendor_service;

Platform tarafından tanımlanan en hizmetler için, doğru türe sahip bir servis bağlam (örneğin, zaten eklenir android.hardware.power.IPower/default zaten olarak işaretlenmiş hal_power_service ). Bir çerçeve istemci birden çok örnek adlarını destekler Ancak, ek örnek adları cihaza özgü ilave edilmelidir service_contexts dosyaları.

    android.hardware.power.IPower/custom_instance u:object_r:hal_power_service:s0

Ekli uzatma arayüzleri

İster doğrudan servis yöneticisine kayıtlı bir üst düzey arayüz isterse bir alt arayüz olsun, herhangi bir bağlayıcı arayüzüne bir uzantı eklenebilir. Bir uzantı alırken, uzantının türünün beklendiği gibi olduğunu onaylamanız gerekir. Uzantılar yalnızca bir bağlayıcıya hizmet eden süreçten ayarlanabilir.

Bir uzantı, mevcut bir HAL'nin işlevselliğini değiştirdiğinde, ekli uzantılar kullanılmalıdır. Tamamen yeni bir işlevsellik gerektiğinde, bu mekanizmanın kullanılmasına gerek yoktur ve doğrudan hizmet yöneticisine bir uzantı arabirimi kaydedilebilir. Ekli uzantı arabirimleri, alt arabirimlere eklendiklerinde en mantıklıdır, çünkü bu hiyerarşiler derin veya çok örnekli olabilir. Başka bir hizmetin bağlayıcı arabirimi hiyerarşisini yansıtmak için genel bir uzantı kullanmak, doğrudan eklenen uzantılara eşdeğer işlevsellik sağlamak için kapsamlı bir defter tutma gerektirir.

Bağlayıcıda bir uzantı ayarlamak için aşağıdaki API'leri kullanın:

  • NDK arka uç olarak: AIBinder_setExtension
  • Java arka uç olarak: android.os.Binder.setExtension
  • CPP arka uç olarak: android::Binder::setExtension

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

  • NDK arka uç olarak: AIBinder_getExtension
  • Java arka uç olarak: android.os.IBinder.getExtension
  • CPP arka uç olarak: android::IBinder::getExtension

Sen belgelerinde bu API'ler için fazla bilgi bulabilirsiniz getExtension gelen arka uç işlev. Uzantılarını nasıl kullanılacağına ilişkin bir örnek bulunabilir donanım / arayüzleri / testler / uzantısı / vibratör .

Başlıca AIDL/HIDL farklılıkları

AIDL HAL'leri veya AIDL HAL arabirimlerini kullanırken, HIDL HAL'leri yazmaya kıyasla farklılıkların farkında olun.

  • AIDL dilinin sözdizimi Java'ya daha yakındır. HIDL sözdizimi C++'a benzer.
  • Tüm AIDL arabirimlerinde yerleşik hata durumları vardır. Bunun yerine özel durum türlerini oluşturma, arayüz dosyaları ve kullanım sürekli durum int'leri oluşturmak EX_SERVICE_SPECIFIC CPP / NDK backends ve ServiceSpecificException Java arka uç.
  • AIDL, bağlayıcı nesneler gönderildiğinde iş parçacığı havuzlarını otomatik olarak başlatmaz. Onlar (bkz El ile başlatılması gereken thread yönetimi ).
  • AIDL kontrolsüz taşıma hataları (HIDL üzerine iptal değil Return kontrolsüz hatalarında düşükle sonlanması).
  • AIDL, dosya başına yalnızca bir tür bildirebilir.
  • AIDL bağımsız değişkenleri, çıktı parametresine ek olarak giriş/çıkış/giriş olarak belirtilebilir ("eşzamanlı geri aramalar" yoktur).
  • AIDL, ilkel tür olarak tutamaç yerine bir fd kullanır.
  • HIDL, uyumsuz değişiklikler için ana sürümleri ve uyumlu değişiklikler için küçük sürümleri kullanır. AIDL'de geriye dönük uyumlu değişiklikler yerinde yapılır. AIDL'nin açık bir ana sürüm kavramı yoktur; bunun yerine, bu paket adlarına dahil edilmiştir. Örneğin, AIDL paket adı kullanabilir bluetooth2 .