App Standby黑白名单配置流程
如图所示,可选择优化和不优化
代码路径:packages\apps\Settings\src\com\android\settings\fuelgauge\HightPowerDetail
@Override
public void onClick(DialogInterface dialog, int which) {
if (which == DialogInterface.BUTTON_POSITIVE) {
boolean newValue = mIsEnabled;
boolean oldValue = mBackend.isWhitelisted(mPackageName);
if (newValue != oldValue) {
logSpecialPermissionChange(newValue, mPackageName, getContext());
if (newValue) {
mBackend.addApp(mPackageName);
} else {
mBackend.removeApp(mPackageName);
}
}
}
}
继续跟踪mBackend
packages\apps\Settings\src\com\android\settings\fuelgauge\PowerWhitelistBackend
public void addApp(String pkg) {
try {
mDeviceIdleService.addPowerSaveWhitelistApp(pkg);
mWhitelistedApps.add(pkg);
} catch (RemoteException e) {
Log.w(TAG, "Unable to reach IDeviceIdleController", e);
}
}
DeviceIdleController.java-->addPowerSaveWhitelistApp()
@Override public void addPowerSaveWhitelistApp(String name) {
if (DEBUG) {
Slog.i(TAG, "addPowerSaveWhitelistApp(name = " + name + ")");
}
getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
null);
long ident = Binder.clearCallingIdentity();
try {
addPowerSaveWhitelistAppInternal(name);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
DeviceIdleController.java-->addPowerSaveWhitelistAppInternal()
public boolean addPowerSaveWhitelistAppInternal(String name) {
synchronized (this) {
try {
ApplicationInfo ai = getContext().getPackageManager().getApplicationInfo(name,
PackageManager.MATCH_ANY_USER);
if (mPowerSaveWhitelistUserApps.put(name, UserHandle.getAppId(ai.uid)) == null) {
reportPowerSaveWhitelistChangedLocked();
updateWhitelistAppIdsLocked();
//将该集合遍历出来写入文件
writeConfigFileLocked();
}
return true;
} catch (PackageManager.NameNotFoundException e) {
return false;
}
}
}
通过应用名获取到对应的ApplicationInfo,然后将应用名存入mPowerSaveWhitelistUserApps集合里,再调用writeConfigFileLocked将该集合遍历出来写入文件。
void writeConfigFileLocked() {
mHandler.removeMessages(MSG_WRITE_CONFIG);
mHandler.sendEmptyMessageDelayed(MSG_WRITE_CONFIG, 5000);
}
case MSG_WRITE_CONFIG: {
// Does not hold a wakelock. Just let this happen whenever.
handleWriteConfigFile();
} break;
void handleWriteConfigFile() {
final ByteArrayOutputStream memStream = new ByteArrayOutputStream();
try {
synchronized (this) {
XmlSerializer out = new FastXmlSerializer();
out.setOutput(memStream, StandardCharsets.UTF_8.name());
writeConfigFileLocked(out);
}
} catch (IOException e) {
}
synchronized (mConfigFile) {
FileOutputStream stream = null;
try {
stream = mConfigFile.startWrite();
memStream.writeTo(stream);
stream.flush();
FileUtils.sync(stream);
stream.close();
mConfigFile.finishWrite(stream);
} catch (IOException e) {
Slog.w(TAG, "Error writing config file", e);
mConfigFile.failWrite(stream);
}
}
}
我们看下这个mConfigFile = new AtomicFile(new File(getSystemDir(), "deviceidle.xml"));
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<config>
<wl n="com.tencent.mm" />
<wl n="com.sina.weibo" />
<wl n="com.tencent.mobileqq" />
<wl n="com.skype.raider" />
<wl n="com.skype.m2" />
<wl n="com.bbm" />
<wl n="com.facebook.katana" />
<wl n="com.whatsapp" />
<wl n="jp.naver.line.android" />
<wl n="com.twitter.android" />
<wl n="com.instagram.android" />
<wl n="com.facebook.orca" />
<wl n="com.facebook.mlite" />
<wl n="com.viber.voip" />
<wl n="com.imo.android.imoim" />
<wl n="com.imo.android.imoimbeta" />
<wl n="pro.imoc.allvideo" />
<wl n="com.facebook.pages.app" />
<wl n="com.facebook.Mentions" />
</config>