Sie müssen HIDL verwenden, um alle Build-Flags zu beschreiben, die für bedingte
Zusammenstellen des Frameworks. Relevante Build-Flags müssen gruppiert und in einer
einzelne .hal
-Datei. HIDL zum Angeben von Konfigurationselementen verwenden
bietet folgende Vorteile:
- Versioniert (Anbieter/OEMs müssen zum Hinzufügen neuer Konfigurationselemente die HAL)
- Gut dokumentiert
- Zugriffssteuerung mit SELinux
- Integritätsprüfung für Konfigurationselemente über die Anbietertest Suite (Bereichsprüfung, Abhängigkeitsprüfung zwischen Elementen usw.)
- Automatisch generierte APIs in C++ und Java
Vom Framework verwendete Build-Flags identifizieren
Beginnen Sie mit der Identifizierung der Build-Konfigurationen, die zum Kompilieren der
Framework und verwerfen Sie dann veraltete Konfigurationen, um den Satz zu verkleinern. Beispiel:
Die folgenden Build-Flags werden für surfaceflinger
identifiziert:
TARGET_USES_HWC2
TARGET_BOARD_PLATFORM
TARGET_DISABLE_TRIPLE_BUFFERING
TARGET_FORCE_HWC_FOR_VIRTUAL_DISPLAYS
NUM_FRAMEBUFFER_SURFACE_BUFFERS
TARGET_RUNNING_WITHOUT_SYNC_FRAMEWORK
VSYNC_EVENT_PHASE_OFFSET_NS
SF_VSYNC_EVENT_PHASE_OFFSET_NS
PRESENT_TIME_OFFSET_FROM_VSYNC_NS
MAX_VIRTUAL_DISPLAY_DIMENSION
HAL-Schnittstelle erstellen
Build-Konfigurationen für ein Subsystem werden über eine HAL-Schnittstelle aufgerufen, während
Schnittstellen zum Bereitstellen von Konfigurationswerten sind im HAL-Paket gruppiert
android.hardware.configstore
(derzeit in Version 1.0).
Wenn Sie beispielsweise eine HAL-Schnittstellendatei für surfaceflinger
erstellen möchten,
hardware/interfaces/configstore/1.0/ISurfaceFlingerConfigs.hal
:
package android.hardware.configstore@1.0; interface ISurfaceFlingerConfigs { // TO-BE-FILLED-BELOW };
Führen Sie nach dem Erstellen der Datei .hal
den folgenden Befehl aus:
hardware/interfaces/update-makefiles.sh
zum Hinzufügen des neuen
.hal
-Datei in den Android.bp
und
Android.mk
-Dateien.
Funktionen für Build-Flags hinzufügen
Fügen Sie der Schnittstelle für jedes Build-Flag eine neue Funktion hinzu. Beispiel:
hardware/interfaces/configstore/1.0/ISurfaceFlingerConfigs.hal
:
interface ISurfaceFlingerConfigs { disableTripleBuffering() generates(OptionalBool ret); forceHwcForVirtualDisplays() generates(OptionalBool ret); enum NumBuffers: uint8_t { USE_DEFAULT = 0, TWO = 2, THREE = 3, }; numFramebufferSurfaceBuffers() generates(NumBuffers ret); runWithoutSyncFramework() generates(OptionalBool ret); vsyncEventPhaseOffsetNs generates (OptionalUInt64 ret); presentTimeOffsetFromSyncNs generates (OptionalUInt64 ret); maxVirtualDisplayDimension() generates(OptionalInt32 ret); };
Wenn Sie eine Funktion hinzufügen:
- Fassen Sie sich kurz. Makefile-Variable nicht konvertieren
in Funktionsnamen umwandeln. Beachten Sie dabei, dass
TARGET_
undBOARD_
-Präfixe sind nicht mehr erforderlich. - Kommentare hinzufügen Helfen Sie Entwicklern, den Zweck der Konfigurationselement, wie es das Framework-Verhalten ändert, gültige Werte und andere relevante Informationen.
Mögliche Rückgabetypen für Funktionen:
Optional[Bool|String|Int32|UInt32|Int64|UInt64]
Typen sind definiert
in types.hal
im selben Verzeichnis und umschließen Sie primitive Werte mit einem
Feld, das angibt, ob der Wert vom HAL angegeben wird; Andernfalls wird die Standardeinstellung
-Wert verwendet wird.
struct OptionalString { bool specified; string value; };
Definieren Sie gegebenenfalls die Aufzählung, die den Typ des
Konfigurationselement und verwenden Sie diese Aufzählung als Rückgabetyp. Im obigen Beispiel
ist die Aufzählung NumBuffers
definiert, um die Anzahl der gültigen
Werte. Fügen Sie zum Definieren solcher benutzerdefinierter Datentypen ein Feld oder einen Aufzählungswert (für
Beispiel: USE_DEFAULT
) für die Angabe, ob der Wert angegeben wurde oder nicht
von HAL.
Es ist nicht obligatorisch, dass ein Build-Flag zu einer einzelnen Funktion in HIDL Modulinhaber können eng verwandte Build-Flags alternativ in eine Struktur und haben eine Funktion, die diese Struktur zurückgibt (dadurch kann die Anzahl der Funktionsaufrufe).
Eine Option zum Aggregieren von zwei Build-Flags in einer einzigen Struktur
in hardware/interfaces/configstore/1.0/ISurfaceFlingerConfigs.hal
lautet:
interface ISurfaceFlingerConfigs { // other functions here struct SyncConfigs { OptionalInt64 vsyncEventPhaseoffsetNs; OptionalInt64 presentTimeoffsetFromSyncNs; }; getSyncConfigs() generates (SyncConfigs ret); // other functions here };
Alternativen zu einer einzelnen HAL-Funktion
Als Alternative zur Verwendung einer einzigen HAL-Funktion für alle Build-Flags kann der HAL
bietet auch einfache Funktionen wie getBoolean(string
key)
und getInteger(string key)
. Die tatsächlichen
key=value
-Paare werden in separaten Dateien und im HAL-Dienst gespeichert
stellt Werte bereit, indem diese Dateien gelesen/geparst werden.
Dieser Ansatz ist zwar leicht zu definieren, bietet aber keine Vorteile. durch HIDL bereitgestellt (erzwungene Versionsverwaltung, einfache Dokumentation, Zugriffssteuerung) und wird daher nicht empfohlen.
Eine und mehrere Benutzeroberflächen
Das Design der HAL-Schnittstelle für Konfigurationselemente Auswahlmöglichkeiten:
- Eine Schnittstelle, die alle Konfigurationselemente abdeckt
- Mehrere Schnittstellen, die jeweils eine Reihe verwandter Konfigurationen abdecken Elemente
Eine zentrale Oberfläche ist einfacher, kann aber unübersichtlich werden, Konfigurationselemente werden der einzelnen Datei hinzugefügt. Außerdem bietet die Zugriffssteuerung ist nicht detailliert, sodass ein Prozess, dem Zugriff auf die Schnittstelle gewährt wurde, Daten lesen kann, Alle Konfigurationselemente (Zugriff auf einen partiellen Satz von Konfigurationselementen kann nicht gewährt). Wenn der Zugriff nicht gewährt wird, können Konfigurationselemente gelesen werden.
Aufgrund dieser Probleme verwendet Android mehrere Schnittstellen mit einem einzigen HAL
für eine Gruppe verwandter Konfigurationselemente. Beispiel:
ISurfaceflingerConfigs
für einen Bezug auf surfaceflinger
Konfigurationselemente und IBluetoothConfigs
für Bluetooth-bezogene
Konfigurationselemente.