حزمة HAL متعددة لأجهزة الاستشعار

‫Sensors Multi-HAL هو إطار عمل يتيح تشغيل طبقات HAL الخاصة بأجهزة الاستشعار جنبًا إلى جنب مع طبقات HAL الأخرى الخاصة بأجهزة الاستشعار. يحمّل Sensors Multi-HAL بشكل ديناميكي وحدات HAL الفرعية لأجهزة الاستشعار المخزّنة كمكتبات ديناميكية في قسم المورّد، ويمنحها عنصر معاودة الاتصال الذي يمكنه التعامل مع نشر الأحداث والحصول على قفل التنشيط وإصداره. طبقة تجريد الأجهزة الفرعية الخاصة بأجهزة الاستشعار هي طبقة تجريد أجهزة خاصة بأجهزة الاستشعار مضمّنة في عنصر مشترك على قسم المورّد وتستخدمها بنية multi-HAL. لا تعتمد وحدات HAL الفرعية على بعضها البعض أو على رمز HAL المتعدد الذي يحتوي على الوظيفة الرئيسية للعملية.

الإصدار 2.1 من Sensors Multi-HAL متاح على الأجهزة التي تعمل بنظام التشغيل Android 11 أو الإصدارات الأحدث، وهو إصدار من Sensors Multi-HAL 2.0 يتيح تحميل وحدات HAL الفرعية التي يمكنها عرض نوع مستشعر زاوية المفصلة. ولإتاحة هذا النوع من أجهزة الاستشعار، يجب أن تستخدم حِزم HAL الفرعية واجهات برمجة التطبيقات الخاصة بحِزم HAL الفرعية المحدّدة في عنوان SubHal 2.1.

بالنسبة إلى الأجهزة التي تعمل بالإصدار 13 من نظام التشغيل Android أو الإصدارات الأحدث والتي تستخدم طبقة تجريد الأجهزة (HAL) المستندة إلى لغة تعريف واجهة Android (AIDL) الخاصة بأجهزة الاستشعار، يمكنك استخدام طبقة التوافق متعددة HAL للسماح بإمكانية استخدام عدة طبقات HAL. للاطّلاع على تفاصيل التنفيذ، يُرجى الرجوع إلى استخدام Sensors Multi-HAL مع Sensors AIDL HAL.

الفرق بين Sensors Multi-HAL 2 وSensors HAL 2

توفّر واجهة Sensors Multi-HAL 2، المتوفّرة على الأجهزة التي تعمل بالإصدار 10 من نظام التشغيل Android أو الإصدارات الأحدث، العديد من عمليات التجريد فوق Sensors HAL 2 لتسهيل التفاعل مع واجهات برمجة التطبيقات الخاصة بطبقة HAL. تقدّم Sensors Multi-HAL 2 فئة HalProxy للتعامل مع تنفيذ واجهة Sensors HAL 2 وواجهة V2_1/SubHal (أو V2_0/SubHal) للسماح لـ HalProxy بالتفاعل مع وحدات HAL الفرعية.

تختلف واجهة ISensorsSubHal عن واجهة 2.1/ISensors.hal (أو 2.0/ISensors.hal) في ما يلي:

  • تمرِّر طريقة initialize الفئة IHalProxyCallback بدلاً من اثنين من FMQ وISensorsCallback.
  • يجب أن تنفّذ طبقات HAL الفرعية وظيفة تصحيح الأخطاء لتوفير معلومات تصحيح الأخطاء في تقارير الأخطاء.
  • يجب أن تنفّذ وحدات HAL الفرعية دالة اسم حتى يمكن تمييز وحدة HAL الفرعية التي تم تحميلها عن وحدات HAL الفرعية الأخرى.

يتمثل الاختلاف الرئيسي بين الإصدار 2 من Sensors Multi-HAL والإصدار 2 من Sensors HAL في دوال initialize. بدلاً من توفير FMQ، توفّر الواجهة طريقتَين، إحداهما لنشر أحداث المستشعر إلى إطار عمل المستشعرات والأخرى لإنشاء أقفال تنبيه.IHalProxyCallback في الخلفية، يدير Sensors Multi-HAL جميع التفاعلات مع قوائم FMQ لضمان تسليم أحداث المستشعر في الوقت المناسب لجميع وحدات HAL الفرعية. ننصح بشدة بأن تستخدم وحدات HAL الفرعية طريقة createScopedWakelock لتفويض عبء انتهاء المهلة لأقفال التنشيط إلى Sensors Multi-HAL، ولتجميع استخدام أقفال التنشيط في قفل تنشيط واحد مشترك لوحدة Sensors Multi-HAL بأكملها، ما يقلّل من طلبات القفل وفتح القفل.

يتضمّن الإصدار 2 من Sensors Multi-HAL أيضًا بعض ميزات الأمان المضمّنة. ويتعامل مع الحالات التي تكون فيها قائمة FMQ الخاصة بجهاز الاستشعار ممتلئة أو التي تتم فيها إعادة تشغيل إطار عمل أجهزة الاستشعار في Android ويجب إعادة ضبط حالة جهاز الاستشعار. بالإضافة إلى ذلك، عندما يتم نشر الأحداث إلى الفئة HalProxy ولكن لا يمكن لإطار عمل أجهزة الاستشعار قبول الأحداث على الفور، يمكن أن ينقل Sensors Multi-HAL الأحداث إلى سلسلة محادثات في الخلفية للسماح بمواصلة العمل على جميع وحدات HAL الفرعية أثناء انتظار نشر الأحداث.

الرمز المصدر والتنفيذ المرجعي

يتوفّر رمز All Sensors Multi-HAL في hardware/interfaces/sensors/common/default/2.X/multihal/. في ما يلي بعض المراجع.

  • HalProxy.h: يتم إنشاء العنصر HalProxy من خلال Sensors multi-HAL ويتولّى عملية نقل البيانات من طبقات HAL الفرعية إلى إطار عمل أجهزة الاستشعار.
  • HalProxy.cpp: يحتوي تنفيذ HalProxy على جميع التعليمات البرمجية اللازمة لإجراء عملية إرسال متعدد بين وحدات HAL الفرعية وإطار عمل أداة الاستشعار.
  • SubHal.h: تحدّد واجهة ISensorsSubHal الواجهة التي يجب أن تلتزم بها وحدات HAL الفرعية لتكون متوافقة مع HalProxy. تنفّذ طبقة HAL الفرعية الطريقة initialize لكي يمكن استخدام العنصر HalProxyCallback مع postEvents وcreateScopedWakelock.

    بالنسبة إلى عمليات تنفيذ Multi-HAL 2.0، استخدِم الإصدار 2.0 من SubHal.h.

  • hardware/interfaces/sensors/common/default/2.X/multihal/tests/: تتحقّق اختبارات الوحدات هذه من تنفيذ HalProxy.

  • hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/: يستخدم هذا المثال لتنفيذ HAL الفرعي أجهزة استشعار وهمية لإنشاء بيانات وهمية. مفيدة لاختبار كيفية تفاعل عدة وحدات HAL فرعية على أحد الأجهزة.

التنفيذ

يوضّح هذا القسم كيفية تنفيذ Sensors Multi-HAL في الحالات التالية:

استخدام Sensors Multi-HAL مع Sensors AIDL HAL

للسماح بإمكانية استخدام HAL المتعددة مع Sensors AIDL HAL، استورِد وحدة طبقة التوافق AIDL Multi-HAL، والتي يمكن العثور عليها في hardware/interfaces/sensors/aidl/default/multihal/. يتعامل هذا النموذج مع عملية التحويل بين أنواع تعريف AIDL وHIDL الخاصة بطبقة تجريد الأجهزة (HAL) لأجهزة الاستشعار، كما يعرّف برنامج تضمين حول واجهة HAL المتعددة الموضّحة في تنفيذ واجهة HAL المتعددة لأجهزة الاستشعار 2.1. طبقة التوافق AIDL Multi-HAL متوافقة مع الأجهزة التي تنفِّذ الإصدار 2.1 من Sensors Multi-HAL.

تتيح لك طبقة AIDL متعددة HAL عرض أنواع أجهزة استشعار تتبُّع حركة الرأس ووحدة القياس بالقصور الذاتي (IMU) ذات المحاور المحدودة في Sensors AIDL HAL. لاستخدام أنواع المستشعرات هذه المحدّدة من خلال واجهة AIDL HAL، اضبط الحقل type في بنية SensorInfo في عملية التنفيذ getSensorsList_2_1(). وهذا الإجراء آمن لأنّ حقول أنواع أجهزة الاستشعار المستندة إلى الأعداد الصحيحة في AIDL وHIDL لا تتداخل.

تنفيذ Sensors Multi-HAL 2.1

لتنفيذ Sensors Multi-HAL 2.1 على جهاز جديد، اتّبِع الخطوات التالية:

  1. نفِّذ واجهة ISensorsSubHal كما هو موضّح في SubHal.h.
  2. نفِّذ طريقة sensorsHalGetSubHal_2_1 في SubHal.h.
  3. أضِف هدف cc_library_shared لإنشاء وحدة HAL الفرعية التي تمّ تنفيذها حديثًا. عند إضافة الهدف:

    1. تأكَّد من نقل الهدف إلى مكان ما في قسم المورّد على الجهاز.
    2. في ملف الإعدادات الموجود في /vendor/etc/sensors/hals.conf، أضِف مسار المكتبة في سطر جديد. إذا لزم الأمر، أنشئ الملف hals.conf.

    للاطّلاع على مثال Android.bp لإدخال إنشاء مكتبة HAL فرعية، يُرجى الرجوع إلى hardware/interfaces/sensors/common/default/2.X/multihal/tests/Android.bp.

  4. أزِل جميع إدخالات android.hardware.sensors من ملف manifest.xml الذي يحتوي على قائمة ببرامج HAL المتوافقة على الجهاز.

  5. أزِل جميع ملفات خدمة android.hardware.sensors وملفات service.rc من الملف device.mk وأضِف android.hardware.sensors@2.1-service.multihal وandroid.hardware.sensors@2.1-service.multihal.rc إلى PRODUCT_PACKAGES.

عند التمهيد، يبدأ HalProxy، ويبحث عن HAL الفرعي الذي تم تنفيذه حديثًا، ثم يهيئه عن طريق استدعاء sensorsHalGetSubHal_2_1.

نقل البيانات من Sensors Multi-HAL 2.0 إلى Multi-HAL 2.1

لإجراء نقل من الإصدار 2.0 من Multi-HAL إلى الإصدار 2.1، عليك تنفيذ واجهة SubHal وإعادة تجميع HAL الفرعي.

في ما يلي الاختلافات بين واجهتَي الإصدارَين 2.0 و2.1 من SubHal:

  • تستخدم IHalProxyCallback الأنواع التي تم إنشاؤها في الإصدار 2.1 من مواصفات ISensors.hal.
  • تعرض الدالة initialize() IHalProxyCallback جديدًا بدلاً من الذي تعرضه واجهة 2.0 SubHal
  • يجب أن تنفّذ طبقات HAL الفرعية getSensorsList_2_1 وinjectSensorData_2_1 بدلاً من getSensorsList وinjectSensorData لأنّ هذه الطرق تستخدم الأنواع الجديدة التي تمت إضافتها في الإصدار 2.1 من مواصفات ISensors.hal.
  • يجب أن تعرض وحدات HAL الفرعية sensorsHalGetSubHal_2_1 بدلاً من sensorsHalGetSubHal كي يتعامل معها Multi-HAL كوحدات HAL فرعية بالإصدار 2.1.

نقل البيانات من Sensors HAL 2.0

عند الترقية إلى الإصدار 2.0 من Sensors Multi-HAL من الإصدار 2.0 من Sensors HAL، تأكَّد من أنّ تنفيذ HAL يستوفي المتطلبات التالية.

إعداد طبقة HAL

يحتوي الإصدار 2.0 من طبقة تجريد الأجهزة (HAL) الخاصة بأدوات الاستشعار على دالة تهيئة تتيح لخدمة أدوات الاستشعار تمرير قوائم انتظار الرسائل السريعة (FMQ) وبرنامج معالجة ديناميكي لأدوات الاستشعار. في الإصدار 2.0 من Sensors Multi-HAL، تمرِّر الدالة initialize() عملية ردّ نداء واحدة يجب استخدامها لنشر أحداث أجهزة الاستشعار والحصول على أقفال التنشيط والإبلاغ عن عمليات الربط والفصل بين أجهزة الاستشعار الديناميكية.

إرسال أحداث المستشعر إلى تنفيذ Multi-HAL

بدلاً من نشر أحداث المستشعر من خلال FMQ، يجب أن يكتب HAL الفرعي أحداث المستشعر إلى IHalProxyCallback عند توفّر أحداث المستشعر.

أحداث WAKE_UP

في Sensors HAL 2.0، يمكن لطبقة HAL إدارة قفل التنشيط لتنفيذها. في الإصدار 2.0 من Sensors Multi-HAL، تتيح وحدات HAL الفرعية تنفيذ Multi-HAL لإدارة عمليات قفل التنشيط، ويمكنها طلب الحصول على قفل تنشيط من خلال استدعاء createScopedWakelock. يجب الحصول على قفل تنشيط ذي نطاق محدد ومقفول وتمريره إلى postEvents عند نشر أحداث التنشيط إلى تنفيذ Multi-HAL.

أجهزة الاستشعار الديناميكية

يتطلّب الإصدار 2.0 من Sensors Multi-HAL استدعاء onDynamicSensorsConnected وonDynamicSensorsDisconnected في IHalProxyCallback كلما تغيّرت اتصالات المستشعر الديناميكي. تتوفّر عمليات رد الاتصال هذه كجزء من مؤشر IHalProxyCallback الذي يتم توفيره من خلال الدالة initialize().

نقل البيانات من Sensors HAL 1.0

عند الترقية إلى الإصدار 2.0 من Sensors Multi-HAL من الإصدار 1.0 من Sensors HAL، تأكَّد من أنّ تنفيذ HAL يستوفي المتطلبات التالية.

إعداد طبقة HAL

يجب توفير الدعم للدالة initialize() من أجل إنشاء رد الاتصال بين وحدة HAL الفرعية وتنفيذ Multi-HAL.

عرض أجهزة الاستشعار المتاحة

في الإصدار 2.0 من Sensors Multi-HAL، يجب أن تعرض الدالة getSensorsList() القيمة نفسها أثناء عملية إعادة تشغيل واحدة للجهاز، حتى عند إعادة تشغيل Sensors HAL. ويتيح ذلك للإطار محاولة إعادة إنشاء اتصالات المستشعر في حال إعادة تشغيل خادم النظام. يمكن أن تتغيّر القيمة التي تعرضها getSensorsList() بعد إعادة تشغيل الجهاز.

إرسال أحداث المستشعر إلى تنفيذ Multi-HAL

في Sensors HAL 2.0، بدلاً من انتظار استدعاء poll()، يجب أن يكتب HAL الفرعي أحداث أجهزة الاستشعار بشكل استباقي إلى IHalProxyCallback كلما توفّرت أحداث أجهزة الاستشعار.

أحداث WAKE_UP

في Sensors HAL 1.0، يمكن أن يدير HAL قفل التنشيط لتنفيذه. في Sensors Multi-HAL 2.0، تتيح وحدات HAL الفرعية تنفيذ Multi-HAL لإدارة عمليات قفل التنشيط، ويمكنها طلب الحصول على عملية قفل تنشيط من خلال استدعاء createScopedWakelock. يجب الحصول على قفل تنشيط ذي نطاق محدد ومقفول وتمريره إلى postEvents عند نشر أحداث التنشيط إلى تنفيذ Multi-HAL.

أجهزة الاستشعار الديناميكية

في Sensors HAL 1.0، يتم عرض أجهزة الاستشعار الديناميكية من خلال الدالة poll(). يتطلّب الإصدار 2.0 من Sensors Multi-HAL استدعاء onDynamicSensorsConnected وonDynamicSensorsDisconnected في IHalProxyCallback كلما تغيّرت اتصالات المستشعر الديناميكي. تتوفّر عمليات رد الاتصال هذه كجزء من مؤشر IHalProxyCallback الذي يتم توفيره من خلال الدالة initialize().

نقل البيانات من الإصدار 1.0 من Sensors Multi-HAL

لنقل عملية تنفيذ حالية من Sensors Multi-HAL 1.0، اتّبِع الخطوات التالية.

  1. تأكَّد من أنّ إعدادات HAL لأدوات الاستشعار تقع في /vendor/etc/sensors/hals.conf. قد يتضمّن ذلك نقل الملف الموجود في /system/etc/sensors/hals.conf.
  2. أزِل أي إشارات إلى hardware/hardware.h و hardware/sensors.h لأنّها غير متاحة في HAL 2.0.
  3. نقل وحدات HAL الفرعية كما هو موضّح في نقل البيانات من Sensors Hal 1.0
  4. اضبط Sensors Multi-HAL 2.0 كطبقة HAL المحدّدة باتّباع الخطوتَين 3 و4 في قسم تنفيذ Sensors Multi-HAL 2.0.

التحقُّق

تشغيل VTS

عند دمج واحد أو أكثر من طبقات HAL الفرعية مع Sensors Multi-Hal 2.1، استخدِم مجموعة اختبارات المورّد (VTS) للتأكّد من أنّ عمليات تنفيذ طبقات HAL الفرعية تستوفي جميع المتطلبات التي تحدّدها واجهة Sensors HAL.

لتشغيل اختبارات VTS الخاصة بأجهزة الاستشعار فقط عند إعداد VTS على جهاز مضيف، نفِّذ الأوامر التالية:

vts-tradefed run commandAndExit vts \
    --skip-all-system-status-check \
    --primary-abi-only \
    --skip-preconditions \
    --module VtsHalSensorsV2_0Target && \
  vts-tradefed run commandAndExit vts \
    --skip-all-system-status-check \
    --primary-abi-only \
    --skip-preconditions \
    --module VtsHalSensorsV2_1Target

إذا كنت تستخدم طبقة التوافق AIDL Multi-HAL، شغِّل VtsAidlHalSensorsTargetTest.

vts-tradefed run commandAndExit vts \
    --skip-all-system-status-check \
    --primary-abi-only \
    --skip-preconditions \
    --module VtsAidlHalSensorsTargetTest

تنفيذ اختبارات الوحدات

تختبر اختبارات الوحدات في HalProxy_test.cpp HalProxy باستخدام وحدات فرعية مزيفة من طبقة HAL يتم إنشاء مثيل لها في اختبار الوحدات ولا يتم تحميلها بشكل ديناميكي. عند إنشاء وحدة HAL فرعية جديدة، يجب أن تكون هذه الاختبارات بمثابة دليل حول كيفية إضافة اختبارات الوحدات التي تتحقّق من تنفيذ وحدة HAL الفرعية الجديدة بشكل صحيح.

لتشغيل الاختبارات، نفِّذ الأوامر التالية:

cd $ANDROID_BUILD_TOP/hardware/interfaces/sensors/common/default/2.X/multihal/tests
atest

الاختبار باستخدام طبقات HAL الفرعية الوهمية

برامج HAL الفرعية الزائفة هي عمليات تنفيذ وهمية لواجهة ISensorsSubHal. تعرض طبقات HAL الفرعية قوائم مختلفة من أجهزة الاستشعار. عند تفعيل أجهزة الاستشعار، تنشر هذه الأجهزة بشكل دوري أحداث أجهزة الاستشعار التي يتم إنشاؤها تلقائيًا إلى HalProxy استنادًا إلى الفواصل الزمنية المحدّدة في طلب جهاز استشعار معيّن.

يمكن استخدام وحدات HAL الفرعية الوهمية لاختبار طريقة عمل رمز Multi-HAL الكامل مع وحدات HAL الفرعية الأخرى التي تم تحميلها في النظام، وللتحقّق من جوانب مختلفة من رمز Multi-HAL الخاص بأجهزة الاستشعار.

يتوفّر اثنان من برامج HAL الفرعية الوهمية في hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/.

لإنشاء وحدات HAL الفرعية الوهمية ونقلها إلى جهاز، اتّبِع الخطوات التالية:

  1. نفِّذ الأوامر التالية لإنشاء ودفع ثلاث وحدات فرعية مختلفة وهمية من طبقة HAL إلى الجهاز:

    $ANDROID_BUILD_TOP/hardware/interfaces/sensors/common/default/2.X/multihal/tests/
    mma
    adb push \
      $ANDROID_BUILD_TOP/out/target/product/<device>/symbols/vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config1.so \
      /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config1.so
    adb push \
      $ANDROID_BUILD_TOP/out/target/product/<device>/symbols/vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config2.so \
      /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config2.so
    adb push \
      $ANDROID_BUILD_TOP/out/target/product/<device>/symbols/vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config3.so \
      /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config3.so
  2. عدِّل إعدادات HAL لأجهزة الاستشعار في /vendor/etc/sensors/hals.conf باستخدام مسارات أجهزة sub-HAL الوهمية.

    /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config1.so
    /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config2.so
    /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config3.so
    
  3. أعِد تشغيل HalProxy وحمِّل وحدات HAL الفرعية الجديدة المُدرَجة في ملف الإعداد.

    adb shell stop
    adb shell start

تصحيح الأخطاء

يمكن للمطوّرين تصحيح إطار العمل من خلال استخدام الأمر lshal. لطلب إخراج تصحيح الأخطاء من Sensors HAL، نفِّذ الأمر التالي:

adb root
adb shell lshal debug android.hardware.sensors@2.1::ISensors/default

بعد ذلك، يتم عرض معلومات عن الحالة الحالية لـ HalProxy ونظام التشغيل الفرعي HAL في الجهاز. في ما يلي مثال على ناتج الأمر الخاص بالكائن HalProxy وHAL الفرعية الوهمية.

Internal values:
  Threads are running: true
  Wakelock timeout start time: 200 ms ago
  Wakelock timeout reset time: 73208 ms ago
  Wakelock ref count: 0
  # of events on pending write queue: 0
  # of non-dynamic sensors across all subhals: 8
  # of dynamic sensors across all subhals: 0
SubHals (2):
  Name: FakeSubHal-OnChange
  Debug dump:
Available sensors:
Name: Ambient Temp Sensor
Min delay: 40000
Flags: 2
Name: Light Sensor
Min delay: 200000
Flags: 2
Name: Proximity Sensor
Min delay: 200000
Flags: 3
Name: Relative Humidity Sensor
Min delay: 40000
Flags: 2
  Name: FakeSubHal-OnChange
  Debug dump:
Available sensors:
Name: Ambient Temp Sensor
Min delay: 40000
Flags: 2
Name: Light Sensor
Min delay: 200000
Flags: 2
Name: Proximity Sensor
Min delay: 200000
Flags: 3
Name: Relative Humidity Sensor
Min delay: 40000
Flags: 2

إذا كان الرقم المحدّد لـ # of events on pending write queue رقمًا كبيرًا (1000 أو أكثر)، يشير ذلك إلى وجود العديد من الأحداث المعلقة التي سيتم تسجيلها في إطار عمل أجهزة الاستشعار. تشير هذه الحالة إلى أنّ خدمة المستشعر في حالة توقّف تام أو تعذّر الوصول إليها، وأنّها لا تعالج أحداث المستشعر، أو أنّه تم مؤخرًا نشر مجموعة كبيرة من أحداث المستشعر من طبقة HAL فرعية.

إذا كان عدد مراجع قفل التنشيط أكبر من 0، يعني ذلك أنّ HalProxy قد حصل على قفل تنشيط. يجب أن تكون هذه القيمة أكبر من 0 فقط إذا تم حظر ScopedWakelock عمدًا أو إذا تم إرسال أحداث التنشيط إلى HalProxy ولم تتم معالجتها بواسطة إطار عمل المستشعر.

يتم تمرير واصف الملف الذي تم تمريره إلى طريقة تصحيح الأخطاء في HalProxy إلى كل وحدة HAL فرعية، لذا يجب أن ينفّذ المطوّرون طريقة تصحيح الأخطاء كجزء من واجهة ISensorsSubHal.