android(linux) 背光流程


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);
        }
    }

LightsService.java (frameworks\base\services\java\com\android\server)

        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);
            }
        }

2. JNI 处理

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);  
}

3. 底层处理

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

你可能感兴趣的:(android(linux) 背光流程)