fix getIfaceStats and getTotalStats bug
root cause: getIfaceStats and getTotalStats is directly reading iface_stat_fmt or eBPF, not include tether stats. solution: add tether stats to getIfaceStats and getTotalStats. Clean cherry-pick of aosp/848934 Bug: 120039819 Test case1: 1. tether offload is enabled on phone, enable MHS on phone. 2. Use test app to check getMobileRxBytes->getIfaceStats 3. Download 10M file on MHS client 4. Use test app to check getMobileRxBytes->getIfaceStats again result: getMobileRxBytes increased around 10M Test case2: 1. tether offload is disabled on phone, enable MHS on phone. repeat above step 2~4 result: getMobileRxBytes increased around 10M Following CTS cases passed run cts -m CtsNetTestCases --test android.net.cts.TrafficStatsTest run cts -m CtsUsageStatsTestCases --test android.app.usage.cts.NetworkUsageStatsTest Change-Id: I3d94acb71c142ec38b750e58822881ff383341cc
This commit is contained in:
@@ -962,12 +962,64 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
||||
|
||||
@Override
|
||||
public long getIfaceStats(String iface, int type) {
|
||||
return nativeGetIfaceStat(iface, type, checkBpfStatsEnable());
|
||||
long nativeIfaceStats = nativeGetIfaceStat(iface, type, checkBpfStatsEnable());
|
||||
if (nativeIfaceStats == -1) {
|
||||
return nativeIfaceStats;
|
||||
} else {
|
||||
// When tethering offload is in use, nativeIfaceStats does not contain usage from
|
||||
// offload, add it back here.
|
||||
// When tethering offload is not in use, nativeIfaceStats contains tethering usage.
|
||||
// this does not cause double-counting of tethering traffic, because
|
||||
// NetdTetheringStatsProvider returns zero NetworkStats
|
||||
// when called with STATS_PER_IFACE.
|
||||
return nativeIfaceStats + getTetherStats(iface, type);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTotalStats(int type) {
|
||||
return nativeGetTotalStat(type, checkBpfStatsEnable());
|
||||
long nativeTotalStats = nativeGetTotalStat(type, checkBpfStatsEnable());
|
||||
if (nativeTotalStats == -1) {
|
||||
return nativeTotalStats;
|
||||
} else {
|
||||
// Refer to comment in getIfaceStats
|
||||
return nativeTotalStats + getTetherStats(IFACE_ALL, type);
|
||||
}
|
||||
}
|
||||
|
||||
private long getTetherStats(String iface, int type) {
|
||||
final NetworkStats tetherSnapshot;
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
tetherSnapshot = getNetworkStatsTethering(STATS_PER_IFACE);
|
||||
} catch (RemoteException e) {
|
||||
Slog.w(TAG, "Error get TetherStats: " + e);
|
||||
return 0;
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
HashSet<String> limitIfaces;
|
||||
if (iface == IFACE_ALL) {
|
||||
limitIfaces = null;
|
||||
} else {
|
||||
limitIfaces = new HashSet<String>();
|
||||
limitIfaces.add(iface);
|
||||
}
|
||||
NetworkStats.Entry entry = tetherSnapshot.getTotal(null, limitIfaces);
|
||||
if (LOGD) Slog.d(TAG, "TetherStats: iface=" + iface + " type=" + type +
|
||||
" entry=" + entry);
|
||||
switch (type) {
|
||||
case 0: // TYPE_RX_BYTES
|
||||
return entry.rxBytes;
|
||||
case 1: // TYPE_RX_PACKETS
|
||||
return entry.rxPackets;
|
||||
case 2: // TYPE_TX_BYTES
|
||||
return entry.txBytes;
|
||||
case 3: // TYPE_TX_PACKETS
|
||||
return entry.txPackets;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkBpfStatsEnable() {
|
||||
|
||||
Reference in New Issue
Block a user