背光设置是在:设置->声音和显示->亮度,通过进度条来设置的。

文件:packages/apps/Settings/src/com/android/settings/BrightnessPreference.java

private static final int MINIMUM_BACKLIGHT = android.os.Power.BRIGHTNESS_DIM + 10;

private static final int MAXIMUM_BACKLIGHT = android.os.Power.BRIGHTNESS_ON;

mSeekBar.setMax(MAXIMUM_BACKLIGHT - MINIMUM_BACKLIGHT);

设置进度条的范围,BRIGHTNESS_DIM = 20  BRIGHTNESS_ON=255,它们的定义在:

frameworks/base/core/java/android/os/Power.java

3.1.2 设置亮度

文件:packages/apps/Settings/src/com/android/settings/BrightnessPreference.java

public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

setMode(isChecked ? Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC

: Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);

if (!isChecked) {

setBrightness(mSeekBar.getProgress() + MINIMUM_BACKLIGHT);

}

}

private void setBrightness(int brightness) {

try {

IPowerManager power = IPowerManager.Stub.asInterface(

ServiceManager.getService("power"));

if (power != null) {

power.setBacklightBrightness(brightness);

}

} catch (RemoteException doe) {

}

}

由以上代码可知,brightness的范围是:20~255;代码通过服务管理器(ServiceManager)获得power服务,然后通过power服务设置亮度。

power.setBacklightBrightness的定义在:

rameworks/base/core/java/android/os/IPowerManager.aidl.java

frameworks/base/core/java/android/os/PowerManager.java

3.2 Power服务

文件:frameworks/base/core/java/android/os/Power.java

/**

* Brightness value for dim backlight

*/

public static final int BRIGHTNESS_DIM = 20;

/**

* Brightness value for fully on

*/

public static final int BRIGHTNESS_ON = 255;

文件:frameworks/base/core/java/android/os/PowerManager.java

/**

* sets the brightness of the backlights (screen, keyboard, button).

*

* @param brightness value from 0 to 255

*

* {@hide}

*/

public void setBacklightBrightness(int brightness)

{

try {

mService.setBacklightBrightness(brightness);

} catch (RemoteException e) {

}

}

电源管理器(powermager)将brightness转给电源服务,该服务位置如下:

文件:frameworks/base/services/java/com/android/server/PowerManagerService.java

public void setBacklightBrightness(int brightness) {

mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);

// Don't let applications turn the screen all the way off

brightness = Math.max(brightness, Power.BRIGHTNESS_DIM);

mHardware.setLightBrightness_UNCHECKED(HardwareService.LIGHT_ID_BACKLIGHT, brightness,

HardwareService.BRIGHTNESS_MODE_USER);

mHardware.setLightBrightness_UNCHECKED(HardwareService.LIGHT_ID_KEYBOARD,

(mKeyboardVisible ? brightness : 0), HardwareService.BRIGHTNESS_MODE_USER);

mHardware.setLightBrightness_UNCHECKED(HardwareService.LIGHT_ID_BUTTONS, brightness,

HardwareService.BRIGHTNESS_MODE_USER);

long identity = Binder.clearCallingIdentity();

try {

mBatteryStats.noteScreenBrightness(brightness);

} catch (RemoteException e) {

Log.w(TAG, "RemoteException calling noteScreenBrightness on BatteryStatsService", e);

} finally {

Binder.restoreCallingIdentity(identity);

}

// update our animation state

if (ANIMATE_SCREEN_LIGHTS) {

mScreenBrightness.curValue = brightness;

mScreenBrightness.animating = false;

mScreenBrightness.targetValue = -1;

}

if (ANIMATE_KEYBOARD_LIGHTS) {

mKeyboardBrightness.curValue = brightness;

mKeyboardBrightness.animating = false;

mKeyboardBrightness.targetValue = -1;

}

if (ANIMATE_BUTTON_LIGHTS) {

mButtonBrightness.curValue = brightness;

mButtonBrightness.animating = false;

mButtonBrightness.targetValue = -1;

}

}

由以上代码可知,同时设置了背光、键盘、按钮的亮度。mHardware 是硬件服务,通过该服务调用底层与设备打交道的C/C++代码,setLightBrightness_UNCHECKED原型如下:

文件:frameworks/base/services/java/com/android/server/HardwareService.java

void setLightBrightness_UNCHECKED(int light, int brightness, int brightnessMode) {

int b = brightness & 0x000000ff;

b = 0xff000000 | (b << 16) | (b << 8) | b;

setLight_native(mNativePointer, light, b, LIGHT_FLASH_NONE, 0, 0, brightnessMode);

}

参数说明:int light 表示类型,选项如下:

static final int LIGHT_ID_BACKLIGHT = 0;

static final int LIGHT_ID_KEYBOARD = 1;

static final int LIGHT_ID_BUTTONS = 2;

static final int LIGHT_ID_BATTERY = 3;

static final int LIGHT_ID_NOTIFICATIONS = 4;

static final int LIGHT_ID_ATTENTION = 5;

int brightness 表示亮度值

int brightnessMode 表示亮度的控制模式,选项如下:

/**

* Light brightness is managed by a user setting.

*/

static final int BRIGHTNESS_MODE_USER = 0;

/**

* Light brightness is managed by a light sensor.

*/

static final int BRIGHTNESS_MODE_SENSOR = 1;

由代码:

int b = brightness & 0x000000ff;

b = 0xff000000 | (b << 16) | (b << 8) | b;

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

3.3 硬件调用

3.3.1获取硬件

文件:frameworks/base/services/jni/com_android_server_HardwareService.cpp

enum {

LIGHT_INDEX_BACKLIGHT = 0,

LIGHT_INDEX_KEYBOARD = 1,

LIGHT_INDEX_BUTTONS = 2,

LIGHT_INDEX_BATTERY = 3,

LIGHT_INDEX_NOTIFICATIONS = 4,

LIGHT_INDEX_ATTENTION = 5,

LIGHT_COUNT

};

#define LIGHTS_HARDWARE_MODULE_ID "lights"

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

} else {

memset(devices, 0, sizeof(Devices));

}

return (jint)devices;

}

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

hw_get_module 的实现原理,如下:

文件:hardware/libhardware/Hardware.c

#define HAL_LIBRARY_PATH "/system/lib/hw"

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"

};

static const int HAL_VARIANT_KEYS_COUNT =

(sizeof(variant_keys)/sizeof(variant_keys[0]));

int hw_get_module(const char *id, const struct hw_module_t **module)

{

int status;

int i;

const struct hw_module_t *hmi = NULL;

char prop[PATH_MAX];

char path[PATH_MAX];

/*

* Here we rely on the fact that calling dlopen multiple times on

* the same .so will simply increment a refcount (and not load

* a new copy of the library).

* We also assume that dlopen() is thread-safe.

*/

/* Loop through the configuration variants looking for a module */

for (i=0 ; i<HAL_VARIANT_KEYS_COUNT+1 ; i++) {

if (i < HAL_VARIANT_KEYS_COUNT) {

if (property_get(variant_keys[i], prop, NULL) == 0) {

continue;

}

snprintf(path, sizeof(path), "%s/%s.%s.so",

HAL_LIBRARY_PATH, id, prop);

} else {

snprintf(path, sizeof(path), "%s/%s.default.so",

HAL_LIBRARY_PATH, id);

}

if (access(path, R_OK)) {

continue;

}

/* we found a library matching this id/variant */

break;

}

status = -ENOENT;

if (i < HAL_VARIANT_KEYS_COUNT+1) {

/* load the module, if this fails, we're doomed, and we should not try

* to load a different variant. */

status = load(id, path, module);

}

return status;

}

property_get(variant_keys[i], prop, NULL) 会按如下顺序去获取如下变量所对应的值,然后返回给prop:

"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"

它们对应的变量为:

"ro.product.board=$TARGET_BOOTLOADER_BOARD_NAME"

"ro.board.platform=$TARGET_BOARD_PLATFORM"

如vendor/htc/dream-open/BoardConfig.mk里定义的TARGET_BOARD_PLATFORM := msm7k,则prop返回” msm7k ”,所以path = /system/lib/hw/lights. msm7k.so,也就是说要获取的硬件模块为lights. msm7k.so。

3.3.2调用硬件

setLight_native对应的jni C/C++代码是:

文件:frameworks/base/services/jni/com_android_server_HardwareService.cpp

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

}

通过light标识找到对应的light设备,然后再设置亮度。

3.3.3 硬件原型

msm7k的lights对应的硬件原型是在:hardware/msm7k/liblights

文件:hardware/msm7k/liblights/Android.mk

LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw

LOCAL_MODULE := lights.$(TARGET_BOARD_PLATFORM)

也就是生成模块:/system/lib/hw/lights. msm7k.so

文件:hardware/msm7k/liblights/lights.c

/** Open a new instance of a lights device using name */

static int open_lights(const struct hw_module_t* module, char const* name,

struct hw_device_t** device)

{

int (*set_light)(struct light_device_t* dev,

struct light_state_t const* state);

if (0 == strcmp(LIGHT_ID_BACKLIGHT, name)) {

set_light = set_light_backlight;

}

else if (0 == strcmp(LIGHT_ID_KEYBOARD, name)) {

set_light = set_light_keyboard;

}

else if (0 == strcmp(LIGHT_ID_BUTTONS, name)) {

set_light = set_light_buttons;

}

else if (0 == strcmp(LIGHT_ID_BATTERY, name)) {

set_light = set_light_battery;

}

else if (0 == strcmp(LIGHT_ID_NOTIFICATIONS, name)) {

set_light = set_light_notifications;

}

else if (0 == strcmp(LIGHT_ID_ATTENTION, name)) {

set_light = set_light_attention;

}

else {

return -EINVAL;

}

pthread_once(&g_init, init_globals);

struct light_device_t *dev = malloc(sizeof(struct light_device_t));

memset(dev, 0, sizeof(*dev));

dev->common.tag = HARDWARE_DEVICE_TAG;

dev->common.version = 0;

dev->common.module = (struct hw_module_t*)module;

dev->common.close = (int (*)(struct hw_device_t*))close_lights;

dev->set_light = set_light;

*device = (struct hw_device_t*)dev;

return 0;

}

static struct hw_module_methods_t lights_module_methods = {

.open =  open_lights,

};

以上代码对应的是:

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

也就是说,对不同的亮度设置给予了不同的设置函数。

举例,背光设置,背光对应的代码如下:

char const*const LCD_FILE

= "/sys/class/leds/lcd-backlight/brightness";

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)

{

int err = 0;

int brightness = rgb_to_brightness(state);

pthread_mutex_lock(&g_lock);

g_backlight = brightness;

err = write_int(LCD_FILE, brightness);

if (g_haveTrackballLight) {

handle_trackball_light_locked(dev);

}

pthread_mutex_unlock(&g_lock);

return err;

}

也就是往文件/sys/class/leds/lcd-backlight/brightness写入亮度值,然后驱动会根据该文件更改背光的亮度。LCD_FILE的路径根据实际情况更改,同时需要在init.rc 修改其权限,使其可写rgb_to_brightness也根据实际更改,比如要直接亮度值控制,那只要获取r,g,b其中的一个值就行了,如:

static int

rgb_to_brightness(struct light_state_t const* state)

{

int color = state->color & 0x000000ff;

return color;

}

android backlight的更多相关文章

  1. I.MX6 Android backlight modify by C demo

    /************************************************************************** * I.MX6 Android backligh ...

  2. imx6 android 进入文件系统闪屏

    imx6进入文件系统的时候都会闪屏,应该是framebuffer未初始化,就已经打开了背光.目前解决办法,在kenel阶段关闭背光,显示android的开机动画之后(此时framebuffer已经初始 ...

  3. sc7731 Android 5.1 LCD驱动简明笔记之二

    此篇笔记基于sc7731 - android 5.1,对lcd的framebuffer做一个简明笔记. 一共分为两大部分:第一部分,关于LCD的硬件方面的:第二部分,关于lcd核心处理(framebu ...

  4. android系统平台显示驱动开发简要:Samsung LCD接口篇『三』

    平台信息: 内核:linux3.4.39系统:android4.4 平台:S5P4418(cortex a9) 作者:瘋耔(欢迎转载,请注明作者) 欢迎指正错误,共同学习.共同进步!! 关注博主新浪博 ...

  5. 【转】android开发 dts、各种接口porting----不错

    原文网址:http://www.xuebuyuan.com/1023185.html 1. repo init -u git://review.sonyericsson.net/platform/ma ...

  6. Android图形合成和显示系统---基于高通MSM8k MDP4平台

    介绍了Android SurfaceFlinger层次以下的图形合成和显示系统,主要基于高通MSM8k MDP4x平台. 做为Android Display专题.SurfaceFlinger的详细介绍 ...

  7. 【转】Android LCD(四):LCD驱动调试篇

    关键词:android LCD TFTSN75LVDS83B  TTL-LVDS LCD电压背光电压 平台信息:内核:linux2.6/linux3.0系统:android/android4.0 平台 ...

  8. Android Application Fundamentals——Android应用程序基础知识

    Application Fundamentals--应用程序基础知识 Key classes--关键类 Activity Service BroadcastReceiver ContentProvid ...

  9. android init.rc 语法分析

    此文来自于对http://source.android.com/porting/index.html中bring up段的简译.其中有一处与源码的 system/core/init/readme.tx ...

随机推荐

  1. 【Dancing Link专题】解题报告

    DLX用于优化精确覆盖问题,由于普通的DFS暴力搜索会超时,DLX是一个很强有力的优化手段,其实DLX的原理很简单,就是利用十字链表的快速删除和恢复特点,在DFS时删除一些行和列以减小查找规模,使得搜 ...

  2. 了解javascript中的事件(一)

    本人目录如下: 零.寒暄 一.事件概念 二.事件流 三.事件处理程序 四.总结 零.寒暄 由于刚入职,近期事情繁多,今天好不容易中期答辩完事,晚上有一些时间,来给大家分享一篇博文. 这段时间每天写js ...

  3. mysql查看连接数和状态,设置连接数和超时时间

    1.mysql> show status like '%connect%'; Connections,试图连接到(不管是否成功)MySQL服务器的连接数.   Max_used_connecti ...

  4. (摘抄)HTTP 协议详解

    这个是从网上摘抄下来的,原文链接在最底下,原文写的比较详细,我这里只取了一部分自己想要的   什么是HTTP协议      协议是指计算机通信网络中两台计算机之间进行通信所必须共同遵守的规定或规则,超 ...

  5. AngularJs学习笔记--concepts(概念)

    原版地址:http://code.angularjs.org/1.0.2/docs/guide/concepts 继续.. 一.总括 本文主要是angular组件(components)的概览,并说明 ...

  6. 持久化消息队列memcacheq的安装配置

    MemcacheQ 是一个基于 MemcacheDB 的消息队列服务器. 一.memcacheq介绍 特性: 1.简单易用 2.处理速度快 3.多条队列 4.并发性能好 5.与memcache的协议兼 ...

  7. HDU 1465 不容易系列之一(错排,递归)

    简而言之,就是把n个信封全部装错的可能数.(中问题,具体看题目) //当n个编号元素放在n个编号位置,元素编号与位置编号各不对应的方法数用M(n)表示, //那么M(n-1)就表示n-1个编号元素放在 ...

  8. 简明Vim练级攻略(转)

    前言今天看到这篇文章,共鸣点非常多.它把Vim使用分为4个级别,目前我自己是熟练运用前面三级的命令,在培养习惯使用第四级.完全就是我这一年来坚持使用Vim的过程.所以不管怎么我要转载这篇文章.翻译自& ...

  9. Linux文件查找命令find,xargs详述

    目录: 一.find 命令格式 1.find命令的一般形式为: 2.find命令的参数: 3.find命令选项: 4.使用exec或ok来执行shell命令: 二.find命令的例子: 1.查找当前用 ...

  10. JavaPersistenceWithHibernate第二版笔记Getting started with ORM-001用JPA和Hibernate实现HellowWorld(JTA、Bitronix)

    一.结构 二.model层 1. package org.jpwh.model.helloworld; import javax.persistence.Entity; import javax.pe ...