LightsService分析 --- JNI分析

3 JNI

3.1 初始化Lights设备

在LightsService初始化时调用的init_native方法如下:

static jlong init_native(JNIEnv* /* env */, jobject /* clazz */)
{
    int err;
    hw_module_t* module;
    Devices* devices;
    devices = (Devices*)malloc(sizeof(Devices));
    err = hw_get_module(LIGHTS_HARDWARE_MODULE_ID, (hw_module_t const**)&module);
    if (err == 0) {
        devices->lights[LIGHT_INDEX_BACKLIGHT]
                = get_device(module, LIGHT_ID_BACKLIGHT);
        devices->lights[LIGHT_INDEX_KEYBOARD]
                = get_device(module, LIGHT_ID_KEYBOARD);
        ...
} ...
return (jlong)devices;
}

该方法主要是完成lights设备的初始化,为每一个light绑定一个硬件设备对象。其中devices是一个灯设备的数组,

用来保存本地为灯设备分配的存储空间,最终会返回这个数组的首地址,它的定义如下:

struct Devices {light_device_t* lights[LIGHT_COUNT];};

light_device_t的定义位于lights.h中,定义如下:

struct light_device_t {
    struct hw_device_t common;
    int (*set_light)(struct light_device_t* dev,
            struct light_state_t const* state);
};

其中包含了一个硬件设备结构体,定义在hardware.h,类似于面向对象中的继承,也就是light_device_t是继承自hw_device_t的。

在完成数组空间分配后,通过hw_get_module方法会获取一个灯设备的硬件模型赋值给module指针,通过这个硬件模型可以为

每一个灯设备打开一个逻辑硬件设备,这个过程是通过get_device方法完成的:

static light_device_t* get_device(hw_module_t* module, char const* name)
{
    int err;
    hw_device_t* device;
    err = module->methods->open(module, name, &device);
    if (err == 0) {
        return (light_device_t*)device;
    } else {
        return NULL;
    }
}

通过module调用open方法来打开硬件设备,这个open方法是每一个硬件模型中都具备的方法,详细实现过程将在分析硬件

抽象层代码时进行讲述。在此处还将硬件设备强制转换返回到light设备,用到了向下转型(downcast)。在初始化过程中会为

每个灯分配空间并打开对应的硬件设备。

3.2 本地setLight方法

本地设置灯的方法如下:

static void setLight_native(JNIEnv* /* env */, jobject /* clazz */, jlong ptr,
        jint light, jint colorARGB, jint flashMode, jint onMS, jint offMS, jint brightnessMode)
{
    Devices* devices = (Devices*)ptr;
    light_state_t state;
    if (light < 0 || light >= LIGHT_COUNT || devices->lights[light] == NULL) {
        return ;
    }
    memset(&state, 0, sizeof(light_state_t));
    state.color = colorARGB;
    state.flashMode = flashMode;
    state.flashOnMS = onMS;
    state.flashOffMS = offMS;
    state.brightnessMode = brightnessMode;
    devices->lights[light]->set_light(devices->lights[light], &state);
}

可以看到在JNI方法中,都会携带诸如JNIEnv,jobject这样的参数类型,而Java层的LightsService并没有带这些参数。

实际上它代表的是子类的实例化对象指针,类似于this指针,JNIEnv的定义如下:

typedef const struct JNINativeInterface *JNIEnv;

JNINativeInterface是一个JNI的本地接口,定义在jni.h,包含了很多实用的函数。而jobject则代表了这个本地类方法对应的java类实例[3]。

该方法将出入的参数赋值给light_state_t结构体,这个结构体定义在light.h中。通过调用底层方法set_light时将设置的状态传入,

set_light方法位于底层代码light.c中,接下来会分析。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值