diff --git a/framework-t/src/android/net/NetworkStats.java b/framework-t/src/android/net/NetworkStats.java index 51ff5ec7ad..0bb98f8f1f 100644 --- a/framework-t/src/android/net/NetworkStats.java +++ b/framework-t/src/android/net/NetworkStats.java @@ -1299,6 +1299,17 @@ public final class NetworkStats implements Parcelable, Iterable mAllMobileIfacesSinceBoot = new ArraySet<>(); + + /* A set of all interfaces that have ever been associated with wifi networks since boot. */ + @GuardedBy("mStatsLock") + private final Set mAllWifiIfacesSinceBoot = new ArraySet<>(); /** Set of all ifaces currently used by traffic that does not explicitly specify a Network. */ @GuardedBy("mStatsLock") @@ -1564,17 +1571,37 @@ public class NetworkStatsService extends INetworkStatsService.Stub { return dataLayer; } + private String[] getAllIfacesSinceBoot(int transport) { + synchronized (mStatsLock) { + final Set ifaceSet; + if (transport == TRANSPORT_WIFI) { + ifaceSet = mAllWifiIfacesSinceBoot; + } else if (transport == TRANSPORT_CELLULAR) { + ifaceSet = mAllMobileIfacesSinceBoot; + } else { + throw new IllegalArgumentException("Invalid transport " + transport); + } + + return ifaceSet.toArray(new String[0]); + } + } + @Override public NetworkStats getUidStatsForTransport(int transport) { PermissionUtils.enforceNetworkStackPermission(mContext); try { - final String[] relevantIfaces = - transport == TRANSPORT_WIFI ? mWifiIfaces : mMobileIfaces; + final String[] ifaceArray = getAllIfacesSinceBoot(transport); // TODO(b/215633405) : mMobileIfaces and mWifiIfaces already contain the stacked // interfaces, so this is not useful, remove it. final String[] ifacesToQuery = - mStatsFactory.augmentWithStackedInterfaces(relevantIfaces); - return getNetworkStatsUidDetail(ifacesToQuery); + mStatsFactory.augmentWithStackedInterfaces(ifaceArray); + final NetworkStats stats = getNetworkStatsUidDetail(ifacesToQuery); + // Clear the interfaces of the stats before returning, so callers won't get this + // information. This is because no caller needs this information for now, and it + // makes it easier to change the implementation later by using the histories in the + // recorder. + stats.clearInterfaces(); + return stats; } catch (RemoteException e) { Log.wtf(TAG, "Error compiling UID stats", e); return new NetworkStats(0L, 0); @@ -1955,7 +1982,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub { final boolean combineSubtypeEnabled = mSettings.getCombineSubtypeEnabled(); final ArraySet mobileIfaces = new ArraySet<>(); - final ArraySet wifiIfaces = new ArraySet<>(); for (NetworkStateSnapshot snapshot : snapshots) { final int displayTransport = getDisplayTransport(snapshot.getNetworkCapabilities().getTransportTypes()); @@ -2000,9 +2026,12 @@ public class NetworkStatsService extends INetworkStatsService.Stub { if (isMobile) { mobileIfaces.add(baseIface); + // If the interface name was present in the wifi set, the interface won't + // be removed from it to prevent stats from getting rollback. + mAllMobileIfacesSinceBoot.add(baseIface); } if (isWifi) { - wifiIfaces.add(baseIface); + mAllWifiIfacesSinceBoot.add(baseIface); } } @@ -2044,9 +2073,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub { findOrCreateNetworkIdentitySet(mActiveUidIfaces, iface).add(ident); if (isMobile) { mobileIfaces.add(iface); + mAllMobileIfacesSinceBoot.add(iface); } if (isWifi) { - wifiIfaces.add(iface); + mAllWifiIfacesSinceBoot.add(iface); } mStatsFactory.noteStackedIface(iface, baseIface); @@ -2055,16 +2085,11 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } mMobileIfaces = mobileIfaces.toArray(new String[0]); - mWifiIfaces = wifiIfaces.toArray(new String[0]); // TODO (b/192758557): Remove debug log. if (CollectionUtils.contains(mMobileIfaces, null)) { throw new NullPointerException( "null element in mMobileIfaces: " + Arrays.toString(mMobileIfaces)); } - if (CollectionUtils.contains(mWifiIfaces, null)) { - throw new NullPointerException( - "null element in mWifiIfaces: " + Arrays.toString(mWifiIfaces)); - } } private static int getSubIdForMobile(@NonNull NetworkStateSnapshot state) { @@ -2532,6 +2557,22 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } pw.decreaseIndent(); + pw.println("All wifi interfaces:"); + pw.increaseIndent(); + for (String iface : mAllWifiIfacesSinceBoot) { + pw.print(iface + " "); + } + pw.println(); + pw.decreaseIndent(); + + pw.println("All mobile interfaces:"); + pw.increaseIndent(); + for (String iface : mAllMobileIfacesSinceBoot) { + pw.print(iface + " "); + } + pw.println(); + pw.decreaseIndent(); + // Get the top openSession callers final HashMap calls; synchronized (mOpenSessionCallsLock) { diff --git a/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java index 9293e5c7fe..cc9c014a49 100644 --- a/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java +++ b/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java @@ -1180,9 +1180,12 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { assertEquals(3, stats.size()); entry1.operations = 1; + entry1.iface = null; assertEquals(entry1, stats.getValues(0, null)); entry2.operations = 1; + entry2.iface = null; assertEquals(entry2, stats.getValues(1, null)); + entry3.iface = null; assertEquals(entry3, stats.getValues(2, null)); }