JNI的实现
1.frameworks/base/services/core/jni/com_android_server_TestLedService.cpp
#define LOG_TAG "TestLedServiceJni"#include "jni.h"#include "JNIHelp.h"#include "android_runtime/AndroidRuntime.h"#include#include#include#include#includenamespace android { struct testled_device_t* testled_device = NULL; static void testled_setLed1(JNIEnv* env, jobject clazz, jint value) { int val = value; ALOGI("TestLed JNI: set value %d to led1.", val); if(!testled_device) { ALOGI("TestLed JNI: device is not open."); return; } if(val > 0){ testled_device->control(0);//on }else{ testled_device->control(1);//off } }static void testled_setLed2(JNIEnv* env, jobject clazz, jint value) { int val = value; ALOGI("TestLed JNI: set value %d to led2.", val); if(!testled_device) { ALOGI("TestLed JNI: device is not open."); return; } if(val > 0){ testled_device->control(2);//on }else{ testled_device->control(3);//off } }static inline int testled_device_open(const hw_module_t* module, struct testled_device_t** device) { return module->methods->open(module, LED_HAL_MODULE_ID, (struct hw_device_t**)device); }static jboolean testled_init(JNIEnv* env, jclass clazz) { testled_module_t* module; ALOGI("TestLed JNI: initializing......"); if(hw_get_module(LED_HAL_MODULE_ID, (const struct hw_module_t**)&module) == 0) { ALOGI("TestLed JNI: testled Stub found."); if(testled_device_open(&(module->common), &testled_device) == 0) { ALOGI("TestLed JNI: testled device is open."); //testled_device->open(); return 0; } ALOGE("TestLed JNI: failed to open testled device."); return -1; } ALOGE("TestLed JNI: failed to get testled stub module."); return -1; } static const JNINativeMethod method_table[] = { {"testledinit_native", "()Z", (void*)testled_init}, {"setled1_native", "(I)V", (void*)testled_setLed1}, {"setled2_native", "(I)V", (void*)testled_setLed2}, }; int register_android_server_TestLedService(JNIEnv *env) { return jniRegisterNativeMethods(env, "com/android/server/TestLedService", method_table, NELEM(method_table)); }};
com_android_server_TestLedService.cpp文件实现了JNI方法testled_setLed1,testled_setLed2,还有JNI初始化的入口函数testled_init。
在testled_init内通过LED_HAL_MODULE_ID匹配到了Hal内的硬件模块,再通过testled_device_open得到了device结构体。在testled_setLed1和 testled_setLed2调用了device结构体在Hal层实现的led操作函数接口。
注意com_android_server_TestLedService文件的命令方法,com_android_server表示的是包名,表示硬件服务TestLedService在frameworks/base/services/java目录下的com/android/server目录下,此目录下的TestLedService的类是可以直接调用jni的内容的。
2.frameworks/base/services/core/jni/onload.cpp
namespace中增加函数声明
namespace android { ……int register_android_server_TestLedService(JNIEnv *env);};JNI_OnLoad增加register_android_server_TestLedService的函数调用extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */){ … register_com_android_server_rkdisplay_RkDisplayModes(env); register_android_server_TestLedService(env);return JNI_VERSION_1_4; }
这一步是Framework加载jni库,也就是在/system/lib/hw/test_led_hal.default.so被导入了。 3.frameworks/base/services/core/jni/Android.mk
在LOCAL_SRC_FILES变量中增加一行
LOCAL_SRC_FILES += \ …… $(LOCAL_REL_DIR)/com_android_server_TestLedService.cpp \$(LOCAL_REL_DIR)/onload.cpp
4.局部编译
mmm frameworks/base/services/jni
make snod
重新打包的system.img镜像文件就包含了LedTest的JNI方法了,后面我们可以通过Android系统的Framework层提供的硬件服务LedTestService来调用这些JNI方法,进而调用更低层的硬件抽象层接口去访问硬件了。Framework层的LedTestService服务在下一篇实现。