Merge "[FUI04] Refactor VpnInfo"
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index 7197831..1b4d2e4 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -31,7 +31,6 @@
import android.net.NetworkState;
import android.net.ProxyInfo;
import android.net.UidRange;
-import android.net.VpnInfo;
import android.net.QosSocketInfo;
import android.os.Bundle;
import android.os.IBinder;
diff --git a/core/java/android/net/INetworkStatsService.aidl b/core/java/android/net/INetworkStatsService.aidl
index d5aede7..0baf11e 100644
--- a/core/java/android/net/INetworkStatsService.aidl
+++ b/core/java/android/net/INetworkStatsService.aidl
@@ -23,7 +23,7 @@
import android.net.NetworkStats;
import android.net.NetworkStatsHistory;
import android.net.NetworkTemplate;
-import android.net.VpnInfo;
+import android.net.UnderlyingNetworkInfo;
import android.net.netstats.provider.INetworkStatsProvider;
import android.net.netstats.provider.INetworkStatsProviderCallback;
import android.os.IBinder;
@@ -70,7 +70,7 @@
in Network[] defaultNetworks,
in NetworkState[] networkStates,
in String activeIface,
- in VpnInfo[] vpnInfos);
+ in UnderlyingNetworkInfo[] underlyingNetworkInfos);
/** Force update of statistics. */
@UnsupportedAppUsage
void forceUpdate();
diff --git a/core/java/android/net/VpnInfo.aidl b/core/java/android/net/UnderlyingNetworkInfo.aidl
similarity index 94%
rename from core/java/android/net/VpnInfo.aidl
rename to core/java/android/net/UnderlyingNetworkInfo.aidl
index 8bcaa81..a56f2f4 100644
--- a/core/java/android/net/VpnInfo.aidl
+++ b/core/java/android/net/UnderlyingNetworkInfo.aidl
@@ -16,4 +16,4 @@
package android.net;
-parcelable VpnInfo;
+parcelable UnderlyingNetworkInfo;
diff --git a/core/java/android/net/UnderlyingNetworkInfo.java b/core/java/android/net/UnderlyingNetworkInfo.java
new file mode 100644
index 0000000..8fb4832
--- /dev/null
+++ b/core/java/android/net/UnderlyingNetworkInfo.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * A lightweight container used to carry information on the networks that underly a given
+ * virtual network.
+ *
+ * @hide
+ */
+public final class UnderlyingNetworkInfo implements Parcelable {
+ /** The owner of this network. */
+ public final int ownerUid;
+ /** The interface name of this network. */
+ @NonNull
+ public final String iface;
+ /** The names of the interfaces underlying this network. */
+ @NonNull
+ public final List<String> underlyingIfaces;
+
+ 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 = underlyingIfaces;
+ }
+
+ private UnderlyingNetworkInfo(@NonNull Parcel in) {
+ this.ownerUid = in.readInt();
+ this.iface = in.readString();
+ this.underlyingIfaces = new ArrayList<>();
+ in.readList(this.underlyingIfaces, null /*classLoader*/);
+ }
+
+ @Override
+ public String toString() {
+ return "UnderlyingNetworkInfo{"
+ + "ownerUid=" + ownerUid
+ + ", iface='" + iface + '\''
+ + ", underlyingIfaces='" + underlyingIfaces.toString() + '\''
+ + '}';
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeInt(ownerUid);
+ dest.writeString(iface);
+ dest.writeList(underlyingIfaces);
+ }
+
+ @NonNull
+ public static final Parcelable.Creator<UnderlyingNetworkInfo> CREATOR =
+ new Parcelable.Creator<UnderlyingNetworkInfo>() {
+ @NonNull
+ @Override
+ public UnderlyingNetworkInfo createFromParcel(@NonNull Parcel in) {
+ return new UnderlyingNetworkInfo(in);
+ }
+
+ @NonNull
+ @Override
+ public UnderlyingNetworkInfo[] newArray(int size) {
+ return new UnderlyingNetworkInfo[size];
+ }
+ };
+
+ @Override
+ public boolean equals(Object o) {
+ 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);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(ownerUid, iface, underlyingIfaces);
+ }
+}
diff --git a/core/java/android/net/VpnInfo.java b/core/java/android/net/VpnInfo.java
deleted file mode 100644
index cf58c57..0000000
--- a/core/java/android/net/VpnInfo.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.Arrays;
-
-/**
- * A lightweight container used to carry information of the ongoing VPN.
- * Internal use only.
- *
- * @hide
- */
-public class VpnInfo implements Parcelable {
- public final int ownerUid;
- @Nullable
- public final String vpnIface;
- @Nullable
- public final String[] underlyingIfaces;
-
- public VpnInfo(int ownerUid, @Nullable String vpnIface, @Nullable String[] underlyingIfaces) {
- this.ownerUid = ownerUid;
- this.vpnIface = vpnIface;
- this.underlyingIfaces = underlyingIfaces;
- }
-
- private VpnInfo(@NonNull Parcel in) {
- this.ownerUid = in.readInt();
- this.vpnIface = in.readString();
- this.underlyingIfaces = in.createStringArray();
- }
-
- @Override
- public String toString() {
- return "VpnInfo{"
- + "ownerUid=" + ownerUid
- + ", vpnIface='" + vpnIface + '\''
- + ", underlyingIfaces='" + Arrays.toString(underlyingIfaces) + '\''
- + '}';
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeInt(ownerUid);
- dest.writeString(vpnIface);
- dest.writeStringArray(underlyingIfaces);
- }
-
- @NonNull
- public static final Parcelable.Creator<VpnInfo> CREATOR = new Parcelable.Creator<VpnInfo>() {
- @NonNull
- @Override
- public VpnInfo createFromParcel(@NonNull Parcel in) {
- return new VpnInfo(in);
- }
-
- @NonNull
- @Override
- public VpnInfo[] newArray(int size) {
- return new VpnInfo[size];
- }
- };
-}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 69e792e..554edc6 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -132,8 +132,8 @@
import android.net.TetheringManager;
import android.net.UidRange;
import android.net.UidRangeParcel;
+import android.net.UnderlyingNetworkInfo;
import android.net.Uri;
-import android.net.VpnInfo;
import android.net.VpnManager;
import android.net.VpnService;
import android.net.metrics.INetdEventListener;
@@ -4854,28 +4854,28 @@
*
* <p>Must be called on the handler thread.
*/
- private VpnInfo[] getAllVpnInfo() {
+ private UnderlyingNetworkInfo[] getAllVpnInfo() {
ensureRunningOnConnectivityServiceThread();
synchronized (mVpns) {
if (mLockdownEnabled) {
- return new VpnInfo[0];
+ return new UnderlyingNetworkInfo[0];
}
}
- List<VpnInfo> infoList = new ArrayList<>();
+ List<UnderlyingNetworkInfo> infoList = new ArrayList<>();
for (NetworkAgentInfo nai : mNetworkAgentInfos) {
- VpnInfo info = createVpnInfo(nai);
+ UnderlyingNetworkInfo info = createVpnInfo(nai);
if (info != null) {
infoList.add(info);
}
}
- return infoList.toArray(new VpnInfo[infoList.size()]);
+ return infoList.toArray(new UnderlyingNetworkInfo[infoList.size()]);
}
/**
* @return VPN information for accounting, or null if we can't retrieve all required
* information, e.g underlying ifaces.
*/
- private VpnInfo createVpnInfo(NetworkAgentInfo nai) {
+ private UnderlyingNetworkInfo createVpnInfo(NetworkAgentInfo nai) {
if (!nai.isVPN()) return null;
Network[] underlyingNetworks = nai.declaredUnderlyingNetworks;
@@ -4907,11 +4907,11 @@
// Must be non-null or NetworkStatsService will crash.
// Cannot happen in production code because Vpn only registers the NetworkAgent after the
// tun or ipsec interface is created.
+ // TODO: Remove this check.
if (nai.linkProperties.getInterfaceName() == null) return null;
- return new VpnInfo(nai.networkCapabilities.getOwnerUid(),
- nai.linkProperties.getInterfaceName(),
- interfaces.toArray(new String[0]));
+ return new UnderlyingNetworkInfo(nai.networkCapabilities.getOwnerUid(),
+ nai.linkProperties.getInterfaceName(), interfaces);
}
/**
@@ -8001,10 +8001,10 @@
activeIface = activeLinkProperties.getInterfaceName();
}
- final VpnInfo[] vpnInfos = getAllVpnInfo();
+ final UnderlyingNetworkInfo[] underlyingNetworkInfos = getAllVpnInfo();
try {
- mStatsService.forceUpdateIfaces(
- getDefaultNetworks(), getAllNetworkState(), activeIface, vpnInfos);
+ mStatsService.forceUpdateIfaces(getDefaultNetworks(), getAllNetworkState(), activeIface,
+ underlyingNetworkInfos);
} catch (Exception ignored) {
}
}
@@ -8264,6 +8264,7 @@
return getVpnIfOwner(mDeps.getCallingUid());
}
+ // TODO: stop calling into Vpn.java and get this information from data in this class.
@GuardedBy("mVpns")
private Vpn getVpnIfOwner(int uid) {
final int user = UserHandle.getUserId(uid);
@@ -8272,7 +8273,7 @@
if (vpn == null) {
return null;
} else {
- final VpnInfo info = vpn.getVpnInfo();
+ final UnderlyingNetworkInfo info = vpn.getUnderlyingNetworkInfo();
return (info == null || info.ownerUid != uid) ? null : vpn;
}
}
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 8ce6746..8094477 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -70,7 +70,7 @@
import android.net.RouteInfo;
import android.net.UidRange;
import android.net.UidRangeParcel;
-import android.net.VpnInfo;
+import android.net.UnderlyingNetworkInfo;
import android.net.VpnManager;
import android.net.VpnService;
import android.net.ipsec.ike.ChildSessionCallback;
@@ -1819,12 +1819,12 @@
* This method should not be called if underlying interfaces field is needed, because it doesn't
* have enough data to fill VpnInfo.underlyingIfaces field.
*/
- public synchronized VpnInfo getVpnInfo() {
+ public synchronized UnderlyingNetworkInfo getUnderlyingNetworkInfo() {
if (!isRunningLocked()) {
return null;
}
- return new VpnInfo(mOwnerUID, mInterface, null);
+ return new UnderlyingNetworkInfo(mOwnerUID, mInterface, new ArrayList<>());
}
public synchronized boolean appliesToUid(int uid) {
diff --git a/services/core/java/com/android/server/net/NetworkStatsFactory.java b/services/core/java/com/android/server/net/NetworkStatsFactory.java
index 4faa790..d042b88 100644
--- a/services/core/java/com/android/server/net/NetworkStatsFactory.java
+++ b/services/core/java/com/android/server/net/NetworkStatsFactory.java
@@ -27,7 +27,7 @@
import android.annotation.Nullable;
import android.net.INetd;
import android.net.NetworkStats;
-import android.net.VpnInfo;
+import android.net.UnderlyingNetworkInfo;
import android.net.util.NetdService;
import android.os.RemoteException;
import android.os.StrictMode;
@@ -81,7 +81,7 @@
private final Object mPersistentDataLock = new Object();
/** Set containing info about active VPNs and their underlying networks. */
- private volatile VpnInfo[] mVpnInfos = new VpnInfo[0];
+ private volatile UnderlyingNetworkInfo[] mUnderlyingNetworkInfos = new UnderlyingNetworkInfo[0];
// A persistent snapshot of cumulative stats since device start
@GuardedBy("mPersistentDataLock")
@@ -116,8 +116,8 @@
*
* @param vpnArray The snapshot of the currently-running VPNs.
*/
- public void updateVpnInfos(VpnInfo[] vpnArray) {
- mVpnInfos = vpnArray.clone();
+ public void updateUnderlyingNetworkInfos(UnderlyingNetworkInfo[] vpnArray) {
+ mUnderlyingNetworkInfos = vpnArray.clone();
}
/**
@@ -319,7 +319,7 @@
// code that will acquire other locks within the system server. See b/134244752.
synchronized (mPersistentDataLock) {
// Take a reference. If this gets swapped out, we still have the old reference.
- final VpnInfo[] vpnArray = mVpnInfos;
+ final UnderlyingNetworkInfo[] vpnArray = mUnderlyingNetworkInfos;
// Take a defensive copy. mPersistSnapshot is mutated in some cases below
final NetworkStats prev = mPersistSnapshot.clone();
@@ -369,8 +369,8 @@
}
@GuardedBy("mPersistentDataLock")
- private NetworkStats adjustForTunAnd464Xlat(
- NetworkStats uidDetailStats, NetworkStats previousStats, VpnInfo[] vpnArray) {
+ private NetworkStats adjustForTunAnd464Xlat(NetworkStats uidDetailStats,
+ NetworkStats previousStats, UnderlyingNetworkInfo[] vpnArray) {
// Calculate delta from last snapshot
final NetworkStats delta = uidDetailStats.subtract(previousStats);
@@ -381,8 +381,9 @@
delta.apply464xlatAdjustments(mStackedIfaces);
// Migrate data usage over a VPN to the TUN network.
- for (VpnInfo info : vpnArray) {
- delta.migrateTun(info.ownerUid, info.vpnIface, info.underlyingIfaces);
+ for (UnderlyingNetworkInfo info : vpnArray) {
+ delta.migrateTun(info.ownerUid, info.iface,
+ info.underlyingIfaces.toArray(new String[0]));
// Filter out debug entries as that may lead to over counting.
delta.filterDebugEntries();
}
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index 4be7b48..0ab35a9 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -104,8 +104,8 @@
import android.net.NetworkStatsHistory;
import android.net.NetworkTemplate;
import android.net.TrafficStats;
+import android.net.UnderlyingNetworkInfo;
import android.net.Uri;
-import android.net.VpnInfo;
import android.net.netstats.provider.INetworkStatsProvider;
import android.net.netstats.provider.INetworkStatsProviderCallback;
import android.net.netstats.provider.NetworkStatsProvider;
@@ -973,7 +973,7 @@
Network[] defaultNetworks,
NetworkState[] networkStates,
String activeIface,
- VpnInfo[] vpnInfos) {
+ UnderlyingNetworkInfo[] underlyingNetworkInfos) {
checkNetworkStackPermission(mContext);
final long token = Binder.clearCallingIdentity();
@@ -986,7 +986,7 @@
// Update the VPN underlying interfaces only after the poll is made and tun data has been
// migrated. Otherwise the migration would use the new interfaces instead of the ones that
// were current when the polled data was transferred.
- mStatsFactory.updateVpnInfos(vpnInfos);
+ mStatsFactory.updateUnderlyingNetworkInfos(underlyingNetworkInfos);
}
@Override
diff --git a/tests/net/common/java/android/net/UnderlyingNetworkInfoTest.kt b/tests/net/common/java/android/net/UnderlyingNetworkInfoTest.kt
new file mode 100644
index 0000000..87cfb34
--- /dev/null
+++ b/tests/net/common/java/android/net/UnderlyingNetworkInfoTest.kt
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net
+
+import android.os.Build
+import androidx.test.filters.SmallTest
+import com.android.testutils.DevSdkIgnoreRule
+import com.android.testutils.DevSdkIgnoreRunner
+import com.android.testutils.assertParcelSane
+import org.junit.Test
+import org.junit.runner.RunWith
+import kotlin.test.assertEquals
+
+private const val TEST_OWNER_UID = 123
+private const val TEST_IFACE = "test_tun0"
+private val TEST_IFACE_LIST = listOf("wlan0", "rmnet_data0", "eth0")
+
+@SmallTest
+@RunWith(DevSdkIgnoreRunner::class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
+class UnderlyingNetworkInfoTest {
+ @Test
+ fun testParcelUnparcel() {
+ val testInfo = UnderlyingNetworkInfo(TEST_OWNER_UID, TEST_IFACE, TEST_IFACE_LIST)
+ assertEquals(TEST_OWNER_UID, testInfo.ownerUid)
+ assertEquals(TEST_IFACE, testInfo.iface)
+ assertEquals(TEST_IFACE_LIST, testInfo.underlyingIfaces)
+ assertParcelSane(testInfo, 3)
+
+ val emptyInfo = UnderlyingNetworkInfo(0, String(), listOf())
+ assertEquals(0, emptyInfo.ownerUid)
+ assertEquals(String(), emptyInfo.iface)
+ assertEquals(listOf(), emptyInfo.underlyingIfaces)
+ assertParcelSane(emptyInfo, 3)
+ }
+}
\ No newline at end of file
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 8b536b2..6523acc 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -201,8 +201,8 @@
import android.net.SocketKeepalive;
import android.net.UidRange;
import android.net.UidRangeParcel;
+import android.net.UnderlyingNetworkInfo;
import android.net.Uri;
-import android.net.VpnInfo;
import android.net.VpnManager;
import android.net.metrics.IpConnectivityLog;
import android.net.shared.NetworkMonitorUtils;
@@ -1076,7 +1076,7 @@
private boolean mAgentRegistered = false;
private int mVpnType = VpnManager.TYPE_VPN_SERVICE;
- private VpnInfo mVpnInfo;
+ private UnderlyingNetworkInfo mUnderlyingNetworkInfo;
// These ConditionVariables allow tests to wait for LegacyVpnRunner to be stopped/started.
// TODO: this scheme is ad-hoc and error-prone because it does not fail if, for example, the
@@ -1250,14 +1250,15 @@
}
@Override
- public synchronized VpnInfo getVpnInfo() {
- if (mVpnInfo != null) return mVpnInfo;
+ public synchronized UnderlyingNetworkInfo getUnderlyingNetworkInfo() {
+ if (mUnderlyingNetworkInfo != null) return mUnderlyingNetworkInfo;
- return super.getVpnInfo();
+ return super.getUnderlyingNetworkInfo();
}
- private synchronized void setVpnInfo(VpnInfo vpnInfo) {
- mVpnInfo = vpnInfo;
+ private synchronized void setUnderlyingNetworkInfo(
+ UnderlyingNetworkInfo underlyingNetworkInfo) {
+ mUnderlyingNetworkInfo = underlyingNetworkInfo;
}
}
@@ -5199,20 +5200,22 @@
private void expectForceUpdateIfaces(Network[] networks, String defaultIface,
Integer vpnUid, String vpnIfname, String[] underlyingIfaces) throws Exception {
ArgumentCaptor<Network[]> networksCaptor = ArgumentCaptor.forClass(Network[].class);
- ArgumentCaptor<VpnInfo[]> vpnInfosCaptor = ArgumentCaptor.forClass(VpnInfo[].class);
+ ArgumentCaptor<UnderlyingNetworkInfo[]> vpnInfosCaptor = ArgumentCaptor.forClass(
+ UnderlyingNetworkInfo[].class);
verify(mStatsService, atLeastOnce()).forceUpdateIfaces(networksCaptor.capture(),
any(NetworkState[].class), eq(defaultIface), vpnInfosCaptor.capture());
assertSameElementsNoDuplicates(networksCaptor.getValue(), networks);
- VpnInfo[] infos = vpnInfosCaptor.getValue();
+ UnderlyingNetworkInfo[] infos = vpnInfosCaptor.getValue();
if (vpnUid != null) {
assertEquals("Should have exactly one VPN:", 1, infos.length);
- VpnInfo info = infos[0];
+ UnderlyingNetworkInfo info = infos[0];
assertEquals("Unexpected VPN owner:", (int) vpnUid, info.ownerUid);
- assertEquals("Unexpected VPN interface:", vpnIfname, info.vpnIface);
- assertSameElementsNoDuplicates(underlyingIfaces, info.underlyingIfaces);
+ assertEquals("Unexpected VPN interface:", vpnIfname, info.iface);
+ assertSameElementsNoDuplicates(underlyingIfaces,
+ info.underlyingIfaces.toArray(new String[0]));
} else {
assertEquals(0, infos.length);
return;
@@ -5273,7 +5276,7 @@
waitForIdle();
verify(mStatsService, never())
.forceUpdateIfaces(eq(onlyCell), any(NetworkState[].class), eq(MOBILE_IFNAME),
- eq(new VpnInfo[0]));
+ eq(new UnderlyingNetworkInfo[0]));
reset(mStatsService);
// Roaming change should update ifaces
@@ -5356,8 +5359,8 @@
// network for the VPN...
verify(mStatsService, never()).forceUpdateIfaces(any(Network[].class),
any(NetworkState[].class), any() /* anyString() doesn't match null */,
- argThat(infos -> infos[0].underlyingIfaces.length == 1
- && WIFI_IFNAME.equals(infos[0].underlyingIfaces[0])));
+ argThat(infos -> infos[0].underlyingIfaces.size() == 1
+ && WIFI_IFNAME.equals(infos[0].underlyingIfaces.get(0))));
verifyNoMoreInteractions(mStatsService);
reset(mStatsService);
@@ -5370,8 +5373,8 @@
waitForIdle();
verify(mStatsService).forceUpdateIfaces(any(Network[].class),
any(NetworkState[].class), any() /* anyString() doesn't match null */,
- argThat(vpnInfos -> vpnInfos[0].underlyingIfaces.length == 1
- && WIFI_IFNAME.equals(vpnInfos[0].underlyingIfaces[0])));
+ argThat(vpnInfos -> vpnInfos[0].underlyingIfaces.size() == 1
+ && WIFI_IFNAME.equals(vpnInfos[0].underlyingIfaces.get(0))));
mEthernetNetworkAgent.disconnect();
waitForIdle();
reset(mStatsService);
@@ -8351,8 +8354,9 @@
assertVpnUidRangesUpdated(true, vpnRange, vpnOwnerUid);
mMockVpn.setVpnType(vpnType);
- final VpnInfo vpnInfo = new VpnInfo(vpnOwnerUid, null, null);
- mMockVpn.setVpnInfo(vpnInfo);
+ final UnderlyingNetworkInfo underlyingNetworkInfo =
+ new UnderlyingNetworkInfo(vpnOwnerUid, VPN_IFNAME, new ArrayList<String>());
+ mMockVpn.setUnderlyingNetworkInfo(underlyingNetworkInfo);
}
private void setupConnectionOwnerUidAsVpnApp(int vpnOwnerUid, @VpnManager.VpnType int vpnType)
diff --git a/tests/net/java/com/android/server/net/NetworkStatsBaseTest.java b/tests/net/java/com/android/server/net/NetworkStatsBaseTest.java
index 1b33930e..a058a46 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsBaseTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsBaseTest.java
@@ -33,7 +33,9 @@
import static org.junit.Assert.assertEquals;
import android.net.NetworkStats;
-import android.net.VpnInfo;
+import android.net.UnderlyingNetworkInfo;
+
+import java.util.Arrays;
/** Superclass with utilities for NetworkStats(Service|Factory)Test */
abstract class NetworkStatsBaseTest {
@@ -107,11 +109,11 @@
assertEquals("unexpected operations", operations, entry.operations);
}
- static VpnInfo createVpnInfo(String[] underlyingIfaces) {
+ static UnderlyingNetworkInfo createVpnInfo(String[] underlyingIfaces) {
return createVpnInfo(TUN_IFACE, underlyingIfaces);
}
- static VpnInfo createVpnInfo(String vpnIface, String[] underlyingIfaces) {
- return new VpnInfo(UID_VPN, vpnIface, underlyingIfaces);
+ static UnderlyingNetworkInfo createVpnInfo(String vpnIface, String[] underlyingIfaces) {
+ return new UnderlyingNetworkInfo(UID_VPN, vpnIface, Arrays.asList(underlyingIfaces));
}
}
diff --git a/tests/net/java/com/android/server/net/NetworkStatsFactoryTest.java b/tests/net/java/com/android/server/net/NetworkStatsFactoryTest.java
index 76647a6..f3ae9b0 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsFactoryTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsFactoryTest.java
@@ -36,7 +36,7 @@
import android.content.res.Resources;
import android.net.NetworkStats;
import android.net.TrafficStats;
-import android.net.VpnInfo;
+import android.net.UnderlyingNetworkInfo;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
@@ -79,7 +79,7 @@
// related to networkStatsFactory is compiled to a minimal native library and loaded here.
System.loadLibrary("networkstatsfactorytestjni");
mFactory = new NetworkStatsFactory(mTestProc, false);
- mFactory.updateVpnInfos(new VpnInfo[0]);
+ mFactory.updateUnderlyingNetworkInfos(new UnderlyingNetworkInfo[0]);
}
@After
@@ -105,8 +105,9 @@
@Test
public void testVpnRewriteTrafficThroughItself() throws Exception {
- VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
- mFactory.updateVpnInfos(vpnInfos);
+ UnderlyingNetworkInfo[] underlyingNetworkInfos =
+ new UnderlyingNetworkInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
+ mFactory.updateUnderlyingNetworkInfos(underlyingNetworkInfos);
// create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
// overhead per packet):
@@ -134,8 +135,9 @@
@Test
public void testVpnWithClat() throws Exception {
- VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {CLAT_PREFIX + TEST_IFACE})};
- mFactory.updateVpnInfos(vpnInfos);
+ final UnderlyingNetworkInfo[] underlyingNetworkInfos = new UnderlyingNetworkInfo[] {
+ createVpnInfo(new String[] {CLAT_PREFIX + TEST_IFACE})};
+ mFactory.updateUnderlyingNetworkInfos(underlyingNetworkInfos);
mFactory.noteStackedIface(CLAT_PREFIX + TEST_IFACE, TEST_IFACE);
// create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
@@ -167,8 +169,9 @@
@Test
public void testVpnWithOneUnderlyingIface() throws Exception {
- VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
- mFactory.updateVpnInfos(vpnInfos);
+ final UnderlyingNetworkInfo[] underlyingNetworkInfos =
+ new UnderlyingNetworkInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
+ mFactory.updateUnderlyingNetworkInfos(underlyingNetworkInfos);
// create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
// overhead per packet):
@@ -191,8 +194,9 @@
@Test
public void testVpnWithOneUnderlyingIfaceAndOwnTraffic() throws Exception {
// WiFi network is connected and VPN is using WiFi (which has TEST_IFACE).
- VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
- mFactory.updateVpnInfos(vpnInfos);
+ final UnderlyingNetworkInfo[] underlyingNetworkInfos =
+ new UnderlyingNetworkInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
+ mFactory.updateUnderlyingNetworkInfos(underlyingNetworkInfos);
// create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
// overhead per packet):
@@ -219,8 +223,9 @@
@Test
public void testVpnWithOneUnderlyingIface_withCompression() throws Exception {
// WiFi network is connected and VPN is using WiFi (which has TEST_IFACE).
- VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
- mFactory.updateVpnInfos(vpnInfos);
+ final UnderlyingNetworkInfo[] underlyingNetworkInfos =
+ new UnderlyingNetworkInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
+ mFactory.updateUnderlyingNetworkInfos(underlyingNetworkInfos);
// create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
// overhead per packet):
@@ -242,8 +247,9 @@
// WiFi and Cell networks are connected and VPN is using WiFi (which has TEST_IFACE) and
// Cell (which has TEST_IFACE2) and has declared both of them in its underlying network set.
// Additionally, VPN is duplicating traffic across both WiFi and Cell.
- VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE, TEST_IFACE2})};
- mFactory.updateVpnInfos(vpnInfos);
+ final UnderlyingNetworkInfo[] underlyingNetworkInfos =
+ new UnderlyingNetworkInfo[] {createVpnInfo(new String[] {TEST_IFACE, TEST_IFACE2})};
+ mFactory.updateUnderlyingNetworkInfos(underlyingNetworkInfos);
// create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
// overhead per packet):
@@ -267,10 +273,10 @@
public void testConcurrentVpns() throws Exception {
// Assume two VPNs are connected on two different network interfaces. VPN1 is using
// TEST_IFACE and VPN2 is using TEST_IFACE2.
- final VpnInfo[] vpnInfos = new VpnInfo[] {
+ final UnderlyingNetworkInfo[] underlyingNetworkInfos = new UnderlyingNetworkInfo[] {
createVpnInfo(TUN_IFACE, new String[] {TEST_IFACE}),
createVpnInfo(TUN_IFACE2, new String[] {TEST_IFACE2})};
- mFactory.updateVpnInfos(vpnInfos);
+ mFactory.updateUnderlyingNetworkInfos(underlyingNetworkInfos);
// create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
// overhead per packet):
@@ -308,8 +314,9 @@
// WiFi and Cell networks are connected and VPN is using WiFi (which has TEST_IFACE) and
// Cell (which has TEST_IFACE2) and has declared both of them in its underlying network set.
// Additionally, VPN is arbitrarily splitting traffic across WiFi and Cell.
- VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE, TEST_IFACE2})};
- mFactory.updateVpnInfos(vpnInfos);
+ final UnderlyingNetworkInfo[] underlyingNetworkInfos =
+ new UnderlyingNetworkInfo[] {createVpnInfo(new String[] {TEST_IFACE, TEST_IFACE2})};
+ mFactory.updateUnderlyingNetworkInfos(underlyingNetworkInfos);
// create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
// overhead per packet):
@@ -335,8 +342,9 @@
// WiFi and Cell networks are connected and VPN is using WiFi (which has TEST_IFACE) and
// Cell (which has TEST_IFACE2) and has declared both of them in its underlying network set.
// Additionally, VPN is arbitrarily splitting compressed traffic across WiFi and Cell.
- VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE, TEST_IFACE2})};
- mFactory.updateVpnInfos(vpnInfos);
+ final UnderlyingNetworkInfo[] underlyingNetworkInfos =
+ new UnderlyingNetworkInfo[] {createVpnInfo(new String[] {TEST_IFACE, TEST_IFACE2})};
+ mFactory.updateUnderlyingNetworkInfos(underlyingNetworkInfos);
// create some traffic (assume 10 bytes of MTU for VPN interface:
// 1000 bytes (100 packets) were sent/received by UID_RED over VPN.
@@ -357,8 +365,9 @@
public void testVpnWithIncorrectUnderlyingIface() throws Exception {
// WiFi and Cell networks are connected and VPN is using Cell (which has TEST_IFACE2),
// but has declared only WiFi (TEST_IFACE) in its underlying network set.
- VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
- mFactory.updateVpnInfos(vpnInfos);
+ final UnderlyingNetworkInfo[] underlyingNetworkInfos =
+ new UnderlyingNetworkInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
+ mFactory.updateUnderlyingNetworkInfos(underlyingNetworkInfos);
// create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
// overhead per packet):
diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
index b4e37de..dde78aa 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -86,7 +86,7 @@
import android.net.NetworkStats;
import android.net.NetworkStatsHistory;
import android.net.NetworkTemplate;
-import android.net.VpnInfo;
+import android.net.UnderlyingNetworkInfo;
import android.net.netstats.provider.INetworkStatsProviderCallback;
import android.os.ConditionVariable;
import android.os.Handler;
@@ -286,7 +286,8 @@
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
- mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]);
+ mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states),
+ new UnderlyingNetworkInfo[0]);
// verify service has empty history for wifi
assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
@@ -328,7 +329,8 @@
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
- mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]);
+ mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states),
+ new UnderlyingNetworkInfo[0]);
// verify service has empty history for wifi
assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
@@ -401,7 +403,8 @@
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
- mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]);
+ mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states),
+ new UnderlyingNetworkInfo[0]);
// modify some number on wifi, and trigger poll event
incrementCurrentTime(2 * HOUR_IN_MILLIS);
@@ -441,7 +444,8 @@
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
- mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), new VpnInfo[0]);
+ mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states),
+ new UnderlyingNetworkInfo[0]);
// create some traffic on first network
incrementCurrentTime(HOUR_IN_MILLIS);
@@ -475,7 +479,8 @@
.insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
.insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L));
- mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), new VpnInfo[0]);
+ mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states),
+ new UnderlyingNetworkInfo[0]);
forcePollAndWaitForIdle();
@@ -514,7 +519,8 @@
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
- mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]);
+ mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states),
+ new UnderlyingNetworkInfo[0]);
// create some traffic
incrementCurrentTime(HOUR_IN_MILLIS);
@@ -581,7 +587,7 @@
setMobileRatTypeAndWaitForIdle(TelephonyManager.NETWORK_TYPE_UMTS);
mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states),
- new VpnInfo[0]);
+ new UnderlyingNetworkInfo[0]);
// Create some traffic.
incrementCurrentTime(MINUTE_IN_MILLIS);
@@ -655,7 +661,8 @@
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
- mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]);
+ mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states),
+ new UnderlyingNetworkInfo[0]);
// create some traffic for two apps
incrementCurrentTime(HOUR_IN_MILLIS);
@@ -713,7 +720,8 @@
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
- mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]);
+ mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states),
+ new UnderlyingNetworkInfo[0]);
NetworkStats.Entry entry1 = new NetworkStats.Entry(
TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L);
@@ -756,7 +764,8 @@
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
- mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]);
+ mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states),
+ new UnderlyingNetworkInfo[0]);
NetworkStats.Entry uidStats = new NetworkStats.Entry(
TEST_IFACE, UID_BLUE, SET_DEFAULT, 0xF00D, 1024L, 8L, 512L, 4L, 0L);
@@ -810,7 +819,8 @@
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
- mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]);
+ mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states),
+ new UnderlyingNetworkInfo[0]);
// create some initial traffic
incrementCurrentTime(HOUR_IN_MILLIS);
@@ -867,7 +877,8 @@
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
- mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]);
+ mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states),
+ new UnderlyingNetworkInfo[0]);
// create some initial traffic
incrementCurrentTime(HOUR_IN_MILLIS);
@@ -906,7 +917,8 @@
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
- mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), new VpnInfo[0]);
+ mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states),
+ new UnderlyingNetworkInfo[0]);
// Create some traffic
incrementCurrentTime(HOUR_IN_MILLIS);
@@ -943,7 +955,8 @@
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
- mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), new VpnInfo[0]);
+ mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states),
+ new UnderlyingNetworkInfo[0]);
// create some tethering traffic
incrementCurrentTime(HOUR_IN_MILLIS);
@@ -999,7 +1012,8 @@
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
- mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]);
+ mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states),
+ new UnderlyingNetworkInfo[0]);
// verify service has empty history for wifi
assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
@@ -1104,7 +1118,8 @@
mService.registerNetworkStatsProvider("TEST", provider);
assertNotNull(cb);
- mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]);
+ mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states),
+ new UnderlyingNetworkInfo[0]);
// Verifies that one requestStatsUpdate will be called during iface update.
provider.expectOnRequestStatsUpdate(0 /* unused */);
@@ -1155,7 +1170,8 @@
expectDefaultSettings();
NetworkState[] states =
new NetworkState[]{buildWifiState(true /* isMetered */, TEST_IFACE)};
- mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]);
+ mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states),
+ new UnderlyingNetworkInfo[0]);
// Register custom provider and retrieve callback.
final TestableNetworkStatsProviderBinder provider =
@@ -1204,7 +1220,7 @@
// 3G network comes online.
setMobileRatTypeAndWaitForIdle(TelephonyManager.NETWORK_TYPE_UMTS);
mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states),
- new VpnInfo[0]);
+ new UnderlyingNetworkInfo[0]);
// Create some traffic.
incrementCurrentTime(MINUTE_IN_MILLIS);
@@ -1274,7 +1290,8 @@
NetworkState[] states = new NetworkState[]{
buildWifiState(true /*isMetered*/, TEST_IFACE2), buildMobile3gState(IMSI_1)};
expectNetworkStatsUidDetail(buildEmptyStats());
- mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]);
+ mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states),
+ new UnderlyingNetworkInfo[0]);
// Create some traffic on mobile network.
incrementCurrentTime(HOUR_IN_MILLIS);