HALs المتاحة ديناميكيًا

يدعم 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 . يمكن أن يشمل ذلك اثنتين من الاستراتيجيات المختلفة، بما في ذلك:

  • يمكن أن تختار HAL استدعاء الخروج من تلقاء نفسها إذا قام شخص ما باستدعاء واجهة برمجة تطبيقات قريبة أو مشابهة عليها. يجب تحديد هذا السلوك في واجهة HAL المقابلة.
  • يمكن إيقاف تشغيل HALs عند اكتمال مهمتهم (موثقة في ملف HAL).

دورات الحياة التلقائية

يضيف Android 10 مزيدًا من الدعم إلى kernel و hwservicemanager ، مما يسمح بإيقاف تشغيل HALs تلقائيًا عندما لا يكون لديهم عملاء. لاستخدام هذه الميزة، قم بتنفيذ جميع الخطوات الواردة في التغييرات على تعريفات HAL بالإضافة إلى:

  • قم بتسجيل الخدمة في C++ باستخدام LazyServiceRegistrar بدلاً من وظيفة العضو، registerAsService ، على سبيل المثال:
    // only one instance of LazyServiceRegistrar per process
    LazyServiceRegistrar registrar;
    registrar.registerAsService(myHidlService /* , "default" */);
  • تأكد من أن عميل HAL يحتفظ بمرجع إلى HAL ذي المستوى الأعلى (الواجهة المسجلة مع hwservicemanager ) فقط عندما يكون قيد الاستخدام. لتجنب التأخير في حالة إسقاط هذا المرجع في مؤشر ترابط hwbinder الذي يستمر في التنفيذ، يجب على العميل أيضًا الاتصال بـ IPCThreadState::self()->flushCommands() بعد إسقاط المرجع للتأكد من إخطار برنامج تشغيل الموثق بعدد المرجع المرتبط التغييرات.