From 50e4760214dc3bab81b5ccf6df4d5ce5fa34d723 Mon Sep 17 00:00:00 2001 From: Adam Lesinski Date: Fri, 4 Dec 2015 17:04:54 -0800 Subject: [PATCH] Record bytes transferred for bluetooth Bug:26039657 Change-Id: Iec42459d12f4106d5733f55313e8544d58930285 --- .../bluetooth/BluetoothActivityEnergyInfo.java | 45 ++++++--- core/java/android/bluetooth/UidTraffic.java | 111 +++++++++++++++++++++ core/java/android/os/BatteryStats.java | 60 ++++++++++- .../com/android/internal/os/BatteryStatsImpl.java | 43 +++++++- 4 files changed, 238 insertions(+), 21 deletions(-) create mode 100644 core/java/android/bluetooth/UidTraffic.java diff --git a/core/java/android/bluetooth/BluetoothActivityEnergyInfo.java b/core/java/android/bluetooth/BluetoothActivityEnergyInfo.java index 834a587d83df..e32a47056fef 100644 --- a/core/java/android/bluetooth/BluetoothActivityEnergyInfo.java +++ b/core/java/android/bluetooth/BluetoothActivityEnergyInfo.java @@ -19,6 +19,8 @@ package android.bluetooth; import android.os.Parcel; import android.os.Parcelable; +import java.util.Arrays; + /** * Record of energy and activity information from controller and * underlying bt stack state.Timestamp the record with system @@ -27,11 +29,12 @@ import android.os.Parcelable; */ public final class BluetoothActivityEnergyInfo implements Parcelable { private final long mTimestamp; - private final int mBluetoothStackState; - private final long mControllerTxTimeMs; - private final long mControllerRxTimeMs; - private final long mControllerIdleTimeMs; - private final long mControllerEnergyUsed; + private int mBluetoothStackState; + private long mControllerTxTimeMs; + private long mControllerRxTimeMs; + private long mControllerIdleTimeMs; + private long mControllerEnergyUsed; + private UidTraffic[] mUidTraffic; public static final int BT_STACK_STATE_INVALID = 0; public static final int BT_STACK_STATE_STATE_ACTIVE = 1; @@ -48,6 +51,17 @@ public final class BluetoothActivityEnergyInfo implements Parcelable { mControllerEnergyUsed = energyUsed; } + @SuppressWarnings("unchecked") + BluetoothActivityEnergyInfo(Parcel in) { + mTimestamp = in.readLong(); + mBluetoothStackState = in.readInt(); + mControllerTxTimeMs = in.readLong(); + mControllerRxTimeMs = in.readLong(); + mControllerIdleTimeMs = in.readLong(); + mControllerEnergyUsed = in.readLong(); + mUidTraffic = in.createTypedArray(UidTraffic.CREATOR); + } + @Override public String toString() { return "BluetoothActivityEnergyInfo{" @@ -57,26 +71,22 @@ public final class BluetoothActivityEnergyInfo implements Parcelable { + " mControllerRxTimeMs=" + mControllerRxTimeMs + " mControllerIdleTimeMs=" + mControllerIdleTimeMs + " mControllerEnergyUsed=" + mControllerEnergyUsed + + " mUidTraffic=" + Arrays.toString(mUidTraffic) + " }"; } public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { public BluetoothActivityEnergyInfo createFromParcel(Parcel in) { - long timestamp = in.readLong(); - int stackState = in.readInt(); - long txTime = in.readLong(); - long rxTime = in.readLong(); - long idleTime = in.readLong(); - long energyUsed = in.readLong(); - return new BluetoothActivityEnergyInfo(timestamp, stackState, - txTime, rxTime, idleTime, energyUsed); + return new BluetoothActivityEnergyInfo(in); } + public BluetoothActivityEnergyInfo[] newArray(int size) { return new BluetoothActivityEnergyInfo[size]; } }; + @SuppressWarnings("unchecked") public void writeToParcel(Parcel out, int flags) { out.writeLong(mTimestamp); out.writeInt(mBluetoothStackState); @@ -84,6 +94,7 @@ public final class BluetoothActivityEnergyInfo implements Parcelable { out.writeLong(mControllerRxTimeMs); out.writeLong(mControllerIdleTimeMs); out.writeLong(mControllerEnergyUsed); + out.writeTypedArray(mUidTraffic, flags); } public int describeContents() { @@ -133,6 +144,14 @@ public final class BluetoothActivityEnergyInfo implements Parcelable { return mTimestamp; } + public UidTraffic[] getUidTraffic() { + return mUidTraffic; + } + + public void setUidTraffic(UidTraffic[] traffic) { + mUidTraffic = traffic; + } + /** * @return if the record is valid */ diff --git a/core/java/android/bluetooth/UidTraffic.java b/core/java/android/bluetooth/UidTraffic.java new file mode 100644 index 000000000000..78013cc0cb02 --- /dev/null +++ b/core/java/android/bluetooth/UidTraffic.java @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2015 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 android.bluetooth; + +import android.os.Parcel; +import android.os.Parcelable; + +/** + * Record of data traffic (in bytes) by an application identified by its UID. + * @hide + */ +public class UidTraffic implements Cloneable, Parcelable { + private final int mAppUid; + private long mRxBytes; + private long mTxBytes; + + public UidTraffic(int appUid) { + mAppUid = appUid; + } + + public UidTraffic(int appUid, long rx, long tx) { + mAppUid = appUid; + mRxBytes = rx; + mTxBytes = tx; + } + + UidTraffic(Parcel in) { + mAppUid = in.readInt(); + mRxBytes = in.readLong(); + mTxBytes = in.readLong(); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(mAppUid); + dest.writeLong(mRxBytes); + dest.writeLong(mTxBytes); + } + + public void setRxBytes(long bytes) { + mRxBytes = bytes; + } + + public void setTxBytes(long bytes) { + mTxBytes = bytes; + } + + public void addRxBytes(long bytes) { + mRxBytes += bytes; + } + + public void addTxBytes(long bytes) { + mTxBytes += bytes; + } + + public int getUid() { + return mAppUid; + } + + public long getRxBytes() { + return mRxBytes; + } + + public long getTxBytes() { + return mTxBytes; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public UidTraffic clone() { + return new UidTraffic(mAppUid, mRxBytes, mTxBytes); + } + + @Override + public String toString() { + return "UidTraffic{" + + "mAppUid=" + mAppUid + + ", mRxBytes=" + mRxBytes + + ", mTxBytes=" + mTxBytes + + '}'; + } + + public static final Creator CREATOR = new Creator() { + @Override + public UidTraffic createFromParcel(Parcel source) { + return new UidTraffic(source); + } + + @Override + public UidTraffic[] newArray(int size) { + return new UidTraffic[size]; + } + }; +} diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index bce38f40682a..918050644ce4 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -378,6 +378,16 @@ public abstract class BatteryStats implements Parcelable { public abstract long getWifiControllerActivity(int type, int which); /** + * Returns the time in milliseconds that this app kept the Bluetooth controller in the + * specified state type. + * @param type one of {@link #CONTROLLER_IDLE_TIME}, {@link #CONTROLLER_RX_TIME}, or + * {@link #CONTROLLER_TX_TIME}. + * @param which one of {@link #STATS_CURRENT}, {@link #STATS_SINCE_CHARGED}, or + * {@link #STATS_SINCE_UNPLUGGED}. + */ + public abstract long getBluetoothControllerActivity(int type, int which); + + /** * {@hide} */ public abstract int getUid(); @@ -2014,7 +2024,9 @@ public abstract class BatteryStats implements Parcelable { public static final int NETWORK_MOBILE_TX_DATA = 1; public static final int NETWORK_WIFI_RX_DATA = 2; public static final int NETWORK_WIFI_TX_DATA = 3; - public static final int NUM_NETWORK_ACTIVITY_TYPES = NETWORK_WIFI_TX_DATA + 1; + public static final int NETWORK_BT_RX_DATA = 4; + public static final int NETWORK_BT_TX_DATA = 5; + public static final int NUM_NETWORK_ACTIVITY_TYPES = NETWORK_BT_TX_DATA + 1; public abstract long getNetworkActivityBytes(int type, int which); public abstract long getNetworkActivityPackets(int type, int which); @@ -3284,6 +3296,8 @@ public abstract class BatteryStats implements Parcelable { final long mobileTxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which); final long wifiRxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which); final long wifiTxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which); + final long btRxTotalBytes = getNetworkActivityBytes(NETWORK_BT_RX_DATA, which); + final long btTxTotalBytes = getNetworkActivityBytes(NETWORK_BT_TX_DATA, which); if (fullWakeLockTimeTotalMicros != 0) { sb.setLength(0); @@ -3517,6 +3531,10 @@ public abstract class BatteryStats implements Parcelable { sb.append("mAh"); pw.println(sb.toString()); + pw.print(prefix); + pw.print(" Bluetooth total received: "); pw.print(formatBytesLocked(btRxTotalBytes)); + pw.print(", sent: "); pw.println(formatBytesLocked(btTxTotalBytes)); + final long bluetoothIdleTimeMs = getBluetoothControllerActivity(CONTROLLER_IDLE_TIME, which); final long bluetoothRxTimeMs = getBluetoothControllerActivity(CONTROLLER_RX_TIME, which); @@ -3838,12 +3856,17 @@ public abstract class BatteryStats implements Parcelable { final long mobileTxBytes = u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which); final long wifiRxBytes = u.getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which); final long wifiTxBytes = u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which); + final long btRxBytes = u.getNetworkActivityBytes(NETWORK_BT_RX_DATA, which); + final long btTxBytes = u.getNetworkActivityBytes(NETWORK_BT_TX_DATA, which); + final long mobileRxPackets = u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which); final long mobileTxPackets = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which); - final long uidMobileActiveTime = u.getMobileRadioActiveTime(which); - final int uidMobileActiveCount = u.getMobileRadioActiveCount(which); final long wifiRxPackets = u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which); final long wifiTxPackets = u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which); + + final long uidMobileActiveTime = u.getMobileRadioActiveTime(which); + final int uidMobileActiveCount = u.getMobileRadioActiveCount(which); + final long fullWifiLockOnTime = u.getFullWifiLockTime(rawRealtime, which); final long wifiScanTime = u.getWifiScanTime(rawRealtime, which); final int wifiScanCount = u.getWifiScanCount(which); @@ -3923,6 +3946,37 @@ public abstract class BatteryStats implements Parcelable { pw.println(sb.toString()); } + if (btRxBytes > 0 || btTxBytes > 0) { + pw.print(prefix); pw.print(" Bluetooth network: "); + pw.print(formatBytesLocked(btRxBytes)); pw.print(" received, "); + pw.print(formatBytesLocked(btTxBytes)); + pw.println(" sent"); + } + + final long uidBtIdleTimeMs = u.getBluetoothControllerActivity(CONTROLLER_IDLE_TIME, + which); + final long uidBtRxTimeMs = u.getBluetoothControllerActivity(CONTROLLER_RX_TIME, which); + final long uidBtTxTimeMs = u.getBluetoothControllerActivity(CONTROLLER_TX_TIME, which); + final long uidBtTotalTimeMs = uidBtIdleTimeMs + uidBtRxTimeMs + uidBtTxTimeMs; + if (uidBtTotalTimeMs > 0) { + sb.setLength(0); + sb.append(prefix).append(" Bluetooth Idle time: "); + formatTimeMs(sb, uidBtIdleTimeMs); + sb.append("(").append(formatRatioLocked(uidBtIdleTimeMs, uidBtTotalTimeMs)) + .append(")\n"); + + sb.append(prefix).append(" Bluetooth Rx time: "); + formatTimeMs(sb, uidBtRxTimeMs); + sb.append("(").append(formatRatioLocked(uidBtRxTimeMs, uidBtTotalTimeMs)) + .append(")\n"); + + sb.append(prefix).append(" Bluetooth Tx time: "); + formatTimeMs(sb, uidBtTxTimeMs); + sb.append("(").append(formatRatioLocked(uidBtTxTimeMs, uidBtTotalTimeMs)) + .append(")"); + pw.println(sb.toString()); + } + if (u.hasUserActivity()) { boolean hasData = false; for (int i=0; i mUidStats = - new SparseArray(); + final SparseArray mUidStats = new SparseArray<>(); // A set of pools of currently active timers. When a timer is queried, we will divide the // elapsed time by the number of active timers to arrive at that timer's share of the time. @@ -4691,6 +4691,13 @@ public final class BatteryStatsImpl extends BatteryStats { mWifiControllerTime[type].addCountLocked(timeMs); } + public void noteBluetoothControllerActivityLocked(int type, long timeMs) { + if (mBluetoothControllerTime[type] == null) { + mBluetoothControllerTime[type] = new LongSamplingCounter(mOnBatteryTimeBase); + } + mBluetoothControllerTime[type].addCountLocked(timeMs); + } + public StopwatchTimer createAudioTurnedOnTimerLocked() { if (mAudioTurnedOnTimer == null) { mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON, @@ -5085,6 +5092,15 @@ public final class BatteryStatsImpl extends BatteryStats { return 0; } + @Override + public long getBluetoothControllerActivity(int type, int which) { + if (type >= 0 && type < NUM_CONTROLLER_ACTIVITY_TYPES && + mBluetoothControllerTime[type] != null) { + return mBluetoothControllerTime[type].getCountLocked(which); + } + return 0; + } + void initNetworkActivityLocked() { mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; mNetworkPacketActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; @@ -7998,7 +8014,7 @@ public final class BatteryStatsImpl extends BatteryStats { */ public void updateBluetoothStateLocked(@Nullable final BluetoothActivityEnergyInfo info) { if (DEBUG_ENERGY) { - Slog.d(TAG, "Updating bluetooth stats"); + Slog.d(TAG, "Updating bluetooth stats: " + info); } if (info != null && mOnBatteryInternal) { @@ -8018,6 +8034,23 @@ public final class BatteryStatsImpl extends BatteryStats { mBluetoothActivityCounters[CONTROLLER_POWER_DRAIN].addCountLocked( (long) (info.getControllerEnergyUsed() / opVolt)); } + + final UidTraffic[] uidTraffic = info.getUidTraffic(); + final int numUids = uidTraffic != null ? uidTraffic.length : 0; + for (int i = 0; i < numUids; i++) { + final UidTraffic traffic = uidTraffic[i]; + + // Add to the global counters. + mNetworkByteActivityCounters[NETWORK_BT_RX_DATA].addCountLocked( + traffic.getRxBytes()); + mNetworkByteActivityCounters[NETWORK_BT_TX_DATA].addCountLocked( + traffic.getTxBytes()); + + // Add to the UID counters. + final Uid u = getUidStatsLocked(mapUid(traffic.getUid())); + u.noteNetworkActivityLocked(NETWORK_BT_RX_DATA, traffic.getRxBytes(), 0); + u.noteNetworkActivityLocked(NETWORK_BT_TX_DATA, traffic.getTxBytes(), 0); + } } } -- 2.11.0