27 展訊Sprd設定-電池-省電白名單
阿新 • • 發佈:2018-11-26
1. 原始碼配置白名單
- vendor/sprd/platform/frameworks/native/data/etc/appPowerSaveConfig.xml
省電白名單文件,可以通過系統原始碼預設配置也可以通過軟體介面進行配置更新
2. 原始碼
2.1 讀取白名單
package com.android.server.power; public class PowerController //extends IPowerController.Stub extends UsageStatsManagerInternal.AppStateEventChangeListener { private void initData() { ... // init app power save settings ui config AppPowerSaveConfig.readConfig(mAppConfigMap); ... }
2.1 AppPowerSaveConfig.readConfig
- 對應的手機目錄位置
C:\Users\fadi.su>adb shell LN9810:/ # find system -name "appPowerSaveConfig.xml" find system -name "appPowerSaveConfig.xml" system/etc/appPowerSaveConfig.xml LN9810:/ # find data -name "appPowerSaveConfig.xml" find data -name "appPowerSaveConfig.xml" data/system/appPowerSaveConfig.xml LN9810:/ #
- 主要解析手機目錄中的 /data/system/appPowerSaveConfig.xml
/** * static API used to read the config from /data/system/appPowerSaveConfig.xml * and save them in appConfigMap * @param appConfigMap The configs read from config file will save to it * @return Returns true for sucess.Return false for fail */ private static final String APPCONFIG_FILENAME = "appPowerSaveConfig.xml"; private static final String XML_TAG_FILE = "app_powersave_config"; private static final String XML_TAG_PKG = "package"; private static final String XML_ATTRIBUTE_PKG_NAME = "name"; private static final String XML_ATTRIBUTE_PKG_OPTIMIZE = "optimize"; private static final String XML_ATTRIBUTE_PKG_ALARM = "alarm"; private static final String XML_ATTRIBUTE_PKG_WAKELOCK = "wakelock"; private static final String XML_ATTRIBUTE_PKG_NETWORK = "network"; private static final String XML_ATTRIBUTE_PKG_AUTOLAUNCH = "autolaunch"; private static final String XML_ATTRIBUTE_PKG_SECONDARYLAUNCH = "secondarylaunch"; private static final String XML_ATTRIBUTE_PKG_LOCKSCREENCLEANUP = "lockscreencleanup"; private static final String XML_ATTRIBUTE_PKG_POWERCONSUMERTYPE = "consumertype"; public static boolean readConfig(Map<String, AppPowerSaveConfig> appConfigMap){ // data/system/appPowerSaveConfig.xml AtomicFile aFile = new AtomicFile(new File(new File(Environment.getDataDirectory(), "system"), APPCONFIG_FILENAME)); InputStream stream = null; // 開啟 data/system/appPowerSaveConfig.xml 檔案,後續軟體介面的白名單,從這個檔案進行更新 try { stream = aFile.openRead(); }catch (FileNotFoundException exp){ Slog.e(TAG, ">>>file not found,"+exp); } // 如果data/system/appPowerSaveConfig.xml為空,則開啟 system/etc/appPowerSaveConfig.xml,這裡一定有 if (null == stream) { // system/etc/appPowerSaveConfig.xml 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; } } // 接下來的操作全部都是xml解析對應節點,獲取原始碼中配置好的白名單資料 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; }
2.2 appPowerSaveConfig.xml
- 例如匯入的內容如下
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<app_powersave_config>
<package name="com.pp.assistant" optimize="1" alarm="0" wakelock="0" network="0" autolaunch="1" secondarylaunch="1" lockscreencleanup="1" consumertype="0" />
<package name="com.comcat.activity" optimize="1" alarm="0" wakelock="0" network="0" autolaunch="2" secondarylaunch="2" lockscreencleanup="2" consumertype="0" />
<package name="com.greenpoint.android.mc10086.activity" optimize="1" alarm="0" wakelock="0" network="0" autolaunch="2" secondarylaunch="2" lockscreencleanup="2" consumertype="0" />
<package name="com.jio.emiddleware" optimize="1" alarm="0" wakelock="0" network="0" autolaunch="2" secondarylaunch="2" lockscreencleanup="2" consumertype="0" />
<package name="com.tencent.mm" optimize="2" alarm="0" wakelock="0" network="0" autolaunch="2" secondarylaunch="2" lockscreencleanup="2" consumertype="0" />
<package name="com.tencent.mobileqq" optimize="2" alarm="2" wakelock="2" network="2" autolaunch="2" secondarylaunch="2" lockscreencleanup="2" consumertype="0" />
<package name="com.tencent.qqlite" optimize="2" alarm="2" wakelock="2" network="2" autolaunch="2" secondarylaunch="2" lockscreencleanup="2" consumertype="0" />
<package name="com.tencent.mobileqqi" optimize="2" alarm="2" wakelock="2" network="2" autolaunch="2" secondarylaunch="2" lockscreencleanup="2" consumertype="0" />
</app_powersave_config>
- 數值含義
public static final int VALUE_INVALID = -1;//無效
public static final int VALUE_AUTO = 0;// 自動
public static final int VALUE_OPTIMIZE = 1;// 省電優化,即黑名單
public static final int VALUE_NO_OPTIMIZE = 2;// 不進行省電優化,即白名單
2.2 讀寫白名單
將白名單資料寫入 /data/system/appPowerSaveConfig.xml 中
/**
* static API used to write the configs in 'appConfigMap' to /data/system/appPowerSaveConfig.xml
* @param appConfigMap The configs that will save to config file.
* @return Returns true for sucess.Return false for fail
*/
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;
}
3. 獲取是否為白名單
- PowerControllerInternal.getAppPowerSaveConfgWithTypeInternal(包名,型別名)
3.1 getAppPowerSaveConfgWithTypeInternal
mPowerControllerInternal = LocalServices.getService(PowerController.LocalService.class);
int autoLaunch = mPowerControllerInternal.getAppPowerSaveConfgWithTypeInternal(targetApp,AppPowerSaveConfig.ConfigType.TYPE_AUTOLAUNCH.value);
int secondLaunch = mPowerControllerInternal.getAppPowerSaveConfgWithTypeInternal(targetApp,AppPowerSaveConfig.ConfigType.TYPE_SECONDARYLAUNCH.value);
3.2 PowerController.LocalService.getAppPowerSaveConfgWithTypeInternal
package com.android.server.power;
public class PowerController extends UsageStatsManagerInternal.AppStateEventChangeListener {
public final class LocalService {
// From ui settings
int getAppPowerSaveConfgWithTypeInternal(String appName, int type) {
AppPowerSaveConfig config = mAppConfigMap.get(appName);
if (null == config) {
return AppPowerSaveConfig.getDefaultValue(type);
}
return AppPowerSaveConfig.getConfigValue(config, type);
}
3.2.1 AppPowerSaveConfig.getDefaultValue
預設為黑名單
private static final String AUTOLAUNCH_DEF_PROP = "persist.sys.pwctl.auto";
private static final String SECONDARYLAUNCH_DEF_PROP = "persist.sys.pwctl.secondary";
private final static int AUTOLAUNCH_DEF = SystemProperties.getInt(AUTOLAUNCH_DEF_PROP, VALUE_OPTIMIZE);
private final static int SECONDARYLAUNCH_DEF = SystemProperties.getInt(SECONDARYLAUNCH_DEF_PROP, VALUE_OPTIMIZE);
static {
mDefConfig[ConfigType.TYPE_AUTOLAUNCH.value] = AUTOLAUNCH_DEF;
mDefConfig[ConfigType.TYPE_SECONDARYLAUNCH.value] = SECONDARYLAUNCH_DEF;
}
/**
* Get the default value of specific config type. The default values are defined in mDefConfig[].
*
* @param type The config type.
* @return Returns the default value.
*/
public static int getDefaultValue(int type) {
return mDefConfig[type];
}
3.2.3 AppPowerSaveConfig.getConfigValue
對應省電功能型別下的對應黑白名單設定
/**
* static api used to return the config value of the 'configType' in the config.
* @param config The AppPowerSaveConfig.
* @param configType The specified config type.
* @return Returns the value of the config type.
*/
public static int getConfigValue(AppPowerSaveConfig config, int configType) {
if (configType == ConfigType.TYPE_OPTIMIZE.value )
return config.optimize;
else if (configType == ConfigType.TYPE_ALARM.value )
return config.alarm;
else if (configType == ConfigType.TYPE_WAKELOCK.value)
return config.wakelock;
else if (configType == ConfigType.TYPE_NETWORK.value)
return config.network;
else if (configType == ConfigType.TYPE_AUTOLAUNCH.value)
return config.autoLaunch;
else if (configType == ConfigType.TYPE_SECONDARYLAUNCH.value)
return config.secondaryLaunch;
else if (configType == ConfigType.TYPE_LOCKSCREENCLEANUP.value)
return config.lockscreenCleanup;
else if (configType == ConfigType.TYPE_POWERCONSUMERTYPE.value)
return config.powerConsumerType;
return VALUE_INVALID;
}