Android R 添加 HIDL 服务

本文详细介绍了Android硬件抽象层(HAL)的接口定义语言HIDL的使用,包括创建manifest文件、定义服务接口、使用hidl-gen生成对应文件、实现服务并配置启动、客户端调用示例等步骤,展示了Android系统中硬件服务的完整开发流程。
摘要由CSDN通过智能技术生成

HAL 接口定义语言(简称 HIDL,发音为“hide-l”)是用于指定 HAL 和其用户之间的接口的一种接口描述语言 (IDL)。HIDL 允许指定类型和方法调用(会汇集到接口和软件包中)。从更广泛的意义上来说,HIDL 是指用于在可以独立编译的代码库之间进行通信的系统。从 Android 10 开始,HIDL 已废弃,Android 将在所有位置改用 AIDL。

1. 准备目录(vendor/my)及hal接口文件

manifest_hello.xml此文件内容在Android R 高通项目中可加入自身项目中device/qcom/xxxxxxx/manifest.xml  用于声明服务

 <manifest version="1.0" type="device">
     <hal format="hidl">
         <name>vendor.my.hello</name>
         <transport>hwbinder</transport>
         <version>1.0</version>
         <interface>
             <name>Ihello</name>
             <instance>default</instance>
         </interface>
     </hal>
 </manifest>

hardware/interfaces/compatibility_matrices/compatibility_matrix.5.xml 用于framework兼容

    <hal format="hidl" optional="true">
        <name>vendor.my.hello</name>
        <version>1.0</version>
        <interface>
            <name>Ihello</name>
            <instance>default</instance>
        </interface>
    </hal>

Ihello.hal   定义服务接口

package vendor.my.hello@1.0;

interface Ihello {
   hello_open();
};

Android.bp  指定包名及目录映射

hidl_package_root {
   name: "vendor.my",
   path: "vendor/my",
}

2. hidl-gen 生成对应的android.bp,源码文件,带hash current.txt

bash 运行脚本

PKG_ROOT=vendor/my
PACKAGE=vendor.my.hello@1.0
HIDL_GEN_OUT=$PKG_ROOT/hello/1.0/default
hidl-gen -L androidbp -rvendor.my:$PKG_ROOT -randroid.hidl:system/libhidl/transport $PACKAGE
hidl-gen -o $HIDL_GEN_OUT -Lc++-impl -r vendor.my:$PKG_ROOT -r android.hidl:system/libhidl/transport $PACKAGE
hidl-gen -L hash -r vendor.my:$PKG_ROOT -randroid.hidl:system/libhidl/transport $PACKAGE >> $PKG_ROOT/current.txt

 文件清单 

current.txt 

4da6c06c236b1b04e6bb150af18dc064b7144b72c7b10cedad9965f8b384b2c5 vendor.my.hello@1.0::types
2eb04c0162c83cc37c953690e46812ac5f5a349ba707c2062c644412ee45d5a8 vendor.my.hello@1.0::Ihello

Android.bp

// This file is autogenerated by hidl-gen -Landroidbp.

hidl_interface {
    name: "vendor.my.hello@1.0",
    root: "vendor.my",
    system_ext_specific: true,
    srcs: [
        "types.hal",
        "Ihello.hal",
    ],
    interfaces: [
        "android.hidl.base@1.0",
    ],
    gen_java: true,
}

3.  实现,编译,配置服务启动

这里将服务编译成一个可执行文件,配置开机rc启动

default/Android.bp

// FIXME: your file license if you have one

cc_binary {
    name: "vendor.my.hello@1.0-service",
    
    
    proprietary: true,
    
    compile_multilib: "32",

    relative_install_path: "hw",

    srcs: [
        "hello.cpp",
    ],

    init_rc: [
        "vendor.my.hello@1.0-service.rc"
    ],

    shared_libs: [
        "libhidlbase",
        "libutils",
        "liblog",
        "vendor.my.hello@1.0",
        "libcutils",
    ],

    cppflags: [
    ],
}

vendor.my.hello@1.0-service.rc
 

service hello_service /vendor/bin/hw/vendor.my.hello@1.0-service
    class hal
    user system
    group system

安装服务 vendor/xxx/qcom/device.mk

PRODUCT_PACKAGES += \
     vendor.my.hello@1.0-service \
     vendor.my.hello@1.0-service.rc

4. 添加权限设置device/qcom/sepolicy_vndr/generic/vendor/common/

attributes

attribute hal_hello_client;
attribute hal_hello_server;
attribute hal_hello;

hwservice.te

type hal_hello_hwservice, hwservice_manager_type;

hwservice_contexts

vendor.my.hello::Ihello            u:object_r:hal_hello_hwservice:s0

新增hal_hello.te

binder_call(hal_hello_client, hal_hello_server)
binder_call(hal_hello_server, hal_hello_client)

add_hwservice(hal_hello_server, hal_hello_hwservice)

allow hal_hello_client hal_hello_hwservice:hwservice_manager find;

新增hal_hello_default.te

type hal_hello_default, domain;
hal_server_domain(hal_hello_default, hal_hello)

type hal_hello_default_exec, exec_type, vendor_file_type, file_type;
init_daemon_domain(hal_hello_default)

vndbinder_use(hal_hello_default)

file_contexts

/(vendor|system/vendor)/bin/hw/vendor\.my\.hello@1\.0-service             u:object_r:hal_hello_default_exec:s0

platform_app.te, system_app.te 添加规则使得这两类应用可以调用

allow platform_app hal_hello_hwservice:hwservice_manager find;
allow platform_app hal_hello_default:binder call;

4. Client端口demo实现

目录列表

Android.mk作为 makefile生成HelloClient可执行文件,验证时将HelloClient push 到设备的/vendor/bin/HelloClient

文件清单如下:

Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := HelloClient

LOCAL_SRC_FILES := HelloClient.cpp main.cpp

LOCAL_SHARED_LIBRARIES:= \
        liblog          \
        libutils        \
        libtinyalsa      \
        vendor.my.hello@1.0  \
        libhidlbase  \
        libhidltransport  \
        libcutils  \
        libdl  \
        libbase  \




LOCAL_LDLIBS += -llog

LOCAL_CERTIFICATE := platform

include $(BUILD_EXECUTABLE)

HelloClient.cpp

#include "HelloClient.h"
#include <hidl/HidlSupport.h>
#include <vendor/my/hello/1.0/Ihello.h>
using ::vendor::my::hello::V1_0::Ihello;
using ::android::sp;

void HelloClient::open_hello() {
    LOGD("open_hello");
    sp<Ihello> mDemo = Ihello::getService();
    mDemo->hello_open();
}

HelloClient.h

#ifndef NATIVEAPP_HELLOCLIENT_H
#define NATIVEAPP_HELLOCLIENT_H

#include <android/log.h>
#define TAG "TAG"

#define  LOGV(...)  __android_log_print(ANDROID_LOG_VERBOSE,    TAG, __VA_ARGS__)
#define  LOGW(...)  __android_log_print(ANDROID_LOG_WARN,       TAG, __VA_ARGS__)
#define  LOGD(...)  __android_log_print(ANDROID_LOG_DEBUG,      TAG, __VA_ARGS__)
#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,       TAG, __VA_ARGS__)
#define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,      TAG, __VA_ARGS__)


class HelloClient {
    public:
        void open_hello();

};


#endif //NATIVEAPP_HELLOCLIENT_H

main.cpp

#include "HelloClient.h"


int main(int argc, char *argv[]) {


	LOGD("HelloClient exec\n");
        HelloClient client;
    client.open_hello();


    LOGD("HelloClient exit!!!\n");
    exit(0);
}

要在Android应用程序使用HIDL服务,需要先了解HIDL服务的接口和功能。通常,HIDL服务会提供一个HIDL接口,该接口定义了与硬件模块通信的方法和功能。 下面是使用HIDL服务的一般步骤: 1. 包含HIDL服务的依赖:在应用程序的build.gradle文件添加对包含HIDL服务的库的依赖项。例如,如果HIDL服务位于"com.example.hidl"包,可以添加以下依赖项: ```groovy implementation 'com.example.hidl:hidl-service:1.0' ``` 2. 获取HIDL服务的引用:在应用程序的代码,使用ServiceManager来获取HIDL服务的引用。ServiceManager是Android系统的系统服务,它允许应用程序获取和管理系统的各种服务。 ```java import android.os.ServiceManager; // 获取HIDL服务的引用 IBaseHidlService hidlService = IBaseHidlService.getService(); ``` 3. 调用HIDL服务的方法:通过获取到的HIDL服务引用,可以调用其定义的方法来与硬件模块进行交互。 ```java // 调用HIDL服务提供的方法 hidlService.doSomething(); ``` 需要注意的是,具体的HIDL接口和方法名称会根据你所使用的HIDL服务而有所不同。你需要查阅相关文档或源代码以了解具体的接口和方法定义。 此外,还需要确保在AndroidManifest.xml文件声明必要的权限和服务,以便应用程序可以访问HIDL服务。 总之,使用HIDL服务的关键是获取HIDL服务的引用,并调用其定义的方法来与硬件模块进行交互。具体的步骤和方法会根据你使用的HIDL服务而有所不同,需要参考相关文档或源代码进行实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值