一系列应用包名的集合。
处于白名单列表中的应用,不受Doze的影响,即Doze不会对该应用进行限制,如该应用的Job、Alarm、网络等不会进行限制。
Doze白名单有两类来源:
用户设置的将最终写到/data/system/deviceidle.xml
文件中。
来看下可以预值的配置文件有哪些?以及是如何读取的。在onStart()方法中,通过SystemConfig类读取了两类配置文件:
@Override
public void onStart() {
synchronized (this) {
SystemConfig sysConfig = SystemConfig.getInstance();
//得到允许在省电模式豁免但不允许IDLE状态豁免的应用列表,读取的是/etc/permissions/platform.xml中
//的元素的应用包名
ArraySet<String> allowPowerExceptIdle = sysConfig.getAllowInPowerSaveExceptIdle();
for (int i=0; i<allowPowerExceptIdle.size(); i++) {
String pkg = allowPowerExceptIdle.valueAt(i);
try {
//过滤只得到系统应用,并加入mPowerSaveWhitelistAppsExceptIdle中
ApplicationInfo ai = pm.getApplicationInfo(pkg,
PackageManager.MATCH_SYSTEM_ONLY);
int appid = UserHandle.getAppId(ai.uid);
mPowerSaveWhitelistAppsExceptIdle.put(ai.packageName, appid);
mPowerSaveWhitelistSystemAppIdsExceptIdle.put(appid, true);
} catch (PackageManager.NameNotFoundException e) {
}
}
//得到允许在省电模式和IDLE状态都豁免的应用列表,读取的是/etc/permissions/platform.xml中
//的元素的应用包名
ArraySet<String> allowPower = sysConfig.getAllowInPowerSave();
for (int i=0; i<allowPower.size(); i++) {
String pkg = allowPower.valueAt(i);
try {
//过滤只得到系统应用,加入mPowerSaveWhitelistAppsExceptIdle和mPowerSaveWhitelistApps中
ApplicationInfo ai = pm.getApplicationInfo(pkg,
PackageManager.MATCH_SYSTEM_ONLY);
int appid = UserHandle.getAppId(ai.uid);
// These apps are on both the whitelist-except-idle as well
// as the full whitelist, so they apply in all cases.
mPowerSaveWhitelistAppsExceptIdle.put(ai.packageName, appid);
mPowerSaveWhitelistSystemAppIdsExceptIdle.put(appid, true);
mPowerSaveWhitelistApps.put(ai.packageName, appid);
mPowerSaveWhitelistSystemAppIds.put(appid, true);
} catch (PackageManager.NameNotFoundException e) {
}
}
//读取/data/system/deviceidle.xml中的配置应用到mPowerSaveWhitelistUserApps中
readConfigFileLocked();
//更新所有的白名单列表
updateWhitelistAppIdsLocked();
}
因此,对于系统应用,可以在/etc/permissions/platform.xml
中预设,如果是三方应用,目前还没有可预置的,只能手动添加。或者可以自定义一个xml文件,在DeviceIdleController中进行读取。
注:/data/system分区下的数据一旦恢复出厂设置,就会被擦除,因此不能预置到/data/system/deviceidle.xml中。
在代码中看到,DeviceIdleController中只会收集白名单应用列表,然后将这个列表传递给对应模块做具体的限制工作:
//将白名单列表传递给AMS
mLocalActivityManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray);
//将白名单列表传递给PMS,申请wakelock时将会判断是否忽略
mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray);
//将白名单列表传递给Alarm,设置Alarm时将会判断是否忽略
mLocalAlarmManager.setDeviceIdleUserWhitelist(mPowerSaveWhitelistUserAppIdArray);
此外,DIC还提供了用于获取白名单列表的接口,其他模块通过LocalService从DeviceIdleController中获取这个列表:
int[] getPowerSaveWhitelistUserAppIds() {
synchronized (this) {
return mPowerSaveWhitelistUserAppIdArray;
}
}
如在DeviceIdleJobController中:
mDeviceIdleWhitelistAppIds =
mLocalDeviceIdleController.getPowerSaveWhitelistUserAppIds();
NOTE:使用
setAndAllowWhileIdle()
和setExactAndAllowWhileIdle()
设置的闹钟将不会被Doze限制。
可以在adb shell环境下通过dumpsys命令来DebugDoze,不过首先必须将电池充电状态置为未充电状态:
adb shell dumpsys battery unplug # 将电池充电状态设置为unplug
然后通过adb shell dumpsys deviceidle
命令就可以进行Debug了,通过adb shell dumpsys deviceidle help
来查看所有参数:
@ubuntu:~$ adb shell dumpsys deviceidle help
Device idle controller (deviceidle) commands:
help
Print this help text.
step [light|deep]
Immediately step to next state, without waiting for alarm.
force-idle [light|deep]
Force directly into idle mode, regardless of other device state.
force-inactive
Force to be inactive, ready to freely step idle states.
unforce
Resume normal functioning after force-idle or force-inactive.
get [light|deep|force|screen|charging|network]
Retrieve the current given state.
disable [light|deep|all]
Completely disable device idle mode.
enable [light|deep|all]
Re-enable device idle mode after it had previously been disabled.
enabled [light|deep|all]
Print 1 if device idle mode is currently enabled, else 0.
whitelist
Print currently whitelisted apps.
whitelist [package ...]
Add (prefix with +) or remove (prefix with -) packages.
except-idle-whitelist [package ...|reset]
Prefix the package with '+' to add it to whitelist or '=' to check if it is already whitelisted
[reset] will reset the whitelist to it's original state
Note that unlike cmd, changes made using this won' t be persisted across boots
tempwhitelist
Print packages that are temporarily whitelisted.
tempwhitelist [-u USER] [-d DURATION] [package ..]
Temporarily place packages in whitelist for DURATION milliseconds.
If no DURATION is specified, 10 seconds is used
如:
adb shell dumpsys deviceidle enable light # 开启LightDoze功能
adb shell dumpsys deviceidle step light #每执行一次,将会进入到LightDoze下一状态
adb shell dumpsys deviceidle whitelist # 查看当前Doze白名单
adb shell dumpsys deviceidle whitelist +com.android.settings #将Settings加入白名单
掌握DIC的dumpsys命令,对于平时调试很有帮助。
至此,Doze模式的分析就告一段落了。