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:
@@ -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.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user