Android Sprd省電管理(二)應用省電模式設定流程
阿新 • • 發佈:2019-01-14
在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;
}