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

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

Merge "Collect per-uid mobile radio usage."

parents a9499d70 d45665bf
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -506,6 +506,17 @@ public class NetworkStats implements Parcelable {
        return entry;
    }

    /**
     * Fast path for battery stats.
     */
    public long getTotalPackets() {
        long total = 0;
        for (int i = size-1; i >= 0; i--) {
            total += rxPackets[i] + txPackets[i];
        }
        return total;
    }

    /**
     * Subtract the given {@link NetworkStats}, effectively leaving the delta
     * between two snapshots in time. Assumes that statistics rows collect over
+114 −26
Original line number Diff line number Diff line
@@ -326,6 +326,8 @@ public abstract class BatteryStats implements Parcelable {
        public abstract boolean hasNetworkActivity();
        public abstract long getNetworkActivityBytes(int type, int which);
        public abstract long getNetworkActivityPackets(int type, int which);
        public abstract long getMobileRadioActiveTime(int which);
        public abstract int getMobileRadioActiveCount(int which);

        public static abstract class Sensor {
            /*
@@ -899,6 +901,28 @@ public abstract class BatteryStats implements Parcelable {
     */
    public abstract long getMobileRadioActiveTime(long batteryRealtime, int which);

    /**
     * Returns the number of times that the mobile network has transitioned to the
     * active state.
     *
     * {@hide}
     */
    public abstract int getMobileRadioActiveCount(int which);

    /**
     * Returns the time in microseconds that the mobile network has been active
     * (in a high power state) but not being able to blame on an app.
     *
     * {@hide}
     */
    public abstract long getMobileRadioActiveUnknownTime(int which);

    /**
     * Return count of number of times radio was app that could not be blamed on apps.
     *
     * {@hide}
     */
    public abstract int getMobileRadioActiveUnknownCount(int which);

    public static final int DATA_CONNECTION_NONE = 0;
    public static final int DATA_CONNECTION_GPRS = 1;
@@ -1238,6 +1262,13 @@ public abstract class BatteryStats implements Parcelable {
        sb.append("ms ");
    }

    private final static void formatTimeMsNoSpace(StringBuilder sb, long time) {
        long sec = time / 1000;
        formatTimeRaw(sb, sec);
        sb.append(time - (sec * 1000));
        sb.append("ms");
    }

    private final String formatRatioLocked(long num, long den) {
        if (den == 0L) {
            return "--%";
@@ -1590,6 +1621,8 @@ public abstract class BatteryStats implements Parcelable {
            long wifiBytesTx = u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
            long mobilePacketsRx = u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
            long mobilePacketsTx = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
            long mobileActiveTime = u.getMobileRadioActiveTime(which);
            int mobileActiveCount = u.getMobileRadioActiveCount(which);
            long wifiPacketsRx = u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
            long wifiPacketsTx = u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
            long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which);
@@ -1598,11 +1631,12 @@ public abstract class BatteryStats implements Parcelable {

            if (mobileBytesRx > 0 || mobileBytesTx > 0 || wifiBytesRx > 0 || wifiBytesTx > 0
                    || mobilePacketsRx > 0 || mobilePacketsTx > 0 || wifiPacketsRx > 0
                    || wifiPacketsTx > 0) {
                    || wifiPacketsTx > 0 || mobileActiveTime > 0 || mobileActiveCount > 0) {
                dumpLine(pw, uid, category, NETWORK_DATA, mobileBytesRx, mobileBytesTx,
                        wifiBytesRx, wifiBytesTx,
                        mobilePacketsRx, mobilePacketsTx,
                        wifiPacketsRx, wifiPacketsTx);
                        wifiPacketsRx, wifiPacketsTx,
                        mobileActiveTime, mobileActiveCount);
            }

            if (fullWifiLockOnTime != 0 || wifiScanTime != 0
@@ -1932,9 +1966,9 @@ public abstract class BatteryStats implements Parcelable {
                pw.print(", sent "); pw.print(wifiTxTotalPackets); pw.println(")");
        sb.setLength(0);
        sb.append(prefix);
                sb.append("  Total full wakelock time: "); formatTimeMs(sb,
                sb.append("  Total full wakelock time: "); formatTimeMsNoSpace(sb,
                        (fullWakeLockTimeTotalMicros + 500) / 1000);
                sb.append(", Total partial wakelock time: "); formatTimeMs(sb,
                sb.append(", Total partial wakelock time: "); formatTimeMsNoSpace(sb,
                        (partialWakeLockTimeTotalMicros + 500) / 1000);
        pw.println(sb.toString());
        
@@ -1964,7 +1998,7 @@ public abstract class BatteryStats implements Parcelable {
        sb.setLength(0);
        sb.append(prefix);
        sb.append("  Signal scanning time: ");
        formatTimeMs(sb, getPhoneSignalScanningTime(batteryRealtime, which) / 1000);
        formatTimeMsNoSpace(sb, getPhoneSignalScanningTime(batteryRealtime, which) / 1000);
        pw.println(sb.toString());

        sb.setLength(0);
@@ -1993,8 +2027,25 @@ public abstract class BatteryStats implements Parcelable {
        sb.setLength(0);
        sb.append(prefix);
        sb.append("  Mobile radio active time: ");
        formatTimeMs(sb, getMobileRadioActiveTime(batteryRealtime, which) / 1000);
        final long mobileActiveTime = getMobileRadioActiveTime(batteryRealtime, which);
        formatTimeMs(sb, mobileActiveTime / 1000);
        sb.append("("); sb.append(formatRatioLocked(mobileActiveTime, whichBatteryRealtime));
        sb.append(") "); sb.append(getMobileRadioActiveCount(which));
        sb.append("x");
        pw.println(sb.toString());

        final long mobileActiveUnknownTime = getMobileRadioActiveUnknownTime(which);
        if (mobileActiveUnknownTime != 0) {
            sb.setLength(0);
            sb.append(prefix);
            sb.append("  Mobile radio active unknown time: ");
            formatTimeMs(sb, mobileActiveUnknownTime / 1000);
            sb.append("(");
            sb.append(formatRatioLocked(mobileActiveUnknownTime, whichBatteryRealtime));
            sb.append(") "); sb.append(getMobileRadioActiveUnknownCount(which));
            sb.append("x");
            pw.println(sb.toString());
        }

        sb.setLength(0);
        sb.append(prefix);
@@ -2132,7 +2183,8 @@ public abstract class BatteryStats implements Parcelable {
                        pw.println();
                        break;
                    case APP:
                        pw.print(prefix); pw.print("    Uid "); pw.print(bs.uidObj.getUid());
                        pw.print(prefix); pw.print("    Uid ");
                        UserHandle.formatUid(pw, bs.uidObj.getUid());
                        pw.print(": "); printmAh(pw, bs.value); pw.println();
                        break;
                    case USER:
@@ -2152,6 +2204,23 @@ public abstract class BatteryStats implements Parcelable {
            pw.println();
        }

        sippers = helper.getMobilemsppList();
        if (sippers != null && sippers.size() > 0) {
            pw.print(prefix); pw.println("  Per-app mobile ms per packet:");
            for (int i=0; i<sippers.size(); i++) {
                BatterySipper bs = sippers.get(i);
                sb.setLength(0);
                sb.append(prefix); sb.append("    Uid ");
                UserHandle.formatUid(sb, bs.uidObj.getUid());
                sb.append(": "); sb.append(BatteryStatsHelper.makemAh(bs.mobilemspp));
                sb.append(" ("); sb.append(bs.mobileRxPackets+bs.mobileTxPackets);
                sb.append(" packets over "); formatTimeMsNoSpace(sb, bs.mobileActive);
                sb.append(")");
                pw.println(sb.toString());
            }
            pw.println();
        }

        if (timers.size() > 0) {
            Collections.sort(timers, timerComparator);
            pw.print(prefix); pw.println("  All partial wake locks:");
@@ -2190,6 +2259,8 @@ public abstract class BatteryStats implements Parcelable {
            long wifiTxBytes = u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
            long mobileRxPackets = u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
            long mobileTxPackets = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
            long uidMobileActiveTime = u.getMobileRadioActiveTime(which);
            int uidMobileActiveCount = u.getMobileRadioActiveCount(which);
            long wifiRxPackets = u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
            long wifiTxPackets = u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
            long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which);
@@ -2204,6 +2275,23 @@ public abstract class BatteryStats implements Parcelable {
                        pw.print(" sent (packets "); pw.print(mobileRxPackets);
                        pw.print(" received, "); pw.print(mobileTxPackets); pw.println(" sent)");
            }
            if (uidMobileActiveTime > 0 || uidMobileActiveCount > 0) {
                sb.setLength(0);
                sb.append(prefix); sb.append("    Mobile radio active: ");
                formatTimeMs(sb, uidMobileActiveTime / 1000);
                sb.append("(");
                sb.append(formatRatioLocked(uidMobileActiveTime, mobileActiveTime));
                sb.append(") "); sb.append(uidMobileActiveCount); sb.append("x");
                long packets = mobileRxPackets + mobileTxPackets;
                if (packets == 0) {
                    packets = 1;
                }
                sb.append(" @ ");
                sb.append(BatteryStatsHelper.makemAh(uidMobileActiveTime / 1000 / (double)packets));
                sb.append(" mspp");
                pw.println(sb.toString());
            }

            if (wifiRxBytes > 0 || wifiTxBytes > 0 || wifiRxPackets > 0 || wifiTxPackets > 0) {
                pw.print(prefix); pw.print("    Wi-Fi network: ");
                        pw.print(formatBytesLocked(wifiRxBytes)); pw.print(" received, ");
@@ -2212,6 +2300,24 @@ public abstract class BatteryStats implements Parcelable {
                        pw.print(" received, "); pw.print(wifiTxPackets); pw.println(" sent)");
            }

            if (fullWifiLockOnTime != 0 || wifiScanTime != 0
                    || uidWifiRunningTime != 0) {
                sb.setLength(0);
                sb.append(prefix); sb.append("    Wifi Running: ");
                        formatTimeMs(sb, uidWifiRunningTime / 1000);
                        sb.append("("); sb.append(formatRatioLocked(uidWifiRunningTime,
                                whichBatteryRealtime)); sb.append(")\n");
                sb.append(prefix); sb.append("    Full Wifi Lock: "); 
                        formatTimeMs(sb, fullWifiLockOnTime / 1000);
                        sb.append("("); sb.append(formatRatioLocked(fullWifiLockOnTime,
                                whichBatteryRealtime)); sb.append(")\n");
                sb.append(prefix); sb.append("    Wifi Scan: ");
                        formatTimeMs(sb, wifiScanTime / 1000);
                        sb.append("("); sb.append(formatRatioLocked(wifiScanTime,
                                whichBatteryRealtime)); sb.append(")");
                pw.println(sb.toString());
            }

            if (u.hasUserActivity()) {
                boolean hasData = false;
                for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
@@ -2234,24 +2340,6 @@ public abstract class BatteryStats implements Parcelable {
                }
            }

            if (fullWifiLockOnTime != 0 || wifiScanTime != 0
                    || uidWifiRunningTime != 0) {
                sb.setLength(0);
                sb.append(prefix); sb.append("    Wifi Running: ");
                        formatTimeMs(sb, uidWifiRunningTime / 1000);
                        sb.append("("); sb.append(formatRatioLocked(uidWifiRunningTime,
                                whichBatteryRealtime)); sb.append(")\n");
                sb.append(prefix); sb.append("    Full Wifi Lock: "); 
                        formatTimeMs(sb, fullWifiLockOnTime / 1000);
                        sb.append("("); sb.append(formatRatioLocked(fullWifiLockOnTime,
                                whichBatteryRealtime)); sb.append(")\n");
                sb.append(prefix); sb.append("    Wifi Scan: ");
                        formatTimeMs(sb, wifiScanTime / 1000);
                        sb.append("("); sb.append(formatRatioLocked(wifiScanTime,
                                whichBatteryRealtime)); sb.append(")");
                pw.println(sb.toString());
            }

            Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
            if (wakelocks.size() > 0) {
                long totalFull = 0, totalPartial = 0, totalWindow = 0;
+7 −0
Original line number Diff line number Diff line
@@ -34,6 +34,8 @@ public class BatterySipper implements Comparable<BatterySipper> {
    public long wakeLockTime;
    public long mobileRxPackets;
    public long mobileTxPackets;
    public long mobileActive;
    public double mobilemspp;         // milliseconds per packet
    public long wifiRxPackets;
    public long wifiTxPackets;
    public long mobileRxBytes;
@@ -69,6 +71,11 @@ public class BatterySipper implements Comparable<BatterySipper> {
        return values;
    }

    public void computeMobilemspp() {
        long packets = mobileRxPackets+mobileTxPackets;
        mobilemspp = packets > 0 ? (mobileActive / (double)packets) : 0;
    }

    @Override
    public int compareTo(BatterySipper other) {
        // Return the flipped value because we want the items in descending order
+75 −4
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ import com.android.internal.os.BatterySipper.DrainType;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;

@@ -73,6 +74,8 @@ public class BatteryStatsHelper {
            = new SparseArray<List<BatterySipper>>();
    private final SparseArray<Double> mUserPower = new SparseArray<Double>();

    private final List<BatterySipper> mMobilemsppList = new ArrayList<BatterySipper>();

    private int mStatsType = BatteryStats.STATS_SINCE_CHARGED;
    private int mAsUser = 0;

@@ -90,6 +93,9 @@ public class BatteryStatsHelper {
    private double mMinDrainedPower;
    private double mMaxDrainedPower;

    // How much the apps together have kept the mobile radio active.
    private long mAppMobileActive;

    // How much the apps together have left WIFI running.
    private long mAppWifiRunning;

@@ -132,7 +138,7 @@ public class BatteryStatsHelper {
    }

    public static String makemAh(double power) {
        if (power < .0001) return String.format("%.8f", power);
        if (power < .00001) return String.format("%.8f", power);
        else if (power < .0001) return String.format("%.7f", power);
        else if (power < .001) return String.format("%.6f", power);
        else if (power < .01) return String.format("%.5f", power);
@@ -160,6 +166,7 @@ public class BatteryStatsHelper {
        mTotalPower = 0;
        mWifiPower = 0;
        mBluetoothPower = 0;
        mAppMobileActive = 0;
        mAppWifiRunning = 0;

        mUsageList.clear();
@@ -167,6 +174,7 @@ public class BatteryStatsHelper {
        mBluetoothSippers.clear();
        mUserSippers.clear();
        mUserPower.clear();
        mMobilemsppList.clear();

        if (mStats == null) {
            return;
@@ -193,6 +201,37 @@ public class BatteryStatsHelper {
                * mPowerProfile.getBatteryCapacity()) / 100;

        processAppUsage();

        // Before aggregating apps in to users, collect all apps to sort by their ms per packet.
        for (int i=0; i<mUsageList.size(); i++) {
            BatterySipper bs = mUsageList.get(i);
            bs.computeMobilemspp();
            if (bs.mobilemspp != 0) {
                mMobilemsppList.add(bs);
            }
        }
        for (int i=0; i<mUserSippers.size(); i++) {
            List<BatterySipper> user = mUserSippers.valueAt(i);
            for (int j=0; j<user.size(); j++) {
                BatterySipper bs = user.get(j);
                bs.computeMobilemspp();
                if (bs.mobilemspp != 0) {
                    mMobilemsppList.add(bs);
                }
            }
        }
        Collections.sort(mMobilemsppList, new Comparator<BatterySipper>() {
            @Override
            public int compare(BatterySipper lhs, BatterySipper rhs) {
                if (lhs.mobilemspp < rhs.mobilemspp) {
                    return 1;
                } else if (lhs.mobilemspp > rhs.mobilemspp) {
                    return -1;
                }
                return 0;
            }
        });

        processMiscUsage();

        if (DEBUG) {
@@ -225,6 +264,7 @@ public class BatteryStatsHelper {
            powerCpuNormal[p] = mPowerProfile.getAveragePower(PowerProfile.POWER_CPU_ACTIVE, p);
        }
        final double mobilePowerPerPacket = getMobilePowerPerPacket();
        final double mobilePowerPerMs = getMobilePowerPerMs();
        final double wifiPowerPerPacket = getWifiPowerPerPacket();
        long appWakelockTime = 0;
        BatterySipper osApp = null;
@@ -320,9 +360,20 @@ public class BatteryStatsHelper {
            final long mobileTx = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, mStatsType);
            final long mobileRxB = u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, mStatsType);
            final long mobileTxB = u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, mStatsType);
            final long mobileActive = u.getMobileRadioActiveTime(mStatsType);
            if (mobileActive > 0) {
                // We are tracking when the radio is up, so can use the active time to
                // determine power use.
                mAppMobileActive += mobileActive;
                p = (mobilePowerPerMs * mobileActive) / 1000;
            } else {
                // We are not tracking when the radio is up, so must approximate power use
                // based on the number of packets.
                p = (mobileRx + mobileTx) * mobilePowerPerPacket;
            }
            if (DEBUG && p != 0) Log.d(TAG, "UID " + u.getUid() + ": mobile packets "
                    + (mobileRx+mobileTx) + " power=" + makemAh(p));
                    + (mobileRx+mobileTx) + " active time " + mobileActive
                    + " power=" + makemAh(p));
            power += p;

            // Add cost of wifi traffic
@@ -406,6 +457,7 @@ public class BatteryStatsHelper {
                app.wakeLockTime = wakelockTime;
                app.mobileRxPackets = mobileRx;
                app.mobileTxPackets = mobileTx;
                app.mobileActive = mobileActive / 1000;
                app.wifiRxPackets = wifiRx;
                app.wifiTxPackets = wifiTx;
                app.mobileRxBytes = mobileRxB;
@@ -474,7 +526,7 @@ public class BatteryStatsHelper {
        double phoneOnPower = mPowerProfile.getAveragePower(PowerProfile.POWER_RADIO_ACTIVE)
                * phoneOnTimeMs / (60*60*1000);
        if (phoneOnPower != 0) {
            addEntry(BatterySipper.DrainType.PHONE, phoneOnTimeMs, phoneOnPower);
            BatterySipper bs = addEntry(BatterySipper.DrainType.PHONE, phoneOnTimeMs, phoneOnPower);
        }
    }

@@ -531,12 +583,18 @@ public class BatteryStatsHelper {
            Log.d(TAG, "Cell radio scanning: time=" + scanningTimeMs + " power=" + makemAh(p));
        }
        power += p;
        long radioActiveTimeUs = mStats.getMobileRadioActiveTime(mBatteryRealtime, mStatsType);
        long remainingActiveTime = (radioActiveTimeUs - mAppMobileActive) / 1000;
        if (remainingActiveTime > 0) {
            power += getMobilePowerPerMs() * remainingActiveTime;
        }
        if (power != 0) {
            BatterySipper bs =
                    addEntry(BatterySipper.DrainType.CELL, signalTimeMs, power);
            if (signalTimeMs != 0) {
                bs.noCoveragePercent = noCoverageTimeMs * 100.0 / signalTimeMs;
            }
            bs.mobileActive = remainingActiveTime;
        }
    }

@@ -551,6 +609,7 @@ public class BatteryStatsHelper {
            bs.wakeLockTime += wbs.wakeLockTime;
            bs.mobileRxPackets += wbs.mobileRxPackets;
            bs.mobileTxPackets += wbs.mobileTxPackets;
            bs.mobileActive += wbs.mobileActive;
            bs.wifiRxPackets += wbs.wifiRxPackets;
            bs.wifiTxPackets += wbs.wifiTxPackets;
            bs.mobileRxBytes += wbs.mobileRxBytes;
@@ -558,6 +617,7 @@ public class BatteryStatsHelper {
            bs.wifiRxBytes += wbs.wifiRxBytes;
            bs.wifiTxBytes += wbs.wifiTxBytes;
        }
        bs.computeMobilemspp();
    }

    private void addWiFiUsage() {
@@ -649,6 +709,13 @@ public class BatteryStatsHelper {
        return (MOBILE_POWER / mobilePps) / (60*60);
    }

    /**
     * Return estimated power (in mAs) of keeping the radio up
     */
    private double getMobilePowerPerMs() {
        return mPowerProfile.getAveragePower(PowerProfile.POWER_RADIO_ACTIVE) / (60*60*1000);
    }

    /**
     * Return estimated power (in mAs) of sending a byte with the Wi-Fi radio.
     */
@@ -691,6 +758,10 @@ public class BatteryStatsHelper {
        return mUsageList;
    }

    public List<BatterySipper> getMobilemsppList() {
        return mMobilemsppList;
    }

    public long getStatsPeriod() { return mStatsPeriod; }

    public int getStatsType() { return mStatsType; };
+126 −18

File changed.

Preview size limit exceeded, changes collapsed.

Loading