halmoudle需要涉及的三个关键结构体:
structhw_module_t;
structhw_module_methods_t;
structhw_device_t;
led.h文件
//HAL不能直接使用hw_module_t结构体,需要使用一个继承
structled_module_t {
struct hw_module_t common;
};
//自定义一个针对led控制的结构体,包含hw_module_t和支持的API操作
structled_control_device_t {
structhw_device_t common;
int(*set_on) (struct led_control_device_t *dev, int32_t led);
int(*set_off)(struct led_control_device_t *dev, int32_t led);
};
structled_control_context_t {
structled_control_device_t device;
};
//定义一个MODULE_ID,HAL层可以根据这个ID找到HALstub
#defineLED_HARDWARE_MODULE_ID “led”
led.c文件
int led_on(struct led_control_device_t *dev, int32_t led)
{
intfd;
charbuff[3] = “”;
intsize = 0;
if((fd= open(DEVICE_NAME,O_RDWR)) == -1)
{
LOGI(“openleds fail”);
return0;
}
memset(buff,'1',5);
buff[0]= 1;//表示led灯开
buff[1]= (char)led;//控制哪一个led灯
size= write(fd,buff,sizeof(buff));
LOGI(“LEDStub:set %d on”,led);
close(fd);
return0;
}
intled_off(struct led_control_device_t *dev, int32_t led)
{
intfd;
charbuff[5] = “”;
intsize = 0;
if((fd= open(DEVICE_NAME,O_RDWR)) == -1)
{
LOGI(“openleds fail”);
return0;
}
memset(buff,0,3);
buff[0]= 0;//表示led灯关
buff[1]= (char)led;
size= write(fd,buff,sizeof(buff));
LOGI(“LEDStub:set %d off”,led);
close(fd);
return0;
}
staticint led_device_open(const struct hw_module_t *module, const char*name, struct hw_device_t **device)
{
structled_control_device_t *dev;
dev =(struct led_control_device_t*)malloc(sizeof(*dev));
memset(dev,0, sizeof(*dev));
dev->common.tag= HARDWARE_DEVICE_TAG;
dev->common.version= 0;
dev->common.module= module;
dev->common.close= led_device_close;
dev->set_on= led_on;//实例化支持的操作
dev->set_off= led_off;
*device=&dev->common;//将实例化后的led_control_device_t地址返回给jni层,这样jni层就可以直接调用led_on,led_off,led_device_close方法
success:
return0;
}
//向系统注册一个ID为LED_HARDWARE_MODULE_ID的stub,注意这里的HAL_MODULE_INFO_SYM不能修改
conststruct led_module_t HAL_MODULE_INFO_SYM = {
common:{
tag: HARDWARE_MODULE_TAG,
version_major: 1,
version_minor: 0,
id:LED_HARDWARE_MODULE_ID,
name: “Sample LED Stub”,
author: “LED CONTROL”;
methods: &led_module_methods,
}
};
JNI层文件:(com_liumr_server_LedService.cpp)
structled_control_device_t *sLedDevice = NULL;
staticjboolean _setOn(JNIEnv *env, jobject thiz, jint led)
{
LOGI(“LedServiceJNI: _setOn() is invoked”);
if(sLedDevice== NULL)
{
LOGI(“LedServiceJNI: sLedDevice was not fetched correctly”);
return-1;
}else{
returnsLedDevice->set_on(sLedDevice,led);//调用HAL层的方法
}
}
staticjboolean _setOff(JNIEnv *env, jobject thiz, jint led)
{
LOGI(“LedServiceJNI: _setOff()is invoked”);
if(sLedDevice== NULL)
{
LOGI(“LedServiceJNI: sLedDevice was not fetched correctly”);
return-1;
}else{
returnsLedDevice->set_off(sLedDevice,led);//调用HAL层的方法
}
}
staticinline int led_control_open(const struct hw_module_t *module, structled_control_device_t **device)
{
//这个过程很重要,JNI通过LED_HARDWARE_MODULE_ID找到对应的Stub
returnmodule->methods->open(module, LED_HARDWARE_MODULE_ID, (structhw_device_t **)device);
}
staticjboolean _init(JNIEnv *env, jclass clazz)
{
led_module_t*module;
//根据LED_HARDWARE_MODULE_ID找到应对的hw_module_t
if(hw_get_module(LED_HARDWARE_MODULE_ID,(consthw_module_t **)&module) == 0) {
LOGI(“LedServiceJNI:LED Stub found”);
if(led_control_open(&module->common,&sLedDevice) == 0) {
LOGI(“LedServiceJNI: Got Stub operations”);
return0;
}
}
LOGE(“LedServiceJNI: Get Stub operations failed”);
return-1;
}
/*
*JNINativeMethod是JNI层注册的方法,Framework层可以使用这些方法,
*()Z 无参数返回值的bool型
*(I)Z 整型参数返回值为bool型
*/
staticconst JNINativeMethod gMethods[] = {
{“_init”, “()Z”,(void*)_init},
{“_set_on”, “(I)Z”, (void *)_setOn},
{“_set_off”,“(I)Z”, (void *)setOff},
};
staticint registerMethods(JNIEnv *env)
{
staticconst char *const kClassName = “com/liumr/server/LedService”;
//必须与Framework层的service类名相同
jclassclazz;
clazz= env->FindClass(kClassName);
if(clazz= = NULL)
{
LOGE(“Can'tfind class %s\n”,kClassName);
return-1;
}
if(env->RegisterNatives(clazz,gMethods, sizeof(gMethods) / sizeof(gMethods[0])) != JNI_OK)
{
LOGE(“Failedregistering methods for %s\n”,kClassName);
return-1;
}
return0;
}
//Framework层加载JNI库时调用
jintJNI_OnLoad(JavaVM *vm, void* reserved)
{
JNIEnv*env = NULL;
jintresult = -1;
if(vm->GetEnv((void**)&env,JNI_VERSION_1_4) != JNI_OK)
{
LOGE(“ERROR:GetEnvfailed \n”);
gotobail;
}
assert(env!= NULL);
if(registerMethods(env)!= 0)
{
LOGE(“ERROR:PlatformLibrary native registeration failed\n”);
gotobail;
}
result= JNI_VERSION_1_4;
bail:
returnresult;
}
framework层的service文件
publicfinal class LedService extends IledService.Stub
{
static{
System.load(“/system/lib/libmokoid_runtime.so”);//动态加载库
}
publicLedService()
{
Log.i(“LedService”,”goto get LED Stub..”);
_init();
}
publicboolean setOn(int led)
{
Log.i(“Platform”,”LEDOn”);
return_set_on(led);
}
publicboolean setOff(int led)
{
Log.i(“Platform”,”LEDOff”);
return _set_off(led);
}
privatestatic native boolean _init();
privatestatic native boolean _set_on(int led);
privatestatic native boolean _set_off(int led);
}
上层应用程序有两种调用模式:
(1)、直接通过service调用.so的jni
(2)、通过Manager调用service
publicclass LedManager
{
privatestatic final String TAG = “LedManager”;
privateIledService mLedService;
publicLedManager()
{
//利用ServiceManager获取LedService,从而调用它提供的方法,这要求LedService必须已经增加到ServiceManager中,这个过程将在App的一个service进程中完成。
mLedService= IledService.Stub.asInterface(ServiceManager.getService(“led”));
if(mLedService!= null)
Log.i(TAG,”TheLedManager object is ready”);
}
publicboolean LedOn(int n)
{
booleanresult = false;
try{
result= mLedService.setOn(n);
}catch(RemoteExceptione){
Log.e(TAG,“RemoteExceptionin LedManager.LedOn”,e);
}
returnresult;
}
publicboolean LedOff(int n)
{
booleanresult = false;
try{
result= mLedService.setOff(n);
}catch(RemoteExceptione) {
Log.e(TAG,”RemoteExceptionin LedManager.LedOff”,e);
}
returnresult;
}
}