软件包

注意:本部分使用 .hal 示例文件来说明 HIDL 语言结构如何映射到 C++。

HIDL 接口软件包位于 hardware/interfacesvendor/ 目录下(少数例外情况除外)。hardware/interfaces 顶层会直接映射到 android.hardware 软件包命名空间;版本是软件包(而不是接口)命名空间下的子目录。

hidl-gen 编译器会将 .hal 文件编译成一组 .h.cpp 文件。这些自动生成的文件可用来编译客户端/服务器实现链接到的共享库。用于编译此共享库的 Android.bp 文件由 hardware/interfaces/update-makefiles.sh 脚本自动生成。每次将新软件包添加到 hardware/interfaces 或在现有软件包中添加/移除 .hal 文件时,您都必须重新运行该脚本,以确保生成的共享库是最新的。

例如,IFoo.hal 示例文件应该位于 hardware/interfaces/samples/1.0 下。IFoo.hal 示例文件可以在 samples 软件包中创建一个 IFoo 接口:

package android.hardware.samples@1.0;
interface IFoo {
    struct Foo {
       int64_t someValue;
       handle  myHandle;
    };

    someMethod() generates (vec<uint32_t>);
    anotherMethod(Foo foo) generates (int32_t ret);
};

生成的文件

HIDL 软件包中自动生成的文件会链接到与软件包同名的单个共享库(例如 android.hardware.samples@1.0)。该共享库还会导出单个标头 IFoo.h,用于包含在客户端和服务器中。绑定式模式使用 hidl-gen 编译器并以 IFoo.hal 接口文件作为输入,它具有以下自动生成的文件:

图 1. 由编译器生成的文件。

  • IFoo.h - 描述 C++ 类中的纯 IFoo 接口;它包含 IFoo.hal 文件中的 IFoo 接口中所定义的方法和类型,必要时会转换为 C++ 类型。不包含与用于实现此接口的 RPC 机制(例如 HwBinder)相关的详细信息。类的命名空间包含软件包名称和版本号,例如 ::android::hardware::samples::IFoo::V1_0。客户端和服务器都包含此标头:客户端用它来调用方法,服务器用它来实现这些方法。
  • IHwFoo.h - 头文件,其中包含用于对接口中使用的数据类型进行序列化的函数的声明。开发者不得直接包含其标头(它不包含任何类)。
  • BpFoo.h - 从 IFoo 继承的类,可描述接口的 HwBinder 代理(客户端)实现。开发者不得直接引用此类。
  • BnFoo.h - 保存对 IFoo 实现的引用的类,可描述接口的 HwBinder 存根(服务器端)实现。开发者不得直接引用此类。
  • FooAll.cpp - 包含 HwBinder 代理和 HwBinder 存根的实现的类。当客户端调用接口方法时,代理会自动从客户端封送参数,并将事务发送到绑定内核驱动程序,该内核驱动程序会将事务传送到另一端的存根(该存根随后会调用实际的服务器实现)。

这些文件的结构类似于由 aidl-cpp 生成的文件(有关详细信息,请参见 HIDL 概览中的“直通模式”)。独立于 HIDL 使用的 RPC 机制的唯一一个自动生成的文件是 IFoo.h,其他所有文件都与 HIDL 使用的 HwBinder RPC 机制相关联。因此,客户端和服务器实现不得直接引用除 IFoo 之外的任何内容。为了满足这项要求,请只包含 IFoo.h 并链接到生成的共享库。

注意:HwBinder 只是一种可能的传输机制,未来可能会添加新的传输机制。

使用软件包中的任何接口的客户端或服务器必须在下面的其中一 (1) 个位置包含该软件包的共享库:

  • Android.mk 中:
    LOCAL_SHARED_LIBRARIES += android.hardware.samples@1.0
    
  • Android.bp 中:
    shared_libs: [
        /* ... */
        "android.hardware.samples@1.0",
    ],
    

对于特定的库:

libhidlbase 包含标准 HIDL 数据类型。除非您的接口只包含直接映射到 C++ 基元的基元,否则您还必须链接到此库:

LOCAL_SHARED_LIBRARIES += libhidlbase
libhidltransport 通过不同的 RPC/IPC 机制处理 HIDL 调用的传输。您必须始终链接到此库:

LOCAL_SHARED_LIBRARIES += libhidltransport
libhwbinder 您还必须链接到此库:

LOCAL_SHARED_LIBRARIES += libhwbinder
libfmq 要使用快速消息队列 IPC,您还必须链接到此库。

LOCAL_SHARED_LIBRARIES += libfmq

命名空间

HIDL 函数和类型(如 Return<T>Void())已在命名空间 ::android::hardware 中进行声明。软件包的 C++ 命名空间由软件包的名称和版本号确定。例如,hardware/interfaces 下版本为 1.2 的软件包 mypackage 具有以下特质:

  • C++ 命名空间::android::hardware::mypackage::V1_2
  • 该软件包中 IMyInterface完全限定名称::android::hardware::mypackage::V1_2::IMyInterfaceIMyInterface 是一个标识符,而不是命名空间的一部分)。
  • 在软件包的 types.hal 文件中定义的类型标识为 ::android::hardware::mypackage::V1_2::MyPackageType