相关文件及目录如下:
packages/apps/Settings/src/com/android/settings/fuelgauge/PowerUsageSummary.java
packages/apps/Settings/src/com/android/settings/fuelgauge/PowerUsageDetail.java
packages/apps/Settings/src/com/android/settings/fuelgauge/BatterySipper.java
frameworks/base/core/java/android/os/BatteryStats.java
frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
frameworks/base/core/java/com/android/internal/os/ProcessStats.java
frameworks/base/core/java/com/android/internal/os/PowerProfile.java
frameworks/base/services/java/com/android/server/am/BatteryStatsService.java
进入devices,选择Settings -> Battery,这里对应的xml为:
<!-- Battery -->
<header
android:id="@+id/battery_settings"
android:fragment="com.android.settings.fuelgauge.PowerUsageSummary"
android:icon="@drawable/ic_settings_battery"
android:title="@string/power_usage_summary_title" />
这部分功能展示是通过PowerUsageSummary来实现的
在PowerUsageSummary.java中:
@Override
public void onCreate(Bundle icicle) {
……
// 获得一个service的接口,字符串”batteryinfo”作为标识
mBatteryInfo = IBatteryStats.Stub.asInterface(
ServiceManager.getService("batteryinfo"));
……
// 从powerprofile.xml创建PowerProfile对象
mPowerProfile = new PowerProfile(getActivity());
……
}
@Override
public void onResume() {
……
refreshStats(); // 更新统计资料
}
private void refreshStats() {
if (mStats == null) {
load(); // 若BatteryStatsImpl对象mStats为null,加载资料
}
……
}
private void load() {
try {
byte[] data = mBatteryInfo.getStatistics(); // 从service接口取得bytes
Parcel parcel = Parcel.obtain();
parcel.unmarshall(data, 0, data.length); // 设置parcel数据
parcel.setDataPosition(0);
mStats = com.android.internal.os.BatteryStatsImpl.CREATOR
.createFromParcel(parcel); // 从parcel创建出mStats
mStats.distributeWorkLocked(BatteryStats.STATS_SINCE_CHARGED); //分发数据
} catch (RemoteException e) {
Log.e(TAG, "RemoteException:", e);
}
}
BatteryStatsService.java中:
BatteryStatsService(String filename) {
mStats = new BatteryStatsImpl(filename); // 创建BatteryStatsImpl对象
}
public void publish(Context context) {
mContext = context;
ServiceManager.addService("batteryinfo", asBinder());
// addService标识”batteryinfo”
mStats.setNumSpeedSteps(new PowerProfile(mContext).getNumSpeedSteps());
……
}
public static IBatteryStats getService() {
……
IBinder b = ServiceManager.getService("batteryinfo");
sService = asInterface(b); // 提供”batteryinfo” service接口
return sService;
}
public byte[] getStatistics() {
// 需要BATTERY_STATS permission
mContext.enforceCallingPermission(
android.Manifest.permission.BATTERY_STATS, null);
Parcel out = Parcel.obtain();
mStats.writeToParcel(out, 0); // 向out中写数据
byte[] data = out.marshall(); // 返回out中的raw bytes
out.recycle();
return data;
}
再到BatteryStatsImpl.java:
public void writeToParcel(Parcel out, int flags) {
writeToParcelLocked(out, true, flags); // 将Time资料写入out中
}
// 上述中BatteryStatsImpl.CREATOR.createFromParcel(parcel) 在这里最终使用如下方法进行构造
public void readFromParcel(Parcel in) {
readFromParcelLocked(in);
}
再实现获取时间接口(内部类)
public final class Proc extends BatteryStats.Uid.Proc implements Unpluggable如:
@Override
public long getUserTime(int which) {
long val;
if (which == STATS_LAST) {
val = mLastUserTime;
} else {
val = mUserTime;
if (which == STATS_CURRENT) {
val -= mLoadedUserTime;
} else if (which == STATS_SINCE_UNPLUGGED) {
val -= mUnpluggedUserTime;
}
}
return val;
}
获取的Time值也都写入Parcel对象中
BatteryStatsImpl对象创建完成后,我们回到PowerUsageSummary.java
private void refreshStats() {
if (mStats == null) {
load();
}
……
processAppUsage(); // 计算出App耗电量
……
}
主要是使用时间的统计计算~