自动背光在Android系统中属于display显示相关模块,具体是和Lights和Power交互比较多,Power控制其亮度,灭屏,暗屏以及自动背光设置开关等,Lights负责背光灯的背光亮度值的变化。
1、代码主要涉及到frameworks/base/services/core/java/com/android/server/display 目录下的DisplayPowerController.java、AutomaticBrightnessController.java。
2、AutomaticBrightnessController.java中的一些变量
mScreenAutoBrightness:屏幕亮度级别是由自动亮度算法决定的,实际的亮度应向这个值靠拢。我们保留这个值,即使我们停止使用光传感器,以便我们可以快速恢复到之前的自动亮度级别。如果当前没有可用的自动亮度值,设置为-1。
// The screen brightness level that has been chosen by the auto-brightness
// algorithm. The actual brightness should ramp towards this value.
// We preserve this value even when we stop using the light sensor so
// that we can quickly revert to the previous auto-brightness level
// while the light sensor warms up.
// Use -1 if there is no current auto-brightness value available.
private int mScreenAutoBrightness = -1;
mResetAmbientLuxAfterWarmUpConfig:如果设置为true,屏幕点亮后,控制器根据当前传感器读到的值调整亮度;如果是false,控制器将收集更多的数据,然后决定是否改变亮度。
// If true immediately after the screen is turned on the controller will try to adjust the
// brightness based on the current sensor reads. If false, the controller will collect more data
// and only then decide whether to change brightness.
private final boolean mResetAmbientLuxAfterWarmUpConfig;
mScreenAutoBrightnessAdjustment:屏幕自动亮度调节的系数,从-1到1。
// The screen auto-brightness adjustment factor in the range -1 (dimmer) to 1 (brighter)
private float mScreenAutoBrightnessAdjustment = 0.0f;
mAmbientLux:当前接收的环境光级别。
// The currently accepted nominal ambient light level.
private float mAmbientLux;
mAmbientLightRingBuffer:一个用来保存最近环境光传感器读值得环形传感器。
// A ring buffer containing all of the recent ambient light sensor readings.
private AmbientLightRingBuffer mAmbientLightRingBuffer;
AMBIENT_LIGHT_PREDICTION_TIME_MILLIS:假定当前传感器读数超出当前时间的有效期,并且确保最后样本的权重非0,这反过来确保了总权重非0。
// How long the current sensor reading is assumed to be valid beyond the current time.
// This provides a bit of prediction, as well as ensures that the weight for the last sample is
// non-zero, which in turn ensures that the total weight is non-zero.
private static final long AMBIENT_LIGHT_PREDICTION_TIME_MILLIS = 100;
mLightSensorWarmUpTimeConfig:亮屏后在等待光传感器准备时自动亮度调整时间,以毫秒为单位。该值在创建AutomaticBrightnessController对象时被赋值。
// Amount of time to delay auto-brightness after screen on while waiting for
// the light sensor to warm-up in milliseconds.
// May be 0 if no warm-up is required.
private int mLightSensorWarmUpTimeConfig;
mAmbientLightHorizen:以毫秒为单位,采集光样本的时间段。mAmbientLightHorizen的初始化在AutomaticBrightnessController的构造方法中,而AutomaticBrightnessController对象的创建是在DisplayPowerController类的构造方法中执行的,最终是从变量config_autoBrightnessAmbientLightHorizon中读取,定义在framework/base/core/res/res/values/config.xml文件中:<integer name="config_autoBrightnessAmbientLightHorizon">10000</integer>,这里定义为10s。
// Period of time in which to consider light samples in milliseconds.
private final int mAmbientLightHorizon;
mInitialHorizonAmbientLightRingBuffer:保存初始阶段光传感器读值得环形缓冲器。
// A ring buffer containing the light sensor readings for the initial horizon period.
private AmbientLightRingBuffer mInitialHorizonAmbientLightRingBuffer;
3、使用dump查看自动亮度调节的变量值
adb shell dumpsys display > e:\display.txt
4、亮度计算算法及调节
自动背光的主要控制功能是DisplayPowerController和AutomaticBrightnessController两个类结合起来工作的。DisplayPowerController属于Display模块,其控制设备屏幕亮灭、背光、与Power关系密切,这里主要看下屏幕亮度的控制这方面的逻辑。
首先,在DisplayManagerService中初始化DisplayPowerController,如下:
private final class LocalService extends DisplayManagerInternal {
@Override
public void initPowerManagement(final DisplayPowerCallbacks callbacks, Handler handler,
SensorManager sensorManager) {
synchronized (mSyncRoot) {
DisplayBlanker blanker = new DisplayBlanker() {
@Override
public void requestDisplayState(int state, int brightness) {
// The order of operations is important for legacy reasons.
if (state == Display.STATE_OFF) {
requestGlobalDisplayStateInternal(state, brightness);
}
callbacks.onDisplayStateChange(state);
if (state != Display.STATE_OFF) {
requestGlobalDisplayStateInternal(state, brightness);
}
}
};
mDisplayPowerController = new DisplayPowerController(
mContext, callbacks, handler, sensorManager, blanker);
}
}
initPowerManagement()方法是比较重要的,这里是重写了DisplayManagerInternal中的initPowerManagement()抽象方法,该方法中有两个重要作用:一是回调到PowerManagerService中设置屏幕显示状态与power状态到底层;二是向LightService里面去设置屏幕背光。其中使用到的参数是由在PowerManagerService中调用initPowerManagement()方法传递的,如下:
// Initialize display power management.
mDisplayManagerInternal.initPowerManagement(
mDisplayPowerCallbacks, mHandler, sensorManager);
我们接着看下DisplayPowerController的构造方法,如下:
/**
* Creates the display power controller.
*/
public DisplayPowerController(Context context,
DisplayPowerCallbacks callbacks, Handler handler,
SensorManager sensorManager, DisplayBlanker blanker) {
mHandler = new DisplayControllerHandler(handler.getLooper());
mCallbacks = callbacks;
mBatteryStats = BatteryStatsService.getService();
mSensorManager = sensorManager;
mWindowManagerPolicy = LocalServices.getService(WindowManagerPolicy.class);
mBlanker = blanker;
mContext = context;
final Resources resources = context.getResources();
final int screenBrightnessSettingMinimum = clampAbsoluteBrightness(resources.getInteger(
com.android.internal.R.integer.config_screenBrightnessSettingMinimum));//屏幕最小亮度值,设置过小可能会点不亮屏幕。(23)
mScreenBrightnessDozeConfig = clampAbsoluteBrightness(resources.getInteger(
com.android.internal.R.integer.config_screenBrightnessDoze));//处于doze状态时的屏幕亮度.(1)
mScreenBrightnessDimConfig = clampAbsoluteBrightness(resources.getInteger(
com.android.internal.R.integer.config_screenBrightnessDim));//屏幕变暗时的值。(23)
mScreenBrightnessDarkConfig = clampAbsoluteBrightness(resources.getInteger(
com.android.internal.R.integer.config_screenBrightnessDark));//屏幕完全黑暗时的值。(23)
if (mScreenBrightnessDarkConfig > mScreenBrightnessDimConfig) {
Slog.w(TAG, "Expected config_screenBrightnessDark ("
+ mScreenBrightnessDarkConfig + ") to be less than or equal to "
+ "config_screenBrightnessDim (" + mScreenBrightnessDimConfig + ").");
}
if (mScreenBrightnessDarkConfig > mScreenBrightnessDimConfig) {
Slog.w(TAG, "Expected config_screenBrightnessDark ("
+ mScreenBrightnessDarkConfig + ") to be less than or equal to "
+ "config_screenBrightnessSettingMinimum ("
+ screenBrightnessSettingMinimum + ").");
}
int screenBrightnessRangeMinimum = Math.min(Math.min(
screenBrightnessSettingMinimum, mScreenBrightnessDimConfig),