屏幕亮度调节—基于Android_6.0(代码源于Google)

来源:互联网 发布:php curl下载远程图片 编辑:程序博客网 时间:2024/06/05 16:24

屏幕亮度调节

对于屏幕亮度调节 framework层已经有很多文章,再次主要分析一下hal层。

1、Framework层主要文件BrightnessController.java

1.1、文件位置

frameworks/base/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java

1.2、主思路代码追踪
 public void onChanged(ToggleSlider view, boolean tracking, boolean automatic, int value,            boolean stopTracking) {        updateIcon(mAutomatic);        if (mExternalChange) return;        if (!mAutomatic) {            final int val = value + mMinimumBacklight;            if (stopTracking) {                MetricsLogger.action(mContext, MetricsEvent.ACTION_BRIGHTNESS, val);            }            setBrightness(val);            if (!tracking) {                AsyncTask.execute(new Runnable() {                        public void run() {                            Settings.System.putIntForUser(mContext.getContentResolver(),                                    Settings.System.SCREEN_BRIGHTNESS, val,                                    UserHandle.USER_CURRENT);                        }                    });            }        } else {            final float adj = value / (BRIGHTNESS_ADJ_RESOLUTION / 2f) - 1;            if (stopTracking) {                MetricsLogger.action(mContext, MetricsEvent.ACTION_BRIGHTNESS_AUTO, value);            }            setBrightnessAdj(adj);            if (!tracking) {                AsyncTask.execute(new Runnable() {                    public void run() {                        Settings.System.putFloatForUser(mContext.getContentResolver(),                                Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, adj,                                UserHandle.USER_CURRENT);                    }                });            }        }        for (BrightnessStateChangeCallback cb : mChangeCallbacks) {            cb.onBrightnessLevelChanged();        }}

当它获取到 设置的 brightness 的值之后,主要调用函数 setbrightness() 函数。通过该服务调用底层与设备打交道的C/C++代码,setLightBrightnes原型如下:

2、跳转到 LightsService.java

2.1、文件位置

frameworks/base/services/core/java/com/android/server/lights/LightsService.java

2.2、主要代码分析
 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);                }

亮度值在此进行了修改,即亮度值的格式变成:FFRRGGBB,FF是没有的,RR、GG、BB分别是256色的红绿蓝,并且红绿蓝的值都是一样的亮度值。

3、硬件调用 接口com_android_server_lights_LightsService.cpp

3.1、文件位置

frameworks/base/services/core/jni/com_android_server_lights_LightsService.cpp

3.2、主要代码分析
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);        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 (jlong)devices;}

用hw_get_module获取ID为LIGHTS_HARDWARE_MODULE_ID的硬件模块,该模块含有6个不同类型的亮度控制。

4、hardware.c 实现 hw_get_module()函数

4.1、文件位置

hardware/libhardware/hardware.c

4.2、主要代码分析

static const char *variant_keys[] = {
“ro.hardware”, /* This goes first so that it can pick up a different
file on the emulator. */
“ro.product.board”,
“ro.board.platform”,
“ro.arch”
};

““““`
/* Loop through the configuration variants looking for a module */
for (i=0 ; i

PRODUCT_PACKAGES += \    logFileManager#add lights HAL for adjust backlightPRODUCT_PACKAGES += lights.abc(项目名或板子名字)PRODUCT_PROPERTY_OVERRIDES += ro.hardware.lights=abc(项目名或板子名字)# SIM ToolkitPRODUCT_PACKAGES += \    Stk
比如vendor/htc/dream-open/BoardConfig.mk里定义的TARGET_BOARD_PLATFORM := msm7k  ,则prop返回” msm7k ”,所以path = /system/lib/hw/lights. msm7k.so,也就是说要获取的硬件模块为lights. msm7k.so。 

5、硬件原型 lights.c 及 android.mk文件

5.1、文件位置

/hardware/qcom/display/项目名/liblight/Android.mk

LOCAL_PATH:= $(call my-dir)include $(CLEAR_VARS)# HAL module implemenation, not prelinked and stored in# hw/<COPYPIX_HARDWARE_MODULE_ID>.<ro.board.platform>.soLOCAL_SRC_FILES := lights.cLOCAL_MODULE_RELATIVE_PATH := hwLOCAL_MODULE_TAGS := optionalLOCAL_SHARED_LIBRARIES := liblogLOCAL_MODULE := lights.(项目名)include $(BUILD_SHARED_LIBRARY)

hardware/qcom/display/项目名/liblight/lights.c

/* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */#define LOG_TAG "lights"#include <cutils/log.h>#include <stdint.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <errno.h>#include <fcntl.h>#include <sys/ioctl.h>#include <sys/types.h>#include <hardware/lights.h>#include <hardware/hardware.h>#define ALOG_ONCE(mask, op, ...)            \    do {                    \        {       \            ALOGE(__VA_ARGS__); \            mask |= op;     \        }               \    } while (0);#define OP_WRITE_OPEN       (1 << 0)#define OP_BRIGHTNESS_PATH  (1 << 1)#define OP_BRIGHTNESS_VALUE (1 << 2)#define OP_BRIGHTNESS_WRITE (1 << 3)#define OP_MAX_BRIGHTNESS_PATH  (1 << 4)#define OP_MAX_BRIGHTNESS_OPEN  (1 << 5)#define OP_MAX_BRIGHTNESS_READ  (1 << 6)struct dragon_lights {    struct light_device_t base;    pthread_mutex_t lock;    char const *sysfs_path;    int max_brightness;    unsigned long logged_failures;};static char const * kBacklightPath =    "/sys/class/backlight/pwm-backlight.0";  (注意此位置不同的设备可能有不同的设备节点)static struct dragon_lights *to_dragon_lights(struct light_device_t *dev){    return (struct dragon_lights *)dev;}static int write_brightness(struct dragon_lights *lights, int brightness){    char buffer[20], path[PATH_MAX];    int fd, bytes, amt, ret = 0;    ALOGI("LIGHTS write_brightness %d", brightness);    bytes = snprintf(path, sizeof(path), "%s/brightness",             lights->sysfs_path);    if (bytes < 0 || (size_t)bytes >= sizeof(path)) {        ALOG_ONCE(lights->logged_failures, OP_BRIGHTNESS_PATH,              "failed to create brightness path %d\n", bytes);        return -EINVAL;    }    fd = open(path, O_RDWR);    if (fd < 0) {        ALOG_ONCE(lights->logged_failures, OP_WRITE_OPEN,              "write_int failed to open %s/%d\n", path, errno);        return -errno;    }    bytes = snprintf(buffer, sizeof(buffer), "%d\n", brightness);    if (bytes < 0 || (size_t)bytes >= sizeof(buffer)) {        ALOG_ONCE(lights->logged_failures, OP_BRIGHTNESS_VALUE,              "failed to create brightness value %d/%d\n",              brightness, bytes);        ret = -EINVAL;        goto out;    }    amt = write(fd, buffer, bytes);    if (amt != bytes) {        ALOG_ONCE(lights->logged_failures, OP_BRIGHTNESS_WRITE,              "failed to write brightness value %d/%d\n", amt,              bytes);        ret = amt == -1 ? -errno : -EINVAL;        goto out;    }out:    close(fd);    return ret;}static int read_max_brightness(struct dragon_lights *lights, int *value){    char buffer[20], path[PATH_MAX];    int ret = 0, fd, bytes;    bytes = snprintf(path, sizeof(path), "%s/max_brightness",             lights->sysfs_path);    if (bytes < 0 || (size_t)bytes >= sizeof(path)) {        ALOG_ONCE(lights->logged_failures, OP_MAX_BRIGHTNESS_PATH,              "failed to create max_brightness path %d\n", bytes);        return -EINVAL;    }    fd = open(path, O_RDONLY);    if (fd < 0) {        ALOG_ONCE(lights->logged_failures, OP_MAX_BRIGHTNESS_OPEN,              "failed to open max_brightness %s/%d\n", path, errno);        return -errno;    }    bytes = read(fd, buffer, sizeof(buffer));    if (bytes <= 0) {        ALOG_ONCE(lights->logged_failures, OP_MAX_BRIGHTNESS_READ,              "failed to read max_brightness %s/%d\n", path, errno);        ret = -errno;        goto out;    }    *value = atoi(buffer);out:    close(fd);    return ret;}static int rgb_to_brightness(struct light_state_t const *state){    int color = state->color & 0x00ffffff;    return ((77 * ((color >> 16) & 0x00ff))            + (150 * ((color >> 8) & 0x00ff)) +            (29 * (color & 0x00ff))) >> 8;}static int set_light_backlight(struct light_device_t *dev,                   struct light_state_t const *state){    struct dragon_lights *lights = to_dragon_lights(dev);    int err, brightness_idx;    int brightness = rgb_to_brightness(state);    if(brightness < 0){        brightness = 0;    }    if(brightness >255){        brightness = 255;    }    pthread_mutex_lock(&lights->lock);    err = write_brightness(lights, brightness);    pthread_mutex_unlock(&lights->lock);    return err;}static int close_lights(struct hw_device_t *dev){    struct dragon_lights *lights = (struct dragon_lights *)dev;    if (lights)        free(lights);    return 0;}static int open_lights(const struct hw_module_t *module, char const *name,               struct hw_device_t **device){    struct dragon_lights *lights;    int ret;    // Only support backlight at the moment    if (strcmp(LIGHT_ID_BACKLIGHT, name))        return -EINVAL;    lights = malloc(sizeof(*lights));    if (lights == NULL) {        ALOGE("failed to allocate lights memory");        return -ENOMEM;    }    memset(lights, 0, sizeof(*lights));    pthread_mutex_init(&lights->lock, NULL);    lights->sysfs_path = kBacklightPath;    ret = read_max_brightness(lights, &lights->max_brightness);    if (ret) {        close_lights((struct hw_device_t *)lights);        return ret;    }    lights->base.common.tag = HARDWARE_DEVICE_TAG;    lights->base.common.version = 0;    lights->base.common.module = (struct hw_module_t *)module;    lights->base.common.close = close_lights;    lights->base.set_light = set_light_backlight;    *device = (struct hw_device_t *)lights;    return 0;}static struct hw_module_methods_t lights_methods = {    .open =  open_lights,};struct hw_module_t HAL_MODULE_INFO_SYM = {    .tag = HARDWARE_MODULE_TAG,    .version_major = 1,    .version_minor = 0,    .id = LIGHTS_HARDWARE_MODULE_ID,    .name = "jindory lights module",    .author = "thundersoft",    .methods = &lights_methods,};

文件参考:

1、 android 设置系统屏幕亮度
http://blog.csdn.net/zhuangxujun/article/details/8601392#comments