Die Implementierung des dynamischen Herunterfahrens umfasst die Verkabelung von Datenflüssen und die Ausführung dynamischer Prozesse, wie in den folgenden Abschnitten beschrieben.
Änderungen an HAL-Definitionen
Für das dynamische Herunterfahren sind Informationen darüber erforderlich, welche Prozesse welche HAL-Schnittstellen bedienen (diese Informationen können später auch in anderen Kontexten nützlich sein) und es dürfen keine Prozesse beim Booten gestartet und beim Beenden nicht neu gestartet werden (bis eine erneute Aufforderung erfolgt).
# 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
Änderungen an init und hwservicemanager
Beim dynamischen Herunterfahren muss der hwservicemanager
init
außerdem anweisen, die angeforderten Dienste zu starten. In Android 9 enthält init
drei zusätzliche Steuernachrichten (z. B. ctl.start
): ctl.interface_start
, ctl.interface_stop
und ctl.interface_restart
. Diese Nachrichten können verwendet werden, um init
zu signalisieren, bestimmte Hardwareschnittstellen hoch- und herunterzufahren. Wenn ein Dienst angefordert und nicht registriert ist, fordert hwservicemanager
den Start des Dienstes an. Dynamische HALs erfordern jedoch keines davon.
Bestimmen Sie den HAL-Ausgang
In Android 9 muss der HAL-Exit manuell festgelegt werden. Für Android 10 und höher kann es auch mit automatischen Lebenszyklen ermittelt werden.
Beim dynamischen Herunterfahren sind mehrere Richtlinien erforderlich, um zu entscheiden, wann ein HAL gestartet und wann ein HAL heruntergefahren werden soll. Wenn sich ein HAL aus irgendeinem Grund zum Beenden entscheidet, wird er automatisch neu gestartet, wenn er erneut benötigt wird. Dabei werden die in der HAL-Definition bereitgestellten Informationen und die durch Änderungen an init
und hwservicemanager
bereitgestellte Infrastruktur verwendet. Dies könnte verschiedene Strategien beinhalten, darunter:
- Ein HAL könnte sich dafür entscheiden, „exit“ für sich selbst aufzurufen, wenn jemand eine „close“-API oder eine ähnliche API dafür aufruft. Dieses Verhalten muss in der entsprechenden HAL-Schnittstelle angegeben werden.
- HALs können heruntergefahren werden, wenn ihre Aufgabe abgeschlossen ist (dokumentiert in der HAL-Datei).
Automatische Lebenszyklen
Android 10 bietet mehr Unterstützung für den Kernel und hwservicemanager
, was es HALs ermöglicht, automatisch herunterzufahren, wenn sie keine Clients haben. Um diese Funktion zu verwenden, führen Sie alle Schritte unter „Änderungen an HAL-Definitionen“ aus und gehen außerdem wie folgt vor:
- Registrieren Sie den Dienst in C++ mit
LazyServiceRegistrar
anstelle der MitgliedsfunktionregisterAsService
, zum Beispiel:// only one instance of LazyServiceRegistrar per process LazyServiceRegistrar registrar; registrar.registerAsService(myHidlService /* , "default" */);
- Stellen Sie sicher, dass der HAL-Client nur dann einen Verweis auf die HAL der obersten Ebene (die bei
hwservicemanager
registrierte Schnittstelle) beibehält, wenn diese verwendet wird. Um Verzögerungen zu vermeiden, wenn diese Referenz in einem Hwbinder-Thread gelöscht wird, der weiterhin ausgeführt wird, sollte der Client nach dem Löschen der Referenz auchIPCThreadState::self()->flushCommands()
aufrufen, um sicherzustellen, dass der Binder-Treiber über den zugehörigen Referenzzähler benachrichtigt wird Änderungen.