aosp新增一个native服务

编写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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值