Android 从上到下写一个例子 本地服务(二)

该博客详细介绍了如何在Android系统中从上到下编写一个使用SELinux权限的例子,涉及本地服务的创建、JNI接口定义、硬件抽象层(HAL)调用。通过`godv_open`和`godv_ioctl`方法实现了与硬件模块的交互,并展示了编译和运行过程,最终在logcat中验证了服务的成功启动。
摘要由CSDN通过智能技术生成

本文继上一篇文章继续写代码Android 从上到下写一个例子 SELinux权限(一)_we1less的博客-CSDN博客

此时需要一个本地服务首先将jni文件写好 包括调用hal层代码

路径frameworks/base/services/core/jni/com_android_server_GodvService.cpp

#define LOG_TAG "godv"

#include "jni.h"
#include <nativehelper/JNIHelp.h>
#include "android_runtime/AndroidRuntime.h"

#include <utils/misc.h>
#include <utils/Log.h>
//hw_module_t的头文件
#include <hardware/hardware.h>

#include <stdio.h>

namespace android
{

//实际硬件的结构体 继承自hw_device_t
struct led_device_t
{
	hw_device_t commn;
	int (*hal_open)();
	int (*hal_ioctl)(int which,int status);
	int (*hal_close)();
};

struct led_device_t *led;

//没用到的形参可以省略
static jint godv_open(JNIEnv*, jobject) {
    ALOGE("native::godv_open");
    struct hw_module_t *module;
    struct hw_device_t *device;
    int res;
    //参数1模块id 参数2要获取的模块的结构体
    res = hw_get_module("godvled", (const struct hw_module_t **)&module);
    if(res == 0) {
        ALOGE("native::hw_get_module success");
        //参数1module 参数2模块id 参数3硬件设备的结构体
        res = module->methods->open(module, "godvled", &device);
        if(res == 0) {
            ALOGE("native::open success");
            led = (struct led_device_t *)device;
            //调用hal层的方法
            led->hal_open();
        }
    }

    return 0;
}

static jint godv_ioctl(JNIEnv*, jobject, jint which, jint status) {
    ALOGE("native::godv_ioctl which == %d , status == %d ", which, status);
    led->hal_ioctl(which, status);
    return 0;
}

static const JNINativeMethod method_table[] = {
    { "godv_open", "()I", (void*)godv_open },
    { "godv_ioctl", "(II)I", (void*)godv_ioctl }
};

int register_android_server_GodvService(JNIEnv *env)
{
    return jniRegisterNativeMethods(env, "com/android/server/GodvService",
            method_table, NELEM(method_table));
}

};

接下来在frameworks/base/services/core/jni/onload.cpp文件中将本地服务注册

extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
{
    JNIEnv* env = NULL;
    jint result = -1;

    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
        ALOGE("GetEnv failed!");
        return result;
    }
    ALOG_ASSERT(env, "Could not retrieve the env!");

    ...
    register_android_server_GodvService(env);
    register_android_hardware_display_DisplayViewport(env);

    return JNI_VERSION_1_4;
}

修改当前路径的mk文件 frameworks/base/services/core/jni

LOCAL_SRC_FILES += \
    ...
    $(LOCAL_REL_DIR)/com_android_server_GodvService.cpp \
    $(LOCAL_REL_DIR)/onload.cpp

编译 make -j16 ANDROID_COMPILE_WITH_JACK=false

编译成功后运行app得到log证明本地服务已经成功

godv@godv-OptiPlex-7070:~/godv/AOSP/android-8.1.0_r1$ adb logcat -s "godv"
--------- beginning of main
--------- beginning of system
--------- beginning of crash
09-09 23:18:32.692  1542  1542 D godv    : GodvService::godv_open
09-09 23:18:32.692  1542  1542 E godv    : native::godv_open
09-09 23:18:32.693  1542  1542 E godv    : native::hw_get_module success
09-09 23:18:32.693  1542  1542 E godv    : native::open success
09-09 23:18:32.693  1542  1542 I godv    : this is led_hal_open
09-09 23:18:47.074  1542  2000 D godv    : GodvService::gov_ioctl
09-09 23:18:47.074  1542  2000 E godv    : native::godv_ioctl which == 0 , status == 1 
09-09 23:18:47.074  1542  2000 I godv    : this is led_hal_ioctl
09-09 23:18:47.074  1542  2000 I godv    : which = 0, status = 1

看一下编译在system/lib/hw目录下的so

generic_x86_64:/system/lib/hw # ls
android.hardware.tests.libhwbinder@1.0-impl.so godvled.default.so  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值