DeviceIdleController的实现逻辑
1.服务启动
Doze功能概述
当系统灭屏并长时间处于静止状态时,系统会进入Doze状态,此时
(1)不在White list里的APP会被限制网络访问
(2)wake lock会被忽略
(3)通过alarm manger设置的alarm 被推迟,除非设置了允许在idle状态也能工作的flag
(5)wifi scan被取消
(6)jobschedule 和sync被推迟
1.1SystemServer.java启动阶段
的startOtherServices() 中有
mSystemServiceManager.startService(DeviceIdleController.class);这里启动DeviceIdleController的服务
首先调用到DeviceIdleController的构造函数:
public DeviceIdleController(Context context) {
super(context);
mConfigFile = new AtomicFile(new File(getSystemDir(), "deviceidle.xml"));
mHandler = new MyHandler(BackgroundThread.getHandler().getLooper());
}
构造函数仅仅做了两件事:1.创建一个保证原子操作的的mConfigFile的文件(系统/data/system/deviceidle.xml文件);2.创建一个handler线程执行idle的状态变化消息处理。
SystemServer的start的函数在执行了service的构造函数之后,会将该函数add到SystemService的list中,然后执行到Service的onStart函数中。
DeviceIdleController的onStart函数总共做了两件事:
mEnabled = getContext().getResources().getBoolean(
com.android.internal.R.bool.config_enableAutoPowerModes);
Idle模式中开关在frameworks/base/core/res/res/values/config.xml中配置。原生逻辑默认是关闭的,可以修改配置打开
SystemConfig sysConfig = SystemConfig.getInstance();
ArraySet<String> allowPowerExceptIdle = sysConfig.getAllowInPowerSaveExceptIdle();
for (int i=0; i<allowPowerExceptIdle.size(); i++) {
String pkg = allowPowerExceptIdle.valueAt(i);
try {
ApplicationInfo ai = pm.getApplicationInfo(pkg, 0);
if ((ai.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
int appid = UserHandle.getAppId(ai.uid);
mPowerSaveWhitelistAppsExceptIdle.put(ai.packageName, appid);
mPowerSaveWhitelistSystemAppIdsExceptIdle.put(appid, true);
}
将配置文件中配置系统应用白名单应用添加到mPowerSaveWhitelistAppsExceptIdle列表中,省电模式下这些应用即使不在前台也能有联网权限(除了在Idle状态下)
ArraySet<String> allowPower = sysConfig.getAllowInPowerSave();
for (int i=0; i<allowPower.size(); i++) {
String pkg = allowPower.valueAt(i);
try {
ApplicationInfo ai = pm.getApplicationInfo(pkg, 0);
if ((ai.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
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