概述
BatteryStatsHelper类用于负责计算各个应用和服务的电量使用情况,利用BatteryStatsService中统计的时长和电源配置文件中的配置值,通过计算得到耗电量信息供Application层使用。在Settings通过refreshStats()
方法从BatteryStatsHelper中获取电池的数据。下面就BatteryStatsHelper从实例化到计算系统用电情况进行分析。
代码路径:
/frameworks/base/core/java/com/android/internal/os/BatteryStatsHelper.java
1.BatteryStatsHelper的初始化方法
要使用BatteryStatsHelper,必须获取其实例,并调用create()
方法。因此这里看看其构造方法和create()
方法,代码如下:
public BatteryStatsHelper(Context context, boolean collectBatteryBroadcast, boolean wifiOnly) {
mContext = context;
//是否需要注册BATTERY_CHANGED广播
mCollectBatteryBroadcast = collectBatteryBroadcast;
//平板等无移动网络,故该值为true
mWifiOnly = wifiOnly;
mPackageManager = context.getPackageManager();
final Resources resources = context.getResources();
//表示将数组中的包名作为系统进程对待
mSystemPackageArray = resources.getStringArray(
com.android.internal.R.array.config_batteryPackageTypeSystem);
//表示将数组中的包名作为系统服务对待
mServicepackageArray = resources.getStringArray(
com.android.internal.R.array.config_batteryPackageTypeService);
}
create()
方法:
public void create(BatteryStats stats) {
mPowerProfile = new PowerProfile(mContext);
mStats = stats;
}
public void create(Bundle icicle) {
if (icicle != null) {
mStats = sStatsXfer;
mBatteryBroadcast = sBatteryBroadcastXfer;
}
mBatteryInfo = IBatteryStats.Stub.asInterface(
ServiceManager.getService(BatteryStats.SERVICE_NAME));
mPowerProfile = new PowerProfile(mContext);
}
构造方法比较简单。create()方法有两个重载,它们有个共同点:获取了PowerProfile对象,这个类在Battery系列三中已经分析过了,是电源配置文件。除此之外,还获得了BatteryStats对象。
1.1.refreshStats()方法
这个方法作为Application层刷新电池使用数据的接口,向上提供数据。电池统计的主要逻辑都是在这个方法中实现的,源代码如下:
public void refreshStats(int statsType, SparseArray<UserHandle> asUsers, long rawRealtimeUs,
long rawUptimeUs) {
// Initialize mStats if necessary.
//获取BatteryStatsImpl对象
getStats();
mMaxPower = 0;//最大耗电量
mMaxRealPower = 0;//最大真实耗电量
mComputedPower = 0;//通过耗电计算器计算的耗电量总和
mTotalPower = 0;//总的耗电量
//存储了BatterySipper的列表,各类耗电量都存储在BatterySipper中,BatterySipper又放在了mUsageList中
mUsageList.clear();
//在统计软件耗电过程中使用到wifi的应用对应的BatterySipper列表
mWifiSippers.clear();
//在统计软件耗电过程中使用到BT的应用对应的BatterySipper列表
mBluetoothSippers.clear();
//设备上有多个用户时,存储了其他用户的耗电信息的SparseArray数据,键为userId,值为对应的List<BatterySipper>
mUserSippers.clear();
//存储有数据接受和发送的BatterySipper对象的列表
mMobilemsppList.clear();
if (mStats == null) {
return;
}
//初始化八个耗电量计算器,此处不做详细分析
if (mCpuPowerCalculator == null) {
mCpuPowerCalculator = new CpuPowerCalculator(mPowerProfile);
}
mCpuPowerCalculator.reset();
if (mMemoryPowerCalculator == null) {
mMemoryPowerCalculator = new MemoryPowerCalculator(mPowerProfile);
}
mMemoryPowerCalculator.reset();
if (mWakelockPowerCalculator == null) {
mWakelockPowerCalculator = new WakelockPowerCalculator(mPowerProfile);
}
mWakelockPowerCalculator.reset();
if (mMobileRadioPowerCalculator == null) {
mMobileRadioPowerCalculator = new MobileRadioPowerCalculator(mPowerProfile, mStats);
}
mMobileRadioPowerCalculator.reset(mStats);
// checkHasWifiPowerReporting can change if we get energy data at a later point, so
// always check this field.
final boolean hasWifiPowerReporting = checkHasWifiPowerReporting(mStats, mPowerProfile);
if (mWifiPowerCalculator == null || hasWifiPowerReporting != mHasWifiPowerReporting) {
mWifiPowerCalculator = hasWifiPowerReporting ?
new WifiPowerCalculator(mPowerProfile) :
new WifiPowerEstimator(mPowerProfile);
mHasWifiPowerReporting = hasWifiPowerReporting;
}
mWifiPowerCalculator.reset();
final boolean hasBluetoothPowerReporting = checkHasBluetoothPowerReporting(mStats,
mPowerProfile);
if (mBluetoothPowerCalculator == null ||
hasBluetoothPowerReporting != mHasBluetoothPowerReporting) {
mBluetoothPowerCalculator = new BluetoothPowerCalculator(mPowerProfile);
mHasBluetoothPowerReporting = hasBluetoothPowerReporting;
}
mBluetoothPowerCalculator.reset();
if (mSensorPowerCalculator == null) {
mSensorPowerCalculator = new SensorPowerCalculator(mPowerProfile,
(SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE));
}
mSensorPowerCalculator.reset();
if (mCameraPowerCalculator == null) {
mCameraPowerCalculator = new CameraPowerCalculator(mPowerProfile);
}
mCameraPowerCalculator.reset();
if (mFlashlightPowerCalculator == null) {
mFlashlightPowerCalculator = new FlashlightPowerCalculator(mPowerProfile);
}
mFlashlightPowerCalculator.reset();
//统计类型,有三种:上次充满电后、上次充电后、当前
mStatsType = statsType;
//当前系统运行时间
mRawUptimeUs = rawUptimeUs;
//当前系统运行时间,包括休眠时间
mRawRealtimeUs = rawRealtimeUs;
//电池放电运行时间
mBatteryUptimeUs = mStats.getBatteryUptime(rawUptimeUs);
//电池放电运行时间,包括休眠时间
mBatteryRealtimeUs = mStats.getBatteryRealtime(rawRealtimeUs);
//对应类型的电池放电运行时间,如上次充满电后的电池运行时间
mTypeBatteryUptimeUs = mStats.computeBatteryUptime(rawUptimeUs, mStatsType);
//对应类型的电池放电运行时间,包括休眠时间
mTypeBatteryRealtimeUs = mStats.computeBatteryRealtime(rawRealtimeUs, mStatsType);
//电池预计使用时长
mBatteryTimeRemainingUs = mStats.computeBatteryTimeRemaining(rawRealtimeUs);
//电池预计多久充满时长
mChargeTimeRemainingUs = mStats.computeChargeTimeRemaining(rawRealtimeUs);
//最低放电量近似值 = (最低放电等级近似值 * PowerProfile中配置电池容量) / 100,是BatteryStatsService中统计的最低放电量近似值
mMinDrainedPower = (mStats.getLowDischargeAmountSinceCharge()
* mPowerProfile.getBatteryCapacity()) / 100;
//最高放电量近似值 = (最高放电等级近似值 * PowerProfile中配置电池容量) / 100,是BatteryStatsService中统计的最高放电量近似值
mMaxDrainedPower = (mStats.getHighDischargeAmountSinceCharge()
* mPowerProfile.getBatteryCapacity()) / 100;
//统计软件的耗电量,统计之后,会将每种类型、每个uid的耗电值存储在对应的BatterySipper中
processAppUsage(asUsers);
// Before aggregating apps in to users, collect all apps to sort by their ms per packet.
//计算每个BatterySipper(每个应用)的每毫接收和发送的数据包mobilemspp
for (int i = 0; i < mUsageList.size(); i++) {
BatterySipper bs = mUsageList.get(i);
bs.computeMobilemspp();
//如果对应应用的mobilemspp!=0,则将该BatterySipper加入到mMobilemsppList列表中
if (bs.mobilemspp !=