NetworkTraffic: Include tethering hw offload statistics
*) Regular interface stats don't include hw offload tethering statistics so collect and include them in our traffic calculations. Change-Id: Id72577429840f65ae20d7b80e7490ec41d826579
This commit is contained in:
committed by
Bruno Martins
parent
c3b5589ccf
commit
f12a1e5568
@@ -32,11 +32,15 @@ import android.net.LinkProperties;
|
||||
import android.net.Network;
|
||||
import android.net.NetworkCapabilities;
|
||||
import android.net.NetworkRequest;
|
||||
import android.net.NetworkStats;
|
||||
import android.net.TrafficStats;
|
||||
import android.os.Handler;
|
||||
import android.os.UserHandle;
|
||||
import android.os.INetworkManagementService;
|
||||
import android.os.Message;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.SystemClock;
|
||||
import android.os.UserHandle;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.util.TypedValue;
|
||||
@@ -97,6 +101,8 @@ public class NetworkTraffic extends TextView {
|
||||
// Network tracking related variables
|
||||
final private ConnectivityManager mConnectivityManager;
|
||||
final private HashMap<Network, NetworkState> mNetworkMap = new HashMap<>();
|
||||
// Used to indicate that the set of sources contributing
|
||||
// to current stats have changed.
|
||||
private boolean mNetworksChanged = true;
|
||||
|
||||
public class NetworkState {
|
||||
@@ -110,6 +116,8 @@ public class NetworkTraffic extends TextView {
|
||||
}
|
||||
};
|
||||
|
||||
private INetworkManagementService mNetworkManagementService;
|
||||
|
||||
public NetworkTraffic(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
@@ -121,6 +129,9 @@ public class NetworkTraffic extends TextView {
|
||||
public NetworkTraffic(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
|
||||
mNetworkManagementService = INetworkManagementService.Stub.asInterface(
|
||||
ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE));
|
||||
|
||||
final Resources resources = getResources();
|
||||
mTextSizeSingle = resources.getDimensionPixelSize(R.dimen.net_traffic_single_text_size);
|
||||
mTextSizeMulti = resources.getDimensionPixelSize(R.dimen.net_traffic_multi_text_size);
|
||||
@@ -189,20 +200,35 @@ public class NetworkTraffic extends TextView {
|
||||
final long timeDelta = now - mLastUpdateTime; /* ms */
|
||||
if (msg.what == MESSAGE_TYPE_PERIODIC_REFRESH
|
||||
&& timeDelta >= REFRESH_INTERVAL * 0.95f) {
|
||||
// Update counters
|
||||
// Sum tx and rx bytes from all sources of interest
|
||||
long txBytes = 0;
|
||||
long rxBytes = 0;
|
||||
// Sum stats from interfaces of interest
|
||||
// Add interface stats
|
||||
for (NetworkState state : mNetworkMap.values()) {
|
||||
final String iface = state.mLinkProperties.getInterfaceName();
|
||||
if (iface == null) {
|
||||
continue;
|
||||
}
|
||||
final long ifaceTxBytes = TrafficStats.getTxBytes(iface);
|
||||
final long ifaceRxBytes = TrafficStats.getRxBytes(iface);
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "adding stats from interface " + iface);
|
||||
Log.d(TAG, "adding stats from interface " + iface
|
||||
+ " txbytes " + ifaceTxBytes + " rxbytes " + ifaceRxBytes);
|
||||
}
|
||||
txBytes += TrafficStats.getTxBytes(iface);
|
||||
rxBytes += TrafficStats.getRxBytes(iface);
|
||||
txBytes += ifaceTxBytes;
|
||||
rxBytes += ifaceRxBytes;
|
||||
}
|
||||
|
||||
// Add tether hw offload counters since these are
|
||||
// not included in netd interface stats.
|
||||
final TetheringStats tetheringStats = getOffloadTetheringStats();
|
||||
txBytes += tetheringStats.txBytes;
|
||||
rxBytes += tetheringStats.rxBytes;
|
||||
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "mNetworksChanged = " + mNetworksChanged);
|
||||
Log.d(TAG, "tether hw offload txBytes: " + tetheringStats.txBytes
|
||||
+ " rxBytes: " + tetheringStats.rxBytes);
|
||||
}
|
||||
|
||||
final long txBytesDelta = txBytes - mLastTxBytes;
|
||||
@@ -350,6 +376,45 @@ public class NetworkTraffic extends TextView {
|
||||
return cm.getActiveNetworkInfo() != null;
|
||||
}
|
||||
|
||||
private class TetheringStats {
|
||||
long txBytes;
|
||||
long rxBytes;
|
||||
}
|
||||
|
||||
private TetheringStats getOffloadTetheringStats() {
|
||||
TetheringStats tetheringStats = new TetheringStats();
|
||||
|
||||
NetworkStats stats = null;
|
||||
try {
|
||||
// STATS_PER_UID returns hw offload and netd stats combined (as entry UID_TETHERING)
|
||||
// STATS_PER_IFACE returns only hw offload stats (as entry UID_ALL)
|
||||
stats = mNetworkManagementService.getNetworkStatsTethering(
|
||||
NetworkStats.STATS_PER_IFACE);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Unable to call getNetworkStatsTethering: " + e);
|
||||
}
|
||||
if (stats == null) {
|
||||
// nothing we can do except return zero stats
|
||||
return tetheringStats;
|
||||
}
|
||||
|
||||
NetworkStats.Entry entry = null;
|
||||
// Entries here are per tethered interface.
|
||||
// Counters persist even after tethering has been disabled.
|
||||
for (int i = 0; i < stats.size(); i++) {
|
||||
entry = stats.getValues(i, entry);
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "tethering stats entry: " + entry);
|
||||
}
|
||||
// hw offload tether stats are reported under UID_ALL.
|
||||
if (entry.uid == NetworkStats.UID_ALL) {
|
||||
tetheringStats.txBytes += entry.txBytes;
|
||||
tetheringStats.rxBytes += entry.rxBytes;
|
||||
}
|
||||
}
|
||||
return tetheringStats;
|
||||
}
|
||||
|
||||
private void updateSettings() {
|
||||
ContentResolver resolver = mContext.getContentResolver();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user