diff options
| author | 2013-06-04 12:29:00 -0700 | |
|---|---|---|
| committer | 2013-06-06 14:35:34 -0700 | |
| commit | 7a1c3fce478122b9f03464117dc94d44f7c1995e (patch) | |
| tree | e7496e9b8041c361eb9201d139e05f9c00975796 | |
| parent | 34bff87b32a10f6267e76a7de0b287eb6a4633f9 (diff) | |
Accumulate network statistics based on deltas.
Network stats are now read out of the kernel in one sweep, instead of
reading per-UID. We now accumulate the delta traffic between each
stats snapshot using the well-tested SamplingCounter pattern.
Since Wi-Fi and mobile traffic have different costs, track each
separately. Avoids counting misc interfaces like loopback and
ethernet under total.
Bug: 5543387
Change-Id: I642004dc530113c27ef79f2abbae51d8af30117f
6 files changed, 365 insertions, 286 deletions
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 78bf9afcbb40..ffcc2974cd0d 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -464,6 +464,21 @@ public class ConnectivityManager { } /** + * Checks if the given network type is backed by a Wi-Fi radio. + * + * @hide + */ + public static boolean isNetworkTypeWifi(int networkType) { + switch (networkType) { + case TYPE_WIFI: + case TYPE_WIFI_P2P: + return true; + default: + return false; + } + } + + /** * Specifies the preferred network type. When the device has more * than one type available the preferred network type will be used. * Note that this made sense when we only had 2 network types, diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index d0f75116a131..32bbfbd3c609 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -130,7 +130,7 @@ public abstract class BatteryStats implements Parcelable { /** * Bump the version on this if the checkin format changes. */ - private static final int BATTERY_STATS_CHECKIN_VERSION = 6; + private static final int BATTERY_STATS_CHECKIN_VERSION = 7; private static final long BYTES_PER_KB = 1024; private static final long BYTES_PER_MB = 1048576; // 1024^2 @@ -259,17 +259,7 @@ public abstract class BatteryStats implements Parcelable { * {@hide} */ public abstract int getUid(); - - /** - * {@hide} - */ - public abstract long getTcpBytesReceived(int which); - - /** - * {@hide} - */ - public abstract long getTcpBytesSent(int which); - + public abstract void noteWifiRunningLocked(); public abstract void noteWifiStoppedLocked(); public abstract void noteFullWifiLockAcquiredLocked(); @@ -304,11 +294,14 @@ public abstract class BatteryStats implements Parcelable { }; public static final int NUM_USER_ACTIVITY_TYPES = 3; - + public abstract void noteUserActivityLocked(int type); public abstract boolean hasUserActivity(); public abstract int getUserActivityCount(int type, int which); - + + public abstract boolean hasNetworkActivity(); + public abstract long getNetworkActivityCount(int type, int which); + public static abstract class Sensor { /* * FIXME: it's not correct to use this magic value because it @@ -929,6 +922,15 @@ public abstract class BatteryStats implements Parcelable { */ public abstract long getBluetoothOnTime(long batteryRealtime, int which); + public static final int NETWORK_MOBILE_RX_BYTES = 0; + public static final int NETWORK_MOBILE_TX_BYTES = 1; + public static final int NETWORK_WIFI_RX_BYTES = 2; + public static final int NETWORK_WIFI_TX_BYTES = 3; + + public static final int NUM_NETWORK_ACTIVITY_TYPES = NETWORK_WIFI_TX_BYTES + 1; + + public abstract long getNetworkActivityCount(int type, int which); + /** * Return whether we are currently running on battery. */ @@ -1246,16 +1248,20 @@ public abstract class BatteryStats implements Parcelable { totalRealtime / 1000, totalUptime / 1000); // Calculate total network and wakelock times across all uids. - long rxTotal = 0; - long txTotal = 0; + long mobileRxTotal = 0; + long mobileTxTotal = 0; + long wifiRxTotal = 0; + long wifiTxTotal = 0; long fullWakeLockTimeTotal = 0; long partialWakeLockTimeTotal = 0; for (int iu = 0; iu < NU; iu++) { Uid u = uidStats.valueAt(iu); - rxTotal += u.getTcpBytesReceived(which); - txTotal += u.getTcpBytesSent(which); - + mobileRxTotal += u.getNetworkActivityCount(NETWORK_MOBILE_RX_BYTES, which); + mobileTxTotal += u.getNetworkActivityCount(NETWORK_MOBILE_TX_BYTES, which); + wifiRxTotal += u.getNetworkActivityCount(NETWORK_WIFI_RX_BYTES, which); + wifiTxTotal += u.getNetworkActivityCount(NETWORK_WIFI_TX_BYTES, which); + Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats(); if (wakelocks.size() > 0) { for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent @@ -1279,7 +1285,8 @@ public abstract class BatteryStats implements Parcelable { // Dump misc stats dumpLine(pw, 0 /* uid */, category, MISC_DATA, screenOnTime / 1000, phoneOnTime / 1000, wifiOnTime / 1000, - wifiRunningTime / 1000, bluetoothOnTime / 1000, rxTotal, txTotal, + wifiRunningTime / 1000, bluetoothOnTime / 1000, + mobileRxTotal, mobileTxTotal, wifiRxTotal, wifiTxTotal, fullWakeLockTimeTotal, partialWakeLockTimeTotal, getInputEventCount(which)); @@ -1350,14 +1357,18 @@ public abstract class BatteryStats implements Parcelable { } Uid u = uidStats.valueAt(iu); // Dump Network stats per uid, if any - long rx = u.getTcpBytesReceived(which); - long tx = u.getTcpBytesSent(which); + long mobileRx = u.getNetworkActivityCount(NETWORK_MOBILE_RX_BYTES, which); + long mobileTx = u.getNetworkActivityCount(NETWORK_MOBILE_TX_BYTES, which); + long wifiRx = u.getNetworkActivityCount(NETWORK_WIFI_RX_BYTES, which); + long wifiTx = u.getNetworkActivityCount(NETWORK_WIFI_TX_BYTES, which); long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which); long wifiScanTime = u.getWifiScanTime(batteryRealtime, which); long uidWifiRunningTime = u.getWifiRunningTime(batteryRealtime, which); - - if (rx > 0 || tx > 0) dumpLine(pw, uid, category, NETWORK_DATA, rx, tx); - + + if (mobileRx > 0 || mobileTx > 0 || wifiRx > 0 || wifiTx > 0) { + dumpLine(pw, uid, category, NETWORK_DATA, mobileRx, mobileTx, wifiRx, wifiTx); + } + if (fullWifiLockOnTime != 0 || wifiScanTime != 0 || uidWifiRunningTime != 0) { dumpLine(pw, uid, category, WIFI_DATA, @@ -1569,8 +1580,10 @@ public abstract class BatteryStats implements Parcelable { pw.println(sb.toString()); // Calculate total network and wakelock times across all uids. - long rxTotal = 0; - long txTotal = 0; + long mobileRxTotal = 0; + long mobileTxTotal = 0; + long wifiRxTotal = 0; + long wifiTxTotal = 0; long fullWakeLockTimeTotalMicros = 0; long partialWakeLockTimeTotalMicros = 0; @@ -1623,9 +1636,11 @@ public abstract class BatteryStats implements Parcelable { for (int iu = 0; iu < NU; iu++) { Uid u = uidStats.valueAt(iu); - rxTotal += u.getTcpBytesReceived(which); - txTotal += u.getTcpBytesSent(which); - + mobileRxTotal += u.getNetworkActivityCount(NETWORK_MOBILE_RX_BYTES, which); + mobileTxTotal += u.getNetworkActivityCount(NETWORK_MOBILE_TX_BYTES, which); + wifiRxTotal += u.getNetworkActivityCount(NETWORK_WIFI_RX_BYTES, which); + wifiTxTotal += u.getNetworkActivityCount(NETWORK_WIFI_TX_BYTES, which); + Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats(); if (wakelocks.size() > 0) { for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent @@ -1658,8 +1673,11 @@ public abstract class BatteryStats implements Parcelable { } pw.print(prefix); - pw.print(" Total received: "); pw.print(formatBytesLocked(rxTotal)); - pw.print(", Total sent: "); pw.println(formatBytesLocked(txTotal)); + pw.print(" Mobile total received: "); pw.print(formatBytesLocked(mobileRxTotal)); + pw.print(", Total sent: "); pw.println(formatBytesLocked(mobileTxTotal)); + pw.print(prefix); + pw.print(" Wi-Fi total received: "); pw.print(formatBytesLocked(wifiRxTotal)); + pw.print(", Total sent: "); pw.println(formatBytesLocked(wifiTxTotal)); sb.setLength(0); sb.append(prefix); sb.append(" Total full wakelock time: "); formatTimeMs(sb, @@ -1801,18 +1819,25 @@ public abstract class BatteryStats implements Parcelable { pw.println(prefix + " #" + uid + ":"); boolean uidActivity = false; - long tcpReceived = u.getTcpBytesReceived(which); - long tcpSent = u.getTcpBytesSent(which); + long mobileRxBytes = u.getNetworkActivityCount(NETWORK_MOBILE_RX_BYTES, which); + long mobileTxBytes = u.getNetworkActivityCount(NETWORK_MOBILE_TX_BYTES, which); + long wifiRxBytes = u.getNetworkActivityCount(NETWORK_WIFI_RX_BYTES, which); + long wifiTxBytes = u.getNetworkActivityCount(NETWORK_WIFI_TX_BYTES, which); long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which); long wifiScanTime = u.getWifiScanTime(batteryRealtime, which); long uidWifiRunningTime = u.getWifiRunningTime(batteryRealtime, which); - - if (tcpReceived != 0 || tcpSent != 0) { - pw.print(prefix); pw.print(" Network: "); - pw.print(formatBytesLocked(tcpReceived)); pw.print(" received, "); - pw.print(formatBytesLocked(tcpSent)); pw.println(" sent"); + + if (mobileRxBytes > 0 || mobileTxBytes > 0) { + pw.print(prefix); pw.print(" Mobile network: "); + pw.print(formatBytesLocked(mobileRxBytes)); pw.print(" received, "); + pw.print(formatBytesLocked(mobileTxBytes)); pw.println(" sent"); } - + if (wifiRxBytes > 0 || wifiTxBytes > 0) { + pw.print(prefix); pw.print(" Wi-Fi network: "); + pw.print(formatBytesLocked(wifiRxBytes)); pw.print(" received, "); + pw.print(formatBytesLocked(wifiTxBytes)); pw.println(" sent"); + } + if (u.hasUserActivity()) { boolean hasData = false; for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl index 823e19f21100..525517c00eb5 100644 --- a/core/java/com/android/internal/app/IBatteryStats.aidl +++ b/core/java/com/android/internal/app/IBatteryStats.aidl @@ -71,6 +71,7 @@ interface IBatteryStats { void noteWifiMulticastEnabledFromSource(in WorkSource ws); void noteWifiMulticastDisabledFromSource(in WorkSource ws); void noteNetworkInterfaceType(String iface, int type); + void noteNetworkStatsEnabled(); void setBatteryState(int status, int health, int plugType, int level, int temp, int volt); long getAwakeTimeBattery(); long getAwakeTimePlugged(); diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 601d3ac4bb71..38a8c19801f9 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -16,7 +16,6 @@ package com.android.internal.os; -import static android.text.format.DateUtils.SECOND_IN_MILLIS; import static com.android.server.NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED; import android.bluetooth.BluetoothDevice; @@ -46,6 +45,7 @@ import android.util.Slog; import android.util.SparseArray; import android.util.TimeUtils; +import com.android.internal.annotations.GuardedBy; import com.android.internal.net.NetworkStatsFactory; import com.android.internal.util.JournaledFile; import com.google.android.collect.Sets; @@ -83,7 +83,7 @@ public final class BatteryStatsImpl extends BatteryStats { private static final int MAGIC = 0xBA757475; // 'BATSTATS' // Current on-disk Parcel version - private static final int VERSION = 65 + (USE_OLD_HISTORY ? 1000 : 0); + private static final int VERSION = 66 + (USE_OLD_HISTORY ? 1000 : 0); // Maximum number of items we will record in the history. private static final int MAX_HISTORY_ITEMS = 2000; @@ -231,6 +231,9 @@ public final class BatteryStatsImpl extends BatteryStats { final StopwatchTimer[] mPhoneDataConnectionsTimer = new StopwatchTimer[NUM_DATA_CONNECTION_TYPES]; + final LongSamplingCounter[] mNetworkActivityCounters = + new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; + boolean mWifiOn; StopwatchTimer mWifiOnTimer; int mWifiOnUid = -1; @@ -275,12 +278,6 @@ public final class BatteryStatsImpl extends BatteryStats { long mLastWriteTime = 0; // Milliseconds - // Mobile data transferred while on battery - private long[] mMobileDataTx = new long[4]; - private long[] mMobileDataRx = new long[4]; - private long[] mTotalDataTx = new long[4]; - private long[] mTotalDataRx = new long[4]; - private long mRadioDataUptime; private long mRadioDataStart; @@ -337,9 +334,12 @@ public final class BatteryStatsImpl extends BatteryStats { private HashMap<String, Integer> mUidCache = new HashMap<String, Integer>(); private final NetworkStatsFactory mNetworkStatsFactory = new NetworkStatsFactory(); + private NetworkStats mLastSnapshot; - /** Network ifaces that {@link ConnectivityManager} has claimed as mobile. */ + @GuardedBy("this") private HashSet<String> mMobileIfaces = Sets.newHashSet(); + @GuardedBy("this") + private HashSet<String> mWifiIfaces = Sets.newHashSet(); // For debugging public BatteryStatsImpl() { @@ -466,7 +466,6 @@ public final class BatteryStatsImpl extends BatteryStats { } public static class SamplingCounter extends Counter { - SamplingCounter(ArrayList<Unpluggable> unpluggables, Parcel in) { super(unpluggables, in); } @@ -480,6 +479,93 @@ public final class BatteryStatsImpl extends BatteryStats { } } + public static class LongSamplingCounter implements Unpluggable { + final ArrayList<Unpluggable> mUnpluggables; + long mCount; + long mLoadedCount; + long mLastCount; + long mUnpluggedCount; + long mPluggedCount; + + LongSamplingCounter(ArrayList<Unpluggable> unpluggables, Parcel in) { + mUnpluggables = unpluggables; + mPluggedCount = in.readLong(); + mCount = mPluggedCount; + mLoadedCount = in.readLong(); + mLastCount = 0; + mUnpluggedCount = in.readLong(); + unpluggables.add(this); + } + + LongSamplingCounter(ArrayList<Unpluggable> unpluggables) { + mUnpluggables = unpluggables; + unpluggables.add(this); + } + + public void writeToParcel(Parcel out) { + out.writeLong(mCount); + out.writeLong(mLoadedCount); + out.writeLong(mUnpluggedCount); + } + + @Override + public void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime) { + mUnpluggedCount = mPluggedCount; + mCount = mPluggedCount; + } + + @Override + public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) { + mPluggedCount = mCount; + } + + public long getCountLocked(int which) { + long val; + if (which == STATS_LAST) { + val = mLastCount; + } else { + val = mCount; + if (which == STATS_SINCE_UNPLUGGED) { + val -= mUnpluggedCount; + } else if (which != STATS_SINCE_CHARGED) { + val -= mLoadedCount; + } + } + + return val; + } + + void addCountLocked(long count) { + mCount += count; + } + + /** + * Clear state of this counter. + */ + void reset(boolean detachIfReset) { + mCount = 0; + mLoadedCount = mLastCount = mPluggedCount = mUnpluggedCount = 0; + if (detachIfReset) { + detach(); + } + } + + void detach() { + mUnpluggables.remove(this); + } + + void writeSummaryFromParcelLocked(Parcel out) { + out.writeLong(mCount); + } + + void readSummaryFromParcelLocked(Parcel in) { + mLoadedCount = in.readLong(); + mCount = mLoadedCount; + mLastCount = 0; + mUnpluggedCount = mPluggedCount = mLoadedCount; + } + } + /** * State for keeping track of timing information. */ @@ -1316,15 +1402,6 @@ public final class BatteryStatsImpl extends BatteryStats { return kwlt; } - private void doDataPlug(long[] dataTransfer, long currentBytes) { - dataTransfer[STATS_LAST] = dataTransfer[STATS_SINCE_UNPLUGGED]; - dataTransfer[STATS_SINCE_UNPLUGGED] = -1; - } - - private void doDataUnplug(long[] dataTransfer, long currentBytes) { - dataTransfer[STATS_SINCE_UNPLUGGED] = currentBytes; - } - /** * Radio uptime in microseconds when transferring data. This value is very approximate. * @return @@ -1571,34 +1648,10 @@ public final class BatteryStatsImpl extends BatteryStats { } public void doUnplugLocked(long elapsedRealtime, long batteryUptime, long batteryRealtime) { - NetworkStats.Entry entry = null; - - // Track UID data usage - final NetworkStats uidStats = getNetworkStatsDetailGroupedByUid(); - final int size = uidStats.size(); - for (int i = 0; i < size; i++) { - entry = uidStats.getValues(i, entry); - - final Uid u = getUidStatsLocked(entry.uid); - u.mStartedTcpBytesReceived = entry.rxBytes; - u.mStartedTcpBytesSent = entry.txBytes; - u.mTcpBytesReceivedAtLastUnplug = u.mCurrentTcpBytesReceived; - u.mTcpBytesSentAtLastUnplug = u.mCurrentTcpBytesSent; - } - for (int i = mUnpluggables.size() - 1; i >= 0; i--) { mUnpluggables.get(i).unplug(elapsedRealtime, batteryUptime, batteryRealtime); } - // Track both mobile and total overall data - final NetworkStats ifaceStats = getNetworkStatsSummary(); - entry = ifaceStats.getTotal(entry, mMobileIfaces); - doDataUnplug(mMobileDataRx, entry.rxBytes); - doDataUnplug(mMobileDataTx, entry.txBytes); - entry = ifaceStats.getTotal(entry); - doDataUnplug(mTotalDataRx, entry.rxBytes); - doDataUnplug(mTotalDataTx, entry.txBytes); - // Track radio awake time mRadioDataStart = getCurrentRadioDataUptime(); mRadioDataUptime = 0; @@ -1609,32 +1662,10 @@ public final class BatteryStatsImpl extends BatteryStats { } public void doPlugLocked(long elapsedRealtime, long batteryUptime, long batteryRealtime) { - NetworkStats.Entry entry = null; - - for (int iu = mUidStats.size() - 1; iu >= 0; iu--) { - Uid u = mUidStats.valueAt(iu); - if (u.mStartedTcpBytesReceived >= 0) { - u.mCurrentTcpBytesReceived = u.computeCurrentTcpBytesReceived(); - u.mStartedTcpBytesReceived = -1; - } - if (u.mStartedTcpBytesSent >= 0) { - u.mCurrentTcpBytesSent = u.computeCurrentTcpBytesSent(); - u.mStartedTcpBytesSent = -1; - } - } for (int i = mUnpluggables.size() - 1; i >= 0; i--) { mUnpluggables.get(i).plug(elapsedRealtime, batteryUptime, batteryRealtime); } - // Track both mobile and total overall data - final NetworkStats ifaceStats = getNetworkStatsSummary(); - entry = ifaceStats.getTotal(entry, mMobileIfaces); - doDataPlug(mMobileDataRx, entry.rxBytes); - doDataPlug(mMobileDataTx, entry.txBytes); - entry = ifaceStats.getTotal(entry); - doDataPlug(mTotalDataRx, entry.rxBytes); - doDataPlug(mTotalDataTx, entry.txBytes); - // Track radio awake time mRadioDataUptime = getRadioDataUptime(); mRadioDataStart = -1; @@ -2441,6 +2472,18 @@ public final class BatteryStatsImpl extends BatteryStats { } else { mMobileIfaces.remove(iface); } + if (ConnectivityManager.isNetworkTypeWifi(networkType)) { + mWifiIfaces.add(iface); + } else { + mWifiIfaces.remove(iface); + } + } + + public void noteNetworkStatsEnabledLocked() { + // During device boot, qtaguid isn't enabled until after the inital + // loading of battery stats. Now that they're enabled, take our initial + // snapshot for future delta calculation. + updateNetworkActivityLocked(); } @Override public long getScreenOnTime(long batteryRealtime, int which) { @@ -2499,6 +2542,15 @@ public final class BatteryStatsImpl extends BatteryStats { return mBluetoothOnTimer.getTotalTimeLocked(batteryRealtime, which); } + @Override + public long getNetworkActivityCount(int type, int which) { + if (type >= 0 && type < mNetworkActivityCounters.length) { + return mNetworkActivityCounters[type].getCountLocked(which); + } else { + return 0; + } + } + @Override public boolean getIsOnBattery() { return mOnBattery; } @@ -2513,17 +2565,6 @@ public final class BatteryStatsImpl extends BatteryStats { public final class Uid extends BatteryStats.Uid { final int mUid; - long mLoadedTcpBytesReceived; - long mLoadedTcpBytesSent; - long mCurrentTcpBytesReceived; - long mCurrentTcpBytesSent; - long mTcpBytesReceivedAtLastUnplug; - long mTcpBytesSentAtLastUnplug; - - // These are not saved/restored when parcelling, since we want - // to return from the parcel with a snapshot of the state. - long mStartedTcpBytesReceived = -1; - long mStartedTcpBytesSent = -1; boolean mWifiRunning; StopwatchTimer mWifiRunningTimer; @@ -2549,6 +2590,8 @@ public final class BatteryStatsImpl extends BatteryStats { Counter[] mUserActivityCounters; + LongSamplingCounter[] mNetworkActivityCounters; + /** * The statistics we have collected for this uid's wake locks. */ @@ -2612,43 +2655,6 @@ public final class BatteryStatsImpl extends BatteryStats { } @Override - public long getTcpBytesReceived(int which) { - if (which == STATS_LAST) { - return mLoadedTcpBytesReceived; - } else { - long current = computeCurrentTcpBytesReceived(); - if (which == STATS_SINCE_UNPLUGGED) { - current -= mTcpBytesReceivedAtLastUnplug; - } else if (which == STATS_SINCE_CHARGED) { - current += mLoadedTcpBytesReceived; - } - return current; - } - } - - public long computeCurrentTcpBytesReceived() { - final long uidRxBytes = getNetworkStatsDetailGroupedByUid().getTotal( - null, mUid).rxBytes; - return mCurrentTcpBytesReceived + (mStartedTcpBytesReceived >= 0 - ? (uidRxBytes - mStartedTcpBytesReceived) : 0); - } - - @Override - public long getTcpBytesSent(int which) { - if (which == STATS_LAST) { - return mLoadedTcpBytesSent; - } else { - long current = computeCurrentTcpBytesSent(); - if (which == STATS_SINCE_UNPLUGGED) { - current -= mTcpBytesSentAtLastUnplug; - } else if (which == STATS_SINCE_CHARGED) { - current += mLoadedTcpBytesSent; - } - return current; - } - } - - @Override public void noteWifiRunningLocked() { if (!mWifiRunning) { mWifiRunning = true; @@ -2911,11 +2917,38 @@ public final class BatteryStatsImpl extends BatteryStats { } } - public long computeCurrentTcpBytesSent() { - final long uidTxBytes = getNetworkStatsDetailGroupedByUid().getTotal( - null, mUid).txBytes; - return mCurrentTcpBytesSent + (mStartedTcpBytesSent >= 0 - ? (uidTxBytes - mStartedTcpBytesSent) : 0); + void noteNetworkActivityLocked(int type, long delta) { + if (mNetworkActivityCounters == null) { + initNetworkActivityLocked(); + } + if (type >= 0 && type < NUM_NETWORK_ACTIVITY_TYPES) { + mNetworkActivityCounters[type].addCountLocked(delta); + } else { + Slog.w(TAG, "Unknown network activity type " + type + " was specified.", + new Throwable()); + } + } + + @Override + public boolean hasNetworkActivity() { + return mNetworkActivityCounters != null; + } + + @Override + public long getNetworkActivityCount(int type, int which) { + if (mNetworkActivityCounters != null && type >= 0 + && type < mNetworkActivityCounters.length) { + return mNetworkActivityCounters[type].getCountLocked(which); + } else { + return 0; + } + } + + void initNetworkActivityLocked() { + mNetworkActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; + for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { + mNetworkActivityCounters[i] = new LongSamplingCounter(mUnpluggables); + } } /** @@ -2961,15 +2994,18 @@ public final class BatteryStatsImpl extends BatteryStats { } } - mLoadedTcpBytesReceived = mLoadedTcpBytesSent = 0; - mCurrentTcpBytesReceived = mCurrentTcpBytesSent = 0; - if (mUserActivityCounters != null) { for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { mUserActivityCounters[i].reset(false); } } + if (mNetworkActivityCounters != null) { + for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { + mNetworkActivityCounters[i].reset(false); + } + } + if (mWakelockStats.size() > 0) { Iterator<Map.Entry<String, Wakelock>> it = mWakelockStats.entrySet().iterator(); while (it.hasNext()) { @@ -3060,6 +3096,11 @@ public final class BatteryStatsImpl extends BatteryStats { mUserActivityCounters[i].detach(); } } + if (mNetworkActivityCounters != null) { + for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { + mNetworkActivityCounters[i].detach(); + } + } } return !active; @@ -3094,12 +3135,6 @@ public final class BatteryStatsImpl extends BatteryStats { pkg.writeToParcelLocked(out); } - out.writeLong(mLoadedTcpBytesReceived); - out.writeLong(mLoadedTcpBytesSent); - out.writeLong(computeCurrentTcpBytesReceived()); - out.writeLong(computeCurrentTcpBytesSent()); - out.writeLong(mTcpBytesReceivedAtLastUnplug); - out.writeLong(mTcpBytesSentAtLastUnplug); if (mWifiRunningTimer != null) { out.writeInt(1); mWifiRunningTimer.writeToParcel(out, batteryRealtime); @@ -3156,6 +3191,14 @@ public final class BatteryStatsImpl extends BatteryStats { } else { out.writeInt(0); } + if (mNetworkActivityCounters != null) { + out.writeInt(1); + for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { + mNetworkActivityCounters[i].writeToParcel(out); + } + } else { + out.writeInt(0); + } } void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) { @@ -3198,12 +3241,6 @@ public final class BatteryStatsImpl extends BatteryStats { mPackageStats.put(packageName, pkg); } - mLoadedTcpBytesReceived = in.readLong(); - mLoadedTcpBytesSent = in.readLong(); - mCurrentTcpBytesReceived = in.readLong(); - mCurrentTcpBytesSent = in.readLong(); - mTcpBytesReceivedAtLastUnplug = in.readLong(); - mTcpBytesSentAtLastUnplug = in.readLong(); mWifiRunning = false; if (in.readInt() != 0) { mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING, @@ -3266,6 +3303,14 @@ public final class BatteryStatsImpl extends BatteryStats { } else { mUserActivityCounters = null; } + if (in.readInt() != 0) { + mNetworkActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; + for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { + mNetworkActivityCounters[i] = new LongSamplingCounter(mUnpluggables, in); + } + } else { + mNetworkActivityCounters = null; + } } /** @@ -4340,6 +4385,9 @@ public final class BatteryStatsImpl extends BatteryStats { for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i, null, mUnpluggables); } + for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { + mNetworkActivityCounters[i] = new LongSamplingCounter(mUnpluggables); + } mWifiOnTimer = new StopwatchTimer(null, -3, null, mUnpluggables); mGlobalWifiRunningTimer = new StopwatchTimer(null, -4, null, mUnpluggables); mBluetoothOnTimer = new StopwatchTimer(null, -5, null, mUnpluggables); @@ -4515,6 +4563,9 @@ public final class BatteryStatsImpl extends BatteryStats { for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { mPhoneDataConnectionsTimer[i].reset(this, false); } + for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { + mNetworkActivityCounters[i].reset(false); + } mWifiOnTimer.reset(this, false); mGlobalWifiRunningTimer.reset(this, false); mBluetoothOnTimer.reset(this, false); @@ -4590,6 +4641,7 @@ public final class BatteryStatsImpl extends BatteryStats { mDischargeStartLevel = level; } updateKernelWakelocksLocked(); + updateNetworkActivityLocked(); mHistoryCur.batteryLevel = (byte)level; mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG; if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: " @@ -4612,6 +4664,7 @@ public final class BatteryStatsImpl extends BatteryStats { doUnplugLocked(realtime, mUnpluggedBatteryUptime, mUnpluggedBatteryRealtime); } else { updateKernelWakelocksLocked(); + updateNetworkActivityLocked(); mHistoryCur.batteryLevel = (byte)level; mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG; if (DEBUG_HISTORY) Slog.v(TAG, "Battery plugged to: " @@ -4744,6 +4797,52 @@ public final class BatteryStatsImpl extends BatteryStats { } } + private void updateNetworkActivityLocked() { + if (!SystemProperties.getBoolean(PROP_QTAGUID_ENABLED, false)) return; + + final NetworkStats snapshot; + try { + snapshot = mNetworkStatsFactory.readNetworkStatsDetail(); + } catch (IOException e) { + Log.wtf(TAG, "Failed to read network stats", e); + return; + } + + if (mLastSnapshot == null) { + mLastSnapshot = snapshot; + return; + } + + final NetworkStats delta = snapshot.subtract(mLastSnapshot); + mLastSnapshot = snapshot; + + NetworkStats.Entry entry = null; + final int size = delta.size(); + for (int i = 0; i < size; i++) { + entry = delta.getValues(i, entry); + + if (entry.rxBytes == 0 || entry.txBytes == 0) continue; + if (entry.tag != NetworkStats.TAG_NONE) continue; + + final Uid u = getUidStatsLocked(entry.uid); + + if (mMobileIfaces.contains(entry.iface)) { + u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_BYTES, entry.rxBytes); + u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_BYTES, entry.txBytes); + + mNetworkActivityCounters[NETWORK_MOBILE_RX_BYTES].addCountLocked(entry.rxBytes); + mNetworkActivityCounters[NETWORK_MOBILE_TX_BYTES].addCountLocked(entry.txBytes); + + } else if (mWifiIfaces.contains(entry.iface)) { + u.noteNetworkActivityLocked(NETWORK_WIFI_RX_BYTES, entry.rxBytes); + u.noteNetworkActivityLocked(NETWORK_WIFI_TX_BYTES, entry.txBytes); + + mNetworkActivityCounters[NETWORK_WIFI_RX_BYTES].addCountLocked(entry.rxBytes); + mNetworkActivityCounters[NETWORK_WIFI_TX_BYTES].addCountLocked(entry.txBytes); + } + } + } + public long getAwakeTimeBattery() { return computeBatteryUptime(getBatteryUptimeLocked(), STATS_CURRENT); } @@ -4834,47 +4933,6 @@ public final class BatteryStatsImpl extends BatteryStats { return getBatteryRealtimeLocked(curTime); } - private long getTcpBytes(long current, long[] dataBytes, int which) { - if (which == STATS_LAST) { - return dataBytes[STATS_LAST]; - } else { - if (which == STATS_SINCE_UNPLUGGED) { - if (dataBytes[STATS_SINCE_UNPLUGGED] < 0) { - return dataBytes[STATS_LAST]; - } else { - return current - dataBytes[STATS_SINCE_UNPLUGGED]; - } - } else if (which == STATS_SINCE_CHARGED) { - return (current - dataBytes[STATS_CURRENT]) + dataBytes[STATS_SINCE_CHARGED]; - } - return current - dataBytes[STATS_CURRENT]; - } - } - - /** Only STATS_UNPLUGGED works properly */ - public long getMobileTcpBytesSent(int which) { - final long mobileTxBytes = getNetworkStatsSummary().getTotal(null, mMobileIfaces).txBytes; - return getTcpBytes(mobileTxBytes, mMobileDataTx, which); - } - - /** Only STATS_UNPLUGGED works properly */ - public long getMobileTcpBytesReceived(int which) { - final long mobileRxBytes = getNetworkStatsSummary().getTotal(null, mMobileIfaces).rxBytes; - return getTcpBytes(mobileRxBytes, mMobileDataRx, which); - } - - /** Only STATS_UNPLUGGED works properly */ - public long getTotalTcpBytesSent(int which) { - final long totalTxBytes = getNetworkStatsSummary().getTotal(null).txBytes; - return getTcpBytes(totalTxBytes, mTotalDataTx, which); - } - - /** Only STATS_UNPLUGGED works properly */ - public long getTotalTcpBytesReceived(int which) { - final long totalRxBytes = getNetworkStatsSummary().getTotal(null).rxBytes; - return getTcpBytes(totalRxBytes, mTotalDataRx, which); - } - @Override public int getDischargeStartLevel() { synchronized(this) { @@ -5354,6 +5412,9 @@ public final class BatteryStatsImpl extends BatteryStats { for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in); } + for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { + mNetworkActivityCounters[i].readSummaryFromParcelLocked(in); + } mWifiOn = false; mWifiOnTimer.readSummaryFromParcelLocked(in); mGlobalWifiRunning = false; @@ -5425,6 +5486,15 @@ public final class BatteryStatsImpl extends BatteryStats { } } + if (in.readInt() != 0) { + if (u.mNetworkActivityCounters == null) { + u.initNetworkActivityLocked(); + } + for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { + u.mNetworkActivityCounters[i].readSummaryFromParcelLocked(in); + } + } + int NW = in.readInt(); if (NW > 100) { Slog.w(TAG, "File corrupt: too many wake locks " + NW); @@ -5507,9 +5577,6 @@ public final class BatteryStatsImpl extends BatteryStats { s.mLaunches = s.mLoadedLaunches = in.readInt(); } } - - u.mLoadedTcpBytesReceived = in.readLong(); - u.mLoadedTcpBytesSent = in.readLong(); } } @@ -5522,6 +5589,7 @@ public final class BatteryStatsImpl extends BatteryStats { public void writeSummaryToParcel(Parcel out) { // Need to update with current kernel wake lock counts. updateKernelWakelocksLocked(); + updateNetworkActivityLocked(); final long NOW_SYS = SystemClock.uptimeMillis() * 1000; final long NOWREAL_SYS = SystemClock.elapsedRealtime() * 1000; @@ -5557,6 +5625,9 @@ public final class BatteryStatsImpl extends BatteryStats { for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL); } + for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { + mNetworkActivityCounters[i].writeSummaryFromParcelLocked(out); + } mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL); mGlobalWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL); mBluetoothOnTimer.writeSummaryFromParcelLocked(out, NOWREAL); @@ -5638,6 +5709,15 @@ public final class BatteryStatsImpl extends BatteryStats { } } + if (u.mNetworkActivityCounters == null) { + out.writeInt(0); + } else { + out.writeInt(1); + for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { + u.mNetworkActivityCounters[i].writeSummaryFromParcelLocked(out); + } + } + int NW = u.mWakelockStats.size(); out.writeInt(NW); if (NW > 0) { @@ -5730,9 +5810,6 @@ public final class BatteryStatsImpl extends BatteryStats { } } } - - out.writeLong(u.getTcpBytesReceived(STATS_SINCE_CHARGED)); - out.writeLong(u.getTcpBytesSent(STATS_SINCE_CHARGED)); } } @@ -5771,6 +5848,9 @@ public final class BatteryStatsImpl extends BatteryStats { mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i, null, mUnpluggables, in); } + for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { + mNetworkActivityCounters[i] = new LongSamplingCounter(mUnpluggables, in); + } mWifiOn = false; mWifiOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in); mGlobalWifiRunning = false; @@ -5801,15 +5881,6 @@ public final class BatteryStatsImpl extends BatteryStats { mDischargeAmountScreenOffSinceCharge = in.readInt(); mLastWriteTime = in.readLong(); - mMobileDataRx[STATS_LAST] = in.readLong(); - mMobileDataRx[STATS_SINCE_UNPLUGGED] = -1; - mMobileDataTx[STATS_LAST] = in.readLong(); - mMobileDataTx[STATS_SINCE_UNPLUGGED] = -1; - mTotalDataRx[STATS_LAST] = in.readLong(); - mTotalDataRx[STATS_SINCE_UNPLUGGED] = -1; - mTotalDataTx[STATS_LAST] = in.readLong(); - mTotalDataTx[STATS_SINCE_UNPLUGGED] = -1; - mRadioDataUptime = in.readLong(); mRadioDataStart = -1; @@ -5859,6 +5930,7 @@ public final class BatteryStatsImpl extends BatteryStats { void writeToParcelLocked(Parcel out, boolean inclUids, int flags) { // Need to update with current kernel wake lock counts. updateKernelWakelocksLocked(); + updateNetworkActivityLocked(); final long uSecUptime = SystemClock.uptimeMillis() * 1000; final long uSecRealtime = SystemClock.elapsedRealtime() * 1000; @@ -5885,6 +5957,9 @@ public final class BatteryStatsImpl extends BatteryStats { for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { mPhoneDataConnectionsTimer[i].writeToParcel(out, batteryRealtime); } + for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { + mNetworkActivityCounters[i].writeToParcel(out); + } mWifiOnTimer.writeToParcel(out, batteryRealtime); mGlobalWifiRunningTimer.writeToParcel(out, batteryRealtime); mBluetoothOnTimer.writeToParcel(out, batteryRealtime); @@ -5909,11 +5984,6 @@ public final class BatteryStatsImpl extends BatteryStats { out.writeInt(mDischargeAmountScreenOffSinceCharge); out.writeLong(mLastWriteTime); - out.writeLong(getMobileTcpBytesReceived(STATS_SINCE_UNPLUGGED)); - out.writeLong(getMobileTcpBytesSent(STATS_SINCE_UNPLUGGED)); - out.writeLong(getTotalTcpBytesReceived(STATS_SINCE_UNPLUGGED)); - out.writeLong(getTotalTcpBytesSent(STATS_SINCE_UNPLUGGED)); - // Write radio uptime for data out.writeLong(getRadioDataUptime()); @@ -5965,6 +6035,7 @@ public final class BatteryStatsImpl extends BatteryStats { public void prepareForDumpLocked() { // Need to retrieve current kernel wake lock stats before printing. updateKernelWakelocksLocked(); + updateNetworkActivityLocked(); } public void dumpLocked(PrintWriter pw, boolean isUnpluggedOnly) { @@ -5996,59 +6067,7 @@ public final class BatteryStatsImpl extends BatteryStats { mGlobalWifiRunningTimer.logState(pr, " "); pr.println("*** Bluetooth timer:"); mBluetoothOnTimer.logState(pr, " "); - pr.println("*** Mobile ifaces:"); - pr.println(mMobileIfaces.toString()); } super.dumpLocked(pw, isUnpluggedOnly); } - - private NetworkStats mNetworkSummaryCache; - private NetworkStats mNetworkDetailCache; - - private NetworkStats getNetworkStatsSummary() { - // NOTE: calls from BatteryStatsService already hold this lock - synchronized (this) { - if (mNetworkSummaryCache == null - || mNetworkSummaryCache.getElapsedRealtimeAge() > SECOND_IN_MILLIS) { - mNetworkSummaryCache = null; - - if (SystemProperties.getBoolean(PROP_QTAGUID_ENABLED, false)) { - try { - mNetworkSummaryCache = mNetworkStatsFactory.readNetworkStatsSummaryDev(); - } catch (IOException e) { - Log.wtf(TAG, "problem reading network stats", e); - } - } - - if (mNetworkSummaryCache == null) { - mNetworkSummaryCache = new NetworkStats(SystemClock.elapsedRealtime(), 0); - } - } - return mNetworkSummaryCache; - } - } - - private NetworkStats getNetworkStatsDetailGroupedByUid() { - // NOTE: calls from BatteryStatsService already hold this lock - synchronized (this) { - if (mNetworkDetailCache == null - || mNetworkDetailCache.getElapsedRealtimeAge() > SECOND_IN_MILLIS) { - mNetworkDetailCache = null; - - if (SystemProperties.getBoolean(PROP_QTAGUID_ENABLED, false)) { - try { - mNetworkDetailCache = mNetworkStatsFactory - .readNetworkStatsDetail().groupedByUid(); - } catch (IOException e) { - Log.wtf(TAG, "problem reading network stats", e); - } - } - - if (mNetworkDetailCache == null) { - mNetworkDetailCache = new NetworkStats(SystemClock.elapsedRealtime(), 0); - } - } - return mNetworkDetailCache; - } - } } diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java index 0d266c27bdc7..a78d68b6c163 100644 --- a/services/java/com/android/server/NetworkManagementService.java +++ b/services/java/com/android/server/NetworkManagementService.java @@ -50,12 +50,14 @@ import android.os.INetworkManagementService; import android.os.Process; import android.os.RemoteCallbackList; import android.os.RemoteException; +import android.os.ServiceManager; import android.os.SystemClock; import android.os.SystemProperties; import android.util.Log; import android.util.Slog; import android.util.SparseBooleanArray; +import com.android.internal.app.IBatteryStats; import com.android.internal.net.NetworkStatsFactory; import com.android.internal.util.Preconditions; import com.android.server.NativeDaemonConnector.Command; @@ -343,6 +345,14 @@ public class NetworkManagementService extends INetworkManagementService.Stub SystemProperties.set(PROP_QTAGUID_ENABLED, mBandwidthControlEnabled ? "1" : "0"); + if (mBandwidthControlEnabled) { + try { + IBatteryStats.Stub.asInterface(ServiceManager.getService("batteryinfo")) + .noteNetworkStatsEnabled(); + } catch (RemoteException e) { + } + } + // push any existing quota or UID rules synchronized (mQuotaLock) { int size = mActiveQuotas.size(); diff --git a/services/java/com/android/server/am/BatteryStatsService.java b/services/java/com/android/server/am/BatteryStatsService.java index 9b3fbe93a909..5a15f0bb8846 100644 --- a/services/java/com/android/server/am/BatteryStatsService.java +++ b/services/java/com/android/server/am/BatteryStatsService.java @@ -431,6 +431,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub { } } + @Override public void noteNetworkInterfaceType(String iface, int type) { enforceCallingPermission(); synchronized (mStats) { @@ -438,6 +439,14 @@ public final class BatteryStatsService extends IBatteryStats.Stub { } } + @Override + public void noteNetworkStatsEnabled() { + enforceCallingPermission(); + synchronized (mStats) { + mStats.noteNetworkStatsEnabledLocked(); + } + } + public boolean isOnBattery() { return mStats.isOnBattery(); } |