يُعيد Android 8 تصميم بنية نظام التشغيل Android لتحديد واجهات واضحة بين
نظام Android الأساسي المستقل عن الجهاز ورمز خاص بالجهاز والمورد.
يُعرِّف نظام Android العديد من هذه الواجهات في شكل واجهات HAL،
تم تحديدها على أنها عناوين C في hardware/libhardware
. يحل HIDL محل هذه
تحتوي واجهات HAL على واجهات مستقرة ذات إصدارات مختلفة، والتي قد تعتمد
واجهات HIDL من جهة الخادم بلغة C++ (الموضّحة أدناه)
Java
تصف الصفحات في هذا القسم استخدامات C++ لواجهات HIDL،
بما في ذلك تفاصيل عن الملفات التي تم إنشاؤها تلقائيًا من شهادة HIDL .hal
الملفات بواسطة المحول البرمجي لـ hidl-gen
وكيفية تجميع هذه الملفات
كيفية دمج هذه الملفات مع كود C++ الذي يستخدمها.
عمليات التنفيذ المتعلقة بالعملاء والخادم
تحتوي واجهات HIDL على عمليات تنفيذ للعميل والخادم:
- العميل لواجهة HIDL هو الرمز الذي يستخدم من خلال استدعاء طرق عليها.
- الخادم هو تنفيذ لواجهة HIDL التي وتلقي المكالمات من العملاء وعرض النتائج (إذا لزم الأمر).
أثناء الانتقال من libhardware
HALs إلى HIDL HALs، يجب أن تكون HAL
يصبح التنفيذ هو الخادم وتصبح العملية التي تستدعي الدخول إلى HAL
للعميل. يمكن أن تخدم آليات التنفيذ التلقائية كلاً من العبور والدمج
HALs ويمكن أن تتغير بمرور الوقت:
الشكل 1. تقدم تطوير HALs القديمة.
إنشاء برنامج HAL
ابدأ بتضمين مكتبات HAL في ملف makefile:
- الماركة:
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) والتي سبق لها إنشاء
ملفات صور ثابتة للخلاصة باستخدام
-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 هنا مستوى تجريد الخلايا البيئي الفعلي.
. عن طريق تسمية البرنامج الثنائي على هذا النحو، يمكن لعملاء الإصدار 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 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 }
يوجد هذا البرنامج الخفي عادةً في $PACKAGE + "-service-suffix"
(لـ
مثل android.hardware.nfc@1.0-service
)، لكن يمكن أن يكون في أي مكان.
يعتمد sepolicy على
وفئة HALs هي التصنيف hal_<module>
(على سبيل المثال،
hal_nfc)
يجب تطبيق هذه السمة على البرنامج الخفي الذي يشغِّل
طبقة تجريد الأجهزة (HAL) معينة (إذا كانت العملية نفسها تخدم العديد من HALs، فإن سمات
تطبيق النموذج الجديد عليها).