‫HALهای دردسترس پویا

‫Android 9 از خاموش شدن پویای زیرسیستم‌های سخت‌افزار Android وقتی درحال استفاده نیستند یا به آن‌ها نیاز نیست پشتیبانی می‌کند. برای مثال، وقتی کاربر از Wi-Fi استفاده نمی‌کند، زیرسیستم‌های Wi-Fi نباید حافظه، برق، یا دیگر منابع سیستم را مصرف کنند. در نسخه‌های قبلی Android، HALها/درایورها در دستگاه‌های Android در کل مدتی که تلفن Android روشن بود باز می‌ماندند.

پیاده‌سازی خاموش کردن پویا شامل سیم‌کشی جریان‌های داده و اجرای فرایندهای پویا است که در بخش‌های زیر به‌تفصیل شرح داده شده است.

تغییرات در تعاریف HAL

خاموش کردن پویا به اطلاعاتی درباره اینکه کدام فرایندها کدام میانای HAL را ارائه می‌دهند نیاز دارد (این اطلاعات ممکن است بعداً در زمینه‌های دیگر نیز مفید باشد) و همچنین فرایندها در زمان راه‌اندازی شروع نمی‌شوند و وقتی خارج می‌شوند دوباره راه‌اندازی نمی‌شوند (تا زمانی که دوباره درخواست شوند).

# some init.rc script associated with the HAL
service vendor.some-service-name /vendor/bin/hw/some-binary-service
    # init language extension, provides information of what service is served
    # if multiple interfaces are served, they can be specified one on each line
    interface android.hardware.light@2.0::ILight default
    # restarted if hwservicemanager dies
    # would also cause the hal to start early during boot if disabled wasn't set
    class hal
    # will not be restarted if it exits until it is requested to be restarted
    oneshot
    # will only be started when requested
    disabled
    # ... other properties

تغییرات در init و hwservicemanager

خاموش کردن پویا همچنین نیازمند این است که hwservicemanager به init بگوید سرویس‌های درخواست‌شده را شروع کند. در Android 9، init شامل سه پیام کنترل اضافی (برای نمونه ctl.start): ctl.interface_start، ctl.interface_stop، و ctl.interface_restart می‌شود. از این پیام‌ها می‌توان برای علامت دادن به init برای بالا و پایین آوردن میاناهای سخت‌افزاری خاص استفاده کرد. وقتی سرویسی درخواست می‌شود و ثبت نشده است، hwservicemanager درخواست می‌کند که سرویس شروع شود. بااین‌حال، HALهای پویا نیازی به استفاده از هیچ‌کدام از این‌ها ندارند.

تعیین خروج HAL

در Android 9، خروج HAL باید به‌صورت دستی تعیین شود. برای Android 10 و نسخه‌های بالاتر، این مدت را می‌توان با چرخه‌های عمر خودکار نیز تعیین کرد.

خاموش کردن پویا به چندین خط‌مشی برای تصمیم‌گیری درباره زمان شروع HAL و زمان خاموش کردن HAL نیاز دارد. اگر HAL به هر دلیلی تصمیم به خروج بگیرد، هنگامی که دوباره به آن نیاز باشد، به‌طور خودکار بااستفاده از اطلاعات ارائه‌شده در تعریف HAL و زیرساخت ارائه‌شده توسط تغییرات در init و hwservicemanager بازراه‌اندازی خواهد شد. این کار می‌تواند شامل چند استراتژی مختلف باشد، ازجمله:

  • اگر کسی یک API نزدیک یا مشابه را روی HAL فراخوانی کند، HAL می‌تواند انتخاب کند که روی خودش فراخوانی خروج انجام دهد. این رفتار باید در واسط HAL مربوطه مشخص شود.
  • وقتی کار HAL تمام شد، می‌تواند خاموش شود (در فایل HAL مستند شده است).

چرخه‌های حیات خودکار

‫Android 10 پشتیبانی بیشتری به هسته و hwservicemanager اضافه می‌کند که به «لایه انتزاع سخت‌افزار» اجازه می‌دهد هرزمان که مشتری نداشته باشد به‌طور خودکار خاموش شود. برای استفاده از این ویژگی، همه مراحل در تغییرات در تعریف‌های HAL و همچنین مراحل زیر را انجام دهید:

  • سرویس را در C++‎ با LazyServiceRegistrar به‌جای تابع عضو، registerAsService، ثبت کنید، برای مثال:
    // only one instance of LazyServiceRegistrar per process
    LazyServiceRegistrar registrar;
    registrar.registerAsService(myHidlService /* , "default" */);
  • بررسی کنید که کارخواه HAL ارجاع به HAL سطح بالا (رابط ثبت‌شده با hwservicemanager) را فقط زمانی حفظ کند که درحال استفاده است. برای جلوگیری از تأخیر درصورت رها شدن این مرجع در رشته hwbinder که به اجرا ادامه می‌دهد، مشتری باید پس‌از رها کردن مرجع، IPCThreadState::self()->flushCommands() را نیز فراخوانی کند تا مطمئن شود که درایور binder از تغییرات تعداد مرجع مرتبط مطلع شده است.