如何新增hidl服务

最好在自己的产品名下新增文件夹,创建相应的HIDL服务,假设目前要在tom下新增HIDL服务,流程如下:

1创建hidl服务文件夹test

/vendor/tom/monet/interfaces/test
在test下新建1.0文件夹
在1.0下新增default文件夹

2. 新增.hal文件

在/vendor/tom/monet/interfaces/test/1.0下新增IwslTest.hal文件,内容如下

package  vendor.monet.hardware.test@1.0;

interface IwslTest{
    test(int32_t side) generates (bool  movingState);
};

3. 编译hidl-gen

source build/envsetup.sh

lunch xx

make hidl-gen

这样后面就可以用hidl-gen工具了,

4. 配置hidl的package root

 LOC=vendor/tom/monet/interfaces/test/1.0/default
 PACKAGE=vendor.monet.hardware.test@1.0

5. 在1.0/default/下生成.cpp和.h文件

在vendor/tom/monet/interfaces/test/1.0/default下生成.cpp和.h文件:

hidl-gen -o $LOC -Lc++-impl -rvendor.monet.hardware:vendor/tom/monet/interfaces -randroid.hidl:system/libhidl/transport $PACKAGE

然后会生成wslTest.cpp 和wslTest.h文件。生成后需要做相关修改,修改后内容如下:

#include "wslTest.h"
#include <android/log.h>
namespace vendor::monet::hardware::test::implementation {

// Methods from ::vendor::monet::hardware::test::V1_0::IwslTest follow.
Return<bool> wslTest::test(int32_t side) {
    // TODO implement
       __android_log_print(ANDROID_LOG_INFO, "simpleperf", "%s", "wslTest::test");
    return bool {};
}

// Methods from ::android::hidl::base::V1_0::IBase follow.
//IwslTest* HIDL_FETCH_IwslTest(const char* /* name */) {
    //return new wslTest();
//}
//
}  // namespace vendor::monet::hardware::test::implementation
#pragma once

#include <vendor/monet/hardware/test/1.0/IwslTest.h>
#include <hidl/MQDescriptor.h>
#include <hidl/Status.h>

namespace vendor::monet::hardware::test::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 wslTest : public V1_0::IwslTest {
    // Methods from ::vendor::monet::hardware::test::V1_0::IwslTest follow.
    Return<bool> test(int32_t side) override;

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

};

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

}  // namespace vendor::monet::hardware::test::implementation

6. 在1.0/下面生成Android.bp

在vendor/tom/monet/interfaces/test/1.0/下生成Android.bp

source system/tools/hidl/update-makefiles-helper.sh
do_makefiles_update vendor.monet.hardware:vendor/tom/monet/interfaces android.hardware:hardware/interfaces android.hidl:system/libhidl/transport

7在vendor/tom/monet/interfaces/test/1.0/default下生成Android.bp

并对其进行修改,修改后如下

cc_defaults{
    name: "test_defaults",
    //relative_install_path: "hw",
    defaults: ["hidl_defaults"],
    //根据项目需求
    //vendor: true,
    proprietary: true,
    cflags: [
       "-Wno-unused-parameter",
       "-Wall",
    ],
    shared_libs: [
            "libcutils",
            "liblog",
            "libbase",
            "libsysutils",
            "libhidlbase",
            "libhidltransport",
            "libutils",
            "vendor.monet.hardware.test@1.0",
        ],

}


cc_library_shared {
    // FIXME: this should only be -impl for a passthrough hal.
    // In most cases, to convert this to a binderized implementation, you should:
    // - change '-impl' to '-service' here and make it a cc_binary instead of a
    //   cc_library_shared.
    // - add a *.rc file for this module.
    // - delete HIDL_FETCH_I* functions.
    // - call configureRpcThreadpool and registerAsService on the instance.
    // You may also want to append '-impl/-service' with a specific identifier like
    // '-vendor' or '-<hardware identifier>' etc to distinguish it.
    name: "vendor.monet.hardware.test@1.0-impl",
    relative_install_path: "hw",
    // FIXME: this should be 'vendor: true' for modules that will eventually be
    // on AOSP.
    proprietary: true,
    srcs: [
        "wslTest.cpp",
    ],
    shared_libs: [
        "libhidlbase",
        "libutils",
        "vendor.monet.hardware.test@1.0",
    ],
        defaults: ["test_defaults"],

}




cc_binary {
    name: "vendor.monet.hardware.test@1.0-service",
    proprietary: true,
    compile_multilib: "both",
    relative_install_path: "hw",
    defaults: ["test_defaults"],
    //rc引用
    init_rc: ["vendor.monet.hardware.test-service.rc"],
    //vintf_fragments引用
    vintf_fragments: ["vendor.monet.hardware.test-service.xml"],
    srcs: [
        "service.cpp",
    ],
    shared_libs: [
        "libcutils",
        "liblog",
        "libbase",
        "libsysutils",
        "libhidlbase",
        "libhidltransport",
        "libutils",
        "vendor.monet.hardware.test@1.0-impl",
    ],

}

8. 在主目录android下执行如下命令生成current.txt

 hidl-gen -Lhash -rvendor.monet.hardware:vendor/tom/monet/interfaces -randroid.hidl:system/libhidl/transport vendor.monet.hardware.test@1.0 > vendor/tom/monet/interfaces/test/current.txt

9. 在1.0/default/下添加vendor.monet.hardware.test-service.rc

添加如下内容

service vendor.monet.hardware.test-1-0 /vendor/bin/hw/vendor.monet.hardware.test@1.0-service
class hal
user system
group system

10. 在1.0/default/下添加vendor.monet.hardware.customizehidl-service.xml


<manifest version="1.0" type="device">
    <hal format="hidl">
        <name>vendor.monet.hardware.test</name>
        <transport>hwbinder</transport>
        <version>1.0</version>
        <interface>
            <name>IwslTest</name>
            <instance>default</instance>
        </interface>
    </hal>
</manifest>

11. 在device/qcom/common/vendor_compatibility_matrix.xml中添加如下内容

<hal format="hidl" optional="true">
  <name>vendor.monet.hardware.test</name>
    <transport>hwbinder</transport>
    <version>1.0</version>
    <interface>
        <name>IwslTest</name>
        <instance>default</instance>
    </interface>
</hal>

12. 在1.0/default/下添加service.cpp

HIDL 这个机制的目的,主要是为了把框架(framework)与 HAL 进行隔离,使得框架部分可以直接被覆盖、更新,而不需要重新对 HAL 进行编译。HAL 的部分将会放在设备的 /vendor 分区中,并且是由设备供应商(vendors)或 SOC 制造商来构建。这使得框架部分可以通过 OTA 方式更新,同时不需要重新编译 HAL。

这种设计被称为Treble机制,从Android 8.0引入。在此之前framework需要调用dlopen打开HAL编译的.so才能和HAL 层通信,这样framework 与 HAL 处在同一个进程 , 两者耦合严重,导致版本升级时供应商需要做大量的适配工作。

   Treble机制解决目前Android 版本之间升级麻烦的问题,将OEM适配的部分vendor与google 对android  大框架升级的部分system部分做了分离,一旦适配了一个版本的vendor信息之后,之后的版本再进行升级时,直接升级system即可,这个就不会给OEM厂商升级带来太大的工作量,直接升级最新功能,可以解决目前市面上Android版本过于凌乱的问题。

Treble机制在Vendor分区中有两种模式,直通模式(Passthrough)和绑定模式(Binderized)

如果采用Binderized方式,如下

#include <android-base/logging.h>
#include <hidl/HidlTransportSupport.h>
#include "wslTest.h"
#include <utils/Log.h>
#include <hidl/LegacySupport.h>
using namespace android;
using vendor::monet::hardware::test::V1_0::IwslTest;
using vendor::monet::hardware::test::implementation::wslTest;
using android::hardware::configureRpcThreadpool;
using android::hardware::joinRpcThreadpool;
using android::sp;

int main(int /* argc */, char ** /* argv */) {
    sp<IwslTest> service = new wslTest();
    configureRpcThreadpool(1, true /*callerWillJoin*/);
    if (::android::OK != service->registerAsService()) {
        return -1;
    }
    joinRpcThreadpool();
    return 0;
}

如果要采用Passthrough方式的话,则需要按如下方法写main,但同时需要将wslTest.cpp以及wslTest.h中的HIDL_FETCH_IwslTest方法放开才可以。


#include <android-base/logging.h>
#include <hidl/HidlTransportSupport.h>
#include "CustomizeHidl.h"
#include <utils/Log.h>
#include <hidl/LegacySupport.h>
using namespace android;
using vendor::monet::hardware::test::V1_0::IwslTest;
using android::hardware::configureRpcThreadpool;
using android::hardware::joinRpcThreadpool;
using android::hardware::defaultPassthroughServiceImplementation;
using android::hardware::registerPassthroughServiceImplementation;
 
int main() {
	android::status_t status;
 
	configureRpcThreadpool(10, false);
	status = registerPassthroughServiceImplementation<IwslTest>();
 
	LOG_ALWAYS_FATAL_IF(status != OK, "Error while registering ICustomizeHidl: %d", status);
 
	joinRpcThreadpool();
	return status;

13. 编写测试bin程序

vendor/tom/monet/interfaces/test/下新增hidl_test_bin文件夹,并添加Android.bp文件

cc_binary {
    name: "hidl_test_bin"                                                                                                                   
    srcs: [
        "hidl_test_bin.cpp",
    ],
    shared_libs: [
        "libcutils",
        "libutils",
        "liblog",
        "libbinder",
        "libhidlbase",
        "libbase",
        "libhidltransport",
        "vendor.monet.hardware.test@1.0",
    ],

    cflags: [
        "-Werror",
        "-Wno-error=deprecated-declarations",
        "-Wno-unused-parameter",
        "-Wall",
    ],
}

新增的测试文件hidl_test_bin.cpp

#define LOG_TAG "hidl_test_bin"
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <binder/ProcessState.h>
#include <cutils/properties.h>
#include <fcntl.h>
#include <utils/Log.h>
#include <iostream>
#include <vendor/monet/hardware/test/1.0/IwslTest.h>
using vendor::monet::hardware::test::V1_0::IwslTest;
using namespace android;
using namespace std;
sp<IwslTest> halService;

int main(int argc, char* argv[]) {
    halService = IwslTest::getService();
    if (halService == NULL){
        cout << "get hal service failed" <<endl;
        return -1;
    }
    cout << "get hal service scuess" <<endl;
    float value = stof(argv[1]);
    cout << "value is " << value <<endl;
    halService->test(value);
    return 0;
}

14测试方式

14.1 单编方法:
source build/envsetup.sh

lunch xxx

cd vendor/tom/monet/interfaces/test

mma(编译hidl服务相关)

cdvendor/tom/monet/interfaces/test/hidl_test_bin

mma(编译test bin相关)

14.2 测试方法:

  1. adb pull vendor/etc/vintf/compatibility_matrix.xml

在最后增加

vendor.monet.hardware.test
hwbinder
1.0

IwslTest
default

  1. 再push回去

adb root
adb remount

adb push compatibility_matrix.xml vendor/etc/vintf/compatibility_matrix.xml

  1. 在out/target/product/qssi下执行–注意根据自己的平台push,如果不知道具体生成在哪些路径可以在上述路径通过指令过滤
    find -iname "vendor.monet.hardware.test@1.0.so "
    find -iname "vendor.monet.hardware.test@1.0-impl.so "
    find -iname "vendor.monet.hardware.test@1.0-service "
    find -iname “vendor.monet.hardware.test-service.xm”

adb push ./product/lib/vendor.monet.hardware.test@1.0.so product/lib/
adb push ./product/lib64/vendor.monet.hardware.test@1.0.so product/lib64/
adb push ./vendor/lib/vendor.monet.hardware.test@1.0.so vendor/lib/
adb push ./vendor/lib64/vendor.monet.hardware.test@1.0.so vendor/lib64/
adb push ./system_ext/lib/vendor.monet.hardware.test@1.0.so system_ext/lib/
adb push ./system_ext/lib64/vendor.monet.hardware.test@1.0.so system_ext/lib64/

adb push ./vendor/lib/hw/vendor.monet.hardware.test@1.0-impl.so vendor/lib/hw/
adb push ./vendor/lib64/hw/vendor.monet.hardware.test@1.0-impl.so vendor/lib64/hw/

adb push ./vendor/bin/hw/vendor.monet.hardware.test@1.0-service vendor/bin/hw/

adb push ./vendor/etc/vintf/manifest/vendor.monet.hardware.test-service.xml vendor/etc/vintf/manifest

adb push system/bin/hidl_test_bin system/bin(测试的bin程序)
然后执行
adb reboot
重启后
关闭selinux: adb shell setenforce 0
窗口1:起hidl服务
adb shell
cd vendor/bin/hw
./vendor.monet.hardware.test@1.0-service

窗口2:起test bin程序
adb shell
hidl_test_bin 100

然后观察窗口2输出什么
如果输出如下则代表两者通信成功
get hal service scuess
value is 100
wslTest::test

15. 可能碰到的问题

15.1 错误1
04-14 12:27:02.103 599 599 I hwservicemanager: getTransport: Cannot find entry vendor.qti.hardware.customizehidl@1.0::ICustomizeHidl/default in either framework or device VINTF manifest.
04-14 12:27:02.104 4169 4169 E HidlServiceManagement: Service vendor.qti.hardware.customizehidl@1.0::ICustomizeHidl/default must be in VINTF manifest in order to register/get

那就是vintf manifest相关的配置出现问题,可以检查下是否有push相应的manifest文件,接口的内容是否书写正确等。

15.2 新增目录放hal服务
如遇到新建的目录编译不出来相关hidl的out下相关文件,需要添加update-makefiles.sh文件,可以从其他hidl的目录中拷贝过来,修改其中的目录即可

set -e

if [ -z “$ANDROID_BUILD_TOP” ]; then
echo “Missing ANDROID_BUILD_TOP env variable. Run ‘lunch’ first.”
exit 1
fi

source $ANDROID_BUILD_TOP/system/tools/hidl/update-makefiles-helper.sh

do_makefiles_update
“vendor/newname/interfaces/customizehidl”

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 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、付费专栏及课程。

余额充值