Hold wifi and mobile interfaces since boot in NetworkStatsService am: a2f1cf3576

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/modules/Connectivity/+/18710006

Change-Id: Ie53afd7a2c6cfdd46a1ed3954a1aceac9bd120eb
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Aaron Huang
2022-06-03 09:25:50 +00:00
committed by Automerger Merge Worker
3 changed files with 70 additions and 15 deletions

View File

@@ -1299,6 +1299,17 @@ public final class NetworkStats implements Parcelable, Iterable<NetworkStats.Ent
return ret; return ret;
} }
/**
* Removes the interface name from all entries.
* This mutates the original structure in place.
* @hide
*/
public void clearInterfaces() {
for (int i = 0; i < size; i++) {
iface[i] = null;
}
}
/** /**
* Only keep entries that match all specified filters. * Only keep entries that match all specified filters.
* *

View File

@@ -25,6 +25,7 @@ import static android.content.Intent.ACTION_UID_REMOVED;
import static android.content.Intent.ACTION_USER_REMOVED; import static android.content.Intent.ACTION_USER_REMOVED;
import static android.content.Intent.EXTRA_UID; import static android.content.Intent.EXTRA_UID;
import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI; import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import static android.net.NetworkStats.DEFAULT_NETWORK_ALL; import static android.net.NetworkStats.DEFAULT_NETWORK_ALL;
import static android.net.NetworkStats.IFACE_ALL; import static android.net.NetworkStats.IFACE_ALL;
@@ -172,6 +173,7 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.concurrent.Semaphore; import java.util.concurrent.Semaphore;
@@ -343,11 +345,16 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
@GuardedBy("mStatsLock") @GuardedBy("mStatsLock")
private String mActiveIface; private String mActiveIface;
/** Set of any ifaces associated with mobile networks since boot. */ /** Set of all ifaces currently associated with mobile networks. */
private volatile String[] mMobileIfaces = new String[0]; private volatile String[] mMobileIfaces = new String[0];
/** Set of any ifaces associated with wifi networks since boot. */ /* A set of all interfaces that have ever been associated with mobile networks since boot. */
private volatile String[] mWifiIfaces = new String[0]; @GuardedBy("mStatsLock")
private final Set<String> mAllMobileIfacesSinceBoot = new ArraySet<>();
/* A set of all interfaces that have ever been associated with wifi networks since boot. */
@GuardedBy("mStatsLock")
private final Set<String> mAllWifiIfacesSinceBoot = new ArraySet<>();
/** Set of all ifaces currently used by traffic that does not explicitly specify a Network. */ /** Set of all ifaces currently used by traffic that does not explicitly specify a Network. */
@GuardedBy("mStatsLock") @GuardedBy("mStatsLock")
@@ -1564,17 +1571,37 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
return dataLayer; return dataLayer;
} }
private String[] getAllIfacesSinceBoot(int transport) {
synchronized (mStatsLock) {
final Set<String> 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 @Override
public NetworkStats getUidStatsForTransport(int transport) { public NetworkStats getUidStatsForTransport(int transport) {
PermissionUtils.enforceNetworkStackPermission(mContext); PermissionUtils.enforceNetworkStackPermission(mContext);
try { try {
final String[] relevantIfaces = final String[] ifaceArray = getAllIfacesSinceBoot(transport);
transport == TRANSPORT_WIFI ? mWifiIfaces : mMobileIfaces;
// TODO(b/215633405) : mMobileIfaces and mWifiIfaces already contain the stacked // TODO(b/215633405) : mMobileIfaces and mWifiIfaces already contain the stacked
// interfaces, so this is not useful, remove it. // interfaces, so this is not useful, remove it.
final String[] ifacesToQuery = final String[] ifacesToQuery =
mStatsFactory.augmentWithStackedInterfaces(relevantIfaces); mStatsFactory.augmentWithStackedInterfaces(ifaceArray);
return getNetworkStatsUidDetail(ifacesToQuery); 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) { } catch (RemoteException e) {
Log.wtf(TAG, "Error compiling UID stats", e); Log.wtf(TAG, "Error compiling UID stats", e);
return new NetworkStats(0L, 0); return new NetworkStats(0L, 0);
@@ -1955,7 +1982,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
final boolean combineSubtypeEnabled = mSettings.getCombineSubtypeEnabled(); final boolean combineSubtypeEnabled = mSettings.getCombineSubtypeEnabled();
final ArraySet<String> mobileIfaces = new ArraySet<>(); final ArraySet<String> mobileIfaces = new ArraySet<>();
final ArraySet<String> wifiIfaces = new ArraySet<>();
for (NetworkStateSnapshot snapshot : snapshots) { for (NetworkStateSnapshot snapshot : snapshots) {
final int displayTransport = final int displayTransport =
getDisplayTransport(snapshot.getNetworkCapabilities().getTransportTypes()); getDisplayTransport(snapshot.getNetworkCapabilities().getTransportTypes());
@@ -2000,9 +2026,12 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
if (isMobile) { if (isMobile) {
mobileIfaces.add(baseIface); 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) { if (isWifi) {
wifiIfaces.add(baseIface); mAllWifiIfacesSinceBoot.add(baseIface);
} }
} }
@@ -2044,9 +2073,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
findOrCreateNetworkIdentitySet(mActiveUidIfaces, iface).add(ident); findOrCreateNetworkIdentitySet(mActiveUidIfaces, iface).add(ident);
if (isMobile) { if (isMobile) {
mobileIfaces.add(iface); mobileIfaces.add(iface);
mAllMobileIfacesSinceBoot.add(iface);
} }
if (isWifi) { if (isWifi) {
wifiIfaces.add(iface); mAllWifiIfacesSinceBoot.add(iface);
} }
mStatsFactory.noteStackedIface(iface, baseIface); mStatsFactory.noteStackedIface(iface, baseIface);
@@ -2055,16 +2085,11 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
} }
mMobileIfaces = mobileIfaces.toArray(new String[0]); mMobileIfaces = mobileIfaces.toArray(new String[0]);
mWifiIfaces = wifiIfaces.toArray(new String[0]);
// TODO (b/192758557): Remove debug log. // TODO (b/192758557): Remove debug log.
if (CollectionUtils.contains(mMobileIfaces, null)) { if (CollectionUtils.contains(mMobileIfaces, null)) {
throw new NullPointerException( throw new NullPointerException(
"null element in mMobileIfaces: " + Arrays.toString(mMobileIfaces)); "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) { private static int getSubIdForMobile(@NonNull NetworkStateSnapshot state) {
@@ -2532,6 +2557,22 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
} }
pw.decreaseIndent(); 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 // Get the top openSession callers
final HashMap calls; final HashMap calls;
synchronized (mOpenSessionCallsLock) { synchronized (mOpenSessionCallsLock) {

View File

@@ -1180,9 +1180,12 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
assertEquals(3, stats.size()); assertEquals(3, stats.size());
entry1.operations = 1; entry1.operations = 1;
entry1.iface = null;
assertEquals(entry1, stats.getValues(0, null)); assertEquals(entry1, stats.getValues(0, null));
entry2.operations = 1; entry2.operations = 1;
entry2.iface = null;
assertEquals(entry2, stats.getValues(1, null)); assertEquals(entry2, stats.getValues(1, null));
entry3.iface = null;
assertEquals(entry3, stats.getValues(2, null)); assertEquals(entry3, stats.getValues(2, null));
} }