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

Commit 22e95c60 authored by Dianne Hackborn's avatar Dianne Hackborn Committed by Android Git Automerger
Browse files

am c8345b32: Merge "Add battery power use reporting to batterystats service."

* commit 'c8345b32':
  Add battery power use reporting to batterystats service.
parents ffe58881 c8345b32
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);
            }
        }
    }