相关文件及目录如下:
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耗电量
- ……
- }
主要是使用时间的统计计算~