HIDL C ++

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 zaten hardware/libhardware C başlıkları olarak tanımlanan HAL arabirimleri biçiminde hardware/libhardware . HIDL, bu HAL arayüzlerini, C ++ (aşağıda açıklanmıştır) veya Java'da istemci ve sunucu tarafı HIDL arayüzleri olabilen kararlı, sürümlü arayüzlerle değiştirir.

Bu bölümdeki sayfalar HIDL arayüzlerinin C ++ uygulamalarını, 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, onları kullanıyor.

İstemci ve sunucu uygulamaları

HIDL arayüzlerinin istemci ve sunucu uygulamaları vardır:

  • Bir HIDL arabiriminin istemcisi , arabirimi üzerinde yöntemleri çağırarak kullanan koddur.
  • Sunucu , istemcilerden gelen çağrıları alan ve sonuçları döndüren (gerekirse) bir HIDL arayüzünün bir uygulamasıdır.

libhardware HAL'lerinden HIDL libhardware geçişte, HAL uygulaması sunucu olur ve HAL'yi çağıran süreç istemci olur. Varsayılan uygulamalar hem geçiş hem de bağlayıcı hale getirilmiş HAL'ler sunabilir ve zamanla değişebilir:

Şekil 1. Eski HAL'ler için geliştirme ilerlemesi.

HAL istemcisini oluşturma

Makefile'a HAL kitaplıklarını 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 sunucusunun oluşturulması

HAL uygulamasını oluşturmak için, .hal temsil eden .hal dosyalarına sahip -Landroidbp ve hidl-gen üzerinde hidl-gen veya -Landroidbp kullanarak -Lmakefile için makefiles oluşturmuş olmanız gerekir ( ./hardware/interfaces/update-makefiles.sh bunu için yapar dahili HAL dosyaları ve iyi bir referanstır). libhardware HAL'leri libhardware , bu işlerin çoğunu c2hal'ı kullanarak kolayca yapabilirsiniz.

HAL'nizi 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'ın geçiş modunda çalışması için, /(system|vendor|...)/lib(64)?/hw/android.hardware.package@3.0-impl( OPTIONAL_IDENTIFIER ).so içinde 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, küçük bir sürüm veya başka bir HAL'nin bir uzantısı ise, bu ikiliyi adlandırmak için temel HAL kullanılmalıdır. Örneğin, android.hardware.graphics.mapper@2.1 uygulamaları yine de android.hardware.graphics.mapper@2.0-impl( OPTIONAL_IDENTIFIER ) adlı bir ikili android.hardware.graphics.mapper@2.0-impl( OPTIONAL_IDENTIFIER ) 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 doğrudan alabilir ve 2.1 istemcileri uygulamayı yukarı yayınlayabilir.

Ardından, koçanları işlevsellikle doldurun ve bir arka plan programı kurun. Örnek arka plan programı kodu (geçişi destekler):

#include <hidl/LegacySupport.h>

int main(int /* argc */, char* /* argv */ []) {
    return defaultPassthroughServiceImplementation<INfc>("nfc");
}

defaultPassthroughServiceImplementation , sağlanan -impl kitaplığını dlopen() ve ciltlenmiş bir hizmet olarak sağlar. Örnek arka plan programı kodu (salt ciltlenmiş 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 ) 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ı süreç birden çok HAL'a hizmet ediyorsa, ona birden çok öznitelik uygulanabilir).