Für die Implementierung des dynamischen Herunterfahrens müssen Datenflüsse verbunden und dynamische Prozesse ausgeführt werden, wie in den folgenden Abschnitten beschrieben.
Änderungen an HAL-Definitionen
Für das dynamische Herunterfahren sind Informationen erforderlich, welche Prozesse welche HAL-Schnittstellen bereitstellen (diese Informationen können auch später in anderen Kontexten nützlich sein). Außerdem dürfen Prozesse beim Starten nicht gestartet und nach dem Beenden nicht neu gestartet werden, bis sie wieder angefordert werden.
# 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
Für das dynamische Herunterfahren muss der hwservicemanager
außerdem dem init
mitteilen, die angeforderten Dienste zu starten. In Android 9 enthält init
drei zusätzliche Steuermeldungen (z.B. ctl.start
): ctl.interface_start
, ctl.interface_stop
und ctl.interface_restart
.
Mit diesen Nachrichten kann init
angewiesen werden, bestimmte Hardwareschnittstellen zu aktivieren und zu deaktivieren. Wenn ein Dienst angefordert wird und nicht registriert ist, fordert hwservicemanager
den Dienst zum Starten auf. Bei dynamischen HALs ist dies jedoch nicht erforderlich.
HAL-Exit ermitteln
Unter Android 9 muss der HAL-Ausstieg manuell festgelegt werden. Unter Android 10 und höher kann sie auch mit automatischen Lebenszyklen bestimmt werden.
Für das dynamische Herunterfahren sind mehrere Richtlinien erforderlich, um zu entscheiden, wann ein HAL gestartet und wann ein HAL heruntergefahren werden soll. Wenn ein HAL aus irgendeinem Grund beendet wird, wird er automatisch neu gestartet, wenn er wieder benötigt wird. Dabei werden die Informationen in der HAL-Definition und die Infrastruktur verwendet, die durch Änderungen an init
und hwservicemanager
bereitgestellt wird. Dazu können verschiedene Strategien gehören, z. B.:
- Eine HAL kann „exit“ auf sich selbst anwenden, wenn jemand eine ähnliche API wie „close“ darauf aufruft. Dieses Verhalten muss in der entsprechenden HAL-Schnittstelle angegeben werden.
- HALs können heruntergefahren werden, wenn ihre Aufgabe abgeschlossen ist (in der HAL-Datei dokumentiert).
Automatische Lebenszyklen
Android 10 bietet mehr Unterstützung für den Kernel und hwservicemanager
, sodass HALs automatisch heruntergefahren werden, wenn sie keine Clients haben. Wenn Sie diese Funktion verwenden möchten, führen Sie alle Schritte unter Änderungen an HAL-Definitionen aus und gehen Sie außerdem so vor:
- Registrieren Sie den Dienst in C++ mit
LazyServiceRegistrar
anstelle der MitgliedsfunktionregisterAsService
, z. B.:// only one instance of LazyServiceRegistrar per process LazyServiceRegistrar registrar; registrar.registerAsService(myHidlService /* , "default" */);
- Prüfen Sie, ob der HAL-Client nur dann einen Verweis auf die HAL der obersten Ebene (die bei
hwservicemanager
registrierte Schnittstelle) beibehält, wenn sie verwendet wird. Um Verzögerungen zu vermeiden, wenn diese Referenz in einem hwbinder-Thread gelöscht wird, der weiter ausgeführt wird, sollte der Client nach dem Löschen der Referenz auchIPCThreadState::self()->flushCommands()
aufrufen, damit der Binder-Treiber über die entsprechenden Änderungen der Referenzanzahl informiert wird.