在Android Sprd省电管理(一)appPowerSaveConfig.xml,我们介绍了appPowerSaveConfig.xml的主要参数的意义,这一篇我们介绍下,怎么设置应用的各种省电模式
首先看SprdManageApplications这个类
以锁屏清理为例,点击开关
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (mApplications != null && mApplications.getCount() > position) {
ApplicationsState.AppEntry entry = mApplications.getAppEntry(position);
String pkg = entry.info.packageName;
muid = entry.info.uid;
//for app standy optimization
if (mArgument == TYPE_APP_WAKEUP) {
Log.d(TAG,"onItemClick pkg = " + pkg);
startAppConfigFragment(SprdAppItemBatterySaverFragment.class, pkg, entry.label);
return;
} else if (mArgument == TYPE_APP_POWER_INTENSIVE) {
restartBatteryStatsLoader();
startAdvancedPowerUsageDetail(pkg);
return;
}
//for lock screen close-app and app auto-run
SprdAppViewHolder holder = (SprdAppViewHolder) view.getTag();
if (holder == null ) return;
holder.app_switch.toggle();
boolean isChecked = holder.app_switch.isChecked();
Log.d(TAG, "isChecked: " + isChecked + " pkg: " + pkg);
mSwitchState = DEFAULT;
int configValue = CLOSE;
if (mArgument == TYPE_APP_CLOSE_LOCKED) {
configValue = isChecked ? CLOSE : DO_NOT_CLOSE;
} else {
configValue = isChecked ? DO_NOT_OPTIMIZE : OPTIMIZE;
}
try {
//将package name, 省电模式,省电模式的值传给setAppPowerSaveConfigWithType
mPowerManagerEx.setAppPowerSaveConfigWithType(pkg, mAppConfigType, configValue);
mApplications.setAppStateText(isChecked, holder);
} catch (RemoteException e) {
// Not much we can do here
}
if (isChecked) {
mApplications.setSwitchIfAllAppOpen();
} else {
if (mAllAppSwitch != null) mAllAppSwitch.setChecked(false);
}
}
}
PowerManagerServiceEx.java-->setAppPowerSaveConfigWithType()
public boolean setAppPowerSaveConfigWithType(String appName, int type, int value) {
return mPowerControllerInternal.setAppPowerSaveConfigWithType(appName, type, value);
}
PowerControll.java-->setAppPowerSaveConfigWithType()
boolean setAppPowerSaveConfigWithType(String appName, int type, int value) {
if (DEBUG) Slog.d(TAG, "setAppPowerSaveConfigWithType(), appName: " + appName + ", type: " + AppPowerSaveConfig.ConfigType2Str(type) + ", value: " + AppPowerSaveConfig.ConfigValue2Str(value));
if ((null == appName) || ((type <= AppPowerSaveConfig.ConfigType.TYPE_NULL.value) || (type >= AppPowerSaveConfig.ConfigType.TYPE_MAX.value))
|| ((value < AppPowerSaveConfig.VALUE_AUTO) || (value > AppPowerSaveConfig.VALUE_NO_OPTIMIZE))) {
return false;
}
try {
synchronized (mMsgLock) {
if
//发送MSG_SET_APP_POWERSAVE_CONFIG_WITHTYPE
(!msgHandler.sendMessage(msgHandler.obtainMessage(MSG_SET_APP_POWERSAVE_CONFIG_WITHTYPE, type, value, appName))) return false;
mMsgLock.wait();
}
} catch (InterruptedException e) {
Slog.e(TAG, e.toString());
}
return true;
}
case MSG_SET_APP_POWERSAVE_CONFIG_WITHTYPE: {
String appName = (String)msg.obj;
setAppPowerSaveConfigWithTypeInternal(appName, msg.arg1, msg.arg2);
}
break;
PowerControll.java-->setAppPowerSaveConfigWithTypeInternal()
private boolean setAppPowerSaveConfigWithTypeInternal(String appName, int type, int value) {
AppPowerSaveConfig oldConfig = mAppConfigMap.get(appName);
if (null == oldConfig) {
oldConfig = new AppPowerSaveConfig();
}
int oldValue = AppPowerSaveConfig.getConfigValue(oldConfig, type);
if (DEBUG) Slog.d(TAG, "setAppPowerSaveConfigWithTypeInternal(), appName: " + appName + ", config type: " + AppPowerSaveConfig.ConfigType2Str(type)
+ ", new value: " + AppPowerSaveConfig.ConfigValue2Str(value)
+ ", old value: " + AppPowerSaveConfig.ConfigValue2Str(oldValue));
if (value != oldValue) {
onPowerSaveConfigChanged(type, appName, oldValue, value, false);
for (int j = 0; j < mHelpers.size(); j++) {
PowerSaveHelper helper = mHelpers.get(j);
if (0 != (AppPowerSaveConfig.mMaskArray[type] & helper.mMask)) {
helper.onPowerSaveConfigChanged(type, appName, oldValue, value, false);
}
}
}
AppPowerSaveConfig.setConfigWithType(oldConfig, type, value);
if (DEBUG) Slog.d(TAG, "setAppPowerSaveConfigWithTypeInternal() config: " + oldConfig);
if (oldConfig.isReset()) {
if (DEBUG) Slog.d(TAG, "setAppPowerSaveConfigWithTypeInternal() remove old");
mAppConfigMap.remove(appName);
} else {
if (DEBUG) Slog.d(TAG, "setAppPowerSaveConfigWithTypeInternal() put new");
mAppConfigMap.put(appName, oldConfig);
}
//写入到xml文件保存
AppPowerSaveConfig.writeConfig(mAppConfigMap);
synchronized(mMsgLock) {
mMsgLock.notify();
}
return true;
}
AppPowerSaveConfig.java-->writeConfig()
public static boolean writeConfig(Map<String, AppPowerSaveConfig> appConfigMap) {
AtomicFile aFile = new AtomicFile(new File(new File(Environment.getDataDirectory(), "system"), APPCONFIG_FILENAME));
FileOutputStream stream;
try {
stream = aFile.startWrite();
} catch (IOException e) {
Slog.e(TAG, "Failed to write state: " + e);
return false;
}
try {
XmlSerializer serializer = new FastXmlSerializer();
serializer.setOutput(stream, "utf-8");
serializer.startDocument(null, true);
serializer.startTag(null, XML_TAG_FILE);
if (appConfigMap!= null) {
for (Map.Entry<String, AppPowerSaveConfig> cur : appConfigMap.entrySet()) {
final String appName = cur.getKey();
final AppPowerSaveConfig config = cur.getValue();
if (config.isReset()) continue;
serializer.startTag(null, XML_TAG_PKG);
serializer.attribute(null, XML_ATTRIBUTE_PKG_NAME, appName);
serializer.attribute(null, XML_ATTRIBUTE_PKG_OPTIMIZE, String.valueOf(config.optimize));
serializer.attribute(null, XML_ATTRIBUTE_PKG_ALARM, String.valueOf(config.alarm));
serializer.attribute(null, XML_ATTRIBUTE_PKG_WAKELOCK, String.valueOf(config.wakelock));
serializer.attribute(null, XML_ATTRIBUTE_PKG_NETWORK, String.valueOf(config.network));
serializer.attribute(null, XML_ATTRIBUTE_PKG_AUTOLAUNCH, String.valueOf(config.autoLaunch));
serializer.attribute(null, XML_ATTRIBUTE_PKG_SECONDARYLAUNCH, String.valueOf(config.secondaryLaunch));
serializer.attribute(null, XML_ATTRIBUTE_PKG_LOCKSCREENCLEANUP, String.valueOf(config.lockscreenCleanup));
serializer.attribute(null, XML_ATTRIBUTE_PKG_POWERCONSUMERTYPE, String.valueOf(config.powerConsumerType));
serializer.endTag(null, XML_TAG_PKG);
}
}
serializer.endTag(null, XML_TAG_FILE);
serializer.endDocument();
aFile.finishWrite(stream);
} catch (IOException e) {
Slog.e(TAG, "Failed to write state, restoring backup."+"exp:"+"\n"+e);
aFile.failWrite(stream);
return false;
}
return true;
}
每次开机的时候,都会读取这个xml文件,将xml的值赋值给mAppConfigMap
private void initData() {
......
AppPowerSaveConfig.readConfig(mAppConfigMap);
......
}
AppPowerSaveConfig.java-->readConfig()
public static boolean readConfig(Map<String, AppPowerSaveConfig> appConfigMap){
AtomicFile aFile = new AtomicFile(new File(new File(Environment.getDataDirectory(), "system"), APPCONFIG_FILENAME));
InputStream stream = null;
try {
stream = aFile.openRead();
}catch (FileNotFoundException exp){
Slog.e(TAG, ">>>file not found,"+exp);
}
if (null == stream) {
aFile = new AtomicFile(new File(new File(Environment.getRootDirectory(), "etc"), APPCONFIG_FILENAME));
try {
stream = aFile.openRead();
} catch (FileNotFoundException exp){
Slog.e(TAG, ">>>default file not found,"+exp);
return false;
}
}
try {
String appName = null;
AppPowerSaveConfig appConfig = null;
XmlPullParser pullParser = Xml.newPullParser();
pullParser.setInput(stream, "UTF-8");
int event = pullParser.getEventType();
while (event != XmlPullParser.END_DOCUMENT) {
switch (event) {
case XmlPullParser.START_DOCUMENT:
//retList = new ArrayList<PowerGuruAlarmInfo>();
break;
case XmlPullParser.START_TAG:
if (XML_TAG_PKG.equals(pullParser.getName())) {
appConfig = new AppPowerSaveConfig();
appName = pullParser.getAttributeValue(null, XML_ATTRIBUTE_PKG_NAME);
appConfig.optimize = Integer.parseInt(pullParser.getAttributeValue(null, XML_ATTRIBUTE_PKG_OPTIMIZE));
appConfig.alarm = Integer.parseInt(pullParser.getAttributeValue(null, XML_ATTRIBUTE_PKG_ALARM));
appConfig.wakelock = Integer.parseInt(pullParser.getAttributeValue(null, XML_ATTRIBUTE_PKG_WAKELOCK));
appConfig.network = Integer.parseInt(pullParser.getAttributeValue(null, XML_ATTRIBUTE_PKG_NETWORK));
appConfig.autoLaunch = Integer.parseInt(pullParser.getAttributeValue(null, XML_ATTRIBUTE_PKG_AUTOLAUNCH));
appConfig.secondaryLaunch = Integer.parseInt(pullParser.getAttributeValue(null, XML_ATTRIBUTE_PKG_SECONDARYLAUNCH));
appConfig.lockscreenCleanup = Integer.parseInt(pullParser.getAttributeValue(null, XML_ATTRIBUTE_PKG_LOCKSCREENCLEANUP));
appConfig.powerConsumerType = Integer.parseInt(pullParser.getAttributeValue(null, XML_ATTRIBUTE_PKG_POWERCONSUMERTYPE));
}
break;
case XmlPullParser.END_TAG:
if(XML_TAG_PKG.equals(pullParser.getName())) {
appConfigMap.put(appName, appConfig);
appConfig = null;
}
break;
}
event = pullParser.next();
}
} catch (IllegalStateException e) {
Slog.e(TAG, "Failed parsing " + e);
return false;
} catch (NullPointerException e) {
Slog.e(TAG, "Failed parsing " + e);
return false;
} catch (NumberFormatException e) {
Slog.e(TAG, "Failed parsing " + e);
return false;
} catch (XmlPullParserException e) {
Slog.e(TAG, "Failed parsing " + e);
return false;
} catch (IOException e) {
Slog.e(TAG, "Failed parsing " + e);
return false;
} catch (IndexOutOfBoundsException e) {
Slog.e(TAG, "Failed parsing " + e);
return false;
} finally {
try {
stream.close();
} catch (IOException e) {
Slog.e(TAG, "Fail to close stream " + e);
return false;
} catch (Exception e) {
Slog.e(TAG, "exception at last,e: " + e);
return false;
}
}
return true;
}