HIDL C ++ ، HIDL C ++

يعمل Android O على إعادة تصميم نظام التشغيل Android لتحديد واجهات واضحة بين نظام Android الأساسي المستقل عن الجهاز والتعليمات البرمجية الخاصة بالجهاز والبائع. يقوم Android بالفعل بتعريف العديد من هذه الواجهات في شكل واجهات HAL، والتي يتم تعريفها على أنها رؤوس C في hardware/libhardware . يستبدل HIDL واجهات HAL هذه بواجهات مستقرة ذات إصدار، والتي يمكن أن تكون واجهات HIDL من جانب العميل والخادم في C++ (الموصوفة أدناه) أو Java .

تصف الصفحات الموجودة في هذا القسم تطبيقات C++ لواجهات HIDL، بما في ذلك تفاصيل حول الملفات التي تم إنشاؤها تلقائيًا من ملفات HIDL .hal بواسطة مترجم hidl-gen ، وكيفية حزم هذه الملفات، وكيفية دمج هذه الملفات مع كود C++ الذي يستخدمها.

تطبيقات العميل والخادم

تحتوي واجهات HIDL على تطبيقات العميل والخادم:

  • عميل واجهة HIDL هو الكود الذي يستخدم الواجهة عن طريق استدعاء الأساليب الموجودة عليها.
  • الخادم هو تطبيق لواجهة HIDL التي تتلقى المكالمات من العملاء وتعيد النتائج (إذا لزم الأمر).

عند الانتقال من HALs libhardware إلى HIDL HALs، يصبح تطبيق HAL هو الخادم وتصبح العملية التي تستدعي HAL هي العميل. يمكن أن تخدم التطبيقات الافتراضية كلاً من طبقات HAL للمرور والربط، ويمكن أن تتغير بمرور الوقت:

الشكل 1. التقدم في تطوير HALs القديمة.

إنشاء عميل HAL

ابدأ بتضمين مكتبات HAL في ملف التعريف:

  • الصنع: LOCAL_SHARED_LIBRARIES += android.hardware.nfc@1.0
  • سونغ: shared_libs: [ …, android.hardware.nfc@1.0 ]

بعد ذلك، قم بتضمين ملفات رأس HAL:

#include <android/hardware/nfc/1.0/IFoo.h>
…
// in code:
sp<IFoo> client = IFoo::getService();
client->doThing();

إنشاء خادم HAL

لإنشاء تطبيق HAL، يجب أن يكون لديك ملفات .hal التي تمثل طبقة HAL الخاصة بك وأن تكون قد قمت بالفعل بإنشاء ملفات تكوين لطبقة HAL الخاصة بك باستخدام -Lmakefile أو -Landroidbp على hidl-gen ( ./hardware/interfaces/update-makefiles.sh يقوم بذلك من أجل ملفات HAL الداخلية وهي مرجع جيد). عند النقل عبر HALs من libhardware ، يمكنك القيام بالكثير من هذا العمل بسهولة باستخدام c2hal.

لإنشاء الملفات الضرورية لتنفيذ HAL الخاص بك:

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 في وضع العبور، يجب أن تكون لديك الدالة HIDL_FETCH_IModuleName الموجودة في /(system|vendor|...)/lib(64)?/hw/android.hardware.package@3.0-impl( OPTIONAL_IDENTIFIER ).so حيث OPTIONAL_IDENTIFIER عبارة عن سلسلة تحدد تنفيذ العبور. يتم استيفاء متطلبات وضع العبور تلقائيًا من خلال الأوامر المذكورة أعلاه، والتي تنشئ أيضًا الهدف android.hardware.nfc@1.0-impl ، ولكن يمكن استخدام أي امتداد. على سبيل المثال، يستخدم android.hardware.nfc@1.0-impl-foo -foo لتمييز نفسه.

إذا كانت نسخة HAL إصدارًا ثانويًا أو امتدادًا لنسخة HAL أخرى، فيجب استخدام طبقة HAL الأساسية لتسمية هذا الثنائي. على سبيل المثال، يجب أن تظل تطبيقات android.hardware.graphics.mapper@2.1 في ملف ثنائي يسمى android.hardware.graphics.mapper@2.0-impl( OPTIONAL_IDENTIFIER ) . عادة، سيتضمن OPTIONAL_IDENTIFIER هنا إصدار HAL الفعلي. من خلال تسمية الثنائي بهذه الطريقة، يمكن لعملاء 2.0 استرداده مباشرة، ويمكن لعملاء 2.1 تحديث التنفيذ.

بعد ذلك، قم بملء بذرة بالوظيفة وقم بإعداد البرنامج الخفي. مثال على الكود الخفي (يدعم العبور):

#include <hidl/LegacySupport.h>

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

سوف يقوم defaultPassthroughServiceImplementation dlopen() مكتبة -impl المتوفرة وتوفيرها كخدمة مربوطة. مثال على الكود الخفي (للخدمة المربوطة النقية):

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
}

عادةً ما يوجد هذا البرنامج الخفي في $PACKAGE + "-service-suffix" (على سبيل المثال، android.hardware.nfc@1.0-service )، ولكنه قد يكون في أي مكان. إن خصوصية فئة معينة من HALs هي السمة hal_<module> (على سبيل المثال، hal_nfc) . يجب تطبيق هذه السمة على البرنامج الخفي الذي يقوم بتشغيل طبقة هال (HAL) معينة (إذا كانت نفس العملية تخدم طبقات HAL متعددة، فيمكن تطبيق سمات متعددة عليها).