美文网首页
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