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 tasarlıyor. Android hardware/libhardware C üstbilgileri olarak tanımlanan HAL arabirimleri biçiminde bu tür birçok arabirimi zaten tanımlamaktadır. HIDL, bu HAL arayüzlerini, C++ (aşağıda açıklanmıştır) veya Java'daki istemci ve sunucu tarafı HIDL arayüzleri olabilen kararlı, sürümlendirilmiş arayüzlerle değiştirir.

Bu bölümdeki sayfalarda, 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 tümleştirileceği hakkında ayrıntılar da dahil olmak üzere, HIDL arabirimlerinin C++ uygulamaları açıklanmaktadır. onları kullanır.

İstemci ve sunucu uygulamaları

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

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

libhardware HAL'lerinden HIDL HAL'lere geçişte, HAL uygulaması sunucu haline gelir ve HAL'i çağıran süreç istemci olur. Varsayılan uygulamalar hem doğrudan geçişli hem de bağlayıcı hale getirilmiş HAL'lere hizmet edebilir ve zaman içinde değişebilir:

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

HAL istemcisini oluşturma

HAL kitaplıklarını makefile'a dahil ederek başlayın:

  • Yapım: LOCAL_SHARED_LIBRARIES += android.hardware.nfc@1.0
  • Kısa süre önce: shared_libs: [ …, android.hardware.nfc@1.0 ]

Daha sonra 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 -Lmakefile veya -Landroidbp kullanarak HAL'iniz için makefile dosyaları oluşturmuş olmanız gerekir ( ./hardware/interfaces/update-makefiles.sh bunu şunun için yapar: dahili HAL dosyalarıdır ve iyi bir referanstır). libhardware HAL'ler üzerinden aktarım yaparken bu işin çoğunu c2hal kullanarak kolayca yapabilirsiniz.

HAL'inizi uygulamak üzere 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 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, aynı zamanda 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'in 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ı 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. İkili dosyayı bu şekilde adlandırarak, 2.0 istemcileri onu doğrudan alabilir ve 2.1 istemcileri uygulamayı yükseltebilir.

Daha sonra, taslakları işlevsellik ile 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() yapacak ve onu bağlayıcı bir hizmet olarak sağlayacaktır. Örnek arka plan programı kodu (saf bağlayıcılaştırılmış 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 bulunur, ancak herhangi bir yerde olabilir. Belirli bir HAL sınıfı için sepolicy hal_<module> (örneğin, hal_nfc) özelliğidir. Bu öznitelik, belirli bir HAL'yi çalıştıran arka plan programına uygulanmalıdır (aynı süreç birden fazla HAL'ye hizmet ediyorsa, ona birden çok öznitelik uygulanabilir).