前面已经添加好了HAL层,由于HAL层由c++开发的,而应用程序框架层中的硬件访问服务是使用java语言开发的,所以硬件访问服务必须通过java本地接口(JNI)来调用硬件抽象层模块的接口。使java代码可以调用c代码
frameworks/base/services/core/jni
com_android_server_DemoService:
#define LOG_TAG "DemoService"
#include "jni.h"
#include "JNIHelp.h"
#include "android_runtime/AndroidRuntime.h"
#include <utils/misc.h>
#include <utils/Log.h>
#include <hardware/hardware.h>
#include <hardware/demo.h>
#include <stdio.h>
namespace android
{
//设置虚拟硬件设备demo的寄存器的值
static void demo_setVal(JNIEnv* env, jobject clazz, jint ptr, jint value) {
//将参数ptr转化为demo_device_t结构体变量
demo_device_t* device = (demo_device_t*)ptr;
if(!device) {
ALOGE("Device demo is not open.");
return;
}
int val = value;
ALOGI("Set value %d to device demo.", val);
device->set_val(device, val);
}
//设置虚拟硬件设备demo的寄存器的值
static jint demo_getVal(JNIEnv* env, jobject clazz, jint ptr) {
//将参数ptr转化为demo_device_t结构体变量
demo_device_t* device = (demo_device_t*)ptr;
if(!device) {
ALOGE("Device demo is not open.");
return 0;
}
int val = 0;
device->get_val(device, &val);
ALOGI("Get value %d from device demo.", val);
return val;
}
//打开虚拟硬件设备demo
static inline int demo_device_open(const hw_module_t* module, struct demo_device_t** device) {
return module->methods->open(module, DEMO_HARDWARE_DEVICE_ID, (struct hw_device_t**)device);
}
//初始化虚拟硬件设备demo
static jint demo_init(JNIEnv* env, jclass clazz) {
demo_module_t* module;
demo_device_t* device;
ALOGI("Initializing HAL stub demo......");
//加载虚拟硬件设备demo
if(hw_get_module(DEMO_HARDWARE_MODULE_ID, (const struct hw_module_t**)&module) == 0) {
ALOGI("Device demo found.");
//打开虚拟硬件设备demo
if(demo_device_open(&(module->common), &device) == 0) {
ALOGI("Device demo is open.");
//将demo_device_t接口转化为整型值返回
return (jint)device;
}
ALOGE("Failed to open device demo.");
return 0;
}
ALOGE("Failed to get HAL stub demo.");
return 0;
}
//java本地接口方法表
static const JNINativeMethod method_table[] = {
{"init_native", "()I", (void*)demo_init},
{"setVal_native", "(II)V", (void*)demo_setVal},
{"getVal_native", "(I)I", (void*)demo_getVal},
};
//注册java本地接口方法
int register_android_server_demoService(JNIEnv *env) {
return jniRegisterNativeMethods(env, "com/android/server/demoService", method_table, NELEM(method_table));
}
};
然后在Android.mk添加编译选项
LOCAL_SRC_FILES += \
...
$(LOCAL_REL_DIR)/com_android_server_DemoService.cpp \
并且在onload.cpp中添加
extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
{
...
register_android_server_DemoService(env);
return JNI_VERSION_1_4;
}
最后编译打包
mmm frameworks/base/services/core/jni
make snod
注意:
这样JNI方法就添加完成了,如果你编译的是eng版本,SELinux是关闭的,那么该JNI方法是可以正常运行的.如果是user版本需要配置SELinux的策略文件才能访问.