hidl开发实践记录

目录

一、hidl基本语法

二、编写hal文件

三、编译环境设置

四、生成Android.bp文件

六、编译

七、添加hidl接口清单

八、selinux配置


一、hidl基本语法

    hidl文件后缀为.hal,语法借鉴了C语言和Java语言,相对来说比较简单。

    /** */ 表示文档注释。此样式只能应用于类型、方法、字段和枚举值声明。
    /* */ 表示多行注释。
    // 表示注释一直持续到行尾。除 // 之外,换行符与任何其他空格一样。

    文件第一行非注释语句为package 包名@版本;

    interface声明接口,不含显式 extends 声明的接口会从 android.hidl.base@1.0::IBase(类似于 Java 中的 java.lang.Object)隐式扩展。隐式导入的 IBase 接口声明了多种不应也不能在用户定义的接口中重新声明或以其他方式使用的预留方法。这些方法包括:

        ping
        interfaceChain
        interfaceDescriptor
        notifySyspropsChanged
        linkToDeath
        unlinkToDeath
        setHALInstrumentation
        getDebugInfo
        debug
        getHashChain

    import 语句是用于访问其他软件包中的软件包接口和类型的 HIDL 机制。import 语句本身涉及两个实体:

        导入实体:可以是软件包或接口;以及被导入实体。
        被导入实体:也可以是软件包或接口。

    导入语句使用完全限定类型名称语法来提供被导入的软件包或接口的名称和版本:

import android.hardware.nfc@1.0;            // import a whole package
import android.hardware.example@1.0::IQuux; // import an interface and types.hal
import android.hardware.example@1.0::types; // import just types.hal

    详细语法和说明请查看:

        接口和软件包  |  Android 开源项目  |  Android Open Source Project (google.cn)

二、编写hal文件

    在hardware/interfaces目录下创建的自己的接口目录和文件,示例如下:

$ mkdir -p helloworld/1.0
$ vim hardware/interfaces/helloworld/1.0/IHelloWorld.hal
    package android.hardware.helloworld@1.0;
    interface IHelloWorld {
        helloworld(string name) generates (int32_t code);
    };

三、编译环境设置

    第一次执行后面的那些命令需要先执行以下命令编译源码:
        source build/envsetup.sh
        lunch
        make
    非初次编译仅执行 source build/envsetup.sh 即可

四、生成Android.bp文件

    在hardware/interfaces目录下执行update-makefiles.sh脚本,会在hardware/interfaces/helloworld/1.0目录下自动生成Android.bp文件,示例如下:

$ ./update-makefiles.sh
$ cat hardware/interfaces/helloworld/1.0/Android.bp
	// This file is autogenerated by hidl-gen -Landroidbp.

	hidl_interface {
		name: "android.hardware.helloworld@1.0",
		root: "android.hardware",
		vndk: {
			enabled: true,
		},
		srcs: [
			"IHelloWorld.hal",
		],
		interfaces: [
			"android.hidl.base@1.0",
		],
		gen_java: true,
	}

    通过命令行执行 hidl-gen -O "" -Landroidbp -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport  android.hardware.helloworld@1.0 也可以达到同样的效果

五、生成c++模板代码

    1. hidl-gen工具安装

        make hidl-gen

    2. hidl-gen工具使用

        使用方法:hidl-gen -o output-path -Llanguage (-rinterface-root) fqname
        示例:

hidl-gen -o hardware/interfaces/helloworld/1.0/default/ -Lc++-impl -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.helloworld@1.0

        参数说明:
            -L: 语言类型,包括c++, c++-headers, c++-sources, export-header, c++-impl, java, java-constants, vts, makefile, androidbp, androidbp-impl, hash等。hidl-gen可根据传入的语言类型产生不同的文件。
            fqname: 完全限定名称的输入文件。比如本例中android.hardware.helloworld@1.0,要求在源码目录下必须有hardware/interfaces/helloworld/1.0/目录。对于单个文件来说,格式如下:package@version::fileName,比如android.hardware.helloworld@1.0::types.Feature。对于目录来说。格式如下package@version,比如android.hardware.helloworld@1.0。
            -r: 格式package:path,可选,对fqname对应的文件来说,用来指定包名和文件所在的目录到Android系统源码根目录的路径。如果没有制定,前缀默认是:android.hardware,目录是Android源码的根目录。
            -o:存放hidl-gen产生的中间文件的路径。

    3. 模板代码

        执行第2步的命令后会在hardware/interfaces/helloworld/1.0/default/生成HelloWorld.h和HelloWorld.cpp两个文件,同时会在out/soong/.intermediates/hardware/interfaces/helloworld/1.0/目录下生成模块代码所依赖的头文件和so库。

    $ cat hardware/interfaces/helloworld/1.0/default/HelloWorld.cpp
		// FIXME: your file license if you have one

		#include "HelloWorld.h"

		namespace android::hardware::helloworld::implementation {

		// Methods from ::android::hardware::helloworld::V1_0::IHelloWorld follow.
		Return<int32_t> HelloWorld::helloworld(const hidl_string& name) {
		  // TODO implement
		  return int32_t {};
		}


		// Methods from ::android::hidl::base::V1_0::IBase follow.

		//IHelloWorld* HIDL_FETCH_IHelloWorld(const char* /* name */) {
		  //return new HelloWorld();
		//}
		//
		}  // namespace android::hardware::helloworld::implementation
	
	$ cat hardware/interfaces/helloworld/1.0/default/HelloWorld.h
        // FIXME: your file license if you have one

		#pragma once

		#include <android/hardware/helloworld/1.0/IHelloWorld.h>
		#include <hidl/MQDescriptor.h>
		#include <hidl/Status.h>

		namespace android::hardware::helloworld::implementation {

		using ::android::hardware::hidl_array;
		using ::android::hardware::hidl_memory;
		using ::android::hardware::hidl_string;
		using ::android::hardware::hidl_vec;
		using ::android::hardware::Return;
		using ::android::hardware::Void;
		using ::android::sp;

		struct HelloWorld : public V1_0::IHelloWorld {
			// Methods from ::android::hardware::helloworld::V1_0::IHelloWorld follow.
			Return<int32_t> helloworld(const hidl_string& name) override;

			// Methods from ::android::hidl::base::V1_0::IBase follow.

		};

		// FIXME: most likely delete, this is only for passthrough implementations
		// extern "C" IHelloWorld* HIDL_FETCH_IHelloWorld(const char* name);

		}  // namespace android::hardware::helloworld::implementation

        HelloWorld.cpp中的HelloWorld::helloworld(const hidl_string& name)就是我们需要实现的方法。

六、编译

      执行命令mm hardware/interfaces/helloworld/1.0/default/就可以编译我们刚才开发的模块了,在out/target/product/<device>/vendor/lib/hw/android::hardware::helloworld@1.0-imp.so

七、添加hidl接口清单

     代码开发完成后我们还需要在system/libhidl/vintfdata/manifest.xml中添加我们新增的接口服务,具体做法如下:

$vim system/libhidl/vintfdata/manifest.xml
    <hal format="hidl">
        <name>android.hardware.helloworld</name>
        <transport>hwbinder</transport>
        <version>1.0</version>
        <interface>
            <name>IHelloWorld</name>
            <instance>default</instance>
        </interface>
        <fqname>@1.0::IHelloWorld/default</fqname>
    </hal>

    详情可参考:Android系统之VINTF(1)manifests&compatibility matrices - 君の内存

八、selinux配置

    具体selinux配置规则可根据项目需求进行配置,这里说一下需要配置的几条基本规则。

$vim system/sepolicy/private/file_contexts
    /vendor/bin/hw/android.hardware.helloworld@1.0-server u:object_r:helloworld_exec:s0

$vim system/sepolicy/public/file.te
    type helloworld_data_file, file_type;
    typeattribute helloworld_data_file data_file_type, core_data_file_type;

$vim system/sepolicy/private/service_contexts
    android.hardware.helloworld::IHelloWorld    u:object_r:android.hardware.helloworld_service:s0

$vim system/sepolicy/private/helloworld.te
    type helloworld, domain, data_between_core_and_vendor_violators, binder_in_vendor_violators, system_executes_vendor_violators, osproc_domain, osplatform_domain, mlstrustedsubject;
    type helloworld_exec, exec_type, vendor_file_type, file_type;
    init_daemon_domain(helloworld)
    type hwhelloworld_service, hwservice_manager_type;
    add_hwservice(helloworld, hwhelloworld_service);
    allow helloworld hwservicemanager_prop:file read;
    allow helloworld hidl_base_hwservice:hwservice_manager add;
    allow helloworld hwservicemanager:binder { transfer call};
    allow helloworld hwservicemanager_prop:file { getattr map open read };

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值