Android O, cihazdan bağımsız Android platformu ile cihaza ve satıcıya özel kod arasında net arayüzler tanımlamak için Android işletim sistemini yeniden tasarlar. Android, bu tür birçok arabirimi, hardware/libhardware
C başlıkları olarak tanımlanan HAL arabirimleri biçiminde zaten tanımlar. HIDL, bu HAL arabirimlerini, C++ (aşağıda açıklanmıştır) veya Java'da istemci ve sunucu tarafı HIDL arabirimleri olabilen kararlı, sürümlü arabirimlerle değiştirir.
Bu bölümdeki sayfalar, hidl-gen
derleyicisi tarafından HIDL .hal
dosyalarından otomatik olarak oluşturulan dosyalar, bu dosyaların nasıl paketlendiği ve bu dosyaların C++ koduyla nasıl entegre edileceği hakkında ayrıntılar dahil olmak üzere HIDL arabirimlerinin C++ uygulamalarını açıklar. onları kullanır.
İstemci ve sunucu uygulamaları
HIDL arayüzleri, istemci ve sunucu uygulamalarına sahiptir:
- Bir HIDL arabiriminin istemcisi , arabirim üzerindeki yöntemleri çağırarak arabirimi kullanan koddur.
- Sunucu , istemcilerden gelen çağrıları alan ve (gerekirse) sonuçları döndüren bir HIDL arabiriminin bir uygulamasıdır.
libhardware
HAL'lerinden HIDL HAL'lere geçişte, HAL uygulaması sunucu olur ve HAL'ı çağıran süreç istemci olur. Varsayılan uygulamalar hem doğrudan geçiş hem de ciltlenmiş HAL'ler sunabilir ve zamanla değişebilir:
Şekil 1. Eski HAL'ler için geliştirme ilerlemesi.
HAL istemcisini oluşturma
HAL kitaplıklarını makefile'e ekleyerek başlayın:
- Yapın:
LOCAL_SHARED_LIBRARIES += android.hardware.nfc@1.0
- Soong:
shared_libs: [ …, android.hardware.nfc@1.0 ]
Ardından, HAL başlık dosyalarını ekleyin:
#include <android/hardware/nfc/1.0/IFoo.h> … // in code: sp<IFoo> client = IFoo::getService(); client->doThing();
HAL sunucusunu oluşturma
HAL uygulamasını oluşturmak için, HAL'inizi temsil eden .hal
dosyalarına sahip olmanız ve hidl-gen
üzerinde -Lmakefile veya -Landroidbp
kullanarak -Lmakefile
için makefile'ler oluşturmuş olmanız gerekir ( ./hardware/interfaces/update-makefiles.sh
bunu aşağıdakiler için yapar: dahili HAL dosyalarıdır ve iyi bir referanstır). libhardware
kullanarak bu işlerin çoğunu kolayca yapabilirsiniz.
HAL'inizi uygulamak için gerekli dosyaları oluşturmak için:
PACKAGE=android.hardware.nfc@1.0 LOC=hardware/interfaces/nfc/1.0/default/ m -j hidl-gen hidl-gen -o $LOC -Lc++-impl -randroid.hardware:hardware/interfaces \ -randroid.hidl:system/libhidl/transport $PACKAGE hidl-gen -o $LOC -Landroidbp-impl -randroid.hardware:hardware/interfaces \ -randroid.hidl:system/libhidl/transport $PACKAGE
HAL'in geçiş modunda çalışması için, /(system|vendor|...)/lib(64)?/hw/android.hardware.package@3.0-impl( OPTIONAL_IDENTIFIER ).so
bulunan HIDL_FETCH_IModuleName işlevine sahip olmanız gerekir. burada OPTIONAL_IDENTIFIER , geçiş uygulamasını tanımlayan bir dizedir. Geçiş modu gereksinimleri, android.hardware.nfc@1.0-impl
hedefini de oluşturan yukarıdaki komutlar tarafından otomatik olarak karşılanır, ancak herhangi bir uzantı kullanılabilir. Örneğin android.hardware.nfc@1.0-impl-foo
, kendisini farklılaştırmak için -foo
kullanır.
Bir HAL, başka bir HAL'ın alt sürümü veya uzantısıysa, bu ikili dosyayı adlandırmak için temel HAL kullanılmalıdır. Örneğin, android.hardware.graphics.mapper@2.1
uygulamaları hala android.hardware.graphics.mapper@2.0-impl( OPTIONAL_IDENTIFIER )
adlı bir ikili dosyada olmalıdır. Genellikle, buradaki OPTIONAL_IDENTIFIER , gerçek HAL sürümünü içerir. İkiliyi bu şekilde adlandırarak, 2.0 istemciler onu doğrudan alabilir ve 2.1 istemciler uygulamayı yükseltebilir.
Ardından, taslakları işlevsellikle doldurun ve bir arka plan programı kurun. Örnek arka plan programı kodu (geçiş desteği):
#include <hidl/LegacySupport.h> int main(int /* argc */, char* /* argv */ []) { return defaultPassthroughServiceImplementation<INfc>("nfc"); }
defaultPassthroughServiceImplementation
, sağlanan -impl
kitaplığını dlopen()
yapacak ve onu bir ciltlenmiş hizmet olarak sağlayacaktır. Örnek arka plan programı kodu (saf ciltleştirilmiş hizmet için):
int main(int /* argc */, char* /* argv */ []) { // This function must be called before you join to ensure the proper // number of threads are created. The threadpool will never exceed // size one because of this call. ::android::hardware::configureRpcThreadpool(1 /*threads*/, true /*willJoin*/); sp<INfc> nfc = new Nfc(); const status_t status = nfc->registerAsService(); if (status != ::android::OK) { return 1; // or handle error } // Adds this thread to the threadpool, resulting in one total // thread in the threadpool. We could also do other things, but // would have to specify 'false' to willJoin in configureRpcThreadpool. ::android::hardware::joinRpcThreadpool(); return 1; // joinRpcThreadpool should never return }
Bu arka plan programı genellikle $PACKAGE + "-service-suffix"
(örneğin, android.hardware.nfc@1.0-service
) içinde yaşar, ancak herhangi bir yerde olabilir. Belirli bir HAL sınıfı için sepolicy , hal_<module>
özniteliğidir (örneğin, hal_nfc)
. Bu öznitelik, belirli bir HAL'ı çalıştıran arka plan programına uygulanmalıdır (aynı işlem birden çok HAL'e hizmet ediyorsa, ona birden çok öznitelik uygulanabilir).