JNIレイヤの追加

4101 ワード

これは一連の文章です.
  • Androidカーネル追加駆動
  • fregドライバをテストする機能内蔵Cプログラム
  • HALレイヤコード
  • を追加
  • JNI層
  • を追加
  • フレーム層追加ハードウェアアクセスサービス
  • このシリーズはandroidの下から上までの各層に簡単なデザインがあり、スズメは小さいが、五臓がそろっている.enjoy now!
    Javaコードを使用するためにcコードを呼び出す.対応するJNIを実現する方法が必要である.
    frameworks/base/services/core/jni/
        ----com_android_server_FregService.cpp
        ----Android.mk
        ----onload.cpp
    system/core/rootdir/ueventd.rc
    

    com_android_server_FregService.cpp
    #define LOG_TAG "FregServiceJNI"
    
    #include "jni.h"
    #include "JNIHelp.h"
    #include "android_runtime/AndroidRuntime.h"
    
    #include 
    #include 
    #include 
    #include 
    
    #include 
    
    namespace android
    {
            static void freg_setVal(JNIEnv* env, jobject clazz, jint ptr, jint value) {
                    freg_device_t* device = (freg_device_t*)ptr;
                    if(!device) {
                            ALOGE("Device freg is not open.");
                            return;
                    }
    
                    int val = value;
    
                    ALOGI("Set value %d to device freg.", val);
    
                    device->set_val(device, val);
            }
    
            static jint freg_getVal(JNIEnv* env, jobject clazz, jint ptr) {
                    freg_device_t* device = (freg_device_t*)ptr;
                    if(!device) {
                            ALOGE("Device freg is not open.");
                            return 0;
                    }
    
                    int val = 0;
    
                    device->get_val(device, &val);
    
                    ALOGI("Get value %d from device freg.", val);
    
                    return val;
            }
    
            static inline int freg_device_open(const hw_module_t* module, struct freg_device_t** device) {
                    return module->methods->open(module, FREG_HARDWARE_DEVICE_ID, (struct hw_device_t**)device);
            }
    
            static jint freg_init(JNIEnv* env, jclass clazz) {
                    freg_module_t* module;
                    freg_device_t* device;
    
                    ALOGI("Initializing HAL stub freg......");
    
                    if(hw_get_module(FREG_HARDWARE_MODULE_ID, (const struct hw_module_t**)&module) == 0) {
                            ALOGI("Device freg found.");
                            if(freg_device_open(&(module->common), &device) == 0) {
                                    ALOGI("Device freg is open.");
                                    return (jint)device;
                            }
    
                            ALOGE("Failed to open device freg.");
                            return 0;
                    }
    
                    ALOGE("Failed to get HAL stub freg.");
    
                    return 0;
            }
    
            static const JNINativeMethod method_table[] = {
                    {"init_native", "()I", (void*)freg_init},
                    {"setVal_native", "(II)V", (void*)freg_setVal},
                    {"getVal_native", "(I)I", (void*)freg_getVal},
            };
    
            int register_android_server_FregService(JNIEnv *env) {
                    return jniRegisterNativeMethods(env, "com/android/server/FregService", method_table, NELEM(method_table));
            }
    };
    

    Android.mk、LOCAL_SRC_FILES +=に追加:
        $(LOCAL_REL_DIR)/com_android_server_FregService.cpp \
    

    onload.cpp、namespace androidに追加:
    int register_android_server_FregService(JNIEnv* env);
    
    extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)に追加:
        register_android_server_FregService(env);
    

    コンパイル:
    mmm frameworks/base/services/core/jni
    

    パッケージシステムイメージ:
    make snod
    

    ハードウェアデバイスへのアクセス権の追加:system/core/rootdir/ueventd.rc追加:
    /dev/freg      0666   root     root
    

    これでJNIメソッドの追加が完了し、engバージョンでSELinuxがオフの場合、このJNIメソッドは正常に動作します.アクセスするには、userバージョンでSELinuxを構成するポリシーファイルが必要です.