سنسورهای Multi-HAL

Sensors Multi-HAL چارچوبی است که به HALهای حسگر اجازه می‌دهد در کنار HALهای حسگر دیگر اجرا شوند. Sensors Multi-HAL به صورت پویا HALهای حسگر ذخیره شده به عنوان کتابخانه‌های پویا را در پارتیشن فروشنده بارگذاری می‌کند و به آنها یک شیء callback می‌دهد که می‌تواند رویدادهای ارسال و دریافت و آزادسازی قفل بیداری را مدیریت کند. یک HAL حسگر، HAL حسگری است که در یک شیء مشترک در پارتیشن فروشنده ساخته شده است و توسط چارچوب multi-HAL استفاده می‌شود. این HALهای فرعی به یکدیگر یا به کد multi-HAL که شامل تابع اصلی فرآیند است، وابسته نیستند.

Sensors Multi-HAL 2.1 که در دستگاه‌های دارای اندروید ۱۱ یا بالاتر موجود است، نسخه‌ای از Sensors Multi-HAL 2.0 است که از بارگذاری sub-HALهایی که می‌توانند نوع حسگر زاویه لولا را نمایش دهند، پشتیبانی می‌کند. برای پشتیبانی از این نوع حسگر، sub-HALها باید از APIهای sub-HAL تعریف شده در هدر SubHal 2.1 استفاده کنند.

برای دستگاه‌هایی که اندروید ۱۳ یا بالاتر دارند و از Sensors AIDL HAL استفاده می‌کنند، می‌توانید از لایه شیم multi-HAL برای فعال کردن قابلیت multi-HAL استفاده کنید. برای جزئیات پیاده‌سازی، به بخش «استفاده از Sensors Multi-HAL با Sensors AIDL HAL» مراجعه کنید.

تفاوت بین سنسورهای Multi-HAL 2 و سنسورهای HAL 2

Sensors Multi-HAL 2 که در دستگاه‌های دارای اندروید ۱۰ یا بالاتر موجود است، چندین انتزاع را بر روی Sensors HAL 2 معرفی می‌کند تا تعامل با APIهای HAL را آسان‌تر کند. Sensors Multi-HAL 2 کلاس HalProxy را برای مدیریت پیاده‌سازی رابط Sensors HAL 2 و رابط V2_1/SubHal (یا V2_0/SubHal ) معرفی می‌کند تا به HalProxy اجازه دهد با sub-HALها تعامل داشته باشد.

رابط ISensorsSubHal با رابط 2.1/ISensors.hal (یا 2.0/ISensors.hal ) از جهات زیر متفاوت است:

  • متد initialize به جای دو FMQ و ISensorsCallback یک کلاس IHalProxyCallback ارسال می‌کند.
  • زیرمجموعه‌های HAL باید یک تابع اشکال‌زدایی برای ارائه اطلاعات اشکال‌زدایی در گزارش‌های اشکال پیاده‌سازی کنند.
  • زیر-HALها باید یک تابع نام را پیاده‌سازی کنند تا زیر-HAL بارگذاری‌شده از سایر زیر-HALها قابل تشخیص باشد.

تفاوت اصلی بین Sensors Multi-HAL 2 و Sensors HAL 2 در توابع مقداردهی اولیه است. رابط IHalProxyCallback به جای ارائه FMQها، دو روش ارائه می‌دهد، یک روش برای ارسال رویدادهای حسگر به چارچوب حسگرها و یک روش برای ایجاد قفل‌های بیدارباش. در باطن، Sensors Multi-HAL تمام تعاملات با FMQها را مدیریت می‌کند تا از تحویل به موقع رویدادهای حسگر برای همه زیر-HALها اطمینان حاصل شود. اکیداً توصیه می‌شود که زیر-HALها از روش createScopedWakelock برای واگذاری بار قفل‌های بیدارباش زمان‌بندی‌شده به Sensors Multi-HAL و متمرکز کردن استفاده از قفل بیدارباش به یک قفل بیدارباش مشترک برای کل Sensors Multi-HAL استفاده کنند، که فراخوانی‌های قفل کردن و باز کردن قفل را به حداقل می‌رساند.

Sensors Multi-HAL 2 همچنین دارای برخی ویژگی‌های ایمنی داخلی است. این نرم‌افزار موقعیت‌هایی را که FMQ حسگر پر شده است یا چارچوب حسگر اندروید مجدداً راه‌اندازی می‌شود و وضعیت حسگر نیاز به تنظیم مجدد دارد، مدیریت می‌کند. علاوه بر این، هنگامی که رویدادها به کلاس HalProxy ارسال می‌شوند اما چارچوب حسگر قادر به پذیرش فوری رویدادها نیست، Sensors Multi-HAL می‌تواند رویدادها را به یک نخ پس‌زمینه منتقل کند تا در حین انتظار برای ارسال رویدادها، کار در تمام HALهای فرعی ادامه یابد.

کد منبع و پیاده‌سازی مرجع

تمام کدهای Sensors Multi-HAL در hardware/interfaces/sensors/common/default/2.X/multihal/ موجود است. در اینجا به برخی از منابع اشاره شده است.

  • HalProxy.h : شیء HalProxy توسط Sensors multi-HAL نمونه‌سازی شده و انتقال داده‌ها از sub-HALها به چارچوب حسگر را مدیریت می‌کند.
  • HalProxy.cpp : پیاده‌سازی HalProxy شامل تمام منطق مورد نیاز برای مالتی‌پلکس کردن ارتباط بین sub-HALها و چارچوب حسگر است.
  • SubHal.h : رابط ISensorsSubHal رابطی را تعریف می‌کند که sub-HALها باید برای سازگاری با HalProxy از آن پیروی کنند. sub-HAL متد initialize را پیاده‌سازی می‌کند تا شیء HalProxyCallback بتواند برای postEvents و createScopedWakelock استفاده شود.

    برای پیاده‌سازی‌های Multi-HAL 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/ : این نمونه پیاده‌سازی sub-HAL از حسگرهای جعلی برای تولید داده‌های جعلی استفاده می‌کند. برای آزمایش نحوه تعامل چندین sub-HAL در یک دستگاه مفید است.

پیاده‌سازی

این بخش نحوه پیاده‌سازی Sensors Multi-HAL را در شرایط زیر شرح می‌دهد:

از سنسورهای Multi-HAL به همراه سنسورهای AIDL HAL استفاده کنید

برای فعال کردن قابلیت multi-HAL با Sensors AIDL HAL، ماژول لایه شیم AIDL Multi-HAL را که در hardware/interfaces/sensors/aidl/default/multihal/ یافت می‌شود، وارد کنید. این ماژول تبدیل بین انواع تعریف HAL ​​سنسورهای AIDL و HIDL را مدیریت می‌کند و یک پوشش (wrapper) در اطراف رابط multi-HAL که در Implementing 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() تنظیم کنید. این روش ایمن است زیرا فیلدهای نوع حسگر با پشتیبانی عدد صحیح حسگرهای AIDL و HIDL HAL با هم همپوشانی ندارند.

پیاده‌سازی حسگرها Multi-HAL 2.1

برای پیاده‌سازی Sensors Multi-HAL 2.1 روی یک دستگاه جدید، این مراحل را دنبال کنید:

  1. رابط ISensorsSubHal را مطابق آنچه در SubHal.h توضیح داده شده است، پیاده‌سازی کنید.
  2. روش sensorsHalGetSubHal_2_1 در SubHal.h پیاده سازی کنید.
  3. برای ساخت sub-HAL تازه پیاده‌سازی شده، یک target cc_library_shared اضافه کنید. هنگام اضافه کردن target:

    1. مطمئن شوید که هدف به جایی در پارتیشن فروشنده دستگاه منتقل شده است.
    2. در فایل پیکربندی واقع در /vendor/etc/sensors/hals.conf ، مسیر کتابخانه را در یک خط جدید اضافه کنید. در صورت لزوم، فایل hals.conf را ایجاد کنید.

    برای مثال، برای ساخت یک کتابخانه فرعی HAL Android.bp ، به 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 شروع به کار می‌کند، به دنبال sub-HAL تازه پیاده‌سازی شده می‌گردد و با فراخوانی sensorsHalGetSubHal_2_1 آن را مقداردهی اولیه می‌کند.

پورت از سنسورهای Multi-HAL 2.0 به Multi-HAL 2.1

برای انتقال از Multi-HAL 2.0 به Multi-HAL 2.1، رابط SubHal را پیاده‌سازی کرده و sub-HAL خود را مجدداً کامپایل کنید.

اینها تفاوت‌های بین رابط‌های SubHal نسخه ۲.۰ و ۲.۱ هستند:

  • IHalProxyCallback از انواع ایجاد شده در نسخه 2.1 از مشخصات ISensors.hal استفاده می‌کند.
  • تابع initialize() به جای IHalProxyCallback از رابط SubHal نسخه ۲.۰، یک IHalProxyCallback جدید ارسال می‌کند.
  • Sub-HALها باید getSensorsList_2_1 و injectSensorData_2_1 به جای getSensorsList و injectSensorData پیاده‌سازی کنند، زیرا این متدها از انواع جدیدی که در نسخه 2.1 از مشخصات ISensors.hal اضافه شده‌اند، استفاده می‌کنند.
  • Sub-HALها باید sensorsHalGetSubHal_2_1 به جای sensorsHalGetSubHal در معرض نمایش قرار دهند تا Multi-HAL با آنها به عنوان sub-HALهای نسخه ۲.۱ رفتار کند.

پورت از سنسورهای HAL 2.0

هنگام ارتقاء از Sensors HAL 2.0 به Sensors Multi-HAL 2.0 ، اطمینان حاصل کنید که پیاده‌سازی HAL الزامات زیر را برآورده می‌کند.

مقداردهی اولیه HAL

حسگرهای HAL 2.0 یک تابع مقداردهی اولیه دارد که به سرویس حسگر اجازه می‌دهد FMQها و یک فراخوانی پویای حسگر را ارسال کند. در حسگرهای 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 درخواست دریافت قفل بیداری را بدهد. هنگام ارسال رویدادهای بیداری به پیاده‌سازی Multi-HAL، یک قفل بیداری محدوده‌دار قفل‌شده باید دریافت و به postEvents ارسال شود.

حسگرهای دینامیکی

Sensors Multi-HAL 2.0 مستلزم آن است که onDynamicSensorsConnected و onDynamicSensorsDisconnected در IHalProxyCallback هر زمان که اتصالات حسگر پویا تغییر کند، فراخوانی شوند. این فراخوانی‌های برگشتی به عنوان بخشی از اشاره‌گر IHalProxyCallback که از طریق تابع initialize() ارائه می‌شود، در دسترس هستند.

پورت از سنسورهای HAL 1.0

هنگام ارتقاء از Sensors HAL 1.0 به Sensors Multi-HAL 2.0، اطمینان حاصل کنید که پیاده‌سازی HAL الزامات زیر را برآورده می‌کند.

مقداردهی اولیه HAL

برای برقراری ارتباط برگشتی بین sub-HAL و پیاده‌سازی Multi-HAL، باید از تابع initialize() پشتیبانی شود.

حسگرهای موجود را افشا کنید

در Sensors Multi-HAL 2.0، تابع getSensorsList() باید در طول بوت یک دستگاه واحد، حتی در بین حسگرهایی که HAL را مجدداً راه‌اندازی می‌کنند، مقدار یکسانی را برگرداند. این به چارچوب اجازه می‌دهد تا در صورت راه‌اندازی مجدد سرور سیستم، اتصالات حسگر را دوباره برقرار کند. مقدار برگردانده شده توسط getSensorsList() می‌تواند پس از راه‌اندازی مجدد دستگاه تغییر کند.

رویدادهای حسگر را به پیاده‌سازی Multi-HAL ارسال کنید

در Sensors HAL 2.0، به جای انتظار برای فراخوانی poll() ، sub-HAL باید هر زمان که رویدادهای حسگر در دسترس هستند، رویدادهای حسگر را به صورت پیشگیرانه در IHalProxyCallback بنویسد.

رویدادهای بیداری (WAKE_UP)

در Sensors HAL 1.0، HAL می‌تواند قفل بیداری را برای پیاده‌سازی خود مدیریت کند. در Sensors Multi-HAL 2.0، زیر-HALها به پیاده‌سازی Multi-HAL اجازه می‌دهند تا قفل‌های بیداری را مدیریت کند و می‌تواند با فراخوانی createScopedWakelock درخواست دریافت قفل بیداری را بدهد. هنگام ارسال رویدادهای بیداری به پیاده‌سازی Multi-HAL، یک قفل بیداری محدوده‌دار قفل‌شده باید دریافت و به postEvents ارسال شود.

حسگرهای دینامیکی

در Sensors HAL 1.0، حسگرهای پویا از طریق تابع poll() بازگردانده می‌شوند. Sensors Multi-HAL 2.0 مستلزم آن است که onDynamicSensorsConnected و onDynamicSensorsDisconnected در IHalProxyCallback هر زمان که اتصالات حسگر پویا تغییر کند، فراخوانی شوند. این فراخوانی‌های برگشتی به عنوان بخشی از اشاره‌گر IHalProxyCallback که از طریق تابع initialize() ارائه می‌شود، در دسترس هستند.

پورت از سنسورهای Multi-HAL 1.0

برای انتقال یک پیاده‌سازی موجود از 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ها را همانطور که در بخش «انتقال از حسگرهای Hal 1.0» توضیح داده شده است، انتقال دهید.
  4. با دنبال کردن مراحل ۳ و ۴ در بخش پیاده‌سازی حسگرهای چند-هال ۲.۰، حسگرهای چند-هال ۲.۰ را به عنوان HAL تعیین‌شده تنظیم کنید.

اعتبارسنجی

اجرای VTS

وقتی یک یا چند sub-HAL را با Sensors Multi-Hal 2.1 ادغام کردید، از Vendor Test Suite (VTS) استفاده کنید تا مطمئن شوید که پیاده‌سازی‌های sub-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های جعلی، پیاده‌سازی‌های ساختگی رابط ISensorsSubHal هستند. زیر-HALها فهرست‌های مختلفی از حسگرها را نمایش می‌دهند. هنگامی که حسگرها فعال می‌شوند، به صورت دوره‌ای رویدادهای حسگر تولید شده به صورت خودکار را بر اساس فواصل زمانی مشخص شده در یک درخواست حسگر معین، به HalProxy ارسال می‌کنند.

از زیر-HALهای جعلی می‌توان برای آزمایش نحوه‌ی عملکرد کد کامل Multi-HAL با سایر زیر-HALهای بارگذاری شده در سیستم و همچنین برای تأکید بر جنبه‌های مختلف کد Sensors Multi-HAL استفاده کرد.

دو sub-HAL جعلی در hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/ موجود است.

برای ساخت و ارسال sub-HAL های جعلی به یک دستگاه، مراحل زیر را انجام دهید:

  1. دستورات زیر را برای ساخت و ارسال سه sub-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 مجدداً راه‌اندازی کنید و sub-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 عدد بزرگی (۱۰۰۰ یا بیشتر) باشد، این نشان می‌دهد که رویدادهای زیادی در انتظار نوشتن در چارچوب حسگرها هستند. این نشان می‌دهد که سرویس حسگر به بن‌بست رسیده یا از کار افتاده است و رویدادهای حسگر را پردازش نمی‌کند، یا اینکه اخیراً دسته بزرگی از رویدادهای حسگر از یک زیر-HAL ارسال شده است.

اگر تعداد ارجاع قفل بیداری بیشتر از 0 باشد، به این معنی است که HalProxy قفل بیداری دریافت کرده است. این مقدار فقط در صورتی باید بیشتر از 0 باشد که یک قفل بیداری ScopedWakelock عمداً در حال اجرا باشد یا رویدادهای بیداری به HalProxy ارسال شده و توسط چارچوب حسگر پردازش نشده باشند.

توصیف‌گر فایلی که به متد اشکال‌زدایی HalProxy ارسال می‌شود، به هر زیر-HAL ارسال می‌شود، بنابراین توسعه‌دهندگان باید متد اشکال‌زدایی را به عنوان بخشی از رابط ISensorsSubHal پیاده‌سازی کنند.