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

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

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

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

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

يقدّم Sensors Multi-HAL 2، المتوفّر على الأجهزة التي تعمل بالإصدار Android 10 أو إصدار أحدث، العديد من التجريدات فوق 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) بالطرق التالية:

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

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

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

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

يتوفّر كل رمز 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 الفرعية طريقة الإعداد حتى يمكن استخدام عنصر 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

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

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

لنقل البيانات من Multi-HAL 2.0 إلى Multi-HAL 2.1، نفِّذ واجهة SubHal وأعِد تجميع وحدة HAL الفرعية.

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

  • تستخدم IHalProxyCallback الأنواع التي تم إنشاؤها في الإصدار 2.1 من مواصفات ISensors.hal.
  • تُمرِّر الدالة initialize() عنصرًا جديدًا IHalProxyCallback بدلاً من العنصر من واجهة SubHal 2.0.
  • يجب أن تنفّذ وحدات 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

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

إعداد HAL

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

نشر أحداث أجهزة الاستشعار في تنفيذ Multi-HAL

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

أحداث WAKE_UP

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

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

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

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

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

إعداد HAL

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

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

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

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

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

  1. تأكَّد من أنّ إعدادات Sensors 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 Mutli-HAL 2.0.

التحقق من صحة البيانات

تشغيل VTS

عند دمج وحدة HAL فرعية واحدة أو أكثر مع Sensors Multi-Hal 2.1، استخدِم Vendor Test Suite (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 الفرعية الأخرى التي تم تحميلها في النظام، وللتحقق من جوانب مختلفة من رمز Sensors 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. عدِّل إعدادات Sensors HAL في /vendor/etc/sensors/hals.conf باستخدام مسارات وحدات 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.