背光设置是在:设置->声音和显示->亮度,通过进度条来设置的。
文件: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);
设置亮度
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的定义在:
frameworks/base/core/java/android/os/IPowerManager.aidl.java
// sets the brightness of the backlights (screen, keyboard, button) 0-255
void setBacklightBrightness(int brightness);
void setAttentionLight(boolean on, int color);
设置进度条的范围,BRIGHTNESS_DIM = 20 BRIGHTNESS_ON=255,它们的定义在:
frameworks/base/core/java/android/os/Power.java
frameworks/base/core/java/android/os/PowerManager.java
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
public void setBacklightBrightness(int brightness)
{
try {
mService.setBacklightBrightness(brightness);
} catch (RemoteException e) {
}
}
电源管理器(powermager)将brightness转给电源服务,该服务位置如下:
----------->/system/framework/services.jar
frameworks/base/services/java/com/android/server/PowerManagerService.java
private LightsService.Light mLcdLight;
private LightsService.Light mButtonLight;
private LightsService.Light mKeyboardLight;
void init(Context context, LightsService lights, IActivityManager activity,
BatteryService battery) {
mLightsService = lights;
mContext = context;
mActivityService = activity;
mBatteryStats = BatteryStatsService.getService();
mBatteryService = battery;
mLcdLight = lights.getLight(LightsService.LIGHT_ID_BACKLIGHT);
mButtonLight = lights.getLight(LightsService.LIGHT_ID_BUTTONS);
mKeyboardLight = lights.getLight(LightsService.LIGHT_ID_KEYBOARD);
mAttentionLight = lights.getLight(LightsService.LIGHT_ID_ATTENTION);
mFlashLedLight= lights.getLight(LightsService.LIGHT_ID_FLASHLED);
//设置亮度
public void setBacklightBrightness(int brightness) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
// Don't let applications turn the screen all the way off
synchronized (mLocks) {
brightness = Math.max(brightness, Power.BRIGHTNESS_DIM);
mLcdLight.setBrightness(brightness);
mKeyboardLight.setBrightness(mKeyboardVisible ? brightness : 0);
mButtonLight.setBrightness(brightness);
long identity = Binder.clearCallingIdentity();
try {
mBatteryStats.noteScreenBrightness(brightness);
} catch (RemoteException e) {
Slog.w(TAG, "RemoteException calling noteScreenBrightness on BatteryStatsService", e);
} finally {
Binder.restoreCallingIdentity(identity);
}
// update our animation state
synchronized (mLocks) {
mScreenBrightness.targetValue = brightness;
mScreenBrightness.jumpToTargetLocked();
}
}
}
方法接口:
mButtonLight.setBrightness(brightness);
mButtonLight.setBrightness(buttonValue);
// make sure button and key backlights are off too
mButtonLight.turnOff();
LightsService.Light是LightsService的内部类,其实现在下面的文件中
----------->/system/framework/services.jar
frameworks/base/services/java/com/android/server/LightsService.java
private void setLightLocked(int color, int mode, int onMS, int offMS, int brightnessMode) {这个文件就是通过JNI调用native函数,把native函数进行封装,以对上层提供更多的API,真正native函数就3个:
private static native int init_native();
private static native void finalize_native(int ptr);
private static native void setLight_native(int ptr, int light, int color, int mode,
int onMS, int offMS, int brightnessMode);
真正的设置亮度是setLight_native,其他成员函数都是对此函数封装,如在PowerManagerService.java中调用的
public void turnOff() {
synchronized (this) {
setLightLocked(0, LIGHT_FLASH_NONE, 0, 0, 0);
}
}
public void setBrightness(int brightness, int brightnessMode)
//brightness是亮度值,brightnessMode是模式即 BRIGHTNESS_MODE_USER (* Light brightness is managed by a user setting
) 还是BRIGHTNESS_MODE_SENSOR( Light brightness is managed by a light sensor.),对应
设置->声音和显示->亮度,
上面3个native函数在此文件中被调用,其实现在com_android_server_LightsService.cpp中
上面两个文件都在services.jar中
----------->/system/lib/libandroid_servers.so
/frameworks/base/services/jni/com_android_server_LightsService.cpp
此文件的入口是register_android_server_LightsService(),在onload.cpp中调用,
主要动作
注册方法表
static JNINativeMethod method_table[] = {
{ "init_native", "()I", (void*)init_native },
{ "finalize_native", "(I)V", (void*)finalize_native },
{ "setLight_native", "(IIIIIII)V", (void*)setLight_native},
//Java fn Cpp Function
};
这就是对应LightsService.java中3个函数的实现
hw_get_module(LIGHTS_HARDWARE_MODULE_ID, (hw_module_t const**)&module);
这就可以调到light的hal层了,于是进入
----------->/system/lib/hw/lights.sprdbp.so
/hardware/sprd/hsdroid/liblights/lights.c
最重要是定义硬件模块,也是文件入口如下/*
* The lights Module
*/
const struct hw_module_t HAL_MODULE_INFO_SYM = {
.tag = HARDWARE_MODULE_TAG,
.version_major = 1,
.version_minor = 0,
.id = LIGHTS_HARDWARE_MODULE_ID,
.name = "SPRD sc8800 lights Module",
.author = "Spreadtrum, Inc.",
.methods = &lights_module_methods,
};
在hal中通过驱动提供的sysfs接口来设置对应led亮度
char const*const KEYBOARD_FILE
= "/sys/class/leds/keyboard-backlight/brightness";
char const*const BUTTON_FILE
= "/sys/class/leds/button-backlight/brightness";
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);
/*
LOGE("####: sprd/lights.c: set_light_backlight() brightness = %d. #####\n",
brightness);
*/
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;
}
再向下就是driver文件
/kernel/drivers/leds/leds-sc8810-kb.c
sprd_kb_led_probe()中led->cdev.name = "keyboard-backlight";
/kernel/drivers/leds/leds-sc8810-lcd.c
参考 http://jinguo.iteye.com/blog/974208
案例:lightsensor调节背光不明显
自动调节背光亮度是通过如下代码来实现的
frameworks/base/core/res/res/values/config.xml
/frameworks/base/services/java/com/android/server/PowerManagerService.java
/*
*@sensorValue:lightsensor传上来的值
*@ values:具体调节背光数组,如是autoBrightnessLcdBacklightValues,或者autoBrightnessButtonBacklightValues
*
*/
private int getAutoBrightnessValue(int sensorValue, int[] values) {