裁剪服务的时候,裁掉了lightservice,想着这可能是灯光控制的,但是改了之后,发现bug了, systemUI背光亮度控制滑动失效了。 最后分析是在lightservice里面的
流程分析首先看类调用
frameworksbasepackagesSystemUIsrccomandroidsystemuisettingsBrightnessController.java中的setBrightness方法开始 frameworksbasecorejavaandroidhardwaredisplayDisplayManager中的setTemporaryBrightness方法 这里DisplayManager会有一些实现类之类的,暂时不需要看,最后是调用到下面的service,属于系统服务了 frameworksbaseservicescorejavacomandroidserverdisplayDisplayManagerService.java frameworksbaseservicescorejavacomandroidserverdisplayDisplayPowerController.java frameworksbaseservicescorejavacomandroidserverdisplayRampAnimator.java frameworksbaseservicescorejavacomandroidserverdisplayDisplayPowerState.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(ListworkQueue) 这里有个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中的 frameworksbaseservicescorejavacomandroidserverdisplayLocalDisplayAdapter.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



