编写native可执行程序,编写rc脚本添加到系统服务
代码目录结构如下:
mynativeservice/
├── Android.mk
├── main_mynativeservice.cpp
└── mynativeservice.rc
- 编写native可执行程序
// mynativeservice/main_mynativeservice.cpp
#include <utils/Log.h>
using namespace android;
int main(int argc, char** argv){
ALOGD("mynativeservice is running.");
}
- 编写对应的mk脚本
# mynativeservice/Android.mk
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
main_mynativeservice.cpp
LOCAL_SHARED_LIBRARIES := \
libutils \
libbinder \
liblog
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE:= mynativeservice
LOCAL_INIT_RC := mynativeservice.rc
include $(BUILD_EXECUTABLE)
- 编写rc脚本,添加到系统服务
# mynativeservice/mynativeservice.rc
service mynativeservice /system/bin/mynativeservice
class main
user root
oneshot
-
配置打包进系统
-
添加selinux权限
新添加的native service,默认不能被client查找到,需要配置selinux权限
# mynativeservice/sepolicy/file_contexts
/system/bin/mynativeservice u:object_r:mynativeservice_exec:s0
# mynativeservice/sepolicy/file_contextsmynativeservice.te
# mynativeservice
type mynativeservice, domain, coredomain;
type mynativeservice_exec, exec_type, file_type, system_file_type;
init_daemon_domain(mynativeservice)
typeattribute mynativeservice coredomain;
typeattribute mynativeservice mlstrustedsubject;
binder_use(mynativeservice)
binder_service(mynativeservice)
allow mynativeservice servicemanager:binder { call transfer };
allow mynativeservice root_block_device:blk_file { read write open };
allow mynativeservice block_device:dir { search };
allow mynativeservice private_block_device:blk_file { read write open };
板型中添加
BOARD_VENDOR_SEPOLICY_DIRS += vendor/aw/public/framework/mynativeservice/sepolicy
定制aidl接口
代码目录结构如下:
mynativeservice/
├── Android.mk
├── libmynativeservice
│ ├── aidl
│ │ └── com
│ │ └── example
│ │ └── IMyNativeService.aidl
│ ├── Android.bp
│ ├── MyNativeService.cpp
│ └── MyNativeService.h
├── main_mynativeservice.cpp
└── mynativeservice.rc
- 编写aidl
// mynativeservice/libmynativeservice/aidl/com/example/IMyNativeService.aidl
package com.example;
interface IMyNativeService {
void hello();
int world();
}
编写服务,并添加到binder
aidl可以编译的时候自动生成binder相关代码,像BnMyNativeService、BpMyNativeService之类的
定义服务接口
// mynativeservice/libmynativeservice/MyNativeService.h
#ifndef BEANSERVICE_H
#define BEANSERVICE_H
#include <com/example/BnMyNativeService.h>
#include <binder/BinderService.h>
namespace android {
class MyNativeService:
public BinderService<MyNativeService>,
public virtual ::com::example::BnMyNativeService,
public virtual IBinder::DeathRecipient
{
public:
// Implementation of BinderService<T>
static char const* getServiceName() { return "my_native.service"; }
// IBinder::DeathRecipient implementation
virtual void binderDied(const wp<IBinder> &who);
MyNativeService();
~MyNativeService();
virtual binder::Status hello();
virtual binder::Status world(int32_t* _aidl_return);
};
}
#endif
- 编写服务
// mynativeservice/libmynativeservice/MyNativeService.cpp
#define LOG_TAG "MyNativeService"
//#define LOG_NDEBUG 0
#include "MyNativeService.h"
#include <iostream>
namespace android {
using binder::Status;
MyNativeService::MyNativeService() {
ALOGD(" MyNativeService::instantiate ");
}
MyNativeService::~MyNativeService() {
}
/*virtual*/void MyNativeService::binderDied(const wp<IBinder> &who) {
ALOGE("%s: Java client's binder died, removing it from the list of active clients, who=%p",
__FUNCTION__, &who);
}
Status MyNativeService::hello() {
ALOGD(" MyNativeService::hello ");
return Status::ok();
}
Status MyNativeService::world(int32_t* _aidl_return) {
ALOGD(" MyNativeService::world ");
*_aidl_return = 10;
return Status::ok();
}
}
- 编写bp,编译生成共享库
// mynativeservice/libmynativeservice/Android.bp
cc_library_shared {
name: "libmynativeservice_aidl",
aidl: {
export_aidl_headers: true,
local_include_dirs: ["aidl"],
include_dirs: [
],
},
srcs: [
":mynativeservice_aidl",
],
shared_libs: [
"libbase",
"libcutils",
"libutils",
"liblog",
"libbinder",
"libgui",
],
cflags: [
"-Werror",
"-Wall",
"-Wextra",
],
}
filegroup {
name: "mynativeservice_aidl",
srcs: [
"aidl/com/example/IMyNativeService.aidl",
],
path: "aidl",
}
cc_library_shared {
name: "libmynativeservice",
srcs: [
"MyNativeService.cpp",
],
header_libs: [
],
shared_libs: [
"libmynativeservice_aidl",
"libbase",
"libui",
"liblog",
"libutils",
"libbinder",
"libcutils",
],
static_libs: [
],
include_dirs: [
],
export_shared_lib_headers: [
"libbinder",
"libmynativeservice_aidl",
],
export_include_dirs: ["."],
cflags: [
"-Wall",
"-Wextra",
"-Werror",
"-Wno-ignored-qualifiers",
],
}
- 启动服务
服务业务代码编写完成后,在main()中启动并添加binder中
// mynativeservice/main_mynativeservice.cpp
#include <utils/Log.h>
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include "MyNativeService.h"
using namespace android;
int main(int argc, char** argv){
ALOGD("mynativeservice is running.");
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
ALOGI("ServiceManager: %p", sm.get());
MyNativeService::instantiate();
ALOGI("ServiceManager: %p done instantiate", sm.get());
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
}
同时,需要修改mk添加共享库依赖
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
main_mynativeservice.cpp
LOCAL_SHARED_LIBRARIES := \
libutils \
libbinder \
liblog \
libmynativeservice # 添加依赖
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE:= mynativeservice
LOCAL_INIT_RC := mynativeservice.rc
include $(BUILD_EXECUTABLE)
编写client调用程序
上面service已经实现并可以跑起来了,现在编写client调用程序
// mynativeservice/client/mynativeservice_client.cpp
#define LOG_TAG "mynativeserviceclient"
#include <com/example/IMyNativeService.h>
#include <binder/IServiceManager.h>
using namespace android;
using com::example::IMyNativeService;
int main(int argc __unused, char** argv __unused) {
ALOGD("mynativeserviceclient start...");
// 先获取IServiceManager
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder;
do {
// 通过服务名称拿到代理对象
binder = sm->getService(String16("my_native.service"));
if (binder != 0) {
break;
}
usleep(500000); // 0.5s
} while (true);
ALOGD("mynativeserviceclient getbinder finish...");
// 转换成IBeanService
sp<IMyNativeService> myNativeService = interface_cast<IMyNativeService>(binder);
// 通过代理调用服务端函数
myNativeService->hello();
return 0;
}
编译固件刷机后正常运行,添加native service和client成功了,最后代码目录如下:
tree mynativeservice/
mynativeservice/
├── Android.mk
├── client
│ ├── Android.bp
│ └── mynativeservice_client.cpp
├── libmynativeservice
│ ├── aidl
│ │ └── com
│ │ └── example
│ │ └── IMyNativeService.aidl
│ ├── Android.bp
│ ├── MyNativeService.cpp
│ └── MyNativeService.h
├── main_mynativeservice.cpp
├── mynativeservice.rc
└── sepolicy
├── file_contexts
└── mynativeservice.te
6 directories, 11 files
参考资料
- https://blog.csdn.net/weixin_41678668/article/details/129828093
- https://blog.csdn.net/a546036242/article/details/136846096