Android 8, cihazdan bağımsız Android platformu ile cihaza ve tedarikçiye özel kod arasında net arayüzler tanımlamak için Android OS'i yeniden yapılandırır.
Android, bu tür birçok arayüzü HAL arayüzü biçiminde tanımlar. Bu arayüzler hardware/libhardware
içinde C üstbilgileri olarak tanımlanır. HIDL, bu HAL arayüzlerini C++ (aşağıda açıklanmıştır) veya Java'da istemci ve sunucu tarafı HIDL arayüzleri olabilecek kararlı, sürümlü arayüzlerle değiştirir.
Bu bölümdeki sayfalarda, HIDL arayüzlerinin C++ uygulamaları açıklanmaktadır. Bu açıklamalarda, hidl-gen
derleyicisi tarafından HIDL .hal
dosyalarından otomatik olarak oluşturulan dosyalar, bu dosyaların paketlenmesi ve bu dosyaların bunları kullanan C++ koduyla nasıl entegre edileceği hakkında ayrıntılar yer alır.
İstemci ve sunucu uygulamaları
HIDL arayüzlerinin istemci ve sunucu uygulamaları vardır:
- HIDL arayüzünün istemcisi, arayüzdeki yöntemleri çağırarak arayüzü kullanan koddur.
- Sunucu, istemcilerden çağrı alan ve (gerekirse) sonuçları döndüren bir HIDL arayüzünün uygulamasıdır.
libhardware
HAL'lerinden HIDL HAL'lerine geçişte HAL uygulaması sunucu olur ve HAL'i çağıran süreç istemci olur. Varsayılan uygulamalar hem geçiş hem de bağlayıcı HAL'ler sunabilir ve zaman içinde değişebilir:
Şekil 1. Eski HAL'ler için geliştirme ilerleme durumu.
HAL istemcisini oluşturma
HAL kitaplıklarını makefile'e ekleyerek başlayın:
- Marka:
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
'da -Lmakefile
veya -Landroidbp
kullanarak HAL'iniz için makefile'ler oluşturmuş olmanız gerekir (./hardware/interfaces/update-makefiles.sh
, dahili HAL dosyaları için bunu yapar ve iyi bir referanstır). libhardware
'ten HAL'leri aktarırken bu işin büyük bir kısmını c2hal kullanarak kolayca yapabilirsiniz.
HAL'inizi uygulamak için gerekli dosyaları oluşturmak üzere:
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'ın geçiş modunda çalışması için HIDL_FETCH_IModuleName
işlevinin /(system|vendor|...)/lib(64)?/hw/android.hardware.package@3.0-impl(OPTIONAL_IDENTIFIER).so
içinde bulunması gerekir. Burada OPTIONAL_IDENTIFIER, geçiş uygulamasını tanımlayan bir dizedir. Geçiş modu koşulları, yukarıdaki komutlar tarafından otomatik olarak karşılanır. Bu komutlar android.hardware.nfc@1.0-impl
hedefini de oluşturur ancak herhangi bir uzantı kullanılabilir. Örneğin, android.hardware.nfc@1.0-impl-foo
kendini farklılaştırmak için -foo
kullanır.
Bir HAL, başka bir HAL'ın küçük bir 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ı hâlâ android.hardware.graphics.mapper@2.0-impl(OPTIONAL_IDENTIFIER)
adlı bir ikili programda olmalıdır.
Genellikle buradaki OPTIONAL_IDENTIFIER, gerçek HAL sürümünü içerir. İkili dosyayı bu şekilde adlandırarak 2.0 istemcileri dosyayı doğrudan alabilir ve 2.1 istemcileri de uygulamayı üst sınıfa taşıyabilir.
Ardından, taslakları işlevlerle doldurun ve bir daemon oluşturun. Örnek daemon kodu (geçiş desteği):
#include <hidl/LegacySupport.h> int main(int /* argc */, char* /* argv */ []) { return defaultPassthroughServiceImplementation<INfc>("nfc"); }
defaultPassthroughServiceImplementation
, sağlanan -impl
kitaplığı için dlopen()
'i çağırır ve bu kitaplığı bir bağlayıcı hizmet olarak sağlar. Örnek daemon kodu (saf bağlayıcı 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 never exceeds // 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 daemon genellikle $PACKAGE + "-service-suffix"
(ör. android.hardware.nfc@1.0-service
) içinde bulunur ancak herhangi bir yerde olabilir.
Belirli bir HAL sınıfı için sepolicy, hal_<module>
özelliğidir (örneğin, hal_nfc)
). Bu özellik, belirli bir HAL'i çalıştıran daemon'a uygulanmalıdır (aynı işlem birden fazla HAL sunuyorsa bu işleme birden fazla özellik uygulanabilir).