android10 systemUI亮度调节分析
裁剪服务的时候,裁掉了lightservice,想着这可能是灯光控制的,但是改了之后,发现bug了, systemUI背光亮度控制滑动失效了。 最后分析是在lightservice里面的
流程分析
首先看类调用
frameworks\base\packages\SystemUI\src\com\android\systemui\settings\BrightnessController.java中的setBrightness方法开始
frameworks\base\core\java\android\hardware\display\DisplayManager中的setTemporaryBrightness方法
这里DisplayManager会有一些实现类之类的,暂时不需要看,最后是调用到下面的service,属于系统服务了
frameworks\base\services\core\java\com\android\server\display\DisplayManagerService.java
frameworks\base\services\core\java\com\android\server\display\DisplayPowerController.java
frameworks\base\services\core\java\com\android\server\display\RampAnimator.java
frameworks\base\services\core\java\com\android\server\display\DisplayPowerState.java
PhotonicModulator内部类
DisplayPowerState -> setScreenBrightness -> scheduleScreenUpdate -> postScreenUpdateThreadSafe
-> mScreenUpdateRunnable -> mPhotonicModulator.setState(mScreenState, brightness)
PhotonicModulator是一个Thread,里面run是死循环,通过setState方法唤醒对象锁Object mLock = new Object();
设置一些状态值,和判断是否改变亮度的条件,关键看下面这句
mBlanker.requestDisplayState(state, backlight);
DisplayBlanker的实现是在DisplayManagerService中的LocalService类中实现的,
来看DisplayBlanker中requestDisplayState的实现
callbacks.onDisplayStateChange(state);改变状态的回调
关键点,亮度调节方法requestGlobalDisplayStateInternal(state, brightness);
这个方法的实现中,会有一些判断,判断是否是超过上限值和下限值之类的,毕竟简单
调用applyGlobalDisplayStateLocked(List<Runnable> workQueue)
这里有个DisplayDevice的循环判断,其实就是判断显示设备,如果有外接hdmi显示,外屏之类的,都是这个类的实现
Runnable runnable = updateDisplayStateLocked(device);
if (runnable != null) {
workQueue.add(runnable);
}
这里updateDisplayStateLocked其实就是调节亮度了
DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
if ((info.flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0) {
return device.requestDisplayStateLocked(mGlobalDisplayState, mGlobalDisplayBrightness);
}
> getDisplayDeviceInfoLocked
> requestDisplayStateLocked
这两个实现全部是在LocalDisplayAdapter.java中的
frameworks\base\services\core\java\com\android\server\display\LocalDisplayAdapter.java
requestDisplayStateLocked返回的是Runable,其实最后的调用就一句话,
mBacklight.setBrightness(brightness);
这个mBacklight就是背光了,看前面的初始化
LightsManager lights = LocalServices.getService(LightsManager.class);
mBacklight = lights.getLight(LightsManager.LIGHT_ID_BACKLIGHT);
是LightsManager 获取的,因为开始我把LightsManager 裁掉了,然后这个位置报错, 我就直接屏蔽掉了代码,
导致背光失效,后面的调用,就是lightservice调用jni了
com_android_server_lights_LightsService.cpp
后面的具体去分析
总结:
裁掉了lightManager导致背光控制失败,实际上是调用不到com_android_server_lights_LightsService.cpp里面的方法,其实在设置中,也可以通过Settings.System.putInt(getContentResolver(),Settings.System.SCREEN_BRIGHTNESS,brightness);
和get方法去设置或者获取亮度值,但是对于滑动的seekbar来说,频繁读写并不好, 所以systemUI才会用displaymanager来控制调用,但是这个设置的值,最后调用的还是DisplayPowerState中的
public static final IntProperty SCREEN_BRIGHTNESS =
new IntProperty(“screenBrightness”) {
@Override
public void setValue(DisplayPowerState object, int value) {
object.setScreenBrightness(value);
}
@Override
public Integer get(DisplayPowerState object) {
return object.getScreenBrightness();
}
};
最终都会走到setScreenBrightness -> scheduleScreenUpdate -> postScreenUpdateThreadSafe -> mScreenUpdateRunnable -> mPhotonicModulator.setState(mScreenState, brightness)跟调用DisplayManager的
setTemporaryBrightness方法最后是一样的,底层同样是用的lightservice,有兴趣的同学可以分析一下lightservice对应jni的调用setLight_native,往下调用的hal层部分,有一些修改过这类亮度控制的,其实就是对sys设备下的节点的读写,
原理基本一样,有空也可以分析,背光节点/sys/class/leds/lcd-backlight