本文主要讲述android5.1系统对背光的处理,从初始化到点击自动背光模式再到UI的同步处理,文章分为三点讲述:
1.背光的初始化
2.自动背光的调用过程:从点击setting中自动调节亮度开始
3.systemUI和setting对背光模式的同步
一:初始化
1.1控制背光服务的启动
大部分的服务的起点都在systemserver,背光的服务也不例外。首先启动一些基础的服务:
private void run() {
// Create the system service manager.
mSystemServiceManager = new SystemServiceManager(mSystemContext);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
// Start services.
try {
startOtherServices();
}
}
创建SystemServiceManager,并将该对象放入一个静态类LocalServices中,这样在systemserver进程中可以直接调用各种静态类中的服务了。在startOtherService中会调用startBootsstrapService方法:
private void startBootstrapServices() {
// Display manager is needed to provide display metrics before package manager
// starts up.
mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
}
进入mSystemServiceManager.startService中,
public <T extends SystemService> T startService(Class<T> serviceClass) {
final String name = serviceClass.getName();
// 创建该服务,创建的服务都是SystemService的子类,需要实现onStart方法。
final T service;
try {
Constructor<T> constructor = serviceClass.getConstructor(Context.class);
service = constructor.newInstance(mContext);
}
// 注册服务,将该服务放到一个列表
mServices.add(service);
// 调用SystemService子类的onStart方法,在该方法中去注册服务到servermanager中
try {
service.onStart();
}
return service;
}
进入DisplayManagerService的构造方法中,可以看出只是构造一个包含handler的环境。
public DisplayManagerService(Context context) {
super(context);
mContext = context;
mHandler = new DisplayManagerHandler(DisplayThread.get().getLooper());
mUiHandler = UiThread.getHandler();
mDisplayAdapterListener = new DisplayAdapterListener();
mSingleDisplayDemoMode = SystemProperties.getBoolean("persist.demo.singledisplay", false);
}
将该服务添加到SystemServiceManager的内部列表中后,就会服务的onStart方法:
public void onStart() {
mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER);
publishBinderService(Context.DISPLAY_SERVICE, new BinderService(),
true /*allowIsolated*/);//将BinderService服务添加到servicemanager中
publishLocalService(DisplayManagerInternal.class, new LocalService());//将LocalService服务添加到LocalServices中
}
可以深入两个方法看看,其实现都在SystemService中,这个类是常见系统服务的父类如PowerManagerService等。
protected final void publishBinderService(String name, IBinder service,
boolean allowIsolated) {
ServiceManager.addService(name, service, allowIsolated);
}
/**
* Publish the service so it is only accessible to the system process.
*从注释可以看出,只让系统进程能获取到,说明这些服务不是binder服务,
*如何让系统服务获取呢,就是添加到LocalServices中,这是个静态类,系统进程通过静态类来添加和获取
*/
protected final <T> void publishLocalService(Class<T> type, T service) {
LocalServices.addService(type, service);
}
这个LocalServices其实就是一个静态类,负责提供内部服务:
public final class LocalServices {
private static final ArrayMap<Class<?>, Object> sLocalServiceObjects =
new ArrayMap<Class<?>, Object>();
public static <T> void addService(Class<T> type, T service) {
synchronized (sLocalServiceObjects) {
sLocalServiceObjects.put(type, service);
}
}
}
其内部也有个Map,负责保存存入LocalServices的类,这些类一般是服务。现在可以知道,在DisplayManagerService的onStart方法中,创建了一个LocalService,并将其加入到LocalServices的列表中,来看看LocalService是什么。
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) {
// The order of operations is important for legacy reasons.
if (state == Display.STATE_OFF) {
requestGlobalDisplayStateInternal(state);
}
callbacks.onDisplayStateChange(state);
if (state != Display.STATE_OFF) {
requestGlobalDisplayStateInternal(state);
}
}
};
mDisplayPowerController = new DisplayPowerController(
mContext, callbacks, handler, sensorManager, blanker);
}
}
.....
}
LocalService是DisplayManagerInternal的子类,这个DisplayManagerInternal其实是个接口类,LocalService负责实现这几个接口。
至此初始化的第一部分结束,主要是构造服务和环境。
1.2PowerManagerService.SystemReady方法
系统服务起来后会调用其systemReady方法:
public void systemReady(IAppOpsService appOps) {
synchronized (mLock) {
mDisplayManagerInternal = getLocalService(DisplayManagerInternal.class);
mScreenBrightnessSettingMinimum = pm.getMinimumScreenBrightnessSetting();
mScreenBrightnessSettingMaximum = pm.getMaximumScreenBrightnessSetting();
mScreenBrightnessSettingDefault = pm.getDefaultScreenBrightnessSetting();
SensorManager sensorManager = new SystemSensorManager(mContext, mHandler.getLooper());
mSettingsObserver = new SettingsObserver(mHandler);
mLightsManager = getLocalService(LightsManager.class);
// Initialize display power management.
mDisplayManagerInternal.initPowerManagement(mDisplayPowerCallbacks, mHandler, sensorManager);
// Register for settings changes.
resolver.registerContentObserver(Settings.System.getUriFor(
Settings.System.SCREEN_BRIGHTNESS),
false, mSettingsObserver, UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.System.getUriFor(
Settings.System.SCREEN_BRIGHTNESS_MODE),
false, mSettingsObserver, UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.System.getUriFor(
Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ),
false, mSettingsObserver, UserHandle.USER_ALL);
mSystemReadyDone.set(true);
......
updatePowerStateLocked}
}
1.2.1 initPowerManagement
可以看出在systemready方法中会获取sensormanager,和lightservice等,最重要的是调用initPowerManagement,从上面的分析可以知道mDisplayManagerInternal其实就是DisplayManagerService.LocalService,其initPowerManagerment方法中创建了DisplayPowerController。
public DisplayPowerController(Context context,
DisplayPowerCallbacks callbacks, Handler handler,
SensorManager sensorManager, DisplayBlanker blanker) {
mHandler = new DisplayControllerHandler(handler.getLooper());
mCallbacks = callbacks;
mBatteryStats = BatteryStatsService.getService();
mLights = LocalServices.getService(LightsManager.class);
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));
mScreenBrightnessDozeConfig = clampAbsoluteBrightness(resources.getInteger(
com.android.internal.R.integer.config_screenBrightnessDoze));
mScreenBrightnessDimConfig = clampAbsoluteBrightness(resources.getInteger(
com.android.internal.R.integer.config_screenBrightnessDim));
mScreenBrightnessDarkConfig = clampAbsoluteBrightness(resources.getInteger(
com.android.internal.R.integer.config_screenBrightnessDark));
int screenBrightnessRangeMinimum = Math.min(Math.min(
screenBrightnessSettingMinimum, mScreenBrightnessDimConfig),