Add getters to UnderlyingNetworkInfo
Address API review feedback, add getters to UnderlyingNetworkInfo instead of exposing fields. Instead of wasting memory by converting this into an array, have migrateTun take a List<String>. In turn, tunAdjustmentInit should also take a List<String>. Bug: 183972554 Test: atest android.net.UnderlyingNetworkInfoTest Change-Id: Id59744097208d91298a25ef110ade91a9cf291a1
This commit is contained in:
@@ -38,6 +38,7 @@ import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Predicate;
|
||||
@@ -1423,11 +1424,11 @@ public final class NetworkStats implements Parcelable {
|
||||
* @hide
|
||||
*/
|
||||
public void migrateTun(int tunUid, @NonNull String tunIface,
|
||||
@NonNull String[] underlyingIfaces) {
|
||||
@NonNull List<String> underlyingIfaces) {
|
||||
// Combined usage by all apps using VPN.
|
||||
final Entry tunIfaceTotal = new Entry();
|
||||
// Usage by VPN, grouped by its {@code underlyingIfaces}.
|
||||
final Entry[] perInterfaceTotal = new Entry[underlyingIfaces.length];
|
||||
final Entry[] perInterfaceTotal = new Entry[underlyingIfaces.size()];
|
||||
// Usage by VPN, summed across all its {@code underlyingIfaces}.
|
||||
final Entry underlyingIfacesTotal = new Entry();
|
||||
|
||||
@@ -1468,7 +1469,7 @@ public final class NetworkStats implements Parcelable {
|
||||
* {@code underlyingIfaces}
|
||||
*/
|
||||
private void tunAdjustmentInit(int tunUid, @NonNull String tunIface,
|
||||
@NonNull String[] underlyingIfaces, @NonNull Entry tunIfaceTotal,
|
||||
@NonNull List<String> underlyingIfaces, @NonNull Entry tunIfaceTotal,
|
||||
@NonNull Entry[] perInterfaceTotal, @NonNull Entry underlyingIfacesTotal) {
|
||||
final Entry recycle = new Entry();
|
||||
for (int i = 0; i < size; i++) {
|
||||
@@ -1488,8 +1489,8 @@ public final class NetworkStats implements Parcelable {
|
||||
|
||||
if (recycle.uid == tunUid) {
|
||||
// Add up traffic through tunUid's underlying interfaces.
|
||||
for (int j = 0; j < underlyingIfaces.length; j++) {
|
||||
if (Objects.equals(underlyingIfaces[j], recycle.iface)) {
|
||||
for (int j = 0; j < underlyingIfaces.size(); j++) {
|
||||
if (Objects.equals(underlyingIfaces.get(j), recycle.iface)) {
|
||||
perInterfaceTotal[j].add(recycle);
|
||||
underlyingIfacesTotal.add(recycle);
|
||||
break;
|
||||
@@ -1515,12 +1516,12 @@ public final class NetworkStats implements Parcelable {
|
||||
* underlyingIfaces}
|
||||
*/
|
||||
private Entry[] addTrafficToApplications(int tunUid, @NonNull String tunIface,
|
||||
@NonNull String[] underlyingIfaces, @NonNull Entry tunIfaceTotal,
|
||||
@NonNull List<String> underlyingIfaces, @NonNull Entry tunIfaceTotal,
|
||||
@NonNull Entry[] perInterfaceTotal, @NonNull Entry underlyingIfacesTotal) {
|
||||
// Traffic that should be moved off of each underlying interface for tunUid (see
|
||||
// deductTrafficFromVpnApp below).
|
||||
final Entry[] moved = new Entry[underlyingIfaces.length];
|
||||
for (int i = 0; i < underlyingIfaces.length; i++) {
|
||||
final Entry[] moved = new Entry[underlyingIfaces.size()];
|
||||
for (int i = 0; i < underlyingIfaces.size(); i++) {
|
||||
moved[i] = new Entry();
|
||||
}
|
||||
|
||||
@@ -1582,8 +1583,8 @@ public final class NetworkStats implements Parcelable {
|
||||
}
|
||||
// In a second pass, distribute these values across interfaces in the proportion that
|
||||
// each interface represents of the total traffic of the underlying interfaces.
|
||||
for (int j = 0; j < underlyingIfaces.length; j++) {
|
||||
tmpEntry.iface = underlyingIfaces[j];
|
||||
for (int j = 0; j < underlyingIfaces.size(); j++) {
|
||||
tmpEntry.iface = underlyingIfaces.get(j);
|
||||
tmpEntry.rxBytes = 0;
|
||||
// Reset 'set' to correct value since it gets updated when adding debug info below.
|
||||
tmpEntry.set = set[i];
|
||||
@@ -1638,14 +1639,14 @@ public final class NetworkStats implements Parcelable {
|
||||
|
||||
private void deductTrafficFromVpnApp(
|
||||
int tunUid,
|
||||
@NonNull String[] underlyingIfaces,
|
||||
@NonNull List<String> underlyingIfaces,
|
||||
@NonNull Entry[] moved) {
|
||||
for (int i = 0; i < underlyingIfaces.length; i++) {
|
||||
for (int i = 0; i < underlyingIfaces.size(); i++) {
|
||||
moved[i].uid = tunUid;
|
||||
// Add debug info
|
||||
moved[i].set = SET_DBG_VPN_OUT;
|
||||
moved[i].tag = TAG_NONE;
|
||||
moved[i].iface = underlyingIfaces[i];
|
||||
moved[i].iface = underlyingIfaces.get(i);
|
||||
moved[i].metered = METERED_ALL;
|
||||
moved[i].roaming = ROAMING_ALL;
|
||||
moved[i].defaultNetwork = DEFAULT_NETWORK_ALL;
|
||||
@@ -1658,7 +1659,7 @@ public final class NetworkStats implements Parcelable {
|
||||
// METERED_NO, which should be the case as it comes directly from the /proc file.
|
||||
// We only blend in the roaming data after applying these adjustments, by checking the
|
||||
// NetworkIdentity of the underlying iface.
|
||||
final int idxVpnBackground = findIndex(underlyingIfaces[i], tunUid, SET_DEFAULT,
|
||||
final int idxVpnBackground = findIndex(underlyingIfaces.get(i), tunUid, SET_DEFAULT,
|
||||
TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO);
|
||||
if (idxVpnBackground != -1) {
|
||||
// Note - tunSubtract also updates moved[i]; whatever traffic that's left is removed
|
||||
@@ -1666,7 +1667,7 @@ public final class NetworkStats implements Parcelable {
|
||||
tunSubtract(idxVpnBackground, this, moved[i]);
|
||||
}
|
||||
|
||||
final int idxVpnForeground = findIndex(underlyingIfaces[i], tunUid, SET_FOREGROUND,
|
||||
final int idxVpnForeground = findIndex(underlyingIfaces.get(i), tunUid, SET_FOREGROUND,
|
||||
TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO);
|
||||
if (idxVpnForeground != -1) {
|
||||
tunSubtract(idxVpnForeground, this, moved[i]);
|
||||
|
||||
@@ -37,36 +37,56 @@ import java.util.Objects;
|
||||
@SystemApi(client = MODULE_LIBRARIES)
|
||||
public final class UnderlyingNetworkInfo implements Parcelable {
|
||||
/** The owner of this network. */
|
||||
public final int ownerUid;
|
||||
private final int mOwnerUid;
|
||||
|
||||
/** The interface name of this network. */
|
||||
@NonNull
|
||||
public final String iface;
|
||||
private final String mIface;
|
||||
|
||||
/** The names of the interfaces underlying this network. */
|
||||
@NonNull
|
||||
public final List<String> underlyingIfaces;
|
||||
private final List<String> mUnderlyingIfaces;
|
||||
|
||||
public UnderlyingNetworkInfo(int ownerUid, @NonNull String iface,
|
||||
@NonNull List<String> underlyingIfaces) {
|
||||
Objects.requireNonNull(iface);
|
||||
Objects.requireNonNull(underlyingIfaces);
|
||||
this.ownerUid = ownerUid;
|
||||
this.iface = iface;
|
||||
this.underlyingIfaces = Collections.unmodifiableList(new ArrayList<>(underlyingIfaces));
|
||||
mOwnerUid = ownerUid;
|
||||
mIface = iface;
|
||||
mUnderlyingIfaces = Collections.unmodifiableList(new ArrayList<>(underlyingIfaces));
|
||||
}
|
||||
|
||||
private UnderlyingNetworkInfo(@NonNull Parcel in) {
|
||||
this.ownerUid = in.readInt();
|
||||
this.iface = in.readString();
|
||||
this.underlyingIfaces = new ArrayList<>();
|
||||
in.readList(this.underlyingIfaces, null /*classLoader*/);
|
||||
mOwnerUid = in.readInt();
|
||||
mIface = in.readString();
|
||||
List<String> underlyingIfaces = new ArrayList<>();
|
||||
in.readList(underlyingIfaces, null /*classLoader*/);
|
||||
mUnderlyingIfaces = Collections.unmodifiableList(underlyingIfaces);
|
||||
}
|
||||
|
||||
/** Get the owner of this network. */
|
||||
public int getOwnerUid() {
|
||||
return mOwnerUid;
|
||||
}
|
||||
|
||||
/** Get the interface name of this network. */
|
||||
@NonNull
|
||||
public String getIface() {
|
||||
return mIface;
|
||||
}
|
||||
|
||||
/** Get the names of the interfaces underlying this network. */
|
||||
@NonNull
|
||||
public List<String> getUnderlyingIfaces() {
|
||||
return mUnderlyingIfaces;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "UnderlyingNetworkInfo{"
|
||||
+ "ownerUid=" + ownerUid
|
||||
+ ", iface='" + iface + '\''
|
||||
+ ", underlyingIfaces='" + underlyingIfaces.toString() + '\''
|
||||
+ "ownerUid=" + mOwnerUid
|
||||
+ ", iface='" + mIface + '\''
|
||||
+ ", underlyingIfaces='" + mUnderlyingIfaces.toString() + '\''
|
||||
+ '}';
|
||||
}
|
||||
|
||||
@@ -77,9 +97,9 @@ public final class UnderlyingNetworkInfo implements Parcelable {
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
dest.writeInt(ownerUid);
|
||||
dest.writeString(iface);
|
||||
dest.writeList(underlyingIfaces);
|
||||
dest.writeInt(mOwnerUid);
|
||||
dest.writeString(mIface);
|
||||
dest.writeList(mUnderlyingIfaces);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@@ -103,13 +123,13 @@ public final class UnderlyingNetworkInfo implements Parcelable {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof UnderlyingNetworkInfo)) return false;
|
||||
final UnderlyingNetworkInfo that = (UnderlyingNetworkInfo) o;
|
||||
return ownerUid == that.ownerUid
|
||||
&& Objects.equals(iface, that.iface)
|
||||
&& Objects.equals(underlyingIfaces, that.underlyingIfaces);
|
||||
return mOwnerUid == that.getOwnerUid()
|
||||
&& Objects.equals(mIface, that.getIface())
|
||||
&& Objects.equals(mUnderlyingIfaces, that.getUnderlyingIfaces());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(ownerUid, iface, underlyingIfaces);
|
||||
return Objects.hash(mOwnerUid, mIface, mUnderlyingIfaces);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -382,8 +382,8 @@ public class NetworkStatsFactory {
|
||||
|
||||
// Migrate data usage over a VPN to the TUN network.
|
||||
for (UnderlyingNetworkInfo info : vpnArray) {
|
||||
delta.migrateTun(info.ownerUid, info.iface,
|
||||
info.underlyingIfaces.toArray(new String[0]));
|
||||
delta.migrateTun(info.getOwnerUid(), info.getIface(),
|
||||
info.getUnderlyingIfaces());
|
||||
// Filter out debug entries as that may lead to over counting.
|
||||
delta.filterDebugEntries();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user