美文网首页
Android之JAVA、JNI、HAL加载流程梳理

Android之JAVA、JNI、HAL加载流程梳理

作者: 锄禾豆 | 来源:发表于2022-02-08 09:06 被阅读0次

    源码

    frameworks/base/services/java/com/android/server/SystemServer.java
    
    libnativehelper/include/nativehelper
    jni.h
    JNIHelp.h
    
    frameworks/base/services/core/jni
    onload.cpp
    com_android_server_HardwarePropertiesManagerService.cpp
    
    hardware/libhardware/include/hardware
    hardware.h
    thermal.h
    
    hardware/libhardware/hardware.c
    hardware/libhardware/modules/thermal/thermal.c
    
    注
    7.1
    

    以system_server中的服务HardwarePropertiesManagerService为案例
    一、java到jni流程
    1.system_server启动

    SystemServer.main --> SystemServer.run
        private void run() {
            ···
            // Initialize native services.
            System.loadLibrary("android_servers");
            ···
        }
        //System.loadLibrary加载共享库libandroid_servers.so
    
    注意
    System.loadLibrary的调用,实际触发so的JNI_OnLoad函数
    

    2.查看共享库libandroid_servers.so中涉及的JNI_OnLoad

    onload.cpp
    
    namespace android {
    ···
    int register_android_server_HardwarePropertiesManagerService(JNIEnv* env);
    ···
    };
    
    using namespace android;
    
    extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
    {
        ··· 
        register_android_server_HardwarePropertiesManagerService(env);
        ···
        return JNI_VERSION_1_4;
    }
    
    注意
    源码涉及路径frameworks/base/services/core/jni。这里,可以根据
    mk中定义的模块“LOCAL_MODULE:= libandroid_servers”查找对应的代码路径
    

    3.查看定义register_android_server_HardwarePropertiesManagerService的文件

    com_android_server_HardwarePropertiesManagerService.cpp
    
    static const JNINativeMethod gHardwarePropertiesManagerServiceMethods[] = {
        /* name, signature, funcPtr */
        { "nativeInit", "()V",
                (void*) nativeInit },//java方法对应的jni方法
        { "nativeGetFanSpeeds", "()[F",
                (void*) nativeGetFanSpeeds },
        { "nativeGetDeviceTemperatures", "(II)[F",
                (void*) nativeGetDeviceTemperatures },
        { "nativeGetCpuUsages", "()[Landroid/os/CpuUsageInfo;",
                (void*) nativeGetCpuUsages }
    };
    
    int register_android_server_HardwarePropertiesManagerService(JNIEnv* env) {
        
        int res = jniRegisterNativeMethods(env, "com/android/server/HardwarePropertiesManagerService",
                                           gHardwarePropertiesManagerServiceMethods,
                                           NELEM(gHardwarePropertiesManagerServiceMethods));//jni的关键点:java的native方法和jni方法绑定起来,这里涉及java类和对应的方法关系建立
    
        return res;
    }
    
    注意:
    1)java和cpp建立起来,涉及一个共享库libnativehelper的推动
    jni.h、JNIHelper.h
    2)JNINativeMethod说明
    typedef struct {
        const char* name;
        const char* signature;
        void*       fnPtr;
    } JNINativeMethod;
    name 对应的signature 怎么来?
    javac ***.java   //生成***.class文件
    javap -s ***.class  //可查对应的signature
    

    二、jni到HAL流程 -- 7.1

    1.前言

    HAL层有3+2+1原则,这跟java和jni建立联系有对应的模式要求一样。
    
    HLAL层的模块为hardware.h、hardware.c
    
    hardware.h
    /**
    * 3个结构体
    */
    struct hw_module_t;
    struct hw_module_methods_t;
    struct hw_device_t;
    
    /**
    * 2个常量
    */
    #define HAL_MODULE_INFO_SYM         HMI
    #define HAL_MODULE_INFO_SYM_AS_STR  "HMI"
    
    /**
    * 1个方法
    */
    int hw_get_module(const char *id, const struct hw_module_t **module);
    
    
    hardware.c
    int hw_get_module(const char *id, const struct hw_module_t **module)
    {
        return hw_get_module_by_class(id, NULL, module);
    }
    
    hw_get_module --> hw_get_module_by_class --> load
    相当于初始化module
    

    2.案例初始化gThermalModule(拓展hw_module_t)结构体

    com_android_server_HardwarePropertiesManagerService.cpp
    
    static struct thermal_module* gThermalModule;
    
    static void nativeInit(JNIEnv* env, jobject obj) {
        status_t err = hw_get_module(THERMAL_HARDWARE_MODULE_ID, (hw_module_t const**)&gThermalModule);
        if (err) {
            ALOGE("Couldn't load %s module (%s)", THERMAL_HARDWARE_MODULE_ID, strerror(-err));
        }
    }
    

    3.查看thermal_module结构体

    thermal.h
    
    typedef struct thermal_module {
        struct hw_module_t common;
    
        ssize_t (*getTemperatures)(struct thermal_module *module, temperature_t *list, size_t size);
    
        ssize_t (*getCpuUsages)(struct thermal_module *module, cpu_usage_t *list);
    
        ssize_t (*getCoolingDevices)(struct thermal_module *module, cooling_device_t *list,
                                     size_t size);
    
    } thermal_module_t;
    

    4.gThermalModule结构体实现之后的样子

    thermal.c
    
    /*====================================================*/
    /* Default Fan HW module interface definition */
    /*=====================================================*/
    static struct hw_module_methods_t thermal_module_methods = {
        .open = NULL,
    };
    
    thermal_module_t HAL_MODULE_INFO_SYM = {
        .common = {
            .tag = HARDWARE_MODULE_TAG,
            .module_api_version = THERMAL_HARDWARE_MODULE_API_VERSION_0_1,
            .hal_api_version = HARDWARE_HAL_API_VERSION,
            .id = THERMAL_HARDWARE_MODULE_ID,
            .name = "Default Thermal HAL",
            .author = "The Android Open Source Project",
            .methods = &thermal_module_methods,
        },
    
        .getTemperatures = get_temperatures,//真正实现的函数定义
        .getCpuUsages = get_cpu_usages,
        .getCoolingDevices = get_cooling_devices,
    };
    

    5.jni和hal的关联

    static jfloatArray nativeGetDeviceTemperatures(JNIEnv *env, jclass /* clazz */, int type,
                                                   int source) {
        if (gThermalModule && gThermalModule->getTemperatures) {
            ···
        }
        ···
    }
    //gThermalModule->getTemperatures就是thermal.c函数get_temperatures
    

    6.其他
    1)日志打印

    #define LOG_TAG "ThermalHAL"
    //#define LOG_NDEBUG  0   //打开此定义,则ALOGV可显示
    #include <utils/Log.h>  //一定要放在后面LOG_TAG/LOG_NDEBUG后面
    

    2)JNI的关键代码

    libnativehelper/include/nativehelper
    jni.h
    JNIHelp.h
    
    libnativerhelper/*
    

    3)快捷编译

    make libandroid_servers  
    1.编译system_server进程加载的共享库
    2.生成路径:system/lib/libandroid_servers.so
    
    编译HAL层模块,例如
    1.编译方式:
    mmm hardware/libhardware/modules/thermal
    2.生成路径:system/lib/hw/thermal.default.so
    

    三、jni到HAL流程 -- 8.0及以上
    前言:
    JNI---通过hidl访问---HAL
    1.com_android_server_HardwarePropertiesManagerService.cpp

    static void nativeInit(JNIEnv* env, jobject obj) {
        std::lock_guard<std::mutex> lock(gThermalHalMutex);
        getThermalHalLocked();
    }
    
    static void getThermalHalLocked() {
        ···
        gThermalHal = IThermal::getService();//通过hidl获取thermal服务
        ···
    }
    

    2.HAL服务的初始化

    代码路径:
    hardware\interfaces\thermal\1.0\default
    android.hardware.thermal@1.0-service.rc \\初始化服务
    
    service.cpp
    int main() {
        return defaultPassthroughServiceImplementation<IThermal>();//直通式初始化服务,调用HIDL_FETCH_interface-name
    }
    
    Thermal.cpp
    IThermal* HIDL_FETCH_IThermal(const char* /* name */) {//初始化调用接口
      thermal_module_t* module;
      status_t err = hw_get_module(THERMAL_HARDWARE_MODULE_ID,
                                   const_cast<hw_module_t const**>(
                                       reinterpret_cast<hw_module_t**>(&module)));//回到7.1的jni到hal业务流程
      ···
      if (err == 0 && module->common.methods->open) {
        struct hw_device_t* device;
        err = module->common.methods->open(&module->common,
                                           THERMAL_HARDWARE_MODULE_ID, &device);
        ···
      }
      return new Thermal(module);
    }
    

    3.JNI与HAL对接起来

    com_android_server_HardwarePropertiesManagerService.cpp
    |
    |
    hidl
    |
    |
    Thermal.cpp
    

    四、参考学习

    https://blog.csdn.net/a469516684/article/details/86600596
    https://www.cnblogs.com/qixingchao/p/11911787.html
    https://blog.csdn.net/hjf161105/article/details/79522662
    https://www.cnblogs.com/welen/articles/5240295.html
    https://www.jianshu.com/p/b71aeb4ed13d
    https://blog.csdn.net/flappy_boy/article/details/81150290
    https://developer.android.google.cn/guide/platform
    

    相关文章

      网友评论

          本文标题:Android之JAVA、JNI、HAL加载流程梳理

          本文链接:https://www.haomeiwen.com/subject/odgqkrtx.html