diff --git a/core/java/android/net/TrafficStats.java b/core/java/android/net/TrafficStats.java index e7bba69dbb..7a79ceb14a 100644 --- a/core/java/android/net/TrafficStats.java +++ b/core/java/android/net/TrafficStats.java @@ -976,11 +976,17 @@ public class TrafficStats { } } - // NOTE: keep these in sync with android_net_TrafficStats.cpp - private static final int TYPE_RX_BYTES = 0; - private static final int TYPE_RX_PACKETS = 1; - private static final int TYPE_TX_BYTES = 2; - private static final int TYPE_TX_PACKETS = 3; - private static final int TYPE_TCP_RX_PACKETS = 4; - private static final int TYPE_TCP_TX_PACKETS = 5; + // NOTE: keep these in sync with {@code com_android_server_net_NetworkStatsService.cpp}. + /** {@hide} */ + public static final int TYPE_RX_BYTES = 0; + /** {@hide} */ + public static final int TYPE_RX_PACKETS = 1; + /** {@hide} */ + public static final int TYPE_TX_BYTES = 2; + /** {@hide} */ + public static final int TYPE_TX_PACKETS = 3; + /** {@hide} */ + public static final int TYPE_TCP_RX_PACKETS = 4; + /** {@hide} */ + public static final int TYPE_TCP_TX_PACKETS = 5; } diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java index 96e3c5163f..bfd0211f18 100644 --- a/services/core/java/com/android/server/net/NetworkStatsService.java +++ b/services/core/java/com/android/server/net/NetworkStatsService.java @@ -1083,9 +1083,11 @@ public class NetworkStatsService extends INetworkStatsService.Stub { if (nativeIfaceStats == -1) { return nativeIfaceStats; } else { - // TODO: When tethering offload is in use, nativeIfaceStats does not contain usage from - // offload, add it back here. - return nativeIfaceStats; + // When tethering offload is in use, nativeIfaceStats does not contain usage from + // offload, add it back here. Note that the included statistics might be stale + // since polling newest stats from hardware might impact system health and not + // suitable for TrafficStats API use cases. + return nativeIfaceStats + getProviderIfaceStats(iface, type); } } @@ -1096,7 +1098,31 @@ public class NetworkStatsService extends INetworkStatsService.Stub { return nativeTotalStats; } else { // Refer to comment in getIfaceStats - return nativeTotalStats; + return nativeTotalStats + getProviderIfaceStats(IFACE_ALL, type); + } + } + + private long getProviderIfaceStats(@Nullable String iface, int type) { + final NetworkStats providerSnapshot = getNetworkStatsFromProviders(STATS_PER_IFACE); + final HashSet limitIfaces; + if (iface == IFACE_ALL) { + limitIfaces = null; + } else { + limitIfaces = new HashSet<>(); + limitIfaces.add(iface); + } + final NetworkStats.Entry entry = providerSnapshot.getTotal(null, limitIfaces); + switch (type) { + case TrafficStats.TYPE_RX_BYTES: + return entry.rxBytes; + case TrafficStats.TYPE_RX_PACKETS: + return entry.rxPackets; + case TrafficStats.TYPE_TX_BYTES: + return entry.txBytes; + case TrafficStats.TYPE_TX_PACKETS: + return entry.txPackets; + default: + return 0; } } @@ -1464,29 +1490,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { final boolean persistUid = (flags & FLAG_PERSIST_UID) != 0; final boolean persistForce = (flags & FLAG_PERSIST_FORCE) != 0; - // Request asynchronous stats update from all providers for next poll. And wait a bit of - // time to allow providers report-in given that normally binder call should be fast. Note - // that size of list might be changed because addition/removing at the same time. For - // addition, the stats of the missed provider can only be collected in next poll; - // for removal, wait might take up to MAX_STATS_PROVIDER_POLL_WAIT_TIME_MS - // once that happened. - // TODO: request with a valid token. - Trace.traceBegin(TRACE_TAG_NETWORK, "provider.requestStatsUpdate"); - final int registeredCallbackCount = mStatsProviderCbList.size(); - mStatsProviderSem.drainPermits(); - invokeForAllStatsProviderCallbacks( - (cb) -> cb.mProvider.onRequestStatsUpdate(0 /* unused */)); - try { - mStatsProviderSem.tryAcquire(registeredCallbackCount, - MAX_STATS_PROVIDER_POLL_WAIT_TIME_MS, TimeUnit.MILLISECONDS); - } catch (InterruptedException e) { - // Strictly speaking it's possible a provider happened to deliver between the timeout - // and the log, and that doesn't matter too much as this is just a debug log. - Log.d(TAG, "requestStatsUpdate - providers responded " - + mStatsProviderSem.availablePermits() - + "/" + registeredCallbackCount + " : " + e); - } - Trace.traceEnd(TRACE_TAG_NETWORK); + performPollFromProvidersLocked(); // TODO: consider marking "untrusted" times in historical stats final long currentTime = mClock.millis(); @@ -1531,6 +1535,33 @@ public class NetworkStatsService extends INetworkStatsService.Stub { Trace.traceEnd(TRACE_TAG_NETWORK); } + @GuardedBy("mStatsLock") + private void performPollFromProvidersLocked() { + // Request asynchronous stats update from all providers for next poll. And wait a bit of + // time to allow providers report-in given that normally binder call should be fast. Note + // that size of list might be changed because addition/removing at the same time. For + // addition, the stats of the missed provider can only be collected in next poll; + // for removal, wait might take up to MAX_STATS_PROVIDER_POLL_WAIT_TIME_MS + // once that happened. + // TODO: request with a valid token. + Trace.traceBegin(TRACE_TAG_NETWORK, "provider.requestStatsUpdate"); + final int registeredCallbackCount = mStatsProviderCbList.size(); + mStatsProviderSem.drainPermits(); + invokeForAllStatsProviderCallbacks( + (cb) -> cb.mProvider.onRequestStatsUpdate(0 /* unused */)); + try { + mStatsProviderSem.tryAcquire(registeredCallbackCount, + MAX_STATS_PROVIDER_POLL_WAIT_TIME_MS, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + // Strictly speaking it's possible a provider happened to deliver between the timeout + // and the log, and that doesn't matter too much as this is just a debug log. + Log.d(TAG, "requestStatsUpdate - providers responded " + + mStatsProviderSem.availablePermits() + + "/" + registeredCallbackCount + " : " + e); + } + Trace.traceEnd(TRACE_TAG_NETWORK); + } + /** * Sample recent statistics summary into {@link EventLog}. */ @@ -2183,6 +2214,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } } + // TODO: Remove unused definitions after removing JNI that fills these variables. + // See {@code com_android_server_net_NetworkStatsService.cpp}. private static int TYPE_RX_BYTES; private static int TYPE_RX_PACKETS; private static int TYPE_TX_BYTES;