1. 上层处理
PowerManagerService.java (frameworks\base\services\java\com\android\server)
private LightsService.Light mLcdLight; private void setLightBrightness(int mask, int value) { int brightnessMode = (mAutoBrightessEnabled ? LightsService.BRIGHTNESS_MODE_SENSOR : LightsService.BRIGHTNESS_MODE_USER); if ((mask & SCREEN_BRIGHT_BIT) != 0) { if (DEBUG_SCREEN_ON) { RuntimeException e = new RuntimeException("here"); e.fillInStackTrace(); Slog.i(TAG, "Set LCD brightness: " + value, e); } mLcdLight.setBrightness(value, brightnessMode); } if ((mask & BUTTON_BRIGHT_BIT) != 0) { mButtonLight.setBrightness(value); } if ((mask & KEYBOARD_BRIGHT_BIT) != 0) { mKeyboardLight.setBrightness(value); } }
public void setBrightness(int brightness, int brightnessMode) { synchronized (this) { int color = brightness & 0x000000ff; color = 0xff000000 | (color << 16) | (color << 8) | color; setLightLocked(color, LIGHT_FLASH_NONE, 0, 0, brightnessMode); } } private void setLightLocked(int color, int mode, int onMS, int offMS, int brightnessMode) { if (color != mColor || mode != mMode || onMS != mOnMS || offMS != mOffMS) { if (DEBUG) Slog.v(TAG, "setLight #" + mId + ": color=#" + Integer.toHexString(color)); mColor = color; mMode = mode; mOnMS = onMS; mOffMS = offMS; setLight_native(mNativePointer, mId, color, mode, onMS, offMS, brightnessMode); } }
com_android_server_LightsService.cpp(/framework/base/services/jni/)
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 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 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; } 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); }
Lights.c (device\marvell\***\lights)
const char * const LCD_BACKLIGHT = "/sys/class/backlight/pwm-backlight.2/brightness"; static int lights_device_open(const struct hw_module_t *module, const char *name, struct hw_device_t **device); static struct hw_module_methods_t lights_module_methods = { .open = lights_device_open }; struct light_module_t { struct hw_module_t common; }; const struct light_module_t HAL_MODULE_INFO_SYM = { common: { tag : HARDWARE_MODULE_TAG, version_major : 1, version_minor : 0, id : LIGHTS_HARDWARE_MODULE_ID, name : "lights module", author : "", methods : &lights_module_methods, } }; int lights_set(struct light_device_t* dev, struct light_state_t const* state, const char* brightness_node) { struct light_state_t const *light_state = (struct light_state_t const*)state; unsigned char brightness = 0; int fd = -1; struct my_light_device_t *mydev = (struct my_light_device_t*)dev; if( light_state ) { unsigned int color = light_state->color; brightness = (color & 0xff) * mydev->max_brightness / 0xff; } else { LOGE("lights_set_brightness failed: light state is null\n"); return -EINVAL; } fd = open(brightness_node, O_RDWR); if( fd >= 0 ) { char buffer[20]; int bytes = sprintf(buffer, "%d", brightness); int rlt = write(fd, buffer, bytes); if( rlt < 0 ){ LOGE("lights_set_brightness %s, fail to set brightness to:%s, errno:%d\n", brightness_node, buffer, errno); close(fd); return -1; } close(fd); } else { static int already_warned = 0; if (already_warned < 5) { LOGE("lights_set_brightness failed to open %s, errno:%d\n", brightness_node, errno); already_warned++; } return -1; } return 0; } int lights_set_lcd(struct light_device_t* dev, struct light_state_t const* state) { return lights_set( dev, state, LCD_BACKLIGHT); } static int lights_device_open(const struct hw_module_t *module, const char *name, struct hw_device_t **device) { int status = -EINVAL; int ret; #ifdef LIGHTS_DEBUG LOGD("lights_device_open: device name: %s\n", name); #endif struct light_device_t *dev = NULL; struct my_light_device_t *mydev = NULL; mydev = (struct my_light_device_t *)calloc(sizeof(struct my_light_device_t), 1); dev = &(mydev->dev); dev->common.tag = HARDWARE_DEVICE_TAG; dev->common.version = 0; dev->common.module = (struct hw_module_t *)(module); dev->common.close = lights_device_close; mydev->max_brightness = 0xff;//default max brightness is 255 *device = &dev->common; if (!strcmp(name, LIGHT_ID_BACKLIGHT)) { dev->set_light = lights_set_lcd; readIntFromFile( LCD_MAX_BACKLIGHT, &mydev->max_brightness); ret = access(LCD_BACKLIGHT, F_OK); if (ret != 0) return status; } else if (!strcmp(name, LIGHT_ID_KEYBOARD)) { dev->set_light = lights_set_keyboard; readIntFromFile( KEYBOARD_MAX_BACKLIGHT, &mydev->max_brightness); ret = access(KEYBOARD_BACKLIGHT, F_OK); if (ret != 0) return status; } else if (!strcmp(name, LIGHT_ID_BUTTONS)) { dev->set_light = lights_set_button; ret = access(BUTTON_BACKLIGHT, F_OK); if (ret != 0) return status; } else if (!strcmp(name, LIGHT_ID_BATTERY)) { dev->set_light = lights_set_battery; ret = access(BATTERY_BACKLIGHT, F_OK); if (ret != 0) return status; } else if (!strcmp(name, LIGHT_ID_NOTIFICATIONS)) { dev->set_light = lights_set_notifications; ret = access(NOTIFICATIONS_BACKLIGHT, F_OK); if (ret != 0) return status; } else if (!strcmp(name, LIGHT_ID_ATTENTION)) { dev->set_light = lights_set_attention; ret = access(ATTENTION_BACKLIGHT, F_OK); if (ret != 0) return status; } else return status; return 0; }
ps:
节点创建位置:
configs/XXX/init/copyfiles/root/init.pxa988.rc
chown system system /sys/class/backlight/pwm-backlight.4/brightness