最近一直在弄离职的东西,有点烦,这里我们介绍下android framework中对backlight的处理,这里我们先介绍下framework中的native层。
首先我们要知道android中lightService对光的控制有很多,比如说提示灯,键盘背光,lcd背光,还有闪光灯等等各种光源设备,这边我们只关注lcd backlight,代码位置:
framework/base/services/jni/com_android_server_LightsService.cpp
之前介绍过很多jni中的东西,不了解的可以先去参考:
http://blog.csdn.net/zhangjie201412/article/details/7296966
http://blog.csdn.net/zhangjie201412/article/details/7238202
咱还是先来研究研究jni代码吧,首先是注册函数:
int register_android_server_LightsService(JNIEnv *env) { return jniRegisterNativeMethods(env, "com/android/server/LightsService", method_table, NELEM(method_table)); }
static JNINativeMethod method_table[] = { { "init_native", "()I", (void*)init_native }, { "finalize_native", "(I)V", (void*)finalize_native }, { "setLight_native", "(IIIIIII)V", (void*)setLight_native }, };
static jint 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); devices->lights[LIGHT_INDEX_BUTTONS] = get_device(module, LIGHT_ID_BUTTONS); devices->lights[LIGHT_INDEX_BATTERY] = get_device(module, LIGHT_ID_BATTERY); devices->lights[LIGHT_INDEX_NOTIFICATIONS] = get_device(module, LIGHT_ID_NOTIFICATIONS); devices->lights[LIGHT_INDEX_ATTENTION] = get_device(module, LIGHT_ID_ATTENTION); devices->lights[LIGHT_INDEX_BLUETOOTH] = get_device(module, LIGHT_ID_BLUETOOTH); devices->lights[LIGHT_INDEX_WIFI] = get_device(module, LIGHT_ID_WIFI); } else { memset(devices, 0, sizeof(Devices)); } return (jint)devices; }
so easy,一看就知道中间那么一大串我们只要关系backlight相关的就可以了,因为这边我们只有backlight,别的啥都没有,首先这里调用了
hw_get_module函数去获得HAL层中的模块,这里应该是default.goldfish.light.so文件,然后就可以使用这个动态库中的方法了。调用相应的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; } }
static int lights_device_open(const struct hw_module_t* module, const char* name, struct hw_device_t** device) { int status = -EINVAL; LOGV("lights_device_open\n"); if (!strcmp(name, LIGHT_ID_BACKLIGHT)) { struct light_device_t *dev; char value[PROPERTY_VALUE_MAX]; dev = malloc(sizeof(*dev)); /* initialize our state here */ memset(dev, 0, sizeof(*dev)); /* initialize the procs */ dev->common.tag = HARDWARE_DEVICE_TAG; dev->common.version = 0; dev->common.module = (struct hw_module_t*) module; dev->common.close = light_close_backlight; dev->set_light = set_light_backlight; *device = &dev->common; // property_get("hw.backlight.dev", value, DEF_BACKLIGHT_DEV); // strcpy(path, DEF_BACKLIGHT_PATH); // strcat(path, value); // strcpy(max_path, path); // strcat(max_path, "/max_brightness"); // strcat(path, "/brightness"); strcpy(path, "/sys/devices/platform/android-backlight.0/backlight/android-backlight.0/brightness"); strcpy(max_path, "/sys/devices/platform/android-backlight.0/backlight/android-backlight.0/max_brightness"); LOGI("max backlight file is %s\n", max_path); LOGI("backlight brightness file is %s\n", path); status = 0; } /* todo other lights device init */ return status; }
然后是我们的第二个方法finalize_native函数,这里就是调用了close函数就不多说了,最后是set_light函数
static void setLight_native(JNIEnv *env, jobject clazz, int ptr, int light, int colorARGB, int flashMode, int onMS, int offMS, int 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); }
---------------------------------------------------------------------
下面我们会介绍到framework中的LightService是如何管理的。