OpenHarmony系统之Service代码一键生成工具介绍
OpenHarmony系统之Service代码一键生成工具介绍前言
当开发者为OpenHarmony系统框架开发某些功能时,有时需要将这个功能包装成一个独立的服务进程运行在系统中,为了其它应用进程能够调用此服务,开发人员需要基于系统IPC通信框架编写一套远程接口调用实现。实现Service远程调用接口需要开发人员熟悉IPC通信框架,了解proxy/stub的继承与实现方式,掌握C++类型转为MessageParcel数据包的各种API方法,有一定的学习成本。而Service代码生成工具能够帮助使用者生成框架代码,提升开发效率。用户只需提供一个定义远程方法的.h头文件,工具会自动生成整个Service框架的代码,包含Ability注册、proxy/stub类实现、MessageParcel数据包构造、Service子系统编译及开机自启动相关配置文件。
1.工具原理
Service框架代码生成工具包含工具入口、工具框架、公共模块、运行环境、系统平台。其中,工具入口描述调用Service框架代码生成工具的入口方式,支持命令行调用、VS Code插件(即VS插件)调用,从而可以根据开发环境的不同,采用相对应的调用Service框架代码生成工具的入口方式,实现Service框架代码生成工具的入口多样性,便于调用Service框架代码生成工具。工具框架包含C++语法解析器、代码生成器两部分,C++语法解析器支持包括但不限于对class、function、properties、parameter等内容的解析,代码生成器支持包括但不限于对proxy、stub、service、interface等服务框架代码的生成。公共模块描述通用的、在不同部分均会使用的公共接口与模块,可以包括通用的正则校验、类型映射、代码模板、文件操作等模块,运行环境描述Service框架代码生成工具运行的环境,包括Nodejs与Python,由于Nodejs本身具有跨平台性特点,故Service框架代码生成工具可以在Windows、linux、mac、OpenHarmony等不同系统平台灵活使用,Service框架代码生成工具的运行环境另一部分是python,针对不同平台做python适配,Service框架代码生成工具即可实现跨平台使用。
架构图
2.使用说明
环境
visual studio code 版本需1.62.0及以上。
步骤
1、 打开VS Code,在左侧边栏中选择插件安装。
2、 在应用商店搜索service-gen插件,再单击安装。
3、 安装完成后就会在VS Code的插件管理器中能看到service-gen这个插件了。
4、 在VS Code中找到需要转换的.h文件,待转换的.h文件内容如下所示:
#ifndef TEST_H
#define TEST_H
namespace OHOS {
namespace Example {
/**
* @brief service服务,提供IPC调用接口
* @ServiceClass
*/
class test {
public:
int testFunc(int v1, int v2, bool v3);
};
}// namespace Example
}// namespace OHOS
#endif// TEST_H5、 右键单击.h文件,选择“ Service Generate Frame”选项。
6、 工具打开 Service Generate Frame窗口,.h文件选择框默认填写被操作的.h文件的绝对路径;输出路径选择框默认填写.h文件所在文件夹路径,可修改为任意路径;serviceID范围是1-16777215之间的整数,超出范围会提示错误,填入正确的serviceID,然后点击ok。
7、 转换成功后,在输出路径下生成service框架代码文件。
输出文件说明
service工具生成文件说明如下图所示:
其中消息调用流程为:
服务端实现SystemAbility接口OnStart(),将自己的serviceId注册到SystemAbility Manager管理类。客户端根据serviceId向SystemAbility Manager管理类获取该service的proxy对象。客户端使用proxy对象调用服务端的远程接口。proxy将客户端传入的c++参数打包成消息数据,通过系统提供的dbinder进程间通信能力发送到服务端进程。服务端OnRemoteRequest()接收到远程调用消息,根据消息id分发给不同的innerFunction()处理。服务端innerFunction()将远程消息数据包还原成C/C++参数,传入业务入口方法供业务开发人员处理。
3.集成说明
本集成说明针对的是OpenHarmony 3.2release系统,其他系统可能存在差别,开发者可自行调试修改。
修改编译文件
[*]修改testservice/BUILD.gn文件,将utils/native 改为 commonlibrary/c_utils,将samgr_standard改为samgr。修改后的BUILD.gn文件内容如下所示:
import("//build/ohos.gni")
ohos_shared_library("testservice") {
sources = [
"//testservice/src/i_test_service.cpp",
"//testservice/src/test_service_stub.cpp",
"//testservice/src/test_service.cpp"
]
include_dirs = [
"//testservice/include",
"//testservice/interface",
"//commonlibrary/c_utils/base/include"
]
deps = [
"//base/startup/syspara_lite/interfaces/innerkits/native/syspara:syspara",
"//commonlibrary/c_utils/base:utils",
]
external_deps = [
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_core",
"safwk:system_ability_fwk",
"samgr:samgr_proxy",
"startup_l2:syspara",
]
part_name = "testservice_part"
subsystem_name = "testservice"
}
ohos_executable("testclient") {
sources = [
"//testservice/src/i_test_service.cpp",
"//testservice/src/test_service_proxy.cpp",
"//testservice/src/test_client.cpp"
]
include_dirs = [
"//testservice/include",
"//testservice/interface",
"//commonlibrary/c_utils/base/include"
]
deps = [
"//commonlibrary/c_utils/base:utils",
]
external_deps = [
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_core",
"samgr:samgr_proxy",
]
part_name = "testservice_part"
subsystem_name = "testservice"
}
[*]修改testservice/bundle.json文件,将"name": "@ohos/testservice"修改为 "name": "@ohos/testservice_part";将"samgr_standard"改为"samgr","utils_base"修改为"c_utils";修改的bundle.json文件内容如下所示:
{
"name": "@ohos/testservice_part",
"description": "system ability framework test",
"homePage": "https://gitee.com/",
"version": "3.1",
"license": "Apache License 2.0",
"repository": "",
"publishAs": "code-segment",
"segment": {
"destPath": "testservice"
},
"dirs": {},
"scripts": {},
"component": {
"name": "testservice_part",
"subsystem": "testservice",
"adapted_system_type": [
"standard"
],
"rom": "2048KB",
"ram": "~4096KB",
"deps": {
"components": [
"hiviewdfx_hilog_native",
"ipc",
"samgr",
"c_utils",
"safwk",
"startup_l2"
],
"third_party": [ "libxml2" ]
},
"build": {
"sub_component": [
"//testservice:testservice",
"//testservice/sa_profile:testservice_sa_profile",
"//testservice:testclient",
"//testservice/etc:test_service_init"
],
"inner_kits": [
],
"test": [
]
}
}
}
修改系统公共文件
基本配置
[*]服务配置foundation/systemabilitymgr/samgr/interfaces/innerkits/samgr_proxy/include/system_ability_definition.h增加以下两行(ID说明: TEST_SERVICE_ID值与用户指定的ID一致;TEST_SERVICE_ID宏值定义必须为这个,因为代码中使用的就是这个)
TEST_SERVICE_ID = 9016,
{TEST_SERVICE_ID, "testservice" },
[*]子系统配置build/subsystem_config.json增加以下内容
"testservice": {
"path":"testservice",
"name": "testservice"
}
[*]产品配置,如rk3568vendor/hihope/rk3568/config.json增加以下内容
{
"subsystem": "testservice",
"components": [
{
"component": "testservice_part",
"features": []
}
]
}注意:若用户需要配置selinux相关配置,则将开关改为true,再根据自身需求进行相关配置
[*]权限配置在相应产品目录下vendor/hihope/rk3568/security_config/high_privilege_process_list.json增加以下内容
{
"name": "testservice",
"uid": "system",
"gid": ["root", "system"]
}
selinux安全配置
[*]testservice/etc/sample_service.cfg"secon" : "u:r:testservice:s0"
[*]base/security/selinux/sepolicy/base/public/service_contexts9016 u:object_r:sa_testservice:s0
[*]base/security/selinux/sepolicy/base/public/service.tetype sa_testservice, sa_service_attr;
[*]base/security/selinux/sepolicy/base/te/init.teallow init testservice:process { getattr rlimitinh siginh transition };
[*]base/security/selinux/sepolicy/base/public/type.tetype testservice, sadomain, domain;
[*]/base/security/selinux/sepolicy/base/te目录下增加新service的te文件,新增文件名即为服务名,例如:testserviceallow testservice init_param:file { map open read };
allow testservice sa_testservice:samgr_class { add get };
4.示例演示
服务端修改
test_service.cpp:在testservice/src/test_service.cpp注释“// TODO: Invoke the business implementation”处添加各个接口的服务端实现代码。本例实现一个简单的加减法,服务端代码如下所示:
int testService::testFunc(int v1, int v2, bool v3)
{
// TODO: Invoke the business implementation
int ret = 0;
printf("service test begin \r\n");
if (v3) {
printf("service test v3 = true\r\n");
ret = v1 + v2;
} else {
printf("service test v3 = false \r\n");
ret = v1 - v2;
}
printf("service test end \r\n");
return ret;
}远程方法的参数包装已在生成代码test_service_stub.cpp中统一处理,开发人员无需关注
客户端修改
test_client.cpp 为自动生成的客户端样例代码。编译烧录后,会在/system/bin/目录下生成可执行程序test_client,在testservice/src/test_client.cpp的main函数中使用proxy对象进行远程方法调用,参考注释示例。本例实现一个简单的加减法,客户端代码如下所示:
int main(int argc, char *argv[])
{
printf("---functest begin---\r\n");
auto proxy = getRemoteProxy();
uint32_t result = 0;
// TODO: Invoke remote method by proxy
result = proxy->testFunc(8, 5, false);
printf("result is : %u\r\n", result);
printf("---functest end---\r\n");
IPCSkeleton::JoinWorkThread();
return 0;
}远程方法的参数包装已在生成代码test_service_proxy.cpp中统一处理,开发人员无需关注
编码完成后,执行镜像编译命令
./build.sh --product-name 产品名若编译rk3568开发板,则执行
./build.sh --product-name rk3568运行
将编译好的镜像烧录到开发板后,使用hdc_std shell登录开发板。 查看服务端进程是否已正常启动
ps -ef | grep testservice
system 682 1 0 08:00:08 ? 00:00:00 testservice_sa--- 服务进程已正常运行如下图所示:
运行客户端
/system/bin/testclient运行结果如下所示:
---functest begin---
result is : 3
---functest end---(客户端具体执行哪些远程调用方法请在test_client.cpp的main方法中实现)
总结
service生成工具是一个开源项目,我们欢迎有兴趣的开发者试用该工具,并提出宝贵的改进意见,我们将继续不断优化和完善该工具软件。我们相信,该工具会成为OpenHarmony生态圈中一个有用的补充。 大佬你好,我按照你这个方法一步步去做了个SA服务,服务可以拉起来,之后直接显示Signal 11,然后服务就失败了,请问遇到过这个问题吗? сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт
сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт
сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт
сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт
сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт
сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт
сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт
сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт сайт
页:
[1]