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服务在下一篇实现。