Android60 设备Idle状态一DeviceIdleController.docx

上传人:b****7 文档编号:25675004 上传时间:2023-06-11 格式:DOCX 页数:28 大小:23.30KB
下载 相关 举报
Android60 设备Idle状态一DeviceIdleController.docx_第1页
第1页 / 共28页
Android60 设备Idle状态一DeviceIdleController.docx_第2页
第2页 / 共28页
Android60 设备Idle状态一DeviceIdleController.docx_第3页
第3页 / 共28页
Android60 设备Idle状态一DeviceIdleController.docx_第4页
第4页 / 共28页
Android60 设备Idle状态一DeviceIdleController.docx_第5页
第5页 / 共28页
点击查看更多>>
下载资源
资源描述

Android60 设备Idle状态一DeviceIdleController.docx

《Android60 设备Idle状态一DeviceIdleController.docx》由会员分享,可在线阅读,更多相关《Android60 设备Idle状态一DeviceIdleController.docx(28页珍藏版)》请在冰豆网上搜索。

Android60 设备Idle状态一DeviceIdleController.docx

Android60设备Idle状态一DeviceIdleController

Android6.0设备Idle状态

(一)DeviceIdleController

一、DeviceIdleController初始化

[java]viewplaincopy在CODE上查看代码片派生到我的代码片

mSystemServiceManager.startService(DeviceIdleController.class);

在SystemServer中启动该服务。

我们先看下其构造函数:

[java]viewplaincopy在CODE上查看代码片派生到我的代码片

publicDeviceIdleController(Contextcontext){

super(context);

mConfigFile=newAtomicFile(newFile(getSystemDir(),"deviceidle.xml"));

mHandler=newMyHandler(BackgroundThread.getHandler().getLooper());

}

privatestaticFilegetSystemDir(){

returnnewFile(Environment.getDataDirectory(),"system");

}

构造函数中,新建了一个file是data/system/deviceidle.xml文件,然后新建了一个handler。

下面我们再看下onStart函数

[java]viewplaincopy在CODE上查看代码片派生到我的代码片

@Override

publicvoidonStart(){

finalPackageManagerpm=getContext().getPackageManager();

synchronized(this){

mEnabled=getContext().getResources().getBoolean(

com.android.internal.R.bool.config_enableAutoPowerModes);

SystemConfigsysConfig=SystemConfig.getInstance();

ArraySetallowPowerExceptIdle=sysConfig.getAllowInPowerSaveExceptIdle();.//从这个函数中读取哪个系统应用允许在idle状态下

for(inti=0;i

Stringpkg=allowPowerExceptIdle.valueAt(i);

try{

ApplicationInfoai=pm.getApplicationInfo(pkg,0);

if((ai.flags&ApplicationInfo.FLAG_SYSTEM)!

=0){

intappid=UserHandle.getAppId(ai.uid);

mPowerSaveWhitelistAppsExceptIdle.put(ai.packageName,appid);

mPowerSaveWhitelistSystemAppIdsExceptIdle.put(appid,true);

}

}catch(PackageManager.NameNotFoundExceptione){

}

}

ArraySetallowPower=sysConfig.getAllowInPowerSave();

for(inti=0;i

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;

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 表格模板 > 书信模板

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1