Android51 PowerManagerService深入分析.docx
- 文档编号:24640459
- 上传时间:2023-05-29
- 格式:DOCX
- 页数:26
- 大小:23.54KB
Android51 PowerManagerService深入分析.docx
《Android51 PowerManagerService深入分析.docx》由会员分享,可在线阅读,更多相关《Android51 PowerManagerService深入分析.docx(26页珍藏版)》请在冰豆网上搜索。
Android51PowerManagerService深入分析
Android5.1PowerManagerService深入分析
PowerManagerService提供Android系统的电源管理服务,主要功能是控制系统的待机状态,控制显示屏的开关和亮度调节等。
PowerManagerService在systemserver中创建,加入到serviceManager中:
[java]viewplaincopy
mPowerManagerService=mSystemServiceManager.startService(PowerManagerService.class);
先从构造函数分析,代码如下:
[java]viewplaincopy
publicPowerManagerService(Contextcontext){
super(context);
mContext=context;
//创建处理消息的线程
mHandlerThread=newServiceThread(TAG,
Process.THREAD_PRIORITY_DISPLAY,false/*allowIo*/);
mHandlerThread.start();
//创建Handler,注意mHandlerThread.getLooper(),每一个线程都只有一个looper,这样消息的处理会放在这个线程中
mHandler=newPowerManagerHandler(mHandlerThread.getLooper());
synchronized(mLock){
mWakeLockSuspendBlocker=createSuspendBlockerLocked("PowerManagerService.WakeLocks");
mDisplaySuspendBlocker=createSuspendBlockerLocked("PowerManagerService.Display");
//防止cpu进入睡眠状态
mDisplaySuspendBlocker.acquire();
mHoldingDisplaySuspendBlocker=true;
mHalAutoSuspendModeEnabled=false;
mHalInteractiveModeEnabled=true;
//当前系统状态正常运行状态
mWakefulness=WAKEFULNESS_AWAKE;
nativeInit();
nativeSetAutoSuspend(false);
nativeSetInteractive(true);
}
}
构造函数比较简单,创建了一个接受消息处理的线程,cpu持锁不让手机睡眠,以及一些变量的初始化。
SystemServer创建完PowerManagerService后,继续调用SystemReady方法,再做一些初始化的工作,代码如下:
[java]viewplaincopy
publicvoidsystemReady(IAppOpsServiceappOps){
synchronized(mLock){
mSystemReady=true;
mAppOps=appOps;
//android5.0后的新方法,localService可以直接取,在4.4中这样service是在init中传对象进来的
mDreamManager=getLocalService(DreamManagerInternal.class);
mDisplayManagerInternal=getLocalService(DisplayManagerInternal.class);
mPolicy=getLocalService(WindowManagerPolicy.class);
mBatteryManagerInternal=getLocalService(BatteryManagerInternal.class);
PowerManagerpm=(PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
//获取缺省、最大、最小屏幕亮度
mScreenBrightnessSettingMinimum=pm.getMinimumScreenBrightnessSetting();
mScreenBrightnessSettingMaximum=pm.getMaximumScreenBrightnessSetting();
mScreenBrightnessSettingDefault=pm.getDefaultScreenBrightnessSetting();
//创建sensorManager和sersorservice交互
SensorManagersensorManager=newSystemSensorManager(mContext,mHandler.getLooper());
//Thenotifierrunsonthesystemserver'smainloopersoasnottointerfere
//withtheanimationsandothercriticalfunctionsofthepowermanager.
mBatteryStats=BatteryStatsService.getService();
mNotifier=newNotifier(Looper.getMainLooper(),mContext,mBatteryStats,
mAppOps,createSuspendBlockerLocked("PowerManagerService.Broadcasts"),
mPolicy);
//创建检测无线充电的对象
mWirelessChargerDetector=newWirelessChargerDetector(sensorManager,
createSuspendBlockerLocked("PowerManagerService.WirelessChargerDetector"),
mHandler);
mSettingsObserver=newSettingsObserver(mHandler);
mLightsManager=getLocalService(LightsManager.class);
mAttentionLight=mLightsManager.getLight(LightsManager.LIGHT_ID_ATTENTION);
//Initializedisplaypowermanagement.
mDisplayManagerInternal.initPowerManagement(
mDisplayPowerCallbacks,mHandler,sensorManager);
//Registerforbroadcastsfromothercomponentsofthesystem.
//监听其他模块的广播
IntentFilterfilter=newIntentFilter();
filter.addAction(Intent.ACTION_BATTERY_CHANGED);
filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
mContext.registerReceiver(newBatteryReceiver(),filter,null,mHandler);
filter=newIntentFilter();
filter.addAction(Intent.ACTION_DREAMING_STARTED);
filter.addAction(Intent.ACTION_DREAMING_STOPPED);
mContext.registerReceiver(newDreamReceiver(),filter,null,mHandler);
filter=newIntentFilter();
filter.addAction(Intent.ACTION_USER_SWITCHED);
mContext.registerReceiver(newUserSwitchedReceiver(),filter,null,mHandler);
filter=newIntentFilter();
filter.addAction(Intent.ACTION_DOCK_EVENT);
mContext.registerReceiver(newDockReceiver(),filter,null,mHandler);
//Registerforsettingschanges.
finalContentResolverresolver=mContext.getContentResolver();
resolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.SCREENSAVER_ENABLED),
false,mSettingsObserver,UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP),
false,mSettingsObserver,UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK),
false,mSettingsObserver,UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.System.getUriFor(
Settings.System.SCREEN_OFF_TIMEOUT),
false,mSettingsObserver,UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.SLEEP_TIMEOUT),
false,mSettingsObserver,UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.Global.getUriFor(
Settings.Global.STAY_ON_WHILE_PLUGGED_IN),
false,mSettingsObserver,UserHandle.USER_ALL);
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);
resolver.registerContentObserver(Settings.Global.getUriFor(
Settings.Global.LOW_POWER_MODE),
false,mSettingsObserver,UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.Global.getUriFor(
Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL),
false,mSettingsObserver,UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.Global.getUriFor(
Settings.Global.THEATER_MODE_ON),
false,mSettingsObserver,UserHandle.USER_ALL);
//Go.
readConfigurationLocked();
updateSettingsLocked();
mDirty|=DIRTY_BATTERY_STATE;
updatePowerStateLocked();
}
}
从在android5.1.1中,service一般都会继承一个虚类SystemService,在其中定义了两个接口onStart和onBootPhase,分别是PowerManagerService启动的时候会调用,而onBootPhase会在系统启动的各个阶段来调用,下面我们分别来看看在powerManagerService中这两个函数的实现:
[java]viewplaincopy
@Override
publicvoidonStart(){
publishBinderService(Context.POWER_SERVICE,newBinderService());
publishLocalService(PowerManagerInternal.class,newLocalService());
Watchdog.getInstance().addMonitor(this);
Watchdog.getInstance().addThread(mHandler);
}
在onstart函数中,必须把一些接口publish,像在之前Binder的接口,都是通过PowerManagerServiceextendsIPowerManager.Stub形式在PowerManagerService中实现接口
而在android5.1.1中都是通过方式重新定义一个类,然后把这个类publish出去。
[java]viewplaincopy
privatefinalclassBinderServiceextendsIPowerManager.Stub{
@Override//Bindercall
publicvoidacquireWakeLockWithUid(IBinderlock,intflags,Stringtag,
StringpackageName,intuid){
if(uid<0){
uid=Binder.getCallingUid();
}
acquireWakeLock(lock,flags,tag,packageName,newWorkSource(uid),null);
}
@Override//Bindercall
publicvoidpowerHint(inthintId,intdata){
if(!
mSystemReady){
//Servicenotreadyyet,sowhotheheckcaresaboutpowerhints,bah.
return;
}
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,null);
powerHintInternal(hintId,data);
}
@Override//Bindercall
publicvoidacquireWakeLock(IBinderlock,intflags,Stringtag,StringpackageName,
WorkSourcews,StringhistoryTag){
[java]viewplaincopy
。
。
。
。
。
。
。
。
。
。
。
。
。
。
而localservice都是一些本地的服务,不是通过Binder实现的。
我们接下来从,powerManager中的wakeLock说起,在powerManager中调用newWakeLock接口会生成一个WakeLock对象,而调用器acqure方法,最终会调用PowerManagerService中的acquireWakeLock方法
而具体的WakeLock有几种如下:
PARTIAL_WAKE_LOCK:
只保持CPU运行,屏幕和键盘光关闭。
FULL_WAKE_LOCK:
都不关闭
SCREEN_BRIGHT_WAKE_LOCK:
屏幕背光不关闭,键盘光关闭
SCREEN_DIM_WAKE_LOCK:
屏幕背光不关闭,键盘光关闭。
但是屏幕背光可以变暗
PROXIMITY_SCREEN_OFF_WAKE_LOCK当持有这种类型wakelock,当距离传感器被遮挡,屏幕将被关闭。
打电话时用这个功能
在PowerManagerService中的acquieWakeLock先要检查权限然后调用acquireWakeLockInternal接口,代码如下:
[java]viewplaincopy
privatevoidacquireWakeLockInternal(IBinderlock,intflags,Stringtag,StringpackageName,
WorkSourcews,StringhistoryTag,intuid,intpid){
synchronized(mLock){
WakeLockwakeLock;
//查找wakelock
intindex=findWakeLockIndexLocked(lock);
booleannotifyAcquire;
if(index>=0){查找到
wakeLock=mWakeLocks.get(index);
if(!
wakeLock.hasSameProperties(flags,tag,ws,uid,pid)){属性不一样,更新
//Updateexistingwakelock.Thisshouldn'thappenbutisharmless.
notifyWakeLockChangingLocked(wakeLock,flags,tag,packageName,
uid,pid,ws,historyTag);
wakeLock.updateProperties(flags,tag,packageName,ws,historyTag,uid,pid);
}
notifyAcquire=false;
}else{没找到,重新建立,添加
wakeLock=newWakeLock(lock,flags,tag,packageName,ws,historyTag,uid,pid);
try{
lock.linkToDeath(wakeLock,0);
}catch(RemoteExceptionex){
thrownewIllegalArgumentException("Wakelockisalreadydead.");
}
mWakeLocks.add(wakeLock);
notifyAcquire=true;
}
//看是否需要点亮屏幕
applyWakeLockFlagsOnAcquireLocked(wakeLock,uid);
//整个PowermanagerService用来记录各个状态变化的一个标志位
mDirty|=DIRTY_WAKE_LOCKS;
//更新各个状态
updatePowerStateLocked();
if(notifyAcquire){
//Thisneedstobedonelastsowearesurewehaveacquiredthe
//kernelwakelock.Otherwisewehavearacewherethesystemmay
//gotosleepbetweenthetimewestarttheaccountinginbattery
//statsandwhenweactuallygetaroundtotellingthekernelto
//stayawake.
notifyWakeLockAcquiredLocked(wakeLock);
}
}
}
整个PowermanagerService都是靠一个mDirty的各个标志位来记录各个状态的变化,随后会调用一个updatePowerStateLocked来更新各个状态。
同样解锁会调用到releaseWakeLockInternal,代码如下:
[java]viewplain
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Android51 PowerManagerService深入分析 PowerManagerService 深入 分析