Stringpkg=allowPower.valueAt(i);
try{
ApplicationInfoai=pm.getApplicationInfo(pkg,0);
if((ai.flags&ApplicationInfo.FLAG_SYSTEM)!
=0){
intappid=UserHandle.getAppId(ai.uid);
//Theseappsareonboththewhitelist-except-idleaswell
//asthefullwhitelist,sotheyapplyinallcases.
mPowerSaveWhitelistAppsExceptIdle.put(ai.packageName,appid);
mPowerSaveWhitelistSystemAppIdsExceptIdle.put(appid,true);
mPowerSaveWhitelistApps.put(ai.packageName,appid);
mPowerSaveWhitelistSystemAppIds.put(appid,true);
}
}catch(PackageManager.NameNotFoundExceptione){
}
}
mConstants=newConstants(mHandler,getContext().getContentResolver());
readConfigFileLocked();//读取deviceidle.xml把用户应用存入内存
updateWhitelistAppIdsLocked();//把所有的白名单的app发给PowerManagerService
mScreenOn=true;
//Startoutassumingwearecharging.Ifwearen't,wewillatleastget
//abatteryupdatethenexttimetheleveldrops.
mCharging=true;
mState=STATE_ACTIVE;
mInactiveTimeout=mConstants.INACTIVE_TIMEOUT;
}
publishBinderService(Context.DEVICE_IDLE_CONTROLLER,newBinderService());
publishLocalService(LocalService.class,newLocalService());
}
我们再来看readConfigFileLocked来解析deviceidle.xml文件
[java]viewplaincopy在CODE上查看代码片派生到我的代码片
voidreadConfigFileLocked(){
if(DEBUG)Slog.d(TAG,"Readingconfigfrom"+mConfigFile.getBaseFile());
mPowerSaveWhitelistUserApps.clear();
FileInputStreamstream;
try{
stream=mConfigFile.openRead();
}catch(FileNotFoundExceptione){
return;
}
try{
XmlPullParserparser=Xml.newPullParser();
parser.setInput(stream,StandardCharsets.UTF_8.name());
readConfigFileLocked(parser);
}catch(XmlPullParserExceptione){
}finally{
try{
stream.close();
}catch(IOExceptione){
}
}
}
privatevoidreadConfigFileLocked(XmlPullParserparser){
finalPackageManagerpm=getContext().getPackageManager();
try{
inttype;
while((type=parser.next())!
=XmlPullParser.START_TAG
&&type!
=XmlPullParser.END_DOCUMENT){
;
}
if(type!
=XmlPullParser.START_TAG){
thrownewIllegalStateException("nostarttagfound");
}
intouterDepth=parser.getDepth();
while((type=parser.next())!
=XmlPullParser.END_DOCUMENT
&&(type!
=XmlPullParser.END_TAG||parser.getDepth()>outerDepth)){
if(type==XmlPullParser.END_TAG||type==XmlPullParser.TEXT){
continue;
}
StringtagName=parser.getName();
if(tagName.equals("wl")){
Stringname=parser.getAttributeValue(null,"n");
if(name!
=null){
try{
ApplicationInfoai=pm.getApplicationInfo(name,0);
mPowerSaveWhitelistUserApps.put(ai.packageName,//把解析出来的app放入这个变量
UserHandle.getAppId(ai.uid));
}catch(PackageManager.NameNotFoundExceptione){
}
}
}else{
Slog.w(TAG,"Unknownelementunder:
"
+parser.getName());
XmlUtils.skipCurrentTag(parser);
}
}
下面我们再来看看updateWhitelistAppIdsLocked如何把白名单传给PowerManagerService
[java]viewplaincopy在CODE上查看代码片派生到我的代码片
privatevoidupdateWhitelistAppIdsLocked(){
mPowerSaveWhitelistExceptIdleAppIdArray=buildAppIdArray(mPowerSaveWhitelistAppsExceptIdle,
mPowerSaveWhitelistUserApps,mPowerSaveWhitelistExceptIdleAppIds);
mPowerSaveWhitelistAllAppIdArray=buildAppIdArray(mPowerSaveWhitelistApps,
mPowerSaveWhitelistUserApps,mPowerSaveWhitelistAllAppIds);
if(mLocalPowerManager!
=null){
if(DEBUG){
Slog.d(TAG,"Settingwakelockwhitelistto"
+Arrays.toString(mPowerSaveWhitelistAllAppIdArray));
}
mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray);
}
}
至于PowerManagerService的设置白名单函数,我们在后续博客分析。
这边只要记住把白名单发给了PowerManagerService。
下面我们再来看看onBootPhase函数
[java]viewplaincopy在CODE上查看代码片派生到我的代码片
publicvoidonBootPhase(intphase){
if(phase==PHASE_SYSTEM_SERVICES_READY){//系统service启动好
synchronized(this){
mAlarmManager=(AlarmManager)getContext().getSystemService(Context.ALARM_SERVICE);
mBatteryStats=BatteryStatsService.getService();
mLocalPowerManager=getLocalService(PowerManagerInternal.class);
mNetworkPolicyManager=INetworkPolicyManager.Stub.asInterface(
ServiceManager.getService(Context.NETWORK_POLICY_SERVICE));
mDisplayManager=(DisplayManager)getContext().getSystemService(
Context.DISPLAY_SERVICE);
mSensorManager=(SensorManager)getContext().getSystemService(Context.SENSOR_SERVICE);
mSigMotionSensor=mSensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION);
mLocationManager=(LocationManager)getContext().getSystemService(
Context.LOCATION_SERVICE);
mLocationRequest=newLocationRequest()
.setQuality(LocationRequest.ACCURACY_FINE)
.setInterval(0)
.setFastestInterval(0)
.setNumUpdates
(1);
mAnyMotionDetector=newAnyMotionDetector(//移动监测
(PowerManager)getContext().getSystemService(Context.POWER_SERVICE),
mHandler,mSensorManager,this);
Intentintent=newIntent(ACTION_STEP_IDLE_STATE)
.setPackage("android")
.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
mAlarmIntent=PendingIntent.getBroadcast(getContext(),0,intent,0);//定义pendingIntent
IntentintentSensing=newIntent(ACTION_STEP_IDLE_STATE)
.setPackage("android")
.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
mSensingAlarmIntent=PendingIntent.getBroadcast(getContext(),0,intentSensing,0);
mIdleIntent=newIntent(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
mIdleIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
|Intent.FLAG_RECEIVER_FOREGROUND);
IntentFilterfilter=newIntentFilter();
filter.addAction(Intent.ACTION_BATTERY_CHANGED);
filter.addAction(ACTION_STEP_IDLE_STATE);
getContext().registerReceiver(mReceiver,filter);//注册registerReceiver
mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray);//设置白名单
mDisplayManager.registerDisplayListener(mDisplayListener,null);//在displayManager中注册回调
updateDisplayLocked();
}
}
}
二、屏幕电池变化
我们再来看DisplayListener和电池变化广播
[java]viewplaincopy在CODE上查看代码片派生到我的代码片
privatefinalDisplayManager.DisplayListenermDisplayListener
=newDisplayManager.DisplayListener(){
@OverridepublicvoidonDisplayAdded(intdisplayId){
}
@OverridepublicvoidonDisplayRemoved(intdisplayId){
}
@OverridepublicvoidonDisplayChanged(intdisplayId){
if(displayId==Display.DEFAULT_DISPLAY){
synchronized(DeviceIdleController.this){
updateDisplayLocked();
}
}
}
};
收到显示变化,调用updateDisplayLocked函数
[java]viewplaincopy在CODE上查看代码片派生到我的代码片
voidupdateDisplayLocked(){
mCurDisplay=mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY);
//Weconsideranysituationwherethedisplayisshowingsomethingtobeiton,
//becauseifthereisanythingshownwearegoingtobeupdatingitatsome
//frequencysocan'tbeallowedtogointodeepsleeps.
booleanscreenOn=mCurDisplay.getState()==Display.STATE_ON;
if(DEBUG)Slog.d(TAG,"updateDisplayLocked:
screenOn="+screenOn);
if(!
screenOn&&mScreenOn){
mScreenOn=false;
if(!
mForceIdle){//mForceIdle是dumpsys设置的
becomeInactiveIfAppropriateLocked();//灭屏
}
}elseif(screenOn){
mScreenOn=true;
if(!
mForceIdle){
becomeActiveLocked("screen",Process.myUid());//亮屏
}
}
}
电池变化会调用updateChargingLocked函数
[java]viewplaincopy在CODE上查看代码片派生到我的代码片
privatefinalBroadcastReceivermReceiver=newBroadcastReceiver(){
@OverridepublicvoidonReceive(Contextcontext,Intentintent){
if(Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())){
intplugged=intent.getIntExtra("plugged",0);
updateChargingLocked(plugged!
=0);
}elseif(ACTION_STEP_IDLE_STATE.equals(intent.getAction())){
synchronized(DeviceIdleController.this){
stepIdleStateLocked();
}
}
}
};
updateChargingLocked函数逻辑和显示的差不多
[java]viewplaincopy在CODE上查看代码片派生到我的代码片
voidupdateChargingLocked(booleancharging){
if(DEBUG)Slog.i(TAG,"updateChargingLocked:
charging="+charging);
if(!
charging&&mCharging){
mCharging=false;