Google 致力于为黑人社区推动种族平等。查看具体举措
Diese Seite wurde von der Cloud Translation API übersetzt.
Switch to English

HIDL C ++

Android O entwickelt das Android-Betriebssystem neu, um klare Schnittstellen zwischen der geräteunabhängigen Android-Plattform und geräte- und herstellerspezifischem Code zu definieren. Android definiert bereits viele solcher Schnittstellen in Form von HAL-Schnittstellen, die in hardware/libhardware als C-Header hardware/libhardware . HIDL ersetzt diese HAL-Schnittstellen durch stabile, versionierte Schnittstellen, bei denen es sich um clientseitige und serverseitige HIDL-Schnittstellen in C ++ (siehe unten) oder Java handeln kann .

Die Seiten in diesem Abschnitt beschreiben C ++ - Implementierungen von HIDL-Schnittstellen, einschließlich Details zu den Dateien, die vom hidl-gen Compiler automatisch aus den HIDL .hal Dateien hidl-gen , wie diese Dateien hidl-gen werden und wie diese Dateien in den C ++ - Code integriert werden benutzt sie.

Client & Server-Implementierungen

HIDL-Schnittstellen haben Client- und Server-Implementierungen:

  • Ein Client einer HIDL-Schnittstelle ist der Code, der die Schnittstelle durch Aufrufen von Methoden verwendet.
  • Ein Server ist eine Implementierung einer HIDL-Schnittstelle, die Anrufe von Clients empfängt und Ergebnisse zurückgibt (falls erforderlich).

Beim Übergang von libhardware HALs zu HIDL-HALs wird die HAL-Implementierung zum Server und der in die HAL aufrufende Prozess zum Client. Standardimplementierungen können sowohl Passthrough- als auch Binder-HALs bedienen und sich im Laufe der Zeit ändern:

Abbildung 1. Entwicklungsfortschritt für ältere HALs.

Erstellen des HAL-Clients

Beginnen Sie, indem Sie die HAL-Bibliotheken in das Makefile aufnehmen:

  • Machen Sie: LOCAL_SHARED_LIBRARIES += android.hardware.nfc@1.0
  • Soong: shared_libs: [ …, android.hardware.nfc@1.0 ]

Fügen Sie als Nächstes die HAL-Header-Dateien hinzu:

#include <android/hardware/nfc/1.0/IFoo.h>
…
// in code:
sp<IFoo> client = IFoo::getService();
client->doThing();

Erstellen des HAL-Servers

Um die HAL-Implementierung zu erstellen, müssen Sie über die .hal Dateien verfügen, die Ihre HAL darstellen und bereits Makefiles für Ihre HAL mit -Lmakefile oder -Landroidbp auf hidl-gen ./hardware/interfaces/update-makefiles.sh ( ./hardware/interfaces/update-makefiles.sh erledigt dies für interne HAL-Dateien und ist eine gute Referenz). Wenn Sie HALs von libhardware , können Sie einen Großteil dieser Arbeit problemlos mit c2hal erledigen.

So erstellen Sie die erforderlichen Dateien zur Implementierung Ihrer HAL:

PACKAGE=android.hardware.nfc@1.0
LOC=hardware/interfaces/nfc/1.0/default/
m -j hidl-gen
hidl-gen -o $LOC -Lc++-impl -randroid.hardware:hardware/interfaces \
    -randroid.hidl:system/libhidl/transport $PACKAGE
hidl-gen -o $LOC -Landroidbp-impl -randroid.hardware:hardware/interfaces \
    -randroid.hidl:system/libhidl/transport $PACKAGE

Damit die HAL im Passthrough-Modus funktioniert, muss sich die Funktion HIDL_FETCH_IModuleName in /(system|vendor|...)/lib(64)?/hw/android.hardware.package@3.0-impl( OPTIONAL_IDENTIFIER ).so Dabei ist OPTIONAL_IDENTIFIER eine Zeichenfolge, die die Passthrough-Implementierung identifiziert. Die Anforderungen für den Passthrough-Modus werden automatisch von den obigen Befehlen erfüllt, die auch das Ziel android.hardware.nfc@1.0-impl erstellen. android.hardware.nfc@1.0-impl kann jedoch jede Erweiterung verwendet werden. Zum Beispiel android.hardware.nfc@1.0-impl-foo Anwendungen -foo selbst zu unterscheiden.

Wenn eine HAL eine Nebenversion oder eine Erweiterung einer anderen HAL ist, sollte die Basis-HAL verwendet werden, um diese Binärdatei zu benennen. Beispielsweise android.hardware.graphics.mapper@2.1 Implementierungen von android.hardware.graphics.mapper@2.1 weiterhin in einer Binärdatei mit dem Namen android.hardware.graphics.mapper@2.0-impl( OPTIONAL_IDENTIFIER ) . Normalerweise enthält der OPTIONAL_IDENTIFIER hier die aktuelle HAL-Version. Wenn Sie die Binärdatei so benennen, können 2.0-Clients sie direkt abrufen und 2.1-Clients können die Implementierung aktualisieren.

Füllen Sie als Nächstes die Stubs mit Funktionen aus und richten Sie einen Daemon ein. Beispiel-Daemon-Code (unterstützt Passthrough):

#include <hidl/LegacySupport.h>

int main(int /* argc */, char* /* argv */ []) {
    return defaultPassthroughServiceImplementation<INfc>("nfc");
}

defaultPassthroughServiceImplementation dlopen() die bereitgestellte -impl Bibliothek und stellt sie als binderisierten Dienst bereit. Beispiel-Daemon-Code (für reinen Binder-Service):

int main(int /* argc */, char* /* argv */ []) {
    // This function must be called before you join to ensure the proper
    // number of threads are created. The threadpool will never exceed
    // size one because of this call.
    ::android::hardware::configureRpcThreadpool(1 /*threads*/, true /*willJoin*/);

    sp<INfc> nfc = new Nfc();
    const status_t status = nfc->registerAsService();
    if (status != ::android::OK) {
        return 1; // or handle error
    }

    // Adds this thread to the threadpool, resulting in one total
    // thread in the threadpool. We could also do other things, but
    // would have to specify 'false' to willJoin in configureRpcThreadpool.
    ::android::hardware::joinRpcThreadpool();
    return 1; // joinRpcThreadpool should never return
}

Dieser Daemon befindet sich normalerweise im $PACKAGE + "-service-suffix" (z. B. android.hardware.nfc@1.0-service ), kann aber überall sein. Die Sepolitik für eine bestimmte Klasse von HALs ist das Attribut hal_<module> (zum Beispiel hal_nfc) . Dieses Attribut muss auf den Dämon angewendet werden, auf dem eine bestimmte HAL ausgeführt wird (wenn derselbe Prozess mehrere HALs bedient, können mehrere Attribute darauf angewendet werden).