Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c8345b32 authored by Dianne Hackborn's avatar Dianne Hackborn Committed by Android (Google) Code Review
Browse files

Merge "Add battery power use reporting to batterystats service."

parents 0430ee5a a7c837f0
Loading
Loading
Loading
Loading
+137 −9
Original line number Diff line number Diff line
@@ -24,11 +24,14 @@ import java.util.Formatter;
import java.util.List;
import java.util.Map;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.telephony.SignalStrength;
import android.util.Printer;
import android.util.SparseArray;
import android.util.TimeUtils;
import com.android.internal.os.BatterySipper;
import com.android.internal.os.BatteryStatsHelper;

/**
 * A class providing access to battery usage statistics, including information on
@@ -166,6 +169,8 @@ public abstract class BatteryStats implements Parcelable {
    private static final String SIGNAL_STRENGTH_COUNT_DATA = "sgc";
    private static final String DATA_CONNECTION_TIME_DATA = "dct";
    private static final String DATA_CONNECTION_COUNT_DATA = "dcc";
    private static final String POWER_USE_SUMMARY_DATA = "pws";
    private static final String POWER_USE_ITEM_DATA = "pwi";

    private final StringBuilder mFormatBuilder = new StringBuilder(32);
    private final Formatter mFormatter = new Formatter(mFormatBuilder);
@@ -865,6 +870,8 @@ public abstract class BatteryStats implements Parcelable {
     */
    public abstract long getBluetoothOnTime(long batteryRealtime, int which);
    
    public abstract int getBluetoothPingCount();

    public static final int NETWORK_MOBILE_RX_DATA = 0;
    public static final int NETWORK_MOBILE_TX_DATA = 1;
    public static final int NETWORK_WIFI_RX_DATA = 2;
@@ -997,6 +1004,8 @@ public abstract class BatteryStats implements Parcelable {
    /** Returns the number of different speeds that the CPU can run at */
    public abstract int getCpuSpeedSteps();

    public abstract void writeToParcelWithoutUids(Parcel out, int flags);

    private final static void formatTimeRaw(StringBuilder out, long seconds) {
        long days = seconds / (60 * 60 * 24);
        if (days != 0) {
@@ -1163,7 +1172,7 @@ public abstract class BatteryStats implements Parcelable {
     * 
     * NOTE: all times are expressed in 'ms'.
     */
    public final void dumpCheckinLocked(PrintWriter pw, int which, int reqUid) {
    public final void dumpCheckinLocked(Context context, PrintWriter pw, int which, int reqUid) {
        final long rawUptime = SystemClock.uptimeMillis() * 1000;
        final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
        final long batteryUptime = getBatteryUptime(rawUptime);
@@ -1300,6 +1309,61 @@ public abstract class BatteryStats implements Parcelable {
            }
        }
        
        BatteryStatsHelper helper = new BatteryStatsHelper(context);
        helper.create(this);
        helper.refreshStats(which, UserHandle.USER_ALL);
        List<BatterySipper> sippers = helper.getUsageList();
        if (sippers != null && sippers.size() > 0) {
            dumpLine(pw, 0 /* uid */, category, POWER_USE_SUMMARY_DATA,
                    BatteryStatsHelper.makemAh(helper.getPowerProfile().getBatteryCapacity()),
                    BatteryStatsHelper.makemAh(helper.getTotalPower()),
                    BatteryStatsHelper.makemAh(helper.getMinDrainedPower()),
                    BatteryStatsHelper.makemAh(helper.getMaxDrainedPower()));
            for (int i=0; i<sippers.size(); i++) {
                BatterySipper bs = sippers.get(i);
                int uid = 0;
                String label;
                switch (bs.drainType) {
                    case IDLE:
                        label="idle";
                        break;
                    case CELL:
                        label="cell";
                        break;
                    case PHONE:
                        label="phone";
                        break;
                    case WIFI:
                        label="wifi";
                        break;
                    case BLUETOOTH:
                        label="blue";
                        break;
                    case SCREEN:
                        label="scrn";
                        break;
                    case APP:
                        uid = bs.uidObj.getUid();
                        label = "uid";
                        break;
                    case USER:
                        uid = UserHandle.getUid(bs.userId, 0);
                        label = "user";
                        break;
                    case UNACCOUNTED:
                        label = "unacc";
                        break;
                    case OVERCOUNTED:
                        label = "over";
                        break;
                    default:
                        label = "???";
                }
                dumpLine(pw, uid, category, POWER_USE_ITEM_DATA, label,
                        BatteryStatsHelper.makemAh(bs.value));
            }
        }

        for (int iu = 0; iu < NU; iu++) {
            final int uid = uidStats.keyAt(iu);
            if (reqUid >= 0 && uid != reqUid) {
@@ -1471,8 +1535,13 @@ public abstract class BatteryStats implements Parcelable {
        }
    }

    private void printmAh(PrintWriter printer, double power) {
        printer.print(BatteryStatsHelper.makemAh(power));
    }

    @SuppressWarnings("unused")
    public final void dumpLocked(PrintWriter pw, String prefix, final int which, int reqUid) {
    public final void dumpLocked(Context context, PrintWriter pw, String prefix, final int which,
            int reqUid) {
        final long rawUptime = SystemClock.uptimeMillis() * 1000;
        final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
        final long batteryUptime = getBatteryUptime(rawUptime);
@@ -1758,6 +1827,65 @@ public abstract class BatteryStats implements Parcelable {
            pw.println();
        }

        BatteryStatsHelper helper = new BatteryStatsHelper(context);
        helper.create(this);
        helper.refreshStats(which, UserHandle.USER_ALL);
        List<BatterySipper> sippers = helper.getUsageList();
        if (sippers != null && sippers.size() > 0) {
            pw.print(prefix); pw.println("  Estimated power use (mAh):");
            pw.print(prefix); pw.print("    Capacity: ");
                    printmAh(pw, helper.getPowerProfile().getBatteryCapacity());
                    pw.print(", Computed drain: "); printmAh(pw, helper.getTotalPower());
                    pw.print(", Min drain: "); printmAh(pw, helper.getMinDrainedPower());
                    pw.print(", Max drain: "); printmAh(pw, helper.getMaxDrainedPower());
                    pw.println();
            for (int i=0; i<sippers.size(); i++) {
                BatterySipper bs = sippers.get(i);
                switch (bs.drainType) {
                    case IDLE:
                        pw.print(prefix); pw.print("    Idle: "); printmAh(pw, bs.value);
                        pw.println();
                        break;
                    case CELL:
                        pw.print(prefix); pw.print("    Cell standby: "); printmAh(pw, bs.value);
                        pw.println();
                        break;
                    case PHONE:
                        pw.print(prefix); pw.print("    Phone calls: "); printmAh(pw, bs.value);
                        pw.println();
                        break;
                    case WIFI:
                        pw.print(prefix); pw.print("    Wifi: "); printmAh(pw, bs.value);
                        pw.println();
                        break;
                    case BLUETOOTH:
                        pw.print(prefix); pw.print("    Bluetooth: "); printmAh(pw, bs.value);
                        pw.println();
                        break;
                    case SCREEN:
                        pw.print(prefix); pw.print("    Screen: "); printmAh(pw, bs.value);
                        pw.println();
                        break;
                    case APP:
                        pw.print(prefix); pw.print("    Uid "); pw.print(bs.uidObj.getUid());
                        pw.print(": "); printmAh(pw, bs.value); pw.println();
                        break;
                    case USER:
                        pw.print(prefix); pw.print("    User "); pw.print(bs.userId);
                        pw.print(": "); printmAh(pw, bs.value); pw.println();
                        break;
                    case UNACCOUNTED:
                        pw.print(prefix); pw.print("    Unaccounted: "); printmAh(pw, bs.value);
                        pw.println();
                        break;
                    case OVERCOUNTED:
                        pw.print(prefix); pw.print("    Over-counted: "); printmAh(pw, bs.value);
                        pw.println();
                        break;
                }
            }
        }

        if (timers.size() > 0) {
            Collections.sort(timers, timerComparator);
            pw.print(prefix); pw.println("  All partial wake locks:");
@@ -2287,7 +2415,7 @@ public abstract class BatteryStats implements Parcelable {
     * @param pw a Printer to receive the dump output.
     */
    @SuppressWarnings("unused")
    public void dumpLocked(PrintWriter pw, boolean isUnpluggedOnly, int reqUid) {
    public void dumpLocked(Context context, PrintWriter pw, boolean isUnpluggedOnly, int reqUid) {
        prepareForDumpLocked();

        long now = getHistoryBaseTime() + SystemClock.elapsedRealtime();
@@ -2344,15 +2472,15 @@ public abstract class BatteryStats implements Parcelable {
            pw.println("Statistics since last charge:");
            pw.println("  System starts: " + getStartCount()
                    + ", currently on battery: " + getIsOnBattery());
            dumpLocked(pw, "", STATS_SINCE_CHARGED, reqUid);
            dumpLocked(context, pw, "", STATS_SINCE_CHARGED, reqUid);
            pw.println("");
        }
        pw.println("Statistics since last unplugged:");
        dumpLocked(pw, "", STATS_SINCE_UNPLUGGED, reqUid);
        dumpLocked(context, pw, "", STATS_SINCE_UNPLUGGED, reqUid);
    }
    
    @SuppressWarnings("unused")
    public void dumpCheckinLocked(
    public void dumpCheckinLocked(Context context,
            PrintWriter pw, List<ApplicationInfo> apps, boolean isUnpluggedOnly,
            boolean includeHistory) {
        prepareForDumpLocked();
@@ -2400,11 +2528,11 @@ public abstract class BatteryStats implements Parcelable {
            }
        }
        if (isUnpluggedOnly) {
            dumpCheckinLocked(pw, STATS_SINCE_UNPLUGGED, -1);
            dumpCheckinLocked(context, pw, STATS_SINCE_UNPLUGGED, -1);
        }
        else {
            dumpCheckinLocked(pw, STATS_SINCE_CHARGED, -1);
            dumpCheckinLocked(pw, STATS_SINCE_UNPLUGGED, -1);
            dumpCheckinLocked(context, pw, STATS_SINCE_CHARGED, -1);
            dumpCheckinLocked(context, pw, STATS_SINCE_UNPLUGGED, -1);
        }
    }
}
+92 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.internal.os;

import android.os.BatteryStats.Uid;

/**
 * Contains power usage of an application, system service, or hardware type.
 */
public class BatterySipper implements Comparable<BatterySipper> {
    public int userId;
    public Uid uidObj;
    public double value;
    public double[] values;
    public DrainType drainType;
    public long usageTime;
    public long cpuTime;
    public long gpsTime;
    public long wifiRunningTime;
    public long cpuFgTime;
    public long wakeLockTime;
    public long mobileRxPackets;
    public long mobileTxPackets;
    public long wifiRxPackets;
    public long wifiTxPackets;
    public long mobileRxBytes;
    public long mobileTxBytes;
    public long wifiRxBytes;
    public long wifiTxBytes;
    public double percent;
    public double noCoveragePercent;
    public String[] mPackages;
    public String packageWithHighestDrain;

    public enum DrainType {
        IDLE,
        CELL,
        PHONE,
        WIFI,
        BLUETOOTH,
        SCREEN,
        APP,
        USER,
        UNACCOUNTED,
        OVERCOUNTED
    }

    public BatterySipper(DrainType drainType, Uid uid, double[] values) {
        this.values = values;
        if (values != null) value = values[0];
        this.drainType = drainType;
        uidObj = uid;
    }

    public double[] getValues() {
        return values;
    }

    @Override
    public int compareTo(BatterySipper other) {
        // Return the flipped value because we want the items in descending order
        return Double.compare(other.value, value);
    }

    /**
     * Gets a list of packages associated with the current user
     */
    public String[] getPackages() {
        return mPackages;
    }

    public int getUid() {
        // Bail out if the current sipper is not an App sipper.
        if (uidObj == null) {
            return 0;
        }
        return uidObj.getUid();
    }
}
+726 −0

File added.

Preview size limit exceeded, changes collapsed.

+12 −10
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import static com.android.server.NetworkManagementSocketTagger.PROP_QTAGUID_ENAB

import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkStats;
import android.os.BatteryManager;
@@ -4940,6 +4941,11 @@ public final class BatteryStatsImpl extends BatteryStats {
        }
    }

    public void pullPendingStateUpdatesLocked() {
        updateKernelWakelocksLocked();
        updateNetworkActivityLocked();
    }

    void setOnBatteryLocked(boolean onBattery, int oldStatus, int level) {
        boolean doWrite = false;
        Message m = mHandler.obtainMessage(MSG_REPORT_POWER_CHANGE);
@@ -4962,8 +4968,7 @@ public final class BatteryStatsImpl extends BatteryStats {
                resetAllStatsLocked();
                mDischargeStartLevel = level;
            }
            updateKernelWakelocksLocked();
            updateNetworkActivityLocked();
            pullPendingStateUpdatesLocked();
            mHistoryCur.batteryLevel = (byte)level;
            mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
            if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: "
@@ -4985,8 +4990,7 @@ public final class BatteryStatsImpl extends BatteryStats {
            mDischargeAmountScreenOff = 0;
            doUnplugLocked(realtime, mUnpluggedBatteryUptime, mUnpluggedBatteryRealtime);
        } else {
            updateKernelWakelocksLocked();
            updateNetworkActivityLocked();
            pullPendingStateUpdatesLocked();
            mHistoryCur.batteryLevel = (byte)level;
            mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
            if (DEBUG_HISTORY) Slog.v(TAG, "Battery plugged to: "
@@ -6282,8 +6286,7 @@ public final class BatteryStatsImpl extends BatteryStats {
    @SuppressWarnings("unused")
    void writeToParcelLocked(Parcel out, boolean inclUids, int flags) {
        // Need to update with current kernel wake lock counts.
        updateKernelWakelocksLocked();
        updateNetworkActivityLocked();
        pullPendingStateUpdatesLocked();

        final long uSecUptime = SystemClock.uptimeMillis() * 1000;
        final long uSecRealtime = SystemClock.elapsedRealtime() * 1000;
@@ -6388,11 +6391,10 @@ public final class BatteryStatsImpl extends BatteryStats {

    public void prepareForDumpLocked() {
        // Need to retrieve current kernel wake lock stats before printing.
        updateKernelWakelocksLocked();
        updateNetworkActivityLocked();
        pullPendingStateUpdatesLocked();
    }

    public void dumpLocked(PrintWriter pw, boolean isUnpluggedOnly, int reqUid) {
    public void dumpLocked(Context context, PrintWriter pw, boolean isUnpluggedOnly, int reqUid) {
        if (DEBUG) {
            Printer pr = new PrintWriterPrinter(pw);
            pr.println("*** Screen timer:");
@@ -6422,6 +6424,6 @@ public final class BatteryStatsImpl extends BatteryStats {
            pr.println("*** Bluetooth timer:");
            mBluetoothOnTimer.logState(pr, "  ");
        }
        super.dumpLocked(pw, isUnpluggedOnly, reqUid);
        super.dumpLocked(context, pw, isUnpluggedOnly, reqUid);
    }
}
+2 −2
Original line number Diff line number Diff line
@@ -568,11 +568,11 @@ public final class BatteryStatsService extends IBatteryStats.Stub {
        if (isCheckin) {
            List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications(0);
            synchronized (mStats) {
                mStats.dumpCheckinLocked(pw, apps, isUnpluggedOnly, includeHistory);
                mStats.dumpCheckinLocked(mContext, pw, apps, isUnpluggedOnly, includeHistory);
            }
        } else {
            synchronized (mStats) {
                mStats.dumpLocked(pw, isUnpluggedOnly, reqUid);
                mStats.dumpLocked(mContext, pw, isUnpluggedOnly, reqUid);
            }
        }
    }